瀏覽代碼

mxg:优化计算外轮廓的速度

mengxiangge 5 年之前
父節點
當前提交
751098babf
共有 1 個文件被更改,包括 111 次插入85 次删除
  1. 111 85
      FWindSoft/Saga.PlugIn/CreateSpaceCommand.cs

+ 111 - 85
FWindSoft/Saga.PlugIn/CreateSpaceCommand.cs

@@ -13,6 +13,7 @@ using FWindSoft.Revit;
 using FWindSoft.Revit.Menu;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Windows.Shapes;
 using FWindSoft.SystemExtensions;
@@ -45,39 +46,48 @@ namespace LRH.Tool
                     options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center;
                     var segments = space.GetBoundarySegments(options);
                     double tolerance = RevitCore.App.ShortCurveTolerance;
+                        var allWalls = DocumentExtension.GetElements<Wall>(RevitCore.Doc);
+                        var tupleWalls = allWalls
+                            .Select(t => new Tuple<Curve, Wall>(ElementExtension.GetLocationCurve(t), t)).ToList();
                     foreach (var segment in segments)
                     {
                         List<XYZ> xyzs = new List<XYZ>();
                         List<XYZ> xyzs2 = new List<XYZ>();
+
+                        Stopwatch watch2 = new Stopwatch();
+                        watch2.Start();
                         foreach (BoundarySegment boundarySegment in segment)
                         {
+                            Stopwatch watch = new Stopwatch();
+                            watch.Start();
                             var segmentElement = RevitCore.Doc.GetElement(boundarySegment.ElementId);
-                            if (segmentElement is FamilyInstance fi)
-                            {
-                                foreach (XYZ tessellate in boundarySegment.GetCurve().Tessellate())
-                                {
-                                    xyzs.Add(tessellate);
-                                }
-                                //var point = ElementExtension.GetLocationPoint(fi);
-                                //if(point!=null)
-                                //    xyzs.Add(point);
-                            }
-                            else if(segmentElement is Wall wall)
+                            if(segmentElement is Wall wall)
                             {
-                                var wallCurve = ElementExtension.GetLocationCurve(wall);
-                                var parallelWalls = GetParallelWalls(wall);
+
+                                watch.Restart();
+                                var parallelWalls = GetParallelWalls(wall, tupleWalls);
+
+                                watch.Stop();
+                                Debug.WriteLine("Start:"+watch.Elapsed);
+                                watch.Restart();
+
                                 var segmentCurve = boundarySegment.GetCurve();
                                 var tessellates = segmentCurve.Tessellate();
                                 foreach (XYZ tessellate in tessellates)
                                 {
                                     xyzs2.Add(tessellate);
 
+                                var wallCurve = ElementExtension.GetLocationCurve(wall);
                                     var project = wallCurve.GetProjectPt(tessellate);
                                     var verticalVector = (project - tessellate).Normalize();
                                     var tempXyz = GetOuterXYZ(tessellate, verticalVector, segmentCurve, parallelWalls);
                                     if (tempXyz != null)
                                         xyzs.Add(tempXyz);
                                 }
+
+                                watch.Stop();
+                                Debug.WriteLine("End:"+watch.Elapsed);
+
                             }
                             else
                             {
@@ -88,64 +98,44 @@ namespace LRH.Tool
                                     xyzs.Add(tessellate);
                                 }
                             }
-                            
-                            
                         }
+                        watch2.Stop();
+                        Debug.WriteLine(watch2.Elapsed);
 
-                        //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;
-                        //}
-
-                        //if (xyzs.Any())
-                        //    xyzs.Add(xyzs[0]);
-                        ////画线-外墙
-                        //for (int i = 0; i < xyzs.Count - 1; i++)
-                        //{
-                        //    try
-                        //    {
-                        //        var p1 = xyzs[i];
-                        //        var p2 = xyzs[i + 1];
-                        //        if (p1.IsAlmostEqualTo(p2)||p1.DistanceTo(p2)<tolerance)
-                        //            continue;
-                        //        Curve curve = Line.CreateBound(p1, p2);
-                        //        RevitCore.DocCreater.NewDetailCurve(RevitCore.UIDoc.ActiveView, curve);
-                        //    }
-                        //    catch (Exception e)
-                        //    {
-                        //        Console.WriteLine(e);
-                        //    }
-                        //}
+                        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;
+                        }
 
