From 1e08a76f1e872a1f38931a6c3e8cf71396fc1209 Mon Sep 17 00:00:00 2001 From: aavtamon Date: Wed, 2 Dec 2020 10:18:15 +0300 Subject: [PATCH] 0031402: Modeling Data - Geom_BSplineSurface::Segment() produces wrong result 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 | 8 ++++++-- src/Geom2d/Geom2d_BSplineCurve.cxx | 26 +++++--------------------- tests/bugs/moddata_3/bug31402_1 | 15 +++++++++++++++ tests/bugs/moddata_3/bug31402_2 | 21 +++++++++++++++++++++ 4 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 tests/bugs/moddata_3/bug31402_1 create mode 100644 tests/bugs/moddata_3/bug31402_2 diff --git a/src/Geom/Geom_BSplineSurface.cxx b/src/Geom/Geom_BSplineSurface.cxx index 262b3d7ecd..5316b0c385 100644 --- a/src/Geom/Geom_BSplineSurface.cxx +++ b/src/Geom/Geom_BSplineSurface.cxx @@ -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; diff --git a/src/Geom2d/Geom2d_BSplineCurve.cxx b/src/Geom2d/Geom2d_BSplineCurve.cxx index 935e2f0d6b..a5ccd50fdf 100644 --- a/src/Geom2d/Geom2d_BSplineCurve.cxx +++ b/src/Geom2d/Geom2d_BSplineCurve.cxx @@ -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 index 0000000000..1016403819 --- /dev/null +++ b/tests/bugs/moddata_3/bug31402_1 @@ -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 index 0000000000..b34e6308dd --- /dev/null +++ b/tests/bugs/moddata_3/bug31402_2 @@ -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