|
@@ -0,0 +1,238 @@
|
|
|
|
+/*-------------------------------------------------------------------------
|
|
|
|
+ * 功能描述:FloorSpaceItems
|
|
|
|
+ * 作者:xulisong
|
|
|
|
+ * 创建时间: 2018/12/21 14:41:27
|
|
|
|
+ * 版本号:v1.0
|
|
|
|
+ * -------------------------------------------------------------------------*/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+using System;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using System.Linq;
|
|
|
|
+using Autodesk.Revit.DB;
|
|
|
|
+using Autodesk.Revit.DB.Mechanical;
|
|
|
|
+using FWindSoft.Data;
|
|
|
|
+using SAGA.DotNetUtils.Extend;
|
|
|
|
+using SAGA.RevitUtils.Extends;
|
|
|
|
+
|
|
|
|
+namespace SAGA.GplotRelationComputerManage.SpaceRelation
|
|
|
|
+{
|
|
|
|
+ /// <summary>
|
|
|
|
+ ///模型解析对应的楼层空间数据
|
|
|
|
+ /// </summary>
|
|
|
|
+ public class FloorSpaceItems
|
|
|
|
+ {
|
|
|
|
+ #region 构造函数
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 初始化解析类
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="doc"></param>
|
|
|
|
+ public FloorSpaceItems(Document doc)
|
|
|
|
+ {
|
|
|
|
+ Document = doc;
|
|
|
|
+ Doors = new List<FamilyInstance>();
|
|
|
|
+ Windows = new List<FamilyInstance>();
|
|
|
|
+ Spaces = new List<Space>();
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ #region 属性相关
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 关联模型信息
|
|
|
|
+ /// </summary>
|
|
|
|
+ public Document Document { get; private set; }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 关联门信息
|
|
|
|
+ /// </summary>
|
|
|
|
+ public List<FamilyInstance> Doors { get; private set; }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 关联窗体信息
|
|
|
|
+ /// </summary>
|
|
|
|
+ public List<FamilyInstance> Windows { get; private set; }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 关联空间信息
|
|
|
|
+ /// </summary>
|
|
|
|
+ public List<Space> Spaces { get; private set; }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 解析
|
|
|
|
+ /// </summary>
|
|
|
|
+ public void Parse()
|
|
|
|
+ {
|
|
|
|
+ var doc = Document;
|
|
|
|
+ Doors = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Doors);
|
|
|
|
+ Windows = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Windows);
|
|
|
|
+ Spaces = doc.GetElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).OfType<Space>().ToList();
|
|
|
|
+ //展开空间关系数据
|
|
|
|
+ var flatSpaceItems = FlatSpaceEdges(Spaces);
|
|
|
|
+ var groupSpaces = flatSpaceItems.GroupBy(t => t.EdgeElement.Id.IntegerValue).ToList();
|
|
|
|
+ var relation = CalcCombineRelations(groupSpaces.ToList().Select(g=>g.Key).ToList());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #region 展开空间与边界的关联关系
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 展开空间与边的关系
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="spaces"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ private List<SpaceEdgeInfo> FlatSpaceEdges(List<Space> spaces)
|
|
|
|
+ {
|
|
|
|
+ var lSpaces = new List<SpaceEdgeInfo>();
|
|
|
|
+ Document doc = Document;
|
|
|
|
+ foreach (var space in spaces)
|
|
|
|
+ {
|
|
|
|
+ IList<IList<BoundarySegment>> segments = space.GetBoundarySegments(new SpatialElementBoundaryOptions());
|
|
|
|
+ foreach (IList<BoundarySegment> boundarySegments in segments)
|
|
|
|
+ {
|
|
|
|
+ foreach (var segment in boundarySegments)
|
|
|
|
+ {
|
|
|
|
+ //去除不能构成边的元素
|
|
|
|
+ if (segment.ElementId.IntegerValue != -1)
|
|
|
|
+ {
|
|
|
|
+ Curve wallLine = null;
|
|
|
|
+ var elem = doc.GetElement(segment.ElementId);
|
|
|
|
+ var type = typeof(object);
|
|
|
|
+ //这里只处理墙和分隔符,跨长度处理
|
|
|
|
+ #region 增加关系对象
|
|
|
|
+ if (elem is Wall wall)
|
|
|
|
+ {
|
|
|
|
+ wallLine = wall.Location.GetCurve();
|
|
|
|
+ type = typeof(Wall);
|
|
|
|
+ }
|
|
|
|
+ else if (elem is ModelCurve modelCurve)
|
|
|
|
+ {
|
|
|
|
+ wallLine = modelCurve.GetCurve();
|
|
|
|
+ type = typeof(ModelCurve);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ Curve segCurve1 = segment.GetCurve();
|
|
|
|
+ lSpaces.Add(new SpaceEdgeInfo()
|
|
|
|
+ {
|
|
|
|
+ Space = space,
|
|
|
|
+ Edge = wallLine,
|
|
|
|
+ SegEdge = segCurve1,
|
|
|
|
+ EdgeElement = elem,
|
|
|
|
+ EType = type
|
|
|
|
+ });
|
|
|
|
+ #endregion
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return lSpaces;
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+
|
|
|
|
+ #region 构件合并整合
|
|
|
|
+ /*
|
|
|
|
+ * 1、合并间距较小的构件看成一个构件关系
|
|
|
|
+ * 2、可合并构件关系为两两关系,且关系不支持传递。如a->b,b->c 不能推导出 a->c
|
|
|
|
+ * 3、在计算空间关系时,动态关联上相关id去计算空间关系
|
|
|
|
+ */
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 计算可合并关联
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="ids"></param>
|
|
|
|
+ private BinaryRelationCollection<int> CalcCombineRelations(List<int> ids)
|
|
|
|
+ {
|
|
|
|
+ BinaryRelationCollection<int> relations = new BinaryRelationCollection<int>(false);
|
|
|
|
+ if (!ids.Any() || ids.Count < 2)
|
|
|
|
+ return relations;
|
|
|
|
+ var doc = Document;
|
|
|
|
+ FilteredElementCollector collectors =
|
|
|
|
+ new FilteredElementCollector(doc, ids.Select(id => new ElementId(id)).ToList());
|
|
|
|
+ var calcElements = collectors.ToElements();
|
|
|
|
+ Dictionary<int, ElementGraphicItem> tempItems = new Dictionary<int, ElementGraphicItem>();
|
|
|
|
+ for (int i = 0; i < calcElements.Count; i++)
|
|
|
|
+ {
|
|
|
|
+ var outElement = calcElements[i];
|
|
|
|
+ var outItem = GetGraphicItem(tempItems, outElement);
|
|
|
|
+ if (outItem == null)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ #region 内部循环
|
|
|
|
+ for (int j = i + 1; j < calcElements.Count; j++)
|
|
|
|
+ {
|
|
|
|
+ var inElement = calcElements[j];
|
|
|
|
+ var inItem = GetGraphicItem(tempItems, inElement);
|
|
|
|
+ if (inItem == null)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (outItem.Location.IsParallel(inItem.Location)) //平行
|
|
|
|
+ {
|
|
|
|
+ //间距小于两个厚度之和的一半
|
|
|
|
+ var basePoint = outItem.Location.StartPoint();
|
|
|
|
+ var project = inItem.Location.GetProjectPt(basePoint);
|
|
|
|
+ var length = (basePoint - project).GetLength();
|
|
|
|
+ if (((outItem.Width + inItem.Width) / 2.0d).IsThanEq(length))
|
|
|
|
+ {
|
|
|
|
+ relations.Add(new BinaryRelationItem<int>(outElement.Id.IntegerValue,
|
|
|
|
+ outElement.Id.IntegerValue));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #endregion
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return relations;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private ElementGraphicItem GetGraphicItem(Dictionary<int, ElementGraphicItem> dic, Element ele)
|
|
|
|
+ {
|
|
|
|
+ if (dic.TryGetValue(ele.Id.IntegerValue, out ElementGraphicItem item))
|
|
|
|
+ {
|
|
|
|
+ return item;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ item = ElementGraphicItem.CreateItem(ele);
|
|
|
|
+ if (item != null)
|
|
|
|
+ {
|
|
|
|
+ dic[ele.Id.IntegerValue] = item;
|
|
|
|
+ }
|
|
|
|
+ return item;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 元素集合条目【内部算法使用】
|
|
|
|
+ /// </summary>
|
|
|
|
+ private class ElementGraphicItem
|
|
|
|
+ {
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 位置
|
|
|
|
+ /// </summary>
|
|
|
|
+ public Line Location { get; set; }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 宽度
|
|
|
|
+ /// </summary>
|
|
|
|
+ public double Width { get; set; }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 创建几何使用Item.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="element"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public static ElementGraphicItem CreateItem(Element element)
|
|
|
|
+ {
|
|
|
|
+ double width = 0;
|
|
|
|
+ if (element is Wall wall)
|
|
|
|
+ {
|
|
|
|
+ width = wall.WallType.GetParameterDouble(BuiltInParameter.WALL_ATTR_WIDTH_PARAM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Line line= element.GetLocationCurve().GetLine();
|
|
|
|
+ if (line != null)
|
|
|
|
+ {
|
|
|
|
+ return new ElementGraphicItem() {Width = width, Location = line};
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #endregion
|
|
|
|
+ }
|
|
|
|
+}
|