0031402: Modeling Data - Geom_BSplineSurface::Segment() produces wrong result IR-2020-12-04 WEEK-49
authoraavtamon <aavtamon@opencascade.com>
Wed, 2 Dec 2020 07:18:15 +0000 (10:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 4 Dec 2020 16:00:48 +0000 (19:00 +0300)
In the method Segment() index1 needs to be checked as well as index2 in Geom_BSplineSurface and Geom2d_BSplineCurve
(Geom_BSplineCurve already has this check).
New test cases bug31402_1, bug31402_2 has been added.

The unnecessary code block in Geom2d_BSplineCurve has been deleted,
and checking index2 block has beed extended.

src/Geom/Geom_BSplineSurface.cxx
src/Geom2d/Geom2d_BSplineCurve.cxx
tests/bugs/moddata_3/bug31402_1 [new file with mode: 0644]
tests/bugs/moddata_3/bug31402_2 [new file with mode: 0644]

index 262b3d7..5316b0c 100644 (file)
@@ -619,9 +619,11 @@ void Geom_BSplineSurface::segment(const Standard_Real U1,
   Standard_Integer ToU2 = uknots->Upper();
   BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
                             NewU1, uperiodic, FromU1, ToU2, index1U, U);
+  if (Abs(uknots->Value(index1U + 1) - U) <= EpsU)
+    index1U++;
   BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
                             NewU1 + deltaU, uperiodic, FromU1, ToU2, index2U, U);
-  if (Abs(uknots->Value(index2U + 1) - U) <= EpsU)
+  if (Abs(uknots->Value(index2U + 1) - U) <= EpsU || index2U == index1U)
     index2U++;
 
   Standard_Integer nbuknots = index2U - index1U + 1;
@@ -659,9 +661,11 @@ void Geom_BSplineSurface::segment(const Standard_Real U1,
   Standard_Integer ToV2 = vknots->Upper();
   BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
                             NewV1, vperiodic, FromV1, ToV2, index1V, V);
+  if (Abs(vknots->Value(index1V + 1) - V) <= EpsV)
+    index1V++;
   BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
                             NewV1 + deltaV, vperiodic, FromV1, ToV2, index2V, V);
-  if (Abs(vknots->Value(index2V + 1) - V) <= EpsV)
+  if (Abs(vknots->Value(index2V + 1) - V) <= EpsV || index2V == index1V)
     index2V++;
 
   Standard_Integer nbvknots = index2V - index1V + 1;
index 935e2f0..a5ccd50 100644 (file)
@@ -660,27 +660,8 @@ void Geom2d_BSplineCurve::Segment(const Standard_Real aU1,
   Standard_Integer i, k, index;
   //
   //f
-  // Checking the input bounds aUj (j=1,2). 
-  // For the case when aUj==knot(i), 
-  // in order to prevent the insertion of a new knot that will be too closed 
-  // to the existing knot,  
-  // we assign Uj=knot(i)
-  Standard_Integer n1, n2;
-  Standard_Real U1, U2;
+  Standard_Real U1 = aU1, U2 = aU2;
   //
-  U1=aU1;
-  U2=aU2;
-  n1=knots->Lower();
-  n2=knots->Upper();
-  for (i=n1; i<=n2; ++i) {
-    U=knots->Value(i);
-    if (Abs(U-aU1)<=Eps) {
-      U1=U;
-    }
-    else if (Abs(U-aU2)<=Eps) {
-      U2=U;
-    }
-  }
   // Henceforward we use U1, U2 as bounds of the segment
   //t
   // 
@@ -730,10 +711,13 @@ void Geom2d_BSplineCurve::Segment(const Standard_Real aU1,
   Standard_Integer ToU2   = knots->Upper();
   BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
                            NewU1,periodic,FromU1,ToU2,index1,U);
+  if (Abs(knots->Value(index1 + 1) - U) <= Eps){
+    index1++;
+  }
   BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
                            NewU2,periodic,FromU1,ToU2,index2,U);
   // Eps = Epsilon(knots->Value(index2+1));
-  if ( Abs(knots->Value(index2+1)-U) <= Eps){
+  if ( Abs(knots->Value(index2+1)-U) <= Eps || index2 == index1){
     index2++;
   }
   
diff --git a/tests/bugs/moddata_3/bug31402_1 b/tests/bugs/moddata_3/bug31402_1
new file mode 100644 (file)
index 0000000..1016403
--- /dev/null
@@ -0,0 +1,15 @@
+puts "==========================================================="
+puts "0031402: Geom_BSplineSurface::Segment produces wrong result"
+puts "==========================================================="
+puts ""
+
+restore [locate_data_file bug31402.brep] face
+
+mksurface s face
+segsur s 0.0, 1.0, 0.49999999999999988898, 0.66666666666666662966
+bounds s u1 u2 v1 v2
+
+checkreal "U1" [dval u1] 0 0.001 0.0001
+checkreal "U2" [dval u2] 1 0.001 0.0001
+checkreal "V1" [dval v1] 0.5 0.001 0.0001
+checkreal "V2" [dval v2] 0.66666667 0.001 0.0001
\ No newline at end of file
diff --git a/tests/bugs/moddata_3/bug31402_2 b/tests/bugs/moddata_3/bug31402_2
new file mode 100644 (file)
index 0000000..b34e630
--- /dev/null
@@ -0,0 +1,21 @@
+puts "==========================================================="
+puts "0031402: Geom_BSplineSurface::Segment produces wrong result"
+puts "==========================================================="
+puts ""
+
+2dbsplinecurve curve 3 4 \
+0 3 1.5 1 2.5 3 3 2 \
+1.0 3.0 1 \
+1.4 3.7 1 \
+1.8 4.1 1 \
+2.2 4.5 1 \
+2.5 4.8 1 \
+2.7 4.9 1 \
+3.0 5.0 1 \
+3.3 5.2 1
+
+segment curve 1.5000000001 2.4999999999998
+bounds curve u1 u2
+
+checkreal "U1" [dval u1] 1.5 0.001 0.0001
+checkreal "U2" [dval u2] 2.5 0.001 0.0001
\ No newline at end of file