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