Revit二次开发入门:第四章图元过滤
本章内容
1.元素过滤器ElementFilter
Revit API提供了元素过滤器,用来遍历元素以及元素的ID。这些过滤器为各种不同的应用程序获取元素提供了更灵活更实用的接口。
元素过滤器是一个检验一个元素是否符合某种标准的类。它被分为三个层次:
快速过滤器 | QuickFilters | 只检查记录的元素并防止元素在内存中展开。这种过滤器可以提高迭代的效率并减少内存的消耗 | 性能好,内存占用低 |
---|---|---|---|
慢速过滤器 | SlowFilters | 现在内存中获取和展开元素,再进行查询,因此在效率上会比较低。推荐的方法是慢速过滤器和快速过滤器结合起来用,这样会减少展开元素的数量。 | 性能较差,耗时多,内存占用多 |
逻辑过滤器 | LogicalFilters | 由两个及以上的过滤器逻辑组成的过滤器 | 多个过滤器的组合 |
注意:无论应用的条件和过滤器的顺序是什么,Revit内部会对过滤器重新排序来减少元素的展开。
- 查找、过来、遍历元素
- 基于Document;支持特定View和元素集
- 支持Filter及复制的组合Filter
- Shortcut方法,快速返回
- 支持集合的合并
2.元素收集器FilterElementCollector
用来迭代以及过滤元素的主要类是收集器,它有三种构造方式,可根据具体情况使用任意一种。
构造函数 | 描述 |
---|---|
FilteredElementCollector(Document document) | 从一个文档构造,迭代文档中所有的元素 |
FilterElementCollector(Document document,Icollection<ElementId> elementIds) | 从一个文档和ElementID集合构造,迭代在集合中进行 |
FilteredElementCollcetor(Document document,ElementId viewId) | c从一个文档和一个试图构造,迭代从所有在传进来的视图中所见的元素中进行 |
3.应用过滤器
过滤操作的步骤:
- 新建FilterElementCollector实例 var coll=new FilterElementCollector(_doc);
- 添加过滤条件 coll.wherePasses(new ElementClassFilter(typeof(Wall)));
- 访问满足条件的对象 IList<Element> walls=wallTypeCollcetor1.ToElements();
4.快速过滤器QuickTilter
ElementCategoryFilter
ElementCategoryFilter是使用类别Category来查询元素的过滤器。
- 支持Element及ElementType
- 共有900+:OST_Door、OST_Column……
- 快捷方法:OfCategory/OfCategoryId
ElementClassFilter
ElementClassFilter是使用类来查询元素的过滤器,他将会精确匹配传入的类或者该类的子类。通用的按元素类进行查找可替代其他Filter:
- Room/Area/Space/…filter
- 快捷方法:OfClass
ElementIsElementTypeFilter
ElementIsElementTypeFilter是用来匹配元素类型的过滤器,可以过滤出文档中所有的元素类型的元素或者过滤出所有非元素类型的元素。
快捷方法:WhereElementIsElementType、WhereElementIsNotElementType
ExclusionFilter
ExclusionFilter是自动排除元素集的过滤器
快捷方法:Excluding
FamilySymbolFilter
FamilySymbolFilter是使用传入的族来得到其所有族类型的过滤器
常用子类
- Category
- Class
- CurveDriven
- ElementType
- OwnerView
- Workset
- FamilySymbol
- BoundingBox
5.慢速管理器SlowFilter
ElementLevelFilter
ElementLeveFilter是使用关联的标高(Level)来匹配其关联或不关联的元素。
ElementParameterFilter
ElementParameterFilter是使用一个或者多个参数过滤规则来匹配元素的过滤器
- 元素参数精确匹配
- RilterRule的用途
- ParameterFilterRuleFactory构造各种Rule
- 四种参数类型
- ==,!=,>=,<=,>,<…
FamilyInstanceFilter
FamilyInstanceFilter是使用族类型来匹配对应族实例元素的过滤器。
CurveElementFilter
CurveElementFilter是匹配线型元素的过滤器。如果想要找模型线、参考线等线型元素,使用这个过滤器会比较方便。
常用子类
- CurveElement
- Room/Area/Space
- FamilyInstance
- XXXUsage
- ElementIntersect
- ElementParameter
- ……
6.逻辑过滤器LogicalFilter
LogicalOrFilter
LogicalOrfilter是过滤器的逻辑或集合,可以查找匹配符合任意一个过滤器条件的元素。
LogicalAndFilter
LogicalAndFilter是过滤器的的逻辑与集合,可以查找匹配符合所有过滤器条件的元素。
其他更多Filter
7.实例练习
实例练习1:元素过滤ElementFilter(1)
在范例图中计算过滤出所有型号为1200*1500mm,且标记为小于5的窗数量。识别并计算门窗总和。
- FilteredElementCollector的使用
- QuickFilter及SlowFilter
- ElementParameterFilter
- LogicalFilter
代码
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;
}
}
}