0025507: Visualization - the method V3d_View::Place() is incorrect
[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);
353 //
354 pPF->Perform();
355 //
356 myEntryPoint=1;
357 PerformInternal(*pPF);
358}
359//=======================================================================
36f4947b 360//function : PerformInternal1
4e57c75e 361//purpose :
362//=======================================================================
36f4947b 363void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
4e57c75e 364{
365 myErrorStatus=0;
366 myWarningStatus=0;
367 //
368 myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
369 myDS=myPaveFiller->PDS();
370 myContext=myPaveFiller->Context();
371 //
372 // 1. CheckData
373 CheckData();
374 if (myErrorStatus && !myWarningStatus) {
375 return;
376 }
377 //
378 // 2. Prepare
379 Prepare();
380 if (myErrorStatus) {
381 return;
382 }
8620e18d 383 //
4e57c75e 384 if(myWarningStatus == 2) {
385 return;
386 }
4e57c75e 387 // 3. Fill Images
388 // 3.1 Vertices
389 FillImagesVertices();
390 if (myErrorStatus) {
391 return;
392 }
393 //
394 BuildResult(TopAbs_VERTEX);
395 if (myErrorStatus) {
396 return;
397 }
398 // 3.2 Edges
399 FillImagesEdges();
400 if (myErrorStatus) {
401 return;
402 }
85915310 403 //
4e57c75e 404 BuildResult(TopAbs_EDGE);
405 if (myErrorStatus) {
406 return;
407 }
4e57c75e 408 //
409 // 3.3 Wires
410 FillImagesContainers(TopAbs_WIRE);
411 if (myErrorStatus) {
412 return;
413 }
85915310 414 //
4e57c75e 415 BuildResult(TopAbs_WIRE);
416 if (myErrorStatus) {
417 return;
418 }
85915310 419 //
4e57c75e 420 // 3.4 Faces
421 FillImagesFaces();
422 if (myErrorStatus) {
423 return;
424 }
425
426 BuildResult(TopAbs_FACE);
427 if (myErrorStatus) {
428 return;
429 }
85915310 430 //
4e57c75e 431 // 3.5 Shells
4e57c75e 432 FillImagesContainers(TopAbs_SHELL);
433 if (myErrorStatus) {
434 return;
435 }
85915310 436 //
4e57c75e 437 BuildResult(TopAbs_SHELL);
438 if (myErrorStatus) {
439 return;
440 }
85915310 441 //
4e57c75e 442 // 3.6 Solids
443 FillImagesSolids();
444 if (myErrorStatus) {
445 return;
446 }
85915310 447 //
4e57c75e 448 BuildResult(TopAbs_SOLID);
449 if (myErrorStatus) {
450 return;
451 }
85915310 452 //
4e57c75e 453 // 3.7 CompSolids
454 FillImagesContainers(TopAbs_COMPSOLID);
455 if (myErrorStatus) {
456 return;
457 }
85915310 458 //
4e57c75e 459 BuildResult(TopAbs_COMPSOLID);
460 if (myErrorStatus) {
461 return;
462 }
85915310 463 //
4e57c75e 464 // 3.8 Compounds
465 FillImagesCompounds();
466 if (myErrorStatus) {
467 return;
468 }
85915310 469 //
4e57c75e 470 BuildResult(TopAbs_COMPOUND);
471 if (myErrorStatus) {
472 return;
473 }
474 //
8620e18d 475 // 4.BuildShape;
4e57c75e 476 BuildShape();
8620e18d 477 if (myErrorStatus) {
478 return;
479 }
4e57c75e 480 //
8620e18d 481 // 5.History
4e57c75e 482 PrepareHistory();
4e57c75e 483 //
8620e18d 484 // 6 Post-treatment
4e57c75e 485 PostTreat();
486}
487//=======================================================================
8620e18d 488//function : BuildRC
489//purpose :
490//=======================================================================
491void BOPAlgo_BOP::BuildRC()
492{
493 Standard_Boolean bFlag1, bFlag2, bIsBound;
494 Standard_Integer aDmin;
495 TopAbs_ShapeEnum aTmin;
496 TopoDS_Compound aC;
497 TopoDS_Shape aSAIm, aSTIm;
498 BRep_Builder aBB;
499 TopExp_Explorer aExp;
500 BOPCol_DataMapOfShapeShape aDMSSA;
955b3e71 501 BOPCol_ListIteratorOfListOfShape aItLS, aItIm;
502 Standard_Boolean bHasInterf;
503 Standard_Integer iX;
504 BOPTools_DataMapOfSetShape aDMSTS;
8620e18d 505 //
506 myErrorStatus=0;
507 //
508 aBB.MakeCompound(aC);
509 //
510 // A. Fuse
511 if (myOperation==BOPAlgo_FUSE) {
512 aTmin=TypeToExplore(myDims[0]);
513 aExp.Init(myShape, aTmin);
514 for (; aExp.More(); aExp.Next()) {
515 const TopoDS_Shape& aS=aExp.Current();
516 aBB.Add(aC, aS);
517 }
518 myRC=aC;
519 return;
520 }
521 //
522 aDmin=myDims[1];
523 if (myDims[0] < myDims[1]) {
524 aDmin=myDims[0];
525 }
526 aTmin=TypeToExplore(aDmin);
527 //
528 // B. Common, Cut, Cut21
529 //
530 bFlag1=(myOperation==BOPAlgo_COMMON || myOperation==BOPAlgo_CUT21);
531 bFlag2=(myOperation==BOPAlgo_CUT || myOperation==BOPAlgo_CUT21);
532 //
533 const BOPCol_ListOfShape& aLA=( bFlag1) ? myArguments : myTools;
534 aItLS.Initialize(aLA);
535 for (; aItLS.More(); aItLS.Next()) {
536 const TopoDS_Shape& aSA=aItLS.Value();
537 //
538 if (myImages.IsBound(aSA)){
539 const BOPCol_ListOfShape& aLSAIm=myImages.Find(aSA);
540 aItIm.Initialize(aLSAIm);
541 for (; aItIm.More(); aItIm.Next()) {
542 const TopoDS_Shape& aSAIm=aItIm.Value();
543 aExp.Init(aSAIm, aTmin);
544 for (; aExp.More(); aExp.Next()) {
545 const TopoDS_Shape aSIm=aExp.Current();
546 aDMSSA.Bind(aSIm, aSIm);
547 }
548 }
549 }
550 //
551 else {
552 aExp.Init(aSA, aTmin);
553 for (; aExp.More(); aExp.Next()) {
554 const TopoDS_Shape aSIm=aExp.Current();
555 aDMSSA.Bind(aSIm, aSIm);
955b3e71 556 if (aTmin==TopAbs_SOLID) {
557 iX=myDS->Index(aSIm);
558 bHasInterf=myDS->HasInterf(iX);
559 if (!bHasInterf) {
560 BOPTools_Set aST;
561 //
562 aST.Add(aSIm, TopAbs_FACE);
563 //
564 aDMSTS.Bind(aST, aSIm);
565 }
566 }
8620e18d 567 }
568 }
569 } //for (; aItLS.More(); aItLS.Next())
570 //
571 const BOPCol_ListOfShape& aLT=(!bFlag1) ? myArguments : myTools;
572 aItLS.Initialize(aLT);
573 for (; aItLS.More(); aItLS.Next()) {
574 const TopoDS_Shape& aST=aItLS.Value();
575 if (myImages.IsBound(aST)){
576 const BOPCol_ListOfShape& aLSTIm=myImages.Find(aST);
577 aItIm.Initialize(aLSTIm);
578 for (; aItIm.More(); aItIm.Next()) {
579 const TopoDS_Shape& aSTIm=aItIm.Value();
580 aExp.Init(aSTIm, aTmin);
581 for (; aExp.More(); aExp.Next()) {
582 const TopoDS_Shape aSIm=aExp.Current();
583 // skip degenerated edges
584 if (aTmin==TopAbs_EDGE) {
585 const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm);
586 if (BRep_Tool::Degenerated(aEIm)) {
587 continue;
588 }
589 }
590 //
591 bIsBound=aDMSSA.IsBound(aSIm);
592 if (!bFlag2) { // ie common
593 if (bIsBound) {
594 const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm);
595 aBB.Add(aC, aSImA);
596 }
597 }
598 else {// ie cut or cut21
599 if (!bIsBound) {
600 aBB.Add(aC, aSIm);
601 }
602 }
603 }
604 }
955b3e71 605 }// if (myImages.IsBound(aST)){
8620e18d 606 else {
607 aExp.Init(aST, aTmin);
608 for (; aExp.More(); aExp.Next()) {
609 const TopoDS_Shape aSIm=aExp.Current();
610 // skip degenerated edges
611 if (aTmin==TopAbs_EDGE) {
612 const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm);
613 if (BRep_Tool::Degenerated(aEIm)) {
614 continue;
615 }
616 }
617 bIsBound=aDMSSA.IsBound(aSIm);
618 if (!bFlag2) { // ie common
619 if (bIsBound) {
620 const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm);
621 aBB.Add(aC, aSImA);
622 }
955b3e71 623 else {
624 if (aTmin==TopAbs_SOLID) {
625 BOPTools_Set aST;
626 //
627 aST.Add(aSIm, TopAbs_FACE);
628 //
629 if (aDMSTS.IsBound(aST)) {
630 const TopoDS_Shape& aSImA=aDMSTS.Find(aST);
631 aBB.Add(aC, aSImA);
632 }
633 }
634 }
8620e18d 635 }
636 else {// ie cut or cut21
637 if (!bIsBound) {
955b3e71 638 if (aTmin==TopAbs_SOLID) {
639 BOPTools_Set aST;
640 //
641 aST.Add(aSIm, TopAbs_FACE);
642 //
643 bIsBound=aDMSTS.IsBound(aST);
644 }
645 //
646 if (!bIsBound) {
647 aBB.Add(aC, aSIm);
648 }
8620e18d 649 }
650 }
651 }
652 }
653 } //for (; aItLS.More(); aItLS.Next())
654 //
655 // the squats around degeneracy
656 if (aTmin!=TopAbs_EDGE) {
657 myRC=aC;
658 return;
659 }
660 //---------------------------------------------------------
661 //
662 // The squats around degenerated edges
663 Standard_Integer i, aNbS, nVD;
664 TopAbs_ShapeEnum aType;
665 BOPCol_IndexedMapOfShape aMVC;
666 //
667 // 1. Vertices of aC
668 BOPTools::MapShapes(aC, TopAbs_VERTEX, aMVC);
669 //
670 // 2. DE candidates
671 aNbS=myDS->NbSourceShapes();
672 for (i=0; i<aNbS; ++i) {
673 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
674 aType=aSI.ShapeType();
675 if (aType!=aTmin) {
676 continue;
677 }
678 //
679 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aSI.Shape());
680 if (!BRep_Tool::Degenerated(aE)) {
681 continue;
682 }
683 //
684 nVD=aSI.SubShapes().First();
685 const TopoDS_Shape& aVD=myDS->Shape(nVD);
686 //
687 if (!aMVC.Contains(aVD)) {
688 continue;
689 }
690 //
691 if (myDS->IsNewShape(nVD)) {
692 continue;
693 }
694 //
695 if (myDS->HasInterf(nVD)) {
696 continue;
697 }
698 //
699 aBB.Add(aC, aE);
700 }
701 //
702 myRC=aC;
703}
704//=======================================================================
4e57c75e 705//function : BuildShape
706//purpose :
707//=======================================================================
8620e18d 708void BOPAlgo_BOP::BuildShape()
4e57c75e 709{
710 Standard_Integer aDmin, aNbLCB;
711 TopAbs_ShapeEnum aT1, aT2, aTR;
712 TopoDS_Shape aR, aRC;
713 TopoDS_Iterator aIt;
714 BRep_Builder aBB;
715 BOPCol_ListOfShape aLCB;
716 BOPCol_ListIteratorOfListOfShape aItLCB;
717 //
718 myErrorStatus=0;
719 //
720 BuildRC();
4e57c75e 721 //
722 aDmin=myDims[1];
723 if (myDims[0]<myDims[1]) {
724 aDmin=myDims[0];
725 }
726 //
727 if (!aDmin) {
728 myShape=myRC;
729 return;
730 }
731 //
732 else if (aDmin==1 || aDmin==2) { //edges, faces
733 aT1=TopAbs_VERTEX;
734 aT2=TopAbs_EDGE;
735 aTR=TopAbs_WIRE;
736 if (aDmin==2) {
737 aT1=TopAbs_EDGE;
738 aT2=TopAbs_FACE;
739 aTR=TopAbs_SHELL;
740 }
741 //
8620e18d 742 BOPTools_AlgoTools::MakeConnexityBlocks
743 (myRC, aT1, aT2, aLCB);
4e57c75e 744 aNbLCB=aLCB.Extent();
745 if (!aNbLCB) {
746 myShape=myRC;
747 return;
748 }
749 //
750 BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);
751 //
752 aItLCB.Initialize(aLCB);
753 for (; aItLCB.More(); aItLCB.Next()) {
754 BOPTools_AlgoTools::MakeContainer(aTR, aR);
755 //
756 const TopoDS_Shape& aCB=aItLCB.Value();
757 aIt.Initialize(aCB);
758 for (; aIt.More(); aIt.Next()) {
759 const TopoDS_Shape& aS=aIt.Value();
760 aBB.Add(aR, aS);
761 }
762 //
763 if (aTR==TopAbs_SHELL) {
764 BOPTools_AlgoTools::OrientFacesOnShell(aR);
765 }
766 //
767 aBB.Add(aRC, aR);
768 }
769 myShape=aRC;
770 }// elase if (aDmin==1 || aDmin==2) {
771
8620e18d 772 else {//aDmin=3
773 Standard_Integer aNbObjs, aNbTools;
774 //
775 aNbObjs=myArguments.Extent();
776 aNbTools=myTools.Extent();
777 //
778 if (aNbObjs==1 && aNbTools==1) {
779 if (myOperation==BOPAlgo_FUSE) {
780 BuildSolid();
4e57c75e 781 }
782 else {
8620e18d 783 myShape=myRC;
4e57c75e 784 }
785 }
8620e18d 786 else {
787 BuildSolid();
4e57c75e 788 }
789 }
4e57c75e 790}
791//=======================================================================
792//function : BuildSolid
793//purpose :
794//=======================================================================
8620e18d 795void BOPAlgo_BOP::BuildSolid()
4e57c75e 796{
955b3e71 797 Standard_Boolean bHasInterf, bHasSharedFaces;
798 Standard_Integer i, aNbF, aNbSx, iX, iErr, aNbZ;
4e57c75e 799 TopAbs_Orientation aOr, aOr1;
800 TopoDS_Iterator aIt;
801 TopoDS_Shape aRC;
802 BRep_Builder aBB;
803 TopExp_Explorer aExp;
804 BOPCol_IndexedMapOfShape aMFI;
805 BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF;
806 BOPCol_ListIteratorOfListOfShape aItLS;
807 BOPCol_ListOfShape aSFS;
955b3e71 808 BOPAlgo_BuilderSolid aSB;
809 BOPCol_MapOfShape aMSA, aMZ;
810 BOPTools_DataMapOfSetShape aDMSTS;
811 BOPTools_DataMapIteratorOfDataMapOfSetShape aItDMSTS;
4e57c75e 812 //
813 myErrorStatus=0;
814 //
955b3e71 815 // Map of of Solids of Arguments
816 for (i=0; i<2; ++i) {
817 const BOPCol_ListOfShape& aLSA=(i) ? myArguments : myTools;
818 aItLS.Initialize(aLSA);
819 for (; aItLS.More(); aItLS.Next()) {
820 const TopoDS_Shape& aSA=aItLS.Value();
821 aExp.Init(aSA, TopAbs_SOLID);
822 for (; aExp.More(); aExp.Next()) {
823 const TopoDS_Shape& aZA=aExp.Current();
824 aMSA.Add(aZA);
825 //
826 BOPTools::MapShapesAndAncestors(aZA,
827 TopAbs_FACE,
828 TopAbs_SOLID,
829 aMFS);
830 }
831 }
832 }
833 //
834 aNbF=aMFS.Extent();
835 for (i=1; i<aNbF; ++i) {
836 //const TopoDS_Shape& aFA=aMFZA.FindKey(i);
837 const BOPCol_ListOfShape& aLZA=aMFS(i);
838 aNbZ=aLZA.Extent();
839 if (aNbZ > 1) {
840 aItLS.Initialize(aLZA);
841 for(; aItLS.More(); aItLS.Next()) {
842 const TopoDS_Shape& aZA=aItLS.Value();
843 aMZ.Add(aZA);
844 }
845 }
846 }
847 //
848 aMFS.Clear();
849 //
4e57c75e 850 aIt.Initialize(myRC);
851 for (; aIt.More(); aIt.Next()) {
852 const TopoDS_Shape& aSx=aIt.Value();
955b3e71 853 if (aMSA.Contains(aSx)) {
854 iX=myDS->Index(aSx);
855 bHasInterf=myDS->HasInterf(iX);
856 bHasSharedFaces=aMZ.Contains(aSx);
857 //
858 if (!bHasInterf && !bHasSharedFaces) {
859 // It means that the solid aSx will be added
860 // to the result as is.
861 // The solid aSx will not participate
862 // in creation of a new solid(s).
863 BOPTools_Set aST;
864 //
865 aST.Add(aSx, TopAbs_FACE);
866 //
867 if (!aDMSTS.IsBound(aST)) {
868 aDMSTS.Bind(aST, aSx);
869 }
870
871 continue;
872 }
873 }
874 //
4e57c75e 875 aExp.Init(aSx, TopAbs_FACE);
876 for (; aExp.More(); aExp.Next()) {
877 const TopoDS_Shape& aFx=aExp.Current();
878 //
879 aOr=aFx.Orientation();
880 if (aOr==TopAbs_INTERNAL) {
881 aMFI.Add(aFx);
882 continue;
883 }
884 //
885 if (!aMFS.Contains(aFx)) {
886 BOPCol_ListOfShape aLSx;
887 //
888 aLSx.Append(aSx);
889 aMFS.Add(aFx, aLSx);
890 }
891 else {
892 iX=aMFS.FindIndex(aFx);
893 const TopoDS_Shape& aFx1=aMFS.FindKey(iX);
894 aOr1=aFx1.Orientation();
895 if (aOr1!=aOr) {
896 BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx);
897 aLSx.Append(aSx);
898 aMFS.Add(aFx, aLSx);
899 }
900 }
901 }
955b3e71 902 } // for (; aIt.More(); aIt.Next()) {
8620e18d 903 //faces that will be added in the end;
904 BOPCol_ListOfShape aLF, aLFx;
4e57c75e 905 // SFS
906 aNbF=aMFS.Extent();
907 for (i=1; i<=aNbF; ++i) {
908 const TopoDS_Shape& aFx=aMFS.FindKey(i);
909 const BOPCol_ListOfShape& aLSx=aMFS(i);
910 aNbSx=aLSx.Extent();
911 if (aNbSx==1) {
8620e18d 912 BOPTools::MapShapesAndAncestors
913 (aFx,TopAbs_EDGE, TopAbs_FACE, aMEF);
4e57c75e 914 if (IsBoundSplits(aFx, aMEF)){
915 aLFx.Append(aFx);
916 continue;
917 }
918 aLF.Append(aFx);
919 }
920 }
921
922 aItLS.Initialize(aLF);
923 for(; aItLS.More(); aItLS.Next()) {
924 const TopoDS_Shape& aFx=aItLS.Value();
925 aSFS.Append(aFx);
926 }
927 // add faces from aLFx to aSFS;
928 aItLS.Initialize(aLFx);
929 for (; aItLS.More(); aItLS.Next()) {
930 const TopoDS_Shape& aFx=aItLS.Value();
931 aSFS.Append(aFx);
932 }
933 //
934 aNbF=aMFI.Extent();
935 for (i=1; i<=aNbF; ++i) {
936 TopoDS_Shape aFx;
937 //
938 aFx=aMFI.FindKey(i);
939 aFx.Orientation(TopAbs_FORWARD);
940 aSFS.Append(aFx);
941 aFx.Orientation(TopAbs_REVERSED);
942 aSFS.Append(aFx);
943 }
944 //
945 // BuilderSolid
946 BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);
947 //
948 aSB.SetContext(myContext);
949 aSB.SetShapes(aSFS);
950 aSB.Perform();
951 iErr=aSB.ErrorStatus();
952 if (iErr) {
953 myErrorStatus=30; // SolidBuilder failed
954 return;
955 }
956 //
957 const BOPCol_ListOfShape& aLSR=aSB.Areas();
958 //
959 aItLS.Initialize(aLSR);
960 for (; aItLS.More(); aItLS.Next()) {
961 const TopoDS_Shape& aSR=aItLS.Value();
962 aBB.Add(aRC, aSR);
963 }
955b3e71 964 //
965 aItDMSTS.Initialize(aDMSTS);
966 for (; aItDMSTS.More(); aItDMSTS.Next()) {
967 const TopoDS_Shape& aSx=aItDMSTS.Value();
968 aBB.Add(aRC, aSx);
969 }
970 //
4e57c75e 971 myShape=aRC;
972}
4e57c75e 973//=======================================================================
85915310 974//function : IsBoundSplits
4e57c75e 975//purpose :
976//=======================================================================
8620e18d 977Standard_Boolean BOPAlgo_BOP::IsBoundSplits
978 (const TopoDS_Shape& aS,
979 BOPCol_IndexedDataMapOfShapeListOfShape& aMEF)
4e57c75e 980{
981 Standard_Boolean bRet = Standard_False;
982 if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) {
983 return !bRet;
984 }
985
986 BOPCol_ListIteratorOfListOfShape aIt;
987 Standard_Integer aNbLS;
988 TopAbs_Orientation anOr;
989 //
990 //check face aF may be connected to face from mySplits
991 TopExp_Explorer aExp(aS, TopAbs_EDGE);
992 for (; aExp.More(); aExp.Next()) {
993 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
994 //
995 anOr = aE.Orientation();
996 if (anOr==TopAbs_INTERNAL) {
997 continue;
998 }
999 //
1000 if (BRep_Tool::Degenerated(aE)) {
1001 continue;
1002 }
1003 //
1004 const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE);
1005 aNbLS = aLS.Extent();
1006 if (!aNbLS) {
1007 continue;
1008 }
1009 //
1010 aIt.Initialize(aLS);
1011 for (; aIt.More(); aIt.Next()) {
1012 const TopoDS_Shape& aSx = aIt.Value();
8620e18d 1013 if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) {
4e57c75e 1014 return !bRet;
1015 }
1016 }
1017 }
8620e18d 1018 //
4e57c75e 1019 return bRet;
1020}
8620e18d 1021//=======================================================================
1022//function : TypeToExplore
1023//purpose :
1024//=======================================================================
1025TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
1026{
1027 TopAbs_ShapeEnum aRet;
1028 //
1029 switch(theDim) {
1030 case 0:
1031 aRet=TopAbs_VERTEX;
1032 break;
1033 case 1:
1034 aRet=TopAbs_EDGE;
1035 break;
1036 case 2:
1037 aRet=TopAbs_FACE;
1038 break;
1039 case 3:
1040 aRet=TopAbs_SOLID;
1041 break;
1042 default:
1043 aRet=TopAbs_SHAPE;
1044 break;
1045 }
1046 return aRet;
1047}