Building a hierarchical view of instantiated element types

Building a hierarchical view of instantiated element types

Anonymous
Not applicable
424 Views
3 Replies
Message 1 of 4

Building a hierarchical view of instantiated element types

Anonymous
Not applicable

I have built a working hierarchical view, showing instantiated element types which look like this:

 

ndahlXUAG7_0-1621596688530.png

 

It uses top level categories and then their respective different lowest level linked types and finally the materials associated with the type.

My problem is that the solution is very very slow for larger models 😞

 

What is the fastest way to retrieve instantiated categories in the model via the Revit API? 

0 Likes
425 Views
3 Replies
Replies (3)
Message 2 of 4

jeremy_tammik
Alumni
Alumni

There are many ways to approach this task. In the end, you will presumably need to retrieve each individual BIM element that you wish to classify, plus whatever information you require for it, e.g., its category and material. So, my first suggestion would be to use a filtered element collector, request all non-element-type elements, and build your hierarchical tree view from that. Then, your performance will depend almost entirely on how effectively (or ineffectively) you work with that data.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 4

Anonymous
Not applicable

Thank you for your reply Jeremy.

I create a FilteredElementCollector as such:

 

FilteredElementCollector collector = new FilteredElementCollector(document)
    .WhereElementIsNotElementType()
    .WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_PreviewLegendComponents, true))
    .WherePasses(new (BuiltInCategory.OST_IOSSketchGrid, true))
    .WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Cameras, true));

 

Afterwards I try and get the relevant categories as such:

 

List<ElementId> categoryIds = new List<ElementId>();
Options opt = _document.Application.Create.NewGeometryOptions();

foreach (Element element in collector.ToElements())
{
    if (element.Category == null)
        continue;

    if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Rooms || 
        element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Areas || 
        element.get_Geometry(opt) != null)
    {
        if (!categoryIds.Contains(element.Category.Id))
        {
            categoryIds.Add(element.Category.Id);
        }
    }
}

 

My thought is that I might be able to speed up my program by excluding even more elements from the collector. 

The issue is that I am not sure how to specify the correct filters.

I am looking for elements that only has some kind of quantites.

0 Likes
Message 4 of 4

jeremy_tammik
Alumni
Alumni

This looks like a very good start.

 

Yes, you can probably speed things up a bit more, but maybe not very much.

 

For instance, you want to select all rooms and areas, regardless of their Geometry property.

 

In your current code, you are achieving this by post-processing the results of the filtered element collector using the subsequent for loop.

 

You could avoid that by adding some logical Boolean combinations to the original filtered element collector.

 

Here are some samples of different approaches to filter for elements in general and specifically model elements only, i.e., real physical BIM elements that have geometry and/or material quantities:

  

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.9

  

The MEP and structural examples show how you can use Boolean filters to create a combination of different criteria.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes