From: msv Date: Fri, 1 Sep 2017 06:10:36 +0000 (+0300) Subject: 0029038: Modeling - IntTools_EdgeEdge::FindParameters() hangs on bad curve X-Git-Tag: V7_3_0_beta~263 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=28c08a7d40e6736f29fdcf6c20b05de48af198f1 0029038: Modeling - IntTools_EdgeEdge::FindParameters() hangs on bad curve Make possibility to dramatically increase the step during iteration on the curve when the global resolution of the curve is too small. Correct the functions FindParameters, FindBestSolution, FindDistPC. The change caused improvement of the test case "boolean bfuse_complex E4", so the bug #27697 has been fixed. The change caused dramatic improvement of the performance of the test "bugs modalg_7 bug27160", and the bug #29080 has been fixed. --- diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index 795686c093..f853f19bf6 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -1888,6 +1888,8 @@ Standard_Boolean GetFaceDir(const TopoDS_Edge& aE, bFound = BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge (aE, aF, aT, aDt, aPx, aDN, theContext); aProjPL.Perform(aPx); + Standard_ASSERT_RETURN(aProjPL.IsDone(), + "GetFaceDir: Project point on plane is failed", Standard_False); aPx = aProjPL.NearestPoint(); gp_Vec aVec(aP, aPx); aDB.SetXYZ(aVec.XYZ()); diff --git a/src/IntTools/IntTools_EdgeEdge.cxx b/src/IntTools/IntTools_EdgeEdge.cxx index 3121648169..2f402c358b 100644 --- a/src/IntTools/IntTools_EdgeEdge.cxx +++ b/src/IntTools/IntTools_EdgeEdge.cxx @@ -505,39 +505,48 @@ Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theB Standard_Real& aTB2) { Standard_Boolean bRet; - Standard_Integer aC, i, k; + Standard_Integer aC, i; Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn; - Standard_Real aDist, aDistP, aDistTol; + Standard_Real aDist, aDistP; gp_Pnt aP; Bnd_Box aCBx; // bRet = Standard_False; aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.; - aDt = theRes; - aDistP = 0.; - aDistTol = 1e-9; aCBx = theCBox; - aCBx.Enlarge(theTol); + aCBx.SetGap(aCBx.GetGap() + theTol); // const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve(); const GeomAbs_CurveType aCurveType = theBAC.GetType(); + Standard_Real aMaxDt = (aT2 - aT1) * 0.01; // for (i = 0; i < 2; ++i) { aTB = !i ? aT1 : aT2; aT = !i ? aT2 : aTB1; aC = !i ? 1 : -1; + aDt = theRes; + aDistP = 0.; bRet = Standard_False; - k = 0; + Standard_Real k = 1; //looking for the point on the edge which is in the box; while (aC*(aT-aTB) >= 0) { theBAC.D0(aTB, aP); aDist = PointBoxDistance(theCBox, aP); if (aDist > theTol) { - if (fabs(aDist - aDistP) < aDistTol) { - aDt = Resolution(aCurve, aCurveType, theResCoeff, (++k)*aDist); - } else { - k = 0; - aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist); + if (aDistP > 0.) { + Standard_Boolean toGrow = Standard_False; + if (Abs(aDistP - aDist) / aDistP < 0.1) { + aDt = Resolution(aCurve, aCurveType, theResCoeff, k*aDist); + if (aDt < aMaxDt) + { + toGrow = Standard_True; + k *= 2; + } + } + if (!toGrow) { + k = 1; + aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist); + } } aTB += aC*aDt; } else { @@ -735,16 +744,14 @@ void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11, Standard_Integer i, aNbS, iErr; Standard_Real aDMin, aD, aRes1, aSolCriteria, aTouchCriteria; Standard_Real aT1A, aT1B, aT1Min, aT2Min; - Standard_Real aT1Im, aT2Im, aT1Touch; GeomAPI_ProjectPointOnCurve aProjPC; IntTools_SequenceOfRanges aRanges; - Standard_Boolean bTouch; // aDMin = Precision::Infinite(); aSolCriteria = 5.e-16; aTouchCriteria = 5.e-13; - bTouch = Standard_False; - aT1Touch = aT11; + Standard_Boolean bTouch = Standard_False; + Standard_Boolean bTouchConfirm = Standard_False; // aRes1 = Resolution(myCurve1.Curve().Curve(), myCurve1.GetType(), myResCoeff1, myTol); @@ -753,15 +760,9 @@ void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11, // aProjPC.Init(myGeom2, aT21, aT22); // - aT1 = (aT11 + aT12) * 0.5; - iErr = DistPC(aT1, myGeom1, aSolCriteria, aProjPC, aD, aT2, -1); - if (iErr == 1) { - aT2 = (aT21 + aT22) * 0.5; - } - // - aT1Im = aT1; - aT2Im = aT2; - // + Standard_Real aT11Touch = aT11, aT12Touch = aT12; + Standard_Real aT21Touch = aT21, aT22Touch = aT22; + Standard_Boolean isSolFound = Standard_False; for (i = 1; i <= aNbS; ++i) { const IntTools_Range& aR1 = aRanges(i); aR1.Range(aT1A, aT1B); @@ -774,26 +775,31 @@ void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11, aT1 = aT1Min; aT2 = aT2Min; aDMin = aD; + isSolFound = Standard_True; } // if (aD < aTouchCriteria) { if (bTouch) { - aT1A = (aT1Touch + aT1Min) * 0.5; - iErr = DistPC(aT1A, myGeom1, aTouchCriteria, - aProjPC, aD, aT2Min, -1); - if (aD > aTouchCriteria) { - aT1 = aT1Im; - aT2 = aT2Im; - break; - } + aT12Touch = aT1Min; + aT22Touch = aT2Min; + bTouchConfirm = Standard_True; } else { - aT1Touch = aT1Min; + aT11Touch = aT1Min; + aT21Touch = aT2Min; bTouch = Standard_True; } } } } + if (!isSolFound || bTouchConfirm) + { + aT1 = (aT11Touch + aT12Touch) * 0.5; + iErr = DistPC(aT1, myGeom1, aSolCriteria, aProjPC, aD, aT2, -1); + if (iErr == 1) { + aT2 = (aT21Touch + aT22Touch) * 0.5; + } + } } //======================================================================= @@ -1128,6 +1134,7 @@ Standard_Integer FindDistPC(const Standard_Real aT1A, return iErr; } // + Standard_Real anEps = Max(theEps, Epsilon(Max(Abs(aA), Abs(aB))) * 10.); for (;;) { if (iC*(aYP - aYL) > 0) { aA = aXL; @@ -1155,7 +1162,7 @@ Standard_Integer FindDistPC(const Standard_Real aT1A, return iErr; } // - if ((aB - aA) < theEps) { + if ((aB - aA) < anEps) { break; } }// for (;;) { diff --git a/src/IntTools/IntTools_EdgeEdge.hxx b/src/IntTools/IntTools_EdgeEdge.hxx index c55977cdd0..ae68b8f39d 100644 --- a/src/IntTools/IntTools_EdgeEdge.hxx +++ b/src/IntTools/IntTools_EdgeEdge.hxx @@ -156,7 +156,7 @@ protected: const IntTools_SequenceOfRanges& theRanges2, const Standard_Boolean bSplit2); - //! Looking for the range of the edge whick is in the box + //! Looking for the range of the edge which is in the box Standard_EXPORT static Standard_Boolean FindParameters(const BRepAdaptor_Curve& theBAC, const Standard_Real aT1, const Standard_Real aT2, const Standard_Real theTol, const Standard_Real theRes, const Standard_Real thePTol, diff --git a/tests/boolean/bfuse_complex/E4 b/tests/boolean/bfuse_complex/E4 index 849d1e694d..213442f86e 100644 --- a/tests/boolean/bfuse_complex/E4 +++ b/tests/boolean/bfuse_complex/E4 @@ -1,8 +1,6 @@ # Original bug : pro14260 # Date : 21 Sept 98 -puts "TODO OCC27697 ALL: Error : is WRONG because number of " - restore [locate_data_file CTO900_pro14260c.rle] c restore [locate_data_file pro14260d.rle] d diff --git a/tests/bugs/modalg_7/bug29038 b/tests/bugs/modalg_7/bug29038 new file mode 100644 index 0000000000..5224bea5d0 --- /dev/null +++ b/tests/bugs/modalg_7/bug29038 @@ -0,0 +1,11 @@ +puts "=======" +puts "0029038" +puts "=======" +puts "" +################################################## +# IntTools_EdgeEdge::FindParameters() hangs on bad curve +################################################## + +restore [locate_data_file bug29038_bfuse_hang.brep] a +explode a +bfuse r a_1 a_2