13. Revit API: Filter(过滤器)

13. Revit API: Filter(过滤器)

前言

在讲Selection之前,还是有必要先了解一下的过滤器的。

对了,关于查找一些比较偏的功能或者API的用法,可以这样查找

关键词 site:https://thebuildingcoder.typepad.com/

site是高级搜索指令,表示从目标网址查找,不同的浏览器都有各自的指令,但部分是通用的。

网站thebuildingcoder里有许多关于Revit的有用的信息。

回到主题,这篇来讲一讲Filter


一、Filter是什么

如其意,Filter就是过滤器,用来过滤/查找我们需要的元素,满足条件的留下,就和用筛子筛豆子一样。当然我们可以遍历检索,但效率低。为了解决效率问题,Revit内置了一些Filter,我们可以直接使用。

在Revit中,Filter相关的类,可以划分为3块

  1. 收集器(Collector),用来执行过滤器,返回过滤结果,且内部封装有过滤器的简单调用方法。
  2. 过滤器(xxFilter),具体的过滤器,按特定的规则进行过滤。
  3. 过滤规则(FilterRule),一些规则,可以有限的影响过滤操作。

下面分别对这3块内容进行讲解。

更具体的类图如下。FilteredWorksetCollector此篇不涉及,我目前还不知道Workset是个什么东西。

二、ElementFilter

先看ElementFilter,它是一众过滤器的基类,并直接派生出3种过滤器。

按照其功能或特性,分别为

  • ElementLogicalFilter:逻辑过滤器,用来对多种过滤器进行组合
  • ElementQuickFilter:快过滤器,采用一个叫ElementRecord的低内存类进行检索,相当于一个包含少量的必要的信息的记录/映射。
  • ElementSlowFilter:慢过滤器,慢是相对于快过滤器的,作用于已展开的Element上,也就是读的信息更多,可以执行更细致的过滤。在使用时,通常会先使用快过滤器缩小范围,以提高效率。

先看看基类ElementFilter吧。

类成员 描述
Inverted { get; } 表示是否反转过滤,True则改为保留不满足 条件的。 反转过滤需要在构造函数上传参确定。
PassesFilter(..) 验证给定元素是否可以通过验证

2.1. ElementLogicalFilter(逻辑过滤器)

逻辑过滤器(ElementLogicalFilter)是用来组合一系列具体的过滤器的。

它本身未公开构造函数,只能通过其派生出的2个子类来构建。

子类名称很直观:

  • 逻辑与(LogicalAndFilter):完成全部过滤器验证,才能保留下来
  • 逻辑或(LogicalOrFilter):完成任意过滤器验证,就可以保留下来

下面的例子,使用了类型过滤器检测地板类型,和类过滤器检测Wall类。并使用收集器执行与结果输出。

csharp 复制代码
private List<ElementId> TestLogicalFilter(Document document)
{
    // 1.collector
    FilteredElementCollector collector = new FilteredElementCollector(document);

    // 2.Filter
    ElementCategoryFilter categoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Floors);
    ElementClassFilter classFilter = new ElementClassFilter(typeof(Wall));

    // logical AND
    LogicalAndFilter logicalAndFilter = new LogicalAndFilter(categoryFilter, classFilter);
    // logical OR
    LogicalOrFilter logicalOrFilter = new LogicalOrFilter(categoryFilter, categoryFilter);

    // 3.wherePasses
    collector.WherePasses(logicalAndFilter);
    //collector.WherePasses(logicalOrFilter);

    // 4.collect
    return collector.ToElementIds().ToList();
}

3.2. ElementQuickFilter(快过滤器)

快过滤器(ElementQuickFilter)由于只拿到Element的一点点信息,所以其子类的过滤规则都比较简单。

都过滤些什么呢?类、类型、包围盒之类的基本是。具体就不列了,看上面的图片,或者翻看文档都可以。

有几个特别的,简单提一下。

  • ElementMulti...Filter:一次塞入多个类/类型
  • ExclusionFilter:排除过滤器,比如进行"查找所有未选中的墙体"这个操作。
  • ExtensibleStorageFilter:扩展存储过滤器,如果用了扩展存储,那这个就很有用。

