Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

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

Journal to assign material, and a body colour

Status
Not open for further replies.

moog3

Marine/Ocean
Nov 29, 2022
63
Hi NX'ers.
I'd like to assign material and body colour, from a journal dropdown list.
Can someone share some code that will help me to achieve this.
I found a closed thread that mentions a journal with what i'm after.
Toost states that he has done this.

I appreciate any help..
 
Replies continue below

Recommended for you

I wrote a GRIP program that did that years ago (maybe 20). I might still have a copy of it (the source code), but I'd have to search for it. Perhaps someone else may still have a copy (if GRIP still works).

John R. Baker, P.E. (ret)
Irvine, CA
Siemens PLM:

The secret of life is not finding someone to live with
It's finding someone you can't live without
 
John,
Thanks, we have a grip program, but it doesn't use the "assign materials" it just changes the density of all bodies, and their colour.. Is yours the same as that?
I'd like to do it with the materials data base feature
 
Yea, that sounds like what my program did. If you have the source code, there should be details in the header section about the program, including who wrote it and when. I think it was written before we had the materials database.

John R. Baker, P.E. (ret)
Irvine, CA
Siemens PLM:

The secret of life is not finding someone to live with
It's finding someone you can't live without
 
I have the source code, but there are none of your notes, but the guy who compiled it could easily have removed them...
 
Hey, I just saw your post and request. I actually shared this a week ago on NXJournaling and GitHub. I explored the same path you mentioned, and even went a bit further. You might be interested in the EW_Material line. For an improved solution, consider the NX_Material line, as it turns out you can assign the proper material to a solid body via journals. Let me know if anything is unclear.
Link
 
WOW, this is SOOoo good, exactly what I'm after (& more), thanks for sharing such great work with the NX community.
 
lj1970 I was not able to get to this page. Is there any other way you can help with sharing the code? This seems to be something Iam looking for too
 
Yes, sorry, I moved the repo and forgot to update this post.
here's the new link to Github:
Link
and on NXJournaling as before:
Link
I hope you find them useful.
 
And the codes for the two different approach (I forgot, how annoying it is to leave the site):

The simple one - I named it to EasyWeight Material Journal
Changes body color, layer and translucency, sets a density value, measures volume, calculates weight, and attributes it: EW_Body_Weight, EW_Material_Density and EW_Material:

Code:
' Written by TW
' Journal desciption: Changes body color, layer and translucency, sets a density value, measures volume, calculates weight, and attributes it: EW_Body_Weight, EW_Material_Density and EW_Material.
' Shared on NXJournaling.com
' Written in VB.Net
' Tested on Siemens NX 2212 and 2306, Native and Teamcenter 13
' V100 - Initial Release - November 2023
' V101 - Unit system support and Configuration Settings

Imports System
Imports NXOpen
Imports System.Collections.Generic
Imports NXOpen.UF

