Understanding NX object and TaggedObject-what sort of object am I processing?

To all

I am "wrestling" with NXobject as part of expanding my vb (NX) programing skill. I am looking for a way of knowing what type of object an object is. For example I tested the following,

[Code]
For Each obj As TaggedObbject In theCAEGroup.GetEntities()
Try
Dim element As CAE.FEElement = CType(obj, CAE.FEElement)
If Not element Is Nothing Then iFEElemFound +=1
Catch
End Try
Next obj
[/Code]

which seems to work but out of pure interest I'd like to know what sort of object the variable 'obj' is. Is it possible to know that (without some fancy loop)?

Thanks
Regards
JXB

I'd suggest the use of the .GetType method along with the TypeOf function. The NXObject and TaggedObject types are fairly generic types defined by the NXOpen API that many (most?) of the NX objects derive from. If you look at the NXObject in the .net_ref.chm, you will see in the inheritance hierarchy that there are many sub-classes of NXObject (PMI, CAEgroup, Feature, Expression, Light, etc etc). The NXObject type only exists to help orgainze these other types; no object in your part file will be of type "NXObject", it must take one of the specific forms listed in the inheritance heirarchy. There are various ways that you can test for specific types; the easy way is to use the TypeOf() function. This function will allow you to test the type of an object against a known type.

This is probably best explained by an example. The code below will gather up all the objects on layer one of the current work part. It will then loop through the objects and report the type of each object it finds. It will write a unique line of text if it finds an object of type: NXOpen.Body.


Option Strict Off
Imports System
Imports NXOpen

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
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 = "NXJ journal"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim theObjects() As NXObject = workPart.Layers.GetAllObjectsOnLayer(1)

For Each obj As NXObject In theObjects
lw.WriteFullline("object type: " & obj.GetType.ToString)
If TypeOf (obj) Is NXOpen.Body Then
lw.WriteLine(" body object type found")
End If

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

Thanks for that NXJournaling. Very helpful and clear as usual

I have seen NXObject and the inheritance thing if the net_ref.chm and only had a vague idea/educated guess of what it meant.

I'll store the "For Each obj As NXObject In theObjects" loop for future use and I reckon it may become handy if I want to deal with the content of NX.CAE groups

Thanks
Regards
JXB

Thanks
Regards

In your particular case, the code might look like this:

For Each obj As TaggedObject In theCAEGroup.GetEntities()
If TypeOf (obj) Is CAE.FEElement Then
iFEElemFound += 1
End If
Next

