diff --git a/src/Extrema/Extrema_ExtPExtS.cxx b/src/Extrema/Extrema_ExtPExtS.cxx index 70cf23cc3c..76c4e42daa 100755 --- a/src/Extrema/Extrema_ExtPExtS.cxx +++ b/src/Extrema/Extrema_ExtPExtS.cxx @@ -126,21 +126,21 @@ void Extrema_ExtPExtS::MakePreciser (Standard_Real& U, while (notFound) { U = U + step; if (U > myusup) { - U = myusup; - break; + U = myusup; + break; } if (U < myuinf) { - U = myuinf; - break; + U = myuinf; + break; } D2e = D2next; Pe = Pnext; Pnext = ProjectPnt (OrtogSection, myDirection, GetValue(U+step, myC)); D2next = P.SquareDistance(Pnext); if (isMin) - notFound = D2e > D2next; + notFound = D2e > D2next; else - notFound = D2e < D2next; + notFound = D2e < D2next; } } } @@ -205,6 +205,7 @@ void Extrema_ExtPExtS::Initialize(const Adaptor3d_SurfaceOfLinearExtrusion& S, myF.Initialize(S); myC = anACurve; + myS = (Adaptor3d_SurfacePtr)&S; myPosition = GetPosition(myC); myDirection = S.Direction(); myIsAnalyticallyComputable = //Standard_False; @@ -225,6 +226,9 @@ void Extrema_ExtPExtS::Initialize(const Adaptor3d_SurfaceOfLinearExtrusion& S, void Extrema_ExtPExtS::Perform (const gp_Pnt& P) { + const Standard_Integer NbExtMax = 4; //dimension of arrays + //myPoint[] and mySqDist[] + //For "analytical" case myDone = Standard_False; myNbExt = 0; @@ -260,10 +264,10 @@ void Extrema_ExtPExtS::Perform (const gp_Pnt& P) U = POC.Parameter(); //// modified by jgv, 23.12.2008 for OCC17194 //// if (myC->IsPeriodic()) - { - Standard_Real U2 = U; - ElCLib::AdjustPeriodic(myuinf, myuinf + 2.*M_PI, Precision::PConfusion(), U, U2); - } + { + Standard_Real U2 = U; + ElCLib::AdjustPeriodic(myuinf, myuinf + 2.*M_PI, Precision::PConfusion(), U, U2); + } ////////////////////////////////////////////////// gp_Pnt E = POC.Value(); Pe = ProjectPnt(anOrtogSection, myDirection, E); @@ -276,6 +280,10 @@ void Extrema_ExtPExtS::Perform (const gp_Pnt& P) myPoint[myNbExt] = Extrema_POnSurf(U, V, Pe); mySqDist[myNbExt] = anExt.SquareDistance(i); myNbExt++; + if(myNbExt == NbExtMax) + { + break; + } // modified by NIZHNY-MKK Thu Sep 18 14:46:18 2003.END } else { @@ -291,17 +299,26 @@ void Extrema_ExtPExtS::Perform (const gp_Pnt& P) // for (Standard_Integer k=1 ; k <= myF.NbExt(); Standard_Integer k; for ( k=1 ; k <= myF.NbExt(); k++) { - if (IsOriginalPnt(myF.Point(k).Value(), myPoint, myNbExt)) { - // modified by NIZHNY-MKK Thu Sep 18 14:46:41 2003.BEGIN - // myPoint[++myNbExt] = myF.Point(k); - // myValue[myNbExt] = myF.Value(k); - myPoint[myNbExt] = myF.Point(k); - mySqDist[myNbExt] = myF.SquareDistance(k); - myNbExt++; - // modified by NIZHNY-MKK Thu Sep 18 14:46:43 2003.END - } + if (IsOriginalPnt(myF.Point(k).Value(), myPoint, myNbExt)) { + // modified by NIZHNY-MKK Thu Sep 18 14:46:41 2003.BEGIN + // myPoint[++myNbExt] = myF.Point(k); + // myValue[myNbExt] = myF.Value(k); + myPoint[myNbExt] = myF.Point(k); + mySqDist[myNbExt] = myF.SquareDistance(k); + myNbExt++; + if(myNbExt == NbExtMax) + { + break; + } + // modified by NIZHNY-MKK Thu Sep 18 14:46:43 2003.END + } + } + if(myNbExt == NbExtMax) + { + break; } // try symmetric point + myF.SetPoint(P); //To clear previous solutions U *= -1; MakePreciser(U, P, isMin, anOrtogSection); E = GetValue(U, myC); @@ -312,15 +329,57 @@ void Extrema_ExtPExtS::Perform (const gp_Pnt& P) aFSR.Perform (myF,UV,UVinf,UVsup); for (k=1 ; k <= myF.NbExt(); k++) { - if (IsOriginalPnt(myF.Point(k).Value(), myPoint, myNbExt)) { - // modified by NIZHNY-MKK Thu Sep 18 14:46:59 2003.BEGIN - // myPoint[++myNbExt] = myF.Point(k); - // myValue[myNbExt] = myF.Value(k); - myPoint[myNbExt] = myF.Point(k); - mySqDist[myNbExt] = myF.SquareDistance(k); - myNbExt++; - // modified by NIZHNY-MKK Thu Sep 18 14:47:04 2003.END - } + if(myF.SquareDistance(k) > Precision::Confusion()*Precision::Confusion()) + { + //Additional checking solution: FSR sometimes is wrong + //when starting point is far from solution. + Standard_Real dist = Sqrt(myF.SquareDistance(k)); + math_Vector Vals(1, 2); + const Extrema_POnSurf& PonS=myF.Point(k); + Standard_Real u, v; + PonS.Parameter(u, v); + UV(1) = u; + UV(2) = v; + myF.Value(UV, Vals); + gp_Vec du, dv; + myS->D1(u, v, Pe, du, dv); + Standard_Real mdu = du.Magnitude(); + Standard_Real mdv = dv.Magnitude(); + u = Abs(Vals(1)); + v = Abs(Vals(2)); + if(mdu > Precision::PConfusion()) + { + if(u / dist / mdu > Precision::PConfusion()) + { + continue; + } + } + if(mdv > Precision::PConfusion()) + { + if(v / dist / mdv > Precision::PConfusion()) + { + continue; + } + } + + } + if (IsOriginalPnt(myF.Point(k).Value(), myPoint, myNbExt)) { + // modified by NIZHNY-MKK Thu Sep 18 14:46:59 2003.BEGIN + // myPoint[++myNbExt] = myF.Point(k); + // myValue[myNbExt] = myF.Value(k); + myPoint[myNbExt] = myF.Point(k); + mySqDist[myNbExt] = myF.SquareDistance(k); + myNbExt++; + if(myNbExt == NbExtMax) + { + break; + } + // modified by NIZHNY-MKK Thu Sep 18 14:47:04 2003.END + } + } + if(myNbExt == NbExtMax) + { + break; } } } diff --git a/tests/bugs/moddata_3/bug24138 b/tests/bugs/moddata_3/bug24138 new file mode 100755 index 0000000000..e2bc25567c --- /dev/null +++ b/tests/bugs/moddata_3/bug24138 @@ -0,0 +1,52 @@ +puts "================" +puts "OCC24138" +puts "================" +puts "" +####################################################################### +# Exception during projection of the point on the face +####################################################################### + +ellipse w 0 0 0 10 5 +mkedge w w +wire w w +mkplane w w +prism s w 2 0 30 +explode s f +copy s_1 f +point p 0.753071156928785 4.98580193823337 0 + +set proj_fp [projponf f p -t] +regexp {proj dist = ([-0-9.+eE]+) uvproj = \(([-0-9.+eE]+) ([-0-9.+eE]+)\); pproj = \(([-0-9.+eE]+) ([-0-9.+eE]+) ([-0-9.+eE]+)\)} ${proj_fp} full dist uproj vproj proj1 proj2 + +puts "dist=${dist}" +puts "uproj=${uproj}" +puts "vproj=${vproj}" +puts "proj1=${proj1}" +puts "proj2=${proj2}" + +set tolmax_f [tolmax f] +regexp {max tol = ([-0-9.+eE]+)} ${tolmax_f} full CMP_TOL + +puts "CMP_TOL=${CMP_TOL}" + +set good_dist 9.16061678111512e-10 +set good_uproj 1.4954178490327235 +set good_vproj -2.3095450102606156e-12 +set good_proj1 0.75307115689421944 +set good_proj2 4.9858019373179632 + +if { [expr abs(${dist} - ${good_dist}) ] > ${CMP_TOL} } { + puts "Error: invalid dist" +} +if { [expr abs(${uproj} - ${good_uproj}) ] > ${CMP_TOL} } { + puts "Error: invalid uproj" +} +if { [expr abs(${vproj} - ${good_vproj}) ] > ${CMP_TOL} } { + puts "Error: invalid vproj" +} +if { [expr abs(${proj1} - ${good_proj1}) ] > ${CMP_TOL} } { + puts "Error: invalid proj1" +} +if { [expr abs(${proj2} - ${good_proj2}) ] > ${CMP_TOL} } { + puts "Error: invalid proj2" +}