Navisworks .NET API : Find Item

By Xiaodong Liang

In the post we introduce the properties of Navisworks objects. On the other hand, we often need to find objects by the properties. Finding items is a large part of the API. There are three main mechanisms.

  1. Iteration

This is the basic way to get the items you are concerned with. However, it has a time cost with lower efficiency.

// Filter the model items from the selected items
foreach (ModelItem oItem in oDoc.CurrentSelection.SelectedItems)   
{ 
//examine the item with property 'Entity Handle' 
// and 'Value' is '187E2' and has geometry
 if (oItem.HasGeometry &&
     oItem.PropertyCategories.FindPropertyByDisplayName
     ("Entity Handle",  "Value").Value.ToDisplayString() = 
                                  "187E2") 
   { 
         // found!
   }
}
  1. Search API

This corresponds to the Find Items functionality in Roamer. It is similar to the product functionality, but with further refined conditions. It is fast because it is happens in native code, but can only do what Roamer can do.

image

Selection:  is what to search (i.e. Where to look).

Conditions:  is what to find. A Condition is basically a test against an object property with quite flexible usage. It also has a few other options that are properties on the Search class.

The basic steps to use this API is as below:

// create a search class
Search search = new Search();
 
// add Selection and Conditions
// this code finds the item
// with Entity Handle >> value = "187E2"
search.Selection.SelectAll();
search.SearchConditions.Add(
SearchCondition.HasPropertyByDisplayName(
     "Entity Handle",
      "Value").EqualValue(VariantData.
       FromDisplayString("187E2")));
 
// Execute Search
ModelItemCollection items = search.FindAll(
        Application.ActiveDocument,false);
 
// highlight the items 
Application.ActiveDocument.CurrentSelection.
    CopyFrom(items);

We will introduce more usage of Search API in another blog.

  1. LINQ

LINQ (Language Integrated Query) is a high level use, which allows much expression. Please refer to MSDN for more details on LINQ.

// in whole model items, find the items that has geometry

IEnumerable items =   
                  from x in doc.Models.GetRootItems().
                      DescendantsAndSelf 
                  where x.HasGeometry   
                  select x; 
// highlight the items
doc.CurrentSelection.CopyFrom(items);

LINQ is slowest because it has to call back and forth between managed and native code. The Search API 'FindAll' method of the search class is internal to the Navisworks API and will usually return faster than the LINQ style method from before which, eventually, works in an iterative manner over the selection. One suggestion could be to use Search to select a subset of the model and then use LINQ to perform more sophisticated searches over the returned selection. e.g.

// assume we have had a search defined by Search API
 
// find the items which are more 
// expensive than 100, on the basis of a search result
// assume a function  'ItemPrice'to check the ‘?price’ˉ 
// information of the items
IEnumerable expensive_items =
   from item in search.FindAll(
       Application.ActiveDocument, false);
   where ItemPrice(item) > 100
   select item;

Comments

12 responses to “Navisworks .NET API : Find Item”

  1. Ricky Medley Avatar
    Ricky Medley

    No mention of SearchCondition.StartGroup(), which is imperative to users trying to replace LINQ funtionality. StartGroup() being the equivalent to an OR statement (compared to previously added SearchConditions. All statmements after StartGroup() are packed in the equivilant of AND’s, until another StartGroup is encountered.
    Only Autodesk documentation mentioning this of course is the API Reference Manual, but an example can be found in the api net examples…
    …/api/net/examples/Controls/Viewers/SearchSelect.cs

  2. Xiaodong Liang Avatar
    Xiaodong Liang

    In addition, StartGroup is a method of COM API, see this post
    http://adndevblog.typepad.com/aec/2012/06/group-a-series-of-operations.html
    While in .NET API, it is AddGroup, as shown in the two posts I enclosed in the last reply.

  3. Ricky Medley Avatar
    Ricky Medley

    No I didn’t see those. But now, anyone that comes across this post will have further reading.
    ;)
    Sincerely,

  4. Ricky Medley Avatar
    Ricky Medley

    I did not know StartGroup() was part of COM.
    Good to know since I’m try to avoid COM. Thank you for your quick replies.
    Sincerely,

  5. Hello Xiaodong Liang,
    Does your code could be applied for excel VBA ? For example, is it possible to do a search in naviswork with vba.
    My purpose is to open naviswork in a first step (I can do it) and in a second step to find an item via what you call “Find Items functionality in Roamer”.
    Best regards,
    Diego,

  6. Hi Diego,
    .net API cannot be used in vba which is COM based. Navisworks also provides COM API which has find ability. You can get started with it by the sdk sample actx_05(before 2013) which is written in vb6. From 2013 this sample is written in c#, but the basic principal is still same.
    In your case, you can either start a Navisworks instance by COM API, open model and use find API. Or embed an activex control in your app of excel vba, and use find API.
    Regards,
    Xiaodong

  7. Thank you for your answer.
    I have read about the sample “sdk sample actx_05” but I cannot find it. Do you have an Idea how could I get it? I’m pretty sure this could help me!
    By now, I know how to select everything, and how to change the background… However this is not going to help me!
    Sincerly,

  8. xiaodong Avatar
    xiaodong

    The ACTX_05 is available in the releases before 2013. You can still refer to the migrated sample in C# at
    C:\Program Files\Autodesk\Navisworks Manage 2013\api\COM\examples\ActiveX\ActiveXFindExample
    And here is one blog of Java script which may give you an idea how the code could be,if in an HTML
    http://adndevblog.typepad.com/aec/2012/05/search-compnents-in-javascript.html

  9. You are my hero. Once I recoded your example here in VBA, I learned lots – in fact I learned that “Item” (instead of Entity Name) means – don’t set a category at all. Your article revealed that.
    Here is a link for an example for anyone looking for “Item”->”Name”->”Value” and how, using VBA (or VBScript for that matter) to do that. It was all inspired by Xiaodong
    http://elbsolutions.com/projects/navisworks-com-api-a-little-old-and-really-cantakerous-but-i-finally-i-can-find-an-object-by-name/

  10. Xiaodong is quite correct. If you are ripping your hair out like I was, see my example below of a working VBA example and how you can figure out all sorts of custom finds as a result. This is the key article to unlocking how all the gears mesh together.

  11. Hi Xiaodong,
    How to find items with override tranparency of of particular value for e.g 0.7?
    And also tell me under wich property it is stored?
    In my NWD file have set override tranparency of an item to 0.7 but the
    property windows shows Transparency (LcOaMaterialTransparency):0.000 while
    Item Tools –> Transparency shows 70%.
    Thank you
    Regards,
    Antony

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading