Index: src/BRepAlgo/BRepAlgo_Loop.cxx
===================================================================
--- src/BRepAlgo/BRepAlgo_Loop.cxx	(revision 1)
+++ src/BRepAlgo/BRepAlgo_Loop.cxx	(working copy)
@@ -23,8 +23,10 @@
 #include <BRepAlgo_Loop.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Surface.hxx>
+#include <GeomLib.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Pnt2d.hxx>
+#include <gp_Ax2.hxx>
 #include <Precision.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
@@ -160,7 +162,16 @@
   }
 }
 
+//=======================================================================
+//function : SetImageVV
+//purpose  : 
+//=======================================================================
 
+void BRepAlgo_Loop::SetImageVV (const BRepAlgo_Image& theImageVV)
+{
+  myImageVV = theImageVV;
+}
+
 //=======================================================================
 //function : UpdateClosedEdge
 //purpose  : If the first or the last vertex of intersection
@@ -606,6 +617,8 @@
   TopoDS_Wire      NW;
   Standard_Boolean End;
 
+  UpdateVEmap (MVE);
+
   TopTools_MapOfShape UsedEdges;
 
   while (MVE.Extent() > 0) {
@@ -924,6 +937,7 @@
 {
   VerVerMap = myVerticesForSubstitute;
 }
+
 //=======================================================================
 //function : VerticesForSubstitute
 //purpose  : 
@@ -933,3 +947,123 @@
 {
   myVerticesForSubstitute = VerVerMap;
 }
+
+//=======================================================================
+//function : UpdateVEmap
+//purpose  : 
+//=======================================================================
+
+void  BRepAlgo_Loop::UpdateVEmap (TopTools_IndexedDataMapOfShapeListOfShape& theVEmap)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape VerLver;
+
+  for (Standard_Integer ii = 1; ii <= theVEmap.Extent(); ii++)
+  {
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex (theVEmap.FindKey(ii));
+    const TopTools_ListOfShape& aElist = theVEmap(ii);
+    if (aElist.Extent() == 1 && myImageVV.IsImage(aVertex))
+    {
+      const TopoDS_Vertex& aProVertex = TopoDS::Vertex (myImageVV.ImageFrom(aVertex));
+      if (VerLver.Contains(aProVertex))
+      {
+        TopTools_ListOfShape& aVlist = VerLver.ChangeFromKey(aProVertex);
+        aVlist.Append (aVertex.Oriented(TopAbs_FORWARD));
+      }
+      else
+      {
+        TopTools_ListOfShape aVlist;
+        aVlist.Append (aVertex.Oriented(TopAbs_FORWARD));
+        VerLver.Add (aProVertex,  aVlist);
+      }
+    }
+  }
+
+  if (VerLver.IsEmpty())
+    return;
+
+  BRep_Builder aBB;
+  for (Standard_Integer ii = 1; ii <= VerLver.Extent(); ii++)
+  {
+    const TopTools_ListOfShape& aVlist = VerLver(ii);
+    if (aVlist.Extent() == 1)
+      continue;
+    
+    Standard_Real aMaxTol = 0.;
+    TColgp_Array1OfPnt Points (1, aVlist.Extent());
+
+    TopTools_ListIteratorOfListOfShape itl (aVlist);
+    Standard_Integer jj = 0;
+    for (; itl.More(); itl.Next())
+    {
+      const TopoDS_Vertex& aVertex = TopoDS::Vertex (itl.Value());
+      Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
+      aMaxTol = Max (aMaxTol, aTol);
+      gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
+      Points(++jj) = aPnt;
+    }
+
+    gp_Ax2 anAxis;
+    Standard_Boolean IsSingular;
+    GeomLib::AxeOfInertia (Points, anAxis, IsSingular);
+    gp_Pnt aCentre = anAxis.Location();
+    Standard_Real aMaxDist = 0.;
+    for (jj = 1; jj <= Points.Upper(); jj++)
+    {
+      Standard_Real aSqDist = aCentre.SquareDistance (Points(jj));
+      aMaxDist = Max (aMaxDist, aSqDist);
+    }
+    aMaxDist = Sqrt(aMaxDist);
+    aMaxTol = Max (aMaxTol, aMaxDist);
+
+    //Find constant vertex
+    TopoDS_Vertex aConstVertex;
+    for (itl.Initialize(aVlist); itl.More(); itl.Next())
+    {
+      const TopoDS_Vertex& aVertex = TopoDS::Vertex (itl.Value());
+      const TopTools_ListOfShape& aElist = theVEmap.FindFromKey(aVertex);
+      const TopoDS_Shape& anEdge = aElist.First();
+      TopTools_ListIteratorOfListOfShape itcedges (myConstEdges);
+      for (; itcedges.More(); itcedges.Next())
+        if (anEdge.IsSame (itcedges.Value()))
+        {
+          aConstVertex = aVertex;
+          break;
+        }
+      if (!aConstVertex.IsNull())
+        break;
+    }
+    if (aConstVertex.IsNull())
+      aConstVertex = TopoDS::Vertex(aVlist.First());
+    aBB.UpdateVertex (aConstVertex, aCentre, aMaxTol);
+
+    for (itl.Initialize(aVlist); itl.More(); itl.Next())
+    {
+      const TopoDS_Vertex& aVertex = TopoDS::Vertex (itl.Value());
+      if (aVertex.IsSame(aConstVertex))
+        continue;
+      
+      const TopTools_ListOfShape& aElist = theVEmap.FindFromKey (aVertex);
+      TopoDS_Edge anEdge = TopoDS::Edge (aElist.First());
+      anEdge.Orientation(TopAbs_FORWARD);
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices (anEdge, aV1, aV2);
+      TopoDS_Vertex aVertexToRemove = (aV1.IsSame(aVertex))? aV1 : aV2;
+      anEdge.Free(Standard_True);
+      aBB.Remove (anEdge, aVertexToRemove);
+      aBB.Add (anEdge, aConstVertex.Oriented (aVertexToRemove.Orientation()));
+    }
+  }
+
+  TopTools_IndexedMapOfShape Emap;
+  for (Standard_Integer ii = 1; ii <= theVEmap.Extent(); ii++)
+  {
+    const TopTools_ListOfShape& aElist = theVEmap(ii);
+    TopTools_ListIteratorOfListOfShape itl (aElist);
+    for (; itl.More(); itl.Next())
+      Emap.Add (itl.Value());
+  }
+
+  theVEmap.Clear();
+  for (Standard_Integer ii = 1; ii <= Emap.Extent(); ii++)
+    TopExp::MapShapesAndAncestors (Emap(ii), TopAbs_VERTEX, TopAbs_EDGE, theVEmap);
+}
Index: src/BRepAlgo/BRepAlgo_Loop.hxx
===================================================================
--- src/BRepAlgo/BRepAlgo_Loop.hxx	(revision 1)
+++ src/BRepAlgo/BRepAlgo_Loop.hxx	(working copy)
@@ -25,6 +25,8 @@
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <BRepAlgo_Image.hxx>
 class TopoDS_Face;
 class TopoDS_Edge;
 
@@ -53,9 +55,15 @@
   //! Add <LE> as a set of const edges.
   Standard_EXPORT void AddConstEdges (const TopTools_ListOfShape& LE);
   
+  //! Sets the Image Vertex - Vertex
+  Standard_EXPORT void SetImageVV (const BRepAlgo_Image& theImageVV);
+  
   //! Make loops.
   Standard_EXPORT void Perform();
   
+  //! Update VE map according to Image Vertex - Vertex
+  Standard_EXPORT void UpdateVEmap (TopTools_IndexedDataMapOfShapeListOfShape& theVEmap);
+  
   //! Cut the  edge <E>  in  several edges  <NE> on the
   //! vertices<VonE>.
   Standard_EXPORT void CutEdge (const TopoDS_Edge& E, const TopTools_ListOfShape& VonE, TopTools_ListOfShape& NE) const;
