Applying Filters

Applying Filters

Filters can be applied to a FilteredElementCollector using ElementFilters. An ElementFilter is a class that examines an element to see if it meets a certain criteria. The ElementFilter base class has three derived classes that divide element filters into three categories.

Most filters may be inverted using an overload constructor that takes a Boolean argument indicating to invert the filter so that elements that would normally be accepted by the filter will be rejected, and elements that would normally be rejected will be accepted. Filters that cannot be inverted are noted in their corresponding sections below.

There is a set of predefined filters available for common uses. Many of these built-in filters provide the basis for the FilteredElementCollector shortcut methods mentioned in the FilteredElementCollector section above. The next three sections provide more information on the built-in filters.

Once a filter is created, it needs to be applied to the FilteredElementCollector. The generic method WherePasses() is used to apply a single ElementFilter to the FilteredElementCollector.

Filters can also be applied using a number of shortcut methods provided by FilteredElementCollector. Some apply a specific filter without further input, such as WhereElementIsCurveDriven(), while others apply a specific filter with a simple piece of input, such as the OfCategory() method which takes a BuiltInCategory as a parameter. And lastly there are methods such as UnionWith() that join filters together. All of these methods return the same collector allowing filters to be easily chained together.

Quick filters

Quick filters operate only on the ElementRecord, a low-memory class which has a limited interface to read element properties. Elements which are rejected by a quick filter will not be expanded in memory. The following table summarizes the built-in quick filters, and some examples follow for a few of the filters.

Table 13: Built-in Quick Filters

Built-in Filter

What it passes

Shortcut Method(s)

BoundingBoxContainsPointFilter

Elements which have a bounding box that contains a given point

None

BoundingBoxIntersectsFilter

Elements which have a bounding box which intersects a given outline

None

BoundingBoxIsInsideFilter

Elements which have a bounding box inside a given outline

None

ElementCategoryFilter

Elements matching the input category id

OfCategoryId()

ElementClassFilter

Elements matching the input runtime class (or derived classes)

OfClass()

ElementDesignOptionFilter

Elements in a particular design option

ContainedInDesignOption()

ElementIsCurveDrivenFilter

Elements which are curve driven

WhereElementIsCurveDriven()

ElementIsElementTypeFilter

Elements which are "Element types"

WhereElementIsElementType() WhereElementIsNotElementType()

ElementMulticategoryFilter Elements matching any of a given set of categories None
ElementMulticlassFilter Elements matching a given set of classes (or derived classes) None

ElementOwnerViewFilter

Elements which are view-specific

OwnedByView() WhereElementIsViewIndependent()

ElementStructuralTypeFilter

Elements matching a given structural type

None

ExclusionFilter

All elements except the element ids input to the filter

Excluding()

FamilySymbolFilter

Symbols of a particular family

Note: The FamilySymbolFilter cannot be inverted.
Note: The bounding box filters exclude all objects derived from View and objects derived from ElementType.

The following example creates an outline in the document and then uses a BoundingBoxIntersectsFilter to find the elements in the document with a bounding box that intersects that outline. It then shows how to use an inverted filter to find all walls whose bounding box do not intersect the given outline. Note that the use of the OfClass() method applies an ElementClassFilter to the collection as well.

Code Region 6-2: BoundingBoxIntersectsFilter example

// Use BoundingBoxIntersects filter to find elements with a bounding box that intersects the 
// given Outline in the document.

// Create a Outline, uses a minimum and maximum XYZ point to initialize the outline. 
Outline myOutLn = new Outline(new XYZ(0, 0, 0), new XYZ(100, 100, 100));

// Create a BoundingBoxIntersects filter with this Outline
BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(myOutLn);

// Apply the filter to the elements in the active document
// This filter excludes all objects derived from View and objects derived from ElementType
FilteredElementCollector collector = new FilteredElementCollector(document);
IList<Element> elements = collector.WherePasses(filter).ToElements();

// Find all walls which don't intersect with BoundingBox: use an inverted filter 
// to match elements
// Use shortcut command OfClass() to find walls only
BoundingBoxIntersectsFilter invertFilter = new BoundingBoxIntersectsFilter(myOutLn, true);
collector = new FilteredElementCollector(document);
IList<Element> notIntersectWalls = collector.OfClass(typeof(Wall)).WherePasses(invertFilter).ToElements();

The next example uses an exclusion filter to find all walls that are not currently selected in the document.

Code Region 6-3: Creating an exclusion filter

// Find all walls that are not currently selected, 
// Get all element ids which are current selected by users, exclude these ids when filtering
ICollection<ElementId> selectedIds = uiDocument.Selection.GetElementIds();

