Hook up a chain using iMate’s with MatchList

I already had a blog post on Hook up a chain using iMate’s, but I was recently asked about more iMate related API samples, so I thought I could also demonstrate the usage of iMate MatchList
In theory, when using a MatchList, the iMates in the various components should be matched automatically when using the “Automatically generate iMates on place” option in the “Place Component” dialog, based on the names provided in the list. I did not realize that they over-match 😬
(i.e. if there are unresolved/unpaired iMates left then they will be matched even if there is no appropriate name in the MatchList
Inventor Idea Station: Match list for imates

This is what I thought of doing as a test:

IMates1

We have 4 parts based on 2 types of models: a and b. There will be four connection points as shown in the above image. So we’ll have an a type part with connections for points 1 and 2 named chain_a_1-2.ipt, one b type part with connections for point 2 and 3 named chain_b_2-3.ipt, etc
iMates will be named following this pattern: “<iMate type [Insert or Mate]><connection point number [1..4]><part type [a or b]>”, e.g. Insert2b
Each iMate will have a MatchList containing the same iMate type for the same connection point but for the opposite part type:

Insert1a will be matching Insert1b, and Insert1b will be matching nothing, etc 

IMates4b

Unfortunately, as I mentioned above, simply relying on the “Automatically generate iMates on place” option in the “Place Component” dialog will not work as it will also match Insert1a to Insert3b and Mate1a to Mate3b when adding the second part to the assembly.

Instead, we can just place all the components in the assembly at the same time without automatic iMate resolution and then use the API to match the iMates.  

Here is the VBA code I used – if you want to use .NET / iLogic instead have a look at Convert VBA to .NET / iLogic

Function GetAlliMates(cd As AssemblyComponentDefinition) As NameValueMap
Dim res As NameValueMap
Set res = ThisApplication.TransientObjects.CreateNameValueMap
Dim occ As ComponentOccurrence
For Each occ In cd.Occurrences
Dim imate As iMateDefinition
For Each imate In occ.iMateDefinitions
Call res.Add(imate.name, imate)
Next
Next
Set GetAlliMates = res
End Function
Function MatchiMate( _
cd As AssemblyComponentDefinition, _
imate As iMateDefinition, _
imates As NameValueMap, _
ByVal name As String) As Boolean
On Error Resume Next
Dim imateMatch As iMateDefinition
Set imateMatch = imates.item(name)
If Not imateMatch Is Nothing Then
Call cd.iMateResults.AddByTwoiMates(imate, imateMatch)
Debug.Print "Matching " + imate.name + " with " + imateMatch.name + " // " + Err.Description
End If
MatchiMate = (Err.Number = 0)
On Error GoTo 0
End Function
Sub HookTheChain()
Dim doc As AssemblyDocument
Set doc = ThisApplication.ActiveDocument
Dim cd As AssemblyComponentDefinition
Set cd = doc.ComponentDefinition
Dim imates As NameValueMap
Set imates = GetAlliMates(cd)
Dim imate As iMateDefinition
For Each imate In imates
Dim item As Variant
For Each item In imate.MatchList
If MatchiMate(cd, imate, imates, item) Then
Exit For
End If
Next
Next
End Sub

When the code finishes, the parts will be on top of each other – I described the same thing in the other article
Best thing is to ground one of the components and then you can move around the others so they come apart and end up like shown in the picture on the top.

The above code only works well if inside the assembly each iMate has a unique name and should only be matched with a specific other iMate.

Here is the Inventor 2020 model I used: Download Chain_with_MatchList


Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading