0025926: 3D offset in mode "Complete" with Join type "Intersection"
authoremv <emv@opencascade.com>
Fri, 30 Oct 2015 13:27:02 +0000 (16:27 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 Nov 2015 12:27:42 +0000 (15:27 +0300)
Extension for colliding cases (Limited to work on planar cases only).

Test cases for issue CR25926

Update of test-cases according to the new behavior

168 files changed:
src/BRepAlgo/BRepAlgo_Tool.cxx
src/BRepOffset/BRepOffset_Inter2d.cxx
src/BRepOffset/BRepOffset_Inter2d.hxx
src/BRepOffset/BRepOffset_Inter3d.cxx
src/BRepOffset/BRepOffset_Inter3d.hxx
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepOffset/BRepOffset_MakeOffset.hxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.hxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.hxx
src/BRepTest/BRepTest_FeatureCommands.cxx
tests/offset/faces_type_i/C5
tests/offset/faces_type_i/C8
tests/offset/faces_type_i/D4
tests/offset/grids.list
tests/offset/shape_type_i/B4
tests/offset/shape_type_i/B6
tests/offset/shape_type_i/B8
tests/offset/shape_type_i/C8
tests/offset/shape_type_i_c/A1 [new file with mode: 0644]
tests/offset/shape_type_i_c/A2 [new file with mode: 0644]
tests/offset/shape_type_i_c/A3 [new file with mode: 0644]
tests/offset/shape_type_i_c/A4 [new file with mode: 0644]
tests/offset/shape_type_i_c/A5 [new file with mode: 0644]
tests/offset/shape_type_i_c/A6 [new file with mode: 0644]
tests/offset/shape_type_i_c/A7 [new file with mode: 0644]
tests/offset/shape_type_i_c/A8 [new file with mode: 0644]
tests/offset/shape_type_i_c/A9 [new file with mode: 0644]
tests/offset/shape_type_i_c/B1 [new file with mode: 0644]
tests/offset/shape_type_i_c/B2 [new file with mode: 0644]
tests/offset/shape_type_i_c/B3 [new file with mode: 0644]
tests/offset/shape_type_i_c/B4 [new file with mode: 0644]
tests/offset/shape_type_i_c/B5 [new file with mode: 0644]
tests/offset/shape_type_i_c/B6 [new file with mode: 0644]
tests/offset/shape_type_i_c/B7 [new file with mode: 0644]
tests/offset/shape_type_i_c/B8 [new file with mode: 0644]
tests/offset/shape_type_i_c/B9 [new file with mode: 0644]
tests/offset/shape_type_i_c/C1 [new file with mode: 0644]
tests/offset/shape_type_i_c/C2 [new file with mode: 0644]
tests/offset/shape_type_i_c/C3 [new file with mode: 0644]
tests/offset/shape_type_i_c/C4 [new file with mode: 0644]
tests/offset/shape_type_i_c/C5 [new file with mode: 0644]
tests/offset/shape_type_i_c/C6 [new file with mode: 0644]
tests/offset/shape_type_i_c/C7 [new file with mode: 0644]
tests/offset/shape_type_i_c/C8 [new file with mode: 0644]
tests/offset/shape_type_i_c/C9 [new file with mode: 0644]
tests/offset/shape_type_i_c/D1 [new file with mode: 0644]
tests/offset/shape_type_i_c/D2 [new file with mode: 0644]
tests/offset/shape_type_i_c/D3 [new file with mode: 0644]
tests/offset/shape_type_i_c/D4 [new file with mode: 0644]
tests/offset/shape_type_i_c/D5 [new file with mode: 0644]
tests/offset/shape_type_i_c/D6 [new file with mode: 0644]
tests/offset/shape_type_i_c/D7 [new file with mode: 0644]
tests/offset/shape_type_i_c/D8 [new file with mode: 0644]
tests/offset/shape_type_i_c/D9 [new file with mode: 0644]
tests/offset/shape_type_i_c/E1 [new file with mode: 0644]
tests/offset/shape_type_i_c/E2 [new file with mode: 0644]
tests/offset/shape_type_i_c/E3 [new file with mode: 0644]
tests/offset/shape_type_i_c/E4 [new file with mode: 0644]
tests/offset/shape_type_i_c/E5 [new file with mode: 0644]
tests/offset/shape_type_i_c/E6 [new file with mode: 0644]
tests/offset/shape_type_i_c/E7 [new file with mode: 0644]
tests/offset/shape_type_i_c/E8 [new file with mode: 0644]
tests/offset/shape_type_i_c/E9 [new file with mode: 0644]
tests/offset/shape_type_i_c/F1 [new file with mode: 0644]
tests/offset/shape_type_i_c/F2 [new file with mode: 0644]
tests/offset/shape_type_i_c/F3 [new file with mode: 0644]
tests/offset/shape_type_i_c/F4 [new file with mode: 0644]
tests/offset/shape_type_i_c/F5 [new file with mode: 0644]
tests/offset/shape_type_i_c/F6 [new file with mode: 0644]
tests/offset/shape_type_i_c/F7 [new file with mode: 0644]
tests/offset/shape_type_i_c/F8 [new file with mode: 0644]
tests/offset/shape_type_i_c/F9 [new file with mode: 0644]
tests/offset/shape_type_i_c/G1 [new file with mode: 0644]
tests/offset/shape_type_i_c/G2 [new file with mode: 0644]
tests/offset/shape_type_i_c/G3 [new file with mode: 0644]
tests/offset/shape_type_i_c/G4 [new file with mode: 0644]
tests/offset/shape_type_i_c/G5 [new file with mode: 0644]
tests/offset/shape_type_i_c/G6 [new file with mode: 0644]
tests/offset/shape_type_i_c/G7 [new file with mode: 0644]
tests/offset/shape_type_i_c/G8 [new file with mode: 0644]
tests/offset/shape_type_i_c/G9 [new file with mode: 0644]
tests/offset/shape_type_i_c/H1 [new file with mode: 0644]
tests/offset/shape_type_i_c/H2 [new file with mode: 0644]
tests/offset/shape_type_i_c/H3 [new file with mode: 0644]
tests/offset/shape_type_i_c/H4 [new file with mode: 0644]
tests/offset/shape_type_i_c/H5 [new file with mode: 0644]
tests/offset/shape_type_i_c/H6 [new file with mode: 0644]
tests/offset/shape_type_i_c/H7 [new file with mode: 0644]
tests/offset/shape_type_i_c/H8 [new file with mode: 0644]
tests/offset/shape_type_i_c/H9 [new file with mode: 0644]
tests/offset/shape_type_i_c/I1 [new file with mode: 0644]
tests/offset/shape_type_i_c/I2 [new file with mode: 0644]
tests/offset/shape_type_i_c/I3 [new file with mode: 0644]
tests/offset/shape_type_i_c/I4 [new file with mode: 0644]
tests/offset/shape_type_i_c/I5 [new file with mode: 0644]
tests/offset/shape_type_i_c/I6 [new file with mode: 0644]
tests/offset/shape_type_i_c/I7 [new file with mode: 0644]
tests/offset/shape_type_i_c/I8 [new file with mode: 0644]
tests/offset/shape_type_i_c/I9 [new file with mode: 0644]
tests/offset/shape_type_i_c/J2 [new file with mode: 0644]
tests/offset/shape_type_i_c/J3 [new file with mode: 0644]
tests/offset/shape_type_i_c/J4 [new file with mode: 0644]
tests/offset/shape_type_i_c/J5 [new file with mode: 0644]
tests/offset/shape_type_i_c/J6 [new file with mode: 0644]
tests/offset/shape_type_i_c/J7 [new file with mode: 0644]
tests/offset/shape_type_i_c/J8 [new file with mode: 0644]
tests/offset/shape_type_i_c/J9 [new file with mode: 0644]
tests/offset/shape_type_i_c/K1 [new file with mode: 0644]
tests/offset/shape_type_i_c/K2 [new file with mode: 0644]
tests/offset/shape_type_i_c/K3 [new file with mode: 0644]
tests/offset/shape_type_i_c/K4 [new file with mode: 0644]
tests/offset/shape_type_i_c/K5 [new file with mode: 0644]
tests/offset/shape_type_i_c/K6 [new file with mode: 0644]
tests/offset/shape_type_i_c/K7 [new file with mode: 0644]
tests/offset/shape_type_i_c/K8 [new file with mode: 0644]
tests/offset/shape_type_i_c/K9 [new file with mode: 0644]
tests/offset/shape_type_i_c/L1 [new file with mode: 0644]
tests/offset/shape_type_i_c/L2 [new file with mode: 0644]
tests/offset/shape_type_i_c/L3 [new file with mode: 0644]
tests/offset/shape_type_i_c/L4 [new file with mode: 0644]
tests/offset/shape_type_i_c/L5 [new file with mode: 0644]
tests/offset/shape_type_i_c/L6 [new file with mode: 0644]
tests/offset/shape_type_i_c/L7 [new file with mode: 0644]
tests/offset/shape_type_i_c/L8 [new file with mode: 0644]
tests/offset/shape_type_i_c/L9 [new file with mode: 0644]
tests/offset/shape_type_i_c/M1 [new file with mode: 0644]
tests/offset/shape_type_i_c/M2 [new file with mode: 0644]
tests/offset/shape_type_i_c/M3 [new file with mode: 0644]
tests/offset/shape_type_i_c/M4 [new file with mode: 0644]
tests/offset/shape_type_i_c/M5 [new file with mode: 0644]
tests/offset/shape_type_i_c/M6 [new file with mode: 0644]
tests/offset/shape_type_i_c/M7 [new file with mode: 0644]
tests/offset/shape_type_i_c/M8 [new file with mode: 0644]
tests/offset/shape_type_i_c/M9 [new file with mode: 0644]
tests/offset/shape_type_i_c/N1 [new file with mode: 0644]
tests/offset/shape_type_i_c/N2 [new file with mode: 0644]
tests/offset/shape_type_i_c/N3 [new file with mode: 0644]
tests/offset/shape_type_i_c/N4 [new file with mode: 0644]
tests/offset/shape_type_i_c/N5 [new file with mode: 0644]
tests/offset/shape_type_i_c/N6 [new file with mode: 0644]
tests/offset/shape_type_i_c/N7 [new file with mode: 0644]
tests/offset/shape_type_i_c/N8 [new file with mode: 0644]
tests/offset/shape_type_i_c/N9 [new file with mode: 0644]
tests/offset/shape_type_i_c/O1 [new file with mode: 0644]
tests/offset/shape_type_i_c/O2 [new file with mode: 0644]
tests/offset/shape_type_i_c/O3 [new file with mode: 0644]
tests/offset/shape_type_i_c/O4 [new file with mode: 0644]
tests/offset/shape_type_i_c/O5 [new file with mode: 0644]
tests/offset/shape_type_i_c/O6 [new file with mode: 0644]
tests/offset/shape_type_i_c/O7 [new file with mode: 0644]
tests/offset/shape_type_i_c/O8 [new file with mode: 0644]
tests/offset/shape_type_i_c/O9 [new file with mode: 0644]
tests/offset/shape_type_i_c/P1 [new file with mode: 0644]
tests/offset/shape_type_i_c/P2 [new file with mode: 0644]
tests/offset/shape_type_i_c/P3 [new file with mode: 0644]
tests/offset/shape_type_i_c/P4 [new file with mode: 0644]
tests/offset/shape_type_i_c/P5 [new file with mode: 0644]
tests/offset/shape_type_i_c/P6 [new file with mode: 0644]
tests/offset/shape_type_i_c/P7 [new file with mode: 0644]
tests/offset/shape_type_i_c/X1 [new file with mode: 0644]
tests/offset/shape_type_i_c/X2 [new file with mode: 0644]
tests/offset/shape_type_i_c/X3 [new file with mode: 0644]
tests/offset/shape_type_i_c/X4 [new file with mode: 0644]
tests/offset/shape_type_i_c/X5 [new file with mode: 0644]
tests/offset/shape_type_i_c/X6 [new file with mode: 0644]
tests/offset/shape_type_i_c/begin [new file with mode: 0644]

index 8d2110c..1cedf30 100644 (file)
@@ -31,7 +31,7 @@
 //purpose  : 
 //=======================================================================
 TopoDS_Shape BRepAlgo_Tool::Deboucle3D(const TopoDS_Shape& S,
-                                        const TopTools_MapOfShape& Boundary)
+                                       const TopTools_MapOfShape& Boundary)
 {
   TopoDS_Shape SS;
 
@@ -49,12 +49,19 @@ 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));
-         if (!Boundary.Contains(anEdge)  && 
-             !BRep_Tool::Degenerated(anEdge) )
-           JeGarde = Standard_False;
-       }
+        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;
+        }
       }
       if ( JeGarde) SS = S;
     }
index 91b16d5..0b8d7f6 100644 (file)
@@ -122,11 +122,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 
@@ -167,90 +167,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);
      }
    }  
@@ -267,11 +267,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) {
@@ -316,117 +317,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) );
+        }
     }
   
   //----------------------------------
@@ -447,30 +448,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()));
       }
     }
   }
@@ -490,31 +491,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++;
       }
     }
     //---------------------------------
@@ -537,12 +538,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) {
@@ -588,17 +590,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]);
@@ -608,12 +610,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() );
@@ -624,12 +626,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);
@@ -648,50 +650,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) );
     }
@@ -714,18 +716,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()));
       }
     }
   }
@@ -745,24 +747,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++;
       }
     }
     //---------------------------------
@@ -774,20 +776,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;
+        }
       }
     }
       
@@ -836,10 +838,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)))
@@ -852,29 +854,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)::DownCast (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)::DownCast (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)::DownCast (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)::DownCast (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();
@@ -957,161 +959,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;
@@ -1120,168 +1122,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)::DownCast (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)::DownCast (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)::DownCast (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)::DownCast (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)::DownCast (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)::DownCast (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
     {
@@ -1289,58 +1291,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 );
     }
@@ -1354,9 +1356,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);
@@ -1386,9 +1388,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;  
 }
@@ -1399,9 +1401,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++;
@@ -1427,9 +1429,10 @@ 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());       
+    const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());        
     j = 1;
     it2LE.Initialize(LE);
     
@@ -1440,10 +1443,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++;
@@ -1464,7 +1467,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
@@ -1488,24 +1492,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());
@@ -1517,15 +1531,15 @@ 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;
 
@@ -1548,48 +1562,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 8c3a843..d49720a 100644 (file)
@@ -41,31 +41,27 @@ public:
   //! 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.
-  Standard_EXPORT static void Compute (const Handle(BRepAlgo_AsDes)& AsDes, const TopoDS_Face& F, const TopTools_IndexedMapOfShape& NewEdges, const Standard_Real Tol);
+  Standard_EXPORT static void Compute (const Handle(BRepAlgo_AsDes)& AsDes, 
+                                       const TopoDS_Face& F, 
+                                       const TopTools_IndexedMapOfShape& NewEdges, 
+                                       const Standard_Real Tol);
   
-  Standard_EXPORT static void ConnexIntByInt (const TopoDS_Face& FI, BRepOffset_Offset& OFI, TopTools_DataMapOfShapeShape& MES, const TopTools_DataMapOfShapeShape& Build, const Handle(BRepAlgo_AsDes)& AsDes, const Standard_Real Offset, const Standard_Real Tol);
+  Standard_EXPORT static void ConnexIntByInt (const TopoDS_Face& FI, 
+                                              BRepOffset_Offset& OFI, 
+                                              TopTools_DataMapOfShapeShape& MES, 
+                                              const TopTools_DataMapOfShapeShape& Build, 
+                                              const Handle(BRepAlgo_AsDes)& AsDes, 
+                                              const Handle(BRepAlgo_AsDes)& AsDes2d, 
+                                              const Standard_Real Offset, 
+                                              const Standard_Real Tol);
 
 
 
 
 protected:
 
-
-
-
-
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BRepOffset_Inter2d_HeaderFile
index 6a7b958..0297153 100644 (file)
@@ -30,6 +30,7 @@
 #include <BRepOffset_Offset.hxx>
 #include <BRepOffset_Tool.hxx>
 #include <Extrema_ExtPC.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <Precision.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
@@ -50,8 +51,8 @@
 //purpose  : 
 //=======================================================================
 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)
@@ -65,8 +66,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); 
@@ -98,117 +99,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 
@@ -251,8 +195,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;
@@ -262,9 +206,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) ||
@@ -274,38 +218,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);
+          }
+        }
       }
     }
   }
@@ -351,13 +301,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);
+        }
+      }          
     }
   }
   //---------------------------------------------------------------------
@@ -379,84 +329,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);
+                  }
+                }
+              }
+            }
+          }
+        }
       }
     }
   }
@@ -474,106 +424,220 @@ void BRepOffset_Inter3d::ConnexIntByInt
  const BRepOffset_Analyse&              Analyse,
  TopTools_DataMapOfShapeShape&          MES,
  TopTools_DataMapOfShapeShape&          Build,
- TopTools_ListOfShape&                  Failed)
+ TopTools_ListOfShape&                  Failed,
+ const Standard_Boolean                 bIsPlanar)
 {
   //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);
+  // map the shape for vertices
+  if (bIsPlanar) {
+    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
   }
 }
 
@@ -589,7 +653,8 @@ void BRepOffset_Inter3d::ContextIntByInt
  const BRepOffset_Analyse&              Analyse,
  TopTools_DataMapOfShapeShape&          MES,
  TopTools_DataMapOfShapeShape&          Build,
- TopTools_ListOfShape&                  Failed)
+ TopTools_ListOfShape&                  Failed,
+ const Standard_Boolean                 bIsPlanar)
 {
   TopTools_MapOfShape              MV;
   TopExp_Explorer                  exp;
@@ -597,10 +662,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 +677,157 @@ 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);
+    //
+    if (bIsPlanar) {
+      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 +839,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 +862,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,18 +921,18 @@ 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;
-      BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
-//      if (mySide == TopAbs_OUT) O1 = TopAbs::Reverse(O1);
-      O1 = TopAbs::Reverse(O1);
-      LInt1.First().Orientation(O1);
+      TopAbs_Orientation anOri1, anOri2;
+      BRepOffset_Tool::OrientSection(OE,CF,OF1, anOri1,anOri2);
+//    if (mySide == TopAbs_OUT);
+      anOri1 = TopAbs::Reverse(anOri1);
+      LInt1.First().Orientation(anOri1);
       Store(CF,OF1,LInt1,LInt2);
       
       //------------------------------------------------------
@@ -807,18 +941,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 +968,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 anOri1, anOri2;
-           BRepOffset_Tool::OrientSection(OE,CF,OF1, anOri1,anOri2);
-//         if (mySide == TopAbs_OUT);
-            anOri1 = TopAbs::Reverse(anOri1);
-           LInt1.First().Orientation(anOri1);
-           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 +1047,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 +1068,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 +1121,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);
@@ -1003,6 +1137,3 @@ void BRepOffset_Inter3d::Store(const TopoDS_Face& F1,
   }
   SetDone(F1,F2);
 }
-
-
-
index 3b2e8c7..e9607c8 100644 (file)
@@ -53,9 +53,9 @@ public:
   
   Standard_EXPORT void ConnexIntByArc (const TopTools_ListOfShape& SetOfFaces, const TopoDS_Shape& ShapeInit, const BRepOffset_Analyse& Analyse, const BRepAlgo_Image& InitOffsetFace);
   
-  Standard_EXPORT void ConnexIntByInt (const TopoDS_Shape& SI, const BRepOffset_DataMapOfShapeOffset& MapSF, const BRepOffset_Analyse& A, TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& Build, TopTools_ListOfShape& Failed);
+  Standard_EXPORT void ConnexIntByInt (const TopoDS_Shape& SI, const BRepOffset_DataMapOfShapeOffset& MapSF, const BRepOffset_Analyse& A, TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& Build, TopTools_ListOfShape& Failed, const Standard_Boolean bIsPlanar = Standard_False);
   
-  Standard_EXPORT void ContextIntByInt (const TopTools_IndexedMapOfShape& ContextFaces, const Standard_Boolean ExtentContext, const BRepOffset_DataMapOfShapeOffset& MapSF, const BRepOffset_Analyse& A, TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& Build, TopTools_ListOfShape& Failed);
+  Standard_EXPORT void ContextIntByInt (const TopTools_IndexedMapOfShape& ContextFaces, const Standard_Boolean ExtentContext, const BRepOffset_DataMapOfShapeOffset& MapSF, const BRepOffset_Analyse& A, TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& Build, TopTools_ListOfShape& Failed, const Standard_Boolean bIsPlanar = Standard_False);
   
   Standard_EXPORT void ContextIntByArc (const TopTools_IndexedMapOfShape& ContextFaces, const Standard_Boolean ExtentContext, const BRepOffset_Analyse& Analyse, const BRepAlgo_Image& InitOffsetFace, BRepAlgo_Image& InitOffsetEdge);
   
index d6e012b..a051d92 100644 (file)
 #include <BRepBuilderAPI_Sewing.hxx>
 #include <Geom_Line.hxx>
 #include <NCollection_Vector.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>
 
 #include <stdio.h>
 // POP for NT
 //=======================================================================
 
 static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
-                                     Handle(BRepAlgo_AsDes)      AsDes)
+                                      Handle(BRepAlgo_AsDes)      AsDes)
 {
   TopTools_ListOfShape               LVP;
   TopTools_ListIteratorOfListOfShape it1LE ;    
@@ -153,34 +166,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
-       }
+        }
       }
     }
   }
@@ -203,30 +216,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++;
     }
@@ -236,6 +249,73 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 }  
 #endif
 
+
+//=======================================================================
+// static methods
+//=======================================================================
+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 ProcessMicroEdge(const TopoDS_Edge& theEdge,
+                                    const Handle(IntTools_Context)& theCtx);
+
+static 
+  Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF,
+                                   const TopoDS_Edge& theE,
+                                   gp_Dir& theDB);
+static 
+  Standard_Boolean CheckBiNormals(const TopoDS_Face& aFIm,
+                                  const TopoDS_Face& aFOr,
+                                  const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                                  const TopTools_MapOfShape& theMFence,
+                                  Standard_Boolean& bKeep,
+                                  Standard_Boolean& bRem,
+                                  const Standard_Boolean RemoveInvalidFaces);
+
+static 
+  void CheckBiNormals(TopTools_ListOfShape&  theLFImages,
+                      const TopoDS_Face& theF,
+                      const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                      TopTools_ListOfShape& theLFKeep,
+                      const Standard_Boolean RemoveInvalidFaces);
+
+static 
+  Standard_Boolean CheckNormals(const TopoDS_Face& theFIm,
+                                const TopoDS_Face& theFOr);
+
+static 
+  void UpdateInitOffset(BRepAlgo_Image&         myInitOffset,
+                        BRepAlgo_Image&         myImageOffset,
+                        const TopoDS_Shape&     myOffsetShape,
+                        const TopAbs_ShapeEnum &theShapeType);
+
+static 
+  void RemoveShapes(TopoDS_Shape& theS,
+                    const TopTools_ListOfShape& theLS);
+
+static 
+  Standard_Boolean IsSolid(const TopoDS_Shape& theS);
+
+static 
+  void UpdateHistory(const TopTools_ListOfShape& theLF,
+                     BOPAlgo_Builder& theGF,
+                     BRepAlgo_Image& theImage);
+
+static
+  Standard_Boolean IsPlanar(const TopoDS_Shape& theS);
+
 static BRepOffset_Error checkSinglePoint(const Standard_Real theUParam,
                                          const Standard_Real theVParam,
                                          const Handle(Geom_Surface)& theSurf,
@@ -243,14 +323,14 @@ static BRepOffset_Error checkSinglePoint(const Standard_Real theUParam,
 
 //---------------------------------------------------------------------
 static void UpdateTolerance (      TopoDS_Shape&               myShape,
-                            const TopTools_IndexedMapOfShape& myFaces);
+                             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)
+                                      const TopoDS_Edge& E,
+                                      Standard_Real& U)
 {
   // Search the vertex in the edge
 
@@ -272,13 +352,13 @@ static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
     const TopoDS_Shape& Vcur = itv.Value();
     if (V.IsSame(Vcur)) {
       if (VF.IsNull()) {
-       VF = Vcur;
+        VF = Vcur;
       }
       else {
-       rev = E.Orientation() == TopAbs_REVERSED;
-       if (Vcur.Orientation() == V.Orientation()) {
-         VF = Vcur;
-       }
+        rev = E.Orientation() == TopAbs_REVERSED;
+        if (Vcur.Orientation() == V.Orientation()) {
+          VF = Vcur;
+        }
       }
     }
     itv.Next();
@@ -308,42 +388,42 @@ static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
     L = L.Predivided(V.Location());
     if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
       BRep_ListIteratorOfListOfPointRepresentation itpr
-       ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
+        ((*((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();
+        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 {
@@ -354,25 +434,25 @@ static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
       BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
       L = L.Predivided(V.Location()); 
       BRep_ListIteratorOfListOfPointRepresentation itpr
-       ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
+        ((*((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();
+        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();
       }
     }
   }
@@ -406,9 +486,9 @@ static void GetEdgePoints(const TopoDS_Edge& anEdge,
 //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)
+                         const BRepOffset_Analyse& Analyser,
+                         TopTools_DataMapOfShapeListOfShape& Contours,
+                         TopTools_DataMapOfShapeShape& MapEF)
 {
   TopTools_ListOfShape Edges;
 
@@ -420,21 +500,21 @@ static void FillContours(const TopoDS_Shape& aShape,
       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);
-               }
-           }
-       }
+        {
+          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;
@@ -447,19 +527,19 @@ static void FillContours(const TopoDS_Shape& aShape,
       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;
-             }
-         }
+        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);
     }
 }
@@ -485,13 +565,15 @@ BRepOffset_MakeOffset::BRepOffset_MakeOffset()
 //=======================================================================
 
 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 Thickening,
+                                             const Standard_Boolean RemoveIntEdges,
+                                             const Standard_Boolean RemInvFaces)
 : 
 myOffset     (Offset),
 myTol        (Tol),
@@ -500,7 +582,9 @@ myMode       (Mode),
 myInter      (Inter),
 mySelfInter  (SelfInter),
 myJoin       (Join),
-myThickening (Thickening),
+myThickening    (Thickening),
+myRemoveIntEdges(RemoveIntEdges),
+myRemoveInvalidFaces(RemInvFaces),
 myDone     (Standard_False)
 
 {
@@ -515,13 +599,15 @@ myDone     (Standard_False)
 //=======================================================================
 
 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 Thickening,
+                                       const Standard_Boolean RemoveIntEdges,
+                                       const Standard_Boolean RemInvFaces)
 {
   myOffset     = Offset;
   myShape      = S;
@@ -530,9 +616,12 @@ void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape&    S,
   myInter      = Inter;
   mySelfInter  = SelfInter;
   myJoin       = Join;
-  myThickening = Thickening;
+  myThickening     = Thickening;
+  myRemoveIntEdges = RemoveIntEdges;
+  myRemoveInvalidFaces = RemInvFaces;
   myDone     = Standard_False;
   myIsPerformSewing = Standard_False;
+  myIsPlanar = Standard_False;
   Clear();
 }
 
@@ -575,7 +664,7 @@ void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
 //=======================================================================
 
 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);
@@ -587,7 +676,7 @@ void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face&  F,
 //=======================================================================
 
 static void RemoveCorks (TopoDS_Shape&               S,
-                        TopTools_IndexedMapOfShape& Faces)
+                         TopTools_IndexedMapOfShape& Faces)
 {  
   TopoDS_Compound SS;
   BRep_Builder    B;
@@ -621,6 +710,10 @@ static void RemoveCorks (TopoDS_Shape&               S,
 
 }
 
+//=======================================================================
+//function : IsConnectedShell
+//purpose  : 
+//=======================================================================
 static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
 {  
   BRepTools_Quilt Glue;
@@ -642,14 +735,17 @@ static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
 //=======================================================================
 
 static void MakeList (TopTools_ListOfShape&             OffsetFaces,
-                     const BRepAlgo_Image&             myInitOffsetFace,
-                     const TopTools_IndexedMapOfShape& myFaces)
+                      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());
+    if (!myFaces.Contains(Root)) {
+      if (myInitOffsetFace.HasImage(Root)) {
+        OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
+      }
+    }
   }
 }
 
@@ -677,6 +773,9 @@ static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
 void BRepOffset_MakeOffset::MakeOffsetShape()
 {  
   myDone = Standard_False;
+  //
+  // check if shape consists of only planar faces
+  myIsPlanar = IsPlanar(myShape);
   //------------------------------------------
   // Construction of myShape without caps.
   //------------------------------------------
@@ -753,6 +852,12 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   //--------------
   SelectShells ();
   //----------------------------------
+  // Remove INTERNAL edges if necessary
+  //----------------------------------
+  if (myRemoveIntEdges) {
+    RemoveInternalEdges();
+  }
+  //----------------------------------
   // Coding of regularities.
   //----------------------------------
   EncodeRegularity();
@@ -920,10 +1025,9 @@ const TopoDS_Shape&  BRepOffset_MakeOffset::Shape() const
 //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)
+void TrimEdge(TopoDS_Edge&                  NE,
+              const Handle(BRepAlgo_AsDes)& AsDes2d,
+              Handle(BRepAlgo_AsDes)& AsDes)
 {
   Standard_Real aSameParTol = Precision::Confusion();
   
@@ -933,31 +1037,33 @@ static void TrimEdge (TopoDS_Edge&                  NE,
   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.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 (!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;
+        UMin = U; V1   = V;
       }
       if (U > UMax) {
-       UMax = U; V2   = V;
+        UMax = U; V2   = V;
       }
     }
+    //
     if (V1.IsNull() || V2.IsNull()) {
       Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
     }
@@ -977,6 +1083,17 @@ static void TrimEdge (TopoDS_Edge&                  NE,
       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) {
+    BRepAdaptor_Curve aBAC(NE);
+    if (aBAC.GetType() == GeomAbs_Line) {
+      if (AsDes->HasAscendant(NE)) {
+        AsDes->Remove(NE);
+      }
     }
   }
 }
@@ -1020,27 +1137,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);
@@ -1064,9 +1181,9 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
 
   BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
   // Intersection between parallel faces
-  Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
+  Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
   // Intersection with caps.
-  Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
+  Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
 
 
   //---------------------------------------------------------------------------------
@@ -1078,7 +1195,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     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.
@@ -1088,53 +1205,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);
+      } 
     }
   }
   
@@ -1150,6 +1314,15 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
       const TopoDS_Face& aLocalFace = TopoDS::Face(MES(OFI));
       LFE.Append(aLocalFace);
       IMOE.SetRoot(aLocalFace);
+      //
+      if (anOrigins.Contains(aLocalFace)) {
+        anOrigins.ChangeFromKey(aLocalFace).Append(FI);
+      }
+      else {
+        TopTools_ListOfShape aLSx;
+        aLSx.Append(FI);
+        anOrigins.Add(aLocalFace, aLSx);
+      }
     }
   }
   
@@ -1174,8 +1347,37 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   //-------------------------------
   // Unwinding of extended Faces.
   //-------------------------------
-  myMakeLoops.Build(LFE  ,AsDes,IMOE);
-
+  //
+  TopTools_MapOfShape aMFDone;
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    TopTools_ListOfShape aLFailed;
+    BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False);
+    if (aLFailed.Extent()) {
+      myMakeLoops.Build(aLFailed, AsDes, IMOE);
+    }
+    //
+    if (LFE.Extent() != aLFailed.Extent()) {
+      TopTools_MapOfShape aMFailed;
+      TopTools_ListIteratorOfListOfShape aItLF(aLFailed);
+      for (; aItLF.More(); aItLF.Next()) {
+        const TopoDS_Shape& aS = aItLF.Value();
+        aMFailed.Add(aS);
+      }
+      //
+      aItLF.Initialize(LFE);
+      for (; aItLF.More(); aItLF.Next()) {
+        const TopoDS_Shape& aS = aItLF.Value();
+        if (!aMFailed.Contains(aS)) {
+          aMFDone.Add(aS);
+        }
+      }
+    }
+  }
+  else {
+    myMakeLoops.Build(LFE, AsDes, IMOE);
+  }
+  //
 #ifdef OCCT_DEBUG
   TopTools_IndexedMapOfShape COES;
 #endif
@@ -1189,91 +1391,95 @@ 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);
+        if (aMFDone.Contains(OF)) {
+          continue;
+        }
+        //
+        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 {
@@ -1281,26 +1487,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));        
+          }
+        }
       } 
     }
   }
@@ -1317,49 +1523,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);
+        }
       }
     }
   }
@@ -1375,38 +1581,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
       }
     }
@@ -1418,6 +1624,326 @@ 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)
+{
+  if (!myIsPlanar) {
+    theLFailed.Assign(theLF);
+    return;
+  }
+  //
+  BOPCol_ListOfShape aLS, aLF;
+  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_Face& aF = *(TopoDS_Face*)&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 (ProcessMicroEdge(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 (ProcessMicroEdge(aEIm, aCtx)) {
+            continue;
+          }
+          //
+          aLS.Append(aEIm);
+          if (!aMFE.Contains(aEIm)) {
+            ++iCountE;
+          }
+        }
+      }
+      else {
+        if (ProcessMicroEdge(aE, aCtx)) {
+          continue;
+        }
+        aLS.Append(aE);
+        if (!aMFE.Contains(aE)) {
+          ++iCountE;
+        }
+      }
+    }
+    //
+    TopTools_ListOfShape aLFImages;
+    //
+    // split the face by the edges
+    if (!iCountE) {
+      if (bLimited && !theImage.HasImage(aF)) {
+        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()) {
+      if (theImage.HasImage(aF)) {
+        theImage.Add(aF, aLFImages);
+      }
+      else {
+        theImage.Bind(aF, aLFImages);
+      }
+    }
+    //
+    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
@@ -1458,27 +1984,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);
@@ -1494,60 +2020,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 aLocalShapeGen = MapSF(Anc.First()).Generated(E);
-         TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShapeGen);
-         aLocalShapeGen = MapSF(Anc.Last()).Generated(E);
-         TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShapeGen);
-//       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 aLocalShapeGen = MapSF(Anc.First()).Generated(E);
+          TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShapeGen);
+          aLocalShapeGen = MapSF(Anc.Last()).Generated(E);
+          TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShapeGen);
+//          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);      
       }
     }
   }
@@ -1566,42 +2092,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));
+          }
+        } 
       }
     }
   }
@@ -1622,12 +2148,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);      
@@ -1636,27 +2162,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());
       }
     }
   }
@@ -1714,14 +2240,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);
       }  
     }
   }
@@ -1735,28 +2261,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);
+            }
+          }
+        }
       }
     }
   }
@@ -1785,26 +2311,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 {
@@ -1812,8 +2338,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);
@@ -1830,9 +2356,9 @@ 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);
     }
@@ -1874,7 +2400,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);
     }
   }
@@ -2034,7 +2560,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())
@@ -2364,7 +2890,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) {
@@ -2420,7 +2946,18 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
     if (!myFaces.Contains(Modif(i)))
       LF.Append(Modif(i));
   }
-  myMakeLoops.Build(LF,myAsDes,myImageOffset);
+  //
+  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.
@@ -2460,9 +2997,22 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
   //----------------------------------
   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)) {
+      LOF.Append(F);
+    }
+  }
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    TopTools_ListOfShape aLFailed;
+    TopTools_IndexedDataMapOfShapeListOfShape anOr;
+    BuildSplitsOfFaces(LOF, myAsDes, anOr, myImageOffset, aLFailed, Standard_True);
+    if (aLFailed.Extent()) {
+      myMakeLoops.BuildFaces(aLFailed, myAsDes, myImageOffset);
+    }
+  }
+  else {
+    myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
   }
-  myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
   
 #ifdef OCCT_DEBUG
   if ( ChronBuild) Clock.Show();
@@ -2473,11 +3023,10 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
 //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&         myImageOffset,
+                              const TopoDS_Shape&     myOffsetShape,
+                              const TopAbs_ShapeEnum &theShapeType) // skv
 {
   BRepAlgo_Image NIOF;
   const TopTools_ListOfShape& Roots = myInitOffset.Roots();
@@ -2947,30 +3496,184 @@ void BRepOffset_MakeOffset::MakeShells ()
     Clock.Start();
   }
 #endif
-  BRepTools_Quilt Glue;
+  //
+  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;
+  if ((myJoin == GeomAbs_Intersection) && myInter &&
+      !myThickening && myFaces.IsEmpty() &&
+      IsSolid(myShape) && myIsPlanar) {
+    //
+    // make shells using MakerVolume algorithm
+    Standard_Integer i, aNb;
+    TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
+    BRep_Builder aBB;
+    //
+    BOPAlgo_MakerVolume aMV1;
+    aMV1.SetArguments(aLSF);
+    aMV1.SetIntersect(Standard_True);
+    aMV1.Perform();
+    //
+    bDone = (aMV1.ErrorStatus() == 0);
+    if (bDone) {
+      UpdateHistory(aLSF, aMV1, myImageOffset);
+      //
+      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 {
+        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;
+                //
+                TopExp_Explorer aExp(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();
+          aBB.Add(aShells, aSh);
+        }
+        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);
@@ -3102,7 +3805,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);                       
       }
     }  
   }
@@ -3214,38 +3917,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;
     }
@@ -3264,32 +3967,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) {
@@ -3297,42 +4000,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;
       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;
+          }
+        }
       }
     }
   }
@@ -3350,7 +4053,7 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
 //=======================================================================
 
 void UpdateTolerance (TopoDS_Shape& S,
-                                       const TopTools_IndexedMapOfShape& Faces)
+                                        const TopTools_IndexedMapOfShape& Faces)
 {
   BRep_Builder B;
   TopTools_MapOfShape View;
@@ -3378,15 +4081,15 @@ void UpdateTolerance (TopoDS_Shape& S,
       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);
+        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);
       }
     }
   }
@@ -3589,6 +4292,66 @@ 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 : checkSinglePoint
@@ -3636,3 +4399,595 @@ BRepOffset_Error checkSinglePoint(const Standard_Real theUParam,
 
   return BRepOffset_NoError;
 }
+
+//=======================================================================
+//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 : 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, bProceeded;
+  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();
+    bProceeded = Standard_False;
+    //
+    // 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);
+        bProceeded = Standard_True;
+      }
+      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);
+        bProceeded = Standard_True;
+      }
+      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;
+    //
+    if (!bProceeded) {
+      break;
+    }
+  }
+}
+
+//=======================================================================
+//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 : ProcessMicroEdge
+//purpose  : 
+//=======================================================================
+Standard_Boolean ProcessMicroEdge(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;
+  bMicro = BOPTools_AlgoTools::IsMicroEdge(theEdge, theCtx);
+  if (bMicro) {
+    BRepAdaptor_Curve aBAC(theEdge);
+    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 : IsSolid
+//purpose  : Check if the shape is solid
+//=======================================================================
+Standard_Boolean IsSolid(const TopoDS_Shape& theS)
+{
+  TopExp_Explorer aExp(theS, TopAbs_SOLID);
+  return aExp.More();
+}
+//=======================================================================
+//function : UpdateHistory
+//purpose  : Updates the history information
+//=======================================================================
+void UpdateHistory(const TopTools_ListOfShape& theLF,
+                   BOPAlgo_Builder& theGF,
+                   BRepAlgo_Image& theImage)
+{
+  TopTools_ListIteratorOfListOfShape aIt(theLF);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aF = aIt.Value();
+    const TopTools_ListOfShape& aLFIm = theGF.Modified(aF);
+    if (aLFIm.Extent()) {
+      if (theImage.HasImage(aF)) {
+        theImage.Add(aF, aLFIm);
+      }
+      else {
+        theImage.Bind(aF, aLFIm);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : IsPlanar
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsPlanar(const TopoDS_Shape& theS)
+{
+  Standard_Boolean bRet;
+  TopExp_Explorer aExp(theS, TopAbs_FACE);
+  for (bRet = Standard_True; aExp.More() && bRet; aExp.Next()) {
+    const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
+    BRepAdaptor_Surface aBAS(aF, Standard_False);
+    bRet = (aBAS.GetType() == GeomAbs_Plane);
+  }
+  return bRet;
+}
index c194998..4af6b24 100644 (file)
@@ -53,9 +53,27 @@ public:
   
   Standard_EXPORT BRepOffset_MakeOffset();
   
-  Standard_EXPORT BRepOffset_MakeOffset(const TopoDS_Shape& S, const Standard_Real Offset, const Standard_Real Tol, const BRepOffset_Mode Mode = BRepOffset_Skin, const Standard_Boolean Intersection = Standard_False, const Standard_Boolean SelfInter = Standard_False, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean Thickening = Standard_False);
-  
-  Standard_EXPORT void Initialize (const TopoDS_Shape& S, const Standard_Real Offset, const Standard_Real Tol, const BRepOffset_Mode Mode = BRepOffset_Skin, const Standard_Boolean Intersection = Standard_False, const Standard_Boolean SelfInter = Standard_False, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean Thickening = Standard_False);
+  Standard_EXPORT BRepOffset_MakeOffset(const TopoDS_Shape& S, 
+                                        const Standard_Real Offset, 
+                                        const Standard_Real Tol, 
+                                        const BRepOffset_Mode Mode = BRepOffset_Skin, 
+                                        const Standard_Boolean Intersection = Standard_False, 
+                                        const Standard_Boolean SelfInter = Standard_False, 
+                                        const GeomAbs_JoinType Join = GeomAbs_Arc, 
+                                        const Standard_Boolean Thickening = Standard_False,
+                                        const Standard_Boolean RemoveIntEdges = Standard_False,
+                                        const Standard_Boolean RemoveInvalidFaces = Standard_False);
+  
+  Standard_EXPORT void Initialize (const TopoDS_Shape& S, 
+                                   const Standard_Real Offset, 
+                                   const Standard_Real Tol, 
+                                   const BRepOffset_Mode Mode = BRepOffset_Skin, 
+                                   const Standard_Boolean Intersection = Standard_False, 
+                                   const Standard_Boolean SelfInter = Standard_False, 
+                                   const GeomAbs_JoinType Join = GeomAbs_Arc, 
+                                   const Standard_Boolean Thickening = Standard_False,
+                                   const Standard_Boolean RemoveIntEdges = Standard_False,
+                                   const Standard_Boolean RemoveInvalidFaces = Standard_False);
   
   Standard_EXPORT void Clear();
   
@@ -106,20 +124,24 @@ public:
   Standard_EXPORT const TopoDS_Shape& GetBadShape() const;
 
 
-
-
 protected:
 
 
-
-
-
 private:
 
   
   Standard_EXPORT void BuildOffsetByArc();
   
   Standard_EXPORT void BuildOffsetByInter();
+
+  //! Building splits of the offset faces by the section curves 
+  //! between the neighboring faces. 
+  Standard_EXPORT void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
+                                          const Handle(BRepAlgo_AsDes)& theAsDes,
+                                          TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+                                          BRepAlgo_Image& theImage,
+                                          TopTools_ListOfShape& theLFailed,
+                                          const Standard_Boolean bLimited);
   
   Standard_EXPORT void SelfInter (TopTools_MapOfShape& Modif);
   
@@ -152,6 +174,10 @@ private:
   //! Private method used to build walls for thickening the shell
   Standard_EXPORT void MakeMissingWalls();
 
+  //! Removes INTERNAL edges from the result
+  Standard_EXPORT void RemoveInternalEdges();
+
+
 
   Standard_Real myOffset;
   Standard_Real myTol;
@@ -161,6 +187,8 @@ private:
   Standard_Boolean mySelfInter;
   GeomAbs_JoinType myJoin;
   Standard_Boolean myThickening;
+  Standard_Boolean myRemoveIntEdges;
+  Standard_Boolean myRemoveInvalidFaces;
   TopTools_DataMapOfShapeReal myFaceOffset;
   TopTools_IndexedMapOfShape myFaces;
   BRepOffset_Analyse myAnalyse;
@@ -174,15 +202,9 @@ private:
   BRepOffset_Error myError;
   BRepOffset_MakeLoops myMakeLoops;
   Standard_Boolean myIsPerformSewing; // Handle bad walls in thicksolid mode.
+  Standard_Boolean myIsPlanar;
   TopoDS_Shape myBadShape;
 
-
 };
 
-
-
-
-
-
-
 #endif // _BRepOffset_MakeOffset_HeaderFile
index 6f3844c..5a7318f 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, Standard_False, RemoveIntEdges);
   Build();
 }
 
index e1e01a6..f37ea51 100644 (file)
@@ -82,6 +82,8 @@ public:
   //! - 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.
@@ -100,8 +102,15 @@ public:
   //! Exceptions
   //! Geom_UndefinedDerivative if the underlying
   //! geometry of S is BSpline with continuity C0.
-  Standard_EXPORT BRepOffsetAPI_MakeOffsetShape(const TopoDS_Shape& S, const Standard_Real Offset, const Standard_Real Tol, const BRepOffset_Mode Mode = BRepOffset_Skin, const Standard_Boolean Intersection = Standard_False, const Standard_Boolean SelfInter = Standard_False, const GeomAbs_JoinType Join = GeomAbs_Arc);
-  
+  Standard_EXPORT BRepOffsetAPI_MakeOffsetShape(const TopoDS_Shape& S, 
+                                                const Standard_Real Offset, 
+                                                const Standard_Real Tol, 
+                                                const BRepOffset_Mode Mode = BRepOffset_Skin, 
+                                                const Standard_Boolean Intersection = Standard_False, 
+                                                const Standard_Boolean SelfInter = Standard_False, 
+                                                const GeomAbs_JoinType Join = GeomAbs_Arc,
+                                                const Standard_Boolean RemoveIntEdges = Standard_False);
+
   Standard_EXPORT virtual const BRepOffset_MakeOffset& MakeOffset() const;
   
   //! Builds the resulting shape (redefined from MakeShape).
index faf8cb2..79f444c 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, Standard_False, RemoveIntEdges);
   TopTools_ListIteratorOfListOfShape it(ClosingFaces);
   for (; it.More(); it.Next()) {
     myOffsetShape.AddFace(TopoDS::Face(it.Value()));
index e89de26..1ef6c6b 100644 (file)
@@ -88,11 +88,21 @@ public:
   //! 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
   //! MakeOffsetShape.
-  Standard_EXPORT BRepOffsetAPI_MakeThickSolid(const TopoDS_Shape& S, const TopTools_ListOfShape& ClosingFaces, const Standard_Real Offset, const Standard_Real Tol, const BRepOffset_Mode Mode = BRepOffset_Skin, const Standard_Boolean Intersection = Standard_False, const Standard_Boolean SelfInter = Standard_False, const GeomAbs_JoinType Join = GeomAbs_Arc);
+  Standard_EXPORT BRepOffsetAPI_MakeThickSolid(const TopoDS_Shape& S, 
+                                               const TopTools_ListOfShape& ClosingFaces, 
+                                               const Standard_Real Offset, 
+                                               const Standard_Real Tol, 
+                                               const BRepOffset_Mode Mode = BRepOffset_Skin, 
+                                               const Standard_Boolean Intersection = Standard_False,
+                                               const Standard_Boolean SelfInter = Standard_False, 
+                                               const GeomAbs_JoinType Join = GeomAbs_Arc,
+                                               const Standard_Boolean RemoveIntEdges = Standard_False);
   
   //! Builds the resulting shape (redefined from MakeOffsetShape).
   Standard_EXPORT virtual void Build() Standard_OVERRIDE;
index a5c0ad0..b4f715c 100644 (file)
@@ -865,7 +865,7 @@ Standard_Integer thickshell(Draw_Interpretor& theCommands,
     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_True);
 
   B.MakeOffsetShape();
 
@@ -942,63 +942,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]);
@@ -1008,7 +1018,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,
+                       Standard_False, RemoveIntEdges, RemoveInvalidFaces);
   //------------------------------------------
   // recuperation et chargement des bouchons.
   //----------------------------------------
