元素Element过滤器的概念和使用
Revit API 提供了元素过滤器,用来遍历元素以及元素的ID。这些过滤器为各种不同的应用程序获取元素提供了更灵活更实用的接口。
(1)收集器FilteredElementCollector
用来迭代以及过滤元素的主要类是收集器,它有三种构造方式。
构造函数 |
描述 |
FilteredElementCollector(Document document) |
从一个文档构造,迭代会从文档的所有元素来进行 |
FilteredElementCollector(Document document,ICollection<ElementId> elementIds) |
从一个文档和ElementId集合来构造,迭代会从传入的集合中进行 |
FilteredElementCollector(Document ElementId viewId) |
从一个文档和一个视图来构建,迭代从所有在传进来的视图中所见的元素中进行 |
FilteredElementCollector提供了一系列的方法,允许用户设置查询和过滤用户感兴趣的元素集:
例子:
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { try { Document document = revit.Application.ActiveUIDocument.Document; //创建一个类别过滤器来过滤出所有的内建类型为OST_StackedWalls的元素 ElementCategoryFilter wallsCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_StackedWalls); FilteredElementCollector collector = new FilteredElementCollector(document); collector.OfClass(typeof(Wall)).WherePasses(wallsCategoryFilter); ICollection<ElementId> foundIds = collector.ToElementIds(); string prompt = "The ids of the StackedWalls in the current document are:"; foreach (ElementId id in foundIds) { prompt += "\n\t" + id.IntegerValue; } TaskDialog.Show("Revit", prompt); } catch (Exception e) { message = e.Message; return Autodesk.Revit.UI.Result.Failed; } return Autodesk.Revit.UI.Result.Succeeded; } |
向收集器设置完必须的过滤器之后,就可以获取符合条件的元素了,有几种方式:
■FilteredElementCollector支持foreach语法:
Document document = revit.Application.ActiveUIDocument.Document; FilteredElementCollector collector = new FilteredElementCollector(document); collector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Levels)) .WhereElementIsNotElementType(); foreach(Level level in collector)//收集器直接支持c# foreach语法。 { TaskDialog.Show("Level Name", level.Name); } |
■FilteredElementCollector支持LINQ:FilteredElementCollector实现了IEnumerable接口,所以支持LINQ查询语句和查询:
Document document = revit.Application.ActiveUIDocument.Document; FilteredElementCollector collector = new FilteredElementCollector(document); collector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Levels)); //LINQ查询:找到名字为“Level 1”的标高 var levelElements = from element in collector where element.Name == "Level 1" select element; List ElementId level1Id = levels[0].Id; |
(2)元素过滤器的层次
快速过滤器:只检查记录的元素并防止元素在内存中展开,可以提高效率减少内存开销。
慢速过滤器:先在内存中获取和展开元素,再进行查询,在效率上比较低,推荐的方法是慢速过滤器和快速过滤器结合起来,会减少展开元素的数量。
逻辑过滤器:由两个或者两个以上的过滤器逻辑组成的过滤器。
(3)内建的过滤器
为了方便使用,Revit提供了一些内置(预制)的过滤器,有些提供了FileterElementCollector的快捷方法:
内建过滤器 |
类型 |
符合条件值 |
快捷方法 |
LogicalAndFilter |
逻辑 |
必须符合两个或者两个以上的过滤器元素 |
WherePasses():添加另外过滤器。 IntersectWith():合并两个独立的过滤器的集合 |
LogicalOrFilter |
逻辑 |
必须符合两个或者两个以上的过滤器中的其中一个过滤器的元素 |
UnionWith():合并两个独立的过滤器集合。 |
ElementCategoryFilter |
快 |
符合传入类别ID的元素 |
OfCategoryId() |
ElementMulticategoryFilter |
快 |
符合任意一个传入类别ID的元素 |
无 |
ElementClassFilter |
快 |
符合传入类的元素 |
OfClass() |
ElementMulticlassFilter |
快 |
符合任意一个传入类的元素 |
无 |
ElementIsElementTypeFilter |
快 |
是元素类型的元素 |
WhereElementIsElementType(), WhereElementIsNotElementType() |
ElementOwnerViewFilter |
快 |
是视图相关的元素 |
OwnedByView(), WhereEmlementIsViewIndependent() |
ElementDesignOptionFilter |
快 |
符合在特定设定选项的元素 |
ContainedInDesignOption() |
ElementIsCurveDrivenFilter |
快 |
是由线驱动的元素 |
WhereElementIsCurveDriven() |
ElementStructuralTypeFilter |
快 |
符合给定结构驱动的元素 |
无 |
ElementWorksetFilter |
快 |
符合在给定工作集里面的元素 |
无 |
FamilySombolFilter |
快 |
特定的族类型 |
无 |
ExclusionFilter |
快 |
除传入过滤器的元素外的所有元素 |
Excluding() |
BoundingBoxIntersectsFilter |
快 |
其边界盒与给定的轮廓(outline)相交的元素 |
无 |
BoundingBoxIsInsideFilter |
快 |
其边界盒在给定的轮廓(outline)内的元素 |
无 |
BoundingBoxContainsPointFilter |
快 |
其边界盒包含了给定点的元素 |
无 |
FamilyInstanceFilter |
慢 |
特定族类型的实例 |
无 |
ElementLevelFilter |
慢 |
和指定标高(level)联系的元素 |
无 |
ElementFhaseStatusFilter |
慢 |
和指定阶段状态联系的元素 |
无 |
ElementParamterFilter |
慢 |
符合一个或多个参数集的元素 |
无 |
ElementIntersectsElementFilter |
慢 |
使用冲突检测来查找符合与传入的元素在几何上相交的元素 |
无 |
ElementIntersectsSolidFilter |
慢 |
使用接口检测来查找符合与传入的实体在几何Solid上相交的元素 |
无 |
PrimaryDesignOptionMemberFilter |
慢 |
主选项所拥有的元素 |
无 |
StructuralInstanceUsageFilter |
慢 |
属于传入的结构实例用法StructuralInstanceUsage的族实例 |
无 |
StructuralWallUsageFilter |
慢 |
属于传入的结构墙用法StructrualWallUsage的墙 |
无 |
StructuralMaterialTypeFilter |
慢 |
属于传入的结构材料类型的族实例 |
无 |
RoomFilter |
慢 |
房间元素 |
无 |
SpaceFilter |
慢 |
空间元素 |
无 |
AreaFilter |
慢 |
面积元素 |
无 |
RoomTagFilter |
慢 |
房间标签元素 |
无 |
SpaceTagFilter |
慢 |
空间标签元素 |
无 |
AreaTagFilter |
慢 |
面积标签元素 |
无 |
CurveElementFilter |
慢 |
属于或者不属于inverted传入线类型的线型元素 |
无 |
(4)快速过滤器ElementQuickFilter
1) ElementCategoryFilter
2) ElementClassFilter
3) ElementIsElementTypeFilter
4) FamilySymbolFilter
5) ExclusionFilter
(5)慢速过滤器ElementSlowFilter
1) ElementLevelFilter
2) ElementParameterFilter
3) CurveElementFilter
(6)逻辑过滤器ElementLogicalFilter
1) LogicalOrFilter
2) LogicalAndFilter
//============代码片段3-37:元素过滤器============ /// /// 使用ElementCategoryFilter过滤元素 /// void TestElementCategoryFilter(Document doc) { // 找到所有属于墙类别的元素:墙实例和墙类型都将会被过滤出来 FilteredElementCollector collector = new FilteredElementCollector(doc); ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Walls); ICollection foreach (Element elem in founds) { Trace.WriteLine(String.Format(" Element id: {0}, type: {1}", elem.Id.IntegerValue, elem.GetType().Name)); } }
//============代码片段3-38:元素过滤器============ /// /// 使用ElementClassFilter过滤元素 /// void TestElementClassFilter(Document doc) { // 找到所有属于FamilySymbol的元素:元素的子类也将被过滤出来 FilteredElementCollector collector = new FilteredElementCollector(doc); ElementClassFilter filter = new ElementClassFilter(typeof(FamilySymbol)); ICollection Trace.WriteLine(String.Format(" Found {0} FamilySymbols.", founds.Count)); }
//============代码片段3-39:元素过滤器============ /// /// 使用ElementIsElementTypeFilter过滤元素 /// void TestElementIsElementTypeFilter(Document doc) { // 找到所有属于ElementType的元素 FilteredElementCollector collector = new FilteredElementCollector(doc); ElementIsElementTypeFilter filter = new ElementIsElementTypeFilter(); ICollection Trace.WriteLine(String.Format(" Found {0} ElementTypes.", founds.Count)); }
//============代码片段3-40:元素过滤器============ /// /// 使用FamilySymbolFilter过滤元素 /// void TestFamilySymbolFilter(Document doc) { // 找到当前文档中族实例所对应的族类型 FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection foreach (ElementId famId in famIds) { collector = new FilteredElementCollector(doc); FamilySymbolFilter filter = new FamilySymbolFilter(famId); int count = collector.WherePasses(filter).ToElementIds().Count; Trace.WriteLine(String.Format(" {0} FamilySybmols belong to Family {1}.", count, famId.IntegerValue)); } }
//============代码片段3-41:元素过滤器============ /// /// 使用ExclusionFilter过滤元素 /// void TestExclusionFilter(Document doc) { // 找到所有除族类型FamilySymbol外的元素类型ElementType FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection
// 创建一个排除族类型FamilySymbol的过滤器 ExclusionFilter filter = new ExclusionFilter(excludes); ICollection Trace.WriteLine(String.Format(" Found {0} ElementTypes which are not FamilySybmols", founds.Count)); }
//============代码片段3-42:元素过滤器============ /// /// 使用ElementLevelFilter过滤元素 /// void TestElementLevelFilter(Document doc) { // 找到当前所有标高对应的所有元素 FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection foreach (ElementId levelId in levelIds) { collector = new FilteredElementCollector(doc); ElementLevelFilter filter = new ElementLevelFilter(levelId); ICollection Trace.WriteLine(String.Format(" {0} Elements are associated to Level {1}.", founds.Count, levelId.IntegerValue)); } }
//============代码片段3-43:元素过滤器============ /// /// 使用ElementParameterFilter过滤元素 /// void TestElementParameterFilter(Document doc) { // 找到所有id大于99的元素 BuiltInParameter testParam = BuiltInParameter.ID_PARAM; // 提供者 ParameterValueProvider pvp = new ParameterValueProvider(new ElementId((int)testParam)); // 评估者 FilterNumericRuleEvaluator fnrv = new FilterNumericGreater(); // 规则值 ElementId ruleValId = new ElementId(99); // Id 大于 99 // 创建规则过滤器及对应的元素参数过滤器 FilterRule fRule = new FilterElementIdRule(pvp, fnrv, ruleValId); ElementParameterFilter filter = new ElementParameterFilter(fRule); FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection foreach (Element elem in founds) { Trace.WriteLine(String.Format(" Element id: {0}", elem.Id.IntegerValue)); } }
//============代码片段3-44:元素过滤器============ /// /// 使用FamilyInstanceFilter过滤元素 /// void TestFamilyInstanceFilter(Document doc) { // 找到名字"W10X49"的族类型 FilteredElementCollector collector = new FilteredElementCollector(Document); collector = collector.OfClass(typeof(FamilySymbol)); var query = from element in collector where element.Name == "W10X49" select element; // Linq 查询 List ElementId symbolId = famSyms[0].Id;
// 创建过滤器并找到该族类型对应的所有族实例 collector = new FilteredElementCollector(doc); FamilyInstanceFilter filter = new FamilyInstanceFilter(doc, symbolId); ICollection foreach (FamilyInstance inst in founds) { Trace.WriteLine(String.Format(" FamilyInstance {0}, FamilySybmol Id {1}, Name: {2}",inst.Id.IntegerValue, inst.Symbol.Id.IntegerValue, inst.Symbol.Name)); } }
//============代码片段3-45:元素过滤器============ /// /// /// 使用CurveElementFilter 过滤元素 /// void TestCurveElementFilter(Document doc) { // 找到所有线元素类型对应的线型元素 Array stTypes = Enum.GetValues(typeof(CurveElementType)); foreach (CurveElementType tstType in stTypes) { if (tstType == CurveElementType.Invalid) continue; FilteredElementCollector collector = new FilteredElementCollector(Document); CurveElementFilter filter = new CurveElementFilter(tstType); int foundNum = collector.WherePasses(filter).ToElementIds().Count; Trace.WriteLine(String.Format(" {0}: elements amount {1}", tstType.GetType().Name, foundNum)); } }
//============代码片段3-46:元素过滤器============ /// /// 使用LogicalOrFilter过滤元素 /// void TestLogicalOrFilter(Document doc) { // 情形 1: 合并两个过滤器 -> // 找到所有属于墙类别或者属于标高类别的元素 ElementCategoryFilter filterWall = new ElementCategoryFilter(BuiltInCategory.OST_Walls); ElementCategoryFilter filterLevel = new ElementCategoryFilter(BuiltInCategory.OST_Levels); LogicalOrFilter orFilter = new LogicalOrFilter(filterWall, filterLevel); FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection foreach(Element elem in founds) { Trace.WriteLine(String.Format(" Element Id {0}, type {1}", elem.Id.IntegerValue, elem.GetType())); }
// 情形 2: 合并两个过滤器集合 -> 找到所有属于传入类型的元素 Type[] elemTypes = { typeof(Wall), typeof(Level), typeof(Floor), typeof(Rebar), typeof(MEPSystem)}; List foreach (Type elemType in elemTypes) { ElementClassFilter filter = new ElementClassFilter(elemType); filterSet.Add(filter); } orFilter = new LogicalOrFilter(filterSet); collector = new FilteredElementCollector(doc); founds = collector.WherePasses(orFilter).ToElements(); foreach (Element elem in founds) { Trace.WriteLine(String.Format(" Element Id {0}, type {1}", elem.Id.IntegerValue, elem.GetType().Name)); } }
//============代码片段3-47:元素过滤器============ /// /// 使用LogicalAndFilter过滤器 /// void TestLogicalAndFilter(Document doc) { // 情形 1: 合并两个过滤器 -> 找到所有符合特定设计选项的墙 ElementClassFilter wallFilter = new ElementClassFilter(typeof(Wall)); FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection foreach(ElementId curId in designOptIds) { ElementDesignOptionFilter designFilter = new ElementDesignOptionFilter(curId); LogicalAndFilter andFilter = new LogicalAndFilter(wallFilter, designFilter); collector = new FilteredElementCollector(doc); int wallCount = collector.WherePasses(andFilter).ToElementIds().Count; Trace.WriteLine(String.Format(" {0} Walls belong to DesignOption {1}.", wallCount, curId.IntegerValue)); }
// 情形 2: 找到所有符合特定设计选项并且其StructuralWallUsage 属于承重的墙 foreach (ElementId curId in designOptIds) { // 构造逻辑与过滤器 List filters.Add(wallFilter); filters.Add(new ElementDesignOptionFilter(curId)); filters.Add(new StructuralWallUsageFilter(StructuralWallUsage.Bearing)); LogicalAndFilter andFilter = new LogicalAndFilter(filters);
// 应用该过滤器并遍历获取到的元素 collector = new FilteredElementCollector(doc); int wallCount = collector.WherePasses(andFilter).ToElementIds().Count; Trace.WriteLine(String.Format(" {0} Bearing Walls belong to DesignOption {1}.", wallCount, curId.IntegerValue)); } }
//============代码片段3-48:元素过滤器============ FilteredElementCollector collector = new FilteredElementCollector(document); // 找到所有符合某种特定设计选项的墙 optionICollection |
1、收集器、元素过滤器的层次。
2、内建的元素过滤器。
3、常用的快速过滤器、慢速过滤器、逻辑过滤器的应用案例和代码操练。