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