// Use the selection to instantiate an exclusion filter
ExclusionFilter filter = new ExclusionFilter(selectedIds);
// For the sake of simplicity we do not test here whether the selection is empty or not,
// but in production code a proper validation would have to be done to avoid an argument
// exception from the filter's consructor.

// Apply the filter to the elements in the active document,
// Use shortcut method OfClass() to find Walls only
FilteredElementCollector collector = new FilteredElementCollector(uiDocument.Document);
IList<Element> walls = collector.WherePasses(filter).OfClass(typeof(Wall)).ToElements();
Note: The ElementClassFilter will match elements whose class is an exact match to the input class, or elements whose class is derived from the input class. The following example uses an ElementClassFilter to get all loads in the document.

Code Region 6-4: Using an ElementClassFilter to get loads

// Use ElementClassFilter to find all loads in the document
// Using typeof(LoadBase) will yield all AreaLoad, LineLoad and PointLoad
ElementClassFilter filter = new ElementClassFilter(typeof(LoadBase));

// Apply the filter to the elements in the active document
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> allLoads = collector.WherePasses(filter).ToElements();
There is a small subset of Element subclasses in the API which are not supported by the element class filter. These types exist in the API, but not in Revit's native object model, which means that this filter doesn't support them. In order to use a class filter to find elements of these types, it is necessary to use a higher level class and then process the results further to find elements matching only the subtype.
Note: Dedicated filters exist for some of these types.
The following types are affected by this restriction:

Type

Dedicated Filter

Subclasses of Autodesk.Revit.DB.Material

None

Subclasses of Autodesk.Revit.DB.CurveElement

CurveElementFilter

Subclasses of Autodesk.Revit.DB.ConnectorElement

None

Subclasses of Autodesk.Revit.DB.HostedSweep

None

Autodesk.Revit.DB.Architecture.Room

RoomFilter

Autodesk.Revit.DB.Mechanical.Space

SpaceFilter

Autodesk.Revit.DB.Area

AreaFilter

Autodesk.Revit.DB.Architecture.RoomTag

RoomTagFilter

Autodesk.Revit.DB.Mechanical.SpaceTag

SpaceTagFilter

Autodesk.Revit.DB.AreaTag

AreaTagFilter

Autodesk.Revit.DB.CombinableElement

None

Autodesk.Revit.DB.Mullion

None

Autodesk.Revit.DB.Panel

None

Autodesk.Revit.DB.AnnotationSymbol

None

Autodesk.Revit.DB.Structure.AreaReinforcementType

None

Autodesk.Revit.DB.Structure.PathReinforcementType

None

Autodesk.Revit.DB.AnnotationSymbolType

None

Autodesk.Revit.DB.Architecture.RoomTagType

None

Autodesk.Revit.DB.Mechanical.SpaceTagType

None

Autodesk.Revit.DB.AreaTagType

None

Autodesk.Revit.DB.Structure.TrussType

None

Slow Filters

Slow filters require that the Element be obtained and expanded in memory first. Thus it is preferable to couple slow filters with at least one ElementQuickFilter, which should minimize the number of Elements that are expanded in order to evaluate against the criteria set by this filter. The following table summarizes the built-in slow filters, while a few examples follow to provide an in-depth look at some of the filters.

Table 14: Built-in Slow Filters

Built-in Filter

What it passes

Shortcut Method(s)

AreaFilter

Areas

None

AreaTagFilter

Area tags

None

CurveElementFilter

CurveElements

None

ElementLevelFilter

Elements associated with a given level id

None

ElementParameterFilter

Elements passing one or more parameter filter rules

None

ElementPhaseStatusFilter Elements with a given phase status on a given phase None

FamilyInstanceFilter

Instances of a particular family instance

None

FamilyStructuralMaterialTypeFilter

Family elements of given structural material type

None

PrimaryDesignOptionMemberFilter

Elements owned by any primary design option

None

RoomFilter

Rooms

None

RoomTagFilter

Room tags

None

SpaceFilter

Spaces

None

SpaceTagFilter

Space tags

None

StructuralInstanceUsageFilter

FamilyInstances of given structural usage

None

StructuralMaterialTypeFilter

FamilyInstances of given structural material type

None

StructuralWallUsageFilter

Walls of given structural wall usage

None

ElementIntersectsElementFilter Elements that intersect the solid geometry of a given element None
ElementIntersectsSolidFilter Elements that intersect the given solid geometry None

The following slow filters cannot be inverted:

  • RoomFilter
  • RoomTagFilter
  • AreaFilter
  • AreaTagFilter
  • SpaceFilter
  • SpaceTagFilter
  • FamilyInstanceFilter

