So I’m struggling to get my filter rule by rule type working…
I want to filter by Level, so I believe I need to feed both the Level Parameter (ie. a parameter) from the floor and the Level Parameter value (ie. a string).
My attempts at retrieving the parameter by name don’t seem to be working (I create a rule but the value is blank) so I’m trying python… But I don’t seem able to return a parameter?
I’m wondering if I’m looking at the wrong problem… I think the filter rule should work if i put the level in, but it only returns a filter if i put in a string (the level name)…
You’re right. Blank for me as well. I’m guessing it’s because the FilterRule node expects a string but the value for Level is an element. I’m guessing this will have to be fixed in an update.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Import RevitAPI
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import ToProtoType, ToRevitType geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import DSCore nodes in Dynamo
clr.AddReference('DSCoreNodes')
import DSCore
from DSCore import *
# Import python library
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import os
import shutil
import math
# Import math library
from math import *
#Import Data and Time
from datetime import datetime
now = datetime.now()
#Import System Library
import System
from System.Collections.Generic import *
from System.IO import Directory, Path
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
def ToList(x):
if isinstance(x,list): return UnwrapElement(x)
else: return [UnwrapElement(x)]
#Preparing input from dynamo to revit
pName = IN[0]
elem = UnwrapElement(IN[1])
filtNames = IN[2]
cats = ToList(IN[3])
catids = List[ElementId]()
catids.Clear()
for cc in cats:
catids.Add(cc.Id)
test = []
p = elem.Parameters
for n in p:
test.append(n.Definition.Name)
pvp = ParameterValueProvider(n.Id)
#if pvp.IsElementIdValueSupported(elem):
if n.Definition.Name == pName:
ePvp = pvp
break
#define subset of element filters
sfilters = List[ElementFilter]()
sfilters.Add(ElementParameterFilter(FilterStringRule(ePvp,FilterStringEquals(),pName,False)))
#define final set of element filters
fRule = LogicalAndFilter(sfilters)
#Do some action in a Transaction #
TransactionManager.Instance.EnsureInTransaction(doc)
for name,cat in zip(filtNames,cats):
paraele = ParameterFilterElement.Create(doc,name,catids)
paraele.SetElementFilter(fRule)
Parafilele.append(paraele)
TransactionManager.Instance.TransactionTaskDone()
OUT = Parafilele
And also, i dont think you need to feed in an element to retrieve the parameter Id, you can either use parametermap for project or sharedparameter element and filter by name to retrieve its Id
The first BIP LEVEL_PARAM didn’t work, it needs the 2nd… I’ll have to run some kind of check…
pId = ElementId(BuiltInParameter.SCHEDULE_LEVEL_PARAM)
sRule = ParameterFilterRuleFactory.CreateEqualsRule(pId, level.Id)
fRule = ElementParameterFilter(sRule)
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for name,cat in zip(filtNames,cats):
paraele = ParameterFilterElement.Create(doc,name,catids)
paraele.SetElementFilter(fRule)
Parafilele.append(paraele)
TransactionManager.Instance.TransactionTaskDone()
OUT = Parafilele
Sorry for the late reply but it seems that you had already figured out. Good for you! but since i already sort of did it already, here is another way to achieve what you want for R19 and above(my above reply is wrong)!
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
#Preparing input from dynamo to revit
pvp1 = ParameterValueProvider(ElementId(BuiltInParameter.SCHEDULE_LEVEL_PARAM))
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
#Empty list of Element Filter
sRule1 = List[ElementFilter]()
#Get all levelids in project
lvlids = FilteredElementCollector(doc).OfClass(Level).ToElementIds()
#You can use this loop to retrieve desired level, just change to ToElements() and search by name
#We can filter by element Id and since element id is numeric, we will use FilterNumericEquals()
for lvlid in lvlids:
sRule1.Add(ElementParameterFilter(FilterElementIdRule(pvp1,FilterNumericEquals(),lvlid)))
#Can use LogicalAndFilter
fRule = LogicalOrFilter(sRule1)
#Get a list to cat ids to be used by the filter
catids = List[ElementId]()
catids.Add(Category.GetCategory(doc,BuiltInCategory.OST_Floors).Id)
#Create the ParameterFilterElement
pfe1 = ParameterFilterElement.Create(doc,"Example view filter1",catids,fRule)
TransactionManager.Instance.TransactionTaskDone()
#Final output
OUT = pfe1
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
#Preparing input from dynamo to revit
pvp1 = ParameterValueProvider(ElementId(BuiltInParameter.SCHEDULE_LEVEL_PARAM))
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
#Empty list of FilterRule
sRule1 = List[FilterRule]()
#Get all levelids in project
lvlids = FilteredElementCollector(doc).OfClass(Level).ToElementIds()
#You can use this loop to retrieve desired level, just change to ToElements() and search by name
#We can filter by element Id and since element id is numeric, we will use FilterNumericEquals()
for lvlid in lvlids:
sRule1.Add(FilterElementIdRule(pvp1,FilterNumericEquals(),lvlid))
#Get a list to cat ids to be used by the filter
catids = List[ElementId]()
catids.Add(Category.GetCategory(doc,BuiltInCategory.OST_Floors).Id)
#Create the ParameterFilterElement
pfe1 = ParameterFilterElement.Create(doc,"Example view filter1",catids,sRule1)
TransactionManager.Instance.TransactionTaskDone()
#Final output
OUT = pfe1
Well… for this i do not have control over it as it is determined by the Autodesk team. If you use revit lookup, you will be able to find which builtin parameter the level is tied to. hahaha