• revit二次开发——过滤器


    一个简单的过滤器

    过滤器

    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;
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    注意:初次创建该对象的时候,是没有应用任何的过滤器的,如果这时试图从该对象中
    迭代或者获取元素列表,会有异常抛出。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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
  • 相关阅读:
    时间序列数据Correlogram图分析
    详情图怎么做二维码?批量线上图片生码图文教学
    [MQ] MQ的应用场景及Docker安装RabbitMQ
    计算机毕业设计Java红色景点自驾游网站管理系统(源码+系统+mysql数据库+lw文档)
    Unity 控制物体透明度变化
    CSS:走进position属性(二)
    基于JAVA门诊预约挂号系统计算机毕业设计源码+数据库+lw文档+系统+部署
    记一次Docker容器失败的逃逸
    程序员面对生活
    HPC、AI与云计算:当智能时代三叉戟在亚马逊云科技完美融合
  • 原文地址:https://blog.csdn.net/weixin_44037272/article/details/126408811