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;
}
相关推荐
张人玉2 小时前
C# TCP 客户端开发笔记(TcpClient)
笔记·tcp/ip·c#
张人玉6 小时前
C# 通讯关键类的API
开发语言·c#
William_cl14 小时前
C# MVC 修复DataTable时间排序以及中英文系统的时间筛选问题
开发语言·c#·mvc
c#上位机14 小时前
wpf之RelativeSource用法总结
c#·wpf
Dm_dotnet15 小时前
WPF应用最小化到系统托盘
c#
*长铗归来*16 小时前
ASP.NET Core Web API 中控制器操作的返回类型及Swagger
后端·c#·asp.net·.netcore
R-G-B19 小时前
【06】C#入门到精通——C# 多个 .cs文件项目 同一项目下添加多个 .cs文件
开发语言·c#·c# 多个 .cs文件项目
懒人Ethan1 天前
解决一个C# 在Framework 4.5反序列化的问题
java·前端·c#
mysolisoft2 天前
Avalonia+ReactiveUI实现记录自动更新
c#·avalonia·reactiveui·sourcegenerator
心疼你的一切2 天前
使用Unity引擎开发Rokid主机应用的模型交互操作
游戏·ui·unity·c#·游戏引擎·交互