]> OCCT Git - occt.git/commitdiff
0033187: Modeling Algorithms - Crash in postprocessing of imported shape
authoratereshi <andrey.tereshin@opencascade.com>
Wed, 26 Oct 2022 13:59:54 +0000 (16:59 +0300)
committerVadim Glukhikh <vadim.glukhikh@opencascade.com>
Mon, 21 Nov 2022 16:53:59 +0000 (19:53 +0300)
Problem: Desynchronization of behaviors of GeomAdaptor_Curve::NbIntervals and
 GeomAdaptor_Curve::Intervals functions. First calculates number of intervals, then
 array is created and second fills the array. In some cases the size of array
 is less than need for filling.

Change:
1. Added function BSplCLib::Intervals that calculates number of interval and fills
 the array with its (if needed).
2. Simplified the algorithm of intervals calculation.
3. GeomAdaptor_Curve::NbIntervals/Intervals and Geom2dAdaptor_Curve::NbIntervals/Intervals
 use BSplCLib::Intervals.
4. When creating an adapter for the base curve, the boundaries of the adapter for the offset curve are applied.
5. Test for problem shape was created: bugs modalg_8 bug33187.

Result: The new approach eliminates the problem of writing outside the array bounds.

12 files changed:
src/BSplCLib/BSplCLib.cxx
src/BSplCLib/BSplCLib.hxx
src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx
src/GeomAdaptor/GeomAdaptor_Curve.cxx
tests/bugs/modalg_8/bug33187 [new file with mode: 0644]
tests/hlr/poly_hlr/A1
tests/hlr/poly_hlr/A2
tests/hlr/poly_hlr/A3
tests/hlr/poly_hlr/A4
tests/hlr/poly_hlr/A5
tests/hlr/poly_hlr/A6
tests/hlr/poly_hlr/A7

index cae229290bb4d5cd16ae338ed0e2fdea2469233f..6a2aa5f1122c671fc2ed7c10a7998a6a391e76f5 100644 (file)
@@ -4234,6 +4234,133 @@ void BSplCLib::Resolution(      Standard_Real&        Poles,
     UTolerance = Tolerance3D / RealSmall();
 }
 
+//=======================================================================
+// function : Intervals 
+// purpose  : 
+//=======================================================================
+Standard_Integer BSplCLib::Intervals (const TColStd_Array1OfReal& theKnots,
+                                      const TColStd_Array1OfInteger& theMults,
+                                      Standard_Integer theDegree,
+                                      Standard_Boolean isPeriodic,
+                                      Standard_Integer theContinuity,
+                                      Standard_Real theFirst,
+                                      Standard_Real theLast,
+                                      Standard_Real theTolerance,
+                                      TColStd_Array1OfReal* theIntervals) 
+{
+  // remove all knots with multiplicity less or equal than (degree - continuity) except first and last
+  Standard_Integer aFirstIndex = isPeriodic ? 1 : FirstUKnotIndex (theDegree, theMults);
+  Standard_Integer aLastIndex = isPeriodic ? theKnots.Size() : LastUKnotIndex (theDegree, theMults);
+  TColStd_Array1OfReal aNewKnots (1, aLastIndex - aFirstIndex + 1);
+  Standard_Integer aNbNewKnots = 0;
+  for (Standard_Integer anIndex = aFirstIndex; anIndex <= aLastIndex; anIndex++)
+  {
+    if (theMults(anIndex) > (theDegree - theContinuity) ||
+    anIndex == aFirstIndex ||
+    anIndex == aLastIndex)
+    {
+      aNbNewKnots++;
+      aNewKnots(aNbNewKnots) = theKnots[anIndex];
+    }
+  }
+  aNewKnots.Resize (1, aNbNewKnots, Standard_True);
+
+  // the range boundaries 
+  Standard_Real aCurFirst = theFirst;
+  Standard_Real aCurLast = theLast;
+  Standard_Real aPeriod = 0.0;
+  Standard_Integer aFirstPeriod = 0;
+  Standard_Integer aLastPeriod = 0;
+  // move boundaries into period
+  if (isPeriodic)
+  {
+    Standard_Real aLower = theKnots.First();
+    Standard_Real anUpper = theKnots.Last();
+    aPeriod = anUpper - aLower;
+    
+    while (aCurFirst < aLower)
+    {
+      aCurFirst += aPeriod;
+      aFirstPeriod--;
+    }
+    while (aCurLast < aLower)
+    {
+      aCurLast += aPeriod;
+      aLastPeriod--;
+    }
+    while (aCurFirst >= anUpper)
+    {
+      aCurFirst -= aPeriod;
+      aFirstPeriod += 1;
+    }
+    while (aCurLast >= anUpper)
+    {
+      aCurLast -= aPeriod;
+      aLastPeriod += 1;
+    }
+  }
+  // locate the left and nearest knot for boundaries
+  Standard_Integer anIndex1 = 0;
+  Standard_Integer anIndex2 = 0;
+  Standard_Real aDummyDouble;
+  // we use version of LocateParameter that doesn't need multiplicities
+  LocateParameter(theDegree, aNewKnots, TColStd_Array1OfInteger(), aCurFirst, Standard_False, 1, aNbNewKnots, anIndex1, aDummyDouble);
+  LocateParameter(theDegree, aNewKnots, TColStd_Array1OfInteger(), aCurLast, Standard_False, 1, aNbNewKnots, anIndex2, aDummyDouble);
+  // the case when the beginning of the range coincides with the next knot
+  if (anIndex1 < aNbNewKnots && Abs(aNewKnots[anIndex1 + 1] - aCurFirst) < theTolerance)
+  {
+    anIndex1 += 1;
+  }
+  // the case when the ending of the range coincides with the current knot
+  if (aNbNewKnots && Abs(aNewKnots[anIndex2] - aCurLast) < theTolerance)
+  {
+    anIndex2 -= 1;
+  }
+  Standard_Integer aNbIntervals = anIndex2 - anIndex1 + 1 + (aLastPeriod - aFirstPeriod) * (aNbNewKnots - 1);
+  
+  // fill the interval array
+  if (theIntervals)
+  {
+    theIntervals->Resize (1, aNbIntervals + 1, Standard_False);
+    if (isPeriodic && aLastPeriod != aFirstPeriod)
+    {
+      Standard_Integer anIndex = 1;
+      // part from the begging of range to the end of the first period
+      for (Standard_Integer i = anIndex1; i < aNewKnots.Size(); i++, anIndex++)
+      {
+        theIntervals->ChangeValue(anIndex) = aNewKnots[i] + aFirstPeriod * aPeriod;
+      }
+      // full periods
+      for (Standard_Integer aPeriodNum = aFirstPeriod + 1; aPeriodNum < aLastPeriod; aPeriodNum++)
+      {
+        for (Standard_Integer i = 1; i < aNewKnots.Size(); i++, anIndex++)
+        {
+          theIntervals->ChangeValue(anIndex) = aNewKnots[i] + aPeriodNum * aPeriod;
+        }
+      }
+      // part from the begging of the last period to the end of range
+      for (Standard_Integer i = 1; i <= anIndex2; i++, anIndex++)
+      {
+        theIntervals->ChangeValue(anIndex) = aNewKnots[i] + aLastPeriod * aPeriod;
+      }
+    }
+    else
+    {
+      Standard_Integer anIndex = 1;
+      for (Standard_Integer i = anIndex1; i <= anIndex2; i++, anIndex++)
+      {
+        theIntervals->ChangeValue(anIndex) = aNewKnots[i] + aFirstPeriod * aPeriod;
+      }
+    }
+    // update the first position (the begging of range doesn't coincide with the knot at anIndex1 in general)
+    theIntervals->ChangeValue(1) = theFirst;
+    // write the ending of the range (we didn't write it at all)
+    theIntervals->ChangeValue(aNbIntervals + 1) = theLast;
+  }
+  
+  return aNbIntervals;
+}
+
 //=======================================================================
 // function: FlatBezierKnots
 // purpose :
index 92efed9613d004441194482d44c04adec326e91e..710c204375122ed23f661fcb18f0110e38d88ed0 100644 (file)
@@ -1456,8 +1456,26 @@ public:
   //! we have |f (u1) - f (u0)| < Tolerance3D
   Standard_EXPORT static void Resolution (const TColgp_Array1OfPnt2d& Poles, const TColStd_Array1OfReal* Weights, const Standard_Integer NumPoles, const TColStd_Array1OfReal& FlatKnots, const Standard_Integer Degree, const Standard_Real Tolerance3D, Standard_Real& UTolerance);
 
-
-
+  //! Splits the given range to BSpline intervals of given continuity
+  //! @param[in] theKnots the knots of BSpline
+  //! @param[in] theMults the knots' multiplicities
+  //! @param[in] theDegree the degree of BSpline
+  //! @param[in] isPeriodic the periodicity of BSpline
+  //! @param[in] theContinuity the target interval's continuity 
+  //! @param[in] theFirst the begin of the target range
+  //! @param[in] theLast the end of the target range
+  //! @param[in] theTolerance the tolerance
+  //! @param[in,out] theIntervals the array to store intervals if isn't nullptr
+  //! @return the number of intervals
+  Standard_EXPORT static Standard_Integer Intervals (const TColStd_Array1OfReal& theKnots,
+                                                     const TColStd_Array1OfInteger& theMults,
+                                                     Standard_Integer theDegree,
+                                                     Standard_Boolean isPeriodic,
+                                                     Standard_Integer theContinuity,
+                                                     Standard_Real theFirst,
+                                                     Standard_Real theLast,
+                                                     Standard_Real theTolerance,
+                                                     TColStd_Array1OfReal* theIntervals);
 
 protected:
 
index f6727ca8e70222a849d27dc4374d0c31488ca01b..10b014ae4380f424157431b37f56d313b3b80cee 100644 (file)
@@ -58,65 +58,6 @@ static const Standard_Real PosTol = Precision::PConfusion() / 2;
 
 IMPLEMENT_STANDARD_RTTIEXT(Geom2dAdaptor_Curve, Adaptor2d_Curve2d)
 
-static void DefinFPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurFirst,
-  Standard_Integer &theFPer);
-
-static void DefinLPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurLast,
-  Standard_Integer &theLPer);
-
-static Standard_Integer LocalNbIntervals(const TColStd_Array1OfReal& theTK,
-  const TColStd_Array1OfInteger& theTM,
-  const TColStd_Array1OfInteger& theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theNbInt,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real theEps,
-  const Standard_Boolean thePeriodicCur,
-  Standard_Integer theNbIntervals,
-  Standard_Real theLower = 0,
-  Standard_Real thePeriod = 0,
-  Standard_Integer theIndex1 = 0,
-  Standard_Integer theIndex2 = 0);
-
-static void WriteIntervals(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theNbInt,
-  const Standard_Integer theIndex1,
-  const Standard_Integer theIndex2,
-  const Standard_Real theCurPeriod,
-  const Standard_Boolean theFlagForFirst,
-  TColStd_Array1OfReal &theT,
-  TColStd_Array1OfInteger &theFinalIntervals,
-  Standard_Integer &theNbIntervals,
-  Standard_Integer &theCurInt);
-
-static void SpreadInt(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theTM,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theFPer,
-  const Standard_Integer theLPer,
-  const Standard_Integer theNbInt,
-  const Standard_Real theLower,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real thePeriod,
-  const Standard_Real theLastParam,
-  const Standard_Real theEps,
-  TColStd_Array1OfReal &theT,
-  Standard_Integer &theNbIntervals);
-
 //=======================================================================
 //function : ShallowCopy
 //purpose  : 
@@ -355,345 +296,55 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
 }
 
 //=======================================================================
-//function : DefinFPeriod
-//purpose  :
+//function : NbIntervals
+//purpose  : 
 //=======================================================================
 
-void DefinFPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurFirst,
-  Standard_Integer &theFPer)
+Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
 {
-  if (theCurFirst >= theLower)
+  if (myTypeCurve == GeomAbs_BSplineCurve)
   {
-    while (theCurFirst >= theUpper)
+    if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
     {
-      theCurFirst = theCurFirst - thePeriod;
-      theFPer++;
-    }
-    if (Abs(theUpper - theCurFirst) <= theEps)
-    {
-      theFPer++;
-      theCurFirst = theLower;
-    }
-  }
-  else
-  {
-    while (theCurFirst < theLower)
-    {
-      theCurFirst = theCurFirst + thePeriod;
-      if (Abs(theLower - theCurFirst) > theEps)
-      {
-        theFPer--;
-      }
+      return 1;
     }
+    
+    Standard_Integer aDegree = myBSplineCurve->Degree();
+    Standard_Integer aCont;
 
-    if (Abs(theUpper - theCurFirst) <= theEps)
+    switch (S)
     {
-      theCurFirst = theLower;
-    }
-  }
-}
-
-//=======================================================================
-//function : DefinLPeriod
-//purpose  :
-//=======================================================================
-
-void DefinLPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurLast,
-  Standard_Integer &theLPer)
-{
-  if (theCurLast >= theLower)
-  {
-    if ((theCurLast >= theUpper) && (Abs(theCurLast - theUpper) <= theEps))
-    {
-      theCurLast = theUpper;
-    }
-    else
-    {
-      while (theCurLast >= theUpper)
-      {
-        theCurLast = theCurLast - thePeriod;
-        theLPer++;
-      }
-      if (Abs(theUpper - theCurLast) <= theEps)
-      {
-        theCurLast = theLower;
-      }
-    }
-  }
-  else
-  {
-    while (theCurLast < theLower)
-    {
-      theCurLast = theCurLast + thePeriod;
-      if (Abs(theLower - theCurLast) > theEps)
-      {
-        theLPer--;
-      }
-    }
-    if (Abs(theUpper - theCurLast) <= theEps)
-    {
-      theCurLast = theLower;
-    }
-  }
-}
-
-//=======================================================================
-//function : LocalNbIntervals
-//purpose  :
-//=======================================================================
-
-Standard_Integer LocalNbIntervals(const TColStd_Array1OfReal& theTK,
-  const TColStd_Array1OfInteger& theTM,
-  const TColStd_Array1OfInteger& theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theNbInt,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real theEps,
-  const Standard_Boolean thePeriodicCur,
-  Standard_Integer theNbIntervals,
-  Standard_Real theLower,
-  Standard_Real thePeriod,
-  Standard_Integer theIndex1,
-  Standard_Integer theIndex2)
-{
-  Standard_Real aNewFirst = theFirst;
-  Standard_Real aNewLast = theLast;
-  if (theIndex1 == 0)
-  {
-    BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theFirst,
-      thePeriodicCur, 1, theNb, theIndex1, aNewFirst);
-  }
-  if (theIndex2 == 0)
-  {
-    BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theLast,
-      thePeriodicCur, 1, theNb, theIndex2, aNewLast);
-  }
-  // Protection against theFirst = UFirst - eps, which located as ULast - eps
-  if (thePeriodicCur && ((aNewLast - aNewFirst) < Precision::PConfusion()))
-  {
-    if (Abs(aNewLast - theLower) < Precision::PConfusion())
-    {
-      aNewLast += thePeriod;
-    }
-    else
-    {
-      aNewFirst -= thePeriod;
-    }
-  }
-
-  if (Abs(aNewFirst - theTK(theIndex1 + 1)) < theEps)
-  {
-    theIndex1++;
-  }
-  if ((aNewLast - theTK(theIndex2)) > theEps)
-  {
-    theIndex2++;
-  }
-  for (Standard_Integer i = 1; i <= theNbInt; i++)
-  {
-    if (theInter(i) > theIndex1 && theInter(i) < theIndex2) theNbIntervals++;
-  }
-  return theNbIntervals;
-}
-
-//=======================================================================
-//function : NbIntervals
-//purpose  : 
-//=======================================================================
-
-Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
-{
-  Standard_Integer myNbIntervals = 1;
-  Standard_Integer NbSplit;
-  if (myTypeCurve == GeomAbs_BSplineCurve) {
-    Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
-    Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
-    TColStd_Array1OfInteger Inter(1, LastIndex - FirstIndex + 1);
-    Standard_Boolean aContPer = (S >= Continuity()) && myBSplineCurve->IsPeriodic();
-    Standard_Boolean aContNotPer = (S > Continuity()) && !myBSplineCurve->IsPeriodic();
-    if (aContPer || aContNotPer) {
-      Standard_Integer Cont;
-      switch (S) {
-      case GeomAbs_G1:
-      case GeomAbs_G2:
-        throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
-        break;
-      case GeomAbs_C0:
-        myNbIntervals = 1;
-        break;
       case GeomAbs_C1:
+        aCont = 1;
+        break;
       case GeomAbs_C2:
+        aCont = 2;
+        break;
       case GeomAbs_C3:
+        aCont = 3;
+        break;
       case GeomAbs_CN:
-      {
-        if (S == GeomAbs_C1) Cont = 1;
-        else if (S == GeomAbs_C2) Cont = 2;
-        else if (S == GeomAbs_C3) Cont = 3;
-        else                       Cont = myBSplineCurve->Degree();
-        Standard_Integer Degree = myBSplineCurve->Degree();
-        Standard_Integer NbKnots = myBSplineCurve->NbKnots();
-        TColStd_Array1OfInteger Mults(1, NbKnots);
-        myBSplineCurve->Multiplicities(Mults);
-        NbSplit = 1;
-        Standard_Integer Index = FirstIndex;
-        Inter(NbSplit) = Index;
-        Index++;
-        NbSplit++;
-        while (Index < LastIndex)
-        {
-          if (Degree - Mults(Index) < Cont)
-          {
-            Inter(NbSplit) = Index;
-            NbSplit++;
-          }
-          Index++;
-        }
-        Inter(NbSplit) = Index;
-
-        Standard_Integer NbInt = NbSplit - 1;
-
-        Standard_Integer Nb = myBSplineCurve->NbKnots();
-        TColStd_Array1OfReal    TK(1, Nb);
-        TColStd_Array1OfInteger TM(1, Nb);
-        myBSplineCurve->Knots(TK);
-        myBSplineCurve->Multiplicities(TM);
-        Standard_Real Eps = Min(Resolution(Precision::Confusion()),
-          Precision::PConfusion());
-
-        myNbIntervals = 1;
-
-        if (!myBSplineCurve->IsPeriodic())
-        {
-          myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-            myFirst, myLast, Eps, Standard_False, myNbIntervals);
-        }
-        else
-        {
-          Standard_Real aCurFirst = myFirst;
-          Standard_Real aCurLast = myLast;
-
-          Standard_Real aLower = myBSplineCurve->FirstParameter();
-          Standard_Real anUpper = myBSplineCurve->LastParameter();
-
-          if ((Abs(aCurFirst - aLower) < Eps) && (aCurFirst < aLower))
-          {
-            aCurFirst = aLower;
-          }
-          if ((Abs(aCurLast - anUpper) < Eps) && (aCurLast < anUpper))
-          {
-            aCurLast = anUpper;
-          }
-
-          Standard_Real aPeriod = myBSplineCurve->Period();
-          Standard_Integer aLPer = 1; Standard_Integer aFPer = 1;
-          
-          if ((Abs(aLower - myFirst) < Eps) && (aCurFirst < aLower))
-          {
-            aCurFirst = aLower;
-          }
-          else
-          {
-            DefinFPeriod(aLower, anUpper,
-              Eps, aPeriod, aCurFirst, aFPer);
-          }
-          DefinLPeriod(aLower, anUpper,
-            Eps, aPeriod, aCurLast, aLPer);
-
-          if ((Abs(aLower - myFirst) < Eps) && (Abs(anUpper - myLast) < Eps))
-          {
-            myNbIntervals = NbInt;
-          }
-          else
-          {
-            Standard_Integer aSumPer = Abs(aLPer - aFPer);
-            
-            Standard_Real aFirst = 0;
-            if (aLower < 0 && anUpper == 0)
-            {
-              if (Abs(aCurLast) < Eps)
-              {
-                aCurLast = 0;
-              }
-              aFirst = aLower;
-            }
-
-            if (aSumPer <= 1)
-            {
-              if ((Abs(myFirst - TK(Nb) - aPeriod * (aFPer - 1)) <= Eps) && (myLast < (TK(Nb) + aPeriod * (aLPer - 1))))
-              {
-                myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                  myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-                return myNbIntervals;
-              }
-              if ((Abs(myFirst - aLower) < Eps) && (Abs(myLast - anUpper) < Eps))
-              {
-                myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                  myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-                return myNbIntervals;
-              }
-            }
-
-            if (aSumPer != 0)
-            {
-              Standard_Integer aFInt = 0;
-              Standard_Integer aLInt = 0;
-              Standard_Integer aPInt = NbInt;
-
-              if ((aCurFirst != aPeriod) || ((aCurFirst != anUpper) && (Abs(myFirst) < Eps)))
-              {
-              aFInt = 1;
-              }
-              if ((aCurLast != 0) && (aCurLast != anUpper))
-              {
-                aLInt = 1;
-              }
-
-              aFInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                aCurFirst, anUpper, Eps, Standard_True, aFInt, aLower, aPeriod);
-
-              if (aCurLast == anUpper)
-              {
-                aLInt = NbInt;
-              }
-              else
-              {
-                if (Abs(aCurLast - aFirst) > Eps)
-                {
-                  aLInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                    aFirst, aCurLast, Eps, Standard_True, aLInt, aLower, aPeriod, 1);
-                }
-                else
-                {
-                  aLInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                    aFirst, aCurLast, Eps, Standard_True, aLInt, aLower, aPeriod);
-                }
-              }
-
-              myNbIntervals = aFInt + aLInt + aPInt * (aSumPer - 1);
-            }
-            else
-            {
-              myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                aCurFirst, aCurLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-            }
-          }
-        }
-      }
-      break;
-      }
+        aCont = aDegree;
+        break;
+      default:
+        throw Standard_DomainError ("Geom2dAdaptor_Curve::NbIntervals()");
     }
