0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepFill / BRepFill_Sweep.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 74e5208..34607d6
 // Created on: 1998-01-07
 // Created by: Philippe MANGIN
 // Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 
-#include <stdio.h>
-
-#include <BRepFill_Sweep.ixx>
-
-#include <BRepFill_SectionLaw.hxx>
-//#include <BRepFill_TrimCorner.hxx>
-#include <BRepFill_CurveConstraint.hxx>
-
-#include <GeomFill_SectionLaw.hxx>
-#include <GeomFill_LocationLaw.hxx>
-#include <GeomFill_Sweep.hxx>
-
-// modified by NIZHNY-MKK  Wed Oct 22 12:25:45 2003
-#include <BRepFill_TrimShellCorner.hxx>
-
-//#include <GeomPlate_BuildPlateSurface.hxx>
-//#include <GeomPlate_Surface.hxx>
-//#include <GeomPlate_PointConstraint.hxx>
-
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec2d.hxx>
-#include <Bnd_Box.hxx>
-
-#include <Geom_Surface.hxx>
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_BezierCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
-#include <GeomLib.hxx>
-#include <GeomLib_IsPlanarSurface.hxx>
-#include <BRepLib_FindSurface.hxx>
-#include <GeomConvert_ApproxSurface.hxx>
-
-#include <BRepAdaptor_HCurve.hxx>
-#include <BRepAdaptor_HCurve2d.hxx>
-#include <BRepAdaptor_HSurface.hxx>
 #include <Adaptor3d_HCurveOnSurface.hxx>
-#include <GeomAdaptor_HSurface.hxx>
-#include <GeomAdaptor_HCurve.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
 #include <Approx_CurveOnSurface.hxx>
 #include <Approx_SameParameter.hxx>
-#include <GCPnts_AbscissaPoint.hxx>
-
+#include <Bnd_Box.hxx>
 #include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
+#include <BRep_CurveRepresentation.hxx>
+#include <BRep_GCurve.hxx>
 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
 #include <BRep_TEdge.hxx>
+#include <BRep_Tool.hxx>
 #include <BRep_TVertex.hxx>
-#include <BRep_CurveRepresentation.hxx>
-#include <BRep_GCurve.hxx>
-
+#include <BRepAdaptor_HCurve.hxx>
+#include <BRepAdaptor_HCurve2d.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepCheck_Edge.hxx>
+#include <BRepFill_CurveConstraint.hxx>
+#include <BRepFill_LocationLaw.hxx>
+#include <BRepFill_SectionLaw.hxx>
+#include <BRepFill_Sweep.hxx>
+#include <BRepFill_TrimShellCorner.hxx>
 #include <BRepLib.hxx>
+#include <BRepLib_FaceError.hxx>
+#include <BRepLib_FindSurface.hxx>
 #include <BRepLib_MakeEdge.hxx>
 #include <BRepLib_MakeFace.hxx>
-#include <BRepLib_FaceError.hxx>
-
+#include <BRepTools_Substitution.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom_BezierCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_SurfaceOfRevolution.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomConvert_ApproxSurface.hxx>
+#include <GeomFill_LocationLaw.hxx>
+#include <GeomFill_SectionLaw.hxx>
+#include <GeomFill_Sweep.hxx>
+#include <GeomLib.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec2d.hxx>
+#include <Precision.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <StdFail_NotDone.hxx>
+#include <TColGeom_Array2OfSurface.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColStd_Array1OfBoolean.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_Array2OfInteger.hxx>
+#include <TColStd_Array2OfReal.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TopAbs_Orientation.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
-#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
 #include <TopoDS_Shell.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopAbs_Orientation.hxx>
-
-#include <TColStd_HArray1OfInteger.hxx>
-#include <TColStd_Array2OfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_Array2OfReal.hxx>
-#include <TColGeom_Array2OfSurface.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-
+#include <TopoDS_Wire.hxx>
 #include <TopTools_Array1OfShape.hxx>
 #include <TopTools_Array2OfShape.hxx>
-#include <TopTools_HArray2OfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
 #include <TopTools_HArray1OfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx> 
-#include <TopTools_ListOfShape.hxx> 
+#include <TopTools_HArray2OfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <BRepTools_WireExplorer.hxx>
-
-#include <Standard_ConstructionError.hxx>
-#include <Precision.hxx>
-#include <BRepBuilderAPI_MakeWire.hxx>
-
-#include <BRepTools_Substitution.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
-#include <TopoDS_Iterator.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 
+#include <stdio.h>
+//#include <BRepFill_TrimCorner.hxx>
+// modified by NIZHNY-MKK  Wed Oct 22 12:25:45 2003
+//#include <GeomPlate_BuildPlateSurface.hxx>
+//#include <GeomPlate_Surface.hxx>
+//#include <GeomPlate_PointConstraint.hxx>
 //OCC500(apo)
-#include <BRepCheck_Edge.hxx>  
-
 #ifdef DRAW
 #include <Draw.hxx>
 #include <DrawTrSurf.hxx>
 #include <DBRep.hxx>
