From f56518cdbef81cf10fa70dad3e57d240fea92558 Mon Sep 17 00:00:00 2001 From: emv Date: Thu, 22 May 2014 18:12:35 +0400 Subject: [PATCH] 0024879: Wrong result of General Fuse operation Modifications: 1. class BOPAlgo_WireSplitter 1.1. Removed static method RecomputeAngles(...). 1.2. Minor corrections. 2. class BOPTools_AlgoTools 2.1 method GetFaceOff For definition of an angles between faces the same step in 3D space has been used for all faces in the list. To define that step new static function MinStep3D has been implemented. Added test case bugs/modalg_5/bug24879 Deleted unnecessary TODOs in test case bugs/modalg_2/bug497_3 --- src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx | 316 ++++++------------------- src/BOPTools/BOPTools_AlgoTools.cxx | 145 +++++++----- tests/bugs/modalg_2/bug497_3 | 5 +- tests/bugs/modalg_5/bug24879 | 18 ++ 4 files changed, 179 insertions(+), 305 deletions(-) create mode 100644 tests/bugs/modalg_5/bug24879 diff --git a/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx b/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx index 7581938340..e0471429dc 100644 --- a/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx +++ b/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx @@ -57,6 +57,11 @@ #include +typedef NCollection_DataMap \ + \ + BOPCol_DataMapOfShapeBoolean; +// + static Standard_Real Angle (const gp_Dir2d& aDir2D); @@ -88,8 +93,7 @@ static const TopoDS_Edge& aE1, const TopoDS_Face& aF); - -static +static Standard_Real ClockWiseAngle(const Standard_Real aAngleIn, const Standard_Real aAngleOut); @@ -103,14 +107,9 @@ static BOPCol_SequenceOfShape& aVertVa, BOPCol_SequenceOfPnt2d& aCoordVa, BOPTools_ConnexityBlock& aCB, - BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap); - -static - Standard_Real Angle2D (const TopoDS_Vertex& aV, - const TopoDS_Edge& anEdge, - const TopoDS_Face& myFace, - const GeomAdaptor_Surface& aGAS, - const Standard_Boolean aFlag); + BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap, + BOPCol_DataMapOfShapeBoolean aVertMap); + static Standard_Real Angle (const gp_Dir2d& aDir2D); @@ -127,17 +126,6 @@ static Standard_Real VTolerance2D (const TopoDS_Vertex& aV, const GeomAdaptor_Surface& aGAS); -static - Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo, - const TopoDS_Face& theFace, - const gp_Pnt2d& thePb, - const TopoDS_Vertex& theVb, - const GeomAdaptor_Surface& theGAS, - const TopoDS_Edge& theEOuta, - const Standard_Boolean& bHasClosed, - const Standard_Real& theTol2D, - BOPCol_SequenceOfReal& theRecomputedAngles); - static void RefineAngles(const TopoDS_Face& myFace, const BOPCol_ListOfShape&, @@ -165,16 +153,18 @@ static void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace, BOPTools_ConnexityBlock& aCB) { - Standard_Boolean bNothingToDo; + Standard_Boolean bNothingToDo, bIsClosed, bIsIN; Standard_Integer aIx, aNb, i, aCntIn, aCntOut; Standard_Real aAngle; TopAbs_Orientation aOr; TopoDS_Iterator aItS; TopoDS_Vertex aVV; + TopoDS_Shape aV1; BOPCol_ListIteratorOfListOfShape aIt; BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI; // BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100); + BOPCol_DataMapOfShapeBoolean aVertMap; // const BOPCol_ListOfShape& myEdges=aCB.Shapes(); // @@ -188,28 +178,40 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace, continue; } // + bIsClosed = BRep_Tool::Degenerated(aE) || + BRep_Tool::IsClosed(aE, myFace); + // aItS.Initialize(aE); - for(; aItS.More(); aItS.Next()) { - const TopoDS_Shape& aV=aItS.Value(); - aIx=mySmartMap.FindIndex(aV); + for(i = 0; aItS.More(); aItS.Next(), ++i) { + const TopoDS_Shape& aV = aItS.Value(); + aIx = mySmartMap.FindIndex(aV); if (!aIx) { BOPAlgo_ListOfEdgeInfo aLEIx; - aIx=mySmartMap.Add(aV, aLEIx); + aIx = mySmartMap.Add(aV, aLEIx); } // - BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(aIx); - // + BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap(aIx); BOPAlgo_EdgeInfo aEI; // aEI.SetEdge(aE); - aOr=aV.Orientation(); - if (aOr==TopAbs_FORWARD) { - aEI.SetInFlag(Standard_False); - } - else if (aOr==TopAbs_REVERSED) { - aEI.SetInFlag(Standard_True); - } + aOr = aV.Orientation(); + bIsIN = (aOr == TopAbs_REVERSED); + aEI.SetInFlag(bIsIN); aLEI.Append(aEI); + // + if (!i) { + aV1 = aV; + } else { + bIsClosed = bIsClosed || aV1.IsSame(aV); + } + // + if (aVertMap.IsBound(aV)) { + if (bIsClosed) { + aVertMap.ChangeFind(aV) = bIsClosed; + } + } else { + aVertMap.Bind(aV, bIsClosed); + } } } // @@ -299,7 +301,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace, const GeomAdaptor_Surface& aGAS=aBAS.Surface(); // for (i=1; i<=aNb; i++) { - const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i))); + const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&mySmartMap.FindKey(i))); const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i); aItLEI.Initialize(aLEI); @@ -307,15 +309,11 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace, BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); const TopoDS_Edge& aE=aEI.Edge(); // - aVV=aV; - if (aEI.IsIn()) { - aVV.Orientation(TopAbs_REVERSED); - aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True); - } - else { // OUT - aVV.Orientation(TopAbs_FORWARD); - aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False); - } + aVV = aV; + bIsIN = aEI.IsIn(); + aOr = bIsIN ? TopAbs_REVERSED : TopAbs_FORWARD; + aVV.Orientation(aOr); + aAngle = Angle2D(aVV, aE, myFace, aGAS, bIsIN); aEI.SetAngle(aAngle); } }// for (i=1; i<=aNb; i++) { @@ -348,7 +346,7 @@ void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace, aCoordVa.Clear(); // Path(aGAS, myFace, aVa, aEOuta, aEI, aLS, - aVertVa, aCoordVa, aCB, mySmartMap); + aVertVa, aCoordVa, aCB, mySmartMap, aVertMap); } } }// for (i=1; i<=aNb; ++i) { @@ -366,18 +364,18 @@ void Path (const GeomAdaptor_Surface& aGAS, BOPCol_SequenceOfShape& aVertVa, BOPCol_SequenceOfPnt2d& aCoordVa, BOPTools_ConnexityBlock& aCB, - BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap) + BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap, + BOPCol_DataMapOfShapeBoolean aVertMap) { Standard_Integer i, j, aNb, aNbj; Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle; Standard_Real aTol2D, aTol2D2, aD2, aTwoPI; Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed; - Standard_Boolean bIsClosed, bRecomputeAngle; + Standard_Boolean bIsClosed; TopoDS_Vertex aVa, aVb; TopoDS_Edge aEOuta; BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; - BOPCol_SequenceOfReal aRecomputedAngles; // aVa = aVFirst; aEOuta = aEFirst; @@ -415,23 +413,7 @@ void Path (const GeomAdaptor_Surface& aGAS, aTol2D = 2.*Tolerance2D(aVb, aGAS); aTol2D2 = aTol2D * aTol2D; // - bIsClosed = BRep_Tool::Degenerated(aEOuta) || - BRep_Tool::IsClosed(aEOuta, myFace) || aVa.IsSame(aVb); - if (!bIsClosed) { - TopoDS_Vertex aV1, aV2; - // - anIt.Initialize(aLEInfo); - for (; anIt.More() && !bIsClosed; anIt.Next()) { - const BOPAlgo_EdgeInfo& anEI = anIt.Value(); - const TopoDS_Edge& aE = anEI.Edge(); - // - bIsClosed = BRep_Tool::Degenerated(aE) || BRep_Tool::IsClosed(aE, myFace); - if (!bIsClosed) { - TopExp::Vertices(aE, aV1, aV2); - bIsClosed = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2); - } - } - } + bIsClosed = aVertMap.Find(aVb); // aNb=aLS.Length(); if (aNb>0) { @@ -512,11 +494,6 @@ void Path (const GeomAdaptor_Surface& aGAS, } } // - aRecomputedAngles.Clear(); - bRecomputeAngle = - RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta, - bIsClosed, aTol2D, aRecomputedAngles); - // // aEOutb BOPAlgo_EdgeInfo *pEdgeInfo=NULL; // @@ -530,7 +507,7 @@ void Path (const GeomAdaptor_Surface& aGAS, const TopoDS_Edge& aE=anEI.Edge(); anIsOut=!anEI.IsIn(); anIsNotPassed=!anEI.Passed(); - + // if (anIsOut && anIsNotPassed) { aCurIndexE++; // @@ -568,12 +545,6 @@ void Path (const GeomAdaptor_Surface& aGAS, // // Look for minimal angle and make the choice. anAngleOut=anEI.Angle(); - // - if(bRecomputeAngle) { - if(aCurIndexE <= aRecomputedAngles.Length()) { - anAngleOut = aRecomputedAngles.Value(aCurIndexE); - } - } anAngle=ClockWiseAngle(anAngleIn, anAngleOut); } if (anAngle < aMinAngle) { @@ -751,7 +722,7 @@ Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo) const TopoDS_Edge& anEdge, const TopoDS_Face& myFace, const GeomAdaptor_Surface& aGAS, - const Standard_Boolean aFlag) + const Standard_Boolean bIsIN) { Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX; gp_Pnt2d aPV, aPV1; @@ -794,14 +765,7 @@ Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo) aC2D->D0 (aTV1, aPV1); aC2D->D0 (aTV, aPV); // - if (aFlag) {//IN - gp_Vec2d aV2DIn(aPV1, aPV); - aV2D=aV2DIn; - } - else { - gp_Vec2d aV2DOut(aPV, aPV1); - aV2D=aV2DOut; - } + aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1); // gp_Dir2d aDir2D(aV2D); anAngle=Angle(aDir2D); @@ -875,155 +839,6 @@ Standard_Real VTolerance2D (const TopoDS_Vertex& aV, return anVr; } -//======================================================================= -// function: RecomputeAngles -// purpose: -//======================================================================= -Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo, - const TopoDS_Face& theFace, - const gp_Pnt2d& thePb, - const TopoDS_Vertex& theVb, - const GeomAdaptor_Surface& theGAS, - const TopoDS_Edge& theEOuta, - const Standard_Boolean& bIsClosed, - const Standard_Real& theTol2D, - BOPCol_SequenceOfReal& theRecomputedAngles) -{ - Standard_Boolean bRecomputeAngle = Standard_False; - BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; - anIt.Initialize(aLEInfo); - - for (; anIt.More(); anIt.Next()) { - const BOPAlgo_EdgeInfo& anEI=anIt.Value(); - const TopoDS_Edge& aE=anEI.Edge(); - Standard_Boolean anIsOut=!anEI.IsIn(); - Standard_Boolean anIsNotPassed=!anEI.Passed(); - - if (anIsOut && anIsNotPassed) { - theRecomputedAngles.Append(anEI.Angle()); - Standard_Integer acurindex = theRecomputedAngles.Length(); - - Standard_Boolean bRecomputeAngleLocal = Standard_False; - TopExp_Explorer anExp1(aE, TopAbs_VERTEX); - - for(; anExp1.More(); anExp1.Next()) { - TopExp_Explorer anExp2(theEOuta, TopAbs_VERTEX); - Standard_Boolean existsInEdge = Standard_False; - - for(; anExp2.More(); anExp2.Next()) { - if(anExp1.Current().IsSame(anExp2.Current())) { - existsInEdge = Standard_True; - break; - } - } - - if(!existsInEdge) { - bRecomputeAngleLocal = Standard_False; - break; - } - bRecomputeAngleLocal = Standard_True; - } - bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal; - - if(!bRecomputeAngle) { - BOPAlgo_ListIteratorOfListOfEdgeInfo anIt2(aLEInfo); - - for(; anIt2.More(); anIt2.Next()) { - const BOPAlgo_EdgeInfo& anEI2=anIt2.Value(); - const TopoDS_Edge& aE2=anEI2.Edge(); - - if(aE2.IsSame(aE)) - continue; - Standard_Boolean anIsOut2=!anEI2.IsIn(); - Standard_Boolean anIsNotPassed2=!anEI2.Passed(); - - if (anIsOut2 && anIsNotPassed2) { - anExp1.Init(aE, TopAbs_VERTEX); - - for(; anExp1.More(); anExp1.Next()) { - TopExp_Explorer anExp2(aE2, TopAbs_VERTEX); - Standard_Boolean existsInEdge = Standard_False; - - for(; anExp2.More(); anExp2.Next()) { - if(anExp1.Current().IsSame(anExp2.Current())) { - existsInEdge = Standard_True; - break; - } - } - - if(!existsInEdge) { - bRecomputeAngleLocal = Standard_False; - break; - } - bRecomputeAngleLocal = Standard_True; - } - bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal; - } - } - } - - bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal; - - if(bRecomputeAngle) { - gp_Pnt2d aP2Dx; - // - aP2Dx=Coord2dVf(aE, theFace); - Standard_Real aD = aP2Dx.Distance(thePb); - - TopoDS_Vertex aVf; - TopExp_Explorer anExp(aE, TopAbs_VERTEX); - - for (; anExp.More(); anExp.Next()) { - const TopoDS_Vertex& aVx=*(TopoDS_Vertex*)(&anExp.Current()); - if (aVx.Orientation()==TopAbs_FORWARD) { - aVf = aVx; - } - } - Standard_Boolean bIgnore = Standard_False; - - if(bIsClosed || aVf.IsNull() || !aVf.IsSame(theVb)) { - bIgnore = (aD > theTol2D); - } - - if(!bIgnore && (theTol2D > M_PI)) { - Standard_Real udist = fabs(aP2Dx.X() - thePb.X()); - Standard_Real vdist = fabs(aP2Dx.Y() - thePb.Y()); - Standard_Real aTolU = 2. * UTolerance2D(theVb, theGAS); - Standard_Real aTolV = 2. * VTolerance2D(theVb, theGAS); - - if((udist > aTolU) || - (vdist > aTolV)) { - bIgnore = Standard_True; - } - } - - if((aD > Precision::Confusion()) && !bIgnore) { - Standard_Real f1, l1; - Handle(Geom2d_Curve) ac1 = BRep_Tool::CurveOnSurface(aE, theFace, f1, l1); - - Standard_Real aTV1 = BRep_Tool::Parameter (aVf, aE, theFace); - Standard_Real aTV12 = 0.; - Standard_Real dt1 = (l1 - f1) * 0.5; - - if (fabs (aTV1-f1) < fabs(aTV1 - l1)) { - aTV12 = aTV1 + dt1; - } - else { - aTV12 = aTV1 - dt1; - } - - gp_Pnt2d aPointNew = ac1->Value(aTV12); - gp_Vec2d aV2DOut(thePb, aPointNew); - - gp_Dir2d aDir2D(aV2DOut); - Standard_Real anAngleOut = Angle(aDir2D); - theRecomputedAngles.ChangeValue(acurindex) = anAngleOut; - } - } - } - } - return bRecomputeAngle; -} //======================================================================= //function : RefineAngles //purpose : @@ -1091,14 +906,15 @@ void RefineAngles(const TopoDS_Vertex& aV, BOPAlgo_ListOfEdgeInfo& aLEI) { Standard_Boolean bIsIn, bIsBoundary, bRefined; - Standard_Integer iCnt; + Standard_Integer iCntBnd, iCntInt; Standard_Real aA, aA1, aA2; BOPCol_DataMapOfShapeReal aDMSR; BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI; // aA1=0.; aA2=0.; - iCnt=0; + iCntBnd=0; + iCntInt=0; aItLEI.Initialize(aLEI); for (; aItLEI.More(); aItLEI.Next()) { BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); @@ -1107,7 +923,7 @@ void RefineAngles(const TopoDS_Vertex& aV, aA=aEI.Angle(); // if (aMBE.Contains(aE)) { - ++iCnt; + ++iCntBnd; if (!bIsIn) { aA1=aA; } @@ -1115,9 +931,12 @@ void RefineAngles(const TopoDS_Vertex& aV, aA2=aA+M_PI; } } + else { + ++iCntInt; + } } // - if (iCnt!=2) { + if (iCntBnd!=2) { return; } // @@ -1133,7 +952,7 @@ void RefineAngles(const TopoDS_Vertex& aV, } // aA=aEI.Angle(); - if (!(aAaA2)) { + if (aA>aA1 && aAD0(aTV, aPV); // - iSign=(fabs(aTV-aT1) < fabs(aTV-aT2)) ? 1 : -1; + aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1; // aGAC1.Load(aC2D, aT1, aT2); aC2D->D0(aT1, aP1); @@ -1237,9 +1061,9 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV, } } // - dT=(iSign==1) ? aT2-aT1max : aT1max-aT1; + dT = aTOp - aT1max; // - aT=aT1max+aCf*dT; + aT=aT1max + aCf*dT; aC2D->D0(aT, aP); gp_Vec2d aV2D(aPV, aP); gp_Dir2d aDir2D(aV2D); diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index ad698ff74e..67cba7f118 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -90,15 +90,21 @@ static gp_Dir& aDN, gp_Dir& aDB, Handle(BOPInt_Context)& theContext, - GeomAPI_ProjectPointOnSurf& aProjPL); + GeomAPI_ProjectPointOnSurf& aProjPL, + const Standard_Real aDt); static - Standard_Boolean FindPointInFace(const TopoDS_Edge& aE, - const TopoDS_Face& aF, + Standard_Boolean FindPointInFace(const TopoDS_Face& aF, const gp_Pnt& aP, gp_Dir& aDB, gp_Pnt& aPOut, Handle(BOPInt_Context)& theContext, - GeomAPI_ProjectPointOnSurf& aProjPL); + GeomAPI_ProjectPointOnSurf& aProjPL, + const Standard_Real aDt); +static + Standard_Real MinStep3D(const TopoDS_Edge& theE1, + const TopoDS_Face& theF1, + const BOPTools_ListOfCoupleOfShape& theLCS, + const gp_Pnt& aP); //======================================================================= // function: MakeConnexityBlocks @@ -805,7 +811,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff Handle(BOPInt_Context)& theContext) { Standard_Boolean bRet; - Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin; + Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D; Standard_Real aUmin, aUsup, aVmin, aVsup; gp_Pnt aPn1, aPn2, aPx; gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF; @@ -830,8 +836,9 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff aPL->Bounds(aUmin, aUsup, aVmin, aVsup); aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup); // + aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx); GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, - aProjPL); + aProjPL, aDt3D); // aDTF=aDN1^aDBF; // @@ -844,7 +851,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff // aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed(); GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, - aProjPL); + aProjPL, aDt3D); //Angle aAngle=AngleWithRef(aDBF, aDBF2, aDTF); // @@ -1811,7 +1818,8 @@ void GetFaceDir(const TopoDS_Edge& aE, gp_Dir& aDN, gp_Dir& aDB, Handle(BOPInt_Context)& theContext, - GeomAPI_ProjectPointOnSurf& aProjPL) + GeomAPI_ProjectPointOnSurf& aProjPL, + const Standard_Real aDt) { BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN); if (aF.Orientation()==TopAbs_REVERSED){ @@ -1820,7 +1828,7 @@ void GetFaceDir(const TopoDS_Edge& aE, aDB = aDN^aDTgt; // gp_Pnt aPx; - if (!FindPointInFace(aE, aF, aP, aDB, aPx, theContext, aProjPL)) { + if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt)) { BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, aDN, theContext); aProjPL.Perform(aPx); @@ -1834,19 +1842,18 @@ void GetFaceDir(const TopoDS_Edge& aE, //function : FindPointInFace //purpose : Find a point in the face in direction of //======================================================================= -Standard_Boolean FindPointInFace(const TopoDS_Edge& aE, - const TopoDS_Face& aF, +Standard_Boolean FindPointInFace(const TopoDS_Face& aF, const gp_Pnt& aP, gp_Dir& aDB, gp_Pnt& aPOut, Handle(BOPInt_Context)& theContext, - GeomAPI_ProjectPointOnSurf& aProjPL) + GeomAPI_ProjectPointOnSurf& aProjPL, + const Standard_Real aDt) { Standard_Integer aNbItMax; - Standard_Real aDt, aDtMin, aTolE, aTolF, aDist, aDTol, aPM; + Standard_Real aDist, aDTol, aPM; Standard_Boolean bRet; gp_Pnt aP1; - BRepAdaptor_Surface aBAS; // aDTol = Precision::Angular(); aPM = aP.XYZ().Modulus(); @@ -1854,49 +1861,9 @@ Standard_Boolean FindPointInFace(const TopoDS_Edge& aE, aDTol = 5.e-16 * aPM; } bRet = Standard_False; - aTolE = BRep_Tool::Tolerance(aE); - aTolF = BRep_Tool::Tolerance(aF); - aDt = 2*(aTolE+aTolF); - aBAS.Initialize(aF, Standard_False); - // - aDtMin=5.e-4; - if (aDt < aDtMin) { - Standard_Real aR; - GeomAbs_SurfaceType aSType=aBAS.GetType(); - switch (aSType) { - case GeomAbs_Cylinder: - aR = aBAS.Cylinder().Radius(); - break; - case GeomAbs_Cone: { - gp_Lin aL(aBAS.Cone().Axis()); - aR = aL.Distance(aP); - break; - } - case GeomAbs_Sphere: - aR = aBAS.Sphere().Radius(); - break; - case GeomAbs_Torus: - aR = aBAS.Torus().MinorRadius(); - break; - case GeomAbs_SurfaceOfRevolution: - aR=1.; - break; - default: - aR=0.001; - } - if (aR < 0.01) { - aDtMin=5.e-6; - } - else if (aR > 100.) { - aDtMin*=10; - } - if (aDt < aDtMin) { - aDt=aDtMin; - } - } + aNbItMax = 15; // GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF); - aNbItMax = 15; // do { aP1.SetCoord(aP.X()+aDt*aDB.X(), @@ -1921,6 +1888,74 @@ Standard_Boolean FindPointInFace(const TopoDS_Edge& aE, return bRet; } //======================================================================= +//function : MinStep3D +//purpose : +//======================================================================= +Standard_Real MinStep3D(const TopoDS_Edge& theE1, + const TopoDS_Face& theF1, + const BOPTools_ListOfCoupleOfShape& theLCS, + const gp_Pnt& aP) +{ + Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR; + BOPTools_CoupleOfShape aCS1; + BOPTools_ListOfCoupleOfShape aLCS; + BOPTools_ListIteratorOfListOfCoupleOfShape aIt; + BRepAdaptor_Surface aBAS; + // + aLCS = theLCS; + aCS1.SetShape1(theE1); + aCS1.SetShape2(theF1); + aLCS.Append(aCS1); + // + aTolE = BRep_Tool::Tolerance(theE1); + aDtMax = -1.; + aDtMin = 5.e-6; + // + aIt.Initialize(aLCS); + for (; aIt.More(); aIt.Next()) { + const BOPTools_CoupleOfShape& aCS = aIt.Value(); + const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2())); + // + aTolF = BRep_Tool::Tolerance(aF); + aDt = 2*(aTolE + aTolF); + // + aR = 0.; + aBAS.Initialize(aF, Standard_False); + GeomAbs_SurfaceType aSType = aBAS.GetType(); + if (aSType == GeomAbs_Cylinder) { + aR = aBAS.Cylinder().Radius(); + } + else if (aSType == GeomAbs_Cone) { + gp_Lin aL(aBAS.Cone().Axis()); + aR = aL.Distance(aP); + } + else if (aSType == GeomAbs_Sphere) { + aR = aBAS.Sphere().Radius(); + } + else if (aSType == GeomAbs_Torus) { + aR = aBAS.Torus().MajorRadius(); + } + else if (aSType == GeomAbs_SurfaceOfRevolution) { + aDtMin = 5.e-4; + } + // + if (aR > 100.) { + Standard_Real d = Precision::PConfusion(); + aDtMin = sqrt(d*d + 2*d*aR); + } + // + if (aDt > aDtMax) { + aDtMax = aDt; + } + } + // + if (aDtMax < aDtMin) { + aDtMax = aDtMin; + } + // + return aDtMax; +} +//======================================================================= //function : IsOpenShell //purpose : //======================================================================= diff --git a/tests/bugs/modalg_2/bug497_3 b/tests/bugs/modalg_2/bug497_3 index 1375ba6a06..d5a7166f19 100755 --- a/tests/bugs/modalg_2/bug497_3 +++ b/tests/bugs/modalg_2/bug497_3 @@ -1,6 +1,3 @@ -puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC12345 ALL: Error : The square of result shape is" - puts "=========" puts " OCC497 " puts "(case 3)" @@ -18,5 +15,5 @@ checkshape a_2 bcut result a_1 a_2 -set square 0 +set square 1773.6 set 2dviewer 0 diff --git a/tests/bugs/modalg_5/bug24879 b/tests/bugs/modalg_5/bug24879 new file mode 100644 index 0000000000..877cd9fc8b --- /dev/null +++ b/tests/bugs/modalg_5/bug24879 @@ -0,0 +1,18 @@ +puts "==========" +puts "OCC24879" +puts "==========" +puts "" +############################################ +# Wrong result of General Fuse operation +############################################ + +restore [locate_data_file bug24879_c.brep] c + +bclearobjects +bcleartools +baddcompound c +bfillds -s +bbuild result +checkshape result + +set 2dviewer 1