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