revit二次开发——过滤器基础

一个简单的过滤器

  • 过滤器
    • 1.1 过滤器
    • 1.2 结果集

过滤器

ElementQuickFilter。 快速过滤器仅对ElementRecord进行操作,是一个低内存占用的类,以一个有限接口来读取图元属性。被快速过滤器丢弃的图元不会展开到内存中。
ElementSlowFilter。 慢速过滤器首先需要获取图元并展开到内存中。因此,更为可取的方法是,将慢速过滤器与至少一个快速过滤器结合使用,尽量减少展开到内存的图元数量,以对照此过滤器设置的标准进行评价。
ElementI ogicalFilter.逻辑过滤器逻辑组合两个或更多过滤器。Revit 以使过滤器执行最快为优先评估条件,可能会将合成过滤器重新排序。

用来迭代以及过滤元素的主要类是收集器,它有三种构造方式

收集器的三种构造函数

构造函数 描述
FilteredElementCollector(Document document) 从一个文档构造,迭代会从文档所有的元索进行
FilteredElementCollector( Document document,ICollection< < Elementld > elementlds) 从一个文档和ElementID集合构造,迭代会从这传进来的集合中进行
FilteredElementCollector( Document document,Elementld viewld) 从一个文档和一个视图构造,迭代会从所有在传进来的视图中所见的元素中进行

1.1 过滤器

过滤器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( )。
这些方法返回收集器本身,并允许不同的过滤器链式调用。

1.2 结果集

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();

你可能感兴趣的:(revit二次开发,c#,revit,Revit二次开发,BIM二次开发)