Revit API梁的净高分析

Posted airforce094

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Revit API梁的净高分析相关的知识,希望对你有一定的参考价值。

原理就是,先从梁的LocationCurve上取点,然后向板的上表面投影。如果有投影点,再从投影点(板上)向梁的底面投影,这时候如果有投影点的话就能得到距离了。

运用该分析的第一条件是梁是在板的上方,勿忘哈!

var beamBottomFaces = FaceUtils.GetBottomFaces(beam); //这个方法是自己封装的
if (null != beamBottomFaces && beamBottomFaces.Any())
{
    var beamLocationCurve = beam.Location as LocationCurve;
    var beamCurve = beamLocationCurve.Curve;
    if (beamCurve != null)
    {
         if (beamCurve is Line)
         {
              beamCurve = GetExtLocationCurve(beamCurve); //如果LocationCurve是Line,最好做个延伸算法来延长,不然有些梁因为扣减的话,locationCurve容易缺少一部分
         }
         var beamPoints = GetPoints(beamCurve, pointRange); //pointRange是取点间隔
         if (beamPoints != null && beamPoints.Any())
         {
              var floorDataList = GetBeamFloorsPairCore(beamBottomFaces, beamPoints, floors); //floors为建筑板                               
         }
    }
}

 

LocationCurve的延伸:

private Curve GetExtLocationCurve(Curve curve)
{
     XYZ dir0 = XYZ.Zero;
     XYZ dir1 = XYZ.Zero;
     if (curve is Line)
     {
          dir0 = (curve as Line).Direction.Negate();
          dir1 = (curve as Line).Direction;
     }
      Curve extCurve = Line.CreateBound(curve.GetEndPoint(0) + 1E3 * dir0, curve.GetEndPoint(1) + 1E3 * dir1);
      return extCurve;
}

 

在Curve上按PointRange选取点位:

private List<XYZ> GetPoints(Curve curve, double pointRange)
{
       var points = new List<XYZ>();
       var beamLength = curve.Length;
       var pointsNumber = beamLength % pointRange == 0 ? ((beamLength / pointRange) - 1) : Math.Floor((beamLength / pointRange));

       for(var i = 1; i <= pointsNumber; i++)
       {
          var point = curve.Evaluate(pointRange * i, false);
          points.Add(point);
       }
       return points;
}

 

 获取距离:

private List<KeyValuePair<Element, List<KeyValuePair<XYZ, double>>>> GetBeamFloorsPairCore(List<PlanarFace> beamBottomFaces, IEnumerable<XYZ> beamPoints, List<Element> floors)
{
      var floorDataList = new List<KeyValuePair<Element, List<KeyValuePair<XYZ, double>>>>();
      //寻找每一块结构梁下的板
      foreach (var floor in constructionFloors)
      {
         //获取该板的最上点坐标
         var floorTopFaces = FaceUtils.GetTopFaces(floor);
         if (null != floorTopFaces && floorTopFaces.Any())
         {
              var defaultFloorOriginZ = floorTopFaces.FirstOrDefault().Origin.Z;
              foreach (var tf in floorTopFaces)
              {
                   var originZ = tf.Origin.Z;
                   if (defaultFloorOriginZ <= originZ)
                   {
                       defaultFloorOriginZ = originZ;
                   }
              }

                   
              var defaultBeamOriginZ = beamBottomFaces.FirstOrDefault().Origin.Z;
              foreach (var bf in beamBottomFaces)
              {
                   var originZ = bf.Origin.Z;
                   if (defaultBeamOriginZ >= originZ)
                   {
                       defaultBeamOriginZ = originZ;
                   }
              }
              //板在梁下面
              var isLower = defaultFloorOriginZ < defaultBeamOriginZ;

              if (isLower)
              {
                   var datalist = new List<KeyValuePair<XYZ, double>>();
                   //梁上一点能投影到板上
                   foreach (var point in beamPoints)
                   {
                       foreach (var tf in floorTopFaces)
                       {
                           var isProject = tf.Project(point);
                           if (null != isProject)
                           {
                               //投影到板上点的坐标
                               var projectPoint = isProject.XYZPoint;

                               //投影点到梁上点的距离
                               foreach (var bf in beamBottomFaces)
                               {
                                   var bp = bf.Project(projectPoint);
                                   if (null != bp)
                                   {
                                       var distance = bp.Distance;
                                       distance = UnitUtils.ConvertFromInternalUnits(distance, DisplayUnitType.DUT_MILLIMETERS);
                                       distance = Math.Floor(distance);

                                       var pointAndDistance = new KeyValuePair<XYZ, double>(projectPoint, distance);
                                       datalist.Add(pointAndDistance);
                                       break;
                                    }
                                }
                            }
                        }                            
                    }

                    if (datalist != null && datalist.Any())
                    {
                       var floorAndData = new KeyValuePair<Element, List<KeyValuePair<XYZ, double>>>(floor, datalist);
                       floorDataList.Add(floorAndData);
                    }
                }
           }
     }
     return floorDataList;
}

 

以上是关于Revit API梁的净高分析的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Revit API 调用 Revit 清除按钮

Revit API调用Revit内部命令PostableCommand

Revit API二次开发入门,完整学习流程,附源码

Revit API获取链接模型中构件

Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段

在 Revit api 中创建门的详细视图