How to set a series Filter Rules using "OR (Any rule may be ture)" instead of "AND (All rules must be true)"?

I’ve done this using Python in Dynamo.

To create a Revit Filter (Parameter Filter Element) you need an ICollection of the categories the filter will apply to and an ElementParameterFilter. The Construction of the Element Parameter Filter is the most confusing part because you can construct ElementParameterFilters our of other previously constructed ElementParameterFilters.

To try to show this I’ll make a filter that works on Framing and Columns and test for either Comments Equals “Magnum” OR (Family Name Begins With “Blue” AND Comments Equals “Steel”)

import clr

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
import System
from System.Collections.Generic import *
from System.Collections.Generic import List

doc=DocumentManager.Instance.CurrentDBDocument
app=DocumentManager.Instance.CurrentUIApplication.Application

First construct an ICollection of StructuralFraming and Structural Column Categories:

beamcolumncatlist=[]
beamcolumncatlist.Add(ElementId(BuiltInCategory.OST_StructuralFraming))
beamcolumncatlist.Add(ElementId(BuiltInCategory.OST_StructuralColumns))
iCollBeamColumnCats=List[ElementId](beamcolumncatlist)

Next get the parameters you will be testing on (in this case the Comments parameter and the Family Name):

pComment=ParameterValueProvider(ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS))
pFamName=ParameterValueProvider(ElementId(BuiltInParameter.ALL_MODEL_FAMILY_NAME))

Next construct the Filter Rules/Tests on those parameters:

xFamName=FilterStringRule(pFamName,FilterStringBeginsWith(),"Blue",False)
xCommSteel=FilterStringRule(pComment,FilterStringEquals(),"Steel",False)
xCommMagnum=FilterStringRule(pComment,FilterStringEquals(),"Magnum",False)

Now construct the actual filter (ParameterFilterElement) - note that this must occur inside a transaction:

TransactionManager.Instance.EnsureInTransaction(doc)

##Make an ICollection of the “Blue” and “Steel” filter tests, then use that ICollection to construct an AND filter set.

beamcolumnfilt1=[]
beamcolumnfilt1.Add(ElementParameterFilter(xFamName))
beamcolumnfilt1.Add(ElementParameterFilter(xCommSteel))
icolbeamcolumnfilt1=List[ElementFilter](beamcolumnfilt1)
andbeamcolumnfilt1=LogicalAndFilter(icolbeamcolumnfilt1)

##Now make an ICollection of the “Magnum” tests and the previous AND of “Blue”+“Steel”, then use that ICollection to construct an OR filter set.

beamcolumnfilt2=[]
beamcolumnfilt2.Add(ElementParameterFilter(xCommMagnum))
beamcolumnfilt2.Add(andbeamcolumnfilt1)
icolbeamcolumnfilt2=List[ElementFilter](beamcolumnfilt2)
orbeamcolumnfilt2=LogicalOrFilter(icolbeamcolumnfilt2)

##Now construct a ParameterFilterElement called “ZoolanderBeamsColumns” using the previously defined beam and column category ICollection and the OR ElementParameterFilter.

pfebeamcolelem=ParameterFilterElement.Create(doc,"ZoolanderBeamsColumns",iCollBeamColumnCats,orbeamcolumnfilt2)
TransactionManager.Instance.TransactionTaskDone()

Hope this helps.

11 Likes