Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CreateGeometryProxy function throwing exception in C#

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
Anonymous
991 Views, 9 Replies

CreateGeometryProxy function throwing exception in C#

I am creating code to assemble component in an assembly and adding constraints. When I creating a proxy for the component, the CreateGeometryProxy function is throwing exception in C#. Here's the code.

 

private void GenerateModelsNew()
{
string assemblyfilename = @"D:\Assembly.iam";
string tailassemblyfilename = @"D:\Component.iam";
string tailmodelstatename = "COMP-512";
AssemblyDocument assemblyDoc = null;
AssemblyComponentDefinition asmCompDef = null;
TransientGeometry geomObj = null;
Matrix matrixObj = null;
try
{
InstantiateInventor();

//Open Assembly
assemblyDoc = (AssemblyDocument)inventorApp.Documents.Open(assemblyfilename, true);

//get component definition
asmCompDef = assemblyDoc.ComponentDefinition;

geomObj = inventorApp.TransientGeometry;
matrixObj = geomObj.CreateMatrix();

//Add component
ComponentOccurrence occObj = asmCompDef.Occurrences.Add(tailassemblyfilename, matrixObj);
AssemblyComponentDefinition occCompDef = (AssemblyComponentDefinition)occObj.Definition;

occObj.ActiveModelState = tailmodelstatename;
occObj.Grounded = false;

assemblyDoc.Update2(true);

//Assembly Work Plane reference
WorkPlane mainAssemblyPlane1 = asmCompDef.WorkPlanes["PlaneRef1"];
WorkPlane mainAssemblyPlane2 = asmCompDef.WorkPlanes["PlaneRef2"];
WorkPlane mainAssemblyPlane3 = asmCompDef.WorkPlanes["PlaneRef3"];

//Component work plance reference
WorkPlane occPlane1 = occCompDef.WorkPlanes["PlaneRef1"];
WorkPlane occPlane2 = occCompDef.WorkPlanes["PlaneRef2"];
WorkPlane occPlane3 = occCompDef.WorkPlanes["PlaneRef3"];


//Create Proxy Plane for Cmponent
Object occProxyPlaneObj;

occObj.CreateGeometryProxy(occPlane1, out occProxyPlaneObj);
WorkPlaneProxy occPlane1Proxy = (WorkPlaneProxy)occProxyPlaneObj;

occObj.CreateGeometryProxy(occPlane2, out occProxyPlaneObj);
WorkPlaneProxy occPlane2Proxy = (WorkPlaneProxy)occProxyPlaneObj;

occObj.CreateGeometryProxy(occPlane3, out occProxyPlaneObj);
WorkPlaneProxy occPlane3Proxy = (WorkPlaneProxy)occProxyPlaneObj;


//Add constraints
asmCompDef.Constraints.AddMateConstraint(mainAssemblyPlane1, occPlane1Proxy, 0, InferredTypeEnum.kNoInference, InferredTypeEnum.kNoInference, null, null);

}
catch (Exception ex)
{
txtStatus.AppendText("Exception: " + ex.Message + "\r\n");
txtStatus.AppendText("StackTrace: " + ex.StackTrace.ToString() + "\r\n");
}
}

 

Thanks in advace,

Karthikeyan.

9 REPLIES 9
Message 2 of 10
WCrihfield
in reply to: Anonymous

Hi @Anonymous.  I admittedly am not well versed in C#, but I can often follow it when it's fairly simple, due to how similar it is to vb.net.  The CreateGeometryProxy method does not specify 'ByRef' on its online help page, but since it is an 'output' object of a specific type that does not exist yet, I treat it that way.  So, I always create the variable for the WorkPlaneProxy (or other proxy type object) before the line of code using that method, then supply that variable in place of that second variable within the method.  Given that history, and it working for me, I suggest the following modified version of that block of code.

//Create Proxy Plane For Cmponent

WorkPlaneProxy occPlane1Proxy;
occObj.CreateGeometryProxy(occPlane1, Out occPlane1Proxy);

WorkPlaneProxy occPlane2Proxy;
occObj.CreateGeometryProxy(occPlane2, Out occPlane2Proxy);

WorkPlaneProxy occPlane3Proxy;
occObj.CreateGeometryProxy(occPlane3, Out occPlane3Proxy);

If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.

If you want and have time, I would appreciate your Vote(s) for My IDEAS :light_bulb: or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 10
Anonymous
in reply to: WCrihfield

 

Thanks for your reply; this modification does not work. Below is the exception.

 

Exception: Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
StackTrace: at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Inventor.ComponentOccurrence.CreateGeometryProxy(Object Geometry, Object& Result)

 

@BrianEkins, any help? 

Message 4 of 10
WCrihfield
in reply to: Anonymous

OK.  I have another thought for you to consider here.  You are first getting the component's definition as an AssemblyComponentDefinition, then on the next line you are setting that component's ModelState.  This might not be the best order of operations.  Once a component is representing a ModelState other than "Master", it seems to me that it would then be representing a ModelState Member document, instead of a ModelState Factory document.  I know this makes a difference when accessing things line iProperties, Parameters, constraints, etc., but I'm not sure about WorkPlanes.  I'm thinking that, in order to get the true factory document's WorkPlanes you would have to get the component's ComponentOccurrence.Definition.FactoryDocument.ComponentDefinition.WorkPlanes, after changing the component's ModelState.  I could be wrong though.  But if I'm right, it could be those work planes from the component that are causing the error when trying to create WorkPlaneProxy objects.  Like I said...just a thought.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 5 of 10
Anonymous
in reply to: WCrihfield

Hi @WCrihfield,

 

