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