@@ -102,6 +110,7 @@
   TopTools_ListOfShape myNewFaces;
   TopTools_DataMapOfShapeListOfShape myCutEdges;
   TopTools_DataMapOfShapeShape myVerticesForSubstitute;
+  BRepAlgo_Image myImageVV;
 
 
 };
Index: src/BRepOffset/BRepOffset_Inter2d.cxx
===================================================================
--- src/BRepOffset/BRepOffset_Inter2d.cxx	(revision 1)
+++ src/BRepOffset/BRepOffset_Inter2d.cxx	(working copy)
@@ -32,6 +32,7 @@
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepAlgo_AsDes.hxx>
+#include <BRepAlgo_Image.hxx>
 #include <BRepLib.hxx>
 #include <BRepLib_MakeVertex.hxx>
 #include <BRepOffset_Analyse.hxx>
@@ -78,6 +79,7 @@
 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 
 #include <stdio.h>
 #ifdef DRAW 
@@ -113,28 +115,154 @@
   return V;
 }
 
-static Standard_Boolean IsOrientationChanged(TopTools_IndexedMapOfShape& theMap,
-                                             const TopoDS_Edge& theEdge)
+static Standard_Integer DefineClosedness(const TopoDS_Face& theFace)
 {
-  Standard_Boolean IsOrChanged = Standard_False;
-  
-  if (!theMap.Contains(theEdge))
-    theMap.Add(theEdge);
-  else
+  TopExp_Explorer anExplo (theFace, TopAbs_EDGE);
+  for (; anExplo.More(); anExplo.Next())
   {
-    Standard_Integer anInd = theMap.FindIndex(theEdge);
-    const TopoDS_Shape& anEdge = theMap(anInd);
-    if (theEdge.Orientation() != anEdge.Orientation())
+    const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+    if (BRepTools::IsReallyClosed(anEdge, theFace))
     {
-      theMap.Substitute( anInd, theEdge );
-      IsOrChanged = Standard_True;
+      Standard_Real fpar, lpar;
+      Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
+      gp_Vec2d aTangent = aPCurve->DN(fpar, 1);
+      Standard_Real aCrossProd1 = aTangent ^ gp::DX2d();
+      Standard_Real aCrossProd2 = aTangent ^ gp::DY2d();
+      if (Abs(aCrossProd2) < Abs(aCrossProd1)) //pcurve is parallel to OY
+        return 1;
+      else
+        return 2;
     }
   }
 
-  return IsOrChanged;
+  return 0;
 }
 
+static void GetEdgesOrientedInFace(const TopoDS_Shape& theShape,
+                                   const TopoDS_Face&  theFace,
+                                   const Handle(BRepAlgo_AsDes)& theAsDes,
+                                   TopTools_SequenceOfShape&     theSeqEdges)
+{
+  const TopTools_ListOfShape& aEdges = theAsDes->Descendant (theFace);
 
+  TopExp_Explorer anExplo (theShape, TopAbs_EDGE);
+  for (; anExplo.More(); anExplo.Next())
+  {
+    const TopoDS_Shape& anEdge = anExplo.Current();
+    TopTools_ListIteratorOfListOfShape itl (aEdges);
+    for (; itl.More(); itl.Next())
+    {
+      const TopoDS_Shape& anEdgeInFace = itl.Value();
+      if (anEdgeInFace.IsSame(anEdge))
+      {
+        theSeqEdges.Append (anEdgeInFace);
+        break;
+      }
+    }
+  }
+
+  if (theSeqEdges.Length() == 1)
+    return;
+
+  TopTools_IndexedDataMapOfShapeListOfShape aVEmap;
+  for (Standard_Integer ii = 1; ii <= theSeqEdges.Length(); ii++)
+    TopExp::MapShapesAndAncestors (theSeqEdges(ii), TopAbs_VERTEX, TopAbs_EDGE, aVEmap);
+
+  TopoDS_Vertex aFirstVertex;
+  TopoDS_Edge aFirstEdge;
+  for (Standard_Integer ii = 1; ii <= aVEmap.Extent(); ii++)
+  {
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVEmap.FindKey(ii));
+    const TopTools_ListOfShape& aElist = aVEmap(ii);
+    if (aElist.Extent() == 1)
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(aElist.First());
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices(anEdge, aV1, aV2, Standard_True); //with orientation
+      if (aV1.IsSame(aVertex))
+      {
+        aFirstVertex = aVertex;
+        aFirstEdge = anEdge;
+        break;
+      }
+    }
+  }
+
+  if (aFirstEdge.IsNull()) //closed set of edges
+  {
+    //Standard_Real aPeriod = 0.;
+    Standard_Integer IndCoord = DefineClosedness (theFace);
+    /*
+    BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
+    if (IndCoord == 1)
+      aPeriod = aBAsurf.LastUParameter() - aBAsurf.FirstUParameter();
+    else if (IndCoord == 2)
+      aPeriod = aBAsurf.LastVParameter() - aBAsurf.FirstVParameter();
+    */
+    
+    if (IndCoord != 0)
+    {
+      Standard_Real aMaxDelta = 0.;
+      for (Standard_Integer ii = 1; ii <= aVEmap.Extent(); ii++)
+      {
+        const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVEmap.FindKey(ii));
+        const TopTools_ListOfShape& aElist = aVEmap(ii);
+        const TopoDS_Edge& anEdge1 = TopoDS::Edge(aElist.First());
+        const TopoDS_Edge& anEdge2 = TopoDS::Edge(aElist.Last());
+        Standard_Real aParam1 = BRep_Tool::Parameter(aVertex, anEdge1);
+        Standard_Real aParam2 = BRep_Tool::Parameter(aVertex, anEdge2);
+        BRepAdaptor_Curve2d aBAcurve1 (anEdge1, theFace);
+        BRepAdaptor_Curve2d aBAcurve2 (anEdge2, theFace);
+        gp_Pnt2d aPnt1 = aBAcurve1.Value(aParam1);
+        gp_Pnt2d aPnt2 = aBAcurve2.Value(aParam2);
+        Standard_Real aDelta = Abs(aPnt1.Coord(IndCoord) - aPnt2.Coord(IndCoord));
+        if (aDelta > aMaxDelta)
+        {
+          aMaxDelta = aDelta;
+          aFirstVertex = aVertex;
+        }
+      }
+      const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aFirstVertex);
+      TopTools_ListIteratorOfListOfShape itl (aElist);
+      for (; itl.More(); itl.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+        TopoDS_Vertex aV1, aV2;
+        TopExp::Vertices(anEdge, aV1, aV2, Standard_True); //with orientation
+        if (aV1.IsSame(aFirstVertex))
+        {
+          aFirstEdge = anEdge;
+          break;
+        }
+      }
+    }
+  }
+
+  Standard_Integer aNbEdges = theSeqEdges.Length();
+  theSeqEdges.Clear();
+  theSeqEdges.Append (aFirstEdge);
+  TopoDS_Edge anEdge = aFirstEdge;
+  for (;;)
+  {
+    TopoDS_Vertex aLastVertex = TopExp::LastVertex (anEdge, Standard_True); //with orientation
+    if (aLastVertex.IsSame(aFirstVertex))
+      break;
+    
+    const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aLastVertex);
+    if (aElist.Extent() == 1)
+      break;
+    
+    if (aElist.First().IsSame(anEdge))
+      anEdge = TopoDS::Edge(aElist.Last());
+    else
+      anEdge = TopoDS::Edge(aElist.First());
+
+    theSeqEdges.Append (anEdge);
+    if (theSeqEdges.Length() == aNbEdges)
+      break;
+  }
+}
+
 //=======================================================================
 //function : Store
 //purpose  : Store the vertices <theLV> into AsDes for the edge <theEdge>.
@@ -505,7 +633,7 @@
     // Vertex storage in DS.
     //---------------------------------
     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
-    TolStore = Max(TolStore, 10.*Tol);
+    TolStore = Max (TolStore, Tol);
     Store (E1,E2,LV1,LV2,TolStore,AsDes, aDMVV);
   }
 }
@@ -518,10 +646,13 @@
                          const BRepAdaptor_Surface&      BAsurf,
                          const TopoDS_Edge&              E1,
                          const TopoDS_Edge&              E2,
