How to use FilterCategoryRule

@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:

  1. What does this rule correspond to in the Revit user interface?
  2. 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?
  3. 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:

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:

has been replaced by

I passed on your questions to the development team, and they reply:

  1. 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.

  2. 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 to ParameterFilterElement.Create.

  3. Q: How do I successfully create a filter based on this filter rule?
    – A: You cannot create a ParameterFilterElement based on this FilterCategoryRule, but you can create an ElementParameterFilter, 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 ElementIdBuiltInCategory.OST_Walls ) );
  cats.Add( new ElementIdBuiltInCategory.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:

Steel rule