Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations pierreick on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

AskBoundingBox Function

Status
Not open for further replies.

junfanbl

Marine/Ocean
Jun 10, 2015
90
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?

 
Replies continue below

Recommended for you

I was curious if you ever figured out how to use AskBoundingBox? I have a need almost identical to yours.
Regards,
Scott
 
There's a .NET file in the GTAC library called "show assembly and all component body bounding boxes", I guess it will do most of what you're looking for.
 
Try this code as well.

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








 
This Journal find has been beneficial, but there is one change I would like to make.
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
 
You can try searching this forum and Siemens forum, the bounding box has been discussed a few times.
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
 
Thanks Toost, I'll do some more searching using those specific recommendations. I've searched these forums, and google initially to find the three journals I am using to try to accomplish my three desired goals: 1) Get bounding information for all my assembly components, 2) Sort the bounding dims from smallest to largest, 3) Output these sorted bounding dims as attributes for each given component. My biggest problem is I'm a very novice programmer, and that knowledge is 7 years old, unused, and in C++.....

I'll keep searching, thanks again.
 
If you ask Cowski very friendly, he will help :)

Regards,
Tomas
 
Ha, anybody know how to get ahold of Cowski? I can ask nicely.
 
Here's a UDO that creates a Bounding Box. It also adds PMI dimensions to the bounding box.

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

 
cowski:
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):
BOM_ve3rto.gif

'******************************************
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
 
BBow said:
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?

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
 
Yeah there is only one body in the component. I have attached a screenshot below, showing the part navigator tree, the part, and the properties/attributes of the file.
MatlMissing_sg8aig.gif
 
I got a chance to work on this a bit today. This version should process all the components in the currently displayed assembly; it measures the first body it finds in the used reference set and adds the bounding dimensions as part attributes. For best results, fully load the assembly. The journal will attempt to fully load the components, if it cannot find a file at the last saved location it will get skipped.

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 Class

www.nxjournaling.com
 
Thanks a lot cowski the journal works great! I have taken some of the new functionality I have been working on and got it merged together with the code you provided.

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?
 
cowski,

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!

 
Works great. Much appreciated!
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?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor