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;
}
相关推荐
czhc114007566311 小时前
2026-09-03 博客:配置与密码 · 合并代码 · 超时排查
c#
格林威13 小时前
C#图像夜间识别率提升:使用OpenCvSharp和Halcon融合DeepSORT实现复杂场景下准确识别
开发语言·人工智能·数码相机·机器学习·计算机视觉·c#·视觉检测
曹牧15 小时前
C#:线程间操作无效,不是从创建控件线程访问
开发语言·c#
anlog1 天前
ini文件读取,EXE同目录文件读取
c#·ini
rockey6271 天前
AScript之编译递归函数
c#·.net·script·动态脚本
yue0081 天前
winform控件篇-按钮
c#
DevOpenClub1 天前
Markdown、HTML 和 PPT 如何稳定交付:文档转换任务的幂等发布流程
开发语言·前端·c#·html·powerpoint
软件黑马王子1 天前
3.单例模式问题1:构造函数
开发语言·单例模式·c#
软件黑马王子1 天前
4.单例模式问题2:重复挂载
开发语言·单例模式·c#
夏霞2 天前
c# 不支持的目标框架 解决方案
开发语言·c#