Using LogicalOrFilter

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()