0028724: Extrema between circle and plane cannot be found
[occt.git] / src / GeomAdaptor / GeomAdaptor_Curve.cxx
index 56e8af3..112a3eb 100644 (file)
@@ -77,18 +77,15 @@ GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
      const 
 {
   Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
-  Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-  Standard_Integer Nb = aBspl->NbKnots();
+  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);
-  aBspl->Knots(TK);
-  aBspl->Multiplicities(TM);
-  BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,U1,aBspl->IsPeriodic(),
+  const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+  const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
+  BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(),
                            1,Nb,Index1,newFirst);
-  BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,U2,aBspl->IsPeriodic(),
+  BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(),
                            1,Nb,Index2,newLast);
   if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) { 
     if (Index1 < Nb) Index1++;
@@ -97,7 +94,7 @@ GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
     Index2--;
   Standard_Integer MultMax;
   // attention aux courbes peridiques.
-  if ( (aBspl->IsPeriodic()) && (Index1 == Nb) )
+  if ( (myBSplineCurve->IsPeriodic()) && (Index1 == Nb) )
     Index1 = 1;
 
   if ( Index2 - Index1 <= 0) {
@@ -108,7 +105,7 @@ GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
     for(Standard_Integer i = Index1+1;i<=Index2;i++) {
       if ( TM(i)>MultMax) MultMax=TM(i);
     }
-    MultMax = aBspl->Degree() - MultMax;
+    MultMax = myBSplineCurve->Degree() - MultMax;
   }
   if ( MultMax <= 0) {
     return GeomAbs_C0;
@@ -139,12 +136,13 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
 {
   myFirst = UFirst;
   myLast  = ULast;
+  myCurveCache.Nullify();
 
   if ( myCurve != C) {
     myCurve = C;
-    myCurveCache = Handle(BSplCLib_Cache)();
-    myNestedEvaluator = Handle(GeomEvaluator_Curve)();
-
+    myNestedEvaluator.Nullify();
+    myBSplineCurve.Nullify();
+    
     const Handle(Standard_Type)& TheType = C->DynamicType();
     if ( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) {
       Load(Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve(),UFirst,ULast);
@@ -166,19 +164,10 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
     }
     else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
       myTypeCurve = GeomAbs_BezierCurve;
-      // Create cache for Bezier
-      Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
-      Standard_Integer aDeg = aBezier->Degree();
-      TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
-      myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
-          aBezier->Poles(), aBezier->Weights());
     }
     else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
       myTypeCurve = GeomAbs_BSplineCurve;
-      // Create cache for B-spline
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(),
-          aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights());
+      myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve);
     }
     else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
       myTypeCurve = GeomAbs_OffsetCurve;
@@ -193,7 +182,7 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
       myTypeCurve = GeomAbs_OtherCurve;
     }
   }
-}  
+}
 
 //    --
 //    --     Global methods - Apply to the whole curve.
@@ -222,11 +211,11 @@ GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
       case GeomAbs_G1: return GeomAbs_G1;
       case GeomAbs_G2: return GeomAbs_G2;
       default:
-        Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
+        throw Standard_NoSuchObject("GeomAdaptor_Curve::Continuity");
     }
   }
   else if (myTypeCurve == GeomAbs_OtherCurve) {
-    Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Contunuity");
+    throw Standard_NoSuchObject("GeomAdaptor_Curve::Contunuity");
   }
 
   return GeomAbs_CN;
@@ -242,16 +231,15 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
   Standard_Integer myNbIntervals = 1;
   Standard_Integer NbSplit;
   if (myTypeCurve == GeomAbs_BSplineCurve) {
-    Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-    Standard_Integer FirstIndex = aBspl->FirstUKnotIndex();
-    Standard_Integer LastIndex  = aBspl->LastUKnotIndex();
+    Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
+    Standard_Integer LastIndex  = myBSplineCurve->LastUKnotIndex();
     TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
     if ( S > Continuity()) {
       Standard_Integer Cont;
       switch ( S) {
       case GeomAbs_G1:
       case GeomAbs_G2:
-        Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
+        throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
         break;
       case GeomAbs_C0:
         myNbIntervals = 1;
@@ -264,11 +252,11 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
           if      ( S == GeomAbs_C1) Cont = 1;
           else if ( S == GeomAbs_C2) Cont = 2;
           else if ( S == GeomAbs_C3) Cont = 3;
-          else                       Cont = aBspl->Degree();
-          Standard_Integer Degree = aBspl->Degree();
-          Standard_Integer NbKnots = aBspl->NbKnots();
+          else                       Cont = myBSplineCurve->Degree();
+          Standard_Integer Degree = myBSplineCurve->Degree();
+          Standard_Integer NbKnots = myBSplineCurve->NbKnots();
           TColStd_Array1OfInteger Mults (1, NbKnots);
-          aBspl->Multiplicities (Mults);
+          myBSplineCurve->Multiplicities (Mults);
           NbSplit = 1;
           Standard_Integer Index   = FirstIndex;
           Inter (NbSplit) = Index;
@@ -287,19 +275,17 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
 
           Standard_Integer NbInt = NbSplit-1;
           
-          Standard_Integer Nb = aBspl->NbKnots();
+          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);
-          aBspl->Knots(TK);
-          aBspl->Multiplicities(TM);
-          BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myFirst,
-                                    aBspl->IsPeriodic(),
+          const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+          const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
+          BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
+                                    myBSplineCurve->IsPeriodic(),
                                     1,Nb,Index1,newFirst);
-          BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myLast,
-                                    aBspl->IsPeriodic(),
+          BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
+                                    myBSplineCurve->IsPeriodic(),
                                     1,Nb,Index2,newLast);
 
           // On decale eventuellement les indices  
@@ -324,7 +310,7 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
     switch(S){
     case GeomAbs_G1:
     case GeomAbs_G2:
-      Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
+      throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
       break;
     case GeomAbs_C0: BaseS = GeomAbs_C1; break;
     case GeomAbs_C1: BaseS = GeomAbs_C2; break;
@@ -364,9 +350,8 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
 
   if (myTypeCurve == GeomAbs_BSplineCurve) 
     {
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      Standard_Integer FirstIndex = aBspl->FirstUKnotIndex();
-      Standard_Integer LastIndex  = aBspl->LastUKnotIndex();
+      Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
+      Standard_Integer LastIndex  = myBSplineCurve->LastUKnotIndex();
       TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
       
       if ( S > Continuity()) {
@@ -374,7 +359,7 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
        switch ( S) {
        case GeomAbs_G1:
        case GeomAbs_G2:
-         Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
+         throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
          break;
        case GeomAbs_C0:
          myNbIntervals = 1;
@@ -387,11 +372,11 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
            if      ( S == GeomAbs_C1) Cont = 1;
            else if ( S == GeomAbs_C2) Cont = 2;
            else if ( S == GeomAbs_C3) Cont = 3;
-           else                       Cont = aBspl->Degree();
-           Standard_Integer Degree = aBspl->Degree();
-           Standard_Integer NbKnots = aBspl->NbKnots();
+           else                       Cont = myBSplineCurve->Degree();
+           Standard_Integer Degree = myBSplineCurve->Degree();
+           Standard_Integer NbKnots = myBSplineCurve->NbKnots();
            TColStd_Array1OfInteger Mults (1, NbKnots);
-           aBspl->Multiplicities (Mults);
+           myBSplineCurve->Multiplicities (Mults);
            NbSplit = 1;
            Standard_Integer Index   = FirstIndex;
            Inter (NbSplit) = Index;
@@ -413,19 +398,17 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
            //        TColStd_Array1OfInteger Inter(1,NbInt+1);
            //        Convector.Splitting( Inter);
            
-           Standard_Integer Nb = aBspl->NbKnots();
+           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);
-           aBspl->Knots(TK);
-           aBspl->Multiplicities(TM);
-           BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myFirst,
-                                     aBspl->IsPeriodic(),
+            const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+            const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
+           BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
+                                     myBSplineCurve->IsPeriodic(),
                                      1,Nb,Index1,newFirst);
-           BSplCLib::LocateParameter(aBspl->Degree(),TK,TM,myLast,
-                                     aBspl->IsPeriodic(),
+           BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
+                                     myBSplineCurve->IsPeriodic(),
                                      1,Nb,Index2,newLast);
             FirstParam = newFirst;
             LastParam = newLast;
@@ -461,7 +444,7 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
     switch(S){
     case GeomAbs_G1:
     case GeomAbs_G2:
-      Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
+      throw Standard_DomainError("GeomAdaptor_Curve::NbIntervals");
       break;
     case GeomAbs_C0: BaseS = GeomAbs_C1; break;
     case GeomAbs_C1: BaseS = GeomAbs_C2; break;
@@ -528,7 +511,7 @@ Standard_Boolean GeomAdaptor_Curve::IsClosed() const
 
 Standard_Boolean GeomAdaptor_Curve::IsPeriodic() const 
 {
-  return (myCurve->IsPeriodic()? IsClosed() : Standard_False);
+  return myCurve->IsPeriodic();
 }
 
 //=======================================================================
@@ -549,19 +532,26 @@ void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
 {
   if (myTypeCurve == GeomAbs_BezierCurve)
   {
+    // Create cache for Bezier
     Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
     Standard_Integer aDeg = aBezier->Degree();
     TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
+    if (myCurveCache.IsNull())
+      myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
+        aBezier->Poles(), aBezier->Weights());
     myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
         aBezier->Poles(), aBezier->Weights());
-  }
+}
   else if (myTypeCurve == GeomAbs_BSplineCurve)
-  {
-    Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-    myCurveCache->BuildCache(theParameter, aBspl->Degree(),
-        aBspl->IsPeriodic(), aBspl->KnotSequence(),
-        aBspl->Poles(), aBspl->Weights());
-  }
+{
+    // Create cache for B-spline
+    if (myCurveCache.IsNull())
+      myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
+        myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
+    myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(),
+        myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(),
+        myBSplineCurve->Poles(), myBSplineCurve->Weights());
+}
 }
 
 //=======================================================================
