Beispiel #1
0
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
Beispiel #2
0
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 []
Beispiel #3
0
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)
Beispiel #4
0
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