Creating View filter and setting up the rules

I have been trying to create the viewFilter that looks at a shared parameter and checks if it contains the word “New”. While I was writing up what I could not figure out I managed to solve it, so I’m leaving this post for any poor souls that are trying to do what I did and vent some frustration with the Revit API docs.

My code:

import clr
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import System
from System import Array
from System.Collections.Generic import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")

import Autodesk 
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication 
app = uiapp.Application 
uidoc = uiapp.ActiveUIDocument
categories = doc.Settings.Categories


# The inputs to this node will be stored as a list in the IN variables.
paraName=UnwrapElement(IN[0])
filterWord1=UnwrapElement(IN[1])
# Place your code below this line

#for testing purposes, remove later and read from input
paraName="BIMEXPERTS_Clash_Status"
filterWord1="New"
#-------------------------------------

filterParam=0
shared_params = FilteredElementCollector(doc).OfClass(SharedParameterElement)
for i in shared_params:
	if(i.Name==paraName):
		filterParam = i


#get category
category=Category.GetCategory(doc,BuiltInCategory.OST_GenericModel).Id
	
#cast categories
catlist=[]
catlist.append(category)
typedCatList=List[ElementId](catlist)
#make rule
rules=[]
rules.append(ParameterFilterRuleFactory.CreateContainsRule(filterParam.Id,filterWord1,False))


TransactionManager.Instance.EnsureInTransaction(doc)

#creating the filter
filter=ParameterFilterElement.Create(doc,"BIMEXPERTS_Clash_Status_New",typedCatList)

#Connecting them
rules2=ElementParameterFilter(rules[0])
filter.SetElementFilter(rules2)

TransactionManager.Instance.TransactionTaskDone()


OUT=0

i have been trying to get it to work by reading this doc:
https://www.revitapidocs.com/2020/b231dc85-516a-5e75-c634-c6cd81b43fc5.htm

but this function ( CreateElementFilterFromFilterRules(filterRules) ) does not exist in the API.

Then i found this post on the forums:

that says you should use LogicalAndFilter but I could not manage to get it to work.

You create a filter by calling the class ParameterFilterElement. This works fine, it creates the filter but it has no rules. The function that creates the filter WITH THE RULES is gone in Revit 2020. That’s why old posts won’t help you.

rules are created by ParameterFilterRuleFactory.

What you need now is to set these rules on the filter object. But you cant do that. The set function needs an ElementFilter class but you have a FilterRule class.
In order to combine these to you need to make an ElementParameterFilter class that can take the rules, and then you can pass this to the SetElementFilter function.

Now look at the names of these classes
ParameterFilterElement for creation and
ElementParameterFilter for connection. They are really similar. You could be reading one thinking its the other. :expressionless:
I have been going around in circles between these 2 clases trying to figure out what the duck is going on.

I hope this helps anybody that comes across it.

2 Likes