How to use FilterCategoryRule
Originally Published in@CaptainDan ↗ raised a very pertinent question in the Revit API discussion forum ↗ thread on using FilterCategoryRule
in the Revit API ↗ that led to some discussion and clarification with the development team:
Question: I have three questions regarding the filter rule represented by the class FilterCategoryRule
:
- What does this rule correspond to in the Revit user interface?
- If this filters by category, then what is the relationship between the set of categories assigned to this rule and the set of categories passed to
ParameterFilterElement.Create
↗? - How do I successfully create a filter based on this filter rule?
Whenever I try to create a filter using this filter rule, it throws a Revit exception of type InternalException
saying:
- An internal error has occurred
I tried the same code in Revit 2017 and 2018 with the same exception occurring.
I searched the Internet and SDK and couldn’t find much mention of it anywhere.
The Revit API help docs on FilterCategoryRule ↗ just say A filter rule that matches elements of a set of categories.
Answer: Yes, the only significant mention of this that I can find is from The Building Coder on What’s New in the Revit 2014 API small enhancements & interface changes:
FilterCategoryRule
The new class FilterCategoryRule can be used in the definition of a ParameterFilterElement. It represents a filter rule that matches elements of a set of categories.
The related method:
- ParameterFilterElement.AllCategoriesFilterable()
has been replaced by
- FilterCategoryRule.AllCategoriesFilterable()
I passed on your questions to the development team, and they reply:
-
Q: What does
FilterCategoryRule
correspond to in the Revit user interface?
– A: There is no direct correspondence in Revit UI, this is the FilterRule to be used in API. -
Q: If this filters by category, then what is the relationship between the set of categories assigned to this rule and the set of categories passed to
ParameterFilterElement.Create()
?
– A: There is no relation toParameterFilterElement.Create
. -
Q: How do I successfully create a filter based on this filter rule?
– A: You cannot create aParameterFilterElement
based on thisFilterCategoryRule
, but you can create anElementParameterFilter
, an API construct, based on it.
Here is an example:
// Find all walls and windows in the document
IList<ElementId> cats = new List<ElementId>();
cats.Add( new ElementId( BuiltInCategory.OST_Walls ) );
cats.Add( new ElementId( BuiltInCategory.OST_Windows ) );
FilterCategoryRule r = new FilterCategoryRule( cats );
ElementParameterFilter f
= new ElementParameterFilter( r, true );
FilteredElementCollector wallsAndWindows
= new FilteredElementCollector( doc )
.WherePasses( f );
The Revit API docs are confusing and not entirely correct, especially this statement: “The new class FilterCategoryRule can be used in the definition of a ParameterFilterElement”. the ParameterFilterElement.Create
method could potentially take a FilterCategoryRule
object instead of a set of category ids, but this flavour of the Create
method was never introduced. We have filed a development task to either correct the docs or add the method. Additional confusion comes from the two API names: ParameterFilterElement
and ElementParameterFilter
:-~
Just as Benoit ↗ points out, FilterCategoryRule
can simply be seen as an extension of the ElementCategoryFilter ↗ and the associated quick filter shortcut methods OfCategory ↗ and OfCategoryId ↗.
It seems to me that it is completely equivalent to a logical or of a bunch of ElementCategoryFilter
instances, such as I used in the MEP and structural filtered element collector examples: