]> OCCT Git - occt-copy.git/commitdiff
0025926: 3D offset in mode "Complete" with Join type "Intersection"
authoremv <emv@opencascade.com>
Thu, 22 Oct 2015 06:31:48 +0000 (09:31 +0300)
committeremv <emv@opencascade.com>
Thu, 22 Oct 2015 06:31:48 +0000 (09:31 +0300)
3D offset algorithm extension for degenerate (colliding) cases.
Patch for version 6.9.1 of Open CASCADE.

It includes the following commits:

Revision: 5a9dc37f84bb8c6c7ac1e43c1dbcf484b4261321
Author: emv <emv@opencascade.com>
Date: 22/10/15 9:00:54 AM
Message:
Make the possibility to produce empty result in case of any invalidity (spikes, self-intersections, faces inversion) optional.
----
Modified: src/BRepOffset/BRepOffset_MakeOffset.cdl
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx
Modified: src/BRepTest/BRepTest_FeatureCommands.cxx

Revision: aadba9a3f585693eddff1ea29b7063a08320ee23
Author: emv <emv@opencascade.com>
Date: 16/10/15 10:21:57 AM
Message:
Due to the small inaccuracy of the calculation of the bi-normal direction (direction inside the face on the edge)

the criterion on the coincidence of these directions has been weakened.
----
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx

Revision: 3564da4b4d631c8ed627d7ca7697328d6c371aae
Author: emv <emv@opencascade.com>
Date: 15/10/15 11:52:23 AM
Message:
The option to remove INTERNAL edges from the faces of the result of Offset operation has been added into Offset API.

By default these edges will be kept in the result.
To remove these edges make sure to set the corresponding flag to TRUE when initializing the Offset algo.

void BRepOffset_MakeOffset::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 RemoveIntEdges,
                                       const Standard_Boolean Thickening)
----
Modified: src/BRepOffset/BRepOffset_MakeOffset.cdl
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx
Modified: src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cdl
Modified: src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx
Modified: src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cdl
Modified: src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx
Modified: src/BRepTest/BRepTest_FeatureCommands.cxx

Revision: fe25cda7b7aa2f84c5fc2e0f9f1ef8b1c27d9ea5
Author: emv <emv@opencascade.com>
Date: 08/10/15 12:11:06 PM
Message:
Temporary patch to produce empty result in case of any invalidity (spikes, self-intersections, faces inversion).
----
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx

Revision: 0fe92803d21a48ca299b88fc565bdcff6256fe70
Author: emv <emv@opencascade.com>
Date: 27/08/15 11:21:55 AM
Message:
Using local face tolerance for edges intersection.
----
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx

Revision: 7a38094a2b8cff5ed10353fc198abadcb073799a
Author: emv <emv@opencascade.com>
Date: 10/07/15 12:52:58 PM
Message:
Corrections in splitting faces and making shells functions.
----
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx

Revision: 2102c85e9fd4e4f3fd73b0f475526a9f67eb721a
Author: emv <emv@opencascade.com>
Date: 07/07/15 2:18:28 PM
Message:
3D Offset algorithm extension for the cases with the shapes having the faces connected only by the VERTEX.
----
Modified: src/BRepOffset/BRepOffset_Inter2d.cdl
Modified: src/BRepOffset/BRepOffset_Inter2d.cxx
Modified: src/BRepOffset/BRepOffset_Inter3d.cxx
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx

Revision: c4362927dc958358996bee5a711eef2733a63154
Author: emv <emv@opencascade.com>
Date: 30/06/15 12:22:42 PM
Message:
Fix for correct shells splitting when building solids.
----
Modified: src/BOPAlgo/BOPAlgo_MakerVolume.cxx
Modified: src/BOPAlgo/BOPAlgo_ShellSplitter.cxx

Revision: ee5d676aee993954c1bac95c28a78acf9f6d39ef
Author: emv <emv@opencascade.com>
Date: 17/06/15 11:30:10 AM
Message:
Treatment of the shells with free edges has been changed to keep the faces with internal edges.
----
Modified: src/BRepAlgo/BRepAlgo_Tool.cxx

Revision: 999dacb4d0b0c1c858961e144be4c0173bd4a49c
Author: emv <emv@opencascade.com>
Date: 04/06/15 10:53:22 AM
Message:
0025926: 3D offset in mode "Complete" with Join type "Intersection"

3D offset algorithm extension for degenerate (colliding) cases.
----
Modified: src/BRepOffset/BRepOffset_Inter2d.cxx
Modified: src/BRepOffset/BRepOffset_Inter3d.cxx
Modified: src/BRepOffset/BRepOffset_MakeOffset.cdl
Modified: src/BRepOffset/BRepOffset_MakeOffset.cxx

src/BRepAlgo/BRepAlgo_Tool.cxx
src/BRepOffset/BRepOffset_Inter2d.cdl
src/BRepOffset/BRepOffset_Inter2d.cxx
src/BRepOffset/BRepOffset_Inter3d.cxx
src/BRepOffset/BRepOffset_MakeOffset.cdl
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cdl
src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cdl
src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx
src/BRepTest/BRepTest_FeatureCommands.cxx

index bc4a6f662bfca298512252973603847f8914f96b..34a9b51ca9d119970f685bedb5125fa1d2a7296e 100644 (file)
@@ -52,8 +52,16 @@ TopoDS_Shape BRepAlgo_Tool::Deboucle3D(const TopoDS_Shape& S,
       
       Standard_Boolean JeGarde = Standard_True;
       for ( Standard_Integer i = 1; i <= Map.Extent() && JeGarde; i++) {
-       if (Map(i).Extent() < 2) {
-         const TopoDS_Edge& anEdge = TopoDS::Edge(Map.FindKey(i));
+        const TopTools_ListOfShape& aLF = Map(i);
+        if (aLF.Extent() < 2) {
+          const TopoDS_Edge& anEdge = TopoDS::Edge(Map.FindKey(i));
+          if (anEdge.Orientation() == TopAbs_INTERNAL) {
+            const TopoDS_Face& aFace = TopoDS::Face(aLF.First());
+            if (aFace.Orientation() != TopAbs_INTERNAL) {
+              continue;
+            }
+          }
+          //
          if (!Boundary.Contains(anEdge)  && 
              !BRep_Tool::Degenerated(anEdge) )
            JeGarde = Standard_False;
index d3929ae1e22e96c100e5eb60b9fa32cb418f9751..30ea15943a8d48f30632fc0015d467fee80c282d 100644 (file)
@@ -18,8 +18,8 @@
 
 class Inter2d from BRepOffset 
 
-       ---Purpose: Computes the intersections betwwen edges on a face
-       --          stores result is SD as AsDes from BRepOffset.
+        ---Purpose: Computes the intersections betwwen edges on a face
+        --          stores result is SD as AsDes from BRepOffset.
 
 uses
     AsDes               from BRepAlgo,
@@ -30,27 +30,28 @@ uses
     Real                from Standard
 
 is
-    Compute(myclass ; AsDes    : AsDes      from BRepAlgo;
-                     F        :         Face       from TopoDS;
-                             NewEdges :         IndexedMapOfShape from TopTools;
-                     Tol      :         Real       from Standard);
-                     
-       ---Purpose: Computes the intersections between the edges stored
-       --          is AsDes as descendants of <F> . Intersections is computed
-       --          between two edges if one of them is bound in NewEdges.
+    Compute(myclass ; AsDes    : AsDes             from BRepAlgo;
+                      F        : Face              from TopoDS;
+                      NewEdges : IndexedMapOfShape from TopTools;
+                      Tol      : Real              from Standard);
+                      
+              ---Purpose: Computes the intersections between the edges stored
+              --          is AsDes as descendants of <F> . Intersections is computed
+              --          between two edges if one of them is bound in NewEdges.
 
     
     --  Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
     --  Add another parameter: offset value.
     ConnexIntByInt(myclass ; 
-                  FI    :          Face                from TopoDS;
-                  OFI   : in out   Offset              from BRepOffset;
-                  MES   : in out   DataMapOfShapeShape from TopTools;  
-                  Build :          DataMapOfShapeShape from TopTools;  
-                  AsDes :  AsDes               from BRepAlgo; 
-                  Offset:          Real                from Standard;
-                  Tol   :          Real                from Standard);
+                   FI      :          Face                from TopoDS;
+                   OFI     : in out   Offset              from BRepOffset;
+                   MES     : in out   DataMapOfShapeShape from TopTools;  
+                   Build   :          DataMapOfShapeShape from TopTools;  
+                   AsDes   :          AsDes               from BRepAlgo; 
+                   AsDes2d :          AsDes               from BRepAlgo; 
+                   Offset  :          Real                from Standard;
+                   Tol     :          Real                from Standard);
     --  Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End
-                           
+                            
 end Inter2d;
 
index 2c6c6438a20e1ca0787383ea6a3f02482cd48686..43d7e32f7f9309e12c16b8839cd9c68589d627d7 100644 (file)
@@ -95,7 +95,7 @@ static Standard_Integer NbNewVertices  = 0;
 //=======================================================================
 
 static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
-                                 TopoDS_Edge& E2)
+                                  TopoDS_Edge& E2)
 {
   TopoDS_Vertex V1[2],V2[2],V;
   //  Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
@@ -120,11 +120,11 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
 //=======================================================================
 
 static void  Store (const TopoDS_Edge&       E1,
-                   const TopoDS_Edge&       E2,
-                   TopTools_ListOfShape&    LV1,
-                   TopTools_ListOfShape&    LV2,
-                   Handle(BRepAlgo_AsDes)   AsDes,
-                   Standard_Real            Tol)
+                    const TopoDS_Edge&       E2,
+                    TopTools_ListOfShape&    LV1,
+                    TopTools_ListOfShape&    LV2,
+                    Handle(BRepAlgo_AsDes)   AsDes,
+                    Standard_Real            Tol)
 {
   //-------------------------------------------------------------
   // Test if the points of intersection correspond to existing 
@@ -165,90 +165,90 @@ static void  Store (const TopoDS_Edge&       E1,
       // Find if the point of intersection corresponds to a vertex of E1.
       //-----------------------------------------------------------------
       for (it.Initialize(VOnE1); it.More(); it.Next()) {
-       P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
-       if (P.IsEqual(P1,Tol)) {
-         V    = TopoDS::Vertex(it.Value());
-         V1   = V;
-         OnE1 = Standard_True;
-         break;
-       }
+        P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
+        if (P.IsEqual(P1,Tol)) {
+          V    = TopoDS::Vertex(it.Value());
+          V1   = V;
+          OnE1 = Standard_True;
+          break;
+        }
       }
     }
     if (!VOnE2.IsEmpty()) {
       if (OnE1) {
-       //-----------------------------------------------------------------
-       // Find if the vertex found on E1 is not already on E2.
-       //-----------------------------------------------------------------
-       for (it.Initialize(VOnE2); it.More(); it.Next()) {
-         if (it.Value().IsSame(V)) {
-           OnE2 = Standard_True;
-           V2   = V;
-           break;
-         }
-       }
+        //-----------------------------------------------------------------
+        // Find if the vertex found on E1 is not already on E2.
+        //-----------------------------------------------------------------
+        for (it.Initialize(VOnE2); it.More(); it.Next()) {
+          if (it.Value().IsSame(V)) {
+            OnE2 = Standard_True;
+            V2   = V;
+            break;
+          }
+        }
       }
       for (it.Initialize(VOnE2); it.More(); it.Next()) {
-       //-----------------------------------------------------------------
-       // Find if the point of intersection corresponds to a vertex of E2.
-       //-----------------------------------------------------------------
-       P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
-       if (P.IsEqual(P2,Tol)) {
-         V  = TopoDS::Vertex(it.Value());
-         V2 = V;
-         OnE2 = Standard_True;
-         break;
-       }
+        //-----------------------------------------------------------------
+        // Find if the point of intersection corresponds to a vertex of E2.
+        //-----------------------------------------------------------------
+        P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
+        if (P.IsEqual(P2,Tol)) {
+          V  = TopoDS::Vertex(it.Value());
+          V2 = V;
+          OnE2 = Standard_True;
+          break;
+        }
       }      
     }  
     if (OnE1 && OnE2) {
       if (!V1.IsSame(V2)) {
-       //---------------------------------------------------------------
-       // Two vertices are actually the same.
-       // V2 will be replaced by V1. 
-       // update the parameters of vertex on edges.
-       //---------------------------------------------------------------
-       Standard_Real UV2;
-       TopoDS_Edge   EWE2;
-       const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
-
-       for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
-         EWE2  = TopoDS::Edge(it.Value());
-         TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
-         UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
-//       UV2   = 
-//         BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
-         aLocalShape = V1.Oriented(TopAbs_INTERNAL);
-         B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
-//       B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
-//                      UV2,EWE2,Tol);
-       }
-       AsDes->Replace(V2,V1);
+        //---------------------------------------------------------------
+        // Two vertices are actually the same.
+        // V2 will be replaced by V1. 
+        // update the parameters of vertex on edges.
+        //---------------------------------------------------------------
+        Standard_Real UV2;
+        TopoDS_Edge   EWE2;
+        const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
+
+        for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
+          EWE2  = TopoDS::Edge(it.Value());
+          TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
+          UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
+//          UV2   = 
+//            BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
+          aLocalShape = V1.Oriented(TopAbs_INTERNAL);
+          B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
+//          B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
+//                         UV2,EWE2,Tol);
+        }
+        AsDes->Replace(V2,V1);
       }
     }
     if (!OnE1) {
       if (OnE2) {
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U1,E1,Tol);
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U1,E1,Tol);
       }
       NewVOnE1.Append(V.Oriented(O1));
     }
     if (!OnE2) {
       if (OnE1) {
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U2,E2,Tol);
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U2,E2,Tol);
       }
       NewVOnE2.Append(V.Oriented(O2));
     }
     
 #ifdef DRAW
-   if (Inter2dAffichInt2d) {     
+   if (Inter2dAffichInt2d) {          
      if (!OnE1 && !OnE2) {
        char name[256];
-       sprintf(name,"VV_%d",NbNewVertices++);  
+       sprintf(name,"VV_%d",NbNewVertices++);        
        DBRep::Set(name,V);
      }
    }  
@@ -265,11 +265,12 @@ static void  Store (const TopoDS_Edge&       E1,
 //=======================================================================
 
 static void EdgeInter(const TopoDS_Face&              F,
-                     const TopoDS_Edge&              E1,
-                     const TopoDS_Edge&              E2,
-                     const Handle(BRepAlgo_AsDes)&   AsDes,
-                     Standard_Real                   Tol,
-                     Standard_Boolean                WithOri)
+                      const BRepAdaptor_Surface&      BAsurf,
+                      const TopoDS_Edge&              E1,
+                      const TopoDS_Edge&              E2,
+                      const Handle(BRepAlgo_AsDes)&   AsDes,
+                      Standard_Real                   Tol,
+                      Standard_Boolean                WithOri)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -314,117 +315,117 @@ static void EdgeInter(const TopoDS_Face&              F,
       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())
-           {
-             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() );
-           }
-       }
-      BRepAdaptor_Surface BAsurf(F);
+        {
+          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() );
+            }
+        }
+      
       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]);
       Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
       Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
       Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
       for (i = 1; i <= Inter2d.NbPoints(); i++)
-       {
-         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_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() );
+        }
 
       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
-             cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
+              cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
 #endif
-             continue;
-           }
-         
-         gp_Pnt P = ResPoints(i); //ponc1.Value();
-         TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
+              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 );
-         
+          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)
-           {
-             cout << "out of limit"<<endl;
-             cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
-           }
-         if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
-           {
-             cout << "out of limit"<<endl;
-             cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
-           }
+          if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
+            {
+              cout << "out of limit"<<endl;
+              cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
+            }
+          if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
+            {
+              cout << "out of limit"<<endl;
+              cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
+            }
           Standard_Real MilTol2 = 1000*Tol*Tol;
-         if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
-           {
-             cout << "Inter2d : Solution rejected "<<endl;
-             cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
-             cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
-             cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
-             cout<<"MaxDist = "<<dist1<<endl;
-           }
+          if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
+            {
+              cout << "Inter2d : Solution rejected "<<endl;
+              cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
+              cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
+              cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
+              cout<<"MaxDist = "<<dist1<<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())
-               cout<<endl<<"CrossProd = "<<CrossProd<<endl;
+              if (Abs(CrossProd) <= gp::Resolution())
+                cout<<endl<<"CrossProd = "<<CrossProd<<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;
+            }
+          LV1.Append( aNewVertex.Oriented(OO1) );
+          LV2.Append( aNewVertex.Oriented(OO2) );
+        }
     }
   
   //----------------------------------
@@ -445,30 +446,30 @@ static void EdgeInter(const TopoDS_Face&              F,
       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
       Standard_Real Dist = P1.Distance(P2); 
       if (Dist < TolConf) {
-       TopoDS_Vertex V = BRepLib_MakeVertex(P1);
-       U1 = (j == 0) ? f[1] : l[1];
-       U2 = (k == 0) ? f[2] : l[2];
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        TopoDS_Vertex V = BRepLib_MakeVertex(P1);
+        U1 = (j == 0) ? f[1] : l[1];
+        U2 = (k == 0) ? f[2] : l[2];
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
 //  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
-       Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
-
-       if (!V1[j].IsSame(V2[k])) {
-         Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
-
-         aTol = Max(aTol, aTol2);
-       }
-
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
-//     B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U2,E2,Tol);
+        Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
+
+        if (!V1[j].IsSame(V2[k])) {
+          Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
+
+          aTol = Max(aTol, aTol2);
+        }
+
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
+//         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
+//         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U1,E1,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U2,E2,Tol);
 //  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
-       LV1.Prepend(V.Oriented(V1[j].Orientation()));
-       LV2.Prepend(V.Oriented(V2[k].Orientation()));
+        LV1.Prepend(V.Oriented(V1[j].Orientation()));
+        LV2.Prepend(V.Oriented(V2[k].Orientation()));
       }
     }
   }
@@ -488,31 +489,31 @@ static void EdgeInter(const TopoDS_Face&              F,
       i = 1;
       Purge = Standard_False;
       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
-          it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
-       j = 1;
-       it2LV1.Initialize(LV1);
-       while (j < i) {      
-         P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
-         P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
+           it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
+        j = 1;
+        it2LV1.Initialize(LV1);
+        while (j < i) {      
+          P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
+          P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
 //  Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
-//       if (P1.IsEqual(P2,10*Tol)) {
-         Standard_Real aTol;
+//           if (P1.IsEqual(P2,10*Tol)) {
+          Standard_Real aTol;
 
-         aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
-                    BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
-         if (P1.IsEqual(P2,aTol)) {
+          aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
+                     BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
+          if (P1.IsEqual(P2,aTol)) {
 //  Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
-           LV1.Remove(it1LV1);
-           LV2.Remove(it1LV2);
-           if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
-           Purge = Standard_True;
-           break;
-         }
-         j++;
-         it2LV1.Next();
-       }
-       if (Purge) break;
-       i++;
+            LV1.Remove(it1LV1);
+            LV2.Remove(it1LV2);
+            if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
+            Purge = Standard_True;
+            break;
+          }
+          j++;
+          it2LV1.Next();
+        }
+        if (Purge) break;
+        i++;
       }
     }
     //---------------------------------
@@ -535,12 +536,13 @@ static void EdgeInter(const TopoDS_Face&              F,
 //=======================================================================
 
 static void RefEdgeInter(const TopoDS_Face&              F,
-                        const TopoDS_Edge&              E1,
-                        const TopoDS_Edge&              E2,
-                        const Handle(BRepAlgo_AsDes)&   AsDes,
-                        Standard_Real                   Tol,
-                        Standard_Boolean                WithOri,
-                        gp_Pnt&                         Pref)
+                         const BRepAdaptor_Surface&      BAsurf,
+                         const TopoDS_Edge&              E1,
+                         const TopoDS_Edge&              E2,
+                         const Handle(BRepAlgo_AsDes)&   AsDes,
+                         Standard_Real                   Tol,
+                         Standard_Boolean                WithOri,
+                         gp_Pnt&                         Pref)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -586,17 +588,17 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       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);
-       }
+        {
+          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() );
-       }
+        {
+          BRepAdaptor_Curve CEdeg( EI[ideg], F );
+          DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
+        }
     }
-  BRepAdaptor_Surface BAsurf(F);
+  
   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]);
   Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
@@ -606,12 +608,12 @@ static void RefEdgeInter(const TopoDS_Face&              F,
     {
       gp_Pnt P3d;
       if (WithDegen)
-       P3d = DegPoint;
+        P3d = DegPoint;
       else
-       {
-         gp_Pnt2d P2d = Inter2d.Point(i).Value();
-         P3d = BAsurf.Value( P2d.X(), P2d.Y() );
-       }
+        {
+          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() );
@@ -622,12 +624,12 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
       Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
       if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
-       {
+        {
 #ifdef OCCT_DEBUG
-         cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
+          cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
 #endif
-         continue;
-       }
+          continue;
+        }
       
       gp_Pnt P = ResPoints(i); //ponc1.Value();
       TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
@@ -646,50 +648,50 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       
 #ifdef OCCT_DEBUG
       if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
-       {
-         cout << "out of limit"<<endl;
-         cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
-       }
+        {
+          cout << "out of limit"<<endl;
+          cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
+        }
       if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
-       {
-         cout << "out of limit"<<endl;
-         cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
-       }
+        {
+          cout << "out of limit"<<endl;
+          cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
+        }
       Standard_Real MilTol2 = 1000*Tol*Tol;
       if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
-       {
-         cout << "Inter2d : Solution rejected"<<endl;
-         cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
-         cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
-         cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
-         cout<<"MaxDist = "<<dist1<<endl;
-       }
+        {
+          cout << "Inter2d : Solution rejected"<<endl;
+          cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
+          cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
+          cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
+          cout<<"MaxDist = "<<dist1<<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;
+        {
+          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())
-           cout<<endl<<"CrossProd = "<<CrossProd<<endl;
+          if (Abs(CrossProd) <= gp::Resolution())
+            cout<<endl<<"CrossProd = "<<CrossProd<<endl;
 #endif
-         if (CrossProd > 0.)
-           OO1 = TopAbs_FORWARD;
-         CrossProd = V1or ^ V2;
-         if (CrossProd > 0.)
-           OO2 = TopAbs_FORWARD;
-       }
+          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) );
     }
@@ -712,18 +714,18 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
       Standard_Real Dist = P1.Distance(P2); 
       if (Dist < TolConf) {
-       TopoDS_Vertex V = BRepLib_MakeVertex(P1);
-       U1 = (j == 0) ? f[1] : l[1];
-       U2 = (k == 0) ? f[2] : l[2];
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U2,E2,Tol);
-       LV1.Prepend(V.Oriented(V1[j].Orientation()));
-       LV2.Prepend(V.Oriented(V2[k].Orientation()));
+        TopoDS_Vertex V = BRepLib_MakeVertex(P1);
+        U1 = (j == 0) ? f[1] : l[1];
+        U2 = (k == 0) ? f[2] : l[2];
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U1,E1,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U2,E2,Tol);
+        LV1.Prepend(V.Oriented(V1[j].Orientation()));
+        LV2.Prepend(V.Oriented(V2[k].Orientation()));
       }
     }
   }
@@ -743,24 +745,24 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       i = 1;
       Purge = Standard_False;
       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
-          it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
-       j = 1;
-       it2LV1.Initialize(LV1);
-       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)) {
-           LV1.Remove(it1LV1);
-           LV2.Remove(it1LV2);
-           if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
-           Purge = Standard_True;
-           break;
-         }
-         j++;
-         it2LV1.Next();
-       }
-       if (Purge) break;
-       i++;
+           it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
+        j = 1;
+        it2LV1.Initialize(LV1);
+        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)) {
+            LV1.Remove(it1LV1);
+            LV2.Remove(it1LV2);
+            if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
+            Purge = Standard_True;
+            break;
+          }
+          j++;
+          it2LV1.Next();
+        }
+        if (Purge) break;
+        i++;
       }
     }
     //---------------------------------
@@ -772,20 +774,20 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       Standard_Real dmin = RealLast();
       TopoDS_Vertex Vmin;
       for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
-       gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
-       Standard_Real d = P.SquareDistance(Pref);
-       if(d < dmin) {
-         dmin = d;
-         Vmin = TopoDS::Vertex(it1LV1.Value());
-       }
+        gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
+        Standard_Real d = P.SquareDistance(Pref);
+        if(d < dmin) {
+          dmin = d;
+          Vmin = TopoDS::Vertex(it1LV1.Value());
+        }
       }
       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
-          it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
-       if(!Vmin.IsSame(it1LV1.Value())) {
-         LV1.Remove(it1LV1);
-         LV2.Remove(it1LV2);
-         if(!it1LV1.More()) break;
-       }
+           it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
+        if(!Vmin.IsSame(it1LV1.Value())) {
+          LV1.Remove(it1LV1);
+          LV2.Remove(it1LV2);
+          if(!it1LV1.More()) break;
+        }
       }
     }
       
@@ -803,7 +805,6 @@ static void RefEdgeInter(const TopoDS_Face&              F,
   }
 }
 
-
 //======================================================================
 //function : EvaluateMaxSegment
 //purpose  : return MaxSegment to pass in approximation
@@ -834,10 +835,10 @@ static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurv
 //=======================================================================
 
 static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
-                                    const Standard_Real anEf,
-                                    const Standard_Real anEl,
-                                    const Standard_Real a2Offset,
-                                    Handle(Geom2d_Curve)& NewPCurve)
+                                     const Standard_Real anEf,
+                                     const Standard_Real anEl,
+                                     const Standard_Real a2Offset,
+                                     Handle(Geom2d_Curve)& NewPCurve)
 {
   NewPCurve = aPCurve;
   if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
@@ -850,29 +851,29 @@ static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
       (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
     {
       if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
-       {
-         Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
-         if (aBezier->NbPoles() == 2)
-           {
-             TColgp_Array1OfPnt2d thePoles(1,2);
-             aBezier->Poles(thePoles);
-             gp_Vec2d aVec(thePoles(1), thePoles(2));
-             NewPCurve = new Geom2d_Line(thePoles(1), aVec);
-             return Standard_True;
-           }
-       }
+        {
+          Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
+          if (aBezier->NbPoles() == 2)
+            {
+              TColgp_Array1OfPnt2d thePoles(1,2);
+              aBezier->Poles(thePoles);
+              gp_Vec2d aVec(thePoles(1), thePoles(2));
+              NewPCurve = new Geom2d_Line(thePoles(1), aVec);
+              return Standard_True;
+            }
+        }
       else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
-       {
-         Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
-         if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
-           {
-             TColgp_Array1OfPnt2d thePoles(1,2);
-             aBSpline->Poles(thePoles);
-             gp_Vec2d aVec(thePoles(1), thePoles(2));
-             NewPCurve = new Geom2d_Line(thePoles(1), aVec);
-             return Standard_True;
-           }
-       }
+        {
+          Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
+          if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
+            {
+              TColgp_Array1OfPnt2d thePoles(1,2);
+              aBSpline->Poles(thePoles);
+              gp_Vec2d aVec(thePoles(1), thePoles(2));
+              NewPCurve = new Geom2d_Line(thePoles(1), aVec);
+              return Standard_True;
+            }
+        }
     }
 
   FirstPar = aPCurve->FirstParameter();
@@ -955,161 +956,161 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
       Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
       Standard_Real FirstPar, LastPar;
       if (CurveRep->IsCurveOnSurface())
-       {
-         NbPCurves++;
-         Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
-         FirstPar = theCurve->FirstParameter();
-         LastPar  = theCurve->LastParameter();
-
-         if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
-             (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
-           {
-             Handle(Geom2d_Curve) NewPCurve;
-             if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
-               {
-                 CurveRep->PCurve(NewPCurve);
-                 FirstPar = NewPCurve->FirstParameter();
-                 LastPar  = NewPCurve->LastParameter();
-                 if (CurveRep->IsCurveOnClosedSurface())
-                   {
-                     Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
-                     if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
-                       CurveRep->PCurve2(NewPCurve);
-                   }
-               }
-           }
-         else if (theCurve->IsPeriodic())
-           {
-             Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
-             delta *= 0.95;
-             FirstPar = anEf - delta;
-             LastPar  = anEl + delta;
-           }
-         else if (theCurve->IsClosed())
-           LastPar -= 0.05*(LastPar - FirstPar);
-
-         //check FirstPar and LastPar: the pcurve should be in its surface
-         theCurve = CurveRep->PCurve();
-         Handle(Geom_Surface) theSurf = CurveRep->Surface();
-         Standard_Real Umin, Umax, Vmin, Vmax;
-         theSurf->Bounds(Umin, Umax, Vmin, Vmax);
-         TColGeom2d_SequenceOfCurve BoundLines;
-         if (!Precision::IsInfinite(Vmin))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
-                                                         gp_Dir2d( 1., 0. ));
-             BoundLines.Append(aLine);
-           }
-         if (!Precision::IsInfinite(Umin))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
-                                                         gp_Dir2d( 0., 1. ));
-             BoundLines.Append(aLine);
-           }
-         if (!Precision::IsInfinite(Vmax))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
-                                                         gp_Dir2d( 1., 0. ));
-             BoundLines.Append(aLine);
-           }
-         if (!Precision::IsInfinite(Umax))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
-                                                         gp_Dir2d( 0., 1. ));
-             BoundLines.Append(aLine);
-           }
-
-         TColStd_SequenceOfReal params;
-         Geom2dInt_GInter IntCC;
-         Geom2dAdaptor_Curve GAcurve(theCurve);
-         for (i = 1; i <= BoundLines.Length(); i++)
-           {
-             Geom2dAdaptor_Curve GAline( BoundLines(i) );
-             IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
-             if (IntCC.IsDone())
-               {
-                 for (j = 1; j <= IntCC.NbPoints(); j++)
-                   {
-                     const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
-                     gp_Pnt2d aPoint = ip.Value();
-                     if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
-                         aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
-                       params.Append( ip.ParamOnFirst() );
-                   }
-                 for (j = 1; j <= IntCC.NbSegments(); j++)
-                   {
-                     const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
-                     if (is.HasFirstPoint())
-                       {
-                         const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
-                         gp_Pnt2d aPoint = ip.Value();
-                         if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
-                             aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
-                           params.Append( ip.ParamOnFirst() );
-                       }
-                     if (is.HasLastPoint())
-                       {
-                         const IntRes2d_IntersectionPoint& ip = is.LastPoint();
-                         gp_Pnt2d aPoint = ip.Value();
-                         if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
-                             aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
-                           params.Append( ip.ParamOnFirst() );
-                       }
-                   }
-               }
-           }
-         if (!params.IsEmpty())
-           {
-             if (params.Length() == 1)
-               {
-                 gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
-                 if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
-                     PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
-                   {
-                     if (LastPar > params(1))
-                       LastPar = params(1);
-                   }
-                 else if (FirstPar < params(1))
-                   FirstPar = params(1);
-               }
-             else
-               {
-                 Standard_Real fpar = RealLast(), lpar = RealFirst();
-                 for (i = 1; i <= params.Length(); i++)
-                   {
-                     if (params(i) < fpar)
-                       fpar = params(i);
-                     if (params(i) > lpar)
-                       lpar = params(i);
-                   }
-                 if (FirstPar < fpar)
-                   FirstPar = fpar;
-                 if (LastPar > lpar)
-                   LastPar = lpar;
-               }
-           }
-         //// end of check ////
-         (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
-         //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
-         //gp_Pnt2d Plast  = theCurve->Value(LastPar);
-         //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
-
-         //update FirstParOnPC and LastParOnPC
-         if (FirstPar > FirstParOnPC)
-           {
-             FirstParOnPC = FirstPar;
-             MinPC   = theCurve;
-             MinSurf = theSurf;
-             MinLoc  = CurveRep->Location();
-           }
-         if (LastPar  < LastParOnPC)
-           {
-             LastParOnPC  = LastPar;
-             MinPC   = theCurve;
-             MinSurf = theSurf;
-             MinLoc  = CurveRep->Location();
-           }
-       }
+        {
+          NbPCurves++;
+          Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
+          FirstPar = theCurve->FirstParameter();
+          LastPar  = theCurve->LastParameter();
+
+          if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
+              (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
+            {
+              Handle(Geom2d_Curve) NewPCurve;
+              if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
+                {
+                  CurveRep->PCurve(NewPCurve);
+                  FirstPar = NewPCurve->FirstParameter();
+                  LastPar  = NewPCurve->LastParameter();
+                  if (CurveRep->IsCurveOnClosedSurface())
+                    {
+                      Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
+                      if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
+                        CurveRep->PCurve2(NewPCurve);
+                    }
+                }
+            }
+          else if (theCurve->IsPeriodic())
+            {
+              Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
+              delta *= 0.95;
+              FirstPar = anEf - delta;
+              LastPar  = anEl + delta;
+            }
+          else if (theCurve->IsClosed())
+            LastPar -= 0.05*(LastPar - FirstPar);
+
+          //check FirstPar and LastPar: the pcurve should be in its surface
+          theCurve = CurveRep->PCurve();
+          Handle(Geom_Surface) theSurf = CurveRep->Surface();
+          Standard_Real Umin, Umax, Vmin, Vmax;
+          theSurf->Bounds(Umin, Umax, Vmin, Vmax);
+          TColGeom2d_SequenceOfCurve BoundLines;
+          if (!Precision::IsInfinite(Vmin))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
+                                                          gp_Dir2d( 1., 0. ));
+              BoundLines.Append(aLine);
+            }
+          if (!Precision::IsInfinite(Umin))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
+                                                          gp_Dir2d( 0., 1. ));
+              BoundLines.Append(aLine);
+            }
+          if (!Precision::IsInfinite(Vmax))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
+                                                          gp_Dir2d( 1., 0. ));
+              BoundLines.Append(aLine);
+            }
+          if (!Precision::IsInfinite(Umax))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
+                                                          gp_Dir2d( 0., 1. ));
+              BoundLines.Append(aLine);
+            }
+
+          TColStd_SequenceOfReal params;
+          Geom2dInt_GInter IntCC;
+          Geom2dAdaptor_Curve GAcurve(theCurve);
+          for (i = 1; i <= BoundLines.Length(); i++)
+            {
+              Geom2dAdaptor_Curve GAline( BoundLines(i) );
+              IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
+              if (IntCC.IsDone())
+                {
+                  for (j = 1; j <= IntCC.NbPoints(); j++)
+                    {
+                      const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
+                      gp_Pnt2d aPoint = ip.Value();
+                      if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
+                          aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
+                        params.Append( ip.ParamOnFirst() );
+                    }
+                  for (j = 1; j <= IntCC.NbSegments(); j++)
+                    {
+                      const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
+                      if (is.HasFirstPoint())
+                        {
+                          const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
+                          gp_Pnt2d aPoint = ip.Value();
+                          if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
+                              aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
+                            params.Append( ip.ParamOnFirst() );
+                        }
+                      if (is.HasLastPoint())
+                        {
+                          const IntRes2d_IntersectionPoint& ip = is.LastPoint();
+                          gp_Pnt2d aPoint = ip.Value();
+                          if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
+                              aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
+                            params.Append( ip.ParamOnFirst() );
+                        }
+                    }
+                }
+            }
+          if (!params.IsEmpty())
+            {
+              if (params.Length() == 1)
+                {
+                  gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
+                  if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
+                      PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
+                    {
+                      if (LastPar > params(1))
+                        LastPar = params(1);
+                    }
+                  else if (FirstPar < params(1))
+                    FirstPar = params(1);
+                }
+              else
+                {
+                  Standard_Real fpar = RealLast(), lpar = RealFirst();
+                  for (i = 1; i <= params.Length(); i++)
+                    {
+                      if (params(i) < fpar)
+                        fpar = params(i);
+                      if (params(i) > lpar)
+                        lpar = params(i);
+                    }
+                  if (FirstPar < fpar)
+                    FirstPar = fpar;
+                  if (LastPar > lpar)
+                    LastPar = lpar;
+                }
+            }
+          //// end of check ////
+          (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
+          //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
+          //gp_Pnt2d Plast  = theCurve->Value(LastPar);
+          //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
+
+          //update FirstParOnPC and LastParOnPC
+          if (FirstPar > FirstParOnPC)
+            {
+              FirstParOnPC = FirstPar;
+              MinPC   = theCurve;
+              MinSurf = theSurf;
+              MinLoc  = CurveRep->Location();
+            }
+          if (LastPar  < LastParOnPC)
+            {
+              LastParOnPC  = LastPar;
+              MinPC   = theCurve;
+              MinSurf = theSurf;
+              MinLoc  = CurveRep->Location();
+            }
+        }
     }
 
   Standard_Real f, l;
@@ -1118,168 +1119,168 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
     {
       MinLoc = E.Location() * MinLoc;
       if (!C3d.IsNull())
-       {
-         if (MinPC->IsClosed())
-           {
-             f = FirstParOnPC;
-             l = LastParOnPC;
-           }
-         else if (C3d->IsPeriodic())
-           {
-             Standard_Real delta = (C3d->Period() - (l - f))*0.5;
-             delta *= 0.95;
-             f -= delta;
-             l += delta;
-           }
-         else if (C3d->IsClosed())
-           l -= 0.05*(l - f);
-         else
-           {
-             f = FirstParOnPC;
-             l = LastParOnPC;
-             GeomAPI_ProjectPointOnCurve Projector;
-             if (!Precision::IsInfinite(FirstParOnPC))
-               {
-                 gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
-                 gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
-                 P1.Transform(MinLoc.Transformation());
-                 Projector.Init( P1, C3d );
-                 if (Projector.NbPoints() > 0)
-                   f = Projector.LowerDistanceParameter();
+        {
+          if (MinPC->IsClosed())
+            {
+              f = FirstParOnPC;
+              l = LastParOnPC;
+            }
+          else if (C3d->IsPeriodic())
+            {
+              Standard_Real delta = (C3d->Period() - (l - f))*0.5;
+              delta *= 0.95;
+              f -= delta;
+              l += delta;
+            }
+          else if (C3d->IsClosed())
+            l -= 0.05*(l - f);
+          else
+            {
+              f = FirstParOnPC;
+              l = LastParOnPC;
+              GeomAPI_ProjectPointOnCurve Projector;
+              if (!Precision::IsInfinite(FirstParOnPC))
+                {
+                  gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
+                  gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
+                  P1.Transform(MinLoc.Transformation());
+                  Projector.Init( P1, C3d );
+                  if (Projector.NbPoints() > 0)
+                    f = Projector.LowerDistanceParameter();
 #ifdef OCCT_DEBUG
-                 else
-                   cout<<"ProjectPointOnCurve not done"<<endl;
+                  else
+                    cout<<"ProjectPointOnCurve not done"<<endl;
 #endif
-               }
-             if (!Precision::IsInfinite(LastParOnPC))
-               {
-                 gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
-                 gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
-                 P2.Transform(MinLoc.Transformation());
-                 Projector.Init( P2, C3d );
-                 if (Projector.NbPoints() > 0)
-                   l = Projector.LowerDistanceParameter();
+                }
+              if (!Precision::IsInfinite(LastParOnPC))
+                {
+                  gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
+                  gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
+                  P2.Transform(MinLoc.Transformation());
+                  Projector.Init( P2, C3d );
+                  if (Projector.NbPoints() > 0)
+                    l = Projector.LowerDistanceParameter();
 #ifdef OCCT_DEBUG
-                 else
-                   cout<<"ProjectPointOnCurve not done"<<endl;
+                  else
+                    cout<<"ProjectPointOnCurve not done"<<endl;
 #endif
-               }
-           }
-         BB.Range( NE, f, l );
-         if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
-           BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-       }
+                }
+            }
+          BB.Range( NE, f, l );
+          if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
+            BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+        }
       else if (!BRep_Tool::Degenerated(E)) //no 3d curve
-       {
-         MinSurf = Handle(Geom_Surface)::DownCast
-           (MinSurf->Transformed(MinLoc.Transformation()));
-         Standard_Real max_deviation = 0.;
-         if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
-           {
-             if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
-               {
-                 Standard_Boolean IsLine = Standard_False;
-                 if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
-                   IsLine = Standard_True;
-                 else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
-                          MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
-                   {
-                     Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
-                     gp_Dir2d LineDir = theLine->Direction();
-                     if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
-                       IsLine = Standard_True;
-                   }
-                 if (IsLine)
-                   {
-                     gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
-                     gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
-                     gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
-                     gp_Vec aVec(P1, P2);
-                     C3d = new Geom_Line( P1, aVec );
-                   }
-               }
-           }
-         else
-           {
-             Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
-             GeomAdaptor_Surface GAsurf( MinSurf );
-             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,*/ average_deviation;
-             GeomAbs_Shape Continuity = GeomAbs_C1;
-             Standard_Integer MaxDegree = 14;
-             Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
-             GeomLib::BuildCurve3d(Precision::Confusion(),
-                                   ConS, FirstParOnPC, LastParOnPC,
-                                   C3d, max_deviation, average_deviation,
-                                   Continuity, MaxDegree, MaxSegment);
-           }
-         BB.UpdateEdge( NE, C3d, max_deviation );
-         //BB.Range( NE, FirstParOnPC, LastParOnPC );
-         Standard_Boolean ProjectionSuccess = Standard_True;
-         if (NbPCurves > 1)
-           //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-           for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
-                itr.More();
-                itr.Next())
-             {
-               Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
-               Standard_Real FirstPar, LastPar;
-               if (CurveRep->IsCurveOnSurface())
-                 {
-                   Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
-                   Handle(Geom_Surface) theSurf  = CurveRep->Surface();
-                   TopLoc_Location      theLoc   = CurveRep->Location();
-                   if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
-                     continue;
-                   FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
-                   LastPar  = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
-                   if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
-                       Abs(LastPar  - LastParOnPC)  > Precision::PConfusion())
-                     {
-                       theLoc = E.Location() * theLoc;
-                       theSurf = Handle(Geom_Surface)::DownCast
-                         (theSurf->Transformed(theLoc.Transformation()));
-
-                       if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
-                           theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
-                         {
-                           gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
-                           if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
-                               theDir.IsParallel(gp::DY2d(), Precision::Angular()))
-                             {
-                               Standard_Real U1, U2, V1, V2;
-                               theSurf->Bounds(U1, U2, V1, V2);
-                               gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
-                               if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
-                                   Abs(Origin.X()-U2) <= Precision::Confusion() ||
-                                   Abs(Origin.Y()-V1) <= Precision::Confusion() ||
-                                   Abs(Origin.Y()-V2) <= Precision::Confusion())
-                                 {
-                                   BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-                                   break;
-                                 }
-                             }
-                         }
-
-                       Handle(Geom2d_Curve) ProjPCurve =
-                         GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
-                       if (ProjPCurve.IsNull())
-                         ProjectionSuccess = Standard_False;
-                       else
-                         CurveRep->PCurve( ProjPCurve );
-                     }
-                 }
-             }
-         if (ProjectionSuccess)
-           BB.Range( NE, FirstParOnPC, LastParOnPC );
-         else
-           {
-             BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
-             BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-           }
-       }
+        {
+          MinSurf = Handle(Geom_Surface)::DownCast
+            (MinSurf->Transformed(MinLoc.Transformation()));
+          Standard_Real max_deviation = 0.;
+          if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
+            {
+              if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
+                {
+                  Standard_Boolean IsLine = Standard_False;
+                  if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
+                    IsLine = Standard_True;
+                  else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
+                           MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
+                    {
+                      Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
+                      gp_Dir2d LineDir = theLine->Direction();
+                      if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
+                        IsLine = Standard_True;
+                    }
+                  if (IsLine)
+                    {
+                      gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
+                      gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
+                      gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
+                      gp_Vec aVec(P1, P2);
+                      C3d = new Geom_Line( P1, aVec );
+                    }
+                }
+            }
+          else
+            {
+              Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
+              GeomAdaptor_Surface GAsurf( MinSurf );
+              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,*/ average_deviation;
+              GeomAbs_Shape Continuity = GeomAbs_C1;
+              Standard_Integer MaxDegree = 14;
+              Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
+              GeomLib::BuildCurve3d(Precision::Confusion(),
+                                    ConS, FirstParOnPC, LastParOnPC,
+                                    C3d, max_deviation, average_deviation,
+                                    Continuity, MaxDegree, MaxSegment);
+            }
+          BB.UpdateEdge( NE, C3d, max_deviation );
+          //BB.Range( NE, FirstParOnPC, LastParOnPC );
+          Standard_Boolean ProjectionSuccess = Standard_True;
+          if (NbPCurves > 1)
+            //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+            for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
+                 itr.More();
+                 itr.Next())
+              {
+                Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
+                Standard_Real FirstPar, LastPar;
+                if (CurveRep->IsCurveOnSurface())
+                  {
+                    Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
+                    Handle(Geom_Surface) theSurf  = CurveRep->Surface();
+                    TopLoc_Location      theLoc   = CurveRep->Location();
+                    if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
+                      continue;
+                    FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
+                    LastPar  = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
+                    if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
+                        Abs(LastPar  - LastParOnPC)  > Precision::PConfusion())
+                      {
+                        theLoc = E.Location() * theLoc;
+                        theSurf = Handle(Geom_Surface)::DownCast
+                          (theSurf->Transformed(theLoc.Transformation()));
+
+                        if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
+                            theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
+                          {
+                            gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
+                            if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
+                                theDir.IsParallel(gp::DY2d(), Precision::Angular()))
+                              {
+                                Standard_Real U1, U2, V1, V2;
+                                theSurf->Bounds(U1, U2, V1, V2);
+                                gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
+                                if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
+                                    Abs(Origin.X()-U2) <= Precision::Confusion() ||
+                                    Abs(Origin.Y()-V1) <= Precision::Confusion() ||
+                                    Abs(Origin.Y()-V2) <= Precision::Confusion())
+                                  {
+                                    BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+                                    break;
+                                  }
+                              }
+                          }
+
+                        Handle(Geom2d_Curve) ProjPCurve =
+                          GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
+                        if (ProjPCurve.IsNull())
+                          ProjectionSuccess = Standard_False;
+                        else
+                          CurveRep->PCurve( ProjPCurve );
+                      }
+                  }
+              }
+          if (ProjectionSuccess)
+            BB.Range( NE, FirstParOnPC, LastParOnPC );
+          else
+            {
+              BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
+              BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+            }
+        }
     }
   else //no pcurves
     {
@@ -1287,58 +1288,58 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
       Standard_Real LastPar  = C3d->LastParameter();
       
       if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
-         (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
-       {
-         Handle(Geom_TrimmedCurve) aTrCurve = 
-           new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
-         
-         // The curve is not prolonged on begin or end.
-         // Trying to prolong it adding a segment to its bound.
-         gp_Pnt                              aPBnd;
-         gp_Vec                              aVBnd;
-         gp_Pnt                              aPBeg;
-         gp_Dir                              aDBnd;
-         Handle(Geom_Line)                   aLin;
-         Handle(Geom_TrimmedCurve)           aSegment;
-         GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
-         Standard_Real                       aTol = Precision::Confusion();
-         Standard_Real                       aDelta = Max(a2Offset, 1.);
-         
-         if (FirstPar > anEf - a2Offset) {
-           C3d->D1(FirstPar, aPBnd, aVBnd);
-           aDBnd.SetXYZ(aVBnd.XYZ());
-           aPBeg    = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
-           aLin     = new Geom_Line(aPBeg, aDBnd);
-           aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
-           
-           if (!aCompCurve.Add(aSegment, aTol))
-             return;
-         }
-         
-         if (LastPar < anEl + a2Offset) {
-           C3d->D1(LastPar, aPBeg, aVBnd);
-           aDBnd.SetXYZ(aVBnd.XYZ());
-           aLin     = new Geom_Line(aPBeg, aDBnd);
-           aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
-           
-           if (!aCompCurve.Add(aSegment, aTol))
-             return;
-         }
-         
-         C3d = aCompCurve.BSplineCurve();
-         FirstPar = C3d->FirstParameter();
-         LastPar  = C3d->LastParameter();
-         BB.UpdateEdge(NE, C3d, Precision::Confusion());
-       }
+          (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
+        {
+          Handle(Geom_TrimmedCurve) aTrCurve = 
+            new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
+          
+          // The curve is not prolonged on begin or end.
+          // Trying to prolong it adding a segment to its bound.
+          gp_Pnt                              aPBnd;
+          gp_Vec                              aVBnd;
+          gp_Pnt                              aPBeg;
+          gp_Dir                              aDBnd;
+          Handle(Geom_Line)                   aLin;
+          Handle(Geom_TrimmedCurve)           aSegment;
+          GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
+          Standard_Real                       aTol = Precision::Confusion();
+          Standard_Real                       aDelta = Max(a2Offset, 1.);
+          
+          if (FirstPar > anEf - a2Offset) {
+            C3d->D1(FirstPar, aPBnd, aVBnd);
+            aDBnd.SetXYZ(aVBnd.XYZ());
+            aPBeg    = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
+            aLin     = new Geom_Line(aPBeg, aDBnd);
+            aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
+            
+            if (!aCompCurve.Add(aSegment, aTol))
+              return;
+          }
+          
+          if (LastPar < anEl + a2Offset) {
+            C3d->D1(LastPar, aPBeg, aVBnd);
+            aDBnd.SetXYZ(aVBnd.XYZ());
+            aLin     = new Geom_Line(aPBeg, aDBnd);
+            aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
+            
+            if (!aCompCurve.Add(aSegment, aTol))
+              return;
+          }
+          
+          C3d = aCompCurve.BSplineCurve();
+          FirstPar = C3d->FirstParameter();
+          LastPar  = C3d->LastParameter();
+          BB.UpdateEdge(NE, C3d, Precision::Confusion());
+        }
       else if (C3d->IsPeriodic())
-       {
-         Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
-         delta *= 0.95;
-         FirstPar = anEf - delta;
-         LastPar  = anEl + delta;
-       }
+        {
+          Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
+          delta *= 0.95;
+          FirstPar = anEf - delta;
+          LastPar  = anEl + delta;
+        }
       else if (C3d->IsClosed())
-       LastPar -= 0.05*(LastPar - FirstPar);
+        LastPar -= 0.05*(LastPar - FirstPar);
       
       BB.Range( NE, FirstPar, LastPar );
     }
@@ -1352,9 +1353,9 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
 //=======================================================================
 
 static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
-                                     TopoDS_Edge&  OE,
-                                     TopoDS_Edge&  NE,
-                                     Standard_Real TolConf)
+                                      TopoDS_Edge&  OE,
+                                      TopoDS_Edge&  NE,
+                                      Standard_Real TolConf)
 {
   BRepAdaptor_Curve OC(OE);
   BRepAdaptor_Curve NC(NE);
@@ -1384,9 +1385,9 @@ static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
 //    TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
     aLocalShape = V.Oriented(TopAbs_INTERNAL);
     B.UpdateVertex(TopoDS::Vertex(aLocalShape),
-                  U,NE,BRep_Tool::Tolerance(NE));
+                   U,NE,BRep_Tool::Tolerance(NE));
 //    B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                U,NE,BRep_Tool::Tolerance(NE));
+//                   U,NE,BRep_Tool::Tolerance(NE));
   }
   return OK;  
 }
@@ -1397,9 +1398,9 @@ static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
 //=======================================================================
 
 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
-                                 const TopoDS_Face&                F,
-                                 const TopTools_IndexedMapOfShape& NewEdges,
-                                 const Standard_Real               Tol)
+                                  const TopoDS_Face&                F,
+                                  const TopTools_IndexedMapOfShape& NewEdges,
+                                  const Standard_Real               Tol)
 {
 #ifdef DRAW
   NbF2d++;
@@ -1416,8 +1417,8 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
   // calculate intersections2d on faces touched by  
   // intersection3d
   //---------------------------------------------------------
-  TopTools_ListIteratorOfListOfShape it1LE ;    
-  TopTools_ListIteratorOfListOfShape it2LE ;  
+  TopTools_ListIteratorOfListOfShape it1LE ;
+  TopTools_ListIteratorOfListOfShape it2LE ;
 
   //-----------------------------------------------
   // Intersection of edges 2*2.
@@ -1425,7 +1426,8 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
   const TopTools_ListOfShape&        LE = AsDes->Descendant(F);
   TopoDS_Vertex                      V1,V2;
   Standard_Integer                   j, i = 1;
-
+  BRepAdaptor_Surface BAsurf(F);
+  //
   for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
     const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());       
     j = 1;
@@ -1438,10 +1440,10 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
       // between them and with edges of restrictions
       //------------------------------------------------------
       if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
-          (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
-       TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
-       EdgeInter(TopoDS::Face(aLocalShape),E1,E2,AsDes,Tol,Standard_True);
-//       EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
+          (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
+        TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
+        EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True);
+        //  EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
       }
       it2LE.Next();
       j++;
@@ -1462,7 +1464,8 @@ void BRepOffset_Inter2d::ConnexIntByInt
  BRepOffset_Offset&            OFI,
  TopTools_DataMapOfShapeShape& MES,
  const TopTools_DataMapOfShapeShape& Build,
- const Handle(BRepAlgo_AsDes)&     AsDes,
+ const Handle(BRepAlgo_AsDes)& AsDes,
+ const Handle(BRepAlgo_AsDes)& AsDes2d,
  const Standard_Real           Offset,
  const Standard_Real           Tol)
 //  Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
@@ -1486,24 +1489,34 @@ void BRepOffset_Inter2d::ConnexIntByInt
     }
     if (YaBuild) {
       for (itL.Initialize(L); itL.More(); itL.Next()) {
-       const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
-       TopoDS_Shape aLocalShape = OFI.Generated(EI);
-       const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
-//     const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI));
-       if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
+        const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
+        TopoDS_Shape aLocalShape = OFI.Generated(EI);
+        const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
+//        const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI));
+        if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
 //  Modified by skv - Fri Dec 26 16:59:52 2003 OCC4455 Begin
-//       ExtentEdge(OE,NE);
-         ExtentEdge(OE,NE, Offset);
+//          ExtentEdge(OE,NE);
+          ExtentEdge(OE,NE, Offset);
 //  Modified by skv - Fri Dec 26 16:59:54 2003 OCC4455 End
-         MES.Bind  (OE,NE);
-       }
+          MES.Bind  (OE,NE);
+        }
       }
     } 
   }
-  
+
   TopoDS_Face           FIO = TopoDS::Face(OFI.Face());
   if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
-
+  //
+  TopTools_MapOfShape aME;
+  const TopTools_ListOfShape& aLE = AsDes->Descendant(FIO);
+  TopTools_ListIteratorOfListOfShape aItLE(aLE);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aE = aItLE.Value();
+    aME.Add(aE);
+  }
+  //
+  BRepAdaptor_Surface BAsurf(FIO);
+  
   TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
   for (; exp.More(); exp.Next()) {
     const TopoDS_Wire&     W = TopoDS::Wire(exp.Current());
@@ -1515,18 +1528,18 @@ void BRepOffset_Inter2d::ConnexIntByInt
     TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
     wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
 //    wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)),
-//           TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
+//      TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
     CurE = FirstE  = wexp.Current(); 
     while (!end) {
       wexp.Next();
       if (wexp.More()) {
-       NextE = wexp.Current();
+        NextE = wexp.Current();
       } 
       else {
-       NextE = FirstE; end = Standard_True;
+        NextE = FirstE; end = Standard_True;
       }
       if (CurE.IsSame(NextE)) continue;
-
+      
       //IFV------------
       TopoDS_Vertex Vref = CommonVertex(CurE, NextE); 
       gp_Pnt Pref = BRep_Tool::Pnt(Vref);
@@ -1546,48 +1559,66 @@ void BRepOffset_Inter2d::ConnexIntByInt
       TopoDS_Shape         NE1,NE2;
       
       if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
-       NE1 = Build(CurE );
-       NE2 = Build(NextE);
+        NE1 = Build(CurE );
+        NE2 = Build(NextE);
       }
       else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
-       NE1 = Build(CurE);
-       NE2 = MES  (NEO);
+        NE1 = Build(CurE);
+        NE2 = MES  (NEO);
       }
       else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
-       NE1 = Build(NextE);
-       NE2 = MES(CEO);
+        NE1 = Build(NextE);
+        NE2 = MES(CEO);
       }
       else {
-       DoInter = 0;
+        DoInter = 0;
       }
       if (DoInter) {
-       //------------------------------------
-       // NE1,NE2 can be a compound of Edges.
-       //------------------------------------
-       TopExp_Explorer Exp1,Exp2;
-       for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
-         for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
-           RefEdgeInter(FIO,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
-                     AsDes,Tol,Standard_True/*Standard_False*/, Pref);
-         }
-       }
+        //------------------------------------
+        // NE1,NE2 can be a compound of Edges.
+        //------------------------------------
+        TopExp_Explorer Exp1,Exp2;
+        for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
+          for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
+            RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
+                         AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+          }
+        }
+        //
+        if (Build.IsBound(Vref)) {
+          TopoDS_Shape NE3 = Build(Vref);
+          //
+          for (Exp2.Init(NE3,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
+            const TopoDS_Edge& aE3 = *(TopoDS_Edge*)&Exp2.Current();
+            if (!aME.Contains(aE3)) {
+              continue;
+            }
+            //
+            for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
+              RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
+                           AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+            }
+            //
+            for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
+              RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
+                           AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+            }
+          }
+        }
       }
       else {
-       if (MES.IsBound(CEO)) {
-         TopoDS_Vertex  V = CommonVertex(CEO,NEO); 
-         UpdateVertex  (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
-         AsDes->Add     (MES(CEO),V);
-       }
-       else if (MES.IsBound(NEO)) {
-         TopoDS_Vertex V = CommonVertex(CEO,NEO); 
-         UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
-         AsDes->Add    (MES(NEO),V);
-       }
+        if (MES.IsBound(CEO)) {
+          TopoDS_Vertex  V = CommonVertex(CEO,NEO); 
+          UpdateVertex  (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
+          AsDes2d->Add     (MES(CEO),V);
+        }
+        else if (MES.IsBound(NEO)) {
+          TopoDS_Vertex V = CommonVertex(CEO,NEO); 
+          UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
+          AsDes2d->Add    (MES(NEO),V);
+        }
       }
       CurE = NextE;
     }
   }
 }
-
-
-
index 334d800cccc9d90c232ad8f42702ca2179da4209..342747fd9429821ab3e83ea32dd90eea5073ed30 100644 (file)
@@ -40,6 +40,7 @@
 #include <Extrema_ExtPC.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <Precision.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 
 
 
@@ -49,8 +50,8 @@
 //=======================================================================
 
 BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes, 
-                                      const TopAbs_State              Side ,
-                                      const Standard_Real             Tol)
+                                       const TopAbs_State              Side ,
+                                       const Standard_Real             Tol)
 :myAsDes(AsDes),
 mySide(Side),
 myTol(Tol)
@@ -64,8 +65,8 @@ myTol(Tol)
 //=======================================================================
 
 static void ExtentEdge(const TopoDS_Face& /*F*/,
-                      const TopoDS_Edge& E,
-                      TopoDS_Edge& NE) 
+                       const TopoDS_Edge& E,
+                       TopoDS_Edge& NE) 
 {
   TopoDS_Shape aLocalShape = E.EmptyCopied();
   NE = TopoDS::Edge(aLocalShape); 
@@ -97,117 +98,60 @@ static void ExtentEdge(const TopoDS_Face& /*F*/,
 //function : SelectEdge
 //purpose  : 
 //=======================================================================
-
-static void SelectEdge (const TopoDS_Face& /*F*/,
-                       const TopoDS_Face& /*EF*/,
-                       const TopoDS_Edge& E,
-                       TopTools_ListOfShape& LInt)
+static void SelectEdge (const TopoDS_Shape& theS,
+                        TopTools_ListOfShape& theLE)
 {
-  //------------------------------------------------------------
-  // Proofing on the intersections on periodical faces
-  //------------------------------------------------------------
-   TopTools_ListIteratorOfListOfShape it(LInt);
-//  Modified by Sergey KHROMOV - Wed Jun  5 11:43:04 2002 Begin
-//   Standard_Real dU = 1.0e100;
-  Standard_Real dU = RealLast();
-//  Modified by Sergey KHROMOV - Wed Jun  5 11:43:05 2002 End
-  TopoDS_Edge   GE;
-
-  Standard_Real Fst, Lst, tmp;
-  BRep_Tool::Range(E, Fst, Lst);
-  BRepAdaptor_Curve  Ad1(E);
-  gp_Pnt PFirst = Ad1.Value( Fst );  
-  gp_Pnt PLast  = Ad1.Value( Lst );  
-
-//  Modified by Sergey KHROMOV - Wed Jun  5 11:23:10 2002 Begin
-   Extrema_ExtPC anExt;
-//  Modified by Sergey KHROMOV - Wed Jun  5 11:23:11 2002 End
-  //----------------------------------------------------------------------
-  // Selection of edge that coversmost of the domain of the initial edge.
-  //---------------------------------------------------------------------- 
-  for (; it.More(); it.Next()) {
-    const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
-
-    BRep_Tool::Range(EI, Fst, Lst);
-    BRepAdaptor_Curve  Ad2(EI);
-
-//  Modified by Sergey KHROMOV - Wed Jun  5 11:25:03 2002 Begin
-    Standard_Integer i;
-    Standard_Real    aTol       = BRep_Tool::Tolerance(EI);
-    Standard_Boolean isMinFound = Standard_False;
-    Standard_Real    aSqrDist1  = Precision::Infinite();
-    Standard_Real    aSqrDist2  = Precision::Infinite();
-
-    anExt.Initialize(Ad2, Fst, Lst, aTol);
-
-// Seek for the min distance for PFirst:
-    anExt.Perform(PFirst);
-    if (anExt.IsDone()) {
-      for (i = 1; i <= anExt.NbExt(); i++) {
-       if (anExt.IsMin(i)) {
-         const gp_Pnt &aPMin = anExt.Point(i).Value();
-
-         aSqrDist1  = PFirst.SquareDistance(aPMin);
-         isMinFound = Standard_True;
-
-         break;
-       }
+  Standard_Real aT1, aT2, aDist, aDistMin;
+  TopExp_Explorer aExp;
+  TopTools_ListIteratorOfListOfShape aIt;
+  GeomAPI_ProjectPointOnCurve aProjPC;
+  gp_Pnt aPE1, aPE2;
+  TopoDS_Edge aRE;
+  //
+  aDistMin = RealLast();
+  //
+  aIt.Initialize(theLE);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Edge& aE = *(TopoDS_Edge*)&aIt.Value();
+    //
+    const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2);
+    //
+    aProjPC.Init(aC, aT1, aT2);
+    aPE1 = aC->Value(aT1);
+    aPE2 = aC->Value(aT2);
+    //
+    aDist = 0.;
+    aExp.Init(theS, TopAbs_VERTEX);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExp.Current();
+      const gp_Pnt aP = BRep_Tool::Pnt(aV);
+      //
+      aProjPC.Perform(aP);
+      if (aProjPC.NbPoints()) {
+        aDist += aProjPC.LowerDistance();
       }
-    }
-    if (!isMinFound) {
-      gp_Pnt aP1 = Ad2.Value(Fst);
-      gp_Pnt aP2 = Ad2.Value(Lst);
-
-      aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst));
-    }
-
-// Seek for the min distance for PLast:
-    isMinFound = Standard_False;
-    anExt.Perform(PLast);
-    if (anExt.IsDone()) {
-      for (i = 1; i <= anExt.NbExt(); i++) {
-       if (anExt.IsMin(i)) {
-         const gp_Pnt &aPMin = anExt.Point(i).Value();
-
-         aSqrDist2  = PLast.SquareDistance(aPMin);
-         isMinFound = Standard_True;
-
-         break;
-       }
+      else {
+        aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2));
       }
     }
-    if (!isMinFound) {
-      gp_Pnt aP1 = Ad2.Value(Fst);
-      gp_Pnt aP2 = Ad2.Value(Lst);
-
-      aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast));
+    //
+    if (aDist < aDistMin) {
+      aDistMin = aDist;
+      aRE = aE;
     }
-
-    tmp = aSqrDist1 + aSqrDist2;
-//     gp_Pnt P1 = Ad2.Value(Fst);
-//     gp_Pnt P2 = Ad2.Value(Lst);
-       
-//     tmp = P1.Distance(PFirst) + P2.Distance(PLast);
-    if( tmp <= dU ) {
-      dU = tmp;
-      GE = EI;
-    } 
-//  Modified by Sergey KHROMOV - Wed Jun  5 11:24:54 2002 End
-
   }
-  LInt.Clear(); 
-  LInt.Append(GE);
+  //
+  theLE.Clear();
+  theLE.Append(aRE);
 }
 
-
 //=======================================================================
 //function : CompletInt
 //purpose  : 
 //=======================================================================
 
 void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
-                                   const BRepAlgo_Image&     InitOffsetFace)
+                                    const BRepAlgo_Image&     InitOffsetFace)
 {
   //---------------------------------------------------------------
   // Calculate the intersections of offset faces 
@@ -250,8 +194,8 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
 //=======================================================================
 
 void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
-                                  const TopoDS_Face& F2,
-                                  const BRepAlgo_Image&     InitOffsetFace)
+                                   const TopoDS_Face& F2,
+                                   const BRepAlgo_Image&     InitOffsetFace)
 {
   TopTools_ListOfShape LInt1, LInt2;
   TopoDS_Edge NullEdge;
@@ -261,9 +205,9 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
   const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
   const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
   Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
-                                InitF1.ShapeType() == TopAbs_EDGE );
+                                 InitF1.ShapeType() == TopAbs_EDGE );
   Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE && 
-                                InitF2.ShapeType() == TopAbs_FACE);
+                                 InitF2.ShapeType() == TopAbs_FACE);
   TopTools_ListOfShape LE,LV;
   LInt1.Clear(); LInt2.Clear(); 
   if (BRepOffset_Tool::HasCommonShapes(F1,F2,LE,LV) ||
@@ -273,38 +217,44 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
     //-------------------------------------------------
     if ( LE.IsEmpty() && !LV.IsEmpty()) {
       if (InterPipes) {
-       //----------------------
-       // tubes share a vertex.
-       //----------------------
-       const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
-       const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
-       TopoDS_Vertex VE1[2],VE2[2];
-       TopExp::Vertices(EE1,VE1[0],VE1[1]);
-       TopExp::Vertices(EE2,VE2[0],VE2[1]);
-       TopoDS_Vertex V;
-       for (Standard_Integer i = 0 ; i < 2; i++) {
-         for (Standard_Integer j = 0 ; j < 2; j++) {
-           if (VE1[i].IsSame(VE2[j])) {
-             V = VE1[i];
-           }
-         }
-       }
-       if (!InitOffsetFace.HasImage(V)) { //no sphere
-         BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
-       }               
+        //----------------------
+        // tubes share a vertex.
+        //----------------------
+        const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
+        const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
+        TopoDS_Vertex VE1[2],VE2[2];
+        TopExp::Vertices(EE1,VE1[0],VE1[1]);
+        TopExp::Vertices(EE2,VE2[0],VE2[1]);
+        TopoDS_Vertex V;
+        for (Standard_Integer i = 0 ; i < 2; i++) {
+          for (Standard_Integer j = 0 ; j < 2; j++) {
+            if (VE1[i].IsSame(VE2[j])) {
+              V = VE1[i];
+            }
+          }
+        }
+        if (!InitOffsetFace.HasImage(V)) { //no sphere
+          BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
+        }                
       }
       else {
-       //--------------------------------------------------------
-       // Intersection having only common vertices
-       // and supports having common edges.
-       // UNSUFFICIENT, but a larger criterion shakes too
-       // many sections.
-       //--------------------------------------------------------
-       if (InterFaces && 
-           BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
-                                            TopoDS::Face(InitF2),LE,LV)) 
-         if (!LE.IsEmpty())
-           BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+        //--------------------------------------------------------
+        // Intersection having only common vertices
+        // and supports having common edges.
+        // UNSUFFICIENT, but a larger criterion shakes too
+        // many sections.
+        //--------------------------------------------------------
+        if (InterFaces) {
+          if (BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
+                                               TopoDS::Face(InitF2),LE,LV)) {
+            if (!LE.IsEmpty()) {
+              BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+            }
+          }
+          else {
+            BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge);
+          }
+        }
       }
     }
   }
@@ -350,13 +300,13 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
       //-----------------------------------------------------------
       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());
-       if (!IsDone(F1,F2)) {
-         BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
-         Store (F1,F2,LInt1,LInt2);
-       }
-      }          
+        F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
+        F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
+        if (!IsDone(F1,F2)) {
+          BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
+          Store (F1,F2,LInt1,LInt2);
+        }
+      }          
     }
   }
   //---------------------------------------------------------------------
@@ -378,84 +328,84 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
       const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1);
       
       for (Standard_Integer i = 0; i < 2; i++) {
-       if (!InitOffsetFace.HasImage(V[i])) {
-         //-----------------------------
-         // the vertex has no sphere.
-         //-----------------------------
-         const TopTools_ListOfShape& Anc     = Analyse.Ancestors(V[i]);
-         TopTools_ListOfShape TangOnV;
-         Analyse.TangentEdges(E1,V[i],TangOnV);
-         TopTools_MapOfShape MTEV;
-         for (it.Initialize(TangOnV); it.More(); it.Next()) {
-           MTEV.Add(it.Value());
-         }
-         for (it.Initialize(Anc); it.More(); it.Next()) {
-           const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
+        if (!InitOffsetFace.HasImage(V[i])) {
+          //-----------------------------
+          // the vertex has no sphere.
+          //-----------------------------
+          const TopTools_ListOfShape& Anc     = Analyse.Ancestors(V[i]);
+          TopTools_ListOfShape TangOnV;
+          Analyse.TangentEdges(E1,V[i],TangOnV);
+          TopTools_MapOfShape MTEV;
+          for (it.Initialize(TangOnV); it.More(); it.Next()) {
+            MTEV.Add(it.Value());
+          }
+          for (it.Initialize(Anc); it.More(); it.Next()) {
+            const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
 //  Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin
-//         if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
-           Standard_Boolean isToSkip = Standard_False;
+//            if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
+            Standard_Boolean isToSkip = Standard_False;
 
-           if (!E1.IsSame(E2)) {
-             const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
+            if (!E1.IsSame(E2)) {
+              const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
 
-             isToSkip = (MTEV.Contains(E2) && 
-                         (aL.IsEmpty() ||
-                         (!aL.IsEmpty() && aL.First().Type() != OT)));
-           }
+              isToSkip = (MTEV.Contains(E2) && 
+                          (aL.IsEmpty() ||
+                          (!aL.IsEmpty() && aL.First().Type() != OT)));
+            }
 
-           if (E1.IsSame(E2) || isToSkip)
-             continue;
+            if (E1.IsSame(E2) || isToSkip)
+              continue;
 //  Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End
-           if (InitOffsetFace.HasImage(E2)) {
-             //-----------------------------
-             // E2 generated a tube.
-             //-----------------------------
-             F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());      
-             if (!IsDone(F1,F2)) {
-               //---------------------------------------------------------------------
-               // Intersection tube/tube if the edges are not tangent (AFINIR).
-               //----------------------------------------------------------------------
-               BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
-               Store (F1,F2,LInt1,LInt2);
-             }
-           }
-           else {
-             //-------------------------------------------------------
-             // Intersection of the tube of E1 with faces //
-             // to face containing E2 if they are not tangent
-             // to the tube or if E2 is not a tangent edge.
-             //-------------------------------------------------------
-             const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
-             if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) {
-               continue;
-             }
-             const TopTools_ListOfShape& AncE2        = Analyse.Ancestors(E2);
-             Standard_Boolean            TangentFaces = Standard_False;
-             if (AncE2.Extent() == 2) {
-               TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
-               TangentFaces = (InitF2.IsSame(AncE1.First()) || 
-                               InitF2.IsSame(AncE1.Last()));
-               if (!TangentFaces) {
-                 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
-                 if (!IsDone(F1,F2)) {
-                   BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
-                   Store (F1,F2,LInt1,LInt2);
-                 }
-               }
-               InitF2 = TopoDS::Face(AncE2.Last ());
-               TangentFaces = (InitF2.IsSame(AncE1.First()) || 
-                               InitF2.IsSame(AncE1.Last()));
-               if (!TangentFaces) {
-                 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
-                 if (!IsDone(F1,F2)) {
-                   BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
-                   Store (F1,F2,LInt1,LInt2);
-                 }
-               }
-             }
-           }
-         }
-       }
+            if (InitOffsetFace.HasImage(E2)) {
+              //-----------------------------
+              // E2 generated a tube.
+              //-----------------------------
+              F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());        
+              if (!IsDone(F1,F2)) {
+                //---------------------------------------------------------------------
+                // Intersection tube/tube if the edges are not tangent (AFINIR).
+                //----------------------------------------------------------------------
+                BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
+                Store (F1,F2,LInt1,LInt2);
+              }
+            }
+            else {
+              //-------------------------------------------------------
+              // Intersection of the tube of E1 with faces //
+              // to face containing E2 if they are not tangent
+              // to the tube or if E2 is not a tangent edge.
+              //-------------------------------------------------------
+              const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
+               if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) {
+                continue;
+              }
+              const TopTools_ListOfShape& AncE2        = Analyse.Ancestors(E2);
+              Standard_Boolean            TangentFaces = Standard_False;
+              if (AncE2.Extent() == 2) {
+                TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
+                TangentFaces = (InitF2.IsSame(AncE1.First()) || 
+                                InitF2.IsSame(AncE1.Last()));
+                if (!TangentFaces) {
+                  F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
+                  if (!IsDone(F1,F2)) {
+                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+                    Store (F1,F2,LInt1,LInt2);
+                  }
+                }
+                InitF2 = TopoDS::Face(AncE2.Last ());
+                TangentFaces = (InitF2.IsSame(AncE1.First()) || 
+                                InitF2.IsSame(AncE1.Last()));
+                if (!TangentFaces) {
+                  F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
+                  if (!IsDone(F1,F2)) {
+                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+                    Store (F1,F2,LInt1,LInt2);
+                  }
+                }
+              }
+            }
+          }
+        }
       }
     }
   }
@@ -476,103 +426,213 @@ void BRepOffset_Inter3d::ConnexIntByInt
  TopTools_ListOfShape&                  Failed)
 {
   //TopExp_Explorer Exp(SI,TopAbs_EDGE);
-  TopTools_IndexedMapOfShape Emap;
-  TopExp::MapShapes( SI, TopAbs_EDGE, Emap );
+  TopTools_IndexedMapOfShape VEmap;
+  TopTools_IndexedDataMapOfShapeListOfShape aMVF;
   TopoDS_Face     F1,F2,OF1,OF2,NF1,NF2;
   TopAbs_State    CurSide = mySide;
   BRep_Builder    B;
-  TopTools_ListIteratorOfListOfShape it;
-
-  //for (; Exp.More(); Exp.Next()) {
-  for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
-    //const TopoDS_Edge&               E = TopoDS::Edge(Exp.Current());
-    const TopoDS_Edge& E = TopoDS::Edge(Emap(i));
-    const BRepOffset_ListOfInterval& L = Analyse.Type(E);
-    if (!L.IsEmpty()) {
+  Standard_Boolean bEdge;
+  Standard_Integer i, aNb;
+  TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
+  //
+  TopExp::MapShapes(SI, TopAbs_EDGE  , VEmap);
+  TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
+  TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
+  //
+  aNb = VEmap.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aS = VEmap(i);
+    //
+    TopoDS_Edge E;
+    TopTools_ListOfShape aLF1, aLF2;
+    //
+    bEdge = (aS.ShapeType() == TopAbs_EDGE);
+    if (bEdge) {
+      // faces connected by the edge
+      E = *(TopoDS_Edge*)&aS;
+      //
+      const BRepOffset_ListOfInterval& L = Analyse.Type(E);
+      if (L.IsEmpty()) {
+        continue;
+      }
+      //
       BRepOffset_Type    OT   = L.First().Type();
-      if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) {
-       if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
-       else                          CurSide = TopAbs_OUT;
-       //-----------------------------------------------------------
-       // edge is of the proper type, return adjacent faces.
-       //-----------------------------------------------------------
-       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
-       if (Anc.Extent() != 2) continue;
-       F1  = TopoDS::Face(Anc.First());
-       F2  = TopoDS::Face(Anc.Last ());
-       OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face());
-       if (!MES.IsBound(OF1)) {
-         Standard_Boolean enlargeU = Standard_True;
-         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
-         BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
-         BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
-         MES.Bind(OF1,NF1);
-       }
-       else {
-         NF1 = TopoDS::Face(MES(OF1));
-       }
-       if (!MES.IsBound(OF2)) {
-         Standard_Boolean enlargeU = Standard_True;
-         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
-         BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
-         BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
-         MES.Bind(OF2,NF2); 
-       }
-       else {
-         NF2 = TopoDS::Face(MES(OF2));
-       }
-       if (!IsDone(NF1,NF2)) {
-         TopTools_ListOfShape LInt1,LInt2;
-         BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True);
-         if (LInt1.Extent() > 1)
-           { 
-             // intersection is in seceral edges (free sewing)
-             SelectEdge( NF1, NF2, E, LInt1 );
-             SelectEdge( NF1, NF2, E, LInt2 );
-           }
-         SetDone(NF1,NF2);
-         if (!LInt1.IsEmpty()) {
-           Store (NF1,NF2,LInt1,LInt2);
-           TopoDS_Compound C;
-           B.MakeCompound(C);
-           for (it.Initialize(LInt1) ; it.More(); it.Next()) {
-             B.Add(C,it.Value());
-           }
-           Build.Bind(E,C);
-         }
-         else {
-           Failed.Append(E);
-         }
-       } else { // IsDone(NF1,NF2)
-         //  Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
-         const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
-         const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
-
-         if (!aLInt1.IsEmpty()) {
-           TopoDS_Compound C;
-           TopTools_ListIteratorOfListOfShape anIt2;
-
-           B.MakeCompound(C);
-
-           for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
-             const TopoDS_Shape &anE1 = it.Value();
-
-             for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) {
-               const TopoDS_Shape &anE2 = anIt2.Value();
-
-               if (anE1.IsSame(anE2))
-                 B.Add(C, anE1);
-             }
-           }
-           Build.Bind(E,C);
-         }
-         else {
-           Failed.Append(E);
-         }
-       }
-       //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
-      }          
+      if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
+        continue;
+      }
+      //
+      if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
+      else                          CurSide = TopAbs_OUT;
+      //-----------------------------------------------------------
+      // edge is of the proper type, return adjacent faces.
+      //-----------------------------------------------------------
+      const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
+      if (Anc.Extent() != 2) {
+        continue;
+      }
+      //
+      F1  = TopoDS::Face(Anc.First());
+      F2  = TopoDS::Face(Anc.Last ());
+      //
+      aLF1.Append(F1);
+      aLF2.Append(F2);
+    }
+    else {
+      // faces connected by the vertex
+      const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS);
+      if (aLF.Extent() < 2) {
+        continue;
+      }
+      //
+      Standard_Boolean bVertexOnly = Standard_False;
+      TopTools_MapOfShape aMFence;
+      //
+      it.Initialize(aLF);
+      for (; it.More(); it.Next()) {
+        const TopoDS_Face& aFV1 = *(TopoDS_Face*)&it.Value();
+        if (!aMFence.Add(aFV1)) {
+          continue;
+        }
+        //
+        TopTools_MapOfShape aME;
+        TopExp_Explorer aExp(aFV1, TopAbs_EDGE);
+        for (; aExp.More(); aExp.Next()) {
+          aME.Add(aExp.Current());
+        }
+        //
+        it1.Initialize(aLF);
+        for (it1.Next(); it1.More(); it1.Next()) {
+          const TopoDS_Face& aFV2 = *(TopoDS_Face*)&it1.Value();
+          if (aMFence.Contains(aFV2)) {
+            continue;
+          }
+          //
+          bVertexOnly = Standard_True;
+          aExp.Init(aFV2, TopAbs_EDGE);
+          for (; aExp.More(); aExp.Next()) {
+            const TopoDS_Shape& aEV2 = aExp.Current();
+            if (aME.Contains(aEV2)) {
+              bVertexOnly = Standard_False;
+              break;
+            }
+          }
+          //
+          if (bVertexOnly) {
+            aLF1.Append(aFV1);
+            aLF2.Append(aFV2);
+            aMFence.Add(aFV2);
+          }
+        }
+      }
+      //
+      if (aLF1.IsEmpty()) {
+        continue;
+      }
+      //
+      CurSide = mySide;
     }
+    //
+    itF1.Initialize(aLF1);
+    itF2.Initialize(aLF2);
+    for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) {
+      F1 = TopoDS::Face(itF1.Value());
+      F2 = TopoDS::Face(itF2.Value());
+      //
+      OF1 = TopoDS::Face(MapSF(F1).Face());
+      OF2 = TopoDS::Face(MapSF(F2).Face());
+      if (!MES.IsBound(OF1)) {
+        Standard_Boolean enlargeU = Standard_True;
+        Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
+        BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
+        BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
+        MES.Bind(OF1,NF1);
+      }
+      else {
+        NF1 = TopoDS::Face(MES(OF1));
+      }
+      //
+      if (!MES.IsBound(OF2)) {
+        Standard_Boolean enlargeU = Standard_True;
+        Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
+        BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
+        BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
+        MES.Bind(OF2,NF2); 
+      }
+      else {
+        NF2 = TopoDS::Face(MES(OF2));
+      }
+      //
+      if (!IsDone(NF1,NF2)) {
+        TopTools_ListOfShape LInt1,LInt2;
+        BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge);
+        if (LInt1.Extent() > 1) { 
+          // intersection is in seceral edges (free sewing)
+          SelectEdge(aS, LInt1);
+          SelectEdge(aS, LInt2);
+        }
+        SetDone(NF1,NF2);
+        if (!LInt1.IsEmpty()) {
+          Store (NF1,NF2,LInt1,LInt2);
+          //
+          TopoDS_Compound C;
+          B.MakeCompound(C);
+          //
+          if (Build.IsBound(aS)) {
+            const TopoDS_Shape& aSE = Build(aS);
+            TopExp_Explorer aExp(aSE, TopAbs_EDGE);
+            for (; aExp.More(); aExp.Next()) {
+              const TopoDS_Shape& aNE = aExp.Current();
+              B.Add(C, aNE);
+            }
+          }
+          //
+          it.Initialize(LInt1);
+          for (; it.More(); it.Next()) {
+            const TopoDS_Shape& aNE = it.Value();
+            B.Add(C, aNE);
+          }
+          //
+          Build.Bind(aS,C);
+        }
+        else {
+          Failed.Append(aS);
+        }
+      } else { // IsDone(NF1,NF2)
+        //  Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
+        const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
+        const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
+        
+        if (!aLInt1.IsEmpty()) {
+          TopoDS_Compound C;
+          B.MakeCompound(C);
+          //
+          if (Build.IsBound(aS)) {
+            const TopoDS_Shape& aSE = Build(aS);
+            TopExp_Explorer aExp(aSE, TopAbs_EDGE);
+            for (; aExp.More(); aExp.Next()) {
+              const TopoDS_Shape& aNE = aExp.Current();
+              B.Add(C, aNE);
+            }
+          }
+          //
+          for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
+            const TopoDS_Shape &anE1 = it.Value();
+            //
+            for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) {
+              const TopoDS_Shape &anE2 = it1.Value();
+              
+              if (anE1.IsSame(anE2))
+                B.Add(C, anE1);
+            }
+          }
+          Build.Bind(aS,C);
+        }
+        else {
+          Failed.Append(aS);
+        }
+      }
+    }
+    //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
   }
 }
 
@@ -597,10 +657,12 @@ void BRepOffset_Inter3d::ContextIntByInt
   TopoDS_Edge                      OE;
   TopoDS_Compound                  C;
   BRep_Builder                     B;
-  TopTools_ListIteratorOfListOfShape it;
-  Standard_Integer i;
-  
-  for (i = 1; i <= ContextFaces.Extent(); i++) {
+  TopTools_ListIteratorOfListOfShape it, itF;
+  Standard_Integer i, j, aNb, aNbVE;
+  Standard_Boolean bEdge;
+
+  aNb = ContextFaces.Extent();
+  for (i = 1; i <= aNb; i++) {
     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
     myTouched.Add(CF);
     if (ExtentContext) {
@@ -610,90 +672,154 @@ void BRepOffset_Inter3d::ContextIntByInt
   }
   TopAbs_State Side = TopAbs_OUT;
  
-  for (i = 1; i <= ContextFaces.Extent(); i++) {
+  for (i = 1; i <= aNb; i++) {
     const TopoDS_Face& CF  = TopoDS::Face(ContextFaces(i));
     if (ExtentContext) WCF = TopoDS::Face(MES(CF));
     else               WCF = CF;
 
-    for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-        exp.More(); exp.Next()) {
-      const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
-      if (!Analyse.HasAncestor(E)) {
-       //----------------------------------------------------------------
-       // the edges of faces of context that are not in the initial shape
-       // can appear in the result.
-       //----------------------------------------------------------------
-       if (!ExtentContext) {
-         myAsDes->Add(CF,E);
-         myNewEdges.Add(E);
-       }
-       else {
-         if (!MES.IsBound(E)) {
-           TopoDS_Edge NE;
-           Standard_Real f,l,Tol;
-           BRep_Tool::Range(E,f,l);
-           Tol = BRep_Tool::Tolerance(E);
-           ExtentEdge(CF,E,NE);
-           TopoDS_Vertex V1,V2;
-           TopExp::Vertices(E,V1,V2);
-           NE.Orientation(TopAbs_FORWARD);
-           myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
-           myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
-           TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
-           B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
-           aLocalShape = V2.Oriented(TopAbs_INTERNAL);
-           B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
-           NE.Orientation(E.Orientation());
-           myAsDes->Add(CF,NE);
-           myNewEdges.Add(NE);
-           MES.Bind(E,NE);
-         }
-         else {
-           TopoDS_Shape NE = MES(E);
-           TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
-           myAsDes->Add(CF,aLocalShape);
-//         myAsDes->Add(CF,NE.Oriented(E.Orientation()));
-         }
-       }
-       continue;
-      } 
-      const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
-      const TopoDS_Face&          F   = TopoDS::Face(Anc.First());
-      OF = TopoDS::Face(MapSF(F).Face());
-      TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
-      OE = TopoDS::Edge(aLocalShape);
-//      OE = TopoDS::Edge(MapSF(F).Generated(E));
-      if (!MES.IsBound(OF)) {
-       BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
-       MES.Bind(OF,NF);
+    TopTools_IndexedMapOfShape VEmap;
+    TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE  , VEmap);
+    TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
+    //
+    aNbVE = VEmap.Extent();
+    for (j = 1; j <= aNbVE; ++j) {
+      const TopoDS_Shape& aS = VEmap(j);
+      //
+      bEdge = (aS.ShapeType() == TopAbs_EDGE);
+      //
+      TopoDS_Edge E;
+      TopTools_ListOfShape Anc;
+      //
+      if (bEdge) {
+        // faces connected by the edge
+        //
+        E = *(TopoDS_Edge*)&aS;
+        if (!Analyse.HasAncestor(E)) {
+          //----------------------------------------------------------------
+          // the edges of faces of context that are not in the initial shape
+          // can appear in the result.
+          //----------------------------------------------------------------
+          if (!ExtentContext) {
+            myAsDes->Add(CF,E);
+            myNewEdges.Add(E);
+          }
+          else {
+            if (!MES.IsBound(E)) {
+              TopoDS_Edge NE;
+              Standard_Real f,l,Tol;
+              BRep_Tool::Range(E,f,l);
+              Tol = BRep_Tool::Tolerance(E);
+              ExtentEdge(CF,E,NE);
+              TopoDS_Vertex V1,V2;
+              TopExp::Vertices(E,V1,V2);
+              NE.Orientation(TopAbs_FORWARD);
+              myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
+              myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
+              TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
+              B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
+              aLocalShape = V2.Oriented(TopAbs_INTERNAL);
+              B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
+//            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
+//            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
+              NE.Orientation(E.Orientation());
+              myAsDes->Add(CF,NE);
+              myNewEdges.Add(NE);
+              MES.Bind(E,NE);
+            }
+            else {
+              TopoDS_Shape NE = MES(E);
+              TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
+              myAsDes->Add(CF,aLocalShape);
+//            myAsDes->Add(CF,NE.Oriented(E.Orientation()));
+            }
+          }
+          continue;
+        } 
+        Anc = Analyse.Ancestors(E);
       }
       else {
-       NF = TopoDS::Face(MES(OF));
+        // faces connected by the vertex
+        //
+        if (!Analyse.HasAncestor(aS)) {
+          continue;
+        }
+        //
+        const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS);
+        it.Initialize(aLE);
+        for (; it.More(); it.Next()) {
+          const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value();
+          //
+          if (BRep_Tool::Degenerated(aE)) {
+            continue;
+          }
+          //
+          if (VEmap.Contains(aE)) {
+            continue;
+          }
+          //
+          const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE);
+          itF.Initialize(aLF);
+          for (; itF.More(); itF.Next()) {
+            const TopoDS_Shape& aF = itF.Value();
+            Standard_Boolean bAdd = Standard_True;
+            exp.Init(aF, TopAbs_EDGE);
+            for (; exp.More() && bAdd; exp.Next()) {
+              const TopoDS_Shape& aEF = exp.Current();
+              bAdd = !VEmap.Contains(aEF);
+            }
+            if (bAdd) {
+              Anc.Append(aF);
+            }
+          }
+        }
       }
-      if (!IsDone(NF,CF)) {
-       TopTools_ListOfShape LInt1,LInt2;
-       TopTools_ListOfShape LOE;
-       LOE.Append(OE);
-       BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True);
-       SetDone(NF,CF);
-       if (!LInt1.IsEmpty()) {
-         Store (CF,NF,LInt1,LInt2);
-         if (LInt1.Extent() == 1) {
-           Build.Bind(E,LInt1.First());
-         }
-         else {
-           B.MakeCompound(C);
-           for (it.Initialize(LInt1) ; it.More(); it.Next()) {
-             B.Add(C,it.Value());
-           }
-           Build.Bind(E,C);
-         }
-       }
-       else {
-         Failed.Append(E);
-       }
+      //
+      itF.Initialize(Anc);
+      for (; itF.More(); itF.Next()) {
+        const TopoDS_Face& F = TopoDS::Face(itF.Value());
+        OF = TopoDS::Face(MapSF(F).Face());
+        TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
+        OE = TopoDS::Edge(aLocalShape);
+//      OE = TopoDS::Edge(MapSF(F).Generated(E));
+        if (!MES.IsBound(OF)) {
+          BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
+          MES.Bind(OF,NF);
+        }
+        else {
+          NF = TopoDS::Face(MES(OF));
+        }
+        if (!IsDone(NF,CF)) {
+          TopTools_ListOfShape LInt1,LInt2;
+          TopTools_ListOfShape LOE;
+          LOE.Append(OE);
+          BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge);
+          SetDone(NF,CF);
+          if (!LInt1.IsEmpty()) {
+            Store (CF,NF,LInt1,LInt2);
+            if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) {
+              Build.Bind(aS,LInt1.First());
+            }
+            else {
+              B.MakeCompound(C);
+              if (Build.IsBound(aS)) {
+                const TopoDS_Shape& aSE = Build(aS);
+                exp.Init(aSE, TopAbs_EDGE);
+                for (; exp.More(); exp.Next()) {
+                  const TopoDS_Shape& aNE = exp.Current();
+                  B.Add(C, aNE);
+                }
+              }
+              //
+              for (it.Initialize(LInt1) ; it.More(); it.Next()) {
+                B.Add(C,it.Value());
+              }
+              Build.Bind(aS,C);
+            }
+          }
+          else {
+            Failed.Append(aS);
+          }
+        }
       }
     }
   }
@@ -705,10 +831,10 @@ void BRepOffset_Inter3d::ContextIntByInt
 //=======================================================================
 
 void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces, 
