0025019: Command "bsection" in Test Harness with flag build pcurve on second shape...
[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//
1e143abb 69#include <IntTools_Context.hxx>
682c9d06 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& ,
1e143abb 78 Handle(IntTools_Context)& );
4e57c75e 79static
80 Standard_Boolean IsInside(const TopoDS_Shape& ,
81 const TopoDS_Shape& ,
1e143abb 82 Handle(IntTools_Context)& );
4e57c75e 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()) {
1e143abb 188 myContext=new IntTools_Context;
4e57c75e 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 //
36f4947b 202 UserBreak();
4e57c75e 203 //
204 PerformShapesToAvoid();
205 if (myErrorStatus) {
206 return;
207 }
208 //
36f4947b 209 UserBreak();
210 //
4e57c75e 211 PerformLoops();
212 if (myErrorStatus) {
213 return;
214 }
36f4947b 215 //
216 UserBreak();
217 //
4e57c75e 218 PerformAreas();
219 if (myErrorStatus) {
220 return;
221 }
36f4947b 222 //
223 UserBreak();
224 //
4e57c75e 225 PerformInternalShapes();
226 if (myErrorStatus) {
227 return;
228 }
229}
230//=======================================================================
231//function :PerformShapesToAvoid
232//purpose :
233//=======================================================================
30ecd5f8 234void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
4e57c75e 235{
236 Standard_Boolean bFound;
237 Standard_Integer i, iCnt, aNbE, aNbF;
238 TopAbs_Orientation aOrE;
239 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
240 BOPCol_ListIteratorOfListOfShape aIt;
241 //
242 myShapesToAvoid.Clear();
243 //
244 iCnt=0;
302f96fb 245 for(;;) {
4e57c75e 246 ++iCnt;
247 bFound=Standard_False;
248 //
249 // 1. MEF
250 aMEF.Clear();
251 aIt.Initialize (myShapes);
252 for (; aIt.More(); aIt.Next()) {
253 const TopoDS_Shape& aF=aIt.Value();
254 if (!myShapesToAvoid.Contains(aF)) {
255 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
256 }
4e57c75e 257 }
258 aNbE=aMEF.Extent();
259 //
260 // 2. myFacesToAvoid
261 for (i=1; i<=aNbE; ++i) {
262 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
263 if (BRep_Tool::Degenerated(aE)) {
264 continue;
265 }
266 //
267 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
268 aNbF=aLF.Extent();
269 if (!aNbF) {
270 continue;
271 }
272 //
273 aOrE=aE.Orientation();
274 //
275 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
276 if (aNbF==1) {
277 if (aOrE==TopAbs_INTERNAL) {
278 continue;
279 }
280 bFound=Standard_True;
281 myShapesToAvoid.Add(aF1);
282 }
283 else if (aNbF==2) {
284 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
285 if (aF2.IsSame(aF1)) {
286 if (BRep_Tool::IsClosed(aE, aF1)) {
287 continue;
288 }
289 //
290 if (aOrE==TopAbs_INTERNAL) {
291 continue;
292 }
293 //
294 bFound=Standard_True;
295 myShapesToAvoid.Add(aF1);
296 myShapesToAvoid.Add(aF2);
297 }
298 }
299 }// for (i=1; i<=aNbE; ++i) {
300 //
301 if (!bFound) {
302 break;
303 }
304 //
682c9d06 305 }//for(;;) {
4e57c75e 306}
307//=======================================================================
308//function : PerformLoops
309//purpose :
310//=======================================================================
30ecd5f8 311void BOPAlgo_BuilderSolid::PerformLoops()
4e57c75e 312{
682c9d06 313 Standard_Integer iErr;
314 BOPCol_ListIteratorOfListOfShape aIt;
4e57c75e 315 TopoDS_Iterator aItS;
4e57c75e 316 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
682c9d06 317 BOPAlgo_ShellSplitter aSSp;
318 //
319 myErrorStatus=0;
320 myLoops.Clear();
4e57c75e 321 //
322 // 1. Shells Usual
682c9d06 323 aIt.Initialize (myShapes);
324 for (; aIt.More(); aIt.Next()) {
325 const TopoDS_Shape& aF=aIt.Value();
326 if (!myShapesToAvoid.Contains(aF)) {
327 aSSp.AddStartElement(aF);
328 }
329 }
4e57c75e 330 //
682c9d06 331 aSSp.SetRunParallel(myRunParallel);
332 aSSp.Perform();
333 iErr=aSSp.ErrorStatus();
334 if (iErr) {
335 return;
4e57c75e 336 }
337 //
682c9d06 338 const BOPCol_ListOfShape& aLSh=aSSp.Shells();
339 aIt.Initialize (aLSh);
340 for (; aIt.More(); aIt.Next()) {
341 const TopoDS_Shape& aSh=aIt.Value();
342 myLoops.Append(aSh);
343 }
344 //=================================================
4e57c75e 345 //
682c9d06 346 // 2. Post Treatment
347 Standard_Integer aNbFA;
348 BRep_Builder aBB;
349 BOPCol_MapOfOrientedShape AddedFacesMap;
350 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
4e57c75e 351 BOPCol_MapOfOrientedShape aMP;
682c9d06 352 //
4e57c75e 353 // a. collect all edges that are in loops
354 aIt.Initialize (myLoops);
355 for (; aIt.More(); aIt.Next()) {
356 const TopoDS_Shape& aS=aIt.Value();
357 aItS.Initialize(aS);
358 for (; aItS.More(); aItS.Next()) {
359 const TopoDS_Shape& aF=aItS.Value();
360 aMP.Add(aF);
361 }
362 }
363 //
364 // b. collect all edges that are to avoid
365 aItM.Initialize(myShapesToAvoid);
366 for (; aItM.More(); aItM.Next()) {
367 const TopoDS_Shape& aF=aItM.Key();
368 aMP.Add(aF);
369 }
370 //
371 // c. add all edges that are not processed to myShapesToAvoid
372 aIt.Initialize (myShapes);
373 for (; aIt.More(); aIt.Next()) {
374 const TopoDS_Shape& aF=aIt.Value();
375 if (!aMP.Contains(aF)) {
376 myShapesToAvoid.Add(aF);
377 }
378 }
379 //=================================================
380 //
682c9d06 381 // 3.Internal Shells
4e57c75e 382 myLoopsInternal.Clear();
383 //
384 aEFMap.Clear();
385 AddedFacesMap.Clear();
386 //
682c9d06 387 aNbFA=myShapesToAvoid.Extent();
388 //
4e57c75e 389 aItM.Initialize(myShapesToAvoid);
390 for (; aItM.More(); aItM.Next()) {
391 const TopoDS_Shape& aFF=aItM.Key();
682c9d06 392 BOPTools::MapShapesAndAncestors(aFF,
1e143abb 393 TopAbs_EDGE, TopAbs_FACE,
394 aEFMap);
4e57c75e 395 }
396 //
397 aItM.Initialize(myShapesToAvoid);
398 for (; aItM.More(); aItM.Next()) {
399 const TopoDS_Shape& aFF=aItM.Key();
400 if (!AddedFacesMap.Add(aFF)) {
401 continue;
402 }
403 //
404 // make a new shell
405 TopoDS_Shell aShell;
406 aBB.MakeShell(aShell);
407 aBB.Add(aShell, aFF);
408 //
409 TopoDS_Iterator aItAddedF (aShell);
410 for (; aItAddedF.More(); aItAddedF.Next()) {
411 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
412 //
413 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
414 for (; aEdgeExp.More(); aEdgeExp.Next()) {
415 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
416 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
682c9d06 417 aIt.Initialize(aLF);
418 for (; aIt.More(); aIt.Next()) {
419 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
4e57c75e 420 if (AddedFacesMap.Add(aFL)){
421 aBB.Add(aShell, aFL);
422 }
423 }
424 }
425 }
426 myLoopsInternal.Append(aShell);
427 }
428}
429//=======================================================================
430//function : PerformAreas
431//purpose :
432//=======================================================================
30ecd5f8 433void BOPAlgo_BuilderSolid::PerformAreas()
4e57c75e 434{
682c9d06 435 Standard_Boolean bIsGrowth, bIsHole;
436 Standard_Integer k,aNbHoles;
4e57c75e 437 BRep_Builder aBB;
682c9d06 438 BOPCol_ListIteratorOfListOfShape aItLS;
4e57c75e 439 BOPCol_ListOfShape aNewSolids, aHoleShells;
440 BOPCol_DataMapOfShapeShape aInOutMap;
4e57c75e 441 BOPCol_IndexedMapOfShape aMHF;
682c9d06 442 BOPCol_ListIteratorOfListOfInteger aItLI;
443 BOPCol_BoxBndTreeSelector aSelector;
444 BOPCol_BoxBndTree aBBTree;
445 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
446 BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
447 BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
448 BOPCol_DataMapOfShapeListOfShape aMSH;
449 BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS;
450 BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
451 //
452 myErrorStatus=0;
4e57c75e 453 //
454 myAreas.Clear();
455 //
456 // Draft solids [aNewSolids]
682c9d06 457 aItLS.Initialize(myLoops);
458 for (k=0; aItLS.More(); aItLS.Next(), ++k) {
459 TopoDS_Solid aSolid;
460 Bnd_Box aBox;
461 BOPAlgo_BuilderSolid_ShapeBox aSB;
462 //
463 const TopoDS_Shape& aShell = aItLS.Value();
464 aSB.SetShape(aShell);
465 //
466 BRepBndLib::Add(aShell, aBox);
467 bIsHole=Standard_False;
4e57c75e 468 //
682c9d06 469 bIsGrowth=IsGrowthShell(aShell, aMHF);
470 if (bIsGrowth) {
4e57c75e 471 // make a growth solid from a shell
682c9d06 472 aBB.MakeSolid(aSolid);
473 aBB.Add (aSolid, aShell);
4e57c75e 474 //
682c9d06 475 aNewSolids.Append (aSolid);
476 aSB.SetShape(aSolid);
4e57c75e 477 }
478 else{
479 // check if a shell is a hole
4e57c75e 480 bIsHole=IsHole(aShell, myContext);
4e57c75e 481 if (bIsHole) {
482 aHoleShells.Append(aShell);
483 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
1e143abb 484 aSB.SetShape(aShell);
4e57c75e 485 }
486 else {
487 // make a growth solid from a shell
682c9d06 488 aBB.MakeSolid(aSolid);
489 aBB.Add (aSolid, aShell);
4e57c75e 490 //
682c9d06 491 aNewSolids.Append (aSolid);
1e143abb 492 aSB.SetShape(aSolid);
4e57c75e 493 }
494 }
682c9d06 495 //
496 aSB.SetBox(aBox);
497 aSB.SetIsHole(bIsHole);
498 aDMISB.Bind(k, aSB);
499 }
500 //
501 // 2. Prepare TreeFiller
502 aItDMISB.Initialize(aDMISB);
503 for (; aItDMISB.More(); aItDMISB.Next()) {
504 k=aItDMISB.Key();
505 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
506 //
507 bIsHole=aSB.IsHole();
508 if (bIsHole) {
509 const Bnd_Box& aBox=aSB.Box();
510 aTreeFiller.Add(k, aBox);
511 }
4e57c75e 512 }
513 //
682c9d06 514 // 3. Shake TreeFiller
515 aTreeFiller.Fill();
516 //
517 // 4. Find outer growth shell that is most close
518 // to each hole shell
519 aItDMISB.Initialize(aDMISB);
520 for (; aItDMISB.More(); aItDMISB.Next()) {
521 k=aItDMISB.Key();
522 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
523 bIsHole=aSB.IsHole();
524 if (bIsHole) {
525 continue;
526 }
527 //
528 const TopoDS_Shape aSolid=aSB.Shape();
529 const Bnd_Box& aBoxSolid=aSB.Box();
4e57c75e 530 //
682c9d06 531 aSelector.Clear();
532 aSelector.SetBox(aBoxSolid);
533 //
534 aNbHoles=aBBTree.Select(aSelector);
535 //
536 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
537 //
538 aItLI.Initialize(aLI);
539 for (; aItLI.More(); aItLI.Next()) {
540 k=aItLI.Value();
541 const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
542 const TopoDS_Shape& aHole=aSBk.Shape();
4e57c75e 543 //
544 if (!IsInside(aHole, aSolid, myContext)){
545 continue;
546 }
547 //
682c9d06 548 if (aInOutMap.IsBound (aHole)){
1e143abb 549 const TopoDS_Shape& aHole2=aInOutMap(aHole);
550 if (IsInside(aHole, aHole2, myContext)) {
4e57c75e 551 aInOutMap.UnBind(aHole);
552 aInOutMap.Bind (aHole, aSolid);
553 }
554 }
555 else{
682c9d06 556 aInOutMap.Bind(aHole, aSolid);
4e57c75e 557 }
558 }
682c9d06 559 }//for (; aItDMISB.More(); aItDMISB.Next()) {
560 //
561 // 5. Map [Solid/Holes] -> aMSH
562 aItDMSS.Initialize(aInOutMap);
563 for (; aItDMSS.More(); aItDMSS.Next()) {
564 const TopoDS_Shape& aHole=aItDMSS.Key();
565 const TopoDS_Shape& aSolid=aItDMSS.Value();
4e57c75e 566 //
682c9d06 567 if (aMSH.IsBound(aSolid)) {
568 BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
569 aLH.Append(aHole);
570 }
571 else {
572 BOPCol_ListOfShape aLH;
573 aLH.Append(aHole);
574 aMSH.Bind(aSolid, aLH);
4e57c75e 575 }
682c9d06 576 }
4e57c75e 577 //
682c9d06 578 // 6. Add aHoles to Solids
4e57c75e 579 aItMSH.Initialize(aMSH);
580 for (; aItMSH.More(); aItMSH.Next()) {
581 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
582 //
583 const BOPCol_ListOfShape& aLH=aItMSH.Value();
682c9d06 584 aItLS.Initialize(aLH);
585 for (; aItLS.More(); aItLS.Next()) {
586 const TopoDS_Shape& aHole = aItLS.Value();
4e57c75e 587 aBB.Add (aSolid, aHole);
588 }
589 //
590 // update classifier
682c9d06 591 BRepClass3d_SolidClassifier& aSC=
592 myContext->SolidClassifier(aSolid);
4e57c75e 593 aSC.Load(aSolid);
594 //
595 }
596 //
682c9d06 597 // 7. These aNewSolids are draft solids that
4e57c75e 598 // do not contain any internal shapes
682c9d06 599 aItLS.Initialize(aNewSolids);
600 for ( ; aItLS.More(); aItLS.Next()) {
601 const TopoDS_Shape& aSx=aItLS.Value();
4e57c75e 602 myAreas.Append(aSx);
603 }
4e57c75e 604 // Add holes that outside the solids to myAreas
682c9d06 605 aItLS.Initialize(aHoleShells);
606 for (; aItLS.More(); aItLS.Next()) {
607 const TopoDS_Shape& aHole = aItLS.Value();
4e57c75e 608 if (!aInOutMap.IsBound(aHole)){
609 TopoDS_Solid aSolid;
682c9d06 610 //
4e57c75e 611 aBB.MakeSolid(aSolid);
612 aBB.Add (aSolid, aHole);
613 //
614 myAreas.Append(aSolid);
615 }
616 }
617}
618//=======================================================================
619//function : PerformInternalShapes
620//purpose :
621//=======================================================================
30ecd5f8 622void BOPAlgo_BuilderSolid::PerformInternalShapes()
4e57c75e 623{
624 myErrorStatus=0;
625 //
626 Standard_Integer aNbFI=myLoopsInternal.Extent();
627 if (!aNbFI) {// nothing to do
628 return;
629 }
630 //
631 BRep_Builder aBB;
632 TopoDS_Iterator aIt;
633 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
634 BOPCol_MapIteratorOfMapOfShape aItMF;
635 //
636 BOPCol_MapOfShape aMF, aMFP, aMFx;
637 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
638 BOPCol_ListOfShape aLSI;
639 //
640 // 1. All internal faces
641 aShellIt.Initialize(myLoopsInternal);
642 for (; aShellIt.More(); aShellIt.Next()) {
643 const TopoDS_Shape& aShell=aShellIt.Value();
644 aIt.Initialize(aShell);
645 for (; aIt.More(); aIt.Next()) {
646 const TopoDS_Shape& aF=aIt.Value();
647 aMF.Add(aF);
648 }
649 }
650 aNbFI=aMF.Extent();
651 //
652 // 2 Process solids
653 aSolidIt.Initialize(myAreas);
654 for ( ; aSolidIt.More(); aSolidIt.Next()) {
655 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
656 //
657 TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
658 for (; anExpSol.More(); anExpSol.Next()) {
659 const TopoDS_Shape& aF = anExpSol.Current();
660 TopoDS_Shape aFF=aF;
661 //
662 aFF.Orientation(TopAbs_FORWARD);
663 aMFx.Add(aFF);
664 aFF.Orientation(TopAbs_REVERSED);
665 aMFx.Add(aFF);
666 }
667 aMEF.Clear();
682c9d06 668 BOPTools::MapShapesAndAncestors(aSolid,
1e143abb 669 TopAbs_EDGE, TopAbs_FACE,
670 aMEF);
4e57c75e 671 //
672 // 2.1 Separate faces to process aMFP
673 aMFP.Clear();
674 aItMF.Initialize(aMF);
675 for (; aItMF.More(); aItMF.Next()) {
676 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
677 if (!aMFx.Contains(aF)) {
682c9d06 678 if (BOPTools_AlgoTools::IsInternalFace(aF,
1e143abb 679 aSolid,
680 aMEF,
681 1.e-14,
682 myContext)) {
4e57c75e 683 aMFP.Add(aF);
684 }
685 }
686 }
687 aMFx.Clear();
688 //
689 // 2.2 Make Internal Shells
690 aLSI.Clear();
691 MakeInternalShells(aMFP, aLSI);
692 //
693 // 2.3 Add them to aSolid
694 aShellIt.Initialize(aLSI);
695 for (; aShellIt.More(); aShellIt.Next()) {
696 const TopoDS_Shape& aSI=aShellIt.Value();
697 aBB.Add (aSolid, aSI);
698 }
699 //
700 // 2.4 Remove faces aMFP from aMF
701 aItMF.Initialize(aMFP);
702 for (; aItMF.More(); aItMF.Next()) {
703 const TopoDS_Shape& aF=aItMF.Key();
704 aMF.Remove(aF);
705 }
706 //
707 aNbFI=aMF.Extent();
708 if (!aNbFI) {
709 break;
710 }
711 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
712 if (aNbFI) {
713 TopoDS_Solid aSolid;
714 aBB.MakeSolid(aSolid);
715 //
716 MakeInternalShells(aMF, aLSI);
717 aShellIt.Initialize(aLSI);
718 for (; aShellIt.More(); aShellIt.Next()) {
719 const TopoDS_Shape& aSI=aShellIt.Value();
720 aBB.Add (aSolid, aSI);
721 }
722 myAreas.Append(aSolid);
723 }
724}
725
726//=======================================================================
727//function : MakeInternalShells
728//purpose :
729//=======================================================================
730void MakeInternalShells(const BOPCol_MapOfShape& theMF,
731 BOPCol_ListOfShape& theShells)
732{
733 BOPCol_ListIteratorOfListOfShape aItF;
734 BRep_Builder aBB;
735 //
736 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
737 BOPCol_MapIteratorOfMapOfShape aItM;
738 BOPCol_MapOfShape aAddedFacesMap;
739 //
740 aItM.Initialize(theMF);
741 for (; aItM.More(); aItM.Next()) {
742 const TopoDS_Shape& aF=aItM.Key();
682c9d06 743 BOPTools::MapShapesAndAncestors(aF,
1e143abb 744 TopAbs_EDGE, TopAbs_FACE,
745 aMEF);
4e57c75e 746 }
747 //
748 aItM.Initialize(theMF);
749 for (; aItM.More(); aItM.Next()) {
750 TopoDS_Shape aFF=aItM.Key();
751 if (!aAddedFacesMap.Add(aFF)) {
752 continue;
753 }
754 //
755 // make a new shell
756 TopoDS_Shell aShell;
757 aBB.MakeShell(aShell);
758 aFF.Orientation(TopAbs_INTERNAL);
759 aBB.Add(aShell, aFF);
760 //
761 TopoDS_Iterator aItAddedF (aShell);
762 for (; aItAddedF.More(); aItAddedF.Next()) {
763 const TopoDS_Shape& aF =aItAddedF.Value();
764 //
765 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
766 for (; aEdgeExp.More(); aEdgeExp.Next()) {
767 const TopoDS_Shape& aE =aEdgeExp.Current();
768 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
769 aItF.Initialize(aLF);
770 for (; aItF.More(); aItF.Next()) {
771 TopoDS_Shape aFL=aItF.Value();
772 if (aAddedFacesMap.Add(aFL)){
773 aFL.Orientation(TopAbs_INTERNAL);
774 aBB.Add(aShell, aFL);
775 }
776 }
777 }
778 }
779 theShells.Append(aShell);
780 }
781}
782//=======================================================================
783//function : IsHole
784//purpose :
785//=======================================================================
786Standard_Boolean IsHole(const TopoDS_Shape& theS2,
1e143abb 787 Handle(IntTools_Context)& theContext)
4e57c75e 788{
789 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
790 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
791 //
792 aClsf.PerformInfinitePoint(::RealSmall());
793 //
794 return (aClsf.State()==TopAbs_IN);
795}
796//=======================================================================
797//function : IsInside
798//purpose :
799//=======================================================================
800Standard_Boolean IsInside(const TopoDS_Shape& theS1,
801 const TopoDS_Shape& theS2,
1e143abb 802 Handle(IntTools_Context)& theContext)
4e57c75e 803{
804 TopExp_Explorer aExp;
805 TopAbs_State aState;
806 //
807 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
808 //
809 aExp.Init(theS1, TopAbs_FACE);
810 if (!aExp.More()){
811 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
812 aClsf.PerformInfinitePoint(::RealSmall());
813 aState=aClsf.State();
814 }
815 else {
816 BOPCol_IndexedMapOfShape aBounds;
817 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
818 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
682c9d06 819 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14,
1e143abb 820 aBounds, theContext);
4e57c75e 821 }
822 return (aState==TopAbs_IN);
823}
824//=======================================================================
825//function : IsGrowthShell
826//purpose :
827//=======================================================================
828Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
829 const BOPCol_IndexedMapOfShape& theMHF)
830{
831 Standard_Boolean bRet;
832 TopoDS_Iterator aIt;
833 //
834 bRet=Standard_False;
835 if (theMHF.Extent()) {
836 aIt.Initialize(theShell);
837 for(; aIt.More(); aIt.Next()) {
838 const TopoDS_Shape& aF=aIt.Value();
839 if (theMHF.Contains(aF)) {
840 return !bRet;
841 }
842 }
843 }
844 return bRet;
845}