0024624: Lost word in license statement in source files
[occt.git] / src / BOPAlgo / BOPAlgo_BuilderSolid.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 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//
973c2be1 7// This file is part of Open CASCADE Technology software library.
4e57c75e 8//
d5f74e42 9// This library is free software; you can redistribute it and/or modify it under
10// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 11// by the Free Software Foundation, with special exception defined in the file
12// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13// distribution for complete text of the license and disclaimer of any warranty.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 17
18#include <BOPAlgo_BuilderSolid.ixx>
682c9d06 19//
20#include <NCollection_List.hxx>
21#include <NCollection_DataMap.hxx>
22#include <NCollection_UBTreeFiller.hxx>
23//
4e57c75e 24#include <gp_Pnt2d.hxx>
25#include <gp_Pln.hxx>
26#include <gp_Vec.hxx>
27#include <gp_Dir.hxx>
28#include <gp_Pnt.hxx>
682c9d06 29//
30#include <TColStd_MapIntegerHasher.hxx>
31//
4e57c75e 32#include <Geom_Curve.hxx>
33#include <Geom_Surface.hxx>
34#include <Geom2d_Curve.hxx>
682c9d06 35//
4e57c75e 36#include <TopAbs.hxx>
682c9d06 37//
4e57c75e 38#include <TopoDS_Iterator.hxx>
39#include <TopoDS_Face.hxx>
40#include <TopoDS_Shape.hxx>
41#include <TopoDS_Shell.hxx>
42#include <TopoDS_Edge.hxx>
43#include <TopoDS_Solid.hxx>
44#include <TopoDS_Vertex.hxx>
45#include <TopoDS_Compound.hxx>
46
47#include <BRep_Builder.hxx>
48#include <BRep_Tool.hxx>
682c9d06 49//
4e57c75e 50#include <TopExp.hxx>
51#include <TopExp_Explorer.hxx>
52//
682c9d06 53#include <BRepBndLib.hxx>
54#include <BRepClass3d_SolidClassifier.hxx>
55//
4e57c75e 56#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
4e57c75e 57#include <BOPCol_ListOfShape.hxx>
58#include <BOPCol_MapOfOrientedShape.hxx>
4e57c75e 59#include <BOPCol_DataMapOfShapeShape.hxx>
60#include <BOPCol_DataMapOfShapeListOfShape.hxx>
4e57c75e 61#include <BOPCol_MapOfShape.hxx>
682c9d06 62#include <BOPCol_BoxBndTree.hxx>
63#include <BOPCol_ListOfInteger.hxx>
64//
65#include <BOPTools.hxx>
66#include <BOPTools_CoupleOfShape.hxx>
67#include <BOPTools_AlgoTools.hxx>
68//
69#include <BOPInt_Context.hxx>
70//
71#include <BOPAlgo_ShellSplitter.hxx>
4e57c75e 72
73static
74 Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
75 const BOPCol_IndexedMapOfShape& );
76static
77 Standard_Boolean IsHole(const TopoDS_Shape& ,
78 Handle(BOPInt_Context)& );
79static
80 Standard_Boolean IsInside(const TopoDS_Shape& ,
81 const TopoDS_Shape& ,
82 Handle(BOPInt_Context)& );
83static
84 void MakeInternalShells(const BOPCol_MapOfShape& ,
85 BOPCol_ListOfShape& );
86
682c9d06 87//=======================================================================
88//class : BOPAlgo_BuilderSolid_ShapeBox
89//purpose : Auxiliary class
90//=======================================================================
91class BOPAlgo_BuilderSolid_ShapeBox {
92 public:
93 BOPAlgo_BuilderSolid_ShapeBox() {
94 myIsHole=Standard_False;
95 };
96 //
97 ~BOPAlgo_BuilderSolid_ShapeBox() {
98 };
99 //
100 void SetShape(const TopoDS_Shape& aS) {
101 myShape=aS;
102 };
103 //
104 const TopoDS_Shape& Shape()const {
105 return myShape;
106 };
107 //
108 void SetBox(const Bnd_Box& aBox) {
109 myBox=aBox;
110 };
111 //
112 const Bnd_Box& Box()const {
113 return myBox;
114 };
115 //
116 void SetIsHole(const Standard_Boolean bFlag) {
117 myIsHole=bFlag;
118 };
119 //
120 Standard_Boolean IsHole()const {
121 return myIsHole;
122 };
123 //
124 protected:
125 Standard_Boolean myIsHole;
126 TopoDS_Shape myShape;
127 Bnd_Box myBox;
128};
129//
130typedef NCollection_DataMap\
131 <Standard_Integer, BOPAlgo_BuilderSolid_ShapeBox, TColStd_MapIntegerHasher> \
132 BOPAlgo_DataMapOfIntegerBSSB;
133//
134typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator \
135 BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
136//
4e57c75e 137//=======================================================================
138//function :
139//purpose :
140//=======================================================================
682c9d06 141BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
4e57c75e 142:
143 BOPAlgo_BuilderArea()
144{
145}
146//=======================================================================
147//function :
148//purpose :
149//=======================================================================
682c9d06 150BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
151 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 152:
153 BOPAlgo_BuilderArea(theAllocator)
154{
155}
156//=======================================================================
157//function : ~
158//purpose :
159//=======================================================================
30ecd5f8 160BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
4e57c75e 161{
162}
163//=======================================================================
30ecd5f8 164//function : SetSolid
165//purpose :
166//=======================================================================
167void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS)
168{
169 mySolid=aS;
170}
171//=======================================================================
172//function : Solid
173//purpose :
174//=======================================================================
175const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
176{
177 return mySolid;
178}
179//=======================================================================
4e57c75e 180//function : Perform
181//purpose :
182//=======================================================================
30ecd5f8 183void BOPAlgo_BuilderSolid::Perform()
4e57c75e 184{
185 myErrorStatus=0;
186 //
187 if (myContext.IsNull()) {
4e57c75e 188 myContext=new BOPInt_Context;
189 }
190 //
191 TopoDS_Compound aC;
192 BRep_Builder aBB;
193 BOPCol_ListIteratorOfListOfShape aIt;
194 //
195 aBB.MakeCompound(aC);
196 aIt.Initialize(myShapes);
197 for(; aIt.More(); aIt.Next()) {
198 const TopoDS_Shape& aF=aIt.Value();
199 aBB.Add(aC, aF);
200 }
201 //
202 //
203 PerformShapesToAvoid();
204 if (myErrorStatus) {
205 return;
206 }
207 //
208 PerformLoops();
209 if (myErrorStatus) {
210 return;
211 }
212 PerformAreas();
213 if (myErrorStatus) {
214 return;
215 }
216 PerformInternalShapes();
217 if (myErrorStatus) {
218 return;
219 }
220}
221//=======================================================================
222//function :PerformShapesToAvoid
223//purpose :
224//=======================================================================
30ecd5f8 225void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
4e57c75e 226{
227 Standard_Boolean bFound;
228 Standard_Integer i, iCnt, aNbE, aNbF;
229 TopAbs_Orientation aOrE;
230 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
231 BOPCol_ListIteratorOfListOfShape aIt;
232 //
233 myShapesToAvoid.Clear();
234 //
235 iCnt=0;
302f96fb 236 for(;;) {
4e57c75e 237 ++iCnt;
238 bFound=Standard_False;
239 //
240 // 1. MEF
241 aMEF.Clear();
242 aIt.Initialize (myShapes);
243 for (; aIt.More(); aIt.Next()) {
244 const TopoDS_Shape& aF=aIt.Value();
245 if (!myShapesToAvoid.Contains(aF)) {
246 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
247 }
4e57c75e 248 }
249 aNbE=aMEF.Extent();
250 //
251 // 2. myFacesToAvoid
252 for (i=1; i<=aNbE; ++i) {
253 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
254 if (BRep_Tool::Degenerated(aE)) {
255 continue;
256 }
257 //
258 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
259 aNbF=aLF.Extent();
260 if (!aNbF) {
261 continue;
262 }
263 //
264 aOrE=aE.Orientation();
265 //
266 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
267 if (aNbF==1) {
268 if (aOrE==TopAbs_INTERNAL) {
269 continue;
270 }
271 bFound=Standard_True;
272 myShapesToAvoid.Add(aF1);
273 }
274 else if (aNbF==2) {
275 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
276 if (aF2.IsSame(aF1)) {
277 if (BRep_Tool::IsClosed(aE, aF1)) {
278 continue;
279 }
280 //
281 if (aOrE==TopAbs_INTERNAL) {
282 continue;
283 }
284 //
285 bFound=Standard_True;
286 myShapesToAvoid.Add(aF1);
287 myShapesToAvoid.Add(aF2);
288 }
289 }
290 }// for (i=1; i<=aNbE; ++i) {
291 //
292 if (!bFound) {
293 break;
294 }
295 //
682c9d06 296 }//for(;;) {
4e57c75e 297}
298//=======================================================================
299//function : PerformLoops
300//purpose :
301//=======================================================================
30ecd5f8 302void BOPAlgo_BuilderSolid::PerformLoops()
4e57c75e 303{
682c9d06 304 Standard_Integer iErr;
305 BOPCol_ListIteratorOfListOfShape aIt;
4e57c75e 306 TopoDS_Iterator aItS;
4e57c75e 307 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
682c9d06 308 BOPAlgo_ShellSplitter aSSp;
309 //
310 myErrorStatus=0;
311 myLoops.Clear();
4e57c75e 312 //
313 // 1. Shells Usual
682c9d06 314 aIt.Initialize (myShapes);
315 for (; aIt.More(); aIt.Next()) {
316 const TopoDS_Shape& aF=aIt.Value();
317 if (!myShapesToAvoid.Contains(aF)) {
318 aSSp.AddStartElement(aF);
319 }
320 }
4e57c75e 321 //
682c9d06 322 aSSp.SetRunParallel(myRunParallel);
323 aSSp.Perform();
324 iErr=aSSp.ErrorStatus();
325 if (iErr) {
326 return;
4e57c75e 327 }
328 //
682c9d06 329 const BOPCol_ListOfShape& aLSh=aSSp.Shells();
330 aIt.Initialize (aLSh);
331 for (; aIt.More(); aIt.Next()) {
332 const TopoDS_Shape& aSh=aIt.Value();
333 myLoops.Append(aSh);
334 }
335 //=================================================
4e57c75e 336 //
682c9d06 337 // 2. Post Treatment
338 Standard_Integer aNbFA;
339 BRep_Builder aBB;
340 BOPCol_MapOfOrientedShape AddedFacesMap;
341 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
4e57c75e 342 BOPCol_MapOfOrientedShape aMP;
682c9d06 343 //
4e57c75e 344 // a. collect all edges that are in loops
345 aIt.Initialize (myLoops);
346 for (; aIt.More(); aIt.Next()) {
347 const TopoDS_Shape& aS=aIt.Value();
348 aItS.Initialize(aS);
349 for (; aItS.More(); aItS.Next()) {
350 const TopoDS_Shape& aF=aItS.Value();
351 aMP.Add(aF);
352 }
353 }
354 //
355 // b. collect all edges that are to avoid
356 aItM.Initialize(myShapesToAvoid);
357 for (; aItM.More(); aItM.Next()) {
358 const TopoDS_Shape& aF=aItM.Key();
359 aMP.Add(aF);
360 }
361 //
362 // c. add all edges that are not processed to myShapesToAvoid
363 aIt.Initialize (myShapes);
364 for (; aIt.More(); aIt.Next()) {
365 const TopoDS_Shape& aF=aIt.Value();
366 if (!aMP.Contains(aF)) {
367 myShapesToAvoid.Add(aF);
368 }
369 }
370 //=================================================
371 //
682c9d06 372 // 3.Internal Shells
4e57c75e 373 myLoopsInternal.Clear();
374 //
375 aEFMap.Clear();
376 AddedFacesMap.Clear();
377 //
682c9d06 378 aNbFA=myShapesToAvoid.Extent();
379 //
4e57c75e 380 aItM.Initialize(myShapesToAvoid);
381 for (; aItM.More(); aItM.Next()) {
382 const TopoDS_Shape& aFF=aItM.Key();
682c9d06 383 BOPTools::MapShapesAndAncestors(aFF,
384 TopAbs_EDGE, TopAbs_FACE,
385 aEFMap);
4e57c75e 386 }
387 //
388 aItM.Initialize(myShapesToAvoid);
389 for (; aItM.More(); aItM.Next()) {
390 const TopoDS_Shape& aFF=aItM.Key();
391 if (!AddedFacesMap.Add(aFF)) {
392 continue;
393 }
394 //
395 // make a new shell
396 TopoDS_Shell aShell;
397 aBB.MakeShell(aShell);
398 aBB.Add(aShell, aFF);
399 //
400 TopoDS_Iterator aItAddedF (aShell);
401 for (; aItAddedF.More(); aItAddedF.Next()) {
402 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
403 //
404 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
405 for (; aEdgeExp.More(); aEdgeExp.Next()) {
406 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
407 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
682c9d06 408 aIt.Initialize(aLF);
409 for (; aIt.More(); aIt.Next()) {
410 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
4e57c75e 411 if (AddedFacesMap.Add(aFL)){
412 aBB.Add(aShell, aFL);
413 }
414 }
415 }
416 }
417 myLoopsInternal.Append(aShell);
418 }
419}
420//=======================================================================
421//function : PerformAreas
422//purpose :
423//=======================================================================
30ecd5f8 424void BOPAlgo_BuilderSolid::PerformAreas()
4e57c75e 425{
682c9d06 426 Standard_Boolean bIsGrowth, bIsHole;
427 Standard_Integer k,aNbHoles;
4e57c75e 428 BRep_Builder aBB;
682c9d06 429 BOPCol_ListIteratorOfListOfShape aItLS;
4e57c75e 430 BOPCol_ListOfShape aNewSolids, aHoleShells;
431 BOPCol_DataMapOfShapeShape aInOutMap;
4e57c75e 432 BOPCol_IndexedMapOfShape aMHF;
682c9d06 433 BOPCol_ListIteratorOfListOfInteger aItLI;
434 BOPCol_BoxBndTreeSelector aSelector;
435 BOPCol_BoxBndTree aBBTree;
436 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
437 BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
438 BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
439 BOPCol_DataMapOfShapeListOfShape aMSH;
440 BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS;
441 BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
442 //
443 myErrorStatus=0;
4e57c75e 444 //
445 myAreas.Clear();
446 //
447 // Draft solids [aNewSolids]
682c9d06 448 aItLS.Initialize(myLoops);
449 for (k=0; aItLS.More(); aItLS.Next(), ++k) {
450 TopoDS_Solid aSolid;
451 Bnd_Box aBox;
452 BOPAlgo_BuilderSolid_ShapeBox aSB;
453 //
454 const TopoDS_Shape& aShell = aItLS.Value();
455 aSB.SetShape(aShell);
456 //
457 BRepBndLib::Add(aShell, aBox);
458 bIsHole=Standard_False;
4e57c75e 459 //
682c9d06 460 bIsGrowth=IsGrowthShell(aShell, aMHF);
461 if (bIsGrowth) {
4e57c75e 462 // make a growth solid from a shell
682c9d06 463 aBB.MakeSolid(aSolid);
464 aBB.Add (aSolid, aShell);
4e57c75e 465 //
682c9d06 466 aNewSolids.Append (aSolid);
467 aSB.SetShape(aSolid);
4e57c75e 468 }
469 else{
470 // check if a shell is a hole
4e57c75e 471 bIsHole=IsHole(aShell, myContext);
4e57c75e 472 if (bIsHole) {
473 aHoleShells.Append(aShell);
474 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
682c9d06 475 aSB.SetShape(aShell);
4e57c75e 476 }
477 else {
478 // make a growth solid from a shell
682c9d06 479 aBB.MakeSolid(aSolid);
480 aBB.Add (aSolid, aShell);
4e57c75e 481 //
682c9d06 482 aNewSolids.Append (aSolid);
483 aSB.SetShape(aSolid);
4e57c75e 484 }
485 }
682c9d06 486 //
487 aSB.SetBox(aBox);
488 aSB.SetIsHole(bIsHole);
489 aDMISB.Bind(k, aSB);
490 }
491 //
492 // 2. Prepare TreeFiller
493 aItDMISB.Initialize(aDMISB);
494 for (; aItDMISB.More(); aItDMISB.Next()) {
495 k=aItDMISB.Key();
496 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
497 //
498 bIsHole=aSB.IsHole();
499 if (bIsHole) {
500 const Bnd_Box& aBox=aSB.Box();
501 aTreeFiller.Add(k, aBox);
502 }
4e57c75e 503 }
504 //
682c9d06 505 // 3. Shake TreeFiller
506 aTreeFiller.Fill();
507 //
508 // 4. Find outer growth shell that is most close
509 // to each hole shell
510 aItDMISB.Initialize(aDMISB);
511 for (; aItDMISB.More(); aItDMISB.Next()) {
512 k=aItDMISB.Key();
513 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
514 bIsHole=aSB.IsHole();
515 if (bIsHole) {
516 continue;
517 }
518 //
519 const TopoDS_Shape aSolid=aSB.Shape();
520 const Bnd_Box& aBoxSolid=aSB.Box();
4e57c75e 521 //
682c9d06 522 aSelector.Clear();
523 aSelector.SetBox(aBoxSolid);
524 //
525 aNbHoles=aBBTree.Select(aSelector);
526 //
527 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
528 //
529 aItLI.Initialize(aLI);
530 for (; aItLI.More(); aItLI.Next()) {
531 k=aItLI.Value();
532 const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
533 const TopoDS_Shape& aHole=aSBk.Shape();
4e57c75e 534 //
535 if (!IsInside(aHole, aSolid, myContext)){
536 continue;
537 }
538 //
682c9d06 539 if (aInOutMap.IsBound (aHole)){
540 const TopoDS_Shape& aHole2=aInOutMap(aHole);
541 if (IsInside(aHole, aHole2, myContext)) {
4e57c75e 542 aInOutMap.UnBind(aHole);
543 aInOutMap.Bind (aHole, aSolid);
544 }
545 }
546 else{
682c9d06 547 aInOutMap.Bind(aHole, aSolid);
4e57c75e 548 }
549 }
682c9d06 550 }//for (; aItDMISB.More(); aItDMISB.Next()) {
551 //
552 // 5. Map [Solid/Holes] -> aMSH
553 aItDMSS.Initialize(aInOutMap);
554 for (; aItDMSS.More(); aItDMSS.Next()) {
555 const TopoDS_Shape& aHole=aItDMSS.Key();
556 const TopoDS_Shape& aSolid=aItDMSS.Value();
4e57c75e 557 //
682c9d06 558 if (aMSH.IsBound(aSolid)) {
559 BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
560 aLH.Append(aHole);
561 }
562 else {
563 BOPCol_ListOfShape aLH;
564 aLH.Append(aHole);
565 aMSH.Bind(aSolid, aLH);
4e57c75e 566 }
682c9d06 567 }
4e57c75e 568 //
682c9d06 569 // 6. Add aHoles to Solids
4e57c75e 570 aItMSH.Initialize(aMSH);
571 for (; aItMSH.More(); aItMSH.Next()) {
572 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
573 //
574 const BOPCol_ListOfShape& aLH=aItMSH.Value();
682c9d06 575 aItLS.Initialize(aLH);
576 for (; aItLS.More(); aItLS.Next()) {
577 const TopoDS_Shape& aHole = aItLS.Value();
4e57c75e 578 aBB.Add (aSolid, aHole);
579 }
580 //
581 // update classifier
682c9d06 582 BRepClass3d_SolidClassifier& aSC=
583 myContext->SolidClassifier(aSolid);
4e57c75e 584 aSC.Load(aSolid);
585 //
586 }
587 //
682c9d06 588 // 7. These aNewSolids are draft solids that
4e57c75e 589 // do not contain any internal shapes
682c9d06 590 aItLS.Initialize(aNewSolids);
591 for ( ; aItLS.More(); aItLS.Next()) {
592 const TopoDS_Shape& aSx=aItLS.Value();
4e57c75e 593 myAreas.Append(aSx);
594 }
4e57c75e 595 // Add holes that outside the solids to myAreas
682c9d06 596 aItLS.Initialize(aHoleShells);
597 for (; aItLS.More(); aItLS.Next()) {
598 const TopoDS_Shape& aHole = aItLS.Value();
4e57c75e 599 if (!aInOutMap.IsBound(aHole)){
600 TopoDS_Solid aSolid;
682c9d06 601 //
4e57c75e 602 aBB.MakeSolid(aSolid);
603 aBB.Add (aSolid, aHole);
604 //
605 myAreas.Append(aSolid);
606 }
607 }
608}
609//=======================================================================
610//function : PerformInternalShapes
611//purpose :
612//=======================================================================
30ecd5f8 613void BOPAlgo_BuilderSolid::PerformInternalShapes()
4e57c75e 614{
615 myErrorStatus=0;
616 //
617 Standard_Integer aNbFI=myLoopsInternal.Extent();
618 if (!aNbFI) {// nothing to do
619 return;
620 }
621 //
622 BRep_Builder aBB;
623 TopoDS_Iterator aIt;
624 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
625 BOPCol_MapIteratorOfMapOfShape aItMF;
626 //
627 BOPCol_MapOfShape aMF, aMFP, aMFx;
628 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
629 BOPCol_ListOfShape aLSI;
630 //
631 // 1. All internal faces
632 aShellIt.Initialize(myLoopsInternal);
633 for (; aShellIt.More(); aShellIt.Next()) {
634 const TopoDS_Shape& aShell=aShellIt.Value();
635 aIt.Initialize(aShell);
636 for (; aIt.More(); aIt.Next()) {
637 const TopoDS_Shape& aF=aIt.Value();
638 aMF.Add(aF);
639 }
640 }
641 aNbFI=aMF.Extent();
642 //
643 // 2 Process solids
644 aSolidIt.Initialize(myAreas);
645 for ( ; aSolidIt.More(); aSolidIt.Next()) {
646 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
647 //
648 TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
649 for (; anExpSol.More(); anExpSol.Next()) {
650 const TopoDS_Shape& aF = anExpSol.Current();
651 TopoDS_Shape aFF=aF;
652 //
653 aFF.Orientation(TopAbs_FORWARD);
654 aMFx.Add(aFF);
655 aFF.Orientation(TopAbs_REVERSED);
656 aMFx.Add(aFF);
657 }
658 aMEF.Clear();
682c9d06 659 BOPTools::MapShapesAndAncestors(aSolid,
660 TopAbs_EDGE, TopAbs_FACE,
661 aMEF);
4e57c75e 662 //
663 // 2.1 Separate faces to process aMFP
664 aMFP.Clear();
665 aItMF.Initialize(aMF);
666 for (; aItMF.More(); aItMF.Next()) {
667 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
668 if (!aMFx.Contains(aF)) {
682c9d06 669 if (BOPTools_AlgoTools::IsInternalFace(aF,
670 aSolid,
671 aMEF,
672 1.e-14,
673 myContext)) {
4e57c75e 674 aMFP.Add(aF);
675 }
676 }
677 }
678 aMFx.Clear();
679 //
680 // 2.2 Make Internal Shells
681 aLSI.Clear();
682 MakeInternalShells(aMFP, aLSI);
683 //
684 // 2.3 Add them to aSolid
685 aShellIt.Initialize(aLSI);
686 for (; aShellIt.More(); aShellIt.Next()) {
687 const TopoDS_Shape& aSI=aShellIt.Value();
688 aBB.Add (aSolid, aSI);
689 }
690 //
691 // 2.4 Remove faces aMFP from aMF
692 aItMF.Initialize(aMFP);
693 for (; aItMF.More(); aItMF.Next()) {
694 const TopoDS_Shape& aF=aItMF.Key();
695 aMF.Remove(aF);
696 }
697 //
698 aNbFI=aMF.Extent();
699 if (!aNbFI) {
700 break;
701 }
702 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
703 if (aNbFI) {
704 TopoDS_Solid aSolid;
705 aBB.MakeSolid(aSolid);
706 //
707 MakeInternalShells(aMF, aLSI);
708 aShellIt.Initialize(aLSI);
709 for (; aShellIt.More(); aShellIt.Next()) {
710 const TopoDS_Shape& aSI=aShellIt.Value();
711 aBB.Add (aSolid, aSI);
712 }
713 myAreas.Append(aSolid);
714 }
715}
716
717//=======================================================================
718//function : MakeInternalShells
719//purpose :
720//=======================================================================
721void MakeInternalShells(const BOPCol_MapOfShape& theMF,
722 BOPCol_ListOfShape& theShells)
723{
724 BOPCol_ListIteratorOfListOfShape aItF;
725 BRep_Builder aBB;
726 //
727 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
728 BOPCol_MapIteratorOfMapOfShape aItM;
729 BOPCol_MapOfShape aAddedFacesMap;
730 //
731 aItM.Initialize(theMF);
732 for (; aItM.More(); aItM.Next()) {
733 const TopoDS_Shape& aF=aItM.Key();
682c9d06 734 BOPTools::MapShapesAndAncestors(aF,
735 TopAbs_EDGE, TopAbs_FACE,
736 aMEF);
4e57c75e 737 }
738 //
739 aItM.Initialize(theMF);
740 for (; aItM.More(); aItM.Next()) {
741 TopoDS_Shape aFF=aItM.Key();
742 if (!aAddedFacesMap.Add(aFF)) {
743 continue;
744 }
745 //
746 // make a new shell
747 TopoDS_Shell aShell;
748 aBB.MakeShell(aShell);
749 aFF.Orientation(TopAbs_INTERNAL);
750 aBB.Add(aShell, aFF);
751 //
752 TopoDS_Iterator aItAddedF (aShell);
753 for (; aItAddedF.More(); aItAddedF.Next()) {
754 const TopoDS_Shape& aF =aItAddedF.Value();
755 //
756 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
757 for (; aEdgeExp.More(); aEdgeExp.Next()) {
758 const TopoDS_Shape& aE =aEdgeExp.Current();
759 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
760 aItF.Initialize(aLF);
761 for (; aItF.More(); aItF.Next()) {
762 TopoDS_Shape aFL=aItF.Value();
763 if (aAddedFacesMap.Add(aFL)){
764 aFL.Orientation(TopAbs_INTERNAL);
765 aBB.Add(aShell, aFL);
766 }
767 }
768 }
769 }
770 theShells.Append(aShell);
771 }
772}
773//=======================================================================
774//function : IsHole
775//purpose :
776//=======================================================================
777Standard_Boolean IsHole(const TopoDS_Shape& theS2,
778 Handle(BOPInt_Context)& theContext)
779{
780 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
781 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
782 //
783 aClsf.PerformInfinitePoint(::RealSmall());
784 //
785 return (aClsf.State()==TopAbs_IN);
786}
787//=======================================================================
788//function : IsInside
789//purpose :
790//=======================================================================
791Standard_Boolean IsInside(const TopoDS_Shape& theS1,
792 const TopoDS_Shape& theS2,
793 Handle(BOPInt_Context)& theContext)
794{
795 TopExp_Explorer aExp;
796 TopAbs_State aState;
797 //
798 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
799 //
800 aExp.Init(theS1, TopAbs_FACE);
801 if (!aExp.More()){
802 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
803 aClsf.PerformInfinitePoint(::RealSmall());
804 aState=aClsf.State();
805 }
806 else {
807 BOPCol_IndexedMapOfShape aBounds;
808 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
809 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
682c9d06 810 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14,
811 aBounds, theContext);
4e57c75e 812 }
813 return (aState==TopAbs_IN);
814}
815//=======================================================================
816//function : IsGrowthShell
817//purpose :
818//=======================================================================
819Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
820 const BOPCol_IndexedMapOfShape& theMHF)
821{
822 Standard_Boolean bRet;
823 TopoDS_Iterator aIt;
824 //
825 bRet=Standard_False;
826 if (theMHF.Extent()) {
827 aIt.Initialize(theShell);
828 for(; aIt.More(); aIt.Next()) {
829 const TopoDS_Shape& aF=aIt.Value();
830 if (theMHF.Contains(aF)) {
831 return !bRet;
832 }
833 }
834 }
835 return bRet;
836}