Revit二次开发入门:第四章图元过滤

本章内容

1.元素过滤器ElementFilter

Revit API提供了元素过滤器,用来遍历元素以及元素的ID。这些过滤器为各种不同的应用程序获取元素提供了更灵活更实用的接口。

元素过滤器是一个检验一个元素是否符合某种标准的类。它被分为三个层次:

快速过滤器 QuickFilters 只检查记录的元素并防止元素在内存中展开。这种过滤器可以提高迭代的效率并减少内存的消耗 性能好,内存占用低
慢速过滤器 SlowFilters 现在内存中获取和展开元素,再进行查询,因此在效率上会比较低。推荐的方法是慢速过滤器和快速过滤器结合起来用,这样会减少展开元素的数量。 性能较差,耗时多,内存占用多
逻辑过滤器 LogicalFilters 由两个及以上的过滤器逻辑组成的过滤器 多个过滤器的组合

注意:无论应用的条件和过滤器的顺序是什么,Revit内部会对过滤器重新排序来减少元素的展开。

2.元素收集器FilterElementCollector

用来迭代以及过滤元素的主要类是收集器,它有三种构造方式,可根据具体情况使用任意一种。

构造函数 描述
FilteredElementCollector(Document document) 从一个文档构造,迭代文档中所有的元素
FilterElementCollector(Document document,Icollection<ElementId> elementIds) 从一个文档和ElementID集合构造,迭代在集合中进行
FilteredElementCollcetor(Document document,ElementId viewId) c从一个文档和一个试图构造,迭代从所有在传进来的视图中所见的元素中进行

1558659212846

3.应用过滤器

过滤操作的步骤:

4.快速过滤器QuickTilter

ElementCategoryFilter

ElementCategoryFilter是使用类别Category来查询元素的过滤器。

1558659997496

ElementClassFilter

ElementClassFilter是使用类来查询元素的过滤器,他将会精确匹配传入的类或者该类的子类。通用的按元素类进行查找可替代其他Filter:

1558660418450

ElementIsElementTypeFilter

ElementIsElementTypeFilter是用来匹配元素类型的过滤器,可以过滤出文档中所有的元素类型的元素或者过滤出所有非元素类型的元素。

1558660636122

快捷方法:WhereElementIsElementType、WhereElementIsNotElementType

1558660696952

ExclusionFilter

ExclusionFilter是自动排除元素集的过滤器

1558660932100

快捷方法:Excluding

1558660955730

FamilySymbolFilter

FamilySymbolFilter是使用传入的族来得到其所有族类型的过滤器

1558662375219

常用子类

1558662500947

5.慢速管理器SlowFilter

ElementLevelFilter

ElementLeveFilter是使用关联的标高(Level)来匹配其关联或不关联的元素。

1558662823744

ElementParameterFilter

ElementParameterFilter是使用一个或者多个参数过滤规则来匹配元素的过滤器

1558663048486

FamilyInstanceFilter

FamilyInstanceFilter是使用族类型来匹配对应族实例元素的过滤器。

1558663159210

CurveElementFilter

CurveElementFilter是匹配线型元素的过滤器。如果想要找模型线、参考线等线型元素,使用这个过滤器会比较方便。

1558664672984

常用子类

1558665584388

6.逻辑过滤器LogicalFilter

1558678337286

LogicalOrFilter

LogicalOrfilter是过滤器的逻辑或集合,可以查找匹配符合任意一个过滤器条件的元素。

1558665880591

LogicalAndFilter

LogicalAndFilter是过滤器的的逻辑与集合,可以查找匹配符合所有过滤器条件的元素。

1558666112209

其他更多Filter

1558666197942

7.实例练习

实例练习1:元素过滤ElementFilter(1)

在范例图中计算过滤出所有型号为1200*1500mm,且标记为小于5的窗数量。识别并计算门窗总和。

1558678792693

代码

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;

namespace FiltersPractise {
    [TransactionAttribute(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    public class Class1 : IExternalCommand {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
            //FilterElementCollect的使用
            UIDocument uiDoc = commandData.Application.ActiveUIDocument;
            Document doc = uiDoc.Document;
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            //QuickFilter过滤所有窗
            collector = collector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilySymbol));
            //FamilyInstanceFilter找1200*1500mm的窗
            IEnumerable<Element> query = from element in collector
                                         where element.Name == "1200*1500mm"
                                         select element;
            List<Element> famSyms = query.ToList<Element>();
            ElementId symbolId = famSyms[1].Id;
            FamilyInstanceFilter fiFilter = new FamilyInstanceFilter(doc, symbolId);
            FilteredElementCollector c1 = new FilteredElementCollector(doc);
            ICollection<Element> found = c1.WherePasses(fiFilter).ToElements();
            //ElementParameterFilter找到标记小于五的窗
            ElementId ruleValId = new ElementId(-10010203);
            FilterRule fr = ParameterFilterRuleFactory.CreateLessRule(ruleValId, "5", true);
            ElementParameterFilter pFilter = new ElementParameterFilter(fr);
            FilteredElementCollector c2 = new FilteredElementCollector(doc);
            c2 = c2.OfCategory(BuiltInCategory.OST_Windows).WherePasses(fiFilter).WherePasses(pFilter);
            //LogicalOrFilter计算门窗总和
            ElementCategoryFilter doorFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
            ElementCategoryFilter windowFilter = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
            LogicalOrFilter lFilter = new LogicalOrFilter(doorFilter, windowFilter);
            FilteredElementCollector c3 = new FilteredElementCollector(doc);
            ICollection<Element> fds = c3.OfClass(typeof(FamilyInstance)).WherePasses(lFilter).ToElements();
            //taskdialog输出结果
            TaskDialog.Show("查找", "已找到型号为“1200*1500mm”的推拉窗" + found.Count.ToString() +
                                  "个\n其中标记小于5的有" + c2.ToList().Count.ToString() + "个\n门窗总和为:" +
                                  fds.Count.ToString());

            return Result.Succeeded;
        }
    }
}

实例练习2:元素过滤ElementFilter(3)

使用ElementInsteresectFilter进行冲突检查

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;

namespace Collision {
    [TransactionAttribute(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    public class Class1 : IExternalCommand {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
            UIDocument uiDoc = commandData.Application.ActiveUIDocument;
            Document doc = uiDoc.Document;
            Transaction tran = new Transaction(doc,"ExCom");
            tran.Start();
            Selection select = uiDoc.Selection;
            Reference r = select.PickObject(ObjectType.Element, "选择需要检查的墙");
            Element column = doc.GetElement(r);
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            //使用ElementIntersectFilter冲突检查
            ElementIntersectsElementFilter iFilter = new ElementIntersectsElementFilter(column, false);
            collector.WherePasses(iFilter);
            List<ElementId> excludes = new List<ElementId> {
                column.Id
            };
            collector.Excluding(excludes);
            List<ElementId> ids = new List<ElementId>();
            select.SetElementIds(ids);
            foreach (Element element in collector) {
                ids.Add(element.Id);
            }
            select.SetElementIds(ids);
            tran.Commit();
            return Result.Succeeded;
        }
    }
}