123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- using Autodesk.Revit.DB;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace SAGA.RevitUtils
- {
- /// <summary>
- /// 边类型
- /// </summary>
- public enum EdgeType
- {
- [Description("原始边")]
- Origin,
- [Description("子边串联")]
- Series,
- [Description("子边并联")]
- Parallel,
- }
- public class ElementsEdge : GraphNode<ElementsEdge>
- {
- #region 创建相关
- protected List<Element> m_RefElelemts;
- public ElementsEdge(List<Element> elements)
- {
- this.m_RefElelemts = new List<Element>(elements);
- this.RefData = new ReadOnlyCollection<Element>(this.m_RefElelemts);
- }
- /// <summary>
- /// 边关联元素
- /// </summary>
- public ReadOnlyCollection<Element> RefData { get; private set; }
- #region 创建edge
- /// <summary>
- /// 根据元素信息创建拓扑边
- /// </summary>
- /// <param name="start"></param>
- /// <param name="end"></param>
- /// <param name="path"></param>
- /// <returns></returns>
- public static ElementsEdge CreateEdge(ElementsVertex start, ElementsVertex end, List<Element> path)
- {
- ElementsEdge edge = new ElementsEdge(path);
- edge.Start = start;
- edge.End = end;
- return edge;
- }
- #endregion
- #endregion
- /// <summary>
- /// 边类型
- /// </summary>
- public EdgeType EdgeType { get; set; }
- /// <summary>
- /// 开始点
- /// </summary>
- public ElementsVertex Start { get; set; }
- /// <summary>
- /// 结束点
- /// </summary>
- public ElementsVertex End { get; set; }
- #region 业务属性
- /// <summary>
- /// 关联系统类型
- /// </summary>
- public string SystemName { get; set; }
- /// <summary>
- /// 边类别
- /// </summary>
- public string EdgeCategory { get; set; }
- /// <summary>
- /// flowType[流出为1,流入为2]
- /// </summary>
- public int FlowType { get; set; }
- #endregion
- #region 真实点维护
- public ElementsVertex m_RealStart;
- /// <summary>
- /// 真实的开始点
- /// </summary>
- public ElementsVertex RealStart
- {
- get
- {
- InitRealEnd(); //缓存控制繁琐,暂时去掉
- if (m_RealStart == null)
- {
- m_RealStart = this.Start.GetRoot();
- }
- return m_RealStart;
- }
- }
- public ElementsVertex m_RealEnd;
- /// <summary>
- /// 真实的结束点
- /// </summary>
- public ElementsVertex RealEnd
- {
- get
- {
- InitRealEnd();
- if (m_RealEnd == null)
- {
- m_RealEnd = this.End.GetRoot();
- }
- return m_RealEnd;
- }
- }
- /// <summary>
- /// 重新获取真实点信息
- /// </summary>
- public void InitRealEnd()
- {
- this.m_RealEnd = null;
- this.m_RealStart = null;
- }
- #endregion
- /// <summary>
- /// 判断两个边是否共享点
- /// </summary>
- /// <param name="edge"></param>
- /// <returns></returns>
- public bool IsSharedVertexByName(ElementsEdge edge)
- {
- List<string> sources = new List<string>() {this.RealStart.Id, this.RealEnd.Id};
- List<string> input = new List<string>() {edge.RealStart.Id, edge.RealEnd.Id};
- return sources.All(s => input.Contains(s));
- }
- /// <summary>
- /// 是否包含节点,-1 不包含,0开始点,1结束点
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- public int ContainVertexById(string id)
- {
- int result = -1;
- if (RealStart.Id == id)
- result = 0;
- else if (RealEnd.Id == id)
- result = 1;
- return result;
- }
- /// <summary>
- /// 获取另一个节点
- /// </summary>
- /// <param name="vertex"></param>
- /// <returns></returns>
- public ElementsVertex GetAnotherVertex(ElementsVertex vertex)
- {
- if (RealStart.Id != vertex.Id)
- return RealStart;
- else if (RealEnd.Id != vertex.Id)
- return RealEnd;
- //前面逻辑不执行,原因是因为可能开始点和结束点相同
- return RealEnd;
- }
- public ElementsVertex GetAnotherVertex(string id)
- {
- if (RealStart.Id != id)
- return RealStart;
- else if (RealEnd.Id != id)
- return RealEnd;
- return null;
- }
- /// <summary>
- /// 设备位置
- /// </summary>
- //public XYZ EquipLocation { get; set; }
- #region 获取边结构几何信息
- private List<ElementsEdge> GetLeavesByType(EdgeType edgeType)
- {
- List<ElementsEdge> result = new List<ElementsEdge>();
- Queue<ElementsEdge> queue = new Queue<ElementsEdge>();
- queue.Enqueue(this);
- while (queue.Any())
- {
- var current = queue.Dequeue();
- if (current != null)
- {
- if (current.Children.Count == 0 && current.Parent != null && current.Parent.EdgeType == edgeType)
- {
- result.Add(current);
- }
- else
- {
- current.Children.ToList().ForEach(c => queue.Enqueue(c));
- }
- }
- }
- return result;
- }
- public int GetWidth()
- {
- return GetWidth(this);
- }
- public static int GetWidth(ElementsEdge edge)
- {
- int result = 0;
- if (edge.Children.Count == 0)
- result = 1;
- if (edge.EdgeType == EdgeType.Parallel)
- {
- foreach (var elementsEdge in edge.Children)
- {
- result += GetWidth(elementsEdge);
- }
- }
- else
- {
- foreach (var elementsEdge in edge.Children)
- {
- result = Math.Max(result, GetWidth(elementsEdge));
- }
- }
- return result;
- }
- public int GetLength()
- {
- return GetLength(this) ;
- }
- public static int GetLength(ElementsEdge edge)
- {
- int result = 0;
- if (edge.Children.Count == 0)
- result = 1;
- if (edge.EdgeType == EdgeType.Parallel)
- {
- foreach (var elementsEdge in edge.Children)
- {
- result = Math.Max(result, GetLength(elementsEdge));
- }
- }
- else
- {
- foreach (var elementsEdge in edge.Children)
- {
- result += GetLength(elementsEdge);
- }
- }
- return result;
- }
- #endregion
- #region 翻转边数据
- private bool m_IsReverseDeep;
- public void Reverse()
- {
- var tempVertex = this.Start;
- this.Start = this.End;
- this.End = tempVertex;
- InitRealEnd();
- this.m_RefElelemts.Reverse();
- this.Children.Reverse();
- if (m_IsReverseDeep)
- {
- foreach (var elementsEdge in this.Children)
- {
- elementsEdge.Reverse();
- }
- }
-
- }
- /// <summary>
- /// 深度翻转
- /// </summary>
- public void ReverseDeep()
- {
- try
- {
- m_IsReverseDeep = true;
- this.Reverse();
- }
- finally
- {
- m_IsReverseDeep = false;
- }
- }
- #endregion
- #region 整理子节点拓扑关系
- public void ArrangeChildrenVertex()
- {
- var availableEdge = this;
- var startVertexId = availableEdge.RealStart.Id;
- if (availableEdge.EdgeType == EdgeType.Parallel)
- {
- var parallelEdges = availableEdge.Children;
- foreach (var parallelEdge in parallelEdges)
- {
- if (parallelEdge.ContainVertexById(startVertexId) == 1)
- {
- parallelEdge.Reverse();
- }
- }
- }
- else
- {
- var seriesEdges = availableEdge.Children;
- foreach (var seriesEdge in seriesEdges)
- {
- if (seriesEdge.ContainVertexById(startVertexId) == 1)
- {
- seriesEdge.Reverse();
- }
- #region 取下一个开始点
- var another = seriesEdge.GetAnotherVertex(startVertexId);
- if (another != null)
- {
- startVertexId = another.Id;
- }
- #endregion
- }
- }
- this.Children.ToList().ForEach(e=>e.ArrangeChildrenVertex());
- }
- #endregion
- }
- }
|