0026308: Segmentation fault in BSplCLib::LocateParameter
authornbv <nbv@opencascade.com>
Mon, 20 Jul 2015 12:23:00 +0000 (15:23 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 20 Jul 2015 12:24:00 +0000 (15:24 +0300)
Detection of "jumping" knot value has been improved.
Test-case for issue #26308
Comment has been added in test case bugs/modalg_6/bug26308.

src/BSplCLib/BSplCLib.cxx
tests/bugs/modalg_6/bug26308 [new file with mode: 0644]

index 0355b45..e4cb5fe 100644 (file)
@@ -234,6 +234,18 @@ void BSplCLib::LocateParameter
  const Standard_Real         UFirst,
  const Standard_Real         ULast)
 {
+  /*
+  Let Knots are distributed as follows (the array is sorted in ascending order):
+    
+      K1, K1,..., K1, K1, K2, K2,..., K2, K2,..., Kn, Kn,..., Kn
+           M1 times             M2 times             Mn times
+
+  NbKnots = sum(M1+M2+...+Mn)
+  If U <= K1 then KnotIndex should be equal to M1.
+  If U >= Kn then KnotIndex should be equal to NbKnots-Mn-1.
+  If Ki <= U < K(i+1) then KnotIndex should be equal to sum (M1+M2+...+Mi).
+  */
+
   Standard_Integer First,Last;
   if (FromK1 < ToK2) {
     First = FromK1;
@@ -257,10 +269,12 @@ void BSplCLib::LocateParameter
   
   BSplCLib::Hunt (Knots, NewU, KnotIndex);
   
-  Standard_Real Eps = Epsilon(U);
   Standard_Real val;
-  if (Eps < 0) Eps = - Eps;
-  Standard_Integer KLower = Knots.Lower();
+  const Standard_Integer  KLower = Knots.Lower(),
+                          KUpper = Knots.Upper();
+
+  const Standard_Real Eps = Epsilon(Min(Abs(Knots(KUpper)), Abs(U)));
+
   const Standard_Real *knots = &Knots(KLower);
   knots -= KLower;
   if ( KnotIndex < Knots.Upper()) {
diff --git a/tests/bugs/modalg_6/bug26308 b/tests/bugs/modalg_6/bug26308
new file mode 100644 (file)
index 0000000..2bd85ab
--- /dev/null
@@ -0,0 +1,39 @@
+puts "========"
+puts "OCC26308"
+puts "========"
+puts ""
+###################################################
+# Segmentation fault in BSplCLib::LocateParameter
+###################################################
+
+#Exception is thrown when computing a value of B-spline
+#surfaces in point, which is outside of its domain.
+
+pload XDE
+
+ReadStep D_First [locate_data_file OCC26308-Face.stp]
+XGetOneShape rr D_First
+explode rr f
+mksurface ss rr_1
+
+svalue ss -1.427997381773311e+018 4.512451574816904e+016 xx yy zz
+
+set bug_info_x [dump xx]
+set bug_info_y [dump yy]
+set bug_info_z [dump zz]
+
+set bug_info_x [string trim [string range $bug_info_x [expr {[string last "\n" $bug_info_x] + 1}] [expr {[string length $bug_info_x] - 1}]]]
+set bug_info_y [string trim [string range $bug_info_y [expr {[string last "\n" $bug_info_y] + 1}] [expr {[string length $bug_info_y] - 1}]]]
+set bug_info_z [string trim [string range $bug_info_z [expr {[string last "\n" $bug_info_z] + 1}] [expr {[string length $bug_info_z] - 1}]]]
+
+if {$bug_info_x != -5.42659125962715e+207} {
+  puts "ERROR: OCC26308 is reproduced. X value is incorrect."
+}
+
+if {$bug_info_y != 2.90803974424011e+209} {
+  puts "ERROR: OCC26308 is reproduced. Y value is incorrect."
+}
+
+if {$bug_info_z != -3.1731154470359e+207} {
+  puts "ERROR: OCC26308 is reproduced. Z value is incorrect."
+}