0025124: [Feature request] Removal of continuity checks for offset geometries
authornbv <nbv@opencascade.com>
Wed, 10 Dec 2014 13:18:05 +0000 (16:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Dec 2014 13:38:14 +0000 (16:38 +0300)
Sometimes curve or surface, which is defined as C0, has continuity G1 or above. Offset can be built from these shapes.
Therefore, this extended checking was added into SetBasisCurve and SetBasisSurface methods.

Main changes in function BRepOffset_Tool::ExtentFace(...):
*  "return" is added if intersection (in 2D-space) between two edges in a face cannot be found.

Basis curve/surface continuity value found (if G1-checking is OK) is set up as BasisContinuity (see myBasisCurveContinuity and myBasisSurfContinuity members which is returned by GetBasisCurveContinuity and GetBasisSurfContinuity() methods). This fact is used in Geom2dAdaptor and in GeomAdaptor classes.

Possibility is entered, which allows for basis elements of offset curve/surface to avoid of C0-checking.

Test cases were changed according to their new behavior.

Test-cases for issue #25124

33 files changed:
src/BRepFill/BRepFill_OffsetWire.cxx
src/BRepOffset/BRepOffset_Inter3d.cxx
src/BRepOffset/BRepOffset_Tool.cxx
src/BSplCLib/BSplCLib.cxx
src/Geom/Geom_BSplineCurve.cdl
src/Geom/Geom_BSplineCurve_1.cxx
src/Geom/Geom_OffsetCurve.cdl
src/Geom/Geom_OffsetCurve.cxx
src/Geom/Geom_OffsetSurface.cdl
src/Geom/Geom_OffsetSurface.cxx
src/Geom/Geom_OsculatingSurface.cxx
src/Geom2d/Geom2d_BSplineCurve.cdl
src/Geom2d/Geom2d_BSplineCurve_1.cxx
src/Geom2d/Geom2d_OffsetCurve.cdl
src/Geom2d/Geom2d_OffsetCurve.cxx
src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx
src/GeomAdaptor/GeomAdaptor_Curve.cxx
tests/bugs/modalg_5/bug25124_1 [new file with mode: 0644]
tests/bugs/modalg_5/bug25124_2 [new file with mode: 0644]
tests/bugs/modalg_5/bug25124_3 [new file with mode: 0644]
tests/bugs/modalg_5/bug25124_4 [new file with mode: 0644]
tests/bugs/modalg_5/bug25124_5 [new file with mode: 0644]
tests/bugs/modalg_5/bug25124_6 [new file with mode: 0644]
tests/bugs/modalg_5/bug25124_7 [new file with mode: 0644]
tests/offset/wire_unclosed_outside_0_005/B3
tests/offset/wire_unclosed_outside_0_005/B4
tests/offset/wire_unclosed_outside_0_005/B6
tests/offset/wire_unclosed_outside_0_025/B2
tests/offset/wire_unclosed_outside_0_025/B4
tests/offset/wire_unclosed_outside_0_025/B6
tests/offset/wire_unclosed_outside_0_075/B1
tests/offset/wire_unclosed_outside_0_075/B2
tests/offset/wire_unclosed_outside_0_075/B6

index 2806ec1..efd39b4 100644 (file)
@@ -217,26 +217,6 @@ static void MakeOffset
  const Standard_Boolean                      IsOpenResult,
  const TopoDS_Vertex *                       Ends);
 
-
-
-//=======================================================================
-//function : CheckFace
-//purpose  : Check if face contains an edge with C0 continuity
-//=======================================================================
-//
-static void CheckFace(const TopoDS_Face& theFace)
-  {
-  TopExp_Explorer ex(theFace,TopAbs_EDGE);
-  for(; ex.More(); ex.Next())
-    {
-    TopoDS_Edge anEdge=TopoDS::Edge(ex.Current());
-    Standard_Real f,l;
-    const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(anEdge,theFace,f,l);
-    if (C->Continuity() == GeomAbs_C0)
-      Standard_ConstructionError::Raise("Initial shape contains an edge with C0 continuity");
-    }
-  }
-
 //=======================================================================
 //function : KPartCircle
 //purpose  : 
@@ -368,9 +348,6 @@ void BRepFill_OffsetWire::Init(const TopoDS_Face&     Spine,
 //  mySpine    = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
   myJoinType = Join;
   myIsOpenResult = IsOpenResult;
-
-  CheckFace(mySpine);
-  
   myMap.Clear();
   myMapSpine.Clear();
   //------------------------------------------------------------------
index 9268669..334d800 100644 (file)
@@ -768,7 +768,22 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
       //---------------------------------------------------
       const TopoDS_Shape SI = Analyse.Ancestors(E).First();
       OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
-      OE  = TopoDS::Edge(InitOffsetEdge.Image(E).First());      
+      OE  = TopoDS::Edge(InitOffsetEdge.Image(E).First());     
+
+      {
+        //Check if OE has pcurve in CF
+
+        Standard_Real   f,l;
+
+        Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
+        Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); 
+
+        if(C1.IsNull() || C2.IsNull())
+        {
+          continue;
+        }
+      }
+
       //--------------------------------------------------
       // MAJ of OE on cap CF.
       //--------------------------------------------------
@@ -804,6 +819,21 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
            //-------------------------------------------------
            OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
            OE  = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
+
+      {
+        //Check if OE has pcurve in CF and OF1
+
+        Standard_Real   f,l;
+
+        Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
+        Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); 
+
+        if(C1.IsNull() || C2.IsNull())
+        {
+          continue;
+        }
+      }
+
            //--------------------------------------------------
            // MAj of OE on cap CF.
            //--------------------------------------------------
index a862d7a..66c80a0 100644 (file)
@@ -3610,101 +3610,135 @@ void BRepOffset_Tool::ExtentFace (const TopoDS_Face&            F,
     TopoDS_Edge          ERef;
     TopoDS_Vertex        V1,V2;
 
-    for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-        exp2.More(); exp2.Next()) {
+    for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next())
+    {
       const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
       TopExp::Vertices (E,V1,V2);
       BRep_Tool::Range (E,f,l);
       TopoDS_Vertex V;
-      if (Build.IsBound(E)) {
-       const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
-       if (Build.IsBound(NEOnV1) && 
-           (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) {
-         if (E.IsSame(NEOnV1)) 
-           V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
-         else {
-           //---------------
-           // intersection.
-           //---------------
-           if (!Build.IsBound(V1)) {
-             Inter2d (EF,TopoDS::Edge(Build(E)),
-                      TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
-             if (Build(E).Orientation() == TopAbs_FORWARD) {
-               V = TopoDS::Vertex(LV.First());
-             }
-             else {
-               V = TopoDS::Vertex(LV.Last());
-             }
-           }
-           else {
-             V = TopoDS::Vertex(Build(V1));
-             if (MVE (V1).Extent() > 2) {
-               V.Orientation(TopAbs_FORWARD);
-               if (Build(E).Orientation() == TopAbs_REVERSED)
-                 V.Orientation(TopAbs_REVERSED);
-               ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
-             }
-           }
-         }
-       }
-       else {
-         //------------
-         //projection
-         //------------
-         V = V1;
-         if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
-         V.Orientation(TopAbs_FORWARD);
-         if (Build(E).Orientation() == TopAbs_REVERSED)
-           V.Orientation(TopAbs_REVERSED);
-         if (!TryParameter    (E,V,TopoDS::Edge(Build(E)),TolConf))
-           ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
-       }
-       ConstShapes.Bind(V1,V);
-       Build.Bind      (V1,V);
-       const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
-       if (Build.IsBound(NEOnV2) && 
-           (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) {
-         if (E.IsSame(NEOnV2)) 
-           V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
-         else {
-           //--------------
-           // intersection.
-           //---------------
-           if (!Build.IsBound(V2)) {
-             Inter2d (EF,TopoDS::Edge(Build(E)),
-                      TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
-             if (Build(E).Orientation() == TopAbs_FORWARD) {
-               V = TopoDS::Vertex(LV.Last());
-             }
-             else {
-               V = TopoDS::Vertex(LV.First());
-             }
-           }
-           else {
-             V = TopoDS::Vertex(Build(V2));
-             if (MVE (V2).Extent() > 2) {
-               V.Orientation(TopAbs_REVERSED);
-               if (Build(E).Orientation() == TopAbs_REVERSED)
-                 V.Orientation(TopAbs_FORWARD);
-               ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
-             }
-           }
-         }
-       }
-       else {
-         //------------
-         //projection
-         //------------
-         V = V2;
-         if (ConstShapes.IsBound(V2))  V = TopoDS::Vertex(ConstShapes(V2));
-         V.Orientation(TopAbs_REVERSED);       
-         if (Build(E).Orientation() == TopAbs_REVERSED)
-           V.Orientation(TopAbs_FORWARD);
-         if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
-           ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
-       }
-       ConstShapes.Bind(V2,V);
-       Build.Bind(V2,V);
+      if (Build.IsBound(E))
+      {
+        const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
+        if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1)))
+        {
+          if (E.IsSame(NEOnV1))
+            V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
+          else
+          {
+            //---------------
+            // intersection.
+            //---------------
+            if (!Build.IsBound(V1))
+            {
+              Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
+              
+              if(!LV.IsEmpty())
+              {
+                if (Build(E).Orientation() == TopAbs_FORWARD)
+                {
+                  V = TopoDS::Vertex(LV.First());
+                }
+                else
+                {
+                  V = TopoDS::Vertex(LV.Last());
+                }
+              }
+              else
+              {
+                return;
+              }
+            }
+            else
+            {
+              V = TopoDS::Vertex(Build(V1));
+              if (MVE (V1).Extent() > 2)
+              {
+                V.Orientation(TopAbs_FORWARD);
+                if (Build(E).Orientation() == TopAbs_REVERSED)
+                  V.Orientation(TopAbs_REVERSED);
+
+                ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
+              }
+            }
+          }
+        }
+        else
+        {
+          //------------
+          //projection
+          //------------
+          V = V1;
+          if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
+          V.Orientation(TopAbs_FORWARD);
+          if (Build(E).Orientation() == TopAbs_REVERSED)
+            V.Orientation(TopAbs_REVERSED);
+          if (!TryParameter    (E,V,TopoDS::Edge(Build(E)),TolConf))
+            ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
+        }
+
+        ConstShapes.Bind(V1,V);
+        Build.Bind      (V1,V);
+        const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
+        if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2)))
+        {
+          if (E.IsSame(NEOnV2))
+            V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
+          else
+          {
+            //--------------
+            // intersection.
+            //---------------
+
+            if (!Build.IsBound(V2))
+            {
+              Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
+
+              if(!LV.IsEmpty())
+              {
+                if (Build(E).Orientation() == TopAbs_FORWARD)
+                {
+                  V = TopoDS::Vertex(LV.Last());
+                }
+                else
+                {
+                  V = TopoDS::Vertex(LV.First());
+                }
+              }
+              else
+              {
+                return;
+              }
+            }
+            else
+            {
+              V = TopoDS::Vertex(Build(V2));
+              if (MVE (V2).Extent() > 2)
+              {
+                V.Orientation(TopAbs_REVERSED);
+                if (Build(E).Orientation() == TopAbs_REVERSED)
+                  V.Orientation(TopAbs_FORWARD);
+
+                ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
+              }
+            }
+          }
+        }
+        else
+        {
+          //------------
+          //projection
+          //------------
+          V = V2;
+          if (ConstShapes.IsBound(V2))
+            V = TopoDS::Vertex(ConstShapes(V2));
+          V.Orientation(TopAbs_REVERSED);      
+          if (Build(E).Orientation() == TopAbs_REVERSED)
+            V.Orientation(TopAbs_FORWARD);
+          if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
+            ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
+        }
+        ConstShapes.Bind(V2,V);
+        Build.Bind(V2,V);
       }
     }
     
index 683e4ab..e53a28d 100644 (file)
@@ -1175,7 +1175,8 @@ void  BSplCLib::Bohm(const Standard_Real U,
       
       for (j = Degm1; j >= i; j--) {
        jDmi--;
-       *pole -= *tbis; *pole /= (knot[jDmi] - knot[j]);
+       *pole -= *tbis;
+  *pole = (knot[jDmi] == knot[j]) ? 0.0 :  *pole / (knot[jDmi] - knot[j]);
        pole--;
        tbis--;
       }
@@ -1219,7 +1220,7 @@ void  BSplCLib::Bohm(const Standard_Real U,
       
       for (j = Degm1; j >= i; j--) {
        jDmi--;
-       coef   = 1. / (knot[jDmi] - knot[j]);
+       coef   = (knot[jDmi] == knot[j]) ? 0.0 : 1. / (knot[jDmi] - knot[j]);
        *pole -= *tbis; *pole *= coef; pole++; tbis++;
        *pole -= *tbis; *pole *= coef;
        pole  -= 3;
@@ -1267,7 +1268,7 @@ void  BSplCLib::Bohm(const Standard_Real U,
       
       for (j = Degm1; j >= i; j--) {
        jDmi--;
-       coef   = 1. / (knot[jDmi] - knot[j]);
+       coef   = (knot[jDmi] == knot[j]) ? 0.0 : 1. / (knot[jDmi] - knot[j]);
        *pole -= *tbis; *pole *= coef; pole++; tbis++;
        *pole -= *tbis; *pole *= coef; pole++; tbis++;
        *pole -= *tbis; *pole *= coef;
@@ -1318,7 +1319,7 @@ void  BSplCLib::Bohm(const Standard_Real U,
       
       for (j = Degm1; j >= i; j--) {
        jDmi--;
-       coef   = 1. / (knot[jDmi] - knot[j]);
+       coef   = (knot[jDmi]  == knot[j]) ? 0.0 : 1. /(knot[jDmi] - knot[j]) ;
        *pole -= *tbis; *pole *= coef; pole++; tbis++;
        *pole -= *tbis; *pole *= coef; pole++; tbis++;
        *pole -= *tbis; *pole *= coef; pole++; tbis++;
@@ -1374,7 +1375,7 @@ void  BSplCLib::Bohm(const Standard_Real U,
        
        for (j = Degm1; j >= i; j--) {
          jDmi--;
-         coef = 1. / (knot[jDmi] - knot[j]);
+         coef = (knot[jDmi] == knot[j]) ? 0.0 : 1. / (knot[jDmi] - knot[j]);
          
          for (k = 0; k < Dimension; k++) {
            *pole -= *tbis; *pole *= coef; pole++; tbis++;
index 7334d82..40ba005 100644 (file)
@@ -563,6 +563,14 @@ is
      raises RangeError;
         ---Purpose : Raised if N < 0.
 
+  IsG1 (me; theTf, theTl, theAngTol : Real) returns Boolean;
+        ---Purpose :
+               --  Check if curve has at least G1 continuity in interval [theTf, theTl]
+        --  Returns true if IsCN(1)  
+        --  or 
+        --  angle betweem "left" and "right" first derivatives at
+        --  knots with C0 continuity is less then theAngTol
+               --  only knots in interval [theTf, theTl] is checked
 
   IsClosed (me)  returns Boolean;
         ---Purpose :
index b5454d5..ec08ce5 100644 (file)
@@ -62,6 +62,84 @@ Standard_Boolean Geom_BSplineCurve::IsCN ( const Standard_Integer N) const
     return Standard_False;
   }
 }
+//=======================================================================
+//function : IsG1
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Geom_BSplineCurve::IsG1 ( const Standard_Real theTf,
+                                           const Standard_Real theTl,
+                                           const Standard_Real theAngTol) const
+{
+  if(IsCN(1))
+  {
+    return Standard_True;
+  }
+
+  Standard_Integer  start = FirstUKnotIndex()+1,
+                    finish = LastUKnotIndex()-1;
+  Standard_Integer aDeg = Degree();
+  for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++)
+  {
+    const Standard_Real aTpar = Knot(aNKnot);
+
+    if(aTpar < theTf)
+      continue;
+    if(aTpar > theTl)
+      break;
+
+    Standard_Integer mult = Multiplicity(aNKnot);
+    if (mult < aDeg)
+      continue;
+
+    gp_Pnt aP1, aP2;
+    gp_Vec aV1, aV2;
+    LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1);
+    LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2);
+
+    if((aV1.SquareMagnitude() <= gp::Resolution()) ||
+        aV2.SquareMagnitude() <= gp::Resolution())
+    {
+      return Standard_False;
+    }
+
+    if(Abs(aV1.Angle(aV2)) > theAngTol)
+      return Standard_False;
+  }
+
+  if(!IsPeriodic())
+    return Standard_True;
+
+  const Standard_Real aFirstParam = FirstParameter(),
+                      aLastParam = LastParameter();
+
+  if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) &&
+      ((aLastParam - theTf)*(theTl - aLastParam) < 0.0))
+  {
+    //Range [theTf, theTl] does not intersect curve bounadries
+    return Standard_True;
+  }
+
+  //Curve is closed or periodic and range [theTf, theTl]
+  //intersect curve boundary. Therefore, it is necessary to 
+  //check if curve is smooth in its first and last point.
+
+  gp_Pnt aP;
+  gp_Vec aV1, aV2;
+  D1(Knot(FirstUKnotIndex()), aP, aV1);
+  D1(Knot(LastUKnotIndex()), aP, aV2);
+
+  if((aV1.SquareMagnitude() <= gp::Resolution()) ||
+      aV2.SquareMagnitude() <= gp::Resolution())
+  {
+    return Standard_False;
+  }
+
+  if(Abs(aV1.Angle(aV2)) > theAngTol)
+    return Standard_False;
+
+  return Standard_True;
+}
 
 //=======================================================================
 //function : IsClosed
index 19b5464..02aeae3 100644 (file)
@@ -84,7 +84,10 @@ is
 
 
 
-  Create (C : Curve from Geom; Offset : Real;  V : Dir)
+  Create (C : Curve from Geom;
+          Offset : Real;
+          V : Dir;
+          isNotCheckC0 : Boolean = Standard_False)
      returns OffsetCurve
         ---Purpose :
         --  C is the basis curve, Offset is the distance between <me> and
@@ -94,6 +97,8 @@ is
         --  at this point, the corresponding point on the offset curve is
         --  in the direction of the vector-product N = V ^ T   where
         --  N is a unitary vector.
+        --  If isNotCheckC0 = TRUE checking if basis curve has C0-continuity
+        --  is not made.
         --  Warnings :
         --  In this package the entities are not shared. The OffsetCurve is
         --  built with a copy of the curve C. So when C is modified the
@@ -122,9 +127,14 @@ is
        -- the point of parameter U on this offset curve.
  
 
-  SetBasisCurve (me : mutable; C : Curve from Geom)
+  SetBasisCurve ( me : mutable;
+                  C : Curve from Geom;
+                  isNotCheckC0 : Boolean = Standard_False)
      raises ConstructionError;
-        ---Purpose :  Changes this offset curve by assigning C as the basis curve from which it is built.
+        ---Purpose :  Changes this offset curve by assigning C
+        --            as the basis curve from which it is built.
+        --            If isNotCheckC0 = TRUE checking if basis curve
+        --            has C0-continuity is not made.
        -- Exceptions
        -- Standard_ConstructionError if the curve C is not at least "C1" continuous.
       
@@ -348,10 +358,15 @@ is
   Copy (me)  returns like me;
        ---Purpose: Creates a new object which is a copy of this offset curve.
 
+  GetBasisCurveContinuity(me)
+    returns Shape from GeomAbs;
+       ---Purpose: Returns continuity of the basis curve.   
+      
 fields
 
   basisCurve  : Curve from Geom;
   direction   : Dir;
   offsetValue : Real;
-
+  myBasisCurveContinuity : Shape from GeomAbs;
+  
 end;
index 58a1cf8..c273f9e 100644 (file)
@@ -59,6 +59,7 @@ typedef gp_XYZ  XYZ;
 //derivee non nulle
 static const int maxDerivOrder = 3;
 static const Standard_Real MinStep   = 1e-7;
+static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
 
 
 
@@ -79,34 +80,17 @@ Handle(Geom_Geometry) Geom_OffsetCurve::Copy () const {
 
 //=======================================================================
 //function : Geom_OffsetCurve
-//purpose  : 
+//purpose  : Basis curve cannot be an Offset curve or trimmed from
+//            offset curve.
 //=======================================================================
 
-Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C,
-                                   const Standard_Real           Offset, 
-                                   const Dir&           V      )
- : direction(V), offsetValue(Offset)
+Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Geom_Curve)& theCurve,
+                                    const Standard_Real       theOffset,
+                                    const gp_Dir&             theDir,
+                                    const Standard_Boolean    isTheNotCheckC0)
+ : direction(theDir), offsetValue(theOffset)
 {
-  if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) {
-    Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
-    SetBasisCurve (OC->BasisCurve());
-
-    Standard_Real PrevOff = OC->Offset();
-    gp_Vec V1(OC->Direction());
-    gp_Vec V2(direction);
-    gp_Vec Vdir(PrevOff*V1 + offsetValue*V2);
-
-    if (Offset >= 0.) {
-      offsetValue = Vdir.Magnitude();
-      direction.SetXYZ(Vdir.XYZ());
-    } else {
-      offsetValue = -Vdir.Magnitude();
-      direction.SetXYZ((-Vdir).XYZ());
-    }
-  }
-  else {
-    SetBasisCurve(C);
-  }
+  SetBasisCurve (theCurve, isTheNotCheckC0);
 }
 
 
@@ -182,36 +166,78 @@ Standard_Real Geom_OffsetCurve::Period () const
 //purpose  : 
 //=======================================================================
 
-void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C)
+void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C,
+                                      const Standard_Boolean isNotCheckC0)
 {
-  Handle(Curve) aBasisCurve = Handle(Curve)::DownCast(C->Copy());
+  const Standard_Real aUf = C->FirstParameter(),
+                      aUl = C->LastParameter();
+  Handle(Curve) aCheckingCurve =  Handle(Curve)::DownCast(C->Copy());
+  Standard_Boolean isTrimmed = Standard_False;
 
-  // Basis curve must be at least C1
-  if (aBasisCurve->Continuity() == GeomAbs_C0)
+  while(aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
+        aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
   {
-    // For B-splines it is sometimes possible to increase continuity by removing 
-    // unnecessarily duplicated knots
-    if (aBasisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
+    if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+    {
+      Handle(Geom_TrimmedCurve) aTrimC = 
+                Handle(Geom_TrimmedCurve)::DownCast(aCheckingCurve);
+      aCheckingCurve = aTrimC->BasisCurve();
+      isTrimmed = Standard_True;
+    }
+
+    if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
     {
-      Handle(Geom_BSplineCurve) aBCurve = Handle(Geom_BSplineCurve)::DownCast(aBasisCurve);
-      Standard_Integer degree = aBCurve->Degree();
-      Standard_Real Toler = Precision::Confusion();
-      Standard_Integer start = aBCurve->IsPeriodic() ? 1 :  aBCurve->FirstUKnotIndex(),
-                       finish = aBCurve->IsPeriodic() ? aBCurve->NbKnots() :  aBCurve->LastUKnotIndex();
-      for (Standard_Integer i = start; i <= finish; i++)
+      Handle(Geom_OffsetCurve) aOC = 
+            Handle(Geom_OffsetCurve)::DownCast(aCheckingCurve);
+      aCheckingCurve = aOC->BasisCurve();
+      Standard_Real PrevOff = aOC->Offset();
+      gp_Vec V1(aOC->Direction());
+      gp_Vec V2(direction);
+      gp_Vec Vdir(PrevOff*V1 + offsetValue*V2);
+
+      if (offsetValue >= 0.)
       {
-        Standard_Integer mult = aBCurve->Multiplicity(i);
-        if ( mult == degree )
-          aBCurve->RemoveKnot(i,degree - 1, Toler);
+        offsetValue = Vdir.Magnitude();
+        direction.SetXYZ(Vdir.XYZ());
+      }
+      else
+      {
+        offsetValue = -Vdir.Magnitude();
+        direction.SetXYZ((-Vdir).XYZ());
       }
     }
+  }
+  
+  myBasisCurveContinuity = aCheckingCurve->Continuity();
+
+  Standard_Boolean isC0 = !isNotCheckC0 &&
+                          (myBasisCurveContinuity == GeomAbs_C0);
+
+  // Basis curve must be at least C1
+  if (isC0 && aCheckingCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
+  {
+    Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCheckingCurve);
+    if(aBC->IsG1(aUf, aUl, MyAngularToleranceForG1))
+    {
+      //Checking if basis curve has more smooth (C1, G2 and above) is not done.
+      //It can be done in case of need.
+      myBasisCurveContinuity = GeomAbs_G1;
+      isC0 = Standard_False;
+    }
 
     // Raise exception if still C0
-    if (aBasisCurve->Continuity() == GeomAbs_C0)
+    if (isC0)
       Standard_ConstructionError::Raise("Offset on C0 curve");
   }
-
-  basisCurve = aBasisCurve;
+  //
+  if(isTrimmed)
+  {
+    basisCurve = new Geom_TrimmedCurve(aCheckingCurve, aUf, aUl);
+  } 
+  else
+  {
+    basisCurve = aCheckingCurve;
+  }
 }
 
 
@@ -235,7 +261,7 @@ Handle(Curve) Geom_OffsetCurve::BasisCurve () const
 GeomAbs_Shape Geom_OffsetCurve::Continuity () const {
 
   GeomAbs_Shape OffsetShape=GeomAbs_C0;
-  switch (basisCurve->Continuity()) {
+  switch (myBasisCurveContinuity) {
     case GeomAbs_C0 : OffsetShape = GeomAbs_C0;       break;
     case GeomAbs_C1 : OffsetShape = GeomAbs_C0;       break;
     case GeomAbs_C2 : OffsetShape = GeomAbs_C1;       break;
@@ -825,13 +851,13 @@ Standard_Real Geom_OffsetCurve::Offset () const { return offsetValue; }
 
 void Geom_OffsetCurve::Value (const Standard_Real theU, Pnt& theP, 
                               Pnt& thePbasis,  Vec& theV1basis) const 
-  {
-  if (basisCurve->Continuity() == GeomAbs_C0)
+{
+  if (myBasisCurveContinuity == GeomAbs_C0)
     Geom_UndefinedValue::Raise("Exception: Basis curve is C0 continuity!");
 
   basisCurve->D1(theU, thePbasis, theV1basis);
   D0(theU,theP);
-  }
+}
 
 
 //=======================================================================
@@ -894,3 +920,12 @@ const
 {
   return basisCurve->ParametricTransformation(T);
 }
+
+//=======================================================================
+//function : GetBasisCurveContinuity
+//purpose  : 
+//=======================================================================
+GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const
+{
+  return myBasisCurveContinuity;
+}
index 5dccb5d..88a3260 100644 (file)
@@ -68,7 +68,10 @@ is
 
 
 
-  Create (S : Surface from Geom; Offset : Real)   returns OffsetSurface
+  Create (S : Surface from Geom;
+          Offset : Real;
+          isNotCheckC0 : Boolean = Standard_False)
+    returns OffsetSurface
         ---Purpose : Constructs a surface offset from the basis surface
        -- S, where Offset is the distance between the offset
        -- surface and the basis surface at any point.
@@ -81,6 +84,8 @@ is
        -- which the offset value is measured is indicated by
        -- this normal vector if Offset is positive, or is the
        -- inverse sense if Offset is negative.
+      -- If isNotCheckC0 = TRUE checking if basis surface has C0-continuity
+      -- is not made.
         --  Warnings :
         -- - The offset surface is built with a copy of the
        --   surface S. Therefore, when S is modified the
@@ -95,12 +100,16 @@ is
 
 
 
-  SetBasisSurface (me : mutable; S : Surface from Geom)
+  SetBasisSurface ( me : mutable;
+                    S : Surface from Geom;
+                    isNotCheckC0 : Boolean = Standard_False)
      raises ConstructionError;
         ---Purpose : Raised if S is not at least C1.
         --  Warnings :
         --  No check is done to verify that a unique normal direction is
         --  defined at any point of the basis surface S.
+        --  If isNotCheckC0 = TRUE checking if basis surface has C0-continuity
+        --  is not made.
        -- Exceptions
        -- Standard_ConstructionError if the surface S is not
        -- at least "C1" continuous.
@@ -484,11 +493,15 @@ is
        --          these vectors have opposite direction.
      returns Boolean from Standard;
 
-  
+  GetBasisSurfContinuity(me)
+    returns Shape from GeomAbs;
+       ---Purpose: Returns continuity of the basis surface.   
+
 fields
 
   basisSurf   : Surface from Geom;
   equivSurf   : Surface from Geom;
   offsetValue : Real;
   myOscSurf   : OsculatingSurface from Geom;
+  myBasisSurfContinuity : Shape from GeomAbs;
 end;
index f4f298c..c708bb0 100644 (file)
@@ -38,6 +38,7 @@
 #include <Geom_BSplineCurve.hxx>
 #include <Geom_Geometry.hxx>
 #include <Geom_Surface.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_ElementarySurface.hxx>
 #include <Geom_CylindricalSurface.hxx>
@@ -50,6 +51,7 @@
 #include <Geom_SurfaceOfLinearExtrusion.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Curve.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_Ellipse.hxx>
 
@@ -81,123 +83,125 @@ typedef gp_Vec  Vec;
 typedef gp_Pnt  Pnt;
 typedef gp_Trsf Trsf;
 typedef gp_XYZ  XYZ;
+
+static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
 //=======================================================================
 //function : derivatives
 //purpose  : 
 //=======================================================================
 
 static void derivatives(Standard_Integer MaxOrder,
-                        Standard_Integer MinOrder,
-                        const Standard_Real U,
-                        const Standard_Real V,
-                        const Handle(Geom_Surface)& basisSurf,
-                        const Standard_Integer Nu,
-                        const Standard_Integer Nv,
-                        const Standard_Boolean AlongU,
-                        const Standard_Boolean AlongV,
-                        const Handle(Geom_BSplineSurface)& L,
-                        TColgp_Array2OfVec& DerNUV,
-                        TColgp_Array2OfVec& DerSurf)
+  Standard_Integer MinOrder,
+  const Standard_Real U,
+  const Standard_Real V,
+  const Handle(Geom_Surface)& basisSurf,
+  const Standard_Integer Nu,
+  const Standard_Integer Nv,
+  const Standard_Boolean AlongU,
+  const Standard_Boolean AlongV,
+  const Handle(Geom_BSplineSurface)& L,
+  TColgp_Array2OfVec& DerNUV,
+  TColgp_Array2OfVec& DerSurf)
 {
-      Standard_Integer i,j;
-      gp_Pnt P;
-      gp_Vec DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3UUV, DL3UVV, DL3V;
-      if (AlongU || AlongV) 
-      {
-       MaxOrder=0;
-       TColgp_Array2OfVec DerSurfL(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1);   
-        switch (MinOrder) 
-        {
-        case 1 :
-               L->D1(U, V, P, DL1U, DL1V);
-               DerSurfL.SetValue(1, 0, DL1U);
-               DerSurfL.SetValue(0, 1, DL1V);
-               break;
-        case 2 :
-               L->D2(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV);
-               DerSurfL.SetValue(1, 0, DL1U);
-               DerSurfL.SetValue(0, 1, DL1V);
-               DerSurfL.SetValue(1, 1, DL2UV);
-               DerSurfL.SetValue(2, 0, DL2U);
-               DerSurfL.SetValue(0, 2, DL2V);
-               break;
-        case 3 :
-               L->D3(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3V ,DL3UUV, DL3UVV);
-               DerSurfL.SetValue(1, 0, DL1U);
-               DerSurfL.SetValue(0, 1, DL1V);
-               DerSurfL.SetValue(1, 1, DL2UV);
-               DerSurfL.SetValue(2, 0, DL2U);
-               DerSurfL.SetValue(0, 2, DL2V);
-               DerSurfL.SetValue(3, 0, DL3U);
-               DerSurfL.SetValue(2, 1, DL3UUV);
-               DerSurfL.SetValue(1, 2, DL3UVV);
-               DerSurfL.SetValue(0, 3, DL3V); 
-               break;
-        default: 
-           break;
-            }
-
-        if(Nu <= Nv) 
-       {
-         for(i=0;i<=MaxOrder+1+Nu;i++)
-            for(j=i;j<=MaxOrder+Nv+1;j++)
-               if(i+j> MinOrder) 
-              {
-                 DerSurfL.SetValue(i,j,L->DN(U,V,i,j));
-                 DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
-                  if (i!=j && j <= Nu+1) 
-                  {
-                     DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
-                     DerSurfL.SetValue(j,i,L->DN(U,V,j,i));
-                  }
-              }
-        }
-       else
-       {
-         for(j=0;j<=MaxOrder+1+Nv;j++)
-            for(i=j;i<=MaxOrder+Nu+1;i++)
-               if(i+j> MinOrder) 
-              {
-                 DerSurfL.SetValue(i,j,L->DN(U,V,i,j));
-                 DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
-                  if (i!=j && i <= Nv+1) 
-                  {
-                     DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
-                     DerSurfL.SetValue(j,i,L->DN(U,V,j,i));
-                  }
-              }
-        }
-       for(i=0;i<=MaxOrder+Nu;i++)
-         for(j=0;j<=MaxOrder+Nv;j++)
-          {
-           if (AlongU)
-             DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurfL,DerSurf));
-           if (AlongV)
-             DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf,DerSurfL));
-         }
+  Standard_Integer i,j;
+  gp_Pnt P;
+  gp_Vec DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3UUV, DL3UVV, DL3V;
 
-      }    
-      else 
-      {
+  if (AlongU || AlongV) 
+  {
+    MaxOrder=0;
+    TColgp_Array2OfVec DerSurfL(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1);      
+    switch (MinOrder) 
+    {
+    case 1 :
+      L->D1(U, V, P, DL1U, DL1V);
+      DerSurfL.SetValue(1, 0, DL1U);
+      DerSurfL.SetValue(0, 1, DL1V);
+      break;
+    case 2 :
+      L->D2(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV);
+      DerSurfL.SetValue(1, 0, DL1U);
+      DerSurfL.SetValue(0, 1, DL1V);
+      DerSurfL.SetValue(1, 1, DL2UV);
+      DerSurfL.SetValue(2, 0, DL2U);
+      DerSurfL.SetValue(0, 2, DL2V);
+      break;
+    case 3 :
+      L->D3(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3V ,DL3UUV, DL3UVV);
+      DerSurfL.SetValue(1, 0, DL1U);
+      DerSurfL.SetValue(0, 1, DL1V);
+      DerSurfL.SetValue(1, 1, DL2UV);
+      DerSurfL.SetValue(2, 0, DL2U);
+      DerSurfL.SetValue(0, 2, DL2V);
+      DerSurfL.SetValue(3, 0, DL3U);
+      DerSurfL.SetValue(2, 1, DL3UUV);
+      DerSurfL.SetValue(1, 2, DL3UVV);
+      DerSurfL.SetValue(0, 3, DL3V); 
+      break;
+    default: 
+      break;
+    }
 
-       for(i=0;i<=MaxOrder+Nu+1;i++)
-         for(j=i;j<=MaxOrder+Nv+1;j++)
-            if(i+j>MinOrder) 
-            {  
-          
-             DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
-             if (i!=j) DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
-           }
-       for(i=0;i<=MaxOrder+Nu;i++)
-         for(j=0;j<=MaxOrder+Nv;j++)
+    if(Nu <= Nv) 
+    {
+      for(i=0;i<=MaxOrder+1+Nu;i++)
+        for(j=i;j<=MaxOrder+Nv+1;j++)
+          if(i+j> MinOrder) 
+          {
+            DerSurfL.SetValue(i,j,L->DN(U,V,i,j));
+            DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
+            if (i!=j && j <= Nu+1) 
+            {
+              DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
+              DerSurfL.SetValue(j,i,L->DN(U,V,j,i));
+            }
+          }
+    }
+    else
+    {
+      for(j=0;j<=MaxOrder+1+Nv;j++)
+        for(i=j;i<=MaxOrder+Nu+1;i++)
+          if(i+j> MinOrder) 
+          {
+            DerSurfL.SetValue(i,j,L->DN(U,V,i,j));
+            DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
+            if (i!=j && i <= Nv+1) 
             {
-              DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
-           }
+              DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
+              DerSurfL.SetValue(j,i,L->DN(U,V,j,i));
+            }
+          }
+    }
+    for(i=0;i<=MaxOrder+Nu;i++)
+      for(j=0;j<=MaxOrder+Nv;j++)
+      {
+        if (AlongU)
+          DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurfL,DerSurf));
+        if (AlongV)
+          DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf,DerSurfL));
       }
-   
+
+  }    
+  else 
+  {
+
+    for(i=0;i<=MaxOrder+Nu+1;i++)
+      for(j=i;j<=MaxOrder+Nv+1;j++)
+        if(i+j>MinOrder) 
+        {  
+
+          DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
+          if (i!=j) DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
+        }
+        for(i=0;i<=MaxOrder+Nu;i++)
+          for(j=0;j<=MaxOrder+Nv;j++)
+          {
+            DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
+          }
+  }
+
 }
-                        
+
 
 //=======================================================================
 //function : Copy
@@ -206,9 +210,9 @@ static void derivatives(Standard_Integer MaxOrder,
 
 Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const {
 
-   Handle(OffsetSurface) S;
-   S = new OffsetSurface (basisSurf, offsetValue);
-   return S;
+  Handle(OffsetSurface) S;
+  S = new OffsetSurface (basisSurf, offsetValue);
+  return S;
 }
 
 
@@ -217,78 +221,147 @@ Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const {
 
 //=======================================================================
 //function : Geom_OffsetSurface
-//purpose  : 
+//purpose  : Basis surface cannot be an Offset surface or trimmed from
+//            offset surface.
 //=======================================================================
 
-Geom_OffsetSurface::Geom_OffsetSurface ( const Handle(Surface)& S, 
-                                        const Standard_Real             Offset ) 
- : offsetValue (Offset) 
+Geom_OffsetSurface::Geom_OffsetSurface (const Handle(Geom_Surface)& theSurf, 
+  const Standard_Real theOffset,
+  const Standard_Boolean isTheNotCheckC0) 
+  : offsetValue (theOffset) 
 {
-  Handle(Geom_OffsetSurface) Off_S;
-  Off_S = Handle(Geom_OffsetSurface)::DownCast(S);
-  if (!Off_S.IsNull()) {
-    offsetValue += Off_S->Offset();
-    SetBasisSurface (Off_S->BasisSurface());
-  }
-  else {
-    SetBasisSurface(S);
-  }
-
-//
-// Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
-// et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso 
-// et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour
-// detecter si une iso est degeneree.
-  Standard_Real Tol = Precision::Confusion(); //0.0001;
-  myOscSurf.Init(basisSurf,Tol);
-}
 
+  SetBasisSurface(theSurf, isTheNotCheckC0);
 
+}
 
 //=======================================================================
 //function : SetBasisSurface
 //purpose  : 
 //=======================================================================
 
-void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S)
+void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S,
+  const Standard_Boolean isNotCheckC0)
 {
-  Handle(Surface) aBasisSurf = Handle(Surface)::DownCast(S->Copy());
+  Standard_Real aUf, aUl, aVf, aVl;
+  S->Bounds(aUf, aUl, aVf, aVl);
+
+  Handle(Surface) aCheckingSurf = Handle(Surface)::DownCast(S->Copy());
+  Standard_Boolean isTrimmed = Standard_False;
+
+  while(aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
+    aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
+  {
+    if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
+    {
+      Handle(Geom_RectangularTrimmedSurface) aTrimS = 
+        Handle(Geom_RectangularTrimmedSurface)::DownCast(aCheckingSurf);
+      aCheckingSurf = aTrimS->BasisSurface();
+      isTrimmed = Standard_True;
+    }
+
+    if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
+    {
+      Handle(Geom_OffsetSurface) aOS = 
+        Handle(Geom_OffsetSurface)::DownCast(aCheckingSurf);
+      aCheckingSurf = aOS->BasisSurface();
+      offsetValue += aOS->Offset();
+    }
+  }
+
+
+  myBasisSurfContinuity = aCheckingSurf->Continuity();
+
+  Standard_Boolean isC0 = !isNotCheckC0 &&
+    (myBasisSurfContinuity == GeomAbs_C0);
 
   // Basis surface must be at least C1
-  if (aBasisSurf->Continuity() == GeomAbs_C0)
+  if (isC0)
   {
-    // For B-splines it is sometimes possible to increase continuity by removing 
-    // unnecessarily duplicated knots
-    if (aBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)))
+    Handle(Geom_Curve) aCurve;
+
+    if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
     {
-      Handle(Geom_BSplineSurface) aBSurf = Handle(Geom_BSplineSurface)::DownCast(aBasisSurf);
-      Standard_Integer uDegree = aBSurf->UDegree(), vDegree = aBSurf->VDegree();
-      Standard_Real Toler = Precision::Confusion();
-      Standard_Integer start = aBSurf->IsUPeriodic() ? 1 :  aBSurf->FirstUKnotIndex(),
-                       finish = aBSurf->IsUPeriodic() ? aBSurf->NbUKnots() :  aBSurf->LastUKnotIndex();
-      for (Standard_Integer i = start; i <= finish; i++)
-      {
-        Standard_Integer mult = aBSurf->UMultiplicity(i);
-        if ( mult == uDegree )
-          aBSurf->RemoveUKnot(i,uDegree - 1, Toler);
-      }
-      start = aBSurf->IsVPeriodic() ? 1 :  aBSurf->FirstVKnotIndex();
-      finish = aBSurf->IsVPeriodic() ? aBSurf->NbVKnots() :  aBSurf->LastVKnotIndex();
-      for (Standard_Integer i = start; i <= finish; i++)
+      Handle(Geom_SurfaceOfRevolution) aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aCheckingSurf);
+      aCurve = aRevSurf->BasisCurve();
+    }
+    else if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))
+    {
+      Handle(Geom_SurfaceOfLinearExtrusion) aLESurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aCheckingSurf);
+      aCurve = aLESurf->BasisCurve();
+    }
+
+    if(!aCurve.IsNull())
+    {
+      while(aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
+        aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
       {
-        Standard_Integer mult = aBSurf->VMultiplicity(i);
-        if ( mult == vDegree )
-          aBSurf->RemoveVKnot(i,vDegree - 1, Toler);
+        if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+        {
+          Handle(Geom_TrimmedCurve) aTrimC = 
+            Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+          aCurve = aTrimC->BasisCurve();
+        }
+
+        if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
+        {
+          Handle(Geom_OffsetCurve) aOC = 
+            Handle(Geom_OffsetCurve)::DownCast(aCurve);
+          aCurve = aOC->BasisCurve();
+        }
       }
     }
 
+    Standard_Real aUIsoPar = (aUf + aUl)/2.0, aVIsoPar = (aVf + aVl)/2.0;
+    Standard_Boolean isUG1 = Standard_False, isVG1 = Standard_False;
+    const Handle(Geom_Curve) aCurv1 = aCurve.IsNull() ? aCheckingSurf->UIso(aUIsoPar) : aCurve;
+    const Handle(Geom_Curve) aCurv2 = aCheckingSurf->VIso(aVIsoPar);
+    isUG1 = !aCurv1->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
+    isVG1 = !aCurv2->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
+
+    if(!isUG1)
+    {
+      Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv1);
+      isUG1 = aBC->IsG1(aVf, aVl, MyAngularToleranceForG1);
+    }
+    //
+    if(!isVG1)
+    {
+      Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv2);
+      isVG1 = aBC->IsG1(aUf, aUl, MyAngularToleranceForG1);
+    }
+    //
+    if(isUG1 && isVG1) 
+    {
+      myBasisSurfContinuity = GeomAbs_G1;
+      isC0 = Standard_False;
+    }
+
     // Raise exception if still C0