@@ -572,12 +562,11 @@ Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
                                                Standard_Integer& theSpanStart,
                                                Standard_Integer& theSpanFinish) const
 {
-  Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-  if (!aBspl.IsNull() && (theU == myFirst || theU == myLast))
+  if (!myBSplineCurve.IsNull() && (theU == myFirst || theU == myLast))
   {
     if (theU == myFirst)
     {
-      aBspl->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
+      myBSplineCurve->LocateU(myFirst, PosTol, theSpanStart, theSpanFinish);
       if (theSpanStart < 1)
         theSpanStart = 1;
       if (theSpanStart >= theSpanFinish)
@@ -585,16 +574,16 @@ Standard_Boolean GeomAdaptor_Curve::IsBoundary(const Standard_Real theU,
     }
     else if (theU == myLast)
     {
-      aBspl->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
-      if (theSpanFinish > aBspl->NbKnots())
-        theSpanFinish = aBspl->NbKnots();
+      myBSplineCurve->LocateU(myLast, PosTol, theSpanStart, theSpanFinish);
+      if (theSpanFinish > myBSplineCurve->NbKnots())
+        theSpanFinish = myBSplineCurve->NbKnots();
       if (theSpanStart >= theSpanFinish)
         theSpanStart = theSpanFinish - 1;
     }
     return Standard_True;
   }
   return Standard_False;
-}
+  }
 
 //=======================================================================
 //function : Value
