def create_modifier_filters(exclude=False): """Create standard rule-based filters for available tag modifiers. Args: exclude (bool, optional): create exclusion filter, defaults to False Returns: list[DB.ParameterFilterElement]: list of created filters """ mfilters = [] existing_filters = [x for x in revit.query.get_rule_filters()] for modif in TagModifiers.get_modifiers(): # create filter name and check availability filter_name = \ '{} {}'.format('NONE' if exclude else 'ALL', modif.name) filter_exists = False for exst_filter in existing_filters: if exst_filter.Name == filter_name: filter_exists = True mfilters.append(exst_filter) if filter_exists: continue # get tags param id param_id = _get_tag_paramid() # create filter rule rules = framework.List[DB.FilterRule]() param_prov = DB.ParameterValueProvider(param_id) param_contains = DB.FilterStringContains() rule = DB.FilterStringRule(param_prov, param_contains, modif.tag, False) if exclude: rule = DB.FilterInverseRule(rule) rules.Add(rule) # collect applicable categories cats = [] for cat in revit.query.get_all_category_set(): if DB.ParameterFilterElement.AllRuleParametersApplicable( revit.doc, framework.List[DB.ElementId]([cat.Id]), rules ): cats.append(cat.Id) # create filter mfilter = DB.ParameterFilterElement.Create( revit.doc, filter_name, framework.List[DB.ElementId](cats), rules ) mfilters.append(mfilter) return mfilters
def get_elements_by_param_value(param_name, param_value, inverse=False, doc=None): doc = doc or HOST_APP.doc param_id = get_project_parameter_id(param_name) if param_id: pvprov = DB.ParameterValueProvider(param_id) pfilter = DB.FilterStringEquals() vrule = DB.FilterStringRule(pvprov, pfilter, param_value, True) if inverse: vrule = DB.FilterInverseRule(vrule) param_filter = DB.ElementParameterFilter(vrule) return DB.FilteredElementCollector(doc)\ .WherePasses(param_filter)\ .ToElements() else: return []
def create_param_value_filter(filter_name, param_id, param_values, evaluator, match_any=True, case_sensitive=False, exclude=False, category_list=None, doc=None): doc = doc or DOCS.doc if HOST_APP.is_newer_than(2019, or_equal=True): rules = None else: rules = framework.List[DB.FilterRule]() param_prov = DB.ParameterValueProvider(param_id) # decide how to combine the rules logical_merge = \ DB.LogicalOrFilter if match_any else DB.LogicalAndFilter # create the rule set for pvalue in param_values: # grab the evaluator param_eval = PARAM_VALUE_EVALUATORS.get(evaluator, None) if not param_eval: raise PyRevitException("Unknown evaluator") # if value is str, eval is expected to be str str_eval, num_eval = param_eval if isinstance(pvalue, str): rule = DB.FilterStringRule(param_prov, str_eval(), pvalue, case_sensitive) # if num_eval is for str, e.g. "contains", or "startswith" # convert numeric values to str elif isinstance(num_eval, DB.FilterStringRuleEvaluator): if isinstance(pvalue, (int, float)): rule = DB.FilterStringRule(param_prov, num_eval(), str(pvalue), False) elif isinstance(pvalue, DB.ElementId): rule = DB.FilterStringRule(param_prov, num_eval(), str(pvalue.IntegerValue), False) # if value is int, eval is expected to be numeric elif isinstance(pvalue, int): rule = DB.FilterIntegerRule(param_prov, num_eval(), pvalue) # if value is float, eval is expected to be numeric elif isinstance(pvalue, float): rule = DB.FilterDoubleRule(param_prov, num_eval(), pvalue, sys.float_info.epsilon) # if value is element id, eval is expected to be numeric elif isinstance(pvalue, DB.ElementId): rule = DB.FilterElementIdRule(param_prov, num_eval(), pvalue) if exclude: rule = DB.FilterInverseRule(rule) if HOST_APP.is_newer_than(2019, or_equal=True): if rules: rules = logical_merge(rules, DB.ElementParameterFilter(rule)) else: rules = DB.ElementParameterFilter(rule) else: rules.Add(rule) # collect applicable categories if category_list: category_set = query.get_category_set(category_list, doc=doc) else: category_set = query.get_all_category_set(doc=doc) # filter the applicable categories filter_cats = [] for cat in category_set: if DB.ParameterFilterElement.AllRuleParametersApplicable( doc, framework.List[DB.ElementId]([cat.Id]), rules): filter_cats.append(cat.Id) # create filter return DB.ParameterFilterElement.Create( doc, filter_name, framework.List[DB.ElementId](filter_cats), rules)
def create_tag_filter(tags, name_format=None, exclude=False): """Create standard rule-based filters for given tags (max of 3 tags). Args: tags (list[Tag]): list of tags to create filter for (max of 3) name_format (str, optional): format for naming the filter, must include `{all_or_none}` and `{tag_names}`. exclude (bool, optional): create exclusion filter, defaults to False Returns: list[DB.ParameterFilterElement]: list of created filters Example: >>> import tagsmgr >>> fname = 'CUSTOM {all_or_none} FILTER FOR {tag_names}' >>> tag_filters = tagmgr.create_tag_filter(tags, ... name_format=fname, ... exclude=True) [<Autodesk.Revit.DB.ParameterFilterElement object at ...>, <Autodesk.Revit.DB.ParameterFilterElement object at ...>] """ sfilters = [] # create filter name and check availability tags_col = join_tags(tags) if not name_format: name_format = tagscfg.TAG_FILTER_NAMING filter_name = name_format.format(all_or_none='NONE' if exclude else 'ALL', tag_names=tags_col.names) for exst_filter in revit.query.get_rule_filters(): if exst_filter.Name == filter_name: sfilters.append(exst_filter) return sfilters # get tags param id param_id = _get_tag_paramid() # create filter rule if HOST_APP.is_newer_than(2019, or_equal=True): rules = None else: rules = framework.List[DB.FilterRule]() param_prov = DB.ParameterValueProvider(param_id) param_contains = DB.FilterStringContains() for tag in tags: rule = DB.FilterStringRule(param_prov, param_contains, tag.name, False) if exclude: rule = DB.FilterInverseRule(rule) if HOST_APP.is_newer_than(2019, or_equal=True): if rules: rules = DB.LogicalOrFilter(rules, DB.ElementParameterFilter(rule)) else: rules = DB.ElementParameterFilter(rule) else: rules.Add(rule) # collect applicable categories cats = [] for cat in revit.query.get_all_category_set(): if DB.ParameterFilterElement.AllRuleParametersApplicable( revit.doc, framework.List[DB.ElementId]([cat.Id]), rules ): cats.append(cat.Id) # create filter sfilter = \ DB.ParameterFilterElement.Create(revit.doc, filter_name, framework.List[DB.ElementId](cats), rules) sfilters.append(sfilter) return sfilters