How to retrieve material name of part/body in assembly

Hi All,

I would like to get material name from part or body or body(linked) in assembly.
First I tried to get it from attributes but it didn't lead anywhere. Attributes were empty probably due to company settings.

The best way would be to work with "User MatML Library" because I need more then material name, like thermal conductivity etc. Till now I have not got it work.

Using AskMaterialOfObject is not possible due to older NX version that I am using

So what i made so far is using "UF_SF_locate_material", see code below
UF_SF_locate_material

My problem is why it only works on linked bodies in assembly and not on the parts? If I select part then it generate error. If I run it in displayed part view then it is ok.

thanks for help

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports System.Collections
Imports System.Collections.Generic

Module RetrieveMat
Dim ui As UI = UI.GetUI()

Sub Main()
Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
Dim ufs As UFSession = UFSession.GetUFSession()

lw.Open()

Dim selectionMask() As Selection.MaskTriple = Nothing
BuildSelectionMask(selectionMask)
Dim prompt As String
Dim title As String

Dim myBodies() As TaggedObject = Nothing
prompt = "Select Bodies bodies"
title = "Select Bodies bodies"
If SelectObjects(selectionMask, myBodies, prompt, title) = Selection.Response.Cancel Then

Return

End If

lw.WriteLine("Number of bodies: " & myBodies.Length)

Dim MaterialTag As Tag
For Each tmpbody As Body In myBodies
lw.WriteLine("body: " & tmpbody.Tag)
ufs.Sf.LocateMaterial(tmpbody.Tag, MaterialTag)
Dim MaterialObject As Material
MaterialObject = theSession.GetObjectManager.GetTaggedObject(MaterialTag)
lw.WriteLine("Material Name: " & MaterialObject.Name)
Next

lw.Close()
End Sub
Sub BuildSelectionMask(ByRef maskArray() As Selection.MaskTriple)

Dim theSelectionMasks As New List(Of Selection.MaskTriple)
Dim newSelMask As Selection.MaskTriple
With newSelMask
.Type = UFConstants.UF_solid_type
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_BODY
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

theSelectionMasks.Add(newSelMask)
maskArray = theSelectionMasks.ToArray
End Sub
Function SelectObjects(ByVal selMask() As Selection.MaskTriple, ByRef selObj() As TaggedObject, ByVal prompt As String, ByVal title As String) As Selection.Response

Dim theUI As UI = UI.GetUI

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.AnyInAssembly
Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(
prompt, title, scope, selAction,
includeFeatures, keepHighlighted, selMask, selObj)

If resp = Selection.Response.Ok Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function

End Module

I needed something similar quite a few days ago and was able to accomplish it by fetching the prototype of an occurrence body. (I might be wrong in the terminologies as I am just getting started)

Option Strict Off
Imports NXOpen
Imports NXOpen.UF
Imports System.Collections.Generic

Module RetrieveMat

ReadOnly ui As UI = UI.GetUI()
Private ReadOnly theSession As Session = Session.GetSession()

Sub Main()
Dim workPart As Part = theSession.Parts.Work
Dim ufs As UFSession = UFSession.GetUFSession()

Dim selectionMask() As Selection.MaskTriple = Nothing
BuildSelectionMask(selectionMask)
Dim prompt As String
Dim title As String

Dim myBodies() As TaggedObject = Nothing
prompt = "Select Bodies bodies"
title = "Select Bodies bodies"
If SelectObjects(selectionMask, myBodies, prompt, title) = Selection.Response.Cancel Then

Return

End If

Echo("Number of bodies: " & myBodies.Length)

Dim MaterialTag As Tag

For Each tmpbody As Body In myBodies

Dim protoBody As Body

If tmpbody.IsOccurrence Then
EnsureLoaded(tmpbody)
protoBody = CType(tmpbody.Prototype, Body)
Echo(vbLf & "Body in " & protoBody.OwningPart.Leaf & " :")
Echo("body: " & protoBody.Tag)
Else
protoBody = tmpbody
Echo(vbLf & "Body in " & workPart.Leaf & " :")
Echo("body: " & protoBody.Tag)
End If

Try
ufs.Sf.LocateMaterial(protoBody.Tag, MaterialTag)
Catch __unusedNXException1__ As NXException
Echo(" Physical Material: not assigned")
Continue For
End Try

Dim theMaterial As PhysicalMaterial = CType(theSession.GetObjectManager().GetTaggedObject(MaterialTag), PhysicalMaterial)
Echo(" Physical Material: " & theMaterial.Name)

If Not theMaterial.IsNonlibraryMaterial() Then

