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