+                         const TopAbs_Orientation        theOr1,
+                         const TopAbs_Orientation        theOr2,
                          const Handle(BRepAlgo_AsDes)&   AsDes,
                          Standard_Real                   Tol,
                          Standard_Boolean                WithOri,
-                         gp_Pnt&                         Pref,
+                         const TopoDS_Vertex&            theVref,
+                         BRepAlgo_Image&                 theImageVV,
                          TopTools_IndexedDataMapOfShapeListOfShape& aDMVV,
                          Standard_Boolean&               theCoincide)
 {
@@ -567,20 +698,20 @@
   Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
   
   if (WithDegen)
+  {
+    Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
+    TopoDS_Iterator iter( EI[ideg] );
+    if (iter.More())
     {
-      Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
-      TopoDS_Iterator iter( EI[ideg] );
-      if (iter.More())
-        {
-          const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
-          DegPoint = BRep_Tool::Pnt(vdeg);
-        }
-      else
-        {
-          BRepAdaptor_Curve CEdeg( EI[ideg], F );
-          DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
-        }
+      const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
+      DegPoint = BRep_Tool::Pnt(vdeg);
     }
+    else
+    {
+      BRepAdaptor_Curve CEdeg( EI[ideg], F );
+      DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
+    }
+  }
   //
   Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
   Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
@@ -596,107 +727,113 @@
       return;
     }
   }
-
+  
   Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
   //
   if (!Inter2d.IsDone() || !Inter2d.NbPoints()) {
     theCoincide = (Inter2d.NbSegments() &&
-                  (GAC1.GetType() == GeomAbs_Line) &&
-                  (GAC2.GetType() == GeomAbs_Line));
+                   (GAC1.GetType() == GeomAbs_Line) &&
+                   (GAC2.GetType() == GeomAbs_Line));
     return;
   }
   //
   for (i = 1; i <= Inter2d.NbPoints(); i++)
+  {
+    gp_Pnt P3d;
+    if (WithDegen)
+      P3d = DegPoint;
+    else
     {
-      gp_Pnt P3d;
-      if (WithDegen)
-        P3d = DegPoint;
-      else
-        {
-          gp_Pnt2d P2d = Inter2d.Point(i).Value();
-          P3d = BAsurf.Value( P2d.X(), P2d.Y() );
-        }
-      ResPoints.Append( P3d );
-      ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
-      ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
+      gp_Pnt2d P2d = Inter2d.Point(i).Value();
+      P3d = BAsurf.Value( P2d.X(), P2d.Y() );
     }
+    ResPoints.Append( P3d );
+    ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
+    ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
+  }
   
   for (i = 1; i <= ResPoints.Length(); i++)
+  {
+    Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
+    Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
+    if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
     {
-      Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
-      Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
-      if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
-        {
 #ifdef OCCT_DEBUG
-          std::cout << "Inter2d : Solution rejected due to infinite parameter"<<std::endl;
+      std::cout << "Inter2d : Solution rejected due to infinite parameter"<<std::endl;
 #endif
-          continue;
-        }
-      
-      gp_Pnt P = ResPoints(i); //ponc1.Value();
-      TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
-      aNewVertex.Orientation(TopAbs_INTERNAL);
-      B.UpdateVertex( aNewVertex, aT1, E1, Tol );
-      B.UpdateVertex( aNewVertex, aT2, E2, Tol );
-      gp_Pnt P1 = CE1.Value(aT1);
-      gp_Pnt P2 = CE2.Value(aT2);
-      Standard_Real dist1, dist2, dist3;
-      dist1 = P1.Distance(P);
-      dist2 = P2.Distance(P);
-      dist3 = P1.Distance(P2);
-      dist1 = Max( dist1, dist2 );
-      dist1 = Max( dist1, dist3 );
-      B.UpdateVertex( aNewVertex, dist1 );
-      
+      continue;
+    }
+    
+    gp_Pnt P = ResPoints(i); //ponc1.Value();
+    TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
+    aNewVertex.Orientation(TopAbs_INTERNAL);
+    B.UpdateVertex( aNewVertex, aT1, E1, Tol );
+    B.UpdateVertex( aNewVertex, aT2, E2, Tol );
+    gp_Pnt P1 = CE1.Value(aT1);
+    gp_Pnt P2 = CE2.Value(aT2);
+    Standard_Real dist1, dist2, dist3;
+    dist1 = P1.Distance(P);
+    dist2 = P2.Distance(P);
+    dist3 = P1.Distance(P2);
+    dist1 = Max( dist1, dist2 );
+    dist1 = Max( dist1, dist3 );
+    B.UpdateVertex( aNewVertex, dist1 );
+    
 #ifdef OCCT_DEBUG
-      if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
-        {
-          std::cout << "out of limit"<<std::endl;
-          std::cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<std::endl;
-        }
-      if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
-        {
-          std::cout << "out of limit"<<std::endl;
-          std::cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<std::endl;
-        }
-      Standard_Real MilTol2 = 1000*Tol*Tol;
-      if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
-        {
-          std::cout << "Inter2d : Solution rejected"<<std::endl;
-          std::cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<std::endl;
-          std::cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<std::endl;
-          std::cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<std::endl;
-          std::cout<<"MaxDist = "<<dist1<<std::endl;
-        }
+    if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
+    {
+      std::cout << "out of limit"<<std::endl;
+      std::cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<std::endl;
+    }
+    if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
+    {
+      std::cout << "out of limit"<<std::endl;
+      std::cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<std::endl;
+    }
+    Standard_Real MilTol2 = 1000*Tol*Tol;
+    if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
+    {
+      std::cout << "Inter2d : Solution rejected"<<std::endl;
+      std::cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<std::endl;
+      std::cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<std::endl;
+      std::cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<std::endl;
+      std::cout<<"MaxDist = "<<dist1<<std::endl;
+    }
 #endif
-      //define the orientation of a new vertex
-      TopAbs_Orientation OO1 = TopAbs_REVERSED;
-      TopAbs_Orientation OO2 = TopAbs_REVERSED;
-      if (WithOri)
-        {
-          BRepAdaptor_Curve2d PCE1( E1, F );
-          BRepAdaptor_Curve2d PCE2( E2, F );
-          gp_Pnt2d P2d1, P2d2;
-          gp_Vec2d V1, V2, V1or, V2or;
-          PCE1.D1( aT1, P2d1, V1 );
-          PCE2.D1( aT2, P2d2, V2 );
-          V1or = V1; V2or = V2;
-          if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
-          if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
-          Standard_Real CrossProd = V2or ^ V1;
+    //define the orientation of a new vertex
+    TopAbs_Orientation OO1 = TopAbs_REVERSED;
+    TopAbs_Orientation OO2 = TopAbs_REVERSED;
+    if (WithOri)
+    {
+      BRepAdaptor_Curve2d PCE1( E1, F );
+      BRepAdaptor_Curve2d PCE2( E2, F );
+      gp_Pnt2d P2d1, P2d2;
+      gp_Vec2d V1, V2, V1or, V2or;
+      PCE1.D1( aT1, P2d1, V1 );
+      PCE2.D1( aT2, P2d2, V2 );
+      V1or = V1; V2or = V2;
+      if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
+      if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
+      Standard_Real CrossProd = V2or ^ V1;
 #ifdef OCCT_DEBUG
-          if (Abs(CrossProd) <= gp::Resolution())
-            std::cout<<std::endl<<"CrossProd = "<<CrossProd<<std::endl;
+      if (Abs(CrossProd) <= gp::Resolution())
+        std::cout<<std::endl<<"CrossProd = "<<CrossProd<<std::endl;
 #endif
-          if (CrossProd > 0.)
-            OO1 = TopAbs_FORWARD;
-          CrossProd = V1or ^ V2;
-          if (CrossProd > 0.)
-            OO2 = TopAbs_FORWARD;
-        }
-      LV1.Append( aNewVertex.Oriented(OO1) );
-      LV2.Append( aNewVertex.Oriented(OO2) );
+      if (CrossProd > 0.)
+        OO1 = TopAbs_FORWARD;
+      CrossProd = V1or ^ V2;
+      if (CrossProd > 0.)
+        OO2 = TopAbs_FORWARD;
     }
+
+    if (theOr1 != TopAbs_EXTERNAL)
+      OO1 = theOr1;
+    if (theOr2 != TopAbs_EXTERNAL)
+      OO2 = theOr2;
+    
+    LV1.Append( aNewVertex.Oriented(OO1) );
+    LV2.Append( aNewVertex.Oriented(OO2) );
+  }
   
   //----------------------------------
   // Test at end.
@@ -755,7 +892,7 @@
         while (j < i) {      
           P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
           P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
-          if (P1.IsEqual(P2,10*Tol)) {
+          if (P1.IsEqual(P2, Tol)) {
             LV1.Remove(it1LV1);
             LV2.Remove(it1LV2);
             if (AffichPurge) std::cout <<"Doubles removed in EdgeInter."<<std::endl;
@@ -775,6 +912,7 @@
 ////-----------------------------------------------------
     if(LV1.Extent() > 1) {
       //std::cout << "IFV - RefEdgeInter: remove vertex" << std::endl;
+      gp_Pnt Pref = BRep_Tool::Pnt(theVref);
       Standard_Real dmin = RealLast();
       TopoDS_Vertex Vmin;
       for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
@@ -794,10 +932,21 @@
         }
       }
     }
+
+    TopTools_ListIteratorOfListOfShape itl (LV1);
+    for (; itl.More(); itl.Next())
+    {
+      TopoDS_Shape aNewVertex = itl.Value();
+      aNewVertex.Orientation(TopAbs_FORWARD);
+      if (theImageVV.HasImage (theVref))
+        theImageVV.Add (theVref.Oriented(TopAbs_FORWARD), aNewVertex);
+      else
+        theImageVV.Bind (theVref.Oriented(TopAbs_FORWARD), aNewVertex);
+    }
       
 ////-----------------------------------------------------
     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
-    TolStore = Max(TolStore, 10.*Tol);
+    TolStore = Max (TolStore, Tol);
     Store (E1,E2,LV1,LV2,TolStore,AsDes, aDMVV);
   }
 }
@@ -1406,6 +1555,7 @@
                                   const TopoDS_Face&                F,
                                   const TopTools_IndexedMapOfShape& NewEdges,
                                   const Standard_Real               Tol,
+                                  const TopTools_DataMapOfShapeListOfShape& theEdgeIntEdges,
                                   TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
 {
 #ifdef DRAW
@@ -1441,12 +1591,41 @@
     
     while (j < i && it2LE.More()) {
       const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
+
+      Standard_Boolean ToIntersect = Standard_True;
+      if (theEdgeIntEdges.IsBound(E1))
+      {
+        const TopTools_ListOfShape& aElist = theEdgeIntEdges(E1);
+        TopTools_ListIteratorOfListOfShape itedges (aElist);
+        for (; itedges.More(); itedges.Next())
+          if (E2.IsSame (itedges.Value()))
+            ToIntersect = Standard_False;
+        
+        if (ToIntersect)
+        {
+          for (itedges.Initialize(aElist); itedges.More(); itedges.Next())
+          {
+            const TopoDS_Shape& anEdge = itedges.Value();
+            if (theEdgeIntEdges.IsBound(anEdge))
+            {
+              const TopTools_ListOfShape& aElist2 = theEdgeIntEdges(anEdge);
+              TopTools_ListIteratorOfListOfShape itedges2 (aElist2);
+              for (; itedges2.More(); itedges2.Next())
+                if (E2.IsSame (itedges2.Value()))
+                  ToIntersect = Standard_False;
+            }
+          }
+        }
+      }
+      
       //--------------------------------------------------------------
       // Intersections of New edges obtained by intersection
       // between them and with edges of restrictions
       //------------------------------------------------------
-      if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
-           (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
+      if (ToIntersect &&
+          (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
+          (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
+        
         TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
         EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True, theDMVV);
 //          EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
@@ -1467,11 +1646,14 @@
   BRepOffset_Offset&            OFI,
   TopTools_DataMapOfShapeShape& MES,
   const TopTools_DataMapOfShapeShape& Build,
+  const Handle(BRepAlgo_AsDes)& theAsDes,
   const Handle(BRepAlgo_AsDes)& AsDes2d,
   const Standard_Real           Offset,
   const Standard_Real           Tol,
   const BRepOffset_Analyse&     Analyse,
   TopTools_IndexedMapOfShape&   FacesWithVerts,
+  BRepAlgo_Image&               theImageVV,
+  TopTools_DataMapOfShapeListOfShape& theEdgeIntEdges,
   TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
 {  
 
@@ -1529,8 +1711,7 @@
       continue; // Protection from case when explorer does not contain edges.
     CurE = FirstE  = wexp.Current();
     TopTools_IndexedMapOfShape Edges;
-    Standard_Boolean ToReverse1, ToReverse2;
-    ToReverse1 = IsOrientationChanged(Edges, CurE);
+    
     while (!end) {
       wexp.Next();
       if (wexp.More()) {
@@ -1541,10 +1722,7 @@
       }
       if (CurE.IsSame(NextE)) continue;
 
-      ToReverse2 = IsOrientationChanged(Edges, NextE);
-
       TopoDS_Vertex Vref = CommonVertex(CurE, NextE); 
-      gp_Pnt Pref = BRep_Tool::Pnt(Vref);
 
       CurE = Analyse.EdgeReplacement (FI, CurE);
       NextE = Analyse.EdgeReplacement (FI, NextE);
@@ -1559,21 +1737,38 @@
       TopTools_ListOfShape LV1,LV2;
       Standard_Boolean     DoInter = 1;
       TopoDS_Shape         NE1,NE2;
+      TopTools_SequenceOfShape NE1seq, NE2seq;
+      TopAbs_Orientation   anOr1 = TopAbs_EXTERNAL, anOr2 = TopAbs_EXTERNAL;
       
+      Standard_Integer aChoice = 0;
       if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
+        aChoice = 1;
         NE1 = Build(CurE );
         NE2 = Build(NextE);
+        GetEdgesOrientedInFace (NE1, FIO, theAsDes, NE1seq);
+        GetEdgesOrientedInFace (NE2, FIO, theAsDes, NE2seq);
+        anOr1 = TopAbs_REVERSED;
+        anOr2 = TopAbs_FORWARD;
       }
       else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
+        aChoice = 2;
         NE1 = Build(CurE);
         NE2 = MES  (NEO);
+        NE2.Orientation (NextE.Orientation());
+        GetEdgesOrientedInFace (NE1, FIO, theAsDes, NE1seq);
+        NE2seq.Append (NE2);
+        anOr1 = TopAbs_REVERSED;
+        anOr2 = TopAbs_FORWARD;
       }
       else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
+        aChoice = 3;
         NE1 = Build(NextE);
         NE2 = MES(CEO);
-        Standard_Boolean Tmp = ToReverse1;
-        ToReverse1 = ToReverse2;
-        ToReverse2 = Tmp;
+        NE2.Orientation (CurE.Orientation());
+        GetEdgesOrientedInFace (NE1, FIO, theAsDes, NE1seq);
+        NE2seq.Append (NE2);
+        anOr1 = TopAbs_FORWARD;
+        anOr2 = TopAbs_REVERSED;
       }
       else {
         DoInter = 0;
@@ -1583,23 +1778,43 @@
         // NE1,NE2 can be a compound of Edges.
         //------------------------------------
         Standard_Boolean bCoincide;
-        TopExp_Explorer Exp1, Exp2;
-        for (Exp1.Init(NE1, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
-          TopoDS_Edge aE1 = TopoDS::Edge(Exp1.Current());
-          for (Exp2.Init(NE2, TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
-            TopoDS_Edge aE2 = TopoDS::Edge(Exp2.Current());
+        TopoDS_Edge aE1, aE2;
+        if (aChoice == 1 || aChoice == 2)
+        {
+          aE1 = TopoDS::Edge (NE1seq.Last());
+          aE2 = TopoDS::Edge (NE2seq.First());
+        }
+        else // aChoice == 3
+        {
+          aE1 = TopoDS::Edge (NE1seq.First());
+          aE2 = TopoDS::Edge (NE2seq.Last());
+        }
 
-            //Correct orientation of edges
-            if (ToReverse1)
-              aE1.Reverse();
-            if (ToReverse2)
-              aE2.Reverse();
-            //////////////////////////////
-            
-            RefEdgeInter(FIO, BAsurf, aE1, aE2, AsDes2d,
-                         Tol, Standard_True, Pref, theDMVV, bCoincide);
-          }
+        if (aE1.Orientation() == TopAbs_REVERSED)
+          anOr1 = TopAbs::Reverse(anOr1);
+        if (aE2.Orientation() == TopAbs_REVERSED)
+          anOr2 = TopAbs::Reverse(anOr2);
+
+        RefEdgeInter(FIO, BAsurf, aE1, aE2, anOr1, anOr2, AsDes2d,
+                     Tol, Standard_True, Vref, theImageVV, theDMVV, bCoincide);
+
+        if (theEdgeIntEdges.IsBound(aE1))
+          theEdgeIntEdges(aE1).Append(aE2);
+        else
+        {
+          TopTools_ListOfShape aElist;
+          aElist.Append(aE2);
+          theEdgeIntEdges.Bind (aE1, aElist);
         }
+        if (theEdgeIntEdges.IsBound(aE2))
+          theEdgeIntEdges(aE2).Append(aE1);
+        else
+        {
+          TopTools_ListOfShape aElist;
+          aElist.Append(aE1);
+          theEdgeIntEdges.Bind (aE2, aElist);
+        }
+        
         //
         // check if some of the offset edges have been
         // generated out of the common vertex
@@ -1622,7 +1837,6 @@
         }
       }
       CurE = wexp.Current();
-      ToReverse1 = ToReverse2;
     }
   }
   return Standard_True;
@@ -1682,7 +1896,6 @@
       if (CurE.IsSame(NextE)) continue;
       //
       TopoDS_Vertex Vref = CommonVertex(CurE, NextE); 
-      gp_Pnt Pref = BRep_Tool::Pnt(Vref);
       if (!Build.IsBound(Vref)) {
         CurE = NextE;
         continue;
@@ -1697,6 +1910,7 @@
       TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
       //
       TopoDS_Shape         NE1,NE2;
+      TopAbs_Orientation   anOr1 = TopAbs_EXTERNAL, anOr2 = TopAbs_EXTERNAL;
       
       if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
         NE1 = Build(CurE );
@@ -1729,8 +1943,9 @@
         // intersection with first edge
         for (Exp1.Init(NE1, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
           const TopoDS_Edge& aE1 = TopoDS::Edge(Exp1.Current());
-          RefEdgeInter(FIO, BAsurf, aE1, aE3, AsDes2d,
-            Tol, Standard_True, Pref, theDMVV, bCoincide);
+          BRepAlgo_Image anEmptyImage;
+          RefEdgeInter(FIO, BAsurf, aE1, aE3, anOr1, anOr2, AsDes2d,
+                       Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide);
           if (bCoincide) {
             // in case of coincidence trim the edge E3 the same way as E1
             Store(aE3, AsDes2d->Descendant(aE1), Tol, Standard_True, AsDes2d, theDMVV);
@@ -1740,8 +1955,9 @@
         // intersection with second edge
         for (Exp1.Init(NE2, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
           const TopoDS_Edge& aE2 = TopoDS::Edge(Exp1.Current());
-          RefEdgeInter(FIO, BAsurf, aE2, aE3, AsDes2d,
-            Tol, Standard_True, Pref, theDMVV, bCoincide);
+          BRepAlgo_Image anEmptyImage;
+          RefEdgeInter(FIO, BAsurf, aE2, aE3, anOr1, anOr2, AsDes2d,
+                       Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide);
           if (bCoincide) {
             // in case of coincidence trim the edge E3 the same way as E2
             Store(aE3, AsDes2d->Descendant(aE2), Tol, Standard_True, AsDes2d, theDMVV);
@@ -1759,8 +1975,9 @@
         for (Exp1.Next(); Exp1.More(); Exp1.Next()) {
           const TopoDS_Edge& aE3Next = TopoDS::Edge(Exp1.Current());
           if (aME.Contains(aE3Next)) {
-            RefEdgeInter(FIO, BAsurf, aE3Next, aE3, AsDes2d,
-              Tol, Standard_True, Pref, theDMVV, bCoincide);
+            BRepAlgo_Image anEmptyImage;
+            RefEdgeInter(FIO, BAsurf, aE3Next, aE3, anOr1, anOr2, AsDes2d,
+                         Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide);
           }
         }
       }
@@ -1795,7 +2012,8 @@
 //purpose  : 
 //=======================================================================
 Standard_Boolean BRepOffset_Inter2d::FuseVertices (const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
-                                                   const Handle(BRepAlgo_AsDes)& theAsDes)
+                                                   const Handle(BRepAlgo_AsDes)& theAsDes,
+                                                   BRepAlgo_Image&               theImageVV)
 {
   BRep_Builder aBB;
   TopTools_MapOfShape aMVDone;
@@ -1837,6 +2055,11 @@
       }
       // and replace the vertex
       theAsDes->Replace(aVOld, aVNew);
+      if (theImageVV.IsImage(aVOld))
+      {
+        const TopoDS_Vertex& aProVertex = TopoDS::Vertex (theImageVV.ImageFrom(aVOld));
+        theImageVV.Add (aProVertex, aVNew.Oriented(TopAbs_FORWARD));
+      }
     }
   }
   return Standard_True;
Index: src/BRepOffset/BRepOffset_Inter2d.hxx
===================================================================
--- src/BRepOffset/BRepOffset_Inter2d.hxx	(revision 1)
+++ src/BRepOffset/BRepOffset_Inter2d.hxx	(working copy)
@@ -50,6 +50,7 @@
                                        const TopoDS_Face& F, 
                                        const TopTools_IndexedMapOfShape& NewEdges, 
                                        const Standard_Real Tol,
+                                       const TopTools_DataMapOfShapeListOfShape& theEdgeIntEdges,
                                        TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
 
   //! Computes the intersection between the offset edges of the <FI>.
@@ -58,15 +59,18 @@
   //! have to be fused using the FuseVertices method.
   //! theDMVV contains the vertices that should be fused.
   Standard_EXPORT static Standard_Boolean ConnexIntByInt (const TopoDS_Face& FI,
-                                              BRepOffset_Offset& OFI,
-                                              TopTools_DataMapOfShapeShape& MES,
-                                              const TopTools_DataMapOfShapeShape& Build,
-                                              const Handle(BRepAlgo_AsDes)& AsDes2d,
-                                              const Standard_Real Offset,
-                                              const Standard_Real Tol,
-                                              const BRepOffset_Analyse& Analyse,
-                                              TopTools_IndexedMapOfShape& FacesWithVerts,
-                                              TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
+                                                          BRepOffset_Offset& OFI,
+                                                          TopTools_DataMapOfShapeShape& MES,
+                                                          const TopTools_DataMapOfShapeShape& Build,
+                                                          const Handle(BRepAlgo_AsDes)& theAsDes,
+                                                          const Handle(BRepAlgo_AsDes)& AsDes2d,
+                                                          const Standard_Real Offset,
+                                                          const Standard_Real Tol,
+                                                          const BRepOffset_Analyse& Analyse,
+                                                          TopTools_IndexedMapOfShape& FacesWithVerts,
+                                                          BRepAlgo_Image& theImageVV,
+                                                          TopTools_DataMapOfShapeListOfShape& theEdgeIntEdges,
+                                                          TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
 
   //! Computes the intersection between the offset edges generated
   //! from vertices and stored into AsDes as descendants of the <FI>.
@@ -88,7 +92,9 @@
   //! and updates AsDes by replacing the old vertices
   //! with the new ones.
   Standard_EXPORT static Standard_Boolean FuseVertices (const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
-                                                        const Handle(BRepAlgo_AsDes)& theAsDes);
+                                                        const Handle(BRepAlgo_AsDes)& theAsDes,
+                                                        BRepAlgo_Image&               theImageVV);
+                                                        
   //! extents the edge
   Standard_EXPORT static Standard_Boolean ExtentEdge (const TopoDS_Edge& E,
                                                       TopoDS_Edge& NE,
Index: src/BRepOffset/BRepOffset_Inter3d.cxx
===================================================================
--- src/BRepOffset/BRepOffset_Inter3d.cxx	(revision 1)
+++ src/BRepOffset/BRepOffset_Inter3d.cxx	(working copy)
@@ -169,6 +169,7 @@
 {
   TopTools_ListOfShape LInt1, LInt2;
   TopoDS_Edge NullEdge;
+  TopoDS_Face NullFace;
 
   if (F1.IsSame(F2)) return;
   if (IsDone(F1,F2)) return;
@@ -221,11 +222,11 @@
           if (BRepOffset_Tool::FindCommonShapes(TopoDS::Face(InitF1),
                                                 TopoDS::Face(InitF2),LE,LV)) {
             if (!LE.IsEmpty()) {
-              BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+              BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
             }
           }
           else {
-            BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge);
+            BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
           }
         }
       }
@@ -236,7 +237,7 @@
       BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
     }
     else {
-      BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+      BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
     }
   }
   Store (F1,F2,LInt1,LInt2);
@@ -259,6 +260,7 @@
   TopTools_ListOfShape           LInt1,LInt2;
   TopoDS_Face                    F1,F2;
   TopoDS_Edge                    NullEdge;
+  TopoDS_Face                    NullFace;
 
   //---------------------------------------------------------------------
   // etape 1 : Intersection of faces // corresponding to the initial faces 
@@ -273,10 +275,13 @@
       //-----------------------------------------------------------
       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
       if (Anc.Extent() == 2) {
-        F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
-        F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
+        
+        const TopoDS_Face& InitF1 = TopoDS::Face(Anc.First());
+        const TopoDS_Face& InitF2 = TopoDS::Face(Anc.Last());
+        F1 = TopoDS::Face(InitOffsetFace.Image(InitF1).First());
+        F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
         if (!IsDone(F1,F2)) {
-          BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
+          BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,InitF1,InitF2);
           Store (F1,F2,LInt1,LInt2);
         }
       }          
@@ -361,7 +366,7 @@
                 if (!TangentFaces) {
                   F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
                   if (!IsDone(F1,F2)) {
-                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
                     Store (F1,F2,LInt1,LInt2);
                   }
                 }
@@ -371,7 +376,7 @@
                 if (!TangentFaces) {
                   F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
                   if (!IsDone(F1,F2)) {
-                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
                     Store (F1,F2,LInt1,LInt2);
                   }
                 }
@@ -635,7 +640,7 @@
       //
       if (!IsDone(NF1,NF2)) {
         TopTools_ListOfShape LInt1,LInt2;
-        BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge);
+        BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,F1,F2);
         SetDone(NF1,NF2);
         if (!LInt1.IsEmpty()) {
           Store (NF1,NF2,LInt1,LInt2);
@@ -1034,7 +1039,7 @@
           TopTools_ListOfShape LInt1,LInt2;
           TopTools_ListOfShape LOE;
           LOE.Append(OE);
-          BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge);
+          BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,CF,F);
           SetDone(NF,CF);
           if (!LInt1.IsEmpty()) {
             Store (CF,NF,LInt1,LInt2);
@@ -1086,6 +1091,7 @@
   TopoDS_Edge                               OE;
   BRep_Builder                              B;  
   TopoDS_Edge                               NullEdge;
+  TopoDS_Face                               NullFace;                  
   Standard_Integer j;
 
   for (j = 1; j <= ContextFaces.Extent(); j++) {
@@ -1255,7 +1261,7 @@
             // If no trace try intersection.
             //-------------------------------------------------------
             if (LInt1.IsEmpty()) {
-              BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
+              BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
             }
             Store (CF,OF1,LInt1,LInt2);
           }
Index: src/BRepOffset/BRepOffset_MakeLoops.cxx
===================================================================
--- src/BRepOffset/BRepOffset_MakeLoops.cxx	(revision 1)
+++ src/BRepOffset/BRepOffset_MakeLoops.cxx	(working copy)
@@ -51,12 +51,14 @@
 
 void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape&   LF, 
 				 const Handle(BRepAlgo_AsDes)& AsDes, 
-				 BRepAlgo_Image&               Image)
+				 BRepAlgo_Image&               Image,
+                                 BRepAlgo_Image&               theImageVV)
 {
   TopTools_ListIteratorOfListOfShape    it(LF);
   TopTools_ListIteratorOfListOfShape    itl,itLCE;
   BRepAlgo_Loop                       Loops;
   Loops.VerticesForSubstitute( myVerVerMap );
+  Loops.SetImageVV (theImageVV);
 
   for (; it.More(); it.Next()) {
     const TopoDS_Face& F = TopoDS::Face(it.Value());
Index: src/BRepOffset/BRepOffset_MakeLoops.hxx
===================================================================
--- src/BRepOffset/BRepOffset_MakeLoops.hxx	(revision 1)
+++ src/BRepOffset/BRepOffset_MakeLoops.hxx	(working copy)
@@ -39,11 +39,20 @@
   
   Standard_EXPORT BRepOffset_MakeLoops();
   
-  Standard_EXPORT void Build (const TopTools_ListOfShape& LF, const Handle(BRepAlgo_AsDes)& AsDes, BRepAlgo_Image& Image);
+  Standard_EXPORT void Build (const TopTools_ListOfShape& LF,
+                              const Handle(BRepAlgo_AsDes)& AsDes,
+                              BRepAlgo_Image& Image,
+                              BRepAlgo_Image& theImageVV);
   
-  Standard_EXPORT void BuildOnContext (const TopTools_ListOfShape& LContext, const BRepOffset_Analyse& Analyse, const Handle(BRepAlgo_AsDes)& AsDes, BRepAlgo_Image& Image, const Standard_Boolean InSide);
+  Standard_EXPORT void BuildOnContext (const TopTools_ListOfShape& LContext,
+                                       const BRepOffset_Analyse& Analyse,
+                                       const Handle(BRepAlgo_AsDes)& AsDes,
+                                       BRepAlgo_Image& Image,
+                                       const Standard_Boolean InSide);
   
-  Standard_EXPORT void BuildFaces (const TopTools_ListOfShape& LF, const Handle(BRepAlgo_AsDes)& AsDes, BRepAlgo_Image& Image);
+  Standard_EXPORT void BuildFaces (const TopTools_ListOfShape& LF,
+                                   const Handle(BRepAlgo_AsDes)& AsDes,
+                                   BRepAlgo_Image& Image);
 
 
 
Index: src/BRepOffset/BRepOffset_MakeOffset.cxx
===================================================================
--- src/BRepOffset/BRepOffset_MakeOffset.cxx	(revision 1)
+++ src/BRepOffset/BRepOffset_MakeOffset.cxx	(working copy)
@@ -591,6 +591,7 @@
 : 
 myOffset     (Offset),
 myTol        (Tol),
+myInitialShape (S),
 myShape      (S),
 myMode       (Mode),
 myInter      (Inter),
@@ -623,6 +624,7 @@
                                        const Standard_Boolean RemoveIntEdges)
 {
   myOffset     = Offset;
+  myInitialShape = S;
   myShape      = S;
   myTol        = Tol;
   myMode       = Mode;
@@ -650,9 +652,11 @@
   myInitOffsetFace .Clear();
   myInitOffsetEdge .Clear();
   myImageOffset    .Clear();
+  myImageVV        .Clear();
   myFaces          .Clear();  
   myOriginalFaces  .Clear();  
   myFaceOffset     .Clear();
+  myEdgeIntEdges   .Clear();
   myAsDes          ->Clear();
   myDone     = Standard_False;
   myGenerated.Clear();
@@ -1256,7 +1260,7 @@
   {
     const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
     Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
-    BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
+    BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, myEdgeIntEdges, aDMVV);
   }
   //----------------------------------------------
   // Intersections 2d on caps.
@@ -1266,10 +1270,10 @@
   {
     const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
     Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
-    BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
+    BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, myEdgeIntEdges, aDMVV);
   }
   //
-  BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
+  BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes, myImageVV);
   //-------------------------------
   // Unwinding of extended Faces.
   //-------------------------------
@@ -1286,7 +1290,7 @@
     }
   }
   else {
-    myMakeLoops.Build(LFE, AsDes, IMOE);
+    myMakeLoops.Build(LFE, AsDes, IMOE, myImageVV);
   }
   //
 #ifdef OCCT_DEBUG
@@ -2526,10 +2530,10 @@
   Standard_Integer i;
   for (i = 1; i <= Modif.Extent(); i++) {
     const TopoDS_Face& F  = TopoDS::Face(Modif(i));
-    BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol, aDMVV);
+    BRepOffset_Inter2d::Compute(myAsDes, F, NewEdges, myTol, myEdgeIntEdges, aDMVV);
   }
   //
-  BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
+  BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes, myImageVV);
   //
 #ifdef OCCT_DEBUG
   if (AffichInt2d) {
@@ -2569,7 +2573,7 @@
     BuildSplitsOfTrimmedFaces(LF, myAsDes, myImageOffset);
   }
   else {
-    myMakeLoops.Build(LF,myAsDes,myImageOffset);
+    myMakeLoops.Build(LF,myAsDes,myImageOffset,myImageVV);
   }
 
   //-----------------------------------------