You are right. Once I commented the code to setting that component's ModelState, it worked. Thank you!

 

Regards,

Karthik.

Message 6 of 10
nagihan.bostan
in reply to: Anonymous

Hi  ,

 

I am having a similar problem. I want to create a Work Axis at the center of the selected cylinder.

My Work Axis is created but its position is wrong.
I couldn't understand how to adapt last suggested solution to the code.

Do you have any ideas?

 

My Code:

private void CreateWorkAxisInAssembly()
{

Inventor.Application application = (Inventor.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application");

AssemblyDocument oAsmDoc = (AssemblyDocument)application.ActiveDocument;

AssemblyComponentDefinition assemblyComponentDefinition = oAsmDoc.ComponentDefinition;

ComponentOccurrence componentOccurrence = application.CommandManager.Pick(SelectionFilterEnum.kAssemblyLeafOccurrenceFilter, "Select a Part");

PartComponentDefinition oCompDef = (PartComponentDefinition)componentOccurrence.Definition;

FaceProxy oCylinderFace = (FaceProxy)application.CommandManager.Pick(SelectionFilterEnum.kPartFaceCylindricalFilter, "Select Cylinder Face");


object oCylinderFaceProxyObj;

componentOccurrence.CreateGeometryProxy(oCylinderFace, out oCylinderFaceProxyObj);

FaceProxy oCylinderFaceProxy = (FaceProxy)oCylinderFaceProxyObj;

 

Inventor.Point circle1Center = oCylinderFaceProxy.Geometry.BasePoint;

UnitVector circle1Normal = oCylinderFaceProxy.Geometry.AxisVector;


WorkAxis workAxis = oCompDef.WorkAxes.AddFixed(circle1Center,circle1Normal);


}

@Anonymous,@WCrihfield

Message 7 of 10
WCrihfield
in reply to: nagihan.bostan

Hi @nagihan.bostan.  It looks to me like you area trying to create the WorkAxis in the context of the Part document, instead of within the main assembly...is that what your intent was?  If that is the case, then unfortunately the source geometry you are using to create it (Point & UnitVector) are derived from proxy objects that are in the context of the main assembly, so that will not work.  The proxy system is good for getting sub-level component geometry in the context of the main assembly, but can't be used by themselves to then transfer geometry back down to sub-level component context again.  I believe you will need to get the transient transformation Matrix of the component object, in the context of the main assembly, then use that to transform those source geometries from assembly space orientation/positioning to part level orientation/positioning.  You will find that both the Point object and the UnitVector object have a TransformBy method.  I believe you will have to use that to transform them for use in the part.  If the part is deeper than top level, you may need to do that for each level.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 8 of 10
nagihan.bostan
in reply to: WCrihfield

Thanks for replying,

 

I want to create a workplane from the center of the selected part with the AddByLinePlaneAndAngle in assembly.

For this i have to create a Work Axis belonging to the selected part.

So the answer to your question is yes.I trying to create the WorkAxis in the context of the Part document , instead of within the main assembly.

 

I tried as in the code, but the position was wrong. How can I use TransformBy correctly?

 

            FaceProxy oCylinderFaceProxy;
            object oCylinderFaceProxyObj;

            componentOccurrence.CreateGeometryProxy(oCylinderFace, out oCylinderFaceProxyObj);

            oCylinderFaceProxy = (FaceProxy)oCylinderFaceProxyObj;

            Inventor.Point circle1Center = oCylinderFaceProxy.Geometry.BasePoint;

            UnitVector circle1Normal = oCylinderFaceProxy.Geometry.AxisVector;

            circle1Center.TransformBy(componentOccurrence.Transformation);

            circle1Normal.TransformBy(componentOccurrence.Transformation);

            WorkAxis workAxis = oCompDef.WorkAxes.AddFixed(circle1Center, circle1Normal);

            WorkPlane wp = oCompDef.WorkPlanes.AddByLinePlaneAndAngle(workAxis, oCompDef.WorkPlanes["XY Plane"], 90);

 

Message 9 of 10
WCrihfield
in reply to: nagihan.bostan

Hi @nagihan.bostan.  Now that I know your plans better, and thought about it again, doing this is much simpler than I had originally thought.  Instead of working with all of that proxy and transformation stuff, you could simply access the NativeObject of the selected cylindrical FaceProxy to get the real Face in the Part, then use the WorkAxes.AddByRevolvedFace(NativeFace) method to directly create it within the part.  As I mentioned earlier in this post, I am not fluent in C#, but I can sometimes follow along with what's going on in C# code, if its simple.  So, I created an iLogic/vb.net equivalent code to show you how to do this, and I tested it in one of my assemblies meant just for testing, and it worked just fine.  I'm sure you can translate the parts of this that you need into C#.

Dim oADoc As AssemblyDocument = ThisDoc.Document
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
oObj = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceCylindricalFilter, "Select a cylinder face.")
If IsNothing(oObj) OrElse (TypeOf oObj Is FaceProxy = False) Then Exit Sub
Dim oFaceProxy As FaceProxy = oObj
Dim oFace As Face = oFaceProxy.NativeObject
Dim oOcc As ComponentOccurrence = oFaceProxy.ContainingOccurrence
Dim oPDef As PartComponentDefinition = oFace.Parent.ComponentDefinition
'Dim oPDoc As PartComponentDefinition = oOcc.Definition
Dim oWAs As WorkAxes = oPDef.WorkAxes
Dim oWA As WorkAxis = oWAs.AddByRevolvedFace(oFace)

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 10 of 10
nagihan.bostan
in reply to: WCrihfield

Hi @WCrihfield ,

Yes! it's a more logical solution, it worked.
Thank you for your help.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report