As mentioned in the quick filters section, some classes do not work with the ElementClassFilter. Some of those classes, such as Room and RoomTag have their own dedicated filters.

Code Region 6-5: Using the Room filter

// Use a RoomFilter to find all room elements in the document. It is necessary to use the 
// RoomFilter and not an ElementClassFilter or the shortcut method OfClass() because the Room 
// class is not supported by those methods.
RoomFilter filter = new RoomFilter();

// Apply the filter to the elements in the active document
FilteredElementCollector collector = new FilteredElementCollector(document);
IList<Element> rooms = collector.WherePasses(filter).ToElements();

The ElementParameterFilter is a powerful filter that can find elements based on values of parameters they may have. It can find elements whose parameter values match a specific value or are greater or less than some value. ElementParameterFilter can also be used to find elements that support a specific shared parameter.

The example below uses an ElementParameterFilter to find rooms whose size is more than 100 square feet and rooms with less than 100 square feet.

Code Region 6-6: Using a parameter filter

// Creates an ElementParameter filter to find rooms whose area is 
// greater than specified value
// Create filter by provider and evaluator 
BuiltInParameter areaParam = BuiltInParameter.ROOM_AREA;
// provider
ParameterValueProvider pvp = new ParameterValueProvider(new ElementId((int)areaParam));
// evaluator
FilterNumericRuleEvaluator fnrv = new FilterNumericGreater();
// rule value 
double ruleValue = 100.0f;      // filter room whose area is greater than 100 SF
// rule
FilterRule fRule = new FilterDoubleRule(pvp, fnrv, ruleValue, 1E-6);

// Create an ElementParameter filter
ElementParameterFilter filter = new ElementParameterFilter(fRule);

// Apply the filter to the elements in the active document
FilteredElementCollector collector = new FilteredElementCollector(document);
IList<Element> rooms = collector.WherePasses(filter).ToElements();

// Find rooms whose area is less than or equal to 100: 
// Use inverted filter to match elements
ElementParameterFilter lessOrEqualFilter = new ElementParameterFilter(fRule, true); 
collector = new FilteredElementCollector(document);
IList<Element> lessOrEqualFounds = collector.WherePasses(lessOrEqualFilter).ToElements();

The following example shows how to use the FamilyStructuralMaterialTypeFilter to find all families whose material type is wood. It also shows how to use an inverted filter to find all families whose material type is not wood.

Code Region 6-7: Find all families with wood material

// Use FamilyStructuralMaterialType filter to find families whose material type is Wood
FamilyStructuralMaterialTypeFilter filter = new FamilyStructuralMaterialTypeFilter(StructuralMaterialType.Wood);

// Apply the filter to the elements in the active document
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> woodFamiles = collector.WherePasses(filter).ToElements();

// Find families are not Wood: Use inverted filter to match families
FamilyStructuralMaterialTypeFilter notWoodFilter = 
        new FamilyStructuralMaterialTypeFilter(StructuralMaterialType.Wood, true);
collector = new FilteredElementCollector(document);
ICollection<Element> notWoodFamilies = collector.WherePasses(notWoodFilter).ToElements();
The last two slow filters derive from ElementIntersectsFilter which is a base class for filters used to match elements which intersect with geometry. See Code Region: Find Nearby Walls in the section Geometry Utility Classesfor an example of the use of this type of filter.

Logical filters

Logical filters combine two or more filters logically. The following table summarizes the built-in logical filters.

Table 15: Built-in Logical Filters

Built-in Filter

What it passes

Shortcut Method(s)

LogicalAndFilter

Elements that pass 2 or more filters

WherePasses()- adds one additional filter

IntersectWith() - joins two sets of independent filters

LogicalOrFilter

Elements that pass at least one of 2 or more filters

UnionWith() - joins two sets of independent filters

In the example below, two quick filters are combined using a logical filter to get all door FamilyInstance elements in the document.

Code Region 6-8: Using LogicalAndFilter to find all door instances

// Find all door instances in the project by finding all elements that both belong to the
// door category and are family instances.
ElementClassFilter familyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance));

// Create a category filter for Doors
ElementCategoryFilter doorsCategoryfilter = 
        new ElementCategoryFilter(BuiltInCategory.OST_Doors);

// Create a logic And filter for all Door FamilyInstances
LogicalAndFilter doorInstancesFilter = new LogicalAndFilter(familyInstanceFilter, 
        doorsCategoryfilter);

// Apply the filter to the elements in the active document
FilteredElementCollector collector = new FilteredElementCollector(document);
IList<Element> doors = collector.WherePasses(doorInstancesFilter).ToElements();