How does Constraints.AddByiMateAndEntity actually work?

How does Constraints.AddByiMateAndEntity actually work?

jalbedyll1
Participant Participant
436 Views
8 Replies
Message 1 of 9

How does Constraints.AddByiMateAndEntity actually work?

jalbedyll1
Participant
Participant

I'm trying to make a code that will create a constraint between an iMate in a hardware part to a selected face in assembly using Constraints.AddByiMateAndEntity and I keep getting this error:

 

Error on line 20 in rule: imate test, in document: JVAU2D_JVA U2D 24x16x30_XXX.iam

Unable to cast COM object of type 'System.__ComObject' to class type 'Autodesk.iLogic.Types.ComponentArgument'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

 

System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to class type 'Autodesk.iLogic.Types.ComponentArgument'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
at ThisRule.Main() in external rule: imate test:line 20
at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

I've posted the code below. I haven't seen many use examples for this snippet. 

 

Sub Main()
Dim oHWPart As ComponentOccurrence
Dim oAttachPart As ComponentOccurrence
oHWPart = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Hardware Part")
	If oHWPart Is Nothing 
		Exit Sub
	End If
oAttachPart = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Attach Part")
	If oAttachPart Is Nothing 
		Exit Sub
	End If

Dim i As Long

For i = 1 To oHWPart.iMateDefinitions.Count

	
	Dim oFace As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFacePlanarFilter, oHWPart.iMateDefinitions.Item(i).Name)
	Constraints.AddByiMateAndEntity("Attach" & i, oHWPart, oHWPart.iMateDefinitions.Item(i).Name, oAttachPart , oFace)
'	Constraints.AddByiMateAndEntity("Mate1", "Part1:1", "iMate:1", "Part2:1", "iMate:1")
'	MessageBox.Show(oHWPart.iMateDefinitions.Item(i).Name & "_" & oHWPart.iMateDefinitions.Count & "_" & i, "TEST")

Next

End Sub

 

Thanks,

 

 

0 Likes
437 Views
8 Replies
Replies (8)
Message 2 of 9

Curtis_Waguespack
Consultant
Consultant

Hi @jalbedyll1 , the best way to understand the syntax, is to manually create the assembly, constrained as you want to do with automation:

 

Curtis_Waguespack_0-1732550249238.png

 

 

Then in a rule, select the constraint and right click and choose Capture Current State ( Constraints Add)

This will extract the code to create the constraint and shown you what is needed.

Then you can work that into your code.

 

Curtis_Waguespack_4-1732550726749.png

 

Hope that helps,
Curtis

EESignature

0 Likes
Message 3 of 9

jalbedyll1
Participant
Participant

hi @Curtis_Waguespack,

 

From what I'm understanding with this now is it does not work the way I'd like it to work. I was hoping to not have to set up imates in parts that I was going to use 1 time. I was hoping to use the imate built in to my hardware parts to constrain to other parts from ComandManager.Pick (planar face) , such as a lock (with imate) onto a door (by selected faces). Is there another function I can look into to make this work without setting up secondary imates in 1 time use parts? 

 

Thanks,

 

Jeremy

0 Likes
Message 4 of 9

Curtis_Waguespack
Consultant
Consultant

Hi @jalbedyll1 , what version of Inventor do you have.

 

I might have an example assembly I can share, that will help with what you're attempting to do.

 

 

EESignature

0 Likes
Message 5 of 9

jalbedyll1
Participant
Participant

Hi @Curtis_Waguespack,

 

That would be awesome. I feel like if I can get a code that does this correctly, it would be incredibly helpful for reusing hardware and quickly placing those hardware files into assemblies. I realize I can constrain 1000 locks onto doors, but it would be so many fewer clicks if I could just select the 3 planes I want them to attach to (example: back, side edge, top edge(named iMates)). The code above allows me to do all the selections, but it errors on the constraints.add line. I can comment that out and it cycles through all the selections.

 

Thanks for looking into this,

 

Jeremy

 

 

0 Likes
Message 6 of 9

Curtis_Waguespack
Consultant
Consultant

what version of Inventor do you have?

 

 

EESignature

0 Likes
Message 7 of 9

jalbedyll1
Participant
Participant

I'm using 2023, we are migrating to 2025 in December or January.

Message 8 of 9

Curtis_Waguespack
Consultant
Consultant

