Pārlūkot izejas kodu

xls:导出时调整空间顺序

xulisong 6 gadi atpakaļ
vecāks
revīzija
3cd2cdf268

+ 5 - 2
MBI/SAGA.MBI/RevitExport/ExportData.cs

@@ -59,8 +59,11 @@ namespace SAGA.MBI.RevitExport
             data.All = new List<RevitElementWrapper>();
             data.Walls.AddRange(collector.Clone().FilterElements<Wall>().Select(e => new RevitElementWrapper(e) { Category = MbiElementCategory.Wall }));
             data.VirtualWalls.AddRange(collector.Clone().FilterElements<CurveElement>(BuiltInCategory.OST_MEPSpaceSeparationLines).Select(e => new RevitElementWrapper(e) { Category = MbiElementCategory.VirtualWall }));
-           // data.Spaces.AddRange(collector.Clone().FilterElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).Select(e => new RevitElementWrapper(e) { Category = MbiElementCategory.Space }));
-            data.Spaces.AddRange(collector.Clone().GetUseSpaces().Select(e => new RevitElementWrapper(e) { Category = MbiElementCategory.Space }));
+            // data.Spaces.AddRange(collector.Clone().FilterElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).Select(e => new RevitElementWrapper(e) { Category = MbiElementCategory.Space }));
+            //增加空间排序功能
+            var originSpaces = collector.Clone().GetUseSpaces();
+            var useSpaces = SpaceSortUtils.Sort(originSpaces);
+            data.Spaces.AddRange(useSpaces.Select(e => new RevitElementWrapper(e) { Category = MbiElementCategory.Space }));
             var familyInstances = collector.Clone().FilterElements<FamilyInstance>();
             foreach (FamilyInstance familyInstance in familyInstances)
             {

+ 176 - 0
MBI/SAGA.MBI/RevitExport/SpaceSortUtils.cs

@@ -0,0 +1,176 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SpaceSortUtils
+ * 作者:xulisong
+ * 创建时间: 2019/5/8 15:38:22
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.MBI.Tools;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.Utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.MBI.RevitExport
+{
+    /// <summary>
+    /// 空间排序工具
+    /// </summary>
+    public static class SpaceSortUtils
+    {
+        public static List<Space> Sort(List<Space> spaces)
+        {
+            List<SpaceDecorator> decorators = spaces.Where(space => space.IsSpace())
+                .Select(space => new SpaceDecorator(space)).ToList();
+            foreach (var spaceDecorator in decorators)
+            {
+                CalcLevel(spaceDecorator, decorators);
+            }
+
+            decorators=decorators.OrderByDescending(s => s.Level).ToList();
+            return decorators.Select(sd => sd.Space).ToList();
+        }
+
+        private static int CalcLevel(SpaceDecorator input, List<SpaceDecorator> decorators)
+        {
+            if (input.IsHandled)
+            {
+                return input.Level;
+            }
+            var useLevel = 0;
+            try
+            {                
+                var containsSpaces = new List<SpaceDecorator>();
+                foreach (SpaceDecorator item in decorators)
+                {
+                    if (item.Space.Id == input.Space.Id)
+                    {
+                        continue;
+                    }
+
+                    if (IsContains(input, item))
+                    {
+                        containsSpaces.Add(item);
+                    }
+                }              
+                foreach (var item in containsSpaces)
+                {
+                    var tempLevel = CalcLevel(item, decorators)+1;
+                    useLevel = Math.Max(useLevel, tempLevel);
+                }
+                return useLevel;
+            }
+            finally
+            {
+                input.Level = useLevel;
+                input.IsHandled = true;
+            }
+        }
+        /// <summary>
+        /// 判断两个空间是否有包含关系
+        /// </summary>
+        /// <param name="aFSpace"></param>
+        /// <param name="bSpace"></param>
+        /// <returns></returns>
+        private static bool  IsContains(SpaceDecorator aFSpace, SpaceDecorator bSpace)
+        {
+            bool flag = false;
+            if (aFSpace.Annular == null || bSpace.Annular == null)
+            {
+                return flag;
+            }
+
+            var basePolygon = aFSpace.Annular.OutPolygon;
+            var refPolygon = bSpace.Annular.OutPolygon;
+            if (basePolygon == null || refPolygon == null)
+            {
+                return flag;
+            }
+            if (PolygonUtil.IsIntersection(basePolygon, refPolygon))
+            {
+                var pointList = basePolygon.ToList();
+                if (refPolygon.All(p => p.PointInPolygonByRay(pointList) > -1))
+                {
+                    //所有点都在外轮廓线内
+                    return true;
+                }
+                
+            }
+            return flag;
+        }
+    }
+
+    public class SpaceDecorator
+    {
+        public SpaceDecorator(Space space)
+        {
+            Space = space;
+            var mySegments = space.GetBoundarySegments(new SpatialElementBoundaryOptions());     
+            Annular = InitAnnular(mySegments);
+        }
+        public Space Space { get; private set; }
+        public int Level { get; set; }
+        /// <summary>
+        /// 轮廓环形
+        /// </summary>
+        public Annular Annular { get; private set; }
+
+        private Annular InitAnnular(IList<IList<BoundarySegment>> segmentsList)
+        {
+            Annular annumlar = null;
+            for (int i = 0; i < segmentsList.Count; i++)
+            {
+                var currentSegments = segmentsList[i];
+                bool useSegments = false;
+                var usePoints = new List<XYZ>();
+                foreach (var boundarySegment in currentSegments)
+                {
+                    if (!useSegments && !(this.Space.Document.GetElement(boundarySegment.ElementId) is FamilyInstance))
+                    {
+                        //如果边框都是由柱子组成,则不进行存储
+                        useSegments = true;
+                    }
+                    var curve = boundarySegment.GetCurve();
+                    var tempPoints = curve.Tessellate();
+                    //取出除最后一点外的所有点
+                    for (int j = 0; j < tempPoints.Count - 1; j++)
+                    {
+                        usePoints.Add(tempPoints[j].NewZ(0));
+                    }
+                }
+                if (!useSegments)
+                    continue;
+                if (i == 0)
+                {
+                    #region 外轮廓处理,默认逆时针
+
+                    annumlar = new Annular(new Polygon(usePoints));
+
+                    #endregion
+                }
+                else
+                {
+                    #region 内轮廓处理,默认顺时针。转成逆时针
+
+                    if (annumlar != null)
+                    {
+                        usePoints.Reverse();
+                        annumlar.InPolygons.Add(new Polygon(usePoints));
+                    }
+                    #endregion
+                }
+            }
+            return annumlar;
+        }
+
+        /// <summary>
+        /// 是否被处理过
+        /// </summary>
+        internal bool IsHandled { get; set; }
+    }
+}

+ 1 - 0
MBI/SAGA.MBI/SAGA.MBI.csproj

@@ -316,6 +316,7 @@
     <Compile Include="RequestData\FileContentTransferUnit.cs" />
     <Compile Include="RequestData\QRCodeRequest.cs" />
     <Compile Include="RequestData\RequestResultUtil.cs" />
+    <Compile Include="RevitExport\SpaceSortUtils.cs" />
     <Compile Include="RevitModelHandle\ParameterDefinitionFactory.cs" />
     <Compile Include="RevitModelHandle\ParameterUtil.cs" />
     <Compile Include="RevitModelHandle\RevitParameterUpdate.cs" />