-    if (aBasisSurf->Continuity() == GeomAbs_C0)
+    if (isC0)
       Standard_ConstructionError::Raise("Offset with no C1 Surface");
   }
 
-  basisSurf = aBasisSurf;
+  if(isTrimmed)
+  {
+    basisSurf = 
+      new Geom_RectangularTrimmedSurface(aCheckingSurf, aUf, aUl, aVf, aVl);
+  }
+  else
+  {
+    basisSurf = aCheckingSurf;
+  }
+  
   equivSurf = Surface();
+  //
+  // Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
+  // et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso 
+  // et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour
+  // detecter si une iso est degeneree.
+  Standard_Real Tol = Precision::Confusion(); //0.0001;
+  myOscSurf.Init(basisSurf,Tol);
+
 }
 
 
@@ -368,11 +441,11 @@ Handle(Surface) Geom_OffsetSurface::BasisSurface () const
 //=======================================================================
 
 void Geom_OffsetSurface::Bounds (Standard_Real& U1, 
-                                Standard_Real& U2, 
-                                Standard_Real& V1, 
-                                Standard_Real& V2) const {
-   
-  basisSurf->Bounds (U1, U2 ,V1, V2);
+  Standard_Real& U2, 
+  Standard_Real& V1, 
+  Standard_Real& V2) const {
+
+    basisSurf->Bounds (U1, U2 ,V1, V2);
 }
 
 
@@ -384,14 +457,14 @@ void Geom_OffsetSurface::Bounds (Standard_Real& U1,
 GeomAbs_Shape Geom_OffsetSurface::Continuity () const {
 
   GeomAbs_Shape OffsetShape=GeomAbs_C0;
-  switch (basisSurf->Continuity()) {
-     case GeomAbs_C0 :        OffsetShape = GeomAbs_C0; break;
-     case GeomAbs_G1 :        OffsetShape = GeomAbs_C0; break;
-     case GeomAbs_C1 :        OffsetShape = GeomAbs_C0; break;
-     case GeomAbs_G2 :        OffsetShape = GeomAbs_C0; break;
-     case GeomAbs_C2 :        OffsetShape = GeomAbs_C1; break;
-     case GeomAbs_C3 :        OffsetShape = GeomAbs_C2; break;
-     case GeomAbs_CN :        OffsetShape = GeomAbs_CN; break;
+  switch (myBasisSurfContinuity) {
+  case GeomAbs_C0 :        OffsetShape = GeomAbs_C0; break;
+  case GeomAbs_G1 :        OffsetShape = GeomAbs_C0; break;
+  case GeomAbs_C1 :        OffsetShape = GeomAbs_C0; break;
+  case GeomAbs_G2 :        OffsetShape = GeomAbs_C0; break;
+  case GeomAbs_C2 :        OffsetShape = GeomAbs_C1; break;
+  case GeomAbs_C3 :        OffsetShape = GeomAbs_C2; break;
+  case GeomAbs_CN :        OffsetShape = GeomAbs_CN; break;
   }
   return OffsetShape;
 }
@@ -406,7 +479,7 @@ void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, Pnt&
 
   Vec D1U, D1V;
 #ifdef CHECK  
-  if (basisSurf->Continuity() == GeomAbs_C0) Geom_UndefinedValue::Raise();
+  if (myBasisSurfContinuity == GeomAbs_C0) Geom_UndefinedValue::Raise();
 #endif
   if (equivSurf.IsNull()){ 
     basisSurf->D1(U, V, P, D1U, D1V);
@@ -422,14 +495,14 @@ void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, Pnt&
 //=======================================================================
 
 void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V, 
-                                  Pnt& P, 
-                                  Vec& D1U, Vec& D1V) const 
+  Pnt& P, 
+  Vec& D1U, Vec& D1V) const 
 {
 
 #ifdef CHECK  
-  if (basisSurf->Continuity()==GeomAbs_C0 || 
-      basisSurf->Continuity()==GeomAbs_C1) { 
-    Geom_UndefinedDerivative::Raise();
+  if (myBasisSurfContinuity==GeomAbs_C0 || 
+    myBasisSurfContinuity==GeomAbs_C1) { 
+      Geom_UndefinedDerivative::Raise();
   }
 #endif
   if (equivSurf.IsNull()) 
@@ -451,24 +524,27 @@ void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V,
 //=======================================================================
 
 void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V, 
-                            Pnt& P, 
-                            Vec& D1U, Vec& D1V,
-                            Vec& D2U, Vec& D2V, Vec& D2UV) const {
-  
+  Pnt& P, 
+  Vec& D1U, Vec& D1V,
+  Vec& D2U, Vec& D2V, Vec& D2UV) const {
+
 #ifdef CHECK  
-  GeomAbs_Shape Continuity = basisSurf->Continuity();
-  if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 ||
-      Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); }
+    if (myBasisSurfContinuity == GeomAbs_C0 ||
+      myBasisSurfContinuity == GeomAbs_C1 ||
+      myBasisSurfContinuity == GeomAbs_C2)
+    {
+      Geom_UndefinedDerivative::Raise();
+    }
 #endif
-  if (equivSurf.IsNull())
+    if (equivSurf.IsNull())
     {
       gp_Vec d3u, d3uuv, d3uvv, d3v;
       basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,
-                   d3u,d3v, d3uuv, d3uvv);
-      
+        d3u,d3v, d3uuv, d3uvv);
+
       SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,d3u,d3v, d3uuv, d3uvv);
     }
-  else equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
+    else equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
 }
 
 
@@ -478,26 +554,26 @@ void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V,
 //=======================================================================
 
 void Geom_OffsetSurface::D3   (const Standard_Real U, const Standard_Real V, 
-                              Pnt& P, 
-                              Vec& D1U, Vec& D1V, 
-                              Vec& D2U, Vec& D2V, Vec& D2UV,
-                              Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV) const {
+  Pnt& P, 
+  Vec& D1U, Vec& D1V, 
+  Vec& D2U, Vec& D2V, Vec& D2UV,
+  Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV) const {
 #ifdef CHECK  
-  if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) { 
-    Geom_UndefinedDerivative::Raise();
+    if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) { 
+      Geom_UndefinedDerivative::Raise();
     }
 #endif
-  if (equivSurf.IsNull())
+    if (equivSurf.IsNull())
     {
-      
+
       basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,
-                   D3U, D3V, D3UUV, D3UVV);
+        D3U, D3V, D3UUV, D3UVV);
       SetD3(U, V, P, D1U, D1V, D2U, D2V, D2UV,
-                   D3U, D3V, D3UUV, D3UVV);
+        D3U, D3V, D3UUV, D3UVV);
     }
-  else equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
+    else equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
 }
-   
+
 
 
 
@@ -507,9 +583,9 @@ void Geom_OffsetSurface::D3   (const Standard_Real U, const Standard_Real V,
 //=======================================================================
 
 Vec Geom_OffsetSurface::DN ( const Standard_Real    U , const Standard_Real    V, 
-                             const Standard_Integer Nu, const Standard_Integer Nv) const 
+  const Standard_Integer Nu, const Standard_Integer Nv) const 
 {
-  
+
   Standard_RangeError_Raise_if (Nu < 0 || Nv < 0 || Nu + Nv < 1, " ");
 #ifdef CHECK  
   if (!(basisSurf->IsCNu (Nu) && basisSurf->IsCNv (Nv))) { 
@@ -520,12 +596,12 @@ Vec Geom_OffsetSurface::DN ( const Standard_Real    U , const Standard_Real    V
 
   if (equivSurf.IsNull())
   {
-     Pnt P;
-     Vec D1U,D1V;
-     basisSurf->D1 (U, V, P, D1U, D1V);
+    Pnt P;
+    Vec D1U,D1V;
+    basisSurf->D1 (U, V, P, D1U, D1V);
 
-     D = SetDN(U,V,Nu,Nv,D1U,D1V);
-   }
+    D = SetDN(U,V,Nu,Nv,D1U,D1V);
+  }
   else D=equivSurf->DN(U,V,Nu,Nv);
   return D; 
 }
@@ -537,47 +613,47 @@ Vec Geom_OffsetSurface::DN ( const Standard_Real    U , const Standard_Real    V
 
 void Geom_OffsetSurface::D1 
   (const Standard_Real U,  const Standard_Real V,
-         Pnt& P,        Pnt& Pbasis, 
-         Vec& D1U,      Vec& D1V,      Vec& D1Ubasis , Vec& D1Vbasis,
-         Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis) const {
-
-     if (basisSurf->Continuity() == GeomAbs_C0 ||
-         basisSurf->Continuity() == GeomAbs_C1) { 
-       Geom_UndefinedDerivative::Raise();
-     }
-     basisSurf->D2 (U, V, Pbasis, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis,
-                    D2UVbasis);
-     Vec Ndir = D1Ubasis.Crossed (D1Vbasis);
-     Standard_Real R2  = Ndir.SquareMagnitude();
-     Standard_Real R   = Sqrt (R2);
-     Standard_Real R3  = R * R2;
-     Vec DUNdir = D2Ubasis.Crossed (D1Vbasis);
-     DUNdir.Add (D1Ubasis.Crossed (D2UVbasis));
-     Vec DVNdir = D2UVbasis.Crossed (D1Vbasis);
-     DVNdir.Add (D1Ubasis.Crossed (D2Vbasis));
-     Standard_Real DRu = Ndir.Dot (DUNdir);
-     Standard_Real DRv = Ndir.Dot (DVNdir);
-     if (R3 <= gp::Resolution()) {
-        if (R2 <= gp::Resolution())  Geom_UndefinedDerivative::Raise();
-        DUNdir.Multiply(R);
-        DUNdir.Subtract (Ndir.Multiplied (DRu/R));
-        DUNdir.Multiply (offsetValue/R2);
-        D1U = D1Ubasis.Added (DUNdir);
-        DVNdir.Multiply(R);
-        DVNdir.Subtract (Ndir.Multiplied (DRv/R));
-        DVNdir.Multiply (offsetValue/R2);
-        D1V = D1Vbasis.Added (DVNdir);
-     }
-     else {
-       DUNdir.Multiply (offsetValue / R);
-       DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3));
-       D1U = D1Ubasis.Added (DUNdir);
-       DVNdir.Multiply (offsetValue / R);
-       DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3));
-       D1V = D1Vbasis.Added (DVNdir);
-     }
-     Ndir.Multiply (offsetValue/R);
-     P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ()));
+  Pnt& P,        Pnt& Pbasis, 
+  Vec& D1U,      Vec& D1V,      Vec& D1Ubasis , Vec& D1Vbasis,
+  Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis) const {
+
+    if (basisSurf->Continuity() == GeomAbs_C0 ||
+      basisSurf->Continuity() == GeomAbs_C1) { 
+        Geom_UndefinedDerivative::Raise();
+    }
+    basisSurf->D2 (U, V, Pbasis, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis,
+      D2UVbasis);
+    Vec Ndir = D1Ubasis.Crossed (D1Vbasis);
+    Standard_Real R2  = Ndir.SquareMagnitude();
+    Standard_Real R   = Sqrt (R2);
+    Standard_Real R3  = R * R2;
+    Vec DUNdir = D2Ubasis.Crossed (D1Vbasis);
+    DUNdir.Add (D1Ubasis.Crossed (D2UVbasis));
+    Vec DVNdir = D2UVbasis.Crossed (D1Vbasis);
+    DVNdir.Add (D1Ubasis.Crossed (D2Vbasis));
+    Standard_Real DRu = Ndir.Dot (DUNdir);
+    Standard_Real DRv = Ndir.Dot (DVNdir);
+    if (R3 <= gp::Resolution()) {
+      if (R2 <= gp::Resolution())  Geom_UndefinedDerivative::Raise();
+      DUNdir.Multiply(R);
+      DUNdir.Subtract (Ndir.Multiplied (DRu/R));
+      DUNdir.Multiply (offsetValue/R2);
+      D1U = D1Ubasis.Added (DUNdir);
+      DVNdir.Multiply(R);
+      DVNdir.Subtract (Ndir.Multiplied (DRv/R));
+      DVNdir.Multiply (offsetValue/R2);
+      D1V = D1Vbasis.Added (DVNdir);
+    }
+    else {
+      DUNdir.Multiply (offsetValue / R);
+      DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3));
+      D1U = D1Ubasis.Added (DUNdir);
+      DVNdir.Multiply (offsetValue / R);
+      DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3));
+      D1V = D1Vbasis.Added (DVNdir);
+    }
+    Ndir.Multiply (offsetValue/R);
+    P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ()));
 }
 
 
@@ -589,106 +665,106 @@ void Geom_OffsetSurface::D1
 
 void Geom_OffsetSurface::D2 
   (const Standard_Real U, const Standard_Real V,
-   Pnt& P, Pnt& Pbasis,
-   Vec& D1U, Vec& D1V, Vec& D2U, Vec& D2V, Vec& D2UV,
-   Vec& D1Ubasis, Vec& D1Vbasis,
-   Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis, 
-   Vec& D3Ubasis, Vec& D3Vbasis, Vec& D3UUVbasis, Vec& D3UVVbasis) const {
-
-
-     GeomAbs_Shape Continuity = basisSurf->Continuity();
-     if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 ||
-         Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); }
-//     Vec D3U, D3V, D3UVV, D3UUV;
-     basisSurf->D3 (U, V, P, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis,
-                    D3Ubasis, D3Vbasis, D3UUVbasis, D3UVVbasis);
-     Vec Ndir = D1Ubasis.Crossed (D1Vbasis);
-     Standard_Real R2  = Ndir.SquareMagnitude();
-     Standard_Real R   = Sqrt (R2);
-     Standard_Real R3  = R2 * R;
-     Standard_Real R4  = R2 * R2;
-     Standard_Real R5  = R3 * R2;
-     Vec DUNdir = D2Ubasis.Crossed (D1Vbasis);
-     DUNdir.Add (D1Ubasis.Crossed (D2UVbasis));
-     Vec DVNdir = D2UVbasis.Crossed (D1Vbasis);
-     DVNdir.Add (D1Ubasis.Crossed (D2Vbasis));
-     Standard_Real DRu = Ndir.Dot (DUNdir);
-     Standard_Real DRv = Ndir.Dot (DVNdir);
-     Vec D2UNdir = D3Ubasis.Crossed (D1Vbasis);
-     D2UNdir.Add (D1Ubasis.Crossed (D3UUVbasis));
-     D2UNdir.Add (2.0 * (D2Ubasis.Crossed (D2UVbasis)));
-     Vec D2VNdir = D3UVVbasis.Crossed (D1Vbasis);
-     D2VNdir.Add (D1Ubasis.Crossed (D3Vbasis));
-     D2VNdir.Add (2.0 * (D2UVbasis.Crossed (D2Vbasis)));
-     Vec D2UVNdir = D2UVbasis.Crossed (D1Vbasis); 
-     D2UVNdir.Add (D1Ubasis.Crossed (D3UVVbasis));
-     D2UVNdir.Add (D2Ubasis.Crossed (D2Vbasis));
-     Standard_Real D2Ru = Ndir.Dot (D2UNdir) + DUNdir.Dot (DUNdir);
-     Standard_Real D2Rv = Ndir.Dot (D2VNdir) + DVNdir.Dot (DVNdir);
-     Standard_Real D2Ruv = DVNdir.Dot (DUNdir) + Ndir.Dot (D2UVNdir);
-
-     if (R5 <= gp::Resolution()) {
-        //We try another computation but the stability is not very good
-        //dixit ISG.
-        if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
-        // V2 = P" (U) :
-        // Standard_Real R4 = R2 * R2;
-        D2UNdir.Subtract (DUNdir.Multiplied (2.0 * DRu / R2));
-        D2UNdir.Subtract (Ndir.Multiplied (D2Ru/R2));
-        D2UNdir.Add (Ndir.Multiplied (3.0 * DRu * DRu / R4));
-        D2UNdir.Multiply (offsetValue / R);
-        D2U = D2Ubasis.Added (D2UNdir);
-        D2VNdir.Subtract (DVNdir.Multiplied (2.0 * DRv / R2));
-        D2VNdir.Subtract (Ndir.Multiplied (D2Rv/R2));
-        D2VNdir.Add (Ndir.Multiplied (3.0 * DRv * DRv / R4));
-        D2VNdir.Multiply (offsetValue / R);
-        D2V = D2Vbasis.Added (D2VNdir);
-
-        D2UVNdir.Subtract (DUNdir.Multiplied (DRv / R2));
-        D2UVNdir.Subtract (DVNdir.Multiplied (DRu / R2));
-        D2UVNdir.Subtract (Ndir.Multiplied (D2Ruv / R2));
-        D2UVNdir.Add (Ndir.Multiplied (3.0 * DRu * DRv / R4));
-        D2UVNdir.Multiply (offsetValue / R);
-        D2UV = D2UVbasis.Added (D2UVNdir);
-
-        DUNdir.Multiply(R);
-        DUNdir.Subtract (Ndir.Multiplied (DRu/R));
-        DUNdir.Multiply (offsetValue/R2);
-        D1U = D1Ubasis.Added (DUNdir);
-        DVNdir.Multiply(R);
-        DVNdir.Subtract (Ndir.Multiplied (DRv/R));
-        DVNdir.Multiply (offsetValue/R2);
-        D1V = D1Vbasis.Added (DVNdir);
-     }
-     else {
-       D2UNdir.Multiply (offsetValue/R);
-       D2UNdir.Subtract (DUNdir.Multiplied (2.0 * offsetValue * DRu / R3));
-       D2UNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ru / R3));
-       D2UNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRu * DRu / R5));
-       D2U = D2Ubasis.Added (D2UNdir);
-
-       D2VNdir.Multiply (offsetValue/R);
-       D2VNdir.Subtract (DVNdir.Multiplied (2.0 * offsetValue * DRv / R3));
-       D2VNdir.Subtract (Ndir.Multiplied (offsetValue * D2Rv / R3));
-       D2VNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRv * DRv / R5));
-       D2V = D2Vbasis.Added (D2VNdir);
-
-       D2UVNdir.Multiply (offsetValue/R);
-       D2UVNdir.Subtract (DUNdir.Multiplied (offsetValue * DRv / R3));
-       D2UVNdir.Subtract (DVNdir.Multiplied (offsetValue * DRu / R3));
-       D2UVNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ruv / R3));
-       D2UVNdir.Add (Ndir.Multiplied (3.0 * offsetValue * DRu * DRv / R5));
-       D2UV = D2UVbasis.Added (D2UVNdir);
-
-       DUNdir.Multiply (offsetValue / R);
-       DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3));
-       D1U = D1Ubasis.Added (DUNdir);
-       DVNdir.Multiply (offsetValue / R);
-       DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3));
-       D1V = D1Vbasis.Added (DVNdir);
-     }
-     Ndir.Multiply (offsetValue/R);
-     P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ()));
+  Pnt& P, Pnt& Pbasis,
+  Vec& D1U, Vec& D1V, Vec& D2U, Vec& D2V, Vec& D2UV,
+  Vec& D1Ubasis, Vec& D1Vbasis,
+  Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis, 
+  Vec& D3Ubasis, Vec& D3Vbasis, Vec& D3UUVbasis, Vec& D3UVVbasis) const {
+
+
+    GeomAbs_Shape Continuity = basisSurf->Continuity();
+    if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 ||
+      Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); }
+    //     Vec D3U, D3V, D3UVV, D3UUV;
+    basisSurf->D3 (U, V, P, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis,
+      D3Ubasis, D3Vbasis, D3UUVbasis, D3UVVbasis);
+    Vec Ndir = D1Ubasis.Crossed (D1Vbasis);
+    Standard_Real R2  = Ndir.SquareMagnitude();
+    Standard_Real R   = Sqrt (R2);
+    Standard_Real R3  = R2 * R;
+    Standard_Real R4  = R2 * R2;
+    Standard_Real R5  = R3 * R2;
+    Vec DUNdir = D2Ubasis.Crossed (D1Vbasis);
+    DUNdir.Add (D1Ubasis.Crossed (D2UVbasis));
+    Vec DVNdir = D2UVbasis.Crossed (D1Vbasis);
+    DVNdir.Add (D1Ubasis.Crossed (D2Vbasis));
+    Standard_Real DRu = Ndir.Dot (DUNdir);
+    Standard_Real DRv = Ndir.Dot (DVNdir);
+    Vec D2UNdir = D3Ubasis.Crossed (D1Vbasis);
+    D2UNdir.Add (D1Ubasis.Crossed (D3UUVbasis));
+    D2UNdir.Add (2.0 * (D2Ubasis.Crossed (D2UVbasis)));
+    Vec D2VNdir = D3UVVbasis.Crossed (D1Vbasis);
+    D2VNdir.Add (D1Ubasis.Crossed (D3Vbasis));
+    D2VNdir.Add (2.0 * (D2UVbasis.Crossed (D2Vbasis)));
+    Vec D2UVNdir = D2UVbasis.Crossed (D1Vbasis); 
+    D2UVNdir.Add (D1Ubasis.Crossed (D3UVVbasis));
+    D2UVNdir.Add (D2Ubasis.Crossed (D2Vbasis));
+    Standard_Real D2Ru = Ndir.Dot (D2UNdir) + DUNdir.Dot (DUNdir);
+    Standard_Real D2Rv = Ndir.Dot (D2VNdir) + DVNdir.Dot (DVNdir);
+    Standard_Real D2Ruv = DVNdir.Dot (DUNdir) + Ndir.Dot (D2UVNdir);
+
+    if (R5 <= gp::Resolution()) {
+      //We try another computation but the stability is not very good
+      //dixit ISG.
+      if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
+      // V2 = P" (U) :
+      // Standard_Real R4 = R2 * R2;
+      D2UNdir.Subtract (DUNdir.Multiplied (2.0 * DRu / R2));
+      D2UNdir.Subtract (Ndir.Multiplied (D2Ru/R2));
+      D2UNdir.Add (Ndir.Multiplied (3.0 * DRu * DRu / R4));
+      D2UNdir.Multiply (offsetValue / R);
+      D2U = D2Ubasis.Added (D2UNdir);
+      D2VNdir.Subtract (DVNdir.Multiplied (2.0 * DRv / R2));
+      D2VNdir.Subtract (Ndir.Multiplied (D2Rv/R2));
+      D2VNdir.Add (Ndir.Multiplied (3.0 * DRv * DRv / R4));
+      D2VNdir.Multiply (offsetValue / R);
+      D2V = D2Vbasis.Added (D2VNdir);
+
+      D2UVNdir.Subtract (DUNdir.Multiplied (DRv / R2));
+      D2UVNdir.Subtract (DVNdir.Multiplied (DRu / R2));
+      D2UVNdir.Subtract (Ndir.Multiplied (D2Ruv / R2));
+      D2UVNdir.Add (Ndir.Multiplied (3.0 * DRu * DRv / R4));
+      D2UVNdir.Multiply (offsetValue / R);
+      D2UV = D2UVbasis.Added (D2UVNdir);
+
+      DUNdir.Multiply(R);
+      DUNdir.Subtract (Ndir.Multiplied (DRu/R));
+      DUNdir.Multiply (offsetValue/R2);
+      D1U = D1Ubasis.Added (DUNdir);
+      DVNdir.Multiply(R);
+      DVNdir.Subtract (Ndir.Multiplied (DRv/R));
+      DVNdir.Multiply (offsetValue/R2);
+      D1V = D1Vbasis.Added (DVNdir);
+    }
+    else {
+      D2UNdir.Multiply (offsetValue/R);
+      D2UNdir.Subtract (DUNdir.Multiplied (2.0 * offsetValue * DRu / R3));
+      D2UNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ru / R3));
+      D2UNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRu * DRu / R5));
+      D2U = D2Ubasis.Added (D2UNdir);
+
+      D2VNdir.Multiply (offsetValue/R);
+      D2VNdir.Subtract (DVNdir.Multiplied (2.0 * offsetValue * DRv / R3));
+      D2VNdir.Subtract (Ndir.Multiplied (offsetValue * D2Rv / R3));
+      D2VNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRv * DRv / R5));
+      D2V = D2Vbasis.Added (D2VNdir);
+
+      D2UVNdir.Multiply (offsetValue/R);
+      D2UVNdir.Subtract (DUNdir.Multiplied (offsetValue * DRv / R3));
+      D2UVNdir.Subtract (DVNdir.Multiplied (offsetValue * DRu / R3));
+      D2UVNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ruv / R3));
+      D2UVNdir.Add (Ndir.Multiplied (3.0 * offsetValue * DRu * DRv / R5));
+      D2UV = D2UVbasis.Added (D2UVNdir);
+
+      DUNdir.Multiply (offsetValue / R);
+      DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3));
+      D1U = D1Ubasis.Added (DUNdir);
+      DVNdir.Multiply (offsetValue / R);
+      DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3));
+      D1V = D1Vbasis.Added (DVNdir);
+    }
+    Ndir.Multiply (offsetValue/R);
+    P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ()));
 }
 
 
@@ -709,10 +785,10 @@ Standard_Real Geom_OffsetSurface::Offset () const {
 //=======================================================================
 
 void Geom_OffsetSurface::LocalD0 (const Standard_Real    U,
-                                  const Standard_Real    V, 
-                                  const Standard_Integer USide,
-                                  const Standard_Integer VSide,
-                                 gp_Pnt&          P     )  const
+  const Standard_Real    V, 
+  const Standard_Integer USide,
+  const Standard_Integer VSide,
+  gp_Pnt&          P     )  const
 {
   if (equivSurf.IsNull()) {
     Vec D1U, D1V;
@@ -724,14 +800,14 @@ void Geom_OffsetSurface::LocalD0 (const Standard_Real    U,
     if (!RTS.IsNull()) {
       Basis = RTS->BasisSurface();
     }
-    
+
     // BSpline case 
     Handle(Geom_BSplineSurface) BSplS; 
     BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis);
     if (!BSplS.IsNull()) {
       Vec D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV; 
       LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV,
-                 D3U,D3V,D3UUV,D3UVV);
+        D3U,D3V,D3UUV,D3UVV);
       SetD0(U,V,P,D1U,D1V);
       return;
     }
@@ -754,7 +830,7 @@ void Geom_OffsetSurface::LocalD0 (const Standard_Real    U,
       SetD0(U,V, P, D1U,D1V);
       return;
     }
-    
+
     // General cases
     basisSurf->D1(U, V, P, D1U, D1V);
     SetD0(U,V, P, D1U,D1V);
@@ -769,12 +845,12 @@ void Geom_OffsetSurface::LocalD0 (const Standard_Real    U,
 //=======================================================================
 
 void Geom_OffsetSurface::LocalD1 (const Standard_Real    U, 
-                                 const Standard_Real    V,
-                                 const Standard_Integer USide, 
-                                 const Standard_Integer VSide,
-                                        gp_Pnt&          P,
-                                        gp_Vec&          D1U, 
-                                        gp_Vec&          D1V)     const
+  const Standard_Real    V,
+  const Standard_Integer USide, 
+  const Standard_Integer VSide,
+  gp_Pnt&          P,
+  gp_Vec&          D1U, 
+  gp_Vec&          D1V)     const
 {
   if (equivSurf.IsNull()) {
     Vec D2U,D2V,D2UV ;
@@ -786,14 +862,14 @@ void Geom_OffsetSurface::LocalD1 (const Standard_Real    U,
     if (!RTS.IsNull()) {
       Basis = RTS->BasisSurface();
     }
-    
+
     // BSpline case 
     Handle(Geom_BSplineSurface) BSplS; 
     BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis);
     if (!BSplS.IsNull()) {
       Vec D3U,D3V,D3UUV,D3UVV; 
       LocateSides(U,V,USide,VSide,BSplS,2,P,D1U,D1V,D2U,D2V,D2UV,
-                 D3U,D3V,D3UUV,D3UVV);
+        D3U,D3V,D3UUV,D3UVV);
       SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV);
       return;
     }
@@ -816,7 +892,7 @@ void Geom_OffsetSurface::LocalD1 (const Standard_Real    U,
       SetD1(U,V, P, D1U,D1V,D2U,D2V,D2UV);
       return;
     }
-    
+
     // General cases
     basisSurf->D2(U, V, P, D1U, D1V,D2U,D2V,D2UV);
     SetD1(U,V, P, D1U,D1V,D2U,D2V,D2UV);
@@ -831,15 +907,15 @@ void Geom_OffsetSurface::LocalD1 (const Standard_Real    U,
 //=======================================================================
 
 void Geom_OffsetSurface::LocalD2 (const Standard_Real    U,
-                                  const Standard_Real    V,
-                                  const Standard_Integer USide, 
-                                  const Standard_Integer VSide,
-                                        gp_Pnt&          P,
-                                        gp_Vec&          D1U,
-                                        gp_Vec&          D1V,
-                                        gp_Vec&          D2U,
-                                        gp_Vec&          D2V,
-                                        gp_Vec&          D2UV) const
+  const Standard_Real    V,
+  const Standard_Integer USide, 
+  const Standard_Integer VSide,
+  gp_Pnt&          P,
+  gp_Vec&          D1U,
+  gp_Vec&          D1V,
+  gp_Vec&          D2U,
+  gp_Vec&          D2V,
+  gp_Vec&          D2UV) const
 {
   if (equivSurf.IsNull()) {
     Handle(Geom_Surface) Basis = basisSurf;
@@ -851,13 +927,13 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real    U,
     if (!RTS.IsNull()) {
       Basis = RTS->BasisSurface();
     }
-    
+
     // BSpline case 
     Handle(Geom_BSplineSurface) BSplS; 
     BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis);
     if (!BSplS.IsNull()) {
       LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV,
-                 D3U,D3V,D3UUV,D3UVV);
+        D3U,D3V,D3UUV,D3UVV);
       SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
       return;
     }
@@ -868,8 +944,8 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real    U,
 
     if (!SE.IsNull()) {
       SE->LocalD3(U,V,USide,P,D1U,D1V,
-                 D2U,D2V,D2UV,
-                 D3U,D3V,D3UUV,D3UVV);
+        D2U,D2V,D2UV,
+        D3U,D3V,D3UUV,D3UVV);
       SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
       return;
     }
@@ -882,7 +958,7 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real    U,
       SetD2(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV);
       return;
     }
-    
+
     // General cases
     basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,D3U, D3V, D3UUV, D3UVV);
     SetD2(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV);
@@ -896,19 +972,19 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real    U,
 //=======================================================================
 
 void Geom_OffsetSurface::LocalD3 (const Standard_Real     U, 
-                                  const Standard_Real    V,
-                                  const Standard_Integer USide, 
-                                  const Standard_Integer VSide,
-                                        gp_Pnt&          P,
-                                        gp_Vec&          D1U,
-                                        gp_Vec&          D1V, 
-                                        gp_Vec&          D2U, 
-                                        gp_Vec&          D2V, 
-                                        gp_Vec&          D2UV, 
-                                        gp_Vec&          D3U,
-                                        gp_Vec&          D3V,
-                                        gp_Vec&          D3UUV,
-                                        gp_Vec&          D3UVV) const
+  const Standard_Real    V,
+  const Standard_Integer USide, 
+  const Standard_Integer VSide,
+  gp_Pnt&          P,
+  gp_Vec&          D1U,
+  gp_Vec&          D1V, 
+  gp_Vec&          D2U, 
+  gp_Vec&          D2V, 
+  gp_Vec&          D2UV, 
+  gp_Vec&          D3U,
+  gp_Vec&          D3V,
+  gp_Vec&          D3UUV,
+  gp_Vec&          D3UVV) const
 {
   if (equivSurf.IsNull()) {
     Handle(Geom_Surface) Basis = basisSurf;
@@ -919,13 +995,13 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real     U,
     if (!RTS.IsNull()) {
       Basis = RTS->BasisSurface();
     }
-    
+
     // BSpline case 
     Handle(Geom_BSplineSurface) BSplS; 
     BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis);
     if (!BSplS.IsNull()) {
       LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV,
-                 D3U,D3V,D3UUV,D3UVV);
+        D3U,D3V,D3UUV,D3UVV);
       SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
       return;
     }
@@ -936,8 +1012,8 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real     U,
 
     if (!SE.IsNull()) {
       SE->LocalD3(U,V,USide,P,D1U,D1V,
-                 D2U,D2V,D2UV,
-                 D3U,D3V,D3UUV,D3UVV);
+        D2U,D2V,D2UV,
+        D3U,D3V,D3UUV,D3UVV);
       SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
       return;
     }
@@ -950,7 +1026,7 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real     U,
       SetD3(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV);
       return;
     }
-    
+
     // General cases
     basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,D3U, D3V, D3UUV, D3UVV);
     SetD3(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV);
@@ -965,57 +1041,57 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real     U,
 //=======================================================================
 
 gp_Vec Geom_OffsetSurface::LocalDN  (const Standard_Real    U, 
-                                    const Standard_Real    V,
-                                    const Standard_Integer USide,
-                                    const Standard_Integer VSide,
-                                    const Standard_Integer Nu,
-                                    const Standard_Integer Nv) const
+  const Standard_Real    V,
+  const Standard_Integer USide,
+  const Standard_Integer VSide,
+  const Standard_Integer Nu,
+  const Standard_Integer Nv) const
 {  
   gp_Vec D(0,0,0);
-  
+
   if(equivSurf.IsNull()) {
 
     Vec D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV; 
     Pnt P;
     Handle(Geom_Surface) Basis = basisSurf;
-    
+
     //   if Basis is Trimmed we make the basis`s basis
     Handle(Geom_RectangularTrimmedSurface) RTS;
     RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis);
-    
+
     if (!RTS.IsNull())  {
       Basis = RTS -> BasisSurface();
     }
-    
+
     //BSpline case 
     Handle(Geom_BSplineSurface) BSplS;
     BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis);
-    
+
     if(!BSplS.IsNull()) {
       LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
       return  D = SetDN(U,V,Nu,Nv,D1U,D1V);
     }
-    
+
     //Extrusion case
     Handle( Geom_SurfaceOfLinearExtrusion) SE;
     SE = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis);
-    
+
     if(!SE.IsNull()) {
-      
+
       SE->LocalD1(U,V,USide,P,D1U,D1V);
       D = SetDN(U,V,Nu,Nv,D1U,D1V);
       return D;
     }
-    
+
     //Revolution case
     Handle(Geom_SurfaceOfRevolution) SR;
     SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis);
-    
+
     if(!SR.IsNull()) {
       D = SR->LocalDN(U,V,VSide,Nu,Nv);
       return D = SetDN(U,V,Nu,Nv,D1U,D1V);
     }
-    
+
     //General cases 
     D = basisSurf->DN(U,V,Nu,Nv);
     return D = SetDN(U,V,Nu,Nv,D1U,D1V);
@@ -1029,22 +1105,22 @@ gp_Vec Geom_OffsetSurface::LocalDN  (const Standard_Real    U,
 //purpose  : 
 //=======================================================================
 void Geom_OffsetSurface::LocateSides(const Standard_Real U,
-                                    const Standard_Real V,
-                                    const Standard_Integer USide,
-                                    const Standard_Integer VSide,
-                                    const Handle(Geom_BSplineSurface)& BSplS,
-                                    const Standard_Integer NDir,
-                                    gp_Pnt& P,
-                                    gp_Vec& D1U,gp_Vec& D1V,
-                                    gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV,
-                                    gp_Vec& D3U,gp_Vec& D3V,gp_Vec& D3UUV,gp_Vec& D3UVV   ) const
+  const Standard_Real V,
+  const Standard_Integer USide,
+  const Standard_Integer VSide,
+  const Handle(Geom_BSplineSurface)& BSplS,
+  const Standard_Integer NDir,
+  gp_Pnt& P,
+  gp_Vec& D1U,gp_Vec& D1V,
+  gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV,
+  gp_Vec& D3U,gp_Vec& D3V,gp_Vec& D3UUV,gp_Vec& D3UVV   ) const
 {
   Standard_Boolean UIsKnot=Standard_False, VIsKnot=Standard_False ;
   Standard_Integer Ideb, Ifin, IVdeb, IVfin;
   Standard_Real ParTol=Precision::PConfusion()/10.;
   BSplS->Geom_BSplineSurface::LocateU(U,ParTol,Ideb, Ifin, Standard_False); 
   BSplS->Geom_BSplineSurface::LocateV(V,ParTol,IVdeb,IVfin,Standard_False);   
+
   if(Ideb == Ifin ) { //knot
 
     if(USide == 1) {Ifin++; UIsKnot=Standard_True;}
@@ -1074,21 +1150,21 @@ void Geom_OffsetSurface::LocateSides(const Standard_Real U,
 
   if(IVfin > BSplS->LastVKnotIndex()) {IVfin = BSplS->LastVKnotIndex(); IVdeb = IVfin - 1;}
 
-    
+
   if((UIsKnot)||(VIsKnot))
     switch(NDir)
-      {
-      case 0 :  BSplS->Geom_BSplineSurface::LocalD0(U,V,Ideb,Ifin,IVdeb,IVfin,P); break;
-      case 1 :  BSplS->Geom_BSplineSurface::LocalD1(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V); break;
-      case 2 :  BSplS->Geom_BSplineSurface::LocalD2(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV); break;
-      case 3 :  BSplS->Geom_BSplineSurface::LocalD3(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;
-      }else   switch(NDir) 
-       {
-       case 0 :  basisSurf->D0(U,V,P); break;
-       case 1 :  basisSurf->D1(U,V,P,D1U,D1V); break;
-       case 2 :  basisSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); break;
-       case 3 :  basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;
-       }
+  {
+    case 0 :  BSplS->Geom_BSplineSurface::LocalD0(U,V,Ideb,Ifin,IVdeb,IVfin,P); break;
+    case 1 :  BSplS->Geom_BSplineSurface::LocalD1(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V); break;
+    case 2 :  BSplS->Geom_BSplineSurface::LocalD2(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV); break;
+    case 3 :  BSplS->Geom_BSplineSurface::LocalD3(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;
+  }else   switch(NDir) 
+  {
+  case 0 :  basisSurf->D0(U,V,P); break;
+  case 1 :  basisSurf->D1(U,V,P,D1U,D1V); break;
+  case 2 :  basisSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); break;
+  case 3 :  basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;
+  }
 }
 
 
@@ -1100,29 +1176,29 @@ void Geom_OffsetSurface::LocateSides(const Standard_Real U,
 
 class Geom_OffsetSurface_UIsoEvaluator : public AdvApprox_EvaluatorFunction
 {
- public:
+public:
   Geom_OffsetSurface_UIsoEvaluator (const Handle(Geom_Surface)& theSurface,
-                                    Standard_Real theU)
-  : CurrentSurface(theSurface), IsoPar(theU) {}
-                                      
+    Standard_Real theU)
+    : CurrentSurface(theSurface), IsoPar(theU) {}
+
   virtual void Evaluate (Standard_Integer *Dimension,
-                        Standard_Real     StartEnd[2],
-                         Standard_Real    *Parameter,
-                         Standard_Integer *DerivativeRequest,
-                         Standard_Real    *Result, // [Dimension]
-                         Standard_Integer *ErrorCode);
-  
- private:
+    Standard_Real     StartEnd[2],
+    Standard_Real    *Parameter,
+    Standard_Integer *DerivativeRequest,
+    Standard_Real    *Result, // [Dimension]
+    Standard_Integer *ErrorCode);
+
+private:
   Handle(Geom_Surface) CurrentSurface;
   Standard_Real IsoPar;
 };
 
 void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
-                                                Standard_Real     /*StartEnd*/[2],
-                                                Standard_Real    *Parameter,
-                                                Standard_Integer *DerivativeRequest,
-                                                Standard_Real    *Result,
-                                                Standard_Integer *ReturnCode) 
+  Standard_Real     /*StartEnd*/[2],
+  Standard_Real    *Parameter,
+  Standard_Integer *DerivativeRequest,
+  Standard_Real    *Result,
+  Standard_Integer *ReturnCode) 
 { 
   gp_Pnt P;
   if (*DerivativeRequest == 0) {
@@ -1141,29 +1217,29 @@ void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
 
 class Geom_OffsetSurface_VIsoEvaluator : public AdvApprox_EvaluatorFunction
 {
- public:
+public:
   Geom_OffsetSurface_VIsoEvaluator (const Handle(Geom_Surface)& theSurface,
-                                    Standard_Real theV)
-  : CurrentSurface(theSurface), IsoPar(theV) {}
-                                      
+    Standard_Real theV)
+    : CurrentSurface(theSurface), IsoPar(theV) {}
+
   virtual void Evaluate (Standard_Integer *Dimension,
-                        Standard_Real     StartEnd[2],
-                         Standard_Real    *Parameter,
-                         Standard_Integer *DerivativeRequest,
-                         Standard_Real    *Result, // [Dimension]
-                         Standard_Integer *ErrorCode);
-  
- private:
+    Standard_Real     StartEnd[2],
+    Standard_Real    *Parameter,
+    Standard_Integer *DerivativeRequest,
+    Standard_Real    *Result, // [Dimension]
+    Standard_Integer *ErrorCode);
+
+private:
   Handle(Geom_Surface) CurrentSurface;
   Standard_Real IsoPar;
 };
 
 void Geom_OffsetSurface_VIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
