1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2015 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <BOPAlgo_CellsBuilder.hxx>
18 #include <TopoDS_Compound.hxx>
20 #include <BRep_Builder.hxx>
23 #include <TopExp_Explorer.hxx>
25 #include <BOPTools.hxx>
26 #include <BOPTools_AlgoTools.hxx>
28 #include <BOPAlgo_BuilderSolid.hxx>
29 #include <BOPAlgo_Alerts.hxx>
31 #include <BOPCol_MapOfInteger.hxx>
33 #include <ShapeUpgrade_UnifySameDomain.hxx>
37 TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim);
40 void MakeTypedContainers(const TopoDS_Shape& theSC,
41 TopoDS_Shape& theResult);
43 static void CollectMaterialBoundaries(const BOPCol_ListOfShape& theLS,
44 TopTools_MapOfShape& theMapKeepBnd);
46 //=======================================================================
47 //function : empty constructor
49 //=======================================================================
50 BOPAlgo_CellsBuilder::BOPAlgo_CellsBuilder()
53 myIndex(100, myAllocator),
54 myMaterials(100, myAllocator),
55 myShapeMaterial(100, myAllocator),
56 myMapModified(100, myAllocator)
60 //=======================================================================
61 //function : empty constructor
63 //=======================================================================
64 BOPAlgo_CellsBuilder::BOPAlgo_CellsBuilder
65 (const Handle(NCollection_BaseAllocator)& theAllocator)
67 BOPAlgo_Builder(theAllocator),
68 myIndex(100, myAllocator),
69 myMaterials(100, myAllocator),
70 myShapeMaterial(100, myAllocator),
71 myMapModified(100, myAllocator)
75 //=======================================================================
78 //=======================================================================
79 BOPAlgo_CellsBuilder::~BOPAlgo_CellsBuilder()
84 //=======================================================================
87 //=======================================================================
88 void BOPAlgo_CellsBuilder::Clear()
90 BOPAlgo_Builder::Clear();
93 myShapeMaterial.Clear();
94 myMapModified.Clear();
97 //=======================================================================
98 //function : GetAllParts
100 //=======================================================================
101 const TopoDS_Shape& BOPAlgo_CellsBuilder::GetAllParts() const
106 //=======================================================================
109 //=======================================================================
110 void BOPAlgo_CellsBuilder::Prepare()
112 BOPAlgo_Builder::Prepare();
114 myFlagHistory=Standard_False;
117 //=======================================================================
118 //function : PerformInternal1
120 //=======================================================================
121 void BOPAlgo_CellsBuilder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
123 BOPAlgo_Builder::PerformInternal1(theFiller);
129 // index all the parts to its origins
132 // and nullify <myShape> for building the result;
133 RemoveAllFromResult();
135 myFlagHistory = Standard_True;
138 //=======================================================================
139 //function : IndexParts
141 //=======================================================================
142 void BOPAlgo_CellsBuilder::IndexParts()
145 // all split parts of the shapes
146 TopoDS_Compound anAllParts;
147 aBB.MakeCompound(anAllParts);
149 BOPCol_MapOfShape aMFence;
150 BOPCol_MapOfInteger aMDims;
152 BOPCol_ListIteratorOfListOfShape aIt(myArguments);
153 for (; aIt.More(); aIt.Next()) {
154 const TopoDS_Shape& aS = aIt.Value();
156 Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
158 TopAbs_ShapeEnum aType = TypeToExplore(iDim);
160 TopExp_Explorer aExp(aS, aType);
161 for (; aExp.More(); aExp.Next()) {
162 const TopoDS_Shape& aST = aExp.Current();
163 const BOPCol_ListOfShape* pLSIm = myImages.Seek(aST);
165 BOPCol_ListOfShape* pLS = myIndex.ChangeSeek(aST);
167 pLS = &myIndex(myIndex.Add(aST, BOPCol_ListOfShape()));
171 if (aMFence.Add(aST)) {
172 aBB.Add(anAllParts, aST);
178 BOPCol_ListIteratorOfListOfShape aItIm(*pLSIm);
179 for (; aItIm.More(); aItIm.Next()) {
180 const TopoDS_Shape& aSTIm = aItIm.Value();
182 BOPCol_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
184 pLS = &myIndex(myIndex.Add(aSTIm, BOPCol_ListOfShape()));
188 if (aMFence.Add(aSTIm)) {
189 aBB.Add(anAllParts, aSTIm);
191 } // for (; aItIm.More(); aItIm.Next()) {
192 } // for (; aExp.More(); aExp.Next()) {
193 } // for (; aIt.More(); aIt.Next()) {
195 myAllParts = anAllParts;
197 if (aMDims.Extent() == 1) {
201 // for the multi-dimensional case
202 // add sub-shapes of the splits into the <myIndex> map
204 Standard_Integer i, aNbS = myIndex.Extent();
205 for (i = 1; i <= aNbS; ++i) {
206 const TopoDS_Shape& aSP = myIndex.FindKey(i);
207 const TopTools_ListOfShape& aLSOr = myIndex(i);
209 Standard_Integer iType = BOPTools_AlgoTools::Dimension(aSP);
210 BOPCol_MapIteratorOfMapOfInteger aItM(aMDims);
211 for (; aItM.More(); aItM.Next()) {
212 Standard_Integer k = aItM.Value();
217 TopExp_Explorer aExp(aSP, TypeToExplore(k));
218 for (; aExp.More(); aExp.Next()) {
219 const TopoDS_Shape& aSS = aExp.Current();
220 BOPCol_ListOfShape* pLSSOr = myIndex.ChangeSeek(aSS);
222 myIndex.Add(aSS, aLSOr);
225 // add ancestors of the shape to the ancestors of the sub-shape
226 BOPCol_ListIteratorOfListOfShape aItLS(aLSOr);
227 for (; aItLS.More(); aItLS.Next()) {
228 const TopoDS_Shape& aSOr = aItLS.Value();
229 // provide uniqueness of the ancestors
230 BOPCol_ListIteratorOfListOfShape aItLSS(*pLSSOr);
231 for (; aItLSS.More(); aItLSS.Next()) {
232 if (aSOr.IsSame(aItLSS.Value())) {
237 if (!aItLSS.More()) {
238 pLSSOr->Append(aSOr);
246 //=======================================================================
247 //function : AddToResult
249 //=======================================================================
250 void BOPAlgo_CellsBuilder::AddToResult(const BOPCol_ListOfShape& theLSToTake,
251 const BOPCol_ListOfShape& theLSToAvoid,
252 const Standard_Integer theMaterial,
253 const Standard_Boolean theUpdate)
256 BOPCol_ListOfShape aParts;
257 FindParts(theLSToTake, theLSToAvoid, aParts);
258 if (aParts.IsEmpty()) {
262 // collect result parts to avoid multiple adding of the same parts
263 BOPCol_MapOfShape aResParts;
264 TopoDS_Iterator aIt(myShape);
265 for (; aIt.More(); aIt.Next()) {
266 aResParts.Add(aIt.Value());
269 Standard_Boolean bChanged = Standard_False;
270 // add parts to result
271 BOPCol_ListIteratorOfListOfShape aItLP(aParts);
272 for (; aItLP.More(); aItLP.Next()) {
273 const TopoDS_Shape& aPart = aItLP.Value();
274 // provide uniqueness of the parts
275 if (aResParts.Add(aPart) && !myShapeMaterial.IsBound(aPart)) {
276 BRep_Builder().Add(myShape, aPart);
277 bChanged = Standard_True;
281 // update the material
282 if (theMaterial != 0) {
283 BOPCol_ListOfShape aLSP;
284 aItLP.Initialize(aParts);
285 for (; aItLP.More(); aItLP.Next()) {
286 const TopoDS_Shape& aPart = aItLP.Value();
287 if (!myShapeMaterial.IsBound(aPart)) {
288 myShapeMaterial.Bind(aPart, theMaterial);
291 } // for (; aIt.More(); aIt.Next()) {
294 BOPCol_ListOfShape* pLS = myMaterials.ChangeSeek(theMaterial);
296 pLS = myMaterials.Bound(theMaterial, BOPCol_ListOfShape());
299 } // if (aLSP.Extent()) {
300 } // if (theMaterial != 0) {
308 RemoveInternalBoundaries();
312 //=======================================================================
313 //function : AddAllToResult
315 //=======================================================================
316 void BOPAlgo_CellsBuilder::AddAllToResult(const Standard_Integer theMaterial,
317 const Standard_Boolean theUpdate)
319 myShapeMaterial.Clear();
321 myMapModified.Clear();
323 myShape = myAllParts;
325 if (theMaterial != 0) {
326 BOPCol_ListOfShape* pLSM = myMaterials.Bound(theMaterial, BOPCol_ListOfShape());
328 TopoDS_Iterator aIt(myAllParts);
329 for (; aIt.More(); aIt.Next()) {
330 const TopoDS_Shape& aPart = aIt.Value();
331 myShapeMaterial.Bind(aPart, theMaterial);
340 RemoveInternalBoundaries();
344 //=======================================================================
345 //function : RemoveFromResult
347 //=======================================================================
348 void BOPAlgo_CellsBuilder::RemoveFromResult(const BOPCol_ListOfShape& theLSToTake,
349 const BOPCol_ListOfShape& theLSToAvoid)
352 BOPCol_ListOfShape aParts;
353 FindParts(theLSToTake, theLSToAvoid, aParts);
354 if (aParts.IsEmpty()) {
358 // collect parts into the map and remove parts from materials
359 BOPCol_MapOfShape aPartsToRemove;
360 BOPCol_ListIteratorOfListOfShape aItP(aParts);
361 for (; aItP.More(); aItP.Next()) {
362 const TopoDS_Shape& aPart = aItP.Value();
363 aPartsToRemove.Add(aPart);
365 const Standard_Integer* pMaterial = myShapeMaterial.Seek(aPart);
367 BOPCol_ListOfShape* pLSM = myMaterials.ChangeSeek(*pMaterial);
369 BOPCol_ListIteratorOfListOfShape aItM(*pLSM);
370 for (; aItM.More(); aItM.Next()) {
371 if (aPart.IsSame(aItM.Value())) {
377 myShapeMaterial.UnBind(aPart);
382 TopoDS_Compound aResult;
383 aBB.MakeCompound(aResult);
384 Standard_Boolean bChanged = Standard_False;
386 TopoDS_Iterator aIt(myShape);
387 for (; aIt.More(); aIt.Next()) {
388 const TopoDS_Shape& aS = aIt.Value();
389 TopAbs_ShapeEnum aType = aS.ShapeType();
390 if (aType != TopAbs_WIRE &&
391 aType != TopAbs_SHELL &&
392 aType != TopAbs_COMPSOLID) {
394 if (aPartsToRemove.Contains(aS)) {
395 bChanged = Standard_True;
398 aBB.Add(aResult, aS);
403 aBB.MakeCompound(aSC);
404 Standard_Boolean bSCNotEmpty = Standard_False;
406 TopoDS_Iterator aItSC(aS);
407 for (; aItSC.More(); aItSC.Next()) {
408 const TopoDS_Shape& aSS = aItSC.Value();
409 if (aPartsToRemove.Contains(aSS)) {
410 bChanged = Standard_True;
414 bSCNotEmpty = Standard_True;
419 MakeTypedContainers(aSC, aResult);
431 //=======================================================================
432 //function : RemoveAllFromResult
434 //=======================================================================
435 void BOPAlgo_CellsBuilder::RemoveAllFromResult()
439 BRep_Builder().MakeCompound(aC);
443 myShapeMaterial.Clear();
444 myMapModified.Clear();
449 //=======================================================================
450 //function : RemoveInternalBoundaries
452 //=======================================================================
453 void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
455 if (myMaterials.IsEmpty()) {
460 TopoDS_Compound aResult;
461 aBB.MakeCompound(aResult);
463 Standard_Boolean bChanged = Standard_False;
464 // try to remove the internal boundaries between the
465 // shapes of the same material
466 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfShape aItM(myMaterials);
467 BOPCol_ListOfShape aLSUnify[2];
468 TopTools_MapOfShape aKeepMap[2];
469 for (; aItM.More(); aItM.Next()) {
470 Standard_Integer iMaterial = aItM.Key();
471 BOPCol_ListOfShape& aLS = aItM.ChangeValue();
477 if (aLS.Extent() == 1) {
478 TopAbs_ShapeEnum aType = aLS.First().ShapeType();
479 if (aType != TopAbs_WIRE &&
480 aType != TopAbs_SHELL &&
481 aType != TopAbs_COMPSOLID) {
482 aBB.Add(aResult, aLS.First());
487 // check the shapes of the same material to be of the same type
488 BOPCol_ListIteratorOfListOfShape aItLS(aLS);
489 TopAbs_ShapeEnum aType = aItLS.Value().ShapeType();
490 for (aItLS.Next(); aItLS.More(); aItLS.Next()) {
491 if (aType != aItLS.Value().ShapeType()) {
499 TopoDS_Compound aMultiDimS;
500 aBB.MakeCompound(aMultiDimS);
501 aBB.Add(aMultiDimS, aLS.First());
502 aBB.Add(aMultiDimS, aItLS.Value());
503 AddWarning(new BOPAlgo_AlertRemovalOfIBForMDimShapes(aMultiDimS));
507 if (aType == TopAbs_EDGE || aType == TopAbs_FACE)
509 // for edges and faces, just collect shapes to unify them later after exiting the loop;
510 // collect boundaries of shapes of current material in the keep map
511 Standard_Integer iType = (aType == TopAbs_EDGE ? 0 : 1);
512 CollectMaterialBoundaries(aLS, aKeepMap[iType]);
513 // save shapes to unify later
514 BOPCol_ListOfShape aCopy(aLS);
515 aLSUnify[iType].Append(aCopy);
521 // remove internal faces between solids of the same material just now
522 BOPCol_ListOfShape aLSNew;
523 if (RemoveInternals(aLS, aLSNew))
525 bChanged = Standard_True;
526 // update materials maps
527 for (aItLS.Initialize(aLSNew); aItLS.More(); aItLS.Next()) {
528 const TopoDS_Shape& aS = aItLS.Value();
529 myShapeMaterial.Bind(aS, iMaterial);
535 // add shapes to result (multidimensional and solids)
536 for (aItLS.Initialize(aLS); aItLS.More(); aItLS.Next()) {
537 const TopoDS_Shape& aS = aItLS.Value();
538 aBB.Add(aResult, aS);
542 // remove internal boundaries for edges and faces
543 for (Standard_Integer iType = 0; iType < 2; ++iType)
545 if (aLSUnify[iType].IsEmpty())
547 BOPCol_ListOfShape aLSN;
548 if (RemoveInternals(aLSUnify[iType], aLSN, aKeepMap[iType]))
549 bChanged = Standard_True;
550 // add shapes to result ([unified] edges or faces)
551 for (BOPCol_ListIteratorOfListOfShape aItLS(aLSN); aItLS.More(); aItLS.Next()) {
552 const TopoDS_Shape& aS = aItLS.Value();
553 aBB.Add(aResult, aS);
558 // add shapes without material into result
559 TopoDS_Iterator aIt(myShape);
560 for (; aIt.More(); aIt.Next()) {
561 const TopoDS_Shape& aS = aIt.Value();
563 if (myShapeMaterial.IsBound(aS)) {
567 // check if it is not a collection
568 TopAbs_ShapeEnum aType = aS.ShapeType();
569 if (aType != TopAbs_WIRE &&
570 aType != TopAbs_SHELL &&
571 aType != TopAbs_COMPSOLID) {
572 aBB.Add(aResult, aS);
576 aBB.MakeCompound(aSC);
577 Standard_Boolean bSCEmpty(Standard_True), bSCChanged(Standard_False);
579 TopoDS_Iterator aItSC(aS);
580 for (; aItSC.More(); aItSC.Next()) {
581 const TopoDS_Shape& aSS = aItSC.Value();
582 if (!myShapeMaterial.IsBound(aSS)) {
584 bSCEmpty = Standard_False;
587 bSCChanged = Standard_True;
596 MakeTypedContainers(aSC, aResult);
599 aBB.Add(aResult, aS);
610 //=======================================================================
611 //function : FindPart
613 //=======================================================================
614 void BOPAlgo_CellsBuilder::FindParts(const BOPCol_ListOfShape& theLSToTake,
615 const BOPCol_ListOfShape& theLSToAvoid,
616 BOPCol_ListOfShape& theParts)
618 if (theLSToTake.IsEmpty()) {
622 // map shapes to avoid
623 BOPCol_MapOfShape aMSToAvoid;
624 BOPCol_ListIteratorOfListOfShape aItArgs(theLSToAvoid);
625 for (; aItArgs.More(); aItArgs.Next()) {
626 const TopoDS_Shape& aS = aItArgs.Value();
630 // map shapes to be taken
631 BOPCol_MapOfShape aMSToTake;
632 aItArgs.Initialize(theLSToTake);
633 for (; aItArgs.More(); aItArgs.Next()) {
634 const TopoDS_Shape& aS = aItArgs.Value();
638 Standard_Integer aNbS = aMSToTake.Extent();
640 // among the shapes to be taken into result, find any one
641 // of minimal dimension
642 Standard_Integer iDimMin = 10;
645 aItArgs.Initialize(theLSToTake);
646 for (; aItArgs.More(); aItArgs.Next()) {
647 const TopoDS_Shape& aS = aItArgs.Value();
648 Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
649 if (iDim < iDimMin) {
655 // among the split parts of the shape of minimal dimension
656 // look for the parts to be taken into result
657 TopAbs_ShapeEnum aType = TypeToExplore(iDimMin);
658 TopExp_Explorer aExp(aSMin, aType);
659 for (; aExp.More(); aExp.Next()) {
660 const TopoDS_Shape& aST = aExp.Current();
661 // get split parts of the shape
662 BOPCol_ListOfShape aLSTIm;
663 if (!myImages.IsBound(aST)) {
666 aLSTIm = myImages.Find(aST);
669 BOPCol_ListIteratorOfListOfShape aItIm(aLSTIm);
670 for (; aItIm.More(); aItIm.Next()) {
671 const TopoDS_Shape& aPart = aItIm.Value();
673 if (!myIndex.Contains(aPart)) {
677 // get input shapes in which the split part is contained
678 const BOPCol_ListOfShape& aLS = myIndex.FindFromKey(aPart);
679 if (aLS.Extent() < aNbS) {
683 // check that input shapes containing the part should not be avoided
684 BOPCol_MapOfShape aMS;
685 aItArgs.Initialize(aLS);
686 for (; aItArgs.More(); aItArgs.Next()) {
687 const TopoDS_Shape& aS = aItArgs.Value();
689 if (aMSToAvoid.Contains(aS)) {
694 if (aItArgs.More()) {
698 // check that all shapes which should be taken contain the part
699 aItArgs.Initialize(theLSToTake);
700 for (; aItArgs.More(); aItArgs.Next()) {
701 if (!aMS.Contains(aItArgs.Value())) {
706 if (!aItArgs.More()) {
707 theParts.Append(aPart);
713 //=======================================================================
714 //function : MakeContainers
716 //=======================================================================
717 void BOPAlgo_CellsBuilder::MakeContainers()
720 TopoDS_Compound aResult;
721 aBB.MakeCompound(aResult);
723 // basic elements of type EDGE, FACE and SOLID added into result
724 BOPCol_ListOfShape aLS[3];
726 TopoDS_Iterator aIt(myShape);
727 for (; aIt.More(); aIt.Next()) {
728 const TopoDS_Shape& aS = aIt.Value();
730 Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
732 aBB.Add(aResult, aS);
736 aLS[iDim-1].Append(aS);
739 for (Standard_Integer i = 0; i < 3; ++i) {
740 if (aLS[i].IsEmpty()) {
745 aBB.MakeCompound(aC);
746 BOPCol_ListIteratorOfListOfShape aItLS(aLS[i]);
747 for (; aItLS.More(); aItLS.Next()) {
748 aBB.Add(aC, aItLS.Value());
751 MakeTypedContainers(aC, aResult);
756 //=======================================================================
757 //function : RemoveInternals
759 //=======================================================================
760 Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape& theLS,
761 BOPCol_ListOfShape& theLSNew,
762 const TopTools_MapOfShape& theMapKeepBnd)
764 Standard_Boolean bRemoved = Standard_False;
765 if (theLS.Extent() < 2) {
770 TopAbs_ShapeEnum aType = theLS.First().ShapeType();
772 if (aType == TopAbs_EDGE ||
773 aType == TopAbs_FACE) {
779 BOPTools_AlgoTools::MakeContainer
780 ((aType == TopAbs_FACE) ? TopAbs_SHELL : TopAbs_WIRE, aShape);
782 for (BOPCol_ListIteratorOfListOfShape aIt(theLS); aIt.More(); aIt.Next()) {
783 const TopoDS_Shape& aS = aIt.Value();
788 Standard_Boolean bFaces, bEdges;
790 bFaces = (aType == TopAbs_FACE);
791 bEdges = (aType == TopAbs_EDGE);
792 ShapeUpgrade_UnifySameDomain anUnify (aShape, bEdges, bFaces);
793 anUnify.KeepShapes(theMapKeepBnd);
795 const TopoDS_Shape& aSNew = anUnify.Shape();
797 TopExp_Explorer aExp(aSNew, aType);
798 for (; aExp.More(); aExp.Next()) {
799 const TopoDS_Shape& aSn = aExp.Current();
800 theLSNew.Append(aSn);
803 if (theLSNew.IsEmpty()) {
806 AddWarning (new BOPAlgo_AlertRemovalOfIBForFacesFailed (aShape));
808 AddWarning (new BOPAlgo_AlertRemovalOfIBForEdgesFailed (aShape));
810 theLSNew.Assign(theLS);
814 // fill map of modified shapes
815 BOPCol_IndexedMapOfShape aMG;
816 Standard_Integer i, aNb;
818 BOPTools::MapShapes(aShape, TopAbs_VERTEX, aMG);
819 BOPTools::MapShapes(aShape, TopAbs_EDGE, aMG);
820 BOPTools::MapShapes(aShape, TopAbs_FACE, aMG);
823 for (i = 1; i <= aNb; ++i) {
824 const TopoDS_Shape& aSS = aMG(i);
825 const Standard_Integer* pMaterial = myShapeMaterial.Seek(aSS);
826 const TopTools_ListOfShape& aLSMod = anUnify.History()->Modified(aSS);
827 TopTools_ListIteratorOfListOfShape aIt(aLSMod);
828 for (; aIt.More(); aIt.Next()) {
829 const TopoDS_Shape& aSU = aIt.Value();
830 myMapModified.Bind(aSS, aSU);
831 bRemoved = Standard_True;
832 if (pMaterial && !myShapeMaterial.IsBound(aSU))
833 myShapeMaterial.Bind(aSU, *pMaterial);
837 else if (aType == TopAbs_SOLID) {
839 TopoDS_Compound aSolids;
840 aBB.MakeCompound(aSolids);
842 BOPCol_ListIteratorOfListOfShape aItLS(theLS);
843 for (; aItLS.More(); aItLS.Next()) {
844 const TopoDS_Shape& aSol = aItLS.Value();
845 aBB.Add(aSolids, aSol);
848 // Make connexity blocks of solids to create from each isolated block one solid.
849 // It will allow attaching internal entities of the solids to new solid.
850 BOPCol_ListOfShape aLCB;
851 BOPTools_AlgoTools::MakeConnexityBlocks(aSolids, TopAbs_FACE, TopAbs_SOLID, aLCB);
853 // for each block remove internal faces
854 BOPCol_ListIteratorOfListOfShape aItLCB(aLCB);
855 for (; aItLCB.More(); aItLCB.Next()) {
856 const TopoDS_Shape& aCB = aItLCB.Value();
858 // Map faces and solids to find boundary faces that can be removed
859 BOPCol_IndexedDataMapOfShapeListOfShape aDMFS;
861 BOPCol_ListOfShape aLSInt;
863 TopoDS_Iterator aItS(aCB);
864 for (; aItS.More(); aItS.Next()) {
865 const TopoDS_Shape& aSol = aItS.Value();
867 TopoDS_Iterator aItIS(aSol);
868 for (; aItIS.More(); aItIS.Next()) {
869 const TopoDS_Shape& aSI = aItIS.Value();
870 if (aSI.Orientation() == TopAbs_INTERNAL) {
874 TopoDS_Iterator aItF(aSI);
875 for (; aItF.More(); aItF.Next()) {
876 const TopoDS_Shape& aF = aItF.Value();
877 BOPCol_ListOfShape *pLSols = aDMFS.ChangeSeek(aF);
879 pLSols = &aDMFS(aDMFS.Add(aF, BOPCol_ListOfShape()));
881 pLSols->Append(aSol);
887 // to build unified solid, select only faces attached to only one solid
888 BOPCol_ListOfShape aLFUnique;
889 Standard_Integer i, aNb = aDMFS.Extent();
890 for (i = 1; i <= aNb; ++i) {
891 if (aDMFS(i).Extent() == 1) {
892 aLFUnique.Append(aDMFS.FindKey(i));
896 if (aNb == aLFUnique.Extent()) {
897 // no faces to remove
898 aItS.Initialize(aCB);
899 for (; aItS.More(); aItS.Next()) {
900 theLSNew.Append(aItS.Value());
906 BOPAlgo_BuilderSolid aBS;
907 aBS.SetShapes(aLFUnique);
910 if (aBS.HasErrors() || aBS.Areas().Extent() != 1) {
913 TopoDS_Compound aUniqeFaces;
914 aBB.MakeCompound(aUniqeFaces);
915 BOPCol_ListIteratorOfListOfShape aItLFUniqe(aLFUnique);
916 for (; aItLFUniqe.More(); aItLFUniqe.Next()) {
917 aBB.Add(aUniqeFaces, aItLFUniqe.Value());
920 AddWarning (new BOPAlgo_AlertRemovalOfIBForSolidsFailed (aUniqeFaces));
923 aItS.Initialize(aCB);
924 for (; aItS.More(); aItS.Next()) {
925 theLSNew.Append(aItS.Value());
930 TopoDS_Solid& aSNew = *(TopoDS_Solid*)&aBS.Areas().First();
932 // put all internal parts into new solid
933 aSNew.Free(Standard_True);
934 BOPCol_ListIteratorOfListOfShape aItLSI(aLSInt);
935 for (; aItLSI.More(); aItLSI.Next()) {
936 aBB.Add(aSNew, aItLSI.Value());
938 aSNew.Free(Standard_False);
940 theLSNew.Append(aSNew);
941 bRemoved = Standard_True;
947 //=======================================================================
948 //function : IsDeleted
950 //=======================================================================
951 Standard_Boolean BOPAlgo_CellsBuilder::IsDeleted(const TopoDS_Shape& theS)
953 Standard_Boolean bRet = Standard_True;
958 TopAbs_ShapeEnum aType = theS.ShapeType();
959 if (!(aType==TopAbs_EDGE || aType==TopAbs_FACE ||
960 aType==TopAbs_VERTEX || aType==TopAbs_SOLID)) {
964 Standard_Boolean bHasImage, bHasModified;
966 bHasImage = myImages.IsBound(theS);
967 bHasModified = myMapModified.IsBound(theS);
968 if (!bHasImage && !bHasModified) {
969 bRet = !myMapShape.Contains(theS);
974 const TopoDS_Shape& aSG = myMapModified.Find(theS);
975 if (myMapShape.Contains(aSG)) {
976 bRet = Standard_False;
982 const BOPCol_ListOfShape& aLSp = myImages.Find(theS);
983 BOPCol_ListIteratorOfListOfShape aIt(aLSp);
984 for (; aIt.More(); aIt.Next()) {
985 const TopoDS_Shape& aSp = aIt.Value();
986 const TopoDS_Shape& aSpR = myShapesSD.IsBound(aSp) ?
987 myShapesSD.Find(aSp) : aSp;
989 const TopoDS_Shape& aSpRG = myMapModified.IsBound(aSpR) ?
990 myMapModified.Find(aSpR) : aSpR;
991 if (myMapShape.Contains(aSpRG)) {
992 bRet = Standard_False;
1001 //=======================================================================
1002 //function : Modified
1004 //=======================================================================
1005 const TopTools_ListOfShape& BOPAlgo_CellsBuilder::Modified(const TopoDS_Shape& theS)
1007 myHistShapes.Clear();
1008 if (theS.IsNull()) {
1009 return myHistShapes;
1012 TopAbs_ShapeEnum aType = theS.ShapeType();
1013 if (!(aType==TopAbs_EDGE || aType==TopAbs_FACE || aType==TopAbs_VERTEX)) {
1014 return myHistShapes;
1017 Standard_Boolean bHasModified = myMapModified.IsBound(theS);
1019 const TopoDS_Shape& aSG = myMapModified.Find(theS);
1020 if (myMapShape.Contains(aSG)) {
1021 myHistShapes.Append(aSG);
1023 return myHistShapes;
1026 Standard_Boolean bHasImage = myImages.IsBound(theS);
1028 return myHistShapes;
1031 BOPCol_MapOfShape aMFence;
1032 const BOPCol_ListOfShape& aLSp = myImages.Find(theS);
1033 BOPCol_ListIteratorOfListOfShape aIt(aLSp);
1034 for (; aIt.More(); aIt.Next()) {
1035 const TopoDS_Shape aSp = aIt.Value();
1036 const TopoDS_Shape& aSpR = myShapesSD.IsBound(aSp) ?
1037 myShapesSD.Find(aSp) : aSp;
1039 if (myMapModified.IsBound(aSpR)) {
1040 const TopoDS_Shape& aSG = myMapModified.Find(aSpR);
1041 if (myMapShape.Contains(aSG)) {
1042 if (aMFence.Add(aSG)) {
1043 myHistShapes.Append(aSG);
1047 else if (aMFence.Add(aSpR))
1049 myHistShapes.Append(aSpR);
1053 return myHistShapes;
1056 //=======================================================================
1057 //function : MakeTypedContainers
1059 //=======================================================================
1060 void MakeTypedContainers(const TopoDS_Shape& theSC,
1061 TopoDS_Shape& theResult)
1063 TopAbs_ShapeEnum aContainerType, aConnexityType, aPartType;
1065 aPartType = TypeToExplore(BOPTools_AlgoTools::Dimension(theSC));
1066 switch (aPartType) {
1068 aContainerType = TopAbs_WIRE;
1069 aConnexityType = TopAbs_VERTEX;
1073 aContainerType = TopAbs_SHELL;
1074 aConnexityType = TopAbs_EDGE;
1077 case TopAbs_SOLID: {
1078 aContainerType = TopAbs_COMPSOLID;
1079 aConnexityType = TopAbs_FACE;
1086 BOPCol_ListOfShape aLCB;
1087 BOPTools_AlgoTools::MakeConnexityBlocks(theSC, aConnexityType, aPartType, aLCB);
1088 if (aLCB.IsEmpty()) {
1093 TopExp_Explorer aExp;
1094 BOPCol_ListIteratorOfListOfShape aItCB;
1096 aItCB.Initialize(aLCB);
1097 for (; aItCB.More(); aItCB.Next()) {
1099 BOPTools_AlgoTools::MakeContainer(aContainerType, aRCB);
1101 const TopoDS_Shape& aCB = aItCB.Value();
1102 aExp.Init(aCB, aPartType);
1103 for (; aExp.More(); aExp.Next()) {
1104 const TopoDS_Shape& aCBS = aExp.Current();
1105 aBB.Add(aRCB, aCBS);
1108 if (aContainerType == TopAbs_SHELL) {
1109 BOPTools_AlgoTools::OrientFacesOnShell(aRCB);
1112 aBB.Add(theResult, aRCB);
1116 //=======================================================================
1117 //function : CollectMaterialBoundaries
1118 //purpose : Add to theMapKeepBnd the boundary shapes of the area defined by shapes from the list
1119 //=======================================================================
1120 static void CollectMaterialBoundaries(const BOPCol_ListOfShape& theLS,
1121 TopTools_MapOfShape& theMapKeepBnd)
1123 TopAbs_ShapeEnum aType = theLS.First().ShapeType();
1124 TopAbs_ShapeEnum aTypeSubsh = (aType == TopAbs_FACE ? TopAbs_EDGE : TopAbs_VERTEX);
1125 TopTools_IndexedDataMapOfShapeListOfShape aMapSubSh;
1126 BOPCol_ListIteratorOfListOfShape anIt(theLS);
1127 for (; anIt.More(); anIt.Next())
1129 const TopoDS_Shape& aS = anIt.Value();
1130 TopExp::MapShapesAndAncestors(aS, aTypeSubsh, aType, aMapSubSh);
1132 for (int i = 1; i <= aMapSubSh.Extent(); i++)
1134 // check if the subshape belongs to boundary of the area
1135 if (aMapSubSh(i).Extent() == 1)
1137 // add to theMapKeepBnd
1138 theMapKeepBnd.Add(aMapSubSh.FindKey(i));
1143 //=======================================================================
1144 //function : TypeToExplore
1146 //=======================================================================
1147 TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
1149 TopAbs_ShapeEnum aRet;