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