Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

NX11 MASS Attribute best practices 1

Status
Not open for further replies.

LindaB

Mechanical
Jul 30, 2021
1
0
0
GB
Hi,

I wish to show the mass of the part model on the drawing and the material also.

I've created a model and saved it. I've already checked "Customer Defaults -> Gateway -> Material/Mass -> Attributes" and checked the "Mass Property Attributes" have been toggled ON (they're ON by default).

There are a series of "Mass Property Attributes" including "MassPropMass", MassPropWeight" and "MassPropDensity". I believe "MassPropMass" is the Mass of the part model.

I've then created a "note" on the drawing as have successfully 'pulled through' the attributes for PART NAME, PART NUMBER, DRAWING SCALE, etc).

However, I cant seem to get the part mass and part material to appear, despite having - what I believe to be - the correct attribute name. Perhaps I'm using the correct attribute name, but am not entering it correctly with 'special characters/syntax'? i.e WRef2*0@, "$" or x0.3 etc etc.

I'm new to NX btw!

Many thanks in advance!

LindaB
 
Replies continue below

Recommended for you

Hello,

I think if You want to show mass on drawing You have two options:
- measure body and check associative, then parameter will be available in expressions
- or create custom attribute and assign mass to it by journal.

First option is difficult to use, because on each part mass value will have different name for example in part one it will be p11 and on part 2 it will be p23, so You will have to manually choose what You want.

Below is journal to calculate mass and write attribute mass_prt to file, it's work on assembly only.

Code:
Option Strict Off
 
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports System.Collections.Generic

Public class PList1

	Public Property Part_Name As String
	Public Property Mass_prt As String
	Public Property Density As String


	Public Sub New(ByVal PartN As String, 
			ByVal MassPRT As String, 
			ByVal DENPRT As String)

	
	Part_Name = PartN
	Mass_prt = MassPRT
	Density = DENPRT

	End Sub

End Class

Module NXJournal
 
    Public theSession As Session = Session.GetSession()
    Public ufs As UFSession = UFSession.GetUFSession()
    Public lw As ListingWindow = theSession.ListingWindow
		
    Dim blnCancel As Boolean = False	

    Dim PName1 as String
    Dim PName as String			
    Dim TextLength as String
	Dim PartList1 as New list (of PList1)
	Dim List1 as New List (of String)

    Sub Main()

    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
	

    Dim rev as String = nothing 	 	
    Dim rev1 as String = nothing	

    lw.open()

	PName = workPart.Leaf
	TextLength = PName.Length
	

	Dim Mass_prt as String = nothing
	Dim mass as String = nothing	
	Dim mass1 as Double	= nothing
	Dim mass2 as Double = nothing
	Dim mass3 as String = nothing
	Dim Density As Double = 0

	

						

    Try

        Dim c As ComponentAssembly = dispPart.ComponentAssembly

        if not IsNothing(c.RootComponent) then
      
			lw.writeline("1) Empty run")

            ReportComponentChildren(c.RootComponent, 0)

			lw.writeline("2) Setting mass")

            ReportComponentChildren1(c.RootComponent, 0)

			lw.writeline("3) End")	
	   
        end if

    Catch e As Exception

        theSession.ListingWindow.WriteLine("Failed: " & e.ToString)

    End Try

		if Not IsNothing(Partlist1) AndAlso Partlist1.Count > 0 Then
		
		'Partlist.sort(Function(x, y) x.part_name.CompareTo(y.Part_name))

		partlist1.sort(AddressOf Comparer)	

		lw.writeline(" ")
		lw.writeline("**********************************************")
		lw.writeline("Parts with set mass and density:      ")
		lw.writeline("**********************************************")
		lw.writeline(" ")
		lw.writeline("----------------------------------------------")
		lw.writeline("| Part name | Mass [kg] | Density [kg/m3] |")
		lw.writeline("----------------------------------------------")
		lw.writeline(" ")
		
		Dim i as integer = 1
		
		for each Part as PList1 in Partlist1
		
			lw.writeline(i & " ) " & Part.Part_Name & " | " & Part.Mass_prt & " | " & Part.Density ) 
			i += 1		
		next	
		
	end if
	
    lw.Close()
 
    End Sub
 
'*****************************************************************************************
' Empty run
'*****************************************************************************************
Sub reportComponentChildren( ByVal comp As Component, ByVal indent As Integer)
	Dim workPart As Part = theSession.Parts.Work
	Dim dispPart As Part = theSession.Parts.Display


	For Each child As Component In comp.GetChildren()

		Dim MyPart As Part = child.Prototype.OwningPart

	Try

		if child.IsSuppressed = true then

			lw.writeline("   Error: " & child.DisplayName & ".prt" & " -> " & "Part closed")
			Continue for
			
		end if
		
			Catch e1 As Exception
			theSession.ListingWindow.WriteLine("Failed: " & e1.ToString)
			
	end try

	
	 If LoadComponent(child) Then	
	    		        

   		
	 Else

                'component could not be loaded

	end if 

            reportComponentChildren(child, indent+1)
       
        Next
		
    End Sub

'*****************************************************************************************
' Setting mass
'*****************************************************************************************
Sub reportComponentChildren1( ByVal comp As Component, ByVal indent As Integer)

    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
    Dim iBodies(0) As IBody

				
	For Each child As Component In comp.GetChildren()

		Dim MyPart As Part = child.Prototype.OwningPart

	Try

		if child.IsSuppressed = true then

			Continue for
			
		end if
		
		Catch e11 As Exception
			theSession.ListingWindow.WriteLine("Failed: " & e11.ToString)
			
	end try

	
	If LoadComponent(child) Then
	 		
 	    PName = child.DisplayName()
	    TextLength = PName.Length


		Dim Mass_prt as String = nothing 
		Dim mass as String = nothing	
		Dim mass1 as Double	= nothing
		Dim mass2 as Double = nothing
		Dim mass3 as String	= nothing
		Dim Density As Double
	
		For each tempBody as Body in mypart.Bodies

			if tempBody.Layer = 1 then

				Dim mm As MeasureManager = myPart.MeasureManager()
	
				iBodies(0) = tempBody

				Dim Units(4) As Unit
				Units(0) = myPart.UnitCollection.GetBase("Area")
				Units(1) = myPart.UnitCollection.GetBase("Volume")
				Units(2) = myPart.UnitCollection.GetBase("Mass")
				Units(3) = myPart.UnitCollection.GetBase("Length")

				Dim mb As MeasureBodies = mm.NewMassProperties(Units, 0.99, iBodies)

				mass3 = Units(2).Abbreviation()

				if Double.TryParse(mb.Mass.ToString(), mass2) then

					mass = math.round(mass2, 3)			    
					'lw.writeline(mypart.leaf & " -> " & mass)

				end if

					mass1 = mass1 + mass

			end if

			'mass1 = mass1 + mass 				 
			ufs.Modl.AskBodyDensity(tempBody.tag, UFModl.DensityUnits.KilogramsMeters, Density)
					
					
		Next 

			Mass_prt = mass1 & " " & mass3	
			myPart.SetUserAttribute("Mass_prt", -1, Mass_prt, update.Option.now)
				
			if not list1.contains(child.name) then 
				
				list1.add(child.name)
				Partlist1.add(new PList1(child.name, Mass_prt, density))	

			end if	
				
	else

		myPart.SetUserAttribute("Mass_prt", -1, "-", update.Option.now)

	end if

		reportComponentChildren1(child, indent+1)    
     
	Next

End Sub

'**********************************************************
' FUNCTION LOADING COMPONENTS 
'**********************************************************

Private Function LoadComponent(ByVal theComponent As Component) As Boolean
 
	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
 
	Try
	
		If thePart.IsFullyLoaded Then
			
			'component is fully loaded
				
		Else
			
			'component is partially loaded
				
		End If
				
		Return True
			
		Catch ex As NullReferenceException
			
		'component is not loaded
			
		Try
			
			ufs.Assem.AskComponentData(theComponent.Tag, partName, refsetName, instanceName, origin, csysMatrix, transform)
 
			Dim theLoadStatus As PartLoadStatus
			theSession.Parts.Open(partName, theLoadStatus)
 
			If theLoadStatus.NumberUnloadedParts > 0 Then
 
				Dim allReadOnly As Boolean = True
				For i As Integer = 0 To theLoadStatus.NumberUnloadedParts - 1
					
				If theLoadStatus.GetStatus(i) = 641058 Then
					'read-only warning, file loaded ok
							
				Else
						
					'641044: file not found
					lw.WriteLine("File not found")
					allReadOnly = False
							
				End If
						
                Next
					
				If allReadOnly Then
					
					Return True
						
				Else
					
					'warnings other than read-only...
					Return False
						
				End If
					
			Else
				
				Return True
					
			End If
 
				Catch ex2 As NXException
				
				if ex2.message = "File not found" then 
				
					lw.WriteLine("Error: " & partname & "   " & "File not found")		
					
				else
				
					lw.WriteLine("Error: " & partname & "   " & ex2.Message)
					
				end if
				
					Return False
					
		End Try
			
			Catch ex As NXException
			
				'unexpected error
				lw.WriteLine("error: " & ex.Message)
				Return False
				
	End Try
 
End Function
	
'**********************************************************
' FUNCTION COMPARE COMPONENTS
'**********************************************************

Private Function Comparer(ByVal x As Plist1, ByVal y As Plist1) As Integer
	Dim result As Integer = x.Part_name.CompareTo(y.Part_name)

	If result = 0 Then
	
		result = x.Mass_prt.CompareTo(y.Mass_prt)
		
	End If

	Return result

End Function

'**********************************************************
Public Function GetUnloadOption(ByVal dummy As String) As Integer

	Return Session.LibraryUnloadOption.Immediately
	
End Function
'**********************************************************
 
End Module

With best regards
Michael
 
Hello Michael,

I am new here and I find the small program very good.
Is there also the possibility that this program writes the assembly weight or whether the weight can be written from the model to the drawing according to MasterModel principle?

Does anyone have a solution or a small tool for this?
That I can call from the Zeichnug and from there write a weight for a single part or an assembly?

That would be super.

Thanks now for any help.

Many greetings
Chris

 
Hello,

This journal create attribute in part called Mass_prt and You can call it on drawing. To do this You have to:
- create a note
- in note show symbols, then on category choose relationship
- then You have two options:
- part attribute - attribute from actual part, i.e nonmaster model part​
- object attribute - attribute from i.e. master model part, to get values You have to choose on assembly navigator interesting part​
- on next window You have to choose interesting attribute - Mass_prt and click ok
- in next window choose close

There is also option to get weight ->> file -> properties -> weight, but it required special license.

With best regards
Michael
 
Hello Michael,

and thank you for your answer.
That is also clear so far.
It would be nice if the journal would write a sum attribute from the assembly to the drawing.

Regards
Chris
 
Try this code:

Code:
Option Strict Off
 
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports System.Collections.Generic

Public class PList1

	Public Property Part_Name As String
	Public Property Mass_prt As String
	Public Property Density As String


	Public Sub New(ByVal PartN As String, 
			ByVal MassPRT As String, 
			ByVal DENPRT As String)

	
	Part_Name = PartN
	Mass_prt = MassPRT
	Density = DENPRT

	End Sub

End Class

Module NXJournal
 
    Public theSession As Session = Session.GetSession()
    Public ufs As UFSession = UFSession.GetUFSession()
    Public lw As ListingWindow = theSession.ListingWindow
		
    Dim blnCancel As Boolean = False	

    Dim PName1 as String
    Dim PName as String			
    Dim TextLength as String
	Dim PartList1 as New list (of PList1)
	Dim List1 as New List (of String)
	Dim Total_mass as String = nothing
	
    Sub Main()

    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
	

    Dim rev as String = nothing 	 	
    Dim rev1 as String = nothing	

    lw.open()

	PName = workPart.Leaf
	TextLength = PName.Length
	

	Dim Mass_prt as String = nothing
	
	Dim mass as String = nothing	
	Dim mass1 as Double	= nothing
	Dim mass2 as Double = nothing
	Dim mass3 as String = nothing
	Dim Density As Double = 0

	
    Try

        Dim c As ComponentAssembly = dispPart.ComponentAssembly

        if not IsNothing(c.RootComponent) then
      
			lw.writeline("1) Empty run")

            ReportComponentChildren(c.RootComponent, 0)

			lw.writeline("2) Setting mass")

            ReportComponentChildren1(c.RootComponent, 0)

			lw.writeline("3) End")	
	   
        end if

    Catch e As Exception

        theSession.ListingWindow.WriteLine("Failed: " & e.ToString)

    End Try

		if Not IsNothing(Partlist1) AndAlso Partlist1.Count > 0 Then
		
		'Partlist.sort(Function(x, y) x.part_name.CompareTo(y.Part_name))

		partlist1.sort(AddressOf Comparer)	

		lw.writeline(" ")
		lw.writeline("**********************************************")
		lw.writeline("Parts with set mass and density:      ")
		lw.writeline("**********************************************")
		lw.writeline(" ")
		lw.writeline("----------------------------------------------")
		lw.writeline("| Part name | Mass [kg] | Density [kg/m3] |")
		lw.writeline("----------------------------------------------")
		lw.writeline(" ")
		
		Dim i as integer = 1
		
		for each Part as PList1 in Partlist1
		
			lw.writeline(i & " ) " & Part.Part_Name & " | " & Part.Mass_prt & " | " & Part.Density ) 
			i += 1		
		next	
		
		lw.writeline(" ")
		lw.writeline("Total Mass = " & Total_mass)
		
	end if
	
    lw.Close()
 
    End Sub
 
'*****************************************************************************************
' Empty run
'*****************************************************************************************
Sub reportComponentChildren( ByVal comp As Component, ByVal indent As Integer)
	Dim workPart As Part = theSession.Parts.Work
	Dim dispPart As Part = theSession.Parts.Display


	For Each child As Component In comp.GetChildren()

		Dim MyPart As Part = child.Prototype.OwningPart

	Try

		if child.IsSuppressed = true then

			lw.writeline("   Error: " & child.DisplayName & ".prt" & " -> " & "Part closed")
			Continue for
			
		end if
		
			Catch e1 As Exception
			theSession.ListingWindow.WriteLine("Failed: " & e1.ToString)
			
	end try

	
	 If LoadComponent(child) Then	
	    		        

   		
	 Else

                'component could not be loaded

	end if 

            reportComponentChildren(child, indent+1)
       
        Next
		
    End Sub

'*****************************************************************************************
' Setting mass
'*****************************************************************************************
Sub reportComponentChildren1( ByVal comp As Component, ByVal indent As Integer)

    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
    Dim iBodies(0) As IBody

				
	For Each child As Component In comp.GetChildren()

		Dim MyPart As Part = child.Prototype.OwningPart

	Try

		if child.IsSuppressed = true then

			Continue for
			
		end if
		
		Catch e11 As Exception
			theSession.ListingWindow.WriteLine("Failed: " & e11.ToString)
			
	end try

	
	If LoadComponent(child) Then
	 		
 	    PName = child.DisplayName()
	    TextLength = PName.Length


		Dim Mass_prt as String = nothing 
		Dim mass as String = nothing	
		Dim mass1 as Double	= nothing
		Dim mass2 as Double = nothing
		Dim mass3 as String	= nothing
		Dim Density As Double
	
		For each tempBody as Body in mypart.Bodies

			if tempBody.Layer = 1 then

				Dim mm As MeasureManager = myPart.MeasureManager()
	
				iBodies(0) = tempBody

				Dim Units(4) As Unit
				Units(0) = myPart.UnitCollection.GetBase("Area")
				Units(1) = myPart.UnitCollection.GetBase("Volume")
				Units(2) = myPart.UnitCollection.GetBase("Mass")
				Units(3) = myPart.UnitCollection.GetBase("Length")

				Dim mb As MeasureBodies = mm.NewMassProperties(Units, 0.99, iBodies)

				mass3 = Units(2).Abbreviation()

				if Double.TryParse(mb.Mass.ToString(), mass2) then

					mass = math.round(mass2, 3)			    
					'lw.writeline(mypart.leaf & " -> " & mass)

				end if

					mass1 = mass1 + mass

			end if

			'mass1 = mass1 + mass 				 
			ufs.Modl.AskBodyDensity(tempBody.tag, UFModl.DensityUnits.KilogramsMeters, Density)
					
					
		Next 

			Mass_prt = mass1 & " " & mass3	
			Total_mass = Total_mass + mass1 
			myPart.SetUserAttribute("Mass_prt", -1, Mass_prt, update.Option.now)
				
			if not list1.contains(child.name) then 
				
				list1.add(child.name)
				Partlist1.add(new PList1(child.name, Mass_prt, density))	

			end if	
				
	else

		myPart.SetUserAttribute("Mass_prt", -1, "-", update.Option.now)

	end if

		reportComponentChildren1(child, indent+1)    
     
	Next

End Sub

'**********************************************************
' FUNCTION LOADING COMPONENTS 
'**********************************************************

Private Function LoadComponent(ByVal theComponent As Component) As Boolean
 
	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
 
	Try
	
		If thePart.IsFullyLoaded Then
			
			'component is fully loaded
				
		Else
			
			'component is partially loaded
				
		End If
				
		Return True
			
		Catch ex As NullReferenceException
			
		'component is not loaded
			
		Try
			
			ufs.Assem.AskComponentData(theComponent.Tag, partName, refsetName, instanceName, origin, csysMatrix, transform)
 
			Dim theLoadStatus As PartLoadStatus
			theSession.Parts.Open(partName, theLoadStatus)
 
			If theLoadStatus.NumberUnloadedParts > 0 Then
 
				Dim allReadOnly As Boolean = True
				For i As Integer = 0 To theLoadStatus.NumberUnloadedParts - 1
					
				If theLoadStatus.GetStatus(i) = 641058 Then
					'read-only warning, file loaded ok
							
				Else
						
					'641044: file not found
					lw.WriteLine("File not found")
					allReadOnly = False
							
				End If
						
                Next
					
				If allReadOnly Then
					
					Return True
						
				Else
					
					'warnings other than read-only...
					Return False
						
				End If
					
			Else
				
				Return True
					
			End If
 
				Catch ex2 As NXException
				
				if ex2.message = "File not found" then 
				
					lw.WriteLine("Error: " & partname & "   " & "File not found")		
					
				else
				
					lw.WriteLine("Error: " & partname & "   " & ex2.Message)
					
				end if
				
					Return False
					
		End Try
			
			Catch ex As NXException
			
				'unexpected error
				lw.WriteLine("error: " & ex.Message)
				Return False
				
	End Try
 
End Function
	
'**********************************************************
' FUNCTION COMPARE COMPONENTS
'**********************************************************

Private Function Comparer(ByVal x As Plist1, ByVal y As Plist1) As Integer
	Dim result As Integer = x.Part_name.CompareTo(y.Part_name)

	If result = 0 Then
	
		result = x.Mass_prt.CompareTo(y.Mass_prt)
		
	End If

	Return result

End Function

'**********************************************************
Public Function GetUnloadOption(ByVal dummy As String) As Integer

	Return Session.LibraryUnloadOption.Immediately
	
End Function
'**********************************************************
 
End Module

With best regards
Michael
 
Status
Not open for further replies.
Back
Top