I was in the middle of changing my function GetGroupElements() to test the Typeof() approach ! (I should really be doing something else but I couldn't help to have a quick go

Is there a reason to use Typeof() instead of trying to "force" a object using the Ctype. (speed, etc)?

Thanks

JXB

Thanks
Regards

TypeOf simply checks the object type, CType will try to convert the object type. I've not done any speed comparison testing, but I imagine the TypeOf will be faster than a CType operation wrapped in a Try block. Also, TypeOf seems more straightforward and appropriate to what you are attempting to accomplish.

There is also the TryCast operator, which is much like the "CType wrapped in a Try block" approach. For more details, see:
https://msdn.microsoft.com/en-us/library/zyy863x8.aspx
http://www.dotnetperls.com/trycast

Carried out a not too scientific test to compare CType() vs. of TypeOf ()

There is a slight improvement (~5%) with TypeOf () so will change code to use that syntax. It does look “neater” to read to!
I tested with more than 200,000 elements but in reality one will never have to create the results for some many elements (it would take hours of NX post-processing)

I have also noticed that when I initialise the GUI it can be a bit slow. I only display the “valid” groups to the user (valid = a group with at least 1 FE element)
I am currently using the same coding technic

Dim element As CAE.FEElement = CType(obj, CAE.FEElement)

so will change that too.

The test was to loop trough each object in the selected group
Test1A: Use of CType() with only element in the group
Dim theElement As CAE.FEElement = CType(obj, CAE.FEElement)
Nb of elm = 209142
T=17.79s

Test1B: Use of CType () with lot of stuff in the group (geo, elm and node)
If TypeOf (obj) Is CAE.FEElement
Nb of elm = 209142
T=207.85s
---------------------------------------------

Test2A: Use of TypeOf () with only element in the group
Nb of elm same as Test 1
T= 17.90s

Test2B: Use of TypeOf () with lot of stuff in the group (geo, elm and node)
Nb of elm same as Test 1

T= 197.98s (~5% faster than 1B)

Group Content for Test 2
Entity Type No. of entities
Elements : 209142
Nodes : 471156
Faces : 191
Bodies : 28
Meshes : 531

Thanks
Regards

Interesting findings!
Thanks for posting your results.

No problem. I'd take the numbers with some (a lot of!) caution as it was quick and dirty. Might not even be able to repeat the numbers! Did it out of intellectual interest.

Thanks
Regards

The NX/Open reference guides (like net_ref.chm) have the full story, but they can be overwhelming. For a simpler description of the NX object hierarchy, you can look at the "Getting Started with SNAP" guide. There's a chapter called "The Jump to NX Open" that talks about the object hierarchy.

What if you were to search for a type of feature say an extrude and wanted to report if that feature is not found?

You can iterate through the part's .Features collection looking for a particular feature type. The code below looks for extrude features. The code could be modified to take action based on the number of extrude features found.

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

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
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 extrude features"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim listExtrudes As New List(Of Features.Extrude)

For Each temp As Features.Feature In workPart.Features
If temp.FeatureType = "EXTRUDE" Then
If temp.IsInternal Then
'skip internal features
Continue For
Else
listExtrudes.Add(temp)
End If
End If
Next

lw.WriteLine(listExtrudes.Count.ToString & " Extrude features were found in the work part:")
For Each temp As Features.Extrude In listExtrudes
lw.WriteLine(" " & temp.GetFeatureName)
Next

lw.Close()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

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

End Function

End Module

Thanks for the start! My code is a little choppy but this works great:

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

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
If IsNothing(theSession.Parts.BaseWork) Then
Return
End If

Dim workPart As Part = theSession.Parts.Work

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

Dim listPATTERN As New List(Of Features.FlatPattern)

For Each tempFeature As Features.Feature In workPart.Features
If TypeOf (tempFeature) Is Features.FlatPattern Then
If tempFeature.IsInternal Then
Continue For
Else
listPATTERN.Add(tempFeature)
End If
End If
Next

if listPATTERN.count <1 then
msgbox("Hello, this part has no FLAT PATTERN to export!", MsgBoxStyle.Critical, "What the...?")
exit sub
else
if listPATTERN.count >0 then
For Each tempFeature As Features.Feature In workPart.Features
If TypeOf (tempFeature) Is Features.FlatPattern Then
ExportTrumpf(workPart.FullPath.Substring(0, workPart.FullPath.Length - 4) & ".geo", tempFeature)
msgbox("Exported: Trumpf GEO file to " & workPart.FullPath.Substring(0, workPart.FullPath.Length - 4), MsgBoxStyle.Information, "Finished")
Exit For
End If
Next
end if
end if

End Sub

Sub ExportTrumpf(ByVal exportFileName As String, ByVal flatPattern As Features.FlatPattern)

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim exportTrumpfBuilder1 As Features.SheetMetal.ExportTrumpfBuilder

exportTrumpfBuilder1 = Workpart.Features.SheetmetalManager.CreateExportTrumpfBuilder()

exportTrumpfBuilder1.OutputGeoFile = exportFileName

exportTrumpfBuilder1.InteriorCutout = True

exportTrumpfBuilder1.SelectFlatPattern.Value = flatPattern

Dim nXObject1 As NXObject
nXObject1 = exportTrumpfBuilder1.Commit()

exportTrumpfBuilder1.Destroy()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

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

End Function

End Module

Glad to help.

I got a good laugh from your message box:

msgbox("Hello, this part has no FLAT PATTERN to export!", MsgBoxStyle.Critical, "What the...?")

Keep those users on their toes!