-                                                Standard_Real     /*StartEnd*/[2],
-                                                Standard_Real    *Parameter,
-                                                Standard_Integer *DerivativeRequest,
-                                                Standard_Real    *Result,
-                                                Standard_Integer *ReturnCode) 
+  Standard_Real     /*StartEnd*/[2],
+  Standard_Real    *Parameter,
+  Standard_Integer *DerivativeRequest,
+  Standard_Real    *Result,
+  Standard_Integer *ReturnCode) 
 { 
   gp_Pnt P;
   if (*DerivativeRequest == 0) {
@@ -1206,11 +1282,11 @@ Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const
 
     Geom_OffsetSurface_UIsoEvaluator ev (this, UU);
     AdvApprox_ApproxAFunction Approx(Num1, Num2, Num3, T1, T2, T3,
-                                     V1, V2, Cont,
-                                     MaxDeg,MaxSeg, ev);
+      V1, V2, Cont,
+      MaxDeg,MaxSeg, ev);
 
     Standard_ConstructionError_Raise_if (!Approx.IsDone(),
-                                         " Geom_OffsetSurface : UIso");
+      " Geom_OffsetSurface : UIso");
 
     Standard_Integer NbPoles = Approx.NbPoles();
 
@@ -1238,14 +1314,14 @@ Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const
 
 void Geom_OffsetSurface::Value 
   ( const Standard_Real U,  const Standard_Real V,
-//          Pnt& P,        Pnt& Pbasis, 
-          Pnt& P,        Pnt& , 
-          Vec& D1Ubasis, Vec& D1Vbasis) const {
+  //          Pnt& P,        Pnt& Pbasis, 
+  Pnt& P,        Pnt& , 
+  Vec& D1Ubasis, Vec& D1Vbasis) const {
 
-  if (basisSurf->Continuity() == GeomAbs_C0)  
-    Geom_UndefinedValue::Raise();
-  
-  SetD0(U,V,P,D1Ubasis,D1Vbasis);
+    if (myBasisSurfContinuity == GeomAbs_C0)  
+      Geom_UndefinedValue::Raise();
+
+    SetD0(U,V,P,D1Ubasis,D1Vbasis);
 }
 
 
@@ -1273,10 +1349,10 @@ Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const
 
     Geom_OffsetSurface_VIsoEvaluator ev (this, VV);
     AdvApprox_ApproxAFunction Approx (Num1, Num2, Num3, T1, T2, T3,
-                                      U1, U2, Cont, MaxDeg, MaxSeg, ev);
+      U1, U2, Cont, MaxDeg, MaxSeg, ev);
 
     Standard_ConstructionError_Raise_if (!Approx.IsDone(),
-                                         " Geom_OffsetSurface : VIso");
+      " Geom_OffsetSurface : VIso");
 
     TColgp_Array1OfPnt      Poles( 1, Approx.NbPoles());
     TColStd_Array1OfReal    Knots( 1, Approx.NbKnots());
@@ -1302,8 +1378,8 @@ Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const
 
 Standard_Boolean Geom_OffsetSurface::IsCNu (const Standard_Integer N) const {
 
-   Standard_RangeError_Raise_if (N < 0, " ");
-   return basisSurf->IsCNu (N+1);
+  Standard_RangeError_Raise_if (N < 0, " ");
+  return basisSurf->IsCNu (N+1);
 }
 
 
@@ -1383,7 +1459,7 @@ Standard_Boolean Geom_OffsetSurface::IsUClosed () const {
     }
     else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { 
       Handle(Geom_SurfaceOfLinearExtrusion) Extru = 
-       Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S);
+        Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S);
 
       Handle(Curve) C = Extru->BasisCurve();
       if (C->IsKind (STANDARD_TYPE(Geom_Circle)) || C->IsKind (STANDARD_TYPE(Geom_Ellipse))) {
@@ -1402,7 +1478,7 @@ Standard_Boolean Geom_OffsetSurface::IsUClosed () const {
     }
     else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { 
       Handle(Geom_SurfaceOfLinearExtrusion) Extru = 
-       Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis);
+        Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis);
 
       Handle(Curve) C = Extru->BasisCurve();
       UClosed = (C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse)));
@@ -1453,9 +1529,9 @@ Standard_Boolean Geom_OffsetSurface::IsVClosed () const {
 
 void Geom_OffsetSurface::Transform (const Trsf& T) 
 {
-   basisSurf->Transform (T);
-   offsetValue *= T.ScaleFactor();
-   equivSurf.Nullify();
+  basisSurf->Transform (T);
+  offsetValue *= T.ScaleFactor();
+  equivSurf.Nullify();
 }
 
 //=======================================================================
@@ -1464,9 +1540,9 @@ void Geom_OffsetSurface::Transform (const Trsf& T)
 //=======================================================================
 
 void Geom_OffsetSurface::TransformParameters(Standard_Real& U,
-                                            Standard_Real& V,
-                                            const gp_Trsf& T) 
-const
+  Standard_Real& V,
+  const gp_Trsf& T) 
+  const
 {
   basisSurf->TransformParameters(U,V,T);
   if(!equivSurf.IsNull()) equivSurf->TransformParameters(U,V,T);
@@ -1478,7 +1554,7 @@ const
 //=======================================================================
 
 gp_GTrsf2d Geom_OffsetSurface::ParametricTransformation
-(const gp_Trsf& T) const
+  (const gp_Trsf& T) const
 {
   return basisSurf->ParametricTransformation(T);
 }
@@ -1508,13 +1584,13 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
     S->Bounds(U1,U2,V1,V2);  
     IsTrimmed = Standard_True;
   }
-   else {
-     IsTrimmed = Standard_False;
-     Base = basisSurf;
-   }
+  else {
+    IsTrimmed = Standard_False;
+    Base = basisSurf;
+  }
 
   // Traite les surfaces cannonique
-    if (TheType == STANDARD_TYPE(Geom_Plane)) 
+  if (TheType == STANDARD_TYPE(Geom_Plane)) 
   {
     Handle(Geom_Plane) P =
       Handle(Geom_Plane)::DownCast(Base);
@@ -1542,7 +1618,7 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
     }
     else 
     {
-// surface degeneree      
+      // surface degeneree      
     }
   }
   else if (TheType == STANDARD_TYPE(Geom_ConicalSurface)) 
@@ -1560,7 +1636,7 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
     }
     else 
     {
-// surface degeneree      
+      // surface degeneree      
     }
   }
   else if (TheType == STANDARD_TYPE(Geom_SphericalSurface)) {
@@ -1582,7 +1658,7 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
       Result->UReverse();
     }
     else {
-//      surface degeneree
+      //      surface degeneree
     }
   }
   else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface)) 
@@ -1596,16 +1672,16 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
     if (MinorRadius <= MajorRadius) 
     {  
       if (Axis.Direct())
-       MinorRadius += offsetValue;
+        MinorRadius += offsetValue;
       else 
-       MinorRadius -= offsetValue;
+        MinorRadius -= offsetValue;
       if (MinorRadius >= Tol) 
-       Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius);
-//      else if (MinorRadius <= -Tol) 
-//        Result->UReverse();
+        Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius);
+      //      else if (MinorRadius <= -Tol) 
+      //        Result->UReverse();
       else 
       {
-//     surface degeneree
+        //     surface degeneree
       }
     }
   }
@@ -1620,17 +1696,17 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
 }
 
 Standard_Boolean Geom_OffsetSurface::UOsculatingSurface(const Standard_Real U,
-                                                       const Standard_Real V,
-                                                       Standard_Boolean& t,
-                                                       Handle(Geom_BSplineSurface)& L) const
+  const Standard_Real V,
+  Standard_Boolean& t,
+  Handle(Geom_BSplineSurface)& L) const
 {
   return myOscSurf.UOscSurf(U,V,t,L);
 }
 
 Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U,
-                                                       const Standard_Real V,
-                                                       Standard_Boolean& t,
-                                                       Handle(Geom_BSplineSurface)& L) const
+  const Standard_Real V,
+  Standard_Boolean& t,
+  Handle(Geom_BSplineSurface)& L) const
 {
   return myOscSurf.VOscSurf(U,V,t,L);
 }
@@ -1641,11 +1717,11 @@ Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U,
 //purpose  : private
 //=======================================================================
 void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V, 
-                              Pnt& P,
-                              const Vec& D1U, const Vec& D1V)const 
+  Pnt& P,
+  const Vec& D1U, const Vec& D1V)const 
 {
   Standard_Boolean AlongU = Standard_False,
-                   AlongV = Standard_False;
+    AlongV = Standard_False;
   Handle(Geom_BSplineSurface) L;
   Standard_Boolean IsOpposite=Standard_False;
   Standard_Real signe = 1.;
@@ -1659,28 +1735,28 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
   CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
 
   if (NStatus == CSLib_Defined) // akm - only in singularities && !AlongU && !AlongV) 
-    {
-      P.SetXYZ(P.XYZ() + offsetValue * Normal.XYZ());
-    }
+  {
+    P.SetXYZ(P.XYZ() + offsetValue * Normal.XYZ());
+  }
   else 
-    {
-      Standard_Integer MaxOrder=3;
-      TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder);
-      TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1);
-      Standard_Integer OrderU,OrderV;
-      Standard_Real Umin,Umax,Vmin,Vmax;
-      Bounds(Umin,Umax,Vmin,Vmax);
-      DerSurf.SetValue(1, 0, D1U);
-      DerSurf.SetValue(0, 1, D1V);
-      derivatives(MaxOrder,1,U,V,basisSurf,0,0,AlongU,AlongV,L,DerNUV,DerSurf);
-      
-      CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
-      if (NStatus == CSLib_Defined) 
-       P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
-      else 
-       Geom_UndefinedValue::Raise();
-      
-    }
+  {
+    Standard_Integer MaxOrder=3;
+    TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder);
+    TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1);
+    Standard_Integer OrderU,OrderV;
+    Standard_Real Umin,Umax,Vmin,Vmax;
+    Bounds(Umin,Umax,Vmin,Vmax);
+    DerSurf.SetValue(1, 0, D1U);
+    DerSurf.SetValue(0, 1, D1V);
+    derivatives(MaxOrder,1,U,V,basisSurf,0,0,AlongU,AlongV,L,DerNUV,DerSurf);
+
+    CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
+    if (NStatus == CSLib_Defined) 
+      P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
+    else 
+      Geom_UndefinedValue::Raise();
+
+  }
 }
 
 //=======================================================================
@@ -1688,11 +1764,11 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
 //purpose  : private
 //=======================================================================/
 void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V, 
-                              Pnt& P, 
-                              Vec& D1U, Vec& D1V,
-                              const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const
+  Pnt& P, 
+  Vec& D1U, Vec& D1V,
+  const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const
 {
-  
+
   Standard_Real MagTol=0.000000001;
   Dir Normal;
   CSLib_NormalStatus NStatus;
@@ -1714,24 +1790,24 @@ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
   DerSurf.SetValue(0, 2, d2v);
   Handle(Geom_BSplineSurface) L;
   Standard_Boolean AlongU = Standard_False,
-  AlongV = Standard_False;
+    AlongV = Standard_False;
   Standard_Boolean IsOpposite=Standard_False;
   Standard_Real signe = 1.;
   AlongU = UOsculatingSurface(U,V,IsOpposite,L); 
   AlongV = VOsculatingSurface(U,V,IsOpposite,L);
   if ((AlongV || AlongU) && IsOpposite) signe = -1;
   derivatives(MaxOrder,2,U,V,basisSurf,1,1,AlongU,AlongV,L,DerNUV,DerSurf);
-  
+
   CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
   if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
-  
+
   P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
-  
+
   D1U = DerSurf(1,0)
     + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
   D1V = DerSurf(0,1)
     + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
-  
+
 }
 
 //=======================================================================
@@ -1739,11 +1815,11 @@ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
 //purpose  : private
 //=======================================================================/
 void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V, 
-                              Pnt& P, 
-                              Vec& D1U, Vec& D1V,
-                              Vec& D2U, Vec& D2V, Vec& D2UV,
-                              const Vec& d3u, const Vec& d3v,
-                              const Vec& d3uuv, const Vec& d3uvv  ) const 
+  Pnt& P, 
+  Vec& D1U, Vec& D1V,
+  Vec& D2U, Vec& D2V, Vec& D2UV,
+  const Vec& d3u, const Vec& d3v,
+  const Vec& d3uuv, const Vec& d3uvv  ) const 
 {
   Standard_Real MagTol=0.000000001;
   Dir Normal;
@@ -1769,28 +1845,28 @@ void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V,
   DerSurf.SetValue(1, 2, d3uvv);
   DerSurf.SetValue(0, 3, d3v);
   //*********************
-  
+
   Handle(Geom_BSplineSurface) L;
   Standard_Boolean AlongU = Standard_False,
-  AlongV = Standard_False;
+    AlongV = Standard_False;
   Standard_Boolean IsOpposite=Standard_False;
   Standard_Real signe = 1.;
   AlongU = UOsculatingSurface(U,V,IsOpposite,L); 
   AlongV = VOsculatingSurface(U,V,IsOpposite,L);
   if ((AlongV || AlongU) && IsOpposite) signe = -1;    
   derivatives(MaxOrder,3,U,V,basisSurf,2,2,AlongU,AlongV,L,DerNUV,DerSurf);
-  
+
   CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
   if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
-  
-  
+
+
   P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
-  
+
   D1U = DerSurf(1,0)
     + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
   D1V = DerSurf(0,1)
     + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
+
   D2U = basisSurf->DN(U,V,2,0) 
     + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV);
   D2V = basisSurf->DN(U,V,0,2)     
@@ -1805,10 +1881,10 @@ void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V,
 //purpose  : private
 //=======================================================================/
 void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V, 
-                              Pnt& P, 
-                              Vec& D1U, Vec& D1V, 
-                              Vec& D2U, Vec& D2V, Vec& D2UV,
-                              Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const 
+  Pnt& P, 
+  Vec& D1U, Vec& D1V, 
+  Vec& D2U, Vec& D2V, Vec& D2UV,
+  Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const 
 {
   Standard_Real MagTol=0.000000001;
   Dir Normal;
@@ -1824,7 +1900,7 @@ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V,
   TColgp_Array2OfVec DerSurf(0,MaxOrder+4,0,MaxOrder+4);
   Standard_Real Umin,Umax,Vmin,Vmax;
   Bounds(Umin,Umax,Vmin,Vmax);
-  
+
   DerSurf.SetValue(1, 0, D1U);
   DerSurf.SetValue(0, 1, D1V);
   DerSurf.SetValue(1, 1, D2UV);
@@ -1834,30 +1910,30 @@ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V,
   DerSurf.SetValue(2, 1, D3UUV);
   DerSurf.SetValue(1, 2, D3UVV);
   DerSurf.SetValue(0, 3, D3V);
-  
-  
+
+
   //*********************
   Handle(Geom_BSplineSurface) L;
   Standard_Boolean AlongU = Standard_False,
-  AlongV = Standard_False;
+    AlongV = Standard_False;
   Standard_Boolean IsOpposite=Standard_False;
   Standard_Real signe = 1.;
   AlongU = UOsculatingSurface(U,V,IsOpposite,L); 
   AlongV = VOsculatingSurface(U,V,IsOpposite,L);
   if ((AlongV || AlongU) && IsOpposite) signe = -1;
   derivatives(MaxOrder,3,U,V,basisSurf,3,3,AlongU,AlongV,L,DerNUV,DerSurf);
-  
+
   CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
   if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
-  
-  
+
+
   P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
-  
+
   D1U = DerSurf(1,0)
     + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
   D1V = DerSurf(0,1)
     + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
-  
+
   D2U = basisSurf->DN(U,V,2,0) 
     + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV);
   D2V = basisSurf->DN(U,V,0,2)     
@@ -1881,8 +1957,8 @@ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V,
 //=======================================================================
 
 Vec Geom_OffsetSurface::SetDN ( const Standard_Real    U , const Standard_Real    V, 
-                              const Standard_Integer Nu, const Standard_Integer Nv,
-                              const Vec& D1U, const Vec& D1V) const 
+  const Standard_Integer Nu, const Standard_Integer Nv,
+  const Vec& D1U, const Vec& D1V) const 
 {
   gp_Vec D(0,0,0);
   Standard_Real MagTol=0.000000001;
@@ -1899,7 +1975,7 @@ Vec Geom_OffsetSurface::SetDN ( const Standard_Real    U , const Standard_Real
   TColgp_Array2OfVec DerSurf(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1);
   Standard_Real Umin,Umax,Vmin,Vmax;
   Bounds(Umin,Umax,Vmin,Vmax);
-  
+
   DerSurf.SetValue(1, 0, D1U);
   DerSurf.SetValue(0, 1, D1V);
   //*********************
@@ -1910,15 +1986,23 @@ Vec Geom_OffsetSurface::SetDN ( const Standard_Real    U , const Standard_Real
   Standard_Real signe = 1.;
   AlongU = UOsculatingSurface(U,V,IsOpposite,L); 
   AlongV = VOsculatingSurface(U,V,IsOpposite,L);
-     if ((AlongV || AlongU) && IsOpposite) signe = -1;
+  if ((AlongV || AlongU) && IsOpposite) signe = -1;
   derivatives(MaxOrder,1,U,V,basisSurf,Nu,Nv,AlongU,AlongV,L,DerNUV,DerSurf);
-  
+
   CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
   if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
-  
+
   D = basisSurf->DN(U,V,Nu,Nv)
     + signe * offsetValue * CSLib::DNNormal(Nu,Nv,DerNUV,OrderU,OrderV);
+
   return D;
 }
 
+//=======================================================================
+//function : GetBasisCurveContinuity
+//purpose  : 
+//=======================================================================
+GeomAbs_Shape Geom_OffsetSurface::GetBasisSurfContinuity() const
+{
+  return myBasisSurfContinuity;
+}
index cc09d95..cd2ab0a 100644 (file)
@@ -33,7 +33,7 @@
 //=======================================================================
 
 Geom_OsculatingSurface::Geom_OsculatingSurface()
-: myAlong(1,4)
+  : myAlong(1,4)
 {
 }
 //=======================================================================
@@ -42,8 +42,8 @@ Geom_OsculatingSurface::Geom_OsculatingSurface()
 //=======================================================================
 
 Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS, 
-                                               const Standard_Real Tol)
-: myAlong(1,4)
+  const Standard_Real Tol)
+  : myAlong(1,4)
 {
   Init(BS,Tol);
 }
@@ -54,7 +54,7 @@ Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS,
 //=======================================================================
 
 void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS,
-                                  const Standard_Real Tol)
+  const Standard_Real Tol)
 {
   ClearOsculFlags();
   myTol=Tol; 
@@ -64,232 +64,232 @@ void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS,
   myOsculSurf1 = new Geom_HSequenceOfBSplineSurface();
   myOsculSurf2 = new Geom_HSequenceOfBSplineSurface();
   if ((BS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) || 
-      (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) 
-    {
-      Standard_Real U1=0,U2=0,V1=0,V2=0;
-      
-      Standard_Integer i = 1;
-      BS->Bounds(U1,U2,V1,V2);
-      myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol));
-      myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol));
-      myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol));
-      myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol));
+    (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) 
+  {
+    Standard_Real U1=0,U2=0,V1=0,V2=0;
+
+    Standard_Integer i = 1;
+    BS->Bounds(U1,U2,V1,V2);
+    myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol));
+    myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol));
+    myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol));
+    myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol));
 #ifdef OCCT_DEBUG
