Python: Custom rules for FilteredElementCollector

I am trying to filter elements with a Python script. My aim is to use FilteredElementCollector with my own set of rules.
I am trying to use FilteredElementCollector.WherePasses(MYFILTERNAME) method, where MYFILTERNAME would be a custom filter that I defined.

I have successfully created ParameterFilterElement with my own rules, however when I use it for the Collector WherePasses() method I get the error that “expected ElementFilter, got ParameterFilterElement instead”, so I assume that I am using wrong kind of filter class here, but I really don’t know any other way to declare my rules.

Please find my python script:

import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

import System
from System.Collections.Generic import *

clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference("RevitAPIUI")

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

clr.AddReference("ProtoGeometry")
from Autodesk.DesignScript.Geometry import *

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

uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

TransactionManager.Instance.EnsureInTransaction(doc)

Parameter = BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS

rules = []
rules.append(ParameterFilterRuleFactory.CreateEqualsRule(ElementId(Parameter), "aaa", True))

WallsCat = IN[0]
CatList = []

for i in WallsCat:
	CatList.append(ElementId(i.Id))

typedCatList = List[ElementId](CatList)

MyFilter = ParameterFilterElement.Create(doc, "MojFiltr", typedCatList, rules)
abc = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().WherePasses(MyFilter).ToElements()
TransactionManager.Instance.TransactionTaskDone()

OUT = abc

I believe ParameterFilterElement is the API method used for View Filters, not for FilteredElementCollectors. Try adjusting the filter portion of your script to this:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

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

doc = DocumentManager.Instance.CurrentDBDocument

bip = BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS
provider = ParameterValueProvider(ElementId(bip))
evaluator = FilterStringEquals();
rule = FilterStringRule(provider, evaluator, "aaa", False);
filter = ElementParameterFilter(rule);
walls = FilteredElementCollector(doc).OfClass(Wall).WherePasses(filter).ToElements()

OUT = walls
8 Likes

Thank you a lot! It worked.

this got me thinking and I played with it a bit for a wall example

#------------------------------------------
#refer to the building coder, forum & revitapidocs.com
#------------------------------------------

#http://thebuildingcoder.typepad.com/blog/2010/06/parameter-filter.html

#https://forum.dynamobim.com/t/python-custom-rules-for-filteredelementcollector/21135/2?u=adam_bear1

#http://www.revitapidocs.com/2018.1/fb011c91-be7e-f737-28c7-3f1e1917a0e0.htm

#------------------------------------------
#boilerplate
#------------------------------------------

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk

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

doc = DocumentManager.Instance.CurrentDBDocument
fec = FilteredElementCollector(doc)


#------------------------------------------
#useful list of bip to copy paste from revitapidocs.com
#------------------------------------------

#StringValues
'ALL_MODEL_DESCRIPTION'
'ALL_MODEL_MARK'
'ALL_MODEL_INSTANCE_COMMENTS'
'ALL_MODEL_TYPE_COMMENTS'

#ElementId
'ID_PARAM'

#Integers
'WALL_BOTTOM_IS_ATTACHED'
'WALL_TOP_IS_ATTACHED'
'WALL_ATTR_ROOM_BOUNDING'
'RELATED_TO_MASS'
'WALL_STRUCTURAL_SIGNIFICANT'
'STRUCTURAL_ANALYTICAL_MODEL'

#Doubles
'ALL_MODEL_COST'

enum = 'WALL_STRUCTURAL_SIGNIFICANT'

#------------------------------------------
#define myclass, bip, provider
#------------------------------------------

myclass = Wall
#bip = BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT
bip = eval('BuiltInParameter.' + enum)
provider = ParameterValueProvider(ElementId(bip))

#------------------------------------------
#evaluate strings, elem id, integer, doubles
#------------------------------------------

#evaluate string values
#test = 'aaa'
#evaluator = FilterStringContains()
#evaluator = FilterStringEquals()
#rule = FilterStringRule(provider, evaluator, test, False)

#evaluate element id
#evaluator = FilterNumericEquals()
#evaluator = FilterNumericGreater()
#test = ElementId(0)
#rule = FilterElementIdRule(provider, evaluator, test)

#evaluate integer values
test = 1
evaluator = FilterNumericEquals()
#evaluator = FilterNumericGreater()
rule = FilterIntegerRule(provider, evaluator, test)

#evaluate double values
#test = 5.55
#evaluator = FilterNumericEquals()
#evaluator = FilterNumericGreater()
#rule = FilterDoubleRule(provider, evaluator, test, 10**-3)

#------------------------------------------
#fec of class passing filter to elements
#------------------------------------------

filter = ElementParameterFilter(rule)
elems = fec.OfClass(myclass).WherePasses(filter).ToElements()

#------------------------------------------
#output
#------------------------------------------

OUT = elems
4 Likes