Browse Source

mxg:空间导出添加OutLine2字段

mengxiangge 5 years ago
parent
commit
7e5009b3b7

+ 1 - 0
Executer/DataExport/JBIM/Component/Space.cs

@@ -24,5 +24,6 @@ namespace JBIM.Component
         }
         public List<List<BimId>> BoundarySegments { get; private set; }
         public double Height { get; set; }
+        public List<Polygon> OutLine2 { get; set; }
     }
 }

+ 4 - 1
Executer/DataExport/RevitToJBim/ComponentParse/ParseSpace.cs

@@ -20,6 +20,7 @@ using JBoundarySegment = JBIM.Component.BoundarySegment;
 using Autodesk.Revit.DB;
 using JBIM.Definition;
 using RevitExport.Export;
+using RevitToJBim.Extension;
 using RevitToJBim.ParseData;
 
 namespace RevitToJBim.ComponentParse
@@ -58,7 +59,7 @@ namespace RevitToJBim.ComponentParse
             //Parameters
             bimObject.Parameters = RevitUtil.GetSpaceParameters(space);
             var options = new SpatialElementBoundaryOptions();
-            options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish;
+            //options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish;
             var segments = space.GetBoundarySegments(options);
             if (segments != null)
             {
@@ -100,6 +101,8 @@ namespace RevitToJBim.ComponentParse
                         bimObject.BoundarySegments.Add(segmentBimids);
                     }
                 }
+                //外轮廓
+                bimObject.OutLine2 = space.GetSpaceOutline();
             }
  
             context.AddBimObject(bimObject);

+ 213 - 0
Executer/DataExport/RevitToJBim/Extension/SpaceExtension.cs

@@ -10,8 +10,11 @@ using System.Text;
 using System.Threading.Tasks;
 using Autodesk.Revit.DB;
 using Autodesk.Revit.DB.Mechanical;
+using JBIM.Definition;
+using RevitToJBim.Common;
 using SAGA.RevitUtils;
 using SAGA.RevitUtils.Extends;
+using XYZ = Autodesk.Revit.DB.XYZ;
 
 namespace RevitToJBim.Extension
 {
@@ -85,5 +88,215 @@ namespace RevitToJBim.Extension
             }
             return space.Level?.Id == useViewId.GenLevel?.Id;
         }
