Creating a bounding box arround a solid

Hello, How can I make a bounding box like rectanglar prisim around a solid with journal?
Thank you!

What version of NX are you working with?
If you are using NX 10, try recording a journal while using the "create box" command.

Hi,
I found this code in Engtips this may useful for you....
and it'll be great help if anyone modifies to allow to user defined direction for X and Y

Option Strict Off
 
Imports System
 
Imports NXOpen
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.UF
 
Module make_bounding_block_of_selected_body_relative_to_wcs
 
    Dim s As Session = Session.GetSession()
    Dim ufs As UFSession = UFSession.GetUFSession()
    Dim lw As ListingWindow = s.ListingWindow()
 
    Sub Main()
 
        Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
        Dim csys As NXOpen.Tag = NXOpen.Tag.Null
        Dim target As NXOpen.Tag = NXOpen.Tag.Null
        Dim blockFeature As NXOpen.Tag = NXOpen.Tag.Null
 
        Dim min_corner(2) As Double
        Dim directions(2, 2) As Double
        Dim distances(2) As Double
        Dim edge_len(2) As String
 
        While select_a_body(a_body) = Selection.Response.Ok
 
            ufs.Csys.AskWcs(csys)
 
            ufs.Modl.AskBoundingBoxExact(a_body, csys, min_corner, directions, _
                distances)
 
            lw.Open()
 
            lw.WriteLine("Min_corner: " & _
                min_corner(0).ToString & ", " & _
                min_corner(1).ToString & ", " & _
                min_corner(2).ToString & ", ")
 
            lw.WriteLine("X direction: " & _
                directions(0, 0).ToString & ", " & _
                directions(0, 1).ToString & ", " & _
                directions(0, 2).ToString & ", ")
            lw.WriteLine("X distance: " & _
                distances(0).ToString)
 
            lw.WriteLine("Y direction: " & _
                directions(1, 0).ToString & ", " & _
                directions(1, 1).ToString & ", " & _
                directions(1, 2).ToString & ", ")
            lw.WriteLine("Y distance: " & _
                distances(1).ToString)
 
            lw.WriteLine("Z direction: " & _
                directions(2, 0).ToString & ", " & _
                directions(2, 1).ToString & ", " & _
                directions(2, 2).ToString & ", ")
            lw.WriteLine("Z distance: " & _
                distances(2).ToString)
 
            edge_len(0) = distances(0).ToString()
            edge_len(1) = distances(1).ToString()
            edge_len(2) = distances(2).ToString()
 
            ufs.Modl.CreateBlock(FeatureSigns.Nullsign, _
                                 target, min_corner, edge_len, blockFeature)
        End While
 
    End Sub
 
    Function select_a_body(ByRef a_body As NXOpen.Tag) As Selection.Response
 
        Dim message As String = "Select a body"
        Dim title As String = "Select a body"
        Dim scope As Integer = UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY
        Dim response As Integer
 
        Dim view As NXOpen.Tag
        Dim cursor(2) As Double
        Dim ip As UFUi.SelInitFnT = AddressOf body_init_proc
 
        ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
 
        Try
            ufs.Ui.SelectWithSingleDialog(message, title, scope, ip, _
                         Nothing, response, a_body, cursor, view)
        Finally
            ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
        End Try
 
        If response <> UFConstants.UF_UI_OBJECT_SELECTED And _
           response <> UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
            Return Selection.Response.Cancel
        Else
            ufs.Disp.SetHighlight(a_body, 0)
            Return Selection.Response.Ok
        End If
 
    End Function
 
    Function body_init_proc(ByVal select_ As IntPtr, _
                           ByVal userdata As IntPtr) As Integer
 
        Dim num_triples As Integer = 1
        Dim mask_triples(0) As UFUi.Mask
        mask_triples(0).object_type = UFConstants.UF_solid_type
        mask_triples(0).object_subtype = UFConstants.UF_solid_body_subtype
        mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_BODY
 
        ufs.Ui.SetSelMask(select_, _
                           UFUi.SelMaskAction.SelMaskClearAndEnableSpecific, _
                           num_triples, mask_triples)
        Return UFConstants.UF_UI_SEL_SUCCESS
 
    End Function
 
    Public Function GetUnloadOption(ByVal dummy As String) As Integer
 
        GetUnloadOption = UFConstants.UF_UNLOAD_IMMEDIATELY
 
    End Function
 
End Module 

-[]-

Hello this code works well to define bounding points, but what does the min_corner imply there?

The "min_corner" gives you the coordinates of the corner of the bounding box. The "directions" variables gives you the orientation of the box and the "distances" gives you the length of the edges of the bounding box.