-      cout<<myAlong(1)<<endl<<myAlong(2)<<endl<<myAlong(3)<<endl<<myAlong(4)<<endl;
+    cout<<myAlong(1)<<endl<<myAlong(2)<<endl<<myAlong(3)<<endl<<myAlong(4)<<endl;
 #endif
-      if (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)) 
-       {
-         Handle(Geom_BSplineSurface) InitSurf, L,S;
-         if (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) 
-           {
-             Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS);
-             TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles());
-             TColStd_Array1OfReal UKnots(1,2);
-             TColStd_Array1OfReal VKnots(1,2);
-             TColStd_Array1OfInteger UMults(1,2);
-             TColStd_Array1OfInteger VMults(1,2);
-             for (i=1;i<=2;i++)
-               {
-                 UKnots.SetValue(i,(i-1));
-                 VKnots.SetValue(i,(i-1));
-                 UMults.SetValue(i,BzS->UDegree()+1);
-                 VMults.SetValue(i,BzS->VDegree()+1);
-               }
-             BzS->Poles(P);
-             InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots,
-                                                UMults,VMults,
-                                                BzS->UDegree(),
-                                                BzS->VDegree(),
-                                                BzS->IsUPeriodic(),
-                                                BzS->IsVPeriodic());
-           }
-         else 
-           {
-             InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf);
-           }
+    if (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)) 
+    {
+      Handle(Geom_BSplineSurface) InitSurf, L,S;
+      if (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) 
+      {
+        Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS);
+        TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles());
+        TColStd_Array1OfReal UKnots(1,2);
+        TColStd_Array1OfReal VKnots(1,2);
+        TColStd_Array1OfInteger UMults(1,2);
+        TColStd_Array1OfInteger VMults(1,2);
+        for (i=1;i<=2;i++)
+        {
+          UKnots.SetValue(i,(i-1));
+          VKnots.SetValue(i,(i-1));
+          UMults.SetValue(i,BzS->UDegree()+1);
+          VMults.SetValue(i,BzS->VDegree()+1);
+        }
+        BzS->Poles(P);
+        InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots,
+          UMults,VMults,
+          BzS->UDegree(),
+          BzS->VDegree(),
+          BzS->IsUPeriodic(),
+          BzS->IsVPeriodic());
+      }
+      else 
+      {
+        InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf);
+      }
 #ifdef OCCT_DEBUG
-         cout<<"UDEG: "<<InitSurf->UDegree()<<endl;
-         cout<<"VDEG: "<<InitSurf->VDegree()<<endl;
+      cout<<"UDEG: "<<InitSurf->UDegree()<<endl;
+      cout<<"VDEG: "<<InitSurf->VDegree()<<endl;
 #endif
-         
-         if(IsAlongU() && IsAlongV()) ClearOsculFlags();
-         //      Standard_ConstructionError_Raise_if((IsAlongU() && IsAlongV()),"Geom_OsculatingSurface");
-         if ((IsAlongU() && InitSurf->VDegree()>1) ||
-             (IsAlongV() && InitSurf->UDegree()>1)) 
-           {
-             myKdeg = new TColStd_HSequenceOfInteger();
-             Standard_Integer k=0;
-             Standard_Boolean IsQPunc;
-             Standard_Integer UKnot,VKnot;
-             if (myAlong(1) || myAlong(2)) 
-               {
-                 for (i=1;i<InitSurf->NbUKnots();i++) 
-                   {
-                     if (myAlong(1)) 
-                       {
-                         S = InitSurf; k=0; IsQPunc=Standard_True;
-                         UKnot=i;
-                         VKnot=1;
-                         while(IsQPunc) 
-                           {
-                             OsculSurf  = BuildOsculatingSurface(V1,UKnot,VKnot,S,L);
-                             if(!OsculSurf) break;
-                             k++;
+
+      if(IsAlongU() && IsAlongV()) ClearOsculFlags();
+      //      Standard_ConstructionError_Raise_if((IsAlongU() && IsAlongV()),"Geom_OsculatingSurface");
+      if ((IsAlongU() && InitSurf->VDegree()>1) ||
+        (IsAlongV() && InitSurf->UDegree()>1)) 
+      {
+        myKdeg = new TColStd_HSequenceOfInteger();
+        Standard_Integer k=0;
+        Standard_Boolean IsQPunc;
+        Standard_Integer UKnot,VKnot;
+        if (myAlong(1) || myAlong(2)) 
+        {
+          for (i=1;i<InitSurf->NbUKnots();i++) 
+          {
+            if (myAlong(1)) 
+            {
+              S = InitSurf; k=0; IsQPunc=Standard_True;
+              UKnot=i;
+              VKnot=1;
+              while(IsQPunc) 
+              {
+                OsculSurf  = BuildOsculatingSurface(V1,UKnot,VKnot,S,L);
+                if(!OsculSurf) break;
+                k++;
 #ifdef OCCT_DEBUG
-                             cout<<"1.k = "<<k<<endl;
+                cout<<"1.k = "<<k<<endl;
 #endif
-                             IsQPunc=IsQPunctual(L,V1,GeomAbs_IsoV,0.,Tol);
-                             UKnot=1;
-                             VKnot=1;
-                             S=L;
-                             
-                           }
-                         if (OsculSurf)
-                           myOsculSurf1->Append(L);
-                         else
-                           ClearOsculFlags(); //myAlong.SetValue(1,Standard_False);
-                         if (myAlong(2) && OsculSurf) 
-                           {
-                             S = InitSurf; k=0; IsQPunc=Standard_True;
-                             UKnot=i;
-                             VKnot=InitSurf->NbVKnots()-1;
-                             
-                             while(IsQPunc) 
-                               {
-                                 OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
-                                 if(!OsculSurf) break;
-                                 k++;
+                IsQPunc=IsQPunctual(L,V1,GeomAbs_IsoV,0.,Tol);
+                UKnot=1;
+                VKnot=1;
+                S=L;
+
+              }
+              if (OsculSurf)
+                myOsculSurf1->Append(L);
+              else
+                ClearOsculFlags(); //myAlong.SetValue(1,Standard_False);
+              if (myAlong(2) && OsculSurf) 
+              {
+                S = InitSurf; k=0; IsQPunc=Standard_True;
+                UKnot=i;
+                VKnot=InitSurf->NbVKnots()-1;
+
+                while(IsQPunc) 
+                {
+                  OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
+                  if(!OsculSurf) break;
+                  k++;
 #ifdef OCCT_DEBUG
-                                 cout<<"2.k = "<<k<<endl;
+                  cout<<"2.k = "<<k<<endl;
 #endif
-                                 IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
-                                 UKnot=1;
-                                 VKnot=1;
-                                 S=L;
-                               }
-                             if(OsculSurf)
-                               {
-                                 myOsculSurf2->Append(L);
-                                 myKdeg->Append(k);
-                               }
-                           } 
-                       }
-                     else 
-                       //if (myAlong(2)) 
-                       {
-                         S = InitSurf; k=0; IsQPunc=Standard_True;
-                         UKnot=i;
-                         VKnot=InitSurf->NbVKnots()-1;
-                         while(IsQPunc) 
-                           {
-                             OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
-                             if(!OsculSurf) break;
-                             k++;
+                  IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
+                  UKnot=1;
+                  VKnot=1;
+                  S=L;
+                }
+                if(OsculSurf)
+                {
+                  myOsculSurf2->Append(L);
+                  myKdeg->Append(k);
+                }
+              } 
+            }
+            else 
+              //if (myAlong(2)) 
+            {
+              S = InitSurf; k=0; IsQPunc=Standard_True;
+              UKnot=i;
+              VKnot=InitSurf->NbVKnots()-1;
+              while(IsQPunc) 
+              {
+                OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
+                if(!OsculSurf) break;
+                k++;
 #ifdef OCCT_DEBUG
-                             cout<<"2.k = "<<k<<endl;
+                cout<<"2.k = "<<k<<endl;
 #endif
-                             IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
-                             UKnot=1;
-                             VKnot=1;
-                             S=L;
-                             
-                           }
-                         if(OsculSurf)
-                           {
-                             myOsculSurf2->Append(L);
-                             myKdeg->Append(k);
-                           }
-                         else
-                           ClearOsculFlags(); //myAlong.SetValue(2,Standard_False);
-                       }
-                   }
-               }
-             if (myAlong(3) || myAlong(4)) 
-               {
-                 for (i=1;i<InitSurf->NbVKnots();i++) 
-                   {
-                     if (myAlong(3)) 
-                       {
-                         S = InitSurf; k=0; IsQPunc=Standard_True;
-                         UKnot=1;
-                         VKnot=i;
-                         while(IsQPunc) 
-                           {
-                             OsculSurf = BuildOsculatingSurface(U1,UKnot,VKnot,S,L);
-                             if(!OsculSurf) break;
-                             k++;
+                IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
+                UKnot=1;
+                VKnot=1;
+                S=L;
+
+              }
+              if(OsculSurf)
+              {
+                myOsculSurf2->Append(L);
+                myKdeg->Append(k);
+              }
+              else
+                ClearOsculFlags(); //myAlong.SetValue(2,Standard_False);
+            }
+          }
+        }
+        if (myAlong(3) || myAlong(4)) 
+        {
+          for (i=1;i<InitSurf->NbVKnots();i++) 
+          {
+            if (myAlong(3)) 
+            {
+              S = InitSurf; k=0; IsQPunc=Standard_True;
+              UKnot=1;
+              VKnot=i;
+              while(IsQPunc) 
+              {
+                OsculSurf = BuildOsculatingSurface(U1,UKnot,VKnot,S,L);
+                if(!OsculSurf) break;
+                k++;
 #ifdef OCCT_DEBUG
-                             cout<<"1.k = "<<k<<endl;
+                cout<<"1.k = "<<k<<endl;
 #endif
-                             IsQPunc=IsQPunctual(L,U1,GeomAbs_IsoU,0.,Tol);
-                             UKnot=1;
-                             VKnot=1;
-                             S=L;
-                           }
-                         if(OsculSurf)
-                           myOsculSurf1->Append(L);
-                         else
-                           ClearOsculFlags(); //myAlong.SetValue(3,Standard_False);
-                         if (myAlong(4) && OsculSurf )
-                           {
-                             S = InitSurf; k=0; IsQPunc=Standard_True;
-                             UKnot=InitSurf->NbUKnots()-1;
-                             VKnot=i;
-                             while(IsQPunc) 
-                               {
-                                 OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
-                                 if(!OsculSurf) break;
-                                 k++;
+                IsQPunc=IsQPunctual(L,U1,GeomAbs_IsoU,0.,Tol);
+                UKnot=1;
+                VKnot=1;
+                S=L;
+              }
+              if(OsculSurf)
+                myOsculSurf1->Append(L);
+              else
+                ClearOsculFlags(); //myAlong.SetValue(3,Standard_False);
+              if (myAlong(4) && OsculSurf )
+              {
+                S = InitSurf; k=0; IsQPunc=Standard_True;
+                UKnot=InitSurf->NbUKnots()-1;
+                VKnot=i;
+                while(IsQPunc) 
+                {
+                  OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
+                  if(!OsculSurf) break;
+                  k++;
 #ifdef OCCT_DEBUG
-                                 cout<<"2.k = "<<k<<endl;
+                  cout<<"2.k = "<<k<<endl;
 #endif
-                                 IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
-                                 UKnot=1;
-                                 VKnot=1;
-                                 S=L;
-                               }
-                             if(OsculSurf)
-                               {
-                                 myOsculSurf2->Append(L);
-                                 myKdeg->Append(k);
-                               }
-                           }
-                       }
-                     else 
-                       {
-                         S = InitSurf; k=0; IsQPunc=Standard_True;
-                         UKnot=InitSurf->NbUKnots()-1;
-                         VKnot=i;
-                         while(IsQPunc) 
-                           {
-                             OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
-                             if(!OsculSurf) break;
-                             k++;
+                  IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
+                  UKnot=1;
+                  VKnot=1;
+                  S=L;
+                }
+                if(OsculSurf)
+                {
+                  myOsculSurf2->Append(L);
+                  myKdeg->Append(k);
+                }
+              }
+            }
+            else 
+            {
+              S = InitSurf; k=0; IsQPunc=Standard_True;
+              UKnot=InitSurf->NbUKnots()-1;
+              VKnot=i;
+              while(IsQPunc) 
+              {
+                OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
+                if(!OsculSurf) break;
+                k++;
 #ifdef OCCT_DEBUG
-                             cout<<"2.k = "<<k<<endl;
+                cout<<"2.k = "<<k<<endl;
 #endif
-                             IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
-                             UKnot=1;
-                             VKnot=1;
-                             S=L;
-                           }
-                         if(OsculSurf)
-                           {
-                             myOsculSurf2->Append(L);
-                             myKdeg->Append(k);
-                           }
-                         else
-                           ClearOsculFlags(); //myAlong.SetValue(4,Standard_False);
-                       }
-                   }
-               }
-           }
-         else
-           {
-             ClearOsculFlags();
-           } 
-       }
+                IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
+                UKnot=1;
+                VKnot=1;
+                S=L;
+              }
+              if(OsculSurf)
+              {
+                myOsculSurf2->Append(L);
+                myKdeg->Append(k);
+              }
+              else
+                ClearOsculFlags(); //myAlong.SetValue(4,Standard_False);
+            }
+          }
+        }
+      }
+      else
+      {
+        ClearOsculFlags();
+      } 
     }
+  }
   else
     ClearOsculFlags();
 }
@@ -299,7 +299,7 @@ void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS,
 //purpose  : 
 //=======================================================================
 
- Handle(Geom_Surface) Geom_OsculatingSurface::BasisSurface() const
+Handle(Geom_Surface) Geom_OsculatingSurface::BasisSurface() const
 {
   return myBasisSurf;
 }
@@ -320,10 +320,10 @@ Standard_Real Geom_OsculatingSurface::Tolerance() const
 //=======================================================================
 
 Standard_Boolean Geom_OsculatingSurface::UOscSurf
-                  (const Standard_Real U,
-                   const Standard_Real V,
-                   Standard_Boolean& t,
-                   Handle(Geom_BSplineSurface)& L) const
+  (const Standard_Real U,
+  const Standard_Real V,
+  Standard_Boolean& t,
+  Handle(Geom_BSplineSurface)& L) const
 {
   Standard_Boolean along = Standard_False;
   if (myAlong(1) || myAlong(2)) 
@@ -337,7 +337,7 @@ Standard_Boolean Geom_OsculatingSurface::UOscSurf
     if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) 
     {
       Handle(Geom_BSplineSurface) BSur = 
-              *((Handle(Geom_BSplineSurface)*)& myBasisSurf);
+        *((Handle(Geom_BSplineSurface)*)& myBasisSurf);
       NbUK = BSur->NbUKnots();
       NbVK = BSur->NbVKnots();
       TColStd_Array1OfReal UKnots(1,NbUK);
@@ -349,9 +349,9 @@ Standard_Boolean Geom_OsculatingSurface::UOscSurf
       if (NU < 1) NU=1;
       if (NU >= NbUK) NU=NbUK-1;
       if (NbVK==2 && NV==1)
-       // Need to find the closest end
-       if (VKnots(NbVK)-V > V-VKnots(1))
-         isToSkipSecond = Standard_True;
+        // Need to find the closest end
+        if (VKnots(NbVK)-V > V-VKnots(1))
+          isToSkipSecond = Standard_True;
     }
     else {NU = 1; NV = 1 ; NbVK = 2 ;}
 
@@ -379,10 +379,10 @@ Standard_Boolean Geom_OsculatingSurface::UOscSurf
 //=======================================================================
 
 Standard_Boolean Geom_OsculatingSurface::VOscSurf
-                  (const Standard_Real U,
-                   const Standard_Real V,
-                   Standard_Boolean& t,
-                   Handle(Geom_BSplineSurface)& L) const
+  (const Standard_Real U,
+  const Standard_Real V,
+  Standard_Boolean& t,
+  Handle(Geom_BSplineSurface)& L) const
 {
   Standard_Boolean along = Standard_False;
   if (myAlong(3) || myAlong(4)) 
@@ -396,7 +396,7 @@ Standard_Boolean Geom_OsculatingSurface::VOscSurf
     if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) 
     {
       Handle(Geom_BSplineSurface) BSur = 
-                    *((Handle(Geom_BSplineSurface)*)& myBasisSurf);
+        *((Handle(Geom_BSplineSurface)*)& myBasisSurf);
       NbUK = BSur->NbUKnots();
       NbVK = BSur->NbVKnots();
       TColStd_Array1OfReal UKnots(1,NbUK);
@@ -408,9 +408,9 @@ Standard_Boolean Geom_OsculatingSurface::VOscSurf
       if (NV < 1) NV=1;
       if (NV >= NbVK) NV=NbVK-1;
       if (NbUK==2 && NU==1)
-       // Need to find the closest end
-       if (UKnots(NbUK)-U > U-UKnots(1))
-         isToSkipSecond = Standard_True;
+        // Need to find the closest end
+        if (UKnots(NbUK)-U > U-UKnots(1))
+          isToSkipSecond = Standard_True;
     }
     else {NU = 1; NV = 1 ; NbUK = 2;}
 
@@ -435,11 +435,11 @@ Standard_Boolean Geom_OsculatingSurface::VOscSurf
 //=======================================================================
 
 Standard_Boolean  Geom_OsculatingSurface::BuildOsculatingSurface
