Bladeren bron

xls:图数据整理

xulisong 6 jaren geleden
bovenliggende
commit
6b128714f1

+ 1 - 1
MBI/SAGA.DotNetUtils/Data/EdgesArray/EAEdge.cs

@@ -76,7 +76,7 @@ namespace SAGA.DotNetUtils.Data
 
         #region 边提供方法
         /// <summary>
-        /// 判断是否包含指定id的点
+        /// 判断是否包含指定id的点(-1 表示不包含;0,开始点,1,结束点)
         /// </summary>
         /// <param name="id"></param>
         /// <returns>(-1 表示不包含;0,开始点,1,结束点)</returns>

+ 57 - 4
MBI/SAGA.DotNetUtils/Data/EdgesArray/EAElement.cs

@@ -14,23 +14,31 @@ namespace SAGA.DotNetUtils.Data
         {
             Children = new EAElementCollection<T>(this as T);
         }
+
         /// <summary>
         /// 节点Id
         /// </summary>
-        public string Id { get;internal set; }
+        public string Id { get; internal set; }
+
         /// <summary>
         /// 节点名称
         /// </summary>
         public string Name { get; set; }
+
         /// <summary>
         /// 关联相关元素
         /// </summary>
         public object Tag { get; set; }
+
         #region 父子关联元素处理
+
         public EAElementCollection<T> Children { get; private set; }
         public T Parent { get; internal set; }
+
         #endregion
+
         #region 公开方法
+
         /// <summary>
         /// 获取根节点
         /// </summary>
@@ -44,8 +52,10 @@ namespace SAGA.DotNetUtils.Data
             {
                 root = root.Parent;
             }
+
             return root;
         }
+
         /// <summary>
         /// 节点深度
         /// </summary>
@@ -93,8 +103,10 @@ namespace SAGA.DotNetUtils.Data
             }
 
             return result;
-        } 
+        }
+
         #endregion
+
         /// <summary>
         /// 有效的Id
         /// </summary>
@@ -102,6 +114,7 @@ namespace SAGA.DotNetUtils.Data
         {
             get { return !string.IsNullOrWhiteSpace(Id); }
         }
+
         /// <summary>
         /// 两个对象是否匹配
         /// </summary>
@@ -109,14 +122,45 @@ namespace SAGA.DotNetUtils.Data
         /// <returns></returns>
         public virtual bool IsMatch(EAElement<T> ea)
         {
-            if (ea == null|| !ValidId)
+            if (ea == null || !ValidId)
             {
                 return false;
             }
+
             return Id == ea.Id || this.Equals(ea);
-        }       
+        }
+
+
+        #region 扩展数据相关
+
+        protected Dictionary<string, object> m_DicRef = new Dictionary<string, object>();
+
+        /// <summary>
+        /// 注册关联值
+        /// </summary>
+        public void Set<V>(string key, V refObject)
+        {
+            m_DicRef[key] = refObject;
+        }
+
+        /// <summary>
+        /// 获取关联对象
+        /// </summary>
+        /// <typeparam name="V"></typeparam>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public V Get<V>(string key)
+        {
+            if (!m_DicRef.ContainsKey(key))
+                return default(V);
+            return (V) m_DicRef[key];
+        }
+
+        #endregion
     }
+
     #region 节点集合类
+
     /// <summary>
     /// 节点子项目集合类
     /// </summary>
@@ -124,6 +168,7 @@ namespace SAGA.DotNetUtils.Data
     public class EAElementCollection<T> : ObservableCollection<T> where T : EAElement<T>
     {
         private T m_Parent;
+
         internal EAElementCollection(T parent)
         {
             m_Parent = parent;
@@ -140,21 +185,26 @@ namespace SAGA.DotNetUtils.Data
                 }
 
             }
+
             base.ClearItems();
         }
+
         protected override void InsertItem(int index, T item)
         {
             base.InsertItem(index, item);
             item.Parent = m_Parent;
         }
+
         protected override void RemoveItem(int index)
         {
             if (this[index] != null)
             {
                 this[index].Parent = null;
             }
+
             base.RemoveItem(index);
         }
+
         protected override void SetItem(int index, T item)
         {
 
@@ -176,5 +226,8 @@ namespace SAGA.DotNetUtils.Data
             list?.Reverse();
         }
     }
+
     #endregion
+
+
 }

+ 18 - 0
MBI/SAGA.DotNetUtils/Data/EdgesArray/EdgesArrayGraph.cs

@@ -439,6 +439,24 @@ namespace SAGA.DotNetUtils.Data
         {
             return GeFirstStateEdges(this.Edges);
         }
+        /// <summary>
+        /// 获取根边
+        /// </summary>
+        /// <returns></returns>
+        public List<E> GetBootEdges()
+        {
+            var edges = this.Edges.Where(e => e.Parent == null).ToList();
+            return edges;
+        }
+        /// <summary>
+        /// 获取根点
+        /// </summary>
+        /// <returns></returns>
+        public List<V> GetBootVertexs()
+        {
+            var vertexes = this.Vertexes.Where(e => e.Parent == null).ToList();
+            return vertexes;
+        }
         #endregion
     }
 }

+ 4 - 0
MBI/SAGA.GplotRelationComputerManage/ColdRoom/EquipmentItem.cs

@@ -20,6 +20,10 @@ namespace SAGA.GplotRelationComputerManage
         /// </summary>
         public string Id { get; set; }
         /// <summary>
+        /// BimId
+        /// </summary>
+        public string BimId { get; set; }
+        /// <summary>
         /// 设备名称
         /// </summary>
         public string Name { get; set; }

+ 368 - 1
MBI/SAGA.GplotRelationComputerManage/RevitSystemParse/Handler/GplotGraphParse.cs

@@ -10,10 +10,377 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Data;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Data.Graph;
+using SAGA.RevitUtils.Extends;
 
 namespace SAGA.GplotRelationComputerManage
 {
-    class GplotGraphParse
+    /// <summary>
+    /// 拓扑图解析
+    /// </summary>
+    public class GplotGraphParse
     {
+        public GplotGraphParse(GplotGraphSetting setting)
+        {
+            Setting = setting;
+        }
+        #region 属性相关
+        /// <summary>
+        /// 系统解析设置
+        /// </summary>
+        public GplotGraphSetting Setting { get; private set; }
+        #endregion
+        /// <summary>
+        /// 创建拓扑结构图
+        /// </summary>
+        /// <param name="startElements"></param>
+        /// <returns></returns>
+        public List<SystemGraph> CreateGplotGraphs(List<Element> startElements)
+        {
+            List<SystemGraph> arrays = new List<SystemGraph>();
+            var newStartElements = startElements.Distinct(new ElementEqualComparer()).ToList();
+            while (newStartElements.Any())
+            {
+                var baseElement = newStartElements[0];
+                var graph = CreateGplotGraph(baseElement);
+                var containElements = graph.GetRefElements();
+                newStartElements = newStartElements.Except(containElements, new ElementEqualComparer()).ToList();
+                arrays.Add(graph);
+            }
+            return arrays;
+        }
+        /// <summary>
+        /// 创建拓扑结构图
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public SystemGraph CreateGplotGraph(Element element)
+        {
+            SystemGraph graph = GetOriginGraph(element);
+            //节点处理
+            ArrangeVertex(graph);
+            //边处理
+            ArrangeEdge(graph);
+            return graph;
+        }
+        #region 解析原始图
+        /// <summary>
+        /// 创建原始的节点图,以起点元素为首个节点
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public SystemGraph GetOriginGraph(Element element)
+        {
+            return SystemGraphUtil.CreateGraph(element, Setting.IgnoredConnector, Setting.BreakElement);
+        }
+        #endregion
+
+        #region 相关子方法
+        #region 节点处理
+        /// <summary>
+        /// 整理点
+        /// </summary>
+        /// <param name="graph"></param>
+        private void ArrangeVertex(SystemGraph graph)
+        {
+            #region 分析
+            /*
+            * 1、如果节点元素是一个管道,则将管道没有连接的那一个点创建一个“空间”设备,标记不可合并
+            * 2、如果节点是设备或者特殊阀门,则标记不能合并,并加载物理世界相关设备信息
+            * 3、如果一个点只有两条边,且该点可以被合并,则创建新边,关联上述两条边和点信息;删除旧的信息
+            * 4、如果一条边的两个点,都是可合并,并过滤所有以这两个点为顶点的边,将这些信息合并成新的点;
+            *     处理这种点融合边的情况,有两种方案:1,创建新点,将旧的点设置为新点的子节点。2、修改所有边的相依的节点Id为新Id
+            *     方案各有利弊,第一种保留了初始状态,第二种以后遍历时方便
+            */
+            #endregion
+            AttachVertexInfo(graph);
+            CombineVertex(graph);
+        }
+        /// <summary>
+        /// 附加节点信息
+        /// </summary>
+        /// <param name="graph"></param>
+        private void AttachVertexInfo(SystemGraph graph)
+        {
+            var useVertexes = graph.GetBootVertexs();
+            #region 
+            foreach (var systemVertex in useVertexes)
+            {
+                var data = systemVertex.Data;
+                if (data.Any())
+                {
+                    continue;
+                }
+                //理论上此时场景,有且仅有一个关联元素
+                var useElement = data[0];
+                #region 虚拟设备处理
+                EquipmentItem item = new EquipmentItem();
+                if (useElement is MEPCurve)
+                {
+                    item.IsVirtual = true;
+                    var edges = graph.GetOutEdges(systemVertex.Id);
+                    if (edges.Count == 1)
+                    {
+                        var currentEdge = edges[0];
+                        var joinItems = JoinItem.GetJoinItems(useElement);
+                        foreach (var joinItem in joinItems)
+                        {
+                            if (joinItem.RefElement != null && currentEdge.Data.All(e => e.Id != joinItem.RefElement.Id))
+                            {
+                                //处理点边关联信息
+                                currentEdge.Data.Add(useElement);
+                                systemVertex.Data.Remove(useElement);
+                                systemVertex.CanCombine = false;
+                                //找到断头点
+                                var location = joinItem.RefConnector.Origin;
+                                var space = useElement.Document.GetSpaceAtPoint(location);
+                                if (space != null)
+                                {
+                                    item.Id = space.Id.ToString();
+                                    item.BimId = space.GetBimId();
+                                }
+                                else
+                                {
+                                    item.Name = string.Format("空间{0}", location.ToString());
+                                }
+                                systemVertex.SetEquipment(item);
+                                break;
+                            }
+                        }
+                    }
+
+                    continue;
+                }
+                #endregion
+
+                #region 真实设备处理
+                item.Id = useElement.Id.ToString();
+                item.BimId = useElement.GetBimId();
+                if (MBIInfoUtil.IsEquipment(useElement))
+                {
+                    systemVertex.CanCombine = false;
+                    systemVertex.SetEquipment(item);
+                    continue;
+                }
+                if (SystemCalcUtil.IsStartValve(useElement))
+                {
+                    systemVertex.CanCombine = false;
+                    item.IsVirtual = true;
+                    systemVertex.SetEquipment(item);
+                    item.Name = useElement.GetFamily()?.Name;
+                    continue;
+                }
+                #endregion
+            }
+            #endregion
+        }
+        /// <summary>
+        /// 合并节点
+        /// </summary>
+        /// <param name="graph"></param>
+        public void CombineVertex(SystemGraph graph)
+        {
+            #region 以点为基础处理
+            var useVertexes = graph.GetBootVertexs();
+            foreach (var systemVertex in useVertexes)
+            {
+                if (!systemVertex.CanCombine)
+                {
+                    continue;
+                }
+                var edges = graph.GetInEdges(systemVertex.Id);
+                if (edges.Count != 2)
+                {
+                    continue;
+                }
+
+                string startId = edges[0].GetAnotherVertex(systemVertex.Id);
+                string endId = edges[1].GetAnotherVertex(systemVertex.Id);
+                edges.ForEach(e => graph.RemoveEdge(e.Id));
+                graph.RemoveVertex(systemVertex.Id);
+                var newEdge = new SystemEdge(startId, endId);
+                newEdge.Data = new SystemData(edges[0].Data);
+                newEdge.Data.ExtendRefElements(edges[1].Data);
+                newEdge.Data.ExtendRefElements(systemVertex.Data);
+                graph.AddEdge(newEdge);
+            }
+            #endregion
+
+            #region 以边为基础处理
+            HandledMap map = new HandledMap();
+            var useEdges = graph.GetBootEdges();
+            for (int i = 0; i < useEdges.Count; i++)
+            {
+                var baseEdge = useEdges[i];
+                if (map.GetHandled(baseEdge))
+                    continue;
+                var startVertex = graph.GetBootStartVertex(baseEdge);
+                var endVertex = graph.GetBootEndVertex(baseEdge);
+                if (startVertex == null || endVertex == null)
+                {
+                    continue;
+                }
+                if (!startVertex.CanCombine || !endVertex.CanCombine)
+                {
+                    continue;
+                }
+                // 如果两个节点之下还有一条其他的包含设备的边,则该边的两点不能合并
+                var refEdges = graph.GetEdges(baseEdge.StartVertex, baseEdge.EndVertex);
+                #region 创建新的点
+                List<Element> elements = new List<Element>();
+                elements.AddRange(startVertex.Data);
+                elements.AddRange(endVertex.Data);
+                foreach (var elementsEdge in refEdges)
+                {
+                    elements.AddRange(elementsEdge.Data);
+                    graph.RemoveEdge(elementsEdge.Id);
+                    map.SetHandled(elementsEdge.Id, true);
+                }
+                graph.RemoveVertex(startVertex.Id);
+                graph.RemoveVertex(endVertex.Id);
+                elements = elements.Distinct(new ElementEqualComparer()).ToList();
+                SystemVertex newVertex = new SystemVertex(new SystemData(elements));
+                newVertex = graph.AddVertex(newVertex);
+                #endregion
+                #region 更新关联边的关联点
+                var vertexIds = new List<string>() { startVertex.Id, endVertex.Id };
+                foreach (var vertexId in vertexIds)
+                {
+                    var edges = graph.GetInEdges(vertexId);
+                    foreach (var systemEdge in edges)
+                    {
+                        var flag = systemEdge.ContainVertex(vertexId);
+                        if (flag == 0)
+                        {
+                            systemEdge.StartVertex = newVertex.Id;
+                        }
+                        else if (flag == 1)
+                        {
+                            systemEdge.EndVertex = newVertex.Id;
+                        }
+                    }
+                }
+                #endregion
+
+            }
+            #endregion
+        }
+        #endregion
+
+        #region 边处理
+        /// <summary>
+        /// 整理边
+        /// </summary>
+        /// <param name="graph"></param>
+        private void ArrangeEdge(SystemGraph graph)
+        {
+            //有向化处理
+            DirectedEdge(graph);
+            graph.IsDirection = true;
+            //串并联处理
+            EdgesArrayGraphUtil.GplotAnalyse(graph);
+        }
+        /// <summary>
+        /// 确定流向
+        /// </summary>
+        /// <param name="graph"></param>
+        private void DirectedEdge(SystemGraph graph)
+        {
+            #region 加载边的系统信息
+            var originEdges = graph.Edges.Where(e => !e.Children.Any()).ToList();
+            foreach (var originEdge in originEdges)
+            {
+                var refElements = originEdge.Data;
+                //获取边系统类型
+                originEdge.SystemName = (refElements.FirstOrDefault(e => e is MEPCurve) as MEPCurve)?.GetSystemTypeName();
+                //根据系统类型和特殊设备确定旁通和补水;未完,待续
+                var systemItem = Setting.RelationTypeShell.GetFirstMatchSystem(originEdge.SystemName);
+                if (systemItem != null)
+                {
+                    originEdge.EdgeCategory = systemItem.ContainEdgeTypes.FirstOrDefault();
+                    originEdge.FlowType = systemItem.FlowType == FlowType.In ? 2 : 1;
+                }
+            }
+            #endregion
+
+            #region 描述
+            /*
+             * 1、查找遍历起点
+             * 2、根据起点遍历所有的节点,并调整节点的顺序
+             */
+            #endregion
+            #region 获取定义端点
+            var vertexes = graph.GetBootVertexs().Where(v => SystemCalcUtil.IsStartValveName(v.GetEquipment()?.Name)).ToList();
+            if (!vertexes.Any())
+                return;
+            foreach (var systemVertex in vertexes)
+            {
+                var tempEdges = graph.GetInEdges(systemVertex.Id);
+                if (tempEdges.Any())
+                {
+                    var item = systemVertex.GetEquipment();
+                    if (item == null)
+                    {
+                        continue;
+                    }
+                    if (tempEdges.Any(e => e.FlowType == 2))
+                    {
+                        item.Name = "出口" + item.Id;
+                    }
+                    else
+                    {
+                        item.Name = "入口" + item.Id;
+                    }
+                }
+            }
+            #endregion
+            #region 确定开始点
+            List<string> edgeIds = new List<string>();
+            List<string> vertexIds = new List<string>();
+            Queue<SystemVertex> queueVertexes = new Queue<SystemVertex>();
+            vertexes.ForEach(v => queueVertexes.Enqueue(v));
+            bool isDeepSearch = false;
+            bool isStart = true;
+            while (queueVertexes.Any())
+            {
+                var currentVertex = queueVertexes.Dequeue();
+                if (!isDeepSearch)
+                {
+                    isStart = (currentVertex.GetEquipment()?.Name ?? string.Empty).Contains("入口");
+                    isDeepSearch = vertexes.LastOrDefault().Id == currentVertex.Id;
+                }
+
+                vertexIds.Add(currentVertex.Id);
+                var edges = graph.GetInEdges(currentVertex.Id);               
+                foreach (var systemEdge in edges)
+                {
+                    if (edgeIds.Contains(systemEdge.Id))
+                    {
+                        continue;
+                    }
+                    edgeIds.Add(systemEdge.Id);
+                    if ((isStart && systemEdge.ContainVertex(currentVertex.Id) == 1)||(!isStart&& systemEdge.ContainVertex(currentVertex.Id) == 0))
+                    {
+                        systemEdge.Reverse();
+                    }
+
+                    var otherId = systemEdge.GetAnotherVertex(currentVertex.Id);
+                    if (!vertexIds.Contains(otherId))
+                    {
+                        var nextVertex = graph.FindVertex(otherId);
+                        if (nextVertex != null)
+                        {
+                            queueVertexes.Enqueue(nextVertex);
+                        }                      
+                    }
+                }
+            }
+            #endregion
+        }
+        #endregion
+        #endregion
     }
 }

+ 17 - 5
MBI/SAGA.GplotRelationComputerManage/RevitSystemParse/Handler/GplotGraphSetting.cs

@@ -33,6 +33,11 @@ namespace SAGA.GplotRelationComputerManage
         public Domain Domain { get; private set; }
 
         #region 忽略连接点
+        /// <summary>
+        /// 忽略的连接点
+        /// </summary>
+        /// <param name="connector"></param>
+        /// <returns></returns>
         public  bool IgnoredConnector(Connector connector)
         {
             bool ignored = true;
@@ -40,18 +45,17 @@ namespace SAGA.GplotRelationComputerManage
             {
                 if (connector.IsLogical())
                     break;
-                if (connector.Domain != Domain.DomainPiping)
+                if (connector.Domain != Domain)
                     break;
                 var useElement = connector.Owner;
-                if (!(useElement is MEPCurve || connector.IsConnected))
+                if (!(useElement is MEPCurve)&&!connector.IsConnected)
                 {
                     break;
                 }
-
                 ignored = InnerIgnoredConnector(connector);
             } while (false);
 
-            return false;
+            return ignored;
         }
 
         private bool InnerIgnoredConnector(Connector connector)
@@ -89,7 +93,15 @@ namespace SAGA.GplotRelationComputerManage
         #endregion
 
         #region 元素断开点
-
+        /// <summary>
+        /// 节点断开条件
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public bool BreakElement(Element element)
+        {
+           return SystemCalcUtil.IsStartValve(element)||MBIInfoUtil.IsEquipment(element);
+        }
         #endregion
     }
 }

+ 0 - 1
MBI/SAGA.GplotRelationComputerManage/RevitSystemParse/Handler/SystemGraphUtil.cs

@@ -57,7 +57,6 @@ namespace SAGA.GplotRelationComputerManage
                 edge.EndVertex = endVertex.Id;
                 edge = graph.AddEdge(edge);
                 #endregion
-
                 #region 延伸遍历项
                 var existJoinElement = joinElements.FirstOrDefault(j => j.Element.Id == end.Id);
                 if (existJoinElement == null)

+ 1 - 1
MBI/SAGA.GplotRelationComputerManage/RevitSystemParse/Handler/SystemParse.cs

@@ -386,7 +386,7 @@ namespace SAGA.GplotRelationComputerManage
                 var systemItem = Setting.RelationTypeShell.GetFirstMatchSystem(originEdge.SystemName);
                 if (systemItem != null)
                 {
-                    originEdge.EdgeCategory = systemItem.ContainEdgeTypes.FirstOrDefault();// Setting.GplotOptions.GetCategory(originEdge.SystemName);
+                    originEdge.EdgeCategory = systemItem.ContainEdgeTypes.FirstOrDefault();
                     originEdge.FlowType = systemItem.FlowType == FlowType.In ? 2 : 1;
                 }
             

+ 40 - 0
MBI/SAGA.GplotRelationComputerManage/RevitSystemParse/Handler/SystemVertexGplotExtension.cs

@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemVertexGplotExtendion
+ * 作者:xulisong
+ * 创建时间: 2019/2/15 11:21:58
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Data.Graph;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    public static class SystemVertexGplotExtension
+    {
+        private static string Equipment = "Equipment";
+        public static void SetEquipment(this SystemVertex vertex, EquipmentItem item)
+        {
+            vertex.Set(Equipment, item);
+        }
+        public static EquipmentItem GetEquipment(this SystemVertex vertex)
+        {
+            return vertex.Get<EquipmentItem>(Equipment);
+        }
+        public static bool IsEquipment(this SystemVertex vertex)
+        {
+            return vertex.GetEquipment() != null;
+        }
+        public static bool IsRealEquipment(this SystemVertex vertex)
+        {
+            var item = vertex.GetEquipment();
+            return item != null && !item.IsVirtual;
+        }
+      
+    }
+}

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

@@ -141,6 +141,7 @@
     <Compile Include="RevitSystemParse\Handler\GplotGraphSetting.cs" />
     <Compile Include="RevitSystemParse\Handler\JoinElement.cs" />
     <Compile Include="RevitSystemParse\Handler\SystemGraphUtil.cs" />
+    <Compile Include="RevitSystemParse\Handler\SystemVertexGplotExtension.cs" />
     <Compile Include="RevitSystemParse\MepExtension.cs" />
     <Compile Include="RevitSystemParse\Handler\ParseQueueItem.cs" />
     <Compile Include="RevitSystemParse\Handler\SystemParse.cs" />

+ 20 - 0
MBI/SAGA.RevitUtils/Data/Graph/SystemEdge.cs

@@ -23,5 +23,25 @@ namespace SAGA.RevitUtils.Data.Graph
         {
             this.Data = data;
         }
+
+        public SystemEdge(string startId, string endId)
+        {
+            this.StartVertex = startId;
+            this.EndVertex = endId;
+        }
+        #region 业务属性
+        /// <summary>
+        /// 关联系统类型
+        /// </summary>
+        public string SystemName { get; set; }
+        /// <summary>
+        /// 边类别
+        /// </summary>
+        public string EdgeCategory { get; set; }
+        /// <summary>
+        /// flowType[2表示从源端流出,1表示流入源端]
+        /// </summary>
+        public int FlowType { get; set; }
+        #endregion
     }
 }

+ 13 - 0
MBI/SAGA.RevitUtils/Data/Graph/SystemGraph.cs

@@ -10,6 +10,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Autodesk.Revit.DB;
 using SAGA.DotNetUtils.Data;
 
 namespace SAGA.RevitUtils.Data.Graph
@@ -29,5 +30,17 @@ namespace SAGA.RevitUtils.Data.Graph
             }
             return base.AddVertex(vertex);
         }
+
+        /// <summary>
+        /// 获取图中涵盖的元素集合
+        /// </summary>
+        /// <returns></returns>
+        public List<Element> GetRefElements()
+        {
+            List<Element> result = new List<Element>();
+            result.AddRange(this.Vertexes.SelectMany(v => v.Data));
+            result.AddRange(this.Edges.SelectMany(e => e.Data));
+            return result.Distinct(new ElementEqualComparer()).ToList();
+        }
     }
 }

+ 11 - 0
MBI/SAGA.RevitUtils/Data/Graph/SystemVertex.cs

@@ -19,6 +19,13 @@ namespace SAGA.RevitUtils.Data.Graph
     /// </summary>
     public class SystemVertex: EAVertex<SystemData>
     {
+        public SystemVertex()
+        { }
+
+        public SystemVertex(SystemData data)
+        {
+            this.Data = data;
+        }
         public override void Merge(EAElement<EAVertex<SystemData>> ea)
         {
             var sv = ea as SystemVertex;
@@ -26,5 +33,9 @@ namespace SAGA.RevitUtils.Data.Graph
                 return;
             this.Data.ExtendRefElements(sv.Data);
         }
+        /// <summary>
+        /// 是否允许合并[默认为true]
+        /// </summary>
+        public bool CanCombine { get; set; } = true;
     }
 }

+ 1 - 1
MBI/SAGA.RevitUtils/MEP/MepJoinUtil.cs

@@ -47,7 +47,7 @@ namespace SAGA.RevitUtils.MEP
         public static bool IsWaterComponment(this Element element)
         {
             var compatibleCategories =
-                new List<int>() {(int) BuiltInCategory.OST_PipeCurves, (int) BuiltInCategory.OST_PipeFitting};
+                new List<int>() {(int) BuiltInCategory.OST_PipeCurves, (int) BuiltInCategory.OST_PipeFitting,(int)BuiltInCategory.OST_DuctCurves, (int)BuiltInCategory.OST_DuctFitting };
 
 
            return compatibleCategories.Any(c => c == element.Category.Id.IntegerValue);