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