-       (const Standard_Real Param,
-       const Standard_Integer SUKnot,
-       const Standard_Integer SVKnot,
-       const Handle(Geom_BSplineSurface)& BS,
-        Handle(Geom_BSplineSurface)& BSpl) const
+  (const Standard_Real Param,
+  const Standard_Integer SUKnot,
+  const Standard_Integer SVKnot,
+  const Handle(Geom_BSplineSurface)& BS,
+  Handle(Geom_BSplineSurface)& BSpl) const
 {
   Standard_Integer i, j;
   Standard_Boolean OsculSurf=Standard_True;
@@ -448,210 +448,233 @@ Standard_Boolean  Geom_OsculatingSurface::BuildOsculatingSurface
   cout<<"======================================"<<endl<<endl;
 #endif
 
-// for cache
+  // for cache
   Standard_Integer MinDegree,
-                  MaxDegree ;
+    MaxDegree ;
   Standard_Real udeg, vdeg;
   udeg = BS->UDegree();
   vdeg = BS->VDegree();
   if( (IsAlongU() && vdeg <=1) || (IsAlongV() && udeg <=1))
   {
 #ifdef OCCT_DEBUG
-      cout<<" surface osculatrice nulle "<<endl;
+    cout<<" surface osculatrice nulle "<<endl;
 #endif
-      //Standard_ConstructionError::Raise("Geom_OsculatingSurface");
-      OsculSurf=Standard_False;
+    //Standard_ConstructionError::Raise("Geom_OsculatingSurface");
+    OsculSurf=Standard_False;
   }
   else
   {
-      MinDegree = (Standard_Integer ) Min(udeg,vdeg) ;
-      MaxDegree = (Standard_Integer ) Max(udeg,vdeg) ;
-
-      TColgp_Array2OfPnt cachepoles(1, MaxDegree + 1, 1, MinDegree + 1);
-// end for cache
-
-// for polynomial grid 
-      Standard_Integer MaxUDegree, MaxVDegree;
-      Standard_Integer UContinuity, VContinuity;
-
-      Handle(TColStd_HArray2OfInteger) NumCoeffPerSurface = 
-                                   new TColStd_HArray2OfInteger(1, 1, 1, 2);
-      Handle(TColStd_HArray1OfReal) PolynomialUIntervals = 
-                                   new TColStd_HArray1OfReal(1, 2);
-      Handle(TColStd_HArray1OfReal) PolynomialVIntervals = 
-                                   new TColStd_HArray1OfReal(1, 2);
-      Handle(TColStd_HArray1OfReal) TrueUIntervals = 
-                                   new TColStd_HArray1OfReal(1, 2);
-      Handle(TColStd_HArray1OfReal) TrueVIntervals = 
-                                   new TColStd_HArray1OfReal(1, 2);
-      MaxUDegree = (Standard_Integer ) udeg;
-      MaxVDegree = (Standard_Integer ) vdeg;
-
-      for (i=1;i<=2;i++) 
-      {
-        PolynomialUIntervals->ChangeValue(i) = i-1;
-        PolynomialVIntervals->ChangeValue(i) = i-1;
-        TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1);
-        TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1);
-      }
+    MinDegree = (Standard_Integer ) Min(udeg,vdeg) ;
+    MaxDegree = (Standard_Integer ) Max(udeg,vdeg) ;
+
+    TColgp_Array2OfPnt cachepoles(1, MaxDegree + 1, 1, MinDegree + 1);
+    // end for cache
+
+    // for polynomial grid 
+    Standard_Integer MaxUDegree, MaxVDegree;
+    Standard_Integer UContinuity, VContinuity;
+
+    Handle(TColStd_HArray2OfInteger) NumCoeffPerSurface = 
+      new TColStd_HArray2OfInteger(1, 1, 1, 2);
+    Handle(TColStd_HArray1OfReal) PolynomialUIntervals = 
+      new TColStd_HArray1OfReal(1, 2);
+    Handle(TColStd_HArray1OfReal) PolynomialVIntervals = 
+      new TColStd_HArray1OfReal(1, 2);
+    Handle(TColStd_HArray1OfReal) TrueUIntervals = 
+      new TColStd_HArray1OfReal(1, 2);
+    Handle(TColStd_HArray1OfReal) TrueVIntervals = 
+      new TColStd_HArray1OfReal(1, 2);
+    MaxUDegree = (Standard_Integer ) udeg;
+    MaxVDegree = (Standard_Integer ) vdeg;
+
+    for (i=1;i<=2;i++) 
+    {
+      PolynomialUIntervals->ChangeValue(i) = i-1;
+      PolynomialVIntervals->ChangeValue(i) = i-1;
+      TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1);
+      TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1);
+    }
 
 
-      Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0;
-      if (IsAlongU()) 
-      {
+    Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0;
+    if (IsAlongU()) 
+    {
 #ifdef OCCT_DEBUG
-        cout<<">>>>>>>>>>> AlongU"<<endl;
+      cout<<">>>>>>>>>>> AlongU"<<endl;
 #endif
-        OscUNumCoeff = (Standard_Integer ) udeg + 1;  
-        OscVNumCoeff = (Standard_Integer ) vdeg;  
-      }
-      if (IsAlongV()) 
-      {
+      OscUNumCoeff = (Standard_Integer ) udeg + 1;  
+      OscVNumCoeff = (Standard_Integer ) vdeg;  
+    }
+    if (IsAlongV()) 
+    {
 #ifdef OCCT_DEBUG
-        cout<<">>>>>>>>>>> AlongV"<<endl;
+      cout<<">>>>>>>>>>> AlongV"<<endl;
 #endif
-        OscUNumCoeff = (Standard_Integer ) udeg;  
-        OscVNumCoeff = (Standard_Integer ) vdeg + 1;  
+      OscUNumCoeff = (Standard_Integer ) udeg;  
+      OscVNumCoeff = (Standard_Integer ) vdeg + 1;  
+    }
+    NumCoeffPerSurface->ChangeValue(1,1) = OscUNumCoeff;  
+    NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff;  
+    Standard_Integer nbc = NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3;
+    //
+    if(nbc == 0)
+    {
+      return Standard_False;
+    }
+    //
+    Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, nbc);
+    //    end for polynomial grid
+
+    //    building the cache
+    Standard_Integer ULocalIndex, VLocalIndex;
+    Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength;
+    TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles());
+
+    Standard_Integer aUfKnotsLength = BS->NbUPoles() + BS->UDegree() + 1;
+    Standard_Integer aVfKnotsLength = BS->NbVPoles() + BS->VDegree() + 1;
+
+    if(BS->IsUPeriodic())
+    {
+      TColStd_Array1OfInteger aMults(1, BS->NbUKnots());
+      BS->UMultiplicities(aMults);
+      aUfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->UDegree(), Standard_True);
+    }
+
+    if(BS->IsVPeriodic())
+    {
+      TColStd_Array1OfInteger aMults(1, BS->NbVKnots());
+      BS->VMultiplicities(aMults);
+      aVfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->VDegree(), Standard_True);
+    }
+
+    TColStd_Array1OfReal UFlatKnots(1, aUfKnotsLength);
+    TColStd_Array1OfReal VFlatKnots(1, aVfKnotsLength);
+    BS->Poles(NewPoles);
+    BS->UKnotSequence(UFlatKnots);
+    BS->VKnotSequence(VFlatKnots);
+
+    VLocalIndex = 0;
+    ULocalIndex = 0;
+    for(j = 1; j <= SVKnot; j++) VLocalIndex += BS->VMultiplicity(j);
+    for(i = 1; i <= SUKnot; i++) ULocalIndex += BS->UMultiplicity(i);
+    ucacheparameter = BS->UKnot(SUKnot);
+    vcacheparameter = BS->VKnot(SVKnot);
+    vspanlength = BS->VKnot(SVKnot + 1) - BS->VKnot(SVKnot);
+    uspanlength = BS->UKnot(SUKnot + 1) - BS->UKnot(SUKnot);
+
+    // On se ramene toujours a un parametrage tel que localement ce soit l'iso 
+    // u=0 ou v=0 qui soit degeneree
+
+    Standard_Boolean IsVNegative = Param > vcacheparameter + vspanlength/2;
+    Standard_Boolean IsUNegative = Param > ucacheparameter + uspanlength/2;
+
+    if (IsAlongU() && (Param > vcacheparameter + vspanlength/2))
+      vcacheparameter = vcacheparameter +  vspanlength;
+    if (IsAlongV() && (Param > ucacheparameter + uspanlength/2))
+      ucacheparameter = ucacheparameter +  uspanlength;
+
+    BSplSLib::BuildCache(ucacheparameter,   
+      vcacheparameter,   
+      uspanlength,         
+      vspanlength,         
+      BS->IsUPeriodic(),
+      BS->IsVPeriodic(),
+      BS->UDegree(),       
+      BS->VDegree(),       
+      ULocalIndex,         
+      VLocalIndex,         
+      UFlatKnots,
+      VFlatKnots,
+      NewPoles,
+      BSplSLib::NoWeights(),
+      cachepoles,
+      BSplSLib::NoWeights());
+    Standard_Integer m, n, index;
+    TColgp_Array2OfPnt OscCoeff(1,OscUNumCoeff , 1, OscVNumCoeff);
+
+    if (IsAlongU()) 
+    {
+      if (udeg > vdeg) 
+      {
+        for(n = 1; n <= udeg + 1; n++) 
+          for(m = 1; m <= vdeg; m++)
+            OscCoeff(n,m) = cachepoles(n,m+1) ;
+      }
+      else
+      {
+        for(n = 1; n <= udeg + 1; n++) 
+          for(m = 1; m <= vdeg; m++)
+            OscCoeff(n,m) = cachepoles(m+1,n) ;
       }
-      NumCoeffPerSurface->ChangeValue(1,1) = OscUNumCoeff;  
-      NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff;  
-
-      Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, 
-             NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3);
-//    end for polynomial grid
-
-//    building the cache
-      Standard_Integer ULocalIndex, VLocalIndex;
-      Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength;
-      TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles());
-      TColStd_Array1OfReal UFlatKnots(1, BS->NbUPoles() + BS->UDegree() + 1);
-      TColStd_Array1OfReal VFlatKnots(1, BS->NbVPoles() + BS->VDegree() + 1);
-      BS->Poles(NewPoles);
-      BS->UKnotSequence(UFlatKnots);
-      BS->VKnotSequence(VFlatKnots);
-
-      VLocalIndex = 0;
-      ULocalIndex = 0;
-      for(j = 1; j <= SVKnot; j++) VLocalIndex += BS->VMultiplicity(j);
-      for(i = 1; i <= SUKnot; i++) ULocalIndex += BS->UMultiplicity(i);
-      ucacheparameter = BS->UKnot(SUKnot);
-      vcacheparameter = BS->VKnot(SVKnot);
-      vspanlength = BS->VKnot(SVKnot + 1) - BS->VKnot(SVKnot);
-      uspanlength = BS->UKnot(SUKnot + 1) - BS->UKnot(SUKnot);
-
-      // On se ramene toujours a un parametrage tel que localement ce soit l'iso 
-      // u=0 ou v=0 qui soit degeneree
-
-      Standard_Boolean IsVNegative = Param > vcacheparameter + vspanlength/2;
-      Standard_Boolean IsUNegative = Param > ucacheparameter + uspanlength/2;
-
-      if (IsAlongU() && (Param > vcacheparameter + vspanlength/2))
-       vcacheparameter = vcacheparameter +  vspanlength;
-      if (IsAlongV() && (Param > ucacheparameter + uspanlength/2))
-       ucacheparameter = ucacheparameter +  uspanlength;
-
-      BSplSLib::BuildCache(ucacheparameter,   
-                          vcacheparameter,   
-                          uspanlength,         
-                          vspanlength,         
-                          BS->IsUPeriodic(),
-                          BS->IsVPeriodic(),
-                          BS->UDegree(),       
-                          BS->VDegree(),       
-                          ULocalIndex,         
-                          VLocalIndex,         
-                          UFlatKnots,
-                          VFlatKnots,
-                          NewPoles,
-                          BSplSLib::NoWeights(),
-                          cachepoles,
-                          BSplSLib::NoWeights());
-      Standard_Integer m, n, index;
-      TColgp_Array2OfPnt OscCoeff(1,OscUNumCoeff , 1, OscVNumCoeff);
-
-      if (IsAlongU()) 
-       {
-         if (udeg > vdeg) 
-           {
-             for(n = 1; n <= udeg + 1; n++) 
-               for(m = 1; m <= vdeg; m++)
-                 OscCoeff(n,m) = cachepoles(n,m+1) ;
-           }
-         else
-           {
-             for(n = 1; n <= udeg + 1; n++) 
-               for(m = 1; m <= vdeg; m++)
-                 OscCoeff(n,m) = cachepoles(m+1,n) ;
-           }
-         if (IsVNegative) PLib::VTrimming(-1,0,OscCoeff,PLib::NoWeights2());
-
-         index=1;
-         for(n = 1; n <= udeg + 1; n++) 
-           for(m = 1; m <= vdeg; m++)
-             {
-               Coefficients->ChangeValue(index++) = OscCoeff(n,m).X();
-               Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y();
-               Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z();
-             }
-       }
-
-      if (IsAlongV()) 
-       {
-         if (udeg > vdeg) 
-           {
-             for(n = 1; n <= udeg; n++) 
-               for(m = 1; m <= vdeg + 1; m++)
-                 OscCoeff(n,m) = cachepoles(n+1,m);
-           }
-         else
-           {
-             for(n = 1; n <= udeg; n++) 
-               for(m = 1; m <= vdeg + 1; m++)
-                 OscCoeff(n,m) = cachepoles(m,n+1);
-           }
-         if (IsUNegative) PLib::UTrimming(-1,0,OscCoeff,PLib::NoWeights2());
-         index=1;
-         for(n = 1; n <= udeg; n++) 
-           for(m = 1; m <= vdeg + 1; m++)
-             {
-               Coefficients->ChangeValue(index++) = OscCoeff(n,m).X();
-               Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y();
-               Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z();
-             }
-       }
-
-      if (IsAlongU()) MaxVDegree--;
-      if (IsAlongV()) MaxUDegree--;
-      UContinuity = - 1;
-      VContinuity = - 1;
-
-      Convert_GridPolynomialToPoles Data(1,1,
-                                        UContinuity,
-                                        VContinuity,
-                                        MaxUDegree,
-                                        MaxVDegree,
-                                        NumCoeffPerSurface,
-                                        Coefficients,
-                                        PolynomialUIntervals,
-                                        PolynomialVIntervals,
-                                        TrueUIntervals,
-                                        TrueVIntervals);
-  
-//      Handle(Geom_BSplineSurface) BSpl = 
-       BSpl =new Geom_BSplineSurface(Data.Poles()->Array2(),
-                               Data.UKnots()->Array1(),
-                               Data.VKnots()->Array1(),
-                               Data.UMultiplicities()->Array1(),
-                               Data.VMultiplicities()->Array1(),
-                               Data.UDegree(),
-                               Data.VDegree(),
-                               0, 0);
+      if (IsVNegative) PLib::VTrimming(-1,0,OscCoeff,PLib::NoWeights2());
+
+      index=1;
+      for(n = 1; n <= udeg + 1; n++) 
+        for(m = 1; m <= vdeg; m++)
+        {
+          Coefficients->ChangeValue(index++) = OscCoeff(n,m).X();
+          Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y();
+          Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z();
+        }
+    }
+
+    if (IsAlongV()) 
+    {
+      if (udeg > vdeg) 
+      {
+        for(n = 1; n <= udeg; n++) 
+          for(m = 1; m <= vdeg + 1; m++)
+            OscCoeff(n,m) = cachepoles(n+1,m);
+      }
+      else
+      {
+        for(n = 1; n <= udeg; n++) 
+          for(m = 1; m <= vdeg + 1; m++)
+            OscCoeff(n,m) = cachepoles(m,n+1);
+      }
+      if (IsUNegative) PLib::UTrimming(-1,0,OscCoeff,PLib::NoWeights2());
+      index=1;
+      for(n = 1; n <= udeg; n++) 
+        for(m = 1; m <= vdeg + 1; m++)
+        {
+          Coefficients->ChangeValue(index++) = OscCoeff(n,m).X();
+          Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y();
+          Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z();
+        }
+    }
+
+    if (IsAlongU()) MaxVDegree--;
+    if (IsAlongV()) MaxUDegree--;
+    UContinuity = - 1;
+    VContinuity = - 1;
+
+    Convert_GridPolynomialToPoles Data(1,1,
+      UContinuity,
+      VContinuity,
+      MaxUDegree,
+      MaxVDegree,
+      NumCoeffPerSurface,
+      Coefficients,
+      PolynomialUIntervals,
+      PolynomialVIntervals,
+      TrueUIntervals,
+      TrueVIntervals);
+
+    //      Handle(Geom_BSplineSurface) BSpl = 
+    BSpl =new Geom_BSplineSurface(Data.Poles()->Array2(),
+      Data.UKnots()->Array1(),
+      Data.VKnots()->Array1(),
+      Data.UMultiplicities()->Array1(),
+      Data.VMultiplicities()->Array1(),
+      Data.UDegree(),
+      Data.VDegree(),
+      0, 0);
 #ifdef OCCT_DEBUG
-      cout<<"^====================================^"<<endl<<endl;
+    cout<<"^====================================^"<<endl<<endl;
 #endif
 
-//      L=BSpl;
-    }
+    //      L=BSpl;
+  }
   return OsculSurf;
 }
 
@@ -661,52 +684,52 @@ Standard_Boolean  Geom_OsculatingSurface::BuildOsculatingSurface
 //=======================================================================
 
 Standard_Boolean Geom_OsculatingSurface::IsQPunctual
-                  (const Handle(Geom_Surface)& S,
-                   const Standard_Real         Param,
-                   const GeomAbs_IsoType       IT,
-                   const Standard_Real         TolMin,
-                   const Standard_Real         TolMax) const
+  (const Handle(Geom_Surface)& S,
+  const Standard_Real         Param,
+  const GeomAbs_IsoType       IT,
+  const Standard_Real         TolMin,
+  const Standard_Real         TolMax) const
 {
-    Standard_Real U1=0,U2=0,V1=0,V2=0,T;
-    Standard_Boolean Along = Standard_True;
-    S->Bounds(U1,U2,V1,V2);
-    gp_Vec D1U,D1V;
-    gp_Pnt P;
-    Standard_Real Step,D1NormMax;
-    if (IT == GeomAbs_IsoV) 
+  Standard_Real U1=0,U2=0,V1=0,V2=0,T;
+  Standard_Boolean Along = Standard_True;
+  S->Bounds(U1,U2,V1,V2);
+  gp_Vec D1U,D1V;
+  gp_Pnt P;
+  Standard_Real Step,D1NormMax;
+  if (IT == GeomAbs_IsoV) 
+  {
+    Step = (U2 - U1)/10;
+    D1NormMax=0.;
+    for (T=U1;T<=U2;T=T+Step) 
     {
-      Step = (U2 - U1)/10;
-      D1NormMax=0.;
-      for (T=U1;T<=U2;T=T+Step) 
-      {
-        S->D1(T,Param,P,D1U,D1V);
-        D1NormMax=Max(D1NormMax,D1U.Magnitude());
-      }
+      S->D1(T,Param,P,D1U,D1V);
+      D1NormMax=Max(D1NormMax,D1U.Magnitude());
+    }
 
 #ifdef OCCT_DEBUG
-      cout << " D1NormMax = " << D1NormMax << endl;
+    cout << " D1NormMax = " << D1NormMax << endl;
 #endif
-      if (D1NormMax >TolMax || D1NormMax < TolMin ) 
-           Along = Standard_False;
-    }
-    else 
+    if (D1NormMax >TolMax || D1NormMax < TolMin ) 
+      Along = Standard_False;
+  }
+  else 
+  {
+    Step = (V2 - V1)/10;
+    D1NormMax=0.;
+    for (T=V1;T<=V2;T=T+Step) 
     {
-      Step = (V2 - V1)/10;
-      D1NormMax=0.;
-      for (T=V1;T<=V2;T=T+Step) 
-      {
-       S->D1(Param,T,P,D1U,D1V);
-        D1NormMax=Max(D1NormMax,D1V.Magnitude());
-      }
+      S->D1(Param,T,P,D1U,D1V);
+      D1NormMax=Max(D1NormMax,D1V.Magnitude());
+    }
 #ifdef OCCT_DEBUG
-      cout << " D1NormMax = " << D1NormMax << endl;
+    cout << " D1NormMax = " << D1NormMax << endl;
 #endif
-      if (D1NormMax >TolMax || D1NormMax < TolMin ) 
-           Along = Standard_False;
+    if (D1NormMax >TolMax || D1NormMax < TolMin ) 
+      Along = Standard_False;
 
 
-    }
-    return Along;
+  }
+  return Along;
 }
 
 //=======================================================================
@@ -714,7 +737,7 @@ Standard_Boolean Geom_OsculatingSurface::IsQPunctual
 //purpose  : 
 //=======================================================================
 
- Standard_Boolean Geom_OsculatingSurface::HasOscSurf() const
+Standard_Boolean Geom_OsculatingSurface::HasOscSurf() const
 {
   return (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4));
 }
@@ -764,10 +787,10 @@ const Geom_SequenceOfBSplineSurface& Geom_OsculatingSurface::GetSeqOfL2() const
 
 void Geom_OsculatingSurface::ClearOsculFlags()
 {
-    myAlong.SetValue(1,Standard_False);
-    myAlong.SetValue(2,Standard_False);
-    myAlong.SetValue(3,Standard_False);
-    myAlong.SetValue(4,Standard_False);
+  myAlong.SetValue(1,Standard_False);
+  myAlong.SetValue(2,Standard_False);
+  myAlong.SetValue(3,Standard_False);
+  myAlong.SetValue(4,Standard_False);
 
 }
 
index ddf9a7c..0196187 100644 (file)
@@ -614,6 +614,14 @@ is
        -- Exceptions Standard_RangeError if N is negative.
           raises RangeError;
       
+  IsG1 (me; theTf, theTl, theAngTol : Real) returns Boolean;
+        ---Purpose :
+               --  Check if curve has at least G1 continuity in interval [theTf, theTl]
+        --  Returns true if IsCN(1)  
+        --  or 
+        --  angle betweem "left" and "right" first derivatives at
+        --  knots with C0 continuity is less then theAngTol
+               --  only knots in interval [theTf, theTl] is checked
 
   IsClosed (me)  returns Boolean;
         --- Purpose :
index 08077e0..b80b415 100644 (file)
@@ -61,6 +61,87 @@ Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const
     return Standard_False;
   }
 }
+//=======================================================================
+//function : IsG1
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Geom2d_BSplineCurve::IsG1 ( const Standard_Real theTf,
+                                           const Standard_Real theTl,
+                                           const Standard_Real theAngTol) const
+{
+
+  if(IsCN(1))
+  {
+    return Standard_True;
+  }
+
+  Standard_Integer  start = FirstUKnotIndex()+1,
+                    finish = LastUKnotIndex()-1;
+  Standard_Integer aDeg = Degree();
+  for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++)
+  {
+    const Standard_Real aTpar = Knot(aNKnot);
+
+    if(aTpar < theTf)
+      continue;
+    if(aTpar > theTl)
+      break;
+
+    Standard_Integer mult = Multiplicity(aNKnot);
+    if (mult < aDeg)
+      continue;
+
+    gp_Pnt2d aP1, aP2;
+    gp_Vec2d aV1, aV2;
+    LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1);
+    LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2);
+
+    if((aV1.SquareMagnitude() <= gp::Resolution()) ||
+        aV2.SquareMagnitude() <= gp::Resolution())
+    {
+      return Standard_False;
+    }
+
+    if(Abs(aV1.Angle(aV2)) > theAngTol)
+      return Standard_False;
+  }
+
+  if(!IsPeriodic())
+    return Standard_True;
+
+  const Standard_Real aFirstParam = FirstParameter(),
+                      aLastParam = LastParameter();
+
+  if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) &&
+      ((aLastParam - theTf)*(theTl - aLastParam) < 0.0))
+  {
+    //Range [theTf, theTl] does not intersect curve bounadries
+    return Standard_True;
+  }
+
+  //Curve is closed or periodic and range [theTf, theTl]
+  //intersect curve boundary. Therefore, it is necessary to 
+  //check if curve is smooth in its first and last point.
+
+  gp_Pnt2d aP;
+  gp_Vec2d aV1, aV2;
+  D1(Knot(FirstUKnotIndex()), aP, aV1);
+  D1(Knot(LastUKnotIndex()), aP, aV2);
+
+  if((aV1.SquareMagnitude() <= gp::Resolution()) ||
+      aV2.SquareMagnitude() <= gp::Resolution())
+  {
+    return Standard_False;
+  }
+
+  if(Abs(aV1.Angle(aV2)) > theAngTol)
+    return Standard_False;
+
+
+  return Standard_True;
+
+}
 
 //=======================================================================
 //function : IsClosed
