0024138: Exception during projection of the point on the face
authoremv <emv@opencascade.com>
Thu, 5 Sep 2013 09:16:47 +0000 (13:16 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 5 Sep 2013 09:17:50 +0000 (13:17 +0400)
Adding test case for issue CR24138

src/Extrema/Extrema_ExtPExtS.cxx
tests/bugs/moddata_3/bug24138 [new file with mode: 0755]

index 70cf23c..76c4e42 100755 (executable)
@@ -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 (executable)
index 0000000..e2bc255
--- /dev/null
@@ -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"
+}