/src/contrib/geom-5.1.2.7/src/GEOMImpl/GEOMImpl_Block6Explorer.cpp

http://pythonocc.googlecode.com/ · C++ · 1308 lines · 918 code · 167 blank · 223 comment · 192 complexity · 91cfedc95cb2e04be1d5d619a4e17552 MD5 · raw file

  1. // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
  2. // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License.
  8. //
  9. // This library is distributed in the hope that it will be useful
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. //
  18. // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
  19. //
  20. #include "utilities.h"
  21. #include <Standard_Stream.hxx>
  22. #include <GEOMImpl_Block6Explorer.hxx>
  23. #include <ShHealOper_ShapeProcess.hxx>
  24. #include <BRep_Tool.hxx>
  25. #include <BRep_TFace.hxx>
  26. #include <BRep_Builder.hxx>
  27. #include <BRepLib.hxx>
  28. #include <BRepLib_FindSurface.hxx>
  29. #include <BRepTools.hxx>
  30. #include <BRepTools_WireExplorer.hxx>
  31. #include <BRepOffsetAPI_ThruSections.hxx>
  32. #include <BRepOffsetAPI_MakeFilling.hxx>
  33. #include <BRepCheck_Analyzer.hxx>
  34. #include <BRepBuilderAPI_Copy.hxx>
  35. #include <BRepBuilderAPI_MakeEdge.hxx>
  36. #include <BRepBuilderAPI_MakeWire.hxx>
  37. #include <BRepBuilderAPI_MakeFace.hxx>
  38. #include <BRepBuilderAPI_Transform.hxx>
  39. #include <TopAbs.hxx>
  40. #include <TopoDS.hxx>
  41. #include <TopoDS_Shape.hxx>
  42. #include <TopoDS_Edge.hxx>
  43. #include <TopoDS_Wire.hxx>
  44. #include <TopoDS_Solid.hxx>
  45. #include <TopExp.hxx>
  46. #include <TopExp_Explorer.hxx>
  47. #include <TopTools_MapOfShape.hxx>
  48. #include <TopTools_ListOfShape.hxx>
  49. #include <TopTools_ListIteratorOfListOfShape.hxx>
  50. #include <TopTools_IndexedMapOfShape.hxx>
  51. #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
  52. #include <Geom_Curve.hxx>
  53. #include <Geom_TrimmedCurve.hxx>
  54. #include <GeomFill_Generator.hxx>
  55. #include <Precision.hxx>
  56. #include <gp_Pnt.hxx>
  57. #include <TColgp_Array1OfPnt.hxx>
  58. #include <StdFail_NotDone.hxx>
  59. #include <Standard_NullObject.hxx>
  60. #include <Standard_TypeMismatch.hxx>
  61. #include <Standard_ConstructionError.hxx>
  62. #include <Standard_NoSuchObject.hxx>
  63. #define NBFACES 6
  64. #define NBEDGES 12
  65. #define NBVERTS 8
  66. static Standard_Integer mod4 (Standard_Integer nb)
  67. {
  68. if (nb <= 0) return nb + 4;
  69. if (nb > 4) return nb - 4;
  70. return nb;
  71. }
  72. static Standard_Integer edge_id (const Standard_Integer theFaceID,
  73. const Standard_Integer theEdgeNB)
  74. {
  75. static Standard_Integer edge_ids[NBFACES][4] = {
  76. { 1, 2, 3, 4 }, // face 1
  77. { 5, 6, 7, 8 }, // face 2
  78. { 9, 5, 10, 1 }, // face 3
  79. { 12, 7, 11, 3 }, // face 4
  80. { 4, 12, 8, 9 }, // face 5
  81. { 2, 11, 6, 10 } }; // face 6
  82. return edge_ids[theFaceID - 1][theEdgeNB - 1];
  83. }
  84. static Standard_Integer side_edge_id (const Standard_Integer theEdgeNB)
  85. {
  86. static Standard_Integer side_edge_ids[4] = {9, 10, 11, 12};
  87. return side_edge_ids[theEdgeNB - 1];
  88. }
  89. static Standard_Integer vertex_id (const Standard_Integer theFaceID,
  90. const Standard_Integer theVertexNB)
  91. {
  92. static Standard_Integer vertex_ids[NBFACES][4] = {
  93. { 1, 2, 3, 4 }, // face 1
  94. { 5, 6, 7, 8 }, // face 2
  95. { 1, 5, 6, 2 }, // face 3
  96. { 4, 8, 7, 3 }, // face 4
  97. { 1, 4, 8, 5 }, // face 5
  98. { 2, 3, 7, 6 } }; // face 6
  99. return vertex_ids[theFaceID - 1][theVertexNB - 1];
  100. }
  101. static Standard_Integer vertex_id_edge (const Standard_Integer theEdgeID, // [1,12]
  102. const Standard_Integer theVertexNB) // [1,2]
  103. {
  104. static Standard_Integer vertex_ids_edge[NBEDGES][2] = {
  105. {1, 2}, // edge 1
  106. {2, 3}, // edge 2
  107. {3, 4}, // edge 3
  108. {4, 1}, // edge 4
  109. {5, 6}, // edge 5
  110. {6, 7}, // edge 6
  111. {7, 8}, // edge 7
  112. {8, 5}, // edge 8
  113. {1, 5}, // edge 9
  114. {2, 6}, // edge 10
  115. {3, 7}, // edge 11
  116. {4, 8} }; // edge 12
  117. return vertex_ids_edge[theEdgeID - 1][theVertexNB - 1];
  118. }
  119. static Standard_Integer face_id_edges (const Standard_Integer theEdge1ID, // [1,12]
  120. const Standard_Integer theEdge2ID) // [1,12]
  121. {
  122. static Standard_Integer face_ids_edges[NBEDGES][NBEDGES] = {
  123. // 1 2 3 4 5 6 7 8 9 10 11 12
  124. { 0, 1, 1, 1, 3, 0, 0, 0, 3, 3, 0, 0 }, // edge 1
  125. { 1, 0, 1, 1, 0, 6, 0, 0, 0, 6, 6, 0 }, // edge 2
  126. { 1, 1, 0, 1, 0, 0, 4, 0, 0, 0, 4, 4 }, // edge 3
  127. { 1, 1, 1, 0, 0, 0, 0, 5, 5, 0, 0, 5 }, // edge 4
  128. { 3, 0, 0, 0, 0, 2, 2, 2, 3, 3, 0, 0 }, // edge 5
  129. { 0, 6, 0, 0, 2, 0, 2, 2, 0, 6, 6, 0 }, // edge 6
  130. { 0, 0, 4, 0, 2, 2, 0, 2, 0, 0, 4, 4 }, // edge 7
  131. { 0, 0, 0, 5, 2, 2, 2, 0, 5, 0, 0, 5 }, // edge 8
  132. { 3, 0, 0, 5, 3, 0, 0, 5, 0, 3, 0, 5 }, // edge 9
  133. { 3, 6, 0, 0, 3, 6, 0, 0, 3, 0, 6, 0 }, // edge 10
  134. { 0, 6, 4, 0, 0, 6, 4, 0, 0, 6, 0, 4 }, // edge 11
  135. { 0, 0, 4, 5, 0, 0, 4, 5, 5, 0, 4, 0 } }; // edge 12
  136. return face_ids_edges[theEdge1ID - 1][theEdge2ID - 1];
  137. }
  138. static Standard_Integer edge_id_vertices (const Standard_Integer theVertex1ID, // [1,8]
  139. const Standard_Integer theVertex2ID) // [1,8]
  140. {
  141. static Standard_Integer edge_ids_vertices[NBVERTS][NBVERTS] = {
  142. // 1 2 3 4 5 6 7 8
  143. { 0, 1, 0, 4, 9, 0, 0, 0}, // vertex 1
  144. { 1, 0, 2, 0, 0, 10, 0, 0}, // vertex 2
  145. { 0, 2, 0, 3, 0, 0, 11, 0}, // vertex 3
  146. { 4, 0, 3, 0, 0, 0, 0, 12}, // vertex 4
  147. { 9, 0, 0, 0, 0, 5, 0, 8}, // vertex 5
  148. { 0, 10, 0, 0, 5, 0, 6, 0}, // vertex 6
  149. { 0, 0, 11, 0, 0, 6, 0, 7}, // vertex 7
  150. { 0, 0, 0, 12, 8, 0, 7, 0} }; // vertex 8
  151. return edge_ids_vertices[theVertex1ID - 1][theVertex2ID - 1];
  152. }
  153. static Standard_Integer edge_id_faces (const Standard_Integer theFace1ID, // [1,6]
  154. const Standard_Integer theFace2ID) // [1,6]
  155. {
  156. static Standard_Integer edge_ids_faces[NBFACES][NBFACES] = {
  157. // 1 2 3 4 5 6
  158. { 0, 0, 1, 3, 4, 2 }, // face 1
  159. { 0, 0, 5, 7, 8, 6 }, // face 2
  160. { 1, 5, 0, 0, 9, 10 }, // face 3
  161. { 3, 7, 0, 0, 12, 11 }, // face 4
  162. { 4, 8, 9, 12, 0, 0 }, // face 5
  163. { 2, 6, 10, 11, 0, 0 } }; // face 6
  164. return edge_ids_faces[theFace1ID - 1][theFace2ID - 1];
  165. }
  166. //=======================================================================
  167. //function : GEOMImpl_Block6Explorer
  168. //purpose : Constructor
  169. //=======================================================================
  170. GEOMImpl_Block6Explorer::GEOMImpl_Block6Explorer ()
  171. : myFaces(1,NBFACES), myEdges(1,NBEDGES), myVertices(1,NBVERTS)
  172. {
  173. }
  174. //=======================================================================
  175. //function : GetVertex
  176. //purpose :
  177. //=======================================================================
  178. TopoDS_Shape GEOMImpl_Block6Explorer::GetVertex (const Standard_Integer theVertexID)
  179. {
  180. TopoDS_Shape aNullShape;
  181. if (theVertexID < 1 || theVertexID > NBVERTS) return aNullShape;
  182. return myVertices(theVertexID);
  183. }
  184. //=======================================================================
  185. //function : GetVertexID
  186. //purpose :
  187. //=======================================================================
  188. Standard_Integer GEOMImpl_Block6Explorer::GetVertexID (const TopoDS_Shape& theVertex)
  189. {
  190. for (Standard_Integer id = 1; id <= NBVERTS; id++) {
  191. if (theVertex.IsSame(myVertices(id))) return id;
  192. }
  193. Standard_NoSuchObject::Raise("The Vertex does not belong to the Block");
  194. return 0;
  195. }
  196. //=======================================================================
  197. //function : GetVertexID
  198. //purpose :
  199. //=======================================================================
  200. Standard_Integer GEOMImpl_Block6Explorer::GetVertexID (const Standard_Integer theFaceID,
  201. const Standard_Integer theVertexNB)
  202. {
  203. return vertex_id(theFaceID, theVertexNB);
  204. }
  205. //=======================================================================
  206. //function : GetVertexOnEdgeID
  207. //purpose :
  208. //=======================================================================
  209. Standard_Integer GEOMImpl_Block6Explorer::GetVertexOnEdgeID
  210. (const Standard_Integer theEdgeID,
  211. const Standard_Integer theVertexNB)
  212. {
  213. return vertex_id_edge(theEdgeID, theVertexNB);
  214. }
  215. //=======================================================================
  216. //function : GetEdge
  217. //purpose :
  218. //=======================================================================
  219. TopoDS_Shape GEOMImpl_Block6Explorer::GetEdge (const Standard_Integer theEdgeID,
  220. const Standard_Boolean doMake)
  221. {
  222. TopoDS_Shape aNullShape;
  223. if (theEdgeID < 1 || theEdgeID > NBEDGES) return aNullShape;
  224. if (myEdges(theEdgeID).IsNull() && doMake) {
  225. // Create the required edge as a linear segment between
  226. // corresponding vertices and put it in the Block's edges
  227. BRepBuilderAPI_MakeEdge ME (TopoDS::Vertex(myVertices(vertex_id_edge(theEdgeID, 1))),
  228. TopoDS::Vertex(myVertices(vertex_id_edge(theEdgeID, 2))));
  229. if (!ME.IsDone()) {
  230. Standard_ConstructionError::Raise("Edge construction failed");
  231. }
  232. myEdges(theEdgeID) = ME.Shape();
  233. }
  234. return myEdges(theEdgeID);
  235. }
  236. //=======================================================================
  237. //function : GetEdgeID
  238. //purpose :
  239. //=======================================================================
  240. Standard_Integer GEOMImpl_Block6Explorer::GetEdgeID (const TopoDS_Shape& theEdge)
  241. {
  242. for (Standard_Integer id = 1; id <= NBEDGES; id++) {
  243. if (theEdge.IsSame(myEdges(id))) return id;
  244. }
  245. Standard_NoSuchObject::Raise("The Edge does not belong to the Block");
  246. return 0;
  247. }
  248. //=======================================================================
  249. //function : GetEdgeID
  250. //purpose :
  251. //=======================================================================
  252. Standard_Integer GEOMImpl_Block6Explorer::GetEdgeID (const Standard_Integer theFaceID,
  253. const Standard_Integer theEdgeNB)
  254. {
  255. return edge_id(theFaceID, theEdgeNB);
  256. }
  257. //=======================================================================
  258. //function : FindEdgeID
  259. //purpose :
  260. //=======================================================================
  261. Standard_Integer GEOMImpl_Block6Explorer::FindEdgeID (const Standard_Integer theVertex1ID,
  262. const Standard_Integer theVertex2ID)
  263. {
  264. return edge_id_vertices(theVertex1ID, theVertex2ID);
  265. }
  266. //=======================================================================
  267. //function : FindCommonEdgeID
  268. //purpose :
  269. //=======================================================================
  270. Standard_Integer GEOMImpl_Block6Explorer::FindCommonEdgeID
  271. (const Standard_Integer theFace1ID,
  272. const Standard_Integer theFace2ID)
  273. {
  274. return edge_id_faces(theFace1ID, theFace2ID);
  275. }
  276. //=======================================================================
  277. //function : GetFace
  278. //purpose :
  279. //=======================================================================
  280. TopoDS_Shape GEOMImpl_Block6Explorer::GetFace (const Standard_Integer theFaceID,
  281. const Standard_Boolean doMake)
  282. {
  283. TopoDS_Shape aNullShape;
  284. if (theFaceID < 1 || theFaceID > NBFACES) return aNullShape;
  285. if (myFaces(theFaceID).IsNull() && doMake) {
  286. // Create the required face between
  287. // corresponding edges and put it in the Block's faces
  288. TopoDS_Shape E1 = GetEdge(edge_id(theFaceID, 1), doMake);
  289. TopoDS_Shape E2 = GetEdge(edge_id(theFaceID, 2), doMake);
  290. TopoDS_Shape E3 = GetEdge(edge_id(theFaceID, 3), doMake);
  291. TopoDS_Shape E4 = GetEdge(edge_id(theFaceID, 4), doMake);
  292. BRepBuilderAPI_MakeWire MW (TopoDS::Edge(E1),
  293. TopoDS::Edge(E2),
  294. TopoDS::Edge(E3),
  295. TopoDS::Edge(E4));
  296. if (!MW.IsDone()) {
  297. Standard_ConstructionError::Raise("Wire construction failed");
  298. }
  299. TopoDS_Shape aFace;
  300. MakeFace(MW, Standard_False, aFace);
  301. if (aFace.IsNull()) {
  302. Standard_ConstructionError::Raise("Face construction failed");
  303. }
  304. myFaces(theFaceID) = aFace;
  305. }
  306. return myFaces(theFaceID);
  307. }
  308. //=======================================================================
  309. //function : GetFaceID
  310. //purpose :
  311. //=======================================================================
  312. Standard_Integer GEOMImpl_Block6Explorer::GetFaceID (const TopoDS_Shape& theFace)
  313. {
  314. for (Standard_Integer id = 1; id <= NBFACES; id++) {
  315. if (theFace.IsSame(myFaces(id))) return id;
  316. }
  317. Standard_NoSuchObject::Raise("The Face does not belong to the Block");
  318. return 0;
  319. }
  320. //=======================================================================
  321. //function : FindFaceID
  322. //purpose :
  323. //=======================================================================
  324. Standard_Integer GEOMImpl_Block6Explorer::FindFaceID (const Standard_Integer theEdge1ID,
  325. const Standard_Integer theEdge2ID)
  326. {
  327. return face_id_edges(theEdge1ID, theEdge2ID);
  328. }
  329. //=======================================================================
  330. //function : GetOppositeFaceID
  331. //purpose :
  332. //=======================================================================
  333. Standard_Integer GEOMImpl_Block6Explorer::GetOppositeFaceID (const Standard_Integer theFaceID)
  334. {
  335. Standard_Integer opp_face_id[NBFACES + 1] = {
  336. 0,
  337. 2, // to 1 face
  338. 1, // to 2 face
  339. 4, // to 3 face
  340. 3, // to 4 face
  341. 6, // to 5 face
  342. 5}; // to 6 face
  343. return opp_face_id[theFaceID];
  344. }
  345. //=======================================================================
  346. //function : IsSimilarFaces
  347. //purpose :
  348. //=======================================================================
  349. Standard_Boolean GEOMImpl_Block6Explorer::IsSimilarFaces (const Standard_Integer theFace1ID,
  350. const Standard_Integer theFace2ID,
  351. const gp_Trsf theTransformation)
  352. {
  353. Standard_Integer common_edge_id = FindCommonEdgeID(theFace1ID, theFace2ID);
  354. if (common_edge_id == 0) { // opposite faces
  355. for (Standard_Integer id = 1; id <= 4; id++) {
  356. TopoDS_Shape E1 = GetEdge(edge_id(theFace1ID, id));
  357. TopoDS_Shape E2 = GetEdge(edge_id(theFace2ID, id));
  358. BRepBuilderAPI_Transform aTrsf (E1, theTransformation, Standard_False);
  359. if (!IsSimilarEdges(aTrsf.Shape(), E2))
  360. return Standard_False;
  361. }
  362. } else { // the faces have common edge
  363. TopTools_Array1OfShape aVerts1 (1,4);
  364. TopTools_Array1OfShape aVerts2 (1,4);
  365. Standard_Integer common_vertex1 = GetVertexOnEdgeID(common_edge_id, 1);
  366. Standard_Integer common_vertex2 = GetVertexOnEdgeID(common_edge_id, 2);
  367. aVerts1(1) = myVertices(common_vertex1);
  368. aVerts1(2) = myVertices(common_vertex2);
  369. aVerts2(1) = myVertices(common_vertex1);
  370. aVerts2(2) = myVertices(common_vertex2);
  371. Standard_Integer not_common_v11 = 0, not_common_v12 = 0;
  372. Standard_Integer vnb, vid;
  373. for (vnb = 1; vnb <= 4; vnb++) {
  374. vid = GetVertexID(theFace1ID, vnb);
  375. if (vid != common_vertex1 && FindEdgeID(vid, common_vertex1) == 0) {
  376. not_common_v12 = vid;
  377. } else {
  378. if (vid != common_vertex2 && FindEdgeID(vid, common_vertex2) == 0) {
  379. not_common_v11 = vid;
  380. }
  381. }
  382. }
  383. Standard_Integer not_common_v21 = 0, not_common_v22 = 0;
  384. for (vnb = 1; vnb <= 4; vnb++) {
  385. vid = GetVertexID(theFace2ID, vnb);
  386. if (vid != common_vertex1 && FindEdgeID(vid, common_vertex1) == 0) {
  387. not_common_v22 = vid;
  388. } else {
  389. if (vid != common_vertex2 && FindEdgeID(vid, common_vertex2) == 0) {
  390. not_common_v21 = vid;
  391. }
  392. }
  393. }
  394. aVerts1(3) = myVertices(not_common_v11);
  395. aVerts1(4) = myVertices(not_common_v12);
  396. aVerts2(3) = myVertices(not_common_v21);
  397. aVerts2(4) = myVertices(not_common_v22);
  398. for (Standard_Integer id = 1; id <= 4; id++) {
  399. BRepBuilderAPI_Transform aTrsf (aVerts1(id), theTransformation, Standard_False);
  400. TopoDS_Vertex V1 = TopoDS::Vertex(aTrsf.Shape());
  401. TopoDS_Vertex V2 = TopoDS::Vertex(aVerts2(id));
  402. if (!BRepTools::Compare(V1, V2)) {
  403. return Standard_False;
  404. }
  405. }
  406. }
  407. return Standard_True;
  408. }
  409. //============ Initialization methods ===================================
  410. //=======================================================================
  411. //function : InitByBlock
  412. //purpose :
  413. //=======================================================================
  414. void GEOMImpl_Block6Explorer::InitByBlock (const TopoDS_Shape& theBlock)
  415. {
  416. // 1. Find any one face of the block
  417. TopExp_Explorer faces (theBlock, TopAbs_FACE);
  418. if (!faces.More()) {
  419. Standard_ConstructionError::Raise("The block has no faces");
  420. }
  421. TopoDS_Shape aFirstFace = faces.Current();
  422. // 2. Store all elements of the block relatively aFirstFace
  423. InitByBlockAndFace(theBlock, aFirstFace);
  424. }
  425. //=======================================================================
  426. //function : InitByBlockAndFace
  427. //purpose :
  428. //=======================================================================
  429. void GEOMImpl_Block6Explorer::InitByBlockAndFace (const TopoDS_Shape& theBlock,
  430. const TopoDS_Shape& theFace)
  431. {
  432. myFaces(1) = theFace;
  433. // 2. Get wire of the first face
  434. TopExp_Explorer wires (myFaces(1), TopAbs_WIRE);
  435. if (!wires.More()) {
  436. Standard_ConstructionError::Raise("A face of the block has no wires");
  437. }
  438. TopoDS_Shape aWire = wires.Current();
  439. wires.Next();
  440. if (wires.More()) {
  441. Standard_ConstructionError::Raise("A face of the block has more than one wires");
  442. }
  443. // 3. Explore wire to init edges and vertices of the first face
  444. BRepTools_WireExplorer aWE (TopoDS::Wire(aWire), TopoDS::Face(myFaces(1)));
  445. Standard_Integer nb = 1;
  446. for (; aWE.More(); aWE.Next(), nb++) {
  447. if (nb > 4) {
  448. Standard_ConstructionError::Raise("A face of the block has more than four edges");
  449. }
  450. myEdges(edge_id(1, nb)) = aWE.Current();
  451. myVertices(vertex_id(1, nb)) = aWE.CurrentVertex();
  452. }
  453. if (nb < 5) {
  454. Standard_ConstructionError::Raise("A face of the block has less than four edges");
  455. }
  456. // 2. Store all other elements of the block
  457. InitByBlockAndVertices (theBlock,
  458. myVertices(vertex_id(1,1)),
  459. myVertices(vertex_id(1,2)),
  460. myVertices(vertex_id(1,3)));
  461. }
  462. //=======================================================================
  463. //function : InitByBlockAndEdges
  464. //purpose :
  465. //=======================================================================
  466. void GEOMImpl_Block6Explorer::InitByBlockAndEdges (const TopoDS_Shape& theBlock,
  467. const TopoDS_Shape& theEdge1,
  468. const TopoDS_Shape& theEdge3)
  469. {
  470. // 1. Store vertices and edges of the first face
  471. // 1.1. Store two given edges
  472. myEdges(edge_id(1, 1)) = theEdge1;
  473. myEdges(edge_id(1, 3)) = theEdge3;
  474. // 1.2. Find and store the first face
  475. TopTools_IndexedDataMapOfShapeListOfShape MEF;
  476. MapShapesAndAncestors(theBlock, TopAbs_EDGE, TopAbs_FACE, MEF);
  477. if (MEF.Extent() != NBEDGES) {
  478. Standard_TypeMismatch::Raise("Block has wrong number of edges");
  479. }
  480. const TopTools_ListOfShape& aFacesOfE1 = MEF.FindFromKey(theEdge1);
  481. const TopTools_ListOfShape& aFacesOfE3 = MEF.FindFromKey(theEdge3);
  482. Standard_Boolean isFound = Standard_False;
  483. TopTools_ListIteratorOfListOfShape anIterF1 (aFacesOfE1);
  484. for (; anIterF1.More() && !isFound; anIterF1.Next()) {
  485. TopTools_ListIteratorOfListOfShape anIterF3 (aFacesOfE3);
  486. for (; anIterF3.More() && !isFound; anIterF3.Next()) {
  487. if (anIterF1.Value().IsSame(anIterF3.Value())) {
  488. isFound = Standard_True;
  489. // Store the face, defined by two opposite edges
  490. myFaces(1) = anIterF1.Value();
  491. }
  492. }
  493. }
  494. if (!isFound) {
  495. Standard_ConstructionError::Raise
  496. ("Edges 1 and 2 do not belong to one face of the block");
  497. }
  498. // 1.3. Make vertices of the first edge the first and the
  499. // second vertices of the first face. Order is free.
  500. TopoDS_Edge E = TopoDS::Edge(theEdge1);
  501. TopoDS_Vertex V1, V2;
  502. TopExp::Vertices(E, V1, V2, Standard_True);
  503. myVertices(vertex_id(1,1)) = V1;
  504. myVertices(vertex_id(1,2)) = V2;
  505. // Init maps vertex->list_of_edges for the face
  506. TopTools_IndexedDataMapOfShapeListOfShape M1;
  507. MapShapesAndAncestors(myFaces(1), TopAbs_VERTEX, TopAbs_EDGE, M1);
  508. if (M1.Extent() != 4) {
  509. Standard_TypeMismatch::Raise("The first face of block has wrong number of vertices");
  510. }
  511. // 1.4. Find and store others elements of the first face
  512. // edges of the first vertex
  513. TopoDS_Shape E1_f = M1.FindFromKey(V1).First();
  514. TopoDS_Shape E1_l = M1.FindFromKey(V1).Last();
  515. if (E1_f.IsSame(theEdge1)) {
  516. myEdges(edge_id(1, 4)) = E1_l;
  517. } else {
  518. myEdges(edge_id(1, 4)) = E1_f;
  519. }
  520. // fourth vertex
  521. TopoDS_Edge E4 = TopoDS::Edge(myEdges(edge_id(1, 4)));
  522. TopoDS_Vertex V41, V42;
  523. TopExp::Vertices(E4, V41, V42, Standard_True);
  524. if (V41.IsSame(V1)) {
  525. myVertices(vertex_id(1,4)) = V42;
  526. } else {
  527. myVertices(vertex_id(1,4)) = V41;
  528. }
  529. // edges of the second vertex
  530. TopoDS_Shape E2_f = M1.FindFromKey(V2).First();
  531. TopoDS_Shape E2_l = M1.FindFromKey(V2).Last();
  532. if (E2_f.IsSame(theEdge1)) {
  533. myEdges(edge_id(1, 2)) = E2_l;
  534. } else {
  535. myEdges(edge_id(1, 2)) = E2_f;
  536. }
  537. // fird vertex
  538. TopoDS_Edge E2 = TopoDS::Edge(myEdges(edge_id(1, 2)));
  539. TopoDS_Vertex V21, V22;
  540. TopExp::Vertices(E2, V21, V22, Standard_True);
  541. if (V21.IsSame(V2)) {
  542. myVertices(vertex_id(1,3)) = V22;
  543. } else {
  544. myVertices(vertex_id(1,3)) = V21;
  545. }
  546. // 2. Store all other elements of the block
  547. InitByBlockAndVertices (theBlock,
  548. myVertices(vertex_id(1,1)),
  549. myVertices(vertex_id(1,2)),
  550. myVertices(vertex_id(1,3)));
  551. }
  552. //=======================================================================
  553. //function : InitByBlockAndVertices
  554. //purpose :
  555. //=======================================================================
  556. void GEOMImpl_Block6Explorer::InitByBlockAndVertices (const TopoDS_Shape& theBlock,
  557. const TopoDS_Shape& theVertex1,
  558. const TopoDS_Shape& theVertex2,
  559. const TopoDS_Shape& theVertex3)
  560. {
  561. // Here we suppose, that vertices are ordered, i.e. exists edge between
  562. // theVertex1 and theVertex2 and edge between theVertex2 and theVertex3
  563. // 1. Store vertices and edges of the first face.
  564. // If the first face is initialized, it means, that this
  565. // method is called from another initialization method, and all
  566. // vertices and edges of the first face are also initialized
  567. if (myFaces(1).IsNull()) {
  568. // 1.1. Store first three vertices
  569. myVertices(vertex_id(1, 1)) = theVertex1;
  570. myVertices(vertex_id(1, 2)) = theVertex2;
  571. myVertices(vertex_id(1, 3)) = theVertex3;
  572. // 1.2. Find and store the first face
  573. TopTools_IndexedDataMapOfShapeListOfShape MVF;
  574. MapShapesAndAncestors(theBlock, TopAbs_VERTEX, TopAbs_FACE, MVF);
  575. if (MVF.Extent() != NBVERTS) {
  576. Standard_TypeMismatch::Raise("Block has wrong number of vertices");
  577. }
  578. const TopTools_ListOfShape& aFacesOfV1 = MVF.FindFromKey(theVertex1);
  579. const TopTools_ListOfShape& aFacesOfV3 = MVF.FindFromKey(theVertex3);
  580. Standard_Boolean isFound = Standard_False;
  581. TopTools_ListIteratorOfListOfShape anIterF1 (aFacesOfV1);
  582. for (; anIterF1.More() && !isFound; anIterF1.Next()) {
  583. TopTools_ListIteratorOfListOfShape anIterF3 (aFacesOfV3);
  584. for (; anIterF3.More() && !isFound; anIterF3.Next()) {
  585. if (anIterF1.Value().IsSame(anIterF3.Value())) {
  586. isFound = Standard_True;
  587. // Store the face, defined by two opposite vertices
  588. myFaces(1) = anIterF1.Value();
  589. }
  590. }
  591. }
  592. if (!isFound) {
  593. Standard_ConstructionError::Raise
  594. ("Vertices 1 and 3 do not belong to one face of the block");
  595. }
  596. // Init maps vertex->list_of_edges for the face
  597. TopTools_IndexedDataMapOfShapeListOfShape M1;
  598. MapShapesAndAncestors(myFaces(1), TopAbs_VERTEX, TopAbs_EDGE, M1);
  599. if (M1.Extent() != 4) {
  600. Standard_TypeMismatch::Raise("The first face of block has wrong number of vertices");
  601. }
  602. // 1.3. Find and store edges and last vertex of the first face
  603. const TopTools_ListOfShape& anEdgesOfV1 = M1.FindFromKey(theVertex1);
  604. const TopTools_ListOfShape& anEdgesOfV2 = M1.FindFromKey(theVertex2);
  605. const TopTools_ListOfShape& anEdgesOfV3 = M1.FindFromKey(theVertex3);
  606. TopTools_ListIteratorOfListOfShape anIterE2 (anEdgesOfV2);
  607. for (; anIterE2.More(); anIterE2.Next()) {
  608. TopTools_ListIteratorOfListOfShape anIterE1 (anEdgesOfV1);
  609. for (; anIterE1.More(); anIterE1.Next()) {
  610. if (anIterE1.Value().IsSame(anIterE2.Value())) {
  611. // Store the first edge, defined by two vertices
  612. myEdges(edge_id(1,1)) = anIterE1.Value();
  613. } else {
  614. // Store the last edge
  615. myEdges(edge_id(1,4)) = anIterE1.Value();
  616. // Find and store the last vertex
  617. TopoDS_Edge E = TopoDS::Edge(myEdges(4));
  618. TopoDS_Vertex V1, V2;
  619. TopExp::Vertices(E, V1, V2, Standard_True);
  620. if (V1.IsSame(theVertex1)) {
  621. myVertices(vertex_id(1,4)) = V2;
  622. } else {
  623. myVertices(vertex_id(1,4)) = V1;
  624. }
  625. }
  626. }
  627. TopTools_ListIteratorOfListOfShape anIterE3 (anEdgesOfV3);
  628. for (; anIterE3.More(); anIterE3.Next()) {
  629. if (anIterE3.Value().IsSame(anIterE2.Value())) {
  630. // Store the second edge, defined by two vertices
  631. myEdges(edge_id(1,2)) = anIterE3.Value();
  632. } else {
  633. // Store the fird edge
  634. myEdges(edge_id(1,3)) = anIterE3.Value();
  635. }
  636. }
  637. }
  638. }
  639. // Init map vertex->list_of_edges for the block
  640. TopTools_IndexedDataMapOfShapeListOfShape MB;
  641. MapShapesAndAncestors(theBlock, TopAbs_VERTEX, TopAbs_EDGE, MB);
  642. if (MB.Extent() != NBVERTS) {
  643. Standard_TypeMismatch::Raise("Block has wrong number of vertices");
  644. }
  645. // 2. Store edges, linking the first face with the second one
  646. // and vertices of the second face
  647. TopTools_IndexedMapOfShape aFaceEdges;
  648. TopExp::MapShapes(myFaces(1), TopAbs_EDGE, aFaceEdges);
  649. Standard_Integer i = 1;
  650. for (; i <= 4; i++) {
  651. // Get i-th vertex of the face 1
  652. TopoDS_Shape Vi = myVertices(vertex_id(1, i));
  653. if (!MB.Contains(Vi)) {
  654. Standard_ConstructionError::Raise("Face does not belong to the block");
  655. }
  656. // Get list of block's edges, sharing this Vertex
  657. const TopTools_ListOfShape& anEdgesOfVi = MB.FindFromKey(Vi);
  658. TopTools_ListIteratorOfListOfShape anEdgesIter (anEdgesOfVi);
  659. // Get Edge (from the List), not belonging to the face 1
  660. Standard_Boolean isFound = Standard_False;
  661. for (; anEdgesIter.More() && !isFound; anEdgesIter.Next()) {
  662. if (!aFaceEdges.Contains(anEdgesIter.Value())) {
  663. isFound = Standard_True;
  664. // Store the linking edge
  665. TopoDS_Shape aLinkEdge = anEdgesIter.Value();
  666. myEdges(side_edge_id(i)) = aLinkEdge;
  667. // Get another vertex of the linking edge
  668. TopoDS_Edge E = TopoDS::Edge(aLinkEdge);
  669. TopoDS_Vertex V1, V2;
  670. TopExp::Vertices(E, V1, V2, Standard_True);
  671. // Store the i-th vertex of the second (opposite to the first) face
  672. if (V1.IsSame(Vi)) {
  673. myVertices(vertex_id(2, i)) = V2;
  674. } else {
  675. myVertices(vertex_id(2, i)) = V1;
  676. }
  677. }
  678. }
  679. }
  680. // 3. Store edges of the second (opposite to the first) face
  681. for (i = 1; i <= 4; i++) {
  682. // Get i-th and (i+1)-th vertices of the face 2
  683. TopoDS_Shape Vi = myVertices(vertex_id(2, i));
  684. TopoDS_Shape Vj = myVertices(vertex_id(2, mod4(i + 1)));
  685. // Get list of block's edges, sharing Vi
  686. const TopTools_ListOfShape& anEdgesOfVi = MB.FindFromKey(Vi);
  687. // Get list of block's edges, sharing Vj
  688. const TopTools_ListOfShape& anEdgesOfVj = MB.FindFromKey(Vj);
  689. // Get Edge (from the List), linking this vertex with the next one
  690. Standard_Boolean isFound = Standard_False;
  691. TopTools_ListIteratorOfListOfShape anEdgesIteri (anEdgesOfVi);
  692. for (; anEdgesIteri.More() && !isFound; anEdgesIteri.Next()) {
  693. TopTools_ListIteratorOfListOfShape anEdgesIterj (anEdgesOfVj);
  694. for (; anEdgesIterj.More() && !isFound; anEdgesIterj.Next()) {
  695. if (anEdgesIteri.Value().IsSame(anEdgesIterj.Value())) {
  696. isFound = Standard_True;
  697. // Store the linking edge
  698. myEdges(edge_id(2, i)) = anEdgesIteri.Value();
  699. }
  700. }
  701. }
  702. }
  703. // 4. Store faces of the block
  704. TopTools_IndexedDataMapOfShapeListOfShape MBE;
  705. MapShapesAndAncestors(theBlock, TopAbs_EDGE, TopAbs_FACE, MBE);
  706. if (MBE.Extent() != NBEDGES) {
  707. Standard_TypeMismatch::Raise("Block has wrong number of edges");
  708. }
  709. for (i = 2; i <= NBFACES; i++) {
  710. TopoDS_Shape Ei1 = myEdges(edge_id(i, 1));
  711. TopoDS_Shape Ei2 = myEdges(edge_id(i, 2));
  712. const TopTools_ListOfShape& aFacesOfEi1 = MBE.FindFromKey(Ei1);
  713. const TopTools_ListOfShape& aFacesOfEi2 = MBE.FindFromKey(Ei2);
  714. Standard_Boolean isFound = Standard_False;
  715. TopTools_ListIteratorOfListOfShape anIterEi1 (aFacesOfEi1);
  716. for (; anIterEi1.More() && !isFound; anIterEi1.Next()) {
  717. TopTools_ListIteratorOfListOfShape anIterEi2 (aFacesOfEi2);
  718. for (; anIterEi2.More() && !isFound; anIterEi2.Next()) {
  719. if (anIterEi1.Value().IsSame(anIterEi2.Value())) {
  720. isFound = Standard_True;
  721. // Store the face, defined by two edges
  722. myFaces(i) = anIterEi1.Value();
  723. }
  724. }
  725. }
  726. }
  727. }
  728. //=======================================================================
  729. //function : InitByTwoFaces
  730. //purpose :
  731. //=======================================================================
  732. void GEOMImpl_Block6Explorer::InitByTwoFaces (const TopoDS_Shape& theFace1,
  733. const TopoDS_Shape& theFace2)
  734. {
  735. if (theFace1.IsSame(theFace2)) {
  736. Standard_ConstructionError::Raise("The faces must be different");
  737. }
  738. // Add two given faces in the structure
  739. myFaces(1) = theFace1;
  740. myFaces(2) = theFace2;
  741. // Step 1. Order vertices (and edges)
  742. // 1.1. Ordered vertices and edges of the first face we put in <myVertices>
  743. // Get wire of the first face
  744. TopExp_Explorer wires1 (myFaces(1), TopAbs_WIRE);
  745. if (!wires1.More()) {
  746. Standard_ConstructionError::Raise("A face for the block has no wires");
  747. }
  748. TopoDS_Shape aWire1 = wires1.Current();
  749. wires1.Next();
  750. if (wires1.More()) {
  751. Standard_ConstructionError::Raise("A face for the block has more than one wire");
  752. }
  753. BRepTools_WireExplorer aWE1 (TopoDS::Wire(aWire1), TopoDS::Face(myFaces(1)));
  754. Standard_Integer nb;
  755. for (nb = 1; aWE1.More(); aWE1.Next(), nb++) {
  756. if (nb > 4) {
  757. Standard_ConstructionError::Raise("A face for the block has more than four edges");
  758. }
  759. myEdges(edge_id(1, nb)) = aWE1.Current();
  760. myVertices(vertex_id(1, nb)) = aWE1.CurrentVertex();
  761. }
  762. if (nb < 5) {
  763. Standard_ConstructionError::Raise("A face for the block has less than four edges");
  764. }
  765. // 1.2. Ordered vertices and edges of the second face we temporarily store
  766. // in arrays, to find for them rigth location in <myVertices> on the Step 2.
  767. // declare arrays
  768. TopTools_Array1OfShape aVertis2(1,4); // ordered vertices of the second face
  769. TopTools_Array1OfShape anEdges2(1,4); // anEdges2(i) links aVertis2(i) and aVertis2(i+1)
  770. // Get wire of the second face
  771. TopExp_Explorer wires2 (myFaces(2), TopAbs_WIRE);
  772. if (!wires2.More()) {
  773. Standard_ConstructionError::Raise("A face for the block has no wires");
  774. }
  775. TopoDS_Shape aWire2 = wires2.Current();
  776. wires2.Next();
  777. if (wires2.More()) {
  778. Standard_ConstructionError::Raise("A face for the block has more than one wire");
  779. }
  780. BRepTools_WireExplorer aWE2 (TopoDS::Wire(aWire2), TopoDS::Face(myFaces(2)));
  781. for (nb = 1; aWE2.More(); aWE2.Next(), nb++) {
  782. if (nb > 4) {
  783. Standard_ConstructionError::Raise("A face for the block has more than four edges");
  784. }
  785. anEdges2(nb) = aWE2.Current();
  786. aVertis2(nb) = aWE2.CurrentVertex();
  787. }
  788. if (nb < 5) {
  789. Standard_ConstructionError::Raise("A face for the block has less than four edges");
  790. }
  791. // Step 2. Find right place in <myVertices> for the <aVertis2>,
  792. // so as to minimize common length of linking edges
  793. // between face 1 and face 2.
  794. // Each linking edge (of four) will link vertices of the
  795. // faces 1 and 2 with equal local numbers.
  796. // The right place is defined by:
  797. // - vertex <aVertis2(i_min)>, which will become the first vertex
  798. // of the second face <myVertices(vertex_id(2,1))>
  799. // - orientation of <aVertis2> relatively their future location
  800. // in <myVertices> (s_min = 1 if direct, s_min = -1 if reversed)
  801. Standard_Integer i_min = 0, s_min = 0;
  802. TColgp_Array1OfPnt aPnts1 (1,4); // points of the first face
  803. aPnts1(1) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 1))));
  804. aPnts1(2) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 2))));
  805. aPnts1(3) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 3))));
  806. aPnts1(4) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 4))));
  807. TColgp_Array1OfPnt aPnts2 (1,4); // points of the second face
  808. aPnts2(1) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(1)));
  809. aPnts2(2) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(2)));
  810. aPnts2(3) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(3)));
  811. aPnts2(4) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(4)));
  812. Standard_Real Dist_min = RealLast();
  813. // try all possible locations to find the best (with minimum sum distance)
  814. Standard_Integer i = 1;
  815. for (; i <= 4; i++) {
  816. // try direct orientation
  817. Standard_Real Dist_plus = aPnts1(1).Distance(aPnts2(i)) +
  818. aPnts1(2).Distance(aPnts2(mod4(i + 1))) +
  819. aPnts1(3).Distance(aPnts2(mod4(i + 2))) +
  820. aPnts1(4).Distance(aPnts2(mod4(i + 3)));
  821. if (Dist_plus < Dist_min) {
  822. Dist_min = Dist_plus;
  823. i_min = i;
  824. s_min = 1;
  825. }
  826. // try reversed orientation
  827. Standard_Real Dist_minus = aPnts1(1).Distance(aPnts2(i)) +
  828. aPnts1(2).Distance(aPnts2(mod4(i - 1))) +
  829. aPnts1(3).Distance(aPnts2(mod4(i - 2))) +
  830. aPnts1(4).Distance(aPnts2(mod4(i - 3)));
  831. if (Dist_minus < Dist_min) {
  832. Dist_min = Dist_minus;
  833. i_min = i;
  834. s_min = - 1;
  835. }
  836. }
  837. // 3. Put vertices and edges of the second face to they
  838. // permanent location in <myVertices> and <myEdges>
  839. for (i = 1; i <= 4; i++) {
  840. Standard_Integer nb = mod4(i_min + s_min*(i - 1));
  841. if (aPnts1(i).Distance(aPnts2(nb)) < Precision::Confusion()) {
  842. Standard_ConstructionError::Raise("The faces are too close");
  843. }
  844. myVertices(vertex_id(2, i)) = aVertis2(nb);
  845. if (s_min == -1) nb = mod4(nb - 1);
  846. myEdges(edge_id(2, i)) = anEdges2(nb);
  847. }
  848. // 4. Generate side surface
  849. if (!aWire1.Closed() || !aWire2.Closed()) {
  850. // BRepOffsetAPI_ThruSections is not applicable on not closed wires
  851. GetFace(3, Standard_True);
  852. GetFace(4, Standard_True);
  853. GetFace(5, Standard_True);
  854. GetFace(6, Standard_True);
  855. } else {
  856. // try to build faces on native surfaces of edges or planar
  857. Standard_Boolean tryThru = Standard_False;
  858. for (Standard_Integer i = 3; i <= 6 && !tryThru; i++) {
  859. Standard_Boolean doMake = Standard_True;
  860. TopoDS_Shape E1 = GetEdge(edge_id(i, 1), doMake);
  861. TopoDS_Shape E2 = GetEdge(edge_id(i, 2), doMake);
  862. TopoDS_Shape E3 = GetEdge(edge_id(i, 3), doMake);
  863. TopoDS_Shape E4 = GetEdge(edge_id(i, 4), doMake);
  864. BRepBuilderAPI_MakeWire MW (TopoDS::Edge(E1),
  865. TopoDS::Edge(E2),
  866. TopoDS::Edge(E3),
  867. TopoDS::Edge(E4));
  868. if (!MW.IsDone()) {
  869. Standard_ConstructionError::Raise("Wire construction failed");
  870. }
  871. BRepBuilderAPI_MakeFace MF (MW, Standard_False);
  872. if (MF.IsDone()) {
  873. myFaces(i) = MF.Shape();
  874. } else {
  875. tryThru = Standard_True;
  876. }
  877. }
  878. // Build side surface by ThruSections algorithm
  879. if (tryThru) {
  880. BRepOffsetAPI_ThruSections THS;
  881. THS.AddWire(TopoDS::Wire(aWire1));
  882. THS.AddWire(TopoDS::Wire(aWire2));
  883. THS.Build();
  884. if (!THS.IsDone()) {
  885. StdFail_NotDone::Raise("Side surface generation failed");
  886. }
  887. for (Standard_Integer i = 1; i <= 4; i++) {
  888. // fill face
  889. myFaces(i+2) = THS.GeneratedFace(myEdges(i));
  890. // fill edge
  891. Standard_Integer ee = side_edge_id(i);
  892. TopTools_IndexedDataMapOfShapeListOfShape MVE;
  893. MapShapesAndAncestors(myFaces(i+2), TopAbs_VERTEX, TopAbs_EDGE, MVE);
  894. FindEdge(myEdges(ee),
  895. myVertices(vertex_id_edge(ee, 1)),
  896. myVertices(vertex_id_edge(ee, 2)),
  897. MVE);
  898. }
  899. }
  900. }
  901. }
  902. //=======================================================================
  903. //function : MapShapesAndAncestors
  904. //purpose :
  905. //=======================================================================
  906. void GEOMImpl_Block6Explorer::MapShapesAndAncestors (const TopoDS_Shape& S,
  907. const TopAbs_ShapeEnum TS,
  908. const TopAbs_ShapeEnum TA,
  909. TopTools_IndexedDataMapOfShapeListOfShape& M)
  910. {
  911. TopTools_ListOfShape empty;
  912. TopTools_MapOfShape mapA;
  913. // visit ancestors
  914. TopExp_Explorer exa (S,TA);
  915. for (; exa.More(); exa.Next()) {
  916. // visit shapes
  917. const TopoDS_Shape& anc = exa.Current();
  918. if (mapA.Add(anc)) {
  919. TopExp_Explorer exs (anc,TS);
  920. TopTools_MapOfShape mapS;
  921. for (; exs.More(); exs.Next()) {
  922. if (mapS.Add(exs.Current())) {
  923. Standard_Integer index = M.FindIndex(exs.Current());
  924. if (index == 0) index = M.Add(exs.Current(),empty);
  925. M(index).Append(anc);
  926. }
  927. }
  928. }
  929. }
  930. // visit shapes not under ancestors
  931. TopExp_Explorer ex (S,TS,TA);
  932. for (; ex.More(); ex.Next()) {
  933. Standard_Integer index = M.FindIndex(ex.Current());
  934. if (index == 0) index = M.Add(ex.Current(),empty);
  935. }
  936. }
  937. //=======================================================================
  938. //function : IsSimilarEdges
  939. //purpose :
  940. //=======================================================================
  941. Standard_Boolean GEOMImpl_Block6Explorer::IsSimilarEdges (const TopoDS_Shape& E1,
  942. const TopoDS_Shape& E2)
  943. {
  944. TopoDS_Edge E1e = TopoDS::Edge(E1);
  945. TopoDS_Edge E2e = TopoDS::Edge(E2);
  946. TopoDS_Vertex V11, V12, V21, V22;
  947. TopExp::Vertices(E1e, V11, V12, Standard_True);
  948. TopExp::Vertices(E2e, V21, V22, Standard_True);
  949. if (BRepTools::Compare(V11, V21) && BRepTools::Compare(V12, V22))
  950. return Standard_True;
  951. if (BRepTools::Compare(V11, V22) && BRepTools::Compare(V12, V21))
  952. return Standard_True;
  953. return Standard_False;
  954. }
  955. //=======================================================================
  956. //function : FindEdge
  957. //purpose :
  958. //=======================================================================
  959. Standard_Integer GEOMImpl_Block6Explorer::FindEdge
  960. (TopoDS_Shape& theResult,
  961. const TopoDS_Shape& V1,
  962. const TopoDS_Shape& V2,
  963. const TopTools_IndexedDataMapOfShapeListOfShape& MVE,
  964. const Standard_Boolean findAll)
  965. {
  966. Standard_Integer isFound = 0;
  967. const TopTools_ListOfShape& anEdgesOfV1 = MVE.FindFromKey(V1);
  968. const TopTools_ListOfShape& anEdgesOfV2 = MVE.FindFromKey(V2);
  969. TopTools_ListIteratorOfListOfShape it1 (anEdgesOfV1);
  970. for (; it1.More(); it1.Next()) {
  971. TopTools_ListIteratorOfListOfShape it2 (anEdgesOfV2);
  972. for (; it2.More(); it2.Next()) {
  973. if (it1.Value().IsSame(it2.Value())) {
  974. isFound++;
  975. theResult = it1.Value();
  976. if (!findAll) return isFound;
  977. }
  978. }
  979. }
  980. return isFound;
  981. }
  982. //=======================================================================
  983. //function : FindFace
  984. //purpose :
  985. //=======================================================================
  986. Standard_Integer GEOMImpl_Block6Explorer::FindFace
  987. (TopoDS_Shape& theResult,
  988. const TopoDS_Shape& V1,
  989. const TopoDS_Shape& V2,
  990. const TopoDS_Shape& V3,
  991. const TopoDS_Shape& V4,
  992. const TopTools_IndexedDataMapOfShapeListOfShape& MVF,
  993. const Standard_Boolean findAll)
  994. {
  995. Standard_Integer isFound = Standard_False;
  996. const TopTools_ListOfShape& aFacesOfV1 = MVF.FindFromKey(V1);
  997. const TopTools_ListOfShape& aFacesOfV2 = MVF.FindFromKey(V2);
  998. const TopTools_ListOfShape& aFacesOfV3 = MVF.FindFromKey(V3);
  999. const TopTools_ListOfShape& aFacesOfV4 = MVF.FindFromKey(V4);
  1000. TopTools_ListIteratorOfListOfShape it1 (aFacesOfV1);
  1001. for (; it1.More(); it1.Next()) {
  1002. TopTools_ListIteratorOfListOfShape it2 (aFacesOfV2);
  1003. for (; it2.More(); it2.Next()) {
  1004. if (it1.Value().IsSame(it2.Value())) {
  1005. TopTools_ListIteratorOfListOfShape it3 (aFacesOfV3);
  1006. for (; it3.More(); it3.Next()) {
  1007. if (it1.Value().IsSame(it3.Value())) {
  1008. TopTools_ListIteratorOfListOfShape it4 (aFacesOfV4);
  1009. for (; it4.More(); it4.Next()) {
  1010. if (it1.Value().IsSame(it4.Value())) {
  1011. isFound++;
  1012. theResult = it1.Value();
  1013. if (!findAll) return isFound;
  1014. }
  1015. }
  1016. }
  1017. }
  1018. }
  1019. }
  1020. }
  1021. return isFound;
  1022. }
  1023. //=======================================================================
  1024. //function : MakeFace
  1025. //purpose :
  1026. //=======================================================================
  1027. void GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire& theWire,
  1028. const Standard_Boolean isPlanarWanted,
  1029. TopoDS_Shape& theResult)
  1030. {
  1031. // try to build face on plane or on any surface under the edges of the wire
  1032. BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted);
  1033. if (MK.IsDone()) {
  1034. theResult = MK.Shape();
  1035. return;
  1036. }
  1037. if (!isPlanarWanted) {
  1038. // try to construct filling surface
  1039. BRepOffsetAPI_MakeFilling MF;
  1040. Standard_Integer nbEdges = 0;
  1041. BRepTools_WireExplorer aWE (theWire);
  1042. for (; aWE.More(); aWE.Next(), nbEdges++) {
  1043. MF.Add(TopoDS::Edge(aWE.Current()), GeomAbs_C0);
  1044. }
  1045. MF.Build();
  1046. if (MF.IsDone()) {
  1047. // Result of filling
  1048. TopoDS_Shape aFace = MF.Shape();
  1049. // 12.04.2006 for PAL12149 begin
  1050. Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(aFace));
  1051. BRepBuilderAPI_MakeFace MK1 (aGS, theWire);
  1052. if (MK1.IsDone()) {
  1053. TopoDS_Shape aFace1 = MK1.Shape();
  1054. BRepCheck_Analyzer ana (aFace1, false);
  1055. if (!ana.IsValid()) {
  1056. TopoDS_Shape aFace2;
  1057. ShHealOper_ShapeProcess aHealer;
  1058. aHealer.Perform(aFace1, aFace2);
  1059. if (aHealer.isDone())
  1060. theResult = aFace2;
  1061. }
  1062. }
  1063. // 12.04.2006 for PAL12149 end
  1064. if (theResult.IsNull()) { // try to deal with pure result of filling
  1065. // Update tolerance
  1066. Standard_Real aTol = MF.G0Error();
  1067. TColgp_Array1OfPnt aPnts (1,nbEdges); // points of the given wire
  1068. BRepTools_WireExplorer aWE1 (theWire);
  1069. Standard_Integer vi = 1;
  1070. for (; aWE1.More() && vi <= nbEdges; aWE1.Next(), vi++) {
  1071. aPnts(vi) = BRep_Tool::Pnt(TopoDS::Vertex(aWE1.CurrentVertex()));
  1072. }
  1073. // Find maximum deviation in vertices
  1074. TopExp_Explorer exp (aFace, TopAbs_VERTEX);
  1075. TopTools_MapOfShape mapShape;
  1076. for (; exp.More(); exp.Next()) {
  1077. if (mapShape.Add(exp.Current())) {
  1078. TopoDS_Vertex aV = TopoDS::Vertex(exp.Current());
  1079. Standard_Real aTolV = BRep_Tool::Tolerance(aV);
  1080. gp_Pnt aP = BRep_Tool::Pnt(aV);
  1081. Standard_Real min_dist = aP.Distance(aPnts(1));
  1082. for (vi = 2; vi <= nbEdges; vi++) {
  1083. min_dist = Min(min_dist, aP.Distance(aPnts(vi)));
  1084. }
  1085. aTol = Max(aTol, aTolV);
  1086. aTol = Max(aTol, min_dist);
  1087. }
  1088. }
  1089. if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) {
  1090. (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol);
  1091. }
  1092. theResult = aFace;
  1093. }
  1094. }
  1095. } else {
  1096. // try to update wire tolerances to build a planar face
  1097. #if 1 //(OCC_VERSION_MAJOR < 6) || (OCC_VERSION_MAJOR == 6 && OCC_VERSION_MINOR <= 1)
  1098. // Find a deviation
  1099. Standard_Real aToleranceReached, aTol;
  1100. BRepLib_FindSurface aFS;
  1101. aFS.Init(theWire, -1., isPlanarWanted);
  1102. aToleranceReached = aFS.ToleranceReached();
  1103. aTol = aFS.Tolerance();
  1104. if (!aFS.Found()) {
  1105. aFS.Init(theWire, aToleranceReached, isPlanarWanted);
  1106. if (!aFS.Found()) return;
  1107. aToleranceReached = aFS.ToleranceReached();
  1108. aTol = aFS.Tolerance();
  1109. }
  1110. aTol = Max(1.2 * aToleranceReached, aTol);
  1111. // Copy the wire, bacause it can be updated with very-very big tolerance here
  1112. BRepBuilderAPI_Copy aMC (theWire);
  1113. if (!aMC.IsDone()) return;
  1114. TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape());
  1115. // Update tolerances to <aTol>
  1116. BRep_Builder B;
  1117. for (TopExp_Explorer expE (aWire, TopAbs_EDGE); expE.More(); expE.Next()) {
  1118. TopoDS_Edge anE = TopoDS::Edge(expE.Current());
  1119. B.UpdateEdge(anE, aTol);
  1120. }
  1121. for (TopExp_Explorer expV (aWire, TopAbs_VERTEX); expV.More(); expV.Next()) {
  1122. TopoDS_Vertex aV = TopoDS::Vertex(expV.Current());
  1123. B.UpdateVertex(aV, aTol);
  1124. }
  1125. //BRepLib::UpdateTolerances(aWire);
  1126. // Build face
  1127. BRepBuilderAPI_MakeFace MK1 (aWire, isPlanarWanted);
  1128. if (MK1.IsDone()) {
  1129. theResult = MK1.Shape();
  1130. return;
  1131. }
  1132. #else // After migration on OCCT version, containing PKV's fix. See bug 8293
  1133. BRepLib_MakeFace aBMF;
  1134. aBMF.Init(theWire, isPlanarWanted, Standard_True);
  1135. if (aBMF.Error() == BRepLib_FaceDone) {
  1136. theResult = aBMF.Shape();
  1137. return;
  1138. }
  1139. #endif
  1140. }
  1141. }