Model Elements Revisited

Scott Conover responded with a wealth of ideas to yesterday's model element selection discussion, which in turn has gone through numerous previous iterations, so this really seems like an endless theme.

Actually it is not even yesterday's, yet, it is still today's. We both wanted to fix it fast.

Here are Scott's comments and suggestions:

First, on the original solution:

  IList<Element> found
    = collector
      .WherePasses( new LogicalOrFilter(
        new ElementIsElementTypeFilter( false ),
        new ElementIsElementTypeFilter( true ) ) )

The WherePasses clause is totally unnecessary. I know this is the 'original' example, but I certainly hope that nobody copies this for further use.

Your 'first solution' post from 2009 appends filters to each other one at a time. Our new LogicalOrFilters support more than two inputs, so it should actually be updated to make more efficient use of 2011 filtering.

Regarding your second solution regarding HasMaterialQuantities – I guess it may not find all required elements. Furniture, for example, doesn't have material quantities, but it is a physical element in the model.

Another solution might be:

Since it seems that 3D elements are what is wanted here, all elements visible in the new (unfiltered) 3D view are targets.

Finally, the final solution contains a redundancy:

  FilteredElementCollector collector 
    = new FilteredElementCollector( doc );
  foreach( Element element in collector )
    // . . .

The redundancy consists in the call to ToElements. It executes the filter over the document and returns all found elements in a collection. Foreach over the collector does the same execution a second time. You should either skip the ToElements call (which is what I would do), or declare a local IList to hold the return of ToElements and run foreach over that.

Many thanks to Scott for this valuable feedback!