Module NXJournal
    Dim theSession As Session
    Dim theUFSession As UFSession
    Dim workPart As Part
    Dim displayPart As Part
    Dim mySelectedObjects As New List(Of DisplayableObject)
    Dim theUI As UI
    Dim bodyWeight As Double

    '------------------------
    ' Configuration Settings:

    ' Material Name - Change this name to your own material
    Dim materialname As String = "Stainless Steel"

    ' Material Density - Kg/m3 or Pound/Cubic Foot - Change this value to your own specific density
    Dim density As Double = 2700

    ' Unit System - "kg" for Kilograms or "lbm" for Pounds.
    Dim unitsystem As String = "kg"

    ' Body Settings:
    Dim bodycolor As Double = 130 ' Set the solid body color to ID: 130
    Dim bodylayer As Double = 1 ' Set the solid body to layer 1
    Dim bodytranslucency As Double = 0 ' Set the solid body transparency to 0

    '------------------------


    Sub Main(ByVal args() As String)
        Try
            theSession = Session.GetSession()
            theUFSession = UFSession.GetUFSession()
            workPart = theSession.Parts.Work
            displayPart = theSession.Parts.Display
            theUI = UI.GetUI()

            Dim markId1 As Session.UndoMarkId = Nothing
            markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Material Journal")

            If SelectObjects("Hey, select multiple somethings", mySelectedObjects) = Selection.Response.Ok Then
                For Each tempComp As Body In mySelectedObjects
                    Dim displayModification1 As DisplayModification
                    displayModification1 = theSession.DisplayManager.NewDisplayModification()

                    With displayModification1
                        .ApplyToAllFaces = False
                        .ApplyToOwningParts = True
                        .NewColor = bodycolor
                        .NewLayer = bodylayer
                        .NewTranslucency = bodytranslucency
                        .Apply({tempComp})
                    End With

                    displayModification1.Dispose()

                    'DeleteAllAttributes(tempComp)
                    AddBodyAttribute(tempComp, "EW_Material", materialname)

                    Dim attributePropertiesBuilder1 As AttributePropertiesBuilder
                    attributePropertiesBuilder1 = theSession.AttributeManager.CreateAttributePropertiesBuilder(workPart, {tempComp}, AttributePropertiesBuilder.OperationType.None)
                    attributePropertiesBuilder1.Title = "EW_Material_Density"
                    attributePropertiesBuilder1.DataType = NXOpen.AttributePropertiesBaseBuilder.DataTypeOptions.Number

                    If unitsystem = "kg" Then
                        attributePropertiesBuilder1.Units = "KilogramPerCubicMeter"
                    Else
                        attributePropertiesBuilder1.Units = "PoundMassPerCubicFoot"
                    End If

                    attributePropertiesBuilder1.NumberValue = density

                    AddBodyAttribute(tempComp, "Component_created", String.Empty)

                    Dim nXObject1 As NXObject
                    nXObject1 = attributePropertiesBuilder1.Commit()
                    attributePropertiesBuilder1.Destroy()

                    ' Calculate volume using mass properties
                    Dim myMeasure As MeasureManager = workPart.MeasureManager()
                    Dim massUnits(4) As Unit
                    massUnits(1) = workPart.UnitCollection.GetBase("Volume")
                    Dim mb As MeasureBodies = myMeasure.NewMassProperties(massUnits, 0.99, {tempComp})

                    ' Create or update an attribute named 'SS_Body_Weight' and assign the weight value to it
                    Dim attributePropertiesBuilderForWeight As AttributePropertiesBuilder
                    attributePropertiesBuilderForWeight = theSession.AttributeManager.CreateAttributePropertiesBuilder(workPart, {tempComp}, AttributePropertiesBuilder.OperationType.Create)

                    If unitsystem = "kg" Then
                        mb.InformationUnit = MeasureBodies.AnalysisUnit.KilogramMilliMeter
                        ' Extract volume and multiply it by density to get weight
                        Dim bodyVolume As Double = mb.Volume
                        bodyWeight = bodyVolume / 1000000000.0 * density
                        attributePropertiesBuilderForWeight.Units = "Kilogram"
                    Else
                        mb.InformationUnit = MeasureBodies.AnalysisUnit.PoundInch
                        Dim bodyVolume As Double = mb.Volume
                        bodyWeight = bodyVolume / 1728 * density
                        attributePropertiesBuilderForWeight.Units = "Lbm"
                    End If

                    attributePropertiesBuilderForWeight.Title = "EW_Body_Weight"
                    attributePropertiesBuilderForWeight.DataType = AttributePropertiesBaseBuilder.DataTypeOptions.Number
                    attributePropertiesBuilderForWeight.NumberValue = bodyWeight
                    Dim attributeObjectForWeight As NXObject = attributePropertiesBuilderForWeight.Commit()
                    attributePropertiesBuilderForWeight.Destroy()
                Next
            End If
        Catch ex As Exception
            Console.WriteLine("Houston, we have a situation... an error occurred: " & ex.Message)
        End Try
    End Sub

    Function SelectObjects(prompt As String,
                           ByRef dispObj As List(Of DisplayableObject)) As Selection.Response
        Dim selObj As NXObject()
        Dim title As String = ("Select solid bodies - " & materialname)
        Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart
        Dim selectionMask_array(0) As Selection.MaskTriple

        With selectionMask_array(0)
            .Type = UFConstants.UF_solid_type
            .SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectObjects(prompt,
            title, scope, selAction,
            includeFeatures, keepHighlighted, selectionMask_array,
            selObj)

        If resp = Selection.Response.ObjectSelected Or
                resp = Selection.Response.ObjectSelectedByName Or
                resp = Selection.Response.Ok Then
            For Each item As NXObject In selObj
                dispObj.Add(CType(item, DisplayableObject))
            Next
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If
    End Function

    Sub AddBodyAttribute(ByVal theBody As Body, ByVal attTitle As String, ByVal attValue As String)
        Dim attributePropertiesBuilder1 As AttributePropertiesBuilder
        attributePropertiesBuilder1 = theSession.AttributeManager.CreateAttributePropertiesBuilder(workPart, {theBody}, AttributePropertiesBuilder.OperationType.None)

        attributePropertiesBuilder1.IsArray = False
        attributePropertiesBuilder1.DataType = AttributePropertiesBaseBuilder.DataTypeOptions.String

        attributePropertiesBuilder1.Title = attTitle
        attributePropertiesBuilder1.StringValue = attValue

        Dim nXObject1 As NXObject
        nXObject1 = attributePropertiesBuilder1.Commit()

        attributePropertiesBuilder1.Destroy()
    End Sub

    Sub DeleteAllAttributes(ByVal theObject As NXObject)
        Dim attributeInfo() As NXObject.AttributeInformation = theObject.GetUserAttributes()

        For Each temp As NXObject.AttributeInformation In attributeInfo
            theObject.DeleteUserAttributes(temp.Type, Update.Option.Now)
        Next
    End Sub

    Public Function GetUnloadOption(ByVal dummy As String) As Integer
        GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
    End Function