+#include <Geom_BoundedSurface.hxx>
 static Standard_Boolean Affich = 0;
 #endif
 
@@ -262,7 +250,7 @@ static Handle(Geom2d_Curve) Couture(const TopoDS_Edge& E,
   while (itcr.More()) {
     Handle(BRep_CurveRepresentation)& cr = itcr.Value();
     if (cr->IsCurveOnSurface(S,l)) {
-      Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
+      Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
       if (GC->IsCurveOnClosedSurface() && Eisreversed) 
        return  GC->PCurve2();
       else
@@ -352,10 +340,11 @@ static Standard_Boolean SameParameter(TopoDS_Edge&    E,
        }
     }
 
-  Approx_SameParameter sp( HC3d, Pcurv, S, tol3d );
+  const Handle(Adaptor3d_HCurve)& aHCurve = HC3d; // to avoid ambiguity
+  Approx_SameParameter sp (aHCurve, Pcurv, S, tol3d );
   if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
   else if(!sp.IsDone() && !sp.IsSameParameter()){
-#ifdef DEB
+#ifdef OCCT_DEBUG
     cout<<"echec SameParameter"<<endl;
 #endif  
     return Standard_False;
@@ -363,7 +352,7 @@ static Standard_Boolean SameParameter(TopoDS_Edge&    E,
 
   ResTol = sp.TolReached();
   if(ResTol > tolreached ){
-#ifdef DEB
+#ifdef OCCT_DEBUG
     cout<<"SameParameter : Tolerance not reached!"<<endl;
     cout<<"tol visee : "<<tol3d<<" tol obtained : "<<ResTol<<endl;
 #endif  
@@ -604,7 +593,7 @@ static void BuildFace(const Handle(Geom_Surface)& S,
       thePlane->UReverse();
     BRepLib_MakeFace MkF( thePlane, WW );
     if (MkF.Error() != BRepLib_FaceDone) {
-#if DEB
+#ifdef OCCT_DEBUG
       BRepLib_FaceError Err = MkF.Error();
       cout << "Planar Face Error :" <<   Err << endl;
 #endif
@@ -913,20 +902,16 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF,
                     f2, l2, C3);
   C2 = C3;
 
-  Standard_Boolean pointu_f,  pointu_l;
 //  P1 = BT.Pnt(Vf);
   P1 = BRep_Tool::Pnt(Vf);
 //  P2 = BT.Pnt(V1);
   P2 = BRep_Tool::Pnt(V1);
 //  pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BT.Tolerance(Vf));
-  pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BRep_Tool::Tolerance(Vf));
 //  P1 = BT.Pnt(Vl);
   P1 = BRep_Tool::Pnt(Vl);
 //  P2 = BT.Pnt(V2);
   P2 = BRep_Tool::Pnt(V2);
 //  pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BT.Tolerance(Vl));
-  pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BRep_Tool::Tolerance(Vl));
-
 
   P2d.SetCoord(0.,f1);
   L = new (Geom2d_Line) (P2d, gp::DX2d());
@@ -1041,12 +1026,12 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF,
                                  GeomAbs_C1, GeomAbs_C1,
                                  8, 8, 2*NbInt, 0);
     if (!App.HasResult()) {
-#if DEB
+#ifdef OCCT_DEBUG
       cout << "Filling_Approx : Pas de resultat" << endl;
 #endif      
       return Standard_False;
     }
-#if DEB
+#ifdef OCCT_DEBUG
     cout <<  "Filling_Approx Error 3d = " << 
       App.MaxError() << endl;
 #endif
@@ -1241,7 +1226,7 @@ static void SetCommonEdgeInFace(BRepTools_Substitution& aSubstitute,
       Substitute( aSubstitute, OldEdge, NewEdge );
     }
   }
-#if DEB
+#ifdef OCCT_DEBUG
   if (!done) cout << "Substitution of Edge failed" << endl;
 #endif  
 }
@@ -1442,13 +1427,17 @@ static TopoDS_Edge BuildEdge(const Handle(Geom_Surface)& S,
   // Associate 2d
   Handle(Geom2d_Line) L;
   TopLoc_Location Loc;
+  Standard_Real Umin, Umax, Vmin, Vmax;
+  S->Bounds(Umin, Umax, Vmin, Vmax);
   if (isUiso) {
-    gp_Pnt2d P(ValIso, 0);
+    //gp_Pnt2d P(ValIso, 0);
+    gp_Pnt2d P( ValIso, Vmin - Iso->FirstParameter() );
     gp_Vec2d V(0., 1.);
     L = new (Geom2d_Line) (P, V);
   }
   else {
-    gp_Pnt2d P(0., ValIso);
+    //gp_Pnt2d P(0., ValIso);
+    gp_Pnt2d P( Umin -Iso->FirstParameter() , ValIso );
     gp_Vec2d V(1., 0.);
     L = new (Geom2d_Line) (P, V);
   }
@@ -1708,7 +1697,9 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
   LastShape  = Last; 
 
   // It is necessary to check the SameRange on its (PRO13551)
+#ifdef OCCT_DEBUG
   Standard_Boolean issame = Standard_True;
+#endif
   BRep_Builder B;
   BRepTools_WireExplorer wexp;
   if (!FirstShape.IsNull()) {
@@ -1716,7 +1707,9 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
       if (!BRepLib::CheckSameRange(wexp.Current())) {
        B.SameRange(wexp.Current(), Standard_False);
        B.SameParameter(wexp.Current(), Standard_False);
+#ifdef OCCT_DEBUG
        issame = Standard_False;
+#endif
       }
     }
   }
@@ -1726,12 +1719,14 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
       if (!BRepLib::CheckSameRange(wexp.Current())) {
        B.SameRange(wexp.Current(), Standard_False); 
        B.SameParameter(wexp.Current(), Standard_False);
+#ifdef OCCT_DEBUG
        issame = Standard_False;
+#endif
       }
     }
   }
 
-#if DEB
+#ifdef OCCT_DEBUG
   if (!issame) 
     cout<<"Sweep Warning : Edge not SameRange in the limits"<<endl;
 #endif
@@ -1938,6 +1933,9 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
  BuildShell(const BRepFill_TransitionStyle /*Transition*/,
            const Standard_Integer IFirst,
            const Standard_Integer ILast,
+            TopTools_MapOfShape& ReversedEdges,
+            BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
+            BRepFill_DataMapOfShapeHArray2OfShape& Rails,
            const Standard_Real ExtendFirst,
            const Standard_Real ExtendLast) 
 {
@@ -2065,151 +2063,242 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
   Standard_Boolean exuv, singu, singv;
   Handle(Geom_Surface) S;
 
-  if (! vclose) {
-    // (2.0) return preexisting Edges and vertices
-    TopoDS_Edge E;
-    if (! FirstShape.IsNull() && (IFirst==1)) {
-      mySec->Init(FirstShape);
-      for (isec=1; isec<=NbLaw; isec++) {
-       E = mySec->CurrentEdge();
-       VEdge(isec, 1) = E;
-        if (E.Orientation() == TopAbs_REVERSED)
-          Vertex(isec+1, 1) = TopExp::FirstVertex(E);
-        else 
-          Vertex(isec+1, 1) =  TopExp::LastVertex(E);
-       UpdateVertex(IFirst-1, isec+1, 
-                    TabErr(isec, 1), Vi(1),  Vertex(isec+1, 1));
-       }
-      if (VEdge(1, 1).Orientation() == TopAbs_REVERSED)
-       Vertex(1, 1) =  TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1)));
+  // (2.0) return preexisting Edges and vertices
+  TopoDS_Edge E;
+  TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
+  IsBuilt.Init(Standard_False);
+  TopTools_Array1OfShape StartEdges(1, NbLaw);
+  if (! FirstShape.IsNull() && (IFirst==1)) {
+    mySec->Init(FirstShape);
+    for (isec=1; isec<=NbLaw; isec++) {
+      E = mySec->CurrentEdge();
+      TopoDS_Vertex Vfirst, Vlast;
+      TopExp::Vertices(E, Vfirst, Vlast);
+      VEdge(isec, 1) = E;
+      if (E.Orientation() == TopAbs_REVERSED)
+        Vertex(isec+1, 1) = Vfirst; //TopExp::FirstVertex(E);
+      else 
+        Vertex(isec+1, 1) = Vlast; //TopExp::LastVertex(E);
+      UpdateVertex(IFirst-1, isec+1, 
+                   TabErr(isec, 1), Vi(1),  Vertex(isec+1, 1));
+
+      StartEdges(isec) = E;
+      if (Tapes.IsBound(E))
+      {
+        IsBuilt(isec) = Standard_True;
+        
+        //Initialize VEdge, UEdge, Vertex and myFaces
+        Standard_Integer j;
+        for (j = 1; j <= NbPath+1; j++)
+        {
+          VEdge(isec, j) = Tapes(E)->Value(1, j);
+          VEdge(isec, j).Reverse(); //direction of round is reversed
+        }
+        Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed
+        for (j = 1; j <= NbPath; j++)
+          UEdge(ifirst, j) = Tapes(E)->Value(2, j);
+        for (j = 1; j <= NbPath; j++)
+          UEdge(ilast, j) = Tapes(E)->Value(3, j);
+        for (j = 1; j <= NbPath+1; j++)
+          Vertex(ifirst, j) = Tapes(E)->Value(4, j);
+        for (j = 1; j <= NbPath+1; j++)
+          Vertex(ilast, j) = Tapes(E)->Value(5, j);
+        for (j = 1; j <= NbPath; j++)
+          myFaces->SetValue(isec, j, Tapes(E)->Value(6, j));
+
+        if (uclose && isec == 1)
+        {
+          for (j = 1; j <= NbPath; j++)
+            UEdge(NbLaw+1, j) = UEdge(1, j);
+          for (j = 1; j <= NbPath+1; j++)
+            Vertex(NbLaw+1, j) = Vertex(1, j);
+        }
+        if (uclose && isec == NbLaw)
+        {
+          for (j = 1; j <= NbPath; j++)
+            UEdge(1, j) = UEdge(NbLaw+1, j);
+          for (j = 1; j <= NbPath+1; j++)
+            Vertex(1, j) = Vertex(NbLaw+1, j);
+        }
+      }
       else
-       Vertex(1, 1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, 1)));
-      UpdateVertex(IFirst-1, 1, 
-                  TabErr(1, 1), Vi(1),  Vertex(1, 1));
-    }
-    else { // Otherwise construct vertices
-      Standard_Real u, v, aux;
-      Standard_Boolean ureverse;
-      for (isec=1; isec<=NbLaw+1; isec++) {
-       // Return data
-       if (isec >NbLaw) {
-         S = TabS(NbLaw, 1);
-         ureverse = UReverse(NbLaw, 1);
-         exuv = ExchUV(NbLaw, 1);
-       }
-       else  {
-         S = TabS(isec, 1);
-         ureverse = UReverse(isec, 1);
-         exuv = ExchUV(isec, 1);
-       }
-       S->Bounds(UFirst, ULast, VFirst, VLast);
-
-       // Choice of parameters
-       if (ureverse) {
-         if (exuv) {
-           aux = VFirst; VFirst = VLast; VLast = aux;    
-         }
-         else {
-           aux = UFirst; UFirst = ULast; ULast = aux;
-         }
-       }
-       if (isec!= NbLaw+1) {
-         u = UFirst;
-         v = VFirst;
-       }
-       else {
-         if (exuv) {
-           u = UFirst;
-           v = VLast;
-         }
-         else {
-           u = ULast;
-           v = VFirst;
-         }
-       }
-
-       // construction of vertices
-       B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)), 
-                    S->Value(u,v), 
-                    mySec->VertexTol(isec-1,Vi(1)));
+      {
+        Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1);
+        Tapes.Bind(E, EmptyArray);
+        Standard_Integer j;
+        if (Rails.IsBound(Vfirst))
+        {
+          Standard_Integer ind = (E.Orientation() == TopAbs_REVERSED)? isec+1 : isec;
+          for (j = 1; j <= NbPath; j++)
+            UEdge(ind, j) = Rails(Vfirst)->Value(1, j);
+          for (j = 1; j <= NbPath+1; j++)
+            Vertex(ind, j) = Rails(Vfirst)->Value(2, j);
+        }
+        if (Rails.IsBound(Vlast))
+        {
+          Standard_Integer ind = (E.Orientation() == TopAbs_FORWARD)? isec+1 : isec;
+          for (j = 1; j <= NbPath; j++)
+            UEdge(ind, j) = Rails(Vlast)->Value(1, j);
+          for (j = 1; j <= NbPath+1; j++)
+            Vertex(ind, j) = Rails(Vlast)->Value(2, j);
+        }
       }
-   }
-
-    if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) {
-      mySec->Init(LastShape);
-      for (isec=1; isec<=NbLaw; isec++) {
-       E = mySec->CurrentEdge();
-       VEdge(isec, NbPath+1) = E;
-       if (E.Orientation() == TopAbs_REVERSED)
-          Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(E);
-       else 
-         Vertex(isec+1, NbPath+1) = TopExp::LastVertex(E);
-       UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath), 
-                    Vi(NbPath+1),  Vertex(isec+1, NbPath+1));
+    }
+    
+    if (VEdge(1, 1).Orientation() == TopAbs_REVERSED)
+      Vertex(1, 1) =  TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1)));
+    else
+      Vertex(1, 1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, 1)));
+    UpdateVertex(IFirst-1, 1, 
+                 TabErr(1, 1), Vi(1),  Vertex(1, 1));
+  }
+  
+  Standard_Real u, v, aux;
+  Standard_Boolean ureverse;
+  for (isec=1; isec<=NbLaw+1; isec++) {
+    // Return data
+    if (isec >NbLaw) {
+      S = TabS(NbLaw, 1);
+      ureverse = UReverse(NbLaw, 1);
+      exuv = ExchUV(NbLaw, 1);
+    }
+    else {
+      S = TabS(isec, 1);
+      ureverse = UReverse(isec, 1);
+      exuv = ExchUV(isec, 1);
+    }
+    S->Bounds(UFirst, ULast, VFirst, VLast);
+    
+    // Choice of parameters
+    if (ureverse) {
+      if (exuv) {
+        aux = VFirst; VFirst = VLast; VLast = aux;       
+      }
+      else {
+        aux = UFirst; UFirst = ULast; ULast = aux;
+      }
+    }
+    if (isec!= NbLaw+1) {
+      u = UFirst;
+      v = VFirst;
+    }
+    else {
+      if (exuv) {
+        u = UFirst;
+        v = VLast;
       }
+      else {
+        u = ULast;
+        v = VFirst;
+      }
+    }
+    
+    // construction of vertices
+    if (Vertex(isec, 1).IsNull())
+      B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)), 
+                   S->Value(u,v), 
+                   mySec->VertexTol(isec-1,Vi(1)));
+    else
+    {
+      TopLoc_Location Identity;
+      Vertex(isec, 1).Location(Identity);
+      B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)),
+                     S->Value(u,v), 
+                       mySec->VertexTol(isec-1,Vi(1)));
+    }
+  } //end of for (isec=1; isec<=NbLaw+1; isec++)
+  
+  if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) {
+    mySec->Init(LastShape);
+    for (isec=1; isec<=NbLaw; isec++) {
+      E = mySec->CurrentEdge();
+      if (VEdge(isec, NbPath+1).IsNull())
+        VEdge(isec, NbPath+1) = E;
+
+      if (Vertex(isec+1, NbPath+1).IsNull())
+      {
+        if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED)
+          Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
+        else 
+          Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
+      }
+      UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath), 
+                   Vi(NbPath+1),  Vertex(isec+1, NbPath+1));
+    }
+
+    if (Vertex(1,  NbPath+1).IsNull())
+    {
       if (VEdge(1,  NbPath+1).Orientation() == TopAbs_REVERSED)
-       Vertex(1,  NbPath+1) =  
-         TopExp::LastVertex(TopoDS::Edge(VEdge(1,  NbPath+1)));
+        Vertex(1,  NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1,  NbPath+1)));
       else
-       Vertex(1,  NbPath+1) = 
-         TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
-      UpdateVertex(ILast-1, 1, 
-                  TabErr(1, NbPath), Vi(NbPath+1),  Vertex(1, NbPath+1 ));
-    }    
+        Vertex(1,  NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
+    }
+    UpdateVertex(ILast-1, 1, 
+                 TabErr(1, NbPath), Vi(NbPath+1),  Vertex(1, NbPath+1 ));
+  }
+  
+  for (isec=1; isec<=NbLaw+1; isec++) {
+    // Return data
+    if (isec >NbLaw) {
+        S = TabS(NbLaw, NbPath);
+        ureverse = UReverse(NbLaw, NbPath);
+        exuv = ExchUV(NbLaw, NbPath);
+    }
     else {
-      Standard_Real u, v, aux;
-      Standard_Boolean ureverse;
-      for (isec=1; isec<=NbLaw+1; isec++) {
-       // Return data
-       if (isec >NbLaw) {
-         S = TabS(NbLaw, NbPath);
-         ureverse = UReverse(NbLaw, NbPath);
-         exuv = ExchUV(NbLaw, NbPath);
-       }
-       else  {
-         S = TabS(isec, NbPath);
-         ureverse = UReverse(isec, NbPath);
-         exuv = ExchUV(isec, NbPath);
-       }
-       S->Bounds(UFirst, ULast, VFirst, VLast);
-
-       // Choice of parametres
-       if (ureverse) {
-         if (exuv) {
-           aux = VFirst; VFirst = VLast; VLast = aux;    
-         }
-         else {
-           aux = UFirst; UFirst = ULast; ULast = aux;
-         }
-       }
-       if (isec == NbLaw+1) {
-         u = ULast;
-         v = VLast;
-       }
-       else {
-         if (exuv) {
-           u = ULast;
-           v = VFirst;
-         }
-         else {
-           u = UFirst;
-           v = VLast;
-         }
-       }
-
-       // construction of vertex
-       B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), 
-                    S->Value(u,v), 
-                    mySec->VertexTol(isec-1, Vi(NbPath+1)));
+      S = TabS(isec, NbPath);
+      ureverse = UReverse(isec, NbPath);
+      exuv = ExchUV(isec, NbPath);
+    }
+    S->Bounds(UFirst, ULast, VFirst, VLast);
+    
+    // Choice of parametres
+    if (ureverse) {
+      if (exuv) {
+        aux = VFirst; VFirst = VLast; VLast = aux;       
+      }
+      else {
+        aux = UFirst; UFirst = ULast; ULast = aux;
       }
     }
-  }
+    if (isec == NbLaw+1) {
+      u = ULast;
+      v = VLast;
+    }
+    else {
+      if (exuv) {
+        u = ULast;
+        v = VFirst;
+      }
+      else {
+        u = UFirst;
+        v = VLast;
+      }
+    }
+    
+    // construction of vertex
+    if (Vertex(isec, NbPath+1).IsNull())
+      B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), 
+                   S->Value(u,v), 
+                   mySec->VertexTol(isec-1, Vi(NbPath+1)));
+      else
+      {
+        TopLoc_Location Identity;
+        Vertex(isec, NbPath+1).Location(Identity);
+        B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), 
+                       S->Value(u,v), 
+                       mySec->VertexTol(isec-1, Vi(NbPath+1)));
+      }
+  } //end of for (isec=1; isec<=NbLaw+1; isec++)
 
  
   // ---------- Creation of Vertex and edge ------------
+  ReversedEdges.Clear();
   for (ipath=1, IPath=IFirst; ipath<=NbPath; 
        ipath++, IPath++) {
     for (isec=1; isec <=NbLaw; isec++) {
+      if (IsBuilt(isec))
+        continue;
+      
       S = TabS(isec, ipath);
       exuv = ExchUV(isec, ipath);
       S->Bounds(UFirst, ULast, VFirst, VLast);
@@ -2261,26 +2350,28 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
         }
        }
 
