]> OCCT Git - occt-copy.git/commitdiff
Check of extension validity
authornbv <nbv@opencascade.com>
Wed, 24 Jan 2018 08:15:36 +0000 (11:15 +0300)
committernbv <nbv@opencascade.com>
Mon, 10 Dec 2018 15:11:34 +0000 (18:11 +0300)
12 files changed:
src/BRepBndLib/BRepBndLib.cxx
src/BRepLib/BRepLib.cxx
src/BRepTools/BRepTools.cxx
src/BRepTools/BRepTools_NurbsConvertModification.cxx
src/BRepTools/BRepTools_TrsfModification.cxx
src/ChFi3d/ChFi3d_Builder_0.cxx
src/Geom2dConvert/Geom2dConvert.cxx
src/GeomConvert/GeomConvert.cxx
src/GeomLib/GeomLib.cxx
src/GeomLib/GeomLib.hxx
src/GeomProjLib/GeomProjLib.cxx
src/ShapeConstruct/ShapeConstruct.cxx

index db806fafaa861f0988bd533154c37ce9478633bf..dcd99bdcc19bf9c2bd4e2da680530d1a4bef07be 100644 (file)
@@ -39,6 +39,7 @@
 #include <BRepTools.hxx>
 #include <Geom_BSplineSurface.hxx>
 #include <Geom_BezierSurface.hxx>
+#include <GeomLib.hxx>
 #include <Bnd_Box2d.hxx>
 #include <BndLib_Add2dCurve.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
@@ -47,6 +48,8 @@
 #include <Geom_Plane.hxx>
 #include <Extrema_ExtSS.hxx>
 #include <GeomAdaptor_Surface.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+
 //
 static Standard_Boolean CanUseEdges(const Adaptor3d_Surface& BS);
 //
@@ -587,33 +590,33 @@ void FindExactUVBounds(const TopoDS_Face FF,
   Handle(Geom_Surface) aS = BRep_Tool::Surface(FF, aLoc);
   Standard_Real aUmin, aUmax, aVmin, aVmax;
   aS->Bounds(aUmin, aUmax, aVmin, aVmax);
-  if(!aS->IsUPeriodic111())
+  if (!GeomLib::AllowExtendUParameter(aBAS.Surface(), umin, umax))
   {
     umin = Max(aUmin, umin);
     umax = Min(aUmax, umax);
   }
   else
   {
-    if(umax - umin > aS->UPeriod())
+    const Standard_Real aDelta = (umax - umin - aBAS.UPeriod()) / 2.0;
+    if (aBAS.IsUPeriodic222() && (aDelta > 0.0))
     {
-      Standard_Real delta = umax - umin - aS->UPeriod();
-      umin += delta/2.;
-      umax -= delta/2;
+      umin += aDelta;
+      umax -= aDelta;
     }
   }
   //
-  if(!aS->IsVPeriodic111())
+  if (!GeomLib::AllowExtendVParameter(aBAS.Surface(), vmin, vmax))
   {
     vmin = Max(aVmin, vmin);
     vmax = Min(aVmax, vmax);
   }
   else
   {
-    if(vmax - vmin > aS->VPeriod())
+    const Standard_Real aDelta = (vmax - vmin - aS->VPeriod()) / 2.0;
+    if (aBAS.IsVPeriodic222() && (aDelta > 0.0))
     {
-      Standard_Real delta = vmax - vmin - aS->VPeriod();
-      vmin += delta/2.;
-      vmax -= delta/2;
+      vmin += aDelta;
+      vmax -= aDelta;
     }
   }
 }
index 3d69de0859c2b49882fbdcbcc1256406a8a3e2af..bb4ceee26ca421feac48d3a238d119ce249e3717 100644 (file)
@@ -1283,17 +1283,21 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
   Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d();
   GeomAdaptor_Surface& GAS = HS->ChangeSurface(); 
 
-  if (!C3d->IsPeriodic111())
+  if (C3d->IsPeriodic111())
   {
-    Standard_Real Udeb = C3d->FirstParameter();
-    Standard_Real Ufin = C3d->LastParameter();
-    // modified by NIZHNY-OCC486  Tue Aug 27 17:17:14 2002 :
-    //if (Udeb > f3d) f3d = Udeb;
-    //if (l3d > Ufin) l3d = Ufin;
-    if (Udeb > f3d) f3d = Udeb;
-    if (l3d > Ufin) l3d = Ufin;
-    // modified by NIZHNY-OCC486  Tue Aug 27 17:17:55 2002 .
+    // Range of the curve cannot be greater than period.
+    // If it is greater then it must be reduced.
+    const Standard_Real aDelta = Max(l3d - f3d - C3d->Period(), 0.0)/2.0;
+    f3d += aDelta;
+    l3d -= aDelta;
   }
+
+  if (!GeomLib::AllowExtend(*C3d, f3d, l3d))
+  {
+    if (C3d->FirstParameter() > f3d) f3d = C3d->FirstParameter();
+    if (l3d > C3d->LastParameter()) l3d = C3d->LastParameter();
+  }
+
   if(!L3d.IsIdentity()){
     C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L3d.Transformation()));
   }
index 2443649aff7f22999b20860d51b46736e7ae11f8..5df00bcf801105ae3e34adb186d1ffc0c5bde741 100644 (file)
@@ -63,6 +63,7 @@
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
 #include <TopTools_SequenceOfShape.hxx>
+#include <GeomLib.hxx>
 #include <GeomLib_CheckCurveOnSurface.hxx>
 #include <errno.h>
 
@@ -1020,12 +1021,32 @@ Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
   //Set first, last to avoid ErrosStatus = 2 because of 
   //too strong checking of limits in class CheckCurveOnSurface
   //
-  if(!C3d->IsPeriodic111())
+
+  if (C3d->IsPeriodic111())
+  {
+    // Range of the curve cannot be greater than period.
+    // If it is greater then it must be reduced.
+    const Standard_Real aDelta = Max(last - first - C3d->Period(), 0.0)/2.0;
+    first += aDelta;
+    last -= aDelta;
+  }
+
+  if (C2d->IsPeriodic111())
+  {
+    // Range of the curve cannot be greater than period.
+    // If it is greater then it must be reduced.
+    const Standard_Real aDelta = Max(last - first - C2d->Period(), 0.0)/2.0;
+    first += aDelta;
+    last -= aDelta;
+  }
+
+  if (!GeomLib::AllowExtend(*C3d, first, last))
   {
     first = Max(first, C3d->FirstParameter());
     last = Min(last, C3d->LastParameter());
   }
-  if(!C2d->IsPeriodic111())
+
+  if (!GeomLib::AllowExtend(*C2d, first, last))
   {
     first = Max(first, C2d->FirstParameter());
     last = Min(last, C2d->LastParameter());
index 50e8c82ef16fbd4ea69a1ee9a3d03f6381028afa..22eb708bbb138500d0426c20d83372a818ea84cf 100644 (file)
@@ -50,6 +50,7 @@
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomConvert.hxx>
+#include <GeomLib.hxx>
 #include <gp_GTrsf2d.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_TrsfForm.hxx>
@@ -386,11 +387,13 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
       C2d = TC->BasisCurve();
     }
 
-    Standard_Real fc = C2d->FirstParameter(), lc = C2d->LastParameter();
+    const Standard_Real fc = C2d->FirstParameter(), 
+                        lc = C2d->LastParameter();
 
-    if(!C2d->IsPeriodic111()) {
-      if(fc - f2d > Precision::PConfusion()) f2d = fc;
-      if(l2d - lc > Precision::PConfusion()) l2d = lc;
+    if (!GeomLib::AllowExtend(*C2d, f2d, l2d))
+    {
+      if (fc - f2d > Precision::PConfusion()) f2d = fc;
+      if (l2d - lc > Precision::PConfusion()) l2d = lc;
     }
 
     C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
index 1afca5c80ba2aa3bc60ea7a88ab590fa8fcda55e..d6671a599d914989f50824d8cfcfc6407e26d844 100644 (file)
@@ -175,21 +175,22 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d
     NewC = TC->BasisCurve();
   }
 
-  Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter();
+  const Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter();
+  if (!GeomLib::AllowExtend(*NewC, f, l))
+  {
+    if (fc - f > Precision::PConfusion()) f = fc;
+    if (l - lc > Precision::PConfusion()) l = lc;
+  }
 
-  if(!NewC->IsPeriodic111()) {
-    if(fc - f > Precision::PConfusion()) f = fc;
-    if(l - lc > Precision::PConfusion()) l = lc;
-    if(Abs(l - f) < Precision::PConfusion())
+  if (!NewC->IsPeriodic111() && (Abs(l - f) < Precision::PConfusion()))
+  {
+    if (Abs(f - fc) < Precision::PConfusion())
+    {
+      l = lc;
+    }
+    else
     {
-      if(Abs(f - fc) < Precision::PConfusion())
-      {
-        l = lc;
-      }
-      else
-      {
-        f = fc;
-      }
+      f = fc;
     }
   }
 
index 727fe259806ba8cb9ac919e2c7738c84913e038d..15e2e08624c1c3bb94c6922a6b62caac017f3d18 100644 (file)
@@ -617,8 +617,16 @@ void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
   Standard_Real vv1 = vmin - Stepv;
   Standard_Real vv2 = vmax + Stepv;
   if(checknaturalbounds) {
-    if(!S.IsUPeriodic222()) {uu1 = Max(uu1,u1);  uu2 = Min(uu2,u2);}
-    if(!S.IsVPeriodic222()) {vv1 = Max(vv1,v1);  vv2 = Min(vv2,v2);}
+    if (!GeomLib::AllowExtendUParameter(S, uu1, uu2))
+    {
+      uu1 = Max(uu1,u1);
+      uu2 = Min(uu2,u2);
+    }
+    if (!GeomLib::AllowExtendVParameter(S, vv1, vv2))
+    {
+      vv1 = Max(vv1, v1);
+      vv2 = Min(vv2, v2);
+    }
   }
   S.Load(surface,uu1,uu2,vv1,vv2);
 }
index 91ad8630cac3fffc981c9d36ae3923ea074e06f3..4fc6b0910bf0727467642ea665fdbe690cbc5946 100644 (file)
@@ -37,6 +37,7 @@
 #include <Geom2dConvert_ApproxCurve.hxx>
 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
 #include <GeomAbs_Shape.hxx>
+#include <GeomLib.hxx>
 #include <gp.hxx>
 #include <gp_Circ2d.hxx>
 #include <gp_Dir2d.hxx>
@@ -207,13 +208,17 @@ const Convert_ParameterisationType  Parameterisation)
 
     // Si la courbe n'est pas vraiment restreinte, on ne risque pas 
     // le Raise dans le BS->Segment.
