]> OCCT Git - occt.git/commitdiff
0033828: Modeling Algorithms, GCPnts_QuasiUniformDeflection returns very different... CR0_720_FixS CR33828_720_FixS
authorjfa <jfa@opencascade.com>
Tue, 17 Sep 2024 16:51:36 +0000 (17:51 +0100)
committerjfa <jfa@opencascade.com>
Mon, 23 Sep 2024 13:25:27 +0000 (14:25 +0100)
src/GCPnts/GCPnts_QuasiUniformDeflection.pxx
tests/bugs/moddata_3/bug33828 [new file with mode: 0644]

index 59ff8ddbda5ccca2ce9c9d6ec63a73506e192444..573dc58f687f87ad15fe09d96360778f13595dc3 100644 (file)
@@ -354,29 +354,54 @@ void QuasiFleche (const TheCurve& C,
     Vdelta = Vfin;
   }
 
+  // square length of chord
   Standard_Real Norme = gp_Vec (Pdeb, Pdelta).SquareMagnitude();
   Standard_Real theFleche = 0;
   Standard_Boolean flecheok = Standard_False;
-  if (Norme > Eps)
+  if (Norme > Eps && Norme > 16. * Deflection2)
   {
     // Evaluation de la fleche par interpolation . Voir IntWalk_IWalking_5.gxx
     Standard_Real N1 = Vdeb.SquareMagnitude();
     Standard_Real N2 = Vdelta.SquareMagnitude();
     if (N1 > Eps && N2 > Eps)
     {
+      // square distance between ends of two normalized vectors [0; 4]
       Standard_Real Normediff = (Vdeb.Normalized().XYZ() - Vdelta.Normalized().XYZ()).SquareModulus();
       if (Normediff > Eps)
       {
         theFleche = Normediff * Norme / 64.;
+        // So, fleche <= (Norme / 16), independently of Vdeb and Vdelta.
+        // And if (Norme / 16) < Deflection2, this approach gives
+        // fleche < Deflection2 independently of real curve.
+        // That is why we exclude case Norme < (16. * Deflection2)
         flecheok = Standard_True;
       }
     }
   }
-  if (!flecheok)
+
+  gp_Pnt Pmid ((Pdeb.XYZ() + Pdelta.XYZ()) * 0.5);
+  gp_Pnt Pverif (Value (C, Udeb + Udelta * 0.5));
+  Standard_Real FlecheMidMid = Pmid.SquareDistance (Pverif);
+
+  if (flecheok)
+  {
+    // Algorithm, evaluating "fleche" by interpolation,
+    // can give false-positive result.
+    // So we check also distance between Pmid and Pverif (FlecheMidMid).
+    // But FlecheMidMid gives worse result in case of non-uniform parameterisation.
+    // Maximum FlecheMidMid, that seems reasonable, is (chord/2)^2 + Deflection2
+    //   .---------------.Pverif  .
+    //   |               |        | Deflection
+    //   ._______. ______.        .
+    // Pdeb    Pmid    Pdelta
+    if (FlecheMidMid > Norme/4. + Deflection2)
+    {
+      theFleche = FlecheMidMid;
+    }
+  }
+  else
   {
-    gp_Pnt Pmid ((Pdeb.XYZ() + Pdelta.XYZ()) * 0.5);
-    gp_Pnt Pverif (Value(C, Udeb + Udelta * 0.5));
-    theFleche = Pmid.SquareDistance (Pverif);
+    theFleche = FlecheMidMid;
   }
 
   if (theFleche < Deflection2)
diff --git a/tests/bugs/moddata_3/bug33828 b/tests/bugs/moddata_3/bug33828
new file mode 100644 (file)
index 0000000..9dbdf6a
--- /dev/null
@@ -0,0 +1,35 @@
+puts "==========================================================="
+puts "0033828: Modeling Data - GCPnts_QuasiUniformDeflection"
+puts "returns very different results under small change in deflection"
+puts "==========================================================="
+
+proc check_crvpoints {cc deflection nb_expected} {
+    upvar ${cc} ${cc}
+
+    set str1 "Nb points +: +(\[-0-9.+eE\]+)\n"
+    set str2 "Max defl: +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
+
+    set info [crvpoints r ${cc} ${deflection}]
+    regexp "${str1}${str2}" ${info} full Nb dmax ufmax ulmax i
+
+    if { ${Nb} != ${nb_expected} } {
+        puts "Error : bad value of Nb points = ${Nb}, expected ${nb_expected}"
+    }
+
+    if { ${dmax} > ${deflection} } {
+        puts "Error : bad value of maximum deflection = ${dmax}, expected < ${deflection}"
+    }
+}
+
+bsplinecurve cu 3 7  0 4  0.17 2  0.33 2  0.5 2  0.67 2  0.83 2  1 4   0.163 0.233 0 1  0.158 0.204 0 1  0.139 0.180 0 1  0.086 0.159 0 1  0.055 0.163 0 1  0.009 0.196 0 1  -0.004 0.225 0 1  0.002 0.281 0 1  0.019 0.307 0 1  0.070 0.332 0 1  0.101 0.331 0 1  0.149 0.301 0 1  0.164 0.274 0 1  0.163 0.246 0 1
+
+check_crvpoints cu .5     2
+check_crvpoints cu .1     3
+check_crvpoints cu .05    5
+check_crvpoints cu .025   5
+check_crvpoints cu .007   9
+check_crvpoints cu .005  17
+check_crvpoints cu .0005 33
+check_crvpoints cu .0003 65
+check_crvpoints cu .0002 65
+check_crvpoints cu .0001 73