0024911: Avoid using virtual functions in NCollection classes
[occt.git] / src / BOPAlgo / BOPAlgo_BOP.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
4e57c75e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
4e57c75e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
4e57c75e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
4e57c75e 14
15#include <BOPAlgo_BOP.ixx>
16
17#include <TopAbs_ShapeEnum.hxx>
18
19#include <TopoDS_Compound.hxx>
20#include <TopoDS_Iterator.hxx>
8620e18d 21#include <TopoDS_Edge.hxx>
4e57c75e 22#include <BRep_Builder.hxx>
23#include <TopExp_Explorer.hxx>
24
8620e18d 25#include <BOPCol_ListOfShape.hxx>
26#include <BOPCol_MapOfShape.hxx>
27#include <BOPCol_IndexedMapOfShape.hxx>
28#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
29#include <BOPCol_DataMapOfShapeShape.hxx>
30
31#include <BOPDS_DS.hxx>
32
4e57c75e 33#include <BOPTools.hxx>
34#include <BOPTools_AlgoTools.hxx>
35#include <BOPTools_AlgoTools3D.hxx>
8620e18d 36#include <BOPTools_AlgoTools.hxx>
4e57c75e 37
4e57c75e 38#include <BOPAlgo_BuilderSolid.hxx>
8620e18d 39
40#include <BRep_Tool.hxx>
ddf2fe8e 41#include <NCollection_IncAllocator.hxx>
4e57c75e 42
43static
44 TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim);
45
8620e18d 46
4e57c75e 47//=======================================================================
48//function :
49//purpose :
50//=======================================================================
8620e18d 51BOPAlgo_BOP::BOPAlgo_BOP()
4e57c75e 52:
53 BOPAlgo_Builder(),
54 myTools(myAllocator),
55 myMapTools(100, myAllocator)
56{
4e57c75e 57 Clear();
58}
59//=======================================================================
60//function :
61//purpose :
62//=======================================================================
8620e18d 63BOPAlgo_BOP::BOPAlgo_BOP
64 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 65:
66 BOPAlgo_Builder(theAllocator),
67 myTools(myAllocator),
68 myMapTools(100, myAllocator)
69{
4e57c75e 70 Clear();
71}
72//=======================================================================
73//function : ~
74//purpose :
75//=======================================================================
8620e18d 76BOPAlgo_BOP::~BOPAlgo_BOP()
4e57c75e 77{
78}
79//=======================================================================
80//function : Clear
81//purpose :
82//=======================================================================
8620e18d 83void BOPAlgo_BOP::Clear()
4e57c75e 84{
85 myOperation=BOPAlgo_UNKNOWN;
86 myTools.Clear();
87 myMapTools.Clear();
88 myDims[0]=-1;
89 myDims[1]=-1;
90 //
91 BOPAlgo_Builder::Clear();
92}
93//=======================================================================
8620e18d 94//function : SetOperation
4e57c75e 95//purpose :
96//=======================================================================
8620e18d 97void BOPAlgo_BOP::SetOperation(const BOPAlgo_Operation theOperation)
4e57c75e 98{
8620e18d 99 myOperation=theOperation;
4e57c75e 100}
101//=======================================================================
8620e18d 102//function : Operation
4e57c75e 103//purpose :
104//=======================================================================
8620e18d 105BOPAlgo_Operation BOPAlgo_BOP::Operation()const
4e57c75e 106{
8620e18d 107 return myOperation;
4e57c75e 108}
109//=======================================================================
8620e18d 110//function : AddTool
4e57c75e 111//purpose :
112//=======================================================================
8620e18d 113void BOPAlgo_BOP::AddTool(const TopoDS_Shape& theShape)
4e57c75e 114{
8620e18d 115 if (myMapTools.Add(theShape)) {
116 myTools.Append(theShape);
117 }
4e57c75e 118}
119//=======================================================================
120//function : CheckData
121//purpose :
122//=======================================================================
8620e18d 123void BOPAlgo_BOP::CheckData()
4e57c75e 124{
8620e18d 125 Standard_Integer i, j, iDim, aNbArgs, aNbTools;
4e57c75e 126 Standard_Boolean bFlag;
8620e18d 127 BOPCol_ListIteratorOfListOfShape aItLS;
4e57c75e 128 //
129 myErrorStatus=0;
130 //
8620e18d 131 aNbArgs=myArguments.Extent();
132 if (!aNbArgs) {
133 myErrorStatus=100; // invalid number of Arguments
134 return;
135 }
136 //
137 aNbTools=myTools.Extent();
138 if (!aNbTools) {
139 myErrorStatus=100; // invalid number of Tools
140 return;
7cfb3968 141 }
142 //
143 if (!myPaveFiller) {
144 myErrorStatus=101;
4e57c75e 145 return;
146 }
147 //
7cfb3968 148 myErrorStatus=myPaveFiller->ErrorStatus();
4e57c75e 149 if (myErrorStatus) {
150 return;
151 }
152 //
8620e18d 153 for (i=0; i<2; ++i) {
154 const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools;
155 aItLS.Initialize(aLS);
156 for (j=0; aItLS.More(); aItLS.Next(), ++j) {
157 const TopoDS_Shape& aS=aItLS.Value();
158 bFlag=BOPTools_AlgoTools3D::IsEmptyShape(aS);
159 if(bFlag) {
160 myWarningStatus=2;
161 }
162 //
163 iDim=BOPTools_AlgoTools::Dimension(aS);
164 if (iDim<0) {
165 myErrorStatus=13; // non-homogenious argument
166 return;
167 }
168 //
169 if (!j) {
170 myDims[i]=iDim;
171 continue;
172 }
173 //
174 if (iDim!=myDims[i]) {
175 myErrorStatus=13; // non-homogenious argument
176 return;
177 }
4e57c75e 178 }
179 }
180 //
181 if (myOperation==BOPAlgo_UNKNOWN) {
7cfb3968 182 myErrorStatus=14; // non-licit operation
4e57c75e 183 return;
184 }
185 else if (myDims[0]<myDims[1]) {
186 if (myOperation==BOPAlgo_FUSE ||
187 myOperation==BOPAlgo_CUT21) {
7cfb3968 188 myErrorStatus=14; // non-licit operation for the arguments
4e57c75e 189 return;
190 }
191 }
192 else if (myDims[0]>myDims[1]) {
193 if (myOperation==BOPAlgo_FUSE ||
194 myOperation==BOPAlgo_CUT) {
7cfb3968 195 myErrorStatus=14; // non-licit operation for the arguments
4e57c75e 196 return;
197 }
198 }
199}
200//=======================================================================
201//function : Prepare
202//purpose :
203//=======================================================================
8620e18d 204void BOPAlgo_BOP::Prepare()
4e57c75e 205{
4e57c75e 206 //
207 BOPAlgo_Builder::Prepare();
208 //
209 if(myWarningStatus == 2) {
8620e18d 210 Standard_Integer i;
211 BRep_Builder aBB;
212 BOPCol_ListIteratorOfListOfShape aItLS;
213 //
4e57c75e 214 switch(myOperation) {
8620e18d 215 case BOPAlgo_FUSE: {
216 for (i=0; i<2; ++i) {
217 const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools;
218 aItLS.Initialize(aLS);
219 for (; aItLS.More(); aItLS.Next()) {
220 const TopoDS_Shape& aS=aItLS.Value();
221 aBB.Add(myShape, aS);
222 }
4e57c75e 223 }
8620e18d 224 }
4e57c75e 225 break;
8620e18d 226 //
227 case BOPAlgo_CUT: {
228 aItLS.Initialize(myArguments);
229 for (; aItLS.More(); aItLS.Next()) {
230 const TopoDS_Shape& aS=aItLS.Value();
231 if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) {
232 aBB.Add(myShape, aS);
233 }
4e57c75e 234 }
8620e18d 235 }
4e57c75e 236 break;
8620e18d 237
238 case BOPAlgo_CUT21: {
239 aItLS.Initialize(myTools);
240 for (; aItLS.More(); aItLS.Next()) {
241 const TopoDS_Shape& aS=aItLS.Value();
242 if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) {
243 aBB.Add(myShape, aS);
244 }
4e57c75e 245 }
8620e18d 246 }
4e57c75e 247 break;
8620e18d 248 //
249 case BOPAlgo_COMMON:
250 case BOPAlgo_SECTION:
4e57c75e 251 default:
252 break;
8620e18d 253 }
254 }
255}
256//=======================================================================
257//function : BuildResult
258//purpose :
259//=======================================================================
260void BOPAlgo_BOP::BuildResult(const TopAbs_ShapeEnum theType)
261{
262 TopAbs_ShapeEnum aType;
263 BRep_Builder aBB;
264 BOPCol_MapOfShape aM;
265 BOPCol_ListIteratorOfListOfShape aIt, aItIm;
266 //
267 myErrorStatus=0;
268 //
269 const BOPCol_ListOfShape& aLA=myDS->Arguments();
270 aIt.Initialize(aLA);
271 for (; aIt.More(); aIt.Next()) {
272 const TopoDS_Shape& aS=aIt.Value();
273 aType=aS.ShapeType();
274 if (aType==theType) {
275 if (myImages.IsBound(aS)){
276 const BOPCol_ListOfShape& aLSIm=myImages.Find(aS);
277 aItIm.Initialize(aLSIm);
278 for (; aItIm.More(); aItIm.Next()) {
279 const TopoDS_Shape& aSIm=aItIm.Value();
280 if (aM.Add(aSIm)) {
281 aBB.Add(myShape, aSIm);
282 }
283 }
284 }
285 else {
286 if (aM.Add(aS)) {
287 aBB.Add(myShape, aS);
288 }
289 }
4e57c75e 290 }
291 }
292}
293//=======================================================================
8620e18d 294//function : Perform
295//purpose :
296//=======================================================================
297void BOPAlgo_BOP::Perform()
298{
299 Handle(NCollection_BaseAllocator) aAllocator;
300 BOPAlgo_PaveFiller* pPF;
301 BOPCol_ListIteratorOfListOfShape aItLS;
302 //
303 myErrorStatus=0;
304 //
305 if (myEntryPoint==1) {
306 if (myPaveFiller) {
307 delete myPaveFiller;
308 myPaveFiller=NULL;
309 }
310 }
311 //
312 aAllocator=new NCollection_IncAllocator;
313 BOPCol_ListOfShape aLS(aAllocator);
314 //
315 aItLS.Initialize(myArguments);
316 for (; aItLS.More(); aItLS.Next()) {
317 const TopoDS_Shape& aS=aItLS.Value();
318 aLS.Append(aS);
319 }
320 //
321 aItLS.Initialize(myTools);
322 for (; aItLS.More(); aItLS.Next()) {
323 const TopoDS_Shape& aS=aItLS.Value();
324 aLS.Append(aS);
325 }
326 //
327 pPF=new BOPAlgo_PaveFiller(aAllocator);
328 pPF->SetArguments(aLS);
329 //
330 pPF->Perform();
331 //
332 myEntryPoint=1;
333 PerformInternal(*pPF);
334}
335//=======================================================================
4e57c75e 336//function : PerformInternal
337//purpose :
338//=======================================================================
8620e18d 339void BOPAlgo_BOP::PerformInternal(const BOPAlgo_PaveFiller& theFiller)
4e57c75e 340{
341 myErrorStatus=0;
342 myWarningStatus=0;
343 //
344 myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
345 myDS=myPaveFiller->PDS();
346 myContext=myPaveFiller->Context();
347 //
348 // 1. CheckData
349 CheckData();
350 if (myErrorStatus && !myWarningStatus) {
351 return;
352 }
353 //
354 // 2. Prepare
355 Prepare();
356 if (myErrorStatus) {
357 return;
358 }
8620e18d 359 //
4e57c75e 360 if(myWarningStatus == 2) {
361 return;
362 }
4e57c75e 363 // 3. Fill Images
364 // 3.1 Vertices
365 FillImagesVertices();
366 if (myErrorStatus) {
367 return;
368 }
369 //
370 BuildResult(TopAbs_VERTEX);
371 if (myErrorStatus) {
372 return;
373 }
374 // 3.2 Edges
375 FillImagesEdges();
376 if (myErrorStatus) {
377 return;
378 }
379
380 BuildResult(TopAbs_EDGE);
381 if (myErrorStatus) {
382 return;
383 }
8620e18d 384 //-------------------------------- SECTION
4e57c75e 385 if (myOperation==BOPAlgo_SECTION) {
386 BuildSection();
387 PrepareHistory();
388 PostTreat();
389 return;
390 }
8620e18d 391 //--------------------------------
4e57c75e 392 //
393 // 3.3 Wires
394 FillImagesContainers(TopAbs_WIRE);
395 if (myErrorStatus) {
396 return;
397 }
398
399 BuildResult(TopAbs_WIRE);
400 if (myErrorStatus) {
401 return;
402 }
403
404 // 3.4 Faces
405 FillImagesFaces();
406 if (myErrorStatus) {
407 return;
408 }
409
410 BuildResult(TopAbs_FACE);
411 if (myErrorStatus) {
412 return;
413 }
414 // 3.5 Shells
415
416 FillImagesContainers(TopAbs_SHELL);
417 if (myErrorStatus) {
418 return;
419 }
420
421 BuildResult(TopAbs_SHELL);
422 if (myErrorStatus) {
423 return;
424 }
425 // 3.6 Solids
426 FillImagesSolids();
427 if (myErrorStatus) {
428 return;
429 }
430
431 BuildResult(TopAbs_SOLID);
432 if (myErrorStatus) {
433 return;
434 }
435 // 3.7 CompSolids
436 FillImagesContainers(TopAbs_COMPSOLID);
437 if (myErrorStatus) {
438 return;
439 }
440
441 BuildResult(TopAbs_COMPSOLID);
442 if (myErrorStatus) {
443 return;
444 }
445 // 3.8 Compounds
446 FillImagesCompounds();
447 if (myErrorStatus) {
448 return;
449 }
450
451 BuildResult(TopAbs_COMPOUND);
452 if (myErrorStatus) {
453 return;
454 }
455 //
8620e18d 456 // 4.BuildShape;
4e57c75e 457 BuildShape();
8620e18d 458 if (myErrorStatus) {
459 return;
460 }
4e57c75e 461 //
8620e18d 462 // 5.History
4e57c75e 463 PrepareHistory();
4e57c75e 464 //
8620e18d 465 // 6 Post-treatment
4e57c75e 466 PostTreat();
467}
468//=======================================================================
8620e18d 469//function : BuildRC
470//purpose :
471//=======================================================================
472void BOPAlgo_BOP::BuildRC()
473{
474 Standard_Boolean bFlag1, bFlag2, bIsBound;
475 Standard_Integer aDmin;
476 TopAbs_ShapeEnum aTmin;
477 TopoDS_Compound aC;
478 TopoDS_Shape aSAIm, aSTIm;
479 BRep_Builder aBB;
480 TopExp_Explorer aExp;
481 BOPCol_DataMapOfShapeShape aDMSSA;
482 BOPCol_ListIteratorOfListOfShape aItLS, aItIm;
483 //
484 myErrorStatus=0;
485 //
486 aBB.MakeCompound(aC);
487 //
488 // A. Fuse
489 if (myOperation==BOPAlgo_FUSE) {
490 aTmin=TypeToExplore(myDims[0]);
491 aExp.Init(myShape, aTmin);
492 for (; aExp.More(); aExp.Next()) {
493 const TopoDS_Shape& aS=aExp.Current();
494 aBB.Add(aC, aS);
495 }
496 myRC=aC;
497 return;
498 }
499 //
500 aDmin=myDims[1];
501 if (myDims[0] < myDims[1]) {
502 aDmin=myDims[0];
503 }
504 aTmin=TypeToExplore(aDmin);
505 //
506 // B. Common, Cut, Cut21
507 //
508 bFlag1=(myOperation==BOPAlgo_COMMON || myOperation==BOPAlgo_CUT21);
509 bFlag2=(myOperation==BOPAlgo_CUT || myOperation==BOPAlgo_CUT21);
510 //
511 const BOPCol_ListOfShape& aLA=( bFlag1) ? myArguments : myTools;
512 aItLS.Initialize(aLA);
513 for (; aItLS.More(); aItLS.Next()) {
514 const TopoDS_Shape& aSA=aItLS.Value();
515 //
516 if (myImages.IsBound(aSA)){
517 const BOPCol_ListOfShape& aLSAIm=myImages.Find(aSA);
518 aItIm.Initialize(aLSAIm);
519 for (; aItIm.More(); aItIm.Next()) {
520 const TopoDS_Shape& aSAIm=aItIm.Value();
521 aExp.Init(aSAIm, aTmin);
522 for (; aExp.More(); aExp.Next()) {
523 const TopoDS_Shape aSIm=aExp.Current();
524 aDMSSA.Bind(aSIm, aSIm);
525 }
526 }
527 }
528 //
529 else {
530 aExp.Init(aSA, aTmin);
531 for (; aExp.More(); aExp.Next()) {
532 const TopoDS_Shape aSIm=aExp.Current();
533 aDMSSA.Bind(aSIm, aSIm);
534 }
535 }
536 } //for (; aItLS.More(); aItLS.Next())
537 //
538 const BOPCol_ListOfShape& aLT=(!bFlag1) ? myArguments : myTools;
539 aItLS.Initialize(aLT);
540 for (; aItLS.More(); aItLS.Next()) {
541 const TopoDS_Shape& aST=aItLS.Value();
542 if (myImages.IsBound(aST)){
543 const BOPCol_ListOfShape& aLSTIm=myImages.Find(aST);
544 aItIm.Initialize(aLSTIm);
545 for (; aItIm.More(); aItIm.Next()) {
546 const TopoDS_Shape& aSTIm=aItIm.Value();
547 aExp.Init(aSTIm, aTmin);
548 for (; aExp.More(); aExp.Next()) {
549 const TopoDS_Shape aSIm=aExp.Current();
550 // skip degenerated edges
551 if (aTmin==TopAbs_EDGE) {
552 const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm);
553 if (BRep_Tool::Degenerated(aEIm)) {
554 continue;
555 }
556 }
557 //
558 bIsBound=aDMSSA.IsBound(aSIm);
559 if (!bFlag2) { // ie common
560 if (bIsBound) {
561 const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm);
562 aBB.Add(aC, aSImA);
563 }
564 }
565 else {// ie cut or cut21
566 if (!bIsBound) {
567 aBB.Add(aC, aSIm);
568 }
569 }
570 }
571 }
572 }
573 else {
574 aExp.Init(aST, aTmin);
575 for (; aExp.More(); aExp.Next()) {
576 const TopoDS_Shape aSIm=aExp.Current();
577 // skip degenerated edges
578 if (aTmin==TopAbs_EDGE) {
579 const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm);
580 if (BRep_Tool::Degenerated(aEIm)) {
581 continue;
582 }
583 }
584 bIsBound=aDMSSA.IsBound(aSIm);
585 if (!bFlag2) { // ie common
586 if (bIsBound) {
587 const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm);
588 aBB.Add(aC, aSImA);
589 }
590 }
591 else {// ie cut or cut21
592 if (!bIsBound) {
593 aBB.Add(aC, aSIm);
594 }
595 }
596 }
597 }
598 } //for (; aItLS.More(); aItLS.Next())
599 //
600 // the squats around degeneracy
601 if (aTmin!=TopAbs_EDGE) {
602 myRC=aC;
603 return;
604 }
605 //---------------------------------------------------------
606 //
607 // The squats around degenerated edges
608 Standard_Integer i, aNbS, nVD;
609 TopAbs_ShapeEnum aType;
610 BOPCol_IndexedMapOfShape aMVC;
611 //
612 // 1. Vertices of aC
613 BOPTools::MapShapes(aC, TopAbs_VERTEX, aMVC);
614 //
615 // 2. DE candidates
616 aNbS=myDS->NbSourceShapes();
617 for (i=0; i<aNbS; ++i) {
618 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
619 aType=aSI.ShapeType();
620 if (aType!=aTmin) {
621 continue;
622 }
623 //
624 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aSI.Shape());
625 if (!BRep_Tool::Degenerated(aE)) {
626 continue;
627 }
628 //
629 nVD=aSI.SubShapes().First();
630 const TopoDS_Shape& aVD=myDS->Shape(nVD);
631 //
632 if (!aMVC.Contains(aVD)) {
633 continue;
634 }
635 //
636 if (myDS->IsNewShape(nVD)) {
637 continue;
638 }
639 //
640 if (myDS->HasInterf(nVD)) {
641 continue;
642 }
643 //
644 aBB.Add(aC, aE);
645 }
646 //
647 myRC=aC;
648}
649//=======================================================================
4e57c75e 650//function : BuildShape
651//purpose :
652//=======================================================================
8620e18d 653void BOPAlgo_BOP::BuildShape()
4e57c75e 654{
655 Standard_Integer aDmin, aNbLCB;
656 TopAbs_ShapeEnum aT1, aT2, aTR;
657 TopoDS_Shape aR, aRC;
658 TopoDS_Iterator aIt;
659 BRep_Builder aBB;
660 BOPCol_ListOfShape aLCB;
661 BOPCol_ListIteratorOfListOfShape aItLCB;
662 //
663 myErrorStatus=0;
664 //
665 BuildRC();
4e57c75e 666 //
667 aDmin=myDims[1];
668 if (myDims[0]<myDims[1]) {
669 aDmin=myDims[0];
670 }
671 //
672 if (!aDmin) {
673 myShape=myRC;
674 return;
675 }
676 //
677 else if (aDmin==1 || aDmin==2) { //edges, faces
678 aT1=TopAbs_VERTEX;
679 aT2=TopAbs_EDGE;
680 aTR=TopAbs_WIRE;
681 if (aDmin==2) {
682 aT1=TopAbs_EDGE;
683 aT2=TopAbs_FACE;
684 aTR=TopAbs_SHELL;
685 }
686 //
8620e18d 687 BOPTools_AlgoTools::MakeConnexityBlocks
688 (myRC, aT1, aT2, aLCB);
4e57c75e 689 aNbLCB=aLCB.Extent();
690 if (!aNbLCB) {
691 myShape=myRC;
692 return;
693 }
694 //
695 BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);
696 //
697 aItLCB.Initialize(aLCB);
698 for (; aItLCB.More(); aItLCB.Next()) {
699 BOPTools_AlgoTools::MakeContainer(aTR, aR);
700 //
701 const TopoDS_Shape& aCB=aItLCB.Value();
702 aIt.Initialize(aCB);
703 for (; aIt.More(); aIt.Next()) {
704 const TopoDS_Shape& aS=aIt.Value();
705 aBB.Add(aR, aS);
706 }
707 //
708 if (aTR==TopAbs_SHELL) {
709 BOPTools_AlgoTools::OrientFacesOnShell(aR);
710 }
711 //
712 aBB.Add(aRC, aR);
713 }
714 myShape=aRC;
715 }// elase if (aDmin==1 || aDmin==2) {
716
8620e18d 717 else {//aDmin=3
718 Standard_Integer aNbObjs, aNbTools;
719 //
720 aNbObjs=myArguments.Extent();
721 aNbTools=myTools.Extent();
722 //
723 if (aNbObjs==1 && aNbTools==1) {
724 if (myOperation==BOPAlgo_FUSE) {
725 BuildSolid();
4e57c75e 726 }
727 else {
8620e18d 728 myShape=myRC;
4e57c75e 729 }
730 }
8620e18d 731 else {
732 BuildSolid();
4e57c75e 733 }
734 }
4e57c75e 735}
736//=======================================================================
737//function : BuildSolid
738//purpose :
739//=======================================================================
8620e18d 740void BOPAlgo_BOP::BuildSolid()
4e57c75e 741{
742 Standard_Integer i, aNbF, aNbSx, iX, iErr;
743 TopAbs_Orientation aOr, aOr1;
744 TopoDS_Iterator aIt;
745 TopoDS_Shape aRC;
746 BRep_Builder aBB;
747 TopExp_Explorer aExp;
748 BOPCol_IndexedMapOfShape aMFI;
749 BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF;
750 BOPCol_ListIteratorOfListOfShape aItLS;
751 BOPCol_ListOfShape aSFS;
752 BOPAlgo_BuilderSolid aSB;
753 //
754 myErrorStatus=0;
755 //
756 aIt.Initialize(myRC);
757 for (; aIt.More(); aIt.Next()) {
758 const TopoDS_Shape& aSx=aIt.Value();
759 aExp.Init(aSx, TopAbs_FACE);
760 for (; aExp.More(); aExp.Next()) {
761 const TopoDS_Shape& aFx=aExp.Current();
762 //
763 aOr=aFx.Orientation();
764 if (aOr==TopAbs_INTERNAL) {
765 aMFI.Add(aFx);
766 continue;
767 }
768 //
769 if (!aMFS.Contains(aFx)) {
770 BOPCol_ListOfShape aLSx;
771 //
772 aLSx.Append(aSx);
773 aMFS.Add(aFx, aLSx);
774 }
775 else {
776 iX=aMFS.FindIndex(aFx);
777 const TopoDS_Shape& aFx1=aMFS.FindKey(iX);
778 aOr1=aFx1.Orientation();
779 if (aOr1!=aOr) {
780 BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx);
781 aLSx.Append(aSx);
782 aMFS.Add(aFx, aLSx);
783 }
784 }
785 }
786 }
8620e18d 787 //faces that will be added in the end;
788 BOPCol_ListOfShape aLF, aLFx;
4e57c75e 789 // SFS
790 aNbF=aMFS.Extent();
791 for (i=1; i<=aNbF; ++i) {
792 const TopoDS_Shape& aFx=aMFS.FindKey(i);
793 const BOPCol_ListOfShape& aLSx=aMFS(i);
794 aNbSx=aLSx.Extent();
795 if (aNbSx==1) {
8620e18d 796 BOPTools::MapShapesAndAncestors
797 (aFx,TopAbs_EDGE, TopAbs_FACE, aMEF);
4e57c75e 798 if (IsBoundSplits(aFx, aMEF)){
799 aLFx.Append(aFx);
800 continue;
801 }
802 aLF.Append(aFx);
803 }
804 }
805
806 aItLS.Initialize(aLF);
807 for(; aItLS.More(); aItLS.Next()) {
808 const TopoDS_Shape& aFx=aItLS.Value();
809 aSFS.Append(aFx);
810 }
811 // add faces from aLFx to aSFS;
812 aItLS.Initialize(aLFx);
813 for (; aItLS.More(); aItLS.Next()) {
814 const TopoDS_Shape& aFx=aItLS.Value();
815 aSFS.Append(aFx);
816 }
817 //
818 aNbF=aMFI.Extent();
819 for (i=1; i<=aNbF; ++i) {
820 TopoDS_Shape aFx;
821 //
822 aFx=aMFI.FindKey(i);
823 aFx.Orientation(TopAbs_FORWARD);
824 aSFS.Append(aFx);
825 aFx.Orientation(TopAbs_REVERSED);
826 aSFS.Append(aFx);
827 }
828 //
829 // BuilderSolid
830 BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);
831 //
832 aSB.SetContext(myContext);
833 aSB.SetShapes(aSFS);
834 aSB.Perform();
835 iErr=aSB.ErrorStatus();
836 if (iErr) {
837 myErrorStatus=30; // SolidBuilder failed
838 return;
839 }
840 //
841 const BOPCol_ListOfShape& aLSR=aSB.Areas();
842 //
843 aItLS.Initialize(aLSR);
844 for (; aItLS.More(); aItLS.Next()) {
845 const TopoDS_Shape& aSR=aItLS.Value();
846 aBB.Add(aRC, aSR);
847 }
848 myShape=aRC;
849}
4e57c75e 850//=======================================================================
851//function : IsBoundImages
852//purpose :
853//=======================================================================
8620e18d 854Standard_Boolean BOPAlgo_BOP::IsBoundSplits
855 (const TopoDS_Shape& aS,
856 BOPCol_IndexedDataMapOfShapeListOfShape& aMEF)
4e57c75e 857{
858 Standard_Boolean bRet = Standard_False;
859 if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) {
860 return !bRet;
861 }
862
863 BOPCol_ListIteratorOfListOfShape aIt;
864 Standard_Integer aNbLS;
865 TopAbs_Orientation anOr;
866 //
867 //check face aF may be connected to face from mySplits
868 TopExp_Explorer aExp(aS, TopAbs_EDGE);
869 for (; aExp.More(); aExp.Next()) {
870 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
871 //
872 anOr = aE.Orientation();
873 if (anOr==TopAbs_INTERNAL) {
874 continue;
875 }
876 //
877 if (BRep_Tool::Degenerated(aE)) {
878 continue;
879 }
880 //
881 const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE);
882 aNbLS = aLS.Extent();
883 if (!aNbLS) {
884 continue;
885 }
886 //
887 aIt.Initialize(aLS);
888 for (; aIt.More(); aIt.Next()) {
889 const TopoDS_Shape& aSx = aIt.Value();
8620e18d 890 if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) {
4e57c75e 891 return !bRet;
892 }
893 }
894 }
8620e18d 895 //
4e57c75e 896 return bRet;
897}
8620e18d 898//=======================================================================
899//function : TypeToExplore
900//purpose :
901//=======================================================================
902TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
903{
904 TopAbs_ShapeEnum aRet;
905 //
906 switch(theDim) {
907 case 0:
908 aRet=TopAbs_VERTEX;
909 break;
910 case 1:
911 aRet=TopAbs_EDGE;
912 break;
913 case 2:
914 aRet=TopAbs_FACE;
915 break;
916 case 3:
917 aRet=TopAbs_SOLID;
918 break;
919 default:
920 aRet=TopAbs_SHAPE;
921 break;
922 }
923 return aRet;
924}