-    if (!Curv->IsPeriodic111()) {     
+    // Attention while processing case like:
+    // 1. Curv is a circle with range [0, 2PI], U1 = 3PI/2, U2=5PI/2.
+    // 2. Curv is a circle with range [0, 2PI], U1 = 7PI/2, U2=4PI.
+    if (!GeomLib::AllowExtend(*Curv, U1, U2))
+    {
       if (U1 < Curv->FirstParameter())
-       U1 =  Curv->FirstParameter();
+        U1 = Curv->FirstParameter();
       if (U2 > Curv->LastParameter())
-       U2 = Curv->LastParameter();
-    } 
-    
+        U2 = Curv->LastParameter();
+    }
+
     if (Curv->IsKind(STANDARD_TYPE(Geom2d_Line))) {
       gp_Pnt2d Pdeb = Ctrim->StartPoint();
       gp_Pnt2d Pfin = Ctrim->EndPoint();
index 174a2fe17464c53caab60d788cfe8df97f201540..5eeb8556f36eeb662a988375bad2bd8e411262f9 100644 (file)
@@ -41,6 +41,7 @@
 #include <GeomConvert.hxx>
 #include <GeomConvert_ApproxCurve.hxx>
 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
+#include <GeomLib.hxx>
 #include <GeomLProp.hxx>
 #include <gp.hxx>
 #include <gp_Ax3.hxx>
@@ -194,11 +195,15 @@ Handle(Geom_BSplineCurve)  GeomConvert::CurveToBSplineCurve
 
     // Si la courbe n'est pas vraiment restreinte, on ne risque pas 
     // le Raise dans le BS->Segment.
-    if (!Curv->IsPeriodic111()) {
+    // Attention while processing case like:
+    // 1. Curv is a circle with range [0, 2PI], U1 = 3PI/2, U2=5PI/2.
+    // 2. Curv is a circle with range [0, 2PI], U1 = 7PI/2, U2=4PI.
+    if (!GeomLib::AllowExtend(*Curv, U1, U2))
+    {
       if (U1 < Curv->FirstParameter())
-       U1 =  Curv->FirstParameter();
+        U1 = Curv->FirstParameter();
       if (U2 > Curv->LastParameter())
-       U2 = Curv->LastParameter();
+        U2 = Curv->LastParameter();
     }
 
     if (Curv->IsKind(STANDARD_TYPE(Geom_Line))) {
index 14cb82f7089b0af058e16b9a6e59fdb450cdd833..dbefd0bcbe3c0c04e1670b55b7202d1e0ba89860 100644 (file)
@@ -53,6 +53,7 @@
 #include <CSLib.hxx>
 #include <CSLib_NormalStatus.hxx>
 #include <ElCLib.hxx>
+#include <Extrema_ECC.hxx>
 #include <Geom2d_BezierCurve.hxx>
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_Circle.hxx>
 #include <Geom_Hyperbola.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_OffsetCurve.hxx>
+#include <Geom_OffsetSurface.hxx>
 #include <Geom_Parabola.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomConvert.hxx>
@@ -2744,12 +2747,99 @@ Standard_Boolean GeomLib::IsBzVClosed (const Handle(Geom_BezierSurface)& S,
   return CompareWeightPoles(aPF, 0, aPL, 0, Tol2);
 }
 
+//=======================================================================
+//function : AllowExtendUParameter
+//purpose  : 
+//=======================================================================
+Standard_Boolean GeomLib::AllowExtendUParameter(const GeomAdaptor_Surface& theS,
+                                                const Standard_Real theNewUFirst,
+                                                const Standard_Real theNewULast)
+{
+  const Handle(Geom_Surface) &aSurf = theS.Surface();
+  const Handle(Geom_Curve) aC = aSurf->VIso(theS.FirstVParameter());
+
+  return (AllowExtend(*aC, theNewUFirst, theNewULast));
+}
+
+//=======================================================================
+//function : AllowExtendVParameter
+//purpose  : 
+//=======================================================================
+Standard_Boolean GeomLib::AllowExtendVParameter(const GeomAdaptor_Surface& theS,
+                                                const Standard_Real theNewVFirst,
+                                                const Standard_Real theNewVLast)
+{
+  const GeomAbs_SurfaceType aSType = theS.GetType();
+
+  const Handle(Geom_Surface) &aSurf = theS.Surface();
+
+  if (aSType == GeomAbs_OffsetSurface)
+  {
+    const Handle(Geom_OffsetSurface) aOS = Handle(Geom_OffsetSurface)::DownCast(aSurf);
+    return AllowExtendVParameter(GeomAdaptor_Surface(aOS->BasisSurface()),
+                                 theNewVFirst, theNewVLast);
+  }
+
+  const Handle(Geom_Curve) aC = aSurf->UIso(theS.FirstUParameter());
+
+  if (!AllowExtend(*aC, theNewVFirst, theNewVLast))
+    return Standard_False;
+
+  switch (aSType)
+  {
+    case GeomAbs_OtherSurface:
+      return Standard_True;
+    case GeomAbs_Sphere:
+    {
+      if ((theNewVFirst < -M_PI_2) || (theNewVLast > M_PI_2))
+      {
+        // After extending, the surface isoline will go 
+        // through the sphere pole
+        return Standard_False;
+      }
+      break;
+    }
+    case GeomAbs_SurfaceOfRevolution:
+    {
+      const Handle(Adaptor3d_HCurve) aCurv = theS.BasisCurve();
+      const Handle(Geom_Line) aL = new Geom_Line(theS.AxeOfRevolution());
+      const GeomAdaptor_Curve aLin(aL);
+
+      Extrema_ECC anExtr(aCurv->Curve(), aLin);
+      anExtr.Perform();
+      if (anExtr.IsDone() && anExtr.NbExt() > 0)
+      {
+        const Standard_Real aParF = theNewVFirst - Precision::PConfusion(),
+                            aParL = theNewVLast + Precision::PConfusion();
+        Extrema_POnCurv aP1, aP2;
+        for (Standard_Integer i = 1; i <= anExtr.NbExt(); i++)
+        {
+          if (anExtr.SquareDistance(i) > Precision::SquareConfusion())
+            continue;
+
+          anExtr.Points(i, aP1, aP2);
+          if ((aParF < aP1.Parameter()) && (aP1.Parameter() < aParL))
+          {
+            // After extending, the surface isoline will go 
+            // through the pole (singular point like pole of sphere)
+
+            return Standard_False;
+          }
+        }
+      }
+      break;
+    }
+  }
+
+  return Standard_True;
+}
+
 //=======================================================================
 //function : CompareWeightPoles
 //purpose  : Checks if thePoles1(i)*theW1(i) is equal to thePoles2(i)*theW2(i)
 //            with tolerance theTol.
 //           It is necessary for not rational B-splines and Bezier curves
-//            to set theW1 and theW2 adresses to zero.
+//            to set theW1 and theW2 addresses to zero.
 //=======================================================================
 static Standard_Boolean CompareWeightPoles(const TColgp_Array1OfPnt& thePoles1, 
                                            const TColStd_Array1OfReal* const theW1,
index 9d4cf1984d90c63eb379ec41d31cd5474652ef8f..3b93cfcfb885d0bc122391c5830fcad4d44a2996 100644 (file)
 class Geom_Curve;
 class gp_Ax2;
 class Geom2d_Curve;
+class Geom_Curve;
 class gp_GTrsf2d;
 class Adaptor3d_CurveOnSurface;
+class Adaptor3d_Surface;
+class GeomAdaptor_Surface;
 class Geom_BoundedCurve;
 class gp_Pnt;
 class gp_Vec;
@@ -54,6 +57,8 @@ class GeomLib_Tool;
 class GeomLib_PolyFunc;
 class GeomLib_LogSample;
 
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
 
 //! Geom    Library.    This   package   provides   an
 //! implementation of  functions for basic computation
@@ -207,6 +212,50 @@ public:
     return (theCur->Value(aFPar).SquareDistance(theCur->Value(aLPar)) < theTol*theTol);
   }
 
+  //! Returns TRUE if theCurve will keep its validity for OCCT-algorithms
+  //! after its trimming in range [theNewFPar, theNewLPar].
+  //! This is a template-method. Therefore, it can be applied to 
+  //! 2D- and 3D-curve and to Adaptor-HCurve.
+  template <typename TypeCurve>
+  Standard_EXPORT static Standard_Boolean AllowExtend(const TypeCurve& theCurve,
+                                                      const Standard_Real theNewFPar,
+                                                      const Standard_Real theNewLPar)
+  {
+    Standard_Real aFPar = theCurve.FirstParameter(),
+                  aLPar = theCurve.LastParameter();
+
+    if ((aFPar <= theNewFPar) && (theNewLPar <= aLPar) && (theNewFPar < theNewLPar))
+    {
+      //New boundaries are in the current ones
+      return Standard_True;
+    }
+
+    if (!theCurve.IsPeriodic111())
+    {
+      return Standard_False;
+    }
+
+    const Standard_Real aPeriod = theCurve.Period();
+
+    if ((theNewLPar - theNewFPar - aPeriod) > Epsilon(aPeriod))
+      return Standard_False;
+
+    return Standard_True;
+  }
+
+  //! Returns TRUE if theS will keep its validity for OCCT-algorithms
+  //! after its trimming in range [theNewUFirst, theNewULast] along U-direction
+  Standard_EXPORT static Standard_Boolean 
+                    AllowExtendUParameter(const GeomAdaptor_Surface& theS,
+                                          const Standard_Real theNewUFirst,
+                                          const Standard_Real theNewULast);
+
+  //! Returns TRUE if theS will keep its validity for OCCT-algorithms
+  //! after its trimming in range [theNewVFirst, theNewVLast] along V-direction
+  Standard_EXPORT static Standard_Boolean
+                    AllowExtendVParameter(const GeomAdaptor_Surface& theS,
+                                          const Standard_Real theNewVFirst,
+                                          const Standard_Real theNewVLast);
 
   //! Returns true if the poles of U1 isoline and the poles of
   //! U2 isoline of surface are identical according to tolerance criterion.
index 5e6362089be9685a61a7a7c15b85adb87382172c..601e13d280b036dadb7c886897a49c3a5290b909 100644 (file)
@@ -41,6 +41,7 @@
 #include <GeomAdaptor_HCurve.hxx>
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
+#include <GeomLib.hxx>
 #include <GeomProjLib.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Pln.hxx>
@@ -144,15 +145,17 @@ Handle(Geom2d_Curve) GeomProjLib::Curve2d(const Handle(Geom_Curve)& C,
     return G2dC;
   }
 
-  if ( C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ) {
+  if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+  {
     Standard_Real U1 = C->FirstParameter();
     Standard_Real U2 = C->LastParameter();
-    if (!G2dC->IsPeriodic111())
+    if (!GeomLib::AllowExtend(*G2dC, U1, U2))
     {
       U1 = Max(U1, G2dC->FirstParameter());
       U2 = Min(U2, G2dC->LastParameter());
     }
-    G2dC = new Geom2d_TrimmedCurve( G2dC, U1, U2);
+
+    G2dC = new Geom2d_TrimmedCurve(G2dC, U1, U2);
   }
 
 #ifdef DRAW
index 6bc2fcd8a9f4bd6dd4d1946d1259cbc02d59eafb..48f316edf322c6b388ea93ad04fd6928e40edd60 100644 (file)
@@ -40,6 +40,7 @@
 #include <GeomConvert_ApproxCurve.hxx>
 #include <GeomConvert_ApproxSurface.hxx>
 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
+#include <GeomLib.hxx>
 #include <gp_Pln.hxx>
 #include <gp_Vec.hxx>
 #include <Precision.hxx>
@@ -392,17 +393,18 @@ static inline HCurve GetCurveCopy(const HCurve& curve,
 }
 
 template<class HCurve> 
-static inline void SegmentCurve (HCurve& curve,
-                                 const Standard_Real first,
-                                 const Standard_Real last)
+static inline void SegmentCurve (HCurve& theCurve,
+                                 const Standard_Real theFirst,
+                                 const Standard_Real theLast)
 {
-  if(curve->FirstParameter() < first - Precision::PConfusion() || 
-     curve->LastParameter() > last + Precision::PConfusion()) {
-    if(curve->IsPeriodic111())
-      curve->Segment(first,last);
-    else curve->Segment(Max(curve->FirstParameter(),first),
-                        Min(curve->LastParameter(),last));
-  } 
+  Standard_Real aF = theFirst, aL = theLast;
+  if (!GeomLib::AllowExtend(*theCurve, aF, aL))
+  {
+    aF = Max(theCurve->FirstParameter(), aF);
+    aL = Min(theCurve->LastParameter(), aL);
+  }
+
+  theCurve->Segment(aF, aL);
 }
 
 template<class HPoint>