ppeterx
Industrial
- Jul 18, 2018
- 2
Hello,
i found following journal from Cowski on this forum. Im using NX 10.0.3.5 MP14. Its exactly what i want (it measures all parts in assembly and dimensions write in parts attribute), but in some cases dimensions isnt correct. Can someone give me a clue where is problem with this journal? Many thanks for your answers.
i found following journal from Cowski on this forum. Im using NX 10.0.3.5 MP14. Its exactly what i want (it measures all parts in assembly and dimensions write in parts attribute), but in some cases dimensions isnt correct. Can someone give me a clue where is problem with this journal? Many thanks for your answers.
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, "X", compBodyDims.Item(0).ToString)
PartStringAttribute(temp.Prototype.OwningPart, "Y", compBodyDims.Item(1).ToString)
PartStringAttribute(temp.Prototype.OwningPart, "Z", 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 X As Double
Dim Y As Double
Dim Z 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)
X = bbox(3) - bbox(0)
Y = bbox(4) - bbox(1)
Z = bbox(5) - bbox(2)
boundingDims.Add(X)
boundingDims.Add(Y)
boundingDims.Add(Z)
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