Hello, When I run the journal on more complex shapes. Output of this journal can not create a bounding box for the shape. But the min corner and distances are true.What might be the problem? What does " body_init_proc" function does and what are the parameters mean? May you help me?
Thank you!

What version of NX are you using? Also, do you get any error message when you run the journal on your complex shape?

The selection function used in this journal (.SelectWithSingleDialog) allows for some complex filtering actions to be specified; in this case, the simpler selection function, .SelectTaggedObject, could have been used. The "body_init_proc" function in this journal simply sets the selection filter to solid bodies. The variable named "select_" is what the user selected and "userdata" is optional "other stuff" that you can pass in for further processing (not used in this journal).

I tried it in nx10 and nx8. The same thing happend. No box but only the results.

Are you working in an assembly or a piece part? If an assembly, make sure the correct part is set as the "work" part before running the journal.

If no "block" feature is created in the part navigator, I'd suggest running the "examine geometry" command. Sometimes when the geometry of the part is corrupt, other commands do not function correctly. Start the examine geometry command and turn on all the face and body checks then window select around the entire body of interest (a window select will pick up the body as well as all the faces and edges). If any issues are reported, these may need to be fixed to get the proper results.

p.s. If you are using NX 10, I would suggest using the "create box" command instead of this journal.

No issues on geometry as well. It is just not working on complex solids. I think there is no solution in this way. How can I make box using these distances in a diffrent corner?
Thank you.

Did the NX 10 command, create box, fail as well?

I've run the code on some complex parts that I have; the code worked correctly on them. Can you email me the part file where the code fails? (info@nxjournaling.com)

If you can't send me the file, perhaps you should have GTAC take a look at it since the journal code was created by them.
http://solutions.industrysoftware.automation.siemens.com/view.php?si=nx_...

There is another version on GTAC that uses the newer "block builder" object instead of the .CreateBlock function. Perhaps that version would work better for you.
http://solutions.industrysoftware.automation.siemens.com/view.php?si=nx_...

Can this be done for Multiple bodies in a single Part?
I don't want want selection mask, I just want to select all the solid Bodies form the displayed part. I am unable to tag all the bodies at once.

 Dim theBodies As Body() = AskAllBodies(MyPart)
                Dim csys As NXOpen.Tag = NXOpen.Tag.Null
                Dim min_corner(2) As Double
                Dim directions(2, 2) As Double
                Dim distances(2) As Double
                Dim edge_len(2) As String
                Dim target As NXOpen.Tag = NXOpen.Tag.Null
                Dim blockFeature As NXOpen.Tag = NXOpen.Tag.Null
                ufs.Csys.AskWcs(csys)
 
                Dim Mybodies As NXOpen.Tag = Nothing
 
                Dim i As Integer = Nothing
                Dim j As Integer = theBodies.Length
                For i = 0 To j - 1
                    Mybodies = theBodies(i).Tag
                Next
 
 
                    ufs.Modl.AskBoundingBoxExact(Mybodies, csys, min_corner, directions, distances)
 
                    edge_len(0) = distances(0).ToString()
                    edge_len(1) = distances(1).ToString()
                    edge_len(2) = distances(2).ToString()
 
                    ufs.Modl.CreateBlock(FeatureSigns.Nullsign, target, min_corner, edge_len, blockFeature)
 
 Function AskAllBodies(ByVal thePart As Part) As Body()
        Dim theBodies As New System.Collections.ArrayList()
 
        Dim aBodyTag As Tag = Tag.Null
        Do
            ufs.Obj.CycleObjsInPart(thePart.Tag, _
                UFConstants.UF_solid_type, aBodyTag)
            If aBodyTag = Tag.Null Then
                Exit Do
            End If
 
            Dim theType As Integer, theSubtype As Integer
            ufs.Obj.AskTypeAndSubtype(aBodyTag, theType, theSubtype)
            If theSubtype = UFConstants.UF_solid_body_subtype Then
                theBodies.Add(theSession.GetObjectManager.GetTaggedObject(aBodyTag))
            End If
        Loop While True
 
        Return DirectCast(theBodies.ToArray(GetType(Body)), Body())
    End Function

Regards,

Joe

According to the API reference docs, the AskBoundingBoxExact function takes only a single object tag as input; trying to pass in an array of tags will probably cause an error.

Is there any way that I can combine all the bodies to one Like Unite.The problem is the parts may not intersect in few cases Still I want to combine those and create Bounding BOX.

Regards,

Joe