-                                        const Standard_Boolean            InSide,
-                                        const BRepOffset_Analyse&         Analyse, 
-                                        const BRepAlgo_Image&             InitOffsetFace, 
-                                              BRepAlgo_Image&             InitOffsetEdge)
+                                         const Standard_Boolean            InSide,
+                                         const BRepOffset_Analyse&         Analyse, 
+                                         const BRepAlgo_Image&             InitOffsetFace, 
+                                               BRepAlgo_Image&             InitOffsetEdge)
 
 { 
   TopTools_ListOfShape                      LInt1,LInt2;
@@ -728,39 +854,39 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
   for (j = 1; j <= ContextFaces.Extent(); j++) {
     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-        exp.More(); exp.Next()) {
+         exp.More(); exp.Next()) {
       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
       if (!Analyse.HasAncestor(E)) {
-       if (InSide)
-         myAsDes->Add(CF,E);
-       else {
-         TopoDS_Edge NE;
-         if (!InitOffsetEdge.HasImage(E)) {
-           Standard_Real f,l,Tol;
-           BRep_Tool::Range(E,f,l);
-           Tol = BRep_Tool::Tolerance(E);
-           ExtentEdge(CF,E,NE);
-           TopoDS_Vertex V1,V2;
-           TopExp::Vertices(E,V1,V2);
-           NE.Orientation(TopAbs_FORWARD);
-           myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
-           myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
-           TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
-           B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
-           aLocalShape = V2.Oriented(TopAbs_INTERNAL);
-           B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
-           NE.Orientation(E.Orientation());
-           myAsDes->Add(CF,NE);
-           InitOffsetEdge.Bind(E,NE);
-         }
-         else {
-           NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
-           myAsDes->Add(CF,NE.Oriented(E.Orientation()));
-         }
-       }
-       continue;
+        if (InSide)
+          myAsDes->Add(CF,E);
+        else {
+          TopoDS_Edge NE;
+          if (!InitOffsetEdge.HasImage(E)) {
+            Standard_Real f,l,Tol;
+            BRep_Tool::Range(E,f,l);
+            Tol = BRep_Tool::Tolerance(E);
+            ExtentEdge(CF,E,NE);
+            TopoDS_Vertex V1,V2;
+            TopExp::Vertices(E,V1,V2);
+            NE.Orientation(TopAbs_FORWARD);
+            myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
+            myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
+            TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
+            B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
+            aLocalShape = V2.Oriented(TopAbs_INTERNAL);
+            B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
+//            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
+//            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
+            NE.Orientation(E.Orientation());
+            myAsDes->Add(CF,NE);
+            InitOffsetEdge.Bind(E,NE);
+          }
+          else {
+            NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
+            myAsDes->Add(CF,NE.Oriented(E.Orientation()));
+          }
+        }
+        continue;
       }
       OE.Nullify();
       //---------------------------------------------------
@@ -787,11 +913,11 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
       //--------------------------------------------------
       // MAJ of OE on cap CF.
       //--------------------------------------------------
-//      TopTools_ListOfShape LOE; LOE.Append(OE);            
+//      TopTools_ListOfShape LOE; LOE.Append(OE);              
 //      BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
 //      LInt2.Clear();
 //      StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
-//                LInt1,LInt2);
+//                   LInt1,LInt2);
       LInt1.Clear(); LInt1.Append(OE);
       LInt2.Clear();    
       TopAbs_Orientation O1,O2;
@@ -807,18 +933,18 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
       TopoDS_Vertex V[2];
       TopExp::Vertices (E,V[0],V[1]);
       for (Standard_Integer i = 0; i < 2; i++) {
-       if (!MV.Add(V[i])) continue;
-       OF1.Nullify(); 
-       const TopTools_ListOfShape& LE =  Analyse.Ancestors(V[i]);
-       TopTools_ListIteratorOfListOfShape itLE(LE);
-       for ( ; itLE.More(); itLE.Next()) {
-         const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
-         if (InitOffsetFace.HasImage(EV)) {
-           //-------------------------------------------------
-           // OF1 parallel face generated by an ancester edge of V[i].
-           //-------------------------------------------------
-           OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
-           OE  = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
+        if (!MV.Add(V[i])) continue;
+        OF1.Nullify(); 
+        const TopTools_ListOfShape& LE =  Analyse.Ancestors(V[i]);
+        TopTools_ListIteratorOfListOfShape itLE(LE);
+        for ( ; itLE.More(); itLE.Next()) {
+          const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
+          if (InitOffsetFace.HasImage(EV)) {
+            //-------------------------------------------------
+            // OF1 parallel face generated by an ancester edge of V[i].
+            //-------------------------------------------------
+            OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
+            OE  = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
 
       {
         //Check if OE has pcurve in CF and OF1
@@ -834,64 +960,64 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
         }
       }
 
-           //--------------------------------------------------
-           // MAj of OE on cap CF.
-           //--------------------------------------------------
-           //        LOE.Clear(); LOE.Append(OE);
-           //        BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
-           //        LInt2.Clear();
-           //        StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
-           //                     LInt1,LInt2);
-           LInt1.Clear(); LInt1.Append(OE);
-           LInt2.Clear();    
-           TopAbs_Orientation O1,O2;
-           BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);      
-//         if (mySide == TopAbs_OUT);
-           O1 = TopAbs::Reverse(O1);
-           LInt1.First().Orientation(O1);
-           Store(CF,OF1,LInt1,LInt2);
-         }
-       }
+            //--------------------------------------------------
+            // MAj of OE on cap CF.
+            //--------------------------------------------------
+            //              LOE.Clear(); LOE.Append(OE);
+            //              BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
+            //              LInt2.Clear();
+            //              StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
+            //                           LInt1,LInt2);
+            LInt1.Clear(); LInt1.Append(OE);
+            LInt2.Clear();    
+            TopAbs_Orientation O1,O2;
+            BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);      
+//            if (mySide == TopAbs_OUT);
+            O1 = TopAbs::Reverse(O1);
+            LInt1.First().Orientation(O1);
+            Store(CF,OF1,LInt1,LInt2);
+          }
+        }
       }
     }
     
     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
-        exp.More(); exp.Next()) {
+         exp.More(); exp.Next()) {
       const TopoDS_Vertex&        V  = TopoDS::Vertex(exp.Current());
       if (!Analyse.HasAncestor(V)) {
-       continue;
+        continue;
       }
       const TopTools_ListOfShape& LE =  Analyse.Ancestors(V);
       TopTools_ListIteratorOfListOfShape itLE(LE);
       for (; itLE.More(); itLE.Next()) {
-       const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
-       const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
-       TopTools_ListIteratorOfListOfShape itLF(LF);
-       for ( ; itLF.More(); itLF.Next()) {
-         const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
-         //-------------------------------------------------
-         // OF1 parallel face generated by uneFace ancestor of V[i].
-         //-------------------------------------------------
-         OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
-         if (!IsDone(OF1,CF)) {
-           //-------------------------------------------------------
-           // Find if one of edges of OF1 has no trace in CF.
-           //-------------------------------------------------------
-           TopTools_ListOfShape LOE;
-           TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
-           for ( ;exp2.More(); exp2.Next()) {
-             LOE.Append(exp2.Current());
-           }
-           BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
-           //-------------------------------------------------------
-           // If no trace try intersection.
-           //-------------------------------------------------------
-           if (LInt1.IsEmpty()) {
-             BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
-           }
-           Store (CF,OF1,LInt1,LInt2);
-         }
-       }
+        const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
+        const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
+        TopTools_ListIteratorOfListOfShape itLF(LF);
+        for ( ; itLF.More(); itLF.Next()) {
+          const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
+          //-------------------------------------------------
+          // OF1 parallel face generated by uneFace ancestor of V[i].
+          //-------------------------------------------------
+          OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
+          if (!IsDone(OF1,CF)) {
+            //-------------------------------------------------------
+            // Find if one of edges of OF1 has no trace in CF.
+            //-------------------------------------------------------
+            TopTools_ListOfShape LOE;
+            TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+            for ( ;exp2.More(); exp2.Next()) {
+              LOE.Append(exp2.Current());
+            }
+            BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
+            //-------------------------------------------------------
+            // If no trace try intersection.
+            //-------------------------------------------------------
+            if (LInt1.IsEmpty()) {
+              BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
+            }
+            Store (CF,OF1,LInt1,LInt2);
+          }
+        }
       }
     } 
   }
@@ -913,7 +1039,7 @@ void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape&)
 //=======================================================================
 
 void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1, 
-                                const TopoDS_Face& F2)
+                                 const TopoDS_Face& F2)
 {
   if (!myDone.IsBound(F1)) {
     TopTools_ListOfShape empty;
@@ -934,7 +1060,7 @@ void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1,
 //=======================================================================
 
 Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1, 
-                                           const TopoDS_Face& F2) 
+                                            const TopoDS_Face& F2) 
 const 
 {
   if (myDone.IsBound(F1)) {
@@ -987,9 +1113,9 @@ TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges()
 //=======================================================================
 
 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1, 
-                              const TopoDS_Face& F2, 
-                              const TopTools_ListOfShape& LInt1, 
-                              const TopTools_ListOfShape& LInt2)
+                               const TopoDS_Face& F2, 
+                               const TopTools_ListOfShape& LInt1, 
+                               const TopTools_ListOfShape& LInt2)
 {
   if (!LInt1.IsEmpty()) {
     myTouched.Add(F1);
index 1b4fbb847e754f5afa010b19a87716cacd23409e..c071d6157d24df54f5c42aae6be0200aaccafd6b 100644 (file)
@@ -19,7 +19,7 @@
 
 class MakeOffset from BRepOffset 
 
-       ---Purpose: 
+        ---Purpose: 
 
 uses
     Image                from BRepAlgo,
@@ -36,47 +36,53 @@ uses
     Edge                 from TopoDS,
     MapOfShape           from TopTools, 
     IndexedMapOfShape    from TopTools, 
-    ListOfShape          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)
-    returns MakeOffset from BRepOffset;             
-            
+    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; 
+             RemoveIntEdges : Boolean  from Standard   = Standard_False;
+             Thickening     : Boolean  from Standard   = Standard_False; 
+             RemoveInvalidFaces: Boolean from Standard = Standard_False)
+    returns MakeOffset 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)
+                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; 
+                RemoveIntEdges : Boolean  from Standard   = Standard_False;
+                Thickening     : 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.
+            ---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> 
+                             F   : Face from TopoDS;
+                             Off : Real from Standard) is static;
+            ---Purpose: set the offset <Off> on the Face <F> 
 
     
 ---Category: Computation.
@@ -88,7 +94,7 @@ is
 ---Category: Querying.
            
     GetAnalyse(me) 
-       ---C++: return const &
+            ---C++: return const &
     returns Analyse from BRepOffset
     is static;
 
@@ -96,18 +102,18 @@ is
     is static;
     
     Shape (me) 
-       ---C++: return const &
+            ---C++: return const &
     returns Shape from TopoDS
     is static;
 
     Error (me) returns Error from BRepOffset;
-       ---Purpose: returns information if IsDone() = FALSE.
-                           
+            ---Purpose: returns information if IsDone() = FALSE.
+                             
 
     OffsetFacesFromShapes (me)
-       ---Purpose: Returns <Image> containing links between initials
-       --          shapes and offset faces.
-       ---C++: return const &
+        ---Purpose: Returns <Image> containing links between initials
+         --          shapes and offset faces.
+         ---C++: return const &
     returns Image from BRepAlgo
     is static;    
     
@@ -115,24 +121,24 @@ is
 -- Query offset join type.
 
     GetJoinType(me) 
-       ---Purpose: Returns myJoin.
+            ---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 &
+        ---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 &
+            ---Purpose: Returns the list of closing faces stores by AddFace 
+        ---C++: return const &
     returns IndexedMapOfShape from TopTools
     is static;
 
@@ -156,18 +162,30 @@ is
     
     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;         
+                    Modif : in out MapOfShape from TopTools)
+    is static private;                
     
     Intersection3D (me        : in out;
-                   Inter     : in out Inter3d from BRepOffset)
-    is static private;             
-                   
+                            Inter     : in out Inter3d from BRepOffset)
+    is static private;                    
     Intersection2D ( me       : in out ;
                      Modif    : IndexedMapOfShape from TopTools;
-                    NewEdges : IndexedMapOfShape from TopTools)
+                     NewEdges : IndexedMapOfShape from TopTools)
     is static private;
     
     MakeLoops ( me    : in out ;
@@ -187,7 +205,7 @@ is
 
     SelectShells (me : in out)
     is static private;
-       
+        
     EncodeRegularity( me : in out)
     is static private;
 
@@ -195,20 +213,24 @@ is
     is static private;
     
     ToContext (me    : in out;
-              MapSF : in out DataMapOfShapeOffset from BRepOffset)
-    is static private; 
+                   MapSF : in out DataMapOfShapeOffset from BRepOffset)
+    is static private;        
     
     UpdateFaceOffset (me: in out) 
-       ---Purpose: Private method use to update the map face<->offset
+        ---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
+        ---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; 
+        ---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
 
@@ -218,13 +240,15 @@ fields
     myMode           : Mode       from BRepOffset;
     myInter          : Boolean    from Standard;
     mySelfInter      : Boolean    from Standard;
-    myJoin           : JoinType   from GeomAbs; 
+    myJoin           : JoinType   from GeomAbs;  
+    myRemoveIntEdges : Boolean    from Standard;
     myThickening     : Boolean    from Standard;
+    myRemoveInvalidFaces : Boolean from Standard;
      
     myFaceOffset     : DataMapOfShapeReal from TopTools;
     
     myFaces          : IndexedMapOfShape from TopTools;
-    myAnalyse        : Analyse          from BRepOffset;
+    myAnalyse        : Analyse           from BRepOffset;
     
     myOffsetShape    : Shape       from TopoDS;       -- Result
     myInitOffsetFace : Image       from BRepAlgo;
@@ -240,5 +264,4 @@ fields
     myBadShape       : Shape     from TopoDS;
     myIsPerformSewing: Boolean   from Standard; -- Handle bad walls in thicksolid mode.
 
-    
 end MakeOffset;
index 71f7615e5207c35517d26b0f1641bb3a58509472..b29ebed6c9dab7f5cf760866e067576f1632aaac 100644 (file)
@@ -34,8 +34,7 @@
 
 
 #include <BRepAdaptor_Surface.hxx>
-#include <BRepCheck_Edge.hxx>
-#include <BRepCheck_Vertex.hxx>
+
 #include <BRepLib.hxx>
 #include <BRepLib_MakeVertex.hxx>
 #include <BRep_Builder.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
 #include <gp_Pnt.hxx>
 
+#include <BRepCheck_Edge.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <BRepCheck_Vertex.hxx>
+
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
@@ -62,6 +65,8 @@
 #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>
@@ -90,7 +95,6 @@
 
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
 #include <Geom_SphericalSurface.hxx>
 #include <TopoDS_Wire.hxx>
 #include <BRepTools_Substitution.hxx>
 #include <Geom_Plane.hxx>
 #include <IntTools_FClass2d.hxx>
 #include <BRepLib_FindSurface.hxx>
-#include <BRepCheck_Analyzer.hxx>
-#include <NCollection_List.hxx>
-#include <GProp_GProps.hxx>
-#include <BRepGProp.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>
 #include <NCollection_Vector.hxx>
 #include <BRepBuilderAPI_Sewing.hxx>
 #include <Geom_Line.hxx>
+#include <BRepGProp.hxx>
+#include <GProp_GProps.hxx>
 
 #ifdef DRAW
 
 //=======================================================================
 
 static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
-                                     Handle(BRepAlgo_AsDes)      AsDes)
+                                      Handle(BRepAlgo_AsDes)      AsDes)
 {
   TopTools_ListOfShape               LVP;
   TopTools_ListIteratorOfListOfShape it1LE ;    
@@ -160,34 +181,34 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
     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;
+        if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
+          LVP.Append(it1LE.Value());
+          cout <<"Vertex on at least 3 edges."<<endl;
 #ifdef DRAW
-         if (AffichInt2d) {
-           sprintf (name,"VP_%d",NVP++);
-           DBRep::Set(name,it1LE.Value());
-         }
+          if (AffichInt2d) {
+            sprintf (name,"VP_%d",NVP++);
+            DBRep::Set(name,it1LE.Value());
+          }
 #endif
-       }
-       else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
-         cout <<"Vertex on more than 3 edges."<<endl;
+        }
+        else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
+          cout <<"Vertex on more than 3 edges."<<endl;
 #ifdef DRAW
-         if (AffichInt2d) {
-           sprintf (name,"VM_%d",NVM++);
-           DBRep::Set(name,it1LE.Value());
-         }
+          if (AffichInt2d) {
+            sprintf (name,"VM_%d",NVM++);
+            DBRep::Set(name,it1LE.Value());
+          }
 #endif
-         
-       }
-       else {
+          
+        }
+        else {
 #ifdef DRAW
-         if (AffichInt2d) {
-           sprintf (name,"VN_%d",NVN++);
-           DBRep::Set(name,it1LE.Value());
-         }
+          if (AffichInt2d) {
+            sprintf (name,"VN_%d",NVN++);
+            DBRep::Set(name,it1LE.Value());
+          }
 #endif
-       }
+        }
       }
     }
   }
@@ -210,30 +231,30 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 
     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);
-         }
-       }
+        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++;
     }
@@ -243,307 +264,186 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 }  
 #endif
 
-//---------------------------------------------------------------------
-static void UpdateTolerance (      TopoDS_Shape&               myShape,
-                            const TopTools_IndexedMapOfShape& myFaces);
-
-static void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList);
-//---------------------------------------------------------------------
-//
-static 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
+// static methods
 //=======================================================================
-static 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());
-}
+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 CorrectSolid(TopoDS_Solid& theSol, 
+                    TopTools_ListOfShape& theSolList);
+
+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);
 
 //=======================================================================
-//function : FillContours
-//purpose  : fills free boundary contours and faces connected (MapEF)
-//=======================================================================
-static 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 : BRepOffset_MakeOffset
 //purpose  : 
 //=======================================================================
-
 BRepOffset_MakeOffset::BRepOffset_MakeOffset()
 {
   myAsDes = new BRepAlgo_AsDes();
 }
 
-
 //=======================================================================
 //function : BRepOffset_MakeOffset
 //purpose  : 
 //=======================================================================
-
 BRepOffset_MakeOffset::BRepOffset_MakeOffset(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_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 RemoveIntEdges,
+                                             const Standard_Boolean Thickening,
+                                             const Standard_Boolean RemInvFaces)
 : 
-myOffset     (Offset),
-myTol        (Tol),
-myShape      (S),
-myMode       (Mode),
-myInter      (Inter),
-mySelfInter  (SelfInter),
-myJoin       (Join),
-myThickening (Thickening),
-myDone     (Standard_False)
+myOffset        (Offset),
+myTol           (Tol),
+myShape         (S),
+myMode          (Mode),
+myInter         (Inter),
+mySelfInter     (SelfInter),
+myJoin          (Join),
+myRemoveIntEdges(RemoveIntEdges),
+myThickening    (Thickening),
+myRemoveInvalidFaces(RemInvFaces),
+myDone          (Standard_False)
 
 {
   myAsDes = new BRepAlgo_AsDes();
   MakeOffsetShape();
 }
 
-
 //=======================================================================
 //function : Initialize
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::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_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 RemoveIntEdges,
+                                       const Standard_Boolean Thickening,
+                                       const Standard_Boolean RemInvFaces)
 {
-  myOffset     = Offset;
-  myShape      = S;
-  myTol        = Tol;
-  myMode       = Mode;
-  myInter      = Inter;
-  mySelfInter  = SelfInter;
-  myJoin       = Join;
-  myThickening = Thickening;
-  myDone     = Standard_False;
+  myOffset         = Offset;
+  myShape          = S;
+  myTol            = Tol;
+  myMode           = Mode;
+  myInter          = Inter;
+  mySelfInter      = SelfInter;
+  myJoin           = Join;
+  myRemoveIntEdges = RemoveIntEdges;
+  myThickening     = Thickening;
+  myRemoveInvalidFaces = RemInvFaces;
+  myDone           = Standard_False;
   myIsPerformSewing = Standard_False;
   Clear();
 }
 
-
 //=======================================================================
 //function : Clear
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::Clear()
 {
   myOffsetShape.Nullify();
@@ -560,7 +460,6 @@ void BRepOffset_MakeOffset::Clear()
 //function : AddFace
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
   myFaces.Add(F);    
   //-------------
@@ -575,124 +474,33 @@ void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
 //function : SetOffsetOnFace
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face&  F, 
-                                           const Standard_Real Off)
+                                            const Standard_Real Off)
 {
   if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
   myFaceOffset.Bind(F,Off);
 }
 
