GplotGraphParse.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:GplotGraphParse
  3. * 作者:xulisong
  4. * 创建时间: 2019/2/14 17:51:58
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using Autodesk.Revit.DB;
  13. using SAGA.DotNetUtils.Data;
  14. using SAGA.DotNetUtils.Extend;
  15. using SAGA.GplotRelationComputerManage.SystemChecks;
  16. using SAGA.RevitUtils;
  17. using SAGA.RevitUtils.Data.Graph;
  18. using SAGA.RevitUtils.Extends;
  19. namespace SAGA.GplotRelationComputerManage
  20. {
  21. /// <summary>
  22. /// 拓扑图解析
  23. /// </summary>
  24. public class GplotGraphParse
  25. {
  26. public GplotGraphParse(GplotGraphSetting setting)
  27. {
  28. Setting = setting;
  29. }
  30. #region 属性相关
  31. /// <summary>
  32. /// 系统解析设置
  33. /// </summary>
  34. public GplotGraphSetting Setting { get; private set; }
  35. #endregion
  36. #region 创建拓扑图信息
  37. /// <summary>
  38. /// 创建拓扑结构图
  39. /// </summary>
  40. /// <param name="startElements"></param>
  41. /// <returns></returns>
  42. public List<SystemGraph> CreateGplotGraphs(List<Element> startElements)
  43. {
  44. List<SystemGraph> arrays = new List<SystemGraph>();
  45. var newStartElements = startElements.Distinct(new ElementEqualComparer()).ToList();
  46. while (newStartElements.Any())
  47. {
  48. var baseElement = newStartElements[0];
  49. newStartElements.Remove(baseElement);
  50. var graph = CreateGplotGraph(baseElement);
  51. var containElements = graph.GetRefElements();
  52. newStartElements = newStartElements.Except(containElements, new ElementEqualComparer()).ToList();
  53. arrays.Add(graph);
  54. }
  55. return arrays;
  56. }
  57. /// <summary>
  58. /// 创建拓扑结构图
  59. /// </summary>
  60. /// <param name="element"></param>
  61. /// <returns></returns>
  62. public SystemGraph CreateGplotGraph(Element element)
  63. {
  64. SystemGraph graph = GetOriginGraph(element);
  65. //节点处理
  66. ArrangeVertex(graph);
  67. //边处理
  68. ArrangeEdge(graph);
  69. return graph;
  70. }
  71. #endregion
  72. #region 解析原始图
  73. /// <summary>
  74. /// 创建原始的节点图,以起点元素为首个节点
  75. /// </summary>
  76. /// <param name="element"></param>
  77. /// <returns></returns>
  78. public SystemGraph GetOriginGraph(Element element)
  79. {
  80. return SystemGraphUtil.CreateGraph(element, Setting.IgnoredConnector, Setting.IgnoredElement,Setting.BreakElement);
  81. }
  82. #endregion
  83. #region 相关子方法
  84. #region 节点处理
  85. /// <summary>
  86. /// 整理点
  87. /// </summary>
  88. /// <param name="graph"></param>
  89. private void ArrangeVertex(SystemGraph graph)
  90. {
  91. #region 分析
  92. /*
  93. * 1、如果节点元素是一个管道,则将管道没有连接的那一个点创建一个“空间”设备,标记不可合并
  94. * 2、如果节点是设备或者特殊阀门,则标记不能合并,并加载物理世界相关设备信息
  95. * 3、如果一个点只有两条边,且该点可以被合并,则创建新边,关联上述两条边和点信息;删除旧的信息
  96. * 4、如果一条边的两个点,都是可合并,并过滤所有以这两个点为顶点的边,将这些信息合并成新的点;
  97. * 处理这种点融合边的情况,有两种方案:1,创建新点,将旧的点设置为新点的子节点。2、修改所有边的相依的节点Id为新Id
  98. * 方案各有利弊,第一种保留了初始状态,第二种以后遍历时方便
  99. */
  100. #endregion
  101. AttachVertexInfo(graph);
  102. var newCount = graph.GetBootVertexs().Count;
  103. var oldCount = 0;
  104. do
  105. {
  106. oldCount = newCount;
  107. CombineVertex(graph);
  108. newCount = graph.GetBootVertexs().Count;
  109. //数量不变,算处理完
  110. } while (oldCount != newCount);
  111. }
  112. /// <summary>
  113. /// 附加节点信息
  114. /// </summary>
  115. /// <param name="graph"></param>
  116. private void AttachVertexInfo(SystemGraph graph)
  117. {
  118. var useVertexes = graph.GetBootVertexs();
  119. #region
  120. foreach (var systemVertex in useVertexes)
  121. {
  122. var data = systemVertex.Data;
  123. if (!data.Any())
  124. {
  125. continue;
  126. }
  127. //理论上此时场景,有且仅有一个关联元素
  128. var useElement = data[0];
  129. #region 虚拟设备处理
  130. EquipmentItem item = new EquipmentItem();
  131. if (useElement is MEPCurve)
  132. {
  133. item.IsVirtual = true;
  134. var edges = graph.GetOutEdges(systemVertex.Id);
  135. if (edges.Count == 1)
  136. {
  137. var currentEdge = edges[0];
  138. var joinItems = JoinItem.GetJoinItems(useElement);
  139. foreach (var joinItem in joinItems)
  140. {
  141. if (joinItem.RefElement != null && currentEdge.Data.All(e => e.Id != joinItem.RefElement.Id))
  142. {
  143. //处理点边关联信息
  144. currentEdge.Data.Add(useElement);
  145. systemVertex.Data.Remove(useElement);
  146. systemVertex.CanCombine = false;
  147. //找到断头点
  148. var location = joinItem.RefConnector.Origin;
  149. var space = useElement.Document.GetSpaceAtPoint(location);
  150. if (space != null)
  151. {
  152. item.Id = space.Id.ToString();
  153. item.BimId = space.GetBimId();
  154. }
  155. else
  156. {
  157. item.Name = string.Format("空间{0}", location.ToString());
  158. }
  159. item.ElementType = SystemCalcUtil.IsStart(useElement)?ElementType.VerticalPipe: ElementType.Space;
  160. if (SystemCalcUtil.IsStart(useElement))
  161. {
  162. item.Name = string.Format("【{0}】立管:{1}", (useElement as MEPCurve).GetSystemTypeName(),useElement.Id.ToString());
  163. }
  164. systemVertex.SetEquipment(item);
  165. break;
  166. }
  167. }
  168. }
  169. continue;
  170. }
  171. #endregion
  172. #region 真实设备处理
  173. item.Id = useElement.Id.ToString();
  174. item.BimId = useElement.GetBimId();
  175. item.Name = useElement.GetFamily()?.Name;
  176. if (MBIInfoUtil.IsEquipment(useElement))
  177. {
  178. systemVertex.CanCombine = false;
  179. item.ElementType = ElementType.Equipment;
  180. systemVertex.SetEquipment(item);
  181. continue;
  182. }
  183. if (SystemCalcUtil.IsStartValve(useElement))
  184. {
  185. systemVertex.CanCombine = false;
  186. item.IsVirtual = true;
  187. item.ElementType = ElementType.Equipment;
  188. systemVertex.SetEquipment(item);
  189. continue;
  190. }
  191. #endregion
  192. }
  193. #endregion
  194. }
  195. /// <summary>
  196. /// 合并节点
  197. /// </summary>
  198. /// <param name="graph"></param>
  199. public void CombineVertex(SystemGraph graph)
  200. {
  201. #region 以点为基础处理
  202. var useVertexes = graph.GetBootVertexs();
  203. foreach (var systemVertex in useVertexes)
  204. {
  205. if (!systemVertex.CanCombine)
  206. {
  207. continue;
  208. }
  209. var edges = graph.GetInEdges(systemVertex.Id);
  210. if (edges.Count != 2)
  211. {
  212. continue;
  213. }
  214. string startId = edges[0].GetAnotherVertex(systemVertex.Id);
  215. string endId = edges[1].GetAnotherVertex(systemVertex.Id);
  216. edges.ForEach(e => graph.RemoveEdge(e.Id));
  217. graph.RemoveVertex(systemVertex.Id);
  218. var newEdge = new SystemEdge(startId, endId);
  219. newEdge.Data = new SystemData(edges[0].Data);
  220. newEdge.Data.ExtendRefElements(edges[1].Data);
  221. newEdge.Data.ExtendRefElements(systemVertex.Data);
  222. graph.AddEdge(newEdge);
  223. }
  224. #endregion
  225. #region 以边为基础处理
  226. HandledMap map = new HandledMap();
  227. var useEdges = graph.GetBootEdges();
  228. for (int i = 0; i < useEdges.Count; i++)
  229. {
  230. var baseEdge = useEdges[i];
  231. if (map.GetHandled(baseEdge.Id))
  232. continue;
  233. var startVertex = graph.GetBootStartVertex(baseEdge);
  234. var endVertex = graph.GetBootEndVertex(baseEdge);
  235. if (startVertex == null || endVertex == null)
  236. {
  237. continue;
  238. }
  239. if (!startVertex.CanCombine || !endVertex.CanCombine)
  240. {
  241. continue;
  242. }
  243. // 如果两个节点之下还有一条其他的包含设备的边,则该边的两点不能合并
  244. var refEdges = graph.GetEdges(baseEdge.StartVertex, baseEdge.EndVertex);
  245. #region 创建新的点
  246. List<Element> elements = new List<Element>();
  247. elements.AddRange(startVertex.Data);
  248. elements.AddRange(endVertex.Data);
  249. foreach (var elementsEdge in refEdges)
  250. {
  251. elements.AddRange(elementsEdge.Data);
  252. graph.RemoveEdge(elementsEdge.Id);
  253. map.SetHandled(elementsEdge.Id, true);
  254. }
  255. graph.RemoveVertex(startVertex.Id);
  256. graph.RemoveVertex(endVertex.Id);
  257. elements = elements.Distinct(new ElementEqualComparer()).ToList();
  258. SystemVertex newVertex = new SystemVertex(new SystemData(elements));
  259. newVertex = graph.AddVertex(newVertex);
  260. #endregion
  261. #region 更新关联边的关联点
  262. var vertexIds = new List<string>() { startVertex.Id, endVertex.Id };
  263. foreach (var vertexId in vertexIds)
  264. {
  265. var edges = graph.GetInEdges(vertexId);
  266. foreach (var systemEdge in edges)
  267. {
  268. var flag = systemEdge.ContainVertex(vertexId);
  269. if (flag == 0)
  270. {
  271. systemEdge.UpdateStartVertex(newVertex.Id);
  272. }
  273. else if (flag == 1)
  274. {
  275. systemEdge.UpdateEndVertex(newVertex.Id);
  276. }
  277. }
  278. }
  279. #endregion
  280. }
  281. #endregion
  282. }
  283. #endregion
  284. #region 边处理
  285. /// <summary>
  286. /// 整理边
  287. /// </summary>
  288. /// <param name="graph"></param>
  289. private void ArrangeEdge(SystemGraph graph)
  290. {
  291. //有向化处理
  292. DirectedEdge(graph);
  293. //DirectedEdge2(graph);
  294. graph.IsDirection = true;
  295. //串并联处理
  296. //EdgesArrayGraphUtil.GplotAnalyse(graph);
  297. }
  298. /// <summary>
  299. /// 确定流向
  300. /// </summary>
  301. /// <param name="graph"></param>
  302. private void DirectedEdge(SystemGraph graph)
  303. {
  304. #region 加载边的系统信息
  305. var originEdges = graph.Edges.Where(e => !e.Children.Any()).ToList();
  306. foreach (var originEdge in originEdges)
  307. {
  308. var refElements = originEdge.Data;
  309. //获取边系统类型
  310. originEdge.SystemName = (refElements.FirstOrDefault(e => e is MEPCurve) as MEPCurve)?.GetSystemTypeName();
  311. //根据系统类型和特殊设备确定旁通和补水;未完,待续
  312. var systemItem = Setting.RelationTypeShell.GetFirstMatchSystem(originEdge.SystemName);
  313. if (systemItem != null)
  314. {
  315. originEdge.EdgeCategory = systemItem.ContainEdgeTypes.FirstOrDefault();
  316. originEdge.FlowType = systemItem.FlowType == FlowType.In ? 2 : 1;
  317. }
  318. }
  319. #endregion
  320. #region 描述
  321. /*
  322. * 1、查找遍历起点
  323. * 2、根据起点遍历所有的节点,并调整节点的顺序
  324. */
  325. #endregion
  326. #region 获取定义端点
  327. var vertexes = graph.GetBootVertexs().Where(v => SystemCalcUtil.IsStartValveName(v.GetEquipment()?.Name)).ToList();
  328. if (!vertexes.Any())
  329. return;
  330. foreach (var systemVertex in vertexes)
  331. {
  332. var tempEdges = graph.GetInEdges(systemVertex.Id);
  333. if (tempEdges.Any())
  334. {
  335. var item = systemVertex.GetEquipment();
  336. if (item == null)
  337. {
  338. continue;
  339. }
  340. if (tempEdges.Any(e => e.FlowType == 2))
  341. {
  342. item.Name = "出口" + item.Id;
  343. }
  344. else
  345. {
  346. item.Name = "入口" + item.Id;
  347. }
  348. }
  349. }
  350. #endregion
  351. #region 确定开始点
  352. HashSet<string> edgeIds = new HashSet<string>();
  353. //点遍历id区分系 flowType信息
  354. HashSet<string> vertexIds = new HashSet<string>();
  355. foreach (var systemVertex in vertexes)
  356. {
  357. if (vertexIds.Contains(systemVertex.Id))
  358. {
  359. continue;
  360. }
  361. bool isStart = true;
  362. var currentVertexName = systemVertex.GetEquipment().Name;
  363. if (string.IsNullOrWhiteSpace(currentVertexName))
  364. {
  365. continue;
  366. }
  367. var useFlowType = 0;
  368. if (currentVertexName.Contains("入口"))
  369. {
  370. useFlowType = 1;
  371. isStart = true;
  372. }
  373. else if(currentVertexName.Contains("出口"))
  374. {
  375. useFlowType = 2;
  376. isStart = false;
  377. }
  378. else
  379. {
  380. continue;
  381. }
  382. Queue<SystemVertex> queueVertexes = new Queue<SystemVertex>();
  383. queueVertexes.Enqueue(systemVertex);
  384. Func<string, string> commonId = (str) => useFlowType + "_" + str ;
  385. while (queueVertexes.Any())
  386. {
  387. var currentVertex = queueVertexes.Dequeue();
  388. //普通节点Id
  389. if (vertexIds.Contains(commonId(currentVertex.Id)))
  390. {
  391. continue;
  392. }
  393. vertexIds.Add(commonId(currentVertex.Id));
  394. var edges = graph.GetInEdges(currentVertex.Id);
  395. foreach (var systemEdge in edges)
  396. {
  397. if (systemEdge.FlowType != useFlowType)
  398. {
  399. continue;
  400. }
  401. if (edgeIds.Contains(systemEdge.Id))
  402. {
  403. continue;
  404. }
  405. var otherId = systemEdge.GetAnotherVertex(currentVertex.Id);
  406. if (vertexes.Any(v => v.Id == otherId))
  407. {
  408. continue;
  409. }
  410. edgeIds.Add(systemEdge.Id);
  411. if ((isStart && systemEdge.ContainVertex(currentVertex.Id) == 1) || (!isStart && systemEdge.ContainVertex(currentVertex.Id) == 0))
  412. {
  413. systemEdge.Reverse();
  414. }
  415. if (!vertexIds.Contains(commonId(otherId)))
  416. {
  417. var nextVertex = graph.FindVertex(otherId);
  418. if (nextVertex != null)
  419. {
  420. queueVertexes.Enqueue(nextVertex);
  421. }
  422. }
  423. }
  424. }
  425. }
  426. #endregion
  427. }
  428. /// <summary>
  429. /// 确定流向,
  430. /// </summary>
  431. /// <param name="graph"></param>
  432. private void DirectedEdge2(SystemGraph graph)
  433. {
  434. #region 加载边的系统信息
  435. var originEdges = graph.Edges.Where(e => !e.Children.Any()).ToList();
  436. foreach (var originEdge in originEdges)
  437. {
  438. var refElements = originEdge.Data;
  439. //获取边系统类型
  440. originEdge.SystemName = (refElements.FirstOrDefault(e => e is MEPCurve) as MEPCurve)?.GetSystemTypeName();
  441. //根据系统类型和特殊设备确定旁通和补水;未完,待续
  442. var systemItem = Setting.RelationTypeShell.GetFirstMatchSystem(originEdge.SystemName);
  443. if (systemItem != null)
  444. {
  445. originEdge.EdgeCategory = systemItem.ContainEdgeTypes.FirstOrDefault();
  446. originEdge.FlowType = systemItem.FlowType == FlowType.In ? 2 : 1;
  447. }
  448. }
  449. #endregion
  450. #region 描述
  451. /*
  452. * 1、查找遍历起点
  453. * 2、根据起点遍历所有的节点,并调整节点的顺序
  454. */
  455. #endregion
  456. #region 获取定义端点
  457. Document refDocument = null;
  458. foreach (var vertex in graph.Vertexes)
  459. {
  460. if (vertex.Data == null)
  461. continue;
  462. refDocument = vertex.Data.FirstOrDefault()?.Document;
  463. if (refDocument != null)
  464. break;
  465. }
  466. if (refDocument == null)
  467. return;
  468. //获取开始的category
  469. //如果没有设定开始点,则使用立管作为开始点
  470. List<SystemVertex> vertexes = new List<SystemVertex>();
  471. List<string> startCategories = GplotSystemCheckManager.GetSourceCategories(refDocument,Setting.RelationTypeShell.RelationItem.Type);
  472. if (startCategories.Any())
  473. {
  474. vertexes = graph.GetBootVertexs().Where(v => startCategories.Contains(MBIInfoUtil.GetEquipmentCategory(v.GetEquipment()?.Name) ?? string.Empty)).ToList();
  475. }
  476. else
  477. {
  478. vertexes = graph.GetBootVertexs().Where(v => v.GetEquipment()!=null&&v.GetEquipment().ElementType==ElementType.VerticalPipe).ToList();
  479. }
  480. if (!vertexes.Any())
  481. return;
  482. #endregion
  483. #region 确定开始点
  484. List<string> edgeIds = new List<string>();
  485. List<string> vertexIds = new List<string>();
  486. for (int i = 0; i < vertexes.Count; i++)
  487. {
  488. var currentVertex = vertexes[i];
  489. if (vertexIds.Contains(currentVertex.Id))
  490. {
  491. continue;
  492. }
  493. vertexIds.Add(currentVertex.Id);
  494. var edges = graph.GetInEdges(currentVertex.Id);
  495. foreach (var systemEdge in edges)
  496. {
  497. if (systemEdge.FlowType > 2)
  498. {
  499. continue;
  500. }
  501. if (edgeIds.Contains(systemEdge.Id))
  502. {
  503. continue;
  504. }
  505. edgeIds.Add(systemEdge.Id);
  506. if ((systemEdge.FlowType==2&&systemEdge.ContainVertex(currentVertex.Id) == 1)|| (systemEdge.FlowType == 1 && systemEdge.ContainVertex(currentVertex.Id) == 0))
  507. {
  508. systemEdge.Reverse();
  509. }
  510. var otherId = systemEdge.GetAnotherVertex(currentVertex.Id);
  511. if (!vertexIds.Contains(otherId))
  512. {
  513. var nextVertex = graph.FindVertex(otherId);
  514. if (nextVertex != null)
  515. {
  516. vertexes.Add(nextVertex);
  517. }
  518. }
  519. }
  520. }
  521. #endregion
  522. }
  523. #region 无向拓扑展开
  524. private class VertexInfo
  525. {
  526. public VertexInfo()
  527. { }
  528. public VertexInfo(List<SystemEdge> edges)
  529. {
  530. AllEdges = edges;
  531. CurrentDegree = edges.Count;
  532. }
  533. /// <summary>
  534. /// 关联边
  535. /// </summary>
  536. public List<SystemEdge> AllEdges { get; set; } = new List<SystemEdge>();
  537. public int CurrentDegree { get; set; }
  538. }
  539. /// <summary>
  540. /// 确定流向
  541. /// </summary>
  542. /// <param name="graph"></param>
  543. private void DirectedEdge3(SystemGraph graph)
  544. {
  545. #region 加载边的系统信息
  546. var originEdges = graph.Edges.Where(e => !e.Children.Any()).ToList();
  547. foreach (var originEdge in originEdges)
  548. {
  549. var refElements = originEdge.Data;
  550. //获取边系统类型
  551. originEdge.SystemName = (refElements.FirstOrDefault(e => e is MEPCurve) as MEPCurve)?.GetSystemTypeName();
  552. //根据系统类型和特殊设备确定旁通和补水;未完,待续
  553. var systemItem = Setting.RelationTypeShell.GetFirstMatchSystem(originEdge.SystemName);
  554. if (systemItem != null)
  555. {
  556. originEdge.EdgeCategory = systemItem.ContainEdgeTypes.FirstOrDefault();
  557. originEdge.FlowType = systemItem.FlowType == FlowType.In ? 2 : 1;
  558. }
  559. }
  560. #endregion
  561. #region 描述
  562. /*
  563. * 1、查找遍历起点
  564. * 2、根据起点遍历所有的节点,并调整节点的顺序
  565. */
  566. #endregion
  567. var allVertexs = graph.GetBootVertexs();
  568. #region 获取定义端点
  569. var vertexes = allVertexs.Where(v => SystemCalcUtil.IsStartValveName(v.GetEquipment()?.Name)).ToList();
  570. if (!vertexes.Any())
  571. return;
  572. //将顶点按前缀分组
  573. Dictionary<string, List<SystemVertex>> dicVertexes = new Dictionary<string, List<SystemVertex>>();
  574. foreach (var systemVertex in vertexes)
  575. {
  576. var tempEdges = graph.GetInEdges(systemVertex.Id);
  577. if (tempEdges.Any())
  578. {
  579. var item = systemVertex.GetEquipment();
  580. if (item == null)
  581. {
  582. continue;
  583. }
  584. if (tempEdges.Any(e => e.FlowType == 2))
  585. {
  586. item.Name = "出口" + item.Id;
  587. dicVertexes.AddGroupValue("出口", systemVertex);
  588. }
  589. else
  590. {
  591. item.Name = "入口" + item.Id;
  592. dicVertexes.AddGroupValue("出口", systemVertex);
  593. }
  594. }
  595. }
  596. #endregion
  597. #region 这里所有点的边集合信息和度的信息
  598. Dictionary<string, VertexInfo> vertexInfos = new Dictionary<string, VertexInfo>();
  599. foreach (var systemVertex in allVertexs)
  600. {
  601. var edges = graph.GetInEdges(systemVertex.Id);
  602. vertexInfos[systemVertex.Id] = new VertexInfo(edges);
  603. }
  604. #endregion
  605. #region 确定开始点
  606. HashSet<string> edgeIds = new HashSet<string>();
  607. //点遍历id区分系 flowType信息
  608. HashSet<string> vertexIds = new HashSet<string>();
  609. foreach (var dicVertex in dicVertexes)
  610. {
  611. #region 确定初始状态
  612. bool isStart = true;
  613. var useFlowType = 0;
  614. var key = dicVertex.Key;
  615. if (key.Contains("入口"))
  616. {
  617. useFlowType = 1;
  618. isStart = true;
  619. }
  620. else if (key.Contains("出口"))
  621. {
  622. useFlowType = 2;
  623. isStart = false;
  624. }
  625. else
  626. {
  627. continue;
  628. }
  629. #endregion
  630. Func<string, string> commonId = (str) => useFlowType + "_" + str;
  631. var useVertexes = new List<SystemVertex>(dicVertex.Value);
  632. useVertexes.ForEach(v => vertexInfos[v.Id].CurrentDegree = -1);
  633. while (useVertexes.Count > 0)
  634. {
  635. var useVertex = useVertexes[0];
  636. var useId = useVertex.Id;
  637. useVertexes.RemoveAt(0);
  638. if (vertexIds.Contains(useId))
  639. {
  640. continue;
  641. }
  642. vertexIds.Add(commonId(useId));
  643. var vertexInfo = vertexInfos[useId];
  644. var currentVextexCount = useVertexes.Count;
  645. foreach (var systemEdge in vertexInfo.AllEdges)
  646. {
  647. if (systemEdge.FlowType != useFlowType)
  648. {
  649. continue;
  650. }
  651. if (edgeIds.Contains(systemEdge.Id))
  652. {
  653. continue;
  654. }
  655. var otherId = systemEdge.GetAnotherVertex(useId);
  656. if (vertexes.Any(v => v.Id == otherId))
  657. {
  658. continue;
  659. }
  660. edgeIds.Add(systemEdge.Id);
  661. if ((isStart && systemEdge.ContainVertex(useId) == 1) || (!isStart && systemEdge.ContainVertex(useId) == 0))
  662. {
  663. systemEdge.Reverse();
  664. }
  665. if (!vertexIds.Contains(commonId(otherId)))
  666. {
  667. var nextVertex = graph.FindVertex(otherId);
  668. if (nextVertex != null)
  669. {
  670. useVertexes.Add(nextVertex);
  671. }
  672. }
  673. var otherInfo = vertexInfos[otherId];
  674. otherInfo.CurrentDegree = otherInfo.CurrentDegree - 1;
  675. }
  676. var newVextexCount = useVertexes.Count;
  677. if (currentVextexCount != newVextexCount)
  678. {
  679. useVertexes = useVertexes.OrderBy(v => vertexInfos[v.Id].CurrentDegree).ToList();
  680. }
  681. }
  682. }
  683. #endregion
  684. }
  685. #endregion
  686. #endregion
  687. #endregion
  688. }
  689. }