Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Rangebox without workfeatures

Anonymous

Rangebox without workfeatures

Anonymous
Not applicable

I have a macro that uses the rangebox of a partdocument to calculate the dimensions of that part to display in a partslist. The problem is that when there is a visible workplane or workaxis present in the part, the rangebox includes that workfeature and the part dimensions are not correct. I know I can also use the rangebox of the first solid in the part, but when it is a multibody part the dimensions will also not be correct.

 

Is there a way to get the rangebox of a part without the workfeatures? Or is there a some other good solution to get the outer dimensions of a part?

0 Likes
Reply
Accepted solutions (1)
1,966 Views
9 Replies
Replies (9)

Anonymous
Not applicable

Try pasting this code into an iLogic rule and running it. It's quick and dirty but it may inspire you into the right direction. It will turn off work features, measure the bounding box, pop up a message box with the outside dimensions, then reset your work features back to visible. It worked for me with multi-body parts and work features. Good Luck.

 

ThisApplication.CommandManager.ControlDefinitions.Item("AppAllWorkfeaturesCmd").Execute

Dim Length As Decimal = 0.0
Dim Height As Decimal = 0.0
Dim Width As Decimal = 0.0

Length = Measure.ExtentsLength
Height = Measure.ExtentsHeight
Width = Measure.ExtentsWidth

Dim SLength As String = Length.ToString()
Dim SHeight As String = Width.ToString()
Dim SWidth As String = Height.ToString()

MessageBox.Show("Complete" & vbLf & "Length: " & SLength & vbLf & "Width: " & SWidth & vbLf & "Height: " & SHeight, "Get Size")
ThisApplication.CommandManager.ControlDefinitions.Item("AppAllWorkfeaturesCmd").Execute

 

0 Likes

Anonymous
Not applicable

Thanks

 

I already tried that approach and it seems to work, however there is one problem. When a user already turned the workfeatures off, the first line of your code will actually enable the workfeatures again.

 

Is there a way to check if the workfeatures are already turned off? There doesn't seem to be proper API support for this (hence the command execution instead of using an API method). Iterating through all workfeatures and check there visibility is to time consuming for a macro that runs every time a part is saved....

 

Daniel

0 Likes

Anonymous
Not applicable

Thats strange because when I run it, it turns off all features, displays the message box, then only turns on the features that were on before I ran the rule.

 

Im not sure how to run through the entire browser and check all the work features.

 

It's strange that it works different for me than it does for you. I'm on Inventor 2015. Maybe if you're in an earlier version something has been changed.

 

Edit: Have you tried running the exact script I posted?

0 Likes

Anonymous
Not applicable

The command you execute, turning off the workfeatures, can also be run manually by the user (see attached image). When a user has all workfeatures turned off this way your code actually turns on the workfeatures first and turns them off when the code finishes.

 

0 Likes

Anonymous
Not applicable

See the attached animated gif.

Notice the rule does not behave for me like you are describing.

0 Likes

ekinsb
Alumni
Alumni
Accepted solution

There are two potential solutions that I can see.  One is to continue the approach you're currently taking but use the API to control the visibility of the work geometry.  The following code demonstrates turning them off and then back on.  It's not just toggling them, which is what the command does but instead you are specifically specifying if they should be on or off.

 

Public Sub VisibilityTest()
    Dim doc As PartDocument
    Set doc = ThisApplication.ActiveDocument
    
    doc.ObjectVisibility.AllWorkFeatures = False
    
    doc.ObjectVisibility.AllWorkFeatures = True
End Sub

 

The second approach is to be indendent of the work feature display and just work with the range of the bodies.  The code below computes a range box that's the combination of all of the bodies in a part.

 

