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