It's not a good idea to try to combine the bodies, you just want to "combine" their boxes. In other words, you want a single box that encloses all the boxes of the individual bodies. If you have access to SNAP, there is a function Snap.Geom.Box3d.Combine that does exactly what you need. If you don't have SNAP, then you just need to take the minimum and maximum XYZ coordinates of the individual boxes.

Trying Some thing like in the following code to combine the bodies. But I am ending up with error in adding the bodies to list (Didn't have time today to diagnose the error). Maybe that's a good idea u given I can create bound boxes for all the bodies in my component then unite them to create new box to measure the desired vale. I just want a rough dimension of the overall part for some estimation.

'Measure Boundingbox Dimensions
            Dim theBodies As Body() = AskAllBodies(MyPart)
            Dim csys As NXOpen.Tag = NXOpen.Tag.Null
            Dim min_corner(2) As Double
            Dim directions(2, 2) As Double
            Dim distances(2) As Double
            Dim target As NXOpen.Tag = NXOpen.Tag.Null
            Dim blockFeature As NXOpen.Tag = NXOpen.Tag.Null
            ufs.Csys.AskWcs(csys)
            Dim XValue As String = Nothing
            Dim YValue As String = Nothing
            Dim ZValue As String = Nothing
 
 
            Dim Mybodies As NXOpen.Tag = Nothing
 
            Dim i As Integer = Nothing
            Dim j As Integer = theBodies.Length
 
            If j > 1 Then
                ' lw.WriteLine("there are " & Bodieslist.Count & " solid bodies on Part)
                Dim Bodieslist As List(Of Body) = Nothing
                For Each temp As Body In theBodies
                    Bodieslist.Add(temp)
                Next
                Dim nullFeatures_BooleanFeature As Features.BooleanFeature = Nothing
                Dim booleanBuilder1 As Features.BooleanBuilder
                booleanBuilder1 = workPart.Features.CreateBooleanBuilderUsingCollector(nullFeatures_BooleanFeature)
                Dim scCollector1 As ScCollector
                scCollector1 = booleanBuilder1.ToolBodyCollector
                booleanBuilder1.Tolerance = 0.001
                booleanBuilder1.Operation = Features.Feature.BooleanType.Unite
                Dim added1 As Boolean
                added1 = booleanBuilder1.Targets.Add(Bodieslist.Item(0))
                Bodieslist.Remove(Bodieslist.Item(0))
                Dim scCollector2 As ScCollector
                scCollector2 = workPart.ScCollectors.CreateCollector()
                Dim bodies1() As Body = Bodieslist.ToArray
                Dim bodyDumbRule1 As BodyDumbRule
                bodyDumbRule1 = workPart.ScRuleFactory.CreateRuleBodyDumb(bodies1)
                Dim rules1(0) As SelectionIntentRule
                rules1(0) = bodyDumbRule1
                scCollector2.ReplaceRules(rules1, False)
                booleanBuilder1.ToolBodyCollector = scCollector2
                Dim nXObject1 As NXObject
                nXObject1 = booleanBuilder1.Commit()
                booleanBuilder1.Destroy()
 
 
                Dim Newbodieslist() As Body = AskAllBodies(MyPart)
                If Newbodieslist.Length = 1 Then
                    Mybodies = Newbodieslist(0).Tag
                Else
                    lw.WriteLine(Partno & ": Part has " & Newbodieslist.Length.ToString & " solid bodies. Please Check the bounding box Dimensions manaully")
                End If
            ElseIf j = 1 Then
                Mybodies = theBodies(0).Tag
            Else
                lw.WriteLine(Partno & ": Part has no solid bodies. Please Check the bounding box Dimensions manaully")
            End If
 
 
 
            Try
                ufs.Modl.AskBoundingBoxExact(Mybodies, csys, min_corner, directions, distances)
                Dim TrimX() As String = Split(distances(0).ToString, ".", 2)
                Dim TrimY() As String = Split(distances(1).ToString, ".", 2)
                Dim TrimZ() As String = Split(distances(2).ToString, ".", 2)
                XValue = TrimX(0) & "." & Left(TrimX(1), 3) & " mm"
                YValue = TrimY(0) & "." & Left(TrimY(1), 3) & " mm"
                ZValue = TrimZ(0) & "." & Left(TrimZ(1), 3) & " mm"
            Catch ex As Exception
                lw.WriteLine(Partno & ": Bound Box Dimensional Error-" & ex.Message.ToString)
                XValue = distances(0).ToString
                YValue = distances(1).ToString
                ZValue = distances(2).ToString
            End Try

Regards,

Joe