@@ -616,26 +605,24 @@ gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
 void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
 {
   switch (myTypeCurve)
-  {
+{
   case GeomAbs_BezierCurve:
   case GeomAbs_BSplineCurve:
   {
     Standard_Integer aStart = 0, aFinish = 0;
     if (IsBoundary(U, aStart, aFinish))
     {
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      aBspl->LocalD0(U, aStart, aFinish, P);
+      myBSplineCurve->LocalD0(U, aStart, aFinish, P);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
-    {
-      if (!myCurveCache->IsCacheValid(U))
+    else
+  {
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D0(U, P);
-    }
-    else
-      myCurve->D0(U, P);
-    break;
   }
+    break;
+}
 
   case GeomAbs_OffsetCurve:
     myNestedEvaluator->D0(U, P);
@@ -643,7 +630,7 @@ void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
 
   default:
     myCurve->D0(U, P);
-  }
+}
 }
 
 //=======================================================================
@@ -654,26 +641,24 @@ void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
 void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const 
 {
   switch (myTypeCurve)
-  {
+{
   case GeomAbs_BezierCurve:
   case GeomAbs_BSplineCurve:
   {
     Standard_Integer aStart = 0, aFinish = 0;
     if (IsBoundary(U, aStart, aFinish))
     {
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      aBspl->LocalD1(U, aStart, aFinish, P, V);
+      myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
-    {
-      if (!myCurveCache->IsCacheValid(U))
+    else
+  {
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D1(U, P, V);
-    }
-    else
-      myCurve->D1(U, P, V);
-    break;
   }
+    break;
+}
 
   case GeomAbs_OffsetCurve:
     myNestedEvaluator->D1(U, P, V);
@@ -681,7 +666,7 @@ void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
 
   default:
     myCurve->D1(U, P, V);
-  }
+}
 }
 
 //=======================================================================
@@ -693,26 +678,24 @@ void GeomAdaptor_Curve::D2(const Standard_Real U,
                            gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const 
 {
   switch (myTypeCurve)
-  {
+{
   case GeomAbs_BezierCurve:
   case GeomAbs_BSplineCurve:
   {
     Standard_Integer aStart = 0, aFinish = 0;
     if (IsBoundary(U, aStart, aFinish))
     {
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      aBspl->LocalD2(U, aStart, aFinish, P, V1, V2);
+      myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
-    {
-      if (!myCurveCache->IsCacheValid(U))
+    else
+  {
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D2(U, P, V1, V2);
-    }
-    else
-      myCurve->D2(U, P, V1, V2);
-    break;
   }
+    break;
+}
 
   case GeomAbs_OffsetCurve:
     myNestedEvaluator->D2(U, P, V1, V2);
@@ -720,7 +703,7 @@ void GeomAdaptor_Curve::D2(const Standard_Real U,
 
   default:
     myCurve->D2(U, P, V1, V2);
-  }
+}
 }
 
 //=======================================================================
@@ -733,26 +716,24 @@ void GeomAdaptor_Curve::D3(const Standard_Real U,
                            gp_Vec& V2, gp_Vec& V3) const 
 {
   switch (myTypeCurve)
-  {
+{
   case GeomAbs_BezierCurve:
   case GeomAbs_BSplineCurve:
   {
     Standard_Integer aStart = 0, aFinish = 0;
     if (IsBoundary(U, aStart, aFinish))
     {
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      aBspl->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
+      myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
-    {
-      if (!myCurveCache->IsCacheValid(U))
+    else
+  {
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D3(U, P, V1, V2, V3);
-    }
-    else
-      myCurve->D3(U, P, V1, V2, V3);
-    break;
   }
+    break;
+}
 
   case GeomAbs_OffsetCurve:
     myNestedEvaluator->D3(U, P, V1, V2, V3);
@@ -760,7 +741,7 @@ void GeomAdaptor_Curve::D3(const Standard_Real U,
 
   default:
     myCurve->D3(U, P, V1, V2, V3);
-  }
+}
 }
 
 //=======================================================================
@@ -772,20 +753,19 @@ gp_Vec GeomAdaptor_Curve::DN(const Standard_Real    U,
                              const Standard_Integer N) const 
 {
   switch (myTypeCurve)
-  {
+{
   case GeomAbs_BezierCurve:
   case GeomAbs_BSplineCurve:
   {
     Standard_Integer aStart = 0, aFinish = 0;
     if (IsBoundary(U, aStart, aFinish))
     {
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      return aBspl->LocalDN(U, aStart, aFinish, N);
+      return myBSplineCurve->LocalDN(U, aStart, aFinish, N);
     }
     else
-      return myCurve->DN(U, N);
+  return myCurve->DN( U, N);
     break;
-  }
+}
 
   case GeomAbs_OffsetCurve:
     return myNestedEvaluator->DN(U, N);
@@ -824,7 +804,7 @@ Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
   }
   case GeomAbs_BSplineCurve: {
     Standard_Real res;
-    Handle(Geom_BSplineCurve)::DownCast (myCurve)->Resolution(R3D,res);
+    myBSplineCurve->Resolution(R3D,res);
     return res;
   }
   default:
@@ -845,7 +825,8 @@ Standard_Real GeomAdaptor_Curve::Resolution(const Standard_Real R3D) const
 
 gp_Lin GeomAdaptor_Curve::Line() const 
 {
-  Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, "");
+  Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Line,
+                                  "GeomAdaptor_Curve::Line() - curve is not a Line");
   return Handle(Geom_Line)::DownCast (myCurve)->Lin();  
 }
 
@@ -856,7 +837,8 @@ gp_Lin GeomAdaptor_Curve::Line() const
 
 gp_Circ  GeomAdaptor_Curve::Circle() const 
 {
-  Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, "");
+  Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Circle,
+                                  "GeomAdaptor_Curve::Circle() - curve is not a Circle");
   return Handle(Geom_Circle)::DownCast (myCurve)->Circ();
 }
 
@@ -867,7 +849,8 @@ gp_Circ  GeomAdaptor_Curve::Circle() const
 
 gp_Elips GeomAdaptor_Curve::Ellipse() const 
 {
-  Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, "");
+  Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Ellipse,
+                                  "GeomAdaptor_Curve::Ellipse() - curve is not an Ellipse");
   return Handle(Geom_Ellipse)::DownCast (myCurve)->Elips();
 }
 
@@ -878,7 +861,8 @@ gp_Elips GeomAdaptor_Curve::Ellipse() const
 
 gp_Hypr GeomAdaptor_Curve::Hyperbola() const 
 {
-  Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, "");
+  Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Hyperbola,
+                                  "GeomAdaptor_Curve::Hyperbola() - curve is not a Hyperbola");
   return Handle(Geom_Hyperbola)::DownCast (myCurve)->Hypr();  
 }
 