+
+    Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
+
+    return BSplCLib::Intervals(myBSplineCurve->Knots(),
+                               myBSplineCurve->Multiplicities(),
+                               aDegree,
+                               myBSplineCurve->IsPeriodic(),
+                               aCont,
+                               myFirst,
+                               myLast,
+                               anEps,
+                               nullptr);
   }
+
   else if (myTypeCurve == GeomAbs_OffsetCurve){
+    Standard_Integer myNbIntervals = 1;
     GeomAbs_Shape BaseS=GeomAbs_C0;
     switch(S){
     case GeomAbs_G1:
@@ -705,366 +356,69 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
     case GeomAbs_C2: BaseS = GeomAbs_C3; break;
     default: BaseS = GeomAbs_CN;
     }
-    Geom2dAdaptor_Curve anAdaptor( Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve() );
+    Geom2dAdaptor_Curve anAdaptor (Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve(), myFirst, myLast);
     myNbIntervals = anAdaptor.NbIntervals(BaseS);
+    return myNbIntervals;
   }
 
-  return myNbIntervals;
-}
-
-//=======================================================================
-//function : WriteIntervals
-//purpose  :
-//=======================================================================
-
-void WriteIntervals(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theNbInt,
-  const Standard_Integer theIndex1,
-  const Standard_Integer theIndex2,
-  const Standard_Real theCurPeriod,
-  const Standard_Boolean theFlagForFirst,
-  TColStd_Array1OfReal &theT,
-  TColStd_Array1OfInteger &theFinalIntervals,
-  Standard_Integer &theNbIntervals,
-  Standard_Integer &theCurInt)
-{
-  if (theFlagForFirst)
-  {
-    for (Standard_Integer anId = 1; anId <= theNbInt; anId++)
-    {
-      if (theInter(anId) > theIndex1 && theInter(anId) <= theIndex2)
-      {
-        theNbIntervals++;
-        theFinalIntervals(theNbIntervals) = theInter(anId);
-      }
-    }
-  }
   else
   {
-    for (Standard_Integer anId = 1; anId <= theNbInt; anId++)
-    {
-      if (theInter(anId) > theIndex1 && theInter(anId) < theIndex2)
-      {
-        theNbIntervals++;
-        theFinalIntervals(theNbIntervals) = theInter(anId);
-      }
-    }
-  }
-
-  theFinalIntervals(theNbIntervals + 1) = theIndex2;
-
-  for (Standard_Integer anId = theCurInt; anId <= theNbIntervals + 1; anId++)
-  {
-    theT(anId) = theTK(theFinalIntervals(anId)) + theCurPeriod;
-    theCurInt++;
+    return 1;
   }
 }
 
 //=======================================================================
-//function : SpreadInt
-//purpose  :
+//function : Intervals
+//purpose  : 
 //=======================================================================
-void SpreadInt(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theTM,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theFPer,
-  const Standard_Integer theLPer,
-  const Standard_Integer theNbInt,
-  const Standard_Real theLower,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real thePeriod,
-  const Standard_Real theLastParam,
-  const Standard_Real theEps,
-  TColStd_Array1OfReal &theT,
-  Standard_Integer &theNbIntervals)
-{
-  Standard_Integer anIndex1 = 0;
-  Standard_Integer anIndex2 = 0;
-  Standard_Real aNewFirst, aNewLast;
-  Standard_Integer anUpper;
-  BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theFirst,
-    Standard_True, 1, theNb, anIndex1, aNewFirst);
-  BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theLastParam,
-    Standard_True, 1, theNb, anIndex2, aNewLast);
-
-  if (Abs(aNewFirst - theTK(anIndex1 + 1)) < theEps)
-  {
-    anIndex1++;
-  }
-  if ((aNewLast - theTK(anIndex2)) > theEps)
-  {
-    anIndex2++;
-  }
-  theNbIntervals = 1;
-
-  if (anIndex1 == theNb)
-  {
-    anIndex1 = 1;
-  }
-  
-  // Count the max number of boundaries of intervals
-  if (Abs(theLPer - theFPer) > 1)
-  {
-    anUpper = theNb - anIndex1 + anIndex2 + (theLPer - theFPer - 1) * theNb + 1;
-  }
-  else
-  {
-    anUpper = theNb - anIndex1 + anIndex2 + 1;
-  }
-
-  if (theLPer == theFPer)
-  {
-    anUpper = theInter.Upper();
-  }
-  TColStd_Array1OfInteger aFinalIntervals(1, anUpper);
-  aFinalIntervals(1) = anIndex1;
-
-  // If first and last are in the same period
-  if ((Abs(theLPer - theFPer) == 0))
-  {
-    Standard_Integer aCurInt = 1;
-    Standard_Real aCurPeriod = theFPer * thePeriod;
-
-    if (theFirst == aNewFirst && theLast == aNewLast)
-    {
-      aCurPeriod = 0;
-    }
-    WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-      anIndex2, aCurPeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
-    return;
-  }
 
-  // If the first and the last are in neighboring periods
-  if (Abs(theLPer - theFPer) == 1)
+void Geom2dAdaptor_Curve::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const 
+{
+  if (myTypeCurve == GeomAbs_BSplineCurve)
   {
-    Standard_Integer aCurInt = 1;
-
-    if (Abs(theLastParam - theLower) < theEps)
-    {
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      return;
-    }
-    else
+    if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
     {
-      // For period with first
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      // For period with last
-      theNbIntervals++;
-      WriteIntervals(theTK, theInter, theNbInt, 1,
-        anIndex2, theLPer * thePeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
+      T( T.Lower() ) = myFirst;
+      T( T.Lower() + 1 ) = myLast;
       return;
     }
-  }
-  // If the first and the last are far apart
-  if (Abs(theLPer - theFPer) > 1)
-  {
-    Standard_Integer aCurInt = 1;
-    if (Abs(theLastParam - theLower) < theEps)
-    {
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-
-      Standard_Integer aNbPer = Abs(theLPer - theFPer);
-      Standard_Integer aCurPer = theFPer + 1;
 
-      while (aNbPer > 1)
-      {
-        theNbIntervals++;
-        WriteIntervals(theTK, theInter, theNbInt, 1,
-          theNb, aCurPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
+    Standard_Integer aDegree = myBSplineCurve->Degree();
+    Standard_Integer aCont;
 
-        aNbPer--;
-        aCurPer++;
-      }
-      return;
-    }
-    else
+    switch (S)
     {
-      // For period with first
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-
-      Standard_Integer aNbPer = Abs(theLPer - theFPer);
-      Standard_Integer aCurPer = theFPer + 1;
-      while (aNbPer > 1)
-      {
-        theNbIntervals++;
-        WriteIntervals(theTK, theInter, theNbInt, 1,
-          theNb, aCurPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-
-        aNbPer--;
-        aCurPer++;
-      }
-      // For period with last
-      theNbIntervals++;
-      WriteIntervals(theTK, theInter, theNbInt, 1,
-        anIndex2, theLPer * thePeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      return;
-    }
-  }
-}
-
-//=======================================================================
-//function : Intervals
-//purpose  : 
-//=======================================================================
-
-void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
-                                   const GeomAbs_Shape S   ) const 
-{
-  Standard_Integer myNbIntervals = 1;
-  Standard_Integer NbSplit;
-  if (myTypeCurve == GeomAbs_BSplineCurve) {
-    Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
-    Standard_Integer LastIndex  = myBSplineCurve->LastUKnotIndex();
-    TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
-    Standard_Boolean aContPer = (S >= Continuity()) && myBSplineCurve->IsPeriodic();
-    Standard_Boolean aContNotPer = (S > Continuity()) && !myBSplineCurve->IsPeriodic();
-    if (aContPer || aContNotPer) {
-      Standard_Integer Cont;
-      switch ( S) {
-      case GeomAbs_G1:
-      case GeomAbs_G2:
-       throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
-       break;
-      case GeomAbs_C0:
-       myNbIntervals = 1;
-       break;
       case GeomAbs_C1:
+        aCont = 1;
+        break;
       case GeomAbs_C2:
-      case GeomAbs_C3: 
-      case GeomAbs_CN: 
-      {
-        if (S == GeomAbs_C1) Cont = 1;
-        else if (S == GeomAbs_C2) Cont = 2;
-        else if (S == GeomAbs_C3) Cont = 3;
-        else                       Cont = myBSplineCurve->Degree();
-        Standard_Integer Degree = myBSplineCurve->Degree();
-        Standard_Integer NbKnots = myBSplineCurve->NbKnots();
-        TColStd_Array1OfInteger Mults(1, NbKnots);
-        myBSplineCurve->Multiplicities(Mults);
-        NbSplit = 1;
-        Standard_Integer Index = FirstIndex;
-        Inter(NbSplit) = Index;
-        Index++;
-        NbSplit++;
-        while (Index < LastIndex)
-        {
-          if (Degree - Mults(Index) < Cont)
-          {
-            Inter(NbSplit) = Index;
-            NbSplit++;
-          }
-          Index++;
-        }
-        Inter(NbSplit) = Index;
-        Standard_Integer NbInt = NbSplit - 1;
-
-        Standard_Integer Nb = myBSplineCurve->NbKnots();
-        Standard_Integer Index1 = 0;
-        Standard_Integer Index2 = 0;
-        Standard_Real newFirst, newLast;
-        TColStd_Array1OfReal    TK(1, Nb);
-        TColStd_Array1OfInteger TM(1, Nb);
-        myBSplineCurve->Knots(TK);
-        myBSplineCurve->Multiplicities(TM);
-        Standard_Real Eps = Min(Resolution(Precision::Confusion()),
-          Precision::PConfusion());
-
-        if (!myBSplineCurve->IsPeriodic())
-        {
-          BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myFirst,
-            myBSplineCurve->IsPeriodic(),
-            1, Nb, Index1, newFirst);
-          BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myLast,
-            myBSplineCurve->IsPeriodic(),
-            1, Nb, Index2, newLast);
-
-
-          // On decale eventuellement les indices  
-          // On utilise une "petite" tolerance, la resolution ne doit 
-                // servir que pour les tres longue courbes....(PRO9248)
-          if (Abs(newFirst - TK(Index1 + 1)) < Eps) Index1++;
-          if (newLast - TK(Index2) > Eps) Index2++;
-
-          Inter(1) = Index1;
-          myNbIntervals = 1;
-          for (Standard_Integer i = 1; i <= NbInt; i++) {
-            if (Inter(i) > Index1 && Inter(i) < Index2) {
-              myNbIntervals++;
-              Inter(myNbIntervals) = Inter(i);
-            }
-          }
-          Inter(myNbIntervals + 1) = Index2;
-
-          Standard_Integer ii = T.Lower() - 1;
-          for (Standard_Integer I = 1; I <= myNbIntervals + 1; I++) {
-            T(ii + I) = TK(Inter(I));
-          }
-        }
-        else
-        {
-          Standard_Real aFirst = myFirst;
-          Standard_Real aLast = myLast;
-
-          Standard_Real aCurFirst = aFirst;
-          Standard_Real aCurLast = aLast;
-
-          Standard_Real aPeriod = myBSplineCurve->Period();
-          Standard_Real aLower = myBSplineCurve->FirstParameter();
-          Standard_Real anUpper = myBSplineCurve->LastParameter();
-
-          Standard_Integer aLPer = 0; Standard_Integer aFPer = 0;
-
-          if (Abs(myFirst - aLower) <= Eps)
-          {
-            aCurFirst = aLower;
-            aFirst = aCurFirst;
-          }
-          if (Abs(myLast - anUpper) <= Eps)
-          {
-            aCurLast = anUpper;
-            aLast = aCurLast;
-          }
-
-          if ((Abs(aLower - myFirst) < Eps) && (aCurFirst < aLower))
-          {
-            aCurFirst = aLower;
-          }
-          else
-          {
-            DefinFPeriod(aLower, anUpper,
-              Eps, aPeriod, aCurFirst, aFPer);
-          }
-          DefinLPeriod(aLower, anUpper,
-            Eps, aPeriod, aCurLast, aLPer);
-
-          if (myFirst == aLower)
-          {
-            aFPer = 0;
-          }
-
-          SpreadInt(TK, TM, Inter, myBSplineCurve->Degree(), Nb, aFPer, aLPer, NbInt, aLower, myFirst, myLast, aPeriod,
-            aCurLast, Eps, T, myNbIntervals);
-          T(T.Lower()) = aFirst;
-          T(T.Lower() + myNbIntervals) = aLast;
-          return;
-
-        }
-      }
-      T(T.Lower()) = myFirst;
-      T(T.Lower() + myNbIntervals) = myLast;
-      return;
-      }
+        aCont = 2;
+        break;
+      case GeomAbs_C3:
+        aCont = 3;
+        break;
+      case GeomAbs_CN:
+        aCont = aDegree;
+        break;
+      default:
+        throw Standard_DomainError ("Geom2dAdaptor_Curve::Intervals()");
     }
+
+    Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
+
+    BSplCLib::Intervals(myBSplineCurve->Knots(),
+                        myBSplineCurve->Multiplicities(),
+                        aDegree,
+                        myBSplineCurve->IsPeriodic(),
+                        aCont,
+                        myFirst,
+                        myLast,
+                        anEps,
+                        &T);
   }
+
   else if (myTypeCurve == GeomAbs_OffsetCurve){
+    Standard_Integer myNbIntervals = 1;
     GeomAbs_Shape BaseS=GeomAbs_C0;
     switch(S){
     case GeomAbs_G1:
@@ -1077,13 +431,18 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
     default: BaseS = GeomAbs_CN;
     }
 
-    Geom2dAdaptor_Curve anAdaptor( Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve() );
+    Geom2dAdaptor_Curve anAdaptor (Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve(), myFirst, myLast);
     myNbIntervals = anAdaptor.NbIntervals(BaseS);
     anAdaptor.Intervals(T, BaseS);
+    T( T.Lower() ) = myFirst;
+    T( T.Lower() + myNbIntervals ) = myLast;
   }
 
-  T( T.Lower() ) = myFirst;
-  T( T.Lower() + myNbIntervals ) = myLast;
+  else
+  {
+    T( T.Lower() ) = myFirst;
+    T( T.Lower() + 1 ) = myLast;
+  }
 }
 
 //=======================================================================
index 24aacacb7757037e22077818d1bf3099658f978c..a68075eeb03d032b4889f60f46b8cbf63f4d8531 100644 (file)
@@ -58,65 +58,6 @@ static const Standard_Real PosTol = Precision::PConfusion() / 2;
 
 IMPLEMENT_STANDARD_RTTIEXT(GeomAdaptor_Curve, Adaptor3d_Curve)
 
-static void DefinFPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurFirst,
-  Standard_Integer &theFPer);
-
-static void DefinLPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurLast,
-  Standard_Integer &theLPer);
-
-static Standard_Integer LocalNbIntervals(const TColStd_Array1OfReal& theTK,
-  const TColStd_Array1OfInteger& theTM,
-  const TColStd_Array1OfInteger& theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theNbInt,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real theEps,
-  const Standard_Boolean thePeriodicCur,
-  Standard_Integer theNbIntervals,
-  Standard_Real theLower = 0,
-  Standard_Real thePeriod = 0,
-  Standard_Integer theIndex1 = 0,
-  Standard_Integer theIndex2 = 0);
-
-static void WriteIntervals(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theNbInt,
-  const Standard_Integer theIndex1,
-  const Standard_Integer theIndex2,
-  const Standard_Real theCurPeriod,
-  const Standard_Boolean theFlagForFirst,
-  TColStd_Array1OfReal &theT,
-  TColStd_Array1OfInteger &theFinalIntervals,
-  Standard_Integer &theNbIntervals,
-  Standard_Integer &theCurInt);
-
-static void SpreadInt(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theTM,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theFPer,
-  const Standard_Integer theLPer,
-  const Standard_Integer theNbInt,
-  const Standard_Real theLower,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real thePeriod,
-  const Standard_Real theLastParam,
-  const Standard_Real theEps,
-  TColStd_Array1OfReal &theT,
-  Standard_Integer &theNbIntervals);
-
 //=======================================================================
 //function : ShallowCopy
 //purpose  : 
@@ -311,366 +252,67 @@ GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
 }
 
 //=======================================================================
-//function : DefinFPeriod
-//purpose  :
+//function : NbIntervals
+//purpose  : 
 //=======================================================================
 
-void DefinFPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurFirst,
-  Standard_Integer &theFPer)
+Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
 {
-  if (theCurFirst >= theLower)
-  {
-    while (theCurFirst >= theUpper)
-    {
-      theCurFirst = theCurFirst - thePeriod;
-      theFPer++;
-    }
-    if (Abs(theUpper - theCurFirst) <= theEps)
-    {
-      theFPer++;
-      theCurFirst = theLower;
-    }
-  }
-  else
+  if (myTypeCurve == GeomAbs_BSplineCurve)
   {
-    while (theCurFirst < theLower)
+    if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
     {
-      theCurFirst = theCurFirst + thePeriod;
-      if ((Abs(theLower - theCurFirst)) > theEps)
-      {
-        theFPer--;
-      }
+      return 1;
     }
 
-    if (Abs(theUpper - theCurFirst) <= theEps)
-    {
-      theCurFirst = theLower;
-    }
-  }
-}
+    Standard_Integer aDegree = myBSplineCurve->Degree();
+    Standard_Integer aCont;
 
-//=======================================================================
-//function : DefinLPeriod
-//purpose  :
-//=======================================================================
-
-void DefinLPeriod(const Standard_Real theLower,
-  const Standard_Real theUpper,
-  const Standard_Real theEps,
-  const Standard_Real thePeriod,
-  Standard_Real &theCurLast,
-  Standard_Integer &theLPer)
-{
-  if (theCurLast >= theLower)
-  {
-    if ((theCurLast >= theUpper) && (Abs(theCurLast - theUpper) <= theEps))
-    {
-      theCurLast = theUpper;
-    }
-    else
-    {
-      while (theCurLast >= theUpper)
-      {
-        theCurLast = theCurLast - thePeriod;
-        theLPer++;
-      }
-      if (Abs(theUpper - theCurLast) <= theEps)
-      {
-        theCurLast = theLower;
-      }
-    }
-  }
-  else
-  {
-    while (theCurLast < theLower)
-    {
-      theCurLast = theCurLast + thePeriod;
-      if (Abs(theLower - theCurLast) > theEps)
-      {
-        theLPer--;
-      }
-    }
-    if ((theUpper - theCurLast) <= theEps)
+    switch (S)
     {
-      theCurLast = theLower;
-    }
-  }
-}
-
-//=======================================================================
-//function : LocalNbIntervals
-//purpose  :
-//=======================================================================
-
-Standard_Integer LocalNbIntervals(const TColStd_Array1OfReal& theTK,
-  const TColStd_Array1OfInteger& theTM,
-  const TColStd_Array1OfInteger& theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theNbInt,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real theEps,
-  const Standard_Boolean thePeriodicCur,
-  Standard_Integer theNbIntervals,
-  Standard_Real theLower,
-  Standard_Real thePeriod,
-  Standard_Integer theIndex1,
-  Standard_Integer theIndex2)
-{
-  Standard_Real aNewFirst = theFirst;
-  Standard_Real aNewLast = theLast;
-  if (theIndex1 == 0)
-  {
-    BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theFirst,
-      thePeriodicCur, 1, theNb, theIndex1, aNewFirst);
-  }
-  if (theIndex2 == 0)
-  {
-    BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theLast,
-      thePeriodicCur, 1, theNb, theIndex2, aNewLast);
-  }
-  // Protection against theFirst = UFirst - eps, which located as ULast - eps
-  if (thePeriodicCur && ((aNewLast - aNewFirst) < Precision::PConfusion()))
-  {
-    if (Abs(aNewLast - theLower) < Precision::PConfusion())
-    {
-      aNewLast += thePeriod;
-    }
-    else
-    {
-      aNewFirst -= thePeriod;
-    }
-  }
-
-  if (Abs(aNewFirst - theTK(theIndex1 + 1)) < theEps)
-  {
-    theIndex1++;
-  }
-  if ((aNewLast - theTK(theIndex2)) > theEps)
-  {
-    theIndex2++;
-  }
-  for (Standard_Integer i = 1; i <= theNbInt; i++)
-  {
-    if (theInter(i) > theIndex1 && theInter(i) < theIndex2) theNbIntervals++;
-  }
-  return theNbIntervals;
-}
-
-
-//=======================================================================
-//function : NbIntervals
-//purpose  : 
-//=======================================================================
-
-Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
-{
-  Standard_Integer myNbIntervals = 1;
-  Standard_Integer NbSplit;
-  if (myTypeCurve == GeomAbs_BSplineCurve) {
-    Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
-    Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
-    TColStd_Array1OfInteger Inter(1, LastIndex - FirstIndex + 1);
-    Standard_Boolean aContPer = (S >= Continuity()) && myBSplineCurve->IsPeriodic();
-    Standard_Boolean aContNotPer = (S > Continuity()) && !myBSplineCurve->IsPeriodic();
-
-    if(aContPer || aContNotPer) {
-      Standard_Integer Cont;
-      switch (S) {
-      case GeomAbs_G1:
-      case GeomAbs_G2:
-        throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
-        break;
-      case GeomAbs_C0:
-        myNbIntervals = 1;
-        break;
       case GeomAbs_C1:
+        aCont = 1;
+        break;
       case GeomAbs_C2:
+        aCont = 2;
+        break;
       case GeomAbs_C3:
+        aCont = 3;
+        break;
       case GeomAbs_CN:
-      {
-        if (S == GeomAbs_C1) Cont = 1;
-        else if (S == GeomAbs_C2) Cont = 2;
-        else if (S == GeomAbs_C3) Cont = 3;
-        else                       Cont = myBSplineCurve->Degree();
-        Standard_Integer Degree = myBSplineCurve->Degree();
-        Standard_Integer NbKnots = myBSplineCurve->NbKnots();
-        TColStd_Array1OfInteger Mults(1, NbKnots);
-        myBSplineCurve->Multiplicities(Mults);
-        NbSplit = 1;
-        Standard_Integer Index = FirstIndex;
-        Inter(NbSplit) = Index;
-        Index++;
-        NbSplit++;
-        while (Index < LastIndex)
-        {
-          if (Degree - Mults(Index) < Cont)
-          {
-            Inter(NbSplit) = Index;
-            NbSplit++;
-          }
-          Index++;
-        }
-        Inter(NbSplit) = Index;
-
-        Standard_Integer NbInt = NbSplit - 1;
-
-        Standard_Integer Nb = myBSplineCurve->NbKnots();
-        Standard_Integer Index1 = 0;
-        Standard_Integer Index2 = 0;
-        const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
-        const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
-        Standard_Real Eps = Min(Resolution(Precision::Confusion()),
-          Precision::PConfusion());
-
-        myNbIntervals = 1;
-
-        if (!myBSplineCurve->IsPeriodic())
-        {
-          myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-            myFirst, myLast, Eps, Standard_False, myNbIntervals);
-        }
-        else
-        {
-          Standard_Real aCurFirst = myFirst;
-          Standard_Real aCurLast = myLast;
-          Standard_Real aLower = myBSplineCurve->FirstParameter();
-          Standard_Real anUpper = myBSplineCurve->LastParameter();
-
-          if ((Abs(aCurFirst - aLower) < Eps) && (aCurFirst < aLower))
-          {
-            aCurFirst = aLower;
-          }
-          if ((Abs(aCurLast - anUpper) < Eps) && (aCurLast < anUpper))
-          {
-            aCurLast = anUpper;
-          }
-
-          Standard_Real aPeriod = myBSplineCurve->Period();
-          Standard_Integer aLPer = 1; Standard_Integer aFPer = 1;
-          if ((Abs(aLower - myFirst) < Eps) && (aCurFirst < aLower))
-          {
-            aCurFirst = aLower;
-          }
-          else
-          {
-            DefinFPeriod(aLower, anUpper,
-              Eps, aPeriod, aCurFirst, aFPer);
-          }
-          DefinLPeriod(aLower, anUpper,
-            Eps, aPeriod, aCurLast, aLPer);
-
-          Standard_Real aNewFirst;
-          Standard_Real aNewLast;
-          BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myFirst,
-            Standard_True, 1, Nb, Index1, aNewFirst);
-          BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myLast,
-            Standard_True, 1, Nb, Index2, aNewLast);
-          if ((aNewFirst == myFirst && aNewLast == myLast) && (aFPer != aLPer))
-          {
-            myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-              myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-          }
-          else
-          {
-            Standard_Integer aSumPer = Abs(aLPer - aFPer);
-            
-            Standard_Real aFirst = 0;
-            if (aLower < 0 && anUpper == 0)
-            {
-              if (Abs(aCurLast) < Eps)
-              {
-                aCurLast = 0;
-              }
-              aFirst = aLower;
-            }
-
-            if (aSumPer <= 1)
-            {
-              if ((Abs(myFirst - TK(Nb) - aPeriod * (aFPer - 1)) <= Eps) && (myLast < (TK(Nb) + aPeriod * (aLPer - 1))))
-              {
-                myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                  myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-                return myNbIntervals;
-              }
-              if ((Abs(myFirst - aLower) < Eps) && (Abs(myLast - anUpper) < Eps))
-              {
-                myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                  myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-                return myNbIntervals;
-              }
-            }
-
-            if (aSumPer != 0)
-            {
-              Standard_Integer aFInt = 0;
-              Standard_Integer aLInt = 0;
-              Standard_Integer aPInt = NbInt;
-
-              if ((aCurFirst != aPeriod) || ((aCurFirst != anUpper) && (Abs(myFirst) < Eps)))
-              {
-                aFInt = 1;
-              }
-              if ((aCurLast != aLower) && (aCurLast != anUpper))
-              {
-                aLInt = 1;
-              }
-
-              aFInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                aCurFirst, anUpper, Eps, Standard_True, aFInt, aLower, aPeriod);
-
-              if (aCurLast == anUpper)
-              {
-                aLInt = NbInt;
-              }
-              else
-              {
-                if (Abs(aCurLast - aFirst) > Eps)
-                {
-                  aLInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                    aFirst, aCurLast, Eps, Standard_True, aLInt, aLower, aPeriod, 1);
-                }
-                else
-                {
-                  aLInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                    aFirst, aCurLast, Eps, Standard_True, aLInt, aLower, aPeriod);
-                }
-              }
-
-              myNbIntervals = aFInt + aLInt + aPInt * (aSumPer - 1);
-            }
-            else
-            {
-              myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
-                aCurFirst, aCurLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
-            }
-          }
-        }
-      }
-      break;
-      }
+        aCont = aDegree;
+        break;
+      default:
+        throw Standard_DomainError ("GeomAdaptor_Curve::NbIntervals()");
     }
+
+    Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
+
+    return BSplCLib::Intervals(myBSplineCurve->Knots(),
+                               myBSplineCurve->Multiplicities(),
+                               aDegree,
+                               myBSplineCurve->IsPeriodic(),
+                               aCont,
+                               myFirst,
+                               myLast,
+                               anEps,
+                               nullptr);
   }
   
   else if (myTypeCurve == GeomAbs_OffsetCurve) {
+    Standard_Integer myNbIntervals = 1;
     GeomAbs_Shape BaseS=GeomAbs_C0;
     switch(S){
-    case GeomAbs_G1:
-    case GeomAbs_G2:
-      throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
-      break;
-    case GeomAbs_C0: BaseS = GeomAbs_C1; break;
-    case GeomAbs_C1: BaseS = GeomAbs_C2; break;
-    case GeomAbs_C2: BaseS = GeomAbs_C3; break;
-    default: BaseS = GeomAbs_CN;
-    }
-    GeomAdaptor_Curve C
-      (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
+      case GeomAbs_G1:
+        case GeomAbs_G2:
+          throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
+          break;
+          case GeomAbs_C0: BaseS = GeomAbs_C1; break;
+          case GeomAbs_C1: BaseS = GeomAbs_C2; break;
+          case GeomAbs_C2: BaseS = GeomAbs_C3; break;
+          default: BaseS = GeomAbs_CN;
+    }
+    GeomAdaptor_Curve C (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve(), myFirst, myLast);
     // akm 05/04/02 (OCC278)  If our curve is trimmed we must recalculate 
     //                    the number of intervals obtained from the basis to
     //              vvv   reflect parameter bounds
@@ -680,388 +322,71 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
       TColStd_Array1OfReal rdfInter(1,1+iNbBasisInt);
       C.Intervals(rdfInter,BaseS);
       for (iInt=1; iInt<=iNbBasisInt; iInt++)
-       if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
-         myNbIntervals++;
+        if (rdfInter(iInt)>myFirst && rdfInter(iInt)<myLast)
+          myNbIntervals++;
     }
     // akm 05/04/02 ^^^
+    return myNbIntervals;
   }
-  return myNbIntervals;
-}
 
-//=======================================================================
-//function : WriteIntervals
-//purpose  :
-//=======================================================================
-
-static void WriteIntervals(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theNbInt,
-  const Standard_Integer theIndex1,
-  const Standard_Integer theIndex2,
-  const Standard_Real theCurPeriod,
-  const Standard_Boolean theFlagForFirst,
-  TColStd_Array1OfReal &theT,
-  TColStd_Array1OfInteger &theFinalIntervals,
-  Standard_Integer &theNbIntervals,
-  Standard_Integer &theCurInt)
-{
-  if (theFlagForFirst)
-  {
-    for (Standard_Integer anId = 1; anId <= theNbInt; anId++)
-    {
-      if (theInter(anId) > theIndex1 && theInter(anId) <= theIndex2)
-      {
-        theNbIntervals++;
-        theFinalIntervals(theNbIntervals) = theInter(anId);
-      }
-    }
-  }
   else
   {
-    for (Standard_Integer anId = 1; anId <= theNbInt; anId++)
-    {
-      if (theInter(anId) > theIndex1 && theInter(anId) < theIndex2)
-      {
-        theNbIntervals++;
-        theFinalIntervals(theNbIntervals) = theInter(anId);
-      }
-    }
-  }
-  theFinalIntervals(theNbIntervals + 1) = theIndex2;
-
-  for (Standard_Integer anId = theCurInt; anId <= theNbIntervals + 1; anId++)
-  {
-    theT(anId) = theTK(theFinalIntervals(anId)) + theCurPeriod;
-    theCurInt++;
+    return 1;
   }
 }
 
 //=======================================================================
-//function : SpreadInt
-//purpose  :
+//function : Intervals
+//purpose  : 
 //=======================================================================
 
-void SpreadInt(const TColStd_Array1OfReal &theTK,
-  const TColStd_Array1OfInteger &theTM,
-  const TColStd_Array1OfInteger &theInter,
-  const Standard_Integer theCurDegree,
-  const Standard_Integer theNb,
-  const Standard_Integer theFPer,
-  const Standard_Integer theLPer,
-  const Standard_Integer theNbInt,
-  const Standard_Real theLower,
-  const Standard_Real theFirst,
-  const Standard_Real theLast,
-  const Standard_Real thePeriod,
-  const Standard_Real theLastParam,
-  const Standard_Real theEps,
-  TColStd_Array1OfReal &theT,
-  Standard_Integer &theNbIntervals)
+void GeomAdaptor_Curve::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
 {
-  Standard_Integer anIndex1 = 0;
-  Standard_Integer anIndex2 = 0;
-  Standard_Real aNewFirst, aNewLast;
-  Standard_Integer anUpper;
-  BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theFirst,
-    Standard_True, 1, theNb, anIndex1, aNewFirst);
-  BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theLastParam,
-    Standard_True, 1, theNb, anIndex2, aNewLast);
-
-  if (Abs(aNewFirst - theTK(anIndex1 + 1)) < theEps)
-  {
-    anIndex1++;
-  }
-  if ((aNewLast - theTK(anIndex2)) > theEps)
-  {
-    anIndex2++;
-  }
-  theNbIntervals = 1;
-
-  if (anIndex1 == theNb)
-  {
-    anIndex1 = 1;
-  }
-
-  // Count the max number of boundaries of intervals
-  if (Abs(theLPer - theFPer) > 1)
-  {
-    anUpper = theNb - anIndex1 + anIndex2 + (theLPer - theFPer - 1) * theNb + 1;
-  }
-  else
-  {
-    anUpper = theNb - anIndex1 + anIndex2 + 1;
-  }
-
-  if (theLPer == theFPer)
-  {
-    anUpper = theInter.Upper();
-  }
-  TColStd_Array1OfInteger aFinalIntervals(1, anUpper);
-  aFinalIntervals(1) = anIndex1;
-
-  // If first and last are in the same period
-  if ((Abs(theLPer - theFPer) == 0))
-  {
-    Standard_Integer aCurInt = 1;
-    Standard_Real aCurPeriod = theFPer * thePeriod;
-
-    if (theFirst == aNewFirst && theLast == aNewLast)
-    {
-      aCurPeriod = 0;
-    }
-    WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-      anIndex2, aCurPeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
-    return;
-  }
-
-  // If the first and the last are in neighboring periods
-  if (Abs(theLPer - theFPer) == 1)
+  if (myTypeCurve == GeomAbs_BSplineCurve)
   {
-    Standard_Integer aCurInt = 1;
-
-    if (Abs(theLastParam - theLower) < theEps)
+    if ((!myBSplineCurve->IsPeriodic() && S <= Continuity()) || S == GeomAbs_C0)
     {
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
+      T( T.Lower() ) = myFirst;
+      T( T.Lower() + 1 ) = myLast;
       return;
     }
-    else
-    {
-      // For period with first
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      // For period with last
-      theNbIntervals++;
-      WriteIntervals(theTK, theInter, theNbInt, 1,
-        anIndex2, theLPer * thePeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      return;
-    }
-  }
-  // If the first and the last are far apart
-  if (Abs(theLPer - theFPer) > 1)
-  {
-    Standard_Integer aCurInt = 1;
 
-    if (Abs(theLastParam - theLower) < theEps)
-    {
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-
-      Standard_Integer aNbPer = Abs(theLPer - theFPer);
-      Standard_Integer aCurPer = theFPer + 1;
-
-      while (aNbPer > 1)
-      {
-        theNbIntervals++;
-        WriteIntervals(theTK, theInter, theNbInt, 1,
-          theNb, aCurPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-        
-        aNbPer--;
-        aCurPer++;
-      }
-      return;
-    }
-    else
-    {
-      // For period with first
-      WriteIntervals(theTK, theInter, theNbInt, anIndex1,
-        theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      
-      Standard_Integer aNbPer = Abs(theLPer - theFPer);
-      Standard_Integer aCurPer = theFPer + 1;
-      while (aNbPer > 1)
-      {
-        theNbIntervals++;
-        WriteIntervals(theTK, theInter, theNbInt, 1,
-          theNb, aCurPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
-
-        aNbPer--;
-        aCurPer++;
-      }
-      // For period with last
-      theNbIntervals++;
-      WriteIntervals(theTK, theInter, theNbInt, 1,
-        anIndex2, theLPer * thePeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
-      return;
-    }
-  }
-}
+    Standard_Integer aDegree = myBSplineCurve->Degree();
+    Standard_Integer aCont;
 
-//=======================================================================
-//function : Intervals
-//purpose  : 
-//=======================================================================
-
-void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
-                                  const GeomAbs_Shape S   ) const
-{
-  Standard_Integer myNbIntervals = 1;
-  Standard_Integer NbSplit;
-  Standard_Real FirstParam = myFirst, LastParam = myLast;
-
-  if (myTypeCurve == GeomAbs_BSplineCurve)
-  {
-    Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
-    Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
-    TColStd_Array1OfInteger Inter(1, LastIndex - FirstIndex + 1);
-    Standard_Boolean aContPer = (S >= Continuity()) && myBSplineCurve->IsPeriodic();
-    Standard_Boolean aContNotPer = (S > Continuity()) && !myBSplineCurve->IsPeriodic();
-
-    if (aContPer || aContNotPer) {
-      Standard_Integer Cont;
-      switch (S) {
-      case GeomAbs_G1:
-      case GeomAbs_G2:
-        throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
-        break;
-      case GeomAbs_C0:
-        myNbIntervals = 1;
-        break;
+    switch (S)
+    {
       case GeomAbs_C1:
+        aCont = 1;
+        break;
       case GeomAbs_C2:
+        aCont = 2;
+        break;
       case GeomAbs_C3:
+        aCont = 3;
+        break;
       case GeomAbs_CN:
-      {
-        if (S == GeomAbs_C1) Cont = 1;
-        else if (S == GeomAbs_C2) Cont = 2;
-        else if (S == GeomAbs_C3) Cont = 3;
-        else                       Cont = myBSplineCurve->Degree();
-        Standard_Integer Degree = myBSplineCurve->Degree();
-        Standard_Integer NbKnots = myBSplineCurve->NbKnots();
-        TColStd_Array1OfInteger Mults(1, NbKnots);
-        myBSplineCurve->Multiplicities(Mults);
-        NbSplit = 1;
-        Standard_Integer Index = FirstIndex;
-        Inter(NbSplit) = Index;
-        Index++;
-        NbSplit++;
-        while (Index < LastIndex)
-        {
-          if (Degree - Mults(Index) < Cont)
-          {
-            Inter(NbSplit) = Index;
-            NbSplit++;
-          }
-          Index++;
-        }
-        Inter(NbSplit) = Index;
-        Standard_Integer NbInt = NbSplit - 1;
-        //        GeomConvert_BSplineCurveKnotSplitting Convector(myBspl, Cont);
-        //        Standard_Integer NbInt = Convector.NbSplits()-1;
-        //        TColStd_Array1OfInteger Inter(1,NbInt+1);
-        //        Convector.Splitting( Inter);
-
-        Standard_Integer Nb = myBSplineCurve->NbKnots();
-        Standard_Integer Index1 = 0;
-        Standard_Integer Index2 = 0;
-        Standard_Real newFirst, newLast;
-        const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
-        const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
-        Standard_Real Eps = Min(Resolution(Precision::Confusion()),
-          Precision::PConfusion());
-
-        if (!myBSplineCurve->IsPeriodic() || ((Abs(myFirst - myBSplineCurve->FirstParameter()) < Eps) &&
-          (Abs(myLast - myBSplineCurve->LastParameter()) < Eps)))
-        {
-          BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myFirst,
-            myBSplineCurve->IsPeriodic(),
-            1, Nb, Index1, newFirst);
-          BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myLast,
-            myBSplineCurve->IsPeriodic(),
-            1, Nb, Index2, newLast);
-          FirstParam = newFirst;
-          LastParam = newLast;
-          // Protection against myFirst = UFirst - eps, which located as ULast - eps
-          if (myBSplineCurve->IsPeriodic() && (LastParam - FirstParam) < Precision::PConfusion())
-          {
-            if (Abs(LastParam - myBSplineCurve->FirstParameter()) < Precision::PConfusion())
-              LastParam += myBSplineCurve->Period();
-            else
-              FirstParam -= myBSplineCurve->Period();
-          }
-          // On decale eventuellement les indices  
-          // On utilise une "petite" tolerance, la resolution ne doit 
-          // servir que pour les tres longue courbes....(PRO9248)
-
-          if (Abs(FirstParam - TK(Index1 + 1)) < Eps) Index1++;
-          if (LastParam - TK(Index2) > Eps) Index2++;
-
-          myNbIntervals = 1;
-
-          TColStd_Array1OfInteger aFinalIntervals(1, Inter.Upper());
-          aFinalIntervals(1) = Index1;
-          for (Standard_Integer i = 1; i <= NbInt; i++) {
-            if (Inter(i) > Index1 && Inter(i) < Index2) {
-              myNbIntervals++;
-              aFinalIntervals(myNbIntervals) = Inter(i);
-            }
-          }
-          aFinalIntervals(myNbIntervals + 1) = Index2;
-
-          for (Standard_Integer I = 1; I <= myNbIntervals + 1; I++) {
-            T(I) = TK(aFinalIntervals(I));
-          }
-        }
-        else
-        {
-          Standard_Real aFirst = myFirst;
-          Standard_Real aLast = myLast;
-
-          Standard_Real aCurFirst = aFirst;
-          Standard_Real aCurLast = aLast;
-
-          Standard_Real aPeriod = myBSplineCurve->Period();
-          Standard_Real aLower = myBSplineCurve->FirstParameter();
-          Standard_Real anUpper = myBSplineCurve->LastParameter();
-
-          Standard_Integer aLPer = 0; Standard_Integer aFPer = 0;
-
-          if (Abs(myFirst - aLower) <= Eps)
-          {
-            aCurFirst = aLower;
-            aFirst = aCurFirst;
-          }
-
-          if (Abs(myLast - anUpper) <= Eps)
-          {
-            aCurLast = anUpper;
-            aLast = aCurLast;
-          }
-
-          if ((Abs(aLower - myFirst) < Eps) && (aCurFirst < aLower))
-          {
-            aCurFirst = aLower;
-          }
-          else
-          {
-            DefinFPeriod(aLower, anUpper,
-              Eps, aPeriod, aCurFirst, aFPer);
-          }
-          DefinLPeriod(aLower, anUpper,
-            Eps, aPeriod, aCurLast, aLPer);
-
-          if (myFirst == aLower)
-          {
-            aFPer = 0;
-          }
-
-          SpreadInt(TK, TM, Inter, myBSplineCurve->Degree(), Nb, aFPer, aLPer, NbInt, aLower, myFirst, myLast, aPeriod,
-            aCurLast, Eps, T, myNbIntervals);
-
-          T(T.Lower()) = aFirst;
-          T(T.Lower() + myNbIntervals) = aLast;
-          return;
-        }
-      }
-      T(T.Lower()) = myFirst;
-      T(T.Lower() + myNbIntervals) = myLast;
-      return;
-      }
+        aCont = aDegree;
+        break;
+      default:
+        throw Standard_DomainError ("GeomAdaptor_Curve::Intervals()");
     }
+
+    Standard_Real anEps = Min(Resolution(Precision::Confusion()), Precision::PConfusion());
+
+    BSplCLib::Intervals(myBSplineCurve->Knots(),
+                        myBSplineCurve->Multiplicities(),
+                        aDegree,
+                        myBSplineCurve->IsPeriodic(),
+                        aCont,
+                        myFirst,
+                        myLast,
+                        anEps,
+                        &T);
   }
 
   else if (myTypeCurve == GeomAbs_OffsetCurve){
+    Standard_Integer myNbIntervals = 1;
     GeomAbs_Shape BaseS=GeomAbs_C0;
     switch(S){
     case GeomAbs_G1:
@@ -1073,8 +398,7 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
     case GeomAbs_C2: BaseS = GeomAbs_C3; break;
     default: BaseS = GeomAbs_CN;
     }
-    GeomAdaptor_Curve C
-      (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve());
+    GeomAdaptor_Curve C (Handle(Geom_OffsetCurve)::DownCast (myCurve)->BasisCurve(), myFirst, myLast);
     // akm 05/04/02 (OCC278)  If our curve is trimmed we must recalculate 
     //                    the array of intervals obtained from the basis to
     //              vvv   reflect parameter bounds
@@ -1090,10 +414,15 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
     // old - myNbIntervals = C.NbIntervals(BaseS);
     // old - C.Intervals(T, BaseS);
     // akm 05/04/02 ^^^
+    T( T.Lower() ) = myFirst;
+    T( T.Lower() + myNbIntervals ) = myLast;
   }
   
-  T( T.Lower() ) = FirstParam;
-  T( T.Lower() + myNbIntervals ) = LastParam;
+  else
+  {
+    T( T.Lower() ) = myFirst;
+    T( T.Lower() + 1 ) = myLast;
+  }
 }
 
 //=======================================================================
diff --git a/tests/bugs/modalg_8/bug33187 b/tests/bugs/modalg_8/bug33187
new file mode 100644 (file)
index 0000000..34b1496
--- /dev/null
@@ -0,0 +1,9 @@
+puts "================================"
+puts "0033187: Modeling Algorithms - Crash in postprocessing of imported shape"
+puts "================================"
+
+restore [locate_data_file bug33187.brep] s
+
+if [catch { fixshape r s } catch_result] {
+  puts "${BugNumber}: Faulty"
+}
index 1b6e75a3cc12573daa3bc75c6dde3eeaf0cb0208..4a5e0ad98fd647868c81961f8801a420301c2161 100644 (file)
@@ -4,7 +4,7 @@ puts "====================================="
 puts ""
 
 set viewname ""
-set length 6.30238
+set length 6.30139
 
 restore [locate_data_file bug27341_hlrsave.brep] a
 COMPUTE_HLR $viewname $algotype
index c116d9dec93e036a3ecb88d490c38577e2e6bb83..39098da4e62ab7e062449c05105a27a04633ccc6 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 8.06872, expected 8.05281"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 7.9487, expected 8.05281"
 
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
index 3e71edfe304d434613bf55bace15ca911ebf3941..804241eb9083efa29740b33ba6d2dd366cca3094 100644 (file)
@@ -4,7 +4,7 @@ puts "====================================="
 puts ""
 
 set viewname "vbottom"
-set length 8.39744
+set length 8.40196
 
 restore [locate_data_file bug27341_hlrsave.brep] a
 COMPUTE_HLR $viewname $algotype
index 72303a8910c27e0a0d0fc56a87e4ed3eb0834578..980d50d0bfec92618c62d438466c03e5592266d1 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 7.44464, expected 7.39488"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 7.4452, expected 7.39488"
 
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
index f276fd4c4dccd07b06ccb1e30b032f134ceca0f1..3423f470fad4255e4e5a3af401f67350cd9231b5 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 9.10542, expected 9.47163"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 9.08401, expected 9.47163"
 
 puts "====================================="
 puts "OCC27341: Incorrect exact HLR results"
index f85f2d0066385fd678b4af1f822e41b8eec6f9cf..f80e6dda0402d8902fda7c130281b2680a0a8c23 100644 (file)
@@ -4,7 +4,7 @@ puts "====================================="
 puts ""
 
 set viewname "vleft"
-set length 7.64599
+set length 7.64618
 
 restore [locate_data_file bug27341_hlrsave.brep] a
 COMPUTE_HLR $viewname $algotype
index dc38a1c33e886efdb500119ded181fe811673aaa..c9f00b1c14f7fcc97234b001758b6916aac64580 100644 (file)
@@ -4,7 +4,7 @@ puts "====================================="
 puts ""
 
 set viewname "vright"
-set length 9.30381
+set length 9.30402
 
 restore [locate_data_file bug27341_hlrsave.brep] a
 COMPUTE_HLR $viewname $algotype