0026682: TopExp::MapShapesAndAncestors() will build map with duplicated ancestors.
[occt.git] / src / BOPAlgo / BOPAlgo_CellsBuilder.cxx
CommitLineData
338434c7 1// Created by: Eugeny MALTCHIKOV
2// Copyright (c) 2015 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15
16#include <BOPAlgo_CellsBuilder.hxx>
17
18#include <TopoDS_Compound.hxx>
19
20#include <BRep_Builder.hxx>
21
22#include <TopExp_Explorer.hxx>
23
24#include <BOPTools.hxx>
25#include <BOPTools_AlgoTools.hxx>
26
27#include <BOPAlgo_BuilderSolid.hxx>
28
29#include <ShapeUpgrade_UnifySameDomain.hxx>
30
31
32static
33 TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim);
34
35static
36 void MakeTypedContainers(const TopoDS_Shape& theSC,
37 const TopAbs_ShapeEnum aType,
38 TopoDS_Shape& theResult);
39
40//=======================================================================
41//function : empty constructor
42//purpose :
43//=======================================================================
44BOPAlgo_CellsBuilder::BOPAlgo_CellsBuilder()
45:
46 BOPAlgo_Builder(),
47 myType(TopAbs_SHAPE),
48 myIndex(100, myAllocator),
49 myMaterials(100, myAllocator),
50 myShapeMaterial(100, myAllocator),
51 myMapGenerated(100, myAllocator)
52{
53}
54
55//=======================================================================
56//function : empty constructor
57//purpose :
58//=======================================================================
59BOPAlgo_CellsBuilder::BOPAlgo_CellsBuilder
60 (const Handle(NCollection_BaseAllocator)& theAllocator)
61:
62 BOPAlgo_Builder(theAllocator),
63 myType(TopAbs_SHAPE),
64 myIndex(100, myAllocator),
65 myMaterials(100, myAllocator),
66 myShapeMaterial(100, myAllocator),
67 myMapGenerated(100, myAllocator)
68{
69}
70
71//=======================================================================
72//function : ~
73//purpose :
74//=======================================================================
75BOPAlgo_CellsBuilder::~BOPAlgo_CellsBuilder()
76{
77 Clear();
78}
79
80
81//=======================================================================
82//function : Clear
83//purpose :
84//=======================================================================
85void BOPAlgo_CellsBuilder::Clear()
86{
87 BOPAlgo_Builder::Clear();
88 myIndex.Clear();
89 myMaterials.Clear();
90 myShapeMaterial.Clear();
91 myMapGenerated.Clear();
92}
93
94//=======================================================================
95//function : GetAllParts
96//purpose :
97//=======================================================================
98const TopoDS_Shape& BOPAlgo_CellsBuilder::GetAllParts() const
99{
100 return myAllParts;
101}
102
103//=======================================================================
104//function : Prepare
105//purpose :
106//=======================================================================
107void BOPAlgo_CellsBuilder::Prepare()
108{
109 BOPAlgo_Builder::Prepare();
110 //
111 myFlagHistory=Standard_False;
112}
113
114//=======================================================================
115// function: CheckData
116// purpose:
117//=======================================================================
118void BOPAlgo_CellsBuilder::CheckData()
119{
120 BOPAlgo_Builder::CheckData();
121 if (myErrorStatus) {
122 return;
123 }
124 //
125 // additional check for the arguments to be of the same dimension.
126 Standard_Integer aDim1, aDimi;
127 BOPCol_ListIteratorOfListOfShape aIt;
128 //
129 aIt.Initialize(myArguments);
130 const TopoDS_Shape& aS1 = aIt.Value();
131 aDim1 = BOPTools_AlgoTools::Dimension(aS1);
132 //
133 for (aIt.Next(); aIt.More(); aIt.Next()) {
134 const TopoDS_Shape& aSi = aIt.Value();
135 aDimi = BOPTools_AlgoTools::Dimension(aSi);
136 //
137 if (aDim1 != aDimi) {
138 myErrorStatus = 201; // non-homogenous arguments
139 break;
140 }
141 }
142}
143
144//=======================================================================
145//function : PerformInternal1
146//purpose :
147//=======================================================================
148void BOPAlgo_CellsBuilder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
149{
150 BOPAlgo_Builder::PerformInternal1(theFiller);
151 //
152 if (myErrorStatus) {
153 return;
154 }
155 //
156 // save the splits to <myAllParts>
157 TakeAllParts();
158 //
159 // index all the parts to its origins
160 IndexParts();
161 //
162 // and nullify <myShape> for building the result;
163 RemoveAllFromResult();
164 //
165 myFlagHistory = Standard_True;
166}
167
168//=======================================================================
169//function : TakeAllParts
170//purpose :
171//=======================================================================
172void BOPAlgo_CellsBuilder::TakeAllParts()
173{
174 Standard_Integer aDim;
175 TopoDS_Compound aC;
176 BRep_Builder aBB;
177 //
178 aDim = BOPTools_AlgoTools::Dimension(myArguments.First());
179 myType = TypeToExplore(aDim);
180 //
181 aBB.MakeCompound(aC);
182 TopExp_Explorer aExp(myShape, myType);
183 for (; aExp.More(); aExp.Next()) {
184 const TopoDS_Shape& aS = aExp.Current();
185 aBB.Add(aC, aS);
186 }
187 myAllParts = aC;
188}
189
190//=======================================================================
191//function : IndexParts
192//purpose :
193//=======================================================================
194void BOPAlgo_CellsBuilder::IndexParts()
195{
196 BOPCol_ListIteratorOfListOfShape aIt, aItIm;
197 TopExp_Explorer aExp;
198 //
199 aIt.Initialize(myArguments);
200 for (; aIt.More(); aIt.Next()) {
201 const TopoDS_Shape& aS = aIt.Value();
202 //
203 aExp.Init(aS, myType);
204 for (; aExp.More(); aExp.Next()) {
205 const TopoDS_Shape& aST = aExp.Current();
dd115e12 206 const BOPCol_ListOfShape* pLSIm = myImages.Seek(aST);
207 if (!pLSIm) {
208 BOPCol_ListOfShape* pLS = myIndex.ChangeSeek(aST);
209 if (!pLS) {
210 pLS = &myIndex(myIndex.Add(aST, BOPCol_ListOfShape()));
211 }
212 pLS ->Append(aS);
338434c7 213 continue;
214 }
215 //
dd115e12 216 aItIm.Initialize(*pLSIm);
338434c7 217 for (; aItIm.More(); aItIm.Next()) {
218 const TopoDS_Shape& aSTIm = aItIm.Value();
219 //
dd115e12 220 BOPCol_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
221 if (!pLS) {
222 pLS = &myIndex(myIndex.Add(aSTIm, BOPCol_ListOfShape()));
338434c7 223 }
dd115e12 224 pLS ->Append(aS);
338434c7 225 } // for (; aItIm.More(); aItIm.Next()) {
226 } // for (; aExp.More(); aExp.Next()) {
227 } // for (; aIt.More(); aIt.Next()) {
228}
229
230//=======================================================================
231//function : AddToResult
232//purpose :
233//=======================================================================
234void BOPAlgo_CellsBuilder::AddToResult(const BOPCol_ListOfShape& theLSToTake,
235 const BOPCol_ListOfShape& theLSToAvoid,
236 const Standard_Integer theMaterial,
237 const Standard_Boolean theUpdate)
238{
239 // find parts
240 BOPCol_ListOfShape aParts;
241 FindParts(theLSToTake, theLSToAvoid, aParts);
242 if (aParts.IsEmpty()) {
243 return;
244 }
245 //
246 Standard_Boolean bChanged;
247 BRep_Builder aBB;
248 BOPCol_MapOfShape aResParts;
249 TopExp_Explorer aExp;
250 BOPCol_ListIteratorOfListOfShape aIt;
251 //
252 bChanged = Standard_False;
253 // collect result parts to avoid multiple adding of the same parts
254 aExp.Init(myShape, myType);
255 for (; aExp.More(); aExp.Next()) {
256 const TopoDS_Shape& aPart = aExp.Current();
257 aResParts.Add(aPart);
258 }
259 // add parts to result
260 aIt.Initialize(aParts);
261 for (; aIt.More(); aIt.Next()) {
262 const TopoDS_Shape& aPart = aIt.Value();
263 if (aResParts.Add(aPart)) {
264 aBB.Add(myShape, aPart);
265 bChanged = Standard_True;
266 }
267 }
268 //
269 // update the material
270 if (theMaterial != 0) {
271 BOPCol_ListOfShape aLSP;
272 aIt.Initialize(aParts);
273 for (; aIt.More(); aIt.Next()) {
274 const TopoDS_Shape& aPart = aIt.Value();
275 if (!myShapeMaterial.IsBound(aPart)) {
276 myShapeMaterial.Bind(aPart, theMaterial);
277 aLSP.Append(aPart);
278 }
279 } // for (; aIt.More(); aIt.Next()) {
280 //
281 if (aLSP.Extent()) {
282 if (myMaterials.IsBound(theMaterial)) {
283 BOPCol_ListOfShape& aLS = myMaterials.ChangeFind(theMaterial);
284 aLS.Append(aLSP);
285 } // if (myMaterials.IsBound(theMaterial)) {
286 else {
287 myMaterials.Bind(theMaterial, aLSP);
288 }
289 } // if (aLSP.Extent()) {
290 } // if (theMaterial != 0) {
291 //
292 if (!theUpdate) {
293 if (bChanged) {
294 PrepareHistory();
295 }
296 }
297 else {
298 RemoveInternalBoundaries();
299 }
300}
301
302//=======================================================================
303//function : AddAllToResult
304//purpose :
305//=======================================================================
306void BOPAlgo_CellsBuilder::AddAllToResult(const Standard_Integer theMaterial,
307 const Standard_Boolean theUpdate)
308{
309 TopoDS_Compound aResult;
310 BRep_Builder aBB;
311 BOPCol_ListOfShape aLSM;
312 //
313 aBB.MakeCompound(aResult);
314 myShapeMaterial.Clear();
315 myMaterials.Clear();
316 myMapGenerated.Clear();
317 //
318 TopoDS_Iterator aIt(myAllParts);
319 for (; aIt.More(); aIt.Next()) {
320 const TopoDS_Shape& aPart = aIt.Value();
321 aBB.Add(aResult, aPart);
322 //
323 if (theMaterial != 0) {
324 myShapeMaterial.Bind(aPart, theMaterial);
325 aLSM.Append(aPart);
326 }
327 }
328 //
329 myShape = aResult;
330 //
331 if (theMaterial != 0) {
332 myMaterials.Bind(theMaterial, aLSM);
333 }
334 //
335 if (!theUpdate) {
336 PrepareHistory();
337 }
338 else {
339 RemoveInternalBoundaries();
340 }
341}
342
343//=======================================================================
344//function : RemoveFromResult
345//purpose :
346//=======================================================================
347void BOPAlgo_CellsBuilder::RemoveFromResult(const BOPCol_ListOfShape& theLSToTake,
348 const BOPCol_ListOfShape& theLSToAvoid)
349{
350 // find parts
351 BOPCol_ListOfShape aParts;
352 FindParts(theLSToTake, theLSToAvoid, aParts);
353 if (aParts.IsEmpty()) {
354 return;
355 }
356 //
357 BOPCol_MapOfShape aPartsToRemove;
358 BOPCol_ListIteratorOfListOfShape aItP, aItM;
359 //
360 // collect parts into the map and remove parts from materials
361 aItP.Initialize(aParts);
362 for (; aItP.More(); aItP.Next()) {
363 const TopoDS_Shape& aPart = aItP.Value();
364 aPartsToRemove.Add(aPart);
365 //
366 if (myShapeMaterial.IsBound(aPart)) {
367 Standard_Integer iMaterial = myShapeMaterial.Find(aPart);
368 if (!myMaterials.IsBound(iMaterial)) {
369 myShapeMaterial.UnBind(aPart);
370 continue;
371 }
372 //
373 BOPCol_ListOfShape& aLSM = myMaterials.ChangeFind(iMaterial);
374 //
375 aItM.Initialize(aLSM);
376 for (; aItM.More(); aItM.Next()) {
377 const TopoDS_Shape& aSM = aItM.Value();
378 if (aSM.IsSame(aPart)) {
379 aLSM.Remove(aItM);
380 break;
381 } // if (aSM.IsSame(aPart)) {
382 } // for (; aItM.More(); aItM.Next()) {
383 //
384 myShapeMaterial.UnBind(aPart);
385 } // if (myShapeMaterial.IsBound(aPart)) {
386 } // for (; aItP.More(); aItP.Next()) {
387 //
388 Standard_Boolean bChanged;
389 TopoDS_Compound aResult;
390 BRep_Builder aBB;
391 TopoDS_Iterator aIt1, aIt2;
392 TopAbs_ShapeEnum aType;
393 //
394 aBB.MakeCompound(aResult);
395 bChanged = Standard_False;
396 //
397 aIt1.Initialize(myShape);
398 for (; aIt1.More(); aIt1.Next()) {
399 const TopoDS_Shape& aS = aIt1.Value();
400 aType = aS.ShapeType();
401 //
402 if (aType == myType) {
403 // basic element
404 if (aPartsToRemove.Contains(aS)) {
405 bChanged = Standard_True;
406 continue;
407 }
408 aBB.Add(aResult, aS);
409 } // if (aType == myType) {
410 else {
411 // container
412 Standard_Boolean bNotEmpty;
413 TopoDS_Compound aSC;
414 aBB.MakeCompound(aSC);
415 //
416 bNotEmpty = Standard_False;
417 aIt2.Initialize(aS);
418 for (; aIt2.More(); aIt2.Next()) {
419 const TopoDS_Shape& aSS = aIt2.Value();
420 if (aPartsToRemove.Contains(aSS)) {
421 bChanged = Standard_True;
422 continue;
423 }
424 aBB.Add(aSC, aSS);
425 bNotEmpty = Standard_True;
426 } // for (; aIt2.More(); aIt2.Next()) {
427 //
428 if (bNotEmpty) {
429 MakeTypedContainers(aSC, myType, aResult);
430 }
431 } // else {
432 } // for (; aIt1.More(); aIt1.Next()) {
433 //
434 if (bChanged) {
435 myShape = aResult;
436 //
437 PrepareHistory();
438 }
439}
440
441//=======================================================================
442//function : RemoveAllFromResult
443//purpose :
444//=======================================================================
445void BOPAlgo_CellsBuilder::RemoveAllFromResult()
446{
447 // empty compound
448 TopoDS_Compound aC;
449 BRep_Builder aBB;
450 //
451 aBB.MakeCompound(aC);
452 myShape = aC;
453 //
454 myMaterials.Clear();
455 myShapeMaterial.Clear();
456 myMapGenerated.Clear();
457 //
458 PrepareHistory();
459}
460
461//=======================================================================
462//function : RemoveInternalBoundaries
463//purpose :
464//=======================================================================
465void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
466{
467 if (myMaterials.IsEmpty()) {
468 return;
469 }
470 //
471 Standard_Integer iMaterial, iErr;
472 TopoDS_Compound aResult;
473 BRep_Builder aBB;
474 TopExp_Explorer aExp;
475 BOPCol_ListIteratorOfListOfShape aItS;
476 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfShape aItM;
477 //
478 aBB.MakeCompound(aResult);
479 aExp.Init(myShape, myType);
480 for (; aExp.More(); aExp.Next()) {
481 const TopoDS_Shape& aS = aExp.Current();
482 if (!myShapeMaterial.IsBound(aS)) {
483 aBB.Add(aResult, aS);
484 }
485 }
486 //
487 aItM.Initialize(myMaterials);
488 for (; aItM.More(); aItM.Next()) {
489 iMaterial = aItM.Key();
490 //
491 BOPCol_ListOfShape aLSNew;
492 BOPCol_ListOfShape& aLS = myMaterials(iMaterial);
493 iErr = RemoveInternals(aLS, aLSNew);
494 if (iErr || aLSNew.IsEmpty()) {
495 myErrorStatus = 202; // unable to remove internal boundaries
496 return;
497 }
498 //
499 // update materials maps and add new shapes to result
500 aLS.Assign(aLSNew);
501 aItS.Initialize(aLSNew);
502 for (; aItS.More(); aItS.Next()) {
503 const TopoDS_Shape& aS = aItS.Value();
504 aBB.Add(aResult, aS);
505 if (!myShapeMaterial.IsBound(aS)) {
506 myShapeMaterial.Bind(aS, iMaterial);
507 }
508 }
509 }
510 //
511 myShape = aResult;
512 //
513 PrepareHistory();
514}
515
516//=======================================================================
517//function : FindPart
518//purpose :
519//=======================================================================
520void BOPAlgo_CellsBuilder::FindParts(const BOPCol_ListOfShape& theLSToTake,
521 const BOPCol_ListOfShape& theLSToAvoid,
522 BOPCol_ListOfShape& theParts)
523{
524 if (theLSToTake.IsEmpty()) {
525 return;
526 }
527 //
528 Standard_Boolean bFound;
529 Standard_Integer aNbS;
530 BOPCol_ListIteratorOfListOfShape aItIm, aItArgs;
531 BOPCol_MapOfShape aMSToTake, aMSToAvoid, aMS;
532 TopExp_Explorer aExp;
533 //
534 aItArgs.Initialize(theLSToAvoid);
535 for (; aItArgs.More(); aItArgs.Next()) {
536 const TopoDS_Shape& aS = aItArgs.Value();
537 aMSToAvoid.Add(aS);
538 }
539 //
540 aItArgs.Initialize(theLSToTake);
541 for (; aItArgs.More(); aItArgs.Next()) {
542 const TopoDS_Shape& aS = aItArgs.Value();
543 aMSToTake.Add(aS);
544 }
545 //
546 aNbS = aMSToTake.Extent();
547 //
548 const TopoDS_Shape& aSToTake = theLSToTake.First();
549 aExp.Init(aSToTake, myType);
550 for (; aExp.More(); aExp.Next()) {
551 const TopoDS_Shape& aST = aExp.Current();
552 BOPCol_ListOfShape aLSTIm;
553 if (!myImages.IsBound(aST)) {
554 aLSTIm.Append(aST);
555 } else {
556 aLSTIm = myImages.Find(aST);
557 }
558 //
559 aItIm.Initialize(aLSTIm);
560 for (; aItIm.More(); aItIm.Next()) {
561 const TopoDS_Shape& aPart = aItIm.Value();
562 //
563 if (!myIndex.Contains(aPart)) {
564 continue;
565 }
566 //
567 const BOPCol_ListOfShape& aLS = myIndex.FindFromKey(aPart);
568 if (aLS.Extent() < aNbS) {
569 continue;
570 }
571 //
572 aMS.Clear();
573 aItArgs.Initialize(aLS);
574 for (bFound = Standard_True; aItArgs.More() && bFound; aItArgs.Next()) {
575 const TopoDS_Shape& aS = aItArgs.Value();
576 bFound = !aMSToAvoid.Contains(aS);
577 aMS.Add(aS);
578 }
579 //
580 if (!bFound) {
581 continue;
582 }
583 //
584 aItArgs.Initialize(theLSToTake);
585 for (; aItArgs.More() && bFound; aItArgs.Next()) {
586 const TopoDS_Shape& aS = aItArgs.Value();
587 bFound = aMS.Contains(aS);
588 }
589 //
590 if (bFound) {
591 theParts.Append(aPart);
592 } // if (bFound) {
593 } // for (; aItIm.More(); aItIm.Next()) {
594 } // for (; aExp.More(); aExp.Next()) {
595}
596
597//=======================================================================
598//function : MakeContainers
599//purpose :
600//=======================================================================
601void BOPAlgo_CellsBuilder::MakeContainers()
602{
603 TopoDS_Compound aResult;
604 BRep_Builder aBB;
605 //
606 aBB.MakeCompound(aResult);
607 MakeTypedContainers(myShape, myType, aResult);
608 myShape = aResult;
609}
610
611//=======================================================================
612//function : RemoveInternals
613//purpose :
614//=======================================================================
615Standard_Integer BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape& theLS,
616 BOPCol_ListOfShape& theLSNew)
617{
618 Standard_Integer iErr = 0;
619 if (theLS.Extent() < 2) {
620 theLSNew = theLS;
621 return iErr;
622 }
e71669c6 623 //
338434c7 624 TopExp_Explorer aExp;
625 //
626 TopAbs_ShapeEnum aType = theLS.First().ShapeType();
627 //
628 if (aType == TopAbs_EDGE ||
629 aType == TopAbs_FACE) {
630 //
631 // make container
632 BRep_Builder aBB;
633 TopoDS_Shape aShape;
634 //
635 BOPTools_AlgoTools::MakeContainer
636 ((aType == TopAbs_FACE) ? TopAbs_SHELL : TopAbs_WIRE, aShape);
637 //
e71669c6 638 for (BOPCol_ListIteratorOfListOfShape aIt(theLS); aIt.More(); aIt.Next()) {
338434c7 639 const TopoDS_Shape& aS = aIt.Value();
640 aBB.Add(aShape, aS);
641 }
642 //
643 // Unify same domain
644 Standard_Boolean bFaces, bEdges;
645 //
646 bFaces = (aType == TopAbs_FACE);
647 bEdges = (aType == TopAbs_EDGE);
648 //
649 ShapeUpgrade_UnifySameDomain anUnify (aShape, bEdges, bFaces);
650 anUnify.Build();
651 const TopoDS_Shape& aSNew = anUnify.Shape();
652 //
653 aExp.Init(aSNew, aType);
654 for (; aExp.More(); aExp.Next()) {
655 const TopoDS_Shape& aSn = aExp.Current();
656 theLSNew.Append(aSn);
657 }
658 //
659 // fill map of generated shapes
660 BOPCol_IndexedMapOfShape aMG;
661 Standard_Integer i, aNb;
662 //
663 BOPTools::MapShapes(aShape, TopAbs_VERTEX, aMG);
664 BOPTools::MapShapes(aShape, TopAbs_EDGE, aMG);
665 BOPTools::MapShapes(aShape, TopAbs_FACE, aMG);
666 //
667 aNb = aMG.Extent();
668 for (i = 1; i <= aNb; ++i) {
669 const TopoDS_Shape& aSS = aMG(i);
e71669c6 670 const TopoDS_Shape& aSGen = anUnify.Generated(aSS);
671 if (!aSGen.IsNull() && !aSS.IsSame(aSGen)) {
672 myMapGenerated.Bind(aSS, aSGen);
338434c7 673 }
674 }
675 }
676 else if (aType == TopAbs_SOLID) {
677 // build all solids from the faces
678 BOPCol_ListOfShape aLSF;
679 //
e71669c6 680 for (BOPCol_ListIteratorOfListOfShape aIt(theLS); aIt.More(); aIt.Next()) {
338434c7 681 const TopoDS_Shape& aS = aIt.Value();
682 //
683 aExp.Init(aS, TopAbs_FACE);
684 for (; aExp.More(); aExp.Next()) {
685 const TopoDS_Shape& aF = aExp.Current();
686 aLSF.Append(aF);
687 }
688 }
689 //
690 BOPAlgo_BuilderSolid aBS;
691 aBS.SetShapes(aLSF);
692 aBS.Perform();
693 //
694 iErr = aBS.ErrorStatus();
695 if (iErr) {
696 return iErr;
697 }
698 //
699 theLSNew = aBS.Areas();
700 if (theLSNew.Extent() == 1) {
701 return iErr;
702 }
703 //
704 // result is a list of solids. we need to select external faces.
705 BOPCol_IndexedDataMapOfShapeListOfShape aDMFS;
706 BOPCol_ListOfShape aLFNew;
707 Standard_Integer i, aNb;
708 //
709 // map faces and solids
e71669c6 710 for (BOPCol_ListIteratorOfListOfShape aIt(theLSNew); aIt.More(); aIt.Next()) {
338434c7 711 const TopoDS_Shape& aS = aIt.Value();
712 //
713 aExp.Init(aS, TopAbs_FACE);
714 for (; aExp.More(); aExp.Next()) {
715 const TopoDS_Shape& aF = aExp.Current();
716 if (aDMFS.Contains(aF)) {
717 BOPCol_ListOfShape& aLFS = aDMFS.ChangeFromKey(aF);
718 aLFS.Append(aS);
719 }
720 else {
721 BOPCol_ListOfShape aLFS;
722 aLFS.Append(aS);
723 aDMFS.Add(aF, aLFS);
724 }
725 }
726 }
727 //
728 // select faces attached to only one solid
729 aNb = aDMFS.Extent();
730 for (i = 1; i <= aNb; ++i) {
731 const BOPCol_ListOfShape& aLS = aDMFS(i);
732 if (aLS.Extent() == 1) {
733 const TopoDS_Shape& aF = aDMFS.FindKey(i);
734 aLFNew.Append(aF);
735 }
736 }
737 //
738 if (aNb == aLFNew.Extent()) {
739 return iErr;
740 }
741 //
742 // build new solid
743 BOPAlgo_BuilderSolid aBS1;
744 aBS1.SetShapes(aLFNew);
745 aBS1.Perform();
746 //
747 iErr = aBS1.ErrorStatus();
748 if (iErr) {
749 return iErr;
750 }
751 //
752 theLSNew = aBS1.Areas();
753 }
754 //
755 return iErr;
756}
757
758//=======================================================================
759//function : IsDeleted
760//purpose :
761//=======================================================================
762Standard_Boolean BOPAlgo_CellsBuilder::IsDeleted(const TopoDS_Shape& theS)
763{
764 Standard_Boolean bRet = Standard_True;
765 if (theS.IsNull()) {
766 return bRet;
767 }
768 //
769 TopAbs_ShapeEnum aType = theS.ShapeType();
770 if (!(aType==TopAbs_EDGE || aType==TopAbs_FACE ||
771 aType==TopAbs_VERTEX || aType==TopAbs_SOLID)) {
772 return bRet;
773 }
774 //
775 Standard_Boolean bHasImage, bHasGenerated;
776 //
777 bHasImage = myImages.IsBound(theS);
778 bHasGenerated = myMapGenerated.IsBound(theS);
779 if (!bHasImage && !bHasGenerated) {
780 bRet = !myMapShape.Contains(theS);
781 return bRet;
782 }
783 //
784 if (bHasGenerated) {
785 const TopoDS_Shape& aSG = myMapGenerated.Find(theS);
786 if (myMapShape.Contains(aSG)) {
787 bRet = Standard_False;
788 return bRet;
789 }
790 }
791 //
792 if (bHasImage) {
793 const BOPCol_ListOfShape& aLSp = myImages.Find(theS);
794 BOPCol_ListIteratorOfListOfShape aIt(aLSp);
795 for (; aIt.More(); aIt.Next()) {
796 const TopoDS_Shape& aSp = aIt.Value();
797 const TopoDS_Shape& aSpR = myShapesSD.IsBound(aSp) ?
798 myShapesSD.Find(aSp) : aSp;
799 //
800 const TopoDS_Shape& aSpRG = myMapGenerated.IsBound(aSpR) ?
801 myMapGenerated.Find(aSpR) : aSpR;
802 if (myMapShape.Contains(aSpRG)) {
803 bRet = Standard_False;
804 break;
805 }
806 }
807 }
808 //
809 return bRet;
810}
811
812//=======================================================================
813//function : Generated
814//purpose :
815//=======================================================================
816const TopTools_ListOfShape& BOPAlgo_CellsBuilder::Generated(const TopoDS_Shape& theS)
817{
818 myHistShapes.Clear();
819 if (theS.IsNull()) {
820 return myHistShapes;
821 }
822 //
823 TopAbs_ShapeEnum aType = theS.ShapeType();
824 if (!(aType==TopAbs_EDGE || aType==TopAbs_FACE || aType==TopAbs_VERTEX)) {
825 return myHistShapes;
826 }
827 //
828 Standard_Boolean bHasGenerated = myMapGenerated.IsBound(theS);
829 if (bHasGenerated) {
830 const TopoDS_Shape& aSG = myMapGenerated.Find(theS);
831 if (myMapShape.Contains(aSG)) {
832 myHistShapes.Append(aSG);
833 }
834 return myHistShapes;
835 }
836 //
837 Standard_Boolean bHasImage = myImages.IsBound(theS);
838 if (!bHasImage) {
839 return myHistShapes;
840 }
841 //
842 BOPCol_MapOfShape aMFence;
843 const BOPCol_ListOfShape& aLSp = myImages.Find(theS);
844 BOPCol_ListIteratorOfListOfShape aIt(aLSp);
845 for (; aIt.More(); aIt.Next()) {
846 const TopoDS_Shape aSp = aIt.Value();
847 const TopoDS_Shape& aSpR = myShapesSD.IsBound(aSp) ?
848 myShapesSD.Find(aSp) : aSp;
849 //
850 if (myMapGenerated.IsBound(aSpR)) {
851 const TopoDS_Shape& aSG = myMapGenerated.Find(aSpR);
852 if (myMapShape.Contains(aSG)) {
853 if (aMFence.Add(aSG)) {
854 myHistShapes.Append(aSG);
855 }
856 }
857 }
858 }
859 //
860 return myHistShapes;
861}
862
863//=======================================================================
864//function : MakeTypedContainers
865//purpose :
866//=======================================================================
867void MakeTypedContainers(const TopoDS_Shape& theSC,
868 const TopAbs_ShapeEnum aType,
869 TopoDS_Shape& theResult)
870{
871 TopAbs_ShapeEnum aContainerType, aConnexityType, aPartType;
872 //
873 aPartType = aType;
874 switch (aPartType) {
875 case TopAbs_EDGE: {
876 aContainerType = TopAbs_WIRE;
877 aConnexityType = TopAbs_VERTEX;
878 break;
879 }
880 case TopAbs_FACE: {
881 aContainerType = TopAbs_SHELL;
882 aConnexityType = TopAbs_EDGE;
883 break;
884 }
885 case TopAbs_SOLID: {
886 aContainerType = TopAbs_COMPSOLID;
887 aConnexityType = TopAbs_FACE;
888 break;
889 }
890 default:
891 return;
892 }
893 //
894 BOPCol_ListOfShape aLCB;
895 BOPTools_AlgoTools::MakeConnexityBlocks(theSC, aConnexityType, aPartType, aLCB);
896 if (aLCB.IsEmpty()) {
897 return;
898 }
899 //
900 BRep_Builder aBB;
901 TopExp_Explorer aExp;
902 BOPCol_ListIteratorOfListOfShape aItCB;
903 //
904 aItCB.Initialize(aLCB);
905 for (; aItCB.More(); aItCB.Next()) {
906 TopoDS_Shape aRCB;
907 BOPTools_AlgoTools::MakeContainer(aContainerType, aRCB);
908 //
909 const TopoDS_Shape& aCB = aItCB.Value();
910 aExp.Init(aCB, aPartType);
911 for (; aExp.More(); aExp.Next()) {
912 const TopoDS_Shape& aCBS = aExp.Current();
913 aBB.Add(aRCB, aCBS);
914 }
915 //
916 if (aContainerType == TopAbs_SHELL) {
917 BOPTools_AlgoTools::OrientFacesOnShell(aRCB);
918 }
919 //
920 aBB.Add(theResult, aRCB);
921 }
922}
923
924//=======================================================================
925//function : TypeToExplore
926//purpose :
927//=======================================================================
928TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
929{
930 TopAbs_ShapeEnum aRet;
931 //
932 switch(theDim) {
933 case 0:
934 aRet=TopAbs_VERTEX;
935 break;
936 case 1:
937 aRet=TopAbs_EDGE;
938 break;
939 case 2:
940 aRet=TopAbs_FACE;
941 break;
942 case 3:
943 aRet=TopAbs_SOLID;
944 break;
945 default:
946 aRet=TopAbs_SHAPE;
947 break;
948 }
949 return aRet;
950}