-      if (ipath == 1)
-       if (uclose && (isec == NbLaw)) {
-         Vertex(isec+1, 1) =  Vertex(1, 1);
-       }  
-       else if (Vertex(isec+1, 1).IsNull()) {
-         if (constSection)
-           myLoc->PerformVertex(IPath-1, 
-                                TopoDS::Vertex(SecVertex(isec+1)),
-                                TabErr(isec,1)+VError(isec+1),
-                                TopoDS::Vertex(Vertex(isec+1, 1)) );
-         else
-           myLoc->PerformVertex(IPath-1, 
-                                mySec->Vertex(isec+1,Vi(1)), 
-                                TabErr(isec,1) +
-                                mySec->VertexTol(isec,Vi(1)),
-                                TopoDS::Vertex(Vertex(isec+1, 1)) );
-         if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) {
-           VEdge(isec, 1) = NullEdge(Vertex(isec, 1)); 
-         }
-       }
+      if (ipath == 1) {
+        if (uclose && (isec == NbLaw)) {
+          Vertex(isec+1, 1) =  Vertex(1, 1);
+        }  
+        else if (Vertex(isec+1, 1).IsNull()) {
+          if (constSection)
+            myLoc->PerformVertex(IPath-1, 
+               TopoDS::Vertex(SecVertex(isec+1)),
+               TabErr(isec,1)+VError(isec+1),
+               TopoDS::Vertex(Vertex(isec+1, 1)) );
+          else
+            myLoc->PerformVertex(IPath-1, 
+               mySec->Vertex(isec+1,Vi(1)), 
+               TabErr(isec,1) +
+               mySec->VertexTol(isec,Vi(1)),
+               TopoDS::Vertex(Vertex(isec+1, 1)) );
+                                            
+          if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) {
+            VEdge(isec, 1) = NullEdge(Vertex(isec, 1)); 
+          }
+        }
+      }
 
       if (uclose && (isec == NbLaw)) {
        Vertex(isec+1, ipath+1) = Vertex(1, ipath+1);
@@ -2313,7 +2404,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                                           Max(myTol3d, TabErr(isec,ipath)));
       }
       if (Degenerated(isec, ipath)) { 
-#if DEB
+#ifdef OCCT_DEBUG
        cout << "Sweep : Degenerated case" << endl;
 #endif
        hasdegen = Standard_True;
@@ -2345,7 +2436,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
        }
   
        // (2.2) Iso-u
-       if (isec == 1) {
+       if (isec == 1 && UEdge(1, ipath).IsNull()) {
          if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) {
            gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath)));
            gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1)));
@@ -2357,44 +2448,95 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                                      Vertex(1,ipath+1),
                                      myTol3d);
        }
-       else UpdateEdge(TopoDS::Edge(UEdge(isec, ipath)), 
-                       S, !exuv, UFirst);
+       else
+        {
+          if (UEdge(isec, ipath).IsNull()) //sweep failed
+            return Standard_False;
+          UpdateEdge(TopoDS::Edge(UEdge(isec, ipath)), 
+                     S, !exuv, UFirst);
+        }
      
        if (uclose && (isec==NbLaw)) {
-         UpdateEdge(TopoDS::Edge(UEdge(1, ipath)), 
-                    S, !exuv, ULast);
-         UEdge(isec+1, ipath) = UEdge(1, ipath);
+          if (UEdge(1, ipath).IsNull()) //degenerated case
+          {
+            UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, 
+                                             Vertex(isec+1, ipath), 
+                                             Vertex(isec+1, ipath+1),
+                                             myTol3d);
+          }
+          else {
+            UpdateEdge(TopoDS::Edge(UEdge(1, ipath)), 
+                      S, !exuv, ULast);
+            UEdge(isec+1, ipath) = UEdge(1, ipath);
+          }
        }
        else {
-         UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, 
-                                          Vertex(isec+1, ipath), 
-                                          Vertex(isec+1, ipath+1),
-                                          myTol3d);
+          if (UEdge(isec+1, ipath).IsNull())
+            UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, 
+                                             Vertex(isec+1, ipath), 
+                                             Vertex(isec+1, ipath+1),
+                                             myTol3d);
+          else
+            UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast);
        }
 
        // (2.3) Iso-v 
