From a728417ae4f35da6c3b1936db2ecc6d6348df45e Mon Sep 17 00:00:00 2001 From: emv Date: Fri, 8 Apr 2016 10:31:15 +0300 Subject: [PATCH] BRepOffset_MakeOffset::BuildSplitsOfFaces() - adding filters for found invalid faces to avoid unnecessary rebuilding of these faces. --- src/BRepOffset/BRepOffset_MakeOffset.cxx | 1281 +++++++++++++--------- 1 file changed, 738 insertions(+), 543 deletions(-) diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index 2213c92db3..d6de2865f1 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -434,9 +434,57 @@ static Handle(BRepAlgo_AsDes)& theAsDes); static - void FilterMaps(const TopoDS_Shape& theS, - TopTools_DataMapOfShapeListOfShape& theOEImages, - TopTools_DataMapOfShapeListOfShape& theOEOrigins); + Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF, + const TopTools_ListOfShape& theLFImages, + const TopoDS_Shape& theCE, + const TopTools_MapOfShape& theMapEInv, + TopTools_MapOfShape& theMENInv, + Handle(BRepAlgo_AsDes)& theAsDes, + const TopTools_DataMapOfShapeListOfShape& theOEImages); + +static + void RemoveInvalidSplitsFromValid(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, + const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_MapOfShape& theMEInverted); + +static + void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, + TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_IndexedMapOfShape& theInvEdges, + TopTools_IndexedMapOfShape& theMERemoved); + +static + void FilterEdgesImages(const TopoDS_Shape& theS, + TopTools_DataMapOfShapeListOfShape& theOEImages, + TopTools_DataMapOfShapeListOfShape& theOEOrigins); + +static + void FilterInvalidFaces(TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, + const TopTools_IndexedDataMapOfShapeListOfShape& theDMFE); + +static + void FilterInvalidEdges(TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_DataMapOfShapeListOfShape& theDMFLIE, + const TopTools_IndexedMapOfShape& theMERemoved); + +static + void RemoveValidSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, + BOPAlgo_Builder& theGF, + const TopTools_MapOfShape& theSpRem, + TopTools_IndexedMapOfShape& theMERemoved); + +static + void RemoveInvalidSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_IndexedMapOfShape& theInvEdges, + BOPAlgo_Builder& theGF, + const TopTools_MapOfShape& theSpRem); static void RemoveSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, @@ -3897,9 +3945,13 @@ void TrimEdges(const TopoDS_Shape& theShape, } } else { - TopoDS_Edge aNewEdge; - BRepOffset_Inter2d::ExtentEdge(TopoDS::Edge(NE), aNewEdge, theOffset); - theETrimEInf.Bind(NE, aNewEdge); + TopoDS_Edge& anEdge = TopoDS::Edge(NE); + BRepAdaptor_Curve aBAC(anEdge); + if (aBAC.GetType() == GeomAbs_Line) { + TopoDS_Edge aNewEdge; + BRepOffset_Inter2d::ExtentEdge(anEdge, aNewEdge, theOffset); + theETrimEInf.Bind(anEdge, aNewEdge); + } } theAsDes->Add(NF, NE); } @@ -4149,8 +4201,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, // get edges by which the face should be split TopoDS_Shape aCE; TopTools_MapOfShape aMapEInv; - bFound = GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, - theEdgesToAvoid, aCtx, theModifiedEdges, aCE, aMapEInv); + bFound = GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, + theEdgesToAvoid, aCtx, theModifiedEdges, aCE, aMapEInv); if (!bFound) { continue; } @@ -4161,90 +4213,23 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, // if (aMapEInv.Extent()) { // check if all possible faces are built - Standard_Boolean bArtificialCase = aLFImages.IsEmpty(); TopTools_MapOfShape aMENInv; - if (!bArtificialCase) { - // all boundary edges should be used - TopTools_IndexedMapOfShape aMEUsed; - TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages); - for (; aItLFIm.More(); aItLFIm.Next()) { - const TopoDS_Shape& aFIm = aItLFIm.Value(); - TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEUsed); - TopExp::MapShapes(aFIm, TopAbs_VERTEX, aMEUsed); - } - // - TopTools_IndexedDataMapOfShapeListOfShape aMVE; - TopExp::MapShapesAndAncestors(aCE, TopAbs_VERTEX, TopAbs_EDGE, aMVE); - // - TopTools_MapIteratorOfMapOfShape aItM(aMapEInv); - for (; aItM.More(); aItM.Next()) { - const TopoDS_Shape& aEInv = aItM.Key(); - TopExp_Explorer aExpV(aEInv, TopAbs_VERTEX); - for (; aExpV.More(); aExpV.Next()) { - const TopoDS_Shape& aVEInv = aExpV.Current(); - if (!aMEUsed.Contains(aVEInv) && aMVE.Contains(aVEInv)) { - const TopTools_ListOfShape& aLENInv = aMVE.FindFromKey(aVEInv); - TopTools_ListIteratorOfListOfShape aItLEInv(aLENInv); - for (; aItLEInv.More(); aItLEInv.Next()) { - const TopoDS_Shape& aENInv = aItLEInv.Value(); - aMENInv.Add(aENInv); - } - } - } - } - // - if (aMENInv.Extent()) { - TopTools_IndexedMapOfShape aMEFound; - TopExp::MapShapes(aCE, TopAbs_EDGE, aMEFound); - // - const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); - TopTools_ListIteratorOfListOfShape aItLE(aLE); - for (; aItLE.More(); aItLE.Next()) { - const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value()); - // - if (theOEImages.IsBound(aE)) { - Standard_Boolean bChecked = Standard_False; - const TopTools_ListOfShape& aLEIm = theOEImages.Find(aE); - TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); - for (; aItLEIm.More(); aItLEIm.Next()) { - const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value()); - if (!aMEFound.Contains(aEIm) || aMENInv.Contains(aEIm)) { - continue; - } - // - bChecked = Standard_True; - if (aMEUsed.Contains(aEIm)) { - break; - } - } - // - if (bChecked && !aItLEIm.More()) { - break; - } - } - else { - if (aMEFound.Contains(aE) && !aMENInv.Contains(aE) && !aMEUsed.Contains(aE)) { - break; - } - } - } - // - bArtificialCase = aItLE.More(); - } - } + Standard_Boolean bArtificialCase = aLFImages.IsEmpty() || + CheckIfArtificial(aF, aLFImages, aCE, aMapEInv, aMENInv, theAsDes, theOEImages); // if (bArtificialCase) { // try to build splits using invalid edges TopTools_IndexedMapOfShape anEmptyInvEdges; TopoDS_Shape aCE1; - GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, anEmptyInvEdges, - aCtx, theModifiedEdges, aCE1, aMapEInv); + GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, anEmptyInvEdges, + aCtx, theModifiedEdges, aCE1, aMapEInv); // TopTools_ListOfShape aLFImages1; BuildSplitsOfFace(aF, aCE1, Standard_False, theFacesOrigins, aLFImages1); // + // additionally check if newly created faces are not the same TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages1); - for (; aItLFIm.More(); ) { + for (; aItLFIm.More();) { const TopoDS_Shape& aFIm = aItLFIm.Value(); TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); for (; aExpE.More(); aExpE.Next()) { @@ -4304,9 +4289,9 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, } // // find invalid edges - FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, - theOEImages, theOEOrigins, theInvEdges, theValidEdges, - aDMFLVE, aDMFLNE, aDMFLIE, aMEInverted); + FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, + theOEImages, theOEOrigins, theInvEdges, theValidEdges, + aDMFLVE, aDMFLNE, aDMFLIE, aMEInverted); // // save the new splits if (theFImages.Contains(aF)) { @@ -4362,476 +4347,115 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, return; } // - // Decide whether to remove the found invalid faces or not. - // The procedure is the following: - // 1. Make connexity blocks from invalid faces; - // 2. Find free edges in this blocks; - // 3. If all free edges are valid for the faces - remove block. + // remove invalid splits from valid splits + RemoveInvalidSplitsFromValid(theFImages, theInvFaces, theArtInvFaces, aMEInverted); // - TopTools_MapOfShape aMFence; - TopoDS_Compound aCFInv; + // remove inside faces + TopTools_IndexedMapOfShape aMERemoved; + RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges, aMERemoved); + // + // make compound of valid splits + TopoDS_Compound aCFIm; BRep_Builder aBB; - aBB.MakeCompound(aCFInv); + aBB.MakeCompound(aCFIm); // - // make compound of invalid faces - TopTools_DataMapOfShapeShape aDMIFOF; + aNb = theFImages.Extent(); for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aF = theInvFaces.FindKey(i); - // artificially invalid faces should not be removed - if (theArtInvFaces.IsBound(aF)) { - continue; - } - const TopTools_ListOfShape& aLFInv = theInvFaces(i); - aItLF.Initialize(aLFInv); + const TopTools_ListOfShape& aLFIm = theFImages(i); + aItLF.Initialize(aLFIm); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Shape& aFIm = aItLF.Value(); - if (aMFence.Add(aFIm)) { - aBB.Add(aCFInv, aFIm); - aDMIFOF.Bind(aFIm, aF); - } + aBB.Add(aCFIm, aFIm); } } // - // make connexity blocks - TopTools_MapOfShape aMFToRem; - BOPCol_ListOfShape aLCBInv; - BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCBInv); + TopTools_IndexedDataMapOfShapeListOfShape aDMFE; + TopExp::MapShapesAndAncestors(aCFIm, TopAbs_EDGE, TopAbs_FACE, aDMFE); // - // analyze each block - BOPCol_ListIteratorOfListOfShape aItLCB(aLCBInv); - for (; aItLCB.More(); aItLCB.Next()) { - const TopoDS_Shape& aCB = aItLCB.Value(); - // - // if connexity block contains only one face - it should be removed; - TopExp_Explorer aExp(aCB, TopAbs_FACE); - aExp.Next(); - Standard_Boolean bRemove = !aExp.More(); - if (!bRemove) { - // if there are few faces in the block - it is necessary to analyze that block - // find free edges in this block - TopTools_IndexedDataMapOfShapeListOfShape aDMEF; - TopExp::MapShapesAndAncestors(aCB, TopAbs_EDGE, TopAbs_FACE, aDMEF); - // - bRemove = Standard_True; - // - aNb = aDMEF.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopTools_ListOfShape& aLF = aDMEF(i); - if (aLF.Extent() > 1) { - continue; - } - // - const TopoDS_Shape& aE = aDMEF.FindKey(i); - const TopoDS_Shape& aF = aLF.First(); - // - if (!theInvEdges.Contains(aE) && !theValidEdges.Contains(aE)) { - continue; - } - // check if the edge is valid for the faces - Standard_Boolean bValid = aDMFLVE.IsBound(aF); - if (bValid) { - const TopTools_ListOfShape& aLE = aDMFLVE.Find(aF); - TopTools_ListIteratorOfListOfShape aItLE(aLE); - for (; aItLE.More(); aItLE.Next()) { - const TopoDS_Shape& aVE = aItLE.Value(); - if (aVE.IsSame(aE)) { - break; - } - } - // - bValid = aItLE.More(); - } - // - if (!bValid) { - bRemove = Standard_False; - break; - } - } - // - if (!bRemove) { - // check if there are valid images left - aExp.Init(aCB, TopAbs_FACE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aFIm = aExp.Current(); - const TopoDS_Shape& aF = aDMIFOF.Find(aFIm); - // - const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); - const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF); - // - if (aLFIm.Extent() == aLFInv.Extent()) { - break; - } - } - // - bRemove = !aExp.More(); - } - // - if (!bRemove) { - // remove faces connected by inverted edges - aExp.Init(aCB, TopAbs_FACE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aFCB = aExp.Current(); - // - TopExp_Explorer aExpE(aFCB, TopAbs_EDGE); - for (; aExpE.More(); aExpE.Next()) { - const TopoDS_Shape& aECB = aExpE.Current(); - if (aDMEF.FindFromKey(aECB).Extent() > 1) { - if (!aMEInverted.Contains(aECB)) { - break; - } - } - } - // - if (!aExpE.More()) { - aMFToRem.Add(aFCB); - } - } - } - } - // - if (bRemove) { - aExp.Init(aCB, TopAbs_FACE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aF = aExp.Current(); - aMFToRem.Add(aF); - } - } + // filter maps of images and origins + FilterEdgesImages(aCFIm, theOEImages, theOEOrigins); + // + // filter invalid faces + FilterInvalidFaces(theInvFaces, theArtInvFaces, theFImages, aDMFE); + aNb = theInvFaces.Extent(); + if (!aNb) { + theInvEdges.Clear(); + return; } // - // remove invalid faces from images - BOPCol_ListOfShape aLS; - TopTools_MapOfShape aMFInv; - aMFence.Clear(); + // filter invalid edges + FilterInvalidEdges(theInvEdges, theInvFaces, theArtInvFaces, aDMFLIE, aMERemoved); + // + theLastInvEdges.Clear(); + aNb = theInvEdges.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aE = theInvEdges(i); + theEdgesToAvoid.Add(aE); + theLastInvEdges.Add(aE); + } // aNb = theInvFaces.Extent(); for (i = 1; i <= aNb; ++i) { const TopoDS_Shape& aF = theInvFaces.FindKey(i); - TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF); - aItLF.Initialize(aLFImages); - for (; aItLF.More(); ) { - const TopoDS_Shape& aFIm = aItLF.Value(); - if (aMFToRem.Contains(aFIm)) { - aLFImages.Remove(aItLF); - } - else { - aItLF.Next(); - } + if (theAlreadyInvFaces.IsBound(aF)) { + theAlreadyInvFaces.ChangeFind(aF)++; } - // - const TopTools_ListOfShape& aLFInv = theInvFaces(i); - aItLF.Initialize(aLFInv); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFIm = aItLF.Value(); - if (aMFence.Add(aFIm)) { - aLS.Append(aFIm); - aMFInv.Add(aFIm); - } + else { + theAlreadyInvFaces.Bind(aF, 1); } } +} + +//======================================================================= +//function : FindFacesToRebuild +//purpose : +//======================================================================= +void FindFacesToRebuild(TopTools_IndexedDataMapOfShapeListOfShape& theLFImages, + const TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild) +{ + Standard_Integer i, aNb = theLFImages.Extent(); + if (!aNb) { + return; + } // - // make the solid from the images and remove those faces inside the shape - aNb = theFImages.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopTools_ListOfShape& aLFImages = theFImages(i); - aItLF.Initialize(aLFImages); + Standard_Boolean bRebuild; + TopTools_ListIteratorOfListOfShape aItLF; + TopTools_ListOfShape aLEValid; + TopTools_IndexedMapOfShape aMEReb; + TopTools_MapOfShape aMFence; + TopExp_Explorer aExp; + // + TopTools_DataMapOfShapeListOfShape aDMFLV; + // get edges from invalid faces + aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; i++) { + const TopoDS_Shape& aF = theInvFaces.FindKey(i); + aMFence.Clear(); + TopTools_ListOfShape aLVAvoid; + const TopTools_ListOfShape& aLFIm = theInvFaces(i); + aItLF.Initialize(aLFIm); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Shape& aFIm = aItLF.Value(); - if (aMFence.Add(aFIm)) { - aLS.Append(aFIm); + aExp.Init(aFIm, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aE = aExp.Current(); + aMEReb.Add(aE); + if (theInvEdges.Contains(aE)) { + TopExp_Explorer aExpV(aE, TopAbs_VERTEX); + for (; aExpV.More(); aExpV.Next()) { + const TopoDS_Shape& aV = aExpV.Current(); + if (aMFence.Add(aV)) { + aLVAvoid.Append(aV); + aMEReb.Add(aV); + } + } + } } } - } - // - BOPAlgo_MakerVolume aMV; - aMV.SetArguments(aLS); - aMV.SetIntersect(Standard_True); - aMV.Perform(); - // - const TopoDS_Shape& aSols = aMV.Shape(); - // - TopTools_IndexedDataMapOfShapeListOfShape aDMFS; - TopExp::MapShapesAndAncestors(aSols, TopAbs_FACE, TopAbs_SOLID, aDMFS); - // - aMFToRem.Clear(); - aNb = aDMFS.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopTools_ListOfShape& aLSol = aDMFS(i); - if (aLSol.Extent() > 1) { - const TopoDS_Shape& aFIm = aDMFS.FindKey(i); - aMFToRem.Add(aFIm); - } - } - // - TopExp_Explorer aExpS(aSols, TopAbs_SOLID); - for (; aExpS.More(); aExpS.Next()) { - const TopoDS_Shape& aSol = aExpS.Current(); - // - Standard_Boolean bAllInv(Standard_True), bAllRemoved(Standard_True); - - TopExp_Explorer aExpF(aSol, TopAbs_FACE); - for (; aExpF.More(); aExpF.Next()) { - const TopoDS_Shape& aFS = aExpF.Current(); - // - if (aFS.Orientation() == TopAbs_INTERNAL) { - aMFToRem.Add(aFS); - } - // - bAllRemoved = bAllRemoved && aMFToRem.Contains(aFS); - bAllInv = bAllInv && (aMFToRem.Contains(aFS) || aMFInv.Contains(aFS)); - } - // - if (bAllInv && !bAllRemoved) { - // remove invalid faces but keep those that have already been marked for removal - TopExp_Explorer aExpF(aSol, TopAbs_FACE); - for (; aExpF.More(); aExpF.Next()) { - const TopoDS_Shape& aFS = aExpF.Current(); - // - if (aMFToRem.Contains(aFS)) { - aMFToRem.Remove(aFS); - } - else { - aMFToRem.Add(aFS); - } - } - } - } - // - // remove newly found faces - RemoveSplits(theFImages, aMV, aMFToRem); - RemoveSplits(theInvFaces, aMV, aMFToRem); - // - // make compound of valid splits - TopoDS_Compound aCFIm; - aBB.MakeCompound(aCFIm); - // - aNb = theFImages.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopTools_ListOfShape& aLFIm = theFImages(i); - aItLF.Initialize(aLFIm); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFIm = aItLF.Value(); - aBB.Add(aCFIm, aFIm); - } - } - // - // filter invalid faces, considering faces having only valid - // images left with non-free edges as valid - // do not remove invalid faces if it creates free edges - // - TopTools_IndexedDataMapOfShapeListOfShape aDMFE; - TopExp::MapShapesAndAncestors(aCFIm, TopAbs_EDGE, TopAbs_FACE, aDMFE); - // - // filter maps of images and origins - FilterMaps(aCFIm, theOEImages, theOEOrigins); - // - // filter invalid faces - TopTools_IndexedDataMapOfShapeListOfShape aReallyInvFaces; - aNb = theInvFaces.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aF = theInvFaces.FindKey(i); - const TopTools_ListOfShape& aLFInv = theInvFaces(i); - // - if (theArtInvFaces.IsBound(aF)) { - if (aLFInv.IsEmpty()) { - theArtInvFaces.UnBind(aF); - } - else { - aReallyInvFaces.Add(aF, aLFInv); - } - continue; - } - // - if (aLFInv.IsEmpty()) { - continue; - } - // - const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); - Standard_Boolean bInvalid = aLFIm.IsEmpty(); - // - if (!bInvalid) { - // check two lists on common splits - aItLF.Initialize(aLFInv); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFInv = aItLF.Value(); - // - TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); - for (; aItLFIm.More(); aItLFIm.Next()) { - const TopoDS_Shape& aFIm = aItLFIm.Value(); - // - if (aFInv.IsSame(aFIm)) { - break; - } - } - // - if (aItLFIm.More()) { - break; - } - } - // - bInvalid = aItLF.More(); - } - // - if (!bInvalid) { - // check for free edges - for (Standard_Integer j = 0; !bInvalid && j < 2; ++j) { - const TopTools_ListOfShape& aLI = !j ? aLFIm : aLFInv; - aItLF.Initialize(aLI); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFIm = aItLF.Value(); - // - TopExp_Explorer aExp(aFIm, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aE = aExp.Current(); - if (aDMFE.Contains(aE)) { - const TopTools_ListOfShape& aLEF = aDMFE.FindFromKey(aE); - if (aLEF.Extent() == 1) { - break; - } - } - } - // - if (aExp.More()) { - break; - } - } - bInvalid = aItLF.More(); - } - } - // - if (bInvalid) { - aReallyInvFaces.Add(aF, aLFInv); - } - } - // - theInvFaces = aReallyInvFaces; - // - aNb = theInvFaces.Extent(); - if (!aNb) { - theInvEdges.Clear(); - return; - } - // - // filter invalid edges - // - TopoDS_Compound aCFInv1; - TopTools_IndexedMapOfShape aMEInv1; - aBB.MakeCompound(aCFInv1); - // - aNb = theInvFaces.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopTools_ListOfShape& aLFInv = theInvFaces(i); - aItLF.Initialize(aLFInv); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFIm = aItLF.Value(); - aBB.Add(aCFInv1, aFIm); - } - } - // - TopExp::MapShapes(aCFInv1, TopAbs_EDGE, aMEInv1); - // - TopTools_IndexedMapOfShape aReallyInvEdges; - // - aNb = theInvFaces.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aF = theInvFaces.FindKey(i); - if (theArtInvFaces.IsBound(aF)) { - const TopTools_ListOfShape& aLEInv = aDMFLIE.Find(aF); - aItLF.Initialize(aLEInv); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aE = aItLF.Value(); - if (aMEInv1.Contains(aE)) { - aReallyInvEdges.Add(aE); - } - } - } - else { - const TopTools_ListOfShape& aLFInv = theInvFaces(i); - aItLF.Initialize(aLFInv); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFIm = aItLF.Value(); - TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); - for (; aExpE.More(); aExpE.Next()) { - const TopoDS_Shape& aE = aExpE.Current(); - if (theInvEdges.Contains(aE)) { - aReallyInvEdges.Add(aE); - } - } - } - } - } - // - theInvEdges = aReallyInvEdges; - // - theLastInvEdges.Clear(); - aNb = theInvEdges.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aE = theInvEdges(i); - theEdgesToAvoid.Add(aE); - theLastInvEdges.Add(aE); - } - // - aNb = theInvFaces.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aF = theInvFaces.FindKey(i); - if (theAlreadyInvFaces.IsBound(aF)) { - theAlreadyInvFaces.ChangeFind(aF)++; - } - else { - theAlreadyInvFaces.Bind(aF, 1); - } - } -} - -//======================================================================= -//function : FindFacesToRebuild -//purpose : -//======================================================================= -void FindFacesToRebuild(TopTools_IndexedDataMapOfShapeListOfShape& theLFImages, - const TopTools_IndexedMapOfShape& theInvEdges, - const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, - TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild) -{ - Standard_Integer i, aNb = theLFImages.Extent(); - if (!aNb) { - return; - } - // - Standard_Boolean bRebuild; - TopTools_ListIteratorOfListOfShape aItLF; - TopTools_ListOfShape aLEValid; - TopTools_IndexedMapOfShape aMEReb; - TopTools_MapOfShape aMFence; - TopExp_Explorer aExp; - // - TopTools_DataMapOfShapeListOfShape aDMFLV; - // get edges from invalid faces - aNb = theInvFaces.Extent(); - for (i = 1; i <= aNb; i++) { - const TopoDS_Shape& aF = theInvFaces.FindKey(i); - aMFence.Clear(); - TopTools_ListOfShape aLVAvoid; - const TopTools_ListOfShape& aLFIm = theInvFaces(i); - aItLF.Initialize(aLFIm); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aFIm = aItLF.Value(); - aExp.Init(aFIm, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aE = aExp.Current(); - aMEReb.Add(aE); - if (theInvEdges.Contains(aE)) { - TopExp_Explorer aExpV(aE, TopAbs_VERTEX); - for (; aExpV.More(); aExpV.Next()) { - const TopoDS_Shape& aV = aExpV.Current(); - if (aMFence.Add(aV)) { - aLVAvoid.Append(aV); - aMEReb.Add(aV); - } - } - } - } - } - if (aLVAvoid.Extent()) { - aDMFLV.Bind(aF, aLVAvoid); + if (aLVAvoid.Extent()) { + aDMFLV.Bind(aF, aLVAvoid); } } // @@ -7469,14 +7093,502 @@ void FindOrigins(const TopTools_ListOfShape& theLFIm1, } // for (i = 0; i < 2; ++i) { } - //======================================================================= -//function : FilterMaps -//purpose : +//function : CheckIfArtificial +//purpose : Checks if the face is artificially invalid //======================================================================= -void FilterMaps(const TopoDS_Shape& theS, - TopTools_DataMapOfShapeListOfShape& theOEImages, - TopTools_DataMapOfShapeListOfShape& theOEOrigins) +Standard_Boolean CheckIfArtificial(const TopoDS_Shape& theF, + const TopTools_ListOfShape& theLFImages, + const TopoDS_Shape& theCE, + const TopTools_MapOfShape& theMapEInv, + TopTools_MapOfShape& theMENInv, + Handle(BRepAlgo_AsDes)& theAsDes, + const TopTools_DataMapOfShapeListOfShape& theOEImages) +{ + // all boundary edges should be used + TopTools_IndexedMapOfShape aMEUsed; + TopTools_ListIteratorOfListOfShape aItLFIm(theLFImages); + for (; aItLFIm.More(); aItLFIm.Next()) { + const TopoDS_Shape& aFIm = aItLFIm.Value(); + TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEUsed); + TopExp::MapShapes(aFIm, TopAbs_VERTEX, aMEUsed); + } + // + TopTools_IndexedDataMapOfShapeListOfShape aMVE; + TopExp::MapShapesAndAncestors(theCE, TopAbs_VERTEX, TopAbs_EDGE, aMVE); + // + TopTools_MapIteratorOfMapOfShape aItM(theMapEInv); + for (; aItM.More(); aItM.Next()) { + const TopoDS_Shape& aEInv = aItM.Key(); + TopExp_Explorer aExpV(aEInv, TopAbs_VERTEX); + for (; aExpV.More(); aExpV.Next()) { + const TopoDS_Shape& aVEInv = aExpV.Current(); + if (!aMEUsed.Contains(aVEInv) && aMVE.Contains(aVEInv)) { + const TopTools_ListOfShape& aLENInv = aMVE.FindFromKey(aVEInv); + TopTools_ListIteratorOfListOfShape aItLEInv(aLENInv); + for (; aItLEInv.More(); aItLEInv.Next()) { + const TopoDS_Shape& aENInv = aItLEInv.Value(); + theMENInv.Add(aENInv); + } + } + } + } + // + if (theMENInv.IsEmpty()) { + return Standard_False; + } + // + TopTools_IndexedMapOfShape aMEFound; + TopExp::MapShapes(theCE, TopAbs_EDGE, aMEFound); + // + const TopTools_ListOfShape& aLE = theAsDes->Descendant(theF); + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value()); + // + if (theOEImages.IsBound(aE)) { + Standard_Boolean bChecked = Standard_False; + const TopTools_ListOfShape& aLEIm = theOEImages.Find(aE); + TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); + for (; aItLEIm.More(); aItLEIm.Next()) { + const TopoDS_Edge& aEIm = TopoDS::Edge(aItLEIm.Value()); + if (!aMEFound.Contains(aEIm) || theMENInv.Contains(aEIm)) { + continue; + } + // + bChecked = Standard_True; + if (aMEUsed.Contains(aEIm)) { + break; + } + } + // + if (bChecked && !aItLEIm.More()) { + break; + } + } + else { + if (aMEFound.Contains(aE) && !theMENInv.Contains(aE) && !aMEUsed.Contains(aE)) { + break; + } + } + } + // + return aItLE.More(); +} + +//======================================================================= +//function : RemoveInvalidSplitsFromValid +//purpose : +//======================================================================= +void RemoveInvalidSplitsFromValid(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, + const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_MapOfShape& theMEInverted) +{ + // Decide whether to remove the found invalid faces or not. + // The procedure is the following: + // 1. Make connexity blocks from invalid faces; + // 2. Find free edges in this blocks; + // 3. If all free edges are valid for the faces - remove block. + // + TopTools_MapOfShape aMFence, aMFToRem; + TopoDS_Compound aCFInv; + BRep_Builder aBB; + aBB.MakeCompound(aCFInv); + TopTools_ListIteratorOfListOfShape aItLF; + // + // make compound of invalid faces + TopTools_DataMapOfShapeShape aDMIFOF; + Standard_Integer i, aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aF = theInvFaces.FindKey(i); + // artificially invalid faces should not be removed + if (theArtInvFaces.IsBound(aF)) { + continue; + } + const TopTools_ListOfShape& aLFInv = theInvFaces(i); + aItLF.Initialize(aLFInv); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFIm = aItLF.Value(); + if (aMFence.Add(aFIm)) { + aBB.Add(aCFInv, aFIm); + aDMIFOF.Bind(aFIm, aF); + } + } + } + // + // make connexity blocks + BOPCol_ListOfShape aLCBInv; + BOPTools_AlgoTools::MakeConnexityBlocks(aCFInv, TopAbs_EDGE, TopAbs_FACE, aLCBInv); + // + // analyze each block + BOPCol_ListIteratorOfListOfShape aItLCB(aLCBInv); + for (; aItLCB.More(); aItLCB.Next()) { + const TopoDS_Shape& aCB = aItLCB.Value(); + // + // if connexity block contains only one face - it should be removed; + TopExp_Explorer aExp(aCB, TopAbs_FACE); + aExp.Next(); + if (aExp.More()) { + // check if there are valid images left + aExp.Init(aCB, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aFIm = aExp.Current(); + const TopoDS_Shape& aF = aDMIFOF.Find(aFIm); + // + const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); + const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF); + // + if (aLFIm.Extent() == aLFInv.Extent()) { + break; + } + } + } + // + if (!aExp.More()) { + aExp.Init(aCB, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aF = aExp.Current(); + aMFToRem.Add(aF); + } + continue; + } + // + // remove faces connected by inverted edges + TopTools_IndexedDataMapOfShapeListOfShape aDMEF; + TopExp::MapShapesAndAncestors(aCB, TopAbs_EDGE, TopAbs_FACE, aDMEF); + // + aExp.Init(aCB, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aFCB = aExp.Current(); + // + TopExp_Explorer aExpE(aFCB, TopAbs_EDGE); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Shape& aECB = aExpE.Current(); + if (aDMEF.FindFromKey(aECB).Extent() > 1) { + if (!theMEInverted.Contains(aECB)) { + break; + } + } + } + // + if (!aExpE.More()) { + aMFToRem.Add(aFCB); + } + } + } + // + if (aMFToRem.Extent()) { + // remove invalid faces from images + aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aF = theInvFaces.FindKey(i); + TopTools_ListOfShape& aLFImages = theFImages.ChangeFromKey(aF); + aItLF.Initialize(aLFImages); + for (; aItLF.More();) { + const TopoDS_Shape& aFIm = aItLF.Value(); + if (aMFToRem.Contains(aFIm)) { + aLFImages.Remove(aItLF); + } + else { + aItLF.Next(); + } + } + } + } +} + +//======================================================================= +//function : RemoveInsideFaces +//purpose : +//======================================================================= +void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, + TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_IndexedMapOfShape& theInvEdges, + TopTools_IndexedMapOfShape& theMERemoved) +{ + BOPCol_ListOfShape aLS; + TopTools_MapOfShape aMFInv, aMFence, aMFToRem; + TopTools_ListIteratorOfListOfShape aItLF; + // + Standard_Integer i, aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopTools_ListOfShape& aLFInv = theInvFaces(i); + aItLF.Initialize(aLFInv); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFIm = aItLF.Value(); + if (aMFence.Add(aFIm)) { + aLS.Append(aFIm); + aMFInv.Add(aFIm); + } + } + } + // + // make the solid from the images and remove those faces inside the shape + aNb = theFImages.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopTools_ListOfShape& aLFImages = theFImages(i); + aItLF.Initialize(aLFImages); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFIm = aItLF.Value(); + if (aMFence.Add(aFIm)) { + aLS.Append(aFIm); + } + } + } + // + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(aLS); + aMV.SetIntersect(Standard_True); + aMV.Perform(); + // + const TopoDS_Shape& aSols = aMV.Shape(); + // + TopTools_IndexedDataMapOfShapeListOfShape aDMFS; + TopExp::MapShapesAndAncestors(aSols, TopAbs_FACE, TopAbs_SOLID, aDMFS); + // + aNb = aDMFS.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopTools_ListOfShape& aLSol = aDMFS(i); + if (aLSol.Extent() > 1) { + const TopoDS_Shape& aFIm = aDMFS.FindKey(i); + aMFToRem.Add(aFIm); + } + } + // + TopExp_Explorer aExpS(aSols, TopAbs_SOLID); + for (; aExpS.More(); aExpS.Next()) { + const TopoDS_Shape& aSol = aExpS.Current(); + // + Standard_Boolean bAllInv(Standard_True), bAllRemoved(Standard_True); + + TopExp_Explorer aExpF(aSol, TopAbs_FACE); + for (; aExpF.More(); aExpF.Next()) { + const TopoDS_Shape& aFS = aExpF.Current(); + // + if (aFS.Orientation() == TopAbs_INTERNAL) { + aMFToRem.Add(aFS); + } + // + bAllRemoved = bAllRemoved && aMFToRem.Contains(aFS); + bAllInv = bAllInv && (aMFToRem.Contains(aFS) || aMFInv.Contains(aFS)); + } + // + if (bAllInv && !bAllRemoved) { + // remove invalid faces but keep those that have already been marked for removal + TopExp_Explorer aExpF(aSol, TopAbs_FACE); + for (; aExpF.More(); aExpF.Next()) { + const TopoDS_Shape& aFS = aExpF.Current(); + // + if (aMFToRem.Contains(aFS)) { + aMFToRem.Remove(aFS); + } + else { + aMFToRem.Add(aFS); + } + } + } + } + // + // remove newly found faces + RemoveValidSplits(theFImages, aMV, aMFToRem, theMERemoved); + RemoveInvalidSplits(theInvFaces, theArtInvFaces, theInvEdges, aMV, aMFToRem); +} + +//======================================================================= +//function : FilterInvalidFaces +//purpose : +//======================================================================= +void FilterInvalidFaces(TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_IndexedDataMapOfShapeListOfShape& theFImages, + const TopTools_IndexedDataMapOfShapeListOfShape& theDMFE) +{ + // + // filter invalid faces, considering faces having only valid + // images left with non-free edges as valid + // do not remove invalid faces if it creates free edges + // + TopTools_IndexedDataMapOfShapeListOfShape aReallyInvFaces; + TopTools_ListIteratorOfListOfShape aItLF; + // + Standard_Integer i, aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aF = theInvFaces.FindKey(i); + const TopTools_ListOfShape& aLFInv = theInvFaces(i); + // + if (theArtInvFaces.IsBound(aF)) { + if (aLFInv.IsEmpty()) { + theArtInvFaces.UnBind(aF); + } + else { + aReallyInvFaces.Add(aF, aLFInv); + } + continue; + } + // + if (aLFInv.IsEmpty()) { + continue; + } + // + const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF); + Standard_Boolean bInvalid = aLFIm.IsEmpty(); + // + if (!bInvalid) { + // check two lists on common splits + aItLF.Initialize(aLFInv); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFInv = aItLF.Value(); + // + TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm); + for (; aItLFIm.More(); aItLFIm.Next()) { + const TopoDS_Shape& aFIm = aItLFIm.Value(); + // + if (aFInv.IsSame(aFIm)) { + break; + } + } + // + if (aItLFIm.More()) { + break; + } + } + // + bInvalid = aItLF.More(); + } + // + if (!bInvalid) { + // check for free edges + for (Standard_Integer j = 0; !bInvalid && j < 2; ++j) { + const TopTools_ListOfShape& aLI = !j ? aLFIm : aLFInv; + aItLF.Initialize(aLI); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFIm = aItLF.Value(); + // + TopExp_Explorer aExp(aFIm, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aE = aExp.Current(); + if (theDMFE.Contains(aE)) { + const TopTools_ListOfShape& aLEF = theDMFE.FindFromKey(aE); + if (aLEF.Extent() == 1) { + break; + } + } + } + // + if (aExp.More()) { + break; + } + } + bInvalid = aItLF.More(); + } + } + // + if (bInvalid) { + aReallyInvFaces.Add(aF, aLFInv); + } + } + // + theInvFaces = aReallyInvFaces; +} + +//======================================================================= +//function : FilterInvalidEdges +//purpose : +//======================================================================= +void FilterInvalidEdges(TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_DataMapOfShapeListOfShape& theDMFLIE, + const TopTools_IndexedMapOfShape& theMERemoved) +{ + TopoDS_Compound aCEInv; + TopTools_IndexedMapOfShape aMEInv; + BRep_Builder aBB; + aBB.MakeCompound(aCEInv); + TopTools_ListIteratorOfListOfShape aItLF; + // + Standard_Integer i, aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopTools_ListOfShape& aLFInv = theInvFaces(i); + aItLF.Initialize(aLFInv); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFIm = aItLF.Value(); + TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEInv); + // + TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Shape& aE = aExpE.Current(); + if (theInvEdges.Contains(aE)) { + aBB.Add(aCEInv, aE); + } + } + } + } + // + // remove edges which have been marked for removal + TopTools_IndexedMapOfShape aMEInvToAvoid; + BOPCol_ListOfShape aLCBE; + BOPTools_AlgoTools::MakeConnexityBlocks(aCEInv, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); + // + BOPCol_ListIteratorOfListOfShape aItLCBE(aLCBE); + for (; aItLCBE.More(); aItLCBE.Next()) { + const TopoDS_Shape& aCBE = aItLCBE.Value(); + TopExp_Explorer aExpCB(aCBE, TopAbs_EDGE); + for (; aExpCB.More(); aExpCB.Next()) { + const TopoDS_Shape& aE = aExpCB.Current(); + if (!theMERemoved.Contains(aE)) { + break; + } + } + // + if (!aExpCB.More()) { + TopExp::MapShapes(aCBE, TopAbs_EDGE, aMEInvToAvoid); + } + } + // + TopTools_IndexedMapOfShape aReallyInvEdges; + // + aNb = theInvFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aF = theInvFaces.FindKey(i); + if (theArtInvFaces.IsBound(aF)) { + const TopTools_ListOfShape& aLEInv = theDMFLIE.Find(aF); + aItLF.Initialize(aLEInv); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aE = aItLF.Value(); + if (aMEInv.Contains(aE) && !aMEInvToAvoid.Contains(aE)) { + aReallyInvEdges.Add(aE); + } + } + } + else { + const TopTools_ListOfShape& aLFInv = theInvFaces(i); + aItLF.Initialize(aLFInv); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aFIm = aItLF.Value(); + TopExp_Explorer aExpE(aFIm, TopAbs_EDGE); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Shape& aE = aExpE.Current(); + if (theInvEdges.Contains(aE) && !aMEInvToAvoid.Contains(aE)) { + aReallyInvEdges.Add(aE); + } + } + } + } + } + // + theInvEdges = aReallyInvEdges; +} + +//======================================================================= +//function : FilterEdgesImages +//purpose : +//======================================================================= +void FilterEdgesImages(const TopoDS_Shape& theS, + TopTools_DataMapOfShapeListOfShape& theOEImages, + TopTools_DataMapOfShapeListOfShape& theOEOrigins) { // map edges TopTools_IndexedMapOfShape aME; @@ -7519,12 +7631,13 @@ void FilterMaps(const TopoDS_Shape& theS, } //======================================================================= -//function : RemoveSplits +//function : RemoveValidSplits //purpose : //======================================================================= -void RemoveSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, - BOPAlgo_Builder& theGF, - const TopTools_MapOfShape& theSpRem) +void RemoveValidSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, + BOPAlgo_Builder& theGF, + const TopTools_MapOfShape& theSpRem, + TopTools_IndexedMapOfShape& theMERemoved) { Standard_Integer i, aNb = theImages.Extent(); if (!aNb) { @@ -7537,6 +7650,7 @@ void RemoveSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, for (; aIt.More(); ) { const TopoDS_Shape& aSIm = aIt.Value(); if (theSpRem.Contains(aSIm)) { + TopExp::MapShapes(aSIm, TopAbs_EDGE, theMERemoved); aLSIm.Remove(aIt); continue; } @@ -7544,15 +7658,19 @@ void RemoveSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, // check if all its images are have to be removed const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm); if (aLSImIm.Extent()) { + Standard_Boolean bAllRem = Standard_True; TopTools_ListIteratorOfListOfShape aIt1(aLSImIm); for (; aIt1.More(); aIt1.Next()) { const TopoDS_Shape& aSImIm = aIt1.Value(); - if (!theSpRem.Contains(aSImIm)) { - break; + if (theSpRem.Contains(aSImIm)) { + TopExp::MapShapes(aSImIm, TopAbs_EDGE, theMERemoved); + } + else { + bAllRem = Standard_False; } } // - if (!aIt1.More()) { + if (bAllRem) { aLSIm.Remove(aIt); continue; } @@ -7562,6 +7680,83 @@ void RemoveSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, } } +//======================================================================= +//function : RemoveInvalidSplits +//purpose : +//======================================================================= +void RemoveInvalidSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages, + const TopTools_DataMapOfShapeShape& theArtInvFaces, + const TopTools_IndexedMapOfShape& theInvEdges, + BOPAlgo_Builder& theGF, + const TopTools_MapOfShape& theSpRem) +{ + Standard_Integer i, aNb = theImages.Extent(); + if (!aNb) { + return; + } + // + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aS = theImages.FindKey(i); + Standard_Boolean bArt = theArtInvFaces.IsBound(aS); + // + TopTools_ListOfShape& aLSIm = theImages(i); + TopTools_ListIteratorOfListOfShape aIt(aLSIm); + for (; aIt.More();) { + const TopoDS_Shape& aSIm = aIt.Value(); + if (theSpRem.Contains(aSIm)) { + aLSIm.Remove(aIt); + continue; + } + // + // check if all its images are have to be removed + const TopTools_ListOfShape& aLSImIm = theGF.Modified(aSIm); + if (aLSImIm.IsEmpty()) { + aIt.Next(); + continue; + } + // + Standard_Boolean bAllRem = Standard_True; + TopTools_IndexedMapOfShape aMERemoved; + TopTools_ListIteratorOfListOfShape aIt1(aLSImIm); + for (; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aSImIm = aIt1.Value(); + if (theSpRem.Contains(aSImIm)) { + TopExp::MapShapes(aSImIm, TopAbs_EDGE, aMERemoved); + } + else { + bAllRem = Standard_False; + } + } + // + if (bAllRem) { + aLSIm.Remove(aIt); + continue; + } + // + if (bArt) { + aIt.Next(); + continue; + } + // + // remove the face from invalid if all invalid edges of this face + // have been marked for removal + TopExp_Explorer aExpE(aSIm, TopAbs_EDGE); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Shape& aEInv = aExpE.Current(); + if (theInvEdges.Contains(aEInv) && !aMERemoved.Contains(aEInv)) { + break; + } + } + if (!aExpE.More()) { + aLSIm.Remove(aIt); + } + else { + aIt.Next(); + } + } + } +} + //======================================================================= //function : AppendToList //purpose : to be used for very short lists (1-3 elements) -- 2.39.5