AskBoundingBox Function
AskBoundingBox Function
(OP)
Hello, I am trying to learn how to use the AskBoundingBox function. I have a journal that is processing every model part in the assembly. I am trying to use the AskBoundingBox feature to measure the length (X, Y and Z) of each model part based on a WCS of absolute, in feet not inches. How do I do that?





RE: AskBoundingBox Function
Regards,
Scott
RE: AskBoundingBox Function
RE: AskBoundingBox Function
By default the AskBoundingBox function only returns units in inches. If you want units in feet (or any other measurement) you will have to perform arithmetic operations on the "bbox()" variables.
For example:
(bbox(0)/12)
That would give you feet instead of inches.
'June 16, 2015
' Update to process instance bodies in the current display part (the assembly)
' instead of looping through the solid bodies in each component.
'
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Module Module2
Dim theSession As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
Dim theUfSession As UFSession = UFSession.GetUFSession()
Dim theUISession As UI = UI.GetUI
Dim response As Integer
Sub Main()
If IsNothing(theSession.Parts.BaseWork) Then
'active part required
Return
End If
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()
Const undoMarkName As String = "NXJ journal"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)
Dim theAttributes() As NXObject.AttributeInformation
theAttributes = displayPart.GetUserAttributes
lw.Open()
Dim myMeasure As MeasureManager = theSession.Parts.Display.MeasureManager()
Dim massUnits(4) As Unit
massUnits(0) = theSession.Parts.Display.UnitCollection.GetBase("Area")
massUnits(1) = theSession.Parts.Display.UnitCollection.GetBase("Volume")
massUnits(2) = theSession.Parts.Display.UnitCollection.GetBase("Mass")
massUnits(3) = theSession.Parts.Display.UnitCollection.GetBase("Length")
Dim theBodies As New List(Of Body)
Dim row as integer
theBodies = AskAllBodies(theSession.Parts.Display)
Dim MdlPrt As String
Dim c As ComponentAssembly = workPart.ComponentAssembly
Dim rootDispName As String = (c.RootComponent.DisplayName).Replace("/", "_")
For Each tempBody As Body In theBodies
'Dim partName As String
'Dim refSetName As String
Dim instanceName As String
'Dim origin(2) As Double
'Dim csysMatrix(8) As Double
'Dim transform(3, 3) As Double
Dim YG as String
Dim XG as String
Dim ZG as String
Dim parentTag As Tag
theUfSession.Assem.AskParentComponent(tempBody.Tag, parentTag)
'theUfSession.Assem.AskComponentData(parentTag, partName, refSetName, instanceName, origin, csysMatrix, transform)
Dim bodyComp As Component = Utilities.NXObjectManager.Get(parentTag)
lw.WriteLine("")
MdlPrt = instanceName
lw.WriteLine(MdlPrt)
lw.WriteLine("")
'lengths returned in part units
Dim bodyLengths(2) As Double
bodyLengths = GetBoundingBox(tempBody)
lw.WriteLine("Extents")
lw.WriteLine("")
lw.WriteLine("X length: " & bodyLengths(0).ToString)
lw.WriteLine("Y length: " & bodyLengths(1).ToString)
lw.WriteLine("Z length: " & bodyLengths(2).ToString)
'Measures Min/Max of all model parts in assembly
Dim bbox(5) as double
Dim tagList(0) As NXOpen.Tag
ufs.Modl.AskBoundingBox(tempBody.Tag,bbox)
lw.WriteLine("Mininum and Maximum Extents")
lw.WriteLine("")
lw.WriteLine("min X: " & bbox(0) & " max X: " & bbox(3))
lw.WriteLine("min Y: " & bbox(1) & " max Y: " & bbox(4))
lw.WriteLine("min Z: " & bbox(2) & " max Z: " & bbox(5))
'lw.WriteLine("X dim: " & bbox(3) - bbox(0))
'lw.WriteLine("Y dim: " & bbox(4) - bbox(1))
'lw.WriteLine("Z dim: " & bbox(5) - bbox(2))
row += 1
Next
End Sub
Function AskAllBodies(ByVal thePart As Part) As List(Of Body)
Dim theBodies As New List(Of Body)
Dim aBodyTag As Tag = Tag.Null
Do
theUfSession.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
theUfSession.Obj.AskTypeAndSubtype(aBodyTag, theType, theSubtype)
If theSubtype = UFConstants.UF_solid_body_subtype Then
theBodies.Add(Utilities.NXObjectManager.Get(aBodyTag))
End If
Loop While True
Return theBodies
End Function
Private Function GetBoundingBox(ByVal solidBody As NXOpen.Body) As Double()
'AskBoundingBox returns min and max coordinates
'this function will simply return the box lengths (x, y, z)
Dim bboxCoordinates(5) As Double
Dim bboxLengths(2) As Double
Try
'get solid body bounding box extents
theUFSession.Modl.AskBoundingBox(solidBody.Tag, bboxCoordinates)
bboxLengths(0) = bboxCoordinates(3) - bboxCoordinates(0)
bboxLengths(1) = bboxCoordinates(4) - bboxCoordinates(1)
bboxLengths(2) = bboxCoordinates(5) - bboxCoordinates(2)
Return bboxLengths
Catch ex As NXException
MsgBox(ex.GetType.ToString & " : " & ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "Solid Body Bounds Error!")
bboxLengths(0) = 0
bboxLengths(1) = 0
bboxLengths(2) = 0
Return bboxLengths
End Try
End Function
Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
End Function
End Module
RE: AskBoundingBox Function
Technically, it will return inches or mm, depending on the base part units.
www.nxjournaling.com
RE: AskBoundingBox Function
How do I get this code to automatically set attributes for each component it opens?
I have added the code below, but all it does is add these attributes to the parent/assembly file, not each child/component.
theSession.Parts.Work.SetAttribute("X-dim", bodyLengths(0).ToString("0.000"))
theSession.Parts.Work.SetAttribute("Y-dim", bodyLengths(1).ToString("0.000"))
theSession.Parts.Work.SetAttribute("Z-dim", bodyLengths(2).ToString("0.000"))
Using NX9
Thanks
RE: AskBoundingBox Function
Try search Google :
"NX bounding box"
also try: ( this search is valid on google, I don't know other search engines)
"NX bounding box site:community.plm.automation.siemens.com"
And :
"NX bounding box site:eng-tips.com"
Regards,
Tomas
RE: AskBoundingBox Function
I'll keep searching, thanks again.
RE: AskBoundingBox Function
Regards,
Tomas
RE: AskBoundingBox Function
RE: AskBoundingBox Function
www.nxjournaling.com
RE: AskBoundingBox Function
Option Strict Off
Imports System
Imports System.Collections
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.BlockStyler
Imports NXOpen.UserDefinedObjects
Imports NXOpen.Annotations
Module BoundingBoxUdoFeature
Dim theSession As Session = Nothing
Dim theUFSession As UFSession = Nothing
Dim bbClass As UserDefinedClass = Nothing
Dim bbUdo As UserDefinedObject = Nothing
Sub Echo(ByVal output As String)
theSession.ListingWindow.Open()
theSession.ListingWindow.WriteLine(output)
theSession.LogFile.WriteLine(output)
End Sub
Sub Show_boundingBox()
Dim theboundingBox As boundingBox
Try
theboundingBox = New boundingBox()
theboundingBox.Show()
theboundingBox.Dispose()
Catch ex As Exception
Echo("Caught Exception in Show_boundingBox: '" & ex.Message() & "'")
End Try
End Sub
Public Function bbUpdateCB(ByVal editEvent As UserDefinedLinkEvent) As Integer
Try
bbUpdateCB = 0
bbUdo = editEvent.UserDefinedObject
Dim links() As UserDefinedObject.LinkDefinition = bbUdo.GetLinks(UserDefinedObject.LinkType.Type3)
Dim anyAlive As Boolean = False
For ii As Integer = 0 To links.Length - 1
If theUFSession.Obj.AskStatus(links(ii).AssociatedObject.Tag) = UFConstants.UF_OBJ_ALIVE Then
anyAlive = True
End If
Next
If Not anyAlive Or links.Length < 1 Then 'Last object to be inside box has been deleted
Dim objects1() As NXObject = {bbUdo.GetUserDefinedObjectFeature, bbUdo}
theSession.UpdateManager.AddToDeleteList(objects1)
Return 0
End If
' Echo("anyAlive = " & anyAlive & ", links.length = " & links.Length)
Dim clinks() As UserDefinedObject.LinkDefinition = bbUdo.GetLinks(UserDefinedObject.LinkType.Type2)
Dim csys As CartesianCoordinateSystem = clinks(0).AssociatedObject
Dim corner(2) As Double
Dim farCorner(2) As Double
Dim dirs(2, 2) As Double
Dim deltas(2) As Double
Dim minCorner(2) As Double
Dim maxCorner(2) As Double
Dim maxDeltas(2) As Double
Dim first As Boolean = True
For ii As Integer = 0 To links.Length - 1
If Not theUFSession.Obj.AskStatus(links(ii).AssociatedObject.Tag) = UFConstants.UF_OBJ_ALIVE Then
Continue For
End If
theUFSession.Modl.AskBoundingBoxExact(links(ii).AssociatedObject.Tag, csys.Tag, corner, dirs, deltas)
For jj As Integer = 0 To 2
farCorner(jj) = corner(jj)
For kk As Integer = 0 To 2
farCorner(jj) += dirs(kk, jj) * deltas(kk)
Next
Next
mapAbs2Dirs(dirs, corner)
mapAbs2Dirs(dirs, farCorner)
If first Then
theUFSession.Vec3.Copy(corner, minCorner)
theUFSession.Vec3.Copy(farCorner, maxCorner)
first = False
Else
For jj As Integer = 0 To 2
If corner(jj) < minCorner(jj) Then
minCorner(jj) = corner(jj)
End If
If farCorner(jj) > maxCorner(jj) Then
maxCorner(jj) = farCorner(jj)
End If
Next
End If
Next
Dim vecX() As Double = {dirs(0, 0), dirs(0, 1), dirs(0, 2)}
Dim vecY() As Double = {dirs(1, 0), dirs(1, 1), dirs(1, 2)}
Dim vecZ() As Double = {dirs(2, 0), dirs(2, 1), dirs(2, 2)}
Dim oldmag As Double = Nothing
theUFSession.Vec3.Sub(maxCorner, minCorner, maxDeltas)
bbUdo.SetLengths(maxDeltas)
theUFSession.Vec3.Unitize(vecX, 0, oldmag, vecX)
theUFSession.Vec3.Unitize(vecY, 0, oldmag, vecY)
theUFSession.Vec3.Unitize(vecZ, 0, oldmag, vecZ)
mapDirs2Abs(dirs, minCorner)
theUFSession.Vec3.Scale(maxDeltas(0), vecX, vecX)
theUFSession.Vec3.Scale(maxDeltas(1), vecY, vecY)
theUFSession.Vec3.Scale(maxDeltas(2), vecZ, vecZ)
Dim tol As Double = Nothing
theUFSession.Modl.AskDistanceTolerance(tol)
Dim isZero(2) As Integer
theUFSession.Vec3.IsZero(vecX, tol, isZero(0))
theUFSession.Vec3.IsZero(vecY, tol, isZero(1))
theUFSession.Vec3.IsZero(vecZ, tol, isZero(2))
If isZero(0) + isZero(1) + isZero(2) > 0 Then
Echo("Selected object is not 3D cannot create Bounding Box")
bbUdo.GetUserDefinedObjectFeature.Suppress()
bbUpdateCB = 1
Else
If bbUdo.GetUserDefinedObjectFeature.Suppressed Then
bbUdo.GetUserDefinedObjectFeature.Unsuppress()
End If
Dim corners(7) As Point3d
Dim cornerNxPoints(7) As Point
corners(0) = New Point3d(minCorner(0), minCorner(1), minCorner(2))
cornerNxPoints(0) = theSession.Parts.Work.Points.CreatePoint(corners(0))
cornerNxPoints(0).SetVisibility(SmartObject.VisibilityOption.Invisible)
Dim coords(2) As Double
theUFSession.Vec3.Add(minCorner, vecX, coords)
corners(1) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(1) = theSession.Parts.Work.Points.CreatePoint(corners(1))
cornerNxPoints(1).SetVisibility(SmartObject.VisibilityOption.Invisible)
theUFSession.Vec3.Add(coords, vecZ, coords)
corners(2) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(2) = theSession.Parts.Work.Points.CreatePoint(corners(2))
cornerNxPoints(2).SetVisibility(SmartObject.VisibilityOption.Invisible)
theUFSession.Vec3.Add(minCorner, vecZ, coords)
corners(3) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(3) = theSession.Parts.Work.Points.CreatePoint(corners(3))
cornerNxPoints(3).SetVisibility(SmartObject.VisibilityOption.Invisible)
theUFSession.Vec3.Add(minCorner, vecY, coords)
corners(4) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(4) = theSession.Parts.Work.Points.CreatePoint(corners(4))
cornerNxPoints(4).SetVisibility(SmartObject.VisibilityOption.Invisible)
theUFSession.Vec3.Add(coords, vecX, coords)
corners(5) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(5) = theSession.Parts.Work.Points.CreatePoint(corners(5))
cornerNxPoints(5).SetVisibility(SmartObject.VisibilityOption.Invisible)
theUFSession.Vec3.Add(coords, vecZ, coords)
corners(6) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(6) = theSession.Parts.Work.Points.CreatePoint(corners(6))
cornerNxPoints(6).SetVisibility(SmartObject.VisibilityOption.Invisible)
theUFSession.Vec3.Sub(coords, vecX, coords)
corners(7) = New Point3d(coords(0), coords(1), coords(2))
cornerNxPoints(7) = theSession.Parts.Work.Points.CreatePoint(corners(7))
cornerNxPoints(7).SetVisibility(SmartObject.VisibilityOption.Invisible)
Dim starts() As Integer = {0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7}
Dim ends() As Integer = {1, 2, 3, 0, 4, 5, 6, 7, 5, 6, 7, 4}
Dim line_links() As UserDefinedObject.LinkDefinition = bbUdo.GetLinks(UserDefinedObject.LinkType.Owning)
If line_links.Length < 1 Then
System.Array.Resize(line_links, 15)
For ii As Integer = 0 To 11
line_links(ii) = New UserDefinedObject.LinkDefinition
line_links(ii).AssociatedObject = theSession.Parts.Work.Curves.CreateLine(corners(starts(ii)), corners(ends(ii)))
Next
Dim newPmiWidth As PmiParallelDimension = Nothing
line_links(12).AssociatedObject = newPmiWidth
Dim newPmiHeight As PmiParallelDimension = Nothing
line_links(13).AssociatedObject = newPmiHeight
Dim newPmiLength As PmiParallelDimension = Nothing
line_links(14).AssociatedObject = newPmiLength
bbUdo.SetLinks(UserDefinedObject.LinkType.Owning, line_links)
Else
For ii As Integer = 0 To 11
Dim aline As Line = line_links(ii).AssociatedObject
aline.SetEndpoints(corners(starts(ii)), corners(ends(ii)))
Next
Dim dimOrigin As Point3d
Dim dirVector As Vector3d
Dim pmiWidth As PmiParallelDimension = line_links(12).AssociatedObject
dirVector = CreateVector(corners(0), corners(3))
dimOrigin.X = (corners(0).X + corners(1).X) / 2 + 1 * dirVector.X
dimOrigin.Y = (corners(0).Y + corners(1).Y) / 2 + 1 * dirVector.Y
dimOrigin.Z = (corners(0).Z + corners(1).Z) / 2 + 1 * dirVector.Z
pmiWidth = DimPtToPt(cornerNxPoints(0), cornerNxPoints(1), dimOrigin, "XZ")
pmiWidth.SetUserAttribute("PMI", 0, "Width", Update.Option.Now)
' YZ Dimension
Dim pmiHeight As PmiParallelDimension = line_links(13).AssociatedObject
dirVector = CreateVector(corners(1), corners(2))
dimOrigin.X = (corners(1).X + corners(5).X) / 2 + 1 * dirVector.X
dimOrigin.Y = (corners(1).Y + corners(5).Y) / 2 + 1 * dirVector.Y
dimOrigin.Z = (corners(1).Z + corners(5).Z) / 2 + 1 * dirVector.Z
pmiHeight = DimPtToPt(cornerNxPoints(1), cornerNxPoints(5), dimOrigin, "YZ")
pmiHeight.SetUserAttribute("PMI", 1, "Height", Update.Option.Now)
' ZX Dimension 2
Dim pmiLength As PmiParallelDimension = line_links(14).AssociatedObject
dirVector = CreateVector(corners(0), corners(1))
dimOrigin.X = (corners(0).X + corners(3).X) / 2 + 1 * dirVector.X
dimOrigin.Y = (corners(0).Y + corners(3).Y) / 2 + 1 * dirVector.Y
dimOrigin.Z = (corners(0).Z + corners(3).Z) / 2 + 1 * dirVector.Z
pmiLength = DimPtToPt(cornerNxPoints(0), cornerNxPoints(3), dimOrigin, "XZ")
pmiLength.SetUserAttribute("PMI", 2, "Length", Update.Option.Now)
End If
End If
Catch ex As NXException
Echo("Caught Exception in bbUpdateCB: '" & ex.Message() & "'")
End Try
End Function
Private Function CreateVector(ByVal iVecHead As Point3d, ByVal iVecTail As Point3d) As Vector3d
Dim Mag As Double
Mag = Math.Sqrt((iVecHead.X - iVecTail.X) ^ 2 + (iVecHead.Y - iVecTail.Y) ^ 2 + (iVecHead.Z - iVecTail.Z) ^ 2)
Dim Vctr As New Vector3d((iVecHead.X - iVecTail.X) / Mag, (iVecHead.Y - iVecTail.Y) / Mag, (iVecHead.Z - iVecTail.Z) / Mag)
Return Vctr
End Function
Public Function DimPtToPt(ByVal Point1 As Point, ByVal Point2 As Point, ByVal Origin As Point3d, ByVal iPlane As String) As PmiParallelDimension
Dim pmiRapidDimensionBuilder1 As Annotations.PmiRapidDimensionBuilder
pmiRapidDimensionBuilder1 = theSession.Parts.Work.Dimensions.CreatePmiRapidDimensionBuilder(Nothing)
pmiRapidDimensionBuilder1.Origin.SetInferRelativeToGeometry(True)
pmiRapidDimensionBuilder1.Origin.Anchor = Annotations.OriginBuilder.AlignmentPosition.MidCenter
If iPlane = "XY" Then
pmiRapidDimensionBuilder1.Origin.Plane.PlaneMethod = Annotations.PlaneBuilder.PlaneMethodType.XyPlane
ElseIf iPlane = "YZ" Then
pmiRapidDimensionBuilder1.Origin.Plane.PlaneMethod = Annotations.PlaneBuilder.PlaneMethodType.YzPlane
Else
pmiRapidDimensionBuilder1.Origin.Plane.PlaneMethod = Annotations.PlaneBuilder.PlaneMethodType.XzPlane
End If
pmiRapidDimensionBuilder1.Origin.SetInferRelativeToGeometry(True)
Dim nullDirection As Direction = Nothing
pmiRapidDimensionBuilder1.Measurement.Direction = nullDirection
Dim nullView As View = Nothing
pmiRapidDimensionBuilder1.Measurement.DirectionView = nullView
pmiRapidDimensionBuilder1.Style.DimensionStyle.NarrowDisplayType = Annotations.NarrowDisplayOption.None
Dim point1_1 As Point3d = New Point3d(Point1.Coordinates.X, Point1.Coordinates.Y, Point1.Coordinates.Z)
Dim point2_1 As Point3d = New Point3d(0.0, 0.0, 0.0)
pmiRapidDimensionBuilder1.FirstAssociativity.SetValue(InferSnapType.SnapType.Exist, Point1, theSession.Parts.Work.ModelingViews.WorkView, point1_1, Nothing, nullView, point2_1)
Dim objects1(0) As NXObject
objects1(0) = Point1
pmiRapidDimensionBuilder1.AssociatedObjects.Nxobjects.SetArray(objects1)
Dim point1_4 As Point3d = New Point3d(Point2.Coordinates.X, Point2.Coordinates.Y, Point2.Coordinates.Z)
Dim point2_4 As Point3d = New Point3d(0.0, 0.0, 0.0)
pmiRapidDimensionBuilder1.SecondAssociativity.SetValue(InferSnapType.SnapType.Mid, Point2, theSession.Parts.Work.ModelingViews.WorkView, point1_4, Nothing, nullView, point2_4)
Dim objects2(1) As NXObject
objects2(0) = Point1
objects2(1) = Point2
pmiRapidDimensionBuilder1.AssociatedObjects.Nxobjects.SetArray(objects2)
pmiRapidDimensionBuilder1.Origin.Origin.SetValue(Nothing, nullView, Origin)
pmiRapidDimensionBuilder1.Origin.SetInferRelativeToGeometry(True)
pmiRapidDimensionBuilder1.Style.LineArrowStyle.LeaderOrientation = Annotations.LeaderSide.Left
Dim nXObject1 As NXObject
nXObject1 = pmiRapidDimensionBuilder1.Commit()
pmiRapidDimensionBuilder1.Destroy()
Return nXObject1
End Function
Sub mapDirs2Abs(ByVal dirs(,) As Double, ByRef vec() As Double)
Dim absCsys() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
Dim dirsCsys() As Double = {0, 0, 0, dirs(0, 0), dirs(0, 1), dirs(0, 2), dirs(1, 0), dirs(1, 1), dirs(1, 2)}
Dim mx(11) As Double
Dim status As Integer
theUFSession.Trns.CreateCsysMappingMatrix(dirsCsys, absCsys, mx, status)
theUFSession.Trns.MapPosition(vec, mx)
End Sub
Sub mapAbs2Dirs(ByVal dirs(,) As Double, ByRef vec() As Double)
Dim absCsys() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
Dim dirsCsys() As Double = {0, 0, 0, dirs(0, 0), dirs(0, 1), dirs(0, 2), dirs(1, 0), dirs(1, 1), dirs(1, 2)}
Dim mx(11) As Double
Dim status As Integer
theUFSession.Trns.CreateCsysMappingMatrix(absCsys, dirsCsys, mx, status)
theUFSession.Trns.MapPosition(vec, mx)
End Sub
Public Function bbEditCB(ByVal editEvent As UserDefinedEvent) As Integer
Try
bbUdo = editEvent.UserDefinedObject
Show_boundingBox()
Catch ex As NXException
Echo("Caught Exception in bbEditCB: '" & ex.Message() & "'")
End Try
bbEditCB = 0
End Function
Public Function bbInfoCB(ByVal editEvent As UserDefinedEvent) As Integer
Try
bbUdo = editEvent.UserDefinedObject
Dim sizes() As Double = bbUdo.GetLengths()
Echo("Bounding Box is " & sizes(0) & " X " & sizes(1) & " X " & sizes(2) & " " & bbUdo.OwningPart.PartUnits.ToString)
Echo(" Volume is " & (sizes(0) * sizes(1) * sizes(2)) & " " & bbUdo.OwningPart.PartUnits.ToString & "^3")
Catch ex As NXException
Echo("Caught Exception in bbEditCB: '" & ex.Message() & "'")
End Try
bbInfoCB = 0
End Function
Public Function initUDO() As Integer
Try
If theSession Is Nothing Then
theSession = Session.GetSession()
theUFSession = NXOpen.UF.UFSession.GetUFSession()
theSession.LogFile.WriteLine("Registering Bounding Box UDO Class")
bbClass = theSession.UserDefinedClassManager.CreateUserDefinedObjectClass("Bounding Box", "Bounding Box")
bbClass.AllowOwnedObjectSelectionOption = UserDefinedClass.AllowOwnedObjectSelection.On
bbClass.AddUpdateHandler(AddressOf bbUpdateCB)
bbClass.AddEditHandler(AddressOf bbEditCB)
bbClass.AddInformationHandler(AddressOf bbInfoCB)
End If
Catch ex As NXException
Echo("Caught Exception in initUDO: '" & ex.Message() & "'" & vbCrLf)
End Try
initUDO = 0
End Function
Sub Main()
Try
initUDO()
Dim workPart As Part = theSession.Parts.Work
If Not workPart Is Nothing Then
bbUdo = workPart.UserDefinedObjectManager.CreateUserDefinedObject(bbClass)
Dim autoTypes() As Integer = {UFConstants.UF_line_type, _
UFConstants.UF_circle_type, _
UFConstants.UF_conic_type, _
UFConstants.UF_spline_type, _
UFConstants.UF_solid_type}
Dim autoSubtypes() As Integer = {0, 0, 0, 0, UFConstants.UF_solid_body_subtype}
Dim selobjs() As DisplayableObject = getAllObjectsByTypesAndSubtypes(autoTypes, autoSubtypes)
If (selobjs.Length < 1) Then Return
Dim links(selobjs.Length - 1) As UserDefinedObject.LinkDefinition
For ii As Integer = 0 To selobjs.Length - 1
links(ii).AssociatedObject = selobjs(ii)
Next
bbUdo.SetLinks(UserDefinedObject.LinkType.Type3, links)
Dim clinks(0) As UserDefinedObject.LinkDefinition
clinks(0).AssociatedObject = theSession.Parts.Work.WCS.CoordinateSystem
bbUdo.SetLinks(UserDefinedObject.LinkType.Type2, clinks)
Dim bbfb As Features.UserDefinedObjectFeatureBuilder = workPart.Features.CreateUserDefinedObjectFeatureBuilder(Nothing)
bbfb.UserDefinedObject = bbUdo
bbfb.Commit()
bbfb.Destroy() ' This is important! See PR 6419778.
Show_boundingBox()
End If
Catch ex As NXException
Echo("Caught Exception in Main: '" & ex.Message() & "'")
End Try
End Sub
Function getAllObjectsByTypesAndSubtypes(ByVal whatTypes() As Integer, ByVal whatSubTypes() As Integer) As DisplayableObject()
Dim objList As ArrayList = New ArrayList
Dim thisType As Integer = 0
Dim thisSubType As Integer = 0
For Each obj As DisplayableObject In theSession.Parts.Work.Views.WorkView.AskVisibleObjects
theUFSession.Obj.AskTypeAndSubtype(obj.Tag, thisType, thisSubType)
For ii As Integer = 0 To whatTypes.Length - 1
If whatTypes(ii) = thisType And whatSubTypes(ii) = thisSubType Then
objList.Add(obj)
End If
Next
Next
Return objList.ToArray(GetType(DisplayableObject))
End Function
Public Function Startup() As Integer
initUDO()
Startup = 0
End Function
Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return CType(Session.LibraryUnloadOption.Explicitly, Integer)
End Function
Public Class boundingBox
Private Shared theUI As UI
Private theDialogName As String
Private theDialog As NXOpen.BlockStyler.BlockDialog
Private group0 As NXOpen.BlockStyler.UIBlock ' Block type: Group
Private selection0 As NXOpen.BlockStyler.UIBlock ' Block type: Selection
Private coord_system0 As NXOpen.BlockStyler.UIBlock ' Block type: Specify Csys\
Private DllFileDirectory As String
Private theDlxFileName As String
Public Sub New()
Try
theSession = Session.GetSession()
theUI = UI.GetUI()
Dim DllFileLocation As String
DllFileLocation = System.Reflection.Assembly.GetExecutingAssembly().Location
DllFileDirectory = ""
For i As Integer = 0 To DllFileLocation.Split("\").Length - 2
DllFileDirectory = DllFileDirectory + DllFileLocation.Split("\")(i) + "\"
Next
theDlxFileName = DllFileDirectory + "boundingBox.dlx"
theDialog = theUI.CreateDialog(theDlxFileName)
'theDialogName = "boundingBox.dlx"
'theDialog = theUI.CreateDialog(theDialogName)
theDialog.AddApplyHandler(AddressOf apply_cb)
theDialog.AddOkHandler(AddressOf ok_cb)
theDialog.AddUpdateHandler(AddressOf update_cb)
theDialog.AddInitializeHandler(AddressOf initialize_cb)
theDialog.AddDialogShownHandler(AddressOf dialogShown_cb)
theUI.SelectionManager.SetSelectionStatusOfUserDefinedClass(bbClass, True)
Catch ex As Exception
Echo("Caught Exception in New: '" & ex.Message() & "'" & vbCrLf)
Throw ex
End Try
End Sub
Public Sub Show()
Try
theDialog.Show(BlockDialog.DialogMode.Edit)
Catch ex As Exception
Echo("Caught Exception in Show: '" & ex.Message() & "'" & vbCrLf)
End Try
End Sub
Public Sub Dispose()
If theDialog IsNot Nothing Then
theDialog.Dispose()
theDialog = Nothing
End If
End Sub
Public Sub initialize_cb()
Try
group0 = CType(theDialog.TopBlock.FindBlock("group0"), NXOpen.BlockStyler.UIBlock)
selection0 = CType(theDialog.TopBlock.FindBlock("selection0"), NXOpen.BlockStyler.UIBlock)
coord_system0 = CType(theDialog.TopBlock.FindBlock("coord_system0"), NXOpen.BlockStyler.UIBlock)
Dim selectionFilter(6) As NXOpen.Selection.MaskTriple
With selectionFilter(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_BODY
End With
With selectionFilter(1)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_FACE
End With
With selectionFilter(2)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
End With
With selectionFilter(3)
.Type = UFConstants.UF_line_type
.Subtype = 0
.SolidBodySubtype = 0
End With
With selectionFilter(4)
.Type = UFConstants.UF_circle_type
.Subtype = 0
.SolidBodySubtype = 0
End With
With selectionFilter(5)
.Type = UFConstants.UF_conic_type
.Subtype = 0
.SolidBodySubtype = 0
End With
With selectionFilter(6)
.Type = UFConstants.UF_spline_type
.Subtype = 0
.SolidBodySubtype = 0
End With
selection0.GetProperties.SetSelectionFilter("SelectionFilter", Selection.SelectionAction.ClearAndEnableSpecific, selectionFilter)
Dim links() As UserDefinedObject.LinkDefinition = bbUdo.GetLinks(UserDefinedObject.LinkType.Type3)
Dim selObjs(links.Length - 1) As DisplayableObject
For ii As Integer = 0 To links.Length - 1
selObjs(ii) = links(ii).AssociatedObject
selObjs(ii).Highlight()
Next
selection0.GetProperties.SetTaggedObjectVector("SelectedObjects", selObjs)
Dim clinks() As UserDefinedObject.LinkDefinition = bbUdo.GetLinks(UserDefinedObject.LinkType.Type2)
If clinks.Length > 0 Then
Dim csys() As TaggedObject = {clinks(0).AssociatedObject}
coord_system0.GetProperties.SetTaggedObjectVector("SelectedObjects", csys)
End If
Catch ex As Exception
Echo("Caught Exception in dialogShown_cb: '" & ex.Message() & "'" & vbCrLf)
End Try
End Sub
Public Sub dialogShown_cb()
End Sub
Public Function apply_cb() As Integer
Dim errorCode As Integer = 0
Try
Dim objs() As TaggedObject = selection0.GetProperties.GetTaggedObjectVector("SelectedObjects")
Dim links(objs.Length - 1) As UserDefinedObject.LinkDefinition
For ii As Integer = 0 To objs.Length - 1
links(ii).AssociatedObject = objs(ii)
Next
bbUdo.SetLinks(UserDefinedObject.LinkType.Type3, links)
Dim clinks(0) As UserDefinedObject.LinkDefinition
objs = coord_system0.GetProperties.GetTaggedObjectVector("SelectedObjects")
clinks(0).AssociatedObject = objs(0)
bbUdo.SetLinks(UserDefinedObject.LinkType.Type2, clinks)
Dim markId1 As Session.UndoMarkId = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Edit Bounding Box")
Dim nErrs2 As Integer = theSession.UpdateManager.DoUpdate(markId1)
theSession.DeleteUndoMark(markId1, Nothing)
Catch ex As Exception
errorCode = 1
Echo("Caught Exception in apply_cb: '" & ex.Message() & "'" & vbCrLf)
End Try
apply_cb = errorCode
End Function
Public Function update_cb(ByVal block As NXOpen.BlockStyler.UIBlock) As Integer
Try
If block Is selection0 Then
ElseIf block Is coord_system0 Then
End If
Catch ex As Exception
Echo("Caught Exception in update_cb: '" & ex.Message() & "'" & vbCrLf)
End Try
update_cb = 0
End Function
Public Function ok_cb() As Integer
Dim errorCode As Integer = 0
Try
errorCode = apply_cb()
Catch ex As Exception
Echo("Caught Exception in ok_cb: '" & ex.Message() & "'" & vbCrLf)
End Try
ok_cb = errorCode
End Function
End Class
End Module
RE: AskBoundingBox Function
The bounding box would need to be aligned with the individual component's. For our designers it is standard practice to establish all component geometry off of the individual component 0,0,0 normal to X & Y if rectangular/square, and then position/constrain the component in the assembly as needed.
I have been 'working' on the code below, and so far it is working fairly well, and is doing mostly what I want, it just requires me to manually do it to every component as a work part. (I'm sure there's a much easier/efficient way to do what I have modified, but that's the best I got with my limited C++ and Excel formulas background. I'm sure you actual programmers out there will get a headache....) Ideally I would like it to run in the assembly to better insure that it can be run as one of the last steps before releasing the BOM and print to increase the accuracy and precision of our BOM to which the tool makers use to cut their stock, and make sure it is done to every component. My current fear is that this still allows the designer to run the journal, then modify a component last minute and the attributes will still show the old bounding box dims from the previous journal run, is there anyway of making it dynamic?
Another question that has arose from doing trials is that sometimes when I assign a material to a body/component the MaterialMissingAssignment locked-attribute does not always switch to FALSE, and that causes issues with my code because I want to use that as a check to make sure I am writing all the attributes I want to when the journal runs. Anybody have experience with this happening?
Your help is greatly appreciated.
One benefit of this journal is it allows me to load my assembly off of my "FULL" attribute which combines the Leaf-name, overall 3 sizes, and then the material and hardness when the component is hovered over with the cursor in the assembly window (picture below):
'******************************************
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Module NXJournal
Sub Main
Dim theSession As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim bbox(5) as double
Dim dblAcc_Value(11) as double
Dim dblMass_Props(46) as double
Dim dblStats(12) as double
dim strOutput as string
dim boundX as double
dim boundY as double
dim boundZ as double
dim dim1 as double
dim dim2 as double
dim dim3 as double
Dim solid1 As Body = SelectSolid()
If solid1 Is Nothing Then
Return
End If
Dim tagList(0) As NXOpen.Tag
tagList(0) = solid1.Tag
'get volume
dblAcc_Value(0)=.999
'AskMassProps3d(in_Tags(),in_num_objs,in_type,in_units,in_density,in_accuracy,in_accuracy_values(),out_mass_props(),out_stats())
ufs.Modl.AskMassProps3d(tagList,1,1,1,.0375,1,dblAcc_Value,dblMass_Props,dblStats)
strOutput = "Surface Area: " & dblMass_Props(0) & vbcrlf
strOutput = strOutput & "Volume: " & dblMass_Props(1) & vbcrlf
strOutput = strOutput & "Mass: " & dblMass_Props(2) & vbcrlf
strOutput = strOutput & "COG: " & dblMass_Props(3) & ", " & dblMass_Props(4) & ", " & dblMass_Props(5) & vbcrlf
strOutput = strOutput & "Density: " & dblMass_Props(46)
' msgbox (strOutput, vbokonly)
'get solid body bounding box extents
ufs.Modl.AskBoundingBox(solid1.Tag,bbox)
' msgbox ("min X: " & bbox(0) & " max X: " & bbox(3) & vbcrlf _
' & "min Y: " & bbox(1) & " max Y: " & bbox(4) & vbcrlf _
' & "min Z: " & bbox(2) & " max Z: " & bbox(5) & vbcrlf & vbcrlf & _
' "X dim: " & bbox(3) - bbox(0) & vbcrlf & _
' "Y dim: " & bbox(4) - bbox(1) & vbcrlf & _
' "Z dim: " & bbox(5) - bbox(2), vbokonly)
boundX = bbox(3) - bbox(0)
boundY = bbox(4) - bbox(1)
boundZ = bbox(5) - bbox(2)
'**********************************************************
'Sort Bounding Box Dimensions To Output Smallest to Largest
If boundX <= boundY And boundY <= boundZ Then dim1=boundX
If boundX <= boundY And boundY <= boundZ Then dim2=boundY
If boundX <= boundY And boundY <= boundZ Then dim3=boundZ
If boundX <= boundY And boundZ <= boundY Then dim1 = boundX
If boundX <= boundY And boundZ <= boundY Then dim2 = boundZ
If boundX <= boundY And boundZ <= boundY Then dim3 = boundY
If boundY <= boundX And boundX <= boundZ Then dim1 = boundY
If boundY <= boundX And boundX <= boundZ Then dim2 = boundX
If boundY <= boundX And boundX <= boundZ Then dim3 = boundZ
If boundY <= boundZ And boundZ <= boundX Then dim1 = boundY
If boundY <= boundZ And boundZ <= boundX Then dim2 = boundZ
If boundY <= boundZ And boundZ <= boundX Then dim3 = boundX
If boundZ <= boundX And boundX <= boundY Then dim1 = boundZ
If boundZ <= boundX And boundX <= boundY Then dim2 = boundX
If boundZ <= boundX And boundX <= boundY Then dim3 = boundY
If boundZ <= boundY And boundY <= boundX Then dim1 = boundZ
If boundZ <= boundY And boundY <= boundX Then dim2 = boundY
If boundZ <= boundY And boundY <= boundX Then dim3 = boundX
workPart.SetAttribute("Bounding_X", dim1.ToString("0.00"))
workPart.SetAttribute("Bounding_Y", dim2.ToString("0.00"))
workPart.SetAttribute("Bounding_Z", dim3.ToString("0.00"))
'**********************************************************
Dim fileName as String = ""
fileName = workPart.Leaf
Dim MaterialUnassigned as String
MaterialUnassigned = workPart.GetStringAttribute("MaterialMissingAssignments")
'**********************************************************
'Material Not Assigned for Work Part
If MaterialUnassigned = "TRUE"
Dim lw As ListingWindow = theSession.ListingWindow
Dim material as String
lw.Open()
lw.WriteLine("Material Needs Assigned for Part")
lw.WriteLine("")
lw.WriteLine("Assign Material and Rerun Journal")
lw.Close()
End If
'**********************************************************
'Material Assigned for Work Part
Dim note As String = " "
'note = workPart.GetStringAttribute("Note")
If MaterialUnassigned = "FALSE"
Dim material as String
material = workPart.GetStringAttribute("material")
workPart.SetAttribute("FULL", fileName & " " & dim1.ToString("0.00") & "_X_" & dim2.ToString("0.00") & "_X_" & dim3.ToString("0.00") & " " & material & " " )
workPart.SetAttribute("MAT'L", material)
workPart.SetAttribute("STOCK", dim1.ToString("0.00") & "_X_" & dim2.ToString("0.00") & "_X_" & dim3.ToString("0.00"))
If material = "S-7" Then
workPart.SetAttribute("RC", "52-56")
workPart.SetAttribute("FULL", fileName & " " & dim1.ToString("0.00") & "_X_" & dim2.ToString("0.00") & "_X_" & dim3.ToString("0.00") & " " & material & " " & "RC 52-56")
End If
' If IsNothing(workPart.GetStringAttribute("CALLOUT")) then
' Dim note as string = ""
' note = workPart.GetStringAttribute("Note")
' On Error Goto Resume Next
' workPart.SetAttribute("FULL", fileName & " " & dim1.ToString("0.00") & " X " & dim2.ToString("0.00") & " X " & dim3.ToString("0.00") & " " & material & " " & note)
' Next
'
' End If
End If
End Sub
'**********************************************************
Public Function SelectSolid() As Body
Dim ui As UI = ui.GetUI
Dim message As String = "Select solid body"
Dim title As String = "Selection"
Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart
Dim keepHighlighted As Boolean = False
Dim includeFeatures As Boolean = True
Dim selectionAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
Dim selectionMask_array(1) As Selection.MaskTriple
Dim selectedObject As NXObject = Nothing
Dim cursor As Point3d
With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With
ui.SelectionManager.SelectObject(message, title, scope, _
selectionAction, includeFeatures, _
keepHighlighted, selectionMask_array, _
selectedObject, cursor)
Dim solid As Body = CType(selectedObject, Body)
If solid Is Nothing Then
Return Nothing
End If
Return solid
End Function
'*******************
End Module
RE: AskBoundingBox Function
Do you have multiple solid bodies in your file? If any solid body does not have a material assigned, you will get the "missing assignment" attribute. As an alternative, you might want to check that the body you selected does have a material assinged.
www.nxjournaling.com
RE: AskBoundingBox Function
RE: AskBoundingBox Function
Caveat: if the assembly uses promoted bodies, assembly cuts, or deformed parts the results may be incorrect.
CODE
Option Strict Off Imports System Imports System.Collections.Generic Imports NXOpen Imports NXOpen.UF Imports NXOpen.Assemblies Module Module3 Public theSession As Session = Session.GetSession() Public ufs As UFSession = UFSession.GetUFSession() Public lw As ListingWindow = theSession.ListingWindow Sub Main() Dim workPart As Part = theSession.Parts.Work Dim dispPart As Part = theSession.Parts.Display lw.Open() Dim myAsmInfo As New NXJ_Assembly_info myAsmInfo.Part = dispPart For Each temp As Component In myAsmInfo.AllComponents lw.WriteLine(temp.DisplayName) lw.WriteLine(temp.ReferenceSet) Dim tempBody As Body = GetCompBody(temp) If IsNothing(tempBody) Then lw.WriteLine("no body") lw.WriteLine("") Continue For Else lw.WriteLine("body tag: " & tempBody.Tag.ToString) End If Dim compBodyDims As New List(Of Double) compBodyDims = BodyBounds(tempBody) lw.WriteLine("X: " & compBodyDims.Item(0).ToString) lw.WriteLine("Y: " & compBodyDims.Item(1).ToString) lw.WriteLine("Z: " & compBodyDims.Item(2).ToString) lw.WriteLine("") PartStringAttribute(temp.Prototype.OwningPart, "BoundX", compBodyDims.Item(0).ToString) PartStringAttribute(temp.Prototype.OwningPart, "BoundY", compBodyDims.Item(1).ToString) PartStringAttribute(temp.Prototype.OwningPart, "BoundZ", compBodyDims.Item(2).ToString) compBodyDims.Sort() Dim bounds As String = compBodyDims.Item(0).ToString & " x " & compBodyDims.Item(1).ToString & " x " & compBodyDims.Item(2).ToString PartStringAttribute(temp.Prototype.OwningPart, "Bounds", bounds) Next lw.Close() End Sub Function GetCompBody(ByVal theComp As Component) As Body 'return the first solid body found in the component's reference set Dim refSetName As String = theComp.ReferenceSet Dim thePart As Part = theComp.Prototype.OwningPart If refSetName.ToLower = "empty" Then Return Nothing End If If refSetName.ToLower = "entire part" Then For Each tempBody As Body In thePart.Bodies If tempBody.IsSolidBody Then Return tempBody End If Next 'no solid bodies in part Return Nothing End If For Each theRefSet As ReferenceSet In thePart.GetAllReferenceSets If theRefSet.Name = refSetName Then Dim refObjs() As NXObject = theRefSet.AskAllDirectMembers For Each temp As NXObject In refObjs If TypeOf (temp) Is Body Then Dim theBody As Body = temp If theBody.IsSolidBody Then Return theBody End If End If Next 'no solid bodies in part Return Nothing End If Next 'reference set not found Return Nothing End Function Function BodyBounds(ByVal theBody As Body) As List(Of Double) Dim bbox(5) As Double Dim boundX As Double Dim boundY As Double Dim boundZ As Double Dim boundingDims As New List(Of Double) 'get solid body bounding box extents ufs.Modl.AskBoundingBox(theBody.Tag, bbox) ' msgbox ("min X: " & bbox(0) & " max X: " & bbox(3) & vbcrlf _ ' & "min Y: " & bbox(1) & " max Y: " & bbox(4) & vbcrlf _ ' & "min Z: " & bbox(2) & " max Z: " & bbox(5) & vbcrlf & vbcrlf & _ ' "X dim: " & bbox(3) - bbox(0) & vbcrlf & _ ' "Y dim: " & bbox(4) - bbox(1) & vbcrlf & _ ' "Z dim: " & bbox(5) - bbox(2), vbokonly) boundX = bbox(3) - bbox(0) boundY = bbox(4) - bbox(1) boundZ = bbox(5) - bbox(2) boundingDims.Add(boundX) boundingDims.Add(boundY) boundingDims.Add(boundZ) Return boundingDims End Function Sub PartStringAttribute(ByVal thePart As Part, ByVal theTitle As String, ByVal theValue As String) Dim markId1 As Session.UndoMarkId markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "part attribute") Dim objects1(0) As NXObject objects1(0) = thePart Dim attributePropertiesBuilder1 As AttributePropertiesBuilder attributePropertiesBuilder1 = theSession.AttributeManager.CreateAttributePropertiesBuilder(thePart, objects1, AttributePropertiesBuilder.OperationType.None) attributePropertiesBuilder1.IsArray = False attributePropertiesBuilder1.DataType = AttributePropertiesBaseBuilder.DataTypeOptions.String attributePropertiesBuilder1.Title = theTitle attributePropertiesBuilder1.StringValue = theValue Dim nXObject1 As NXObject nXObject1 = attributePropertiesBuilder1.Commit() Dim nErrs1 As Integer nErrs1 = theSession.UpdateManager.DoUpdate(markId1) attributePropertiesBuilder1.Destroy() End Sub Public Function GetUnloadOption(ByVal dummy As String) As Integer Return Session.LibraryUnloadOption.Immediately End Function End Module Public Class NXJ_Assembly_info #Region "Private Variables" Private Const Version As String = "0.2.0" Private _theSession As Session = Session.GetSession() Private _theUfSession As UFSession = UFSession.GetUFSession Private _components As New List(Of Assemblies.Component) Private _uniqueParts As New List(Of Part) Private _allComponents As New List(Of Assemblies.Component) Private _allUniqueParts As New List(Of Part) Private _notLoaded As New List(Of String) Private lg As LogFile = _theSession.LogFile #End Region #Region "Properties" Private _isTCRunning As Boolean Public ReadOnly Property IsTCRunning() As Boolean Get Return _isTCRunning End Get End Property Private _thePart As Part = Nothing Public Property Part() As Part Get Return _thePart End Get Set(ByVal value As Part) _thePart = value 'Me.GetInfo() Me.GetAllInfo() End Set End Property Public ReadOnly Property AllComponents() As List(Of Component) Get Return _allComponents End Get End Property Public ReadOnly Property AllUniqueParts() As List(Of Part) Get Return _allUniqueParts End Get End Property Public ReadOnly Property Components As List(Of Component) Get Return _components End Get End Property Public ReadOnly Property UniqueParts As List(Of Part) Get Return _uniqueParts End Get End Property Public ReadOnly Property NotLoaded As List(Of String) Get Return _notLoaded End Get End Property #End Region Public Sub New() lg.WriteLine("") lg.WriteLine("~ NXJournaling.com: NXJ_Assembly_info object created ~") lg.WriteLine(" ~~ Version: " & Version & " ~~") lg.WriteLine(" ~~ Timestamp of run: " & DateTime.Now.ToString & " ~~") lg.WriteLine("NXJ_Assembly_info Sub New()") 'determine if we are running under TC or native _theUfSession.UF.IsUgmanagerActive(_isTCRunning) lg.WriteLine("IsTcRunning: " & _isTCRunning.ToString) lg.WriteLine("exiting Sub New") lg.WriteLine("") End Sub Private Sub GetAllInfo() 'get all component info from assembly (all levels) lg.WriteLine("Sub GetAllInfo()") Try Dim c As ComponentAssembly = Part.ComponentAssembly If Not IsNothing(c.RootComponent) Then '*** insert code to process 'root component' (assembly file) lg.WriteLine(" part has components") '*** end of code to process root component lg.WriteLine(" calling GetAllComponentChildren") GetAllComponentChildren(c.RootComponent) Else '*** insert code to process piece part, part has no components lg.WriteLine(" part has no components") End If Catch ex As NXException lg.WriteLine("Sub GetAllInfo error: " & ex.ErrorCode) lg.WriteLine(" " & ex.Message) End Try lg.WriteLine("exiting Sub GetAllInfo()") End Sub Private Sub GetAllComponentChildren(ByVal comp As Component) For Each child As Component In comp.GetChildren() lg.WriteLine(child.DisplayName) '*** insert code to process component or subassembly If Me.LoadComponent(child) Then _allComponents.Add(child) Dim tempPart As Part = child.Prototype.OwningPart If Not _allUniqueParts.Contains(tempPart) Then _allUniqueParts.Add(tempPart) End If Else 'component could not be loaded End If '*** end of code to process component or subassembly If child.GetChildren.Length <> 0 Then '*** this is a subassembly, add code specific to subassemblies '*** end of code to process subassembly Else 'this component has no children (it is a leaf node) 'add any code specific to bottom level components End If Me.GetAllComponentChildren(child) Next End Sub Private Sub GetInfo() 'get top level component info from assembly (no recursion) lg.WriteLine("Sub GetInfo()") Try Dim c As ComponentAssembly = Part.ComponentAssembly If Not IsNothing(c.RootComponent) Then '*** insert code to process 'root component' (assembly file) lg.WriteLine(" part has components") '*** end of code to process root component lg.WriteLine(" calling GetComponentChildren") Me.GetComponentChildren(c.RootComponent) Else '*** insert code to process piece part, part has no components lg.WriteLine(" part has no components") End If Catch ex As NXException lg.WriteLine("Sub GetInfo error: " & ex.ErrorCode) lg.WriteLine(" " & ex.Message) End Try lg.WriteLine("exiting GetInfo()") End Sub Private Sub GetComponentChildren(ByVal comp As Component) For Each child As Component In comp.GetChildren() '*** insert code to process component or subassembly _components.Add(child) Dim tempPart As Part = child.Prototype.OwningPart If Not _uniqueParts.Contains(tempPart) Then _uniqueParts.Add(tempPart) End If '*** end of code to process component or subassembly If child.GetChildren.Length <> 0 Then '*** this is a subassembly, add code specific to subassemblies '*** end of code to process subassembly Else 'this component has no children (it is a leaf node) 'add any code specific to bottom level components End If Next End Sub Private Function LoadComponent(ByVal theComponent As Component) As Boolean lg.WriteLine("Sub LoadComponent()") Dim thePart As Part = theComponent.Prototype.OwningPart Dim partName As String = "" Dim refsetName As String = "" Dim instanceName As String = "" Dim origin(2) As Double Dim csysMatrix(8) As Double Dim transform(3, 3) As Double Dim curLoadOptions As UFAssem.Options _theUfSession.Assem.AskAssemOptions(curLoadOptions) Dim newLoadOptions As UFAssem.Options _theUfSession.Assem.AskAssemOptions(newLoadOptions) newLoadOptions.load_options = UFConstants.UF_ASSEM_load_as_saved _theUfSession.Assem.SetAssemOptions(newLoadOptions) Try If thePart.IsFullyLoaded Then 'component is fully loaded lg.WriteLine(" component: " & theComponent.DisplayName & " is already fully loaded") Else 'component is partially loaded lg.WriteLine(" component: " & theComponent.DisplayName & " is already partially loaded") lg.WriteLine(" attempting to fully load the part file") thePart.LoadThisPartFully() End If lg.WriteLine(" return: True") lg.WriteLine("exiting Sub LoadComponent()") lg.WriteLine("") Return True Catch ex As NullReferenceException 'component is not loaded Try lg.WriteLine(" component not loaded, retrieving part information") _theUfSession.Assem.AskComponentData(theComponent.Tag, partName, refsetName, instanceName, origin, csysMatrix, transform) lg.WriteLine(" component part file: " & partName) Dim theLoadStatus As PartLoadStatus _theSession.Parts.Open(partName, theLoadStatus) If theLoadStatus.NumberUnloadedParts > 0 Then If theLoadStatus.NumberUnloadedParts > 1 Then lg.WriteLine(" problem loading " & theLoadStatus.NumberUnloadedParts.ToString & " components") Else lg.WriteLine(" problem loading 1 component") End If Dim allReadOnly As Boolean = True For i As Integer = 0 To theLoadStatus.NumberUnloadedParts - 1 lg.WriteLine("part name: " & theLoadStatus.GetPartName(i)) lg.WriteLine("part status: " & theLoadStatus.GetStatus(i)) If theLoadStatus.GetStatus(i) = 641058 Then 'read-only warning, file loaded ok Else '641044: file not found allReadOnly = False If Not _notLoaded.Contains(partName) Then _notLoaded.Add(partName) End If End If lg.WriteLine("status description: " & theLoadStatus.GetStatusDescription(i)) lg.WriteLine("") Next If allReadOnly Then lg.WriteLine(" 'read-only' warnings only") lg.WriteLine(" return: True") Return True Else 'warnings other than read-only... lg.WriteLine(" return: False") lg.WriteLine("exiting Sub LoadComponent()") lg.WriteLine("") Return False End If Else lg.WriteLine(" component(s) loaded successfully") lg.WriteLine(" return: True") lg.WriteLine("exiting Sub LoadComponent()") lg.WriteLine("") Return True End If Catch ex2 As NXException lg.WriteLine(" Load error: " & ex2.Message) lg.WriteLine(" error code: " & ex2.ErrorCode) lg.WriteLine(" return: False") lg.WriteLine("exiting Sub LoadComponent()") lg.WriteLine("") If ex2.Message.ToLower = "file not found" Then If Not _notLoaded.Contains(partName) Then _notLoaded.Add(partName) End If End If Return False End Try Catch ex As NXException 'unexpected error lg.WriteLine(" Error in Sub LoadComponent: " & ex.Message) lg.WriteLine(" return: False") lg.WriteLine("exiting Sub LoadComponent()") lg.WriteLine("") Return False Finally 'Reset assembly load option to the user's preference. _theUfSession.Assem.SetAssemOptions(curLoadOptions) End Try End Function End Classwww.nxjournaling.com
RE: AskBoundingBox Function
One quick question, is there a way to archive each component as it goes through the loop so it doesn't run the journal for each instance of a component? I have added a prompt to ask if the part is round if two of the bounding box dimensions are equal, and this code makes me answer the redundant question as many times as the component is in the assembly. Maybe this is a quick solution to archive the temp.Prototype.OwningPart and then skip it when it's seen again in the journal, or is there a way for a journal to recognize an overall dimension as round/round stock?
RE: AskBoundingBox Function
www.nxjournaling.com
RE: AskBoundingBox Function
I tried to run this in an assembly and it just displays the Reference and XYZ dimensions
Is it possible to add a solid bounding box around each part it in the assembly level, without going into each part and crate the box individually
Thanks!
RE: AskBoundingBox Function
This coding is something I would like to learn more about, I think it could be a huge time savings for our department, what would you recommend in terms of a good path for learning VB and the NX specifics? Does Siemens ever have classes on this?
RE: AskBoundingBox Function
Here's some code that I found on this forum in my searches that I think does at least close to what you want to do.
CODE --> Code
'June 16, 2015 ' Update to process instance bodies in the current display part (the assembly) ' instead of looping through the solid bodies in each component. ' Option Strict Off Imports System Imports System.Collections.Generic Imports NXOpen Imports NXOpen.UF Imports NXOpen.Assemblies Module Module2 Dim theSession As Session = Session.GetSession() Dim ufs As UFSession = UFSession.GetUFSession() Dim workPart As Part = theSession.Parts.Work Dim lw As ListingWindow = theSession.ListingWindow Dim theUfSession As UFSession = UFSession.GetUFSession() Dim theUISession As UI = UI.GetUI Dim response As Integer Sub Main() If IsNothing(theSession.Parts.BaseWork) Then 'active part required Return End If Dim workPart As Part = theSession.Parts.Work Dim displayPart As Part = theSession.Parts.Display Dim lw As ListingWindow = theSession.ListingWindow lw.Open() Const undoMarkName As String = "NXJ journal" Dim markId1 As Session.UndoMarkId markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName) Dim theAttributes() As NXObject.AttributeInformation theAttributes = displayPart.GetUserAttributes lw.Open() Dim myMeasure As MeasureManager = theSession.Parts.Display.MeasureManager() Dim massUnits(4) As Unit massUnits(0) = theSession.Parts.Display.UnitCollection.GetBase("Area") massUnits(1) = theSession.Parts.Display.UnitCollection.GetBase("Volume") massUnits(2) = theSession.Parts.Display.UnitCollection.GetBase("Mass") massUnits(3) = theSession.Parts.Display.UnitCollection.GetBase("Length") Dim theBodies As New List(Of Body) Dim row as integer theBodies = AskAllBodies(theSession.Parts.Display) Dim MdlPrt As String Dim c As ComponentAssembly = workPart.ComponentAssembly Dim rootDispName As String = (c.RootComponent.DisplayName).Replace("/", "_") For Each tempBody As Body In theBodies 'Dim partName As String 'Dim refSetName As String Dim instanceName As String 'Dim origin(2) As Double 'Dim csysMatrix(8) As Double 'Dim transform(3, 3) As Double Dim YG as String Dim XG as String Dim ZG as String Dim parentTag As Tag theUfSession.Assem.AskParentComponent(tempBody.Tag, parentTag) 'theUfSession.Assem.AskComponentData(parentTag, partName, refSetName, instanceName, origin, csysMatrix, transform) Dim bodyComp As Component = Utilities.NXObjectManager.Get(parentTag) lw.WriteLine("") MdlPrt = instanceName lw.WriteLine(MdlPrt) lw.WriteLine("") 'lengths returned in part units Dim bodyLengths(2) As Double bodyLengths = GetBoundingBox(tempBody) lw.WriteLine("Extents") lw.WriteLine("") lw.WriteLine("X length: " & bodyLengths(0).ToString) lw.WriteLine("Y length: " & bodyLengths(1).ToString) lw.WriteLine("Z length: " & bodyLengths(2).ToString) 'Measures Min/Max of all model parts in assembly Dim bbox(5) as double Dim tagList(0) As NXOpen.Tag ufs.Modl.AskBoundingBox(tempBody.Tag,bbox) lw.WriteLine("Mininum and Maximum Extents") lw.WriteLine("") lw.WriteLine("min X: " & bbox(0) & " max X: " & bbox(3)) lw.WriteLine("min Y: " & bbox(1) & " max Y: " & bbox(4)) lw.WriteLine("min Z: " & bbox(2) & " max Z: " & bbox(5)) 'lw.WriteLine("X dim: " & bbox(3) - bbox(0)) 'lw.WriteLine("Y dim: " & bbox(4) - bbox(1)) 'lw.WriteLine("Z dim: " & bbox(5) - bbox(2)) row += 1 Next End Sub Function AskAllBodies(ByVal thePart As Part) As List(Of Body) Dim theBodies As New List(Of Body) Dim aBodyTag As Tag = Tag.Null Do theUfSession.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 theUfSession.Obj.AskTypeAndSubtype(aBodyTag, theType, theSubtype) If theSubtype = UFConstants.UF_solid_body_subtype Then theBodies.Add(Utilities.NXObjectManager.Get(aBodyTag)) End If Loop While True Return theBodies End Function Private Function GetBoundingBox(ByVal solidBody As NXOpen.Body) As Double() 'AskBoundingBox returns min and max coordinates 'this function will simply return the box lengths (x, y, z) Dim bboxCoordinates(5) As Double Dim bboxLengths(2) As Double Try 'get solid body bounding box extents theUFSession.Modl.AskBoundingBox(solidBody.Tag, bboxCoordinates) bboxLengths(0) = bboxCoordinates(3) - bboxCoordinates(0) bboxLengths(1) = bboxCoordinates(4) - bboxCoordinates(1) bboxLengths(2) = bboxCoordinates(5) - bboxCoordinates(2) Return bboxLengths Catch ex As NXException MsgBox(ex.GetType.ToString & " : " & ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "Solid Body Bounds Error!") bboxLengths(0) = 0 bboxLengths(1) = 0 bboxLengths(2) = 0 Return bboxLengths End Try End Function Public Function GetUnloadOption(ByVal dummy As String) As Integer 'Unloads the image when the NX session terminates GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination End Function End Module