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