• Revit SDK 介绍:MeasurePanelArea 统计分割表面中族的面积


    前言

    这个例子介绍如果从分割表面中,获取内部Tile(或者Panel)的族里面的几何实体的面的面积。

    内容

    在这里插入图片描述

    本例子的逻辑相对来说比较简单,主要是对 DividedSurface 和 Element 的API接口要熟悉。

    核心逻辑

    1. 设置单个面板Panel的面积上限和下限
    2. 获取所有分割表面
      1. 如果用户已经选择了分割表面,就使用当前选择
      2. 如果用户没有选择,就过滤出文件中的所有分割表面
    3. 对于每一个分割表面
      1. 查询获取它内部的 Panel Family Instance: ds.GetTileFamilyInstance(gn, 0);
      2. 遍历 Family Instance 的几何,得到所有的面
        1. 遍历输出面的面积到日志文件
        2. 记录最后一个面的面积(估计是因为是sample,代码写的比较随意)
      3. 根据Family Instance 最后一个面的面积,统计是符合要求、高于上限、低于下限

    设置单个面板Panel的面积上限和下限

    下图为启动界面:
    在这里插入图片描述

    获取所有分割表面

    用于获取特定类型 Element 的模板方法

    protected List<T> GetElements<T>() where T : Element
    {
       List<T> returns = new List<T>();
       FilteredElementCollector collector = new FilteredElementCollector(m_uiDoc.Document);
       ICollection<Element> founds = collector.OfClass(typeof(T)).ToElements();
       foreach (Element elem in founds)
       {
          returns.Add(elem as T);
       }
       return returns;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    获取分割表面的逻辑:

    private void GetDividedSurfaces(){
       // 获取所有的分割表面
       if (m_uiDoc.Selection.GetElementIds().Count == 0){
          m_dividedSurfaceList = GetElements<DividedSurface>();
          return;
       }
    
       // 后去用户选择的分割表面
       foreach (ElementId elementId in m_uiDoc.Selection.GetElementIds()){
          Element element = m_uiDoc.Document.GetElement(elementId);
          DividedSurface ds = element as DividedSurface;
          if (ds != null){
             m_dividedSurfaceList.Add(ds);
          }
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    对于每一个分割表面

    获取每一个分割表面中 Tile(或者Panel)的逻辑框架:

    for (int u = 0; u < ds.NumberOfUGridlines; u++){
       for (int v = 0; v < ds.NumberOfVGridlines; v++){
          GridNode gn = new GridNode(u, v);
          if (false == ds.IsSeedNode(gn)){
             continue;
          }
          FamilyInstance familyinstance = ds.GetTileFamilyInstance(gn, 0);
          if (familyinstance != null){
             // 获取族实例的面积
             double panelArea = GetAreaOfTileInstance(familyinstance);
          }
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    遍历获取族几何体面积的核心逻辑:

    private double GetAreaOfTileInstance(FamilyInstance familyinstance)
    {
       double panelArea = 0d;
       // 获取族实例的几何
       Autodesk.Revit.DB.Options opt = m_uiApp.Application.Create.NewGeometryOptions();
       opt.ComputeReferences = true;
       Autodesk.Revit.DB.GeometryElement geomElem = familyinstance.get_Geometry(opt);
       // 遍历几何
       IEnumerator<GeometryObject> Objects = geomElem.GetEnumerator();
       while (Objects.MoveNext()){
          GeometryObject geomObject1 = Objects.Current;
          // 获取实体,只支持族实例本身就是solid,或者是GeometryInstance,且其中包含 solid
          Solid solid = null;
          if (geomObject1 is Solid){
             solid = (Solid)geomObject1;
             if (null == solid){continue;}
          }
          else if (geomObject1 is GeometryInstance){
             GeometryInstance geomInst = geomObject1 as GeometryInstance;
             IEnumerator<GeometryObject> Objects1 = geomInst.SymbolGeometry.GetEnumerator();
             while (Objects1.MoveNext()){
                Object geomObj = Objects1.Current;
                solid = geomObj as Solid;
                if (solid != null) break;
             }
          }
          // 如果 solid 里没有 face,则跳过(未检查solid本身为null
          if (null == solid.Faces || 0 == solid.Faces.Size){ continue; }
          // 遍历输出面的面积到日志文件
          // 记录最后一个面的面积(估计是因为是sample,代码写的比较随意)
          foreach (Face face in solid.Faces) {
             panelArea = face.Area;
             m_writeFile.WriteLine(familyinstance.Id.IntegerValue + " : " + panelArea);
          }
       }
       return panelArea;
    }
    
    • 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
  • 相关阅读:
    【算法】传智杯练习赛:平等的交易
    前端工作总结249-uni-关闭onshow的加载方法uni.hideLoading
    【响应式】使用媒体查询实现响应式页面
    JDBC PreparedStatement 的命名参数实现
    从html radio到android RadioButton
    PythonStudy6
    高防服务器如何对异常流量进行识别
    力扣--268丢失的数字(三种解法)
    二、常见的EDID问题
    手机软件开发价格的大概范围是什么?
  • 原文地址:https://blog.csdn.net/weixin_44153630/article/details/132774078