From 19d6e40d3f8e222c248a0e559f10579895d7faa2 Mon Sep 17 00:00:00 2001 From: pkv Date: Fri, 1 Feb 2013 17:19:18 +0400 Subject: [PATCH] 0023711: Incorrect result done by fuse operation Correction of misprint Adding of test case --- src/BOP/BOP_SolidSolid.cdl | 11 +- src/BOP/BOP_SolidSolid.cxx | 47 +++- src/BOP/BOP_SolidSolid_1.cxx | 404 ++++++++++++++++++++++++----- tests/boolean/bopcommon_simple/ZP8 | 2 +- tests/boolean/bopcut_simple/ZP9 | 2 +- tests/boolean/bopfuse_simple/ZP5 | 2 +- tests/boolean/boptuc_simple/ZP4 | 2 +- tests/bugs/modalg/bug23711 | 15 ++ 8 files changed, 411 insertions(+), 74 deletions(-) create mode 100755 tests/bugs/modalg/bug23711 diff --git a/src/BOP/BOP_SolidSolid.cdl b/src/BOP/BOP_SolidSolid.cdl index ee9a4a6a97..7103a442cd 100755 --- a/src/BOP/BOP_SolidSolid.cdl +++ b/src/BOP/BOP_SolidSolid.cdl @@ -36,6 +36,7 @@ uses IndexedDataMapOfIntegerIndexedMapOfInteger from BOPTColStd, DataMapOfShapeInteger from TopTools, Shape from TopoDS, + Solid from TopoDS, State from TopAbs, ListOfShape from TopTools @@ -102,6 +103,12 @@ is theBaseFaceIndex: Integer from Standard) returns Boolean from Standard is private; - ---fields + + PrepareReferences(me:out) + is protected; + +fields + myRefObject: Solid from TopoDS is protected; + myRefTool : Solid from TopoDS is protected; + end SolidSolid; diff --git a/src/BOP/BOP_SolidSolid.cxx b/src/BOP/BOP_SolidSolid.cxx index 0298f11462..ce2226fe77 100755 --- a/src/BOP/BOP_SolidSolid.cxx +++ b/src/BOP/BOP_SolidSolid.cxx @@ -153,19 +153,20 @@ static Standard_Boolean LocalIsKeepTwice(const TopoDS_Face& aF1, try { OCC_CATCH_SIGNALS - // modified by NIZHNY-MKK Fri Sep 3 15:14:17 2004.BEGIN if(!myDSFiller->IsDone()) { myErrorStatus = 1; BOPTColStd_Dump::PrintMessage("DSFiller is invalid: Can not build result\n"); return; } - // modified by NIZHNY-MKK Fri Sep 3 15:14:20 2004.END + // + PrepareReferences(); + // Standard_Boolean bIsNewFiller; bIsNewFiller=aDSFiller.IsNewFiller(); if (bIsNewFiller) { Prepare(); - + PrepareFaceSplits(); aDSFiller.SetNewFiller(!bIsNewFiller); @@ -199,7 +200,43 @@ static Standard_Boolean LocalIsKeepTwice(const TopoDS_Face& aF1, BOPTColStd_Dump::PrintMessage("Can not build result\n"); } } - +//================================================================================= +// function: PrepareReferences +// purpose: +//================================================================================= +void BOP_SolidSolid::PrepareReferences() +{ + Standard_Integer i; + const BooleanOperations_ShapesDataStructure& aDS = myDSFiller->DS(); + // + for (i=0; i<2; ++i) { + const TopoDS_Shape& aS=(!i)? aDS.Object() : aDS.Tool(); + // + TopoDS_Solid aRefSolid; + // + if(aS.ShapeType() == TopAbs_SOLID) { + aRefSolid = TopoDS::Solid(aS); + } + else { + BRep_Builder aBB; + TopExp_Explorer aExp; + // + aBB.MakeSolid(aRefSolid); + // + aExp.Init(aS, TopAbs_SHELL); + for(; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aShell = aExp.Current(); + aBB.Add(aRefSolid, aShell); + } + } + if(!i) { + myRefObject=aRefSolid; + } + else { + myRefTool=aRefSolid; + } + } +} //================================================================================= // function: BuildResult // purpose: @@ -391,7 +428,6 @@ static Standard_Boolean LocalIsKeepTwice(const TopoDS_Face& aF1, } } - // modified by NIZHNY-MKK Tue Sep 16 11:11:22 2003.BEGIN Standard_Boolean bIsCommonalgo = CheckFaceIntersection(nF1, myDSFiller); BOP_WireEdgeSet atmpWES (myFace); BOP_WireEdgeSet atmpWESAvoid (myFace); @@ -726,7 +762,6 @@ static Standard_Boolean LocalIsKeepTwice(const TopoDS_Face& aF1, } //end for (; aWES2.MoreStartElements... } - // modified by NIZHNY-MKK Tue Sep 16 11:11:33 2003.END // //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/BOP/BOP_SolidSolid_1.cxx b/src/BOP/BOP_SolidSolid_1.cxx index caf2e65668..db826889be 100755 --- a/src/BOP/BOP_SolidSolid_1.cxx +++ b/src/BOP/BOP_SolidSolid_1.cxx @@ -23,6 +23,20 @@ #include #include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -33,11 +47,23 @@ #include #include #include +#include +#include +// +#include +#include +#include + +#include #include #include +#include #include +#include +#include + #include #include #include @@ -48,22 +74,12 @@ #include #include #include - +#include #include - -#include +#include #include -#include -#include - -#include -#include -#include -#include -#include - static Standard_Integer GetIndex(const TopoDS_Shape& theShape, const BooleanOperations_ShapesDataStructure& theDS); @@ -83,11 +99,12 @@ void GetStatesOfAdjacentFaces(const TColStd_ListOfInteger& theListOfFacesToCheck Standard_Boolean& bFoundOUTOUT); static -Standard_Boolean ComputeStateForAnalyticalSurfaces(const Standard_Integer theFaceIndex, - const Standard_Integer theBaseFaceIndex, - const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap, - const BOPTools_DSFiller& theDSFiller, - TopAbs_State& theState); + Standard_Boolean ComputeStateForAnalyticalSurfaces + (const Standard_Integer theFaceIndex, + const Standard_Integer theBaseFaceIndex, + const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap, + const BOPTools_DSFiller& theDSFiller, + TopAbs_State& theState); static Standard_Boolean IsEdgeValidForFace(const Standard_Integer theEdgeIndex, @@ -95,6 +112,28 @@ Standard_Boolean IsEdgeValidForFace(const Standard_Integer theEdgeIndex, BOPTools_SSInterference& theFF, const BOPTools_DSFiller& theDSFiller); +static + TopAbs_State ComputeState(const TopoDS_Face& theF, + const TopoDS_Solid& theRef, + const Standard_Real theTol, + const Handle(IntTools_Context)& theCtx); + +static + Standard_Integer PntInFace(const TopoDS_Face& aF, + gp_Pnt& theP, + gp_Pnt2d& theP2D); + +static + Standard_Integer PntHoverFace(const TopoDS_Face& aF, + gp_Pnt& theP); + +static + TopAbs_State ComputeState(const gp_Pnt& theP, + const TopoDS_Solid& theRef, + const Standard_Real theTol, + const Handle(IntTools_Context)& theCtx); + + //================================================================================= // function: PrepareFaceSplits // purpose: @@ -263,15 +302,16 @@ Standard_Boolean BOP_SolidSolid::PropagateFaceStateByEdges(const TopoDS_Shape& t return Standard_True; } -// ===================================================================================================================== -// function: ComputeStateByInsidePoints -// purpose: -// ===================================================================================================================== -Standard_Boolean BOP_SolidSolid::ComputeStateByInsidePoints(const Standard_Integer theFaceIndex, - const Standard_Integer theBaseFaceIndex, - const Standard_Integer theFaceRank, - const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap, - TopAbs_State& theState) +//======================================================================= +//function : ComputeStateByInsidePoints +//purpose : +//======================================================================= +Standard_Boolean BOP_SolidSolid:: + ComputeStateByInsidePoints(const Standard_Integer theFaceIndex, + const Standard_Integer theBaseFaceIndex, + const Standard_Integer theFaceRank, + const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap, + TopAbs_State& theState) { TopAbs_State aState = TopAbs_ON; @@ -344,11 +384,10 @@ Standard_Boolean BOP_SolidSolid::ComputeStateByInsidePoints(const Standard_Integ return Standard_True; } - -// ===================================================================================================================== -// function: TakeOnSplit -// purpose: -// ===================================================================================================================== +//======================================================================= +//function : TakeOnSplit +//purpose : +//======================================================================= Standard_Boolean BOP_SolidSolid::TakeOnSplit(const Standard_Integer theFaceIndex, const Standard_Integer theBaseFaceIndex) const { @@ -361,13 +400,59 @@ Standard_Boolean BOP_SolidSolid::TakeOnSplit(const Standard_Integer theFaceIndex TColStd_MapOfInteger aMapOfUsedIndices; TColStd_ListOfInteger aListOfFacesToCheck; aListOfFacesToCheck.Append(theFaceIndex); - - GetStatesOfAdjacentFaces(aListOfFacesToCheck, *myDSFiller, aMapOfUsedIndices, binout, binin, boutout); + //DEB + Handle(IntTools_Context) aCtx; + TopAbs_Orientation aOrF1; + TopoDS_Face aF1, aFSp; + // + const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS(); + const BOPTools_PaveFiller& aPF =myDSFiller->PaveFiller(); + BOPTools_PaveFiller* pPF = (BOPTools_PaveFiller*)&aPF; + aCtx=pPF->Context(); + // + aF1=TopoDS::Face(aDS.Shape(theBaseFaceIndex)); + aOrF1=aF1.Orientation(); + aFSp=TopoDS::Face(aDS.Shape(theFaceIndex)); + aFSp.Orientation(aOrF1); + // + GetStatesOfAdjacentFaces(aListOfFacesToCheck, + *myDSFiller, + aMapOfUsedIndices, + binout, binin, boutout); + //zzf + if (!binout && !binin && !boutout) { + Standard_Real aTol; + TopAbs_State aState; + // + aTol=1.e-5; + aState=ComputeState(aFSp, myRefTool, aTol, aCtx); + // + if (aState==TopAbs_IN) { + if (myOperation==BOP_FUSE || myOperation==BOP_COMMON) { + bTake=Standard_False; + } + else { + bTake=Standard_True; + } + } + // + else if (aState==TopAbs_OUT) { + if (myOperation==BOP_FUSE || myOperation==BOP_COMMON) { + bTake=Standard_True; + } + else { + bTake=Standard_False; + } + } + // + return bTake; + }//if (!binout && !binin && !boutout) { + //zzt switch(myOperation) { case BOP_FUSE: { if(binout || (!binin && !boutout)) { - bTake = Standard_True; + bTake = Standard_True; } break; } @@ -477,11 +562,10 @@ void GetAttachedFaces(const Standard_Integer theEdgeIndex, } } } - -// ------------------------------------------------------------------------------------ -// static function: GetStatesOfAdjacentFaces -// purpose: -// ------------------------------------------------------------------------------------ +//======================================================================= +//function : GetStatesOfAdjacentFaces +//purpose : +//======================================================================= void GetStatesOfAdjacentFaces(const TColStd_ListOfInteger& theListOfFacesToCheck, const BOPTools_DSFiller& theDSFiller, TColStd_MapOfInteger& theMapOfUsedIndices, @@ -489,33 +573,38 @@ void GetStatesOfAdjacentFaces(const TColStd_ListOfInteger& theListOfFacesToCheck Standard_Boolean& bFoundININ, Standard_Boolean& bFoundOUTOUT) { - - const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS(); TColStd_ListOfInteger aLisOfON; + Standard_Integer nE, nF, nFa; + BooleanOperations_StateOfShape aStFa; + // + const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS(); + // TColStd_ListIteratorOfListOfInteger anItF(theListOfFacesToCheck); - for(; anItF.More(); anItF.Next()) { - Standard_Integer nF = anItF.Value(); + nF = anItF.Value(); + const TopoDS_Shape& aF=aDS.Shape(nF); if(theMapOfUsedIndices.Contains(nF)) { continue; } + // theMapOfUsedIndices.Add(nF); - + TopoDS_Shape aFace = aDS.Shape(nF); TopExp_Explorer anExpE(aFace, TopAbs_EDGE); for(; anExpE.More(); anExpE.Next()) { const TopoDS_Shape& anEdge = anExpE.Current(); - Standard_Integer nE = 0; nE = GetIndex(anEdge, aDS); - if(nE <= 0) + if(nE <= 0) { continue; - - if(theMapOfUsedIndices.Contains(nE)) + } + if(theMapOfUsedIndices.Contains(nE)) { continue; + } + // theMapOfUsedIndices.Add(nE); TColStd_ListOfInteger aListOfFaces, aListOfIN, aListOfOUT; GetAttachedFaces(nE, nF, theDSFiller, aListOfFaces); @@ -523,18 +612,23 @@ void GetStatesOfAdjacentFaces(const TColStd_ListOfInteger& theListOfFacesToCheck TColStd_ListIteratorOfListOfInteger anIt(aListOfFaces); for(; anIt.More(); anIt.Next()) { - if(theMapOfUsedIndices.Contains(anIt.Value())) - continue; - - // if((aDS.GetState(anIt.Value()) != BooleanOperations_IN) && - // (aDS.GetState(anIt.Value()) != BooleanOperations_OUT)) - if(aDS.GetState(anIt.Value()) == BooleanOperations_ON) - aLisOfON.Append(anIt.Value()); - - if(aDS.GetState(anIt.Value()) == BooleanOperations_IN) - aListOfIN.Append(anIt.Value()); - else if(aDS.GetState(anIt.Value()) == BooleanOperations_OUT) - aListOfOUT.Append(anIt.Value()); + nFa=anIt.Value(); + aStFa=aDS.GetState(nFa); + // + const TopoDS_Shape& aFa=aDS.Shape(nFa); + if(theMapOfUsedIndices.Contains(nFa)) { + continue; + } + // + if(aStFa==BooleanOperations_ON) { + aLisOfON.Append(nFa); + } + if(aStFa==BooleanOperations_IN) { + aListOfIN.Append(nFa); + } + else if(aStFa==BooleanOperations_OUT) { + aListOfOUT.Append(nFa); + } } bFoundINOUT = bFoundINOUT || (!aListOfIN.IsEmpty() && !aListOfOUT.IsEmpty()); bFoundININ = bFoundININ || (!aListOfIN.IsEmpty() && aListOfOUT.IsEmpty()); @@ -707,7 +801,193 @@ Standard_Boolean IsEdgeValidForFace(const Standard_Integer theEdgeIndex, } } } - - return Standard_False; } +//======================================================================= +// function: ComputeState +// purpose: +//======================================================================= +TopAbs_State ComputeState(const TopoDS_Face& theF, + const TopoDS_Solid& theRef, + const Standard_Real theTol, + const Handle(IntTools_Context)& theCtx) +{ + Standard_Integer iErr; + TopAbs_State aRet; + gp_Pnt aP; + // + aRet=TopAbs_UNKNOWN; + // + iErr=PntHoverFace(theF, aP); + if (iErr) { + return aRet; + } + // + aRet=ComputeState(aP, theRef, theTol, theCtx); + return aRet; +} + +//======================================================================= +// function: ComputeState +// purpose: +//======================================================================= +TopAbs_State ComputeState(const gp_Pnt& theP, + const TopoDS_Solid& theRef, + const Standard_Real theTol, + const Handle(IntTools_Context)& theCtx) +{ + TopAbs_State aState; + // + BRepClass3d_SolidClassifier& aSC=theCtx->SolidClassifier(theRef); + aSC.Perform(theP, theTol); + // + aState=aSC.State(); + // + return aState; +} +//======================================================================= +//function : PntHoverFace +//purpose : +//======================================================================= +Standard_Integer PntHoverFace(const TopoDS_Face& aF, + gp_Pnt& theP) +{ + Standard_Integer iErr; + Standard_Real aU, aV, aX; + gp_Pnt aP; + gp_Vec aDN; + gp_Pnt2d aP2D; + // + iErr=PntInFace(aF, aP, aP2D); + if (iErr) { + return iErr; + } + // + aX=1e-4; + // + aP2D.Coord(aU, aV); + BOPTools_Tools2D::FaceNormal(aF, aU, aV, aDN); + // + theP.SetXYZ(aP.XYZ()+aX*aDN.XYZ()); + // + return iErr; +} +//======================================================================= +//function : PntInFace +//purpose : +//======================================================================= +Standard_Integer PntInFace(const TopoDS_Face& aF, + gp_Pnt& theP, + gp_Pnt2d& theP2D) +{ + Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; + Standard_Integer iErr, aIx, aNbDomains, i; + Standard_Real aUMin, aUMax, aVMin, aVMax; + Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT; + Standard_Real aTolArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D; + gp_Dir2d aD2D (0., 1.); + gp_Pnt2d aP2D; + gp_Pnt aPx; + Handle(Geom2d_Curve) aC2D; + Handle(Geom2d_TrimmedCurve) aCT2D; + Handle(Geom2d_Line) aL2D; + Handle(Geom_Surface) aS; + TopAbs_Orientation aOrE; + TopoDS_Face aFF; + TopExp_Explorer aExp; + // + aTolHatch2D=1.e-8; + aTolHatch3D=1.e-8; + aTolArcIntr=1.e-10; + aTolTangfIntr=1.e-10; + // + Geom2dHatch_Intersector aIntr(aTolArcIntr, aTolTangfIntr); + Geom2dHatch_Hatcher aHatcher(aIntr, + aTolHatch2D, aTolHatch3D, + Standard_True, Standard_False); + // + iErr=0; + aEpsT=1.e-12; + // + aFF=aF; + aFF.Orientation (TopAbs_FORWARD); + // + aS=BRep_Tool::Surface(aFF); + BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); + // + // 1 + aExp.Init (aFF, TopAbs_EDGE); + for (; aExp.More() ; aExp.Next()) { + const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current()); + aOrE=aE.Orientation(); + // + aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2); + if (aC2D.IsNull() ) { + iErr=1; + return iErr; + } + if (fabs(aU1-aU2) < aEpsT) { + iErr=2; + return iErr; + } + // + aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2); + aHatcher.AddElement(aCT2D, aOrE); + }// for (; aExp.More() ; aExp.Next()) { + // + // 2 + aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax); + aP2D.SetCoord(aUx, 0.); + aL2D=new Geom2d_Line (aP2D, aD2D); + Geom2dAdaptor_Curve aHCur(aL2D); + // + aIx=aHatcher.AddHatching(aHCur) ; + // + // 3. + aHatcher.Trim(); + bIsDone=aHatcher.TrimDone(aIx); + if (!bIsDone) { + iErr=3; + return iErr; + } + // + aHatcher.ComputeDomains(aIx); + bIsDone=aHatcher.IsDone(aIx); + if (!bIsDone) { + iErr=4; + return iErr; + } + // + // 4. + aNbDomains=aHatcher.NbDomains(aIx); + for (i=1; i<=aNbDomains; ++i) { + const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; + bHasFirstPoint=aDomain.HasFirstPoint(); + if (!bHasFirstPoint) { + iErr=5; + return iErr; + } + // + aV1=aDomain.FirstPoint().Parameter(); + // + bHasSecondPoint=aDomain.HasSecondPoint(); + if (!bHasSecondPoint) { + iErr=6; + return iErr; + } + // + aV2=aDomain.SecondPoint().Parameter(); + // + aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); + // + break; + } + // + aS->D0(aUx, aVx, aPx); + // + theP2D.SetCoord(aUx, aVx); + theP=aPx; + // + return iErr; +} + diff --git a/tests/boolean/bopcommon_simple/ZP8 b/tests/boolean/bopcommon_simple/ZP8 index 0366271c53..4ca00499bf 100644 --- a/tests/boolean/bopcommon_simple/ZP8 +++ b/tests/boolean/bopcommon_simple/ZP8 @@ -13,4 +13,4 @@ explode r so bop r_1 b1 bopcommon result -set square 96 +set square empty diff --git a/tests/boolean/bopcut_simple/ZP9 b/tests/boolean/bopcut_simple/ZP9 index 8e7dc20b38..0f62898c13 100644 --- a/tests/boolean/bopcut_simple/ZP9 +++ b/tests/boolean/bopcut_simple/ZP9 @@ -13,4 +13,4 @@ explode r so bop r_1 b1 bopcut result -set square 600 +set square 696 diff --git a/tests/boolean/bopfuse_simple/ZP5 b/tests/boolean/bopfuse_simple/ZP5 index 2d55fda44a..9a554d2775 100644 --- a/tests/boolean/bopfuse_simple/ZP5 +++ b/tests/boolean/bopfuse_simple/ZP5 @@ -13,4 +13,4 @@ explode r so bop r_1 b1 bopfuse result -set square 696 +set square 600 diff --git a/tests/boolean/boptuc_simple/ZP4 b/tests/boolean/boptuc_simple/ZP4 index 1c5760e13a..9fb33a6aec 100644 --- a/tests/boolean/boptuc_simple/ZP4 +++ b/tests/boolean/boptuc_simple/ZP4 @@ -13,4 +13,4 @@ explode r so bop r_1 b1 boptuc result -set square empty +set square 96 diff --git a/tests/bugs/modalg/bug23711 b/tests/bugs/modalg/bug23711 new file mode 100755 index 0000000000..0765851aa9 --- /dev/null +++ b/tests/bugs/modalg/bug23711 @@ -0,0 +1,15 @@ +puts "========" +puts "CR23711" +puts "========" +######################################################## +## Incorrect result done by fuse operation +######################################################## + +restore [locate_data_file bug23711_sph1.brep] b1 +restore [locate_data_file bug23711_sph2.brep] b2 + +bop b1 b2 +bopfuse result + +set square 1256.63 +set 2dviewer 1