至于使用上,就按照上面的示例代码那样:

  1. 创一个收集器
  2. New一些过滤器
  3. 让收集器WherePasses过滤器
  4. 从收集器上拿到元素(ID)集合。

对于包围盒过滤器存在的问题,看Revit获取元素Solid和计算包围盒

简单来说就是Element.BoundingBox的问题,它会将非几何结构也计入到元素范围中,这当然是合理的,但是"反直觉"。

3.3. ElementSlowFilter(慢过滤器)

慢过滤器(ElementSlowFilter)检索了更多的元素信息,相较于快过滤器慢一些,相对的,慢过滤器上的规则就更多样。

同样的,不一一列出各个过滤器。比较常用的,就FamilyInstanceFilter吧。

还有一个最特殊的,元素参数过滤器(ElementParameterFilter),因为这是唯一用到FilterRule的过滤器了。这在后面过滤器规则那段一起讲。


三、FilteredElementCollector

看到这儿,我们已经对收集器(FilteredElementCollector)有所了解。

先创建收集器,再创建过滤器,然后进行运用,最后拿到结果。

流程很丝滑,但不够简洁。对此,收集器本身封装了常用过滤器的创建方法,并可采用链式结构调用,这样就极大的简化了过滤操作。

同样的,对于上面的代码示例,我们可以这样进行简写。

csharp 复制代码
FilteredElementCollector collector = new FilteredElementCollector(document);
var ids = collector
    .OfCategory(BuiltInCategory.OST_Floors)
    .OfClass(typeof(Wall))
    .ToElementIds().ToList();

通过这种方式,就能将一些单条件的过滤器快速运用到收集器上。

构造函数:

Constructors Description
FilteredElementCollector(Document) 目标元素为整个文档
FilteredElementCollector(Document, ViewId) 目标元素为指定视图种可见的元素
FilteredElementCollector(Document, List) 目标元素为传入的元素

方法:

Methods Description
ToElementIds ToElements 获取过滤后的元素ID集合 获取过滤后的元素集合
WherePasses 应用过滤器
UnionWith 和另一个收集器的结果合并
OfClass OfCategory(/Id) 应用类过滤器(ElementClassFilter) 应用类型过滤器(ElementCategoryFilter)
OwnedByView 应用当前视图过滤器(ElementOwnerViewFilter)
Excluding 应用排除过滤器(ExclusionFilter)
WhereElementIsCurveDriven WhereElementIs(/Not)ElementType WhereElementIsViewIndependent 应用曲线驱动验证过滤器(ElementIsCurveDrivenFilter) 应用元素验证过滤器(ElementIsElementTypeFilter) 应用(ElementOwnerViewFilter)
ContainedInDesignOption 应用(ElementDesignOptionFilter)

四、FilterRule

过滤规则(FilterRule)允许开发者自定义一些过滤条件。

前面也说了,元素参数过滤器(ElementParameterFilter)是唯一和FilterRule够上的过滤器,它是一个慢过滤器,毕竟涉及到元素的参数信息了,它的构造函数要求传入FilterRule。

但元素参数过滤器并不是RevitAPI种唯一使用过滤规则的类,还有一个非常有迷惑性的类,叫ParameterFilterElement(参数过滤器元素)。

ParameterFilterElement:一个类似Collector的东西,里面封装了并提供了一些过滤规则相关的方法。

4.1. FilterRule的派生类

看下图(最上方大图的一部分)

  • FilterCategoryRule:定义类型过滤规则,相当于一个慢速的类型过滤器
  • FilterInverseRule:定义反转过滤规则,效果用反转过滤器
  • FilterValueRule:定义值过滤规则。
  • SharedParameterApplicableRule:定义共享参数过滤规则

这里有个叫FilterCategoryRule的规则,效果上完全就是一个慢速版的类型过滤器。

关于这部分运用,主要是在 值过滤规则 上,我们来看看。

4.2. FilterValueRule(值过滤规则)