If theMaterial.GetLibraryName().EndsWith(".dat") Then
Echo(" Referenced library: " & theMaterial.GetLibraryName())
Echo(" ! .dat legacy material library format is no longer supported!")
Continue For
End If

theMaterial.UpdateMaterialProperties()

End If

Next

End Sub

Private Sub ReportPartLoadStatus(ByVal load_status As PartLoadStatus)
If load_status.NumberUnloadedParts = 0 Then Return
Echo(" Load notes:")

For ii As Integer = 0 To load_status.NumberUnloadedParts - 1
Echo(" " & load_status.GetPartName(ii) & " - " + load_status.GetStatusDescription(ii))
Next
End Sub

Private Sub EnsureLoaded(ByVal theNXObject As NXObject)
If Not theNXObject.IsOccurrence Then Return
Dim option1 As Boolean
option1 = theSession.Parts.LoadOptions.UsePartialLoading
theSession.Parts.LoadOptions.UsePartialLoading = False
Dim componentsToOpen1 As NXOpen.Assemblies.Component() = {theNXObject.OwningComponent}
Dim openStatus1 As NXOpen.Assemblies.ComponentAssembly.OpenComponentStatus() = Nothing
Dim partLoadStatus1 As PartLoadStatus = theNXObject.OwningPart.ComponentAssembly.OpenComponents(NXOpen.Assemblies.ComponentAssembly.OpenOption.ComponentOnly, componentsToOpen1, openStatus1)
theSession.Parts.LoadOptions.UsePartialLoading = option1
ReportPartLoadStatus(partLoadStatus1)
End Sub

Private Sub BuildSelectionMask(ByRef maskArray() As Selection.MaskTriple)

Dim theSelectionMasks As New List(Of Selection.MaskTriple)
Dim newSelMask As Selection.MaskTriple
With newSelMask
.Type = UFConstants.UF_solid_type
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_BODY
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

theSelectionMasks.Add(newSelMask)
maskArray = theSelectionMasks.ToArray
End Sub

Private Function SelectObjects(ByVal selMask() As Selection.MaskTriple, ByRef selObj() As TaggedObject, ByVal prompt As String, ByVal title As String) As Selection.Response

Dim theUI As UI = UI.GetUI

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.AnyInAssembly
Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(
prompt, title, scope, selAction,
includeFeatures, keepHighlighted, selMask, selObj)

If resp = Selection.Response.Ok Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Private Sub Echo(ByVal output As String)
theSession.ListingWindow.Open()
theSession.ListingWindow.WriteLine(output)
theSession.LogFile.WriteLine(output)
End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function

End Module

Very good job, you saved me a lot of time! Thanks
Now I can extend the code for purpose that I originally needed, that means retrieve properties from NX material library.
So I added to your code an another piece of code from Cowski1.

Option Strict Off
Imports NXOpen
Imports NXOpen.UF
Imports System.Collections.Generic
Imports System

Module RetrieveMat

ReadOnly ui As UI = UI.GetUI()
Private ReadOnly theSession As Session = Session.GetSession()

Sub Main()
Dim lw As ListingWindow = theSession.ListingWindow
Dim workPart As Part = theSession.Parts.Work
Dim ufs As UFSession = UFSession.GetUFSession()

Dim selectionMask() As Selection.MaskTriple = Nothing
BuildSelectionMask(selectionMask)
Dim prompt As String
Dim title As String

Dim myBodies() As TaggedObject = Nothing
prompt = "Select Bodies"
title = "Select Bodies"
If SelectObjects(selectionMask, myBodies, prompt, title) = Selection.Response.Cancel Then

Return

End If

Echo("Number of bodies: " & myBodies.Length)

Dim MaterialTag As Tag

For Each tmpbody As Body In myBodies

Dim protoBody As Body

If tmpbody.IsOccurrence Then
EnsureLoaded(tmpbody)
protoBody = CType(tmpbody.Prototype, Body)
Echo(vbLf & "Body in " & protoBody.OwningPart.Leaf & " :")
Echo("body: " & protoBody.Tag)
Else
protoBody = tmpbody
Echo(vbLf & "Body in " & workPart.Leaf & " :")
Echo("body: " & protoBody.JournalIdentifier)
End If

Try
ufs.Sf.LocateMaterial(protoBody.Tag, MaterialTag)
Catch __unusedNXException1__ As NXException
Echo(" Physical Material: not assigned")
Continue For
End Try

Dim theMaterial As PhysicalMaterial = CType(theSession.GetObjectManager().GetTaggedObject(MaterialTag), PhysicalMaterial)
Echo("Physical Material: " & theMaterial.Name)