-       if (ipath == 1 && VEdge(isec, ipath).IsNull())
-         VEdge(isec, ipath) = BuildEdge(S, exuv, VFirst, 
-                                        Vertex(isec  , 1), 
-                                        Vertex(isec+1, 1),
-                                        myTol3d);
+       if (ipath == 1)
+        {
+          TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst, 
+                                                Vertex(isec  , 1), 
+                                                Vertex(isec+1, 1),
+                                                myTol3d);
+          if (VEdge(isec, ipath).IsNull())
+            VEdge(isec, ipath) = aNewFirstEdge;
+          else //rebuild first edge
+          {
+            RebuildTopOrBottomEdge(aNewFirstEdge,
+                                   TopoDS::Edge(VEdge(isec, ipath)),
+                                   ReversedEdges);
+            if (ReversedEdges.Contains(VEdge(isec, ipath)))
+              StartEdges(isec).Reverse();
+          }
+        }
        
        else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)), 
                        S, exuv, VFirst);
        
        if (vclose && (ipath == NbPath)) {
-         UpdateEdge(TopoDS::Edge(VEdge(isec, 1)), 
-                    S, exuv, VLast);
-         VEdge(isec, ipath+1) = VEdge(isec, 1);
+          if (VEdge(isec, 1).IsNull()) //degenerated case
+          {
+            VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast, 
+                                            Vertex(isec  , ipath+1), 
+                                             Vertex(isec+1, ipath+1),
+                                             myTol3d);
+          }
+          else {
+            UpdateEdge(TopoDS::Edge(VEdge(isec, 1)), 
+                      S, exuv, VLast);
+            VEdge(isec, ipath+1) = VEdge(isec, 1);
+          }
        }
        else if (VEdge(isec, ipath+1).IsNull())
          VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast, 
                                           Vertex(isec  , ipath+1), 
                                           Vertex(isec+1, ipath+1),
                                           myTol3d);
-       else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), 
-                       S, exuv, VLast);
-         
+       else
+        {
+          if (ipath != NbPath || vclose)
+            UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), 
+                       S, exuv, VLast);
+          else //ipath == NbPath && !vclose => rebuild last edge
+          {
+            TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast, 
+                                                 Vertex(isec  , ipath+1), 
+                                                 Vertex(isec+1, ipath+1),
+                                                 myTol3d);
+            RebuildTopOrBottomEdge(aNewLastEdge,
+                                   TopoDS::Edge(VEdge(isec, ipath+1)),
+                                   ReversedEdges);
+          }
+        }
       }
     }// End of construction of edges
   }
@@ -2433,7 +2575,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
        else  
          myFaces->SetValue(isec, IPath, VEdge(isec, ipath));
       }
-      else {
+      else if (myFaces->Value(isec, IPath).IsNull()) {
        BuildFace(TabS(isec,ipath), 
                  TopoDS::Edge(UEdge(isec, ipath)),
                  TopoDS::Edge(VEdge(isec, ipath)),
@@ -2448,6 +2590,12 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
     }
   }
 
+  // (3.1) Reverse the faces that have been built ealier
+  for (ipath = 1; ipath <= NbPath; ipath++)
+    for (isec = 1; isec <= NbLaw; isec++)
+      if (IsBuilt(isec))
+        myFaces->ChangeValue(isec, ipath).Reverse();
+  
 
   // (4) History and Continuity 
 
@@ -2506,6 +2654,48 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
       } 
     }
   }
+
+  // (5) Update Tapes and Rails
+  Standard_Integer j;
+  if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell
+  {
+    for (isec = 1; isec <= NbLaw; isec++)
+    {
+      for (j = 1; j <= NbPath+1; j++)
+        Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j));
+      for (j = 1; j <= NbPath; j++)
+        Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j));
+      for (j = 1; j <= NbPath; j++)
+        Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j));
+      for (j = 1; j <= NbPath+1; j++)
+        Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j));
+      for (j = 1; j <= NbPath+1; j++)
+        Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j));
+      for (j = 1; j <= NbPath; j++)
+        Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j));
+      TopoDS_Vertex Vfirst, Vlast;
+      TopExp::Vertices(TopoDS::Edge(StartEdges(isec)), Vfirst, Vlast, Standard_True); //with orientation
+      if (!Rails.IsBound(Vfirst))
+      {
+        Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
+        for (j = 1; j <= NbPath; j++)
+          anArray->SetValue(1, j, myUEdges->Value(isec, j));
+        for (j = 1; j <= NbPath+1; j++)
+          anArray->SetValue(2, j, Vertex(isec, j));
+        Rails.Bind(Vfirst, anArray);
+      }
+      if (!Rails.IsBound(Vlast))
+      {
+        Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
+        for (j = 1; j <= NbPath; j++)
+          anArray->SetValue(1, j, myUEdges->Value(isec+1, j));
+        for (j = 1; j <= NbPath+1; j++)
+          anArray->SetValue(2, j, Vertex(isec+1, j));
+        Rails.Bind(Vlast, anArray);
+      }
+    }
+  }
+  
   return Standard_True;
 }
 
@@ -2513,11 +2703,14 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
 //function : Build
 //purpose  : Construt the result of sweeping
 //======================================================================
