ElementQuickFilter。 快速过滤器仅对ElementRecord进行操作,是一个低内存占用的类,以一个有限接口来读取图元属性。被快速过滤器丢弃的图元不会展开到内存中。
ElementSlowFilter。 慢速过滤器首先需要获取图元并展开到内存中。因此,更为可取的方法是,将慢速过滤器与至少一个快速过滤器结合使用,尽量减少展开到内存的图元数量,以对照此过滤器设置的标准进行评价。
ElementI ogicalFilter.逻辑过滤器逻辑组合两个或更多过滤器。Revit 以使过滤器执行最快为优先评估条件,可能会将合成过滤器重新排序。
用来迭代以及过滤元素的主要类是收集器,它有三种构造方式
收集器的三种构造函数
构造函数 | 描述 |
---|---|
FilteredElementCollector(Document document) | 从一个文档构造,迭代会从文档所有的元索进行 |
FilteredElementCollector( Document document,ICollection< < Elementld > elementlds) | 从一个文档和ElementID集合构造,迭代会从这传进来的集合中进行 |
FilteredElementCollector( Document document,Elementld viewld) | 从一个文档和一个视图构造,迭代会从所有在传进来的视图中所见的元素中进行 |
过滤器Revit API提供一种机制,用于过滤和迭代Revit文件中的图元。这是用于获取一组相关图元的最好方式,如文件中所有的墙或门。过滤器也可以用来寻找出一-组很具体的图元,如某一特定尺寸的所有的梁。
通过指定过滤器获取图元的基本步骤如下: .
(1)新建一个FilteredElementCollector;
(2)对它运用一个或多个过滤器;
(3)获取滤过的图元或图元ID (使用几种方法之一)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
namespace DemoRevitFilter
{
//属性,Revit 不会自动创建事务
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
//实现Revit API 中的 IExternalCommand 接口
public class DemoRevitFilter : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
//通过commandData获取UIDocument
UIDocument uidoc = commandData.Application.ActiveUIDocument;
//通过uidoc获取revit当前文档
Document doc = uidoc.Document;
//创建图元过滤集
FilteredElementCollector cltor = new FilteredElementCollector(doc);
//声明并初始化参数msg
string msg = string.Empty;
//声明一个图元集合
IList<Element> elementList = new List<Element>();
//使用类别过滤器找到所有墙实例
cltor.OfCategory(BuiltInCategory.OST_Walls);
elementList = cltor.ToElements();
//遍历得到名称和id
foreach (Element ele in elementList)
{
msg += ele.Name + ":" + ele.Id + "\n";
}
//输出显示
TaskDialog.Show(this.GetType().Name, msg);
return Autodesk.Revit.UI.Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Autodesk.Revit.UI.Result.Failed;
}
}
}
}
注意:初次创建该对象的时候,是没有应用任何的过滤器的,如果这时试图从该对象中
迭代或者获取元素列表,会有异常抛出。FilteredElementCollector提供了一.系列的方法,允许用户设置查询和过滤感兴趣的元素集:
●通用方法WherePasses( ),在收集器中应用单一的ElementFilter。该方法可以在结果中重复使用来增加不同的过滤器(filter)。
●快捷方法,不需要传初始化过滤器对象的易于使用的方法,相当于常用过滤器filter的快捷键。比如OfClass( ), OfCategoryId( ), OwnedByView( )。
●并集、交集等运算方法,比如UnionWith( )和IntersectWith( )。
这些方法返回收集器本身,并允许不同的过滤器链式调用。
FilteredElementCollector在应用过滤器后可直接ToElements, ToElementIds或者调用IEnumerable泛型接口支持的方法获得结果集,例如ToList()等等,请务必使用以上几种方式获得结果集
对FilteredElementCollector 应用-一个或多 个过滤器之后,过滤出的图元集可由以下三
种方式之一来检索:
(1)获取图元或图元ID的集合。
●ToElements(): 返回通过过滤器的所有图元。
●ToElementIds(): 返回通过过滤器所有图元的图元ID。
(2)获取匹配过滤器的第一个图元或图元ID。
●FirstElement(): 返回通过过滤器的第一个图元。
●FirstElementld(): 返回通过过滤器第一个图元的ID。
(3)获取图元ID或图元迭代器。
●GetElementIdIterator( ):返回通过过滤器的图元ID的FilteredElementIdIterator。
●GetElementIterator(): 返回通过过滤器的图元的FilteredElementIdIterator.
●GetEnumerator(): 返回一个lEnumerator
枚举,其遍历通过的图元集。
每次应只使用这几组方法其中之一;如果再调用其他方法来提取图元,采集器会重置。
因而,如果先前已获得一个迭代器,若再调用其他方法来提取图元,则会被中止,而不会遍历更多图元。
//============代码片段3-34:元素过滤器============
FilteredElementCollector collection = new FilteredElementCollector(RevitDoc);
ElementFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_StackedWalls);
collection.OfClass(typeof(Wall)).WherePasses(filter);
ICollection<ElementId> foundIds = collection.ToElementIds();
//============代码片段3-35:元素过滤器============
FilteredElementCollector collector = new FilteredElementCollector(m_doc);
// 查询并遍历文档中所有的Level
collector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Levels)).WhereElementIsNotElementType();
foreach(Level level in collector)
{
TaskDialog.Show("Level Name", level.Name);
}
//============代码片段3-36:元素过滤器============
FilteredElementCollector collector = new FilteredElementCollector(m_doc);
// 首先使用一个内建的过滤器来减少后面使用LINQ查询的元素数量
collector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Levels));
// LINQ查询:找到名字为"Level 1"的标高
var levelElements = from element in collector
where element.Name == "Level 1"
select element;
List<Autodesk.Revit.DB.Element> levels = levelElements.ToList<Autodesk.Revit.DB.Element>();
ElementId level1Id = levels[0].Id;
//============代码片段3-37:元素过滤器============
///
/// 使用ElementCategoryFilter过滤元素
///
void TestElementCategoryFilter(Document doc)
{
// 找到所有属于墙类别的元素:墙实例和墙类型都将会被过滤出来
FilteredElementCollector collector = new FilteredElementCollector(doc);
ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
ICollection<Element> founds = collector.WherePasses(filter).ToElements();
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<ElementId> founds = collector.WherePasses(filter).ToElementIds();
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<ElementId> founds = collector.WherePasses(filter).ToElementIds();
Trace.WriteLine(String.Format(" Found {0} ElementTypes.", founds.Count));
}
//============代码片段3-40:元素过滤器============
///
/// 使用FamilySymbolFilter过滤元素
///
void TestFamilySymbolFilter(Document doc)
{
// 找到当前文档中族实例所对应的族类型
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<ElementId> famIds = collector.OfClass(typeof(Family)).ToElementIds();
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<ElementId> excludes = collector.OfClass(typeof(FamilySymbol)).ToElementIds();
// 创建一个排除族类型FamilySymbol的过滤器
ExclusionFilter filter = new ExclusionFilter(excludes);
ICollection<ElementId> founds = collector.WhereElementIsElementType().WherePasses(filter).ToElementIds();
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<ElementId> levelIds = collector.OfClass(typeof(Level)).ToElementIds();
foreach (ElementId levelId in levelIds)
{
collector = new FilteredElementCollector(doc);
ElementLevelFilter filter = new ElementLevelFilter(levelId);
ICollection<ElementId> founds = collector.WherePasses(filter).ToElementIds();
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<Element> founds = collector.WherePasses(filter).ToElements();
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<Autodesk.Revit.DB.Element> famSyms = query.ToList<Autodesk.Revit.DB.Element>();
ElementId symbolId = famSyms[0].Id;
// 创建过滤器并找到该族类型对应的所有族实例
collector = new FilteredElementCollector(doc);
FamilyInstanceFilter filter = new FamilyInstanceFilter(doc, symbolId);
ICollection<Element> founds = collector.WherePasses(filter).ToElements();
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<Element> founds = collector.WherePasses(orFilter).ToElements();
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<ElementFilter> filterSet = new List<ElementFilter>();
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<ElementId> designOptIds = collector.OfClass(typeof(DesignOption)).ToElementIds();
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<ElementFilter> filters = new List<ElementFilter>();
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<ElementId> walls = collector.OfClass(typeof(Wall)).ContainedInDesignOption(myDesignOptionId).ToElementIds();