Public Sub GetBodyRange()
    Dim doc As PartDocument
    Set doc = ThisApplication.ActiveDocument
    Dim bodies As SurfaceBodies
    Set bodies = doc.ComponentDefinition.SurfaceBodies
    
    ' Initialize the range with the first body.
    Dim allRange As Box
    Set allRange = bodies.Item(1).RangeBox
    
    Debug.Print "(" & Format(allRange.minPoint.X, "0.000000") _
                & ", " & Format(allRange.minPoint.Y, "0.000000") _
                & ", " & Format(allRange.minPoint.Z, "0.000000") _
                & ")-(" & Format(allRange.maxPoint.X, "0.000000") _
                & ", " & Format(allRange.maxPoint.Y, "0.000000") _
                & ", " & Format(allRange.maxPoint.Z, "0.000000") & ")"
    
    ' Expand the range using any additional bodies.
    Dim i As Integer
    For i = 2 To bodies.Count
        Dim bodyRange As Box
        Set bodyRange = bodies.Item(i).RangeBox
        Dim minPoint As Point
        Dim maxPoint As Point
        Set minPoint = allRange.minPoint
        Set maxPoint = allRange.maxPoint
        
        If bodyRange.minPoint.X < allRange.minPoint.X Then
            minPoint.X = bodyRange.minPoint.X
        End If
        
        If bodyRange.minPoint.Y < allRange.minPoint.Y Then
            minPoint.Y = bodyRange.minPoint.Y
        End If
        
        If bodyRange.minPoint.Z < allRange.minPoint.Z Then
            minPoint.Z = bodyRange.minPoint.Z
        End If
        
        If bodyRange.maxPoint.X > allRange.maxPoint.X Then
            maxPoint.X = bodyRange.maxPoint.X
        End If
        
        If bodyRange.maxPoint.Y > allRange.maxPoint.Y Then
            maxPoint.Y = bodyRange.maxPoint.Y
        End If
        
        If bodyRange.maxPoint.Z > allRange.maxPoint.Z Then
            maxPoint.Z = bodyRange.maxPoint.Z
        End If
    Next
    
    allRange.minPoint = minPoint
    allRange.maxPoint = maxPoint
    
    Debug.Print "(" & Format(allRange.minPoint.X, "0.000000") _
                & ", " & Format(allRange.minPoint.Y, "0.000000") _
                & ", " & Format(allRange.minPoint.Z, "0.000000") _
                & ")-(" & Format(allRange.maxPoint.X, "0.000000") _
                & ", " & Format(allRange.maxPoint.Y, "0.000000") _
                & ", " & Format(allRange.maxPoint.Z, "0.000000") & ")"
End Sub

 


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
0 Likes

Anonymous
Not applicable

Thanks Brian!

 

This is something I can use, as always you are a great help.

 

Daniel

0 Likes

el_jefe_de_steak
Collaborator
Collaborator

Here is a more simple version of the code:

ThisApplication.CommandManager.ControlDefinitions.Item("AppAllWorkfeaturesCmd").Execute
Dim dims(0 To 2) As Decimal
dims(0) = Measure.ExtentsLength
dims(1) = Measure.ExtentsHeight
dims(2) = Measure.ExtentsWidth

MessageBox.Show("Complete" & vbLf & "Length: " & dims(0).ToString & vbLf & "Width: " & dims(1).ToString & vbLf & "Height: " & dims(2).ToString, "Get Size")
ThisApplication.CommandManager.ControlDefinitions.Item("AppAllWorkfeaturesCmd").Execute
0 Likes

dba78
Advocate
Advocate

I'm not sure, since when this is available, as of Inventor 2020.3 the SurfaceBody object has a(n undocumented) Property: 'OrientedMinimumRangeBox'. This provides an 'OrientedBox' (introduced in Inventor 2016 - API help says). 

The OrientedBox Object consists of a CornerPoint and 3 vectors. The length of these gives you the Extent of the SurfaceBody in these 3 directions independent of the XYZ-Orientation.

 

Since there is apparently no Add Method, in multibody environments you will need to create a surfacebody by BRep and call the property on that temporary body. 

Something like this (VBA):

'requires a part open with 2 SolidBodies
Sub getSurfaceBody()
Dim doc As PartDocument
Dim cd As PartComponentDefinition

Set doc = ThisApplication.ActiveDocument
Set cd = doc.ComponentDefinition

Dim body1 As SurfaceBody
Dim body2 As SurfaceBody
Set body1 = ThisApplication.TransientBRep.copy(cd.SurfaceBodies(1))
Set body2 = ThisApplication.TransientBRep.copy(cd.SurfaceBodies(2))

ThisApplication.TransientBRep.DoBoolean body1, body2, kBooleanTypeUnion

Dim box As OrientedBox
Set box = body1.OrientedMinimumRangeBox

'Code below is just for graphical illustration :-)

Dim sk As Sketch3D
Set sk = cd.Sketches3D.Add

Set p0 = box.CornerPoint.copy
sk.Edit
Set p1 = p0.copy
p1.TranslateBy box.DirectionOne
sk.SketchLines3D.AddByTwoPoints p0, p1, False

Set p1 = p0.copy
p1.TranslateBy box.DirectionTwo
sk.SketchLines3D.AddByTwoPoints p0, p1, False

Set p1 = p0.copy
p1.TranslateBy box.DirectionThree
sk.SketchLines3D.AddByTwoPoints p0, p1, False

sk.ExitEdit
End Sub

 

For C# you will need to cast the SurfaceBody to dynamic type to make this work (don't expect intellisense to assist you:winking_face:)

var orientedBox = ((dynamic)body).OrientedMinimumRangeBox;

 

0 Likes