1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <Standard_Stream.hxx>
25 #include <GEOMImpl_Block6Explorer.hxx>
27 #include <ShHealOper_ShapeProcess.hxx>
29 #include "utilities.h"
31 #include <BRep_Tool.hxx>
32 #include <BRep_TFace.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRepLib.hxx>
35 #include <BRepLib_FindSurface.hxx>
36 #include <BRepTools.hxx>
37 #include <BRepTools_WireExplorer.hxx>
38 #include <BRepOffsetAPI_ThruSections.hxx>
39 #include <BRepOffsetAPI_MakeFilling.hxx>
40 #include <BRepCheck_Analyzer.hxx>
41 #include <BRepBuilderAPI_Copy.hxx>
42 #include <BRepBuilderAPI_MakeEdge.hxx>
43 #include <BRepBuilderAPI_MakeWire.hxx>
44 #include <BRepBuilderAPI_MakeFace.hxx>
45 #include <BRepBuilderAPI_Transform.hxx>
49 #include <TopoDS_Shape.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Wire.hxx>
52 #include <TopoDS_Solid.hxx>
54 #include <TopExp_Explorer.hxx>
55 #include <TopTools_MapOfShape.hxx>
56 #include <TopTools_ListOfShape.hxx>
57 #include <TopTools_ListIteratorOfListOfShape.hxx>
58 #include <TopTools_IndexedMapOfShape.hxx>
59 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
61 #include <Geom_Curve.hxx>
62 #include <Geom_TrimmedCurve.hxx>
63 #include <GeomFill_Generator.hxx>
65 #include <Precision.hxx>
67 #include <TColgp_Array1OfPnt.hxx>
69 #include <StdFail_NotDone.hxx>
70 #include <Standard_NullObject.hxx>
71 #include <Standard_TypeMismatch.hxx>
72 #include <Standard_ConstructionError.hxx>
73 #include <Standard_NoSuchObject.hxx>
79 static Standard_Integer mod4 (Standard_Integer nb)
81 if (nb <= 0) return nb + 4;
82 if (nb > 4) return nb - 4;
86 static Standard_Integer edge_id (const Standard_Integer theFaceID,
87 const Standard_Integer theEdgeNB)
89 static Standard_Integer edge_ids[NBFACES][4] = {
90 { 1, 2, 3, 4 }, // face 1
91 { 5, 6, 7, 8 }, // face 2
92 { 9, 5, 10, 1 }, // face 3
93 { 12, 7, 11, 3 }, // face 4
94 { 4, 12, 8, 9 }, // face 5
95 { 2, 11, 6, 10 } }; // face 6
97 return edge_ids[theFaceID - 1][theEdgeNB - 1];
100 static Standard_Integer side_edge_id (const Standard_Integer theEdgeNB)
102 static Standard_Integer side_edge_ids[4] = {9, 10, 11, 12};
104 return side_edge_ids[theEdgeNB - 1];
107 static Standard_Integer vertex_id (const Standard_Integer theFaceID,
108 const Standard_Integer theVertexNB)
110 static Standard_Integer vertex_ids[NBFACES][4] = {
111 { 1, 2, 3, 4 }, // face 1
112 { 5, 6, 7, 8 }, // face 2
113 { 1, 5, 6, 2 }, // face 3
114 { 4, 8, 7, 3 }, // face 4
115 { 1, 4, 8, 5 }, // face 5
116 { 2, 3, 7, 6 } }; // face 6
118 return vertex_ids[theFaceID - 1][theVertexNB - 1];
121 static Standard_Integer vertex_id_edge (const Standard_Integer theEdgeID, // [1,12]
122 const Standard_Integer theVertexNB) // [1,2]
124 static Standard_Integer vertex_ids_edge[NBEDGES][2] = {
138 return vertex_ids_edge[theEdgeID - 1][theVertexNB - 1];
141 static Standard_Integer face_id_edges (const Standard_Integer theEdge1ID, // [1,12]
142 const Standard_Integer theEdge2ID) // [1,12]
144 static Standard_Integer face_ids_edges[NBEDGES][NBEDGES] = {
145 // 1 2 3 4 5 6 7 8 9 10 11 12
146 { 0, 1, 1, 1, 3, 0, 0, 0, 3, 3, 0, 0 }, // edge 1
147 { 1, 0, 1, 1, 0, 6, 0, 0, 0, 6, 6, 0 }, // edge 2
148 { 1, 1, 0, 1, 0, 0, 4, 0, 0, 0, 4, 4 }, // edge 3
149 { 1, 1, 1, 0, 0, 0, 0, 5, 5, 0, 0, 5 }, // edge 4
150 { 3, 0, 0, 0, 0, 2, 2, 2, 3, 3, 0, 0 }, // edge 5
151 { 0, 6, 0, 0, 2, 0, 2, 2, 0, 6, 6, 0 }, // edge 6
152 { 0, 0, 4, 0, 2, 2, 0, 2, 0, 0, 4, 4 }, // edge 7
153 { 0, 0, 0, 5, 2, 2, 2, 0, 5, 0, 0, 5 }, // edge 8
154 { 3, 0, 0, 5, 3, 0, 0, 5, 0, 3, 0, 5 }, // edge 9
155 { 3, 6, 0, 0, 3, 6, 0, 0, 3, 0, 6, 0 }, // edge 10
156 { 0, 6, 4, 0, 0, 6, 4, 0, 0, 6, 0, 4 }, // edge 11
157 { 0, 0, 4, 5, 0, 0, 4, 5, 5, 0, 4, 0 } }; // edge 12
159 return face_ids_edges[theEdge1ID - 1][theEdge2ID - 1];
162 static Standard_Integer edge_id_vertices (const Standard_Integer theVertex1ID, // [1,8]
163 const Standard_Integer theVertex2ID) // [1,8]
165 static Standard_Integer edge_ids_vertices[NBVERTS][NBVERTS] = {
167 { 0, 1, 0, 4, 9, 0, 0, 0}, // vertex 1
168 { 1, 0, 2, 0, 0, 10, 0, 0}, // vertex 2
169 { 0, 2, 0, 3, 0, 0, 11, 0}, // vertex 3
170 { 4, 0, 3, 0, 0, 0, 0, 12}, // vertex 4
171 { 9, 0, 0, 0, 0, 5, 0, 8}, // vertex 5
172 { 0, 10, 0, 0, 5, 0, 6, 0}, // vertex 6
173 { 0, 0, 11, 0, 0, 6, 0, 7}, // vertex 7
174 { 0, 0, 0, 12, 8, 0, 7, 0} }; // vertex 8
176 return edge_ids_vertices[theVertex1ID - 1][theVertex2ID - 1];
179 static Standard_Integer edge_id_faces (const Standard_Integer theFace1ID, // [1,6]
180 const Standard_Integer theFace2ID) // [1,6]
182 static Standard_Integer edge_ids_faces[NBFACES][NBFACES] = {
184 { 0, 0, 1, 3, 4, 2 }, // face 1
185 { 0, 0, 5, 7, 8, 6 }, // face 2
186 { 1, 5, 0, 0, 9, 10 }, // face 3
187 { 3, 7, 0, 0, 12, 11 }, // face 4
188 { 4, 8, 9, 12, 0, 0 }, // face 5
189 { 2, 6, 10, 11, 0, 0 } }; // face 6
191 return edge_ids_faces[theFace1ID - 1][theFace2ID - 1];
194 //=======================================================================
195 //function : GEOMImpl_Block6Explorer
196 //purpose : Constructor
197 //=======================================================================
198 GEOMImpl_Block6Explorer::GEOMImpl_Block6Explorer ()
199 : myFaces(1,NBFACES), myEdges(1,NBEDGES), myVertices(1,NBVERTS)
203 //=======================================================================
204 //function : GetVertex
206 //=======================================================================
207 TopoDS_Shape GEOMImpl_Block6Explorer::GetVertex (const Standard_Integer theVertexID)
209 TopoDS_Shape aNullShape;
210 if (theVertexID < 1 || theVertexID > NBVERTS) return aNullShape;
211 return myVertices(theVertexID);
214 //=======================================================================
215 //function : GetVertexID
217 //=======================================================================
218 Standard_Integer GEOMImpl_Block6Explorer::GetVertexID (const TopoDS_Shape& theVertex)
220 for (Standard_Integer id = 1; id <= NBVERTS; id++) {
221 if (theVertex.IsSame(myVertices(id))) return id;
223 Standard_NoSuchObject::Raise("The Vertex does not belong to the Block");
227 //=======================================================================
228 //function : GetVertexID
230 //=======================================================================
231 Standard_Integer GEOMImpl_Block6Explorer::GetVertexID (const Standard_Integer theFaceID,
232 const Standard_Integer theVertexNB)
234 return vertex_id(theFaceID, theVertexNB);
237 //=======================================================================
238 //function : GetVertexOnEdgeID
240 //=======================================================================
241 Standard_Integer GEOMImpl_Block6Explorer::GetVertexOnEdgeID
242 (const Standard_Integer theEdgeID,
243 const Standard_Integer theVertexNB)
245 return vertex_id_edge(theEdgeID, theVertexNB);
248 //=======================================================================
251 //=======================================================================
252 TopoDS_Shape GEOMImpl_Block6Explorer::GetEdge (const Standard_Integer theEdgeID,
253 const Standard_Boolean doMake)
255 TopoDS_Shape aNullShape;
256 if (theEdgeID < 1 || theEdgeID > NBEDGES) return aNullShape;
257 if (myEdges(theEdgeID).IsNull() && doMake) {
258 // Create the required edge as a linear segment between
259 // corresponding vertices and put it in the Block's edges
260 BRepBuilderAPI_MakeEdge ME (TopoDS::Vertex(myVertices(vertex_id_edge(theEdgeID, 1))),
261 TopoDS::Vertex(myVertices(vertex_id_edge(theEdgeID, 2))));
263 Standard_ConstructionError::Raise("Edge construction failed");
265 myEdges(theEdgeID) = ME.Shape();
268 return myEdges(theEdgeID);
271 //=======================================================================
272 //function : GetEdgeID
274 //=======================================================================
275 Standard_Integer GEOMImpl_Block6Explorer::GetEdgeID (const TopoDS_Shape& theEdge)
277 for (Standard_Integer id = 1; id <= NBEDGES; id++) {
278 if (theEdge.IsSame(myEdges(id))) return id;
280 Standard_NoSuchObject::Raise("The Edge does not belong to the Block");
284 //=======================================================================
285 //function : GetEdgeID
287 //=======================================================================
288 Standard_Integer GEOMImpl_Block6Explorer::GetEdgeID (const Standard_Integer theFaceID,
289 const Standard_Integer theEdgeNB)
291 return edge_id(theFaceID, theEdgeNB);
294 //=======================================================================
295 //function : FindEdgeID
297 //=======================================================================
298 Standard_Integer GEOMImpl_Block6Explorer::FindEdgeID (const Standard_Integer theVertex1ID,
299 const Standard_Integer theVertex2ID)
301 return edge_id_vertices(theVertex1ID, theVertex2ID);
304 //=======================================================================
305 //function : FindCommonEdgeID
307 //=======================================================================
308 Standard_Integer GEOMImpl_Block6Explorer::FindCommonEdgeID
309 (const Standard_Integer theFace1ID,
310 const Standard_Integer theFace2ID)
312 return edge_id_faces(theFace1ID, theFace2ID);
315 //=======================================================================
318 //=======================================================================
319 TopoDS_Shape GEOMImpl_Block6Explorer::GetFace (const Standard_Integer theFaceID,
320 const Standard_Boolean doMake)
322 TopoDS_Shape aNullShape;
323 if (theFaceID < 1 || theFaceID > NBFACES) return aNullShape;
325 if (myFaces(theFaceID).IsNull() && doMake) {
327 // Create the required face between
328 // corresponding edges and put it in the Block's faces
330 TopoDS_Shape E1 = GetEdge(edge_id(theFaceID, 1), doMake);
331 TopoDS_Shape E2 = GetEdge(edge_id(theFaceID, 2), doMake);
332 TopoDS_Shape E3 = GetEdge(edge_id(theFaceID, 3), doMake);
333 TopoDS_Shape E4 = GetEdge(edge_id(theFaceID, 4), doMake);
335 BRepBuilderAPI_MakeWire MW (TopoDS::Edge(E1),
340 Standard_ConstructionError::Raise("Wire construction failed");
343 MakeFace(MW, Standard_False, aFace);
344 if (aFace.IsNull()) {
345 Standard_ConstructionError::Raise("Face construction failed");
347 myFaces(theFaceID) = aFace;
350 return myFaces(theFaceID);
353 //=======================================================================
354 //function : GetFaceID
356 //=======================================================================
357 Standard_Integer GEOMImpl_Block6Explorer::GetFaceID (const TopoDS_Shape& theFace)
359 for (Standard_Integer id = 1; id <= NBFACES; id++) {
360 if (theFace.IsSame(myFaces(id))) return id;
362 Standard_NoSuchObject::Raise("The Face does not belong to the Block");
366 //=======================================================================
367 //function : FindFaceID
369 //=======================================================================
370 Standard_Integer GEOMImpl_Block6Explorer::FindFaceID (const Standard_Integer theEdge1ID,
371 const Standard_Integer theEdge2ID)
373 return face_id_edges(theEdge1ID, theEdge2ID);
376 //=======================================================================
377 //function : GetOppositeFaceID
379 //=======================================================================
380 Standard_Integer GEOMImpl_Block6Explorer::GetOppositeFaceID (const Standard_Integer theFaceID)
382 Standard_Integer opp_face_id[NBFACES + 1] = {
391 return opp_face_id[theFaceID];
394 //=======================================================================
395 //function : IsSimilarFaces
397 //=======================================================================
398 Standard_Boolean GEOMImpl_Block6Explorer::IsSimilarFaces (const Standard_Integer theFace1ID,
399 const Standard_Integer theFace2ID,
400 const gp_Trsf theTransformation)
402 Standard_Integer common_edge_id = FindCommonEdgeID(theFace1ID, theFace2ID);
404 if (common_edge_id == 0) { // opposite faces
405 for (Standard_Integer id = 1; id <= 4; id++) {
406 TopoDS_Shape E1 = GetEdge(edge_id(theFace1ID, id));
407 TopoDS_Shape E2 = GetEdge(edge_id(theFace2ID, id));
409 BRepBuilderAPI_Transform aTrsf (E1, theTransformation, Standard_False);
410 if (!IsSimilarEdges(aTrsf.Shape(), E2))
411 return Standard_False;
413 } else { // the faces have common edge
414 TopTools_Array1OfShape aVerts1 (1,4);
415 TopTools_Array1OfShape aVerts2 (1,4);
417 Standard_Integer common_vertex1 = GetVertexOnEdgeID(common_edge_id, 1);
418 Standard_Integer common_vertex2 = GetVertexOnEdgeID(common_edge_id, 2);
419 aVerts1(1) = myVertices(common_vertex1);
420 aVerts1(2) = myVertices(common_vertex2);
421 aVerts2(1) = myVertices(common_vertex1);
422 aVerts2(2) = myVertices(common_vertex2);
424 Standard_Integer not_common_v11 = 0, not_common_v12 = 0;
425 Standard_Integer vnb, vid;
426 for (vnb = 1; vnb <= 4; vnb++) {
427 vid = GetVertexID(theFace1ID, vnb);
428 if (vid != common_vertex1 && FindEdgeID(vid, common_vertex1) == 0) {
429 not_common_v12 = vid;
431 if (vid != common_vertex2 && FindEdgeID(vid, common_vertex2) == 0) {
432 not_common_v11 = vid;
437 Standard_Integer not_common_v21 = 0, not_common_v22 = 0;
438 for (vnb = 1; vnb <= 4; vnb++) {
439 vid = GetVertexID(theFace2ID, vnb);
440 if (vid != common_vertex1 && FindEdgeID(vid, common_vertex1) == 0) {
441 not_common_v22 = vid;
443 if (vid != common_vertex2 && FindEdgeID(vid, common_vertex2) == 0) {
444 not_common_v21 = vid;
448 aVerts1(3) = myVertices(not_common_v11);
449 aVerts1(4) = myVertices(not_common_v12);
450 aVerts2(3) = myVertices(not_common_v21);
451 aVerts2(4) = myVertices(not_common_v22);
453 for (Standard_Integer id = 1; id <= 4; id++) {
454 BRepBuilderAPI_Transform aTrsf (aVerts1(id), theTransformation, Standard_False);
455 TopoDS_Vertex V1 = TopoDS::Vertex(aTrsf.Shape());
456 TopoDS_Vertex V2 = TopoDS::Vertex(aVerts2(id));
457 if (!BRepTools::Compare(V1, V2)) {
458 return Standard_False;
463 return Standard_True;
466 //============ Initialization methods ===================================
468 //=======================================================================
469 //function : InitByBlock
471 //=======================================================================
472 void GEOMImpl_Block6Explorer::InitByBlock (const TopoDS_Shape& theBlock)
474 // 1. Find any one face of the block
475 TopExp_Explorer faces (theBlock, TopAbs_FACE);
477 Standard_ConstructionError::Raise("The block has no faces");
479 TopoDS_Shape aFirstFace = faces.Current();
481 // 2. Store all elements of the block relatively aFirstFace
482 InitByBlockAndFace(theBlock, aFirstFace);
485 //=======================================================================
486 //function : InitByBlockAndFace
488 //=======================================================================
489 void GEOMImpl_Block6Explorer::InitByBlockAndFace (const TopoDS_Shape& theBlock,
490 const TopoDS_Shape& theFace)
492 myFaces(1) = theFace;
494 // 2. Get wire of the first face
495 TopExp_Explorer wires (myFaces(1), TopAbs_WIRE);
497 Standard_ConstructionError::Raise("A face of the block has no wires");
499 TopoDS_Shape aWire = wires.Current();
502 Standard_ConstructionError::Raise("A face of the block has more than one wires");
505 // 3. Explore wire to init edges and vertices of the first face
506 BRepTools_WireExplorer aWE (TopoDS::Wire(aWire), TopoDS::Face(myFaces(1)));
507 Standard_Integer nb = 1;
508 for (; aWE.More(); aWE.Next(), nb++) {
510 Standard_ConstructionError::Raise("A face of the block has more than four edges");
512 myEdges(edge_id(1, nb)) = aWE.Current();
513 myVertices(vertex_id(1, nb)) = aWE.CurrentVertex();
516 Standard_ConstructionError::Raise("A face of the block has less than four edges");
519 // 2. Store all other elements of the block
520 InitByBlockAndVertices (theBlock,
521 myVertices(vertex_id(1,1)),
522 myVertices(vertex_id(1,2)),
523 myVertices(vertex_id(1,3)));
526 //=======================================================================
527 //function : InitByBlockAndEdges
529 //=======================================================================
530 void GEOMImpl_Block6Explorer::InitByBlockAndEdges (const TopoDS_Shape& theBlock,
531 const TopoDS_Shape& theEdge1,
532 const TopoDS_Shape& theEdge3)
534 // 1. Store vertices and edges of the first face
536 // 1.1. Store two given edges
537 myEdges(edge_id(1, 1)) = theEdge1;
538 myEdges(edge_id(1, 3)) = theEdge3;
540 // 1.2. Find and store the first face
541 TopTools_IndexedDataMapOfShapeListOfShape MEF;
542 MapShapesAndAncestors(theBlock, TopAbs_EDGE, TopAbs_FACE, MEF);
543 if (MEF.Extent() != NBEDGES) {
544 Standard_TypeMismatch::Raise("Block has wrong number of edges");
546 const TopTools_ListOfShape& aFacesOfE1 = MEF.FindFromKey(theEdge1);
547 const TopTools_ListOfShape& aFacesOfE3 = MEF.FindFromKey(theEdge3);
549 Standard_Boolean isFound = Standard_False;
550 TopTools_ListIteratorOfListOfShape anIterF1 (aFacesOfE1);
551 for (; anIterF1.More() && !isFound; anIterF1.Next()) {
553 TopTools_ListIteratorOfListOfShape anIterF3 (aFacesOfE3);
554 for (; anIterF3.More() && !isFound; anIterF3.Next()) {
556 if (anIterF1.Value().IsSame(anIterF3.Value())) {
557 isFound = Standard_True;
559 // Store the face, defined by two opposite edges
560 myFaces(1) = anIterF1.Value();
565 Standard_ConstructionError::Raise
566 ("Edges 1 and 2 do not belong to one face of the block");
569 // 1.3. Make vertices of the first edge the first and the
570 // second vertices of the first face. Order is free.
571 TopoDS_Edge E = TopoDS::Edge(theEdge1);
572 TopoDS_Vertex V1, V2;
573 TopExp::Vertices(E, V1, V2, Standard_True);
574 myVertices(vertex_id(1,1)) = V1;
575 myVertices(vertex_id(1,2)) = V2;
577 // Init maps vertex->list_of_edges for the face
578 TopTools_IndexedDataMapOfShapeListOfShape M1;
579 MapShapesAndAncestors(myFaces(1), TopAbs_VERTEX, TopAbs_EDGE, M1);
580 if (M1.Extent() != 4) {
581 Standard_TypeMismatch::Raise("The first face of block has wrong number of vertices");
584 // 1.4. Find and store others elements of the first face
586 // edges of the first vertex
587 TopoDS_Shape E1_f = M1.FindFromKey(V1).First();
588 TopoDS_Shape E1_l = M1.FindFromKey(V1).Last();
590 if (E1_f.IsSame(theEdge1)) {
591 myEdges(edge_id(1, 4)) = E1_l;
593 myEdges(edge_id(1, 4)) = E1_f;
597 TopoDS_Edge E4 = TopoDS::Edge(myEdges(edge_id(1, 4)));
598 TopoDS_Vertex V41, V42;
599 TopExp::Vertices(E4, V41, V42, Standard_True);
600 if (V41.IsSame(V1)) {
601 myVertices(vertex_id(1,4)) = V42;
603 myVertices(vertex_id(1,4)) = V41;
606 // edges of the second vertex
607 TopoDS_Shape E2_f = M1.FindFromKey(V2).First();
608 TopoDS_Shape E2_l = M1.FindFromKey(V2).Last();
610 if (E2_f.IsSame(theEdge1)) {
611 myEdges(edge_id(1, 2)) = E2_l;
613 myEdges(edge_id(1, 2)) = E2_f;
617 TopoDS_Edge E2 = TopoDS::Edge(myEdges(edge_id(1, 2)));
618 TopoDS_Vertex V21, V22;
619 TopExp::Vertices(E2, V21, V22, Standard_True);
620 if (V21.IsSame(V2)) {
621 myVertices(vertex_id(1,3)) = V22;
623 myVertices(vertex_id(1,3)) = V21;
626 // 2. Store all other elements of the block
627 InitByBlockAndVertices (theBlock,
628 myVertices(vertex_id(1,1)),
629 myVertices(vertex_id(1,2)),
630 myVertices(vertex_id(1,3)));
633 //=======================================================================
634 //function : InitByBlockAndVertices
636 //=======================================================================
637 void GEOMImpl_Block6Explorer::InitByBlockAndVertices (const TopoDS_Shape& theBlock,
638 const TopoDS_Shape& theVertex1,
639 const TopoDS_Shape& theVertex2,
640 const TopoDS_Shape& theVertex3)
642 // Here we suppose, that vertices are ordered, i.e. exists edge between
643 // theVertex1 and theVertex2 and edge between theVertex2 and theVertex3
645 // 1. Store vertices and edges of the first face.
646 // If the first face is initialized, it means, that this
647 // method is called from another initialization method, and all
648 // vertices and edges of the first face are also initialized
649 if (myFaces(1).IsNull()) {
651 // 1.1. Store first three vertices
652 myVertices(vertex_id(1, 1)) = theVertex1;
653 myVertices(vertex_id(1, 2)) = theVertex2;
654 myVertices(vertex_id(1, 3)) = theVertex3;
656 // 1.2. Find and store the first face
657 TopTools_IndexedDataMapOfShapeListOfShape MVF;
658 MapShapesAndAncestors(theBlock, TopAbs_VERTEX, TopAbs_FACE, MVF);
659 if (MVF.Extent() != NBVERTS) {
660 Standard_TypeMismatch::Raise("Block has wrong number of vertices");
662 const TopTools_ListOfShape& aFacesOfV1 = MVF.FindFromKey(theVertex1);
663 const TopTools_ListOfShape& aFacesOfV3 = MVF.FindFromKey(theVertex3);
665 Standard_Boolean isFound = Standard_False;
666 TopTools_ListIteratorOfListOfShape anIterF1 (aFacesOfV1);
667 for (; anIterF1.More() && !isFound; anIterF1.Next()) {
669 TopTools_ListIteratorOfListOfShape anIterF3 (aFacesOfV3);
670 for (; anIterF3.More() && !isFound; anIterF3.Next()) {
672 if (anIterF1.Value().IsSame(anIterF3.Value())) {
673 isFound = Standard_True;
675 // Store the face, defined by two opposite vertices
676 myFaces(1) = anIterF1.Value();
681 Standard_ConstructionError::Raise
682 ("Vertices 1 and 3 do not belong to one face of the block");
685 // Init maps vertex->list_of_edges for the face
686 TopTools_IndexedDataMapOfShapeListOfShape M1;
687 MapShapesAndAncestors(myFaces(1), TopAbs_VERTEX, TopAbs_EDGE, M1);
688 if (M1.Extent() != 4) {
689 Standard_TypeMismatch::Raise("The first face of block has wrong number of vertices");
692 // 1.3. Find and store edges and last vertex of the first face
693 const TopTools_ListOfShape& anEdgesOfV1 = M1.FindFromKey(theVertex1);
694 const TopTools_ListOfShape& anEdgesOfV2 = M1.FindFromKey(theVertex2);
695 const TopTools_ListOfShape& anEdgesOfV3 = M1.FindFromKey(theVertex3);
697 TopTools_ListIteratorOfListOfShape anIterE2 (anEdgesOfV2);
698 for (; anIterE2.More(); anIterE2.Next()) {
700 TopTools_ListIteratorOfListOfShape anIterE1 (anEdgesOfV1);
701 for (; anIterE1.More(); anIterE1.Next()) {
703 if (anIterE1.Value().IsSame(anIterE2.Value())) {
704 // Store the first edge, defined by two vertices
705 myEdges(edge_id(1,1)) = anIterE1.Value();
708 // Store the last edge
709 myEdges(edge_id(1,4)) = anIterE1.Value();
711 // Find and store the last vertex
712 TopoDS_Edge E = TopoDS::Edge(myEdges(4));
713 TopoDS_Vertex V1, V2;
714 TopExp::Vertices(E, V1, V2, Standard_True);
716 if (V1.IsSame(theVertex1)) {
717 myVertices(vertex_id(1,4)) = V2;
719 myVertices(vertex_id(1,4)) = V1;
724 TopTools_ListIteratorOfListOfShape anIterE3 (anEdgesOfV3);
725 for (; anIterE3.More(); anIterE3.Next()) {
727 if (anIterE3.Value().IsSame(anIterE2.Value())) {
728 // Store the second edge, defined by two vertices
729 myEdges(edge_id(1,2)) = anIterE3.Value();
732 // Store the fird edge
733 myEdges(edge_id(1,3)) = anIterE3.Value();
739 // Init map vertex->list_of_edges for the block
740 TopTools_IndexedDataMapOfShapeListOfShape MB;
741 MapShapesAndAncestors(theBlock, TopAbs_VERTEX, TopAbs_EDGE, MB);
742 if (MB.Extent() != NBVERTS) {
743 Standard_TypeMismatch::Raise("Block has wrong number of vertices");
746 // 2. Store edges, linking the first face with the second one
747 // and vertices of the second face
748 TopTools_IndexedMapOfShape aFaceEdges;
749 TopExp::MapShapes(myFaces(1), TopAbs_EDGE, aFaceEdges);
751 Standard_Integer i = 1;
752 for (; i <= 4; i++) {
753 // Get i-th vertex of the face 1
754 TopoDS_Shape Vi = myVertices(vertex_id(1, i));
755 if (!MB.Contains(Vi)) {
756 Standard_ConstructionError::Raise("Face does not belong to the block");
759 // Get list of block's edges, sharing this Vertex
760 const TopTools_ListOfShape& anEdgesOfVi = MB.FindFromKey(Vi);
761 TopTools_ListIteratorOfListOfShape anEdgesIter (anEdgesOfVi);
763 // Get Edge (from the List), not belonging to the face 1
764 Standard_Boolean isFound = Standard_False;
765 for (; anEdgesIter.More() && !isFound; anEdgesIter.Next()) {
766 if (!aFaceEdges.Contains(anEdgesIter.Value())) {
767 isFound = Standard_True;
769 // Store the linking edge
770 TopoDS_Shape aLinkEdge = anEdgesIter.Value();
771 myEdges(side_edge_id(i)) = aLinkEdge;
773 // Get another vertex of the linking edge
774 TopoDS_Edge E = TopoDS::Edge(aLinkEdge);
775 TopoDS_Vertex V1, V2;
776 TopExp::Vertices(E, V1, V2, Standard_True);
778 // Store the i-th vertex of the second (opposite to the first) face
780 myVertices(vertex_id(2, i)) = V2;
782 myVertices(vertex_id(2, i)) = V1;
788 // 3. Store edges of the second (opposite to the first) face
789 for (i = 1; i <= 4; i++) {
790 // Get i-th and (i+1)-th vertices of the face 2
791 TopoDS_Shape Vi = myVertices(vertex_id(2, i));
792 TopoDS_Shape Vj = myVertices(vertex_id(2, mod4(i + 1)));
794 // Get list of block's edges, sharing Vi
795 const TopTools_ListOfShape& anEdgesOfVi = MB.FindFromKey(Vi);
796 // Get list of block's edges, sharing Vj
797 const TopTools_ListOfShape& anEdgesOfVj = MB.FindFromKey(Vj);
799 // Get Edge (from the List), linking this vertex with the next one
800 Standard_Boolean isFound = Standard_False;
801 TopTools_ListIteratorOfListOfShape anEdgesIteri (anEdgesOfVi);
802 for (; anEdgesIteri.More() && !isFound; anEdgesIteri.Next()) {
804 TopTools_ListIteratorOfListOfShape anEdgesIterj (anEdgesOfVj);
805 for (; anEdgesIterj.More() && !isFound; anEdgesIterj.Next()) {
807 if (anEdgesIteri.Value().IsSame(anEdgesIterj.Value())) {
808 isFound = Standard_True;
810 // Store the linking edge
811 myEdges(edge_id(2, i)) = anEdgesIteri.Value();
817 // 4. Store faces of the block
818 TopTools_IndexedDataMapOfShapeListOfShape MBE;
819 MapShapesAndAncestors(theBlock, TopAbs_EDGE, TopAbs_FACE, MBE);
820 if (MBE.Extent() != NBEDGES) {
821 Standard_TypeMismatch::Raise("Block has wrong number of edges");
824 for (i = 2; i <= NBFACES; i++) {
825 TopoDS_Shape Ei1 = myEdges(edge_id(i, 1));
826 TopoDS_Shape Ei2 = myEdges(edge_id(i, 2));
827 const TopTools_ListOfShape& aFacesOfEi1 = MBE.FindFromKey(Ei1);
828 const TopTools_ListOfShape& aFacesOfEi2 = MBE.FindFromKey(Ei2);
830 Standard_Boolean isFound = Standard_False;
831 TopTools_ListIteratorOfListOfShape anIterEi1 (aFacesOfEi1);
832 for (; anIterEi1.More() && !isFound; anIterEi1.Next()) {
834 TopTools_ListIteratorOfListOfShape anIterEi2 (aFacesOfEi2);
835 for (; anIterEi2.More() && !isFound; anIterEi2.Next()) {
837 if (anIterEi1.Value().IsSame(anIterEi2.Value())) {
838 isFound = Standard_True;
840 // Store the face, defined by two edges
841 myFaces(i) = anIterEi1.Value();
848 //=======================================================================
849 //function : InitByTwoFaces
851 //=======================================================================
852 void GEOMImpl_Block6Explorer::InitByTwoFaces (const TopoDS_Shape& theFace1,
853 const TopoDS_Shape& theFace2)
855 if (theFace1.IsSame(theFace2)) {
856 Standard_ConstructionError::Raise("The faces must be different");
859 // Add two given faces in the structure
860 myFaces(1) = theFace1;
861 myFaces(2) = theFace2;
863 // Step 1. Order vertices (and edges)
865 // 1.1. Ordered vertices and edges of the first face we put in <myVertices>
867 // Get wire of the first face
868 TopExp_Explorer wires1 (myFaces(1), TopAbs_WIRE);
869 if (!wires1.More()) {
870 Standard_ConstructionError::Raise("A face for the block has no wires");
872 TopoDS_Shape aWire1 = wires1.Current();
875 Standard_ConstructionError::Raise("A face for the block has more than one wire");
878 BRepTools_WireExplorer aWE1 (TopoDS::Wire(aWire1), TopoDS::Face(myFaces(1)));
880 for (nb = 1; aWE1.More(); aWE1.Next(), nb++) {
882 Standard_ConstructionError::Raise("A face for the block has more than four edges");
884 myEdges(edge_id(1, nb)) = aWE1.Current();
885 myVertices(vertex_id(1, nb)) = aWE1.CurrentVertex();
888 Standard_ConstructionError::Raise("A face for the block has less than four edges");
891 // 1.2. Ordered vertices and edges of the second face we temporarily store
892 // in arrays, to find for them rigth location in <myVertices> on the Step 2.
895 TopTools_Array1OfShape aVertis2(1,4); // ordered vertices of the second face
896 TopTools_Array1OfShape anEdges2(1,4); // anEdges2(i) links aVertis2(i) and aVertis2(i+1)
898 // Get wire of the second face
899 TopExp_Explorer wires2 (myFaces(2), TopAbs_WIRE);
900 if (!wires2.More()) {
901 Standard_ConstructionError::Raise("A face for the block has no wires");
903 TopoDS_Shape aWire2 = wires2.Current();
906 Standard_ConstructionError::Raise("A face for the block has more than one wire");
909 BRepTools_WireExplorer aWE2 (TopoDS::Wire(aWire2), TopoDS::Face(myFaces(2)));
910 for (nb = 1; aWE2.More(); aWE2.Next(), nb++) {
912 Standard_ConstructionError::Raise("A face for the block has more than four edges");
914 anEdges2(nb) = aWE2.Current();
915 aVertis2(nb) = aWE2.CurrentVertex();
918 Standard_ConstructionError::Raise("A face for the block has less than four edges");
921 // Step 2. Find right place in <myVertices> for the <aVertis2>,
922 // so as to minimize common length of linking edges
923 // between face 1 and face 2.
924 // Each linking edge (of four) will link vertices of the
925 // faces 1 and 2 with equal local numbers.
926 // The right place is defined by:
927 // - vertex <aVertis2(i_min)>, which will become the first vertex
928 // of the second face <myVertices(vertex_id(2,1))>
929 // - orientation of <aVertis2> relatively their future location
930 // in <myVertices> (s_min = 1 if direct, s_min = -1 if reversed)
931 Standard_Integer i_min = 0, s_min = 0;
933 TColgp_Array1OfPnt aPnts1 (1,4); // points of the first face
934 aPnts1(1) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 1))));
935 aPnts1(2) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 2))));
936 aPnts1(3) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 3))));
937 aPnts1(4) = BRep_Tool::Pnt(TopoDS::Vertex(myVertices(vertex_id(1, 4))));
939 TColgp_Array1OfPnt aPnts2 (1,4); // points of the second face
940 aPnts2(1) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(1)));
941 aPnts2(2) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(2)));
942 aPnts2(3) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(3)));
943 aPnts2(4) = BRep_Tool::Pnt(TopoDS::Vertex(aVertis2(4)));
945 Standard_Real Dist_min = RealLast();
946 // try all possible locations to find the best (with minimum sum distance)
947 Standard_Integer i = 1;
948 for (; i <= 4; i++) {
949 // try direct orientation
950 Standard_Real Dist_plus = aPnts1(1).Distance(aPnts2(i)) +
951 aPnts1(2).Distance(aPnts2(mod4(i + 1))) +
952 aPnts1(3).Distance(aPnts2(mod4(i + 2))) +
953 aPnts1(4).Distance(aPnts2(mod4(i + 3)));
954 if (Dist_plus < Dist_min) {
955 Dist_min = Dist_plus;
960 // try reversed orientation
961 Standard_Real Dist_minus = aPnts1(1).Distance(aPnts2(i)) +
962 aPnts1(2).Distance(aPnts2(mod4(i - 1))) +
963 aPnts1(3).Distance(aPnts2(mod4(i - 2))) +
964 aPnts1(4).Distance(aPnts2(mod4(i - 3)));
965 if (Dist_minus < Dist_min) {
966 Dist_min = Dist_minus;
972 // 3. Put vertices and edges of the second face to they
973 // permanent location in <myVertices> and <myEdges>
974 for (i = 1; i <= 4; i++) {
975 Standard_Integer nb = mod4(i_min + s_min*(i - 1));
977 if (aPnts1(i).Distance(aPnts2(nb)) < Precision::Confusion()) {
978 Standard_ConstructionError::Raise("The faces are too close");
981 myVertices(vertex_id(2, i)) = aVertis2(nb);
983 if (s_min == -1) nb = mod4(nb - 1);
984 myEdges(edge_id(2, i)) = anEdges2(nb);
987 // check the wires closure
988 TopoDS_Wire wire1 = TopoDS::Wire(aWire1);
989 TopoDS_Wire wire2 = TopoDS::Wire(aWire2);
990 TopoDS_Vertex aV1, aV2;
992 TopExp::Vertices(wire1, aV1, aV2);
993 if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) )
994 aWire1.Closed( true );
996 TopExp::Vertices(wire2, aV1, aV2);
997 if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) )
998 aWire2.Closed( true );
1000 // 4. Generate side surface
1001 if (!aWire1.Closed() || !aWire2.Closed()) {
1002 // BRepOffsetAPI_ThruSections is not applicable on not closed wires
1003 GetFace(3, Standard_True);
1004 GetFace(4, Standard_True);
1005 GetFace(5, Standard_True);
1006 GetFace(6, Standard_True);
1008 // try to build faces on native surfaces of edges or planar
1009 Standard_Boolean tryThru = Standard_False;
1010 for (Standard_Integer i = 3; i <= 6 && !tryThru; i++) {
1011 Standard_Boolean doMake = Standard_True;
1012 TopoDS_Shape E1 = GetEdge(edge_id(i, 1), doMake);
1013 TopoDS_Shape E2 = GetEdge(edge_id(i, 2), doMake);
1014 TopoDS_Shape E3 = GetEdge(edge_id(i, 3), doMake);
1015 TopoDS_Shape E4 = GetEdge(edge_id(i, 4), doMake);
1017 BRepBuilderAPI_MakeWire MW (TopoDS::Edge(E1),
1022 Standard_ConstructionError::Raise("Wire construction failed");
1025 BRepBuilderAPI_MakeFace MF (MW, Standard_False);
1027 myFaces(i) = MF.Shape();
1029 tryThru = Standard_True;
1033 // Build side surface by ThruSections algorithm
1035 BRepOffsetAPI_ThruSections THS;
1036 THS.AddWire(TopoDS::Wire(aWire1));
1037 THS.AddWire(TopoDS::Wire(aWire2));
1039 if (!THS.IsDone()) {
1040 StdFail_NotDone::Raise("Side surface generation failed");
1042 for (Standard_Integer i = 1; i <= 4; i++) {
1044 myFaces(i+2) = THS.GeneratedFace(myEdges(i));
1047 Standard_Integer ee = side_edge_id(i);
1048 TopTools_IndexedDataMapOfShapeListOfShape MVE;
1049 MapShapesAndAncestors(myFaces(i+2), TopAbs_VERTEX, TopAbs_EDGE, MVE);
1050 FindEdge(myEdges(ee),
1051 myVertices(vertex_id_edge(ee, 1)),
1052 myVertices(vertex_id_edge(ee, 2)),
1059 //=======================================================================
1060 //function : MapShapesAndAncestors
1062 //=======================================================================
1063 void GEOMImpl_Block6Explorer::MapShapesAndAncestors (const TopoDS_Shape& S,
1064 const TopAbs_ShapeEnum TS,
1065 const TopAbs_ShapeEnum TA,
1066 TopTools_IndexedDataMapOfShapeListOfShape& M)
1068 TopTools_ListOfShape empty;
1069 TopTools_MapOfShape mapA;
1072 TopExp_Explorer exa (S,TA);
1073 for (; exa.More(); exa.Next()) {
1075 const TopoDS_Shape& anc = exa.Current();
1076 if (mapA.Add(anc)) {
1077 TopExp_Explorer exs (anc,TS);
1078 TopTools_MapOfShape mapS;
1079 for (; exs.More(); exs.Next()) {
1080 if (mapS.Add(exs.Current())) {
1081 Standard_Integer index = M.FindIndex(exs.Current());
1082 if (index == 0) index = M.Add(exs.Current(),empty);
1083 M(index).Append(anc);
1089 // visit shapes not under ancestors
1090 TopExp_Explorer ex (S,TS,TA);
1091 for (; ex.More(); ex.Next()) {
1092 Standard_Integer index = M.FindIndex(ex.Current());
1093 if (index == 0) index = M.Add(ex.Current(),empty);
1097 //=======================================================================
1098 //function : IsSimilarEdges
1100 //=======================================================================
1101 Standard_Boolean GEOMImpl_Block6Explorer::IsSimilarEdges (const TopoDS_Shape& E1,
1102 const TopoDS_Shape& E2)
1104 TopoDS_Edge E1e = TopoDS::Edge(E1);
1105 TopoDS_Edge E2e = TopoDS::Edge(E2);
1106 TopoDS_Vertex V11, V12, V21, V22;
1107 TopExp::Vertices(E1e, V11, V12, Standard_True);
1108 TopExp::Vertices(E2e, V21, V22, Standard_True);
1109 if (BRepTools::Compare(V11, V21) && BRepTools::Compare(V12, V22))
1110 return Standard_True;
1111 if (BRepTools::Compare(V11, V22) && BRepTools::Compare(V12, V21))
1112 return Standard_True;
1114 return Standard_False;
1117 //=======================================================================
1118 //function : FindEdge
1120 //=======================================================================
1121 Standard_Integer GEOMImpl_Block6Explorer::FindEdge
1122 (TopoDS_Shape& theResult,
1123 const TopoDS_Shape& V1,
1124 const TopoDS_Shape& V2,
1125 const TopTools_IndexedDataMapOfShapeListOfShape& MVE,
1126 const Standard_Boolean findAll)
1128 Standard_Integer isFound = 0;
1130 const TopTools_ListOfShape& anEdgesOfV1 = MVE.FindFromKey(V1);
1131 const TopTools_ListOfShape& anEdgesOfV2 = MVE.FindFromKey(V2);
1133 TopTools_ListIteratorOfListOfShape it1 (anEdgesOfV1);
1134 for (; it1.More(); it1.Next()) {
1135 TopTools_ListIteratorOfListOfShape it2 (anEdgesOfV2);
1136 for (; it2.More(); it2.Next()) {
1137 if (it1.Value().IsSame(it2.Value())) {
1139 theResult = it1.Value();
1140 if (!findAll) return isFound;
1148 //=======================================================================
1149 //function : FindFace
1151 //=======================================================================
1152 Standard_Integer GEOMImpl_Block6Explorer::FindFace
1153 (TopoDS_Shape& theResult,
1154 const TopoDS_Shape& V1,
1155 const TopoDS_Shape& V2,
1156 const TopoDS_Shape& V3,
1157 const TopoDS_Shape& V4,
1158 const TopTools_IndexedDataMapOfShapeListOfShape& MVF,
1159 const Standard_Boolean findAll)
1161 Standard_Integer isFound = Standard_False;
1163 const TopTools_ListOfShape& aFacesOfV1 = MVF.FindFromKey(V1);
1164 const TopTools_ListOfShape& aFacesOfV2 = MVF.FindFromKey(V2);
1165 const TopTools_ListOfShape& aFacesOfV3 = MVF.FindFromKey(V3);
1166 const TopTools_ListOfShape& aFacesOfV4 = MVF.FindFromKey(V4);
1168 TopTools_ListIteratorOfListOfShape it1 (aFacesOfV1);
1169 for (; it1.More(); it1.Next()) {
1170 TopTools_ListIteratorOfListOfShape it2 (aFacesOfV2);
1171 for (; it2.More(); it2.Next()) {
1172 if (it1.Value().IsSame(it2.Value())) {
1173 TopTools_ListIteratorOfListOfShape it3 (aFacesOfV3);
1174 for (; it3.More(); it3.Next()) {
1175 if (it1.Value().IsSame(it3.Value())) {
1176 TopTools_ListIteratorOfListOfShape it4 (aFacesOfV4);
1177 for (; it4.More(); it4.Next()) {
1178 if (it1.Value().IsSame(it4.Value())) {
1180 theResult = it1.Value();
1181 if (!findAll) return isFound;
1193 //=======================================================================
1194 //function : MakeFace
1196 //=======================================================================
1197 void GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire& theWire,
1198 const Standard_Boolean isPlanarWanted,
1199 TopoDS_Shape& theResult)
1201 // try to build face on plane or on any surface under the edges of the wire
1202 BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted);
1204 theResult = MK.Shape();
1208 if (!isPlanarWanted) {
1209 // try to construct filling surface
1210 BRepOffsetAPI_MakeFilling MF;
1212 Standard_Integer nbEdges = 0;
1213 BRepTools_WireExplorer aWE (theWire);
1214 for (; aWE.More(); aWE.Next(), nbEdges++) {
1215 MF.Add(TopoDS::Edge(aWE.Current()), GeomAbs_C0);
1220 // Result of filling
1221 TopoDS_Shape aFace = MF.Shape();
1223 // 12.04.2006 for PAL12149 begin
1224 Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(aFace));
1225 BRepBuilderAPI_MakeFace MK1 (aGS, theWire);
1227 TopoDS_Shape aFace1 = MK1.Shape();
1229 BRepCheck_Analyzer ana (aFace1, false);
1230 if (!ana.IsValid()) {
1231 TopoDS_Shape aFace2;
1232 ShHealOper_ShapeProcess aHealer;
1233 aHealer.Perform(aFace1, aFace2);
1234 if (aHealer.isDone())
1238 // 12.04.2006 for PAL12149 end
1240 if (theResult.IsNull()) { // try to deal with pure result of filling
1242 Standard_Real aTol = MF.G0Error();
1244 TColgp_Array1OfPnt aPnts (1,nbEdges); // points of the given wire
1245 BRepTools_WireExplorer aWE1 (theWire);
1246 Standard_Integer vi = 1;
1247 for (; aWE1.More() && vi <= nbEdges; aWE1.Next(), vi++) {
1248 aPnts(vi) = BRep_Tool::Pnt(TopoDS::Vertex(aWE1.CurrentVertex()));
1251 // Find maximum deviation in vertices
1252 TopExp_Explorer exp (aFace, TopAbs_VERTEX);
1253 TopTools_MapOfShape mapShape;
1254 for (; exp.More(); exp.Next()) {
1255 if (mapShape.Add(exp.Current())) {
1256 TopoDS_Vertex aV = TopoDS::Vertex(exp.Current());
1257 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
1258 gp_Pnt aP = BRep_Tool::Pnt(aV);
1259 Standard_Real min_dist = aP.Distance(aPnts(1));
1260 for (vi = 2; vi <= nbEdges; vi++) {
1261 min_dist = Min(min_dist, aP.Distance(aPnts(vi)));
1263 aTol = Max(aTol, aTolV);
1264 aTol = Max(aTol, min_dist);
1268 if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) {
1269 (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol);
1275 // try to update wire tolerances to build a planar face
1277 #if 1 //(OCC_VERSION_MAJOR < 6) || (OCC_VERSION_MAJOR == 6 && OCC_VERSION_MINOR <= 1)
1279 Standard_Real aToleranceReached, aTol;
1280 BRepLib_FindSurface aFS;
1281 aFS.Init(theWire, -1., isPlanarWanted);
1282 aToleranceReached = aFS.ToleranceReached();
1283 aTol = aFS.Tolerance();
1286 aFS.Init(theWire, aToleranceReached, isPlanarWanted);
1287 if (!aFS.Found()) return;
1288 aToleranceReached = aFS.ToleranceReached();
1289 aTol = aFS.Tolerance();
1291 aTol = Max(1.2 * aToleranceReached, aTol);
1293 // Copy the wire, bacause it can be updated with very-very big tolerance here
1294 BRepBuilderAPI_Copy aMC (theWire);
1295 if (!aMC.IsDone()) return;
1296 TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape());
1297 // Update tolerances to <aTol>
1299 for (TopExp_Explorer expE (aWire, TopAbs_EDGE); expE.More(); expE.Next()) {
1300 TopoDS_Edge anE = TopoDS::Edge(expE.Current());
1301 B.UpdateEdge(anE, aTol);
1303 for (TopExp_Explorer expV (aWire, TopAbs_VERTEX); expV.More(); expV.Next()) {
1304 TopoDS_Vertex aV = TopoDS::Vertex(expV.Current());
1305 B.UpdateVertex(aV, aTol);
1307 //BRepLib::UpdateTolerances(aWire);
1309 BRepBuilderAPI_MakeFace MK1 (aWire, isPlanarWanted);
1311 theResult = MK1.Shape();
1315 #else // After migration on OCCT version, containing PKV's fix. See bug 8293
1316 BRepLib_MakeFace aBMF;
1317 aBMF.Init(theWire, isPlanarWanted, Standard_True);
1318 if (aBMF.Error() == BRepLib_FaceDone) {
1319 theResult = aBMF.Shape();