CreatePipeTool.h 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395
  1. #pragma once
  2. #include <BRepAlgoAPI_Cut.hxx>
  3. #include <BRepAlgoAPI_Fuse.hxx>
  4. #include <BRepBuilderAPI_MakeEdge.hxx>
  5. #include <BRepBuilderAPI_MakeFace.hxx>
  6. #include <BRepBuilderAPI_MakePolygon.hxx>
  7. #include <BRepBuilderAPI_MakeWire.hxx>
  8. #include <BRepFilletAPI_MakeFillet.hxx>
  9. #include <BRepOffsetAPI_MakePipe.hxx>
  10. #include <BRepOffsetAPI_ThruSections.hxx>
  11. #include <BRepPrimAPI_MakePrism.hxx>
  12. #include <GC_MakeArcOfCircle.hxx>
  13. #include <GeomAPI_ExtremaCurveCurve.hxx>
  14. #include <GeomAPI_IntCS.hxx>
  15. #include <Geom_Line.hxx>
  16. #include <Standard_UUID.hxx>
  17. #include <TopExp_Explorer.hxx>
  18. #include <TopoDS_Face.hxx>
  19. #include <TopoDS_Shape.hxx>
  20. #include <TopoDS_Wire.hxx>
  21. #include <algorithm>
  22. #include <gp_Ax2.hxx>
  23. #include <gp_Circ.hxx>
  24. #include <gp_Lin.hxx>
  25. #include <gp_Pnt.hxx>
  26. #include <iostream>
  27. using namespace std;
  28. struct Pipe {
  29. Pipe(gp_Pnt p1, gp_Pnt p2, double r)
  30. : startP(p1)
  31. , endP(p2)
  32. , radius(r) {
  33. };
  34. Pipe(std::string ndstr, gp_Pnt p1, gp_Pnt p2, double r)
  35. : nd(ndstr)
  36. , startP(p1)
  37. , endP(p2)
  38. , radius(r) {
  39. };
  40. std::string id; // 唯一标识
  41. std::string nd; // 公称通径
  42. gp_Pnt startP; // 起始点
  43. gp_Pnt endP; // 结束点
  44. double radius = -1; // 公称半径
  45. std::string startConnectId; // 起始管接头id
  46. std::string endConnectId; // 终点管接头id
  47. };
  48. struct PipeConnect {
  49. PipeConnect() {};
  50. PipeConnect(int n, double r1, double r2)
  51. : type(n)
  52. , radiusD1(r1)
  53. , radiusD2(r2) {
  54. };
  55. PipeConnect(int n, std::string tj, double r1, double r2, double C, double M) // 四通用
  56. : type(n)
  57. , nd(tj)
  58. , radiusD1(r1)
  59. , radiusD2(r2)
  60. , lengthC(C)
  61. , lengthM(M) {
  62. };
  63. PipeConnect(int n, std::string tj, double r1, double C) // 二通用
  64. : type(n)
  65. , nd(tj)
  66. , radiusD1(r1)
  67. , lengthC(C) {
  68. };
  69. PipeConnect(int n, gp_Pnt p1, double r1, double r2)
  70. : type(n)
  71. , center(p1)
  72. , radiusD1(r1)
  73. , radiusD2(r2) {
  74. };
  75. std::string id; // 唯一标识
  76. int type; // 类型 2:弯头 3:三通 4:四通 5:变径管
  77. // 1.当type=2时为弯头,此时radiusD1为图例中的0.5*OD,radiusD2和lengthM的值为空,lengthC表示为图例中的A短半径
  78. // 2.当type=3或4时,points前两个点对应截面半径为radiusD1,后两个对应radiusD2
  79. // 3.当type=5时,points前两个点对应变径管的起始点和结束点
  80. std::string nd; // 公称通径
  81. double radiusD1 = -1; // 公称半径
  82. double radiusD2 = -1; // 公称半径
  83. double lengthC = -1; // C/短半径
  84. double lengthM = -1; // M
  85. gp_Pnt center; // 中心点(管道的交点)
  86. vector<gp_Pnt> points; // 截面中心点
  87. };
  88. struct PipeResult {
  89. std::vector<Pipe> pipes;
  90. std::vector<PipeConnect> pipeConnects;
  91. bool isOk;
  92. std::string error;
  93. };
  94. class CreatePipeTool {
  95. public:
  96. static TopoDS_Wire CreateCircularWire(const gp_Pnt& center, const gp_Dir& normal, double radius)
  97. {
  98. if (radius <= 0) {
  99. return {};
  100. }
  101. gp_Ax2 axis2(center, normal);
  102. gp_Circ circle = gp_Circ(axis2, radius);
  103. BRepBuilderAPI_MakeEdge edgeMaker(circle);
  104. TopoDS_Edge edge = edgeMaker;
  105. if (!edgeMaker.IsDone()) {
  106. throw std::runtime_error("Failed to create edge from circle.");
  107. }
  108. BRepBuilderAPI_MakeWire wireMaker(edge);
  109. TopoDS_Wire wire = wireMaker;
  110. if (!wireMaker.IsDone()) {
  111. throw std::runtime_error("Failed to create wire from edge.");
  112. }
  113. return wire;
  114. }
  115. static ShapeResult getPipe(Pipe pipe)
  116. {
  117. ShapeResult result;
  118. gp_Vec vec(pipe.endP.XYZ() - pipe.startP.XYZ());
  119. gp_Dir dir(vec);
  120. TopoDS_Wire wire = CreateCircularWire(pipe.startP, dir, pipe.radius);
  121. TopoDS_Face face = BRepBuilderAPI_MakeFace(wire);
  122. BRepPrimAPI_MakePrism prism(face, vec);
  123. result.shape = prism.Shape();
  124. return result;
  125. }
  126. static ShapeResult getPipeChange(PipeConnect pipeCon)
  127. {
  128. ShapeResult result;
  129. if (pipeCon.points.size() < 2) {
  130. result.isOk = false;
  131. result.error += "pipeCon.points.size() < 2 \n";
  132. return result;
  133. }
  134. try {
  135. gp_Vec vec(pipeCon.points[1].XYZ() - pipeCon.points[0].XYZ());
  136. gp_Dir dir(vec);
  137. TopoDS_Wire wire1 = CreateCircularWire(pipeCon.points[0], dir, pipeCon.radiusD1);
  138. TopoDS_Wire wire2 = CreateCircularWire(pipeCon.points[1], dir, pipeCon.radiusD2);
  139. BRepOffsetAPI_ThruSections generator(Standard_True); // 标志是否生成Solid
  140. generator.AddWire(wire1);
  141. generator.AddWire(wire2);
  142. result.shape = generator.Shape();
  143. }
  144. catch (const std::exception& e) {
  145. result.isOk = false;
  146. std::string ee = e.what();
  147. result.error += "Error: " + ee + "\n";
  148. }
  149. return result;
  150. }
  151. static ShapeResult FuseShapes(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2)
  152. {
  153. ShapeResult result;
  154. try {
  155. BRepAlgoAPI_Fuse fuse(shape1, shape2);
  156. if (!fuse.IsDone()) {
  157. result.error += "Boolean operation failed.\n";
  158. throw std::runtime_error("");
  159. }
  160. result.shape = fuse.Shape();
  161. }
  162. catch (const std::exception& e) {
  163. result.isOk = false;
  164. std::string ee = e.what();
  165. result.error += "Error: " + ee + "\n";
  166. }
  167. return result;
  168. }
  169. static ShapeResult CutShapes(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2)
  170. {
  171. ShapeResult result;
  172. try {
  173. BRepAlgoAPI_Cut cut(shape1, shape2);
  174. if (!cut.IsDone()) {
  175. result.error += "Boolean operation failed.\n";
  176. throw std::runtime_error("");
  177. }
  178. result.shape = cut.Shape();
  179. }
  180. catch (const std::exception& e) {
  181. result.isOk = false;
  182. std::string ee = e.what();
  183. result.error += "Error: " + ee + "\n";
  184. }
  185. return result;
  186. }
  187. // 根据参数计算管道shape
  188. static TopoDS_Shape getCylinder(Pipe pipe)
  189. {
  190. gp_Vec vec(pipe.endP.XYZ() - pipe.startP.XYZ());
  191. gp_Dir dir(vec);
  192. TopoDS_Wire wire = CreateCircularWire(pipe.startP, dir, pipe.radius);
  193. TopoDS_Face Face = BRepBuilderAPI_MakeFace(wire);
  194. BRepPrimAPI_MakePrism prism(Face, vec);
  195. return prism.Shape();
  196. }
  197. static ShapeResult getPipeConnect3Part(PipeConnect pipeCon, int num)
  198. {
  199. ShapeResult result;
  200. try {
  201. gp_Pnt startP(0, 0, 0);
  202. gp_Pnt endP(0, 0, 50);
  203. Pipe pipe1(startP, endP, 30);
  204. gp_Pnt startP2(0, 0, 25);
  205. gp_Pnt endP2(40, 0, 25);
  206. Pipe pipe2(startP2, endP2, 20);
  207. if (num == 0) {
  208. ShapeResult res1 = getPipe(pipe1);
  209. if (!res1.isOk) {
  210. result = res1;
  211. return result;
  212. }
  213. TopoDS_Shape shape2 = getCylinder(pipe2);
  214. result = CutShapes(res1.shape, shape2);
  215. }
  216. else {
  217. ShapeResult res1 = getPipe(pipe2);
  218. if (!res1.isOk) {
  219. result = res1;
  220. return result;
  221. }
  222. TopoDS_Shape shape2 = getCylinder(pipe1);
  223. result = CutShapes(res1.shape, shape2);
  224. }
  225. }
  226. catch (const std::exception& e) {
  227. result.isOk = false;
  228. std::string ee = e.what();
  229. result.error += "Error: " + ee + "\n";
  230. }
  231. return result;
  232. }
  233. static ShapeResult getPipeConnect3(PipeConnect pipeCon)
  234. {
  235. ShapeResult result;
  236. if (pipeCon.points.size() < 3) {
  237. result.isOk = false;
  238. result.error += "pipeCon.points.size() < 3 \n";
  239. return result;
  240. }
  241. try {
  242. // ShapeResult res1 = getPipeConnect3Part(pipeCon, 0);
  243. // ShapeResult res2 = getPipeConnect3Part(pipeCon, 1);
  244. Pipe pipe1(pipeCon.points[0], pipeCon.points[1], pipeCon.radiusD1);
  245. Pipe pipe2(pipeCon.points[2], pipeCon.center, pipeCon.radiusD2);
  246. ShapeResult res1 = getPipe(pipe1);
  247. ShapeResult res2 = getPipe(pipe2);
  248. result = FuseShapes(res1.shape, res2.shape);
  249. }
  250. catch (const std::exception& e) {
  251. result.isOk = false;
  252. std::string ee = e.what();
  253. result.error += "Error: " + ee + "\n";
  254. }
  255. return result;
  256. }
  257. static ShapeResult getPipeConnect4(PipeConnect pipeCon)
  258. {
  259. ShapeResult result;
  260. if (pipeCon.points.size() < 4) {
  261. result.isOk = false;
  262. result.error += "pipeCon.points.size() < 4 \n";
  263. return result;
  264. }
  265. try {
  266. Pipe pipe1(pipeCon.points[0], pipeCon.points[1], pipeCon.radiusD1);
  267. Pipe pipe2(pipeCon.points[2], pipeCon.points[3], pipeCon.radiusD2);
  268. ShapeResult res1 = getPipe(pipe1);
  269. ShapeResult res2 = getPipe(pipe2);
  270. result = FuseShapes(res1.shape, res2.shape);
  271. }
  272. catch (const std::exception& e) {
  273. result.isOk = false;
  274. std::string ee = e.what();
  275. result.error += "Error: " + ee + "\n";
  276. }
  277. return result;
  278. }
  279. // 创建一个圆弧路径
  280. static TopoDS_Wire CreateWireFromArc(
  281. const gp_Pnt& startPt, const gp_Pnt& circleCenter, const gp_Pnt& endPt, double radius)
  282. {
  283. // 使用GC_MakeArcOfCircle创建圆弧
  284. gp_Vec vec1(startPt.XYZ() - circleCenter.XYZ());
  285. gp_Vec vec2(endPt.XYZ() - circleCenter.XYZ());
  286. gp_Vec midVec = vec1 + vec2;
  287. midVec.Normalize();
  288. midVec.Multiply(radius);
  289. gp_Pnt midPt = circleCenter.Translated(midVec);
  290. GC_MakeArcOfCircle mkArc(startPt, midPt, endPt);
  291. if (!mkArc.IsDone()) {
  292. throw std::runtime_error("Failed to create arc of circle.");
  293. }
  294. Handle(Geom_TrimmedCurve) arc = mkArc.Value();
  295. BRepBuilderAPI_MakeEdge edgeMaker(arc);
  296. if (!edgeMaker.IsDone()) {
  297. throw std::runtime_error("Failed to create edge from arc.");
  298. }
  299. TopoDS_Edge edge = edgeMaker;
  300. BRepBuilderAPI_MakeWire wireMaker(edge);
  301. if (!wireMaker.IsDone()) {
  302. throw std::runtime_error("Failed to create wire from edge.");
  303. }
  304. return wireMaker.Wire();
  305. }
  306. // 创建一个圆形截面
  307. static TopoDS_Wire CreateCircularSection(const gp_Pnt& center, gp_Dir normal, double radius)
  308. {
  309. gp_Ax2 axis2(center, normal);
  310. gp_Circ circle = gp_Circ(axis2, radius);
  311. BRepBuilderAPI_MakeEdge edgeMaker(circle);
  312. TopoDS_Edge edge = edgeMaker;
  313. BRepBuilderAPI_MakeWire wireMaker(edge);
  314. return wireMaker.Wire();
  315. }
  316. // 执行管道操作(沿路径拉伸)
  317. static TopoDS_Shape SweepAlongPath(const TopoDS_Wire& section, const TopoDS_Wire& path)
  318. {
  319. TopoDS_Face face = BRepBuilderAPI_MakeFace(section);
  320. BRepOffsetAPI_MakePipe pipeMaker(path, face);
  321. return pipeMaker.Shape();
  322. }
  323. static ShapeResult getPipeConnect2(PipeConnect pipeCon)
  324. {
  325. ShapeResult result;
  326. if (pipeCon.points.size() < 2) {
  327. result.isOk = false;
  328. result.error += "pipeCon.points.size() < 2 \n";
  329. return result;
  330. }
  331. if (pipeCon.lengthC < 0) {
  332. result.isOk = false;
  333. result.error += "短半径值无效 \n";
  334. return result;
  335. }
  336. try {
  337. gp_Vec vec1(pipeCon.center.XYZ() - pipeCon.points[0].XYZ());
  338. gp_Dir dir1(vec1);
  339. gp_Vec vec2(pipeCon.points[1].XYZ() - pipeCon.center.XYZ());
  340. gp_Dir dir2(vec2);
  341. TopoDS_Wire cir = CreateCircularSection(pipeCon.points[0], vec1, pipeCon.radiusD1);
  342. gp_Vec vecToCenter(dir2);
  343. vecToCenter *= pipeCon.lengthC;
  344. gp_Pnt circleCenter = pipeCon.points[0].Translated(vecToCenter);
  345. TopoDS_Wire path = CreateWireFromArc(pipeCon.points[0], circleCenter, pipeCon.points[1], pipeCon.lengthC);
  346. result.shape = /*path*/ SweepAlongPath(cir, path);
  347. }
  348. catch (const std::exception& e) {
  349. std::string ee = e.what();
  350. result.error += "Error: " + ee + "\n";
  351. }
  352. return result;
  353. }
  354. // 根据参数计算管道接头和变径管
  355. static ShapeResult getPipeConnect(PipeConnect pipeCon)
  356. {
  357. ShapeResult result;
  358. switch (pipeCon.type) {
  359. case 2: {
  360. result = getPipeConnect2(pipeCon);
  361. break;
  362. }
  363. case 3: {
  364. result = getPipeConnect3(pipeCon);
  365. break;
  366. }
  367. case 4: {
  368. result = getPipeConnect4(pipeCon);
  369. break;
  370. }
  371. case 5: {
  372. result = getPipeChange(pipeCon);
  373. break;
  374. }
  375. default:
  376. break;
  377. }
  378. return result;
  379. }
  380. std::string GenerateUUID()
  381. {
  382. // 生成一个新的随机UUID
  383. // 将UUID转换为字符串形式以便打印
  384. std::string uuidStr /*= aUUID.()*/;
  385. return uuidStr;
  386. }
  387. // 计算两条直线的交点
  388. static bool calculateIntersection(gp_Pnt& intersectionPoint, const gp_Lin& line1, const gp_Lin& line2)
  389. {
  390. // 将直线转换为参数方程的形式
  391. gp_Pnt origin1 = line1.Location();
  392. gp_Dir direction1 = line1.Direction();
  393. gp_Pnt origin2 = line2.Location();
  394. gp_Dir direction2 = line2.Direction();
  395. // 使用向量数学计算交点
  396. gp_Vec v1(origin1, origin2);
  397. gp_Vec dirVec1(direction1);
  398. gp_Vec dirVec2(direction2);
  399. // 计算分母,两个方向向量的叉乘大小
  400. gp_Vec crossProduct = dirVec1.Crossed(dirVec2);
  401. double denom = crossProduct.Magnitude(); // 分母应该是叉乘向量的模
  402. if (std::abs(denom) < 1e-6) { // 平行或共线
  403. std::cerr << "Lines are parallel or coincident." << std::endl;
  404. return false; // 返回默认构造的点作为错误指示
  405. }
  406. // 计算t参数,即从line1的原点到交点的距离参数
  407. double t = (v1.Crossed(dirVec2)).Magnitude() / denom;
  408. // 计算line1上的交点
  409. gp_Vec vecOnLine1(dirVec1);
  410. vecOnLine1.Multiply(t);
  411. intersectionPoint = origin1.Translated(vecOnLine1);
  412. return true;
  413. }
  414. // 求交点
  415. static bool computeInterPt(gp_Pnt& intersectionPoint, const vector<Pipe>& pipes)
  416. {
  417. if (pipes.size() < 2)
  418. return false;
  419. gp_Lin line1(pipes.front().startP, gp_Dir(gp_Vec(pipes.front().startP, pipes.front().endP)));
  420. gp_Lin line2(pipes[1].startP, gp_Dir(gp_Vec(pipes[1].startP, pipes[1].endP)));
  421. if (!calculateIntersection(intersectionPoint, line1, line2)) {
  422. std::cout << "No intersection found." << std::endl;
  423. return false;
  424. }
  425. return true;
  426. }
  427. static bool AreLinesCollinear(const gp_Lin& line1, const gp_Lin& line2, double tolerance = 1e-7)
  428. {
  429. // 获取两条直线的方向向量
  430. gp_Dir dir1 = line1.Direction();
  431. gp_Dir dir2 = line2.Direction();
  432. // 检查方向向量是否相同或相反
  433. if (!dir1.IsEqual(dir2, tolerance) && !dir1.IsOpposite(dir2, tolerance)) {
  434. return false;
  435. }
  436. // 获取line1上的一个点并检查它是否在line2上
  437. gp_Pnt pointOnLine1 = line1.Location();
  438. double u = 0.0;
  439. return line2.Contains(pointOnLine1, u);
  440. }
  441. static bool IsPipesCollinear(const vector<Pipe>& pipes)
  442. {
  443. if (pipes.size() < 2)
  444. return false;
  445. gp_Lin line1(pipes.front().startP, gp_Dir(gp_Vec(pipes.front().startP, pipes.front().endP)));
  446. gp_Lin line2(pipes[1].startP, gp_Dir(gp_Vec(pipes[1].startP, pipes[1].endP)));
  447. return AreLinesCollinear(line1, line2);
  448. }
  449. static bool isAlmostEqual(double a, double b, double tolerance = 1e-6)
  450. {
  451. if (std::abs(a - b) <= tolerance)
  452. return true;
  453. return false;
  454. }
  455. static std::vector<PipeConnect> getAllPipeConnect4()
  456. {
  457. std::vector<PipeConnect> vecPipeConnect4;
  458. PipeConnect con4_50_50_50(4, "50*50*50", 57 * 0.5, 57 * 0.5, 64, 64);
  459. PipeConnect con4_50_50_40(4, "50*50*40", 57 * 0.5, 45 * 0.5, 64, 60);
  460. vecPipeConnect4.insert(vecPipeConnect4.end(), { con4_50_50_50, con4_50_50_40 });
  461. return vecPipeConnect4;
  462. }
  463. static std::vector<PipeConnect> getAllPipeConnect5()
  464. {
  465. std::vector<PipeConnect> vecPipeConnect5;
  466. //PipeConnect con5_40_32(5, "40*32", 48.3 * 0.5, 42.4 * 0.5, 64, 64);
  467. //PipeConnect con5_40_25(5, "40*25", 48.3 * 0.5, 33.7 * 0.5, 64, 64);
  468. //PipeConnect con5_50_40(5, "50*40", 60.3 * 0.5, 48.3 * 0.5, 76, 76);
  469. //PipeConnect con5_50_32(5, "50*32", 60.3 * 0.5, 42.4 * 0.5, 76, 76);
  470. PipeConnect con5_40_32(5, "40*32", 45 * 0.5, 38 * 0.5, 64, 64);
  471. PipeConnect con5_40_25(5, "40*25", 45 * 0.5, 32 * 0.5, 64, 64);
  472. PipeConnect con5_50_40(5, "50*40", 57 * 0.5, 45 * 0.5, 76, 76);
  473. PipeConnect con5_50_32(5, "50*32", 57 * 0.5, 38 * 0.5, 76, 76);
  474. vecPipeConnect5.insert(vecPipeConnect5.end(), { con5_40_32, con5_40_25, con5_50_40, con5_50_32 });
  475. return vecPipeConnect5;
  476. }
  477. static std::vector<PipeConnect> getAllPipeConnect2()
  478. {
  479. std::vector<PipeConnect> vecPipeConnect2;
  480. PipeConnect con4_50(2, "50", 57 * 0.5, 50);
  481. PipeConnect con4_40(2, "40", 45 * 0.5, 40);
  482. vecPipeConnect2.insert(vecPipeConnect2.end(), { con4_50, con4_40 });
  483. return vecPipeConnect2;
  484. }
  485. static PipeConnect getPipeConnect4(bool& isneedChange1, bool& isneedChange2, double r1, double r2)
  486. {
  487. PipeConnect conRes;
  488. conRes.type = 4;
  489. std::vector<PipeConnect> vecPipeConnect4 = getAllPipeConnect4();
  490. if (vecPipeConnect4.size() < 1) {
  491. return conRes;
  492. }
  493. std::vector<int> numTrue1, numTrue2;
  494. for (int i = 0; i < vecPipeConnect4.size(); i++) {
  495. PipeConnect con = vecPipeConnect4[i];
  496. int num = 0;
  497. if (isAlmostEqual(con.radiusD1, r1))
  498. num++;
  499. if (isAlmostEqual(con.radiusD2, r2))
  500. num++;
  501. numTrue1.push_back(num);
  502. }
  503. for (int i = 0; i < vecPipeConnect4.size(); i++) {
  504. PipeConnect con = vecPipeConnect4[i];
  505. int num = 0;
  506. if (isAlmostEqual(con.radiusD1, r2))
  507. num++;
  508. if (isAlmostEqual(con.radiusD2, r1))
  509. num++;
  510. numTrue2.push_back(num);
  511. }
  512. if (numTrue1.empty()) {
  513. return conRes;
  514. }
  515. int maxIndex1 = 0;
  516. int maxValue1 = numTrue1[0];
  517. for (int i = 1; i < numTrue1.size(); ++i) {
  518. if (numTrue1[i] > maxValue1) {
  519. maxValue1 = numTrue1[i];
  520. maxIndex1 = i;
  521. }
  522. }
  523. if (numTrue2.empty()) {
  524. return conRes;
  525. }
  526. int maxIndex2 = 0;
  527. int maxValue2 = numTrue2[0];
  528. for (int i = 1; i < numTrue2.size(); ++i) {
  529. if (numTrue2[i] > maxValue2) {
  530. maxValue2 = numTrue2[i];
  531. maxIndex2 = i;
  532. }
  533. }
  534. if (maxValue1 == 0 && maxValue2 == 0) {
  535. return vecPipeConnect4[0];
  536. }
  537. if (maxIndex1 >= maxIndex2) {
  538. conRes = vecPipeConnect4[maxIndex1];
  539. }
  540. else {
  541. conRes.nd = vecPipeConnect4[maxIndex2].nd;
  542. conRes.radiusD1 = vecPipeConnect4[maxIndex2].radiusD2;
  543. conRes.radiusD2 = vecPipeConnect4[maxIndex2].radiusD1;
  544. conRes.lengthC = vecPipeConnect4[maxIndex2].lengthM;
  545. conRes.lengthM = vecPipeConnect4[maxIndex2].lengthC;
  546. }
  547. if (isAlmostEqual(conRes.radiusD1, r1))
  548. isneedChange1 = false;
  549. if (isAlmostEqual(conRes.radiusD2, r2))
  550. isneedChange2 = false;
  551. conRes.id = "newConnect"; // 用UUID
  552. return conRes;
  553. }
  554. static std::string getNominalDiameter1(const PipeConnect& con)
  555. {
  556. std::string str = con.nd;
  557. std::string result = str;
  558. size_t pos = str.find('*');
  559. if (pos != std::string::npos && pos != 0) {
  560. result = str.substr(0, pos);
  561. }
  562. return result;
  563. }
  564. static std::string getNominalDiameter2(const PipeConnect& con)
  565. {
  566. std::string str = con.nd;
  567. std::string result = str;
  568. size_t pos = str.rfind('*');
  569. if (pos != std::string::npos && pos != str.length() - 1) {
  570. result = str.substr(pos + 1);
  571. }
  572. return result;
  573. }
  574. static PipeConnect getPipeConnect5(bool& isexist, std::string D1, std::string D2)
  575. {
  576. PipeConnect conRes;
  577. conRes.type = 5;
  578. std::vector<PipeConnect> vecPipeConnect5 = getAllPipeConnect5();
  579. if (vecPipeConnect5.size() < 1) {
  580. return conRes;
  581. }
  582. for (int i = 0; i < vecPipeConnect5.size(); i++) {
  583. PipeConnect con = vecPipeConnect5[i];
  584. if ((getNominalDiameter1(con) == D1 && getNominalDiameter2(con) == D2)
  585. || (getNominalDiameter1(con) == D2 && getNominalDiameter2(con) == D1)) {
  586. isexist = true;
  587. conRes = con;
  588. conRes.id = "newConnect"; // 用UUID
  589. return conRes;
  590. }
  591. }
  592. isexist = false;
  593. conRes.id = "newConnect"; // 用UUID
  594. return conRes;
  595. }
  596. static PipeConnect getPipeConnect4(bool& isneedChange1, bool& isneedChange2, std::string D1, std::string D2)
  597. {
  598. PipeConnect conRes;
  599. conRes.type = 4;
  600. std::vector<PipeConnect> vecPipeConnect4 = getAllPipeConnect4();
  601. if (vecPipeConnect4.size() < 1) {
  602. return conRes;
  603. }
  604. std::vector<int> numTrue1, numTrue2;
  605. for (int i = 0; i < vecPipeConnect4.size(); i++) {
  606. PipeConnect con = vecPipeConnect4[i];
  607. int num = 0;
  608. if (getNominalDiameter1(con) == D1)
  609. num++;
  610. if (getNominalDiameter2(con) == D2)
  611. num++;
  612. numTrue1.push_back(num);
  613. }
  614. for (int i = 0; i < vecPipeConnect4.size(); i++) {
  615. PipeConnect con = vecPipeConnect4[i];
  616. int num = 0;
  617. if (getNominalDiameter1(con) == D2)
  618. num++;
  619. if (getNominalDiameter2(con) == D1)
  620. num++;
  621. numTrue2.push_back(num);
  622. }
  623. if (numTrue1.empty()) {
  624. return conRes;
  625. }
  626. int maxIndex1 = 0;
  627. int maxValue1 = numTrue1[0];
  628. for (int i = 1; i < numTrue1.size(); ++i) {
  629. if (numTrue1[i] > maxValue1) {
  630. maxValue1 = numTrue1[i];
  631. maxIndex1 = i;
  632. }
  633. }
  634. if (numTrue2.empty()) {
  635. return conRes;
  636. }
  637. int maxIndex2 = 0;
  638. int maxValue2 = numTrue2[0];
  639. for (int i = 1; i < numTrue2.size(); ++i) {
  640. if (numTrue2[i] > maxValue2) {
  641. maxValue2 = numTrue2[i];
  642. maxIndex2 = i;
  643. }
  644. }
  645. if (maxValue1 == 0 && maxValue2 == 0) {
  646. return vecPipeConnect4[0];
  647. }
  648. if (maxValue1 >= maxValue2) {
  649. conRes = vecPipeConnect4[maxIndex1];
  650. if (getNominalDiameter1(conRes) == D1)
  651. isneedChange1 = false;
  652. if (getNominalDiameter2(conRes) == D2)
  653. isneedChange2 = false;
  654. }
  655. else {
  656. conRes.nd = vecPipeConnect4[maxIndex2].nd;
  657. conRes.radiusD1 = vecPipeConnect4[maxIndex2].radiusD2;
  658. conRes.radiusD2 = vecPipeConnect4[maxIndex2].radiusD1;
  659. conRes.lengthC = vecPipeConnect4[maxIndex2].lengthM;
  660. conRes.lengthM = vecPipeConnect4[maxIndex2].lengthC;
  661. if (getNominalDiameter2(conRes) == D1)
  662. isneedChange1 = false;
  663. if (getNominalDiameter1(conRes) == D2)
  664. isneedChange2 = false;
  665. }
  666. conRes.id = "newConnect"; // 用UUID
  667. return conRes;
  668. }
  669. static PipeConnect getPipeConnect3(bool& isneedChange1, bool& isneedChange2, double D1, double D2)
  670. {
  671. PipeConnect conRes;
  672. std::vector<PipeConnect> vecPipeConnect4 = getAllPipeConnect4();
  673. if (vecPipeConnect4.size() < 1) {
  674. return conRes;
  675. }
  676. std::vector<int> numTrue1;
  677. for (int i = 0; i < vecPipeConnect4.size(); i++) {
  678. PipeConnect con = vecPipeConnect4[i];
  679. int num = 0;
  680. if (isAlmostEqual(con.radiusD1, D1))
  681. num++;
  682. if (isAlmostEqual(con.radiusD2, D2))
  683. num++;
  684. numTrue1.push_back(num);
  685. }
  686. if (numTrue1.empty()) {
  687. return conRes;
  688. }
  689. int maxIndex1 = 0;
  690. int maxValue1 = numTrue1[0];
  691. for (int i = 1; i < numTrue1.size(); ++i) {
  692. if (numTrue1[i] > maxValue1) {
  693. maxValue1 = numTrue1[i];
  694. maxIndex1 = i;
  695. }
  696. }
  697. if (maxValue1 == 0) {
  698. return vecPipeConnect4[0];
  699. }
  700. conRes = vecPipeConnect4[maxIndex1];
  701. conRes.type = 3;
  702. conRes.id = "newConnect"; // 用UUID
  703. if (isAlmostEqual(conRes.radiusD1, D1))
  704. isneedChange1 = false;
  705. if (isAlmostEqual(conRes.radiusD2, D2))
  706. isneedChange2 = false;
  707. return conRes;
  708. }
  709. static PipeConnect getPipeConnect3(bool& isneedChange1, bool& isneedChange2, std::string D1, std::string D2)
  710. {
  711. PipeConnect conRes;
  712. std::vector<PipeConnect> vecPipeConnect4 = getAllPipeConnect4();
  713. if (vecPipeConnect4.size() < 1) {
  714. return conRes;
  715. }
  716. std::vector<int> numTrue1;
  717. for (int i = 0; i < vecPipeConnect4.size(); i++) {
  718. PipeConnect con = vecPipeConnect4[i];
  719. int num = 0;
  720. if (getNominalDiameter1(con) == D1)
  721. num++;
  722. if (getNominalDiameter2(con) == D2)
  723. num++;
  724. numTrue1.push_back(num);
  725. }
  726. if (numTrue1.empty()) {
  727. return conRes;
  728. }
  729. int maxIndex1 = 0;
  730. int maxValue1 = numTrue1[0];
  731. for (int i = 1; i < numTrue1.size(); ++i) {
  732. if (numTrue1[i] > maxValue1) {
  733. maxValue1 = numTrue1[i];
  734. maxIndex1 = i;
  735. }
  736. }
  737. if (maxValue1 == 0) {
  738. return vecPipeConnect4[0];
  739. }
  740. conRes = vecPipeConnect4[maxIndex1];
  741. conRes.type = 3;
  742. conRes.id = "newConnect"; // 用UUID
  743. if (getNominalDiameter1(conRes) == D1)
  744. isneedChange1 = false;
  745. if (getNominalDiameter2(conRes) == D2)
  746. isneedChange2 = false;
  747. return conRes;
  748. }
  749. static PipeConnect getPipeConnect2(bool& isneedChange1, bool& isneedChange2, double D1, double D2)
  750. {
  751. PipeConnect conRes;
  752. conRes.type = 2;
  753. std::vector<PipeConnect> vecPipeConnect2 = getAllPipeConnect2();
  754. if (vecPipeConnect2.size() < 1) {
  755. return conRes;
  756. }
  757. std::vector<int> numTrue1;
  758. for (int i = 0; i < vecPipeConnect2.size(); i++) {
  759. PipeConnect con = vecPipeConnect2[i];
  760. int num = 0;
  761. if (isAlmostEqual(con.radiusD1, D1))
  762. num++;
  763. if (isAlmostEqual(con.radiusD1, D2))
  764. num++;
  765. numTrue1.push_back(num);
  766. }
  767. if (numTrue1.empty()) {
  768. return conRes;
  769. }
  770. int maxIndex1 = 0;
  771. int maxValue1 = numTrue1[0];
  772. for (int i = 1; i < numTrue1.size(); ++i) {
  773. if (numTrue1[i] > maxValue1) {
  774. maxValue1 = numTrue1[i];
  775. maxIndex1 = i;
  776. }
  777. }
  778. if (maxValue1 == 0) {
  779. return vecPipeConnect2[0];
  780. }
  781. conRes = vecPipeConnect2[maxIndex1];
  782. conRes.id = "newConnect"; // 用UUID
  783. if (isAlmostEqual(conRes.radiusD1, D1))
  784. isneedChange1 = false;
  785. if (isAlmostEqual(conRes.radiusD1, D2))
  786. isneedChange2 = false;
  787. return conRes;
  788. }
  789. static PipeConnect getPipeConnect2(bool& isneedChange1, bool& isneedChange2, std::string D1, std::string D2)
  790. {
  791. PipeConnect conRes;
  792. conRes.type = 2;
  793. std::vector<PipeConnect> vecPipeConnect2 = getAllPipeConnect2();
  794. if (vecPipeConnect2.size() < 1) {
  795. return conRes;
  796. }
  797. std::vector<int> numTrue1;
  798. for (int i = 0; i < vecPipeConnect2.size(); i++) {
  799. PipeConnect con = vecPipeConnect2[i];
  800. int num = 0;
  801. if (getNominalDiameter1(con) == D1)
  802. num++;
  803. if (getNominalDiameter1(con) == D2)
  804. num++;
  805. numTrue1.push_back(num);
  806. }
  807. if (numTrue1.empty()) {
  808. return conRes;
  809. }
  810. int maxIndex1 = 0;
  811. int maxValue1 = numTrue1[0];
  812. for (int i = 1; i < numTrue1.size(); ++i) {
  813. if (numTrue1[i] > maxValue1) {
  814. maxValue1 = numTrue1[i];
  815. maxIndex1 = i;
  816. }
  817. }
  818. if (maxValue1 == 0) {
  819. return vecPipeConnect2[0];
  820. }
  821. conRes = vecPipeConnect2[maxIndex1];
  822. conRes.id = "newConnect"; // 用UUID
  823. if (getNominalDiameter1(conRes) == D1)
  824. isneedChange1 = false;
  825. if (getNominalDiameter1(conRes) == D2)
  826. isneedChange2 = false;
  827. return conRes;
  828. }
  829. static void AdjustPipesSequence(vector<Pipe>& pipes)
  830. {
  831. // 调整顺序:原管道(黄色)在前,新管道(红色)在后 (没id代表管道需要新增,有id代表需要修改)
  832. if (pipes.size() < 2)
  833. return;
  834. if (pipes[0].id.empty() && !pipes[1].id.empty()) {
  835. std::reverse(pipes.begin(), pipes.end());
  836. }
  837. }
  838. static void countPipesByPart2Pipe(vector<Pipe>& pipes, vector<PipeConnect>& pipeCons)
  839. {
  840. if (pipes.size() < 2)
  841. return;
  842. AdjustPipesSequence(pipes);
  843. gp_Pnt p1 = pipes[0].startP;
  844. gp_Pnt p2 = pipes[0].endP;
  845. gp_Pnt p3 = pipes[1].startP;
  846. gp_Pnt p4 = pipes[1].endP;
  847. double lenLine1 = p1.Distance(p2);
  848. double lenLine2 = p3.Distance(p4);
  849. gp_Pnt intersectionPoint;
  850. bool isPipesCollinear = IsPipesCollinear(pipes);
  851. if (isPipesCollinear) // 共线
  852. {
  853. gp_Pnt pipe1nearPt = p1.Distance(p3) < p2.Distance(p3) ? p1 : p2;
  854. gp_Pnt pipe2nearPt = p3.Distance(pipe1nearPt) < p4.Distance(p3) ? p3 : p4;
  855. intersectionPoint = gp_Pnt((pipe1nearPt.X() + pipe2nearPt.X()) * 0.5,
  856. (pipe1nearPt.Y() + pipe2nearPt.Y()) * 0.5,
  857. (pipe1nearPt.Z() + pipe2nearPt.Z()) * 0.5);
  858. }
  859. computeInterPt(intersectionPoint, pipes);
  860. double dis_p1_int = p1.Distance(intersectionPoint);
  861. double dis_p2_int = p2.Distance(intersectionPoint);
  862. double dis_p3_int = p3.Distance(intersectionPoint);
  863. double dis_p4_int = p4.Distance(intersectionPoint);
  864. bool intPonLine1 = dis_p1_int + dis_p2_int - lenLine1 <= 1e-6 ? true : false;
  865. bool intPonLine2 = dis_p3_int + dis_p4_int - lenLine2 <= 1e-6 ? true : false;
  866. auto computeNewPt = [intersectionPoint](gp_Vec vec, double len) {
  867. vec.Normalize();
  868. vec.Multiply(len);
  869. gp_Pnt line1newPt = intersectionPoint.Translated(vec);
  870. return line1newPt;
  871. };
  872. if (isPipesCollinear) // 共线
  873. {
  874. if (pipes[0].nd == pipes[1].nd)
  875. {
  876. if (dis_p1_int < dis_p2_int) {
  877. pipes[0].startP = dis_p3_int > dis_p4_int ? p3 : p4;
  878. pipes[0].startConnectId = dis_p3_int > dis_p4_int ? pipes[1].startConnectId : pipes[1].endConnectId;
  879. }
  880. else {
  881. pipes[0].endP = dis_p3_int > dis_p4_int ? p3 : p4;
  882. pipes[0].endConnectId = dis_p3_int > dis_p4_int ? pipes[1].startConnectId : pipes[1].endConnectId;
  883. }
  884. pipes.erase(pipes.begin() + 1);
  885. return;
  886. }
  887. else
  888. {
  889. bool isexist = true;
  890. PipeConnect newChange1 = getPipeConnect5(isexist, pipes[0].nd, pipes[1].nd);
  891. if (!isexist)
  892. {
  893. return;
  894. }
  895. gp_Pnt pipe1farPt = p1.Distance(p3) > p2.Distance(p3) ? p1 : p2;
  896. gp_Pnt pipe2farPt = p3.Distance(pipe1farPt) > p4.Distance(p3) ? p3 : p4;
  897. gp_Vec vec1 = gp_Vec(pipe2farPt.XYZ() - pipe1farPt.XYZ());
  898. gp_Pnt changeStartPt = computeNewPt(vec1, -(newChange1.lengthC * 0.5));
  899. gp_Pnt changeEndPt = computeNewPt(vec1, (newChange1.lengthC * 0.5));
  900. if (pipes[0].radius > pipes[0].radius) {
  901. newChange1.points.insert(newChange1.points.end(), { changeStartPt, changeEndPt });
  902. }
  903. else
  904. {
  905. newChange1.points.insert(newChange1.points.end(), { changeEndPt, changeStartPt });
  906. }
  907. pipeCons.push_back(newChange1);
  908. if (dis_p1_int < dis_p2_int) {
  909. pipes[0].startP = changeStartPt;
  910. pipes[0].startConnectId = newChange1.id;
  911. }
  912. else {
  913. pipes[0].endP = changeStartPt;
  914. pipes[0].endConnectId = newChange1.id;
  915. }
  916. if (dis_p3_int < dis_p4_int) {
  917. pipes[1].startP = changeEndPt;
  918. pipes[1].startConnectId = newChange1.id;
  919. }
  920. else {
  921. pipes[1].endP = changeEndPt;
  922. pipes[1].endConnectId = newChange1.id;
  923. }
  924. return;
  925. }
  926. }
  927. // 查表
  928. bool isneedChange1 = true;
  929. bool isneedChange2 = true;
  930. PipeConnect Con4 = getPipeConnect4(isneedChange1, isneedChange2, pipes[0].nd, pipes[1].nd);
  931. bool isOver = false;
  932. // 截断后为新增管道
  933. auto insertPipe = [&pipes](Pipe& pipe, gp_Pnt newPipeStartPt, gp_Pnt pipeNewEndPt, std::string connectId) {
  934. Pipe newPipe1(newPipeStartPt, pipe.endP, pipe.radius);
  935. newPipe1.startConnectId = connectId;
  936. pipes.push_back(newPipe1);
  937. // pipe.endP = pipeNewEndPt;
  938. // pipe.endConnectId = connectId;
  939. };
  940. // ChangePipe起点是接头、终点是管道
  941. auto insert2ChangePipe1Pipe =
  942. [&](Pipe& pipe, gp_Pnt pt1, gp_Pnt pt2, gp_Vec vec1, gp_Vec vec2, std::string strConDiameter, double lenCM) {
  943. bool isexist = false;
  944. PipeConnect newChange1 = getPipeConnect5(isexist, strConDiameter, pipe.nd);
  945. if (!isexist) {
  946. std::cout << "The PipeChange is not existed " << std::endl;
  947. isOver = true;
  948. }
  949. gp_Pnt changeEndPt1 = computeNewPt(vec1, lenCM + newChange1.lengthC);
  950. newChange1.points.insert(newChange1.points.end(), { pt1, changeEndPt1 });
  951. pipeCons.push_back(newChange1);
  952. PipeConnect newChange2 = getPipeConnect5(isexist, strConDiameter, pipe.nd);
  953. if (!isexist) {
  954. std::cout << "The PipeChange is not existed " << std::endl;
  955. isOver = true;
  956. }
  957. gp_Pnt changeEndPt2 = computeNewPt(vec2, lenCM + newChange2.lengthC);
  958. newChange2.points.insert(newChange2.points.end(), { pt2, changeEndPt2 });
  959. pipeCons.push_back(newChange2);
  960. Pipe newPipe1(changeEndPt2, pipe.endP, pipe.radius);
  961. newPipe1.startConnectId = newChange2.id;
  962. pipes.push_back(newPipe1);
  963. return std::pair<gp_Pnt, std::string>(changeEndPt1, newChange1.id);
  964. };
  965. auto insertOneChangePipe
  966. = [&](Pipe& pipe, gp_Pnt conPt, gp_Vec vecInterPt2Pt, std::string strConDiameter, double lenCM) {
  967. bool isexist = false;
  968. PipeConnect newChange1 = getPipeConnect5(isexist, strConDiameter, pipe.nd);
  969. if (!isexist) {
  970. std::cout << "The PipeChange is not existed " << std::endl;
  971. isOver = true;
  972. }
  973. gp_Pnt changeEndPt1 = computeNewPt(vecInterPt2Pt, lenCM + newChange1.lengthC);
  974. newChange1.points.insert(newChange1.points.end(), { conPt, changeEndPt1 });
  975. pipeCons.push_back(newChange1);
  976. };
  977. // 先检查是否能形成四通、不行再看能否形成三通、最后二通(弯头)
  978. if (intPonLine1 && intPonLine2 && !Con4.nd.empty() && dis_p1_int >= Con4.lengthC && dis_p2_int >= Con4.lengthC
  979. && dis_p3_int >= Con4.lengthM && dis_p4_int >= Con4.lengthM) // 四通
  980. {
  981. gp_Vec vec1 = gp_Vec(p1.XYZ() - intersectionPoint.XYZ());
  982. gp_Pnt conPt1 = computeNewPt(vec1, Con4.lengthC);
  983. gp_Vec vec2 = gp_Vec(p2.XYZ() - intersectionPoint.XYZ());
  984. gp_Pnt conPt2 = computeNewPt(vec2, Con4.lengthC);
  985. gp_Vec vec3 = gp_Vec(p3.XYZ() - intersectionPoint.XYZ());
  986. gp_Pnt conPt3 = computeNewPt(vec3, Con4.lengthM);
  987. gp_Vec vec4 = gp_Vec(p4.XYZ() - intersectionPoint.XYZ());
  988. gp_Pnt conPt4 = computeNewPt(vec4, Con4.lengthM);
  989. Con4.points.insert(Con4.points.end(), { conPt1, conPt2, conPt3, conPt4 });
  990. Con4.center = intersectionPoint;
  991. pipeCons.push_back(Con4);
  992. if (!isneedChange1) {
  993. // 现有条件不足以证明应该把Con4.id给startConnectId还是endConnectId
  994. // 新增管道
  995. insertPipe(pipes[0], conPt2, conPt1, Con4.id);
  996. pipes[0].endP = conPt1;
  997. pipes[0].endConnectId = Con4.id;
  998. if (!isneedChange2) {
  999. insertPipe(pipes[1], conPt4, conPt3, Con4.id);
  1000. pipes[1].endP = conPt3;
  1001. pipes[1].endConnectId = Con4.id;
  1002. }
  1003. else {
  1004. // 2需要接变径管
  1005. std::pair<gp_Pnt, std::string> pair = insert2ChangePipe1Pipe(
  1006. pipes[1], conPt3, conPt4, vec3, vec4, getNominalDiameter2(Con4), Con4.lengthM);
  1007. if (isOver)
  1008. {
  1009. pipeCons.clear();
  1010. return;
  1011. }
  1012. pipes[1].endP = pair.first;
  1013. pipes[1].endConnectId = pair.second;
  1014. }
  1015. }
  1016. else {
  1017. std::pair<gp_Pnt, std::string> pair = insert2ChangePipe1Pipe(
  1018. pipes[0], conPt1, conPt2, vec1, vec2, getNominalDiameter1(Con4), Con4.lengthC);
  1019. if (isOver) {
  1020. pipeCons.clear();
  1021. return;
  1022. }
  1023. pipes[0].endP = pair.first;
  1024. pipes[0].endConnectId = pair.second;
  1025. if (!isneedChange2) {
  1026. insertPipe(pipes[1], conPt4, conPt3, Con4.id);
  1027. pipes[1].endP = conPt3;
  1028. pipes[1].endConnectId = Con4.id;
  1029. }
  1030. else {
  1031. std::pair<gp_Pnt, std::string> pair = insert2ChangePipe1Pipe(
  1032. pipes[1], conPt3, conPt4, vec3, vec4, getNominalDiameter2(Con4), Con4.lengthM);
  1033. if (isOver) {
  1034. pipeCons.clear();
  1035. return;
  1036. }
  1037. pipes[1].endP = pair.first;
  1038. pipes[1].endConnectId = pair.second;
  1039. }
  1040. }
  1041. }
  1042. // 三通和四通规格一样
  1043. else if ((intPonLine1 && dis_p1_int >= Con4.lengthC && dis_p2_int >= Con4.lengthC)
  1044. || (intPonLine2 && dis_p3_int >= Con4.lengthM && dis_p4_int >= Con4.lengthM)) // 三通
  1045. {
  1046. bool isneedChange1 = true;
  1047. bool isneedChange2 = true;
  1048. if (intPonLine1 && dis_p1_int >= Con4.lengthC && dis_p2_int >= Con4.lengthC) {
  1049. PipeConnect Con3 = getPipeConnect3(isneedChange1, isneedChange2, pipes[0].nd, pipes[1].nd);
  1050. gp_Vec vec1 = gp_Vec(p1.XYZ() - intersectionPoint.XYZ());
  1051. gp_Pnt conPt1 = computeNewPt(vec1, Con3.lengthC);
  1052. gp_Vec vec2 = gp_Vec(p2.XYZ() - intersectionPoint.XYZ());
  1053. gp_Pnt conPt2 = computeNewPt(vec2, Con3.lengthC);
  1054. gp_Vec vecLine2;
  1055. if (dis_p3_int < dis_p4_int) {
  1056. vecLine2 = gp_Vec(p4.XYZ() - intersectionPoint.XYZ());
  1057. }
  1058. else {
  1059. vecLine2 = gp_Vec(p3.XYZ() - intersectionPoint.XYZ());
  1060. }
  1061. gp_Pnt conLine2Pt = computeNewPt(vecLine2, Con3.lengthM);
  1062. Con3.points.insert(Con3.points.end(), { conPt1, conPt2, conLine2Pt });
  1063. Con3.center = intersectionPoint;
  1064. pipeCons.push_back(Con3);
  1065. if (!isneedChange1) {
  1066. insertPipe(pipes[0], conPt2, conPt1, Con3.id);
  1067. pipes[0].endP = conPt1;
  1068. pipes[0].endConnectId = Con3.id;
  1069. }
  1070. else {
  1071. std::pair<gp_Pnt, std::string> pair = insert2ChangePipe1Pipe(
  1072. pipes[0], conPt1, conPt2, vec1, vec2, getNominalDiameter1(Con3), Con3.lengthC);
  1073. if (isOver) {
  1074. pipeCons.clear();
  1075. return;
  1076. }
  1077. pipes[0].endP = pair.first;
  1078. pipes[0].endConnectId = pair.second;
  1079. }
  1080. if (!isneedChange2) {
  1081. if (dis_p3_int < dis_p4_int) {
  1082. pipes[1].startP = conLine2Pt;
  1083. pipes[1].startConnectId = Con3.id;
  1084. }
  1085. else {
  1086. pipes[1].endP = conLine2Pt;
  1087. pipes[1].endConnectId = Con3.id;
  1088. }
  1089. }
  1090. else {
  1091. insertOneChangePipe(pipes[1], conLine2Pt, vecLine2, getNominalDiameter2(Con3), Con3.lengthM);
  1092. if (isOver) {
  1093. pipeCons.clear();
  1094. return;
  1095. }
  1096. if (dis_p3_int < dis_p4_int) {
  1097. pipes[1].startP = conLine2Pt;
  1098. pipes[1].startConnectId = Con3.id;
  1099. }
  1100. else {
  1101. pipes[1].endP = conLine2Pt;
  1102. pipes[1].endConnectId = Con3.id;
  1103. }
  1104. std::pair<gp_Pnt, std::string> pair = insert2ChangePipe1Pipe(
  1105. pipes[0], conPt1, conPt2, vec1, vec2, getNominalDiameter1(Con3), Con3.lengthC);
  1106. if (isOver) {
  1107. pipeCons.clear();
  1108. return;
  1109. }
  1110. pipes[0].endP = pair.first;
  1111. pipes[0].endConnectId = pair.second;
  1112. }
  1113. }
  1114. else // Line2被贯穿
  1115. {
  1116. PipeConnect Con3 = getPipeConnect3(isneedChange2, isneedChange1, pipes[1].nd, pipes[0].nd);
  1117. gp_Vec vecLine1; // 此时向量应用远端的
  1118. if (dis_p1_int < dis_p2_int) {
  1119. vecLine1 = gp_Vec(p2.XYZ() - intersectionPoint.XYZ());
  1120. }
  1121. else {
  1122. vecLine1 = gp_Vec(p1.XYZ() - intersectionPoint.XYZ());
  1123. }
  1124. gp_Pnt conLine1Pt = computeNewPt(vecLine1, Con3.lengthC);
  1125. gp_Vec vec3 = gp_Vec(p3.XYZ() - intersectionPoint.XYZ());
  1126. gp_Pnt conPt3 = computeNewPt(vec3, Con3.lengthM);
  1127. gp_Vec vec4 = gp_Vec(p4.XYZ() - intersectionPoint.XYZ());
  1128. gp_Pnt conPt4 = computeNewPt(vec4, Con3.lengthM);
  1129. if (!isneedChange2) {
  1130. insertPipe(pipes[1], conPt4, conPt3, Con3.id);
  1131. pipes[1].endP = conPt3;
  1132. pipes[1].endConnectId = Con3.id;
  1133. }
  1134. else {
  1135. std::pair<gp_Pnt, std::string> pair = insert2ChangePipe1Pipe(
  1136. pipes[1], conPt3, conPt4, vec3, vec4, getNominalDiameter1(Con3), Con3.lengthC);
  1137. if (isOver) {
  1138. pipeCons.clear();
  1139. return;
  1140. }
  1141. pipes[1].endP = pair.first;
  1142. pipes[1].endConnectId = pair.second;
  1143. }
  1144. Con3.points.insert(Con3.points.end(), { conPt3, conPt4, conLine1Pt });
  1145. Con3.center = intersectionPoint;
  1146. pipeCons.push_back(Con3);
  1147. if (!isneedChange1) {
  1148. if (dis_p1_int < dis_p2_int) {
  1149. pipes[0].startP = conLine1Pt;
  1150. pipes[0].startConnectId = Con3.id;
  1151. }
  1152. else {
  1153. pipes[0].endP = conLine1Pt;
  1154. pipes[0].endConnectId = Con3.id;
  1155. }
  1156. }
  1157. else {
  1158. insertOneChangePipe(pipes[0], conLine1Pt, vecLine1, getNominalDiameter1(Con3), Con3.lengthM);
  1159. if (isOver) {
  1160. pipeCons.clear();
  1161. return;
  1162. }
  1163. if (dis_p1_int < dis_p2_int) {
  1164. pipes[0].startP = conLine1Pt;
  1165. pipes[0].startConnectId = Con3.id;
  1166. }
  1167. else {
  1168. pipes[0].endP = conLine1Pt;
  1169. pipes[0].endConnectId = Con3.id;
  1170. }
  1171. }
  1172. }
  1173. }
  1174. else // 二通接头
  1175. {
  1176. bool isneedChange1 = true;
  1177. bool isneedChange2 = true;
  1178. PipeConnect Con2 = getPipeConnect2(isneedChange1, isneedChange2, pipes[0].nd, pipes[1].nd);
  1179. gp_Vec vec1; // 此时向量应用远端的
  1180. if (dis_p1_int < dis_p2_int) {
  1181. vec1 = gp_Vec(p2.XYZ() - intersectionPoint.XYZ());
  1182. }
  1183. else {
  1184. vec1 = gp_Vec(p1.XYZ() - intersectionPoint.XYZ());
  1185. }
  1186. gp_Pnt con2StartPt = computeNewPt(vec1, Con2.lengthC);
  1187. gp_Vec vec2;
  1188. if (dis_p3_int < dis_p4_int) {
  1189. vec2 = gp_Vec(p4.XYZ() - intersectionPoint.XYZ());
  1190. }
  1191. else {
  1192. vec2 = gp_Vec(p3.XYZ() - intersectionPoint.XYZ());
  1193. }
  1194. gp_Pnt con2EndPt = computeNewPt(vec2, Con2.lengthC);
  1195. Con2.points.push_back(con2StartPt);
  1196. Con2.points.push_back(con2EndPt);
  1197. Con2.center = intersectionPoint;
  1198. pipeCons.push_back(Con2);
  1199. if (!isneedChange1) {
  1200. if (dis_p1_int < dis_p2_int) {
  1201. pipes.front().startP = con2StartPt;
  1202. pipes.front().startConnectId = Con2.id;
  1203. }
  1204. else {
  1205. pipes.front().endP = con2StartPt;
  1206. pipes.front().endConnectId = Con2.id;
  1207. }
  1208. if (!isneedChange2) {
  1209. if (dis_p3_int < dis_p4_int) {
  1210. pipes[1].startP = con2EndPt;
  1211. }
  1212. else {
  1213. pipes[1].endP = con2EndPt;
  1214. }
  1215. }
  1216. else {
  1217. insertOneChangePipe(pipes[1], con2EndPt, vec2, getNominalDiameter1(Con2), Con2.lengthC);
  1218. if (isOver) {
  1219. pipeCons.clear();
  1220. return;
  1221. }
  1222. if (dis_p3_int < dis_p4_int) {
  1223. pipes[1].startP = pipeCons.back().points.back();
  1224. }
  1225. else {
  1226. pipes[1].endP = pipeCons.back().points.back();
  1227. }
  1228. }
  1229. }
  1230. else {
  1231. // 1需要接变径管
  1232. insertOneChangePipe(pipes[0], con2StartPt, vec1, getNominalDiameter1(Con2), Con2.lengthC);
  1233. if (isOver) {
  1234. pipeCons.clear();
  1235. return;
  1236. }
  1237. if (dis_p1_int < dis_p2_int) {
  1238. pipes.front().startP = pipeCons.back().points.back();
  1239. pipes.front().startConnectId = pipeCons.back().id;
  1240. }
  1241. else {
  1242. pipes.front().endP = pipeCons.back().points.back();
  1243. pipes.front().endConnectId = pipeCons.back().id;
  1244. }
  1245. if (!isneedChange2) {
  1246. if (dis_p3_int < dis_p4_int) {
  1247. pipes[1].startP = con2EndPt;
  1248. }
  1249. else {
  1250. pipes[1].endP = con2EndPt;
  1251. }
  1252. }
  1253. else {
  1254. // 2也需要接变径管
  1255. insertOneChangePipe(pipes[1], con2StartPt, vec1, getNominalDiameter1(Con2), Con2.lengthC);
  1256. if (isOver) {
  1257. pipeCons.clear();
  1258. return;
  1259. }
  1260. if (dis_p3_int < dis_p4_int) {
  1261. pipes[1].startP = pipeCons.back().points.back();
  1262. pipes[1].startConnectId = pipeCons.back().id;
  1263. }
  1264. else {
  1265. pipes[1].endP = pipeCons.back().points.back();
  1266. pipes[1].endConnectId = pipeCons.back().id;
  1267. }
  1268. }
  1269. }
  1270. }
  1271. }
  1272. static PipeResult countPipesByPart(vector<Pipe>& pipes, vector<PipeConnect>& pipeCons)
  1273. {
  1274. int num = (int)pipes.size();
  1275. if (num < 2)
  1276. return PipeResult{ pipes ,pipeCons ,false,"" };
  1277. switch (num) {
  1278. case 2: {
  1279. countPipesByPart2Pipe(pipes, pipeCons);
  1280. break;
  1281. }
  1282. default:
  1283. break;
  1284. }
  1285. return PipeResult{ pipes ,pipeCons ,true,"" };
  1286. }
  1287. };