|
![]() |
The 'find' functionality in Navisworks can be replicated (and further refined) using the Search method within the .NET API. Here we discuss the Search method and the classes involved.
PropertyCategory and PropertyCategoryCollection classes
The PropertyCategory class represents a group of properties, all of which have a common category. Instances of the class are found in ModelItem..::..PropertyCategories which is an instance of the collection class PropertyCategoryCollection.
DataProperty and DataPropertyCollection classes
The DataProperty class represents a named property, instances of which are found in PropertyCategory..::..Properties, which is itself an instance of DataPropertyCollection. DataProperty objects have several key properties:
-
DataProperty..::..Name – The internal name of the property (suitable for programmatic use)
-
DataProperty..::..DisplayName – The name suitable for display to the end user.
-
DataProperty..::..CombinedName – A combination of the DisplayName and the Name properties.
-
DataProperty..::..Value – An instance of the VariantData class which encapsulates the true value.
Search class
Search can be used to find ModelItems matching a set of criteria given by instances of the SearchCondition class. This controls the search.
SearchCondition class
SearchCondition is used to define conditions based on the PropertyCategorys of ModelItems to use in a search.
Using searches
To better illustrate searches, let's use an example where (using LINQ style notation) we search for the descendents of items in the Model that have ModelItem..::..Geometry.

//Select the items in the model that are contained in the collection
Autodesk.Navisworks.Api.Application.ActiveDocument.CurrentSelection.CopyFrom(
Autodesk.Navisworks.Api.Application.ActiveDocument.Models.RootItemDescendantsAndSelf.
Where(x => x.HasGeometry)
);
In this example, we are manually iterating over the items in the selection, this has the advantage that using LINQ style notation we can easily add extra tests to the existing 'ModelItem..::..HasGeometry' test. For example to add in an extra test for visible (not Hidden), the code above could be rewritten with an extra test.

Autodesk.Navisworks.Api.Application.ActiveDocument.CurrentSelection.CopyFrom( Autodesk.Navisworks.Api.Application.ActiveDocument.Models.RootItemDescendantsAndSelf. Where(x => (x.HasGeometry && !x.IsHidden)) );
However it will usually be slower than using the Search methods. Here is the same solution, using the Search method.

//Create a new search Search s = new Search(); //Add a search condition for ModelItems with Geometry only... s.SearchConditions.Add( SearchCondition.HasCategoryByName(PropertyCategoryNames.Geometry)); //...and not hidden s.SearchConditions.Add(SearchCondition.HasPropertyByName(PropertyCategoryNames.Item, DataPropertyNames.ItemHidden).EqualValue(VariantData.FromBoolean(false))); //set the selection to everything s.Selection.SelectAll(); s.Locations = SearchLocations.DescendantsAndSelf; //get the resulting collection by applying this search and apply it to the selection Autodesk.Navisworks.Api.Application.ActiveDocument.CurrentSelection.CopyFrom( s.FindAll(Autodesk.Navisworks.Api.Application.ActiveDocument, false));
This is not as pretty to look at as the previous examples. Given there are more lines of code, it could be assumed that this method would take longer to run. However, the search itself is achieved using the 'FindAll' method of the search class which is internal to the Navisworks API. This method will usually return faster than the LINQ style method from before which, eventually, works in an iterative manner over the selection. To see how much faster the Search class is, developers can try the SearchComparison plug-in which is included in the API samples. This sample performs the same search using 3 different methods and displays the time taken by each.