Macro Inventor: Fonction Récursive et Enumérateur

autodesk-inventor-automation-recursive-and-enumerator-post

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.

You may also like...