• 【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;
    }
  • 相关阅读:
    boost.property_tree的高级用法(你们没见过的操作)
    MFC- OnIdle空闲处理
    华为代码质量军规 (1) 数组访问,必须进行越界保护
    WinSocket 编程
    【C/C++】链表的理解与使用
    单链表
    C++ lambda表达式 (二)
    C++ lambda表达式 (一)
    C++11 volatile 类型
    关于结构体内存对齐方式的总结(#pragma pack()和alignas())
  • 原文地址:https://www.cnblogs.com/lovecsharp094/p/9104448.html
Copyright © 2020-2023  润新知