0027059: Point->Curve Projection/Extrema fails [OCCT 7 only]
authoraml <aml@opencascade.com>
Mon, 11 Jan 2016 09:21:01 +0000 (12:21 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 13 Jan 2016 12:56:19 +0000 (15:56 +0300)
Add check to run extrema search when necessary condition of extrema is true (small value of first derivative of objective function).
Test case added.

src/Extrema/Extrema_GExtPC.gxx
tests/bugs/moddata_3/bug27059 [new file with mode: 0644]

index 400491b..a61234c 100644 (file)
@@ -103,9 +103,9 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
       TheCurveTool::BSpline(aCurve)->Knots(aKnots); 
 
       // Workaround to work with:
-      // blend, where knots may be moved from param space.
+      // blend, where knots may be moved from parameter space.
       Standard_Real aPeriodJump = 0.0;
-      // Avoid prolem with too close knots.
+      // Avoid problem with too close knots.
       const Standard_Real aTolCoeff = (myusup - myuinf) * Precision::PConfusion();
       if (TheCurveTool::IsPeriodic(aCurve))
       {
@@ -203,7 +203,7 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
         }
       }
 
-      // Solve on first and last interval.
+      // Solve on the first and last intervals.
       if (mydist1 > Precision::SquareConfusion())
       {
         ThePoint aP1, aP2;
@@ -216,8 +216,10 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
 
         // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
         // Necessary condition - when point lies on curve.
+        // Necessary condition - when derivative of point is too small.
         if(aVal1 * aVal2 <= 0.0 ||
-           aBase1.Dot(aBase2) <= 0.0)
+           aBase1.Dot(aBase2) <= 0.0 ||
+           2.0 * Abs(aVal1) < Precision::Confusion() )
         {
           myintuinf = aParam(aVal.Lower());
           myintusup = aParam(aVal.Lower() + 1);
@@ -237,8 +239,10 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
 
         // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
         // Necessary condition - when point lies on curve.
+        // Necessary condition - when derivative of point is too small.
         if(aVal1 * aVal2 <= 0.0 ||
-           aBase1.Dot(aBase2) <= 0.0)
+           aBase1.Dot(aBase2) <= 0.0 ||
+           2.0 * Abs(aVal2) < Precision::Confusion() )
         {
           myintuinf = aParam(aVal.Upper() - 1);
           myintusup = aParam(aVal.Upper());
diff --git a/tests/bugs/moddata_3/bug27059 b/tests/bugs/moddata_3/bug27059
new file mode 100644 (file)
index 0000000..8114ae9
--- /dev/null
@@ -0,0 +1,57 @@
+puts "================"
+puts "0027059"
+puts "================"
+puts ""
+##############################################################
+# Point->Curve Projection/Extrema fails.
+# (No extrema found)
+##############################################################
+
+set absTol 1.0e-6
+set relTol 0.001
+set expectedLength 1.0e-6
+set exp_x 12.700000
+set exp_y 16.8949999999593
+set exp_z  0.534684851975074
+
+restore [locate_data_file bug27059.brep] aC
+explode aC
+mkcurve curve aC_2
+
+# case 1: Curve
+# existence check
+set info1 [proj curve 12.699999 16.8949999999593 0.534684851975074]
+
+if {![regexp {ext_1} $info1]} {
+  puts "Error: No extrema found in case 1"
+}
+# length check
+set case1Info [length ext_1]
+regexp {The length ext_1 is ([-0-9.+eE]+)} $case1Info full case1Length
+checkreal "case 1 extrema value" $case1Length $expectedLength $absTol $relTol
+
+
+# case 2: Curve
+# existence check
+set info2 [proj curve 12.700001 16.8949999999593 0.534684851975074]
+
+if {![regexp {ext_1} $info2]} {
+  puts "Error: No extrema found in case 2"
+}
+# length check
+set case2Info [length ext_1]
+regexp {The length ext_1 is ([-0-9.+eE]+)} $case2Info full case2Length
+checkreal "case 2 extrema value" $case2Length $expectedLength $absTol $relTol
+
+#case 3: Point
+# existence check
+set info3 [proj curve 12.700000 16.8949999999593 0.534684851975074]
+if {![regexp {ext_1} $info3]} {
+  puts "Error: No extrema found in case 3"
+}
+# point coords check
+set case3Info [dump ext_1]
+regexp {Point : ([-0-9.+eE]+), ([-0-9.+eE]+), ([-0-9.+eE]+)} $case3Info full x y z
+checkreal "case 3 coord X" $x $exp_x $absTol $relTol
+checkreal "case 3 coord Y" $y $exp_y $absTol $relTol
+checkreal "case 3 coord Z" $z $exp_z $absTol $relTol