Almost six years later and derive components via API is STILL painfully slow

AlexFielder
Advisor Advisor
294 Views
0 Replies
Message 1 of 1

Almost six years later and derive components via API is STILL painfully slow

AlexFielder
Advisor
Advisor

Hi all,

 

I recently had cause to revisit some VB.NET Inventor API code I originally wrote back in 2016(!) and, despite the recent advances in multi-core use within Inventor, having just run the code again, it still seems just as slow as when I wrote it. (FULL disclosure: If my memory serves, in 2016 this same code took ~10 minutes to process one assembly; Here in 2022 the outputs take ~7 minutes - so it IS a little faster than it was)

 

Am I misunderstanding how I should use the API for this? The reason I ask that is because with the file in question (containing 46 Solid bodies) takes < 30 seconds to produce the same number of derived components.

 

Here is the method that carries out the bulk of the process:

 

 

Sub BuildandPlaceSurfaceBodies(ByVal ThisPart As PartDocument, ByVal ResultsFolder As String, ByVal Thispartname As String, ByVal IsMirrored As Boolean, ByRef ThisAssembly As AssemblyDocument, _
                                ByRef PanelACollection As ObjectCollection, ByRef PanelBCollection As ObjectCollection, ByRef PanelCCollection As ObjectCollection, _
                                ByRef PanelDCollection As ObjectCollection, ByVal NumRightSpinesCount As String, ByVal thisbalcony As Balcony)
    Try

        'base work axes
        Dim XAxis As WorkAxis
        Dim YAxis As WorkAxis
        Dim Zaxis As WorkAxis
        With ThisAssembly.ComponentDefinition
            XAxis = .WorkAxes(1)
            YAxis = .WorkAxes(2)
            Zaxis = .WorkAxes(3)
        End With

        'base work planes

        Dim XYPlane As WorkPlane = Nothing
        Dim YZPlane As WorkPlane = Nothing
        Dim XZPlane As WorkPlane = Nothing
        With ThisAssembly.ComponentDefinition
            XYPlane = .WorkPlanes.Item("XY Plane")
            YZPlane = .WorkPlanes.Item("YZ Plane")
            XZPlane = .WorkPlanes.Item("XZ Plane")
        End With

        For i As Integer = 1 To ThisPart.ComponentDefinition.SurfaceBodies.Count
            Dim surfacebody As SurfaceBody = ThisPart.ComponentDefinition.SurfaceBodies.Item(i)
            Dim surfaceBodyName As String = surfacebody.Name
            If surfaceBodyName.StartsWith("Solid") Or surfaceBodyName.Contains("Source") Then
                Continue For
            End If
            Dim partdocument As PartDocument = g_inventorApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, g_inventorApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kPartDocumentObject))

            Dim p As Inventor.Property = partdocument.PropertySets("{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Description")
            p.Expression = surfaceBodyName

            Dim derivedpartcomponents As DerivedPartComponents = partdocument.ComponentDefinition.ReferenceComponents.DerivedPartComponents

            Dim derivedpartuniformscaledefinition As DerivedPartUniformScaleDef = derivedpartcomponents.CreateUniformScaleDef(ThisPart.FullDocumentName)

            Dim derivedpartentity As DerivedPartEntity
            For Each derivedpartentity In derivedpartuniformscaledefinition.Solids
                If Not derivedpartentity.ReferencedEntity Is surfacebody Then
                    derivedpartentity.IncludeEntity = False
                Else
                    derivedpartentity.IncludeEntity = True
                End If
            Next
            ' theory copied from here: http://adndevblog.typepad.com/manufacturing/2012/06/includeexclude-parameters-from-the-base-part-in-a-derived-part.html
            Dim paramtoderive As DerivedPartEntity
            For Each paramtoderive In derivedpartuniformscaledefinition.Parameters
                paramtoderive.IncludeEntity = True
            Next

            Call derivedpartcomponents.Add(derivedpartuniformscaledefinition)

            If surfaceBodyName.Contains("Panel") Then
                SetMaterialToPart(partdocument, My.Settings.BalconyPanelMaterialName)
            Else
                SetMaterialToPart(partdocument, My.Settings.BalconyAluMaterialName)
            End If

            Dim newfilename As String = Regex.Replace(surfaceBodyName, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 ")

            Call partdocument.SaveAs(ResultsFolder + Thispartname + "-" + newfilename + ".ipt", False)

            If IsMirrored Then
                MirrorDerivedPart(partdocument, DerivedPartMirrorPlaneEnum.kDerivedPartMirrorPlaneYZ)
            End If
            Dim mx As Matrix = g_inventorApplication.TransientGeometry.CreateMatrix()
            Dim oOcc1 As ComponentOccurrence = ThisAssembly.ComponentDefinition.Occurrences.AddByComponentDefinition(partdocument.ComponentDefinition, mx)

            If surfaceBodyName = "C3" Then
                Dim objCol As ObjectCollection = g_inventorApplication.TransientObjects.CreateObjectCollection
                objCol.Add(oOcc1)
                'Based on this:
                ' http://adndevblog.typepad.com/manufacturing/2012/12/inventor-create-pattern-of-component-occurrences.html
                Call ThisAssembly.ComponentDefinition.OccurrencePatterns.AddRectangularPattern(objCol,
                                                                                                    YAxis,
                                                                                                    True,
                                                                                                    Parameters.GetParameter(My.Settings.BalconyCSpacingParameterName).Expression,
                                                                                                    My.Settings.BalconyChannelsCount)
            ElseIf surfaceBodyName = "Fin" Then
                Dim objCol As ObjectCollection = g_inventorApplication.TransientObjects.CreateObjectCollection
                objCol.Add(oOcc1)
                Call ThisAssembly.ComponentDefinition.OccurrencePatterns.AddRectangularPattern(objCol, YAxis, True, Parameters.GetParameter(My.Settings.BalconyCSpacingParameterName).Expression, My.Settings.BalconyFinsCount)
            ElseIf surfaceBodyName.Contains("Panel") Then
                If surfacebody.Name.StartsWith("PanelA") Then
                    PanelACollection.Add(oOcc1)
                ElseIf surfacebody.Name.StartsWith("PanelB") Then
                    PanelBCollection.Add(oOcc1)
                ElseIf surfacebody.Name.StartsWith("PanelC") Then
                    PanelCCollection.Add(oOcc1)
                ElseIf surfacebody.Name.StartsWith("PanelD") Then
                    PanelDCollection.Add(oOcc1)
                End If
            ElseIf surfaceBodyName = "SpineConnectingPlateRight" Or surfaceBodyName = "SpineConnectingPlateLeft" Then
                Dim objCol As ObjectCollection = g_inventorApplication.TransientObjects.CreateObjectCollection
                objCol.Add(oOcc1)
                Call ThisAssembly.ComponentDefinition.OccurrencePatterns.AddRectangularPattern(objCol, YAxis, True, Parameters.GetParameter(My.Settings.BalconyPanelDSpineFixingHoleParamName).Expression, My.Settings.BalconyConnectingPlateCount)
            ElseIf surfaceBodyName = "ShortSpineC" Then
                If thisbalcony.NumPanels > 3 Then
                    Dim objCol As ObjectCollection = g_inventorApplication.TransientObjects.CreateObjectCollection
                    objCol.Add(oOcc1)
                    Dim rectangpattern As RectangularOccurrencePattern = ThisAssembly.ComponentDefinition.OccurrencePatterns.AddRectangularPattern(objCol, XAxis, False, Parameters.GetParameter(My.Settings.T1BalconyShortSpineXSpacingParamName).Expression, 2)
                    Dim rectangColl2 As ObjectCollection = g_inventorApplication.TransientObjects.CreateObjectCollection
                End If
            ElseIf surfaceBodyName = "ShortSpineLeft" Or surfaceBodyName = "ShortSpineRight" Then
                Dim objCol As ObjectCollection = g_inventorApplication.TransientObjects.CreateObjectCollection
                objCol.Add(oOcc1)
                Call ThisAssembly.ComponentDefinition.OccurrencePatterns.AddRectangularPattern(objCol, YAxis, True, Parameters.GetParameter(My.Settings.T1BalconySpineFixingHoleParamName).Expression, My.Settings.BalconyConnectingPlateCount)
            ElseIf surfaceBodyName = "LongSpineB1" Then
                MirrorPartInAssy(ThisAssembly, YZPlane, oOcc1) 'workplanes.item(1) = YZ
            End If
            Call partdocument.Close()
        Next
    Catch ex As Exception
        MessageBox.Show("Error info: " & vbNewLine & ex.ToString)
    End Try
End Sub

 

 

Can this run in a parallel fashion..? Is there a different method I can use..?

 

Thanks,

 

Alex.

 

{Edit: to tidy the code a little}

0 Likes
295 Views
0 Replies
Replies (0)