要定义值过滤规则,需要有两个东西:

  1. 值的来源(ParameterValueProvider
  2. 值的验证比较方式(RuleEvaluator
4.2.1. ParameterValueProvider(值提供者)

我们先来看看值的获取。

好吧,看文档有点迷惑,直接看例子:

c 复制代码
// 获取元素的"面积"参数 
ElementId areaParamId = new ElementId(BuiltInParameter.HOST_AREA_COMPUTED);
ParameterValueProvider doubleValueProvider = new ParameterValueProvider(areaParamId);
4.2.2. RuleEvaluator(验证器)

不同类型的值,有不同的比较方式。

a) 字符串: FilterStringRuleEvaluator

  • FilterStringBeginsWith:开始于
  • FilterStringEndsWith:结束于
  • FilterStringContains:包含
  • FilterStringGreater(/OrEqual):排序在后(或等于)
  • FilterStringLess(/OrEqual):排序在前(或等于)

b) 数字: FilterNumericRuleEvaluator

  • FilterNumericEquals:等于
  • FilterNumericGreater(/OrEqual):大于(或等于)
  • FilterNumericLess(/OrEqual):小于(或等于)

4.2.3. 代码示例

结合一个代码示例来看看吧。

以下代码:检索结构用途为"非承重"、面积大于等于1000平方英尺的墙体。

c 复制代码
private List<ElementId> TestParameterFilter(Document document)
{
    // 1. collector
    FilteredElementCollector collector = new FilteredElementCollector(document);

    // 2. rule
    // 2.1. category rule
    FilterCategoryRule filterCategoryRule = new FilterCategoryRule([new ElementId(BuiltInCategory.OST_Walls)]);  // 墙

    // 2.2. value rule => string
    ParameterValueProvider stringValueProvider = new ParameterValueProvider(new ElementId(BuiltInParameter.WALL_STRUCTURAL_USAGE_PARAM));  // 结构用途
    FilterStringRuleEvaluator stringEvaluator = new FilterStringEquals();  // 等于
    FilterStringRule stringRule = new FilterStringRule(stringValueProvider, stringEvaluator, "非承重", false);

    // 2.3. value rule => number => double
    ElementId areaParamId = new ElementId(BuiltInParameter.HOST_AREA_COMPUTED);
    ParameterValueProvider doubleValueProvider = new ParameterValueProvider(areaParamId);  
    FilterNumericRuleEvaluator doubleEvaluator = new FilterNumericGreaterOrEqual();  // 大于等于
    FilterDoubleRule doubleRule = new FilterDoubleRule(doubleValueProvider, doubleEvaluator, 1000, 10e-3);

    // 3. filter
    ElementParameterFilter elementParameterFilter = new ElementParameterFilter([filterCategoryRule, stringRule, doubleRule]);

    // 4. result
    return collector.WherePasses(elementParameterFilter).ToElementIds().ToList();
}

使用Revit自带的项目"Technical_school-current_m.rvt"进行验证。

将上面检索到的墙体放入选择列表中,效果如下图:


总结

这篇讲解了过滤器相关的API以及使用方法,我觉得还是比较全面的😺。

这篇又提到了哪些本篇范围外的呢,参数(Parameter),平方英尺/单位(Unit),放入选择列表(Selection)。

下一篇,就写Selection命名空间下的那几个了。

相关推荐
HSunR2 分钟前
概率论 期末 笔记
笔记·概率论
红色的山茶花13 分钟前
YOLOv9-0.1部分代码阅读笔记-loss_tal.py
笔记·深度学习·yolo
车轮滚滚__1 小时前
uniapp对接unipush 1.0 ios/android
笔记
云边有个稻草人4 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
冷眼看人间恩怨12 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
Hejjon18 小时前
SpringBoot 整合 SQLite 数据库
笔记
西洼工作室20 小时前
【java 正则表达式 笔记】
java·笔记·正则表达式
初学者7.21 小时前
Webpack学习笔记(2)
笔记·学习·webpack
新手上路狂踩坑1 天前
Android Studio的笔记--BusyBox相关
android·linux·笔记·android studio·busybox
stm 学习ing1 天前
HDLBits训练3
c语言·经验分享·笔记·算法·fpga·eda·verilog hdl