@@ -3345,7 +3349,7 @@
 
 const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
 {
-  return myFaces;
+  return myOriginalFaces;
 }
 
 
@@ -3998,8 +4002,8 @@
   {
     const TopoDS_Face& aF  = TopoDS::Face (it.Value());
     aTolF = BRep_Tool::Tolerance (aF);
-    if (!BRepOffset_Inter2d::ConnexIntByInt(aF, theMapSF(aF), theMES, theBuild, theAsDes2d,
-                                            myOffset, aTolF, myAnalyse, aMFV, aDMVV))
+    if (!BRepOffset_Inter2d::ConnexIntByInt(aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d,
+                                            myOffset, aTolF, myAnalyse, aMFV, myImageVV, myEdgeIntEdges, aDMVV))
     {
       myError = BRepOffset_CannotExtentEdge;
       return;
@@ -4015,7 +4019,7 @@
   }
   //
   // fuse vertices on edges
-  if (!BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d))
+  if (!BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d, myImageVV))
   {
     myError = BRepOffset_CannotFuseVertices;
     return;
@@ -4490,9 +4494,24 @@
     Standard_FALLTHROUGH
     case TopAbs_FACE:
     {
-      if (myInitOffsetFace.HasImage (theS))
+      TopoDS_Shape aS = theS;
+      const TopoDS_Shape* aPlanface = myFacePlanfaceMap.Seek(aS);
+      if (aPlanface)
+        aS = TopoDS::Face(*aPlanface);
+      
+      if (!myFaces.Contains (aS) &&
+          myInitOffsetFace.HasImage (aS))
       {
-        myInitOffsetFace.LastImage (theS, myGenerated);
+        myInitOffsetFace.LastImage (aS, myGenerated);
+
+        if (!myFaces.IsEmpty())
+        {
+          // Reverse generated shapes in case of small solids.
+          // Useful only for faces without influence on others.
+          TopTools_ListIteratorOfListOfShape it(myGenerated);
+          for (; it.More(); it.Next())
+            it.Value().Reverse();
+        }
       }
       break;
     }
@@ -4524,9 +4543,33 @@
 //function : Modified
 //purpose  : 
 //=======================================================================
-const TopTools_ListOfShape& BRepOffset_MakeOffset::Modified (const TopoDS_Shape&)
+const TopTools_ListOfShape& BRepOffset_MakeOffset::Modified (const TopoDS_Shape& theShape)
 {
   myGenerated.Clear();
+
+  if (theShape.ShapeType() == TopAbs_FACE)
+  {
+    TopoDS_Shape aS = theShape;
+    const TopoDS_Shape* aPlanface = myFacePlanfaceMap.Seek(aS);
+    if (aPlanface)
+      aS = TopoDS::Face(*aPlanface);
+    
+    if (myFaces.Contains (aS) &&
+        myInitOffsetFace.HasImage (aS))
+    {
+      myInitOffsetFace.LastImage (aS, myGenerated);
+      
+      if (!myFaces.IsEmpty())
+      {
+        // Reverse generated shapes in case of small solids.
+        // Useful only for faces without influence on others.
+        TopTools_ListIteratorOfListOfShape it(myGenerated);
+        for (; it.More(); it.Next())
+          it.Value().Reverse();
+      }
+    }
+  }
+  
   return myGenerated;
 }
 
Index: src/BRepOffset/BRepOffset_MakeOffset.hxx
===================================================================
--- src/BRepOffset/BRepOffset_MakeOffset.hxx	(revision 1)
+++ src/BRepOffset/BRepOffset_MakeOffset.hxx	(working copy)
@@ -97,7 +97,7 @@
   
   const TopoDS_Shape& InitShape() const
   {
-    return myShape;
+    return myInitialShape;
   }
 
   //! returns information about offset state.
@@ -231,6 +231,7 @@
 
   Standard_Real myOffset;
   Standard_Real myTol;
+  TopoDS_Shape myInitialShape;
   TopoDS_Shape myShape;
   TopoDS_Compound myFaceComp;
   BRepOffset_Mode myMode;
@@ -248,8 +249,10 @@
   BRepAlgo_Image myInitOffsetFace;
   BRepAlgo_Image myInitOffsetEdge;
   BRepAlgo_Image myImageOffset;
+  BRepAlgo_Image myImageVV;
   TopTools_ListOfShape myWalls;
   Handle(BRepAlgo_AsDes) myAsDes;
+  TopTools_DataMapOfShapeListOfShape myEdgeIntEdges;
   Standard_Boolean myDone;
   BRepOffset_Error myError;
   BRepOffset_MakeLoops myMakeLoops;
Index: src/BRepOffset/BRepOffset_MakeOffset_1.cxx
===================================================================
--- src/BRepOffset/BRepOffset_MakeOffset_1.cxx	(revision 1)
+++ src/BRepOffset/BRepOffset_MakeOffset_1.cxx	(working copy)
@@ -5678,7 +5678,9 @@
   TopAbs_State aSide = TopAbs_OUT;
   TopTools_ListOfShape aLInt1, aLInt2;
   TopoDS_Edge aNullEdge;
-  BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide, aNullEdge);
+  TopoDS_Face aNullFace;
+  BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide,
+                           aNullEdge, aNullFace, aNullFace);
   //
   if (aLInt1.IsEmpty()) {
     return;
Index: src/BRepOffset/BRepOffset_Tool.cxx
===================================================================
--- src/BRepOffset/BRepOffset_Tool.cxx	(revision 1)
+++ src/BRepOffset/BRepOffset_Tool.cxx	(working copy)
@@ -1401,8 +1401,9 @@
 			      TopTools_ListOfShape& L1,
 			      TopTools_ListOfShape& L2,
 			      const TopAbs_State    Side,
-			      const TopoDS_Edge&     RefEdge,
-			      const Standard_Boolean IsRefEdgeDefined)
+			      const TopoDS_Edge&    RefEdge,
+                              const TopoDS_Face&    theRefFace1,
+                              const TopoDS_Face&    theRefFace2)
 {
 #ifdef DRAW
   if (AffichInter) {
@@ -1445,7 +1446,7 @@
   aPF.Perform();
   
   TopTools_IndexedMapOfShape TrueEdges;
-  if (IsRefEdgeDefined)
+  if (!RefEdge.IsNull())
     CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
 
   Standard_Boolean addPCurve1 = 1;
@@ -1494,33 +1495,33 @@
         if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
           Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
           if(!aC3DETrim.IsNull()) {
-		Handle(Geom2d_Curve) aC2dNew;
-		
-		if(aC3DE->IsPeriodic()) {
-                  BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l,  aC2d, aC2dNew, aContext);
-		  }
-		else {
-                  BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext); 
-		  }
-		aC2d = aC2dNew;
-	      }
-	      BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
+            Handle(Geom2d_Curve) aC2dNew;
+            
+            if(aC3DE->IsPeriodic()) {
+              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l,  aC2d, aC2dNew, aContext);
+            }
+            else {
+              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext); 
+            }
+            aC2d = aC2dNew;
+          }
+          BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
         }
         
         if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
           Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
           if(!aC3DETrim.IsNull()) {
-		Handle(Geom2d_Curve) aC2dNew;
-		
-		if(aC3DE->IsPeriodic()) {
-                  BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l,  aC2d, aC2dNew, aContext);
-		  }
-		else {
-                  BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext); 
-		  }
-		aC2d = aC2dNew;
-	      }
-	      BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
+            Handle(Geom2d_Curve) aC2dNew;
+            
+            if(aC3DE->IsPeriodic()) {
+              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l,  aC2d, aC2dNew, aContext);
+            }
+            else {
+              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext); 
+            }
+            aC2d = aC2dNew;
+          }
+          BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
         }
          
         OrientSection (anEdge, F1, F2, O1, O2);
