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:
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
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



Leave a Reply