-                        if (xyzs2.Any())
-                            xyzs2.Add(xyzs2[0]);
-                        //画线-
-                        for (int i = 0; i < xyzs2.Count - 1; i++)
+                        if (xyzs.Any())
+                            xyzs.Add(xyzs[0]);
+                        //画线-外墙
+                        for (int i = 0; i < xyzs.Count - 1; i++)
                         {
                             try
                             {
-                                var p1 = xyzs2[i];
-                                var p2 = xyzs2[i + 1];
+                                var p1 = xyzs[i];
+                                var p2 = xyzs[i + 1];
                                 if (p1.IsAlmostEqualTo(p2) || p1.DistanceTo(p2) < tolerance)
                                     continue;
                                 Curve curve = Line.CreateBound(p1, p2);
@@ -155,8 +145,28 @@ namespace LRH.Tool
                             {
                                 Console.WriteLine(e);
                             }
-
                         }
+
+                        //if (xyzs2.Any())
+                        //    xyzs2.Add(xyzs2[0]);
+                        ////画线-内墙
+                        //for (int i = 0; i < xyzs2.Count - 1; i++)
+                        //{
+                        //    try
+                        //    {
+                        //        var p1 = xyzs2[i];
+                        //        var p2 = xyzs2[i + 1];
+                        //        if (p1.IsAlmostEqualTo(p2) || p1.DistanceTo(p2) < tolerance)
+                        //            continue;
+                        //        Curve curve = Line.CreateBound(p1, p2);
+                        //        RevitCore.DocCreater.NewDetailCurve(RevitCore.UIDoc.ActiveView, curve);
+                        //    }
+                        //    catch (Exception e)
+                        //    {
+                        //        Console.WriteLine(e);
+                        //    }
+
+                        //}
                     }
 
 
@@ -171,51 +181,67 @@ namespace LRH.Tool
             return Result.Succeeded;
         }
 
-        private double m_RedundancySpace = 10d;
+        private double m_RedundancySpace = 10d.ToApi();
         /// <summary>
         /// 获取平行墙,平行且投影有重叠部分
         /// </summary>
         /// <param name="wall"></param>
         /// <returns></returns>
-        public List<Wall> GetParallelWalls(Wall wall)
+        public List<Wall> GetParallelWalls(Wall wall,List<Tuple<Curve, Wall>> tupleWalls)
         {
             List<Wall> walls = new List<Wall>();
             walls.Add(wall);
-            var doc = wall.Document;
-            var allWalls = DocumentExtension.GetElements<Wall>(doc);
             var curve = ElementExtension.GetLocationCurve(wall);
-            var parallelWalls = allWalls.Where(t => ElementExtension.GetLocationCurve(t).IsParallel(curve));
+            var parallelWallTuples = tupleWalls.Where(t => t.Item1.IsParallel(curve));
 
             int len = walls.Count;
             do
             {
                 len = walls.Count;
-                foreach (Wall parallelWall in parallelWalls)
+                foreach (Tuple<Curve, Wall> parallelWallTuple in parallelWallTuples)
                 {
-                    var curve1 = ElementExtension.GetLocationCurve(parallelWall);
+                    var curve1 = parallelWallTuple.Item1;
+                    var parallelWall = parallelWallTuple.Item2;
                     var startP11 = CurveExtend.StartPoint(curve1);
                     var endP11 = CurveExtend.EndPoint(curve1);
-                    double width1 = parallelWall.Width.FromApi();
+                    double width1 = parallelWall.Width;
                     for (int i = 0; i < walls.Count; i++)
                     {
                         Wall referenceWall = walls[i];
                         if (walls.Contains(parallelWall)) continue;
                         var curve2 = ElementExtension.GetLocationCurve(referenceWall);
+                        if(curve1.IsEqual(curve2))continue;
                         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))
+                        if (startP12.IsOnCurve(curve2))
                         {
-                            double width2 = referenceWall.Width.FromApi();
-                            double distacne = curve1.Distance(curve2).FromApi();
+                            double width2 = referenceWall.Width;
+                            double distacne = startP11.DistanceTo(endP11);
                             if (distacne < (width1 + width2) / 2.0 + m_RedundancySpace)
                                 walls.Add(parallelWall);
                         }
+                        else
+                        {
+                            var endP12 = CurveExtend.GetProjectPt(curve2, endP11);
+                            if (endP12.IsOnCurve(curve2))
+                            {
+                                double width2 = referenceWall.Width;
+                                double distacne = startP11.DistanceTo(endP11);
+                                if (distacne < (width1 + width2) / 2.0 + m_RedundancySpace)
+                                    walls.Add(parallelWall);
+                            }
+                        }
+
+                        //var endP12 = CurveExtend.GetProjectPt(curve2, endP11);
+                        //没有重叠部分
+                        //if (startP12.IsOnCurve(curve2) || endP12.IsOnCurve(curve2)
+                        //                               //|| startP22.IsOnCurve(curve1) ||endP22.IsOnCurve(curve1)
+                        //                               )
+                        //{
+                        //    double width2 = referenceWall.Width;
+                        //    double distacne = startP11.DistanceTo(endP11);
+                        //    if (distacne < (width1 + width2) / 2.0 + m_RedundancySpace)
+                        //        walls.Add(parallelWall);
+                        //}
                     }
                 }
             } while (len != walls.Count);
@@ -279,7 +305,7 @@ namespace LRH.Tool
                 }
             }
 
-            return outerXyz;
+            return outerXyz.NewZ(xyz.Z);
         }
         /// <summary>
         /// 获取墙底面的轮廓,主要处理门窗分割墙问题