@jalbedyll1 , see the attached zip file. This example uses insert constraints and edge, vs planes and mates. But it will give an idea of how this is done.

 

This is way outside of the workflow Autodesk intended for iLogic, so just know that. But it works fine once set up.

 

 

Here  is the reused part with named entities authored within it and setup ahead of time

Curtis_Waguespack_0-1732559183120.png

 

The one time use part, has no named entities to start with

Curtis_Waguespack_1-1732559203257.png

 

Running the rule in the assembly, prompts you to select an edge.

When you do, a named entity is created in the plate part on the fly.

And then the cam and pins are placed and constrained.

Curtis_Waguespack_2-1732559269259.png

 

EESignature

0 Likes
Message 9 of 9

jalbedyll1
Participant
Participant

Hi Curtis,

 

Thanks for the assembly and code. I've been trying some of the things you have in your code and I've gotten all my faces to name, it's erroring out if I try to do a second operation, though trying to rename them as if I was trying to attach a second hardware part. I've decided to just mate the iMates from the browser to the parts for now. From constraints dialog, I select the iMate, then select the face and everything is connecting. It's not too many more clicks to find the iMates in the window but it eventually I'd still like to get this to work.

 

Current iteration:

 

Imports System.Text.RegularExpressions
Imports Inventor

Sub Main()
Dim doc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oHWPart As ComponentOccurrence
Dim oAttachPart As ComponentOccurrence

' Select the hardware part (oHWPart)
oHWPart = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Hardware Part")
If oHWPart Is Nothing Then Exit Sub

' Select the attach part (oAttachPart)
oAttachPart = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Attach Part")
If oAttachPart Is Nothing Then Exit Sub

' Get the part document from oAttachPart
Dim attachDoc As PartDocument = Nothing
If TypeOf oAttachPart.Definition.Document Is PartDocument Then
attachDoc = CType(oAttachPart.Definition.Document, PartDocument)
Else
MessageBox.Show("The selected attach part is not a PartDocument.", "Error")
Exit Sub
End If

Dim iLogicAuto = iLogicVb.Automation
Dim oNamedEntities = iLogicAuto.GetNamedEntities(attachDoc)

' Iterate through all the iMates in oHWPart
For i = 1 To oHWPart.iMateDefinitions.Count

Dim mateDef As iMateDefinition = oHWPart.iMateDefinitions.Item(i)
Dim mateName As String = mateDef.Name

' Request the user to select a face for each iMate
Dim oFace As Object = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFacePlanarFilter, "Select face for Mate: " & mateName)
If oFace Is Nothing Then
MessageBox.Show("Face not selected for iMate: " & mateName, "Error")
Exit Sub
End If

' Assign the iMate name to the selected face
Dim oFaceName As String = AssigniMateNameToFace(oFace, mateName, oNamedEntities)
If oFaceName Is Nothing Then
MessageBox.Show("Failed to assign iMate name to face: " & mateName, "Error")
Else
MessageBox.Show("Assigned iMate name to face: " & oFaceName, "Success")
End If
Next
End Sub

Private Function AssigniMateNameToFace(oFace As Face, iMateName As String, oNamedEntities As Object) As String
Try
' Check if the face already has a name
Dim currentName As String = ""
Try
currentName = oNamedEntities.GetName(oFace)
Catch
' If no name exists, this will throw an exception; we handle it silently
End Try

' If a name already exists, return it
If Not String.IsNullOrEmpty(currentName) Then
MessageBox.Show("Face already named: " & currentName, "Debug")
Return currentName
End If

' Use the iMate name directly as the face name
Dim newName As String = iMateName

' Attempt to set the name and handle conflicts
Try
oNamedEntities.SetName(oFace, iMateName)
MessageBox.Show("Face named successfully: " & newName, "Success")
Return newName
Catch ex As Exception
' Handle conflict by generating a unique name
MessageBox.Show("Name conflict detected for: " & newName & ". Generating a unique name.", "Warning")
newName &= "_" & Now().ToString("yyyyMMddHHmmssfff")
oNamedEntities.SetName(oFace, iMateName)
MessageBox.Show("Face named successfully with unique name: " & newName, "Success")
Return newName
End Try
Catch ex As Exception
MessageBox.Show("Error in AssigniMateNameToFace: " & ex.Message, "Error")
Return Nothing
End Try
End Function

0 Likes