- void BRepFill_Sweep::Build(const BRepFill_TransitionStyle Transition,
-                           const GeomAbs_Shape Continuity,
-                           const GeomFill_ApproxStyle Approx,
-                           const Standard_Integer Degmax,
-                           const Standard_Integer Segmax) 
+void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
+                           BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
+                           BRepFill_DataMapOfShapeHArray2OfShape& Rails,
+                           const BRepFill_TransitionStyle Transition,
+                           const GeomAbs_Shape Continuity,
+                           const GeomFill_ApproxStyle Approx,
+                           const Standard_Integer Degmax,
+                           const Standard_Integer Segmax) 
 {
   myContinuity  = Continuity;
   myApproxStyle = Approx;
@@ -2554,6 +2747,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
       if (NbTrous==1)  Extend = EvalExtrapol(1, Transition);
       isDone = BuildShell(Transition, 
                          1, NbPath+1,
+                          ReversedEdges,
+                          Tapes, Rails,
                          Extend, Extend);
     }
     else { //  This is done piece by piece
@@ -2564,6 +2759,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
        else ILast = Trous->Value(ii);
        isDone = BuildShell(Transition, 
                            IFirst, ILast,
+                            ReversedEdges,
+                            Tapes, Rails,
                            EvalExtrapol(IFirst, Transition),
                            EvalExtrapol(ILast,  Transition));
        if (IFirst>1) {
@@ -2797,7 +2994,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
     t2 = M.Column(3);
 
     if (t1.Angle(t2) < myAngMin) {
-#if DEB
+#ifdef OCCT_DEBUG
       cout << "BRepFill_Sweep::PerformCorner : This is not a corner !" << endl;
 #endif
       return;
@@ -2890,7 +3087,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
   }
   else if ((TheTransition == BRepFill_Right) ||
           aTrim.HasSection() ) { 
-#if DEB
+#ifdef OCCT_DEBUG
     cout << "Fail of TrimCorner" << endl;
 #endif
     return; // Nothing is touched
@@ -2958,7 +3155,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
          if (ii==1) BordFirst = Bord1;
        }
       }
-#if DEB
+#ifdef OCCT_DEBUG
       else cout << "PerformCorner : Unsymmetry of free border" << endl;
 #endif
     }
@@ -3106,3 +3303,105 @@ void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath,
     B.UpdateVertex(TheV, Tol);
   }
 }
+
+//=======================================================================
+//function : RebuildTopOrBottomEdge
+//purpose  : Rebuild v-iso edge of top or bottom section
+//           inserting new 3d and 2d curves taken from swept surfaces
+//======================================================================
+void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge,
+                                            TopoDS_Edge& anEdge,
+                                            TopTools_MapOfShape& ReversedEdges) const
+{
+  Standard_Real fpar, lpar;
+  Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar);
+  TopLoc_Location Identity;
+  
+  Standard_Boolean ToReverse = Standard_False;
+  Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge);
+  if (IsDegen)
+    BRep_Tool::Range(aNewEdge, fpar, lpar);
+  else
+  {
+    TopoDS_Vertex V1, V2, NewV1, NewV2;
+    TopExp::Vertices(anEdge, V1, V2);
+    if (!V1.IsSame(V2))
+    {
+      TopExp::Vertices(aNewEdge, NewV1, NewV2);
+      V1.Location(Identity);
+      if (!V1.IsSame(NewV1))
+      {
+        if (V1.IsSame(NewV2))
+          ToReverse = Standard_True;
+        else
+        {
+          gp_Pnt Pnt1 = BRep_Tool::Pnt(V1);
+          gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1);
+          Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1);
+          if (!Pnt1.IsEqual(NewPnt1, TolSum))
+            ToReverse = Standard_True;
+        }
+      }
+    }
+    else
+    {
+      Standard_Real OldFirst, OldLast;
+      Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast);
+      gp_Vec OldD1, NewD1;
+      gp_Pnt MidPnt;
+      OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1);
+      aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1);
+      if (OldD1 * NewD1 < 0.)
+        ToReverse = Standard_True;
+    }
+  }
+  
+  anEdge.Location(Identity);
+  const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape());
+  TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge));
+  BRep_Builder BB;
+  BB.Range(anEdge, fpar, lpar);
+  BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion());
+  const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape());
+  const BRep_ListOfCurveRepresentation& lcr = TE->Curves();
+  BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr);
+  for (; itrep.More(); itrep.Next())
+  {
+    const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value();
+    if (CurveRep->IsCurveOnSurface())
+    {
+      Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (CurveRep));
+      Handle(Geom2d_Curve) aPCurve = GC->PCurve();
+      Handle(Geom_Surface) aSurf = GC->Surface();
+      TopLoc_Location aLoc = aNewEdge.Location() * GC->Location();
+      BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion());
+    }
+  }
+  
+  anEdge.Free(Standard_True);
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(anEdge, V1, V2);
+
+  TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD);
+  
+  BB.Remove(anEdgeFORWARD, V1);
+  BB.Remove(anEdgeFORWARD, V2);
+  V1.Location(Identity);
+  V2.Location(Identity);
+  if (ToReverse)
+  {
+    V2.Orientation(TopAbs_FORWARD);
+    V1.Orientation(TopAbs_REVERSED);
+  }
+  BB.Add(anEdgeFORWARD, V1);
+  BB.Add(anEdgeFORWARD, V2);
+  
+  if (ToReverse)
+  {
+    anEdge.Reverse();
+    ReversedEdges.Add(anEdge);
+  }
+
+  BB.Degenerated(anEdge, IsDegen);
+}