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;
}
相关推荐
上位机付工5 小时前
C#与倍福TwinCAT3进行ADS通信
开发语言·c#
土了个豆子的6 小时前
02.继承MonoBehaviour的单例模式基类
开发语言·visualstudio·单例模式·c#·里氏替换原则
疯狂的维修6 小时前
c#中public类比博图
c#·自动化
土了个豆子的9 小时前
03.缓存池
开发语言·前端·缓存·visualstudio·c#
xiaowu0801 天前
策略模式-不同的鸭子的案例
开发语言·c#·策略模式
VisionPowerful1 天前
九.弗洛伊德(Floyd)算法
算法·c#
ArabySide1 天前
【C#】 资源共享和实例管理:静态类,Lazy<T>单例模式,IOC容器Singleton我们该如何选
单例模式·c#·.net core
gc_22991 天前
C#测试调用OpenXml操作word文档的基本用法
c#·word·openxml
almighty271 天前
C#海康车牌识别实战指南带源码
c#·海康车牌识别·c#实现车牌识别·车牌识别源码·c#车牌识别
c#上位机2 天前
wpf之TextBlock
c#·wpf