]> OCCT Git - occt-copy.git/commitdiff
Old implementation of the offset algorithm has been added alongside the new one ...
authoremv <emv@opencascade.com>
Fri, 25 Mar 2016 05:58:57 +0000 (08:58 +0300)
committeremv <emv@opencascade.com>
Fri, 25 Mar 2016 05:58:57 +0000 (08:58 +0300)
New key has been added to the offsetparameter command to choose the version of the algorithm (old version is default).

src/BRepOffset/BRepOffset.cdl
src/BRepOffset/BRepOffset_MakeOffsetOld.cdl [new file with mode: 0644]
src/BRepOffset/BRepOffset_MakeOffsetOld.cxx [new file with mode: 0644]
src/BRepTest/BRepTest_FeatureCommands.cxx

index 2147e086ba8e3609f44aabd8ee6f66b160d2667f..9d29348dcc920809de8e65481413c22df16c8295 100644 (file)
@@ -76,6 +76,7 @@ is
     end Error;
     
     class MakeOffset;
+    class MakeOffsetOld;
        
     --class Loop;
     
diff --git a/src/BRepOffset/BRepOffset_MakeOffsetOld.cdl b/src/BRepOffset/BRepOffset_MakeOffsetOld.cdl
new file mode 100644 (file)
index 0000000..ba88546
--- /dev/null
@@ -0,0 +1,254 @@
+-- Created on: 1995-10-26
+-- Created by: Yves FRICAUD
+-- Copyright (c) 1995-1999 Matra Datavision
+-- Copyright (c) 1999-2014 OPEN CASCADE SAS
+--
+-- This file is part of Open CASCADE Technology software library.
+--
+-- 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.
+--
+-- Alternatively, this file may be used under the terms of Open CASCADE
+-- commercial license or contractual agreement.
+
+-- Modified by skv - Tue Mar 15 16:17:37 2005
+-- Add methods for supporting history.
+
+class MakeOffsetOld from BRepOffset 
+
+        ---Purpose: 
+
+uses
+    Image                from BRepAlgo,
+    AsDes                from BRepAlgo,
+    Analyse              from BRepOffset,
+    Mode                 from BRepOffset,
+    DataMapOfShapeOffset from BRepOffset, 
+    Error                from BRepOffset,
+    Inter3d              from BRepOffset,
+    DataMapOfShapeReal   from TopTools,
+    Shape                from TopoDS,
+    JoinType             from GeomAbs,
+    Face                 from TopoDS,
+    Edge                 from TopoDS,
+    MapOfShape           from TopTools, 
+    IndexedMapOfShape    from TopTools, 
+    ListOfShape          from TopTools, 
+    DataMapOfShapeShape  from TopTools, 
+    IndexedDataMapOfShapeListOfShape from TopTools,
+    MakeLoops            from BRepOffset
+
+is
+
+    Create;
+    
+    Create ( S              : Shape    from TopoDS;
+             Offset         : Real     from Standard;
+             Tol            : Real     from Standard;
+             Mode           : Mode     from BRepOffset = BRepOffset_Skin;
+             Intersection   : Boolean  from Standard   = Standard_False;
+             SelfInter      : Boolean  from Standard   = Standard_False;
+             Join           : JoinType from GeomAbs    = GeomAbs_Arc; 
+             Thickening     : Boolean  from Standard   = Standard_False; 
+             RemoveIntEdges : Boolean  from Standard   = Standard_False;
+             RemoveInvalidFaces: Boolean from Standard = Standard_False)
+    returns MakeOffsetOld from BRepOffset;             
+             
+---Category: Initialization.
+
+    Initialize (me : in out;
+                S              : Shape    from TopoDS;
+                Offset         : Real     from Standard;
+                Tol            : Real     from Standard;
+                Mode           : Mode     from BRepOffset = BRepOffset_Skin;
+                Intersection   : Boolean  from Standard   = Standard_False;
+                SelfInter      : Boolean  from Standard   = Standard_False;
+                Join           : JoinType from GeomAbs    = GeomAbs_Arc; 
+                Thickening     : Boolean  from Standard   = Standard_False;
+                RemoveIntEdges : Boolean  from Standard   = Standard_False;
+                RemoveInvalidFaces: Boolean from Standard = Standard_False)
+    is static;
+    
+    Clear (me : in out) 
+    is static;
+
+    AddFace (me : in out; F  : Face from TopoDS) is static;
+            ---Purpose: Add Closing Faces,  <F>  has to be  in  the initial
+            --          shape S.
+      
+    SetOffsetOnFace (me  : in out; 
+                             F   : Face from TopoDS;
+                             Off : Real from Standard) is static;
+            ---Purpose: set the offset <Off> on the Face <F> 
+
+    
+---Category: Computation.
+    
+    MakeOffsetShape (me : in out) is static;
+    
+    MakeThickSolid  (me : in out) is static;
+    
+---Category: Querying.
+           
+    GetAnalyse(me) 
+            ---C++: return const &
+    returns Analyse from BRepOffset
+    is static;
+
+    IsDone (me) returns Boolean from Standard
+    is static;
+    
+    Shape (me) 
+            ---C++: return const &
+    returns Shape from TopoDS
+    is static;
+
+    Error (me) returns Error from BRepOffset;
+            ---Purpose: returns information if IsDone() = FALSE.
+                             
+
+    OffsetFacesFromShapes (me)
+        ---Purpose: Returns <Image> containing links between initials
+         --          shapes and offset faces.
+         ---C++: return const &
+    returns Image from BRepAlgo
+    is static;    
+    
+-- Modified by skv - Tue Mar 15 16:17:37 2005 Begin
+-- Query offset join type.
+
+    GetJoinType(me) 
+            ---Purpose: Returns myJoin.
+    returns JoinType from GeomAbs 
+    is static;
+-- Add methods for supporting history.
+
+    OffsetEdgesFromShapes (me)
+        ---Purpose: Returns <Image> containing links between initials
+         --          shapes and offset edges.
+         ---C++: return const &
+    returns Image from BRepAlgo
+    is static;    
+    
+-- Modified by skv - Tue Mar 15 16:17:37 2005 End
+
+    ClosingFaces (me)   
+            ---Purpose: Returns the list of closing faces stores by AddFace 
+        ---C++: return const &
+    returns IndexedMapOfShape from TopTools
+    is static;
+
+---Category: private methods
+
+    BuildOffsetByArc ( me : in out )
+    is static private; 
+    
+    BuildOffsetByInter ( me : in out )
+    is static private;
+    BuildSplitsOfFaces (me:in out; 
+        theLF    : ListOfShape from TopTools; 
+        theAsDes : AsDes from BRepAlgo; 
+        theOrMap : out IndexedDataMapOfShapeListOfShape from TopTools;
+        theImage : out Image from BRepAlgo;
+        theLFail : out ListOfShape from TopTools; 
+        bLimited : Boolean from Standard)
+    is static private;
+    ---Purpose: 
+    -- Building splits of the offset faces by the section curves 
+    -- between the neighboring faces. 
+    SelfInter  (me    : in out ; 
+                    Modif : in out MapOfShape from TopTools)
+    is static private;                
+    
+    Intersection3D (me        : in out;
+                            Inter     : in out Inter3d from BRepOffset)
+    is static private;                    
+    Intersection2D ( me       : in out ;
+                     Modif    : IndexedMapOfShape from TopTools;
+                     NewEdges : IndexedMapOfShape from TopTools)
+    is static private;
+    
+    MakeLoops ( me    : in out ;
+                Modif : in out IndexedMapOfShape from TopTools)
+    is static private;
+
+    MakeLoopsOnContext ( me    : in out ;
+                         Modif : in out MapOfShape from TopTools)
+    is static private;
+    
+    MakeFaces ( me    : in out ;
+                Modif : in out IndexedMapOfShape from TopTools)
+    is static private;
+    
+    MakeShells (me    : in out )
+    is static private;
+
+    SelectShells (me : in out)
+    is static private;
+        
+    EncodeRegularity( me : in out)
+    is static private;
+
+    MakeSolid (me : in out)
+    is static private;
+    
+    ToContext (me    : in out;
+                   MapSF : in out DataMapOfShapeOffset from BRepOffset)
+    is static private;        
+    
+    UpdateFaceOffset (me: in out) 
+        ---Purpose: Private method use to update the map face<->offset
+    is static private; 
+     
+    CorrectConicalFaces (me: in out)
+        ---Purpose: Private method used to correct degenerated edges on conical faces
+    is static private; 
+
+    MakeMissingWalls (me: in out)
+        ---Purpose: Private method used to build walls for thickening the shell
+    is static private;  
+     
+    RemoveInternalEdges (me: in out)
+        ---Purpose: Removes INTERNAL edges from the faces
+    is static private;  
+
+fields
+
+    myOffset         : Real       from Standard;
+    myTol            : Real       from Standard;
+    myShape          : Shape      from TopoDS;     -- Initial
+    myMode           : Mode       from BRepOffset;
+    myInter          : Boolean    from Standard;
+    mySelfInter      : Boolean    from Standard;
+    myJoin           : JoinType   from GeomAbs;  
+    myThickening     : Boolean    from Standard;
+    myRemoveIntEdges : Boolean    from Standard;
+    myRemoveInvalidFaces : Boolean from Standard;
+    
+    myFaceOffset     : DataMapOfShapeReal from TopTools;
+    
+    myFaces          : IndexedMapOfShape from TopTools;
+    myAnalyse        : Analyse           from BRepOffset;
+    
+    myOffsetShape    : Shape       from TopoDS;       -- Result
+    myInitOffsetFace : Image       from BRepAlgo;
+    myInitOffsetEdge : Image       from BRepAlgo;
+    myImageOffset    : Image       from BRepAlgo; 
+    myWalls          : ListOfShape from TopTools;
+    myAsDes          : AsDes       from BRepAlgo;
+    myDone           : Boolean  from Standard;
+    myError          : Error    from BRepOffset;
+    
+    myMakeLoops      : MakeLoops from BRepOffset;
+
+    myIsPlanar       : Boolean from Standard;
+
+end MakeOffsetOld;
diff --git a/src/BRepOffset/BRepOffset_MakeOffsetOld.cxx b/src/BRepOffset/BRepOffset_MakeOffsetOld.cxx
new file mode 100644 (file)
index 0000000..586e55d
--- /dev/null
@@ -0,0 +1,4557 @@
+// Created on: 1995-10-27
+// Created by: Yves FRICAUD
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+//  Modified by skv - Tue Mar 15 16:20:43 2005
+// Add methods for supporting history.
+
+//  Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455
+
+#include <BRepOffset_MakeOffsetOld.ixx>
+#include <BRepOffset_Analyse.hxx>
+#include <BRepOffset_DataMapOfShapeOffset.hxx> 
+#include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
+#include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
+#include <BRepOffset_Interval.hxx>
+#include <BRepOffset_ListOfInterval.hxx>
+#include <BRepOffset_Offset.hxx>
+#include <BRepOffset_Tool.hxx>
+#include <BRepOffset_Inter2d.hxx>
+#include <BRepOffset_Inter3d.hxx>
+#include <BRepOffset_MakeLoops.hxx>
+
+
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepCheck_Edge.hxx>
+#include <BRepCheck_Vertex.hxx>
+#include <BRepLib.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRep_TVertex.hxx>
+#include <BRepTools_Quilt.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <gp_Pnt.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include <Standard_NotImplemented.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <Precision.hxx>
+
+#include <TopTools_SequenceOfShape.hxx>
+#include <Geom_OffsetSurface.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRepTools.hxx>
+#include <gp_Cone.hxx>
+#include <ElSLib.hxx>
+#include <ElCLib.hxx>
+#include <gp_Lin2d.hxx>
+#include <GCE2d_MakeLine.hxx>
+#include <Geom2d_Line.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <BRepLib_MakeFace.hxx>
+#include <Geom_Circle.hxx>
+
+#include <BRep_PointRepresentation.hxx>
+#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Curve2d.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <TopoDS_Wire.hxx>
+#include <BRepTools_Substitution.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+
+#include <BRepTools_WireExplorer.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <gce_MakeDir.hxx>
+#include <GC_MakeCylindricalSurface.hxx>
+#include <gce_MakeCone.hxx>
+#include <Geom_SurfaceOfLinearExtrusion.hxx>
+
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <GeomLib.hxx>
+#include <GeomFill_Generator.hxx>
+#include <Geom_Plane.hxx>
+#include <IntTools_FClass2d.hxx>
+#include <BRepLib_FindSurface.hxx>
+
+#include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Builder.hxx>
+#include <BOPAlgo_MakerVolume.hxx>
+
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPCol_DataMapOfShapeShape.hxx>
+#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
+
+#include <BOPTools.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
+#include <BOPTools_AlgoTools.hxx>
+
+#include <IntTools_Context.hxx>
+#include <IntTools_ShrunkRange.hxx>
+
+#include <CPnts_AbscissaPoint.hxx>
+
+
+// POP for NT
+#include <stdio.h>
+
+#ifdef DRAW
+
+#include <DBRep.hxx>
+#endif
+#ifdef OCCT_DEBUG
+#include <OSD_Chronometer.hxx>
+//#define DEB_VERB
+  Standard_Boolean AffichInt2dOld = Standard_False;       
+  Standard_Boolean AffichOffCOld  = Standard_False;       
+  Standard_Boolean ChronBuildOld  = Standard_False;
+  Standard_Integer NbAEOld        = 0;
+  Standard_Integer NbAFOld        = 0;  
+  Standard_Integer NVPOld        = 0;  
+  Standard_Integer NVMOld        = 0;  
+  Standard_Integer NVNOld        = 0;  
+  static OSD_Chronometer  ClockOld;
+  char nameOl[100];
+
+
+
+
+//=======================================================================
+//function :  DEBVerticesControlOld
+//purpose  : 
+//=======================================================================
+
+static void DEBVerticesControlOld (const TopTools_IndexedMapOfShape& NewEdges,
+                                      Handle(BRepAlgo_AsDes)      AsDes)
+{
+  TopTools_ListOfShape               LVP;
+  TopTools_ListIteratorOfListOfShape it1LE ;    
+  TopTools_ListIteratorOfListOfShape it2LE ;
+  
+  Standard_Integer i;
+  for (i = 1; i <= NewEdges.Extent(); i++) {
+    const TopoDS_Edge& NE = TopoDS::Edge(NewEdges(i));
+    if (AsDes->HasDescendant(NE)) {
+      for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
+        if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
+          LVP.Append(it1LE.Value());
+          cout <<"Vertex on at least 3 edges."<<endl;
+#ifdef DRAW
+          if (AffichInt2dOld) {
+            sprintf (nameOld,"VP_%d",NVPOld++);
+            DBRep::Set(nameOld,it1LE.Value());
+          }
+#endif
+        }
+        else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
+          cout <<"Vertex on more than 3 edges."<<endl;
+#ifdef DRAW
+          if (AffichInt2dOld) {
+            sprintf (nameOld,"VM_%d",NVMOld++);
+            DBRep::Set(nameOld,it1LE.Value());
+          }
+#endif
+          
+        }
+        else {
+#ifdef DRAW
+          if (AffichInt2dOld) {
+            sprintf (nameOld,"VN_%d",NVNOld++);
+            DBRep::Set(nameOld,it1LE.Value());
+          }
+#endif
+        }
+      }
+    }
+  }
+  //------------------------------------------------
+  // Try to mix spoiled vertices.
+  //------------------------------------------------
+  BRep_Builder B;
+  TopTools_ListIteratorOfListOfShape it1(LVP);
+  Standard_Real                      TolConf = 1.e-5;
+  Standard_Real                      Tol     = Precision::Confusion();
+  //Standard_Integer                   i = 1;
+  
+  i = 1;
+  for ( ; it1.More(); it1.Next()) {
+    TopoDS_Shape   V1 = it1.Value();
+    gp_Pnt         P1 = BRep_Tool::Pnt(TopoDS::Vertex(V1));
+    Standard_Real  distmin = Precision::Infinite();
+    TopTools_ListIteratorOfListOfShape it2(LVP);
+    Standard_Integer j = 1;
+
+    for ( ; it2.More(); it2.Next()) {
+      if (j > i) {
+        TopoDS_Shape V2 = it2.Value();
+        gp_Pnt       P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2));
+        if (!V1.IsSame(V2)) {
+          Standard_Real       dist    = P1.Distance(P2);
+          if (dist < distmin) distmin = dist;
+          if (dist < TolConf) {
+            Standard_Real UV2;
+            TopoDS_Edge   EWE2;
+            const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
+            TopTools_ListIteratorOfListOfShape itAsDes;
+            for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) {
+              EWE2  = TopoDS::Edge(itAsDes.Value());
+              TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL);
+              UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
+              aLocalShape = V1.Oriented(TopAbs_INTERNAL) ;
+              B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
+//              UV2   = 
+//                BRep_Tool::Parameter(TopoDS::Vertex(),EWE2);
+//              B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
+//                             UV2,EWE2,Tol);
+            }
+            AsDes->Replace(V2,V1);
+          }
+        }
+      }
+      j++;
+    }
+    i++;
+    cout <<" distmin between VP : "<<distmin<<endl;
+  }
+}  
+#endif
+
+
+//=======================================================================
+// static methods
+//=======================================================================
+static 
+  void UpdateTolerance(TopoDS_Shape& myShape,
+                       const TopTools_IndexedMapOfShape& myFaces);
+
+static 
+  Standard_Boolean FindParameter(const TopoDS_Vertex& V, 
+                                 const TopoDS_Edge& E,
+                                 Standard_Real& U);
+
+static 
+  void GetEdgePoints(const TopoDS_Edge& anEdge,
+                     const TopoDS_Face& aFace,
+                     gp_Pnt& fPnt, gp_Pnt& mPnt,
+                     gp_Pnt& lPnt);
+
+static 
+  void FillContours(const TopoDS_Shape& aShape,
+                    const BRepOffset_Analyse& Analyser,
+                    TopTools_DataMapOfShapeListOfShape& Contours,
+                    TopTools_DataMapOfShapeShape& MapEF);
+
+static 
+  void RemoveCorks(TopoDS_Shape&               S,
+                   TopTools_IndexedMapOfShape& Faces);
+
+static 
+  Standard_Boolean IsConnectedShell(const TopoDS_Shape& S);
+
+static 
+  void MakeList(TopTools_ListOfShape&             OffsetFaces,
+                const BRepAlgo_Image&             myInitOffsetFace,
+                const TopTools_IndexedMapOfShape& myFaces);
+
+static 
+  void EvalMax(const TopoDS_Shape& S, 
+               Standard_Real& Tol);
+
+static 
+  void TrimEdge(TopoDS_Edge&                  NE,
+                const Handle(BRepAlgo_AsDes)& AsDes2d,
+                Handle(BRepAlgo_AsDes)& AsDes);
+
+static 
+  void SortFaces(const TopTools_ListOfShape& theLIm, 
+                 TopTools_ListOfShape& theLFImages,
+                 const Standard_Boolean bKeepFirst);
+
+static 
+  Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
+                             const TopoDS_Shape& theSWhere,
+                             TopoDS_Shape& theRes);
+
+static 
+  void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                     BOPAlgo_Builder& theGF);
+
+static 
+  Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge,
+                               const Handle(IntTools_Context)& theCtx);
+
+static 
+  Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF,
+                                   const TopoDS_Edge& theE,
+                                   gp_Dir& theDB);
+static 
+  Standard_Boolean CheckBiNormals(const TopoDS_Face& aFIm,
+                                  const TopoDS_Face& aFOr,
+                                  const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                                  const TopTools_MapOfShape& theMFence,
+                                  Standard_Boolean& bKeep,
+                                  Standard_Boolean& bRem,
+                                  const Standard_Boolean RemoveInvalidFaces);
+
+static 
+  void CheckBiNormals(TopTools_ListOfShape&  theLFImages,
+                      const TopoDS_Face& theF,
+                      const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                      TopTools_ListOfShape& theLFKeep,
+                      const Standard_Boolean RemoveInvalidFaces);
+
+static 
+  Standard_Boolean CheckNormals(const TopoDS_Face& theFIm,
+                                const TopoDS_Face& theFOr);
+
+static 
+  void UpdateInitOffset(BRepAlgo_Image&         myInitOffset,
+                        BRepAlgo_Image&         myImageOffset,
+                        const TopoDS_Shape&     myOffsetShape,
+                        const TopAbs_ShapeEnum &theShapeType);
+
+static 
+  void RemoveShapes(TopoDS_Shape& theS,
+                    const TopTools_ListOfShape& theLS);
+
+static
+  Standard_Boolean IsPlanar(const TopoDS_Shape& theS);
+
+//=======================================================================
+
+
+//=======================================================================
+//function : BRepOffset_MakeOffsetOld
+//purpose  : 
+//=======================================================================
+BRepOffset_MakeOffsetOld::BRepOffset_MakeOffsetOld()
+{
+  myAsDes = new BRepAlgo_AsDes();
+}
+
+//=======================================================================
+//function : BRepOffset_MakeOffsetOld
+//purpose  : 
+//=======================================================================
+BRepOffset_MakeOffsetOld::BRepOffset_MakeOffsetOld(const TopoDS_Shape&    S, 
+                                             const Standard_Real    Offset, 
+                                             const Standard_Real    Tol, 
+                                             const BRepOffset_Mode  Mode, 
+                                             const Standard_Boolean Inter, 
+                                             const Standard_Boolean SelfInter, 
+                                             const GeomAbs_JoinType Join,
+                                             const Standard_Boolean Thickening,
+                                             const Standard_Boolean RemoveIntEdges,
+                                             const Standard_Boolean RemInvFaces)
+: 
+myOffset        (Offset),
+myTol           (Tol),
+myShape         (S),
+myMode          (Mode),
+myInter         (Inter),
+mySelfInter     (SelfInter),
+myJoin          (Join),
+myThickening    (Thickening),
+myRemoveIntEdges(RemoveIntEdges),
+myRemoveInvalidFaces(RemInvFaces),
+myDone          (Standard_False)
+
+{
+  myAsDes = new BRepAlgo_AsDes();
+  MakeOffsetShape();
+}
+
+//=======================================================================
+//function : Initialize
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::Initialize(const TopoDS_Shape&    S, 
+                                       const Standard_Real    Offset, 
+                                       const Standard_Real    Tol, 
+                                       const BRepOffset_Mode  Mode,
+                                       const Standard_Boolean Inter,
+                                       const Standard_Boolean SelfInter,
+                                       const GeomAbs_JoinType Join,
+                                       const Standard_Boolean Thickening,
+                                       const Standard_Boolean RemoveIntEdges,
+                                       const Standard_Boolean RemInvFaces)
+{
+  myOffset         = Offset;
+  myShape          = S;
+  myTol            = Tol;
+  myMode           = Mode;
+  myInter          = Inter;
+  mySelfInter      = SelfInter;
+  myJoin           = Join;
+  myThickening     = Thickening;
+  myRemoveIntEdges = RemoveIntEdges;
+  myRemoveInvalidFaces = RemInvFaces;
+  myDone           = Standard_False;
+  myIsPlanar       = Standard_False;
+  Clear();
+}
+
+//=======================================================================
+//function : Clear
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::Clear()
+{
+  myOffsetShape.Nullify();
+  myInitOffsetFace .Clear();
+  myInitOffsetEdge .Clear();
+  myImageOffset    .Clear();
+  myFaces          .Clear();  
+  myFaceOffset     .Clear();
+  myAsDes          ->Clear();
+  myDone     = Standard_False;
+}
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::AddFace(const TopoDS_Face& F) {
+  myFaces.Add(F);    
+  //-------------
+  // MAJ SD.
+  //-------------
+  myInitOffsetFace.SetRoot (F)  ;    
+  myInitOffsetFace.Bind    (F,F);
+  myImageOffset.SetRoot    (F)  ;  
+}
+
+//=======================================================================
+//function : SetOffsetOnFace
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::SetOffsetOnFace(const TopoDS_Face&  F, 
+                                            const Standard_Real Off)
+{
+  if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
+  myFaceOffset.Bind(F,Off);
+}
+
+//=======================================================================
+//function : MakeOffsetShape
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeOffsetShape()
+{  
+  myDone     = Standard_False;
+  //
+  // check if shape consists of only planar faces
+  myIsPlanar = IsPlanar(myShape);
+  //------------------------------------------
+  // Construction of myShape without caps.
+  //------------------------------------------
+  RemoveCorks (myShape,myFaces);
+  
+  if (! IsConnectedShell(myShape))
+    Standard_ConstructionError::Raise("BRepOffset_MakeOffsetOld : Incorrect set of faces to remove, the remaining shell is not connected");
+
+  if (Abs(myOffset) < myTol) return;
+
+  TopAbs_State       Side = TopAbs_IN;
+  if (myOffset < 0.) Side = TopAbs_OUT;
+  // ------------
+  // Preanalyse.
+  // ------------
+  EvalMax(myShape,myTol);
+  if (myTol > Abs(myOffset*0.5)) {
+    Standard_ConstructionError::Raise("BRepOffset_MakeOffsetOld : Tol > Offset");
+  }
+  Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
+  myAnalyse.Perform(myShape,TolAngle);
+  //---------------------------------------------------
+  // Construction of Offset from preanalysis.
+  //---------------------------------------------------  
+  //----------------------------
+  // MaJ of SD Face - Offset
+  //----------------------------
+  UpdateFaceOffset();
+
+  if (myJoin == GeomAbs_Arc)          
+    BuildOffsetByArc();
+  else if (myJoin == GeomAbs_Intersection) 
+    BuildOffsetByInter();
+  //-----------------
+  // Auto unwinding.
+  //-----------------
+  // if (mySelfInter)  SelfInter(Modif);
+  //-----------------
+  // Intersection 3d .
+  //-----------------
+
+
+  //if (!Intersection3D()) {
+    BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
+    Intersection3D (Inter);
+    //-----------------
+    // Intersection2D
+    //-----------------
+    TopTools_IndexedMapOfShape& Modif    = Inter.TouchedFaces(); 
+    TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
+    
+    if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
+    //-------------------------------------------------------
+    // Unwinding 2D and reconstruction of modified faces
+    //----------------------------------------------------
+    MakeLoops (Modif);
+    //-----------------------------------------------------
+    // Reconstruction of non modified faces sharing 
+    // reconstructed edges
+    //------------------------------------------------------
+    if (!Modif.IsEmpty()) MakeFaces (Modif);
+  //}
+
+
+  //
+  if (myThickening)
+    MakeMissingWalls();
+
+  //-------------------------
+  // Construction of shells.
+  //-------------------------
+  MakeShells ();
+  //--------------
+  // Unwinding 3D.
+  //--------------
+  SelectShells ();
+  //----------------------------------
+  // Remove INTERNAL edges if necessasry
+  //----------------------------------
+  if (myRemoveIntEdges) {
+    RemoveInternalEdges();
+  }
+  //----------------------------------
+  // Coding of regularities.
+  //----------------------------------
+  EncodeRegularity();
+  //----------------------
+  // Creation of solids.
+  //----------------------
+  MakeSolid ();
+
+  //-----------------------------
+  // MAJ Tolerance edge and Vertex
+  // ----------------------------
+  if (!myOffsetShape.IsNull()) {
+    UpdateTolerance (myOffsetShape,myFaces);
+    BRepLib::UpdateTolerances( myOffsetShape );
+  }
+
+  CorrectConicalFaces();
+
+  myDone = Standard_True;
+}
+
+//=======================================================================
+//function : MakeThickSolid
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeThickSolid() 
+{
+  //--------------------------------------------------------------
+  // Construction of shell parallel to shell (initial without cap).
+  //--------------------------------------------------------------
+  MakeOffsetShape ();
+
+  //--------------------------------------------------------------------
+  // Construction of a solid with the initial shell, parallel shell 
+  // limited by caps.
+  //--------------------------------------------------------------------
+  if (!myFaces.IsEmpty()) {
+    TopoDS_Solid    Res;
+    TopExp_Explorer exp;
+    BRep_Builder    B;
+    Standard_Integer NbF = myFaces.Extent();
+
+    B.MakeSolid(Res);
+
+    BRepTools_Quilt Glue;
+    for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
+      NbF++;
+      Glue.Add (exp.Current());
+    } 
+    Standard_Boolean YaResult = 0;
+    if (!myOffsetShape.IsNull())
+      {
+      for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next())
+        {
+        YaResult = 1;
+        Glue.Add (exp.Current().Reversed());
+        }
+#ifdef OCCT_DEBUG
+      if(YaResult == 0)
+        {
+        cout << "OffsetShape does not contain a FACES." << endl;
+        }
+#endif
+      }
+#ifdef OCCT_DEBUG
+    else
+      {
+      cout << "OffsetShape is null!" << endl;
+      }
+#endif
+
+    if (YaResult == 0)
+      {
+      myDone = Standard_False;
+      return;
+      }
+
+    myOffsetShape = Glue.Shells();
+    for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
+      B.Add(Res,exp.Current());
+    }
+    Res.Closed(Standard_True);
+    myOffsetShape = Res;
+
+    // Test of Validity of the result of thick Solid 
+    // more face than the initial solid.
+        
+    Standard_Integer NbOF = 0;
+    for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
+      NbOF++;
+    }
+    if (NbOF <= NbF) {
+      myDone = Standard_False;
+      return;
+    }
+  }
+
+  if (myOffset > 0 ) myOffsetShape.Reverse();  
+
+  myDone = Standard_True;
+}
+
+//=======================================================================
+//function : IsDone
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepOffset_MakeOffsetOld::IsDone() const
+{
+  return myDone;
+}
+
+//=======================================================================
+//function : Error
+//purpose  : 
+//=======================================================================
+BRepOffset_Error BRepOffset_MakeOffsetOld::Error() const
+{
+  return myError;
+}
+
+//=======================================================================
+//function : Shape
+//purpose  : 
+//=======================================================================
+const TopoDS_Shape&  BRepOffset_MakeOffsetOld::Shape() const 
+{
+  return myOffsetShape;
+}
+
+//=======================================================================
+//function : BuildOffsetByInter
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::BuildOffsetByInter()
+{
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) {
+    cout << " CONSTRUCTION OF OFFSETS :" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();
+  }
+#endif
+
+  BRepOffset_DataMapOfShapeOffset MapSF;
+  TopTools_MapOfShape             Done;
+  Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
+  //--------------------------------------------------------
+  // Construction of faces parallel to initial faces
+  //--------------------------------------------------------
+  TopExp_Explorer Exp;
+  TopTools_ListOfShape LF;
+  TopTools_ListIteratorOfListOfShape itLF;
+
+  BRepLib::SortFaces(myShape,LF);
+
+  TopTools_DataMapOfShapeShape ShapeTgt;
+  for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
+    const TopoDS_Face&   F = TopoDS::Face(itLF.Value());
+    Standard_Real CurOffset = myOffset;
+    if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
+    BRepOffset_Offset    OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
+    TopTools_ListOfShape Let;
+    myAnalyse.Edges(F,BRepOffset_Tangent,Let);
+    TopTools_ListIteratorOfListOfShape itl(Let);
+    
+    for ( ; itl.More(); itl.Next()) {
+      const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
+      if ( !ShapeTgt.IsBound(Cur)) {
+        TopoDS_Shape aLocalShape = OF.Generated(Cur);
+        const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
+//        const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
+        ShapeTgt.Bind(Cur,OF.Generated(Cur));
+        TopoDS_Vertex V1,V2,OV1,OV2;
+        TopExp::Vertices (Cur,V1,V2);
+        TopExp::Vertices (OTE,OV1,OV2);      
+        TopTools_ListOfShape LE;
+        if (!ShapeTgt.IsBound(V1)) {
+          myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
+          const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
+          if (LE.Extent() == LA.Extent())
+            ShapeTgt.Bind(V1,OV1);
+        }
+        if (!ShapeTgt.IsBound(V2)) {
+          LE.Clear();
+          myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
+          const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
+          if (LE.Extent() == LA.Extent())
+            ShapeTgt.Bind(V2,OV2);
+        }
+      }
+    }
+    MapSF.Bind(F,OF);
+  }
+  //--------------------------------------------------------------------
+  // MES   : Map of OffsetShape -> Extended Shapes.
+  // Build : Map of Initial SS  -> OffsetShape build by Inter.
+  //                               can be an edge or a compound of edges       
+  //---------------------------------------------------------------------
+  TopTools_DataMapOfShapeShape MES;  
+  TopTools_DataMapOfShapeShape Build; 
+  TopTools_ListOfShape         Failed;
+  TopAbs_State                 Side = TopAbs_IN;  
+  Handle(BRepAlgo_AsDes)       AsDes = new BRepAlgo_AsDes();
+
+  //-------------------------------------------------------------------
+  // Extension of faces and calculation of new edges of intersection.
+  //-------------------------------------------------------------------
+  Standard_Boolean  ExtentContext = 0;
+  if (myOffset > 0) ExtentContext = 1;
+
+  BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
+  // Intersection between parallel faces
+  Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
+  // Intersection with caps.
+  Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
+
+
+  //---------------------------------------------------------------------------------
+  // Extension of neighbor edges of new edges and intersection between neighbors.
+  //--------------------------------------------------------------------------------
+  Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
+  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+    const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
+    Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(FI);
+    BRepOffset_Inter2d::ConnexIntByInt (FI, MapSF(FI), MES, Build, 
+                                        AsDes, AsDes2d, myOffset, aCurrFaceTol);
+  }
+  //-----------------------------------------------------------
+  // Great restriction of new edges and update of AsDes.
+  //------------------------------------------ ----------------
+  TopTools_IndexedMapOfShape NewEdges;
+  TopExp_Explorer Exp2,ExpC;
+  TopoDS_Shape    NE;
+  TopoDS_Edge     TNE;
+  TopoDS_Face     NF;
+  TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
+  
+  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+    const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
+    NF = MapSF(FI).Face();
+    if (MES.IsBound(NF)) {
+      NF = TopoDS::Face(MES(NF));
+    }
+    //
+    TopTools_MapOfShape View;
+    TopTools_IndexedMapOfShape VEmap;
+    Standard_Integer i, aNb;
+    //
+    TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE  , VEmap);
+    TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
+    //
+    aNb = VEmap.Extent();
+    for (i = 1; i <= aNb; ++i) {
+      const TopoDS_Shape& aS = VEmap(i);
+      if (!View.Add(aS)) {
+        continue;
+      }
+      //
+      if (Build.IsBound(aS)) {
+        NE = Build(aS);
+        if (NE.ShapeType() == TopAbs_EDGE) {
+          if (anOrigins.Contains(NE)) {
+            anOrigins.ChangeFromKey(NE).Append(aS);
+          }
+          else {
+            TopTools_ListOfShape aLSx;
+            aLSx.Append(aS);
+            anOrigins.Add(NE, aLSx);
+          }
+          //
+          if (NewEdges.Add(NE)) {
+            TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);
+          }
+        }
+        else {
+          //------------------------------------------------------------
+          // The Intersections are on several edges.
+          // The pieces without intersections with neighbors  
+          // are removed from AsDes.
+          //------------------------------------------------------------
+          for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
+            TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
+            if (NewEdges.Add(NEC)) {
+              NEC.Free(Standard_True);
+              if (anOrigins.Contains(NEC)) {
+                anOrigins.ChangeFromKey(NEC).Append(aS);
+              }
+              else {
+                TopTools_ListOfShape aLSx;
+                aLSx.Append(aS);
+                anOrigins.Add(NEC, aLSx);
+              }
+              //
+              if (!AsDes2d->Descendant(NEC).IsEmpty()) {
+                TrimEdge (NEC,AsDes2d,AsDes);
+              }
+              else {
+                if (AsDes->HasAscendant(NEC)) {
+                  AsDes->Remove(NEC);
+                }
+              }
+            }
+          }
+        }
+      }
+      else {
+        if (aS.ShapeType() != TopAbs_EDGE) {
+          continue;
+        }
+        //
+        NE = MapSF(FI).Generated(aS);
+        //// modified by jgv, 19.12.03 for OCC4455 ////
+        NE.Orientation(aS.Orientation());
+        if (anOrigins.Contains(NE)) {
+          anOrigins.ChangeFromKey(NE).Append(aS);
+        }
+        else {
+          TopTools_ListOfShape aLSx;
+          aLSx.Append(aS);
+          anOrigins.Add(NE, aLSx);
+        }
+        //
+        if (MES.IsBound(NE)) {
+          NE = MES(NE);
+          NE.Orientation(aS.Orientation());
+          if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} 
+        }
+        AsDes->Add(NF,NE);
+      } 
+    }
+  }
+  
+  //--------------------------------- 
+  // Intersection 2D on //
+  //---------------------------------  
+  TopTools_ListOfShape LFE; 
+  BRepAlgo_Image     IMOE;
+  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+    const TopoDS_Shape& FI  = Exp.Current();
+    const TopoDS_Shape& OFI = MapSF(FI).Face();
+    if (MES.IsBound(OFI)) {
+      const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
+      LFE.Append(NF);
+      IMOE.SetRoot(NF);
+      //
+      if (anOrigins.Contains(NF)) {
+        anOrigins.ChangeFromKey(NF).Append(FI);
+      }
+      else {
+        TopTools_ListOfShape aLSx;
+        aLSx.Append(FI);
+        anOrigins.Add(NF, aLSx);
+      }
+    }
+  }
+  
+  TopTools_ListIteratorOfListOfShape itLFE(LFE);
+  for (; itLFE.More(); itLFE.Next()) {
+    const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
+    Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
+    BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol);
+  }
+  //----------------------------------------------
+  // Intersections 2d on caps.
+  //----------------------------------------------
+  Standard_Integer i;
+  for (i = 1; i <= myFaces.Extent(); i++) {
+    const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
+    Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
+    BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol);
+  }
+
+  //-------------------------------
+  // Unwinding of extended Faces.
+  //-------------------------------
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    TopTools_ListOfShape aLFailed;
+    BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False);
+    if (aLFailed.Extent()) {
+      myMakeLoops.Build(aLFailed, AsDes, IMOE);
+    }
+  }
+  else {
+    myMakeLoops.Build(LFE, AsDes, IMOE);
+  }
+  //
+#ifdef OCCT_DEBUG
+  TopTools_IndexedMapOfShape COES;
+#endif
+  //---------------------------
+  // MAJ SD. for faces //
+  //---------------------------
+  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+    const TopoDS_Shape& FI   = Exp.Current();
+    myInitOffsetFace.SetRoot(FI);
+    TopoDS_Face  OF  = MapSF(FI).Face();
+    if (MES.IsBound(OF)) {
+      OF = TopoDS::Face(MES(OF));
+      if (IMOE.HasImage(OF)) {
+        const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
+        myInitOffsetFace.Bind(FI,LOFE);
+        for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
+          const TopoDS_Shape& OFE =  itLF.Value();
+          myImageOffset.SetRoot(OFE);
+#ifdef DRAW
+          if (AffichInt2dOld) {
+            sprintf(nameOld,"AF_%d",NbAFOld++);
+            DBRep::Set(nameOld,OFE);
+          }
+#endif
+          TopTools_MapOfShape View;
+          for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+               Exp2.More(); Exp2.Next()) {
+            const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
+            
+            myAsDes->Add (OFE,COE);
+#ifdef DRAW
+            if (AffichInt2dOld) {
+              sprintf(nameOld,"AE_%d",NbAEOld++);
+              DBRep::Set(nameOld,COE);
+              COES.Add(COE);
+            }
+#endif
+            if (View.Add(COE)){
+              if (!myAsDes->HasDescendant(COE)) {
+                TopoDS_Vertex CV1,CV2;
+                TopExp::Vertices(COE,CV1,CV2);
+                if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+                if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));        
+              }
+            }
+          }
+        }
+      }
+      else {
+        /*myInitOffsetFace.Bind(FI,OF);
+        myImageOffset.SetRoot(OF);
+#ifdef DRAW 
+        if (AffichInt2dOld) {
+          sprintf(nameOld,"AF_%d",NbAFOld++);
+          DBRep::Set(nameOld,OF);
+        }
+#endif
+        const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
+        for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
+          const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
+          if (IMOE.HasImage(OE)) {
+            const TopTools_ListOfShape& LOE = IMOE.Image(OE);
+            TopTools_ListIteratorOfListOfShape itLOE(LOE);
+            for (; itLOE.More(); itLOE.Next()) {
+              TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
+              const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
+//              const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
+              myAsDes->Add(OF,COE);
+#ifdef DRAW
+              if (AffichInt2dOld) {
+                sprintf(nameOld,"AE_%d",NbAEOld++);
+                DBRep::Set(nameOld,COE);
+                COES.Add(COE);
+              }
+#endif
+              
+              if (!myAsDes->HasDescendant(COE)) {
+                TopoDS_Vertex CV1,CV2;
+                TopExp::Vertices(COE,CV1,CV2);
+                 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+                if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));        
+              }
+            }
+          }
+          else {
+            myAsDes->Add(OF,OE);
+#ifdef DRAW
+            if (AffichInt2dOld) {
+              sprintf(nameOld,"AE_%d",NbAEOld++);
+              DBRep::Set(nameOld,OE);
+              COES.Add(OE);
+            }
+#endif
+
+            const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
+            myAsDes->Add(OE,LV);
+          }
+        }*/
+      }
+    }
+    else {
+      myInitOffsetFace.Bind(FI,OF);
+      myImageOffset.SetRoot(OF);
+      TopTools_MapOfShape View;
+      for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+           Exp2.More(); Exp2.Next()) {
+
+        const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
+        myAsDes->Add (OF,COE);
+#ifdef DRAW
+        if (AffichInt2dOld) {
+          sprintf(nameOld,"AE_%d",NbAEOld++);
+          DBRep::Set(nameOld,COE);
+          COES.Add(COE);
+        }
+#endif
+        
+        if (View.Add(Exp2.Current())) {
+          if (!myAsDes->HasDescendant(COE)) {
+            TopoDS_Vertex CV1,CV2;
+            TopExp::Vertices(COE,CV1,CV2);
+            if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+            if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));        
+          }
+        }
+      } 
+    }
+  }
+  //  Modified by skv - Tue Mar 15 16:20:43 2005
+  // Add methods for supporting history.
+  TopTools_MapOfShape aMapEdges;
+
+  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+    const TopoDS_Shape& aFaceRef = Exp.Current();
+
+    Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
+
+    for (; Exp2.More(); Exp2.Next()) {
+      const TopoDS_Shape& anEdgeRef = Exp2.Current();
+
+      if (aMapEdges.Add(anEdgeRef)) {
+        myInitOffsetEdge.SetRoot(anEdgeRef);
+        if (Build.IsBound(anEdgeRef)) {
+          TopoDS_Shape aNewShape = Build(anEdgeRef);
+          
+          if (aNewShape.ShapeType() == TopAbs_EDGE) {
+            if (IMOE.HasImage(aNewShape)) {
+              const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
+              
+              myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
+            } else
+              myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
+          } else { // aNewShape != TopAbs_EDGE
+            TopTools_ListOfShape aListNewEdge;
+            
+            for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
+              const TopoDS_Shape &aResEdge = ExpC.Current();
+              
+              if (IMOE.HasImage(aResEdge)) {
+                const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
+                TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
+                
+                for (; aNewEIter.More(); aNewEIter.Next())
+                  aListNewEdge.Append(aNewEIter.Value());
+              } else
+                aListNewEdge.Append(aResEdge);
+            }
+            
+            myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
+          }
+        } 
+        else { // Free boundary.
+          TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
+
+          if (MES.IsBound(aNewEdge))
+            aNewEdge = MES(aNewEdge);
+
+          if (IMOE.HasImage(aNewEdge)) {
+            const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
+
+            myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
+          } else
+            myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
+        }
+      }
+    }
+  }
+//  Modified by skv - Tue Mar 15 16:20:43 2005
+
+  //---------------------------
+  // MAJ SD. for caps 
+  //---------------------------
+  //TopTools_MapOfShape View; 
+  for (i = 1; i <= myFaces.Extent(); i++) {
+    const TopoDS_Shape& Cork = myFaces(i);
+    const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
+    for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
+      const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
+      if (IMOE.HasImage(OE)) {
+        const TopTools_ListOfShape& LOE = IMOE.Image(OE);
+          TopTools_ListIteratorOfListOfShape itLOE(LOE);
+        for (; itLOE.More(); itLOE.Next()) {
+          const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
+          myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
+#ifdef DRAW
+          if (AffichInt2dOld) {
+            sprintf(nameOld,"AE_%d",NbAEOld++);
+            DBRep::Set(nameOld,COE);
+            COES.Add(COE);
+          }
+#endif
+          
+          if (!myAsDes->HasDescendant(COE)) {
+            TopoDS_Vertex CV1,CV2;
+            TopExp::Vertices(COE,CV1,CV2);
+            if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+            if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));          
+          }
+        }
+      }
+      else {
+        myAsDes->Add(Cork,OE);
+        if (AsDes->HasDescendant(OE)) {
+          myAsDes->Add(OE,AsDes->Descendant(OE));
+        }
+#ifdef DRAW
+        if (AffichInt2dOld) {
+          sprintf(nameOld,"AE_%d",NbAEOld++);
+          DBRep::Set(nameOld,OE);
+          COES.Add(OE);
+        }
+#endif
+      }
+    }
+  }
+  
+#ifdef OCCT_DEBUG
+  DEBVerticesControlOld (COES,myAsDes);
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : BuildSplitsOfFaces
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::BuildSplitsOfFaces
+  (const TopTools_ListOfShape& theLF,
+   const Handle(BRepAlgo_AsDes)& theAsDes,
+   TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+   BRepAlgo_Image& theImage,
+   TopTools_ListOfShape& theLFailed,
+   const Standard_Boolean bLimited)
+{
+  BOPCol_ListOfShape aLS;
+  BOPCol_ListIteratorOfListOfShape aIt;
+  TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1;
+  TopTools_DataMapOfShapeListOfShape anEImages;
+  BRep_Builder aBB;
+  TopoDS_Compound aFaces;
+  //
+  aBB.MakeCompound(aFaces);
+  //
+  // firstly it is necessary to fuse all the edges
+  Handle(IntTools_Context) aCtx = new IntTools_Context();
+  //
+  aItLF.Initialize(theLF);
+  for (; aItLF.More(); aItLF.Next()) {
+    const TopoDS_Shape& aF = aItLF.Value();
+    //
+    const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF);
+    aItLE.Initialize(aLE);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value();
+      if (BRep_Tool::Degenerated(aE)) {
+        continue;
+      }
+      //
+      if (IsMicroEdge(aE, aCtx)) {
+        continue;
+      }
+      //
+      aLS.Append(aE);
+    }
+  }
+  //
+  if (aLS.Extent() > 1) {
+    BOPAlgo_Builder aGFE;
+    //
+    aGFE.SetArguments(aLS);
+    aGFE.Perform();
+    if (aGFE.ErrorStatus() == 0) {
+      // fill map with edges images
+      aIt.Initialize(aLS);
+      for (; aIt.More(); aIt.Next()) {
+        const TopoDS_Shape& aE = aIt.Value();
+        //
+        const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE);
+        if (aLEIm.Extent()) {
+          anEImages.Bind(aE, aLEIm);
+        }
+      }
+      //
+      UpdateOrigins(theOrigins, aGFE);
+    }
+  }
+  //
+  // now we can split the faces
+  aItLF.Initialize(theLF);
+  for (; aItLF.More(); aItLF.Next()) {
+    const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value();
+    //
+    // the offset face
+    aLS.Clear();
+    aLS.Append(aF.Oriented(TopAbs_FORWARD));
+    //
+    Standard_Integer iCountE = 0;
+    TopTools_MapOfShape aMFE;
+    TopExp_Explorer aExp(aF, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Shape& aE = aExp.Current();
+      if (anEImages.IsBound(aE)) {
+        const TopTools_ListOfShape& aLEIm = anEImages.Find(aE);
+        aItLE.Initialize(aLEIm);
+        for (; aItLE.More(); aItLE.Next()) {
+          const TopoDS_Shape& aEIm = aItLE.Value();
+          aMFE.Add(aEIm);
+        }
+      }
+      else {
+        aMFE.Add(aE);
+      }
+    }
+    //
+    // the edges by which the offset face should be split
+    const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF);
+    aItLE.Initialize(aLE);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value();
+      if (BRep_Tool::Degenerated(aE)) {
+        continue;
+      }
+      //
+      if (anEImages.IsBound(aE)) {
+        const TopTools_ListOfShape& aLEIm = anEImages.Find(aE);
+        aItLE1.Initialize(aLEIm);
+        for (; aItLE1.More(); aItLE1.Next()) {
+          const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aItLE1.Value();
+          // check for micro edge
+          if (IsMicroEdge(aEIm, aCtx)) {
+            continue;
+          }
+          //
+          aLS.Append(aEIm);
+          if (!aMFE.Contains(aEIm)) {
+            ++iCountE;
+          }
+        }
+      }
+      else {
+        if (IsMicroEdge(aE, aCtx)) {
+          continue;
+        }
+        aLS.Append(aE);
+        if (!aMFE.Contains(aE)) {
+          ++iCountE;
+        }
+      }
+    }
+    //
+    TopTools_ListOfShape aLFImages;
+    //
+    // split the face by the edges
+    if (!iCountE) {
+      if (bLimited) {
+        aLFImages.Append(aF);
+        theImage.Bind(aF, aLFImages);
+        aBB.Add(aFaces, aF);
+      }
+      continue;
+    }
+    //
+    BOPAlgo_Builder aGF;
+    //
+    aGF.SetArguments(aLS);
+    aGF.Perform();
+    if (aGF.ErrorStatus()) {
+      theLFailed.Append(aF);
+      continue;
+    }
+    //
+    // splits of the offset shape
+    aLFImages = aGF.Modified(aF);
+    if (aLFImages.IsEmpty()) {
+      theLFailed.Append(aF);
+      continue;
+    }
+    //
+    TopTools_MapOfShape aME;
+    // collect images of Edges
+    aItLE.Initialize(aLE);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Shape& aE = aItLE.Value();
+      if (anEImages.IsBound(aE)) {
+        TopTools_MapOfShape aMFence;
+        TopTools_ListOfShape aLEImNew;
+        Standard_Boolean bModif = Standard_False;
+        //
+        TopTools_ListOfShape& aLEIm = anEImages.ChangeFind(aE);
+        aItLE1.Initialize(aLEIm);
+        for (; aItLE1.More(); aItLE1.Next()) {
+          const TopoDS_Shape& aEIm = aItLE1.Value();
+          const TopTools_ListOfShape& aLEImIm = aGF.Modified(aEIm);
+          if (aLEImIm.Extent()) {
+            bModif = Standard_True;
+            TopTools_ListIteratorOfListOfShape aItLEIm(aLEImIm);
+            for (; aItLEIm.More(); aItLEIm.Next()) {
+              const TopoDS_Shape& aEImIm = aItLEIm.Value();
+              if (aMFence.Add(aEImIm)) {
+                aLEImNew.Append(aEImIm);
+                aME.Add(aEImIm);
+              }
+            }
+          }
+          else {
+            aLEImNew.Append(aEIm);
+            aME.Add(aEIm);
+          }
+        }
+        //
+        if (bModif) {
+          aLEIm.Assign(aLEImNew);
+        }
+      }
+      else {
+        const TopTools_ListOfShape& aLEIm = aGF.Modified(aE);
+        if (aLEIm.Extent()) {
+          anEImages.Bind(aE, aLEIm);
+          TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
+          for (; aItLEIm.More(); aItLEIm.Next()) {
+            const TopoDS_Shape& aEIm = aItLEIm.Value();
+            aME.Add(aEIm);
+          }
+        }
+        else {
+          aME.Add(aE);
+        }
+      }
+    }
+    //
+    if (!bLimited) {
+      //
+      // to overcome the often errors in trimming edges it is 
+      // better to remove first the faces containing the boundaries
+      // of the extended surfaces;
+      Standard_Boolean bKeep;
+      aItLE.Initialize(aLFImages);
+      for (; aItLE.More();) {
+        const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLE.Value();
+        //
+        aExp.Init(aFIm, TopAbs_EDGE);
+        for (bKeep = Standard_True; aExp.More() && bKeep; aExp.Next()) {
+          const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+          //
+          if (BRep_Tool::Degenerated(aE)) {
+            continue;
+          }
+          //
+          bKeep = aME.Contains(aE);
+        }
+        //
+        if (bKeep) {
+          aItLE.Next();
+        }
+        else {
+          aLFImages.Remove(aItLE);
+        }
+      }
+      //
+      UpdateOrigins(theOrigins, aGF);
+      //
+      if (aLFImages.Extent() >= 1) {
+        TopTools_ListOfShape aLFKeep;
+        //
+        // check offset faces on the coincidence of the 
+        // bi-normal directions with the original faces
+        CheckBiNormals(aLFImages, aF, theOrigins, aLFKeep, myRemoveInvalidFaces);
+        //
+        // limit the face
+        if (aLFImages.Extent() > 1) {
+          TopTools_ListOfShape aLFTmp = aLFImages;
+          aLFImages.Clear();
+          //
+          SortFaces(aLFTmp, aLFImages, Standard_True);
+        }
+        //
+        if (aLFKeep.Extent()) {
+          TopTools_MapOfShape aMFence;
+          aItLE.Initialize(aLFImages);
+          for (; aItLE.More(); aItLE.Next()) {
+            const TopoDS_Shape& aFIm = aItLE.Value();
+            aMFence.Add(aFIm);
+          }
+          //
+          aItLE.Initialize(aLFKeep);
+          for (; aItLE.More(); aItLE.Next()) {
+            const TopoDS_Shape& aFIm = aItLE.Value();
+            if (aMFence.Add(aFIm)) {
+              aLFImages.Append(aFIm);
+            }
+          }
+        }
+      }
+    }
+    //
+    // Fill history for faces
+    if (aLFImages.Extent()) {
+      theImage.Bind(aF, aLFImages);
+    }
+    else {
+      BRepAdaptor_Surface aBAS(aF, Standard_False);
+      if (aBAS.GetType() != GeomAbs_Plane) {
+        theLFailed.Append(aF);
+      }
+    }
+    //
+    aItLE.Initialize(aLFImages);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Shape& aFIm = aItLE.Value();
+      aBB.Add(aFaces, aFIm);
+    }
+  }
+  //
+  // fill history for edges
+  TopTools_IndexedMapOfShape aMFE;
+  TopExp::MapShapes(aFaces, TopAbs_EDGE, aMFE);
+  //
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages);
+  for (; aItEIm.More(); aItEIm.Next()) {
+    const TopoDS_Shape& aE = aItEIm.Key();
+    const TopTools_ListOfShape& aLEIm = aItEIm.Value();
+    //
+    Standard_Boolean bHasImage = theImage.HasImage(aE);
+    aItLE.Initialize(aLEIm);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Shape& aEIm = aItLE.Value();
+      if (aMFE.Contains(aEIm)) {
+        if (bHasImage) {
+          theImage.Add(aE, aEIm);
+        }
+        else {
+          theImage.Bind(aE, aEIm);
+          bHasImage = Standard_True;
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : BuildOffsetByArc
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::BuildOffsetByArc()
+{
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) {
+    cout << " CONSTRUCTION OF OFFSETS :" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();
+  }
+#endif
+
+  BRepOffset_DataMapOfShapeOffset MapSF;
+  TopTools_MapOfShape             Done;
+  Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
+  //--------------------------------------------------------
+  // Construction of faces parallel to initial faces
+  //--------------------------------------------------------
+  TopExp_Explorer Exp;
+  TopTools_ListOfShape LF;
+  TopTools_ListIteratorOfListOfShape itLF;
+
+  BRepLib::SortFaces(myShape,LF);
+
+  TopTools_DataMapOfShapeShape EdgeTgt;
+  for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
+    const TopoDS_Face&   F = TopoDS::Face(itLF.Value());
+    Standard_Real CurOffset = myOffset;
+    if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
+    BRepOffset_Offset    OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
+    TopTools_ListOfShape Let;
+    myAnalyse.Edges(F,BRepOffset_Tangent,Let);
+    TopTools_ListIteratorOfListOfShape itl(Let);
+    
+    for ( ; itl.More(); itl.Next()) {
+      const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
+      if ( !EdgeTgt.IsBound(Cur)) {
+        TopoDS_Shape aLocalShape = OF.Generated(Cur);
+        const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
+//        const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
+        EdgeTgt.Bind(Cur,OF.Generated(Cur));
+        TopoDS_Vertex V1,V2,OV1,OV2;
+        TopExp::Vertices (Cur,V1,V2);
+        TopExp::Vertices (OTE,OV1,OV2);      
+        TopTools_ListOfShape LE;
+        if (!EdgeTgt.IsBound(V1)) {
+          myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
+          const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
+          if (LE.Extent() == LA.Extent())
+            EdgeTgt.Bind(V1,OV1);
+        }
+        if (!EdgeTgt.IsBound(V2)) {
+          LE.Clear();
+          myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
+          const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
+          if (LE.Extent() == LA.Extent())
+              EdgeTgt.Bind(V2,OV2);
+        }
+      }
+    }
+    MapSF.Bind(F,OF);
+  }
+  //--------------------------------------------------------
+  // Construction of tubes on edge.
+  //--------------------------------------------------------
+  BRepOffset_Type    OT = BRepOffset_Convex;
+  if (myOffset < 0.) OT = BRepOffset_Concave; 
+   
+  for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
+    const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
+    if (Done.Add(E)) {
+      const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
+      if (Anc.Extent() == 2) {
+        const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
+        if (!L.IsEmpty() && L.First().Type() == OT) {
+          Standard_Real CurOffset = myOffset;
+          if ( myFaceOffset.IsBound(Anc.First()))
+            CurOffset = myFaceOffset(Anc.First());
+          TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
+          TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
+          aLocalShape = MapSF(Anc.Last()).Generated(E);
+          TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
+//          TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
+//          TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
+          // find if exits tangent edges in the original shape
+          TopoDS_Edge E1f, E1l;
+          TopoDS_Vertex V1f, V1l;
+          TopExp::Vertices(E,V1f,V1l);
+          TopTools_ListOfShape TangE;
+          myAnalyse.TangentEdges(E,V1f,TangE);
+          // find if the pipe on the tangent edges are soon created.
+          TopTools_ListIteratorOfListOfShape itl(TangE);
+          Standard_Boolean Find = Standard_False;
+          for ( ; itl.More() && !Find; itl.Next()) {
+            if ( MapSF.IsBound(itl.Value())) {
+              TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
+              E1f  = TopoDS::Edge(aLocalShape);
+//              E1f  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
+              Find = Standard_True;
+            }
+          }
+          TangE.Clear();
+          myAnalyse.TangentEdges(E,V1l,TangE);
+          // find if the pipe on the tangent edges are soon created.
+          itl.Initialize(TangE);
+          Find = Standard_False;
+          for ( ; itl.More() && !Find; itl.Next()) {
+            if ( MapSF.IsBound(itl.Value())) {
+              TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
+              E1l  = TopoDS::Edge(aLocalShape);
+//              E1l  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
+              Find = Standard_True;
+            }
+          }
+          BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
+          MapSF.Bind(E,OF);
+        }
+      }
+      else {
+        // ----------------------
+        // free border.
+        // ----------------------
+        TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
+        TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
+///        TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
+        myInitOffsetEdge.SetRoot(E); // skv: supporting history.
+        myInitOffsetEdge.Bind (E,EOn1);      
+      }
+    }
+  }
+
+  //--------------------------------------------------------
+  // Construction of spheres on vertex.
+  //--------------------------------------------------------
+  Done.Clear();
+  TopTools_ListIteratorOfListOfShape it;
+
+  for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
+    const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
+    if (Done.Add(V)) {
+      const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
+      TopTools_ListOfShape LE;
+      myAnalyse.Edges(V,OT,LE);
+
+      if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
+        TopTools_ListOfShape LOE;
+        //--------------------------------------------------------
+        // Return connected edges on tubes.
+        //--------------------------------------------------------
+        for (it.Initialize(LE) ; it.More(); it.Next()) {
+          LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
+        }
+        //----------------------
+        // construction sphere.
+        //-----------------------
+        const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
+        const TopoDS_Shape& FF = LLA.First();
+        Standard_Real CurOffset = myOffset;
+        if ( myFaceOffset.IsBound(FF))
+          CurOffset = myFaceOffset(FF);
+        
+        BRepOffset_Offset OF(V,LOE,CurOffset);
+        MapSF.Bind(V,OF);
+      }
+      //--------------------------------------------------------------
+      // Particular processing if V is at least a free border.
+      //-------------------------------------------------------------
+      TopTools_ListOfShape LBF;
+      myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
+      if (!LBF.IsEmpty()) {        
+        Standard_Boolean First = Standard_True;
+        for (it.Initialize(LE) ; it.More(); it.Next()) {
+          if (First) {
+            myInitOffsetEdge.SetRoot(V); // skv: supporting history.
+            myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
+            First = Standard_False;
+          }
+          else {
+            myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
+          }
+        } 
+      }
+    }
+  }
+
+  //------------------------------------------------------------
+  // Extension of parallel faces to the context.
+  // Extended faces are ordered in DS and removed from MapSF.
+  //------------------------------------------------------------
+  if (!myFaces.IsEmpty()) ToContext (MapSF);
+
+  //------------------------------------------------------
+  // MAJ SD.
+  //------------------------------------------------------
+  BRepOffset_Type    RT = BRepOffset_Concave;
+  if (myOffset < 0.) RT = BRepOffset_Convex;
+  BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
+  for ( ; It.More(); It.Next()) {
+    const TopoDS_Shape& SI = It.Key(); 
+    const BRepOffset_Offset& SF = It.Value();
+    if (SF.Status() == BRepOffset_Reversed ||
+        SF.Status() == BRepOffset_Degenerated ) {
+      //------------------------------------------------
+      // Degenerated or returned faces are not stored.
+      //------------------------------------------------
+      continue; 
+    }        
+
+    const TopoDS_Face&  OF = It.Value().Face();
+    myInitOffsetFace.Bind    (SI,OF);      
+    myInitOffsetFace.SetRoot (SI);      // Initial<-> Offset
+    myImageOffset.SetRoot    (OF);      // FaceOffset root of images
+    
+    if (SI.ShapeType() == TopAbs_FACE) {
+      for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+           Exp.More(); Exp.Next()) {
+        //--------------------------------------------------------------------
+        // To each face are associatedthe edges that restrict that 
+        // The edges that do not generate tubes or are not tangent
+        // to two faces are removed.
+        //--------------------------------------------------------------------
+        const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
+        const BRepOffset_ListOfInterval& L  = myAnalyse.Type(E);
+        if (!L.IsEmpty() && L.First().Type() != RT) {
+          TopAbs_Orientation OO  = E.Orientation();
+          TopoDS_Shape aLocalShape = It.Value().Generated(E);
+          TopoDS_Edge        OE  = TopoDS::Edge(aLocalShape);
+//          TopoDS_Edge        OE  = TopoDS::Edge(It.Value().Generated(E));
+          myAsDes->Add (OF,OE.Oriented(OO));
+        }
+      }
+    }
+    else {
+      for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+           Exp.More(); Exp.Next()) {
+        myAsDes->Add (OF,Exp.Current());
+      }
+    }
+  }
+
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : SelfInter
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::SelfInter(TopTools_MapOfShape& /*Modif*/)
+{
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) {
+    cout << " AUTODEBOUCLAGE:" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();
+  }    
+#endif  
+
+  Standard_NotImplemented::Raise();
+
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : ToContext
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
+{
+  TopTools_DataMapOfShapeShape        Created;   
+  TopTools_DataMapOfShapeShape        MEF;
+  TopTools_IndexedMapOfShape          FacesToBuild;
+  TopTools_ListIteratorOfListOfShape  itl;
+  TopExp_Explorer                     exp;
+
+//  TopAbs_State       Side = TopAbs_IN;  
+//  if (myOffset < 0.) Side = TopAbs_OUT;
+
+  TopAbs_State       Side = TopAbs_OUT; 
+
+  /*
+  Standard_Integer i;
+  for (i = 1; i <= myFaces.Extent(); i++) {
+    const TopoDS_Face& CF = TopoDS::Face(myFaces(i));
+    for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+         exp.More(); exp.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+      if (!myAnalyse.HasAncestor(E)) {
+        //----------------------------------------------------------------
+        // The edges of context faces that are not in the initial shape
+        // can appear in the result.
+        //----------------------------------------------------------------
+        //myAsDes->Add(CF,E);
+      }  
+    }
+  }
+  */
+  
+  //--------------------------------------------------------
+  // Determine the edges and faces reconstructed by  
+  // intersection.
+  //---------------------------------------------------------
+  Standard_Integer j;
+  for (j = 1; j <= myFaces.Extent(); j++) {
+    const TopoDS_Face& CF = TopoDS::Face(myFaces(j));
+    for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+         exp.More(); exp.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); 
+      if (myAnalyse.HasAncestor(E)) {
+        const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
+        for (itl.Initialize(LEA); itl.More(); itl.Next()) {
+          const BRepOffset_Offset& OF = MapSF(itl.Value());
+          FacesToBuild.Add(itl.Value());
+          MEF.Bind(OF.Generated(E),CF);
+        }
+         TopoDS_Vertex V[2];
+        TopExp::Vertices(E,V[0],V[1]);
+        for (Standard_Integer i = 0; i < 2; i++) {
+          const TopTools_ListOfShape& LVA =  myAnalyse.Ancestors(V[i]);
+          for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
+            const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
+            if (MapSF.IsBound(EV)) {
+              const BRepOffset_Offset& OF = MapSF(EV);
+              FacesToBuild.Add(EV);
+              MEF.Bind(OF.Generated(V[i]),CF);
+            }
+          }
+        }
+      }
+    }
+  }
+  //---------------------------
+  // Reconstruction of faces.
+  //---------------------------
+  TopoDS_Face        F,NF;
+  BRepOffset_Type    RT = BRepOffset_Concave;
+  if (myOffset < 0.) RT = BRepOffset_Convex;
+  TopoDS_Shape       OE,NE;
+  TopAbs_Orientation Or;
+
+  for (j = 1; j <= FacesToBuild.Extent(); j++) {
+    const TopoDS_Shape& S   = FacesToBuild(j);
+    BRepOffset_Offset   BOF;
+    BOF = MapSF(S);
+    F = TopoDS::Face(BOF.Face());
+    BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
+    MapSF.UnBind(S);
+    //--------------
+    // MAJ SD.
+    //--------------
+    myInitOffsetFace.Bind    (S,NF);      
+    myInitOffsetFace.SetRoot (S);      // Initial<-> Offset
+    myImageOffset.SetRoot    (NF);
+
+    if (S.ShapeType() == TopAbs_FACE) {
+      for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+           exp.More(); exp.Next()) {
+        
+        const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+        const BRepOffset_ListOfInterval& L  = myAnalyse.Type(E);
+        OE = BOF.Generated(E);
+        Or = E.Orientation();
+        OE.Orientation(Or);
+        if (!L.IsEmpty() && L.First().Type() != RT) {
+          if (Created.IsBound(OE)) {
+            NE = Created(OE); 
+            if (NE.Orientation() == TopAbs_REVERSED) 
+              NE.Orientation(TopAbs::Reverse(Or));
+            else
+              NE.Orientation(Or);
+            myAsDes->Add(NF,NE);
+          }
+          else {
+            myAsDes->Add(NF,OE);
+          }
+        }
+      }
+    }
+    else {
+      //------------------
+      // Tube
+      //---------------------
+      for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+           exp.More(); exp.Next()) {
+        myAsDes->Add (NF,exp.Current());
+      }
+    }    
+    MapSF.UnBind(S);
+  }
+
+  //------------------
+  // MAJ free borders
+  //------------------
+  TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
+  for (itc.Initialize(Created); itc.More(); itc.Next()) {
+    OE = itc.Key();
+    NE = itc.Value();
+    if (myInitOffsetEdge.IsImage(OE)) {
+      TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
+      Or = myInitOffsetEdge.Image(E).First().Orientation();
+      if (NE.Orientation() == TopAbs_REVERSED) 
+        NE.Orientation(TopAbs::Reverse(Or));
+      else
+        NE.Orientation(Or);
+      myInitOffsetEdge.Remove(OE);
+      myInitOffsetEdge.Bind(E,NE);
+    }
+  }
+}
+
+//=======================================================================
+//function : UpdateFaceOffset
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::UpdateFaceOffset()
+{
+  TopTools_MapOfShape M;
+  TopTools_DataMapOfShapeReal CopiedMap;
+  CopiedMap.Assign(myFaceOffset);
+  TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
+
+  BRepOffset_Type    RT = BRepOffset_Convex;
+  if (myOffset < 0.) RT = BRepOffset_Concave;
+
+  for ( ; it.More(); it.Next()) {
+    const TopoDS_Face& F = TopoDS::Face(it.Key());
+    Standard_Real CurOffset = CopiedMap(F);
+    if ( !M.Add(F)) continue;
+    TopoDS_Compound Co;
+    BRep_Builder Build;
+    Build.MakeCompound(Co);
+    TopTools_MapOfShape Dummy;
+    Build.Add(Co,F);
+    if (myJoin == GeomAbs_Arc)
+      myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
+    else   
+      myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
+
+    TopExp_Explorer exp(Co,TopAbs_FACE);
+    for (; exp.More(); exp.Next()) {
+      const TopoDS_Face& FF = TopoDS::Face(exp.Current());
+      if ( !M.Add(FF)) continue;
+      if ( myFaceOffset.IsBound(FF))
+        myFaceOffset.UnBind(FF);
+      myFaceOffset.Bind(FF,CurOffset);
+    }
+  }
+}
+
+//=======================================================================
+//function : CorrectConicalFaces
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::CorrectConicalFaces()
+{
+  TopTools_SequenceOfShape Cones;
+  TopTools_SequenceOfShape Circs;
+  TopTools_SequenceOfShape Seams;
+  Standard_Real TolApex = 1.e-5;
+
+  Standard_Integer i;
+
+  TopTools_DataMapOfShapeListOfShape FacesOfCone;
+  //TopTools_DataMapOfShapeShape DegEdges;
+  TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
+  if (myJoin == GeomAbs_Arc)
+  {
+    for (; Explo.More(); Explo.Next())
+    {
+      TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
+      Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
+      //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
+      //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
+      
+      TopTools_IndexedMapOfShape Emap;
+      TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
+      for (i = 1; i <= Emap.Extent(); i++)
+      {
+        TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
+        //Standard_Real f, l;
+        //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
+        //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
+        if (BRep_Tool::Degenerated(anEdge))
+        {
+          //Check if anEdge is a really degenerated edge or not
+          BRepAdaptor_Curve BACurve(anEdge, aFace);
+          gp_Pnt Pfirst, Plast, Pmid;
+          Pfirst = BACurve.Value(BACurve.FirstParameter());
+          Plast  = BACurve.Value(BACurve.LastParameter());
+          Pmid   = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
+          if (Pfirst.Distance(Plast) <= TolApex &&
+              Pfirst.Distance(Pmid)  <= TolApex)
+            continue;
+          //Cones.Append( aFace );
+          //Circs.Append( anEdge );
+          //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
+          TopoDS_Edge OrEdge = 
+            TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
+          TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
+          if ( FacesOfCone.IsBound(VF) )
+          {
+            //add a face to the existing list
+            TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
+            aFaces.Append (aFace);
+            //DegEdges.Bind(aFace, anEdge);
+          }
+          else
+          {
+            //the vertex is not in the map => create a new key and items
+            TopTools_ListOfShape aFaces;
+            aFaces.Append (aFace);
+            FacesOfCone.Bind(VF, aFaces);
+            //DegEdges.Bind(aFace, anEdge);
+          }
+        }
+      } //for (i = 1; i <= Emap.Extent(); i++)
+    } //for (; fexp.More(); fexp.Next())
+  } //if (myJoin == GeomAbs_Arc)
+
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
+  BRep_Builder BB;
+  TopLoc_Location L;
+  for (; Cone.More(); Cone.Next() ) {
+    gp_Sphere theSphere;
+    Handle(Geom_SphericalSurface) aSphSurf;
+    TopoDS_Wire SphereWire;
+    BB.MakeWire(SphereWire);
+    TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
+    const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
+    TopTools_ListIteratorOfListOfShape itFaces(Faces);
+    Standard_Boolean isFirstFace = Standard_True;
+    gp_Pnt FirstPoint;
+    TopoDS_Vertex theFirstVertex, CurFirstVertex;
+    for (; itFaces.More(); itFaces.Next())
+    {
+      TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
+      TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
+      for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+      {
+        DegEdge = TopoDS::Edge(Explo.Current());
+        if (BRep_Tool::Degenerated(DegEdge))
+        {
+          TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
+          TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
+          if (VF.IsSame(anApex))
+            break;
+        }
+      }
+      TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
+      TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
+      BB.Degenerated(CurEdge, Standard_False);
+      BB.SameRange(CurEdge, Standard_False);
+      BB.SameParameter(CurEdge, Standard_False);
+      gp_Pnt fPnt, lPnt, mPnt;
+      GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
+      Standard_Real f, l;
+      BRep_Tool::Range(CurEdge, f, l);
+      if (isFirstFace)
+      {
+        gp_Vec aVec1(fPnt, mPnt);
+        gp_Vec aVec2(fPnt, lPnt);
+        gp_Vec aNorm = aVec1.Crossed(aVec2);
+        gp_Pnt theApex = BRep_Tool::Pnt(anApex);
+        gp_Vec ApexToFpnt(theApex, fPnt);
+        gp_Vec Ydir = aNorm ^ ApexToFpnt;
+        gp_Vec Xdir = Ydir ^ aNorm;
+        //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
+        gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
+        theSphere.SetRadius(myOffset);
+        theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
+        aSphSurf = new Geom_SphericalSurface(theSphere);
+        FirstPoint = fPnt;
+        theFirstVertex = BRepLib_MakeVertex(fPnt);
+        CurFirstVertex = theFirstVertex;
+      }
+      
+      TopoDS_Vertex v1, v2, FirstVert, EndVert;
+      TopExp::Vertices(CurEdge, v1, v2);
+      FirstVert = CurFirstVertex;
+      if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
+        EndVert = theFirstVertex;
+      else
+        EndVert = BRepLib_MakeVertex(lPnt);
+      CurEdge.Free( Standard_True );
+      BB.Remove(CurEdge, v1);
+      BB.Remove(CurEdge, v2);
+      BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
+      BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
+      //take the curve from sphere an put it to the edge
+      Standard_Real Uf, Vf, Ul, Vl;
+      ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
+      ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
+      if (Abs(Ul) <= Precision::Confusion())
+        Ul = 2.*M_PI;
+      Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
+      /*
+        if (!isFirstFace)
+        {
+        gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
+        if (Abs(Uf - f) > Precision::Confusion())
+        {
+        aCircle.Rotate(aCircle.Axis(), f - Uf);
+        aCurv = new Geom_Circle(aCircle);
+        }
+        }
+      */
+      Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
+      BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
+      BB.Range(CurEdge, Uf, Ul, Standard_True);
+      Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
+      Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
+      BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
+      BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
+      BRepLib::SameParameter(CurEdge);
+      BB.Add(SphereWire, CurEdge);
+      //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
+      BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
+      gp_Pnt2d fPnt2d, lPnt2d;
+      fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
+      lPnt2d = BAc2d.Value(BAc2d.LastParameter());
+      TopTools_IndexedMapOfShape Emap;
+      TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
+      TopoDS_Edge EE [2];
+      Standard_Integer j = 0, k;
+      for (k = 1; k <= Emap.Extent(); k++)
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
+        if (!BRep_Tool::Degenerated(anEdge))
+        {
+          TopoDS_Vertex V1, V2;
+          TopExp::Vertices(anEdge, V1, V2);
+          if (V1.IsSame(v1) || V2.IsSame(v1))
+            EE[j++] = anEdge;
+        }
+      }
+      for (k = 0; k < j; k++)
+      {
+        TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
+        TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
+        Eforward.Free(Standard_True);
+        TopoDS_Vertex V1, V2;
+        TopExp::Vertices( Eforward, V1, V2 );
+        BRepAdaptor_Curve2d EEc( Eforward, aFace );
+        gp_Pnt2d p2d1, p2d2;
+        p2d1 = EEc.Value(EEc.FirstParameter());
+        p2d2 = EEc.Value(EEc.LastParameter());
+        if (V1.IsSame(v1))
+        {
+          TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
+            FirstVert : EndVert;
+          BB.Remove( Eforward, V1 );
+          BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
+        }
+        else
+        {
+          TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
+            FirstVert : EndVert;
+          BB.Remove( Eforward, V2 );
+          BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
+        }
+      }
+      
+      isFirstFace = Standard_False;
+      CurFirstVertex = EndVert;
+    }
+    //Building new spherical face
+    Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
+    gp_Pnt2d p2d1, p2d2;
+    TopTools_ListOfShape EdgesOfWire;
+    TopoDS_Iterator itw(SphereWire);
+    for (; itw.More(); itw.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
+      EdgesOfWire.Append(anEdge);
+      Standard_Real f, l;
+      Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
+      p2d1 = aC2d->Value(f);
+      p2d2 = aC2d->Value(l);
+      if (p2d1.X() < Ufirst)
+        Ufirst = p2d1.X();
+      if (p2d1.X() > Ulast)
+        Ulast = p2d1.X();
+      if (p2d2.X() < Ufirst)
+        Ufirst = p2d2.X();
+      if (p2d2.X() > Ulast)
+        Ulast = p2d2.X();
+    }
+    TopTools_ListOfShape NewEdges;
+    TopoDS_Edge FirstEdge;
+    TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
+    for (; itl.More(); itl.Next())
+    {
+      FirstEdge = TopoDS::Edge(itl.Value());
+      Standard_Real f, l;
+      Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
+      p2d1 = aC2d->Value(f);
+      p2d2 = aC2d->Value(l);
+      if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
+      {
+        EdgesOfWire.Remove(itl);
+        break;
+      }
+    }
+    NewEdges.Append(FirstEdge);
+    TopoDS_Vertex Vf1, CurVertex;
+    TopExp::Vertices(FirstEdge, Vf1, CurVertex);
+    itl.Initialize(EdgesOfWire);
+    while (itl.More())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+      TopoDS_Vertex V1, V2;
+      TopExp::Vertices(anEdge, V1, V2);
+      if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
+      {
+        NewEdges.Append(anEdge);
+        CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
+        EdgesOfWire.Remove(itl);
+      }
+      else
+        itl.Next();
+    }
+    
+    Standard_Real Vfirst, Vlast;
+    if (p2d1.Y() > 0.)
+    {
+      Vfirst = p2d1.Y(); Vlast = M_PI/2.;
+    }
+    else
+    {
+      Vfirst = -M_PI/2.; Vlast = p2d1.Y();
+    }
+    TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
+    TopoDS_Edge OldEdge;
+    for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+    {
+      OldEdge = TopoDS::Edge(Explo.Current());
+      if (!BRep_Tool::Degenerated(OldEdge))
+      {
+        BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
+        p2d1 = BAc2d.Value(BAc2d.FirstParameter());
+        p2d2 = BAc2d.Value(BAc2d.LastParameter());
+        if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
+            Abs(p2d2.X() - Ulast)  <= Precision::Confusion())
+          break;
+      }
+    }
+    TopoDS_Vertex V1, V2;
+    TopExp::Vertices(OldEdge, V1, V2);
+    TopTools_ListOfShape LV1, LV2;
+    LV1.Append(Vf1);
+    LV2.Append(CurVertex);
+    BRepTools_Substitution theSubstitutor;
+    theSubstitutor.Substitute(V1, LV1);
+    if (!V1.IsSame(V2))
+      theSubstitutor.Substitute(V2, LV2);
+    theSubstitutor.Substitute(OldEdge, NewEdges);
+    theSubstitutor.Build(NewSphericalFace);
+    if (theSubstitutor.IsCopied(NewSphericalFace))
+    {
+      const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
+      NewSphericalFace = TopoDS::Face(listSh.First());
+    }
+    
+    //Adding NewSphericalFace to the shell
+    Explo.Init( myOffsetShape, TopAbs_SHELL );
+    TopoDS_Shape theShell = Explo.Current();
+    theShell.Free( Standard_True );
+    BB.Add( theShell, NewSphericalFace );
+  }
+
+  if (myShape.ShapeType() == TopAbs_SOLID || myThickening)
+  {
+    Explo.Init( myOffsetShape, TopAbs_SHELL );
+    
+    if (Explo.More()) {
+      TopoDS_Shape theShell = Explo.Current();
+      theShell.Closed( Standard_True );
+    }
+    
+    Standard_Integer            NbShell = 0;
+    TopoDS_Compound             NC;
+    TopoDS_Shape                S1;
+    BB.MakeCompound (NC);
+    
+    for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
+      const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
+      NbShell++;
+      if (Sh.Closed()) {
+        TopoDS_Solid  Sol;
+        BB.MakeSolid  (Sol);
+        BB.Add        (Sol,Sh);
+        Sol.Closed(Standard_True);
+        BB.Add (NC,Sol);
+        if (NbShell == 1) S1 = Sol;
+      }
+      else {
+        BB.Add (NC,Sh);
+        if (NbShell == 1) S1 = Sh;
+      }
+    }
+    if (NbShell == 1) myOffsetShape = S1;
+    else              myOffsetShape = NC;
+  }
+}
+
+//=======================================================================
+//function : Intersection3D
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::Intersection3D(BRepOffset_Inter3d& Inter)
+{
+#ifdef OCCT_DEBUG
+  if (ChronBuildOld) {
+    cout << " INTERSECTION 3D:" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();  
+  }
+#endif
+  TopTools_ListOfShape OffsetFaces;  // list of faces // created.
+  MakeList (OffsetFaces, myInitOffsetFace, myFaces);
+
+  if (!myFaces.IsEmpty()) {     
+    Standard_Boolean InSide = (myOffset < 0.); // Temporary
+    // it is necessary to calculate Inside taking account of the concavity or convexity of edges
+    // between the cap and the part.
+
+    if (myJoin == GeomAbs_Arc) 
+      Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
+  }
+  if (myInter) {
+    //-------------
+    //Complete.
+    //-------------
+    Inter.CompletInt (OffsetFaces,myInitOffsetFace);
+    TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
+    if (myJoin == GeomAbs_Intersection) {
+      BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
+    }
+  }
+  else {
+    //--------------------------------
+    // Only between neighbor faces.
+    //--------------------------------
+    Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
+  }
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : Intersection2D
+//purpose  : 
+//=======================================================================
+
+void BRepOffset_MakeOffsetOld::Intersection2D(const TopTools_IndexedMapOfShape& Modif,
+                                           const TopTools_IndexedMapOfShape& NewEdges)
+{
+#ifdef OCCT_DEBUG
+  if (ChronBuildOld) {
+    cout << " INTERSECTION 2D:" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();  
+  }
+#endif
+  //--------------------------------------------------------
+  // calculate intersections2d on faces concerned by 
+  // intersection3d
+  //---------------------------------------------------------
+  //TopTools_MapIteratorOfMapOfShape it(Modif);
+  //-----------------------------------------------
+  // Intersection of edges 2 by 2.
+  //-----------------------------------------------
+  Standard_Integer i;
+  for (i = 1; i <= Modif.Extent(); i++) {
+    const TopoDS_Face& F  = TopoDS::Face(Modif(i));
+    Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(F);
+    BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,aCurrFaceTol);
+  }
+
+#ifdef OCCT_DEBUG
+  if (AffichInt2dOld) {
+    DEBVerticesControlOld (NewEdges,myAsDes);
+  }
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : MakeLoops
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeLoops(TopTools_IndexedMapOfShape& Modif)
+{
+#ifdef OCCT_DEBUG
+  if (ChronBuildOld) {
+     cout << " DEBOUCLAGE 2D:" << endl;
+     ClockOld.Reset();
+     ClockOld.Start(); 
+  }
+#endif
+  //TopTools_MapIteratorOfMapOfShape    it(Modif);
+  TopTools_ListOfShape                LF,LC;
+  //-----------------------------------------
+  // unwinding of faces // modified.
+  //-----------------------------------------
+  Standard_Integer i;
+  for (i = 1; i <= Modif.Extent(); i++) { 
+    if (!myFaces.Contains(Modif(i)))
+      LF.Append(Modif(i));
+  }
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    TopTools_ListOfShape aLFailed;
+    TopTools_IndexedDataMapOfShapeListOfShape anOr;
+    BuildSplitsOfFaces(LF, myAsDes, anOr, myImageOffset, aLFailed, Standard_True);
+    if (aLFailed.Extent()) {
+      myMakeLoops.Build(aLFailed, myAsDes, myImageOffset);
+    }
+  }
+  else {
+    myMakeLoops.Build(LF,myAsDes,myImageOffset);
+  }
+  //-----------------------------------------
+  // unwinding of caps.
+  //-----------------------------------------
+  for (i = 1; i <= myFaces.Extent(); i++)
+    LC.Append(myFaces(i));
+
+  Standard_Boolean   InSide = 1;
+  if (myOffset > 0 ) InSide = 0;
+  myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
+
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : MakeFaces
+//purpose  : Reconstruction of topologically unchanged faces that
+//           share edges that were reconstructed.
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
+{
+#ifdef OCCT_DEBUG
+  if (ChronBuildOld) {  
+    cout << " RECONSTRUCTION OF FACES:" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();
+  }
+#endif
+  TopTools_ListIteratorOfListOfShape itr;
+  const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
+  TopTools_ListOfShape        LOF;
+  TopTools_MapOfShape aMFence;
+  //----------------------------------
+  // Loop on all faces //.
+  //----------------------------------
+  for (itr.Initialize(Roots); itr.More(); itr.Next()) {
+    TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
+    if (!myImageOffset.HasImage(F) && aMFence.Add(F)) {
+      LOF.Append(F);
+    }
+  }
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    TopTools_ListOfShape aLFailed;
+    TopTools_IndexedDataMapOfShapeListOfShape anOr;
+    BuildSplitsOfFaces(LOF, myAsDes, anOr, myImageOffset, aLFailed, Standard_True);
+    if (aLFailed.Extent()) {
+      myMakeLoops.Build(aLFailed, myAsDes, myImageOffset);
+    }
+  }
+  else {
+    myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
+  }
+  //
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : MakeMissingWalls
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeMissingWalls ()
+{
+  TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
+  TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
+  Standard_Real OffsetVal = Abs(myOffset);
+
+  FillContours(myShape, myAnalyse, Contours, MapEF);
+
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
+  for (; iter.More(); iter.Next())
+    {
+      TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
+      TopoDS_Edge StartEdge;
+      const TopTools_ListOfShape& aContour = iter.Value();
+      TopTools_ListIteratorOfListOfShape itl(aContour);
+      Standard_Boolean FirstStep = Standard_True;
+      TopoDS_Edge PrevEdge;
+      TopoDS_Vertex PrevVertex = StartVertex;
+      for (; itl.More(); itl.Next())
+        {
+          TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+          if (!myInitOffsetEdge.HasImage(anEdge))
+            continue;
+          //if (BRep_Tool::Degenerated(anEdge))
+            //continue;
+          TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
+          //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
+          TopTools_ListOfShape LOE, LOE2;
+          myInitOffsetEdge.LastImage( anEdge, LOE );
+          myImageOffset.LastImage( LOE.Last(), LOE2 );
+          TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
+          ////////////////////////////////////////////////////////////////////////
+          TopoDS_Vertex V1, V2, V3, V4;
+          TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
+          TopExp::Vertices(OE,     V4, V3/*, Standard_True*/);
+          Standard_Boolean ToReverse = Standard_False;
+          if (!V1.IsSame(PrevVertex))
+            {
+              TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
+              aVtx = V3; V3 = V4; V4 = aVtx;
+              ToReverse = Standard_True;
+            }
+          //Temporary
+          //anEdge.Reverse();
+          OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
+          TopoDS_Edge E3, E4;
+          if (FirstStep)
+            {
+              E4 = BRepLib_MakeEdge( V1, V4 );
+              StartEdge = E4;
+            }
+          else
+            E4 = PrevEdge;
+          Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
+          if (V2.IsSame(StartVertex) && !ArcOnV2)
+            E3 = StartEdge;
+          else
+            E3 = BRepLib_MakeEdge( V2, V3 );
+          E4.Reverse();
+          TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
+          const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
+          Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
+          Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
+          BRep_Builder BB;
+          TopoDS_Wire theWire;
+          BB.MakeWire(theWire);
+          if (ToReverse)
+            {
+              BB.Add(theWire, anEdge.Reversed());
+              BB.Add(theWire, E3.Reversed());
+              BB.Add(theWire, OE.Reversed());
+              BB.Add(theWire, E4.Reversed());
+            }
+          else
+            {
+              BB.Add(theWire, anEdge);
+              BB.Add(theWire, E3);
+              BB.Add(theWire, OE);
+              BB.Add(theWire, E4);
+            }
+          BRepLib::BuildCurves3d( theWire, myTol );
+          theWire.Closed(Standard_True);
+          TopoDS_Face NewFace;
+          Handle(Geom_Surface) theSurf;
+          BRepAdaptor_Curve BAcurve(anEdge);
+          BRepAdaptor_Curve BAcurveOE(OE);
+          Standard_Real fpar = BAcurve.FirstParameter();
+          Standard_Real lpar = BAcurve.LastParameter();
+          gp_Pnt PonE  = BAcurve.Value(fpar);
+          gp_Pnt PonOE = BAcurveOE.Value(fpar);
+          gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
+          Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
+          Standard_Boolean IsPlanar = Standard_False;
+          if (BAcurve.GetType() == GeomAbs_Circle &&
+              BAcurveOE.GetType() == GeomAbs_Circle)
+          {
+            gp_Circ aCirc = BAcurve.Circle();
+            gp_Circ aCircOE = BAcurveOE.Circle();
+            gp_Lin anAxisLine(aCirc.Axis());
+            gp_Dir CircAxisDir = aCirc.Axis().Direction();
+            if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) &&
+                anAxisLine.Contains(aCircOE.Location(), Precision::Confusion()))
+            { //cylinder, plane or cone
+              if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder
+                theSurf = GC_MakeCylindricalSurface(aCirc).Value();
+              else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane
+                IsPlanar = Standard_True;
+                //
+                gp_Pnt PonEL = BAcurve.Value(lpar);
+                if (PonEL.Distance(PonE) <= Precision::PConfusion()) {
+                  Standard_Boolean bIsHole;
+                  TopoDS_Edge aE1, aE2;
+                  TopoDS_Wire aW1, aW2;
+                  Handle(Geom_Plane) aPL;
+                  IntTools_FClass2d aClsf;
+                  //
+                  if (aCirc.Radius()>aCircOE.Radius()) {
+                    aE1 = anEdge;
+                    aE2 = OE;
+                  } else {
+                    aE1 = OE;
+                    aE2 = anEdge;
+                  }
+                  //
+                  BB.MakeWire(aW1);
+                  BB.Add(aW1, aE1);
+                  BB.MakeWire(aW2);
+                  BB.Add(aW2, aE2);
+                  //
+                  aPL = new Geom_Plane(aCirc.Location(), CircAxisDir);
+                  for (Standard_Integer i = 0; i < 2; ++i) {
+                    TopoDS_Wire& aW = (i==0) ? aW1 : aW2;
+                    TopoDS_Edge& aE = (i==0) ? aE1 : aE2;
+                    //
+                    TopoDS_Face aFace;
+                    BB.MakeFace(aFace, aPL, Precision::Confusion());
+                    BB.Add (aFace, aW);
+                    aClsf.Init(aFace, Precision::Confusion());
+                    bIsHole=aClsf.IsHole();
+                    if ((bIsHole && !i) || (!bIsHole && i)) {
+                      aW.Nullify();
+                      BB.MakeWire(aW);
+                      BB.Add(aW, aE.Reversed());
+                    }
+                  }
+                  //
+                  BB.MakeFace(NewFace, aPL, Precision::Confusion());
+                  BB.Add(NewFace, aW1);
+                  BB.Add(NewFace, aW2);
+                }
+              }
+              else //case of cone
+              {
+                gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
+                                               aCirc.Radius(), aCircOE.Radius());
+                gp_Ax3 theAx3(aCirc.Position());
+                if (CircAxisDir * theCone.Axis().Direction() < 0.)
+                {
+                  theAx3.ZReverse();
+                  CircAxisDir.Reverse();
+                }
+                theCone.SetPosition(theAx3);
+                theSurf = new Geom_ConicalSurface(theCone);
+              }
+              if (!IsPlanar) {
+                TopLoc_Location Loc;
+                EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
+                BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
+                Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
+                OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
+                BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
+                aLine2d  = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
+                aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
+                if (E3.IsSame(E4))
+                {
+                  if (Coeff > 0.)
+                    BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
+                  else
+                  {
+                    BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
+                    theWire.Nullify();
+                    BB.MakeWire(theWire);
+                    BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
+                    BB.Add(theWire, E4);
+                    BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
+                    BB.Add(theWire, E3);
+                    theWire.Closed(Standard_True);
+                  }
+                }
+                else
+                {
+                  BB.SameParameter(E3, Standard_False);
+                  BB.SameRange(E3, Standard_False);
+                  BB.SameParameter(E4, Standard_False);
+                  BB.SameRange(E4, Standard_False);
+                  BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
+                  BB.Range(E3, theSurf, Loc, 0., OffsetVal);
+                  BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
+                  BB.Range(E4, theSurf, Loc, 0., OffsetVal);
+                }
+                NewFace = BRepLib_MakeFace(theSurf, theWire);
+              }
+            } //cylinder or cone
+          } //if both edges are arcs of circles
+          if (NewFace.IsNull())
+            {
+              BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
+              if (MF.Error() == BRepLib_FaceDone)
+                {
+                  NewFace = MF.Face();
+                  IsPlanar = Standard_True;
+                }
+              else //Extrusion (by thrusections)
+                {
+                  Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
+                  Handle(Geom_TrimmedCurve) TrEdgeCurve =
+                    new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
+                  Standard_Real fparOE, lparOE;
+                  Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
+                  Handle(Geom_TrimmedCurve) TrOffsetCurve =
+                    new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
+                  GeomFill_Generator ThrusecGenerator;
+                  ThrusecGenerator.AddCurve( TrEdgeCurve );
+                  ThrusecGenerator.AddCurve( TrOffsetCurve );
+                  ThrusecGenerator.Perform( Precision::PConfusion() );
+                  theSurf = ThrusecGenerator.Surface();
+                  //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
+                  Standard_Real Uf, Ul, Vf, Vl;
+                  theSurf->Bounds(Uf, Ul, Vf, Vl);
+                  TopLoc_Location Loc;
+                  EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
+                  BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
+                  OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
+                  BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
+                  Standard_Real UonV1 = (ToReverse)? Ul : Uf;
+                  Standard_Real UonV2 = (ToReverse)? Uf : Ul;
+                  aLine2d  = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
+                  aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
+                  if (E3.IsSame(E4))
+                    {
+                      BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
+                      Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
+                      BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
+                      BB.Range(E3, Vf, Vl);
+                    }
+                  else
+                    {
+                      BB.SameParameter(E3, Standard_False);
+                      BB.SameRange(E3, Standard_False);
+                      BB.SameParameter(E4, Standard_False);
+                      BB.SameRange(E4, Standard_False);
+                      BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
+                      BB.Range(E3, theSurf, Loc, Vf, Vl);
+                      BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
+                      BB.Range(E4, theSurf, Loc, Vf, Vl);
+                      Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
+                      BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
+                      BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
+                      Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
+                      BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
+                      BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
+                    }
+                  NewFace = BRepLib_MakeFace(theSurf, theWire);
+                }
+            }
+          if (!IsPlanar)
+            {
+              Standard_Real fparOE = BAcurveOE.FirstParameter();
+              Standard_Real lparOE = BAcurveOE.LastParameter();
+              TopLoc_Location Loc;
+              if (Abs(fpar - fparOE) > Precision::Confusion())
+                {
+                  const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
+                  gp_Pnt2d fp2d   = EdgeLine2d->Value(fpar);
+                  gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
+                  aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
+                  Handle(Geom_Curve) aCurve;
+                  Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
+                  Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
+                  GeomAdaptor_Surface GAsurf( theSurf );
+                  Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
+                  Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
+                  Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
+                  Standard_Real max_deviation = 0., average_deviation;
+                  GeomLib::BuildCurve3d(Precision::Confusion(),
+                                        ConS, FirstPar, LastPar,
+                                        aCurve, max_deviation, average_deviation);
+                  BB.UpdateEdge( anE4, aCurve, max_deviation );
+                  BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
+                  BB.Range( anE4, FirstPar, LastPar );
+                }
+              if (Abs(lpar - lparOE) > Precision::Confusion())
+                {
+                  const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
+                  gp_Pnt2d lp2d   = EdgeLine2d->Value(lpar);
+                  gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
+                  aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
+                  Handle(Geom_Curve) aCurve;
+                  Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
+                  Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
+                  GeomAdaptor_Surface GAsurf( theSurf );
+                  Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
+                  Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
+                  Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
+                  Standard_Real max_deviation = 0., average_deviation;
+                  GeomLib::BuildCurve3d(Precision::Confusion(),
+                                        ConS, FirstPar, LastPar,
+                                        aCurve, max_deviation, average_deviation);
+                  BB.UpdateEdge( anE3, aCurve, max_deviation );
+                  BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
+                  BB.Range( anE3, FirstPar, LastPar );
+                }
+            }
+          BRepLib::SameParameter(NewFace);
+          BRepTools::Update(NewFace);
+          myWalls.Append(NewFace);
+          if (ArcOnV2)
+            {
+              TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
+              TopoDS_Vertex arcV1, arcV2;
+              TopExp::Vertices(anArc, arcV1, arcV2);
+              Standard_Boolean ArcReverse = Standard_False;
+              if (!arcV1.IsSame(V3))
+                {
+                  TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
+                  ArcReverse = Standard_True;
+                }
+              TopoDS_Edge EA1, EA2;
+              //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
+              EA1 = E3;
+              EA1.Reverse();
+              if (ToReverse)
+                EA1.Reverse();
+              //////////////////////////////////////////////////////
+              if (V2.IsSame(StartVertex))
+                EA2 = StartEdge;
+              else
+                EA2 = BRepLib_MakeEdge( V2, arcV2 );
+              anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
+              if (EA1.Orientation() == TopAbs_REVERSED)
+                anArc.Reverse();
+              EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
+              TopoDS_Wire arcWire;
+              BB.MakeWire(arcWire);
+              BB.Add(arcWire, EA1);
+              BB.Add(arcWire, anArc);
+              BB.Add(arcWire, EA2);
+              BRepLib::BuildCurves3d( arcWire, myTol );
+              arcWire.Closed(Standard_True);
+              TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
+              BRepTools::Update(arcFace);
+              myWalls.Append(arcFace);
+              TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
+              const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
+              PrevEdge = CEA2;
+              PrevVertex = V2;
+            }
+          else
+            {
+              PrevEdge = E3;
+              PrevVertex = V2;
+            }
+          FirstStep = Standard_False;
+        }
+    }
+}
+
+//=======================================================================
+//function : MakeShells
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeShells()
+{
+#ifdef OCCT_DEBUG
+  if (ChronBuildOld) {  
+    cout << " RECONSTRUCTION OF SHELLS:" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();
+  }
+#endif
+
+  //if ((myJoin == GeomAbs_Intersection) && myInter) {
+  //
+  // make shells using MakerVolume algorithm
+  //
+  TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
+  //
+  BOPCol_ListOfShape aLSF;
+  const TopTools_ListOfShape& R = myImageOffset.Roots();
+  TopTools_ListIteratorOfListOfShape it(R);
+  //
+  for (; it.More(); it.Next()) {
+    TopTools_ListOfShape Image;
+    myImageOffset.LastImage(it.Value(),Image);
+    TopTools_ListIteratorOfListOfShape it2(Image);
+    for (; it2.More(); it2.Next()) {
+      const TopoDS_Shape& aF = it2.Value();
+      aLSF.Append(aF);
+      //
+      if (anOrigins.Contains(aF)) {
+        anOrigins.ChangeFromKey(aF).Append(it.Value());
+      } 
+      else {
+        TopTools_ListOfShape aLOr;
+        aLOr.Append(it.Value());
+        anOrigins.Add(aF, aLOr);
+      }
+    }
+  }
+  //
+  if (myThickening) {
+    TopExp_Explorer Explo(myShape, TopAbs_FACE);
+    for (; Explo.More(); Explo.Next()) {
+      const TopoDS_Shape& aF = Explo.Current();
+      aLSF.Append(aF);
+    }
+    //
+    it.Initialize(myWalls);
+    for (; it.More(); it.Next()) {
+      const TopoDS_Shape& aF = it.Value();
+      aLSF.Append(aF);
+    }
+  }
+  //
+  Standard_Boolean bDone = Standard_False;
+  // build all possible solids
+  /*if (!myThickening && !myFaces.IsEmpty()) {
+    TopExp_Explorer Explo(myShape, TopAbs_FACE);
+    for (; Explo.More(); Explo.Next()) {
+      const TopoDS_Shape& aF = Explo.Current();
+      aLSF.Append(aF);
+    }
+  }*/
+  //
+  Standard_Boolean bFaces = !myFaces.IsEmpty();
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    Standard_Integer i, aNb;
+    TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
+    BRep_Builder aBB;
+    //
+    TopoDS_Compound aCSF;
+    aBB.MakeCompound(aCSF);
+    //
+    BOPAlgo_Builder aGF;
+    //
+    aGF.SetArguments(aLSF);
+    aGF.Perform();
+    bDone = (aGF.ErrorStatus() == 0);
+    if (bDone) {
+      const TopoDS_Shape& aR = aGF.Shape();
+      TopExp_Explorer aExp(aR, TopAbs_FACE);
+      aLSF.Clear();
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Shape& aF = aExp.Current();
+        aLSF.Append(aF);
+        aBB.Add(aCSF, aF);
+      }
+      //
+      bDone = ((myOffset > 0) || !bFaces);
+      if (bDone) {
+        UpdateOrigins(anOrigins, aGF);
+        //
+        BOPAlgo_MakerVolume aMV1;
+        //
+        aMV1.AddArgument(aCSF);
+        aMV1.SetIntersect(Standard_False);
+        //
+        if (bFaces) {
+          aNb = myFaces.Extent();
+          for (i = 1; i <= aNb; ++i) {
+            const TopoDS_Shape& aFEx = myFaces(i);
+            aMV1.AddArgument(aFEx);
+          }
+          aMV1.SetIntersect(Standard_True);
+        }
+        //
+        aMV1.Perform();
+        bDone = (aMV1.ErrorStatus() == 0);
+        if (bDone) {
+          //
+          TopoDS_Shape aResult = aMV1.Shape();
+          //
+          TopTools_IndexedMapOfShape aMFResult;
+          TopExp::MapShapes(aResult, TopAbs_FACE, aMFResult);
+          //
+          // check the result
+          Standard_Boolean bGood = Standard_True;
+          if (myRemoveInvalidFaces) {
+            BOPCol_ListIteratorOfListOfShape aItLSF(aLSF);
+            for (; aItLSF.More(); aItLSF.Next()) {
+              const TopoDS_Shape& aFx = aItLSF.Value();
+              if (!aMFResult.Contains(aFx)) {
+                const TopTools_ListOfShape& aLFMx = aMV1.Modified(aFx);
+                if (aLFMx.IsEmpty()) {
+                  bGood = Standard_False;
+                  break;
+                }
+              }
+            }
+          }
+          //
+          TopoDS_Compound aShells;
+          //
+          aBB.MakeCompound(aShells);
+          //
+          if (!bGood) {
+            myOffsetShape = aShells;
+          }
+          else {
+            // collect images of the faces
+            TopTools_MapOfShape aMFaces;
+            aNb = myFaces.Extent();
+            for (i = 1; i <= aNb; ++i) {
+              const TopoDS_Shape& aFEx = myFaces(i);
+              const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx);
+              if (!aLFEx.IsEmpty()) {
+                aItLS.Initialize(aLFEx);
+                for (; aItLS.More(); aItLS.Next()) {
+                  const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value();
+                  aMFaces.Add(aFExIm);
+                }
+              }
+              else {
+                aMFaces.Add(aFEx);
+              }
+            }
+            //
+            if (aResult.ShapeType() == TopAbs_COMPOUND) {
+              // collect faces attached to only one solid
+              BOPCol_IndexedDataMapOfShapeListOfShape aMFS;
+              BOPCol_ListOfShape aLSF2;
+              //
+              BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS);
+              aNb = aMFS.Extent();
+              bDone = (aNb > 0);
+              //
+              if (bDone) {
+                for (i = 1; i <= aNb; ++i) {
+                  const BOPCol_ListOfShape& aLSx = aMFS(i);
+                  if (aLSx.Extent() == 1) {
+                    const TopoDS_Shape& aFx = aMFS.FindKey(i);
+                    aLSF2.Append(aFx);
+                  }
+                }
+                //
+                // make solids from the new list
+                BOPAlgo_MakerVolume aMV2;
+                //
+                aMV2.SetArguments(aLSF2);
+                aMV2.SetIntersect(Standard_False);
+                //
+                aMV2.Perform();
+                bDone = (aMV2.ErrorStatus() == 0);
+                if (bDone) {
+                  aResult = aMV2.Shape();
+                  if (aResult.ShapeType() == TopAbs_COMPOUND) {
+                    BOPCol_ListOfShape aLSF3;
+                    //
+                    aExp.Init(aResult, TopAbs_FACE);
+                    for (; aExp.More(); aExp.Next()) {
+                      const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
+                      //
+                      // check orientation
+                      if (!anOrigins.Contains(aF)) {
+                        aLSF3.Append(aF);
+                        continue;
+                      }
+                      //
+                      const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aF);
+                      aItLS.Initialize(aLFOr);
+                      for (; aItLS.More(); aItLS.Next()) {
+                        const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
+                        //
+                        if (CheckNormals(aF, aFOr)) {
+                          aLSF3.Append(aF);
+                          break;
+                        }
+                      }
+                    }
+                    //
+                    // make solid containing most outer faces
+                    BOPAlgo_MakerVolume aMV3;
+                    //
+                    aMV3.SetArguments(aLSF3);
+                    aMV3.SetIntersect(Standard_False);
+                    //
+                    aMV3.Perform();
+                    bDone = (aMV3.ErrorStatus() == 0);
+                    if (bDone) {
+                      aResult = aMV3.Shape();
+                    }
+                  }
+                }
+              }
+            }
+            //
+            TopExp_Explorer aExp(aResult, TopAbs_SHELL);
+            bDone = aExp.More();
+            for (; aExp.More(); aExp.Next()) {
+              const TopoDS_Shell& aSh = *(TopoDS_Shell*)&aExp.Current();
+              //
+              TopoDS_Shell aShellNew;
+              if (bFaces) {
+                aBB.MakeShell(aShellNew);
+                //
+                TopExp_Explorer aExp(aSh, TopAbs_FACE);
+                for (; aExp.More(); aExp.Next()) {
+                  const TopoDS_Face& aFSh = *(TopoDS_Face*)&aExp.Current();
+                  if (!aMFaces.Contains(aFSh)) {
+                    aBB.Add(aShellNew, aFSh);
+                  }
+                }
+              }
+              else {
+                aShellNew = aSh;
+              }
+              //
+              aBB.Add(aShells, aShellNew);
+            }
+            myOffsetShape = aShells;
+          }
+        }
+      }
+    }
+  }
+  //
+  if (!bDone) {
+    BRepTools_Quilt Glue;
+    BOPCol_ListIteratorOfListOfShape aItLS;
+    //
+    aItLS.Initialize(aLSF);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aF = aItLS.Value();
+      Glue.Add(aF);
+    }
+    myOffsetShape = Glue.Shells();
+  }
+}
+
+//=======================================================================
+//function : MakeSolid
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::MakeSolid ()
+{
+ if (myOffsetShape.IsNull()) return;
+
+//  Modified by skv - Mon Apr  4 18:17:27 2005 Begin
+//  Supporting history.
+  UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
+  UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
+//  Modified by skv - Mon Apr  4 18:17:27 2005 End
+  TopExp_Explorer             exp;
+  BRep_Builder                B;
+  Standard_Integer            NbShell = 0;
+  TopoDS_Compound             NC;
+  TopoDS_Shape                S1;
+  B.MakeCompound (NC);
+
+  for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
+    TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
+    if (myThickening && myOffset > 0.)
+      Sh.Reverse();
+    NbShell++;
+    if (Sh.Closed()) {
+      TopoDS_Solid  Sol;
+      B.MakeSolid  (Sol);
+      B.Add        (Sol,Sh);
+      Sol.Closed(Standard_True);
+      B.Add (NC,Sol);
+      if (NbShell == 1) S1 = Sol;
+    }
+    else {
+      B.Add (NC,Sh);
+      if (NbShell == 1) S1 = Sh;
+    }
+  }
+  if (NbShell == 1) myOffsetShape = S1;
+  else              myOffsetShape = NC;
+}
+
+//=======================================================================
+//function : SelectShells
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::SelectShells ()
+{  
+  TopTools_MapOfShape FreeEdges;
+  TopExp_Explorer exp(myShape,TopAbs_EDGE);
+  //-------------------------------------------------------------
+  // FreeEdges all edges that can have free border in the  
+  // parallel shell
+  // 1 - free borders of myShape .
+  //-------------------------------------------------------------
+  for ( ; exp.More(); exp.Next()) {
+    const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+    const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
+    if (LA.Extent() < 2) {
+      if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
+        FreeEdges.Add(E);                       
+      }
+    }  
+  }
+  // myShape has free borders and there are no caps
+  // no unwinding 3d.
+  if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
+
+  myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
+}
+
+//=======================================================================
+//function : OffsetFacesFromShapes
+//purpose  : 
+//=======================================================================
+const BRepAlgo_Image& BRepOffset_MakeOffsetOld::OffsetFacesFromShapes() const
+{
+  return myInitOffsetFace;
+}
+
+//  Modified by skv - Tue Mar 15 16:20:43 2005 Begin
+
+//=======================================================================
+//function : GetJoinType
+//purpose  : Query offset join type.
+//=======================================================================
+GeomAbs_JoinType BRepOffset_MakeOffsetOld::GetJoinType() const
+{
+  return myJoin;
+}
+
+//=======================================================================
+//function : OffsetEdgesFromShapes
+//purpose  : 
+//=======================================================================
+const BRepAlgo_Image& BRepOffset_MakeOffsetOld::OffsetEdgesFromShapes() const
+{
+  return myInitOffsetEdge;
+}
+
+//  Modified by skv - Tue Mar 15 16:20:43 2005 End
+
+//=======================================================================
+//function : ClosingFaces
+//purpose  : 
+//=======================================================================
+const TopTools_IndexedMapOfShape& BRepOffset_MakeOffsetOld::ClosingFaces () const
+{
+  return myFaces;
+}
+
+//=======================================================================
+//function : EncodeRegularity
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::EncodeRegularity ()
+{
+#ifdef OCCT_DEBUG
+  if (ChronBuildOld) {  
+    cout << " CODING OF REGULARITIES:" << endl;
+    ClockOld.Reset();
+    ClockOld.Start();
+  }
+#endif
+
+  if (myOffsetShape.IsNull()) return;
+  // find edges G1 in the result
+  TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
+
+  BRep_Builder B;
+  TopTools_MapOfShape MS;
+
+  for ( ; exp.More(); exp.Next()) {
+    TopoDS_Edge OE  = TopoDS::Edge(exp.Current());
+    BRepLib::BuildCurve3d(OE,myTol);
+    TopoDS_Edge ROE = OE;
+    
+    if ( !MS.Add(OE)) continue;
+      
+    if ( myImageOffset.IsImage(OE)) 
+      ROE = TopoDS::Edge(myImageOffset.Root(OE));
+
+    const TopTools_ListOfShape& LofOF    = myAsDes->Ascendant(ROE);
+    
+    if (LofOF.Extent() != 2) {
+#ifdef OCCT_DEBUG_VERB
+    cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
+#endif
+      continue;
+    }
+
+    const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
+    const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
+    
+    if ( F1.IsNull() || F2.IsNull()) 
+      continue;
+   
+    const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
+    const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
+
+    TopAbs_ShapeEnum Type1 = Root1.ShapeType();
+    TopAbs_ShapeEnum Type2 = Root2.ShapeType();
+    if (F1.IsSame(F2)) {      
+      if (BRep_Tool::IsClosed(OE,F1)) {
+        // Temporary Debug for the Bench.
+        // Check with YFR.
+        // In mode intersection, the edges are not coded in myInitOffsetEdge
+        // so, manage case by case
+        // Note DUB; for Hidden parts, it is NECESSARY to code CN 
+        // Analytic Surfaces.
+        if (myJoin == GeomAbs_Intersection) {
+          BRepAdaptor_Surface BS(F1,Standard_False);
+          GeomAbs_SurfaceType SType = BS.GetType();
+          if (SType == GeomAbs_Cylinder ||
+              SType == GeomAbs_Cone     ||
+              SType == GeomAbs_Sphere   ||
+              SType == GeomAbs_Torus      ) {
+            B.Continuity(OE,F1,F1,GeomAbs_CN);
+          }
+          else {
+            // See YFR : MaJ of myInitOffsetFace
+          }
+        }
+        else if (myInitOffsetEdge.IsImage(ROE)) {
+          if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
+            const TopoDS_Face& FRoot = TopoDS::Face(Root1);
+            const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
+            GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
+            if (Conti == GeomAbs_CN) {
+              B.Continuity(OE,F1,F1,GeomAbs_CN);
+            }
+            else if ( Conti > GeomAbs_C0) {
+              B.Continuity(OE,F1,F1,GeomAbs_G1);
+            }
+          }
+        }
+      }
+      continue;
+    }
+
+
+    //  code regularities G1 between :
+    //    - sphere and tube : one root is a vertex, the other is an edge 
+    //                        and the vertex is included in the edge
+    //    - face and tube   : one root is a face, the other an edge 
+    //                        and the edge is included in the face
+    //    - face and face    : if two root faces are tangent in 
+    //                        the initial shape, they will be tangent in the offset shape
+    //    - tube and tube  : if 2 edges generating tubes are
+    //                        tangents, the 2 will be tangent either.
+    if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
+      TopoDS_Vertex V1,V2;
+      TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
+      if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
+        B.Continuity(OE,F1,F2,GeomAbs_G1);
+      }
+    }
+    else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
+      TopoDS_Vertex V1,V2;
+      TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
+      if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
+        B.Continuity(OE,F1,F2,GeomAbs_G1);
+      }
+    }
+    else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
+      TopExp_Explorer exp2(Root1,TopAbs_EDGE);
+      for ( ; exp2.More(); exp2.Next()) {
+        if ( exp2.Current().IsSame(Root2)) {
+          B.Continuity(OE,F1,F2,GeomAbs_G1);
+          break;
+        }
+      }
+    }
+    else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
+      TopExp_Explorer exp2(Root2,TopAbs_EDGE);
+      for ( ; exp2.More(); exp2.Next()) {
+        if ( exp2.Current().IsSame(Root1)) {
+          B.Continuity(OE,F1,F2,GeomAbs_G1);
+          break;
+        }
+      }
+    }
+    else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
+    //  if two root faces are tangent in 
+    //  the initial shape, they will be tangent in the offset shape
+      TopTools_ListOfShape LE,LV;
+      BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
+                                       TopoDS::Face(Root2),
+                                       LE,LV);
+      if ( LE.Extent() == 1) { 
+        const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
+        if ( myAnalyse.HasAncestor(Ed)) {
+          const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
+          if (LI.Extent()       == 1   && 
+              LI.First().Type() == BRepOffset_Tangent) {
+            B.Continuity(OE,F1,F2,GeomAbs_G1);
+          }
+        }
+      }
+    }
+    else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
+      TopTools_ListOfShape LV;
+      TopExp_Explorer exp1,exp2;
+      for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
+        TopExp_Explorer exp2(F2,TopAbs_EDGE);
+        for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
+          if (exp1.Current().IsSame(exp2.Current())) {
+            LV.Append(exp1.Current());
+          }
+        }
+      }
+      if ( LV.Extent() == 1) {
+        TopTools_ListOfShape LEdTg;
+        myAnalyse.TangentEdges(TopoDS::Edge(Root1),
+                               TopoDS::Vertex(LV.First()),
+                               LEdTg);
+        TopTools_ListIteratorOfListOfShape it(LEdTg);
+        for (; it.More(); it.Next()) {
+          if ( it.Value().IsSame(Root2)) {
+            B.Continuity(OE,F1,F2,GeomAbs_G1);
+            break;
+          }
+        }
+      }
+    }
+  }
+
+#ifdef OCCT_DEBUG
+  if ( ChronBuildOld) ClockOld.Show();
+#endif
+}
+
+//=======================================================================
+//function : RemoveInternalEdges
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffsetOld::RemoveInternalEdges()
+{
+  Standard_Boolean bRemoveWire, bRemoveEdge;
+  TopExp_Explorer aExpF, aExpW, aExpE;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
+  //
+  TopExp::MapShapesAndAncestors(myOffsetShape, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+  //
+  aExpF.Init(myOffsetShape, TopAbs_FACE);
+  for (; aExpF.More(); aExpF.Next()) {
+    TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
+    //
+    TopTools_ListOfShape aLIW;
+    //
+    aExpW.Init(aF, TopAbs_WIRE);
+    for (; aExpW.More(); aExpW.Next()) {
+      TopoDS_Wire& aW = *(TopoDS_Wire*)&aExpW.Current();
+      //
+      bRemoveWire = Standard_True;
+      TopTools_ListOfShape aLIE;
+      //
+      aExpE.Init(aW, TopAbs_EDGE);
+      for (; aExpE.More(); aExpE.Next()) {
+        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
+        if (aE.Orientation() != TopAbs_INTERNAL) {
+          bRemoveWire = Standard_False;
+          continue;
+        }
+        //
+        const TopTools_ListOfShape& aLF = aDMELF.FindFromKey(aE);
+        bRemoveEdge = (aLF.Extent() == 1);
+        if (bRemoveEdge) {
+          aLIE.Append(aE);
+        }
+        else {
+          bRemoveWire = Standard_False;
+        }
+      }
+      //
+      if (bRemoveWire) {
+        aLIW.Append(aW);
+      }
+      else if (aLIE.Extent()) {
+        RemoveShapes(aW, aLIE);
+      }
+    }
+    //
+    if (aLIW.Extent()) {
+      RemoveShapes(aF, aLIW);
+    }
+  }
+}
+
+//=======================================================================
+// static methods implementation
+//=======================================================================
+
+//=======================================================================
+//function : RemoveShapes
+//purpose  : Removes the shapes <theLS> from the shape <theS>
+//=======================================================================
+void RemoveShapes(TopoDS_Shape& theS,
+                  const TopTools_ListOfShape& theLS)
+{
+  BRep_Builder aBB;
+  //
+  Standard_Boolean bFree = theS.Free();
+  theS.Free(Standard_True);
+  //
+  TopTools_ListIteratorOfListOfShape aIt(theLS);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aSI = aIt.Value();
+    aBB.Remove(theS, aSI);
+  }
+  //
+  theS.Free(bFree);
+}
+
+//=======================================================================
+//function : UpDateTolerance
+//purpose  : 
+//=======================================================================
+void UpdateTolerance (TopoDS_Shape& S,
+                      const TopTools_IndexedMapOfShape& Faces)
+{
+  BRep_Builder B;
+  TopTools_MapOfShape View;
+  TopoDS_Vertex V[2];
+
+  // The edges of caps are not modified.
+  Standard_Integer j;
+  for (j = 1; j <= Faces.Extent(); j++) {
+    const TopoDS_Shape& F = Faces(j);
+    TopExp_Explorer Exp;
+    for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
+      View.Add(Exp.Current());
+    }
+  }
+  
+  TopExp_Explorer Exp;
+  for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) {
+    TopoDS_Edge E = TopoDS::Edge(Exp.Current());
+    if (View.Add(E)) {
+      Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E);
+      Standard_Real    Tol = EdgeCorrector->Tolerance();
+      B.UpdateEdge (E,Tol);
+      
+      // Update the vertices.
+      TopExp::Vertices(E,V[0],V[1]);
+     
+      for (Standard_Integer i = 0 ; i <=1 ; i++) {
+        if (View.Add(V[i])) {
+          Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
+          TV->Tolerance(0.);
+          Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]);
+          B.UpdateVertex (V[i],VertexCorrector->Tolerance());
+          // use the occasion to clean the vertices.
+          (TV->ChangePoints()).Clear();
+        }
+        B.UpdateVertex(V[i],Tol);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : FindParameter
+//purpose  : 
+//=======================================================================
+Standard_Boolean FindParameter(const TopoDS_Vertex& V, 
+                               const TopoDS_Edge& E,
+                               Standard_Real& U)
+{
+  // Search the vertex in the edge
+
+  Standard_Boolean rev = Standard_False;
+  TopoDS_Shape VF;
+  TopAbs_Orientation orient = TopAbs_INTERNAL;
+
+  TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
+
+  // if the edge has no vertices
+  // and is degenerated use the vertex orientation
+  // RLE, june 94
+
+  if (!itv.More() && BRep_Tool::Degenerated(E)) {
+    orient = V.Orientation();
+  }
+
+  while (itv.More()) {
+    const TopoDS_Shape& Vcur = itv.Value();
+    if (V.IsSame(Vcur)) {
+      if (VF.IsNull()) {
+        VF = Vcur;
+      }
+      else {
+        rev = E.Orientation() == TopAbs_REVERSED;
+        if (Vcur.Orientation() == V.Orientation()) {
+          VF = Vcur;
+        }
+      }
+    }
+    itv.Next();
+  }
+  
+  if (!VF.IsNull()) orient = VF.Orientation();
+  Standard_Real f,l;
+
+  if (orient ==  TopAbs_FORWARD) {
+    BRep_Tool::Range(E,f,l);
+    //return (rev) ? l : f;
+    U = (rev) ? l : f;
+    return Standard_True;
+  }
+  else if (orient ==  TopAbs_REVERSED) {
+    BRep_Tool::Range(E,f,l);
+    //return (rev) ? f : l;
+    U = (rev) ? f : l;
+    return Standard_True;
+   }
+
+  else {
+    TopLoc_Location L;
+    const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
+    L = L.Predivided(V.Location());
+    if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
+      BRep_ListIteratorOfListOfPointRepresentation itpr
+        ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
+
+      while (itpr.More()) {
+        const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+        if (pr->IsPointOnCurve(C,L)) {
+          Standard_Real p = pr->Parameter();
+          Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
+          if (!C.IsNull()) {
+            // Closed curves RLE 16 june 94
+            if (Precision::IsNegativeInfinite(f))
+              {
+                //return pr->Parameter();//p;
+                U = pr->Parameter();
+                return Standard_True;
+              }
+            if (Precision::IsPositiveInfinite(l))
+              {
+                //return pr->Parameter();//p;
+                U = pr->Parameter();
+                return Standard_True;
+              }
+            gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
+            gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
+            Standard_Real tol = BRep_Tool::Tolerance(V);
+            if (Pf.Distance(Pl) < tol) {
+              if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
+                if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
+                else                                   res = l;//p = l;
+              }
+            }
+          }
+          //return res;//p;
+          U = res;
+          return Standard_True;
+        }
+        itpr.Next();
+      }
+    }
+    else {
+      // no 3d curve !!
+      // let us try with the first pcurve
+      Handle(Geom2d_Curve) PC;
+      Handle(Geom_Surface) S;
+      BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
+      L = L.Predivided(V.Location()); 
+      BRep_ListIteratorOfListOfPointRepresentation itpr
+        ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
+
+      while (itpr.More()) {
+        const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+        if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
+          Standard_Real p = pr->Parameter();
+          // Closed curves RLE 16 june 94
+          if (PC->IsClosed()) {
+            if ((p == PC->FirstParameter()) || 
+                (p == PC->LastParameter())) {
+              if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
+              else                                   p = PC->LastParameter();
+            }
+          }
+          //return p;
+          U = p;
+          return Standard_True;
+        }
+        itpr.Next();
+      }
+    }
+  }
+  
+  //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
+  return Standard_False;
+}
+
+//=======================================================================
+//function : GetEdgePoints
+//purpose  : gets the first, last and middle points of the edge
+//=======================================================================
+void GetEdgePoints(const TopoDS_Edge& anEdge,
+                   const TopoDS_Face& aFace,
+                   gp_Pnt& fPnt, gp_Pnt& mPnt,
+                   gp_Pnt& lPnt)
+{
+  Standard_Real f, l;
+  Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
+  gp_Pnt2d fPnt2d = theCurve->Value(f);
+  gp_Pnt2d lPnt2d = theCurve->Value(l);
+  gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+  fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
+  lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
+  mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
+}
+
+//=======================================================================
+//function : FillContours
+//purpose  : fills free boundary contours and faces connected (MapEF)
+//=======================================================================
+void FillContours(const TopoDS_Shape& aShape,
+                  const BRepOffset_Analyse& Analyser,
+                  TopTools_DataMapOfShapeListOfShape& Contours,
+                  TopTools_DataMapOfShapeShape& MapEF)
+{
+  TopTools_ListOfShape Edges;
+
+  TopExp_Explorer Explo(aShape, TopAbs_FACE);
+  BRepTools_WireExplorer Wexp;
+
+  for (; Explo.More(); Explo.Next())
+    {
+      TopoDS_Face aFace = TopoDS::Face(Explo.Current());
+      TopoDS_Iterator itf(aFace);
+      for (; itf.More(); itf.Next())
+        {
+          TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
+          for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
+            {
+              TopoDS_Edge anEdge = Wexp.Current();
+              if (BRep_Tool::Degenerated(anEdge))
+                continue;
+              const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
+              if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
+                {
+                  MapEF.Bind(anEdge, aFace);
+                  Edges.Append(anEdge);
+                }
+            }
+        }
+    }
+
+  TopTools_ListIteratorOfListOfShape itl;
+  while (!Edges.IsEmpty())
+    {
+      TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
+      Edges.RemoveFirst();
+      TopoDS_Vertex StartVertex, CurVertex;
+      TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
+      TopTools_ListOfShape aContour;
+      aContour.Append(StartEdge);
+      while (!CurVertex.IsSame(StartVertex))
+        for (itl.Initialize(Edges); itl.More(); itl.Next())
+          {
+            TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+            TopoDS_Vertex V1, V2;
+            TopExp::Vertices(anEdge, V1, V2);
+            if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
+              {
+                aContour.Append(anEdge);
+                CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
+                Edges.Remove(itl);
+                break;
+              }
+          }
+      Contours.Bind(StartVertex, aContour);
+    }
+}
+
+//=======================================================================
+//function : RemoveCorks
+//purpose  : 
+//=======================================================================
+void RemoveCorks (TopoDS_Shape&               S,
+                  TopTools_IndexedMapOfShape& Faces)
+{  
+  TopoDS_Compound SS;
+  BRep_Builder    B;
+  B.MakeCompound (SS);
+  //-----------------------------------------------------
+  // Construction of a shape without caps.
+  // and Orientation of caps as in shape S.
+  //-----------------------------------------------------
+  TopExp_Explorer exp(S,TopAbs_FACE);
+  for (; exp.More(); exp.Next()) {
+    const TopoDS_Shape& Cork = exp.Current(); 
+    if (!Faces.Contains(Cork)) {
+      B.Add(SS,Cork);
+    }
+    else {
+      //Faces.Remove (Cork);
+      //begin instead of Remove//
+      TopoDS_Shape LastShape = Faces(Faces.Extent());
+      Faces.RemoveLast();
+      if (Faces.FindIndex(Cork) != 0)
+        Faces.Substitute(Faces.FindIndex(Cork), LastShape);
+      //end instead of Remove  //
+      Faces.Add(Cork); // to reset it with proper orientation.
+    }
+  }
+  S = SS;
+#ifdef DRAW
+  if ( AffichOffCOld) 
+    DBRep::Set("myInit", SS);
+#endif
+
+}
+
+//=======================================================================
+//function : IsConnectedShell
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
+{  
+  BRepTools_Quilt Glue;
+  Glue.Add( S );
+
+  TopoDS_Shape SS = Glue.Shells();
+  TopExp_Explorer Explo( SS, TopAbs_SHELL );
+  Explo.Next();
+  if (Explo.More())
+    return Standard_False;
+  
+  return Standard_True;
+}
+
+//=======================================================================
+//function : MakeList
+//purpose  : 
+//=======================================================================
+void MakeList (TopTools_ListOfShape&             OffsetFaces,
+               const BRepAlgo_Image&             myInitOffsetFace,
+               const TopTools_IndexedMapOfShape& myFaces)
+{
+  TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
+  for ( ; itLOF.More(); itLOF.Next()) {
+    const TopoDS_Shape& Root = itLOF.Value();
+    if (myInitOffsetFace.HasImage(Root)) {
+      if (!myFaces.Contains(Root)) {
+        OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : EvalMax
+//purpose  : 
+//=======================================================================
+void EvalMax(const TopoDS_Shape& S, 
+             Standard_Real& Tol)
+{
+  TopExp_Explorer exp;
+  for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
+    const TopoDS_Vertex& V    = TopoDS::Vertex(exp.Current());
+    Standard_Real        TolV = BRep_Tool::Tolerance(V); 
+    if (TolV > Tol) Tol = TolV;
+  }
+  //Patch
+  Tol *= 5.;
+}
+
+//=======================================================================
+//function : TrimEdge
+//purpose  : Trim the edge of the largest of descendants in AsDes2d.
+//           Order in AsDes two vertices that have trimmed the edge.
+//=======================================================================
+void TrimEdge(TopoDS_Edge&                  NE,
+              const Handle(BRepAlgo_AsDes)& AsDes2d,
+              Handle(BRepAlgo_AsDes)& AsDes)
+{
+  Standard_Real aSameParTol = Precision::Confusion();
+  
+  TopoDS_Vertex V1,V2;
+  Standard_Real U = 0.;
+  Standard_Real UMin =  Precision::Infinite();
+  Standard_Real UMax = -UMin;
+
+  const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
+  //
+  Standard_Boolean bTrim = Standard_False;
+  //
+  if (LE.Extent() > 1) {
+    TopTools_ListIteratorOfListOfShape it (LE);
+    for (; it.More(); it.Next()) {
+      TopoDS_Vertex V = TopoDS::Vertex(it.Value());
+      if (NE.Orientation() == TopAbs_REVERSED)
+        V.Reverse();
+      //V.Orientation(TopAbs_INTERNAL);
+      if (!FindParameter(V, NE, U)) {
+        Standard_Real f, l;
+        Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
+        gp_Pnt thePoint = BRep_Tool::Pnt(V);
+        GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
+        if (Projector.NbPoints() == 0)
+          Standard_ConstructionError::Raise("BRepOffset_MakeOffsetOld::TrimEdge no projection");
+        U = Projector.LowerDistanceParameter();
+      }
+      if (U < UMin) {
+        UMin = U; V1   = V;
+      }
+      if (U > UMax) {
+        UMax = U; V2   = V;
+      }
+    }
+    //
+    if (V1.IsNull() || V2.IsNull()) {
+      Standard_ConstructionError::Raise("BRepOffset_MakeOffsetOld::TrimEdge");
+    }
+    if (!V1.IsSame(V2)) {
+      NE.Free( Standard_True );
+      BRep_Builder B;
+      TopAbs_Orientation Or = NE.Orientation();
+      NE.Orientation(TopAbs_FORWARD);
+      TopoDS_Vertex VF,VL;
+      TopExp::Vertices (NE,VF,VL);
+      B.Remove(NE,VF);
+      B.Remove(NE,VL);
+      B.Add  (NE,V1.Oriented(TopAbs_FORWARD));
+      B.Add  (NE,V2.Oriented(TopAbs_REVERSED));
+      B.Range(NE,UMin,UMax);
+      NE.Orientation(Or);
+      AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
+      AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
+      BRepLib::SameParameter(NE, aSameParTol, Standard_True);
+      //
+      bTrim = Standard_True;
+    }
+  }
+  //
+  if (!bTrim) {
+    if (!BRep_Tool::Degenerated(NE)) {
+      BRepAdaptor_Curve aBAC(NE);
+      if (!aBAC.IsClosed()) {
+        if (AsDes->HasAscendant(NE)) {
+          AsDes->Remove(NE);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : SortFaces
+//purpose  : 
+//=======================================================================
+void SortFaces(const TopTools_ListOfShape& theLIm, 
+               TopTools_ListOfShape& theLFImages,
+               const Standard_Boolean bKeepFirst)
+{
+  Standard_Integer bKeep; // 1 - keep; -1 - remove
+  Standard_Boolean bFlag;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
+  TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp;
+  TopTools_MapOfShape aMV;
+  TopTools_ListIteratorOfListOfShape aItLF;
+  TopExp_Explorer aExp;
+  //
+  aLFLeft = theLIm;
+  //
+  bKeep = bKeepFirst ? 1 : -1;
+  for (;;) {
+    aLFTmp = aLFLeft;
+    //
+    aLFLeft.Clear();
+    aLFKeep.Clear();
+    aDMELF.Clear();
+    //
+    // map list of images  edge - faces
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+    }
+    //
+    // find images that have edge attached to only one face
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      aExp.Init(aFIm, TopAbs_EDGE);
+      for (bFlag = Standard_False; aExp.More(); aExp.Next()) {
+        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+        const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
+        if (aLEF.Extent() == 1) {
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices(aE, aV1, aV2);
+          aMV.Add(aV1);
+          aMV.Add(aV2);
+          //
+          bFlag = Standard_True;
+        }
+      }
+      //
+      if (bFlag) {
+        aLFKeep.Append(aFIm);
+      }
+      else {
+        aLFLeft.Append(aFIm);
+      }
+    }
+    //
+    // map shapes left for processing
+    aDMELF.Clear();
+    aLFTmp = aLFLeft;
+    aLFLeft.Clear();
+    //
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+    }
+    //
+    // find outer edges and check if they touch the first part of edges
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      aExp.Init(aFIm, TopAbs_EDGE);
+      for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) {
+        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+        const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
+        if (aLEF.Extent() == 1) {
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices(aE, aV1, aV2);
+          //
+          bFlag = aMV.Contains(aV1) || aMV.Contains(aV2);
+        }
+      }
+      //
+      if (bFlag) {
+        aLFKeep.Append(aFIm);
+      }
+      else {
+        aLFLeft.Append(aFIm);
+      }
+    }
+    //
+    if (bKeep == 1) {
+      // aLFKeep should be kept
+      // aLFLeft left for further processing
+      aItLF.Initialize(aLFKeep);
+      for (; aItLF.More(); aItLF.Next()) {
+        const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+        theLFImages.Append(aFIm);
+      }
+    }
+    //
+    if (aLFLeft.IsEmpty()) {
+      break;
+    }
+    //
+    bKeep *= -1;
+  }
+}
+
+//=======================================================================
+//function : FindShape
+//purpose  : 
+//=======================================================================
+Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
+                           const TopoDS_Shape& theSWhere,
+                           TopoDS_Shape& theRes)
+{
+  Standard_Boolean bFound = Standard_False;
+  TopAbs_ShapeEnum aType = theSWhat.ShapeType();
+  TopExp_Explorer aExp(theSWhere, aType);
+  for (; aExp.More(); aExp.Next()) {
+    const TopoDS_Shape& aS = aExp.Current();
+    if (aS.IsSame(theSWhat)) {
+      theRes = aS;
+      bFound = Standard_True;
+      break;
+    }
+  }
+  return bFound;
+}
+
+//=======================================================================
+//function : UpdateOrigins
+//purpose  : 
+//=======================================================================
+void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                   BOPAlgo_Builder& theGF)
+{
+  TopTools_ListOfShape aLSTmp;
+  TopTools_MapOfShape aMFence;
+  BOPCol_ListIteratorOfListOfShape aItA;
+  TopTools_ListIteratorOfListOfShape aIt, aIt1;
+  //
+  const BOPCol_ListOfShape& aLSU = theGF.Arguments();
+  aItA.Initialize(aLSU);
+  for (; aItA.More(); aItA.Next()) {
+    const TopoDS_Shape& aS = aItA.Value();
+    //
+    if (!theOrigins.Contains(aS)) {
+      continue;
+    }
+    //
+    const TopTools_ListOfShape& aLSIm = theGF.Modified(aS);
+    if (aLSIm.IsEmpty()) {
+      continue;
+    }
+    //
+    const TopTools_ListOfShape& aLS = theOrigins.FindFromKey(aS);
+    //      
+    aIt.Initialize(aLSIm);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aSIm = aIt.Value();
+      //
+      if (!theOrigins.Contains(aSIm)) {
+        theOrigins.Add(aSIm, aLS);
+        continue;
+      }
+      //
+      aMFence.Clear();
+      //
+      TopTools_ListOfShape& aLS1 = theOrigins.ChangeFromKey(aSIm);
+      aLSTmp.Assign(aLS1);
+      //
+      aLS1.Clear();
+      aIt1.Initialize(aLSTmp);
+      for (; aIt1.More(); aIt1.Next()) {
+        const TopoDS_Shape& aS1 = aIt1.Value();
+        if (aMFence.Add(aS1)) {
+          aLS1.Append(aS1);
+        }
+      }
+      //
+      aIt1.Initialize(aLS);
+      for (; aIt1.More(); aIt1.Next()) {
+        const TopoDS_Shape& aS1 = aIt1.Value();
+        if (aMFence.Add(aS1)) {
+          aLS1.Append(aS1);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : IsMicroEdge
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge,
+                             const Handle(IntTools_Context)& theCtx)
+{
+  TopoDS_Vertex aV1, aV2;
+  TopExp::Vertices(theEdge, aV1, aV2);
+  Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull();
+  if (bNull) {
+    return Standard_False;
+  }
+  //
+  Standard_Boolean bMicro;
+  Standard_Real aT1, aT2;
+  IntTools_ShrunkRange aSR;
+  //
+  BRepAdaptor_Curve aBAC(theEdge);
+  //
+  aT1 = BRep_Tool::Parameter(aV1, theEdge);
+  aT2 = BRep_Tool::Parameter(aV2, theEdge);
+  if (aT2 < aT1) {
+    Standard_Real aTmp = aT1;
+    aT1 = aT2;
+    aT2 = aTmp;
+  }
+  //
+  aSR.SetContext(theCtx);
+  aSR.SetData(theEdge, aT1, aT2, aV1, aV2);
+  aSR.Perform();
+  bMicro = (aSR.ErrorStatus() != 0);
+  if (!bMicro) {
+    Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2;
+    //
+    aTolV1 = BRep_Tool::Tolerance(aV1);
+    aTolV2 = BRep_Tool::Tolerance(aV2);
+    //
+    anEps = aBAC.Resolution(aTolV1 + aTolV2);
+    if (anEps < 1.e-8) {
+      anEps = 1.e-8;
+    }
+    //
+    aSR.ShrunkRange(aTS1, aTS2);
+    bMicro = (aTS2 - aTS1) <= anEps;
+  }
+  //
+  if (bMicro) {
+    if (aBAC.GetType() == GeomAbs_Line) {
+      BRep_Builder aBB;
+      Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC);
+      //
+      aBB.UpdateVertex(aV1, aLen/2.);
+      aBB.UpdateVertex(aV2, aLen/2.);
+    }
+  }
+  //
+  return bMicro;
+}
+
+//=======================================================================
+//function : ComputeBiNormal
+//purpose  : 
+//=======================================================================
+Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF,
+                                 const TopoDS_Edge& theE,
+                                 gp_Dir& theDB)
+{
+  Standard_Boolean bDone = Standard_False;
+  Standard_Real aT1, aT2, aTm;
+  //
+  const Handle(Geom2d_Curve)& aC2d = 
+    BRep_Tool::CurveOnSurface(theE, theF, aT1, aT2);
+  if (aC2d.IsNull()) {
+    return bDone;
+  }
+  //
+  gp_Pnt2d aP2dNear;
+  gp_Pnt aP, aPNear;
+  //
+  const Handle(Geom_Curve)& aC3d = 
+    BRep_Tool::Curve(theE, aT1, aT2);
+  //
+  aTm = (aT1 + aT2) * 0.5;
+  aP = aC3d->Value(aTm);
+  //
+  BOPTools_AlgoTools3D::PointNearEdge(theE, theF, aTm, 1.e-5, aP2dNear, aPNear);
+  //
+  gp_Vec aVB(aP, aPNear);
+  theDB = gp_Dir(aVB);
+  return !bDone;
+}
+
+//=======================================================================
+//function : CheckBiNormals
+//purpose  : 
+//=======================================================================
+Standard_Boolean CheckBiNormals
+  (const TopoDS_Face& aFIm,
+   const TopoDS_Face& aFOr,
+   const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+   const TopTools_MapOfShape& theMFence,
+   Standard_Boolean& bKeep,
+   Standard_Boolean& bRemove,
+   const Standard_Boolean RemoveInvalidFaces)
+{
+  Standard_Boolean bChecked;
+  Standard_Integer aNbEdgesChecked;
+  Standard_Real anAngle;
+  TopTools_IndexedMapOfShape aMEInv;
+  //
+  aNbEdgesChecked = 0;
+  //
+  const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
+  TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
+  for (; aExp.More(); aExp.Next()) {
+    const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
+    //
+    if (BRep_Tool::Degenerated(aEIm)) {
+      continue;
+    }
+    //
+    if (!theOrigins.Contains(aEIm)) {
+      continue;
+    }
+    //
+    const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
+    const TopoDS_Shape& aSOr = aLEOr.First();
+    if (aSOr.ShapeType() != TopAbs_EDGE) {
+      continue;
+    }
+    //
+    if (aLEOr.Extent() > 1) {
+      TopTools_MapOfShape aME, aMV;
+      Standard_Integer aNbE, aNbV;
+      //
+      TopTools_ListIteratorOfListOfShape aItLS(aLEOr);
+      for (; aItLS.More(); aItLS.Next()) {
+        const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS.Value();
+        aME.Add(aEOr);
+        //
+        TopExp_Explorer aExpE(aEOr, TopAbs_VERTEX);
+        for (; aExpE.More(); aExpE.Next()) {
+          const TopoDS_Shape& aV = aExpE.Current();
+          aMV.Add(aV);
+        }
+      }
+      //
+      aNbV = aMV.Extent();
+      aNbE = aME.Extent();
+      //
+      if ((aNbE > 1) && (aNbV == 2*aNbE)) {
+        continue;
+      }
+    }
+    //
+    if (!RemoveInvalidFaces) {
+      if (theMFence.Contains(aEIm)) {
+        bChecked = Standard_True;
+        bKeep = Standard_True;
+        bRemove = Standard_False;
+        return bChecked;
+      }
+    }
+    //
+    const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aLEOr.First();
+    //
+    TopoDS_Edge aEOrF;
+    if (!FindShape(aEOr, aFOr, aEOrF)) {
+      continue;
+    }
+    //
+    // compute bi-normal for face aFIm on the edge aEIm
+    gp_Dir aDB1;
+    if (!ComputeBiNormal(aFIm, aEIm, aDB1)) {
+      continue;
+    }
+    //
+    // compute bi-normal for face aFOr on the edge aEOrF
+    gp_Dir aDB2;
+    if (!ComputeBiNormal(aFOr, aEOrF, aDB2)) {
+      continue;
+    }
+    //
+    ++aNbEdgesChecked;
+    //
+    anAngle = aDB1.Angle(aDB2);
+    if (Abs(anAngle - M_PI) < 1.e-4) {
+      aMEInv.Add(aEIm);
+    }
+  }
+  //
+  bChecked = (aNbEdgesChecked > 0);
+  if (!bChecked) {
+    return bChecked;
+  }
+  //
+  // decide whether to remove the split face or not
+  bKeep = Standard_True;
+  bRemove = Standard_False;
+  //
+  Standard_Integer  aNb = aMEInv.Extent();
+  if (aNb == 0) {
+    return bChecked;
+  }
+  //
+  if (aNb == aNbEdgesChecked) {
+    bKeep = Standard_False;
+    bRemove = Standard_True;
+  }
+  //
+  if (!bRemove) {
+    for (Standard_Integer i = 1; i <= aNb; ++i) {
+      const TopoDS_Shape& aE = aMEInv(i);
+      if (theMFence.Contains(aE)) {
+        bKeep = Standard_False;
+        bRemove = Standard_True;
+        break;
+      }
+    }
+  }
+  //
+  return bChecked;
+}
+
+//=======================================================================
+//function : CheckBiNormals
+//purpose  : 
+//=======================================================================
+void CheckBiNormals
+  (TopTools_ListOfShape&  theLFImages,
+   const TopoDS_Face& theF,
+   const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+   TopTools_ListOfShape& theLFKeep,
+   const Standard_Boolean RemoveInvalidFaces)
+{
+  Standard_Boolean bChecked, bKeep, bRem;
+  Standard_Integer i, aNb;
+  TopTools_ListOfShape aLFKeep;
+  TopTools_MapOfShape aMEToKeep;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
+  TopTools_ListIteratorOfListOfShape aItLF;
+  //
+  // collect outer edges
+  aItLF.Initialize(theLFImages);
+  for (; aItLF.More(); aItLF.Next()) {
+    const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+    TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+  }
+  //
+  aNb = aDMELF.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopTools_ListOfShape& aLF = aDMELF(i);
+    if (aLF.Extent() == 1) {
+      const TopoDS_Shape& aE = aDMELF.FindKey(i);
+      aMEToKeep.Add(aE);
+    }
+  }
+  //
+  const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(theF).First();
+  //
+  aItLF.Initialize(theLFImages);
+  for (; aItLF.More(); ) {
+    const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+    //
+    bChecked = CheckBiNormals(aFIm, aFOr, theOrigins, aMEToKeep, bKeep, bRem, RemoveInvalidFaces);
+    //
+    if (bChecked) {
+      if (bRem) {
+        theLFImages.Remove(aItLF);
+      }
+      else {
+        if (bKeep) {
+          theLFKeep.Append(aFIm);
+        }
+        aItLF.Next();
+      }
+    }
+    else {
+      aItLF.Next();
+    }
+  }
+}
+
+//=======================================================================
+//function : CheckNormals
+//purpose  : 
+//=======================================================================
+Standard_Boolean CheckNormals(const TopoDS_Face& theFIm,
+                              const TopoDS_Face& theFOr)
+{
+  
+  Standard_Real aUMin, aUMax, aVMin, aVMax, aU, aV, anAngle;
+  gp_Pnt aP;
+  gp_Vec aVecU, aVecV, aVNIm, aVNOr;
+  Standard_Boolean bIsCollinear;
+  //
+  BRepAdaptor_Surface aSFIm(theFIm), aSFOr(theFOr);
+  //
+  aUMin = aSFIm.FirstUParameter();
+  aUMax = aSFIm.LastUParameter();
+  aVMin = aSFIm.FirstVParameter();
+  aVMax = aSFIm.LastVParameter();
+  //
+  aU = (aUMin + aUMax) * 0.5;
+  if (Precision::IsInfinite(aUMin) && 
+      Precision::IsInfinite(aUMax)) {
+    aU = 0.;
+  }
+  else if (Precision::IsInfinite(aUMin) && 
+           !Precision::IsInfinite(aUMax)) {
+    aU = aUMax;
+  }
+  else if (!Precision::IsInfinite(aUMin) && 
+           Precision::IsInfinite(aUMax)) {
+    aU = aUMin;
+  }
+  //
+  aV = (aVMin + aVMax) * 0.5;
+  if (Precision::IsInfinite(aVMin) && 
+      Precision::IsInfinite(aVMax)) {
+    aV = 0.;
+  }
+  else if (Precision::IsInfinite(aVMin) && 
+           !Precision::IsInfinite(aVMax)) {
+    aV = aVMax;
+  }
+  else if (!Precision::IsInfinite(aVMin) && 
+           Precision::IsInfinite(aVMax)) {
+    aV = aVMin;
+  }
+  //
+  aSFIm.D1(aU, aV, aP, aVecU, aVecV);
+  aVNIm = aVecU.Crossed(aVecV);
+  if (theFIm.Orientation() == TopAbs_REVERSED) {
+    aVNIm.Reverse();
+  }
+  //
+  aSFOr.D1(aU, aV, aP, aVecU, aVecV);
+  aVNOr = aVecU.Crossed(aVecV);
+  if (theFOr.Orientation() == TopAbs_REVERSED) {
+    aVNOr.Reverse();
+  }
+  //
+  anAngle = aVNIm.Angle(aVNOr);
+  bIsCollinear = (anAngle < Precision::Confusion());
+  return bIsCollinear;
+}
+
+//=======================================================================
+//function : UpdateInitOffset
+//purpose  : Update and cleaning of myInitOffset 
+//=======================================================================
+void UpdateInitOffset(BRepAlgo_Image&         myInitOffset,
+                      BRepAlgo_Image&         myImageOffset,
+                      const TopoDS_Shape&     myOffsetShape,
+                      const TopAbs_ShapeEnum &theShapeType) // skv
+{
+  BRepAlgo_Image NIOF;
+  const TopTools_ListOfShape& Roots = myInitOffset.Roots();
+  TopTools_ListIteratorOfListOfShape it(Roots);
+  for (; it.More(); it.Next()) {
+    NIOF.SetRoot (it.Value());    
+  }
+  for (it.Initialize(Roots); it.More(); it.Next()) {
+    const TopoDS_Shape& SI = it.Value();
+    TopTools_ListOfShape LI;
+    TopTools_ListOfShape L1;
+    myInitOffset.LastImage(SI,L1);
+    TopTools_ListIteratorOfListOfShape itL1(L1);
+    for (; itL1.More(); itL1.Next()) {
+      const TopoDS_Shape& O1 = itL1.Value();
+      TopTools_ListOfShape L2;
+      myImageOffset.LastImage(O1,L2);
+      LI.Append(L2);
+    }
+    NIOF.Bind(SI,LI);
+  }
+//  Modified by skv - Mon Apr  4 18:17:27 2005 Begin
+//  Supporting history.
+//   NIOF.Filter(myOffsetShape,TopAbs_FACE);
+  NIOF.Filter(myOffsetShape, theShapeType);
+//  Modified by skv - Mon Apr  4 18:17:27 2005 End
+  myInitOffset = NIOF;
+}
+//=======================================================================
+//function : IsPlanar
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsPlanar(const TopoDS_Shape& theS)
+{
+  TopExp_Explorer aExp(theS, TopAbs_FACE);
+  for (; aExp.More(); aExp.Next()) {
+    const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
+    BRepAdaptor_Surface aBAS(aF, Standard_False);
+    if (aBAS.GetType() != GeomAbs_Plane) {
+      break;
+    }
+  }
+  return !aExp.More();
+}
\ No newline at end of file
index 0278b40cb181734d194ed89cfff0e79726ecfb53..fbab3f47a019c45bdacb8473bfd761bc461fea8e 100644 (file)
@@ -50,6 +50,8 @@
 #include <BRepFeat_MakeDPrism.hxx>
 #include <BRepFeat_MakeLinearForm.hxx>
 #include <BRepFeat_MakeRevolutionForm.hxx>
+#include <BRepOffset_MakeOffset.hxx>
+#include <BRepOffset_MakeOffsetOld.hxx>
 
 #include <LocOpe_FindEdges.hxx>
 #include <LocOpe_FindEdgesInFace.hxx>
@@ -902,6 +904,7 @@ Standard_Integer offsetshape(Draw_Interpretor& ,
 }
 
 static BRepOffset_MakeOffset TheOffset;
+static BRepOffset_MakeOffsetOld TheOffsetOld;
 static Standard_Real         TheRadius;
 static Standard_Boolean      theYaBouchon;
 static Standard_Real         TheTolerance = Precision::Confusion();
@@ -909,12 +912,13 @@ static Standard_Boolean      TheInter     = Standard_False;
 static GeomAbs_JoinType      TheJoin      = GeomAbs_Arc;
 static Standard_Boolean      RemoveIntEdges = Standard_False;
 static Standard_Boolean      RemoveInvalidFaces = Standard_False;
+static Standard_Boolean      UseNewOffsetAPI = Standard_False;
 
 Standard_Integer offsetparameter(Draw_Interpretor& di,
                                  Standard_Integer n, const char** a)
 {
   if ( n == 1 ) { 
-    di << " OffsetParameter Tol Inter(c/p) JoinType(a/i/t) [RemoveInternalEdges(r/k) RemoveInvalidFaces(r/k)] " << "\n";
+    di << " OffsetParameter Tol Inter(c/p) JoinType(a/i/t) [RemoveInternalEdges(r/k) RemoveInvalidFaces(r/k) UseNewOffsetAPI(n/o)] " << "\n";
     di << " Current Values" << "\n";
     di << "   --> Tolerance : " << TheTolerance << "\n";
     di << "   --> TheInter  : ";
@@ -947,6 +951,13 @@ Standard_Integer offsetparameter(Draw_Interpretor& di,
     else {
       di << "Keep";
     }
+    di << "\n" << "   --> Version of the Offset API : ";
+    if (UseNewOffsetAPI) {
+      di << "New";
+    }
+    else {
+      di << "Old";
+    }
     di << "\n";
     //
     return 0;
@@ -962,7 +973,8 @@ Standard_Integer offsetparameter(Draw_Interpretor& di,
   else if ( !strcmp(a[3],"t")) TheJoin = GeomAbs_Tangent;
   //
   RemoveIntEdges = (n >= 5) ? !strcmp(a[4], "r") : Standard_False;
-  RemoveInvalidFaces = (n == 6) ? !strcmp(a[5], "r") : Standard_False;
+  RemoveInvalidFaces = (n >= 6) ? !strcmp(a[5], "r") : Standard_False;
+  UseNewOffsetAPI = (n == 7) ? !strcmp(a[6], "n") : Standard_False;
   //
   return 0;
 }
@@ -983,16 +995,26 @@ Standard_Integer offsetload(Draw_Interpretor& ,
   Standard_Real    Of    = Draw::Atof(a[2]);
   TheRadius = Of;
 //  Standard_Boolean Inter = Standard_True;
-  
-  TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin,
-                       Standard_False, RemoveIntEdges, RemoveInvalidFaces);
+  if (UseNewOffsetAPI) {
+    TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin,
+                         Standard_False, RemoveIntEdges, RemoveInvalidFaces);
+  }
+  else {
+    TheOffsetOld.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin,
+                            Standard_False, RemoveIntEdges, RemoveInvalidFaces);
+  }
   //------------------------------------------
   // recuperation et chargement des bouchons.
   //----------------------------------------
   for (Standard_Integer i = 3 ; i < n; i++) {
     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
     if (!SF.IsNull()) {
-      TheOffset.AddFace(TopoDS::Face(SF));
+      if (UseNewOffsetAPI) {
+        TheOffset.AddFace(TopoDS::Face(SF));
+      }
+      else {
+        TheOffsetOld.AddFace(TopoDS::Face(SF));
+      }
     }
   }
   if (n < 4)  theYaBouchon = Standard_False; //B.MakeOffsetShape();
@@ -1015,7 +1037,12 @@ Standard_Integer offsetonface(Draw_Interpretor&, Standard_Integer n, const char*
     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
     if (!SF.IsNull()) {
       Standard_Real Of = Draw::Atof(a[i+1]);
-      TheOffset.SetOffsetOnFace(TopoDS::Face(SF),Of);
+      if (UseNewOffsetAPI) {
+        TheOffset.SetOffsetOnFace(TopoDS::Face(SF),Of);
+      }
+      else {
+        TheOffsetOld.SetOffsetOnFace(TopoDS::Face(SF),Of);
+      }
     }
   }
   
@@ -1032,20 +1059,34 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands,
   {
   if ( theNArg < 2) return 1;
 
-  if (theYaBouchon)
-    TheOffset.MakeThickSolid ();
-  else
-    TheOffset.MakeOffsetShape();
+  if (UseNewOffsetAPI) {
+    if (theYaBouchon)
+      TheOffset.MakeThickSolid ();
+    else
+      TheOffset.MakeOffsetShape();
 
-  if(TheOffset.IsDone())
-    {
-    DBRep::Set(a[1],TheOffset.Shape());
+    if(TheOffset.IsDone()) {
+      DBRep::Set(a[1],TheOffset.Shape());
     }
-  else
-    {
-    theCommands << "ERROR. offsetperform operation not done.";
-    return 1;
+    else {
+      theCommands << "ERROR. offsetperform operation not done.";
+      return 1;
     }
+  }
+  else {
+    if (theYaBouchon)
+      TheOffsetOld.MakeThickSolid ();
+    else
+      TheOffsetOld.MakeOffsetShape();
+
+    if(TheOffsetOld.IsDone()) {
+      DBRep::Set(a[1],TheOffsetOld.Shape());
+    }
+    else {
+      theCommands << "ERROR. offsetperform operation not done.";
+      return 1;
+    }
+  }
 
   return 0;
   }