@@ -889,7 +873,8 @@ gp_Hypr GeomAdaptor_Curve::Hyperbola() const
 
 gp_Parab GeomAdaptor_Curve::Parabola() const 
 {
-  Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, "");
+  Standard_NoSuchObject_Raise_if (myTypeCurve != GeomAbs_Parabola,
+                                  "GeomAdaptor_Curve::Parabola() - curve is not a Parabola");
   return Handle(Geom_Parabola)::DownCast (myCurve)->Parab();
 }
 
@@ -903,11 +888,9 @@ Standard_Integer GeomAdaptor_Curve::Degree() const
   if (myTypeCurve == GeomAbs_BezierCurve)
     return Handle(Geom_BezierCurve)::DownCast (myCurve)->Degree();
   else if (myTypeCurve == GeomAbs_BSplineCurve)
-    return Handle(Geom_BSplineCurve)::DownCast (myCurve)->Degree();
+    return myBSplineCurve->Degree();
   else
-    Standard_NoSuchObject::Raise();
-  // portage WNT 
-  return 0;
+    throw Standard_NoSuchObject();
 }
 
 //=======================================================================
@@ -918,7 +901,7 @@ Standard_Integer GeomAdaptor_Curve::Degree() const
 Standard_Boolean GeomAdaptor_Curve::IsRational() const {
   switch( myTypeCurve) {
   case GeomAbs_BSplineCurve:
-    return Handle(Geom_BSplineCurve)::DownCast (myCurve)->IsRational();
+    return myBSplineCurve->IsRational();
   case GeomAbs_BezierCurve:
     return Handle(Geom_BezierCurve)::DownCast (myCurve)->IsRational();
   default:
@@ -936,11 +919,9 @@ Standard_Integer GeomAdaptor_Curve::NbPoles() const
   if (myTypeCurve == GeomAbs_BezierCurve)
     return Handle(Geom_BezierCurve)::DownCast (myCurve)->NbPoles();
   else if (myTypeCurve == GeomAbs_BSplineCurve)
-    return Handle(Geom_BSplineCurve)::DownCast (myCurve)->NbPoles();
+    return myBSplineCurve->NbPoles();
   else
-    Standard_NoSuchObject::Raise();
-  // portage WNT
-  return 0;
+    throw Standard_NoSuchObject();
 }
 
 //=======================================================================
@@ -951,8 +932,8 @@ Standard_Integer GeomAdaptor_Curve::NbPoles() const
 Standard_Integer GeomAdaptor_Curve::NbKnots() const
 {
   if ( myTypeCurve != GeomAbs_BSplineCurve)
-    Standard_NoSuchObject::Raise("GeomAdaptor_Curve::NbKnots");
-  return Handle(Geom_BSplineCurve)::DownCast (myCurve)->NbKnots();
+    throw Standard_NoSuchObject("GeomAdaptor_Curve::NbKnots");
+  return myBSplineCurve->NbKnots();
 }
 
 //=======================================================================
@@ -963,7 +944,7 @@ Standard_Integer GeomAdaptor_Curve::NbKnots() const
 Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const 
 {
  if ( myTypeCurve != GeomAbs_BezierCurve)
-    Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Bezier");
+    throw Standard_NoSuchObject("GeomAdaptor_Curve::Bezier");
   return Handle(Geom_BezierCurve)::DownCast (myCurve);
 }
 
@@ -975,7 +956,19 @@ Handle(Geom_BezierCurve) GeomAdaptor_Curve::Bezier() const
 Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const 
 {
  if ( myTypeCurve != GeomAbs_BSplineCurve)
-    Standard_NoSuchObject::Raise("GeomAdaptor_Curve::BSpline");
+    throw Standard_NoSuchObject("GeomAdaptor_Curve::BSpline");
 
-  return Handle(Geom_BSplineCurve)::DownCast (myCurve);
+  return myBSplineCurve;
+}
+
+//=======================================================================
+//function : BasisCurve
+//purpose  : 
+//=======================================================================
+
+Handle(Geom_OffsetCurve) GeomAdaptor_Curve::OffsetCurve() const
+{
+  if ( myTypeCurve != GeomAbs_OffsetCurve)
+    throw Standard_NoSuchObject("GeomAdaptor_Curve::OffsetCurve");
+  return Handle(Geom_OffsetCurve)::DownCast(myCurve);
 }