In the NXOpen API, the "part" object is among the most used and most useful to the programmer. The part object gives us access to dozens (hundreds?) of properties and collections of other objects that we can use to query and modify the part. Let's take a look at the NXOpen.Feature object and the {part}.Features collection.
The feature tree in the part navigator will be immediately familiar if you have been using NX to create models for any length of time. The order of the features in the navigator act as an algorithm for creating the current model that you see in the graphics window. Scroll through the part navigator, and you can quickly tell which feature is current, which features are suppressed, and which features have update errors (hopefully none!). Expanding the "dependencies" window will give quick access to the selected feature's parent feauture(s) and any dependent features. The NXOpen part object gives us similar access to the part's features through our program. The part navigator lists all of the features in the current model; the part's .Features collection is analogous to the part navigator, it is a container for the individual feature objects that make up the model.
The code below shows how to access the features collection and process each feature object that it contains.
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() For Each partFeature As Features.Feature In workPart.Features lw.WriteLine("feature name: " & partFeature.GetFeatureName) lw.WriteLine("feature type: " & partFeature.GetType.ToString) lw.WriteLine("") 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
Ok, so the code above isn't all that exciting. There are, however, a few interesting aspects that may not be immediately obvious. First, depending on the features used in your current work part, the journal output may list more features than what you see in the part navigator; furthermore, multiple features may report the same timestamp. If you did not experience this with your current part and would like to see it for yourself, try the following: create a block feature then start the hole command, select a large face of the block to sketch on and pick multiple points on the face for the hole locations. Now run the journal again. In the part navigator you will see the block and hole commands, but in the journal output, in addition to the block and hole, you will also see a sketch feature and instead of a single hole feature, there will be multiple hole features. So what's going on here? An error in the journal code? or worse, a bug in the API? Actually, neither. Here the curtain starts to part and we begin to see the inner workings of NX. Some features can be internal to other features. In this case, the sketch feature and the individual hole features are wrapped up and presented to the user as a single feature in the part navigator. This behavior helps the user by keeping the feature tree concise, but we now know that each of these items is a feature in its own right.
The second item of note about the journal code above is not about feature objects or even the NXOpen API, but about programming in general; specifically it is about object oriented programming (OOP). Take another look at the For loop variable "partFeature"; you will notice that it is declared as type "Features.Feature", yet none of the reported features were of the type "Features.Feature". In the journal output, each feature was reported as a specific type such as .Features.Block or Features.HolePackage. How did we process these specific feature types if we didn't declare our variable as the proper type? If you look up the Feature object type in the NXOpen API reference, you will see that it is described as an "abstract" class. Dozens of specific feature types are shown as deriving from the Feature class. If you are familiar with OOP, the Feature class is a "superclass" or "base class". The Feature class defines all of the properties and methods that will be common to all feature types. Specific feature objects, such as a hole feature, will automatically "inherit" all of the properties and methods defined in the "Feature" class. These specific feature types, also known as "subclasses" or "child classes", may use these properties and methods differently and the subclass will often add new properties and/or methods that are specific to the subclass. Any subclass object can be treated as if it were of the superclass type. What this means for us is that every specific feature type (subclass) can be treated as if it were of type Features.Feature (superclass); any calls to properties or methods that are defined in the superclass will work on the subclass objects. This gives us access to a variety of useful properties and methods without needing to know the specific feature type.
Iterating through the part features and querying each feature's properties is a good way to learn more about specific features. Once you know the .FeatureType, you can look it up in the API reference to see what specific properties and methods the feature type supports. This knowledge better equips you to write useful and robust code to handle the feature type. When learning about a new feature, the first thing that I do is create a file that uses the feature and run the journal code below:
Option Strict Off Imports System Imports NXOpen Imports NXOpen.UF Imports NXOpen.Features Module Module2 Sub Main() Dim theSession As Session = Session.GetSession() Dim theUfSession As UFSession = UFSession.GetUFSession Dim lw As ListingWindow = theSession.ListingWindow lw.Open() lw.WriteLine("*** All Features ***") For Each myFeature As Feature In theSession.Parts.Work.Features lw.WriteLine(".GetFeatureName: " & myFeature.GetFeatureName) lw.WriteLine(".Name: " & myFeature.Name) lw.WriteLine(".IsInternal: " & myFeature.IsInternal.ToString) lw.WriteLine(".FeatureType: " & myFeature.FeatureType) lw.WriteLine(".GetType: " & myFeature.GetType.ToString) lw.WriteLine(".Timestamp: " & myFeature.Timestamp.ToString) lw.WriteLine(".Suppressed: " & myFeature.Suppressed.ToString) Try lw.WriteLine(".Location: " & myFeature.Location.ToString) Catch ex As NXException End Try lw.WriteLine("") Next lw.Close() End Sub End Module
The call to the .Location property is wrapped in a Try block; this is because even though .Location is defined in the .Feature superclass, not all feature types make use of it. For those features that do not make use of it, the .Location property will be empty and trying to access its value will throw an error.
Conclusion
Have a look at the API reference for the Feature object type. There are many more interesting properties and methods that this article did not touch on. You should now have a better idea of how to use the feature collection and how to interrogate the individual features.

Comments
Collection of solid bodies in the whole assembly
Is there a way to collect all solids in the assembly (at each level).
I want to create a journal that will mirror the whole assembly as (Mirrored Body Wavelink) with all solids included, regardless if they are inside a part or the assembly.
For solids collection (.Bodies) I need to reference the Part.
Component.OwningPart doesnt seem to work for me...
re: get bodies in assembly
The code below demonstrates the easiest method that I have found so far to get all the bodies from a given assembly.