|
@@ -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; }
|
|
|
|
+ }
|
|
|
|
+}
|