From 5faddbe4a97adb0b62d026256716dc55ec3fdd98 Mon Sep 17 00:00:00 2001 From: pkv Date: Mon, 12 Mar 2012 20:13:09 +0400 Subject: [PATCH] 0023004: Boolean operation cut produces incorrect result. --- src/BOP/BOP_FaceBuilder.cdl | 151 +++--- src/BOP/BOP_FaceBuilder.cxx | 942 +++++++++++++++++++++++------------- 2 files changed, 690 insertions(+), 403 deletions(-) diff --git a/src/BOP/BOP_FaceBuilder.cdl b/src/BOP/BOP_FaceBuilder.cdl index e37cdead6a..069edc98a6 100755 --- a/src/BOP/BOP_FaceBuilder.cdl +++ b/src/BOP/BOP_FaceBuilder.cdl @@ -19,16 +19,16 @@ uses Wire from TopoDS, Edge from TopoDS, Vertex from TopoDS, - ListOfShape from TopTools, - SequenceOfInteger from TColStd, - - LoopSet from BOP, - BlockIterator from BOP, - BlockBuilder from BOP, + SequenceOfInteger from TColStd, + Context from IntTools, WireEdgeSet from BOP, - FaceAreaBuilder from BOP, PWireEdgeSet from BOP +-- LoopSet from BOP, +-- BlockIterator from BOP, +-- BlockBuilder from BOP, +-- FaceAreaBuilder from BOP, + is @@ -47,16 +47,27 @@ is --- 3. Make Areas from Loops --- 4. Make Faces from Areas --- - DoInternalEdges (me :out) - is private; - ---Purpose: - --- Processes internal edges if they exists + --- - BuildNewFaces (me :out) - is private; +-- BuildNewFaces (me :out) +-- is private; ---Purpose: --- Make Faces from Areas - --- + --- + +--modified by NIZNHY-PKV Wed Feb 29 10:57:40 2012f + SetContext(me:out; + aCtx:Context from IntTools); + ---Purpose: + -- Sets intersection context + + Context(me) + returns Context from IntTools; + ---C++: return const & + ---Purpose: + -- Returns intersection context +--modified by NIZNHY-PKV Wed Feb 29 10:57:52 2012t + WES (me) returns WireEdgeSet from BOP; ---C++: return const & @@ -76,21 +87,21 @@ is --- 0 -Treat internal edges, --- 1 -Do not treat internal edges --- - SetManifoldFlag(me: out; - aMFlag: Boolean from Standard); - ---Purpose: - --- Modifier - --- + SetTreatSDScales (me: out; aTreatment: Integer from Standard); ---Purpose: --- Modifier --- 1 -Treat scale configured same domain faces, --- 0 -Do not treat them. - --- - - ManifoldFlag(me) - returns Boolean from Standard; + --- +-- SetManifoldFlag(me: out; +-- aMFlag: Boolean from Standard); + ---Purpose: + --- Modifier + --- +-- ManifoldFlag(me) +-- returns Boolean from Standard; ---Purpose: --- Selector --- @@ -108,82 +119,92 @@ is --- --- Faces' iterator --- - InitFace(me:out) - returns Integer from Standard; +-- InitFace(me:out) +-- returns Integer from Standard; - MoreFace(me) - returns Boolean from Standard; +-- MoreFace(me) +-- returns Boolean from Standard; - NextFace(me:out); +-- NextFace(me:out); ---Purpose: --- --- --- Wires' iterator --- - InitWire(me:out) - returns Integer from Standard; +-- InitWire(me:out) +-- returns Integer from Standard; - MoreWire(me) - returns Boolean from Standard; +-- MoreWire(me) +-- returns Boolean from Standard; - NextWire(me:out); +-- NextWire(me:out); - IsOldWire(me) - returns Boolean from Standard; +-- IsOldWire(me) +-- returns Boolean from Standard; - OldWire(me) - returns Shape from TopoDS; - ---C++: return const & +-- OldWire(me) +-- returns Shape from TopoDS; + -- ---C++: return const & - Wire(me) - returns Wire from TopoDS; - ---C++: return const & - ---Purpose: - --- +-- Wire(me) +-- returns Wire from TopoDS; +-- ---C++: return const & +-- ---Purpose: +-- --- --- --- Edges' iterator --- - FindNextValidElement(me:out); +-- FindNextValidElement(me:out); - InitEdge(me:out) - returns Integer from Standard; +-- InitEdge(me:out) +-- returns Integer from Standard; - MoreEdge(me) - returns Boolean from Standard; +-- MoreEdge(me) +-- returns Boolean from Standard; - NextEdge(me : in out); +-- NextEdge(me : in out); - Edge(me) - returns Edge from TopoDS; - ---C++: return const & +-- Edge(me) +-- returns Edge from TopoDS; +-- ---C++: return const & ---Purpose: - --- - MakeLoops(me :out; - SS :out WireEdgeSet from BOP) - is private; + --- + +-- MakeLoops(me :out; +-- SS :out WireEdgeSet from BOP) +-- is protected; ---Purpose: --- Make Loops from wires --- + DoInternalEdges (me :out) + is protected; + ---Purpose: + --- Processes internal edges if they exists + SDScales(me :out) - is private; + is protected; ---Purpose: --- Treatment SD faces with a "scale" --- - + --modified by NIZNHY-PKV Wed Feb 29 09:12:17 2012f + PerformAreas(me :out; + SS :out WireEdgeSet from BOP) + is protected; + --modified by NIZNHY-PKV Wed Feb 29 09:12:20 2012t + fields myFace : Face from TopoDS; - myLoopSet : LoopSet from BOP; - myBlockIterator : BlockIterator from BOP; - myBlockBuilder : BlockBuilder from BOP; - myFaceAreaBuilder : FaceAreaBuilder from BOP; +-- myLoopSet : LoopSet from BOP; +-- myBlockIterator : BlockIterator from BOP; +-- myBlockBuilder : BlockBuilder from BOP; +-- myFaceAreaBuilder : FaceAreaBuilder from BOP; myWES : PWireEdgeSet from BOP; myNewFaces : ListOfShape from TopTools; - myTreatment : Integer from Standard; - myManifoldFlag : Boolean from Standard; +-- myManifoldFlag : Boolean from Standard; myTreatSDScales : Integer from Standard; myNegatives : SequenceOfInteger from TColStd; - + myContext : Context from IntTools; end FaceBuilder; diff --git a/src/BOP/BOP_FaceBuilder.cxx b/src/BOP/BOP_FaceBuilder.cxx index dedca025eb..55a26e6740 100755 --- a/src/BOP/BOP_FaceBuilder.cxx +++ b/src/BOP/BOP_FaceBuilder.cxx @@ -47,35 +47,124 @@ #include #include -static void DoTopologicalVerification(TopoDS_Face& F); +//modified by NIZNHY-PKV Wed Feb 29 10:04:56 2012t +#include +#include +#include +#include +#include + +static + Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire, + const TopTools_IndexedMapOfShape& theMHE); +static + Standard_Boolean IsHole(const TopoDS_Shape& aW, + const TopoDS_Shape& aFace); +static + Standard_Boolean IsInside(const TopoDS_Shape& theHole, + const TopoDS_Shape& theF2, + const Handle(IntTools_Context)& theContext); +//modified by NIZNHY-PKV Wed Feb 29 10:05:21 2012t +static + void DoTopologicalVerification(TopoDS_Face& F); //======================================================================= //function : BOP_FaceBuilder //purpose : //======================================================================= - BOP_FaceBuilder::BOP_FaceBuilder(): +BOP_FaceBuilder::BOP_FaceBuilder(): myTreatment(0), - myManifoldFlag(Standard_True), +// myManifoldFlag(Standard_True), myTreatSDScales(0) { } - +//======================================================================= +//function : SetContext +//purpose : +//======================================================================= +void BOP_FaceBuilder::SetContext(const Handle(IntTools_Context)& aCtx) +{ + myContext=aCtx; +} +//======================================================================= +//function : Context +//purpose : +//======================================================================= +const Handle(IntTools_Context)& BOP_FaceBuilder::Context()const +{ + return myContext; +} +//======================================================================= +//function : SetTreatment +//purpose : +//======================================================================= +void BOP_FaceBuilder::SetTreatment(const Standard_Integer aTreatment) +{ + myTreatment=aTreatment; +} +//======================================================================= +//function : Treatment +//purpose : +//======================================================================= +Standard_Integer BOP_FaceBuilder::Treatment()const +{ + return myTreatment; +} +//======================================================================= +//function : SetTreatSDScales +//purpose : +//======================================================================= +void BOP_FaceBuilder::SetTreatSDScales(const Standard_Integer aTreatment) +{ + myTreatSDScales=aTreatment; +} +//======================================================================= +//function : TreatSDScales +//purpose : +//======================================================================= +Standard_Integer BOP_FaceBuilder::TreatSDScales()const +{ + return myTreatSDScales; +} +//======================================================================= +//function : WES +//purpose : +//======================================================================= +const BOP_WireEdgeSet& BOP_FaceBuilder::WES() const +{ + return *myWES; +} +//======================================================================= +//function : NewFaces +//purpose : +//======================================================================= +const TopTools_ListOfShape& BOP_FaceBuilder::NewFaces() const +{ + return myNewFaces; +} //======================================================================= //function : Do //purpose : //======================================================================= - void BOP_FaceBuilder::Do(const BOP_WireEdgeSet& aWES, - const Standard_Boolean bForceClass) +void BOP_FaceBuilder::Do(const BOP_WireEdgeSet& aWES, + const Standard_Boolean bForceClass) { myFace=aWES.Face(); myWES=(BOP_WireEdgeSet*) &aWES; // - // + //modified by NIZNHY-PKV Wed Feb 29 10:57:31 2012f + if (myContext.IsNull()) { + myContext=new IntTools_Context; + } + //modified by NIZNHY-PKV Wed Feb 29 10:57:34 2012t + // BOP_WESCorrector aWESCor; aWESCor.SetWES(aWES); aWESCor.Do(); BOP_WireEdgeSet& aNewWES=aWESCor.NewWES(); // + //modified by NIZNHY-PKV Wed Feb 29 09:28:06 2012f + /* //Make Loops. Only Loops are allowed after WESCorrector MakeLoops(aNewWES); // @@ -86,7 +175,10 @@ static void DoTopologicalVerification(TopoDS_Face& F); myFaceAreaBuilder.InitFaceAreaBuilder(LS, WEC, bForceClass); BuildNewFaces(); + */ + PerformAreas(aNewWES); + //modified by NIZNHY-PKV Wed Feb 29 09:28:08 2012t if (myTreatment==0) { DoInternalEdges(); @@ -103,13 +195,11 @@ static void DoTopologicalVerification(TopoDS_Face& F); DoTopologicalVerification(aF); } } - - //======================================================================= //function : DoInternalEdges //purpose : //======================================================================= - void BOP_FaceBuilder::DoInternalEdges() +void BOP_FaceBuilder::DoInternalEdges() { Standard_Integer i, aNbE, aNbSE, aNb, aNbF; TopTools_IndexedDataMapOfShapeListOfShape aDifferenceMap, aFLEMap; @@ -133,9 +223,6 @@ static void DoTopologicalVerification(TopoDS_Face& F); anEdgesMap.Add(aE); } } - - - aNbSE=aStartElementsMap.Extent(); aNbE=anEdgesMap.Extent(); @@ -211,8 +298,11 @@ static void DoTopologicalVerification(TopoDS_Face& F); for (; anIt.More(); anIt.Next()) { TopoDS_Face& aF=TopoDS::Face(anIt.Value()); // - IntTools_Context aCtx; - bIsPointInOnFace=aCtx.IsPointInOnFace(aF, aP2D); + //modified by NIZNHY-PKV Wed Feb 29 10:59:40 2012f + //IntTools_Context aCtx; + //bIsPointInOnFace=aCtx.IsPointInOnFace(aF, aP2D); + bIsPointInOnFace=myContext->IsPointInOnFace(aF, aP2D); + //modified by NIZNHY-PKV Wed Feb 29 10:59:43 2012t // if (bIsPointInOnFace) { // @@ -267,152 +357,541 @@ static void DoTopologicalVerification(TopoDS_Face& F); // } } - //======================================================================= -//function : BuildNewFaces +// function: TreatSDScales +// purpose : +//======================================================================= +void BOP_FaceBuilder::SDScales() +{ + + Standard_Integer iNegativeFlag, aNbFR, i, aNbEFOpen, iCnt; + + TopTools_ListOfShape aLFR; + TopTools_ListIteratorOfListOfShape anIt, anItFR; + TopTools_IndexedMapOfShape aMFR; + // + iCnt=myNewFaces.Extent(); + if (iCnt<2){ + return; + } + // + // 1. Collect all faces with negative (infinite) area + anIt.Initialize(myNewFaces); + for (i=1; anIt.More(); anIt.Next(), ++i) { + const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); + + iNegativeFlag=myNegatives(i); + if (iNegativeFlag) { + aLFR.Append(aF); + } + } + // + aNbFR=aLFR.Extent(); + // + if (!aNbFR) { + return; + } + // + // + BOP_ListOfConnexityBlock aLCB; + BOP_ListIteratorOfListOfConnexityBlock aLCBIt; + // + BOP_BuilderTools::MakeConnexityBlocks (myNewFaces, TopAbs_FACE, aLCB); + // + anItFR.Initialize(aLFR); + for (; anItFR.More(); anItFR.Next()) { + const TopoDS_Face& aFR=TopoDS::Face(anItFR.Value()); + // + iCnt=1; + TopTools_IndexedMapOfShape aMEFOpen; + BOP_ConnexityBlock* pCBR=NULL; + // + TopExp::MapShapes(aFR, TopAbs_EDGE, aMEFOpen); + aNbEFOpen=aMEFOpen.Extent(); + // + // Look for ConnexityBlock to which aFR belongs to (pCBR) + aLCBIt.Initialize(aLCB); + for (; aLCBIt.More() && iCnt; aLCBIt.Next()) { + const BOP_ConnexityBlock& aCB=aLCBIt.Value(); + + const TopTools_ListOfShape& aLCF=aCB.Shapes(); + anIt.Initialize(aLCF); + for (; anIt.More() && iCnt; anIt.Next()) { + const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); + TopTools_IndexedMapOfShape aMECB; + TopExp::MapShapes(aF, TopAbs_EDGE, aMECB); + + for (i=1; i<=aNbEFOpen; ++i) { + const TopoDS_Shape& aEFOpen= aMEFOpen(i); + if (aMECB.Contains(aEFOpen)) { + iCnt=0; + pCBR=(BOP_ConnexityBlock*) &aCB; + break; + } + } + } + } + // + if (iCnt) { + // it is strange + continue; + } + // + // Collect Faces to remove in the map aMFR + const TopTools_ListOfShape& aLCR=pCBR->Shapes(); + anIt.Initialize(aLCR); + for (; anIt.More(); anIt.Next()) { + const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); + aMFR.Add(aF); + } + } // for (; anItFR.More(); anItFR.Next()) + // + // + iCnt=aMFR.Extent(); + if (!iCnt) { + // Nothing to remove + return; + } + // + TopTools_ListOfShape aLFOut; + anIt.Initialize(myNewFaces); + for (; anIt.More(); anIt.Next()) { + const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); + if (!aMFR.Contains(aF)) { + aLFOut.Append(aF); + } + } + // + myNewFaces.Clear(); + anIt.Initialize(aLFOut); + for (; anIt.More(); anIt.Next()) { + const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); + myNewFaces.Append(aF); + } +} +//modified by NIZNHY-PKV Wed Feb 29 08:57:52 2012f +//======================================================================= +//function : PerformAreas //purpose : //======================================================================= - void BOP_FaceBuilder::BuildNewFaces() +void BOP_FaceBuilder::PerformAreas(BOP_WireEdgeSet& aWES) { - Standard_Integer nF, nW, nE; - Standard_Real aTol; - TopLoc_Location aLoc; - TopoDS_Face newFace; - TopoDS_Wire newWire; + Standard_Boolean bIsGrowth, bIsHole; + Standard_Real aTol; + TopTools_ListOfShape aNewFaces, aHoleWires, aLoops; + TopoDS_Shape anInfinitePointShape; + TopTools_DataMapOfShapeShape aInOutMap; + TopTools_DataMapOfShapeListOfShape aMSH; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH; + TopTools_ListIteratorOfListOfShape aIt1, aIt2; + TopTools_IndexedMapOfShape aMHE; BRep_Builder aBB; - Standard_Boolean bValidWire, bValidFace; - - Handle(Geom_Surface) aSurface=BRep_Tool::Surface(myFace, aLoc); + Handle(Geom_Surface) aS; + TopLoc_Location aLoc; + // aTol=BRep_Tool::Tolerance(myFace); - + aS=BRep_Tool::Surface(myFace, aLoc); + // myNewFaces.Clear(); - myNegatives.Clear(); - - nF=InitFace(); - for (; MoreFace(); NextFace()) { - bValidFace=Standard_False; - aBB.MakeFace (newFace, aSurface, aLoc, aTol); - - nW=InitWire(); - for (; MoreWire(); NextWire()) { - if (IsOldWire()) { - newWire=TopoDS::Wire(OldWire()); + // + for(aWES.InitShapes(); aWES.MoreShapes(); aWES.NextShape()) { + const TopoDS_Shape& aW=aWES.Shape(); + aLoops.Append(aW); + } + // + // Draft faces [aNewFaces] + aIt1.Initialize(aLoops); + for ( ; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aWire=aIt1.Value(); + // + bIsGrowth=IsGrowthWire(aWire, aMHE); + if (bIsGrowth) { + // make a growth face from a wire + TopoDS_Face aFace; + aBB.MakeFace(aFace, aS, aLoc, aTol); + aBB.Add (aFace, aWire); + // + aNewFaces.Append (aFace); + } + else{ + // check if a wire is a hole + bIsHole=IsHole(aWire, myFace); + //XX + if (bIsHole) { + aHoleWires.Append(aWire); + TopExp::MapShapes(aWire, TopAbs_EDGE, aMHE); } else { - aBB.MakeWire(newWire); - nE=InitEdge(); - for (; MoreEdge(); NextEdge()) { - const TopoDS_Edge& newEdge=Edge(); - aBB.Add(newWire, newEdge); - } + // make a growth face from a wire + TopoDS_Face aFace; + aBB.MakeFace(aFace, aS, aLoc, aTol); + aBB.Add (aFace, aWire); + // + aNewFaces.Append (aFace); } - - bValidWire=BOPTools_Tools3D::IsConvexWire(newWire); - if (bValidWire) { - bValidFace=Standard_True; - aBB.Add(newFace, newWire); + } + } + // + // 2. Find outer growth shell that is most close to each hole shell + aIt2.Initialize(aHoleWires); + for (; aIt2.More(); aIt2.Next()) { + const TopoDS_Shape& aHole = aIt2.Value(); + // + aIt1.Initialize(aNewFaces); + for ( ; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aF=aIt1.Value(); + // + if (!IsInside(aHole, aF, myContext)){ + continue; } - - else { - if (!myManifoldFlag && myTreatment==1) { - myNewFaces.Append (newWire); - } + // + if ( aInOutMap.IsBound (aHole)){ + const TopoDS_Shape& aF2=aInOutMap(aHole); + if (IsInside(aF, aF2, myContext)) { + aInOutMap.UnBind(aHole); + aInOutMap.Bind (aHole, aF); + } } - } // end of for (; MoreWire(); NextWire()) - - if (bValidFace) { - - Standard_Boolean bIsValidIn2D, bNegativeFlag; - Standard_Integer iNegativeFlag; - - bIsValidIn2D=BOPTools_Tools3D::IsValidArea (newFace, bNegativeFlag); - if(bIsValidIn2D) { - myNewFaces.Append (newFace); - iNegativeFlag=(Standard_Integer)bNegativeFlag; - myNegatives.Append(iNegativeFlag); + else{ + aInOutMap.Bind (aHole, aF); } - + } + // + // Add aHole to a map Face/ListOfHoles [aMSH] + if (aInOutMap.IsBound(aHole)){ + const TopoDS_Shape& aF=aInOutMap(aHole); + if (aMSH.IsBound(aF)) { + TopTools_ListOfShape& aLH=aMSH.ChangeFind(aF); + aLH.Append(aHole); + } + else { + TopTools_ListOfShape aLH; + aLH.Append(aHole); + aMSH.Bind(aF, aLH); + } + } + }// for (; aIt2.More(); aIt2.Next()) + // + // 3. Add aHoles to Faces + aItMSH.Initialize(aMSH); + for (; aItMSH.More(); aItMSH.Next()) { + TopoDS_Face aF=TopoDS::Face(aItMSH.Key()); + // + const TopTools_ListOfShape& aLH=aItMSH.Value(); + aIt2.Initialize(aLH); + for (; aIt2.More(); aIt2.Next()) { + const TopoDS_Shape& aHole = aIt2.Value(); + aBB.Add (aF, aHole); + } + // + // update classifier + aTol=BRep_Tool::Tolerance(aF); + IntTools_FClass2d& aClsf=myContext->FClass2d(aF); + aClsf.Init(aF, aTol); + } + // + // These aNewFaces are draft faces that + // do not contain any internal shapes + // + Standard_Boolean bIsValidIn2D, bNegativeFlag; + Standard_Integer iNegativeFlag; + // + myNewFaces.Clear(); + myNegatives.Clear(); + // + aIt1.Initialize(aNewFaces); + for ( ; aIt1.More(); aIt1.Next()) { + const TopoDS_Face& aFx=TopoDS::Face(aIt1.Value()); + bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFx, bNegativeFlag); + if(bIsValidIn2D) { + myNewFaces.Append (aFx); + iNegativeFlag=(Standard_Integer)bNegativeFlag; + myNegatives.Append(iNegativeFlag); } } + // } - //======================================================================= -//function : MakeLoops +//function : IsGrowthWire //purpose : //======================================================================= - void BOP_FaceBuilder::MakeLoops(BOP_WireEdgeSet& SS) +Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire, + const TopTools_IndexedMapOfShape& theMHE) { - //BOP_BlockBuilder& BB = myBlockBuilder; - BOP_ListOfLoop& LL = myLoopSet.ChangeListOfLoop(); - - // Build blocks on elements of SS [ Ready to remove this invocation] - // make list of loop (LL) of the LoopSet - // - on shapes of the ShapeSet (SS) - // - on blocks of the BlockBuilder (BB) - // - // Add shapes of SS as shape loops - LL.Clear(); - for(SS.InitShapes();SS.MoreShapes();SS.NextShape()) { - const TopoDS_Shape& S = SS.Shape(); - Handle(BOP_Loop) ShapeLoop = new BOP_Loop(S); - LL.Append(ShapeLoop); + Standard_Boolean bRet; + TopoDS_Iterator aIt; + // + bRet=Standard_False; + if (theMHE.Extent()) { + aIt.Initialize(theWire); + for(; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aE=aIt.Value(); + if (theMHE.Contains(aE)) { + return !bRet; + } + } } - + return bRet; } - //======================================================================= -//function : SetTreatment +//function : IsHole //purpose : //======================================================================= - void BOP_FaceBuilder::SetTreatment(const Standard_Integer aTreatment) +Standard_Boolean IsHole(const TopoDS_Shape& aW, + const TopoDS_Shape& aFace) { - myTreatment=aTreatment; + Standard_Boolean bIsHole; + Standard_Real aTolF; + TopoDS_Shape aFE; + TopoDS_Face aFF; + BRep_Builder aBB; + IntTools_FClass2d aFClass2d; + // + aFE=aFace.EmptyCopied(); + aFF=TopoDS::Face(aFE); + aFF.Orientation(TopAbs_FORWARD); + aBB.Add(aFF, aW); + // + aTolF=BRep_Tool::Tolerance(aFF); + // + aFClass2d.Init(aFF, aTolF); + // + bIsHole=aFClass2d.IsHole(); + // + return bIsHole; } - //======================================================================= -//function : Treatment +//function : IsInside //purpose : //======================================================================= - Standard_Integer BOP_FaceBuilder::Treatment()const +Standard_Boolean IsInside(const TopoDS_Shape& theHole, + const TopoDS_Shape& theF2, + const Handle(IntTools_Context)& theContext) { - return myTreatment; + Standard_Boolean bRet; + Standard_Real aT, aU, aV; + + TopAbs_State aState; + TopExp_Explorer aExp; + TopTools_IndexedMapOfShape aME2; + gp_Pnt2d aP2D; + // + bRet=Standard_False; + aState=TopAbs_UNKNOWN; + const TopoDS_Face& aF2=TopoDS::Face(theF2); + // + TopExp::MapShapes(aF2, TopAbs_EDGE, aME2); + // + aExp.Init(theHole, TopAbs_EDGE); + if (aExp.More()) { + const TopoDS_Edge& aE = TopoDS::Edge(aExp.Current()); + if (aME2.Contains(aE)) { + return bRet; + } + // + aT=BOPTools_Tools2D::IntermediatePoint(aE); + BOPTools_Tools2D::PointOnSurface(aE, aF2, aT, aU, aV); + aP2D.SetCoord(aU, aV); + // + IntTools_FClass2d& aClsf=theContext->FClass2d(aF2); + aState=aClsf.Perform(aP2D); + bRet=(aState==TopAbs_IN); + } + // + return bRet; } +//modified by NIZNHY-PKV Wed Feb 29 08:57:55 2012t + //======================================================================= -//function : SetTreatSDScales +//function : DoTopologicalVerification //purpose : //======================================================================= - void BOP_FaceBuilder::SetTreatSDScales(const Standard_Integer aTreatment) +void DoTopologicalVerification(TopoDS_Face& F) { - myTreatSDScales=aTreatment; -} + TopTools_IndexedDataMapOfShapeListOfShape mapVE; + mapVE.Clear(); + TopExp::MapShapesAndAncestors(F,TopAbs_VERTEX,TopAbs_EDGE,mapVE); + + Standard_Real pF1 = 0., pL1 = 0., pF2 = 0., pL2 = 0.; + Standard_Integer nbKeys = mapVE.Extent(), iKey = 0; + + for( iKey = 1; iKey <= nbKeys; iKey++ ) { + const TopoDS_Vertex& iV = TopoDS::Vertex(mapVE.FindKey(iKey)); + if( iV.IsNull() ) continue; + + Standard_Real TolV = BRep_Tool::Tolerance(iV); + + const TopTools_ListOfShape& iLE = mapVE.FindFromIndex(iKey); + Standard_Integer nbE = iLE.Extent(); + if( nbE != 2 ) break; + + const TopoDS_Edge& iE1 = TopoDS::Edge(iLE.First()); + const TopoDS_Edge& iE2 = TopoDS::Edge(iLE.Last()); + + if(BRep_Tool::Degenerated(iE1) || BRep_Tool::Degenerated(iE2) ) continue; + + Standard_Real iPE1 = BRep_Tool::Parameter(iV,iE1); + Standard_Real iPE2 = BRep_Tool::Parameter(iV,iE2); + + Handle(Geom_Curve) aC3D1 = BRep_Tool::Curve(iE1,pF1,pL1); + Handle(Geom_Curve) aC3D2 = BRep_Tool::Curve(iE2,pF2,pL2); + if( aC3D1.IsNull() || aC3D2.IsNull() ) break; + + Standard_Boolean is1F = (fabs(iPE1-pF1) < fabs(iPE1-pL1)); + Standard_Boolean is2F = (fabs(iPE2-pF2) < fabs(iPE2-pL2)); + + Standard_Real useP1 = iPE1; + if( is1F ) { + if( fabs(iPE1-pF1) > 1.e-7 ) useP1 = pF1; + } + else { + if( fabs(iPE1-pL1) > 1.e-7 ) useP1 = pL1; + } + + Standard_Real useP2 = iPE2; + if( is2F ) { + if( fabs(iPE2-pF2) > 1.e-7 ) useP2 = pF2; + } + else { + if( fabs(iPE2-pL2) > 1.e-7 ) useP2 = pL2; + } + + gp_Pnt aPnt1 = aC3D1->Value(useP1); + gp_Pnt aPnt2 = aC3D2->Value(useP2); + gp_Pnt aPntV = BRep_Tool::Pnt(iV); + + Standard_Real distV1 = aPntV.Distance(aPnt1); + Standard_Real distV2 = aPntV.Distance(aPnt2); + + // update vertex tolerance checking 3D curves + if( distV1 > TolV || distV2 > TolV ) { + Standard_Real distMax = Max(distV1,distV2); + Standard_Real delta = fabs(distMax-TolV); + Standard_Real newTol = TolV + delta + 2.e-7; + TopoDS_Vertex & aV = (TopoDS_Vertex &) iV; + BRep_Builder bb; + bb.UpdateVertex(aV,newTol); + TolV = newTol; + } + gp_Pnt2d aPnt2dF, aPnt2dL; + BRep_Tool::UVPoints(iE1,F,aPnt2dF, aPnt2dL); + gp_Pnt2d aPnt2dE1 = (is1F) ? aPnt2dF : aPnt2dL; + BRep_Tool::UVPoints(iE2,F,aPnt2dF, aPnt2dL); + gp_Pnt2d aPnt2dE2 = (is2F) ? aPnt2dF : aPnt2dL; + + BRepAdaptor_Surface aFSurf (F,Standard_False); + aPnt1 = aFSurf.Value(aPnt2dE1.X(), aPnt2dE1.Y()); + aPnt2 = aFSurf.Value(aPnt2dE2.X(), aPnt2dE2.Y()); + distV1 = aPntV.Distance(aPnt1); + distV2 = aPntV.Distance(aPnt2); + + // update vertex tolerance checking 3D points on surface + if( distV1 > TolV || distV2 > TolV ) { + Standard_Real distMax = Max(distV1,distV2); + Standard_Real delta = fabs(distMax-TolV); + Standard_Real newTol = TolV + delta + 2.e-7; + TopoDS_Vertex & aV = (TopoDS_Vertex &) iV; + BRep_Builder bb; + bb.UpdateVertex(aV,newTol); + TolV = newTol; + } + } +} +//modified by NIZNHY-PKV Wed Feb 29 10:07:16 2012f +/* //======================================================================= -//function : TreatSDScales +//function : MakeLoops //purpose : //======================================================================= - Standard_Integer BOP_FaceBuilder::TreatSDScales()const + void BOP_FaceBuilder::MakeLoops(BOP_WireEdgeSet& SS) { - return myTreatSDScales; + //BOP_BlockBuilder& BB = myBlockBuilder; + BOP_ListOfLoop& LL = myLoopSet.ChangeListOfLoop(); + + // Build blocks on elements of SS [ Ready to remove this invocation] + // make list of loop (LL) of the LoopSet + // - on shapes of the ShapeSet (SS) + // - on blocks of the BlockBuilder (BB) + // + // Add shapes of SS as shape loops + LL.Clear(); + for(SS.InitShapes();SS.MoreShapes();SS.NextShape()) { + const TopoDS_Shape& S = SS.Shape(); + Handle(BOP_Loop) ShapeLoop = new BOP_Loop(S); + LL.Append(ShapeLoop); + } } +*/ +/* //======================================================================= -//function : SetManifoldFlag +//function : BuildNewFaces //purpose : //======================================================================= - void BOP_FaceBuilder::SetManifoldFlag(const Standard_Boolean aManifoldFlag) + void BOP_FaceBuilder::BuildNewFaces() { - myManifoldFlag=aManifoldFlag; -} + Standard_Integer nF, nW, nE; + Standard_Real aTol; + TopLoc_Location aLoc; + TopoDS_Face newFace; + TopoDS_Wire newWire; + BRep_Builder aBB; + Standard_Boolean bValidWire, bValidFace; + + Handle(Geom_Surface) aSurface=BRep_Tool::Surface(myFace, aLoc); + aTol=BRep_Tool::Tolerance(myFace); + myNewFaces.Clear(); + myNegatives.Clear(); -//======================================================================= -//function : ManifoldFlag -//purpose : -//======================================================================= - Standard_Boolean BOP_FaceBuilder::ManifoldFlag()const -{ - return myManifoldFlag; -} + nF=InitFace(); + for (; MoreFace(); NextFace()) { + bValidFace=Standard_False; + aBB.MakeFace (newFace, aSurface, aLoc, aTol); + nW=InitWire(); + for (; MoreWire(); NextWire()) { + if (IsOldWire()) { + newWire=TopoDS::Wire(OldWire()); + } + else { + aBB.MakeWire(newWire); + nE=InitEdge(); + for (; MoreEdge(); NextEdge()) { + const TopoDS_Edge& newEdge=Edge(); + aBB.Add(newWire, newEdge); + } + } + + bValidWire=BOPTools_Tools3D::IsConvexWire(newWire); + if (bValidWire) { + bValidFace=Standard_True; + aBB.Add(newFace, newWire); + } + + else { + if (!myManifoldFlag && myTreatment==1) { + myNewFaces.Append (newWire); + } + } + } // end of for (; MoreWire(); NextWire()) + + if (bValidFace) { + + Standard_Boolean bIsValidIn2D, bNegativeFlag; + Standard_Integer iNegativeFlag; + + bIsValidIn2D=BOPTools_Tools3D::IsValidArea (newFace, bNegativeFlag); + if(bIsValidIn2D) { + myNewFaces.Append (newFace); + iNegativeFlag=(Standard_Integer)bNegativeFlag; + myNegatives.Append(iNegativeFlag); + } + } + } +} +*/ +/* //======================================================================= //function : InitFace //purpose : @@ -439,6 +918,7 @@ static void DoTopologicalVerification(TopoDS_Face& F); { myFaceAreaBuilder.NextArea(); } + //======================================================================= //function : InitWire //purpose : @@ -493,7 +973,8 @@ static void DoTopologicalVerification(TopoDS_Face& F); { return TopoDS::Wire(OldWire()); } - +*/ +/* //======================================================================= //function : InitEdge //purpose : @@ -569,238 +1050,23 @@ static void DoTopologicalVerification(TopoDS_Face& F); return anEdge; } - +*/ +/* //======================================================================= -//function : WES +//function : SetManifoldFlag //purpose : //======================================================================= - const BOP_WireEdgeSet& BOP_FaceBuilder::WES() const + void BOP_FaceBuilder::SetManifoldFlag(const Standard_Boolean aManifoldFlag) { - return *myWES; + myManifoldFlag=aManifoldFlag; } - //======================================================================= -//function : NewFaces +//function : ManifoldFlag //purpose : //======================================================================= - const TopTools_ListOfShape& BOP_FaceBuilder::NewFaces() const -{ - return myNewFaces; -} - -//======================================================================= -// function: TreatSDScales Jan 15 12:25:34 2002 -// purpose : -//======================================================================= - void BOP_FaceBuilder::SDScales() -{ - - Standard_Integer iNegativeFlag, aNbFR, i, aNbEFOpen, iCnt; - - TopTools_ListOfShape aLFR; - TopTools_ListIteratorOfListOfShape anIt, anItFR; - TopTools_IndexedMapOfShape aMFR; - // - iCnt=myNewFaces.Extent(); - if (iCnt<2){ - return; - } - // - // 1. Collect all faces with negative (infinite) area - anIt.Initialize(myNewFaces); - for (i=1; anIt.More(); anIt.Next(), ++i) { - const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); - - iNegativeFlag=myNegatives(i); - if (iNegativeFlag) { - aLFR.Append(aF); - } - } - // - aNbFR=aLFR.Extent(); - // - if (!aNbFR) { - return; - } - // - // - BOP_ListOfConnexityBlock aLCB; - BOP_ListIteratorOfListOfConnexityBlock aLCBIt; - // - BOP_BuilderTools::MakeConnexityBlocks (myNewFaces, TopAbs_FACE, aLCB); - // - anItFR.Initialize(aLFR); - for (; anItFR.More(); anItFR.Next()) { - const TopoDS_Face& aFR=TopoDS::Face(anItFR.Value()); - // - iCnt=1; - TopTools_IndexedMapOfShape aMEFOpen; - BOP_ConnexityBlock* pCBR=NULL; - // - TopExp::MapShapes(aFR, TopAbs_EDGE, aMEFOpen); - aNbEFOpen=aMEFOpen.Extent(); - // - // Look for ConnexityBlock to which aFR belongs to (pCBR) - aLCBIt.Initialize(aLCB); - for (; aLCBIt.More() && iCnt; aLCBIt.Next()) { - const BOP_ConnexityBlock& aCB=aLCBIt.Value(); - - const TopTools_ListOfShape& aLCF=aCB.Shapes(); - anIt.Initialize(aLCF); - for (; anIt.More() && iCnt; anIt.Next()) { - const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); - TopTools_IndexedMapOfShape aMECB; - TopExp::MapShapes(aF, TopAbs_EDGE, aMECB); - - for (i=1; i<=aNbEFOpen; ++i) { - const TopoDS_Shape& aEFOpen= aMEFOpen(i); - if (aMECB.Contains(aEFOpen)) { - iCnt=0; - pCBR=(BOP_ConnexityBlock*) &aCB; - break; - } - } - } - } - // - if (iCnt) { - // it is strange - continue; - } - // - // Collect Faces to remove in the map aMFR - const TopTools_ListOfShape& aLCR=pCBR->Shapes(); - anIt.Initialize(aLCR); - for (; anIt.More(); anIt.Next()) { - const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); - aMFR.Add(aF); - } - } // for (; anItFR.More(); anItFR.Next()) - // - // - iCnt=aMFR.Extent(); - if (!iCnt) { - // Nothing to remove - return; - } - // - TopTools_ListOfShape aLFOut; - anIt.Initialize(myNewFaces); - for (; anIt.More(); anIt.Next()) { - const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); - if (!aMFR.Contains(aF)) { - aLFOut.Append(aF); - } - } - // - myNewFaces.Clear(); - anIt.Initialize(aLFOut); - for (; anIt.More(); anIt.Next()) { - const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); - myNewFaces.Append(aF); - } - -} - -void DoTopologicalVerification(TopoDS_Face& F) + Standard_Boolean BOP_FaceBuilder::ManifoldFlag()const { - TopTools_IndexedDataMapOfShapeListOfShape mapVE; - mapVE.Clear(); - TopExp::MapShapesAndAncestors(F,TopAbs_VERTEX,TopAbs_EDGE,mapVE); - - Standard_Real pF1 = 0., pL1 = 0., pF2 = 0., pL2 = 0.; - Standard_Integer nbKeys = mapVE.Extent(), iKey = 0; - - for( iKey = 1; iKey <= nbKeys; iKey++ ) { - const TopoDS_Vertex& iV = TopoDS::Vertex(mapVE.FindKey(iKey)); - if( iV.IsNull() ) continue; - - Standard_Real TolV = BRep_Tool::Tolerance(iV); - - const TopTools_ListOfShape& iLE = mapVE.FindFromIndex(iKey); - Standard_Integer nbE = iLE.Extent(); - if( nbE != 2 ) break; - - const TopoDS_Edge& iE1 = TopoDS::Edge(iLE.First()); - const TopoDS_Edge& iE2 = TopoDS::Edge(iLE.Last()); - - if(BRep_Tool::Degenerated(iE1) || BRep_Tool::Degenerated(iE2) ) continue; - - Standard_Real iPE1 = BRep_Tool::Parameter(iV,iE1); - Standard_Real iPE2 = BRep_Tool::Parameter(iV,iE2); - - Handle(Geom_Curve) aC3D1 = BRep_Tool::Curve(iE1,pF1,pL1); - Handle(Geom_Curve) aC3D2 = BRep_Tool::Curve(iE2,pF2,pL2); - if( aC3D1.IsNull() || aC3D2.IsNull() ) break; - - Standard_Boolean is1F = (fabs(iPE1-pF1) < fabs(iPE1-pL1)); - Standard_Boolean is2F = (fabs(iPE2-pF2) < fabs(iPE2-pL2)); - - Standard_Real useP1 = iPE1; - if( is1F ) { - if( fabs(iPE1-pF1) > 1.e-7 ) useP1 = pF1; - } - else { - if( fabs(iPE1-pL1) > 1.e-7 ) useP1 = pL1; - } - - Standard_Real useP2 = iPE2; - if( is2F ) { - if( fabs(iPE2-pF2) > 1.e-7 ) useP2 = pF2; - } - else { - if( fabs(iPE2-pL2) > 1.e-7 ) useP2 = pL2; - } - - gp_Pnt aPnt1 = aC3D1->Value(useP1); - gp_Pnt aPnt2 = aC3D2->Value(useP2); - gp_Pnt aPntV = BRep_Tool::Pnt(iV); - - Standard_Real distV1 = aPntV.Distance(aPnt1); - Standard_Real distV2 = aPntV.Distance(aPnt2); - - // update vertex tolerance checking 3D curves - if( distV1 > TolV || distV2 > TolV ) { - Standard_Real distMax = Max(distV1,distV2); - Standard_Real delta = fabs(distMax-TolV); - Standard_Real newTol = TolV + delta + 2.e-7; - TopoDS_Vertex & aV = (TopoDS_Vertex &) iV; - BRep_Builder bb; - bb.UpdateVertex(aV,newTol); - TolV = newTol; - } - - gp_Pnt2d aPnt2dF, aPnt2dL; - BRep_Tool::UVPoints(iE1,F,aPnt2dF, aPnt2dL); - gp_Pnt2d aPnt2dE1 = (is1F) ? aPnt2dF : aPnt2dL; - BRep_Tool::UVPoints(iE2,F,aPnt2dF, aPnt2dL); - gp_Pnt2d aPnt2dE2 = (is2F) ? aPnt2dF : aPnt2dL; - - BRepAdaptor_Surface aFSurf (F,Standard_False); - aPnt1 = aFSurf.Value(aPnt2dE1.X(), aPnt2dE1.Y()); - aPnt2 = aFSurf.Value(aPnt2dE2.X(), aPnt2dE2.Y()); - distV1 = aPntV.Distance(aPnt1); - distV2 = aPntV.Distance(aPnt2); - - // update vertex tolerance checking 3D points on surface - if( distV1 > TolV || distV2 > TolV ) { - Standard_Real distMax = Max(distV1,distV2); - Standard_Real delta = fabs(distMax-TolV); - Standard_Real newTol = TolV + delta + 2.e-7; - TopoDS_Vertex & aV = (TopoDS_Vertex &) iV; - BRep_Builder bb; - bb.UpdateVertex(aV,newTol); - TolV = newTol; - } - -// Standard_Real dist2d = aPnt2dE1.Distance(aPnt2dE2); -// // update veretex tolerance checking distance in 2D -// if( dist2d > TolV ) { -// Standard_Real delta2d = fabs(dist2d-TolV); -// Standard_Real newTolV = TolV + delta2d + 2.e-7; -// TopoDS_Vertex & aV = (TopoDS_Vertex &) iV; -// BRep_Builder bb; -// bb.UpdateVertex(aV,newTolV); -// } - } + return myManifoldFlag; } +*/ +//modified by NIZNHY-PKV Wed Feb 29 10:07:05 2012t -- 2.39.5