0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BOPAlgo / BOPAlgo_BuilderFace.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
db8e4b9a 2// Copyright (c) 2010-2012 OPEN CASCADE SAS
4e57c75e 3// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6//
4e57c75e 7//
d5f74e42 8// This file is part of Open CASCADE Technology software library.
4e57c75e 9//
d5f74e42 10// This library is free software; you can redistribute it and/or modify it under
11// the terms of the GNU Lesser General Public License version 2.1 as published
12// by the Free Software Foundation, with special exception defined in the file
13// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
14// distribution for complete text of the license and disclaimer of any warranty.
15//
16// Alternatively, this file may be used under the terms of Open CASCADE
17// commercial license or contractual agreement.
4e57c75e 18
42cf5bc1 19#include <Bnd_Box.hxx>
20#include <BOPAlgo_BuilderFace.hxx>
21#include <BOPAlgo_WireEdgeSet.hxx>
22#include <BOPAlgo_WireSplitter.hxx>
33ba8565 23#include <BOPAlgo_Alerts.hxx>
42cf5bc1 24#include <BOPCol_Box2DBndTree.hxx>
25#include <BOPCol_DataMapOfShapeListOfShape.hxx>
26#include <BOPCol_DataMapOfShapeShape.hxx>
27#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
28#include <BOPCol_ListOfShape.hxx>
29#include <BOPCol_MapOfShape.hxx>
319da2e4 30#include <BOPCol_MapOfOrientedShape.hxx>
42cf5bc1 31#include <BOPTools.hxx>
32#include <BOPTools_AlgoTools.hxx>
33#include <BOPTools_AlgoTools2D.hxx>
34#include <BRep_Builder.hxx>
35#include <BRep_Tool.hxx>
36#include <BRepBndLib.hxx>
37#include <BRepTools.hxx>
38#include <Geom_Surface.hxx>
4e57c75e 39#include <gp_Dir.hxx>
42cf5bc1 40#include <gp_Pln.hxx>
4e57c75e 41#include <gp_Pnt.hxx>
42cf5bc1 42#include <gp_Pnt2d.hxx>
43#include <gp_Vec.hxx>
44#include <IntTools_Context.hxx>
45#include <IntTools_FClass2d.hxx>
46#include <NCollection_DataMap.hxx>
47#include <NCollection_UBTreeFiller.hxx>
48#include <TColStd_MapIntegerHasher.hxx>
4e57c75e 49#include <TopAbs.hxx>
42cf5bc1 50#include <TopExp.hxx>
51#include <TopExp_Explorer.hxx>
4e57c75e 52#include <TopLoc_Location.hxx>
42cf5bc1 53#include <TopoDS_Edge.hxx>
4e57c75e 54#include <TopoDS_Face.hxx>
42cf5bc1 55#include <TopoDS_Iterator.hxx>
4e57c75e 56#include <TopoDS_Shape.hxx>
4e57c75e 57#include <TopoDS_Vertex.hxx>
42cf5bc1 58#include <TopoDS_Wire.hxx>
59
60//
4e57c75e 61static
62 Standard_Boolean IsGrowthWire(const TopoDS_Shape& ,
63 const BOPCol_IndexedMapOfShape& );
64
65static
66 Standard_Boolean IsInside(const TopoDS_Shape& ,
67 const TopoDS_Shape& ,
1e143abb 68 Handle(IntTools_Context)& );
4e57c75e 69static
319da2e4 70 void MakeInternalWires(const BOPCol_IndexedMapOfShape& ,
4e57c75e 71 BOPCol_ListOfShape& );
db8e4b9a 72static
73 void GetWire(const TopoDS_Shape& ,
1e143abb 74 TopoDS_Shape& );
db8e4b9a 75//
36f4947b 76
db8e4b9a 77//
78//=======================================================================
79//class : BOPAlgo_ShapeBox2D
80//purpose : Auxiliary class
81//=======================================================================
82class BOPAlgo_ShapeBox2D {
83 public:
84 BOPAlgo_ShapeBox2D() {
85 myIsHole=Standard_False;
86 };
87 //
88 ~BOPAlgo_ShapeBox2D() {
89 };
90 //
91 void SetShape(const TopoDS_Shape& aS) {
92 myShape=aS;
93 };
94 //
95 const TopoDS_Shape& Shape()const {
96 return myShape;
97 };
98 //
99 void SetBox2D(const Bnd_Box2d& aBox2D) {
100 myBox2D=aBox2D;
101 };
102 //
103 const Bnd_Box2d& Box2D()const {
104 return myBox2D;
105 };
106 //
107 void SetIsHole(const Standard_Boolean bFlag) {
108 myIsHole=bFlag;
109 };
110 //
111 Standard_Boolean IsHole()const {
112 return myIsHole;
113 };
114 //
115 protected:
116 Standard_Boolean myIsHole;
117 TopoDS_Shape myShape;
118 Bnd_Box2d myBox2D;
119};
120//
b858a698 121typedef NCollection_IndexedDataMap
122 <Standard_Integer,
123 BOPAlgo_ShapeBox2D,
124 TColStd_MapIntegerHasher> BOPAlgo_IndexedDataMapOfIntegerShapeBox2D;
125
126typedef NCollection_IndexedDataMap
127 <TopoDS_Shape,
128 TopoDS_Shape,
129 TopTools_ShapeMapHasher> BOPCol_IndexedDataMapOfShapeShape;
db8e4b9a 130//
4e57c75e 131//=======================================================================
132//function :
133//purpose :
134//=======================================================================
db8e4b9a 135BOPAlgo_BuilderFace::BOPAlgo_BuilderFace()
4e57c75e 136:
137 BOPAlgo_BuilderArea()
138{
acccace3 139 myOrientation=TopAbs_EXTERNAL;
4e57c75e 140}
141//=======================================================================
142//function :
143//purpose :
144//=======================================================================
db8e4b9a 145BOPAlgo_BuilderFace::BOPAlgo_BuilderFace
146 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 147:
148 BOPAlgo_BuilderArea(theAllocator)
acccace3 149{
150 myOrientation=TopAbs_EXTERNAL;
4e57c75e 151}
152//=======================================================================
153//function : ~
154//purpose :
155//=======================================================================
156 BOPAlgo_BuilderFace::~BOPAlgo_BuilderFace()
157{
158}
159//=======================================================================
160//function : SetFace
161//purpose :
162//=======================================================================
db8e4b9a 163void BOPAlgo_BuilderFace::SetFace(const TopoDS_Face& theFace)
4e57c75e 164{
acccace3 165 myOrientation=theFace.Orientation();
4e57c75e 166 myFace=theFace;
acccace3 167 myFace.Orientation(TopAbs_FORWARD);
168}
169//=======================================================================
170//function : Orientation
171//purpose :
172//=======================================================================
173TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
174{
175 return myOrientation;
4e57c75e 176}
177//=======================================================================
178//function : Face
179//purpose :
180//=======================================================================
db8e4b9a 181const TopoDS_Face& BOPAlgo_BuilderFace::Face()const
4e57c75e 182{
183 return myFace;
184}
185//=======================================================================
186//function : CheckData
187//purpose :
188//=======================================================================
db8e4b9a 189void BOPAlgo_BuilderFace::CheckData()
4e57c75e 190{
4e57c75e 191 if (myFace.IsNull()) {
33ba8565 192 AddError (new BOPAlgo_AlertNullInputShapes);
4e57c75e 193 return;
194 }
db8e4b9a 195 if (myContext.IsNull()) {
1e143abb 196 myContext = new IntTools_Context;
db8e4b9a 197 }
4e57c75e 198}
199//=======================================================================
200//function : Perform
201//purpose :
202//=======================================================================
db8e4b9a 203void BOPAlgo_BuilderFace::Perform()
4e57c75e 204{
33ba8565 205 GetReport()->Clear();
4e57c75e 206 //
207 CheckData();
33ba8565 208 if (HasErrors()) {
4e57c75e 209 return;
210 }
211 //
36f4947b 212 UserBreak();
213 //
4e57c75e 214 PerformShapesToAvoid();
33ba8565 215 if (HasErrors()) {
4e57c75e 216 return;
217 }
218 //
36f4947b 219 UserBreak();
220 //
4e57c75e 221 PerformLoops();
33ba8565 222 if (HasErrors()) {
4e57c75e 223 return;
224 }
225 //
36f4947b 226 UserBreak();
227 //
4e57c75e 228 PerformAreas();
33ba8565 229 if (HasErrors()) {
4e57c75e 230 return;
231 }
232 //
36f4947b 233 UserBreak();
234 //
4e57c75e 235 PerformInternalShapes();
33ba8565 236 if (HasErrors()) {
4e57c75e 237 return;
238 }
239}
240//=======================================================================
241//function :PerformShapesToAvoid
242//purpose :
243//=======================================================================
db8e4b9a 244void BOPAlgo_BuilderFace::PerformShapesToAvoid()
4e57c75e 245{
246 Standard_Boolean bFound;
247 Standard_Integer i, iCnt, aNbV, aNbE;
248 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
249 BOPCol_ListIteratorOfListOfShape aIt;
250 //
251 myShapesToAvoid.Clear();
252 //
253 iCnt=0;
302f96fb 254 for(;;) {
4e57c75e 255 ++iCnt;
256 bFound=Standard_False;
257 //
258 // 1. MEF
259 aMVE.Clear();
260 aIt.Initialize (myShapes);
261 for (; aIt.More(); aIt.Next()) {
262 const TopoDS_Shape& aE=aIt.Value();
263 if (!myShapesToAvoid.Contains(aE)) {
264 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
265 }
4e57c75e 266 }
267 aNbV=aMVE.Extent();
268 //
269 // 2. myEdgesToAvoid
270 for (i=1; i<=aNbV; ++i) {
271 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aMVE.FindKey(i)));
272 //
273 BOPCol_ListOfShape& aLE=aMVE.ChangeFromKey(aV);
274 aNbE=aLE.Extent();
275 if (!aNbE) {
276 continue;
277 }
278 //
279 const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aLE.First()));
280 if (aNbE==1) {
281 if (BRep_Tool::Degenerated(aE1)) {
282 continue;
283 }
284 if (aV.Orientation()==TopAbs_INTERNAL) {
285 continue;
286 }
287 bFound=Standard_True;
288 myShapesToAvoid.Add(aE1);
289 }
290 else if (aNbE==2) {
291 const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aLE.Last()));
292 if (aE2.IsSame(aE1)) {
293 TopoDS_Vertex aV1x, aV2x;
294 //
295 TopExp::Vertices(aE1, aV1x, aV2x);
296 if (aV1x.IsSame(aV2x)) {
297 continue;
298 }
299 bFound=Standard_True;
300 myShapesToAvoid.Add(aE1);
301 myShapesToAvoid.Add(aE2);
302 }
303 }
304 }// for (i=1; i<=aNbE; ++i) {
305 //
306 if (!bFound) {
307 break;
308 }
309 //
310 }//while (1)
311 //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt);
312}
313//=======================================================================
314//function : PerformLoops
315//purpose :
316//=======================================================================
db8e4b9a 317void BOPAlgo_BuilderFace::PerformLoops()
4e57c75e 318{
4e57c75e 319 Standard_Boolean bFlag;
33ba8565 320 Standard_Integer i, aNbEA;
4e57c75e 321 BOPCol_ListIteratorOfListOfShape aIt;
4e57c75e 322 BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
323 BOPCol_MapOfOrientedShape aMAdded;
324 TopoDS_Iterator aItW;
325 BRep_Builder aBB;
326 BOPAlgo_WireEdgeSet aWES(myAllocator);
327 BOPAlgo_WireSplitter aWSp(myAllocator);
328 //
329 // 1.
330 myLoops.Clear();
331 aWES.SetFace(myFace);
332 //
333 aIt.Initialize(myShapes);
334 for (; aIt.More(); aIt.Next()) {
335 const TopoDS_Shape& aE=aIt.Value();
336 if (!myShapesToAvoid.Contains(aE)) {
337 aWES.AddStartElement(aE);
338 }
339 }
340 //
341 aWSp.SetWES(aWES);
db8e4b9a 342 aWSp.SetRunParallel(myRunParallel);
51db0179 343 aWSp.SetContext(myContext);
4e57c75e 344 aWSp.Perform();
33ba8565 345 if (aWSp.HasErrors()) {
4e57c75e 346 return;
347 }
348 //
349 const BOPCol_ListOfShape& aLW=aWES.Shapes();
350 aIt.Initialize (aLW);
351 for (; aIt.More(); aIt.Next()) {
352 const TopoDS_Shape& aW=aIt.Value();
353 myLoops.Append(aW);
354 }
355 // Post Treatment
356 BOPCol_MapOfOrientedShape aMEP;
357 //
358 // a. collect all edges that are in loops
359 aIt.Initialize (myLoops);
360 for (; aIt.More(); aIt.Next()) {
361 const TopoDS_Shape& aW=aIt.Value();
362 aItW.Initialize(aW);
363 for (; aItW.More(); aItW.Next()) {
364 const TopoDS_Shape& aE=aItW.Value();
365 aMEP.Add(aE);
366 }
367 }
368 //
369 // b. collect all edges that are to avoid
319da2e4 370 aNbEA = myShapesToAvoid.Extent();
371 for (i = 1; i <= aNbEA; ++i) {
372 const TopoDS_Shape& aE = myShapesToAvoid(i);
4e57c75e 373 aMEP.Add(aE);
374 }
375 //
376 // c. add all edges that are not processed to myShapesToAvoid
377 aIt.Initialize (myShapes);
378 for (; aIt.More(); aIt.Next()) {
379 const TopoDS_Shape& aE=aIt.Value();
380 if (!aMEP.Contains(aE)) {
381 myShapesToAvoid.Add(aE);
382 }
383 }
384 //
385 // 2. Internal Wires
386 myLoopsInternal.Clear();
387 //
319da2e4 388 aNbEA = myShapesToAvoid.Extent();
389 for (i = 1; i <= aNbEA; ++i) {
390 const TopoDS_Shape& aEE = myShapesToAvoid(i);
1e143abb 391 BOPTools::MapShapesAndAncestors(aEE,
392 TopAbs_VERTEX,
393 TopAbs_EDGE,
394 aVEMap);
4e57c75e 395 }
396 //
397 bFlag=Standard_True;
319da2e4 398 for (i = 1; (i <= aNbEA) && bFlag; ++i) {
399 const TopoDS_Shape& aEE = myShapesToAvoid(i);
4e57c75e 400 if (!aMAdded.Add(aEE)) {
401 continue;
402 }
403 //
404 // make new wire
405 TopoDS_Wire aW;
406 aBB.MakeWire(aW);
407 aBB.Add(aW, aEE);
408 //
409 aItW.Initialize(aW);
410 for (; aItW.More()&&bFlag; aItW.Next()) {
411 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
412 //
413 TopoDS_Iterator aItE(aE);
414 for (; aItE.More()&&bFlag; aItE.Next()) {
415 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aItE.Value()));
416 const BOPCol_ListOfShape& aLE=aVEMap.FindFromKey(aV);
417 aIt.Initialize(aLE);
418 for (; aIt.More()&&bFlag; aIt.Next()) {
419 const TopoDS_Shape& aEx=aIt.Value();
420 if (aMAdded.Add(aEx)) {
421 aBB.Add(aW, aEx);
422 if(aMAdded.Extent()==aNbEA) {
423 bFlag=!bFlag;
424 }
425 }
426 }//for (; aIt.More(); aIt.Next()) {
427 }//for (; aItE.More(); aItE.Next()) {
428 }//for (; aItW.More(); aItW.Next()) {
c5d8782c 429 aW.Closed(BRep_Tool::IsClosed(aW));
4e57c75e 430 myLoopsInternal.Append(aW);
319da2e4 431 }//for (i = 1; (i <= aNbEA) && bFlag; ++i) {
4e57c75e 432}
433//=======================================================================
434//function : PerformAreas
435//purpose :
436//=======================================================================
db8e4b9a 437void BOPAlgo_BuilderFace::PerformAreas()
4e57c75e 438{
4e57c75e 439 Standard_Boolean bIsGrowth, bIsHole;
d2d9e8dc 440 Standard_Integer k, aNbS, aNbHoles, aNbDMISB, m, aNbMSH, aNbInOutMap;
4e57c75e 441 Standard_Real aTol;
db8e4b9a 442 TopLoc_Location aLoc;
443 Handle(Geom_Surface) aS;
444 BRep_Builder aBB;
445 TopoDS_Face aFace;
db8e4b9a 446 BOPCol_ListIteratorOfListOfInteger aItLI;
447 BOPCol_IndexedMapOfShape aMHE;
db8e4b9a 448 BOPCol_ListIteratorOfListOfShape aIt1;
b858a698 449 BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
450 BOPCol_IndexedDataMapOfShapeShape aInOutMap;
451 BOPAlgo_IndexedDataMapOfIntegerShapeBox2D aDMISB(100);
db8e4b9a 452 //
453 BOPCol_Box2DBndTreeSelector aSelector;
454 BOPCol_Box2DBndTree aBBTree;
455 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
456 //
d2d9e8dc 457 aNbHoles=0;
4e57c75e 458 //
459 aTol=BRep_Tool::Tolerance(myFace);
460 aS=BRep_Tool::Surface(myFace, aLoc);
461 //
462 myAreas.Clear();
463 //
f47b8d2b 464 if (myLoops.IsEmpty()) {
465 if (myContext->IsInfiniteFace(myFace)) {
466 aBB.MakeFace(aFace, aS, aLoc, aTol);
467 if (BRep_Tool::NaturalRestriction(myFace)) {
468 aBB.NaturalRestriction(aFace, Standard_True);
469 }
470 myAreas.Append(aFace);
471 }
472 return;
473 }
474 //
db8e4b9a 475 // 1. Growthes and Holes -> aDMISB: [Index/ShapeBox2D]
4e57c75e 476 aIt1.Initialize(myLoops);
db8e4b9a 477 for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
478 Bnd_Box2d aBox2D;
479 //
4e57c75e 480 const TopoDS_Shape& aWire=aIt1.Value();
481 //
db8e4b9a 482 aBB.MakeFace(aFace, aS, aLoc, aTol);
483 aBB.Add (aFace, aWire);
484 BRepTools::AddUVBounds(aFace, aBox2D);
485 //
4e57c75e 486 bIsGrowth=IsGrowthWire(aWire, aMHE);
487 if (bIsGrowth) {
db8e4b9a 488 bIsHole=Standard_False;
4e57c75e 489 }
490 else{
491 // check if a wire is a hole
4e57c75e 492 IntTools_FClass2d& aClsf=myContext->FClass2d(aFace);
493 aClsf.Init(aFace, aTol);
494 //
495 bIsHole=aClsf.IsHole();
4e57c75e 496 if (bIsHole) {
4e57c75e 497 BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
d2d9e8dc 498 //
499 bIsHole=Standard_True;
4e57c75e 500 }
501 else {
1e143abb 502 bIsHole=Standard_False;
4e57c75e 503 }
504 }
db8e4b9a 505 //
506 BOPAlgo_ShapeBox2D aSB2D;
507 //
508 aSB2D.SetShape(aFace);
509 aSB2D.SetBox2D(aBox2D);
510 aSB2D.SetIsHole(bIsHole);
511 //
b858a698 512 aDMISB.Add(k, aSB2D);
513 }// for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
db8e4b9a 514 //
515 // 2. Prepare TreeFiller
b858a698 516 aNbDMISB=aDMISB.Extent();
517 for (m=1; m<=aNbDMISB; ++m) {
518 k=aDMISB.FindKey(m);
519 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
db8e4b9a 520 //
521 bIsHole=aSB2D.IsHole();
522 if (bIsHole) {
523 const Bnd_Box2d& aBox2D=aSB2D.Box2D();
524 aTreeFiller.Add(k, aBox2D);
d2d9e8dc 525 ++aNbHoles;
db8e4b9a 526 }
4e57c75e 527 }
528 //
db8e4b9a 529 // 3. Shake TreeFiller
530 aTreeFiller.Fill();
531 //
532 // 4. Find outer growth shell that is most close
533 // to each hole shell
b858a698 534 for (m=1; m<=aNbDMISB; ++m) {
535 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
db8e4b9a 536 bIsHole=aSB2D.IsHole();
537 if (bIsHole) {
538 continue;
539 }
540 //
541 const Bnd_Box2d& aBox2DF=aSB2D.Box2D();
542 const TopoDS_Shape aF=aSB2D.Shape();
4e57c75e 543 //
db8e4b9a 544 aSelector.Clear();
545 aSelector.SetBox(aBox2DF);
546 //
d2d9e8dc 547 aNbS = aBBTree.Select(aSelector);
548 if (!aNbS) {
549 continue;
550 }
db8e4b9a 551 //
552 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
553 //
554 aItLI.Initialize(aLI);
555 for (; aItLI.More(); aItLI.Next()) {
556 k=aItLI.Value();
b858a698 557 const BOPAlgo_ShapeBox2D& aSB2Dk=aDMISB.FindFromKey(k);
db8e4b9a 558 const TopoDS_Shape& aHole=aSB2Dk.Shape();
4e57c75e 559 //
560 if (!IsInside(aHole, aF, myContext)){
561 continue;
562 }
563 //
b858a698 564 if (aInOutMap.Contains(aHole)){
565 TopoDS_Shape& aF2=aInOutMap.ChangeFromKey(aHole);
1e143abb 566 if (IsInside(aF, aF2, myContext)) {
b858a698 567 aF2=aF;
4e57c75e 568 }
569 }
570 else{
b858a698 571 aInOutMap.Add(aHole, aF);
4e57c75e 572 }
573 }
b858a698 574 }// for (m=1; m<=aNbDMISB; ++m)
db8e4b9a 575 //
d2d9e8dc 576 // 5.1 Map [Face/Holes] -> aMSH
b858a698 577 aNbInOutMap=aInOutMap.Extent();
578 for (m=1; m<=aNbInOutMap; ++m) {
579 const TopoDS_Shape& aHole=aInOutMap.FindKey(m);
580 const TopoDS_Shape& aF=aInOutMap.FindFromIndex(m);
4e57c75e 581 //
b858a698 582 if (aMSH.Contains(aF)) {
583 BOPCol_ListOfShape& aLH=aMSH.ChangeFromKey(aF);
db8e4b9a 584 aLH.Append(aHole);
4e57c75e 585 }
db8e4b9a 586 else {
587 BOPCol_ListOfShape aLH;
588 aLH.Append(aHole);
b858a698 589 aMSH.Add(aF, aLH);
db8e4b9a 590 }
591 }
4e57c75e 592 //
d2d9e8dc 593 // 5.2. Add unused holes to the original face
594 if (aNbHoles != aNbInOutMap) {
595 Bnd_Box aBoxF;
596 BRepBndLib::Add(myFace, aBoxF);
597 if (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
598 aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
599 aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax()) {
600 //
601 BOPCol_ListOfShape anUnUsedHoles;
602 for (m = 1; m <= aNbDMISB; ++m) {
603 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
604 if (aSB2D.IsHole()) {
605 const TopoDS_Shape& aHole = aSB2D.Shape();
606 if (!aInOutMap.Contains(aHole)) {
607 anUnUsedHoles.Append(aHole);
608 }
609 }
610 }
611 //
612 if (anUnUsedHoles.Extent()) {
d2d9e8dc 613 aBB.MakeFace(aFace, aS, aLoc, aTol);
614 aMSH.Add(aFace, anUnUsedHoles);
615 //
616 BOPAlgo_ShapeBox2D aSB2D;
617 //
618 aSB2D.SetShape(aFace);
619 aSB2D.SetIsHole(Standard_False);
620 //
621 aDMISB.Add(aNbDMISB, aSB2D);
622 ++aNbDMISB;
623 }
624 }
625 }
626 //
b858a698 627 // 6. Add aHoles to Faces
628 aNbMSH=aMSH.Extent();
629 for (m=1; m<=aNbMSH; ++m) {
630 TopoDS_Face aF=(*(TopoDS_Face *)(&aMSH.FindKey(m)));
631 const BOPCol_ListOfShape& aLH=aMSH.FindFromIndex(m);
4e57c75e 632 //
db8e4b9a 633 aIt1.Initialize(aLH);
634 for (; aIt1.More(); aIt1.Next()) {
635 TopoDS_Shape aWHole;
636 //
637 const TopoDS_Shape& aFHole=aIt1.Value();
638 GetWire(aFHole, aWHole);
639 aBB.Add (aF, aWHole);
4e57c75e 640 }
641 //
642 // update classifier
643 aTol=BRep_Tool::Tolerance(aF);
644 IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
645 aClsf.Init(aF, aTol);
646 }
647 //
db8e4b9a 648 // 7. Fill myAreas
649 // NB:These aNewFaces are draft faces that
650 // do not contain any internal shapes
b858a698 651 for (m=1; m<=aNbDMISB; ++m) {
652 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
db8e4b9a 653 bIsHole=aSB2D.IsHole();
654 if (!bIsHole) {
655 const TopoDS_Shape aF=aSB2D.Shape();
656 myAreas.Append(aF);
657 }
658 }
659}
660//=======================================================================
661//function : GetWire
662//purpose :
663//=======================================================================
664void GetWire(const TopoDS_Shape& aF, TopoDS_Shape& aW)
665{
666 TopoDS_Shape aWx;
667 TopoDS_Iterator aIt;
4e57c75e 668 //
db8e4b9a 669 aIt.Initialize(aF);
670 for (; aIt.More(); aIt.Next()) {
671 aW=aIt.Value();
4e57c75e 672 }
673}
674//=======================================================================
675//function : PerformInternalShapes
676//purpose :
677//=======================================================================
db8e4b9a 678void BOPAlgo_BuilderFace::PerformInternalShapes()
4e57c75e 679{
291fced1 680 if (myAvoidInternalShapes) {
681 return;
682 }
4e57c75e 683 //
684 Standard_Integer aNbWI=myLoopsInternal.Extent();
685 if (!aNbWI) {// nothing to do
686 return;
687 }
688 //
689 //Standard_Real aTol;
319da2e4 690 Standard_Integer i;
4e57c75e 691 BRep_Builder aBB;
692 BOPCol_ListIteratorOfListOfShape aIt1, aIt2;
693 TopoDS_Iterator aIt;
319da2e4 694 BOPCol_IndexedMapOfShape aME1, aME2, aMEP;
4e57c75e 695 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
696 BOPCol_ListOfShape aLSI;
697 //
698 // 1. All internal edges
699 aIt1.Initialize(myLoopsInternal);
700 for (; aIt1.More(); aIt1.Next()) {
701 const TopoDS_Shape& aWire=aIt1.Value();
702 aIt.Initialize(aWire);
703 for (; aIt.More(); aIt.Next()) {
704 const TopoDS_Shape& aE=aIt.Value();
319da2e4 705 aME1.Add(aE);
4e57c75e 706 }
707 }
4e57c75e 708 //
709 // 2 Process faces
710 aIt2.Initialize(myAreas);
711 for ( ; aIt2.More(); aIt2.Next()) {
712 TopoDS_Face& aF=(*(TopoDS_Face *)(&aIt2.Value()));
713 //
714 aMVE.Clear();
715 BOPTools::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
716 //
717 // 2.1 Separate faces to process aMEP
319da2e4 718 aME2.Clear();
4e57c75e 719 aMEP.Clear();
319da2e4 720 aNbWI = aME1.Extent();
721 for (i = 1; i <= aNbWI; ++i) {
722 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aME1(i)));
4e57c75e 723 if (IsInside(aE, aF, myContext)) {
724 aMEP.Add(aE);
725 }
319da2e4 726 else {
727 aME2.Add(aE);
728 }
4e57c75e 729 }
730 //
731 // 2.2 Make Internal Wires
732 aLSI.Clear();
733 MakeInternalWires(aMEP, aLSI);
734 //
735 // 2.3 Add them to aF
736 aIt1.Initialize(aLSI);
737 for (; aIt1.More(); aIt1.Next()) {
738 const TopoDS_Shape& aSI=aIt1.Value();
739 aBB.Add (aF, aSI);
740 }
741 //
742 // 2.4 Remove faces aMFP from aMF
319da2e4 743 aME1 = aME2;
4e57c75e 744 //
319da2e4 745 aNbWI = aME1.Extent();
4e57c75e 746 if (!aNbWI) {
747 break;
748 }
749 } //for ( ; aIt2.More(); aIt2.Next()) {
750}
751//=======================================================================
752//function : MakeInternalWires
753//purpose :
754//=======================================================================
319da2e4 755void MakeInternalWires(const BOPCol_IndexedMapOfShape& theME,
4e57c75e 756 BOPCol_ListOfShape& theWires)
757{
319da2e4 758 Standard_Integer i, aNbE;
4e57c75e 759 BOPCol_MapOfShape aAddedMap;
760 BOPCol_ListIteratorOfListOfShape aItE;
761 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
762 BRep_Builder aBB;
763 //
319da2e4 764 aNbE = theME.Extent();
765 for (i = 1; i <= aNbE; ++i) {
766 const TopoDS_Shape& aE = theME(i);
4e57c75e 767 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
768 }
769 //
319da2e4 770 for (i = 1; i <= aNbE; ++i) {
771 TopoDS_Shape aEE = theME(i);
4e57c75e 772 if (!aAddedMap.Add(aEE)) {
773 continue;
774 }
775 //
776 // make a new shell
777 TopoDS_Wire aW;
778 aBB.MakeWire(aW);
779 aEE.Orientation(TopAbs_INTERNAL);
780 aBB.Add(aW, aEE);
781 //
782 TopoDS_Iterator aItAdded (aW);
783 for (; aItAdded.More(); aItAdded.Next()) {
784 const TopoDS_Shape& aE =aItAdded.Value();
785 //
786 TopExp_Explorer aExp(aE, TopAbs_VERTEX);
787 for (; aExp.More(); aExp.Next()) {
788 const TopoDS_Shape& aV =aExp.Current();
789 const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aV);
790 aItE.Initialize(aLE);
791 for (; aItE.More(); aItE.Next()) {
792 TopoDS_Shape aEL=aItE.Value();
793 if (aAddedMap.Add(aEL)){
794 aEL.Orientation(TopAbs_INTERNAL);
795 aBB.Add(aW, aEL);
796 }
797 }
798 }
799 }
c5d8782c 800 aW.Closed(BRep_Tool::IsClosed(aW));
4e57c75e 801 theWires.Append(aW);
802 }
803}
804//=======================================================================
805//function : IsInside
806//purpose :
807//=======================================================================
808Standard_Boolean IsInside(const TopoDS_Shape& theHole,
809 const TopoDS_Shape& theF2,
1e143abb 810 Handle(IntTools_Context)& theContext)
4e57c75e 811{
812 Standard_Boolean bRet;
813 Standard_Real aT, aU, aV;
814
815 TopAbs_State aState;
816 TopExp_Explorer aExp;
817 BOPCol_IndexedMapOfShape aME2;
818 gp_Pnt2d aP2D;
819 //
820 bRet=Standard_False;
821 aState=TopAbs_UNKNOWN;
822 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&theF2));
823 //
824 BOPTools::MapShapes(aF2, TopAbs_EDGE, aME2);//AA
825 //
826 aExp.Init(theHole, TopAbs_EDGE);
827 if (aExp.More()) {
828 const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current()));
829 if (aME2.Contains(aE)) {
830 return bRet;
831 }
832 if (!BRep_Tool::Degenerated(aE)) {
833 //
834 aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
51db0179 835 BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV, theContext);
4e57c75e 836 aP2D.SetCoord(aU, aV);
837 //
838 IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
839 aState=aClsf.Perform(aP2D);
840 bRet=(aState==TopAbs_IN);
841 }
842 }
843 //
844 return bRet;
845}
846
847//=======================================================================
848//function : IsGrowthWire
849//purpose :
850//=======================================================================
851Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
852 const BOPCol_IndexedMapOfShape& theMHE)
853{
854 Standard_Boolean bRet;
855 TopoDS_Iterator aIt;
856 //
857 bRet=Standard_False;
858 if (theMHE.Extent()) {
859 aIt.Initialize(theWire);
860 for(; aIt.More(); aIt.Next()) {
861 const TopoDS_Shape& aE=aIt.Value();
862 if (theMHE.Contains(aE)) {
863 return !bRet;
864 }
865 }
866 }
867 return bRet;
868}