0030581: Modeling Data - Standard_OutOfRange within Geom_BSplineSurface::LocateV()
authorkgv <kgv@opencascade.com>
Sat, 16 Mar 2019 06:33:37 +0000 (09:33 +0300)
committerapn <apn@opencascade.com>
Mon, 18 Mar 2019 16:41:40 +0000 (19:41 +0300)
Geom2d_BSplineCurve::LocateU(),Geom_BSplineCurve::LocateU, Law_BSpline::LocateU()
Geom_BSplineSurface::LocateU() and Geom_BSplineSurface::LocateV()
have been corrected with missing range checks.
BSplCLib::Hunt() documentation has been corrected to reflect its actual implementation.

src/BSplCLib/BSplCLib.cxx
src/BSplCLib/BSplCLib.hxx
src/GCPnts/GCPnts_QuasiUniformDeflection.pxx
src/GCPnts/GCPnts_UniformDeflection.pxx
src/Geom/Geom_BSplineCurve_1.cxx
src/Geom/Geom_BSplineSurface_1.cxx
src/Geom2d/Geom2d_BSplineCurve_1.cxx
src/Law/Law_BSpline.cxx

index 00f1e18..340c30d 100644 (file)
@@ -73,31 +73,40 @@ public:
 //purpose  : 
 //=======================================================================
 