End Module

And the proper one - NXWeight Material Journal
Changes body color, layer and translucency, and sets a NX's built in material.

Code:
' Written by TW
' Journal desciption: Changes body color, layer and translucency, and sets a NX's built in material.
' Shared on NXJournaling.com
' Written in VB.Net
' Tested on Siemens NX 2212 and 2306, Native and Teamcenter 13
' V100 - Initial Release - November 2023
' V101 - Code cleanup to focus mainly on NX's built in material and added Configuration Settings

Imports System
Imports NXOpen
Imports System.Collections.Generic
Imports NXOpen.UF

Module NXJournal
    Dim theSession As Session
    Dim theUFSession As UFSession
    Dim workPart As Part
    Dim displayPart As Part
    Dim mySelectedObjects As New List(Of DisplayableObject)
	Dim physicalMaterial1 As PhysicalMaterial = Nothing
	Dim theUI As UI


	'------------------------
	' Configuration Settings:

	' Material Name - This name has to match with your created material in your library
	Dim materialName As String = "Stainless Steel" 

	' Material Library Path
	Dim materialLibraryPath As String = "C:\Your Folder\To your material library\physicalmateriallibrary_custom.xml"

	' Body Settings:
	Dim bodycolor As Double = 130 ' Set the solid body color to ID: 130
	Dim bodylayer As Double = 1 ' Set the solid body to layer 1
	Dim bodytranslucency As Double = 0 ' Set the solid body transparency to 0
	'------------------------


	Sub Main(ByVal args() As String)

		Try
			theSession = Session.GetSession()
			theUFSession = UFSession.GetUFSession()
			workPart = theSession.Parts.Work
			displayPart = theSession.Parts.Display
			theUI = UI.GetUI()
			Dim lw As ListingWindow = theSession.ListingWindow
			lw.Open()

			Dim markId1 As Session.UndoMarkId = Nothing
			markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Material Journal")

			' Initialize the builders
			Dim physicalMaterialListBuilder1 As NXOpen.PhysMat.PhysicalMaterialListBuilder = Nothing
			Dim physicalMaterialAssignBuilder1 As NXOpen.PhysMat.PhysicalMaterialAssignBuilder = Nothing
			physicalMaterialListBuilder1 = workPart.MaterialManager.PhysicalMaterials.CreateListBlockBuilder()
			physicalMaterialAssignBuilder1 = workPart.MaterialManager.PhysicalMaterials.CreateMaterialAssignBuilder()
			Dim materialLibraryLoaded As Boolean = False
			Try
				' Check if the material is already loaded
				Dim loadedMaterial As NXOpen.Material = workPart.MaterialManager.PhysicalMaterials.GetLoadedLibraryMaterial(materialLibraryPath, materialName)
				If loadedMaterial Is Nothing Then
					' Material is not loaded, load it from the library
					physicalMaterial1 = workPart.MaterialManager.PhysicalMaterials.LoadFromMatmlLibrary(materialLibraryPath, materialName)
					materialLibraryLoaded = True
					'lw.WriteLine("Material library loaded.")
				Else
					physicalMaterial1 = loadedMaterial
					materialLibraryLoaded = True
					'lw.WriteLine("Material already loaded.")
				End If
			Catch ex As Exception
				'lw.WriteLine("Failed to check/load material library: " & ex.Message)
			End Try

			If SelectObjects("Hey, select multiple somethings", mySelectedObjects) = Selection.Response.Ok Then
				For Each tempComp As Body In mySelectedObjects
					Try
						Dim pmaterialname as String = ("PhysicalMaterial[" & materialName & "]")
						Dim physicalMaterial1 As NXOpen.PhysicalMaterial = CType(workPart.MaterialManager.PhysicalMaterials.FindObject(pmaterialname), NXOpen.PhysicalMaterial)
						If physicalMaterial1 Is Nothing Then
							lw.WriteLine("Error: Material " & materialName & " not found.")
							Return
						End If

						Dim displayModification1 As DisplayModification
						displayModification1 = theSession.DisplayManager.NewDisplayModification()

						With displayModification1
							.ApplyToAllFaces = False
							.ApplyToOwningParts = True
							.NewColor = bodycolor
							.NewLayer = bodylayer 
							.NewTranslucency = bodytranslucency 
							.Apply({tempComp})
						End With

						displayModification1.Dispose()

						AddBodyAttribute(tempComp, "Component_created", String.Empty)

						If physicalMaterial1 IsNot Nothing Then
							physicalMaterial1.AssignObjects(New NXOpen.NXObject() {tempComp})
							'lw.WriteLine("Material " & materialName & " successfully assigned to body: " & tempComp.JournalIdentifier)
						Else
							lw.WriteLine("Error: Material " & materialName & " not found in the material library.")
						End If
					Catch ex As Exception
						lw.WriteLine("Error processing body: " & tempComp.JournalIdentifier & " - " & ex.Message)
						lw.WriteLine("Exception occurred: " & ex.ToString())
					End Try
				Next
				theSession.UpdateManager.DoUpdate(markId1)
			Else
				lw.WriteLine("No objects were selected.")
			End If

			If physicalMaterialAssignBuilder1 IsNot Nothing Then
				physicalMaterialAssignBuilder1.Destroy()
				physicalMaterialAssignBuilder1 = Nothing
			End If

			If physicalMaterialListBuilder1 IsNot Nothing Then
				physicalMaterialListBuilder1.Destroy()
				physicalMaterialListBuilder1 = Nothing
			End If
		Catch ex As Exception
			Console.WriteLine("Houston, we have a situation... an error occurred: " & ex.Message)
		Finally
			If physicalMaterial1 IsNot Nothing Then
				physicalMaterial1 = Nothing
			End If
        End Try
    End Sub

    Function SelectObjects(prompt As String,
                           ByRef dispObj As List(Of DisplayableObject)) As Selection.Response
        Dim selObj As NXObject()
		Dim title As String = ("Select solid bodies - " & materialName)
		Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart
        Dim selectionMask_array(0) As Selection.MaskTriple

        With selectionMask_array(0)
            .Type = UFConstants.UF_solid_type
            .SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectObjects(prompt,
            title, scope, selAction,
            includeFeatures, keepHighlighted, selectionMask_array,
            selObj)

        If resp = Selection.Response.ObjectSelected Or
                resp = Selection.Response.ObjectSelectedByName Or
                resp = Selection.Response.Ok Then
            For Each item As NXObject In selObj
                dispObj.Add(CType(item, DisplayableObject))
            Next
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If
    End Function

	Sub AddBodyAttribute(ByVal theBody As Body, ByVal attTitle As String, ByVal attValue As String)
		Dim attributePropertiesBuilder1 As AttributePropertiesBuilder
		attributePropertiesBuilder1 = theSession.AttributeManager.CreateAttributePropertiesBuilder(workPart, {theBody}, AttributePropertiesBuilder.OperationType.None)

		attributePropertiesBuilder1.IsArray = False
		attributePropertiesBuilder1.DataType = AttributePropertiesBaseBuilder.DataTypeOptions.String

		attributePropertiesBuilder1.Title = attTitle
		attributePropertiesBuilder1.StringValue = attValue

		Dim nXObject1 As NXObject
		nXObject1 = attributePropertiesBuilder1.Commit()

		attributePropertiesBuilder1.Destroy()
	End Sub

    Public Function GetUnloadOption(ByVal dummy As String) As Integer
        GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
    End Function
End Module
 
I keep getting " No object found with this name" error. When I run the journal

Error processing body: BLOCK(0) - No object found with this name
Exception occurred: NXOpen.NXException: No object found with this name
at NXOpen.PhysicalMaterialCollection.FindObject(String journalIdentifier)
at NXJournal.Main(String[] args) in
 
Tutorial for the Material Journals

Which should you use - EasyWeight Material Journal or NXWeight Material Journal?

It's important to understand that the Easyweight project originated from a straightforward concept: circumventing NX's limitations when using it without a material license, allowing for body modifications and the assignment of a material name. As the project evolved, I discovered that it was also possible to assign built-in materials, presenting you with two options. Ideally, I should deprecate the first one, but I've chosen to keep it because it represents the original concept — and I love its simple and elegant solution to such limitations. The choice is ultimately yours, but I encourage you to develop your own built-in material library and use the second - associative - option.

Your mentioned error occurs in the NXWeight Material Journal when trying to load the material library: the specified MatML file is not found.

1. Warm-up exercise:
To create and edit journals, I recommend using Notepad++. Remember to save the files with a .vb extension.

Change Line 74 - Remove the ' (Apostrophe) before lw.WriteLine, so the error message will be visible to you next time. ( I forgot to remove it and now I can't edit the post...[glasses])

It should look like this:
lw.WriteLine("Failed to check/load material library: " & ex.Message)

2. Search for "How to Create new UG NX Material Library" on the Internet (YouTube) and create your own library.
Remember where you saved the .xml file.

3. Create your own color system in NX
Go to Menu / Preferences / Color Palette and hover your mouse over any color to reveal its ID number.

4. Create one journal for each material you wish to use
Save as and edit. Where you see these lines at the beginning of the journal, fill up with your data.

Code:
'------------------------
' Configuration Settings:

' Material Name - This name has to match with your created material in your library
Dim materialName As String = "12mm Plywood" 

' Material Library Path
Dim materialLibraryPath As String = "C:\Your Folder\To your material library\physicalmateriallibrary_custom.xml"

' Body Settings:
Dim bodycolor As Double = 111 ' Set the solid body color to ID: 111
Dim bodylayer As Double = 1 ' Set the solid body to layer 1
Dim bodytranslucency As Double = 0 ' Set the solid body transparency to 0
'------------------------

5. Create custom buttons in your ribbon
I recommend creating icons as well, using the same colors, for visual feedback. You could also create a dropdown list (an idea from moog3 - looks neat if you have many).

Here’s what mine looks like:

MyEWSetup_wvxnvc.png


And that's all. I hope this helps.
Happy coding!
 
I wonder if you can help me to edit one of the journals in this package.
I like the component creator, but i've been trying to remove the "-PANEL" from the end of the parts created.
Thanks..
 
I've had success modifying the code, but I'm wondering if ONE more change is possible.
I've managed to remove the "-PANEL" and changed the 101, to 001.
what I'd like to do is, change the scope of the wave link selection to "ENTIRE ASSEMBLY"
My files are such that I need to create SUB assemblies, each with
assy-nav-1_c4cbl6.jpg
"created components" in them (for the 2 material types).
My parametric (PRM) file has all the panels, of different materials, I need to add sub assemblies(which I've done) then make THEM the work part, and use the "component creator" to link DOWN from that _PRM file.
therefore the scope needs to be set to "entire assembly"
Once I finish the assembly, I suppress the _PRM file, so its invisible from upper levels of the assembly.
Could someone please help me to achieve this..
assy-1_w66wpd.jpg
 
If you haven't found the solution yet, look here:
NXJournaling - Adding An Interactive Selection Routine Using SelectObject(...) And SelectObjects(...):
Link

But in short, change the SelectObjects function at the end of the journal. Look for the following line (I haven't checked, but it should work with Wavelink):

Code:
Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart

Code:
Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly

Another solution would be to create the components and simply drag and drop them where you need.
As long as:

Dim wlMakePositionIndependent As Boolean = True
(WaveLink - Make Context-independent - the linked component maintains its associativity after the move)
is set, you are good to go regarding your request. Just double-check their location relative to the original design orientation.

I will make a little tutorial soon about solid body names and how you can set them so the journal can create proper components, but I think we should drive this conversation back to its respective sub where I shared my code:

Other than that, great job editing the journal! I hope this helps with the issue you were trying to achieve.
 
Thanks for the reply Tamas, this looks like just what I need, i'll give it a go implementing it, if it works, i'll share it back to the other thread you just linked
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor