ElementsEdge.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. using Autodesk.Revit.DB;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.ComponentModel;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace SAGA.RevitUtils
  10. {
  11. /// <summary>
  12. /// 边类型
  13. /// </summary>
  14. public enum EdgeType
  15. {
  16. [Description("原始边")]
  17. Origin,
  18. [Description("子边串联")]
  19. Series,
  20. [Description("子边并联")]
  21. Parallel,
  22. }
  23. public class ElementsEdge : GraphNode<ElementsEdge>
  24. {
  25. #region 创建相关
  26. protected List<Element> m_RefElelemts;
  27. public ElementsEdge(List<Element> elements)
  28. {
  29. this.m_RefElelemts = new List<Element>(elements);
  30. this.RefData = new ReadOnlyCollection<Element>(this.m_RefElelemts);
  31. }
  32. /// <summary>
  33. /// 边关联元素
  34. /// </summary>
  35. public ReadOnlyCollection<Element> RefData { get; private set; }
  36. #region 创建edge
  37. /// <summary>
  38. /// 根据元素信息创建拓扑边
  39. /// </summary>
  40. /// <param name="start"></param>
  41. /// <param name="end"></param>
  42. /// <param name="path"></param>
  43. /// <returns></returns>
  44. public static ElementsEdge CreateEdge(ElementsVertex start, ElementsVertex end, List<Element> path)
  45. {
  46. ElementsEdge edge = new ElementsEdge(path);
  47. edge.Start = start;
  48. edge.End = end;
  49. return edge;
  50. }
  51. #endregion
  52. #endregion
  53. /// <summary>
  54. /// 边类型
  55. /// </summary>
  56. public EdgeType EdgeType { get; set; }
  57. /// <summary>
  58. /// 开始点
  59. /// </summary>
  60. public ElementsVertex Start { get; set; }
  61. /// <summary>
  62. /// 结束点
  63. /// </summary>
  64. public ElementsVertex End { get; set; }
  65. #region 业务属性
  66. /// <summary>
  67. /// 关联系统类型
  68. /// </summary>
  69. public string SystemName { get; set; }
  70. /// <summary>
  71. /// 边类别
  72. /// </summary>
  73. public string EdgeCategory { get; set; }
  74. /// <summary>
  75. /// flowType[流出为1,流入为2]
  76. /// </summary>
  77. public int FlowType { get; set; }
  78. #endregion
  79. #region 真实点维护
  80. public ElementsVertex m_RealStart;
  81. /// <summary>
  82. /// 真实的开始点
  83. /// </summary>
  84. public ElementsVertex RealStart
  85. {
  86. get
  87. {
  88. InitRealEnd(); //缓存控制繁琐,暂时去掉
  89. if (m_RealStart == null)
  90. {
  91. m_RealStart = this.Start.GetRoot();
  92. }
  93. return m_RealStart;
  94. }
  95. }
  96. public ElementsVertex m_RealEnd;
  97. /// <summary>
  98. /// 真实的结束点
  99. /// </summary>
  100. public ElementsVertex RealEnd
  101. {
  102. get
  103. {
  104. InitRealEnd();
  105. if (m_RealEnd == null)
  106. {
  107. m_RealEnd = this.End.GetRoot();
  108. }
  109. return m_RealEnd;
  110. }
  111. }
  112. /// <summary>
  113. /// 重新获取真实点信息
  114. /// </summary>
  115. public void InitRealEnd()
  116. {
  117. this.m_RealEnd = null;
  118. this.m_RealStart = null;
  119. }
  120. #endregion
  121. /// <summary>
  122. /// 判断两个边是否共享点
  123. /// </summary>
  124. /// <param name="edge"></param>
  125. /// <returns></returns>
  126. public bool IsSharedVertexByName(ElementsEdge edge)
  127. {
  128. List<string> sources = new List<string>() {this.RealStart.Id, this.RealEnd.Id};
  129. List<string> input = new List<string>() {edge.RealStart.Id, edge.RealEnd.Id};
  130. return sources.All(s => input.Contains(s));
  131. }
  132. /// <summary>
  133. /// 是否包含节点,-1 不包含,0开始点,1结束点
  134. /// </summary>
  135. /// <param name="id"></param>
  136. /// <returns></returns>
  137. public int ContainVertexById(string id)
  138. {
  139. int result = -1;
  140. if (RealStart.Id == id)
  141. result = 0;
  142. else if (RealEnd.Id == id)
  143. result = 1;
  144. return result;
  145. }
  146. /// <summary>
  147. /// 获取另一个节点
  148. /// </summary>
  149. /// <param name="vertex"></param>
  150. /// <returns></returns>
  151. public ElementsVertex GetAnotherVertex(ElementsVertex vertex)
  152. {
  153. if (RealStart.Id != vertex.Id)
  154. return RealStart;
  155. else if (RealEnd.Id != vertex.Id)
  156. return RealEnd;
  157. //前面逻辑不执行,原因是因为可能开始点和结束点相同
  158. return RealEnd;
  159. }
  160. public ElementsVertex GetAnotherVertex(string id)
  161. {
  162. if (RealStart.Id != id)
  163. return RealStart;
  164. else if (RealEnd.Id != id)
  165. return RealEnd;
  166. return null;
  167. }
  168. /// <summary>
  169. /// 设备位置
  170. /// </summary>
  171. //public XYZ EquipLocation { get; set; }
  172. #region 获取边结构几何信息
  173. private List<ElementsEdge> GetLeavesByType(EdgeType edgeType)
  174. {
  175. List<ElementsEdge> result = new List<ElementsEdge>();
  176. Queue<ElementsEdge> queue = new Queue<ElementsEdge>();
  177. queue.Enqueue(this);
  178. while (queue.Any())
  179. {
  180. var current = queue.Dequeue();
  181. if (current != null)
  182. {
  183. if (current.Children.Count == 0 && current.Parent != null && current.Parent.EdgeType == edgeType)
  184. {
  185. result.Add(current);
  186. }
  187. else
  188. {
  189. current.Children.ToList().ForEach(c => queue.Enqueue(c));
  190. }
  191. }
  192. }
  193. return result;
  194. }
  195. public int GetWidth()
  196. {
  197. return GetWidth(this);
  198. }
  199. public static int GetWidth(ElementsEdge edge)
  200. {
  201. int result = 0;
  202. if (edge.Children.Count == 0)
  203. result = 1;
  204. if (edge.EdgeType == EdgeType.Parallel)
  205. {
  206. foreach (var elementsEdge in edge.Children)
  207. {
  208. result += GetWidth(elementsEdge);
  209. }
  210. }
  211. else
  212. {
  213. foreach (var elementsEdge in edge.Children)
  214. {
  215. result = Math.Max(result, GetWidth(elementsEdge));
  216. }
  217. }
  218. return result;
  219. }
  220. public int GetLength()
  221. {
  222. return GetLength(this) ;
  223. }
  224. public static int GetLength(ElementsEdge edge)
  225. {
  226. int result = 0;
  227. if (edge.Children.Count == 0)
  228. result = 1;
  229. if (edge.EdgeType == EdgeType.Parallel)
  230. {
  231. foreach (var elementsEdge in edge.Children)
  232. {
  233. result = Math.Max(result, GetLength(elementsEdge));
  234. }
  235. }
  236. else
  237. {
  238. foreach (var elementsEdge in edge.Children)
  239. {
  240. result += GetLength(elementsEdge);
  241. }
  242. }
  243. return result;
  244. }
  245. #endregion
  246. #region 翻转边数据
  247. private bool m_IsReverseDeep;
  248. public void Reverse()
  249. {
  250. var tempVertex = this.Start;
  251. this.Start = this.End;
  252. this.End = tempVertex;
  253. InitRealEnd();
  254. this.m_RefElelemts.Reverse();
  255. this.Children.Reverse();
  256. if (m_IsReverseDeep)
  257. {
  258. foreach (var elementsEdge in this.Children)
  259. {
  260. elementsEdge.Reverse();
  261. }
  262. }
  263. }
  264. /// <summary>
  265. /// 深度翻转
  266. /// </summary>
  267. public void ReverseDeep()
  268. {
  269. try
  270. {
  271. m_IsReverseDeep = true;
  272. this.Reverse();
  273. }
  274. finally
  275. {
  276. m_IsReverseDeep = false;
  277. }
  278. }
  279. #endregion
  280. #region 整理子节点拓扑关系
  281. public void ArrangeChildrenVertex()
  282. {
  283. var availableEdge = this;
  284. var startVertexId = availableEdge.RealStart.Id;
  285. if (availableEdge.EdgeType == EdgeType.Parallel)
  286. {
  287. var parallelEdges = availableEdge.Children;
  288. foreach (var parallelEdge in parallelEdges)
  289. {
  290. if (parallelEdge.ContainVertexById(startVertexId) == 1)
  291. {
  292. parallelEdge.Reverse();
  293. }
  294. }
  295. }
  296. else
  297. {
  298. var seriesEdges = availableEdge.Children;
  299. foreach (var seriesEdge in seriesEdges)
  300. {
  301. if (seriesEdge.ContainVertexById(startVertexId) == 1)
  302. {
  303. seriesEdge.Reverse();
  304. }
  305. #region 取下一个开始点
  306. var another = seriesEdge.GetAnotherVertex(startVertexId);
  307. if (another != null)
  308. {
  309. startVertexId = another.Id;
  310. }
  311. #endregion
  312. }
  313. }
  314. this.Children.ToList().ForEach(e=>e.ArrangeChildrenVertex());
  315. }
  316. #endregion
  317. }
  318. }