If Not theMaterial.IsNonlibraryMaterial() Then

If theMaterial.GetLibraryName().EndsWith(".dat") Then
Echo(" Referenced library: " & theMaterial.GetLibraryName())
Echo(" ! .dat legacy material library format is no longer supported!")
Continue For
End If

theMaterial.UpdateMaterialProperties()

End If
'------------------- starts Cowski1's code ------------------'

Dim theChosenMaterial As PhysicalMaterial = Nothing
'use material if it is loaded
theChosenMaterial = workPart.MaterialManager.PhysicalMaterials.GetLoadedLibraryMaterial("physicalmateriallibrary.xml", theMaterial.Name)

If IsNothing(theChosenMaterial) Then
'load material from library
theChosenMaterial = workPart.MaterialManager.PhysicalMaterials.LoadFromNxmatmllibrary(theMaterial.Name)
End If

If IsNothing(theChosenMaterial) Then
lw.WriteLine("material not found in NX material library")
Return
End If

Dim propTable As BasePropertyTable = theChosenMaterial.GetPropTable
Dim youngsModProp As Fields.ScalarFieldWrapper = propTable.GetScalarFieldWrapperPropertyValue("YoungsModulus")
Dim ymExp As Expression = youngsModProp.GetExpression

Try
Dim ymExpVal As Double = ymExp.Value
Dim ymExpAbb As String = ymExp.Units.Symbol 'ymExp.Units.Abbreviation(older)
Catch ex_ymExpVal1 As NullReferenceException

Echo("Young's Modulus: Empty")
Continue For
End Try

lw.WriteLine("Young's Modulus: " & ymExp.Value & " " & ymExp.Units.Symbol)

Dim poissonRatio As Fields.ScalarFieldWrapper = propTable.GetScalarFieldWrapperPropertyValue("PoissonsRatio")
Dim poissonExp As Expression = poissonRatio.GetExpression

Try
Dim poissonVal As Double = poissonExp.Value
Catch ex_poissonVal As NullReferenceException
Echo("poissonExp: Empty")
Continue For
End Try

lw.WriteLine("poissonExp: " & poissonExp.Value)

'------------------- ends Cowski1's code ------------------'
Next

End Sub

Private Sub ReportPartLoadStatus(ByVal load_status As PartLoadStatus)
If load_status.NumberUnloadedParts = 0 Then Return
Echo("Load notes:")

For ii As Integer = 0 To load_status.NumberUnloadedParts - 1
Echo(" " & load_status.GetPartName(ii) & " - " + load_status.GetStatusDescription(ii))
Next
End Sub

Private Sub EnsureLoaded(ByVal theNXObject As NXObject)
If Not theNXObject.IsOccurrence Then Return
Dim option1 As Boolean
option1 = theSession.Parts.LoadOptions.UsePartialLoading
theSession.Parts.LoadOptions.UsePartialLoading = False
Dim componentsToOpen1 As NXOpen.Assemblies.Component() = {theNXObject.OwningComponent}
Dim openStatus1 As NXOpen.Assemblies.ComponentAssembly.OpenComponentStatus() = Nothing
Dim partLoadStatus1 As PartLoadStatus = theNXObject.OwningPart.ComponentAssembly.OpenComponents(NXOpen.Assemblies.ComponentAssembly.OpenOption.ComponentOnly, componentsToOpen1, openStatus1)
theSession.Parts.LoadOptions.UsePartialLoading = option1
ReportPartLoadStatus(partLoadStatus1)
End Sub

Private Sub BuildSelectionMask(ByRef maskArray() As Selection.MaskTriple)

Dim theSelectionMasks As New List(Of Selection.MaskTriple)
Dim newSelMask As Selection.MaskTriple
With newSelMask
.Type = UFConstants.UF_solid_type
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_BODY
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

theSelectionMasks.Add(newSelMask)
maskArray = theSelectionMasks.ToArray
End Sub

Private Function SelectObjects(ByVal selMask() As Selection.MaskTriple, ByRef selObj() As TaggedObject, ByVal prompt As String, ByVal title As String) As Selection.Response

Dim theUI As UI = UI.GetUI

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.AnyInAssembly
Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(
prompt, title, scope, selAction,
includeFeatures, keepHighlighted, selMask, selObj)

If resp = Selection.Response.Ok Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Private Sub Echo(ByVal output As String)
theSession.ListingWindow.Open()
theSession.ListingWindow.WriteLine(output)
theSession.LogFile.WriteLine(output)
End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function

End Module