index cca2edb..7c994d4 100644 (file)
@@ -77,7 +77,11 @@ raises ConstructionError   from Standard,
 is
 
 
-  Create (C : Curve from Geom2d; Offset : Real)   returns OffsetCurve
+  Create (C : Curve from Geom2d;
+          Offset : Real;
+          isNotCheckC0 : Boolean = Standard_False)
+
+  returns OffsetCurve
         --- Purpose : Constructs a curve offset from the basis curve C,
        -- where Offset is the distance between the offset
        -- curve and the basis curve at any point.
@@ -89,11 +93,14 @@ is
        -- the offset value is measured is indicated by this
        -- normal vector if Offset is positive, or in the inverse
        -- sense if Offset is negative.
+      -- If isNotCheckC0 = TRUE checking if basis curve has C0-continuity
+      -- is not made.
         --   Warnings :
         --  In this package the entities are not shared. The OffsetCurve is
         --  built with a copy of the curve C. So when C is modified the
         --  OffsetCurve is not modified 
-       --  Warning!  ConstructionError  raised if the basis curve C is not at least C1.
+       --  Warning!  if isNotCheckC0 = false, 
+           -- ConstructionError  raised if the basis curve C is not at least C1.
         --  No check is done to know if ||V^Z|| != 0.0 at any point.
      raises ConstructionError;
 
@@ -115,11 +122,16 @@ is
        -- the point of parameter U on this offset curve.
 
 
-  SetBasisCurve (me : mutable; C : Curve from Geom2d)
+  SetBasisCurve ( me : mutable;
+                  C : Curve from Geom2d;
+                  isNotCheckC0 : Boolean = Standard_False)
      raises ConstructionError;
         --- Purpose : Changes this offset curve by assigning C as the
        -- basis curve from which it is built.
+      -- If isNotCheckC0 = TRUE checking if basis curve has C0-continuity
+      -- is not made.
        -- Exceptions
+               -- if isNotCheckC0 = false, 
        -- Standard_ConstructionError if the curve C is not at least "C1" continuous.
 
   SetOffsetValue (me : mutable; D : Real);
@@ -329,10 +341,17 @@ is
 
 
   Copy (me)  returns like me;
-       ---Purpose: Creates a new object, which is a copy of this offset curve.     
+       ---Purpose: Creates a new object, which is a copy of this offset curve.   
+
+  GetBasisCurveContinuity(me)
+    returns Shape from GeomAbs;
+       ---Purpose: Returns continuity of the basis curve.   
+    
+      
 fields
 
   basisCurve  : Curve from Geom2d;
   offsetValue : Real;
+  myBasisCurveContinuity : Shape from GeomAbs;
 
 end;
index 30c7940..07126a7 100644 (file)
@@ -34,6 +34,7 @@
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <gp_XY.hxx>
+#include <Precision.hxx>
 
 typedef Handle(Geom2d_OffsetCurve) Handle(OffsetCurve);
 typedef Geom2d_OffsetCurve         OffsetCurve;
@@ -51,7 +52,7 @@ typedef gp_XY     XY;
 //derivee non nulle
 static const int maxDerivOrder = 3;
 static const Standard_Real MinStep   = 1e-7;
-
+static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
 
 //=======================================================================
 //function : Copy
@@ -68,21 +69,16 @@ Handle(Geom2d_Geometry) Geom2d_OffsetCurve::Copy () const
 
 //=======================================================================
 //function : Geom2d_OffsetCurve
-//purpose  : 
+//purpose  : Basis curve cannot be an Offset curve or trimmed from
+//            offset curve.
 //=======================================================================
 
-Geom2d_OffsetCurve::Geom2d_OffsetCurve (const Handle(Curve)& C,
-                                       const Standard_Real Offset)  
-: offsetValue (Offset) 
+Geom2d_OffsetCurve::Geom2d_OffsetCurve (const Handle(Geom2d_Curve)& theCurve,
+                                        const Standard_Real theOffset,
+                                        const Standard_Boolean isTheNotCheckC0)  
+: offsetValue (theOffset) 
 {
-  if (C->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) {
-    Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
-    SetBasisCurve (OC->BasisCurve());
-    offsetValue += OC->Offset();
-  }
-  else {
-    SetBasisCurve(C);
-  }
+  SetBasisCurve (theCurve, isTheNotCheckC0);
 }
 
 //=======================================================================
@@ -111,36 +107,65 @@ Standard_Real Geom2d_OffsetCurve::ReversedParameter( const Standard_Real U) cons
 //purpose  : 
 //=======================================================================
 
-void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C) 
+void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C,
+                                        const Standard_Boolean isNotCheckC0) 
 {
-  Handle(Geom2d_Curve) aBasisCurve = Handle(Geom2d_Curve)::DownCast(C->Copy());
+  const Standard_Real aUf = C->FirstParameter(),
+                      aUl = C->LastParameter();
+  Handle(Geom2d_Curve) aCheckingCurve = C;
+  Standard_Boolean isTrimmed = Standard_False;
+
+  while(aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) ||
+        aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
+  {
+    if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+    {
+      Handle(Geom2d_TrimmedCurve) aTrimC = 
+                Handle(Geom2d_TrimmedCurve)::DownCast(aCheckingCurve);
+      aCheckingCurve = aTrimC->BasisCurve();
+      isTrimmed = Standard_True;
+    }
+
+    if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
+    {
+      Handle(Geom2d_OffsetCurve) aOC = 
+                Handle(Geom2d_OffsetCurve)::DownCast(aCheckingCurve);
+      aCheckingCurve = aOC->BasisCurve();
+      offsetValue += aOC->Offset();
+    }
+  }
+
+  myBasisCurveContinuity = aCheckingCurve->Continuity();
+
+  Standard_Boolean isC0 = !isNotCheckC0 &&
+                          (myBasisCurveContinuity == GeomAbs_C0);
 
   // Basis curve must be at least C1
-  if (aBasisCurve->Continuity() == GeomAbs_C0)
+  if (isC0 && aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
   {
-    // For B-splines it is sometimes possible to increase continuity by removing 
-    // unnecessarily duplicated knots
-    if (aBasisCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
+    Handle(Geom2d_BSplineCurve) aBC = Handle(Geom2d_BSplineCurve)::DownCast(aCheckingCurve);
+    if(aBC->IsG1(aUf, aUl, MyAngularToleranceForG1))
     {
-      Handle(Geom2d_BSplineCurve) aBCurve = Handle(Geom2d_BSplineCurve)::DownCast(aBasisCurve);
-      Standard_Integer degree = aBCurve->Degree();
-      Standard_Real Toler = 1e-7;
-      Standard_Integer start = aBCurve->IsPeriodic() ? 1 :  aBCurve->FirstUKnotIndex(),
-                       finish = aBCurve->IsPeriodic() ? aBCurve->NbKnots() :  aBCurve->LastUKnotIndex();
-      for (Standard_Integer i = start; i <= finish; i++)
-      {
-        Standard_Integer mult = aBCurve->Multiplicity(i);
-        if ( mult == degree )
-          aBCurve->RemoveKnot(i,degree - 1, Toler);
-      }
+      //Checking if basis curve has more smooth (C1, G2 and above) is not done.
+      //It can be done in case of need.
+      myBasisCurveContinuity = GeomAbs_G1;
+      isC0 = Standard_False;
     }
 
     // Raise exception if still C0
-    if (aBasisCurve->Continuity() == GeomAbs_C0)
+    if (isC0)
       Standard_ConstructionError::Raise("Offset on C0 curve");
   }
+  //
+  if(isTrimmed)
+  {
+    basisCurve = new Geom2d_TrimmedCurve(aCheckingCurve, aUf, aUl);
+  } 
+  else
+  {
+    basisCurve = aCheckingCurve;
+  }
 
-  basisCurve = aBasisCurve;
 }
 
 //=======================================================================
@@ -168,7 +193,7 @@ Handle(Curve) Geom2d_OffsetCurve::BasisCurve () const
 GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const 
 {
   GeomAbs_Shape OffsetShape=GeomAbs_C0;
-  switch (basisCurve->Continuity()) {
+  switch (myBasisCurveContinuity) {
      case GeomAbs_C0 : OffsetShape = GeomAbs_C0;   break;
      case GeomAbs_C1 : OffsetShape = GeomAbs_C0;   break;
      case GeomAbs_C2 : OffsetShape = GeomAbs_C1;   break;
@@ -177,6 +202,7 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const
      case GeomAbs_G1 : OffsetShape = GeomAbs_G1;   break;
      case GeomAbs_G2 : OffsetShape = GeomAbs_G2;   break;
   }
+
   return OffsetShape;
 }
 
@@ -926,3 +952,12 @@ Standard_Real Geom2d_OffsetCurve::ParametricTransformation(const gp_Trsf2d& T) c
 {
   return basisCurve->ParametricTransformation(T);
 }
+
+//=======================================================================
+//function : GetBasisCurveContinuity
+//purpose  : 
+//=======================================================================
+GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const
+{
+  return myBasisCurveContinuity;
+}
index 56ca509..a1cb67b 100644 (file)
@@ -214,12 +214,15 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
   }
   else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
     GeomAbs_Shape S = 
-      (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()->Continuity(); 
+      (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); 
     switch(S){
     case GeomAbs_CN: return GeomAbs_CN;
     case GeomAbs_C3: return GeomAbs_C2;
     case GeomAbs_C2: return GeomAbs_C1;
     case GeomAbs_C1: return GeomAbs_C0;  
+    case GeomAbs_G1: return GeomAbs_G1;
+    case GeomAbs_G2: return GeomAbs_G2;
+
     default:
       Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity");
     }
index 3f211fa..8cb5a73 100644 (file)
@@ -179,15 +179,17 @@ GeomAbs_Shape GeomAdaptor_Curve::Continuity() const
   if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
   {
     const GeomAbs_Shape S =
-      (*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve()->Continuity();
+      (*((Handle(Geom_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity();
     switch(S)
     {
       case GeomAbs_CN: return GeomAbs_CN;
       case GeomAbs_C3: return GeomAbs_C2;
       case GeomAbs_C2: return GeomAbs_C1;
-      case GeomAbs_C1: return GeomAbs_C0;  
+      case GeomAbs_C1: return GeomAbs_C0; 
+      case GeomAbs_G1: return GeomAbs_G1;
+      case GeomAbs_G2: return GeomAbs_G2;
       default:
-      Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
+        Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity");
     }
   }
   else if (myTypeCurve == GeomAbs_OtherCurve) {
diff --git a/tests/bugs/modalg_5/bug25124_1 b/tests/bugs/modalg_5/bug25124_1
new file mode 100644 (file)
index 0000000..f91699f
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+set ver_info_1 "\n\n*********** Dump of cc *************\nTrimmed curve\nParameters : 2 5\nBasis curve :\nOffsetCurveOffset : 10\nDirection : 0, 0, 1 \nBasis curve :\nTrimmed curve\nParameters : 1 6\nBasis curve :\nCircle"
+set ver_info_2 "\n\n*********** Dump of oc *************\nOffsetCurveOffset : 20\nDirection : 0, 0, 1 \nBasis curve :\nTrimmed curve\nParameters : 2 5\nBasis curve :\nCircle"
+
+point pp 0 0 1
+circle cc 20 40 30 20
+trim cc cc 1 6
+offsetcurve oc cc 10 pp
+trim cc oc 2 5
+set bug_info_1 [dump cc]
+offsetcurve oc cc 10 pp
+set bug_info_2 [dump oc]
+
+if {[string first $ver_info_1 $bug_info_1] == -1} {
+  puts "ERROR: OCC25124 is reproduced (dump of cc)."
+}
+if {[string first $ver_info_2 $bug_info_2] == -1} {
+  puts "ERROR: OCC25124 is reproduced (dump of oc)."
+}
+
+donly oc cc
+fit
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25124_2 b/tests/bugs/modalg_5/bug25124_2
new file mode 100644 (file)
index 0000000..3860c68
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+set ver_info_1 "\n\n*********** Dump of cc *************\nTrimmed curve\nParameters : 2 5\nBasis curve :\nOffsetCurveOffset : 10\nBasis curve :\nTrimmed curve\nParameters : 1 6\nBasis curve :\nCircle"
+set ver_info_2 "\n\n*********** Dump of oc *************\nOffsetCurveOffset : 20\nBasis curve :\nTrimmed curve\nParameters : 2 5\nBasis curve :\nCircle"
+
+circle cc 20 40 20
+trim cc cc 1 6
+offset2dcurve oc cc 10
+trim cc oc 2 5
+set bug_info_1 [dump cc]
+offset2dcurve oc cc 10
+set bug_info_2 [dump oc]
+
+if {[string first $ver_info_1 $bug_info_1] == -1} {
+  puts "ERROR: OCC25124 is reproduced (dump of cc)."
+}
+if {[string first $ver_info_2 $bug_info_2] == -1} {
+  puts "ERROR: OCC25124 is reproduced (dump of oc)."
+}
+
+donly oc cc
+fit
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25124_3 b/tests/bugs/modalg_5/bug25124_3
new file mode 100644 (file)
index 0000000..7f1f1e0
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+set ver_info_1 "\n\n*********** Dump of ss *************\nRectangularTrimmedSurface\nParameters : 1 5.5 -0.8 0.5\nBasisSurface :\nOffsetSurface\nOffset : 10\nBasisSurface :\nRectangularTrimmedSurface\nParameters : 1 5.5 -0.8 0.5\nBasisSurface :\nSphericalSurface"
+set ver_info_2 "\n\n*********** Dump of os *************\nOffsetSurface\nOffset : 20\nBasisSurface :\nRectangularTrimmedSurface\nParameters : 1 5.5 -0.8 0.5\nBasisSurface :\nSphericalSurface"
+
+sphere ss 30
+trim ss ss 0.5 6 -1 1
+offset os ss 10
+trim ss os 1 5.5 -0.8 0.5
+set bug_info_1 [dump ss]
+offset os ss 10
+set bug_info_2 [dump os]
+
+if {[string first $ver_info_1 $bug_info_1] == -1} {
+  puts "ERROR: OCC25124 is reproduced (dump of ss)."
+}
+if {[string first $ver_info_2 $bug_info_2] == -1} {
+  puts "ERROR: OCC25124 is reproduced (dump of os)."
+}
+
+donly os ss
+fit
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25124_4 b/tests/bugs/modalg_5/bug25124_4
new file mode 100644 (file)
index 0000000..916a82e
--- /dev/null
@@ -0,0 +1,38 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+point pp 0 0 1
+circle cc 20 40 30 20
+convert bc cc
+trim bc bc 1 6
+offsetcurve oc bc 10 pp
+trim bc oc 2 5
+extsurf se bc 0 0 1
+offset os se 15
+
+set bug_info [getsurfcontinuity se]
+getsurfcontinuity os
+
+if {[string compare $bug_info "se has G1 continuity.\n"] != 0} {
+  puts "ERROR: OCC25124 is reproduced (se does not have G1 continuity)."
+}
+
+set bug_info_1 [dump se]
+set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]]
+set bug_info_2 [dump os]
+set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]]
+if {[string compare $bug_info_1 $bug_info_2] == 0} {
+  puts "ERROR: OCC25124 is reproduced (se = os)."
+}
+
+donly os se
+fit
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25124_5 b/tests/bugs/modalg_5/bug25124_5
new file mode 100644 (file)
index 0000000..4480b04
--- /dev/null
@@ -0,0 +1,38 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+point pp 0 0 1
+circle cc 20 40 30 20
+convert bc cc
+trim bc bc 1 6
+offsetcurve oc bc 10 pp
+trim bc oc 2 5
+revsurf se bc 0 0 0 0 1 0
+offset os se 15
+
+set bug_info [getsurfcontinuity se]
+getsurfcontinuity os
+
+if {[string compare $bug_info "se has G1 continuity.\n"] != 0} {
+  puts "ERROR: OCC25124 is reproduced (se does not have G1 continuity)."
+}
+
+set bug_info_1 [dump se]
+set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]]
+set bug_info_2 [dump os]
+set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]]
+if {[string compare $bug_info_1 $bug_info_2] == 0} {
+  puts "ERROR: OCC25124 is reproduced (se = os)."
+}
+
+donly os se
+fit
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25124_6 b/tests/bugs/modalg_5/bug25124_6
new file mode 100644 (file)
index 0000000..d3d94ab
--- /dev/null
@@ -0,0 +1,27 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+restore [locate_data_file OCC25124_a_2999.draw] a1
+getsurfcontinuity a1
+offset o1 a1 20
+getsurfcontinuity o1
+
+set bug_info_1 [dump a1]
+set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]]
+set bug_info_2 [dump o1]
+set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]]
+if {[string compare $bug_info_1 $bug_info_2] == 0} {
+  puts "ERROR: OCC25124 is reproduced (a1 = o1)."
+}
+
+donly a1 o1
+fit
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25124_7 b/tests/bugs/modalg_5/bug25124_7
new file mode 100644 (file)
index 0000000..57539d9
--- /dev/null
@@ -0,0 +1,27 @@
+puts "========"
+puts "OCC25124"
+puts "========"
+puts ""
+######################################################
+# Removal of continuity checks for offset geometries
+######################################################
+
+smallview
+
+restore [locate_data_file OCC25124_a_15592.draw] a2
+getsurfcontinuity a2
+offset o2 a2 20
+getsurfcontinuity o2
+
+set bug_info_1 [dump a2]
+set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]]
+set bug_info_2 [dump o2]
+set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]]
+if {[string compare $bug_info_1 $bug_info_2] == 0} {
+  puts "ERROR: OCC25124 is reproduced (a2 = o2)."
+}
+
+donly a2 o2
+fit
+
+set only_screen_axo 1
index 39385d6..2b9eb8d 100644 (file)
@@ -1,13 +1,9 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
+puts "TODO OCC25124068 ALL: Error : big tolerance of shape result"
 
 restore [locate_data_file offset_wire_034.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 910.505
+set nbsh_v 14
+set nbsh_e 14
+set nbsh_w 1
 
index 7194103..f7be28e 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file case_3_wire2.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 910.505
+set nbsh_v 30
+set nbsh_e 30
+set nbsh_w 1
 
index 32aafb7..0011e4e 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file offset_wire_058.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 3316.27
+set nbsh_v 62
+set nbsh_e 62
+set nbsh_w 1
 
index 4184b6b..f6a4e3a 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file offset_wire_033.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 68.7414
+set nbsh_v 61
+set nbsh_e 61
+set nbsh_w 1
 
index 7194103..49cfa13 100644 (file)
@@ -1,13 +1,9 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
+puts "TODO OCC25109 ALL: Faulty shapes in variables"
 
 restore [locate_data_file case_3_wire2.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 957.647
+set nbsh_v 86
+set nbsh_e 86
+set nbsh_w 2
 
index 32aafb7..ecbabe5 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file offset_wire_058.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 2582.56
+set nbsh_v 47
+set nbsh_e 47
+set nbsh_w 1
 
index 395f5e3..6b01cec 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file offset_wire_032.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 92.0671
+set nbsh_v 41
+set nbsh_e 41
+set nbsh_w 1
 
index 4184b6b..1219529 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file offset_wire_033.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 78.0343
+set nbsh_v 60
+set nbsh_e 60
+set nbsh_w 1
 
index 32aafb7..1736ba2 100644 (file)
@@ -1,13 +1,7 @@
-puts "TODO ?OCC23068 ALL: Error : result is not a topological shape"
-puts "TODO ?OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO ?OCC23068 ALL: An exception was caught"
-puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*"
-puts "TODO ?OCC23748 ALL: Error: Offset is not done."
-
 restore [locate_data_file offset_wire_058.brep] s
 
-set length 0
-set nbsh_v 0
-set nbsh_e 0
-set nbsh_w 0
+set length 3127.75
+set nbsh_v 39
+set nbsh_e 39
+set nbsh_w 1