@@ -1563,6 +1564,84 @@
   else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
     isEl2 = Standard_True;
 
+  if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
+  {
+    //remove excess edges that are out of range
+    TopoDS_Vertex aV1, aV2;
+    TopExp::Vertices (RefEdge, aV1, aV2);
+    if (!aV1.IsSame(aV2)) //only if RefEdge is open
+    {
+      Handle(Geom_Surface) aRefSurf1 = BRep_Tool::Surface (theRefFace1);
+      Handle(Geom_Surface) aRefSurf2 = BRep_Tool::Surface (theRefFace2);
+      if (aRefSurf1->IsUClosed() || aRefSurf1->IsVClosed() ||
+          aRefSurf2->IsUClosed() || aRefSurf2->IsVClosed())
+      {
+        TopoDS_Edge MinAngleEdge;
+        Standard_Real MinAngle = Precision::Infinite();
+        BRepAdaptor_Curve aRefBAcurve (RefEdge);
+        gp_Pnt aRefPnt = aRefBAcurve.Value ((aRefBAcurve.FirstParameter() + aRefBAcurve.LastParameter())/2);
+        
+        TopTools_ListIteratorOfListOfShape itl (L1);
+        for (; itl.More(); itl.Next())
+        {
+          const TopoDS_Edge& anEdge = TopoDS::Edge (itl.Value());
+          
+          BRepAdaptor_Curve aBAcurve (anEdge);
+          gp_Pnt aMidPntOnEdge = aBAcurve.Value ((aBAcurve.FirstParameter() + aBAcurve.LastParameter())/2);
+          gp_Vec RefToMid (aRefPnt, aMidPntOnEdge);
+          
+          Extrema_ExtPC aProjector (aRefPnt, aBAcurve);
+          if (aProjector.IsDone())
+          {
+            Standard_Integer imin = 0;
+            Standard_Real MinSqDist = Precision::Infinite();
+            for (Standard_Integer ind = 1; ind <= aProjector.NbExt(); ind++)
+            {
+              Standard_Real aSqDist = aProjector.SquareDistance(ind);
+              if (aSqDist < MinSqDist)
+              {
+                MinSqDist = aSqDist;
+                imin = ind;
+              }
+            }
+            if (imin != 0)
+            {
+              gp_Pnt aProjectionOnEdge = aProjector.Point(imin).Value();
+              gp_Vec RefToProj (aRefPnt, aProjectionOnEdge);
+              Standard_Real anAngle = RefToProj.Angle(RefToMid);
+              if (anAngle < MinAngle)
+              {
+                MinAngle = anAngle;
+                MinAngleEdge = anEdge;
+              }
+            }
+          }
+        }
+
+        if (!MinAngleEdge.IsNull())
+        {
+          TopTools_ListIteratorOfListOfShape itlist1 (L1);
+          TopTools_ListIteratorOfListOfShape itlist2 (L2);
+          
+          while (itlist1.More())
+          {
+            const TopoDS_Shape& anEdge = itlist1.Value();
+            if (anEdge.IsSame(MinAngleEdge))
+            {
+              itlist1.Next();
+              itlist2.Next();
+            }
+            else
+            {
+              L1.Remove(itlist1);
+              L2.Remove(itlist2);
+            }
+          }
+        }
+      } //if closed
+    } //if (!aV1.IsSame(aV2))
+  } //if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
+
   if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
     TopTools_SequenceOfShape eseq;
     TopTools_SequenceOfShape EdgesForConcat;
@@ -1724,7 +1803,7 @@
             eseq.Append( aLocalEdgesForConcat(j) );
         else
           eseq.Append( AssembledEdge );
-      }
+      } //for (i = 1; i <= wseq.Length(); i++)
     } //end of else (when TrueEdges is empty)
     
     if (eseq.Length() < L1.Extent())
@@ -3468,7 +3547,8 @@
       if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
       if (ToBuild.IsBound(E)) {
         EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
-        BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
+        TopoDS_Face NullFace;
+        BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,NullFace,NullFace);
         // No intersection, it may happen for example for a chosen (non-offseted) planar face and 
         // its neighbour offseted cylindrical face, if the offset is directed so that 
         // the radius of the cylinder becomes smaller.
Index: src/BRepOffset/BRepOffset_Tool.hxx
===================================================================
--- src/BRepOffset/BRepOffset_Tool.hxx	(revision 1)
+++ src/BRepOffset/BRepOffset_Tool.hxx	(working copy)
@@ -87,9 +87,10 @@
                                        const TopoDS_Face& F2,
                                        TopTools_ListOfShape& LInt1,
                                        TopTools_ListOfShape& LInt2,
-                                       const TopAbs_State Side,
-                                       const TopoDS_Edge& RefEdge,
-                                       const Standard_Boolean IsRefEdgeDefined = Standard_False);
+                                       const TopAbs_State    Side,
+                                       const TopoDS_Edge&    RefEdge,
+                                       const TopoDS_Face&    RefFace1,
+                                       const TopoDS_Face&    RefFace2);
   
   //! Find if the edges <Edges> of the face <F2> are on
   //! the face <F1>.
Index: src/BiTgte/BiTgte_Blend.cxx
===================================================================
--- src/BiTgte/BiTgte_Blend.cxx	(revision 1)
+++ src/BiTgte/BiTgte_Blend.cxx	(working copy)
@@ -1780,10 +1780,12 @@
 	  }
 	}
       }
+      TopTools_DataMapOfShapeListOfShape anEmptyMap;
       BRepOffset_Inter2d::Compute(myAsDes,
 				  CurOF,
 				  myEdges,
 				  myTol,
+                                  anEmptyMap,
 				  aDMVV);
     }
   }
@@ -1813,20 +1815,23 @@
       myAsDes->Add(CurOF,CurOE);
     }
 
+    TopTools_DataMapOfShapeListOfShape anEmptyMap;
     BRepOffset_Inter2d::Compute(myAsDes,
 				CurOF,
 				myEdges,
 				myTol,
+                                anEmptyMap,
 				aDMVV);
   }
   //
   // fuse vertices on edges stored in AsDes
-  BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
+  BRepAlgo_Image anEmptyImage;
+  BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes, anEmptyImage);
   // ------------
   // unwinding 
   // ------------
   BRepOffset_MakeLoops MakeLoops;
-  MakeLoops.Build( LOF, myAsDes, myImageOffset );
+  MakeLoops.Build (LOF, myAsDes, myImageOffset, anEmptyImage);
 
   // ------------------------------------------------------------
   // It is possible to unwind edges at least one ancestor which of 
