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 的模板方法

csharp 复制代码
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;
}

获取分割表面的逻辑:

csharp 复制代码
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);
      }
   }
}

对于每一个分割表面

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

csharp 复制代码
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);
      }
   }
}

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

csharp 复制代码
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;
}
相关推荐
0x000736 分钟前
译 Anders Hejlsberg 谈 C# 与 .NET
开发语言·c#·.net
Xin_ye100861 小时前
C# 零基础到精通教程 - 第十七章:前端集成——Blazor 基础
开发语言·c#
daopuyun1 小时前
《C#语言源代码漏洞测试规范》解读,如何依据GB/T 34946-2017标准建立代码测试技术体系
c#·代码测试·源代码安全检测
魔法阵维护师2 小时前
从零开发游戏需要学习的c#模块,第三十一章(技能冷却系统 —— 范围爆炸)
学习·游戏·c#
吴可可1233 小时前
ModelSpace常量正确用法解析
c#
影寂ldy3 小时前
C#List泛型集合
windows·c#·list
狂人开飞机4 小时前
01. 工厂模式(Factory Pattern)
设计模式·c#
我是唐青枫4 小时前
C#.NET YARP 服务发现实战:接入 Consul 和 Kubernetes 动态发现后端服务
c#·服务发现·.net
魔法阵维护师4 小时前
从零开发游戏需要学习的c#模块,第三十章(掉落物品 —— 血包与能量)
学习·游戏·c#