-//=======================================================================
-//function : RemoveCorks
-//purpose  : 
-//=======================================================================
-
-static 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 ( AffichOffC) 
-    DBRep::Set("myInit", SS);
-#endif
-
-}
-
-static 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  : 
-//=======================================================================
-
-static 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 (!myFaces.Contains(Root))
-      OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
-  }
-}
-
-//=======================================================================
-//function : EvalMax
-//purpose  : 
-//=======================================================================
-
-static 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;
-  }
-}
-
-
 //=======================================================================
 //function : MakeOffsetShape
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::MakeOffsetShape()
 {  
-  myDone = Standard_False;
+  myDone     = Standard_False;
   //------------------------------------------
   // Construction of myShape without caps.
   //------------------------------------------
-  if(!myFaces.IsEmpty())
-  {
+  if(!myFaces.IsEmpty()) {
     RemoveCorks (myShape,myFaces);
   }
-
+  
   if (!CheckInputData())
   {
     // There is error in input data.
     // Check Error() method.
-      return;
-    }
+    return;
+  }
 
   TopAbs_State       Side = TopAbs_IN;
   if (myOffset < 0.) Side = TopAbs_OUT;
@@ -731,7 +539,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   //-----------------
   TopTools_IndexedMapOfShape& Modif    = Inter.TouchedFaces(); 
   TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
-
+  
   if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
   //-------------------------------------------------------
   // Unwinding 2D and reconstruction of modified faces
@@ -742,7 +550,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   // reconstructed edges
   //------------------------------------------------------
   if (!Modif.IsEmpty()) MakeFaces (Modif);
-
+  //
   if (myThickening)
     MakeMissingWalls();
 
@@ -755,6 +563,12 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   //--------------
   SelectShells ();
   //----------------------------------
+  // Remove INTERNAL edges if necessary
+  //----------------------------------
+  if (myRemoveIntEdges) {
+    RemoveInternalEdges();
+  }
+  //----------------------------------
   // Coding of regularities.
   //----------------------------------
   EncodeRegularity();
@@ -784,13 +598,10 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   myDone = Standard_True;
 }
 
-
-
 //=======================================================================
 //function : MakeThickSolid
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::MakeThickSolid() 
 {
   //--------------------------------------------------------------
@@ -872,7 +683,6 @@ void BRepOffset_MakeOffset::MakeThickSolid()
 //function : IsDone
 //purpose  : 
 //=======================================================================
-
 Standard_Boolean BRepOffset_MakeOffset::IsDone() const
 {
   return myDone;
@@ -882,7 +692,6 @@ Standard_Boolean BRepOffset_MakeOffset::IsDone() const
 //function : Error
 //purpose  : 
 //=======================================================================
-
 BRepOffset_Error BRepOffset_MakeOffset::Error() const
 {
   return myError;
@@ -892,78 +701,11 @@ BRepOffset_Error BRepOffset_MakeOffset::Error() const
 //function : Shape
 //purpose  : 
 //=======================================================================
-
 const TopoDS_Shape&  BRepOffset_MakeOffset::Shape() const 
 {
   return myOffsetShape;
 }
 
-//=======================================================================
-//function : TrimEdge
-//purpose  : Trim the edge of the largest of descendants in AsDes2d.
-//           Order in AsDes two vertices that have trimmed the edge.
-//=======================================================================
-
-static 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);
-  
-  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_MakeOffset::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_MakeOffset::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);
-    }
-  }
-}
-
 //=======================================================================
 //function : BuildOffsetByInter
 //purpose  : 
@@ -1003,27 +745,27 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     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);
-       }
+        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);
@@ -1056,12 +798,11 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   // 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())
-  {
+  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, 
-                                        AsDes2d, myOffset, aCurrFaceTol);
+                                        AsDes, AsDes2d, myOffset, aCurrFaceTol);
   }
   //-----------------------------------------------------------
   // Great restriction of new edges and update of AsDes.
@@ -1071,53 +812,100 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   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));}
+    if (MES.IsBound(NF)) {
+      NF = TopoDS::Face(MES(NF));
+    }
+    //
     TopTools_MapOfShape View;
-    for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
-      const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current());
-      if (View.Add(EI)) {
-       if (Build.IsBound(EI)) {
-         NE = Build(EI);
-         if (NE.ShapeType() == TopAbs_EDGE) {
-           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()) {
-             if (NewEdges.Add(ExpC.Current())) {
-               TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
-               NEC.Free(Standard_True);
-               if (!AsDes2d->Descendant(NEC).IsEmpty()) {
-                 TrimEdge (NEC,AsDes2d,AsDes);
-               }
-               else {
-                 AsDes->Remove(NEC);
-               }
-             }
-           }
-         }
-       }
-       else {
-         NE = MapSF(FI).Generated(EI);
-         //// modified by jgv, 19.12.03 for OCC4455 ////
-         NE.Orientation( EI.Orientation() );
-         ///////////////////////////////////////////////
-         if (MES.IsBound(NE)) {
-           NE = MES(NE);
-           NE.Orientation(EI.Orientation());
-           if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} 
-         }
-         AsDes->Add(NF,NE);
-       } 
+    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);
+      } 
     }
   }
   
@@ -1133,12 +921,20 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
       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())
-  {
+  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);
@@ -1147,8 +943,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   // Intersections 2d on caps.
   //----------------------------------------------
   Standard_Integer i;
-  for (i = 1; i <= myFaces.Extent(); 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);
@@ -1157,8 +952,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   //-------------------------------
   // Unwinding of extended Faces.
   //-------------------------------
-  myMakeLoops.Build(LFE  ,AsDes,IMOE);
-
+  //
+  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
@@ -1172,91 +977,91 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     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);
+        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 (AffichInt2d) {
-           sprintf(name,"AF_%d",NbAF++);
-           DBRep::Set(name,OFE);
-         }
+          if (AffichInt2d) {
+            sprintf(name,"AF_%d",NbAF++);
+            DBRep::Set(name,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);
+          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 (AffichInt2d) {
-             sprintf(name,"AE_%d",NbAE++);
-             DBRep::Set(name,COE);
-             COES.Add(COE);
-           }
+            if (AffichInt2d) {
+              sprintf(name,"AE_%d",NbAE++);
+              DBRep::Set(name,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));     
-             }
-           }
-         }
-       }
+            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);
+        /*myInitOffsetFace.Bind(FI,OF);
+        myImageOffset.SetRoot(OF);
 #ifdef DRAW 
-       if (AffichInt2d) {
-         sprintf(name,"AF_%d",NbAF++);
-         DBRep::Set(name,OF);
-       }
+        if (AffichInt2d) {
+          sprintf(name,"AF_%d",NbAF++);
+          DBRep::Set(name,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);
+        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 (AffichInt2d) {
-               sprintf(name,"AE_%d",NbAE++);
-               DBRep::Set(name,COE);
-               COES.Add(COE);
-             }
+              if (AffichInt2d) {
+                sprintf(name,"AE_%d",NbAE++);
+                DBRep::Set(name,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);
+              
+              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 (AffichInt2d) {
-             sprintf(name,"AE_%d",NbAE++);
-             DBRep::Set(name,OE);
-             COES.Add(OE);
-           }
+            if (AffichInt2d) {
+              sprintf(name,"AE_%d",NbAE++);
+              DBRep::Set(name,OE);
+              COES.Add(OE);
+            }
 #endif
 
-           const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
-           myAsDes->Add(OE,LV);
-         }
-       }
+            const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
+            myAsDes->Add(OE,LV);
+          }
+        }*/
       }
     }
     else {
@@ -1264,26 +1069,26 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
       myImageOffset.SetRoot(OF);
       TopTools_MapOfShape View;
       for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-          Exp2.More(); Exp2.Next()) {
+           Exp2.More(); Exp2.Next()) {
 
-       const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
-       myAsDes->Add (OF,COE);
+        const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
+        myAsDes->Add (OF,COE);
 #ifdef DRAW
-       if (AffichInt2d) {
-         sprintf(name,"AE_%d",NbAE++);
-         DBRep::Set(name,COE);
-         COES.Add(COE);
-       }
+        if (AffichInt2d) {
+          sprintf(name,"AE_%d",NbAE++);
+          DBRep::Set(name,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)); 
-         }
-       }
+        
+        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));        
+          }
+        }
       } 
     }
   }
@@ -1300,49 +1105,49 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
       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);
-       }
+        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);
+        }
       }
     }
   }
@@ -1358,38 +1163,38 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     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())) ;
+        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 (AffichInt2d) {
-           sprintf(name,"AE_%d",NbAE++);
-           DBRep::Set(name,COE);
-           COES.Add(COE);
-         }
+          if (AffichInt2d) {
+            sprintf(name,"AE_%d",NbAE++);
+            DBRep::Set(name,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));   
-         }
-       }
+          
+          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));
-       }
+        myAsDes->Add(Cork,OE);
+        if (AsDes->HasDescendant(OE)) {
+          myAsDes->Add(OE,AsDes->Descendant(OE));
+        }
 #ifdef DRAW
-       if (AffichInt2d) {
-         sprintf(name,"AE_%d",NbAE++);
-         DBRep::Set(name,OE);
-         COES.Add(OE);
-       }
+        if (AffichInt2d) {
+          sprintf(name,"AE_%d",NbAE++);
+          DBRep::Set(name,OE);
+          COES.Add(OE);
+        }
 #endif
       }
     }
@@ -1401,6 +1206,322 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
 #endif
 }
 
+//=======================================================================
+//function : BuildSplitsOfFaces
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffset::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
@@ -1441,27 +1562,27 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
     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);
-       }
+        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);
@@ -1477,60 +1598,60 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
     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);
-       }
+        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));
+        // ----------------------
+        // 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);      
+        myInitOffsetEdge.Bind (E,EOn1);      
       }
     }
   }
@@ -1549,42 +1670,42 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
       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);
+        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));
-         }
-       } 
+      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));
+          }
+        
       }
     }
   }
@@ -1605,12 +1726,12 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
     const TopoDS_Shape& SI = It.Key(); 
     const BRepOffset_Offset& SF = It.Value();
     if (SF.Status() == BRepOffset_Reversed ||
-       SF.Status() == BRepOffset_Degenerated ) {
+        SF.Status() == BRepOffset_Degenerated ) {
       //------------------------------------------------
       // Degenerated or returned faces are not stored.
       //------------------------------------------------
       continue; 
-    }  
+    }        
 
     const TopoDS_Face&  OF = It.Value().Face();
     myInitOffsetFace.Bind    (SI,OF);      
@@ -1619,27 +1740,27 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
     
     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));
-       }
+           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());
+           Exp.More(); Exp.Next()) {
+        myAsDes->Add (OF,Exp.Current());
       }
     }
   }
@@ -1649,13 +1770,10 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
 #endif
 }
 
-
-
 //=======================================================================
 //function : SelfInter
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
 {
 #ifdef OCCT_DEBUG
@@ -1673,12 +1791,10 @@ void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
 #endif
 }
 
-
 //=======================================================================
 //function : ToContext
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
 {
   TopTools_DataMapOfShapeShape        Created;   
@@ -1697,14 +1813,14 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
   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()) {
+         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);
+        //----------------------------------------------------------------
+        // The edges of context faces that are not in the initial shape
+        // can appear in the result.
+        //----------------------------------------------------------------
+        //myAsDes->Add(CF,E);
       }  
     }
   }
@@ -1718,28 +1834,28 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
   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()) {
+         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);
-           }
-         }
-       }
+        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);
+            }
+          }
+        }
       }
     }
   }
@@ -1768,26 +1884,26 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
 
     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);
-         }
-       }
+           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 {
@@ -1795,8 +1911,8 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
       // Tube
       //---------------------
       for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-          exp.More(); exp.Next()) {
-       myAsDes->Add (NF,exp.Current());
+           exp.More(); exp.Next()) {
+        myAsDes->Add (NF,exp.Current());
       }
     }    
     MapSF.UnBind(S);
@@ -1813,21 +1929,19 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
       TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
       Or = myInitOffsetEdge.Image(E).First().Orientation();
       if (NE.Orientation() == TopAbs_REVERSED) 
-       NE.Orientation(TopAbs::Reverse(Or));
+        NE.Orientation(TopAbs::Reverse(Or));
       else
-       NE.Orientation(Or);
+        NE.Orientation(Or);
       myInitOffsetEdge.Remove(OE);
       myInitOffsetEdge.Bind(E,NE);
     }
   }
 }
 
-
 //=======================================================================
 //function : UpdateFaceOffset
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::UpdateFaceOffset()
 {
   TopTools_MapOfShape M;
@@ -1857,7 +1971,7 @@ void BRepOffset_MakeOffset::UpdateFaceOffset()
       const TopoDS_Face& FF = TopoDS::Face(exp.Current());
       if ( !M.Add(FF)) continue;
       if ( myFaceOffset.IsBound(FF))
-       myFaceOffset.UnBind(FF);
+        myFaceOffset.UnBind(FF);
       myFaceOffset.Bind(FF,CurOffset);
     }
   }
