Hello,
I am trying to write a script to create multiple Filters for each IWS code (screenshot below). I have go so far but am being challenged with how to setup the LogicalOrFilter for for the two rules below using the IsLegendTypeElement property.
Any ideas on how I could set this up?
Thank you in advance
Create Filter.dyn (61.1 KB)
Hi @Joaquim_Agostinho1
Creating nested filters can be a real headache, and here you need to implement a FilterCategoryRule
, so I’m not sure if this is possible with OOTB nodes.
here is a solution with Python
python code (compatible all engine, except in Revit 2024, need IronPython at this time)
import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import net library
from System.Collections.Generic import List
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
def get_Filter_by_name(nameFilter, lstRvt_Categories, parameterName):
"""
Get or create a ParameterFilterElement with the specified name, categories, and parameter name.
Parameters:
nameFilter (str): The name of the filter.
lstRvt_Categories (list): List of Revit categories.
parameterName (str): Name of the parameter.
Returns:
ParameterFilterElement: The created or existing parameter filter element.
"""
# if exist get it
filter_by_Name = System.Predicate[System.Object](lambda x : x.Name == nameFilter)
filter_ = FilteredElementCollector(doc).OfClass(ParameterFilterElement).ToElements().Find(filter_by_Name)
if filter_ is not None:
return filter_
# else create it
else:
iListBic = List[ElementId]([cat.Id for cat in lstRvt_Categories ])
# search the parametere Element
filterParabyName = System.Predicate[System.Object](lambda x : x.Name == parameterName)
param_elem = List[DB.Element](FilteredElementCollector(doc).OfClass(ParameterElement).WhereElementIsNotElementType().ToElements()).Find(filterParabyName)
if param_elem is None:
param_elem = List[DB.Element](FilteredElementCollector(doc).OfClass(SharedParameterElement).WhereElementIsNotElementType().ToElements()).Find(filterParabyName)
if param_elem is not None:
# create 1st filter
#
filterRuleA = ParameterFilterRuleFactory.CreateContainsRule(ElementId(BuiltInParameter.KEYNOTE_PARAM), "IWS-01", False)
filterA = ElementParameterFilter(filterRuleA)
#
# create 2nd filter by multi-rules
subFilterB = List[ElementFilter]()
subrulesB = List[FilterRule]()
subrulesB.Add(FilterCategoryRule(List[ElementId]([lstRvt_Categories[0].Id])))
subrulesB.Add(ParameterFilterRuleFactory.CreateNotContainsRule(param_elem.Id, "Y", False))
subFilterB.Add(ElementParameterFilter(subrulesB))
#
subrulesB = List[FilterRule]()
subrulesB.Add(FilterCategoryRule(List[ElementId]([lstRvt_Categories[1].Id])))
subrulesB.Add(ParameterFilterRuleFactory.CreateContainsRule(param_elem.Id, "Y", False))
subFilterB.Add(ElementParameterFilter(subrulesB))
filterB = LogicalOrFilter(subFilterB)
# compute the main filter
mainFilterAB = LogicalAndFilter(filterA, filterB)
# compute the ParameterFilterElement
filter_ = ParameterFilterElement.Create(doc, nameFilter, iListBic, mainFilterAB)
return filter_
lstRvt_Categories = UnwrapElement(IN[0])
nameFilter = IN[1]
parameterName = IN[2]
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
OUT = get_Filter_by_name(nameFilter, lstRvt_Categories, parameterName)
TransactionManager.Instance.TransactionTaskDone()