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

前言

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

内容

Revit SDK 介绍:MeasurePanelArea 统计分割表面中族的面积_第1张图片

本例子的逻辑相对来说比较简单,主要是对 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的面积上限和下限

下图为启动界面:
Revit SDK 介绍:MeasurePanelArea 统计分割表面中族的面积_第2张图片

获取所有分割表面

用于获取特定类型 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;
}

获取分割表面的逻辑:

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)的逻辑框架:

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);
      }
   }
}

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

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;
}

你可能感兴趣的:(Revit,SDK,介绍,C#)