@@ -1867,7 +1981,6 @@ void BRepOffset_MakeOffset::UpdateFaceOffset()
 //function : CorrectConicalFaces
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::CorrectConicalFaces()
 {
   if(myOffsetShape.IsNull())
@@ -2017,7 +2130,7 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
         Ul = 2.*M_PI;
       Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
       /*
-       if (!isFirstFace)
+        if (!isFirstFace)
         {
         gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
         if (Abs(Uf - f) > Precision::Confusion())
@@ -2294,12 +2407,10 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
   }
 }
 
-
 //=======================================================================
 //function : Intersection3D
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
 {
 #ifdef OCCT_DEBUG
@@ -2310,7 +2421,7 @@ void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
   }
 #endif
   TopTools_ListOfShape OffsetFaces;  // list of faces // created.
-  MakeList (OffsetFaces,myInitOffsetFace,myFaces);
+  MakeList (OffsetFaces, myInitOffsetFace, myFaces);
 
   if (!myFaces.IsEmpty()) {     
     Standard_Boolean InSide = (myOffset < 0.); // Temporary
@@ -2347,7 +2458,7 @@ void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
 //=======================================================================
 
 void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Modif,
-                                          const TopTools_IndexedMapOfShape& NewEdges)
+                                           const TopTools_IndexedMapOfShape& NewEdges)
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {
@@ -2367,7 +2478,8 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod
   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);
+    Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(F);
+    BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,aCurrFaceTol);
   }
 
 #ifdef OCCT_DEBUG
@@ -2378,12 +2490,10 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod
 #endif
 }
 
-
 //=======================================================================
 //function : MakeLoops
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
 {
 #ifdef OCCT_DEBUG
@@ -2403,10 +2513,20 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
     if (!myFaces.Contains(Modif(i)))
       LF.Append(Modif(i));
   }
-  myMakeLoops.Build(LF,myAsDes,myImageOffset);
-
-  //-----------------------------------------
-  // unwinding of caps.
+  //
+  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));
@@ -2425,7 +2545,6 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
 //purpose  : Reconstruction of topologically unchanged faces that
 //           share edges that were reconstructed.
 //=======================================================================
-
 void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
 {
 #ifdef OCCT_DEBUG
@@ -2438,58 +2557,34 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
   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());
-    LOF.Append(F);
+    if (!myImageOffset.HasImage(F) && aMFence.Add(F)) {
+      LOF.Append(F);
+    }
   }
-  myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
-  
+  //
+  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 ( ChronBuild) Clock.Show();
 #endif
 }
 
-//=======================================================================
-//function : UpdateInitOffset
-//purpose  : Update and cleaning of myInitOffset 
-//=======================================================================
-
-static 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 : MakeMissingWalls
 //purpose  : 
@@ -2504,35 +2599,35 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
 
   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;
+  {
+    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;
     Standard_Boolean isBuildFromScratch = Standard_False; // Problems with edges.
-      for (; itl.More(); itl.Next())
-       {
-         TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
-
+    for (; itl.More(); itl.Next())
+    {
+      TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+      
       // Check for offset existence.
-         if (!myInitOffsetEdge.HasImage(anEdge))
-           continue;
-
+      if (!myInitOffsetEdge.HasImage(anEdge))
+        continue;
+      
       // Check for existence of two different vertices.
-         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;
+      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(OE,     V4, V3);
       TopExp::Vertices(anEdge, V1, V2);
       Standard_Real aF, aL;
       const Handle(Geom_Curve) &aC = BRep_Tool::Curve(anEdge, aF, aL);
       if (!aC.IsNull() &&
-         (!aC->IsClosed() && !aC->IsPeriodic()))
+          (!aC->IsClosed() && !aC->IsPeriodic()))
       {
         gp_Pnt aPntF = BRep_Tool::Pnt(V1);
         gp_Pnt aPntL = BRep_Tool::Pnt(V2);
@@ -2565,338 +2660,338 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
       }
 
       TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
-         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;
-           }
-
-         OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
-         TopoDS_Edge E3, E4;
+      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;
+      }
+
+      OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
+      TopoDS_Edge E3, E4;
       Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
       if (FirstStep || isBuildFromScratch)
-           {
-             E4 = BRepLib_MakeEdge( V1, V4 );
+      {
+        E4 = BRepLib_MakeEdge( V1, V4 );
         if (FirstStep)
-             StartEdge = E4;
-           }
-         else
-           E4 = PrevEdge;
-         if (V2.IsSame(StartVertex) && !ArcOnV2)
-           E3 = StartEdge;
-         else
-           E3 = BRepLib_MakeEdge( V2, V3 );
-         E4.Reverse();
-
+          StartEdge = E4;
+      }
+      else
+        E4 = PrevEdge;
+      if (V2.IsSame(StartVertex) && !ArcOnV2)
+        E3 = StartEdge;
+      else
+        E3 = BRepLib_MakeEdge( V2, V3 );
+      E4.Reverse();
+      
       if (isBuildFromScratch)
       {
         E3.Reverse();
         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;
+      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;
                 //
-                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);
+                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());
                 }
               }
-              else //case of cone
+              //
+              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
               {
-                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);
+                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);
               }
-            } //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
-           {
+            }
+            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
+      {
         if (isBuildFromScratch)
         {
           PrevEdge = TopoDS::Edge(E4);
@@ -2905,21 +3000,20 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
         }
         else
         {
-             PrevEdge = E3;
-             PrevVertex = V2;
-           }
+          PrevEdge = E3;
+          PrevVertex = V2;
+        }
       }
-         FirstStep = Standard_False;
-       }
+      FirstStep = Standard_False;
     }
+  }
 }
 
 //=======================================================================
 //function : MakeShells
 //purpose  : 
 //=======================================================================
-
-void BRepOffset_MakeOffset::MakeShells ()
+void BRepOffset_MakeOffset::MakeShells()
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {  
@@ -2928,30 +3022,264 @@ void BRepOffset_MakeOffset::MakeShells ()
     Clock.Start();
   }
 #endif
-  BRepTools_Quilt Glue;
+
+  //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()) {
+  //
+  for (; it.More(); it.Next()) {
     TopTools_ListOfShape Image;
     myImageOffset.LastImage(it.Value(),Image);
     TopTools_ListIteratorOfListOfShape it2(Image);
-    for ( ; it2.More(); it2.Next()) {
-      Glue.Add(it2.Value());
+    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)
-  {
+  //
+  if (myThickening) {
     TopExp_Explorer Explo(myShape, TopAbs_FACE);
-    for (; Explo.More(); Explo.Next())
-           Glue.Add(Explo.Current());
-      
-    for (it.Initialize(myWalls); it.More(); it.Next())
-           Glue.Add(it.Value());
+    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();
   }
-
-  myOffsetShape = Glue.Shells();
   //
   //Set correct value for closed flag
   TopExp_Explorer Explo(myOffsetShape, TopAbs_SHELL);
@@ -2965,14 +3293,13 @@ void BRepOffset_MakeOffset::MakeShells ()
         aS.Closed(Standard_True);
       }
     }
-  }               
+  }
 }
 
 //=======================================================================
 //function : MakeSolid
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::MakeSolid ()
 {
  if (myOffsetShape.IsNull()) return;
@@ -3068,7 +3395,6 @@ void BRepOffset_MakeOffset::MakeSolid ()
 //function : SelectShells
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::SelectShells ()
 {  
   TopTools_MapOfShape FreeEdges;
@@ -3083,7 +3409,7 @@ void BRepOffset_MakeOffset::SelectShells ()
     const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
     if (LA.Extent() < 2) {
       if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
-             FreeEdges.Add(E);                       
+        FreeEdges.Add(E);                       
       }
     }  
   }
@@ -3098,7 +3424,6 @@ void BRepOffset_MakeOffset::SelectShells ()
 //function : OffsetFacesFromShapes
 //purpose  : 
 //=======================================================================
-
 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
 {
   return myInitOffsetFace;
@@ -3110,7 +3435,6 @@ const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
 //function : GetJoinType
 //purpose  : Query offset join type.
 //=======================================================================
-
 GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
 {
   return myJoin;
@@ -3120,7 +3444,6 @@ GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
 //function : OffsetEdgesFromShapes
 //purpose  : 
 //=======================================================================
-
 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
 {
   return myInitOffsetEdge;
@@ -3132,19 +3455,15 @@ const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
 //function : ClosingFaces
 //purpose  : 
 //=======================================================================
-
 const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
 {
   return myFaces;
 }
 
-
-
 //=======================================================================
 //function : EncodeRegularity
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::EncodeRegularity ()
 {
 #ifdef OCCT_DEBUG
@@ -3195,38 +3514,38 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
  
     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);
-           }
-         }
-       }
+        // 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;
     }
@@ -3245,32 +3564,32 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
       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);
+        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);
+        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;
-       }
+        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;
-       }
+        if ( exp2.Current().IsSame(Root1)) {
+          B.Continuity(OE,F1,F2,GeomAbs_G1);
+          break;
+        }
       }
     }
     else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
@@ -3278,42 +3597,42 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
     //  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);
+                                       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);
-         }
-       }
+        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());
-         }
-       }
+        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;
-         }
-       }
+        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;
+          }
+        }
       }
     }
   }
@@ -3324,141 +3643,16 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
 }
 
 
-
 //=======================================================================
-//function : UpDateTolerance
-//purpose  : 
+//function : CheckInputData
+//purpose  : Check input data for possiblity of offset perform.
 //=======================================================================
-
-void UpdateTolerance (TopoDS_Shape& S,
-                                       const TopTools_IndexedMapOfShape& Faces)
+Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
 {
-  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 : CorrectSolid
-//purpose  : 
-//=======================================================================
-void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
-{
-  BRep_Builder aBB;
-  TopoDS_Shape anOuterShell;
-  NCollection_List<Standard_Real> aVols;
-  Standard_Real aVolMax = 0., anOuterVol = 0.;
-
-  TopoDS_Iterator anIt(theSol);
-  for(; anIt.More(); anIt.Next())
-  {
-    const TopoDS_Shape& aSh = anIt.Value();
-    GProp_GProps aVProps;
-    BRepGProp::VolumeProperties(aSh, aVProps, Standard_True);
-    if(Abs(aVProps.Mass()) > aVolMax)
-    {
-      anOuterVol = aVProps.Mass();
-      aVolMax = Abs(anOuterVol);
-      anOuterShell = aSh; 
-    }
-    aVols.Append(aVProps.Mass());
-  }
-  //
-  if(anOuterVol < 0.)
-  {
-    anOuterShell.Reverse();
-  }
-  TopoDS_Solid aNewSol;
-  aBB.MakeSolid(aNewSol);
-  aNewSol.Closed(Standard_True);
-  aBB.Add(aNewSol, anOuterShell);
-  BRepClass3d_SolidClassifier aSolClass(aNewSol);
-  //
-  anIt.Initialize(theSol);
-  NCollection_List<Standard_Real>::Iterator aVIt(aVols);
-  for(; anIt.More(); anIt.Next(), aVIt.Next())
-  {
-    TopoDS_Shell aSh = TopoDS::Shell(anIt.Value());
-    if(aSh.IsSame(anOuterShell))
-    {
-      continue;
-    }
-    else
-    {
-      TopExp_Explorer aVExp(aSh, TopAbs_VERTEX);
-      const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current());
-      gp_Pnt aP = BRep_Tool::Pnt(aV);
-      aSolClass.Perform(aP, BRep_Tool::Tolerance(aV));
-      if(aSolClass.State() == TopAbs_IN)
-      {
-        if(aVIt.Value() > 0.)
-        {
-          aSh.Reverse();
-        }
-        aBB.Add(aNewSol, aSh);
-      }
-      else
-      {
-        if(aVIt.Value() < 0.)
-        {
-          aSh.Reverse();
-        }
-        TopoDS_Solid aSol;
-        aBB.MakeSolid(aSol);
-        aSol.Closed(Standard_True);
-        aBB.Add(aSol, aSh);
-        theSolList.Append(aSol);
-      }
-    }
-  }
-  theSol = aNewSol;
-}
-
-//=======================================================================
-//function : CheckInputData
-//purpose  : Check input data for possiblity of offset perform.
-//=======================================================================
-Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
-{
-  // Set initial error state.
-  myError = BRepOffset_NoError;
-  TopoDS_Shape aTmpShape;
-  myBadShape = aTmpShape;
+  // Set initial error state.
+  myError = BRepOffset_NoError;
+  TopoDS_Shape aTmpShape;
+  myBadShape = aTmpShape;
 
   // Non-null offset.
   if (Abs(myOffset) <= myTol)
@@ -3612,7 +3806,6 @@ Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
   return Standard_True;
 }
 
-
 //=======================================================================
 //function : CheckInputData
 //purpose  : Check input data for possiblity of offset perform.
@@ -3621,3 +3814,1181 @@ const TopoDS_Shape& BRepOffset_MakeOffset::GetBadShape() const
 {
   return myBadShape;
 }
+
+//=======================================================================
+//function : RemoveInternalEdges
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffset::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 ( AffichOffC) 
+    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;
+  }
+}
+
+//=======================================================================
+//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_MakeOffset::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_MakeOffset::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 : CorrectSolid
+//purpose  : 
+//=======================================================================
+void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
+{
+  BRep_Builder aBB;
+  TopoDS_Shape anOuterShell;
+  NCollection_List<Standard_Real> aVols;
+  Standard_Real aVolMax = 0., anOuterVol = 0.;
+
+  TopoDS_Iterator anIt(theSol);
+  for(; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Shape& aSh = anIt.Value();
+    GProp_GProps aVProps;
+    BRepGProp::VolumeProperties(aSh, aVProps, Standard_True);
+    if(Abs(aVProps.Mass()) > aVolMax)
+    {
+      anOuterVol = aVProps.Mass();
+      aVolMax = Abs(anOuterVol);
+      anOuterShell = aSh; 
+    }
+    aVols.Append(aVProps.Mass());
+  }
+  //
+  if(anOuterVol < 0.)
+  {
+    anOuterShell.Reverse();
+  }
+  TopoDS_Solid aNewSol;
+  aBB.MakeSolid(aNewSol);
+  aNewSol.Closed(Standard_True);
+  aBB.Add(aNewSol, anOuterShell);
+  BRepClass3d_SolidClassifier aSolClass(aNewSol);
+  //
+  anIt.Initialize(theSol);
+  NCollection_List<Standard_Real>::Iterator aVIt(aVols);
+  for(; anIt.More(); anIt.Next(), aVIt.Next())
+  {
+    TopoDS_Shell aSh = TopoDS::Shell(anIt.Value());
+    if(aSh.IsSame(anOuterShell))
+    {
+      continue;
+    }
+    else
+    {
+      TopExp_Explorer aVExp(aSh, TopAbs_VERTEX);
+      const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current());
+      gp_Pnt aP = BRep_Tool::Pnt(aV);
+      aSolClass.Perform(aP, BRep_Tool::Tolerance(aV));
+      if(aSolClass.State() == TopAbs_IN)
+      {
+        if(aVIt.Value() > 0.)
+        {
+          aSh.Reverse();
+        }
+        aBB.Add(aNewSol, aSh);
+      }
+      else
+      {
+        if(aVIt.Value() < 0.)
+        {
+          aSh.Reverse();
+        }
+        TopoDS_Solid aSol;
+        aBB.MakeSolid(aSol);
+        aSol.Closed(Standard_True);
+        aBB.Add(aSol, aSh);
+        theSolList.Append(aSol);
+      }
+    }
+  }
+  theSol = aNewSol;
+}
+
+//=======================================================================
+//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;
+}
index a8a97f7277a9341fd6a30ec754a3cc43e7a9729c..c41af537226740812957d1c803eb2b0cd7784aae 100644 (file)
@@ -46,7 +46,8 @@ is
             Mode         : Mode     from BRepOffset = BRepOffset_Skin;
             Intersection : Boolean  from Standard   = Standard_False;
             SelfInter    : Boolean  from Standard   = Standard_False;
-             Join         : JoinType from GeomAbs    = GeomAbs_Arc)
+             Join         : JoinType from GeomAbs    = GeomAbs_Arc;
+             RemoveIntEdges:Boolean  from Standard   = Standard_False)
        ---Purpose: Constructs a shape parallel to the shape S, where
        -- - S may be a face, a shell, a solid or a compound of these shape kinds;
        -- - Offset is the offset value. The offset shape is constructed:
@@ -82,6 +83,8 @@ is
        -- - if Join is equal to GeomAbs_Intersection, then the parallels to the
        -- two adjacent faces are enlarged and intersected,
        -- so that there are no free edges on parallels to faces.
+        -- RemoveIntEdges flag defines whether to remove the INTERNAL edges 
+        -- from the result or not.
        --   Warnings
        -- 1. All the faces of the shape S should be based on the surfaces
        -- with continuity at least C1.
index f4245d5bb77523a7b9de25f8079196579a78bacf..9b1d0b73b06f97b70538725f75f51f02d03844d4 100644 (file)
@@ -43,9 +43,11 @@ BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape
  const BRepOffset_Mode  Mode, 
  const Standard_Boolean Intersection,
  const Standard_Boolean SelfInter,
- const GeomAbs_JoinType Join)
+ const GeomAbs_JoinType Join,
+ const Standard_Boolean RemoveIntEdges)
 {
-  myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter,Join);
+  myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter,
+                            Join, RemoveIntEdges);
   Build();
 }
 
index ec8a6a4bec6e33756cdfcca5ab2c3c288b43523d..bec7ba2638193a6100aee50e27fa2f595b2d6056 100644 (file)
@@ -53,7 +53,8 @@ is
             Mode         : Mode        from BRepOffset = BRepOffset_Skin;
             Intersection : Boolean     from Standard   = Standard_False;
             SelfInter    : Boolean     from Standard   = Standard_False;
-             Join         : JoinType    from GeomAbs    = GeomAbs_Arc)
+             Join         : JoinType    from GeomAbs    = GeomAbs_Arc;
+             RemoveIntEdges : Boolean   from Standard   = Standard_False)
        ---Purpose:  Constructs a hollowed solid from
        -- the solid S by removing the set of faces ClosingFaces from S, where:
        --       Offset defines the thickness of the walls. Its sign indicates
@@ -88,6 +89,8 @@ is
        --   then the parallels to the two adjacent faces are
        --   enlarged and intersected, so that there are no free
        --   edges on parallels to faces.
+        -- - RemoveIntEdges flag defines whether to remove the INTERNAL edges 
+        --   from the result or not.
        --   Warnings
        -- Since the algorithm of MakeThickSolid is based on
        -- MakeOffsetShape algorithm, the warnings are the same as for
index e8d865274605c3ad09c5c49cf5c7b6978c7c2026..5f645ab0805ad21c16c72dbb95c72f7c041a9158 100644 (file)
@@ -44,9 +44,11 @@ BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid
  const BRepOffset_Mode       Mode,
  const Standard_Boolean      Intersection,
  const Standard_Boolean      SelfInter,
- const GeomAbs_JoinType      Join)
+ const GeomAbs_JoinType      Join,
+ const Standard_Boolean      RemoveIntEdges)
 {
-  myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter,Join);
+  myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter,
+                            Join, RemoveIntEdges);
   TopTools_ListIteratorOfListOfShape it(ClosingFaces);
   for (; it.More(); it.Next()) {
     myOffsetShape.AddFace(TopoDS::Face(it.Value()));
index 987ce26f3c6439c0c6c7b4f1b293cf6d2e5e9f23..be3fa1751322ee2bf2bc39f8cfd9b47a3a1e8005 100644 (file)
@@ -803,7 +803,7 @@ static Standard_Integer SPLS(Draw_Interpretor& ,
 //=======================================================================
 
 Standard_Integer thickshell(Draw_Interpretor& ,
-                           Standard_Integer n, const char** a)
+                            Standard_Integer n, const char** a)
 {
 
   //OSD_Chronometer Clock;
@@ -818,9 +818,9 @@ Standard_Integer thickshell(Draw_Interpretor& ,
   if (n > 4)
     {
       if (!strcmp(a[4],"i"))
-       JT = GeomAbs_Intersection;
+        JT = GeomAbs_Intersection;
       if (!strcmp(a[4],"t"))
-       JT = GeomAbs_Tangent;
+        JT = GeomAbs_Tangent;
     }
   
   Standard_Boolean Inter = Standard_False; //Standard_True;
@@ -829,7 +829,7 @@ Standard_Integer thickshell(Draw_Interpretor& ,
     Tol = Draw::Atof(a[5]);
 
   BRepOffset_MakeOffset B;
-  B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT, Standard_True);
+  B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT, Standard_False, Standard_True);
 
 //  Clock.Start();
 
@@ -849,7 +849,7 @@ Standard_Integer thickshell(Draw_Interpretor& ,
 //=======================================================================
 
 Standard_Integer offsetshape(Draw_Interpretor& ,
-                            Standard_Integer n, const char** a)
+                             Standard_Integer n, const char** a)
 {
 
   //OSD_Chronometer Clock;
@@ -907,63 +907,73 @@ static Standard_Boolean      theYaBouchon;
 static Standard_Real         TheTolerance = Precision::Confusion();
 static Standard_Boolean      TheInter     = Standard_False;
 static GeomAbs_JoinType      TheJoin      = GeomAbs_Arc;
+static Standard_Boolean      RemoveIntEdges = Standard_False;
+static Standard_Boolean      RemoveInvalidFaces = Standard_False;
 
 Standard_Integer offsetparameter(Draw_Interpretor& di,
-                                Standard_Integer n, const char** a)
+                                 Standard_Integer n, const char** a)
 {
   if ( n == 1 ) { 
-    //cout << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << endl;
-    //cout << " Current Values" << endl;
-    //cout << "   --> Tolerance :" << TheTolerance << endl;
-    //cout << "   --> TheInter  :";
-    di << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << "\n";
+    di << " OffsetParameter Tol Inter(c/p) JoinType(a/i/t) [RemoveInternalEdges(r/k) RemoveInvalidFaces(r/k)]" << "\n";
     di << " Current Values" << "\n";
-    di << "   --> Tolerance :" << TheTolerance << "\n";
-    di << "   --> TheInter  :";
+    di << "   --> Tolerance : " << TheTolerance << "\n";
+    di << "   --> TheInter  : ";
     if ( TheInter) {
-      //cout << "Complet" ;
       di << "Complet" ;
     } else {
-      //cout << "Partial";
       di << "Partial";
     }
-    //cout << endl << "   --> TheJoin   :";
-    di << "\n" << "   --> TheJoin   :";
+    di << "\n" << "   --> TheJoin   : ";
     
     switch (TheJoin) {
-    //case GeomAbs_Arc:          cout << " Arc";          break;
-    //case GeomAbs_Intersection: cout << " Intersection"; break;
-    case GeomAbs_Arc:          di << " Arc";          break;
-    case GeomAbs_Intersection: di << " Intersection"; break;
+    case GeomAbs_Arc:          di << "Arc";          break;
+    case GeomAbs_Intersection: di << "Intersection"; break;
     default:
       break ;
     }
-    //cout << endl;
+    //
+    di << "\n" << "   --> Internal Edges : ";
+    if (RemoveIntEdges) {
+      di << "Remove";
+    }
+    else {
+      di << "Keep";
+    }
+    //
+    di << "\n" << "   --> Invalid Faces : ";
+    if (RemoveInvalidFaces) {
+      di << "Remove";
+    }
+    else {
+      di << "Keep";
+    }
     di << "\n";
-
+    //
     return 0;
   }
 
   if ( n < 4 ) return 1;
-  
+  //
   TheTolerance = Draw::Atof(a[1]);
   TheInter     = strcmp(a[2],"p");
-  
+  //
   if      ( !strcmp(a[3],"a")) TheJoin = GeomAbs_Arc;
   else if ( !strcmp(a[3],"i")) TheJoin = GeomAbs_Intersection;
   else if ( !strcmp(a[3],"t")) TheJoin = GeomAbs_Tangent;
-    
-  return 0;    
+  //
+  RemoveIntEdges = (n >= 5) ? !strcmp(a[4], "r") : Standard_False;
+  RemoveInvalidFaces = (n == 6) ? !strcmp(a[5], "r") : Standard_False;
+  //
+  return 0;
 }
 
-
 //=======================================================================
 //function : offsetinit
 //purpose  : 
 //=======================================================================
 
 Standard_Integer offsetload(Draw_Interpretor& ,
-                           Standard_Integer n, const char** a)
+                            Standard_Integer n, const char** a)
 {
   if ( n < 2) return 1;
   TopoDS_Shape  S  = DBRep::Get(a[1]);
@@ -973,7 +983,8 @@ Standard_Integer offsetload(Draw_Interpretor& ,
   TheRadius = Of;
 //  Standard_Boolean Inter = Standard_True;
   
-  TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin);
+  TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin,
+                       RemoveIntEdges,Standard_False,RemoveInvalidFaces);
   //------------------------------------------
   // recuperation et chargement des bouchons.
   //----------------------------------------
@@ -1076,7 +1087,7 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands,
 //=======================================================================
 
 static Standard_Integer Debou(Draw_Interpretor& theCommands,
-                             Standard_Integer narg, const char** a)
+                              Standard_Integer narg, const char** a)
 {
   Standard_Integer i ;
   Standard_Integer newnarg ;