Description
A filter is nothing more then a condition based on which an object gets rejected or approved. The criteria can be anything from a property belonging to that object or an action performed on it. What does it actually mean? Well first you must have a list of objects, the original stack. Then you iterate each object and filter elements out.
Imagine that you have a bag of apples and you want to filter out some apples based on some criteria, what can those be?
- Is the apple Red? (Colour)
- Is the apple organic? (Composition)
- Is the apple rotten? (Freshness)
There are many applications for filters and they have advantages or disadvantages. Filtering elements require always iterating through a list and performing actions. There are slow and fast filters based on what operations are performed.
Element Level Filter
Revit defines multiple kinds of Filters and I will not present today all of them (frankly because I don’t know all of them, I have used only a few) but one filter I needed was ElementLevelFilter. This filter allows you to reduce a set of elements to those that belong to a certain level defined by it’s ElementId.
This filter is a slow filter because the element has to be expanded first (what in fact means is that not all information is available on the first query but information has to be added first, thus making this process a bit more cpu-expensive).
What is particularly interesting about filters in Revit is the way you combine filters in order to obtain a set of elements with a very specific information.
The example below shows how to get the list of doors on a certain level:
BuiltInCategory – A list of all the built in categories within Revit.
FilteredElementCollector -This class is used to search, filter and iterate through a set of elements.
- OfCategory(BuiltInCategory cat) – applies an ElementCategoryFilter to the collector.
-
WherePasses (ElementFilter filter) – applies an element filter to the collector.
ElementLevelFilter – filter used to match elements by their associated level.
ElementId levelId = new ElementId(myLevelId); // pass the level id as an integer FilteredElementCollector filteredElementCollector = new FilteredElementCollector(RevitDBDocument); ElementLevelFilter elementLevelFilter = new ElementLevelFilter(levelId); filteredElementCollector.OfCategory(BuiltInCategory.OST_Doors).WherePasses(elementLevelFilter); IList revitDoors = filteredElementCollector.ToElements(); foreach (Element item in revitDoors) { if (item is FamilyInstance) { FamilyInstance elDoor = (FamilyInstance)item; //do something with elDoor } }
Hi
Instead of using for each loop, would it be simpler to use WhereElementIsNotElementType() to get only the instances ?
Hi Yien,
Yes indeed, I haven’t paid much attention to all available filters, what you are saying it’s correct, this filter will indeed get all elements that are not types or symbols.
Since here I am already getting the doors using the built-in-category, it will work fine.
Note that this filter will not get only FamilyInstances. There is an explanation in the following article (check out Jeremy’s response) https://forums.autodesk.com/t5/revit-api-forum/filteredelementcollector-for-to-get-system-families-and-quot/td-p/6745319