-void BSplCLib::Hunt (const Array1OfReal& XX, 
-                    const Standard_Real X,
-                    Standard_Integer&   Ilc)
+void BSplCLib::Hunt (const TColStd_Array1OfReal& theArray,
+                     const Standard_Real theX,
+                     Standard_Integer&   theXPos)
 {
   // replaced by simple dichotomy (RLE)
-  Ilc = XX.Lower();
-  if (XX.Length() <= 1) return;
-  const Standard_Real *px = &XX(Ilc);
-  px -= Ilc;
-
-  if (X < px[Ilc]) {
-    Ilc--;
+  if (theArray.First() > theX)
+  {
+    theXPos = theArray.Lower() - 1;
+    return;
+  }
+  else if (theArray.Last() < theX)
+  {
+    theXPos = theArray.Upper() + 1;
     return;
   }
-  Standard_Integer Ihi = XX.Upper();
-  if (X > px[Ihi]) {
-    Ilc = Ihi + 1;
+
+  theXPos = theArray.Lower();
+  if (theArray.Length() <= 1)
+  {
     return;
   }
-  Standard_Integer Im;
 
-  while (Ihi - Ilc != 1) {
-    Im = (Ihi + Ilc) >> 1;
-    if (X > px[Im]) Ilc = Im;
-    else            Ihi = Im;
+  Standard_Integer aHi = theArray.Upper();
+  while (aHi - theXPos != 1)
+  {
+    const Standard_Integer aMid = (aHi + theXPos) / 2;
+    if (theArray.Value (aMid) < theX)
+    {
+      theXPos = aMid;
+    }
+    else
+    {
+      aHi = aMid;
+    }
   }
 }
 
index 78701cc..946ac3c 100644 (file)
@@ -124,23 +124,16 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  //! This routine searches the position of the real
-  //! value X in  the ordered set of  real  values XX.
-  //!
-  //! The  elements   in   the  table    XX  are   either
-  //! monotonically    increasing     or    monotonically
-  //! decreasing.
-  //!
-  //! The input   value Iloc is    used to initialize the
-  //! algorithm  :  if  Iloc  is outside  of   the bounds
-  //! [XX.Lower(), -- XX.Upper()] the bisection algorithm
-  //! is used else  the routine searches from  a previous
-  //! known position  by increasing steps  then converges
-  //! by bisection.
-  //!
-  //! This  routine is used to  locate a  knot value in a
-  //! set of knots.
-  Standard_EXPORT static void Hunt (const TColStd_Array1OfReal& XX, const Standard_Real X, Standard_Integer& Iloc);
+  //! This routine searches the position of the real value theX
+  //! in the monotonically increasing set of real values theArray using bisection algorithm.
+  //!
+  //! If the given value is out of range or array values, algorithm returns either
+  //! theArray.Lower()-1 or theArray.Upper()+1 depending on theX position in the ordered set.
+  //!
+  //! This routine is used to locate a knot value in a set of knots.
+  Standard_EXPORT static void Hunt (const TColStd_Array1OfReal& theArray,
+                                    const Standard_Real theX,
+                                    Standard_Integer& theXPos);
   
   //! Computes the index of the knots value which gives
   //! the start point of the curve.
index 91ee68b..aff5f87 100644 (file)
@@ -215,7 +215,9 @@ static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& Parameters,
   Standard_Real Ua = U1;
   for (Standard_Integer Index = PIndex;;)
   {
-    Standard_Real Ub = Min (U2, TI (Index + 1));
+    Standard_Real Ub = Index + 1 <= TI.Upper()
+                     ? Min (U2, TI (Index + 1))
+                     : U2;
     if (!PerformCurve (Parameters, Points, C, Deflection,
                                   Ua, Ub, EPSILON, Continuity))
       return Standard_False;
index ab582b5..f50fb5c 100644 (file)
@@ -174,7 +174,9 @@ static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& Parameters,
   Standard_Real Ua = U1;
   for (Standard_Integer Index = PIndex;;)
   {
-    Standard_Real Ub = Min (U2, TI (Index + 1));
+    Standard_Real Ub = Index + 1 <= TI.Upper()
+                     ? Min (U2, TI (Index + 1))
+                     : U2;
     if (!PerformCurve (Parameters, Points, C, Deflection,
                    Ua, Ub, EPSILON, WithControl))
     {
index 0354196..303374e 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-// 03-02-97 : pmn ->LocateU sur Periodic (PRO6963), 
-//            bon appel a LocateParameter (PRO6973) et mise en conformite avec
-//            le cdl de LocateU, lorsque U est un noeud (PRO6988)
-
-#define No_Standard_OutOfRange
-#define No_Standard_DimensionError
-
-
 #include <BSplCLib.hxx>
 #include <Geom_BSplineCurve.hxx>
 #include <Geom_Geometry.hxx>
@@ -809,7 +801,12 @@ void Geom_BSplineCurve::LocateU
   else {
     I1 = 1;
     BSplCLib::Hunt (CKnots, NewU, I1);
-    while ( Abs( CKnots(I1+1) - NewU) <= PParametricTolerance) I1++;
+    I1 = Max (Min (I1, CKnots.Upper()), CKnots.Lower());
+    while (I1 + 1 <= CKnots.Upper()
+        && Abs (CKnots (I1 + 1) - NewU) <= PParametricTolerance)
+    {
+      I1++;
+    }
     if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) {
       I2 = I1;
     }
index db99bfc..0261008 100644 (file)
 //                 + bon appel a LocateParameter (PRO6973).
 // RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537).
 
-#define No_Standard_OutOfRange
-#define No_Standard_DimensionError
-
-
 #include <BSplCLib.hxx>
 #include <BSplSLib.hxx>
 #include <Geom_BSplineCurve.hxx>
@@ -1360,7 +1356,12 @@ void Geom_BSplineSurface::LocateU
   else {
     I1 = 1;
     BSplCLib::Hunt (Knots, NewU, I1);
-    while ( Abs( Knots(I1+1) - NewU) <= PParametricTolerance) I1++;
+    I1 = Max (Min (I1, Knots.Upper()), Knots.Lower());
+    while (I1 + 1 <= Knots.Upper()
+        && Abs (Knots (I1 + 1) - NewU) <= PParametricTolerance)
+    {
+      I1++;
+    }
     if ( Abs( Knots(I1) - NewU) <= PParametricTolerance) {
       I2 = I1;
     }
@@ -1408,7 +1409,12 @@ void Geom_BSplineSurface::LocateV
   else {
     I1 = 1;
     BSplCLib::Hunt (Knots, NewV, I1);
-    while ( Abs( Knots(I1+1) - NewV) <= PParametricTolerance) I1++;
+    I1 = Max (Min (I1, Knots.Upper()), Knots.Lower());
+    while (I1 + 1 <= Knots.Upper()
+        && Abs (Knots (I1 + 1) - NewV) <= PParametricTolerance)
+    {
+      I1++;
+    }
     if ( Abs( Knots(I1) - NewV) <= PParametricTolerance) {
       I2 = I1;
     }
index a4142a5..d6b231e 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-// 03-02-97 : pmn ->LocateU sur Periodic (PRO6963), 
-//            bon appel a LocateParameter (PRO6973) et mise en conformite avec
-//            le cdl de LocateU, lorsque U est un noeud (PRO6988)
-
-#define No_Standard_OutOfRange
-#define No_Standard_DimensionError
-
-
 #include <BSplCLib.hxx>
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_Geometry.hxx>
@@ -820,7 +812,12 @@ void Geom2d_BSplineCurve::LocateU
   else {
     I1 = 1;
     BSplCLib::Hunt (CKnots, NewU, I1);
-    while ( Abs( CKnots(I1+1) - NewU) <= PParametricTolerance) I1++;
+    I1 = Max (Min (I1, CKnots.Upper()), CKnots.Lower());
+    while (I1 + 1 <= CKnots.Upper()
+        && Abs (CKnots (I1 + 1) - NewU) <= PParametricTolerance)
+    {
+      I1++;
+    }
     if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) {
       I2 = I1;
     }
index 1d19cf8..c4eaeb3 100644 (file)
@@ -1943,7 +1943,12 @@ void Law_BSpline::LocateU
   else {
     I1 = 1;
     BSplCLib::Hunt (CKnots, NewU, I1);
-    while ( Abs( CKnots(I1+1) - NewU) <= Abs(ParametricTolerance)) I1++;
+    I1 = Max (Min (I1, CKnots.Upper()), CKnots.Lower());
+    while (I1 + 1 <= CKnots.Upper()
+        && Abs (CKnots (I1 + 1) - NewU) <= Abs(ParametricTolerance))
+    {
+      I1++;
+    }
     if ( Abs( CKnots(I1) - NewU) <= Abs(ParametricTolerance)) {
       I2 = I1;
     }