+
+
+        /// <summary>
+        /// 获取空间的外轮廓
+        /// </summary>
+        /// <param name="space"></param>
+        /// <returns></returns>
+        public static List<Polygon> GetSpaceOutline(this Space space)
+        {
+            List<Polygon> outlines=new List<Polygon>();
+            try
+            {
+                SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions();
+                //options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish;
+                var segments = space.GetBoundarySegments(options);
+                double tolerance = space.Document.Application.ShortCurveTolerance;
+                foreach (var segment in segments)
+                {
+                    #region 取外轮廓的点
+
+                    List<XYZ> xyzs = new List<XYZ>();
+                    foreach (BoundarySegment boundarySegment in segment)
+                    {
+                        var segmentElement = space.Document.GetElement(boundarySegment.ElementId);
+                        if (segmentElement is Wall wall)
+                        {
+                            var wallCurve = wall.GetLocationCurve();
+                            var parallelWalls = GetParallelWalls(wall);
+                            var segmentCurve = boundarySegment.GetCurve();
+                            var tessellates = segmentCurve.Tessellate();
+                            foreach (XYZ tessellate in tessellates)
+                            {
+                                var project = wallCurve.GetProjectPt(tessellate);
+                                var verticalVector = (project - tessellate).Normalize();
+                                var tempXyz = GetOuterXYZ(tessellate, verticalVector, segmentCurve, parallelWalls);
+                                if (tempXyz != null)
+                                    xyzs.Add(tempXyz);
+                            }
+                        }
+                        else
+                        {
+                            foreach (XYZ tessellate in boundarySegment.GetCurve().Tessellate())
+                            {
+                                xyzs.Add(tessellate);
+                            }
+                        }
+                    }
+
+                    #endregion
+
+                    #region 处理内拐角
+
+                    int count = xyzs.Count;
+                    /*
+                     * 相邻两条线求交点
+                     * 处理内拐角
+                     */
+                    for (int i = 0; i < count; i++)
+                    {
+                        if (count < 4) continue;
+                        var p1 = xyzs[i];
+                        int j2 = i + 1 >= xyzs.Count ? i + 1 - count : i + 1;
+                        var p2 = xyzs[j2];
+                        int j3 = i + 2 >= xyzs.Count ? i + 2 - count : i + 2;
+                        var p3 = xyzs[j3];
+                        int j4 = i + 3 >= xyzs.Count ? i + 3 - count : i + 3;
+                        var p4 = xyzs[j4];
+                        if (p2.IsEqual(p3) || p1.DistanceTo(p2) < tolerance || p3.DistanceTo(p4) < tolerance)
+                            continue;
+                        Curve curve1 = Line.CreateBound(p1, p2);
+                        Curve curve2 = Line.CreateBound(p3, p4);
+                        XYZ intersection = curve1.GetIntersection(curve2);
+                        if (intersection == null) continue;
+                        xyzs[j2] = intersection;
+                        xyzs[j3] = intersection;
+                    }
+
+                    #endregion
+
+                    //添加起始点,形成闭合区域
+                    if (xyzs.Any())
+                        xyzs.Add(xyzs[0]);
+
+                    //整理数据
+                    Polygon outLine = new Polygon();
+                    var usePoints = xyzs.Select(xyz => BimConvert.ConvertToXYZ(xyz)).ToList();
+                    outLine.AddRange(usePoints.GetRange(0, usePoints.Count - 1));
+                    StandardUtil.ArrangeLoop(outLine);
+                    outlines.Add(outLine);
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+                throw;
+            }
+
+            return outlines;
+        }
+
+        private static double m_RedundancySpace = 10d;
+        /// <summary>
+        /// 获取平行墙,平行且投影有重叠部分
+        /// </summary>
+        /// <param name="wall"></param>
+        /// <returns></returns>
+        public static List<Wall> GetParallelWalls(Wall wall)
+        {
+            List<Wall> walls = new List<Wall>();
+            walls.Add(wall);
+            var doc = wall.Document;
+            var allWalls = doc.GetElements<Wall>();
+            var curve = wall.GetLocationCurve();
+            var parallelWalls = allWalls.Where(t => t.GetLocationCurve().IsParallel(curve));
+
+            int len = walls.Count;
+            do
+            {
+                len = walls.Count;
+                foreach (Wall parallelWall in parallelWalls)
+                {
+                    var curve1 = parallelWall.GetLocationCurve();
+                    var startP11 = CurveExtend.StartPoint(curve1);
+                    var endP11 = CurveExtend.EndPoint(curve1);
+                    double width1 = parallelWall.Width.FromApi();
+                    for (int i = 0; i < walls.Count; i++)
+                    {
+                        Wall referenceWall = walls[i];
+                        if (walls.Contains(parallelWall)) continue;
+                        var curve2 = referenceWall.GetLocationCurve();
+                        var startP12 = CurveExtend.GetProjectPt(curve2, startP11);
+                        var endP12 = CurveExtend.GetProjectPt(curve2, endP11);
+                        var startP21 = CurveExtend.StartPoint(curve2);
+                        var endP21 = CurveExtend.EndPoint(curve2);
+                        var startP22 = CurveExtend.GetProjectPt(curve1, startP21);
+                        var endP22 = CurveExtend.GetProjectPt(curve1, endP21);
+                        //判断是否有重叠部分
+                        if (startP12.IsOnCurve(curve2) || endP12.IsOnCurve(curve2) || startP22.IsOnCurve(curve1) ||
+                            endP22.IsOnCurve(curve1))
+                        {
+                            double width2 = referenceWall.Width.FromApi();
+                            double distacne = curve1.Distance(curve2).FromApi();
+                            if (distacne < (width1 + width2) / 2.0 + m_RedundancySpace)
+                                walls.Add(parallelWall);
+                        }
+                    }
+                }
+            } while (len != walls.Count);
+
+            return walls;
+        }
+        /// <summary>
+        /// 获取外廓后的点
+        /// </summary>
+        /// <param name="xyz">外廓点</param>
+        /// <param name="verticalVector">外廓向量</param>
+        /// <param name="segmentCurve">参考Curve</param>
+        /// <param name="walls">平行墙集合</param>
+        /// <returns></returns>
+        public static XYZ GetOuterXYZ(XYZ xyz, XYZ verticalVector, Curve segmentCurve, List<Wall> walls)
+        {
+            XYZ outerXyz = xyz;
+            double distance = 0;
+            foreach (Wall wall in walls)
+            {
+                /*
+                 * 注意幕墙,没有底面,直接取原始点xyz
+                 */
+                List<PlanarFace> faces = wall.GetBottomFaces();
+                foreach (PlanarFace face in faces)
+                {
+                    foreach (CurveLoop curveLoop in face.GetEdgesAsCurveLoops())
+                    {
+                        foreach (Curve curve in curveLoop)
+                        {
+                            /*
+                             * 1. 获取平行边
+                             * 2. 平行边求投影,投影点形成向量为向外
+                             * 3. 投影点在线上
+                             */
+                            if (!segmentCurve.IsParallel(curve))
+                                continue;
+                            var projectPt = curve.GetProjectPt(xyz);
+                            var tempVector = (projectPt - xyz).Normalize();
+                            if (projectPt.IsOnCurve(curve) && !projectPt.IsEqual(xyz) && tempVector.IsEqual(verticalVector))
+                            {
+                                var tempDistance = xyz.DistanceTo(projectPt);
+                                if (tempDistance >= distance)
+                                {
+                                    distance = tempDistance;
+                                    outerXyz = projectPt;
+                                }
+                            }
+                            else
+                            {
+                                /*
+                                 * 无投影点,给个默认投影点的情况
+                                 * 处理斜边投影不到的情况边上的情况,
+                                 * 目前任意取了一个,多个取最近的??
+                                 */
+                                if (outerXyz == null || outerXyz.IsEqual(xyz))
+                                    outerXyz = projectPt;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return outerXyz;
+        }
     }
 }

+ 1 - 1
Starter/Starter/Program.cs

@@ -39,7 +39,7 @@ namespace ExportStart
                 command = "DataExport";
                 //command = "DataCheck";
                 path = @"E:\导出测试\testSpace.rvt";
-                path = @"E:\导出测试\徐州系统图模型1127\冷源系统图模型第一版V1128 .rvt";
+                path = @"E:\导出测试\编码修改后模型v1203\热源系统图模型第一版V1129.rvt";
                 JObject jObject=new JObject();
                 jObject.Add("ResultFileName", @"C:\Users\SAGACLOUD\AppData\Local\RevitService\Result_e26be2fd-2097-462b-bdd0-a2a86b616928.txt");
                 param = jObject.ToString();