The code I copied from http://www.nxjournaling.com/content/creating-bounding-box-arround-solid is very good but it is accurate when applied to the displayed part only. In the assembly mode, it is not accurate as it does not create box around the correct directions.In other words, the box dimensions reported in displayed-part mode and assembly mode are not the same. How should the code be adjusted so the dimensions in assembly mode is the same as the displayed part mode?
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
How do I pass the component
How do I pass the component to the
AskBoundingBoxExact
instead of using the selection dialog?You Can't input component
AskBoundingBoxExact will only take one body as input, If you want to do it for all items in the assembly you can add all bodies to a for loop and you can do it. If you want to do it to only specific bodies you have to find a way to filter them using name or color or other properties. The difference between the displayed part and in assembly mode is due to the reference coordinates
" ufs.Csys.AskWcs(csys)"
you can add a function to allow the user to select which CSYS they want. This will give same result in both cases.
For going through all the bodies you can use the code below.
Function AskAllBodies(ByVal thePart As Part) As List(Of Body)
Dim theBodies As New List(Of Body)
Try
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(Utilities.NXObjectManager.Get(aBodyTag))
End If
Loop While True
Catch ex As NXException
lw.WriteLine(ex.ErrorCode & ex.Message)
End Try
Return theBodies
End Function
Regards,
Joe
Thanks, Alto. I tried to pass
Thanks, Alto. I tried to pass a workPart to get List(of Body) but I got this message
Unhandled exception has occurred in a component in your application. If you click Continue, the application will ignore this error and attempt to continue.
Object variable or With block variable not set.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim workPart As NXOpen.Part = theSession.Parts.Work
MsgBox(AskAllBodies(workPart)(0).Name)
End Sub
re: error message
Based on the little code that you've posted, I'd guess that the error is one of two things:
1) The NXOpen dll is not referenced properly in your project.
or
2) The subroutine does not have access to the "theSession" variable. It will need to be declared with the proper scope, or a reference needs to be passed to the subroutine for it to have access.
Could you ask an example code
Could you ask an example code on how to run the function? (1) I am very sure I added the dll correctly as I have been building other codes as well. (2) I added
Dim theSession As Session = Session.GetSession()
to my sub, the program could be built but still same error.Post Full code
If you post full code only it is easy to identify the error where it went wrong. This following one is working good for me.
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.UF
Module BoundBox
Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim theUI As UI = UI.GetUI
Dim ufs As UFSession = UFSession.GetUFSession
Dim lw As ListingWindow = theSession.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
lw.Open()
Dim min_corner(2) As Double
Dim directions(2, 2) As Double
Dim distances(2) As Double
Dim edge_len(2) As String
'Retrive Bodies here from function
Dim MybodyList As List(Of Body) = New List(Of Body)
MybodyList = AskAllBodies(workPart)
If MybodyList.Count = 0 Then
MsgBox("There are No bodies to measure in Work Part")
End If
For Each Mybody As Body In MybodyList
a_body = Mybody.Tag
ufs.Csys.AskWcs(csys)
ufs.Modl.AskBoundingBoxExact(a_body, csys, min_corner, directions, _
distances)
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)
Next
End Sub
Function AskAllBodies(ByVal thePart As Part) As List(Of Body)
Dim theBodies As New List(Of Body)
Try
Dim aBodyTag As Tag = NXOpen.Tag.Null
Do
ufs.Obj.CycleObjsInPart(thePart.Tag, _
UFConstants.UF_solid_type, aBodyTag)
If aBodyTag = NXOpen.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(Utilities.NXObjectManager.Get(aBodyTag))
End If
Loop While True
Catch ex As NXException
lw.WriteLine(ex.ErrorCode & ex.Message)
End Try
Return theBodies
End Function
Public Function GetUnloadOption(ByVal dummy As String) As Integer
GetUnloadOption = UFConstants.UF_UNLOAD_IMMEDIATELY
End Function
End Module
Regards,
Joe
Thanks, Joe. Let me review
Thanks, Joe. Let me review your code and study to see if I know why I could not get my code worked.
re: bounding boxes
GTAC also has some example code. Search the GTAC solution center for "bounding box" to find several examples. Here are 2:
http://solutions.industrysoftware.automation.siemens.com/view.php?si=nx_...
http://solutions.industrysoftware.automation.siemens.com/view.php?si=nx_...
Link to solution center:
https://solutions.industrysoftware.automation.siemens.com/
I will try to figure these 2
I will try to figure these 2 things out sometime tonight as all of the licenses @ my company are occupied now. But just in case you know or you can provide quick hints for 2 questions on the 2nd link
(1) How could I adjust the code to run in Make Displayed Part mode? It does not return anything when I run the code for the part (Assembly --> Right Click --> Make Displayed Part).
(2) could I use the coordinates of the parts' instead of the main assembly coordinate? This will help me get the dimensions of the boxes correctly.
Thank you very much.
re: display part mode
1) This thread has lots of code and links to code in it. You'll need to specify which journal that you are running on a piece part before anyone can give a specific answer.
2) You will need to calculate the bounding box for the prototype body rather than the assembly occurrence body. The code in one of the GTAC links above shows how to do that. Note: I had pasted an incorrect link in the previous reply - I have edited the reply to correct the link.
1. Sorry, I meant https:/
1. Sorry, I meant https://solutions.industrysoftware.automation.siemens.com/view.php?si=nx...
However, I looked into the code from your new link and I think it should already solve the problem.
2. Thanks.