Macro Inventor: Fonction Récursive et Enumérateur
Lors de l’automatisation d’Inventor, il arrive souvent que nous aillons besoin de traverser plusieurs niveau d’objets, notamment lorsque l’on veut itérer à travers tous les composants et sous-composants d’un assemblage.
Pour ce faire, il est commun d’utiliser une Récursive, soit une fonction se rappelant elle-meme un nombre indéfinit de fois.
Comme dans l’exemple suivant ou l’on récupère une collection de nom de tous les composants d’un assemblage :
Private Sub ComponentsNames_Recursive()
Dim cNames As Collection
Dim oAssyDoc As AssemblyDocument
Set oAssyDoc = ThisApplication.ActiveDocument
Set cNames = GetAllComponentsNames(oAssyDoc)
End Sub
Private Function GetAllComponentsNames(ByVal oAssyDoc As AssemblyDocument) As Collection
Dim cNames As New Collection
Dim oCompOcc As ComponentOccurrence
For Each oCompOcc In oAssyDoc.ComponentDefinition.Occurrences
cNames.Add oCompOcc.Name
If oCompOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
Dim cSubCompOccNames As Collection
Set cSubCompOccNames = GetAllComponentsNames(oCompOcc.Definition.Document)
Dim sSubCompOccName As Variant
For Each sSubCompOccName In cSubCompOccNames
cNames.Add sSubCompOccName
Next
End If
Next
Set GetAllComponentsNames = cNames
End Function
Public Sub ComponentsNames_Recursive()
Dim assemblyDocument As AssemblyDocument = InventorApplication.ActiveDocument
Dim names As Collection = GetAllComponentsNames(assemblyDocument)
End Sub
Private Function GetAllComponentsNames(ByVal assemblyDocument As AssemblyDocument) As Collection
Dim names As New Collection
Dim occurrence As ComponentOccurrence
For Each occurrence In assemblyDocument.ComponentDefinition.Occurrences
names.Add(occurrence.Name)
If occurrence.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim subOccNames As Collection = GetAllComponentsNames(occurrence.Definition.Document)
For Each subOccName as Object In subOccNames
names.Add(subOccName)
Next
End If
Next
Return names
End Function
public void ComponentsNames_Recursive()
{
AssemblyDocument assemblyDocument = InventorApplication.ActiveDocument;
Collection names = GetAllComponentsNames(assemblyDocument);
}
private Collection GetAllComponentsNames(AssemblyDocument assemblyDocument)
{
Collection names = new Collection();
ComponentOccurrence occurrence;
foreach (var occurrence in assemblyDocument.ComponentDefinition.Occurrences)
{
names.Add(occurrence.Name);
if (occurrence.DefinitionDocumentType == DocumentTypeEnum.kAssemblyDocumentObject)
{
Collection subOccNames = GetAllComponentsNames(occurrence.Definition.Document);
foreach (object subOccName in subOccNames)
names.Add(subOccName);
}
}
return names;
}
Mais on peut aussi arriver au même résultat en moins de ligne de code en passant par les Énumérateurs, comme dans l’exemple suivant :
Private Sub ComponentsNames_Enumerator()
Dim cNames As New Collection
Dim oAssyDoc As AssemblyDocument
Dim oCompOccEnum As ComponentOccurrencesEnumerator
Dim oCompOcc As ComponentOccurrence
Set oAssyDoc = ThisApplication.ActiveDocument
Set oCompOccEnum = oAssyDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(oAssyDoc.ComponentDefinition)
For Each oCompOcc In oCompOccEnum
cNames.Add oCompOcc.Name
Next
End Sub
Public Sub ComponentsNames_Enumerator()
Dim names As New Collection
Dim assemblyDocument As AssemblyDocument = InventorApplication.ActiveDocument
Dim compOccEnum As ComponentOccurrencesEnumerator = assemblyDocument.ComponentDefinition.Occurrences.AllReferencedOccurrences(assemblyDocument.ComponentDefinition)
For Each compOcc As ComponentOccurrence In compOccEnum
names.Add(compOcc.Name)
Next
End Sub
public void ComponentsNames_Enumerator()
{
Collection names = new Collection();
AssemblyDocument assemblyDocument = InventorApplication.ActiveDocument;
ComponentOccurrencesEnumerator compOccEnum = assemblyDocument.ComponentDefinition.Occurrences.AllReferencedOccurrences(assemblyDocument.ComponentDefinition);
foreach (ComponentOccurrence compOcc in compOccEnum)
names.Add(compOcc.Name);
}
L’avantage est surtout au niveau performance car les Énumérateurs sont normalement optimisés pour l’itération.
Maintenant à vous de choisir l’avenue que vous préférez.
