• Blog posts

    Bio

    by Luke Davenport

    Hello friends,

    How do you scale an Inventor part while keeping all its sketches, work geometry and relationships between parameters intact? Well it’s a question that I’ve been musing on for a while – and it’s also an unresolved topic on the Autodesk forums here. http://autode.sk/11AjTN4

    Obviously deriving the part allows you to scale it – but of course this gives you a dumb copy of the geometry and isn’t editable in its own right. iLogic to the rescue!

    Check out the code below – as you can see it’s not quite as simple as multiplying each parameter in the part by a scale factor; What if the parameter is an angle? What if the parameter is based on another parameter with an equation?  Well it took me a while but I’ve got a pretty foolproof solution that keeps all your parameter relationships functioning nicely and spits out a shiny scaled model good as new!

    Hint: Make sure you check that all the sketches in the part are fully constrained before using this rule – obviously if geometry isn’t controlled by a dimension it can’t be multiplied and you’ll get some VERY strange results!

    Also – there’s a fair few things to be aware of in the rule. For instance I’ve included the option to include any hole features in the scaling operation or not. I’d definitely recommend checking out the walkthrough video before using the rule in anger. AND as always DON’T FORGET TO SAVE A BACKUP COPY OF A PART FIRST and don’t come crying to me if you don’t. Enjoy!

    Here’s all the code. Copy and paste this into an iLogic rule.

     

    ‘Start of iLogic Code. Code written by Luke Davenport @ Cadline Copyright © 2013

    'Please note that you'll get errors in the code when you paste it into an ilogic rule UNLESS you remove any extra line spaces (empty lines) that have been added during the copy and paste'

     

    '[

    Dim oDoc As PartDocument = ThisApplication.ActiveDocument

    Dim oDef As PartComponentDefinition = oDoc.ComponentDefinition

    Dim oModParam As Parameter

    Dim oHole As HoleFeature

    Dim oHoles As HoleFeatures = oDef.Features.HoleFeatures

    Dim oFeatureDim As FeatureDimension

     

    'get user input for scale value

    enteragain:

    ScaleValue = InputBox("Enter Required Scale Value for Part" & vbLf & vbLf & "Value must be:" _

    & vbLf & vbLf & "1) Numeric" & vbLf & "2) Greater than zero" & vbLf & "3) Not equal To 1" _

    & vbLf & vbLf & "Enter 'c' to cancel","iLogic", "Enter Here")

    Try

        If ScaleValue = "c" Then

        Return

        Else If IsNumeric(ScaleValue) And ScaleValue > 0 And ScaleValue <> 1 Then

        Else

        Goto enteragain

        End If

    Catch

    Goto enteragain

    End Try

     

    'Does the user want to scale the holes also?

     

    If oHoles.Count > 0 Then

    ScaleHoles = MessageBox.Show("Do you want to include the " & oHoles.Count & " hole features in the scaling?" & vbLf & vbLf & _

    "Note - any threaded features will need a manual update if 'Yes' is selected","Scale Holes Also?" _

    ,MessageBoxButtons.YesNo,MessageBoxIcon.Question,MessageBoxDefaultButton.Button1)

    End If

     

    Dim oHoleParams As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

    Dim oHoleFeatureDimensions As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

    Dim oFinalHoleParams As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

    Dim oSketchDimensions As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

    Dim oSketch As Sketch

    oSketches = oDef.Sketches

    Dim oSketchDim As DimensionConstraint

     

    'Add Hole Parameters to collection

    For Each oHole In oHoles

        For aaa = 1 To oHole.Parameters.Count

        oHoleParams.Add(oHole.Parameters.Item(aaa))

        'MessageBox.Show("Adding to oHoleParams Parameter " & oHole.Parameters.Item(aaa).Name, "Title")

        Next aaa

    Next

     

    'Is the parameter a dimension in a sketch? If so add it to sketch dims collection

    For Each oSketch In oSketches

        'MessageBox.Show("Sketch is " & oSketch.Name, "Title")

        For Each oSketchDim In oSketch.DimensionConstraints

        oSketchDimensions.Add(oSketchDim.Parameter)

        'MessageBox.Show("Sketch constraint is " & oSketchDim.Parameter.Name, "Title")

        Next

    Next

     

    For bbb = 1 To oSketchDimensions.Count

    'MessageBox.Show("Sketch dims are as follows: " & oSketchDimensions.Item(bbb).Name, "Title")

    Next bbb

     

    Try

    'Add Hole feature dimensions to collection also

    For Each oHole In oHoles

         For Each oFeatureDim In oHole.FeatureDimensions

          oHoleFeatureDimensions.Add(oFeatureDim.Parameter)

         'MessageBox.Show("ADDING HOLE FEATURE DIMENSION PARAMETER " & oFeatureDim.Parameter.Name, "Title")

           Next

    Next

    Catch

    MessageBox.Show("ERROR 1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "Title")

    End Try

     

    Try

    For Each oModParam In oHoleParams

    'Iterate through both oSketchDimensions and oHoleFeatureDimensions. Will only add parameter to

    'final collection of hole params if it is not present in either of those collections

        ccc = 0

        For ddd = 1 To oSketchDimensions.Count

            If oSketchDimensions.item(ddd).Name = oModParam.Name Then

            ccc = 1

            'MessageBox.Show("Need to remove item " & oModParam.Name, "Title")

            End If

        Next ddd

       

        For eee = 1 To oHoleFeatureDimensions.Count

            If oHoleFeatureDimensions.item(eee).Name = oModParam.Name Then

            ccc = 1

            End If

        Next eee

          

        If ccc = 0 Then

        oFinalHoleParams.Add(oModParam)

        End If

     

    Next

    Catch

    MessageBox.Show("ERROR 2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "Title")

    End Try

     

    'Now finally add holefeature.holediameter to the final list

    Try

    For Each oHole In oHoles

        oFinalHoleParams.Add(oHole.HoleDiameter)

        'MessageBox.Show("Adding to oFinalHoleParams Parameter " & oHole.HoleDiameter.Name, "Title")

    Next

    Catch

    MessageBox.Show("An attempt to modify a hole size has failed - please check hole sizes", "iLogic")

    End Try

     

    'What is our final list of hole parameters? (These are excluded from the scaling if ScaleHoles = vbNo)

    For fff = 1 To oFinalHoleParams.Count

    'MessageBox.Show("Parameter " & fff & " in the final HOLE parameter list is " & oFinalHoleParams.Item(fff).Name, "Title")

    Next fff

    ']

     

    'CREATE NEW OBJECT COLLECTION TO HOLD FINAL PARAMETERS TO PERFORM OPERATIONS ON.

    Dim oFinalParams As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

     

    Try

    'IF SCALEHOLES = YES THEN ADD ALL PARAMETERS TO FINAL LIST

    If ScaleHoles = vbYes Then

    For Each oModParam In oDef.Parameters

    oFinalParams.Add(oModParam)

    Next

    Else

    'IF SCALEHOLES = NO THEN ONLY ADD ANY PARAMETERS THAT DON'T APPEAR IN OFINALHOLEPARAMS TO THE LIST

            For Each oModParam In oDef.Parameters

            ggg = 0

                For hhh = 1 To oFinalHoleParams.Count

                    If oFinalHoleParams.item(hhh).Name = oModParam.Name Then

                    ggg = 1

                    End If

                Next hhh

                If ggg = 0 Then

                oFinalParams.Add(oModParam)

                End If

            Next

    End If   

    Catch

    MessageBox.Show("ERROR 4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "Title")

    End Try

     

    'MessageBox.Show("QUANTITY IN THE MAIN PARAMETERS LIST IS:" & oDef.Parameters.Count, "Title")

    'MessageBox.Show("QUANTITY IN THE FINAL HOLES PARAMETERS LIST IS:" & oFinalHoleParams.Count, "Title")

    'MessageBox.Show("THEREFORE QUANTITY IN THE FINAL PARAMETERS LIST IS:" & oFinalParams.Count, "Title")

     

    'Loop 1 - CHECK IF PARAMETER IS DRIVEN BY ANYTHING. IF SO THEN ADD REQUIRED END VALUE IN COMMENT FIELD

    For Each oModParam In oFinalParams

     

    'Add exclusions -

        If oModParam.Units <> "deg" And oModParam.Units <> "ul" And oModParam.Units <> "text" Then

       

            Dim oCADlineDrivenBy As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

                Try

                'Add driving parameters to collection

                    oCADlineDrivenBy = oModParam.DrivenBy

                    If oCADlineDrivenBy.Count > 0 Then

                    'MessageBox.Show("Loop 1 - Parameter " & oModParam.Name & " is driven by something - adding comment", "Title")

                    oModParam.Comment = (ScaleValue*oModParam.ModelValue*10)

                    End If

                Catch

                'MessageBox.Show("comment adding doesn't work for parameter " & oModParam.Name, "Title")

                End Try

        End If

    Next

     

    'Loop 2 - CHECK IF PARAMETER IS DRIVEN BY ANYTHING. IF SO THEN IGNORE, IF NOT THEN SIMPLY ADD SCALE VALUE TO EXPRESSION

    For Each oModParam In oFinalParams

     

        'Add exclusions -

        If oModParam.Units <> "deg" And oModParam.Units <> "ul" And oModParam.Units <> "text" Then

     

            'Create object collection to hold 'Driven By' and 'Drives' objects

            Dim oCADlineDrivenBy As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

            Try

            'Check if parameter is driven

            oCADlineDrivenBy = oModParam.DrivenBy

                If oCADlineDrivenBy.Count = 0 Then

                'MessageBox.Show("Loop 2 - Parameter " & oModParam.Name & " is not driven by something -

                'hence will multiply by " & ScaleValue, "Title")

                oModParam.Expression = (ScaleValue & "*" & oModParam.Expression)

                End If

            Catch

            'MessageBox.Show("multiplying by " & ScaleValue & " hasn't worked for parameter " & oModParam.Name, "Title")

            End Try

     

        End If

    Next

     

    oDoc.Update

     

    'Loop 3 - IF PARAMETER IS DRIVEN BY ANYTHING - COMPARE VALUE IN COMMENT FIELD WITH MODEL VALUE. IF INCORRECT (TO 5 D.P.)

    'THEN ADD MULTIPLICATION BY THE REQUIRED CORRECTION FACTOR TO EXPRESSION TO CORRECT

    For Each oModParam In oFinalParams

     

        'Add exclusions -

        If oModParam.Units <> "deg" And oModParam.Units <> "ul" And oModParam.Units <> "text" Then

     

        'Create object collection to hold 'Driven By' objects

        Dim oCADlineDrivenBy As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

        Try

        'Check if parameter is driven

        oCADlineDrivenBy = oModParam.DrivenBy

            If oCADlineDrivenBy.Count > 0 Then

            ReqValue = Round(Val(oModParam.Comment),5)

            'MessageBox.Show("Loop 3 - Parameter " & oModParam.Name & " is driven by something - may need correcting", "Title")

            'MessageBox.Show("Loop 3 - Parameter Value is " & oModParam.ModelValue*10 & " and it should be " & ReqValue, "Title")

                If ReqValue <> Round((oModParam.ModelValue*10),5) Then

                'MessageBox.Show("Loop 3 - Therefore multiplying by " & (ReqValue/(oModParam.ModelValue*10)), "Title")

                oModParam.Expression = ((ReqValue/(oModParam.ModelValue*10)) & "*" & oModParam.Expression)

                End If

            End If

        Catch

        MessageBox.Show("multiplying by " & (ReqValue/(oModParam.ModelValue*10)) & " hasn't worked for parameter " & _

        oModParam.Name, "iLogic Information")

        End Try

     

        End If

    Next

     

    'Notify user regarding threaded features

    Dim oThreadFeatures As ThreadFeatures

    oThreadFeatures = oDef.Features.ThreadFeatures

    Dim oThreadFeature As ThreadFeature

    Dim oThreadInfo As ThreadInfo

    Dim ThreadList As New List(Of String)

     

    If oThreadFeatures.Count > 0 Then

        For iii = 1 To oThreadFeatures.Count

        ThreadList.Add(oThreadFeatures.Item(iii).Name)

        Next iii

     

    Dim ThreadString As String = String.Join(vbLf, ThreadList)

    MessageBox.Show("The following threaded features could not be scaled:" & vbLf & vbLf & _

    ThreadString & vbLf & vbLf & "Please correct and update these manually as required.", "iLogic")

    Else

    MessageBox.Show("Part Scale By " & ScaleValue & " Was Successful!", "iLogic")

    End If

     

    oDoc.Update