index b7dc738..3f00a58 100644 (file)
@@ -1,6 +1,6 @@
-puts "TODO OCC23068 ALL: An exception was caught"
-puts "TODO OCC23068 ALL: \\*\\* Exception \\*\\*"
-puts "TODO OCC23068 ALL: TEST INCOMPLETE"
+puts "TODO OCC23068 ALL: ERROR. offsetperform operation not done."
+puts "TODO OCC23068 ALL: Error : The offset cannot be built."
+
 psphere s 15 90
 trotate s 0 0 0 0 0 1 90
 
index 21bd8d9..1cd0622 100644 (file)
@@ -1,5 +1,5 @@
 puts "TODO OCC23068 ALL: Error : The volume of the resulting shape is"
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
+puts "TODO OCC25406 ALL: Faulty shapes in variables faulty_1 to"
 
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
index 7736486..22902d2 100644 (file)
@@ -1,6 +1,6 @@
-puts "TODO OCC23068 ALL: An exception was caught"
-puts "TODO OCC23068 ALL: \\*\\* Exception \\*\\*"
-puts "TODO OCC23068 ALL: TEST INCOMPLETE"
+puts "TODO OCC23068 ALL: ERROR. offsetperform operation not done."
+puts "TODO OCC23068 ALL: Error : The offset cannot be built."
+
 ptorus s 10 10 0 45
 
 OFFSETSHAPE 1 {s_2} $calcul $type
index 41ce96d..3d18842 100644 (file)
@@ -14,4 +14,5 @@
 014 wire_unclosed_outside_0_025
 015 wire_unclosed_outside_0_075
 016 with_intersect_20
-017 with_intersect_80
\ No newline at end of file
+017 with_intersect_80
+018 shape_type_i_c
index 3cf22f8..935eb16 100644 (file)
@@ -1,9 +1,6 @@
-puts "TODO OCC23068 ALL: An exception was caught"
-puts "TODO OCC23068 ALL: \\*\\* Exception \\*\\*"
-puts "TODO OCC23068 ALL: TEST INCOMPLETE"
 psphere s 15 90
 trotate s 0 0 0 0 0 1 90
 
 OFFSETSHAPE 1 {} $calcul $type
 
-set volume 0
+set volume 1.77778e+16
index 23deee6..e1991d0 100644 (file)
@@ -1,8 +1,7 @@
-puts "TODO OCC23068 ALL: An exception was caught"
-puts "TODO OCC23068 ALL: \\*\\* Exception \\*\\*"
-puts "TODO OCC23068 ALL: TEST INCOMPLETE"
+puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero."
+
 psphere s 15 270
 
 OFFSETSHAPE 1 {} $calcul $type
 
-set volume 0
+set volume 1.77778e+16
index a611289..769c60a 100644 (file)
@@ -1,6 +1,6 @@
-puts "TODO OCC23068 ALL: An exception was caught"
-puts "TODO OCC23068 ALL: \\*\\* Exception \\*\\*"
+puts "TODO OCC23068 ALL: result is not a topological shape"
 puts "TODO OCC23068 ALL: TEST INCOMPLETE"
+
 ptorus s 10 10 0 45
 
 OFFSETSHAPE 1 {} $calcul $type
index 21bd8d9..8f27825 100644 (file)
@@ -1,5 +1,5 @@
+puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to"
 puts "TODO OCC23068 ALL: Error : The volume of the resulting shape is"
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
 
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
diff --git a/tests/offset/shape_type_i_c/A1 b/tests/offset/shape_type_i_c/A1
new file mode 100644 (file)
index 0000000..6800b2f
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 0.1 {} $calcul $type
+
+set volume 925.196
diff --git a/tests/offset/shape_type_i_c/A2 b/tests/offset/shape_type_i_c/A2
new file mode 100644 (file)
index 0000000..b7a1c45
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 0.3 {} $calcul $type
+
+set volume 1068.58
diff --git a/tests/offset/shape_type_i_c/A3 b/tests/offset/shape_type_i_c/A3
new file mode 100644 (file)
index 0000000..95ab7ac
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 0.6 {} $calcul $type
+
+set volume 1296.86
diff --git a/tests/offset/shape_type_i_c/A4 b/tests/offset/shape_type_i_c/A4
new file mode 100644 (file)
index 0000000..c954a3c
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 0.9 {} $calcul $type
+
+set volume 1543.91
diff --git a/tests/offset/shape_type_i_c/A5 b/tests/offset/shape_type_i_c/A5
new file mode 100644 (file)
index 0000000..1829ba0
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 1.2 {} $calcul $type
+
+set volume 1817.34
diff --git a/tests/offset/shape_type_i_c/A6 b/tests/offset/shape_type_i_c/A6
new file mode 100644 (file)
index 0000000..b288726
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 1.5 {} $calcul $type
+
+set volume 2119
diff --git a/tests/offset/shape_type_i_c/A7 b/tests/offset/shape_type_i_c/A7
new file mode 100644 (file)
index 0000000..c1d1149
--- /dev/null
@@ -0,0 +1,5 @@
+restore [locate_data_file bug25926_box_cut_4boxes.brep] s
+
+OFFSETSHAPE 1.8 {} $calcul $type
+
+set volume 2450.18
diff --git a/tests/offset/shape_type_i_c/A8 b/tests/offset/shape_type_i_c/A8
new file mode 100644 (file)
index 0000000..53d08ee
--- /dev/null