Return Physical Material Usage

Does anyone know of a method to determine if a PhysicalMaterial is used in the current part?

I have
Dim LocalMaterials() As PhysicalMaterial = displaypart.MaterialManager.PhysicalMaterials.GetUsedMaterials

but this return materials that are used in components as well as displayPart. The Manage Materials windows differentiates between used, un-used, and used in components. I just can't seem to locate a method to get this information.

This may not be the best or only way to do this, but here's what I came up with. It will report the materials available (locally) in the work part, it reports the material assigned to each body, and it reports which available materials are not used in the part. If you want to query an assembly, you could modify the code to process each component and report the used/unused materials in the full assembly.

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

Module Module2

Sub Main()

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()
If IsNothing(theSession.Parts.BaseWork) Then
'active part required
Return
End If

Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()

Const undoMarkName As String = "report material usage"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim materialsInPart As New List(Of PhysicalMaterial)
Dim unusedMaterialsInPart As New List(Of String)

For Each tempMaterial As PhysicalMaterial In workPart.MaterialManager.PhysicalMaterials.GetUsedMaterials
materialsInPart.Add(tempMaterial)
unusedMaterialsInPart.Add(tempMaterial.Name)
Next

lw.WriteLine("Materials available in part")
For Each temp As PhysicalMaterial In materialsInPart
lw.WriteLine(temp.Name)
Next
lw.WriteLine("")

lw.WriteLine("Bodies in part")
For Each tempBody As Body In workPart.Bodies

lw.WriteLine("body tag: " & tempBody.Tag.ToString)

If tempBody.HasUserAttribute("Material", NXObject.AttributeType.String, -1) Then
'body has a material assigned, remove it from the "unused" list
Dim materialAttribute As NXObject.AttributeInformation
materialAttribute = tempBody.GetUserAttribute("Material", NXObject.AttributeType.String, -1)
unusedMaterialsInPart.Remove(materialAttribute.StringValue)

lw.WriteLine("material assigned: " & materialAttribute.StringValue)

Else
lw.WriteLine("no material assigned")
End If

lw.WriteLine("")

Next
lw.WriteLine("")

lw.WriteLine("Unused materials")
For Each temp As String In unusedMaterialsInPart
lw.WriteLine(temp)
Next

lw.Close()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image immediately after execution within NX
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

End Function

End Module

I did a similar approach to this as well. The problem I had run into is if the same material is used in both the part and the component there is not a way to differentiate between the materials in order to only delete(or reuse) the one in this part.

Hello NX Journaling,
I have tried using your above code to show the list of materials used and unused. As a test case i assigned three different materials one after the other and after running the macro it displayed the three available materials in the part and also displays all three materials as unused material. i want to create a macro which would delete the unused materials.

Balaji