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
Comments
0 comments
Please sign in to leave a comment.