]> OCCT Git - occt-copy.git/commitdiff
0025926: 3D offset in mode "Complete" with Join type "Intersection"
authoremv <emv@opencascade.com>
Thu, 4 Jun 2015 07:53:22 +0000 (10:53 +0300)
committeremv <emv@opencascade.com>
Thu, 4 Jun 2015 07:53:22 +0000 (10:53 +0300)
3D offset algorithm extension for degenerate (colliding) cases.

src/BRepOffset/BRepOffset_Inter2d.cxx
src/BRepOffset/BRepOffset_Inter3d.cxx
src/BRepOffset/BRepOffset_MakeOffset.cdl
src/BRepOffset/BRepOffset_MakeOffset.cxx

index 2c6c6438a20e1ca0787383ea6a3f02482cd48686..7e694d9f140e564bc94d0f18ab9e363bd8dff68e 100644 (file)
@@ -95,7 +95,7 @@ static Standard_Integer NbNewVertices  = 0;
 //=======================================================================
 
 static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
-                                 TopoDS_Edge& E2)
+                                  TopoDS_Edge& E2)
 {
   TopoDS_Vertex V1[2],V2[2],V;
   //  Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
@@ -120,11 +120,11 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
 //=======================================================================
 
 static void  Store (const TopoDS_Edge&       E1,
-                   const TopoDS_Edge&       E2,
-                   TopTools_ListOfShape&    LV1,
-                   TopTools_ListOfShape&    LV2,
-                   Handle(BRepAlgo_AsDes)   AsDes,
-                   Standard_Real            Tol)
+                    const TopoDS_Edge&       E2,
+                    TopTools_ListOfShape&    LV1,
+                    TopTools_ListOfShape&    LV2,
+                    Handle(BRepAlgo_AsDes)   AsDes,
+                    Standard_Real            Tol)
 {
   //-------------------------------------------------------------
   // Test if the points of intersection correspond to existing 
@@ -165,90 +165,90 @@ static void  Store (const TopoDS_Edge&       E1,
       // Find if the point of intersection corresponds to a vertex of E1.
       //-----------------------------------------------------------------
       for (it.Initialize(VOnE1); it.More(); it.Next()) {
-       P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
-       if (P.IsEqual(P1,Tol)) {
-         V    = TopoDS::Vertex(it.Value());
-         V1   = V;
-         OnE1 = Standard_True;
-         break;
-       }
+        P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
+        if (P.IsEqual(P1,Tol)) {
+          V    = TopoDS::Vertex(it.Value());
+          V1   = V;
+          OnE1 = Standard_True;
+          break;
+        }
       }
     }
     if (!VOnE2.IsEmpty()) {
       if (OnE1) {
-       //-----------------------------------------------------------------
-       // Find if the vertex found on E1 is not already on E2.
-       //-----------------------------------------------------------------
-       for (it.Initialize(VOnE2); it.More(); it.Next()) {
-         if (it.Value().IsSame(V)) {
-           OnE2 = Standard_True;
-           V2   = V;
-           break;
-         }
-       }
+        //-----------------------------------------------------------------
+        // Find if the vertex found on E1 is not already on E2.
+        //-----------------------------------------------------------------
+        for (it.Initialize(VOnE2); it.More(); it.Next()) {
+          if (it.Value().IsSame(V)) {
+            OnE2 = Standard_True;
+            V2   = V;
+            break;
+          }
+        }
       }
       for (it.Initialize(VOnE2); it.More(); it.Next()) {
-       //-----------------------------------------------------------------
-       // Find if the point of intersection corresponds to a vertex of E2.
-       //-----------------------------------------------------------------
-       P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
-       if (P.IsEqual(P2,Tol)) {
-         V  = TopoDS::Vertex(it.Value());
-         V2 = V;
-         OnE2 = Standard_True;
-         break;
-       }
+        //-----------------------------------------------------------------
+        // Find if the point of intersection corresponds to a vertex of E2.
+        //-----------------------------------------------------------------
+        P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
+        if (P.IsEqual(P2,Tol)) {
+          V  = TopoDS::Vertex(it.Value());
+          V2 = V;
+          OnE2 = Standard_True;
+          break;
+        }
       }      
     }  
     if (OnE1 && OnE2) {
       if (!V1.IsSame(V2)) {
-       //---------------------------------------------------------------
-       // Two vertices are actually the same.
-       // V2 will be replaced by V1. 
-       // update the parameters of vertex on edges.
-       //---------------------------------------------------------------
-       Standard_Real UV2;
-       TopoDS_Edge   EWE2;
-       const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
-
-       for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
-         EWE2  = TopoDS::Edge(it.Value());
-         TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
-         UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
-//       UV2   = 
-//         BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
-         aLocalShape = V1.Oriented(TopAbs_INTERNAL);
-         B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
-//       B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
-//                      UV2,EWE2,Tol);
-       }
-       AsDes->Replace(V2,V1);
+        //---------------------------------------------------------------
+        // Two vertices are actually the same.
+        // V2 will be replaced by V1. 
+        // update the parameters of vertex on edges.
+        //---------------------------------------------------------------
+        Standard_Real UV2;
+        TopoDS_Edge   EWE2;
+        const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
+
+        for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
+          EWE2  = TopoDS::Edge(it.Value());
+          TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
+          UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
+//          UV2   = 
+//            BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
+          aLocalShape = V1.Oriented(TopAbs_INTERNAL);
+          B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
+//          B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
+//                         UV2,EWE2,Tol);
+        }
+        AsDes->Replace(V2,V1);
       }
     }
     if (!OnE1) {
       if (OnE2) {
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U1,E1,Tol);
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U1,E1,Tol);
       }
       NewVOnE1.Append(V.Oriented(O1));
     }
     if (!OnE2) {
       if (OnE1) {
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U2,E2,Tol);
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U2,E2,Tol);
       }
       NewVOnE2.Append(V.Oriented(O2));
     }
     
 #ifdef DRAW
-   if (Inter2dAffichInt2d) {     
+   if (Inter2dAffichInt2d) {          
      if (!OnE1 && !OnE2) {
        char name[256];
-       sprintf(name,"VV_%d",NbNewVertices++);  
+       sprintf(name,"VV_%d",NbNewVertices++);        
        DBRep::Set(name,V);
      }
    }  
@@ -265,11 +265,12 @@ static void  Store (const TopoDS_Edge&       E1,
 //=======================================================================
 
 static void EdgeInter(const TopoDS_Face&              F,
-                     const TopoDS_Edge&              E1,
-                     const TopoDS_Edge&              E2,
-                     const Handle(BRepAlgo_AsDes)&   AsDes,
-                     Standard_Real                   Tol,
-                     Standard_Boolean                WithOri)
+                      const BRepAdaptor_Surface&      BAsurf,
+                      const TopoDS_Edge&              E1,
+                      const TopoDS_Edge&              E2,
+                      const Handle(BRepAlgo_AsDes)&   AsDes,
+                      Standard_Real                   Tol,
+                      Standard_Boolean                WithOri)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -314,117 +315,117 @@ static void EdgeInter(const TopoDS_Face&              F,
       Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
       
       if (WithDegen)
-       {
-         Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
-         TopoDS_Iterator iter( EI[ideg] );
-         if (iter.More())
-           {
-             const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
-             DegPoint = BRep_Tool::Pnt(vdeg);
-           }
-         else
-           {
-             BRepAdaptor_Curve CEdeg( EI[ideg], F );
-             DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
-           }
-       }
-      BRepAdaptor_Surface BAsurf(F);
+        {
+          Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
+          TopoDS_Iterator iter( EI[ideg] );
+          if (iter.More())
+            {
+              const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
+              DegPoint = BRep_Tool::Pnt(vdeg);
+            }
+          else
+            {
+              BRepAdaptor_Curve CEdeg( EI[ideg], F );
+              DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
+            }
+        }
+      
       Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
       Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
       Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
       Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
       Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
       for (i = 1; i <= Inter2d.NbPoints(); i++)
-       {
-         gp_Pnt P3d;
-         if (WithDegen)
-           P3d = DegPoint;
-         else
-           {
-             gp_Pnt2d P2d = Inter2d.Point(i).Value();
-             P3d = BAsurf.Value( P2d.X(), P2d.Y() );
-           }
-         ResPoints.Append( P3d );
-         ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
-         ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
-       }
+        {
+          gp_Pnt P3d;
+          if (WithDegen)
+            P3d = DegPoint;
+          else
+            {
+              gp_Pnt2d P2d = Inter2d.Point(i).Value();
+              P3d = BAsurf.Value( P2d.X(), P2d.Y() );
+            }
+          ResPoints.Append( P3d );
+          ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
+          ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
+        }
 
       for (i = 1; i <= ResPoints.Length(); i++)
-       {
-         Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
-         Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
-         if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
-           {
+        {
+          Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
+          Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
+          if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
+            {
 #ifdef OCCT_DEBUG
-             cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
+              cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
 #endif
-             continue;
-           }
-         
-         gp_Pnt P = ResPoints(i); //ponc1.Value();
-         TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
+              continue;
+            }
+          
+          gp_Pnt P = ResPoints(i); //ponc1.Value();
+          TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
           aNewVertex.Orientation(TopAbs_INTERNAL);
-         B.UpdateVertex( aNewVertex, aT1, E1, Tol );
-         B.UpdateVertex( aNewVertex, aT2, E2, Tol );
-         gp_Pnt P1 = CE1.Value(aT1);
-         gp_Pnt P2 = CE2.Value(aT2);
-         Standard_Real dist1, dist2, dist3;
-         dist1 = P1.Distance(P);
-         dist2 = P2.Distance(P);
-         dist3 = P1.Distance(P2);
-         dist1 = Max( dist1, dist2 );
-         dist1 = Max( dist1, dist3 );
-         B.UpdateVertex( aNewVertex, dist1 );
-         
+          B.UpdateVertex( aNewVertex, aT1, E1, Tol );
+          B.UpdateVertex( aNewVertex, aT2, E2, Tol );
+          gp_Pnt P1 = CE1.Value(aT1);
+          gp_Pnt P2 = CE2.Value(aT2);
+          Standard_Real dist1, dist2, dist3;
+          dist1 = P1.Distance(P);
+          dist2 = P2.Distance(P);
+          dist3 = P1.Distance(P2);
+          dist1 = Max( dist1, dist2 );
+          dist1 = Max( dist1, dist3 );
+          B.UpdateVertex( aNewVertex, dist1 );
+          
 #ifdef OCCT_DEBUG
-         if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
-           {
-             cout << "out of limit"<<endl;
-             cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
-           }
-         if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
-           {
-             cout << "out of limit"<<endl;
-             cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
-           }
+          if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
+            {
+              cout << "out of limit"<<endl;
+              cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
+            }
+          if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
+            {
+              cout << "out of limit"<<endl;
+              cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
+            }
           Standard_Real MilTol2 = 1000*Tol*Tol;
-         if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
-           {
-             cout << "Inter2d : Solution rejected "<<endl;
-             cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
-             cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
-             cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
-             cout<<"MaxDist = "<<dist1<<endl;
-           }
+          if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
+            {
+              cout << "Inter2d : Solution rejected "<<endl;
+              cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
+              cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
+              cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
+              cout<<"MaxDist = "<<dist1<<endl;
+            }
 #endif
-         //define the orientation of a new vertex
-         TopAbs_Orientation OO1 = TopAbs_REVERSED;
-         TopAbs_Orientation OO2 = TopAbs_REVERSED;
-         if (WithOri)
-           {
-             BRepAdaptor_Curve2d PCE1( E1, F );
-             BRepAdaptor_Curve2d PCE2( E2, F );
-             gp_Pnt2d P2d1, P2d2;
-             gp_Vec2d V1, V2, V1or, V2or;
-             PCE1.D1( aT1, P2d1, V1 );
-             PCE2.D1( aT2, P2d2, V2 );
-             V1or = V1; V2or = V2;
-             if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
-             if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
-             Standard_Real CrossProd = V2or ^ V1;
+          //define the orientation of a new vertex
+          TopAbs_Orientation OO1 = TopAbs_REVERSED;
+          TopAbs_Orientation OO2 = TopAbs_REVERSED;
+          if (WithOri)
+            {
+              BRepAdaptor_Curve2d PCE1( E1, F );
+              BRepAdaptor_Curve2d PCE2( E2, F );
+              gp_Pnt2d P2d1, P2d2;
+              gp_Vec2d V1, V2, V1or, V2or;
+              PCE1.D1( aT1, P2d1, V1 );
+              PCE2.D1( aT2, P2d2, V2 );
+              V1or = V1; V2or = V2;
+              if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
+              if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
+              Standard_Real CrossProd = V2or ^ V1;
 #ifdef OCCT_DEBUG
-             if (Abs(CrossProd) <= gp::Resolution())
-               cout<<endl<<"CrossProd = "<<CrossProd<<endl;
+              if (Abs(CrossProd) <= gp::Resolution())
+                cout<<endl<<"CrossProd = "<<CrossProd<<endl;
 #endif
-             if (CrossProd > 0.)
-               OO1 = TopAbs_FORWARD;
-             CrossProd = V1or ^ V2;
-             if (CrossProd > 0.)
-               OO2 = TopAbs_FORWARD;
-           }
-         LV1.Append( aNewVertex.Oriented(OO1) );
-         LV2.Append( aNewVertex.Oriented(OO2) );
-       }
+              if (CrossProd > 0.)
+                OO1 = TopAbs_FORWARD;
+              CrossProd = V1or ^ V2;
+              if (CrossProd > 0.)
+                OO2 = TopAbs_FORWARD;
+            }
+          LV1.Append( aNewVertex.Oriented(OO1) );
+          LV2.Append( aNewVertex.Oriented(OO2) );
+        }
     }
   
   //----------------------------------
@@ -445,30 +446,30 @@ static void EdgeInter(const TopoDS_Face&              F,
       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
       Standard_Real Dist = P1.Distance(P2); 
       if (Dist < TolConf) {
-       TopoDS_Vertex V = BRepLib_MakeVertex(P1);
-       U1 = (j == 0) ? f[1] : l[1];
-       U2 = (k == 0) ? f[2] : l[2];
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        TopoDS_Vertex V = BRepLib_MakeVertex(P1);
+        U1 = (j == 0) ? f[1] : l[1];
+        U2 = (k == 0) ? f[2] : l[2];
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
 //  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
-       Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
-
-       if (!V1[j].IsSame(V2[k])) {
-         Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
-
-         aTol = Max(aTol, aTol2);
-       }
-
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
-//     B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U2,E2,Tol);
+        Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
+
+        if (!V1[j].IsSame(V2[k])) {
+          Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
+
+          aTol = Max(aTol, aTol2);
+        }
+
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
+//         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
+//         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U1,E1,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U2,E2,Tol);
 //  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
-       LV1.Prepend(V.Oriented(V1[j].Orientation()));
-       LV2.Prepend(V.Oriented(V2[k].Orientation()));
+        LV1.Prepend(V.Oriented(V1[j].Orientation()));
+        LV2.Prepend(V.Oriented(V2[k].Orientation()));
       }
     }
   }
@@ -488,31 +489,31 @@ static void EdgeInter(const TopoDS_Face&              F,
       i = 1;
       Purge = Standard_False;
       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
-          it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
-       j = 1;
-       it2LV1.Initialize(LV1);
-       while (j < i) {      
-         P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
-         P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
+           it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
+        j = 1;
+        it2LV1.Initialize(LV1);
+        while (j < i) {      
+          P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
+          P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
 //  Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
-//       if (P1.IsEqual(P2,10*Tol)) {
-         Standard_Real aTol;
+//           if (P1.IsEqual(P2,10*Tol)) {
+          Standard_Real aTol;
 
-         aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
-                    BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
-         if (P1.IsEqual(P2,aTol)) {
+          aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
+                     BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
+          if (P1.IsEqual(P2,aTol)) {
 //  Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
-           LV1.Remove(it1LV1);
-           LV2.Remove(it1LV2);
-           if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
-           Purge = Standard_True;
-           break;
-         }
-         j++;
-         it2LV1.Next();
-       }
-       if (Purge) break;
-       i++;
+            LV1.Remove(it1LV1);
+            LV2.Remove(it1LV2);
+            if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
+            Purge = Standard_True;
+            break;
+          }
+          j++;
+          it2LV1.Next();
+        }
+        if (Purge) break;
+        i++;
       }
     }
     //---------------------------------
@@ -535,12 +536,13 @@ static void EdgeInter(const TopoDS_Face&              F,
 //=======================================================================
 
 static void RefEdgeInter(const TopoDS_Face&              F,
-                        const TopoDS_Edge&              E1,
-                        const TopoDS_Edge&              E2,
-                        const Handle(BRepAlgo_AsDes)&   AsDes,
-                        Standard_Real                   Tol,
-                        Standard_Boolean                WithOri,
-                        gp_Pnt&                         Pref)
+                         const BRepAdaptor_Surface&      BAsurf,
+                         const TopoDS_Edge&              E1,
+                         const TopoDS_Edge&              E2,
+                         const Handle(BRepAlgo_AsDes)&   AsDes,
+                         Standard_Real                   Tol,
+                         Standard_Boolean                WithOri,
+                         gp_Pnt&                         Pref)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -586,17 +588,17 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
       TopoDS_Iterator iter( EI[ideg] );
       if (iter.More())
-       {
-         const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
-         DegPoint = BRep_Tool::Pnt(vdeg);
-       }
+        {
+          const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
+          DegPoint = BRep_Tool::Pnt(vdeg);
+        }
       else
-       {
-         BRepAdaptor_Curve CEdeg( EI[ideg], F );
-         DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
-       }
+        {
+          BRepAdaptor_Curve CEdeg( EI[ideg], F );
+          DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
+        }
     }
-  BRepAdaptor_Surface BAsurf(F);
+  
   Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
   Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
   Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
@@ -606,12 +608,12 @@ static void RefEdgeInter(const TopoDS_Face&              F,
     {
       gp_Pnt P3d;
       if (WithDegen)
-       P3d = DegPoint;
+        P3d = DegPoint;
       else
-       {
-         gp_Pnt2d P2d = Inter2d.Point(i).Value();
-         P3d = BAsurf.Value( P2d.X(), P2d.Y() );
-       }
+        {
+          gp_Pnt2d P2d = Inter2d.Point(i).Value();
+          P3d = BAsurf.Value( P2d.X(), P2d.Y() );
+        }
       ResPoints.Append( P3d );
       ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
       ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
@@ -622,12 +624,12 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
       Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
       if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
-       {
+        {
 #ifdef OCCT_DEBUG
-         cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
+          cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
 #endif
-         continue;
-       }
+          continue;
+        }
       
       gp_Pnt P = ResPoints(i); //ponc1.Value();
       TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
@@ -646,50 +648,50 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       
 #ifdef OCCT_DEBUG
       if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
-       {
-         cout << "out of limit"<<endl;
-         cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
-       }
+        {
+          cout << "out of limit"<<endl;
+          cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
+        }
       if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
-       {
-         cout << "out of limit"<<endl;
-         cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
-       }
+        {
+          cout << "out of limit"<<endl;
+          cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
+        }
       Standard_Real MilTol2 = 1000*Tol*Tol;
       if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
-       {
-         cout << "Inter2d : Solution rejected"<<endl;
-         cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
-         cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
-         cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
-         cout<<"MaxDist = "<<dist1<<endl;
-       }
+        {
+          cout << "Inter2d : Solution rejected"<<endl;
+          cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
+          cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
+          cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
+          cout<<"MaxDist = "<<dist1<<endl;
+        }
 #endif
       //define the orientation of a new vertex
       TopAbs_Orientation OO1 = TopAbs_REVERSED;
       TopAbs_Orientation OO2 = TopAbs_REVERSED;
       if (WithOri)
-       {
-         BRepAdaptor_Curve2d PCE1( E1, F );
-         BRepAdaptor_Curve2d PCE2( E2, F );
-         gp_Pnt2d P2d1, P2d2;
-         gp_Vec2d V1, V2, V1or, V2or;
-         PCE1.D1( aT1, P2d1, V1 );
-         PCE2.D1( aT2, P2d2, V2 );
-         V1or = V1; V2or = V2;
-         if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
-         if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
-         Standard_Real CrossProd = V2or ^ V1;
+        {
+          BRepAdaptor_Curve2d PCE1( E1, F );
+          BRepAdaptor_Curve2d PCE2( E2, F );
+          gp_Pnt2d P2d1, P2d2;
+          gp_Vec2d V1, V2, V1or, V2or;
+          PCE1.D1( aT1, P2d1, V1 );
+          PCE2.D1( aT2, P2d2, V2 );
+          V1or = V1; V2or = V2;
+          if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
+          if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
+          Standard_Real CrossProd = V2or ^ V1;
 #ifdef OCCT_DEBUG
-         if (Abs(CrossProd) <= gp::Resolution())
-           cout<<endl<<"CrossProd = "<<CrossProd<<endl;
+          if (Abs(CrossProd) <= gp::Resolution())
+            cout<<endl<<"CrossProd = "<<CrossProd<<endl;
 #endif
-         if (CrossProd > 0.)
-           OO1 = TopAbs_FORWARD;
-         CrossProd = V1or ^ V2;
-         if (CrossProd > 0.)
-           OO2 = TopAbs_FORWARD;
-       }
+          if (CrossProd > 0.)
+            OO1 = TopAbs_FORWARD;
+          CrossProd = V1or ^ V2;
+          if (CrossProd > 0.)
+            OO2 = TopAbs_FORWARD;
+        }
       LV1.Append( aNewVertex.Oriented(OO1) );
       LV2.Append( aNewVertex.Oriented(OO2) );
     }
@@ -712,18 +714,18 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
       Standard_Real Dist = P1.Distance(P2); 
       if (Dist < TolConf) {
-       TopoDS_Vertex V = BRepLib_MakeVertex(P1);
-       U1 = (j == 0) ? f[1] : l[1];
-       U2 = (k == 0) ? f[2] : l[2];
-       TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-       B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U1,E1,Tol);
-//     B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                    U2,E2,Tol);
-       LV1.Prepend(V.Oriented(V1[j].Orientation()));
-       LV2.Prepend(V.Oriented(V2[k].Orientation()));
+        TopoDS_Vertex V = BRepLib_MakeVertex(P1);
+        U1 = (j == 0) ? f[1] : l[1];
+        U2 = (k == 0) ? f[2] : l[2];
+        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
+        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U1,E1,Tol);
+//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
+//                       U2,E2,Tol);
+        LV1.Prepend(V.Oriented(V1[j].Orientation()));
+        LV2.Prepend(V.Oriented(V2[k].Orientation()));
       }
     }
   }
@@ -743,24 +745,24 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       i = 1;
       Purge = Standard_False;
       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
-          it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
-       j = 1;
-       it2LV1.Initialize(LV1);
-       while (j < i) {      
-         P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
-         P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
-         if (P1.IsEqual(P2,10*Tol)) {
-           LV1.Remove(it1LV1);
-           LV2.Remove(it1LV2);
-           if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
-           Purge = Standard_True;
-           break;
-         }
-         j++;
-         it2LV1.Next();
-       }
-       if (Purge) break;
-       i++;
+           it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
+        j = 1;
+        it2LV1.Initialize(LV1);
+        while (j < i) {      
+          P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
+          P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
+          if (P1.IsEqual(P2,10*Tol)) {
+            LV1.Remove(it1LV1);
+            LV2.Remove(it1LV2);
+            if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
+            Purge = Standard_True;
+            break;
+          }
+          j++;
+          it2LV1.Next();
+        }
+        if (Purge) break;
+        i++;
       }
     }
     //---------------------------------
@@ -772,20 +774,20 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       Standard_Real dmin = RealLast();
       TopoDS_Vertex Vmin;
       for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
-       gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
-       Standard_Real d = P.SquareDistance(Pref);
-       if(d < dmin) {
-         dmin = d;
-         Vmin = TopoDS::Vertex(it1LV1.Value());
-       }
+        gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
+        Standard_Real d = P.SquareDistance(Pref);
+        if(d < dmin) {
+          dmin = d;
+          Vmin = TopoDS::Vertex(it1LV1.Value());
+        }
       }
       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
-          it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
-       if(!Vmin.IsSame(it1LV1.Value())) {
-         LV1.Remove(it1LV1);
-         LV2.Remove(it1LV2);
-         if(!it1LV1.More()) break;
-       }
+           it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
+        if(!Vmin.IsSame(it1LV1.Value())) {
+          LV1.Remove(it1LV1);
+          LV2.Remove(it1LV2);
+          if(!it1LV1.More()) break;
+        }
       }
     }
       
@@ -834,10 +836,10 @@ static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurv
 //=======================================================================
 
 static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
-                                    const Standard_Real anEf,
-                                    const Standard_Real anEl,
-                                    const Standard_Real a2Offset,
-                                    Handle(Geom2d_Curve)& NewPCurve)
+                                     const Standard_Real anEf,
+                                     const Standard_Real anEl,
+                                     const Standard_Real a2Offset,
+                                     Handle(Geom2d_Curve)& NewPCurve)
 {
   NewPCurve = aPCurve;
   if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
@@ -850,29 +852,29 @@ static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
       (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
     {
       if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
-       {
-         Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
-         if (aBezier->NbPoles() == 2)
-           {
-             TColgp_Array1OfPnt2d thePoles(1,2);
-             aBezier->Poles(thePoles);
-             gp_Vec2d aVec(thePoles(1), thePoles(2));
-             NewPCurve = new Geom2d_Line(thePoles(1), aVec);
-             return Standard_True;
-           }
-       }
+        {
+          Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
+          if (aBezier->NbPoles() == 2)
+            {
+              TColgp_Array1OfPnt2d thePoles(1,2);
+              aBezier->Poles(thePoles);
+              gp_Vec2d aVec(thePoles(1), thePoles(2));
+              NewPCurve = new Geom2d_Line(thePoles(1), aVec);
+              return Standard_True;
+            }
+        }
       else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
-       {
-         Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
-         if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
-           {
-             TColgp_Array1OfPnt2d thePoles(1,2);
-             aBSpline->Poles(thePoles);
-             gp_Vec2d aVec(thePoles(1), thePoles(2));
-             NewPCurve = new Geom2d_Line(thePoles(1), aVec);
-             return Standard_True;
-           }
-       }
+        {
+          Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
+          if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
+            {
+              TColgp_Array1OfPnt2d thePoles(1,2);
+              aBSpline->Poles(thePoles);
+              gp_Vec2d aVec(thePoles(1), thePoles(2));
+              NewPCurve = new Geom2d_Line(thePoles(1), aVec);
+              return Standard_True;
+            }
+        }
     }
 
   FirstPar = aPCurve->FirstParameter();
@@ -955,161 +957,161 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
       Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
       Standard_Real FirstPar, LastPar;
       if (CurveRep->IsCurveOnSurface())
-       {
-         NbPCurves++;
-         Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
-         FirstPar = theCurve->FirstParameter();
-         LastPar  = theCurve->LastParameter();
-
-         if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
-             (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
-           {
-             Handle(Geom2d_Curve) NewPCurve;
-             if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
-               {
-                 CurveRep->PCurve(NewPCurve);
-                 FirstPar = NewPCurve->FirstParameter();
-                 LastPar  = NewPCurve->LastParameter();
-                 if (CurveRep->IsCurveOnClosedSurface())
-                   {
-                     Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
-                     if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
-                       CurveRep->PCurve2(NewPCurve);
-                   }
-               }
-           }
-         else if (theCurve->IsPeriodic())
-           {
-             Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
-             delta *= 0.95;
-             FirstPar = anEf - delta;
-             LastPar  = anEl + delta;
-           }
-         else if (theCurve->IsClosed())
-           LastPar -= 0.05*(LastPar - FirstPar);
-
-         //check FirstPar and LastPar: the pcurve should be in its surface
-         theCurve = CurveRep->PCurve();
-         Handle(Geom_Surface) theSurf = CurveRep->Surface();
-         Standard_Real Umin, Umax, Vmin, Vmax;
-         theSurf->Bounds(Umin, Umax, Vmin, Vmax);
-         TColGeom2d_SequenceOfCurve BoundLines;
-         if (!Precision::IsInfinite(Vmin))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
-                                                         gp_Dir2d( 1., 0. ));
-             BoundLines.Append(aLine);
-           }
-         if (!Precision::IsInfinite(Umin))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
-                                                         gp_Dir2d( 0., 1. ));
-             BoundLines.Append(aLine);
-           }
-         if (!Precision::IsInfinite(Vmax))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
-                                                         gp_Dir2d( 1., 0. ));
-             BoundLines.Append(aLine);
-           }
-         if (!Precision::IsInfinite(Umax))
-           {
-             Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
-                                                         gp_Dir2d( 0., 1. ));
-             BoundLines.Append(aLine);
-           }
-
-         TColStd_SequenceOfReal params;
-         Geom2dInt_GInter IntCC;
-         Geom2dAdaptor_Curve GAcurve(theCurve);
-         for (i = 1; i <= BoundLines.Length(); i++)
-           {
-             Geom2dAdaptor_Curve GAline( BoundLines(i) );
-             IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
-             if (IntCC.IsDone())
-               {
-                 for (j = 1; j <= IntCC.NbPoints(); j++)
-                   {
-                     const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
-                     gp_Pnt2d aPoint = ip.Value();
-                     if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
-                         aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
-                       params.Append( ip.ParamOnFirst() );
-                   }
-                 for (j = 1; j <= IntCC.NbSegments(); j++)
-                   {
-                     const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
-                     if (is.HasFirstPoint())
-                       {
-                         const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
-                         gp_Pnt2d aPoint = ip.Value();
-                         if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
-                             aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
-                           params.Append( ip.ParamOnFirst() );
-                       }
-                     if (is.HasLastPoint())
-                       {
-                         const IntRes2d_IntersectionPoint& ip = is.LastPoint();
-                         gp_Pnt2d aPoint = ip.Value();
-                         if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
-                             aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
-                           params.Append( ip.ParamOnFirst() );
-                       }
-                   }
-               }
-           }
-         if (!params.IsEmpty())
-           {
-             if (params.Length() == 1)
-               {
-                 gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
-                 if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
-                     PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
-                   {
-                     if (LastPar > params(1))
-                       LastPar = params(1);
-                   }
-                 else if (FirstPar < params(1))
-                   FirstPar = params(1);
-               }
-             else
-               {
-                 Standard_Real fpar = RealLast(), lpar = RealFirst();
-                 for (i = 1; i <= params.Length(); i++)
-                   {
-                     if (params(i) < fpar)
-                       fpar = params(i);
-                     if (params(i) > lpar)
-                       lpar = params(i);
-                   }
-                 if (FirstPar < fpar)
-                   FirstPar = fpar;
-                 if (LastPar > lpar)
-                   LastPar = lpar;
-               }
-           }
-         //// end of check ////
-         (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
-         //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
-         //gp_Pnt2d Plast  = theCurve->Value(LastPar);
-         //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
-
-         //update FirstParOnPC and LastParOnPC
-         if (FirstPar > FirstParOnPC)
-           {
-             FirstParOnPC = FirstPar;
-             MinPC   = theCurve;
-             MinSurf = theSurf;
-             MinLoc  = CurveRep->Location();
-           }
-         if (LastPar  < LastParOnPC)
-           {
-             LastParOnPC  = LastPar;
-             MinPC   = theCurve;
-             MinSurf = theSurf;
-             MinLoc  = CurveRep->Location();
-           }
-       }
+        {
+          NbPCurves++;
+          Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
+          FirstPar = theCurve->FirstParameter();
+          LastPar  = theCurve->LastParameter();
+
+          if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
+              (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
+            {
+              Handle(Geom2d_Curve) NewPCurve;
+              if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
+                {
+                  CurveRep->PCurve(NewPCurve);
+                  FirstPar = NewPCurve->FirstParameter();
+                  LastPar  = NewPCurve->LastParameter();
+                  if (CurveRep->IsCurveOnClosedSurface())
+                    {
+                      Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
+                      if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
+                        CurveRep->PCurve2(NewPCurve);
+                    }
+                }
+            }
+          else if (theCurve->IsPeriodic())
+            {
+              Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
+              delta *= 0.95;
+              FirstPar = anEf - delta;
+              LastPar  = anEl + delta;
+            }
+          else if (theCurve->IsClosed())
+            LastPar -= 0.05*(LastPar - FirstPar);
+
+          //check FirstPar and LastPar: the pcurve should be in its surface
+          theCurve = CurveRep->PCurve();
+          Handle(Geom_Surface) theSurf = CurveRep->Surface();
+          Standard_Real Umin, Umax, Vmin, Vmax;
+          theSurf->Bounds(Umin, Umax, Vmin, Vmax);
+          TColGeom2d_SequenceOfCurve BoundLines;
+          if (!Precision::IsInfinite(Vmin))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
+                                                          gp_Dir2d( 1., 0. ));
+              BoundLines.Append(aLine);
+            }
+          if (!Precision::IsInfinite(Umin))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
+                                                          gp_Dir2d( 0., 1. ));
+              BoundLines.Append(aLine);
+            }
+          if (!Precision::IsInfinite(Vmax))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
+                                                          gp_Dir2d( 1., 0. ));
+              BoundLines.Append(aLine);
+            }
+          if (!Precision::IsInfinite(Umax))
+            {
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
+                                                          gp_Dir2d( 0., 1. ));
+              BoundLines.Append(aLine);
+            }
+
+          TColStd_SequenceOfReal params;
+          Geom2dInt_GInter IntCC;
+          Geom2dAdaptor_Curve GAcurve(theCurve);
+          for (i = 1; i <= BoundLines.Length(); i++)
+            {
+              Geom2dAdaptor_Curve GAline( BoundLines(i) );
+              IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
+              if (IntCC.IsDone())
+                {
+                  for (j = 1; j <= IntCC.NbPoints(); j++)
+                    {
+                      const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
+                      gp_Pnt2d aPoint = ip.Value();
+                      if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
+                          aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
+                        params.Append( ip.ParamOnFirst() );
+                    }
+                  for (j = 1; j <= IntCC.NbSegments(); j++)
+                    {
+                      const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
+                      if (is.HasFirstPoint())
+                        {
+                          const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
+                          gp_Pnt2d aPoint = ip.Value();
+                          if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
+                              aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
+                            params.Append( ip.ParamOnFirst() );
+                        }
+                      if (is.HasLastPoint())
+                        {
+                          const IntRes2d_IntersectionPoint& ip = is.LastPoint();
+                          gp_Pnt2d aPoint = ip.Value();
+                          if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
+                              aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
+                            params.Append( ip.ParamOnFirst() );
+                        }
+                    }
+                }
+            }
+          if (!params.IsEmpty())
+            {
+              if (params.Length() == 1)
+                {
+                  gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
+                  if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
+                      PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
+                    {
+                      if (LastPar > params(1))
+                        LastPar = params(1);
+                    }
+                  else if (FirstPar < params(1))
+                    FirstPar = params(1);
+                }
+              else
+                {
+                  Standard_Real fpar = RealLast(), lpar = RealFirst();
+                  for (i = 1; i <= params.Length(); i++)
+                    {
+                      if (params(i) < fpar)
+                        fpar = params(i);
+                      if (params(i) > lpar)
+                        lpar = params(i);
+                    }
+                  if (FirstPar < fpar)
+                    FirstPar = fpar;
+                  if (LastPar > lpar)
+                    LastPar = lpar;
+                }
+            }
+          //// end of check ////
+          (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
+          //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
+          //gp_Pnt2d Plast  = theCurve->Value(LastPar);
+          //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
+
+          //update FirstParOnPC and LastParOnPC
+          if (FirstPar > FirstParOnPC)
+            {
+              FirstParOnPC = FirstPar;
+              MinPC   = theCurve;
+              MinSurf = theSurf;
+              MinLoc  = CurveRep->Location();
+            }
+          if (LastPar  < LastParOnPC)
+            {
+              LastParOnPC  = LastPar;
+              MinPC   = theCurve;
+              MinSurf = theSurf;
+              MinLoc  = CurveRep->Location();
+            }
+        }
     }
 
   Standard_Real f, l;
@@ -1118,168 +1120,168 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
     {
       MinLoc = E.Location() * MinLoc;
       if (!C3d.IsNull())
-       {
-         if (MinPC->IsClosed())
-           {
-             f = FirstParOnPC;
-             l = LastParOnPC;
-           }
-         else if (C3d->IsPeriodic())
-           {
-             Standard_Real delta = (C3d->Period() - (l - f))*0.5;
-             delta *= 0.95;
-             f -= delta;
-             l += delta;
-           }
-         else if (C3d->IsClosed())
-           l -= 0.05*(l - f);
-         else
-           {
-             f = FirstParOnPC;
-             l = LastParOnPC;
-             GeomAPI_ProjectPointOnCurve Projector;
-             if (!Precision::IsInfinite(FirstParOnPC))
-               {
-                 gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
-                 gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
-                 P1.Transform(MinLoc.Transformation());
-                 Projector.Init( P1, C3d );
-                 if (Projector.NbPoints() > 0)
-                   f = Projector.LowerDistanceParameter();
+        {
+          if (MinPC->IsClosed())
+            {
+              f = FirstParOnPC;
+              l = LastParOnPC;
+            }
+          else if (C3d->IsPeriodic())
+            {
+              Standard_Real delta = (C3d->Period() - (l - f))*0.5;
+              delta *= 0.95;
+              f -= delta;
+              l += delta;
+            }
+          else if (C3d->IsClosed())
+            l -= 0.05*(l - f);
+          else
+            {
+              f = FirstParOnPC;
+              l = LastParOnPC;
+              GeomAPI_ProjectPointOnCurve Projector;
+              if (!Precision::IsInfinite(FirstParOnPC))
+                {
+                  gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
+                  gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
+                  P1.Transform(MinLoc.Transformation());
+                  Projector.Init( P1, C3d );
+                  if (Projector.NbPoints() > 0)
+                    f = Projector.LowerDistanceParameter();
 #ifdef OCCT_DEBUG
-                 else
-                   cout<<"ProjectPointOnCurve not done"<<endl;
+                  else
+                    cout<<"ProjectPointOnCurve not done"<<endl;
 #endif
-               }
-             if (!Precision::IsInfinite(LastParOnPC))
-               {
-                 gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
-                 gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
-                 P2.Transform(MinLoc.Transformation());
-                 Projector.Init( P2, C3d );
-                 if (Projector.NbPoints() > 0)
-                   l = Projector.LowerDistanceParameter();
+                }
+              if (!Precision::IsInfinite(LastParOnPC))
+                {
+                  gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
+                  gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
+                  P2.Transform(MinLoc.Transformation());
+                  Projector.Init( P2, C3d );
+                  if (Projector.NbPoints() > 0)
+                    l = Projector.LowerDistanceParameter();
 #ifdef OCCT_DEBUG
-                 else
-                   cout<<"ProjectPointOnCurve not done"<<endl;
+                  else
+                    cout<<"ProjectPointOnCurve not done"<<endl;
 #endif
-               }
-           }
-         BB.Range( NE, f, l );
-         if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
-           BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-       }
+                }
+            }
+          BB.Range( NE, f, l );
+          if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
+            BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+        }
       else if (!BRep_Tool::Degenerated(E)) //no 3d curve
-       {
-         MinSurf = Handle(Geom_Surface)::DownCast
-           (MinSurf->Transformed(MinLoc.Transformation()));
-         Standard_Real max_deviation = 0.;
-         if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
-           {
-             if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
-               {
-                 Standard_Boolean IsLine = Standard_False;
-                 if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
-                   IsLine = Standard_True;
-                 else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
-                          MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
-                   {
-                     Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
-                     gp_Dir2d LineDir = theLine->Direction();
-                     if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
-                       IsLine = Standard_True;
-                   }
-                 if (IsLine)
-                   {
-                     gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
-                     gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
-                     gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
-                     gp_Vec aVec(P1, P2);
-                     C3d = new Geom_Line( P1, aVec );
-                   }
-               }
-           }
-         else
-           {
-             Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
-             GeomAdaptor_Surface GAsurf( MinSurf );
-             Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
-             Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
-             Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
-             Standard_Real /*max_deviation,*/ average_deviation;
-             GeomAbs_Shape Continuity = GeomAbs_C1;
-             Standard_Integer MaxDegree = 14;
-             Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
-             GeomLib::BuildCurve3d(Precision::Confusion(),
-                                   ConS, FirstParOnPC, LastParOnPC,
-                                   C3d, max_deviation, average_deviation,
-                                   Continuity, MaxDegree, MaxSegment);
-           }
-         BB.UpdateEdge( NE, C3d, max_deviation );
-         //BB.Range( NE, FirstParOnPC, LastParOnPC );
-         Standard_Boolean ProjectionSuccess = Standard_True;
-         if (NbPCurves > 1)
-           //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-           for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
-                itr.More();
-                itr.Next())
-             {
-               Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
-               Standard_Real FirstPar, LastPar;
-               if (CurveRep->IsCurveOnSurface())
-                 {
-                   Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
-                   Handle(Geom_Surface) theSurf  = CurveRep->Surface();
-                   TopLoc_Location      theLoc   = CurveRep->Location();
-                   if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
-                     continue;
-                   FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
-                   LastPar  = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
-                   if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
-                       Abs(LastPar  - LastParOnPC)  > Precision::PConfusion())
-                     {
-                       theLoc = E.Location() * theLoc;
-                       theSurf = Handle(Geom_Surface)::DownCast
-                         (theSurf->Transformed(theLoc.Transformation()));
-
-                       if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
-                           theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
-                         {
-                           gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
-                           if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
-                               theDir.IsParallel(gp::DY2d(), Precision::Angular()))
-                             {
-                               Standard_Real U1, U2, V1, V2;
-                               theSurf->Bounds(U1, U2, V1, V2);
-                               gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
-                               if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
-                                   Abs(Origin.X()-U2) <= Precision::Confusion() ||
-                                   Abs(Origin.Y()-V1) <= Precision::Confusion() ||
-                                   Abs(Origin.Y()-V2) <= Precision::Confusion())
-                                 {
-                                   BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-                                   break;
-                                 }
-                             }
-                         }
-
-                       Handle(Geom2d_Curve) ProjPCurve =
-                         GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
-                       if (ProjPCurve.IsNull())
-                         ProjectionSuccess = Standard_False;
-                       else
-                         CurveRep->PCurve( ProjPCurve );
-                     }
-                 }
-             }
-         if (ProjectionSuccess)
-           BB.Range( NE, FirstParOnPC, LastParOnPC );
-         else
-           {
-             BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
-             BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-           }
-       }
+        {
+          MinSurf = Handle(Geom_Surface)::DownCast
+            (MinSurf->Transformed(MinLoc.Transformation()));
+          Standard_Real max_deviation = 0.;
+          if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
+            {
+              if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
+                {
+                  Standard_Boolean IsLine = Standard_False;
+                  if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
+                    IsLine = Standard_True;
+                  else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
+                           MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
+                    {
+                      Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
+                      gp_Dir2d LineDir = theLine->Direction();
+                      if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
+                        IsLine = Standard_True;
+                    }
+                  if (IsLine)
+                    {
+                      gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
+                      gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
+                      gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
+                      gp_Vec aVec(P1, P2);
+                      C3d = new Geom_Line( P1, aVec );
+                    }
+                }
+            }
+          else
+            {
+              Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
+              GeomAdaptor_Surface GAsurf( MinSurf );
+              Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
+              Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
+              Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
+              Standard_Real /*max_deviation,*/ average_deviation;
+              GeomAbs_Shape Continuity = GeomAbs_C1;
+              Standard_Integer MaxDegree = 14;
+              Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
+              GeomLib::BuildCurve3d(Precision::Confusion(),
+                                    ConS, FirstParOnPC, LastParOnPC,
+                                    C3d, max_deviation, average_deviation,
+                                    Continuity, MaxDegree, MaxSegment);
+            }
+          BB.UpdateEdge( NE, C3d, max_deviation );
+          //BB.Range( NE, FirstParOnPC, LastParOnPC );
+          Standard_Boolean ProjectionSuccess = Standard_True;
+          if (NbPCurves > 1)
+            //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+            for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
+                 itr.More();
+                 itr.Next())
+              {
+                Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
+                Standard_Real FirstPar, LastPar;
+                if (CurveRep->IsCurveOnSurface())
+                  {
+                    Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
+                    Handle(Geom_Surface) theSurf  = CurveRep->Surface();
+                    TopLoc_Location      theLoc   = CurveRep->Location();
+                    if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
+                      continue;
+                    FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
+                    LastPar  = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
+                    if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
+                        Abs(LastPar  - LastParOnPC)  > Precision::PConfusion())
+                      {
+                        theLoc = E.Location() * theLoc;
+                        theSurf = Handle(Geom_Surface)::DownCast
+                          (theSurf->Transformed(theLoc.Transformation()));
+
+                        if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
+                            theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
+                          {
+                            gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
+                            if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
+                                theDir.IsParallel(gp::DY2d(), Precision::Angular()))
+                              {
+                                Standard_Real U1, U2, V1, V2;
+                                theSurf->Bounds(U1, U2, V1, V2);
+                                gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
+                                if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
+                                    Abs(Origin.X()-U2) <= Precision::Confusion() ||
+                                    Abs(Origin.Y()-V1) <= Precision::Confusion() ||
+                                    Abs(Origin.Y()-V2) <= Precision::Confusion())
+                                  {
+                                    BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+                                    break;
+                                  }
+                              }
+                          }
+
+                        Handle(Geom2d_Curve) ProjPCurve =
+                          GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
+                        if (ProjPCurve.IsNull())
+                          ProjectionSuccess = Standard_False;
+                        else
+                          CurveRep->PCurve( ProjPCurve );
+                      }
+                  }
+              }
+          if (ProjectionSuccess)
+            BB.Range( NE, FirstParOnPC, LastParOnPC );
+          else
+            {
+              BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
+              BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
+            }
+        }
     }
   else //no pcurves
     {
@@ -1287,58 +1289,58 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
       Standard_Real LastPar  = C3d->LastParameter();
       
       if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
-         (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
-       {
-         Handle(Geom_TrimmedCurve) aTrCurve = 
-           new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
-         
-         // The curve is not prolonged on begin or end.
-         // Trying to prolong it adding a segment to its bound.
-         gp_Pnt                              aPBnd;
-         gp_Vec                              aVBnd;
-         gp_Pnt                              aPBeg;
-         gp_Dir                              aDBnd;
-         Handle(Geom_Line)                   aLin;
-         Handle(Geom_TrimmedCurve)           aSegment;
-         GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
-         Standard_Real                       aTol = Precision::Confusion();
-         Standard_Real                       aDelta = Max(a2Offset, 1.);
-         
-         if (FirstPar > anEf - a2Offset) {
-           C3d->D1(FirstPar, aPBnd, aVBnd);
-           aDBnd.SetXYZ(aVBnd.XYZ());
-           aPBeg    = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
-           aLin     = new Geom_Line(aPBeg, aDBnd);
-           aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
-           
-           if (!aCompCurve.Add(aSegment, aTol))
-             return;
-         }
-         
-         if (LastPar < anEl + a2Offset) {
-           C3d->D1(LastPar, aPBeg, aVBnd);
-           aDBnd.SetXYZ(aVBnd.XYZ());
-           aLin     = new Geom_Line(aPBeg, aDBnd);
-           aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
-           
-           if (!aCompCurve.Add(aSegment, aTol))
-             return;
-         }
-         
-         C3d = aCompCurve.BSplineCurve();
-         FirstPar = C3d->FirstParameter();
-         LastPar  = C3d->LastParameter();
-         BB.UpdateEdge(NE, C3d, Precision::Confusion());
-       }
+          (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
+        {
+          Handle(Geom_TrimmedCurve) aTrCurve = 
+            new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
+          
+          // The curve is not prolonged on begin or end.
+          // Trying to prolong it adding a segment to its bound.
+          gp_Pnt                              aPBnd;
+          gp_Vec                              aVBnd;
+          gp_Pnt                              aPBeg;
+          gp_Dir                              aDBnd;
+          Handle(Geom_Line)                   aLin;
+          Handle(Geom_TrimmedCurve)           aSegment;
+          GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
+          Standard_Real                       aTol = Precision::Confusion();
+          Standard_Real                       aDelta = Max(a2Offset, 1.);
+          
+          if (FirstPar > anEf - a2Offset) {
+            C3d->D1(FirstPar, aPBnd, aVBnd);
+            aDBnd.SetXYZ(aVBnd.XYZ());
+            aPBeg    = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
+            aLin     = new Geom_Line(aPBeg, aDBnd);
+            aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
+            
+            if (!aCompCurve.Add(aSegment, aTol))
+              return;
+          }
+          
+          if (LastPar < anEl + a2Offset) {
+            C3d->D1(LastPar, aPBeg, aVBnd);
+            aDBnd.SetXYZ(aVBnd.XYZ());
+            aLin     = new Geom_Line(aPBeg, aDBnd);
+            aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
+            
+            if (!aCompCurve.Add(aSegment, aTol))
+              return;
+          }
+          
+          C3d = aCompCurve.BSplineCurve();
+          FirstPar = C3d->FirstParameter();
+          LastPar  = C3d->LastParameter();
+          BB.UpdateEdge(NE, C3d, Precision::Confusion());
+        }
       else if (C3d->IsPeriodic())
-       {
-         Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
-         delta *= 0.95;
-         FirstPar = anEf - delta;
-         LastPar  = anEl + delta;
-       }
+        {
+          Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
+          delta *= 0.95;
+          FirstPar = anEf - delta;
+          LastPar  = anEl + delta;
+        }
       else if (C3d->IsClosed())
-       LastPar -= 0.05*(LastPar - FirstPar);
+        LastPar -= 0.05*(LastPar - FirstPar);
       
       BB.Range( NE, FirstPar, LastPar );
     }
@@ -1352,9 +1354,9 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real
 //=======================================================================
 
 static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
-                                     TopoDS_Edge&  OE,
-                                     TopoDS_Edge&  NE,
-                                     Standard_Real TolConf)
+                                      TopoDS_Edge&  OE,
+                                      TopoDS_Edge&  NE,
+                                      Standard_Real TolConf)
 {
   BRepAdaptor_Curve OC(OE);
   BRepAdaptor_Curve NC(NE);
@@ -1384,9 +1386,9 @@ static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
 //    TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
     aLocalShape = V.Oriented(TopAbs_INTERNAL);
     B.UpdateVertex(TopoDS::Vertex(aLocalShape),
-                  U,NE,BRep_Tool::Tolerance(NE));
+                   U,NE,BRep_Tool::Tolerance(NE));
 //    B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                U,NE,BRep_Tool::Tolerance(NE));
+//                   U,NE,BRep_Tool::Tolerance(NE));
   }
   return OK;  
 }
@@ -1397,9 +1399,9 @@ static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
 //=======================================================================
 
 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
-                                 const TopoDS_Face&                F,
-                                 const TopTools_IndexedMapOfShape& NewEdges,
-                                 const Standard_Real               Tol)
+                                  const TopoDS_Face&                F,
+                                  const TopTools_IndexedMapOfShape& NewEdges,
+                                  const Standard_Real               Tol)
 {
 #ifdef DRAW
   NbF2d++;
@@ -1416,8 +1418,8 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
   // calculate intersections2d on faces touched by  
   // intersection3d
   //---------------------------------------------------------
-  TopTools_ListIteratorOfListOfShape it1LE ;    
-  TopTools_ListIteratorOfListOfShape it2LE ;  
+  TopTools_ListIteratorOfListOfShape it1LE ;
+  TopTools_ListIteratorOfListOfShape it2LE ;
 
   //-----------------------------------------------
   // Intersection of edges 2*2.
@@ -1425,7 +1427,8 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
   const TopTools_ListOfShape&        LE = AsDes->Descendant(F);
   TopoDS_Vertex                      V1,V2;
   Standard_Integer                   j, i = 1;
-
+  BRepAdaptor_Surface BAsurf(F);
+  //
   for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
     const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());       
     j = 1;
@@ -1438,10 +1441,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++;
@@ -1486,17 +1489,17 @@ 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);
+        }
       }
     } 
   }
@@ -1504,6 +1507,8 @@ void BRepOffset_Inter2d::ConnexIntByInt
   TopoDS_Face           FIO = TopoDS::Face(OFI.Face());
   if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
 
+  BRepAdaptor_Surface BAsurf(FIO);
+  
   TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
   for (; exp.More(); exp.Next()) {
     const TopoDS_Wire&     W = TopoDS::Wire(exp.Current());
@@ -1515,18 +1520,18 @@ void BRepOffset_Inter2d::ConnexIntByInt
     TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
     wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
 //    wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)),
-//           TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
+//      TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
     CurE = FirstE  = wexp.Current(); 
     while (!end) {
       wexp.Next();
       if (wexp.More()) {
-       NextE = wexp.Current();
+        NextE = wexp.Current();
       } 
       else {
-       NextE = FirstE; end = Standard_True;
+        NextE = FirstE; end = Standard_True;
       }
       if (CurE.IsSame(NextE)) continue;
-
+      
       //IFV------------
       TopoDS_Vertex Vref = CommonVertex(CurE, NextE); 
       gp_Pnt Pref = BRep_Tool::Pnt(Vref);
@@ -1546,43 +1551,43 @@ 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()),
+                         AsDes,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);
+          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);
+        }
       }
       CurE = NextE;
     }
index 334d800cccc9d90c232ad8f42702ca2179da4209..37c632ab163aa3bf66f87c3bff2ba9b45ce2340d 100644 (file)
@@ -49,8 +49,8 @@
 //=======================================================================
 
 BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes, 
-                                      const TopAbs_State              Side ,
-                                      const Standard_Real             Tol)
+                                       const TopAbs_State              Side ,
+                                       const Standard_Real             Tol)
 :myAsDes(AsDes),
 mySide(Side),
 myTol(Tol)
@@ -64,8 +64,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); 
@@ -99,9 +99,9 @@ static void ExtentEdge(const TopoDS_Face& /*F*/,
 //=======================================================================
 
 static void SelectEdge (const TopoDS_Face& /*F*/,
-                       const TopoDS_Face& /*EF*/,
-                       const TopoDS_Edge& E,
-                       TopTools_ListOfShape& LInt)
+                        const TopoDS_Face& /*EF*/,
+                        const TopoDS_Edge& E,
+                        TopTools_ListOfShape& LInt)
 {
   //------------------------------------------------------------
   // Proofing on the intersections on periodical faces
@@ -145,14 +145,14 @@ static void SelectEdge (const TopoDS_Face& /*F*/,
     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();
+        if (anExt.IsMin(i)) {
+          const gp_Pnt &aPMin = anExt.Point(i).Value();
 
-         aSqrDist1  = PFirst.SquareDistance(aPMin);
-         isMinFound = Standard_True;
+          aSqrDist1  = PFirst.SquareDistance(aPMin);
+          isMinFound = Standard_True;
 
-         break;
-       }
+          break;
+        }
       }
     }
     if (!isMinFound) {
@@ -167,14 +167,14 @@ static void SelectEdge (const TopoDS_Face& /*F*/,
     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();
+        if (anExt.IsMin(i)) {
+          const gp_Pnt &aPMin = anExt.Point(i).Value();
 
-         aSqrDist2  = PLast.SquareDistance(aPMin);
-         isMinFound = Standard_True;
+          aSqrDist2  = PLast.SquareDistance(aPMin);
+          isMinFound = Standard_True;
 
-         break;
-       }
+          break;
+        }
       }
     }
     if (!isMinFound) {
@@ -207,7 +207,7 @@ static void SelectEdge (const TopoDS_Face& /*F*/,
 //=======================================================================
 
 void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
-                                   const BRepAlgo_Image&     InitOffsetFace)
+                                    const BRepAlgo_Image&     InitOffsetFace)
 {
   //---------------------------------------------------------------
   // Calculate the intersections of offset faces 
@@ -250,8 +250,8 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
 //=======================================================================
 
 void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
-                                  const TopoDS_Face& F2,
-                                  const BRepAlgo_Image&     InitOffsetFace)
+                                   const TopoDS_Face& F2,
+                                   const BRepAlgo_Image&     InitOffsetFace)
 {
   TopTools_ListOfShape LInt1, LInt2;
   TopoDS_Edge NullEdge;
@@ -261,9 +261,9 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
   const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
   const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
   Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
-                                InitF1.ShapeType() == TopAbs_EDGE );
+                                 InitF1.ShapeType() == TopAbs_EDGE );
   Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE && 
-                                InitF2.ShapeType() == TopAbs_FACE);
+                                 InitF2.ShapeType() == TopAbs_FACE);
   TopTools_ListOfShape LE,LV;
   LInt1.Clear(); LInt2.Clear(); 
   if (BRepOffset_Tool::HasCommonShapes(F1,F2,LE,LV) ||
@@ -273,38 +273,44 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
     //-------------------------------------------------
     if ( LE.IsEmpty() && !LV.IsEmpty()) {
       if (InterPipes) {
-       //----------------------
-       // tubes share a vertex.
-       //----------------------
-       const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
-       const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
-       TopoDS_Vertex VE1[2],VE2[2];
-       TopExp::Vertices(EE1,VE1[0],VE1[1]);
-       TopExp::Vertices(EE2,VE2[0],VE2[1]);
-       TopoDS_Vertex V;
-       for (Standard_Integer i = 0 ; i < 2; i++) {
-         for (Standard_Integer j = 0 ; j < 2; j++) {
-           if (VE1[i].IsSame(VE2[j])) {
-             V = VE1[i];
-           }
-         }
-       }
-       if (!InitOffsetFace.HasImage(V)) { //no sphere
-         BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
-       }               
+        //----------------------
+        // tubes share a vertex.
+        //----------------------
+        const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
+        const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
+        TopoDS_Vertex VE1[2],VE2[2];
+        TopExp::Vertices(EE1,VE1[0],VE1[1]);
+        TopExp::Vertices(EE2,VE2[0],VE2[1]);
+        TopoDS_Vertex V;
+        for (Standard_Integer i = 0 ; i < 2; i++) {
+          for (Standard_Integer j = 0 ; j < 2; j++) {
+            if (VE1[i].IsSame(VE2[j])) {
+              V = VE1[i];
+            }
+          }
+        }
+        if (!InitOffsetFace.HasImage(V)) { //no sphere
+          BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
+        }                
       }
       else {
-       //--------------------------------------------------------
-       // Intersection having only common vertices
-       // and supports having common edges.
-       // UNSUFFICIENT, but a larger criterion shakes too
-       // many sections.
-       //--------------------------------------------------------
-       if (InterFaces && 
-           BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
-                                            TopoDS::Face(InitF2),LE,LV)) 
-         if (!LE.IsEmpty())
-           BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+        //--------------------------------------------------------
+        // Intersection having only common vertices
+        // and supports having common edges.
+        // UNSUFFICIENT, but a larger criterion shakes too
+        // many sections.
+        //--------------------------------------------------------
+        if (InterFaces) {
+          if (BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
+                                               TopoDS::Face(InitF2),LE,LV)) {
+            if (!LE.IsEmpty()) {
+              BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
+            }
+          }
+          else {
+            BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge);
+          }
+        }
       }
     }
   }
@@ -350,13 +356,13 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
       //-----------------------------------------------------------
       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
       if (Anc.Extent() == 2) {
-       F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
-       F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
-       if (!IsDone(F1,F2)) {
-         BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
-         Store (F1,F2,LInt1,LInt2);
-       }
-      }          
+        F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
+        F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
+        if (!IsDone(F1,F2)) {
+          BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
+          Store (F1,F2,LInt1,LInt2);
+        }
+      }          
     }
   }
   //---------------------------------------------------------------------
@@ -378,84 +384,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);
+                  }
+                }
+              }
+            }
+          }
+        }
       }
     }
   }
@@ -491,87 +497,87 @@ void BRepOffset_Inter3d::ConnexIntByInt
     if (!L.IsEmpty()) {
       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_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
+      }          
     }
   }
 }
@@ -616,48 +622,48 @@ void BRepOffset_Inter3d::ContextIntByInt
     else               WCF = CF;
 
     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)) {
-       //----------------------------------------------------------------
-       // 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;
+        //----------------------------------------------------------------
+        // 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());
@@ -666,34 +672,34 @@ void BRepOffset_Inter3d::ContextIntByInt
       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);
+        BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
+        MES.Bind(OF,NF);
       }
       else {
-       NF = TopoDS::Face(MES(OF));
+        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,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);
-       }
+        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);
+        }
       }
     }
   }
@@ -705,10 +711,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 +734,39 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
   for (j = 1; j <= ContextFaces.Extent(); j++) {
     const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-        exp.More(); exp.Next()) {
+         exp.More(); exp.Next()) {
       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
       if (!Analyse.HasAncestor(E)) {
-       if (InSide)
-         myAsDes->Add(CF,E);
-       else {
-         TopoDS_Edge NE;
-         if (!InitOffsetEdge.HasImage(E)) {
-           Standard_Real f,l,Tol;
-           BRep_Tool::Range(E,f,l);
-           Tol = BRep_Tool::Tolerance(E);
-           ExtentEdge(CF,E,NE);
-           TopoDS_Vertex V1,V2;
-           TopExp::Vertices(E,V1,V2);
-           NE.Orientation(TopAbs_FORWARD);
-           myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
-           myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
-           TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
-           B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
-           aLocalShape = V2.Oriented(TopAbs_INTERNAL);
-           B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
-           NE.Orientation(E.Orientation());
-           myAsDes->Add(CF,NE);
-           InitOffsetEdge.Bind(E,NE);
-         }
-         else {
-           NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
-           myAsDes->Add(CF,NE.Oriented(E.Orientation()));
-         }
-       }
-       continue;
+        if (InSide)
+          myAsDes->Add(CF,E);
+        else {
+          TopoDS_Edge NE;
+          if (!InitOffsetEdge.HasImage(E)) {
+            Standard_Real f,l,Tol;
+            BRep_Tool::Range(E,f,l);
+            Tol = BRep_Tool::Tolerance(E);
+            ExtentEdge(CF,E,NE);
+            TopoDS_Vertex V1,V2;
+            TopExp::Vertices(E,V1,V2);
+            NE.Orientation(TopAbs_FORWARD);
+            myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
+            myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
+            TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
+            B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
+            aLocalShape = V2.Oriented(TopAbs_INTERNAL);
+            B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
+//            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
+//            B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
+            NE.Orientation(E.Orientation());
+            myAsDes->Add(CF,NE);
+            InitOffsetEdge.Bind(E,NE);
+          }
+          else {
+            NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
+            myAsDes->Add(CF,NE.Oriented(E.Orientation()));
+          }
+        }
+        continue;
       }
       OE.Nullify();
       //---------------------------------------------------
@@ -787,11 +793,11 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
       //--------------------------------------------------
       // MAJ of OE on cap CF.
       //--------------------------------------------------
-//      TopTools_ListOfShape LOE; LOE.Append(OE);            
+//      TopTools_ListOfShape LOE; LOE.Append(OE);              
 //      BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
 //      LInt2.Clear();
 //      StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
-//                LInt1,LInt2);
+//                   LInt1,LInt2);
       LInt1.Clear(); LInt1.Append(OE);
       LInt2.Clear();    
       TopAbs_Orientation O1,O2;
@@ -807,18 +813,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 +840,64 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
         }
       }
 
-           //--------------------------------------------------
-           // MAj of OE on cap CF.
-           //--------------------------------------------------
-           //        LOE.Clear(); LOE.Append(OE);
-           //        BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
-           //        LInt2.Clear();
-           //        StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
-           //                     LInt1,LInt2);
-           LInt1.Clear(); LInt1.Append(OE);
-           LInt2.Clear();    
-           TopAbs_Orientation O1,O2;
-           BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);      
-//         if (mySide == TopAbs_OUT);
-           O1 = TopAbs::Reverse(O1);
-           LInt1.First().Orientation(O1);
-           Store(CF,OF1,LInt1,LInt2);
-         }
-       }
+            //--------------------------------------------------
+            // MAj of OE on cap CF.
+            //--------------------------------------------------
+            //              LOE.Clear(); LOE.Append(OE);
+            //              BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
+            //              LInt2.Clear();
+            //              StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
+            //                           LInt1,LInt2);
+            LInt1.Clear(); LInt1.Append(OE);
+            LInt2.Clear();    
+            TopAbs_Orientation O1,O2;
+            BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);      
+//            if (mySide == TopAbs_OUT);
+            O1 = TopAbs::Reverse(O1);
+            LInt1.First().Orientation(O1);
+            Store(CF,OF1,LInt1,LInt2);
+          }
+        }
       }
     }
     
     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
-        exp.More(); exp.Next()) {
+         exp.More(); exp.Next()) {
       const TopoDS_Vertex&        V  = TopoDS::Vertex(exp.Current());
       if (!Analyse.HasAncestor(V)) {
-       continue;
+        continue;
       }
       const TopTools_ListOfShape& LE =  Analyse.Ancestors(V);
       TopTools_ListIteratorOfListOfShape itLE(LE);
       for (; itLE.More(); itLE.Next()) {
-       const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
-       const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
-       TopTools_ListIteratorOfListOfShape itLF(LF);
-       for ( ; itLF.More(); itLF.Next()) {
-         const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
-         //-------------------------------------------------
-         // OF1 parallel face generated by uneFace ancestor of V[i].
-         //-------------------------------------------------
-         OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
-         if (!IsDone(OF1,CF)) {
-           //-------------------------------------------------------
-           // Find if one of edges of OF1 has no trace in CF.
-           //-------------------------------------------------------
-           TopTools_ListOfShape LOE;
-           TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
-           for ( ;exp2.More(); exp2.Next()) {
-             LOE.Append(exp2.Current());
-           }
-           BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
-           //-------------------------------------------------------
-           // If no trace try intersection.
-           //-------------------------------------------------------
-           if (LInt1.IsEmpty()) {
-             BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
-           }
-           Store (CF,OF1,LInt1,LInt2);
-         }
-       }
+        const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
+        const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
+        TopTools_ListIteratorOfListOfShape itLF(LF);
+        for ( ; itLF.More(); itLF.Next()) {
+          const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
+          //-------------------------------------------------
+          // OF1 parallel face generated by uneFace ancestor of V[i].
+          //-------------------------------------------------
+          OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
+          if (!IsDone(OF1,CF)) {
+            //-------------------------------------------------------
+            // Find if one of edges of OF1 has no trace in CF.
+            //-------------------------------------------------------
+            TopTools_ListOfShape LOE;
+            TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+            for ( ;exp2.More(); exp2.Next()) {
+              LOE.Append(exp2.Current());
+            }
+            BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
+            //-------------------------------------------------------
+            // If no trace try intersection.
+            //-------------------------------------------------------
+            if (LInt1.IsEmpty()) {
+              BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
+            }
+            Store (CF,OF1,LInt1,LInt2);
+          }
+        }
       }
     } 
   }
@@ -913,7 +919,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 +940,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 +993,9 @@ TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges()
 //=======================================================================
 
 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1, 
-                              const TopoDS_Face& F2, 
-                              const TopTools_ListOfShape& LInt1, 
-                              const TopTools_ListOfShape& LInt2)
+                               const TopoDS_Face& F2, 
+                               const TopTools_ListOfShape& LInt1, 
+                               const TopTools_ListOfShape& LInt2)
 {
   if (!LInt1.IsEmpty()) {
     myTouched.Add(F1);
index e37b08d567959a371b18b33f32a151bc5b9955b1..ca16ccca38eb56a2ea05e3b2a052ef61f53b3081 100644 (file)
@@ -19,7 +19,7 @@
 
 class MakeOffset from BRepOffset 
 
-       ---Purpose: 
+        ---Purpose: 
 
 uses
     Image                from BRepAlgo,
@@ -36,7 +36,9 @@ uses
     Edge                 from TopoDS,
     MapOfShape           from TopTools, 
     IndexedMapOfShape    from TopTools, 
-    ListOfShape          from TopTools,
+    ListOfShape          from TopTools, 
+    DataMapOfShapeShape  from TopTools, 
+    IndexedDataMapOfShapeListOfShape from TopTools,
     MakeLoops            from BRepOffset
 
 is
@@ -45,38 +47,38 @@ is
     
     Create ( S            : Shape    from TopoDS;
              Offset       : Real     from Standard;
-            Tol          : Real     from Standard;
-            Mode         : Mode     from BRepOffset = BRepOffset_Skin;
-            Intersection : Boolean  from Standard   = Standard_False;
-            SelfInter    : Boolean  from Standard   = Standard_False;
+             Tol          : Real     from Standard;
+             Mode         : Mode     from BRepOffset = BRepOffset_Skin;
+                 Intersection : Boolean  from Standard   = Standard_False;
+             SelfInter    : Boolean  from Standard   = Standard_False;
              Join         : JoinType from GeomAbs    = GeomAbs_Arc;
-            Thickening   : Boolean  from Standard   = Standard_False)
-    returns MakeOffset from BRepOffset;             
-            
+             Thickening   : Boolean  from Standard   = Standard_False)
+    returns MakeOffset from BRepOffset;             
+             
 ---Category: Initialization.
 
     Initialize (me : in out;
-               S            : Shape    from TopoDS;
+                    S            : Shape    from TopoDS;
                 Offset       : Real     from Standard;
-               Tol          : Real     from Standard;
-               Mode         : Mode     from BRepOffset = BRepOffset_Skin;
-               Intersection : Boolean  from Standard   = Standard_False;
-               SelfInter    : Boolean  from Standard   = Standard_False;
+                Tol          : Real     from Standard;
+                Mode         : Mode     from BRepOffset = BRepOffset_Skin;
+                    Intersection : Boolean  from Standard   = Standard_False;
+                SelfInter    : Boolean  from Standard   = Standard_False;
                 Join         : JoinType from GeomAbs    = GeomAbs_Arc; 
-               Thickening   : Boolean  from Standard   = Standard_False)
+                Thickening   : Boolean  from Standard   = Standard_False)
     is static;
     
     Clear (me : in out) 
     is static;
 
     AddFace (me : in out; F  : Face from TopoDS) is static;
-       ---Purpose: Add Closing Faces,  <F>  has to be  in  the initial
-       --          shape S.
+            ---Purpose: Add Closing Faces,  <F>  has to be  in  the initial
+            --          shape S.
       
     SetOffsetOnFace (me  : in out; 
-                    F   : Face from TopoDS;
-                    Off : Real from Standard) is static;
-       ---Purpose: set the offset <Off> on the Face <F> 
+                             F   : Face from TopoDS;
+                             Off : Real from Standard) is static;
+            ---Purpose: set the offset <Off> on the Face <F> 
 
     
 ---Category: Computation.
@@ -88,7 +90,7 @@ is
 ---Category: Querying.
            
     GetAnalyse(me) 
-       ---C++: return const &
+            ---C++: return const &
     returns Analyse from BRepOffset
     is static;
 
@@ -96,18 +98,18 @@ is
     is static;
     
     Shape (me) 
-       ---C++: return const &
+            ---C++: return const &
     returns Shape from TopoDS
     is static;
 
     Error (me) returns Error from BRepOffset;
-       ---Purpose: returns information if IsDone() = FALSE.
-                           
+            ---Purpose: returns information if IsDone() = FALSE.
+                             
 
     OffsetFacesFromShapes (me)
-       ---Purpose: Returns <Image> containing links between initials
-       --          shapes and offset faces.
-       ---C++: return const &
+        ---Purpose: Returns <Image> containing links between initials
+         --          shapes and offset faces.
+         ---C++: return const &
     returns Image from BRepAlgo
     is static;    
     
@@ -115,24 +117,24 @@ is
 -- Query offset join type.
 
     GetJoinType(me) 
-       ---Purpose: Returns myJoin.
+            ---Purpose: Returns myJoin.
     returns JoinType from GeomAbs 
     is static;
  
 -- Add methods for supporting history.
 
     OffsetEdgesFromShapes (me)
-       ---Purpose: Returns <Image> containing links between initials
-       --          shapes and offset edges.
-       ---C++: return const &
+        ---Purpose: Returns <Image> containing links between initials
+         --          shapes and offset edges.
+         ---C++: return const &
     returns Image from BRepAlgo
     is static;    
     
 -- Modified by skv - Tue Mar 15 16:17:37 2005 End
 
     ClosingFaces (me)   
-       ---Purpose: Returns the list of closing faces stores by AddFace 
-       ---C++: return const &
+            ---Purpose: Returns the list of closing faces stores by AddFace 
+        ---C++: return const &
     returns IndexedMapOfShape from TopTools
     is static;
 
@@ -143,18 +145,30 @@ is
     
     BuildOffsetByInter ( me : in out )
     is static private;
-       
+    BuildSplitsOfFaces (me:in out; 
+        theLF    : ListOfShape from TopTools; 
+        theAsDes : AsDes from BRepAlgo; 
+        theOrMap : out IndexedDataMapOfShapeListOfShape from TopTools;
+        theImage : out Image from BRepAlgo;
+        theLFail : out ListOfShape from TopTools; 
+        bLimited : Boolean from Standard)
+    is static private;
+    ---Purpose: 
+    -- Building splits of the offset faces by the section curves 
+    -- between the neighboring faces. 
     SelfInter  (me    : in out ; 
-               Modif : in out MapOfShape from TopTools)
-    is static private;         
+                    Modif : in out MapOfShape from TopTools)
+    is static private;                
     
     Intersection3D (me        : in out;
-                   Inter     : in out Inter3d from BRepOffset)
-    is static private;             
-                   
+                            Inter     : in out Inter3d from BRepOffset)
+    is static private;                    
     Intersection2D ( me       : in out ;
                      Modif    : IndexedMapOfShape from TopTools;
-                    NewEdges : IndexedMapOfShape from TopTools)
+                     NewEdges : IndexedMapOfShape from TopTools)
     is static private;
     
     MakeLoops ( me    : in out ;
@@ -174,7 +188,7 @@ is
 
     SelectShells (me : in out)
     is static private;
-       
+        
     EncodeRegularity( me : in out)
     is static private;
 
@@ -182,19 +196,19 @@ is
     is static private;
     
     ToContext (me    : in out;
-              MapSF : in out DataMapOfShapeOffset from BRepOffset)
-    is static private; 
+                   MapSF : in out DataMapOfShapeOffset from BRepOffset)
+    is static private;        
     
     UpdateFaceOffset (me: in out) 
-       ---Purpose: Private method use to update the map face<->offset
+        ---Purpose: Private method use to update the map face<->offset
     is static private; 
      
     CorrectConicalFaces (me: in out)
-       ---Purpose: Private method used to correct degenerated edges on conical faces
+        ---Purpose: Private method used to correct degenerated edges on conical faces
     is static private; 
 
     MakeMissingWalls (me: in out)
-       ---Purpose: Private method used to build walls for thickening the shell
+        ---Purpose: Private method used to build walls for thickening the shell
     is static private; 
 
 fields
@@ -211,7 +225,7 @@ fields
     myFaceOffset     : DataMapOfShapeReal from TopTools;
     
     myFaces          : IndexedMapOfShape from TopTools;
-    myAnalyse        : Analyse          from BRepOffset;
+    myAnalyse        : Analyse           from BRepOffset;
     
     myOffsetShape    : Shape       from TopoDS;       -- Result
     myInitOffsetFace : Image       from BRepAlgo;
index 69ca98244269046ffe7868e8ee3585f30fb540f9..8e5e4aaa327f2c27eeaa44d672d6479b2546769c 100644 (file)
 //=======================================================================
 
 static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
-                                     Handle(BRepAlgo_AsDes)      AsDes)
+                                      Handle(BRepAlgo_AsDes)      AsDes)
 {
   TopTools_ListOfShape               LVP;
   TopTools_ListIteratorOfListOfShape it1LE ;    
@@ -155,34 +155,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
-       }
+        }
       }
     }
   }
@@ -205,30 +205,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++;
     }
@@ -240,12 +240,12 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 
 
 static void UpdateTolerance (      TopoDS_Shape&               myShape,
-                            const TopTools_IndexedMapOfShape& myFaces);
+                             const TopTools_IndexedMapOfShape& myFaces);
 
 
 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
 
@@ -267,13 +267,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();
@@ -303,42 +303,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 {
@@ -349,25 +349,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();
       }
     }
   }
@@ -401,9 +401,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;
 
@@ -415,21 +415,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;
@@ -442,19 +442,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);
     }
 }
@@ -476,13 +476,13 @@ 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)
 : 
 myOffset     (Offset),
 myTol        (Tol),
@@ -506,13 +506,13 @@ 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)
 {
   myOffset     = Offset;
   myShape      = S;
@@ -565,7 +565,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);
@@ -577,7 +577,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;
@@ -632,14 +632,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 (myInitOffsetFace.HasImage(Root)) {
+      if (!myFaces.Contains(Root)) {
+        OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
+      }
+    }
   }
 }
 
@@ -708,25 +711,31 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   //-----------------
   // Intersection 3d .
   //-----------------
-  BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
-  Intersection3D (Inter);
-  //-----------------
-  // Intersection2D
-  //-----------------
-  TopTools_IndexedMapOfShape& Modif    = Inter.TouchedFaces(); 
-  TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
-
-  if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
-  //-------------------------------------------------------
-  // Unwinding 2D and reconstruction of modified faces
-  //----------------------------------------------------
-  MakeLoops (Modif);
-  //-----------------------------------------------------
-  // Reconstruction of non modified faces sharing 
-  // reconstructed edges
-  //------------------------------------------------------
-  if (!Modif.IsEmpty()) MakeFaces (Modif);
 
+
+  //if (!Intersection3D()) {
+    BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
+    Intersection3D (Inter);
+    //-----------------
+    // Intersection2D
+    //-----------------
+    TopTools_IndexedMapOfShape& Modif    = Inter.TouchedFaces(); 
+    TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
+    
+    if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
+    //-------------------------------------------------------
+    // Unwinding 2D and reconstruction of modified faces
+    //----------------------------------------------------
+    MakeLoops (Modif);
+    //-----------------------------------------------------
+    // Reconstruction of non modified faces sharing 
+    // reconstructed edges
+    //------------------------------------------------------
+    if (!Modif.IsEmpty()) MakeFaces (Modif);
+  //}
+
+
+  //
   if (myThickening)
     MakeMissingWalls();
 
@@ -881,8 +890,8 @@ const TopoDS_Shape&  BRepOffset_MakeOffset::Shape() const
 //=======================================================================
 
 static void TrimEdge (TopoDS_Edge&                  NE,
-                     const Handle(BRepAlgo_AsDes)& AsDes2d,
-                           Handle(BRepAlgo_AsDes)& AsDes)
+                      const Handle(BRepAlgo_AsDes)& AsDes2d,
+                            Handle(BRepAlgo_AsDes)& AsDes)
 {
   Standard_Real aSameParTol = Precision::Confusion();
   
@@ -898,23 +907,23 @@ static void TrimEdge (TopoDS_Edge&                  NE,
     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();
-       }
+        {
+          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()) {
@@ -940,6 +949,606 @@ static void TrimEdge (TopoDS_Edge&                  NE,
   }
 }
 
+
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPAlgo_Builder.hxx>
+#include <BOPAlgo_MakerVolume.hxx>
+#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
+#include <BOPTools.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <BOPAlgo_PaveFiller.hxx>
+#include <BOPDS_DS.hxx>
+#include <BOPDS_VectorOfInterfVE.hxx>
+#include <BOPCol_DataMapOfShapeShape.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
+
+//=======================================================================
+//function : SortFaces
+//purpose  : 
+//=======================================================================
+static void SortFaces(const TopTools_ListOfShape& theLIm, 
+                      TopTools_ListOfShape& theLFImages,
+                      const Standard_Boolean bKeepFirst)
+{
+  Standard_Integer bKeep; // 1 - keep; -1 - remove
+  Standard_Boolean bFlag;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
+  TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp;
+  TopTools_MapOfShape aMV;
+  TopTools_ListIteratorOfListOfShape aItLF;
+  TopExp_Explorer aExp;
+  //
+  aLFLeft = theLIm;
+  //
+  bKeep = bKeepFirst ? 1 : -1;
+  for (;;) {
+    aLFTmp = aLFLeft;
+    //
+    aLFLeft.Clear();
+    aLFKeep.Clear();
+    aDMELF.Clear();
+    //
+    // map list of images  edge - faces
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+    }
+    //
+    // find images that have edge attached to only one face
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      aExp.Init(aFIm, TopAbs_EDGE);
+      for (bFlag = Standard_False; aExp.More(); aExp.Next()) {
+        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+        const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
+        if (aLEF.Extent() == 1) {
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices(aE, aV1, aV2);
+          aMV.Add(aV1);
+          aMV.Add(aV2);
+          //
+          bFlag = Standard_True;
+        }
+      }
+      //
+      if (bFlag) {
+        aLFKeep.Append(aFIm);
+      }
+      else {
+        aLFLeft.Append(aFIm);
+      }
+    }
+    //
+    // map shapes left for processing
+    aDMELF.Clear();
+    aLFTmp = aLFLeft;
+    aLFLeft.Clear();
+    //
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+    }
+    //
+    // find outer edges and check if they touche the first part of edges
+    aItLF.Initialize(aLFTmp);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+      aExp.Init(aFIm, TopAbs_EDGE);
+      for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) {
+        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+        const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
+        if (aLEF.Extent() == 1) {
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices(aE, aV1, aV2);
+          //
+          bFlag = aMV.Contains(aV1) ||
+            aMV.Contains(aV2);
+        }
+      }
+      //
+      if (bFlag) {
+        aLFKeep.Append(aFIm);
+      }
+      else {
+        aLFLeft.Append(aFIm);
+      }
+    }
+    //
+    if (bKeep == 1) {
+      // aLFKeep should be kept
+      // aLFLeft left for further processing
+      aItLF.Initialize(aLFKeep);
+      for (; aItLF.More(); aItLF.Next()) {
+        const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+        theLFImages.Append(aFIm);
+      }
+    }
+    //
+    if (aLFLeft.IsEmpty()) {
+      break;
+    }
+    //
+    bKeep *= -1;
+  }
+}
+
+//=======================================================================
+//function : FindShape
+//purpose  : 
+//=======================================================================
+static 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 : ComputeBiNormal
+//purpose  : 
+//=======================================================================
+static 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 : UpdateOrigins
+//purpose  : 
+//=======================================================================
+static 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 : BuildSplitsOfFaces
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffset::BuildSplitsOfFaces
+  (const TopTools_ListOfShape& theLF,
+   const Handle(BRepAlgo_AsDes)& theAsDes,
+   TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+   BRepAlgo_Image& theImage,
+   TopTools_ListOfShape& theLFailed,
+   const Standard_Boolean bLimited)
+{
+  BOPCol_ListOfShape aLS;
+  BOPCol_ListIteratorOfListOfShape aIt;
+  TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1;
+  TopTools_DataMapOfShapeListOfShape anEImages;
+  //
+  // firstly it is necessary to fuse all the edges
+  aItLF.Initialize(theLF);
+  for (; aItLF.More(); aItLF.Next()) {
+    const TopoDS_Shape& aF = aItLF.Value();
+    //
+    const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF);
+    aItLE.Initialize(aLE);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value();
+      if (BRep_Tool::Degenerated(aE)) {
+        continue;
+      }
+      aLS.Append(aE);
+    }
+  }
+  //
+  if (aLS.Extent() > 1) {
+    BOPAlgo_PaveFiller aPF;
+    //
+    aPF.SetArguments(aLS);
+    aPF.Perform();
+    if (aPF.ErrorStatus() == 0) {
+      BOPAlgo_Builder aGFE;
+      //
+      aGFE.SetArguments(aLS);
+      aGFE.PerformWithFiller(aPF);
+      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_Shape& aF = 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_Shape& aEIm = aItLE1.Value();
+          aLS.Append(aEIm);
+          if (!aMFE.Contains(aEIm)) {
+            ++iCountE;
+          }
+        }
+      }
+      else {
+        aLS.Append(aE);
+        if (!aMFE.Contains(aE)) {
+          ++iCountE;
+        }
+      }
+    }
+    //
+    TopTools_ListOfShape aLFImages;
+    //
+    // split the face by the edges
+    if (!iCountE) {
+      aLFImages.Append(aF);
+      theImage.Bind(aF, aLFImages);
+      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();
+          bKeep = aME.Contains(aE);
+        }
+        //
+        if (bKeep) {
+          aItLE.Next();
+        }
+        else {
+          aLFImages.Remove(aItLE);
+        }
+      }
+      //
+      // check offset faces on the coincidence of the 
+      // bi-normal directions with the original faces
+      //
+      UpdateOrigins(theOrigins, aGF);
+      //
+      Standard_Real anAngle;
+      Standard_Boolean bRem;
+      TopTools_ListOfShape aLFKeep;
+      //
+      const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(aF).First();
+      //
+      aItLE.Initialize(aLFImages);
+      for (; aItLE.More(); ) {
+        const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLE.Value();
+        const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
+        //
+        bKeep = Standard_True;
+        bRem = Standard_True;
+        //
+        TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
+        for (; aExp.More(); aExp.Next()) {
+          const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
+          //
+          if (!theOrigins.Contains(aEIm)) {
+            continue;
+          }
+          //
+          const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
+          //
+          if (aLEOr.Extent() > 1) {
+            TopTools_MapOfShape aME, aMV;
+            Standard_Integer aNbE, aNbV;
+            //
+            TopTools_ListIteratorOfListOfShape aItLS1(aLEOr);
+            for (; aItLS1.More(); aItLS1.Next()) {
+              const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS1.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;
+            }
+          }
+          //
+          const TopoDS_Shape& 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;
+          }
+          //
+          // check coincidence of bi-normals
+          anAngle = aDB1.Angle(aDB2);
+          if (Abs(anAngle - M_PI) < Precision::Confusion()) {
+            bKeep = Standard_False;
+            bRem = bRem && Standard_True;
+          }
+          else {
+            bRem = Standard_False;
+          }
+          //
+          if (!bKeep && !bRem) {
+            break;
+          }
+        }
+        //
+        if (bRem) {
+          aLFImages.Remove(aItLE);
+        }
+        else {
+          if (bKeep) {
+            aLFKeep.Append(aFIm);
+          }
+          aItLE.Next();
+        }
+      }
+      //
+      TopTools_ListOfShape aLFTmp = aLFImages;
+      aLFImages.Clear();
+      // limit the face
+      SortFaces(aLFTmp, aLFImages, Standard_True);
+      //
+      TopTools_MapOfShape aMFence;
+      aItLE.Initialize(aLFImages);
+      for (; aItLE.More(); aItLE.Next()) {
+        const TopoDS_Shape& aFIm = aItLE.Value();
+        aMFence.Add(aFIm);
+      }
+      //
+      aItLE.Initialize(aLFKeep);
+      for (; aItLE.More(); aItLE.Next()) {
+        const TopoDS_Shape& aFIm = aItLE.Value();
+        if (aMFence.Add(aFIm)) {
+          aLFImages.Append(aFIm);
+        }
+      }
+    }
+    //
+    // Fill history for faces
+    if (aLFImages.Extent()) {
+      theImage.Bind(aF, aLFImages);
+    }
+    else {
+      theLFailed.Append(aF);
+    }
+  }
+  //
+  // fill history for edges
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages);
+  for (; aItEIm.More(); aItEIm.Next()) {
+    const TopoDS_Shape& aE = aItEIm.Key();
+    const TopTools_ListOfShape& aLEIm = aItEIm.Value();
+    if (theImage.HasImage(aE)) {
+      theImage.Add(aE, aLEIm);
+    }
+    else {
+      theImage.Bind(aE, aLEIm);
+    }
+  }
+}
+
 //=======================================================================
 //function : BuildOffsetByInter
 //purpose  : 
@@ -979,27 +1588,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);
@@ -1047,6 +1656,7 @@ 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());
@@ -1056,43 +1666,72 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     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);
-       } 
+        if (Build.IsBound(EI)) {
+          NE = Build(EI);
+          if (NE.ShapeType() == TopAbs_EDGE) {
+            if (anOrigins.Contains(NE)) {
+              anOrigins.ChangeFromKey(NE).Append(EI);
+            }
+            else {
+              TopTools_ListOfShape aLSx;
+              aLSx.Append(EI);
+              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(EI);
+                }
+                else {
+                  TopTools_ListOfShape aLSx;
+                  aLSx.Append(EI);
+                  anOrigins.Add(NEC, aLSx);
+                }
+                //
+                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 (anOrigins.Contains(NE)) {
+            anOrigins.ChangeFromKey(NE).Append(EI);
+          }
+          else {
+            TopTools_ListOfShape aLSx;
+            aLSx.Append(EI);
+            anOrigins.Add(NE, aLSx);
+          }
+          ///////////////////////////////////////////////
+          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);
+        } 
       }
     }
   }
@@ -1109,6 +1748,15 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
       const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
       LFE.Append(NF);
       IMOE.SetRoot(NF);
+      //
+      if (anOrigins.Contains(NF)) {
+        anOrigins.ChangeFromKey(NF).Append(FI);
+      }
+      else {
+        TopTools_ListOfShape aLSx;
+        aLSx.Append(FI);
+        anOrigins.Add(NF, aLSx);
+      }
     }
   }
   
@@ -1129,8 +1777,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   //-------------------------------
   // Unwinding of extended Faces.
   //-------------------------------
-  myMakeLoops.Build(LFE  ,AsDes,IMOE);
-
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    TopTools_ListOfShape aLFailed;
+    BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False);
+    if (aLFailed.Extent()) {
+      myMakeLoops.Build(aLFailed, AsDes, IMOE);
+    }
+  }
+  else {
+    myMakeLoops.Build(LFE, AsDes, IMOE);
+  }
+  //
 #ifdef OCCT_DEBUG
   TopTools_IndexedMapOfShape COES;
 #endif
@@ -1144,91 +1802,91 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     if (MES.IsBound(OF)) {
       OF = TopoDS::Face(MES(OF));
       if (IMOE.HasImage(OF)) {
-       const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
-       myInitOffsetFace.Bind(FI,LOFE);
-       for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
-         const TopoDS_Shape& OFE =  itLF.Value();
-         myImageOffset.SetRoot(OFE);
+        const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
+        myInitOffsetFace.Bind(FI,LOFE);
+        for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
+          const TopoDS_Shape& OFE =  itLF.Value();
+          myImageOffset.SetRoot(OFE);
 #ifdef DRAW
-         if (AffichInt2d) {
-           sprintf(name,"AF_%d",NbAF++);
-           DBRep::Set(name,OFE);
-         }
+          if (AffichInt2d) {
+            sprintf(name,"AF_%d",NbAF++);
+            DBRep::Set(name,OFE);
+          }
 #endif
-         TopTools_MapOfShape View;
-         for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
-              Exp2.More(); Exp2.Next()) {
-           const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
-           
-           myAsDes->Add (OFE,COE);
+          TopTools_MapOfShape View;
+          for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
+               Exp2.More(); Exp2.Next()) {
+            const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
+            
+            myAsDes->Add (OFE,COE);
 #ifdef DRAW
-           if (AffichInt2d) {
-             sprintf(name,"AE_%d",NbAE++);
-             DBRep::Set(name,COE);
-             COES.Add(COE);
-           }
+            if (AffichInt2d) {
+              sprintf(name,"AE_%d",NbAE++);
+              DBRep::Set(name,COE);
+              COES.Add(COE);
+            }
 #endif
-           if (View.Add(COE)){
-             if (!myAsDes->HasDescendant(COE)) {
-               TopoDS_Vertex CV1,CV2;
-               TopExp::Vertices(COE,CV1,CV2);
-               if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
-               if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));     
-             }
-           }
-         }
-       }
+            if (View.Add(COE)){
+              if (!myAsDes->HasDescendant(COE)) {
+                TopoDS_Vertex CV1,CV2;
+                TopExp::Vertices(COE,CV1,CV2);
+                if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+                if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));        
+              }
+            }
+          }
+        }
       }
       else {
-       myInitOffsetFace.Bind(FI,OF);
-       myImageOffset.SetRoot(OF);
+        /*myInitOffsetFace.Bind(FI,OF);
+        myImageOffset.SetRoot(OF);
 #ifdef DRAW 
-       if (AffichInt2d) {
-         sprintf(name,"AF_%d",NbAF++);
-         DBRep::Set(name,OF);
-       }
+        if (AffichInt2d) {
+          sprintf(name,"AF_%d",NbAF++);
+          DBRep::Set(name,OF);
+        }
 #endif
-       const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
-       for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
-         const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
-         if (IMOE.HasImage(OE)) {
-           const TopTools_ListOfShape& LOE = IMOE.Image(OE);
-           TopTools_ListIteratorOfListOfShape itLOE(LOE);
-           for (; itLOE.More(); itLOE.Next()) {
-             TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
-             const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
-//           const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
-             myAsDes->Add(OF,COE);
+        const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
+        for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
+          const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
+          if (IMOE.HasImage(OE)) {
+            const TopTools_ListOfShape& LOE = IMOE.Image(OE);
+            TopTools_ListIteratorOfListOfShape itLOE(LOE);
+            for (; itLOE.More(); itLOE.Next()) {
+              TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
+              const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
+//              const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
+              myAsDes->Add(OF,COE);
 #ifdef DRAW
-             if (AffichInt2d) {
-               sprintf(name,"AE_%d",NbAE++);
-               DBRep::Set(name,COE);
-               COES.Add(COE);
-             }
+              if (AffichInt2d) {
+                sprintf(name,"AE_%d",NbAE++);
+                DBRep::Set(name,COE);
+                COES.Add(COE);
+              }
 #endif
-             
-             if (!myAsDes->HasDescendant(COE)) {
-               TopoDS_Vertex CV1,CV2;
-               TopExp::Vertices(COE,CV1,CV2);
-               if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
-               if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));     
-             }
-           }
-         }
-         else {
-           myAsDes->Add(OF,OE);
+              
+              if (!myAsDes->HasDescendant(COE)) {
+                TopoDS_Vertex CV1,CV2;
+                TopExp::Vertices(COE,CV1,CV2);
+                 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+                if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));        
+              }
+            }
+          }
+          else {
+            myAsDes->Add(OF,OE);
 #ifdef DRAW
-           if (AffichInt2d) {
-             sprintf(name,"AE_%d",NbAE++);
-             DBRep::Set(name,OE);
-             COES.Add(OE);
-           }
+            if (AffichInt2d) {
+              sprintf(name,"AE_%d",NbAE++);
+              DBRep::Set(name,OE);
+              COES.Add(OE);
+            }
 #endif
 
-           const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
-           myAsDes->Add(OE,LV);
-         }
-       }
+            const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
+            myAsDes->Add(OE,LV);
+          }
+        }*/
       }
     }
     else {
@@ -1236,26 +1894,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));        
+          }
+        }
       } 
     }
   }
@@ -1272,49 +1930,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);
+        }
       }
     }
   }
@@ -1330,38 +1988,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
       }
     }
@@ -1413,27 +2071,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);
@@ -1449,60 +2107,60 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
     if (Done.Add(E)) {
       const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
       if (Anc.Extent() == 2) {
-       const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
-       if (!L.IsEmpty() && L.First().Type() == OT) {
-         Standard_Real CurOffset = myOffset;
-         if ( myFaceOffset.IsBound(Anc.First()))
-           CurOffset = myFaceOffset(Anc.First());
-         TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
-         TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
-         aLocalShape = MapSF(Anc.Last()).Generated(E);
-         TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
-//       TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
-//       TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
-         // find if exits tangent edges in the original shape
-         TopoDS_Edge E1f, E1l;
-         TopoDS_Vertex V1f, V1l;
-         TopExp::Vertices(E,V1f,V1l);
-         TopTools_ListOfShape TangE;
-         myAnalyse.TangentEdges(E,V1f,TangE);
-         // find if the pipe on the tangent edges are soon created.
-         TopTools_ListIteratorOfListOfShape itl(TangE);
-         Standard_Boolean Find = Standard_False;
-         for ( ; itl.More() && !Find; itl.Next()) {
-           if ( MapSF.IsBound(itl.Value())) {
-             TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
-             E1f  = TopoDS::Edge(aLocalShape);
-//           E1f  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
-             Find = Standard_True;
-           }
-         }
-         TangE.Clear();
-         myAnalyse.TangentEdges(E,V1l,TangE);
-         // find if the pipe on the tangent edges are soon created.
-         itl.Initialize(TangE);
-         Find = Standard_False;
-         for ( ; itl.More() && !Find; itl.Next()) {
-           if ( MapSF.IsBound(itl.Value())) {
-             TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
-             E1l  = TopoDS::Edge(aLocalShape);
-//           E1l  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
-             Find = Standard_True;
-           }
-         }
-         BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
-         MapSF.Bind(E,OF);
-       }
+        const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
+        if (!L.IsEmpty() && L.First().Type() == OT) {
+          Standard_Real CurOffset = myOffset;
+          if ( myFaceOffset.IsBound(Anc.First()))
+            CurOffset = myFaceOffset(Anc.First());
+          TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
+          TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
+          aLocalShape = MapSF(Anc.Last()).Generated(E);
+          TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
+//          TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
+//          TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
+          // find if exits tangent edges in the original shape
+          TopoDS_Edge E1f, E1l;
+          TopoDS_Vertex V1f, V1l;
+          TopExp::Vertices(E,V1f,V1l);
+          TopTools_ListOfShape TangE;
+          myAnalyse.TangentEdges(E,V1f,TangE);
+          // find if the pipe on the tangent edges are soon created.
+          TopTools_ListIteratorOfListOfShape itl(TangE);
+          Standard_Boolean Find = Standard_False;
+          for ( ; itl.More() && !Find; itl.Next()) {
+            if ( MapSF.IsBound(itl.Value())) {
+              TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
+              E1f  = TopoDS::Edge(aLocalShape);
+//              E1f  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
+              Find = Standard_True;
+            }
+          }
+          TangE.Clear();
+          myAnalyse.TangentEdges(E,V1l,TangE);
+          // find if the pipe on the tangent edges are soon created.
+          itl.Initialize(TangE);
+          Find = Standard_False;
+          for ( ; itl.More() && !Find; itl.Next()) {
+            if ( MapSF.IsBound(itl.Value())) {
+              TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
+              E1l  = TopoDS::Edge(aLocalShape);
+//              E1l  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
+              Find = Standard_True;
+            }
+          }
+          BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
+          MapSF.Bind(E,OF);
+        }
       }
       else {
-       // ----------------------
-       // free border.
-       // ----------------------
-       TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
-       TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
-///    TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
+        // ----------------------
+        // free border.
+        // ----------------------
+        TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
+        TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
+///        TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
         myInitOffsetEdge.SetRoot(E); // skv: supporting history.
-       myInitOffsetEdge.Bind (E,EOn1);      
+        myInitOffsetEdge.Bind (E,EOn1);      
       }
     }
   }
@@ -1521,42 +2179,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));
+          }
+        
       }
     }
   }
@@ -1577,12 +2235,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);      
@@ -1591,27 +2249,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());
       }
     }
   }
@@ -1669,14 +2327,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);
       }  
     }
   }
@@ -1690,28 +2348,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);
+            }
+          }
+        }
       }
     }
   }
@@ -1740,26 +2398,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 {
@@ -1767,8 +2425,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);
@@ -1785,9 +2443,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);
     }
@@ -1829,7 +2487,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);
     }
   }
@@ -1983,7 +2641,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())
@@ -2192,12 +2850,10 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
   }
 }
 
-
 //=======================================================================
 //function : Intersection3D
 //purpose  : 
 //=======================================================================
-
 void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
 {
 #ifdef OCCT_DEBUG
@@ -2208,7 +2864,7 @@ void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
   }
 #endif
   TopTools_ListOfShape OffsetFaces;  // list of faces // created.
-  MakeList (OffsetFaces,myInitOffsetFace,myFaces);
+  MakeList (OffsetFaces, myInitOffsetFace, myFaces);
 
   if (!myFaces.IsEmpty()) {     
     Standard_Boolean InSide = (myOffset < 0.); // Temporary
@@ -2245,7 +2901,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) {
@@ -2301,8 +2957,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.
   //-----------------------------------------
@@ -2356,9 +3022,9 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
 //=======================================================================
 
 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();
@@ -2412,82 +3078,82 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
       TopoDS_Edge PrevEdge;
       TopoDS_Vertex PrevVertex = StartVertex;
       for (; itl.More(); itl.Next())
-       {
-         TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
-         if (!myInitOffsetEdge.HasImage(anEdge))
-           continue;
-         //if (BRep_Tool::Degenerated(anEdge))
-           //continue;
-         TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
-         //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
-         TopTools_ListOfShape LOE, LOE2;
-         myInitOffsetEdge.LastImage( anEdge, LOE );
-         myImageOffset.LastImage( LOE.Last(), LOE2 );
-         TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
-         ////////////////////////////////////////////////////////////////////////
-         TopoDS_Vertex V1, V2, V3, V4;
-         TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
-         TopExp::Vertices(OE,     V4, V3/*, Standard_True*/);
-         Standard_Boolean ToReverse = Standard_False;
-         if (!V1.IsSame(PrevVertex))
-           {
-             TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
-             aVtx = V3; V3 = V4; V4 = aVtx;
-             ToReverse = Standard_True;
-           }
-         //Temporary
-         //anEdge.Reverse();
-         OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
-         TopoDS_Edge E3, E4;
-         if (FirstStep)
-           {
-             E4 = BRepLib_MakeEdge( V1, V4 );
-             StartEdge = E4;
-           }
-         else
-           E4 = PrevEdge;
-         Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
-         if (V2.IsSame(StartVertex) && !ArcOnV2)
-           E3 = StartEdge;
-         else
-           E3 = BRepLib_MakeEdge( V2, V3 );
-         E4.Reverse();
-         TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
-         const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
-         Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
-         Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
-         BRep_Builder BB;
-         TopoDS_Wire theWire;
-         BB.MakeWire(theWire);
-         if (ToReverse)
-           {
-             BB.Add(theWire, anEdge.Reversed());
-             BB.Add(theWire, E3.Reversed());
-             BB.Add(theWire, OE.Reversed());
-             BB.Add(theWire, E4.Reversed());
-           }
-         else
-           {
-             BB.Add(theWire, anEdge);
-             BB.Add(theWire, E3);
-             BB.Add(theWire, OE);
-             BB.Add(theWire, E4);
-           }
-         BRepLib::BuildCurves3d( theWire, myTol );
-         theWire.Closed(Standard_True);
-         TopoDS_Face NewFace;
-         Handle(Geom_Surface) theSurf;
-         BRepAdaptor_Curve BAcurve(anEdge);
-         BRepAdaptor_Curve BAcurveOE(OE);
-         Standard_Real fpar = BAcurve.FirstParameter();
-         Standard_Real lpar = BAcurve.LastParameter();
-         gp_Pnt PonE  = BAcurve.Value(fpar);
-         gp_Pnt PonOE = BAcurveOE.Value(fpar);
-         gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
-         Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
-         Standard_Boolean IsPlanar = Standard_False;
-         if (BAcurve.GetType() == GeomAbs_Circle &&
-             BAcurveOE.GetType() == GeomAbs_Circle)
+        {
+          TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+          if (!myInitOffsetEdge.HasImage(anEdge))
+            continue;
+          //if (BRep_Tool::Degenerated(anEdge))
+            //continue;
+          TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
+          //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
+          TopTools_ListOfShape LOE, LOE2;
+          myInitOffsetEdge.LastImage( anEdge, LOE );
+          myImageOffset.LastImage( LOE.Last(), LOE2 );
+          TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
+          ////////////////////////////////////////////////////////////////////////
+          TopoDS_Vertex V1, V2, V3, V4;
+          TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
+          TopExp::Vertices(OE,     V4, V3/*, Standard_True*/);
+          Standard_Boolean ToReverse = Standard_False;
+          if (!V1.IsSame(PrevVertex))
+            {
+              TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
+              aVtx = V3; V3 = V4; V4 = aVtx;
+              ToReverse = Standard_True;
+            }
+          //Temporary
+          //anEdge.Reverse();
+          OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
+          TopoDS_Edge E3, E4;
+          if (FirstStep)
+            {
+              E4 = BRepLib_MakeEdge( V1, V4 );
+              StartEdge = E4;
+            }
+          else
+            E4 = PrevEdge;
+          Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
+          if (V2.IsSame(StartVertex) && !ArcOnV2)
+            E3 = StartEdge;
+          else
+            E3 = BRepLib_MakeEdge( V2, V3 );
+          E4.Reverse();
+          TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
+          const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
+          Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
+          Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
+          BRep_Builder BB;
+          TopoDS_Wire theWire;
+          BB.MakeWire(theWire);
+          if (ToReverse)
+            {
+              BB.Add(theWire, anEdge.Reversed());
+              BB.Add(theWire, E3.Reversed());
+              BB.Add(theWire, OE.Reversed());
+              BB.Add(theWire, E4.Reversed());
+            }
+          else
+            {
+              BB.Add(theWire, anEdge);
+              BB.Add(theWire, E3);
+              BB.Add(theWire, OE);
+              BB.Add(theWire, E4);
+            }
+          BRepLib::BuildCurves3d( theWire, myTol );
+          theWire.Closed(Standard_True);
+          TopoDS_Face NewFace;
+          Handle(Geom_Surface) theSurf;
+          BRepAdaptor_Curve BAcurve(anEdge);
+          BRepAdaptor_Curve BAcurveOE(OE);
+          Standard_Real fpar = BAcurve.FirstParameter();
+          Standard_Real lpar = BAcurve.LastParameter();
+          gp_Pnt PonE  = BAcurve.Value(fpar);
+          gp_Pnt PonOE = BAcurveOE.Value(fpar);
+          gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
+          Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
+          Standard_Boolean IsPlanar = Standard_False;
+          if (BAcurve.GetType() == GeomAbs_Circle &&
+              BAcurveOE.GetType() == GeomAbs_Circle)
           {
             gp_Circ aCirc = BAcurve.Circle();
             gp_Circ aCircOE = BAcurveOE.Circle();
@@ -2597,175 +3263,239 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
               }
             } //cylinder or cone
           } //if both edges are arcs of circles
-         if (NewFace.IsNull())
-           {
-             BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
-             if (MF.Error() == BRepLib_FaceDone)
-               {
-                 NewFace = MF.Face();
-                 IsPlanar = Standard_True;
-               }
-             else //Extrusion (by thrusections)
-               {
-                 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
-                 Handle(Geom_TrimmedCurve) TrEdgeCurve =
-                   new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
-                 Standard_Real fparOE, lparOE;
-                 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
-                 Handle(Geom_TrimmedCurve) TrOffsetCurve =
-                   new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
-                 GeomFill_Generator ThrusecGenerator;
-                 ThrusecGenerator.AddCurve( TrEdgeCurve );
-                 ThrusecGenerator.AddCurve( TrOffsetCurve );
-                 ThrusecGenerator.Perform( Precision::PConfusion() );
-                 theSurf = ThrusecGenerator.Surface();
-                 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
-                 Standard_Real Uf, Ul, Vf, Vl;
-                 theSurf->Bounds(Uf, Ul, Vf, Vl);
-                 TopLoc_Location Loc;
-                 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
-                 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
-                 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
-                 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
-                 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
-                 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
-                 aLine2d  = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
-                 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
-                 if (E3.IsSame(E4))
-                   {
-                     BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
-                     Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
-                     BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
-                     BB.Range(E3, Vf, Vl);
-                   }
-                 else
-                   {
-                     BB.SameParameter(E3, Standard_False);
-                     BB.SameRange(E3, Standard_False);
-                     BB.SameParameter(E4, Standard_False);
-                     BB.SameRange(E4, Standard_False);
-                     BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
-                     BB.Range(E3, theSurf, Loc, Vf, Vl);
-                     BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
-                     BB.Range(E4, theSurf, Loc, Vf, Vl);
-                     Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
-                     BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
-                     BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
-                     Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
-                     BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
-                     BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
-                   }
-                 NewFace = BRepLib_MakeFace(theSurf, theWire);
-               }
-           }
-         if (!IsPlanar)
-           {
-             Standard_Real fparOE = BAcurveOE.FirstParameter();
-             Standard_Real lparOE = BAcurveOE.LastParameter();
-             TopLoc_Location Loc;
-             if (Abs(fpar - fparOE) > Precision::Confusion())
-               {
-                 const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
-                 gp_Pnt2d fp2d   = EdgeLine2d->Value(fpar);
-                 gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
-                 aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
-                 Handle(Geom_Curve) aCurve;
-                 Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
-                 Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
-                 GeomAdaptor_Surface GAsurf( theSurf );
-                 Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
-                 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
-                 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
-                 Standard_Real max_deviation = 0., average_deviation;
-                 GeomLib::BuildCurve3d(Precision::Confusion(),
-                                       ConS, FirstPar, LastPar,
-                                       aCurve, max_deviation, average_deviation);
-                 BB.UpdateEdge( anE4, aCurve, max_deviation );
-                 BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
-                 BB.Range( anE4, FirstPar, LastPar );
-               }
-             if (Abs(lpar - lparOE) > Precision::Confusion())
-               {
-                 const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
-                 gp_Pnt2d lp2d   = EdgeLine2d->Value(lpar);
-                 gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
-                 aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
-                 Handle(Geom_Curve) aCurve;
-                 Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
-                 Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
-                 GeomAdaptor_Surface GAsurf( theSurf );
-                 Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
-                 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
-                 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
-                 Standard_Real max_deviation = 0., average_deviation;
-                 GeomLib::BuildCurve3d(Precision::Confusion(),
-                                       ConS, FirstPar, LastPar,
-                                       aCurve, max_deviation, average_deviation);
-                 BB.UpdateEdge( anE3, aCurve, max_deviation );
-                 BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
-                 BB.Range( anE3, FirstPar, LastPar );
-               }
-           }
-         BRepLib::SameParameter(NewFace);
-         BRepTools::Update(NewFace);
-         myWalls.Append(NewFace);
-         if (ArcOnV2)
-           {
-             TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
-             TopoDS_Vertex arcV1, arcV2;
-             TopExp::Vertices(anArc, arcV1, arcV2);
-             Standard_Boolean ArcReverse = Standard_False;
-             if (!arcV1.IsSame(V3))
-               {
-                 TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
-                 ArcReverse = Standard_True;
-               }
-             TopoDS_Edge EA1, EA2;
-             //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
-             EA1 = E3;
-             EA1.Reverse();
-             if (ToReverse)
-               EA1.Reverse();
-             //////////////////////////////////////////////////////
-             if (V2.IsSame(StartVertex))
-               EA2 = StartEdge;
-             else
-               EA2 = BRepLib_MakeEdge( V2, arcV2 );
-             anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
-             if (EA1.Orientation() == TopAbs_REVERSED)
-               anArc.Reverse();
-             EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
-             TopoDS_Wire arcWire;
-             BB.MakeWire(arcWire);
-             BB.Add(arcWire, EA1);
-             BB.Add(arcWire, anArc);
-             BB.Add(arcWire, EA2);
-             BRepLib::BuildCurves3d( arcWire, myTol );
-             arcWire.Closed(Standard_True);
-             TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
-             BRepTools::Update(arcFace);
-             myWalls.Append(arcFace);
-             TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
-             const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
-             PrevEdge = CEA2;
-             PrevVertex = V2;
-           }
-         else
-           {
-             PrevEdge = E3;
-             PrevVertex = V2;
-           }
-         FirstStep = Standard_False;
-       }
+          if (NewFace.IsNull())
+            {
+              BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
+              if (MF.Error() == BRepLib_FaceDone)
+                {
+                  NewFace = MF.Face();
+                  IsPlanar = Standard_True;
+                }
+              else //Extrusion (by thrusections)
+                {
+                  Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
+                  Handle(Geom_TrimmedCurve) TrEdgeCurve =
+                    new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
+                  Standard_Real fparOE, lparOE;
+                  Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
+                  Handle(Geom_TrimmedCurve) TrOffsetCurve =
+                    new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
+                  GeomFill_Generator ThrusecGenerator;
+                  ThrusecGenerator.AddCurve( TrEdgeCurve );
+                  ThrusecGenerator.AddCurve( TrOffsetCurve );
+                  ThrusecGenerator.Perform( Precision::PConfusion() );
+                  theSurf = ThrusecGenerator.Surface();
+                  //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
+                  Standard_Real Uf, Ul, Vf, Vl;
+                  theSurf->Bounds(Uf, Ul, Vf, Vl);
+                  TopLoc_Location Loc;
+                  EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
+                  BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
+                  OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
+                  BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
+                  Standard_Real UonV1 = (ToReverse)? Ul : Uf;
+                  Standard_Real UonV2 = (ToReverse)? Uf : Ul;
+                  aLine2d  = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
+                  aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
+                  if (E3.IsSame(E4))
+                    {
+                      BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
+                      Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
+                      BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
+                      BB.Range(E3, Vf, Vl);
+                    }
+                  else
+                    {
+                      BB.SameParameter(E3, Standard_False);
+                      BB.SameRange(E3, Standard_False);
+                      BB.SameParameter(E4, Standard_False);
+                      BB.SameRange(E4, Standard_False);
+                      BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
+                      BB.Range(E3, theSurf, Loc, Vf, Vl);
+                      BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
+                      BB.Range(E4, theSurf, Loc, Vf, Vl);
+                      Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
+                      BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
+                      BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
+                      Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
+                      BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
+                      BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
+                    }
+                  NewFace = BRepLib_MakeFace(theSurf, theWire);
+                }
+            }
+          if (!IsPlanar)
+            {
+              Standard_Real fparOE = BAcurveOE.FirstParameter();
+              Standard_Real lparOE = BAcurveOE.LastParameter();
+              TopLoc_Location Loc;
+              if (Abs(fpar - fparOE) > Precision::Confusion())
+                {
+                  const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
+                  gp_Pnt2d fp2d   = EdgeLine2d->Value(fpar);
+                  gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
+                  aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
+                  Handle(Geom_Curve) aCurve;
+                  Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
+                  Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
+                  GeomAdaptor_Surface GAsurf( theSurf );
+                  Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
+                  Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
+                  Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
+                  Standard_Real max_deviation = 0., average_deviation;
+                  GeomLib::BuildCurve3d(Precision::Confusion(),
+                                        ConS, FirstPar, LastPar,
+                                        aCurve, max_deviation, average_deviation);
+                  BB.UpdateEdge( anE4, aCurve, max_deviation );
+                  BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
+                  BB.Range( anE4, FirstPar, LastPar );
+                }
+              if (Abs(lpar - lparOE) > Precision::Confusion())
+                {
+                  const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
+                  gp_Pnt2d lp2d   = EdgeLine2d->Value(lpar);
+                  gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
+                  aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
+                  Handle(Geom_Curve) aCurve;
+                  Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
+                  Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
+                  GeomAdaptor_Surface GAsurf( theSurf );
+                  Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
+                  Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
+                  Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
+                  Standard_Real max_deviation = 0., average_deviation;
+                  GeomLib::BuildCurve3d(Precision::Confusion(),
+                                        ConS, FirstPar, LastPar,
+                                        aCurve, max_deviation, average_deviation);
+                  BB.UpdateEdge( anE3, aCurve, max_deviation );
+                  BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
+                  BB.Range( anE3, FirstPar, LastPar );
+                }
+            }
+          BRepLib::SameParameter(NewFace);
+          BRepTools::Update(NewFace);
+          myWalls.Append(NewFace);
+          if (ArcOnV2)
+            {
+              TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
+              TopoDS_Vertex arcV1, arcV2;
+              TopExp::Vertices(anArc, arcV1, arcV2);
+              Standard_Boolean ArcReverse = Standard_False;
+              if (!arcV1.IsSame(V3))
+                {
+                  TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
+                  ArcReverse = Standard_True;
+                }
+              TopoDS_Edge EA1, EA2;
+              //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
+              EA1 = E3;
+              EA1.Reverse();
+              if (ToReverse)
+                EA1.Reverse();
+              //////////////////////////////////////////////////////
+              if (V2.IsSame(StartVertex))
+                EA2 = StartEdge;
+              else
+                EA2 = BRepLib_MakeEdge( V2, arcV2 );
+              anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
+              if (EA1.Orientation() == TopAbs_REVERSED)
+                anArc.Reverse();
+              EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
+              TopoDS_Wire arcWire;
+              BB.MakeWire(arcWire);
+              BB.Add(arcWire, EA1);
+              BB.Add(arcWire, anArc);
+              BB.Add(arcWire, EA2);
+              BRepLib::BuildCurves3d( arcWire, myTol );
+              arcWire.Closed(Standard_True);
+              TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
+              BRepTools::Update(arcFace);
+              myWalls.Append(arcFace);
+              TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
+              const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
+              PrevEdge = CEA2;
+              PrevVertex = V2;
+            }
+          else
+            {
+              PrevEdge = E3;
+              PrevVertex = V2;
+            }
+          FirstStep = Standard_False;
+        }
     }
 }
 
 //=======================================================================
-//function : MakeShells
+//function : CheckNormals
 //purpose  : 
 //=======================================================================
+static 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;
+}
 
-void BRepOffset_MakeOffset::MakeShells ()
+//=======================================================================
+//function : MakeShells
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffset::MakeShells()
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {  
@@ -2774,30 +3504,165 @@ void BRepOffset_MakeOffset::MakeShells ()
     Clock.Start();
   }
 #endif
-  BRepTools_Quilt Glue;
+
+  //if ((myJoin == GeomAbs_Intersection) && myInter) {
+  //
+  // make shells using MakerVolume algorithm
+  //
+  TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
+  //
+  BOPCol_ListOfShape aLSF;
   const TopTools_ListOfShape& R = myImageOffset.Roots();
   TopTools_ListIteratorOfListOfShape it(R);
-
-  for ( ; it.More(); it.Next()) {
+  //
+  for (; it.More(); it.Next()) {
     TopTools_ListOfShape Image;
     myImageOffset.LastImage(it.Value(),Image);
     TopTools_ListIteratorOfListOfShape it2(Image);
-    for ( ; it2.More(); it2.Next()) {
-      Glue.Add(it2.Value());
+    for (; it2.More(); it2.Next()) {
+      const TopoDS_Shape& aF = it2.Value();
+      aLSF.Append(aF);
+      //
+      if (anOrigins.Contains(aF)) {
+        anOrigins.ChangeFromKey(aF).Append(it.Value());
+      } 
+      else {
+        TopTools_ListOfShape aLOr;
+        aLOr.Append(it.Value());
+        anOrigins.Add(aF, aLOr);
+      }
     }
   }
-
-  if (myThickening)
-    {
-      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());
+  //
+  if (myThickening) {
+    TopExp_Explorer Explo(myShape, TopAbs_FACE);
+    for (; Explo.More(); Explo.Next()) {
+      const TopoDS_Shape& aF = Explo.Current();
+      aLSF.Append(aF);
     }
-
-  myOffsetShape = Glue.Shells();
+    //
+    it.Initialize(myWalls);
+    for (; it.More(); it.Next()) {
+      const TopoDS_Shape& aF = it.Value();
+      aLSF.Append(aF);
+    }
+  }
+  //
+  Standard_Boolean bDone = Standard_False;
+  // build all possible solids
+  /*if (!myThickening && !myFaces.IsEmpty()) {
+    TopExp_Explorer Explo(myShape, TopAbs_FACE);
+    for (; Explo.More(); Explo.Next()) {
+      const TopoDS_Shape& aF = Explo.Current();
+      aLSF.Append(aF);
+    }
+  }*/
+  //
+  if ((myJoin == GeomAbs_Intersection) && myInter) {
+    Standard_Integer i, aNb;
+    TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
+    //
+    BOPAlgo_Builder aGF;
+    //
+    aGF.SetArguments(aLSF);
+    aGF.Perform();
+    if (aGF.ErrorStatus() == 0) {
+      const TopoDS_Shape& aR = aGF.Shape();
+      TopExp_Explorer aExp(aR, TopAbs_FACE);
+      aLSF.Clear();
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Shape& aF = aExp.Current();
+        aLSF.Append(aF);
+      }
+      //
+      UpdateOrigins(anOrigins, aGF);
+    }
+    //
+    if (myFaces.IsEmpty()) {
+      BOPAlgo_MakerVolume aMV1;
+      //
+      aMV1.SetArguments(aLSF);
+      aMV1.SetIntersect(Standard_False);
+      //
+      aMV1.Perform();
+      bDone = (aMV1.ErrorStatus() == 0);
+      if (bDone) {
+        TopoDS_Compound aShells;
+        BRep_Builder aBB;
+        //
+        aBB.MakeCompound(aShells);
+        //
+        TopoDS_Shape aResult = aMV1.Shape();
+        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 TopoDS_Shape& aFx = aMFS.FindKey(i);
+              const BOPCol_ListOfShape& aLSx = aMFS(i);
+              if (aLSx.Extent() == 1) {
+                // check orientation
+                const TopoDS_Face& aF = *(TopoDS_Face*)&aFx;
+                if (!anOrigins.Contains(aF)) {
+                  aLSF2.Append(aFx);
+                  continue;
+                }
+                //
+                const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx);
+                aItLS.Initialize(aLFOr);
+                for (; aItLS.More(); aItLS.Next()) {
+                  const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
+                  //
+                  if (CheckNormals(aF, aFOr)) {
+                    aLSF2.Append(aFx);
+                    break;
+                  }
+                }
+              }
+            }
+            //
+            // make solid containing most outer faces
+            BOPAlgo_MakerVolume aMV2;
+            //
+            aMV2.SetArguments(aLSF2);
+            aMV2.SetIntersect(Standard_False);
+            //
+            aMV2.Perform();
+            bDone = (aMV2.ErrorStatus() == 0);
+            if (bDone) {
+              aResult = aMV2.Shape();
+            }
+          }
+        }
+        //
+        TopExp_Explorer aExp(aResult, TopAbs_SHELL);
+        bDone = aExp.More();
+        for (; aExp.More(); aExp.Next()) {
+          const TopoDS_Shape& aSh = 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();
+  }
 }
 
 //=======================================================================
@@ -2862,7 +3727,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);                       
       }
     }  
   }
@@ -2974,38 +3839,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;
     }
@@ -3024,32 +3889,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) {
@@ -3057,42 +3922,42 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
     //  the initial shape, they will be tangent in the offset shape
       TopTools_ListOfShape LE,LV;
       BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
-                                      TopoDS::Face(Root2),
-                                      LE,LV);
+                                       TopoDS::Face(Root2),
+                                       LE,LV);
       if ( LE.Extent() == 1) { 
-       const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
-       if ( myAnalyse.HasAncestor(Ed)) {
-         const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
-         if (LI.Extent()       == 1   && 
-             LI.First().Type() == BRepOffset_Tangent) {
-           B.Continuity(OE,F1,F2,GeomAbs_G1);
-         }
-       }
+        const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
+        if ( myAnalyse.HasAncestor(Ed)) {
+          const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
+          if (LI.Extent()       == 1   && 
+              LI.First().Type() == BRepOffset_Tangent) {
+            B.Continuity(OE,F1,F2,GeomAbs_G1);
+          }
+        }
       }
     }
     else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
       TopTools_ListOfShape LV;
       TopExp_Explorer exp1,exp2;
       for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
-       TopExp_Explorer exp2(F2,TopAbs_EDGE);
-       for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
-         if (exp1.Current().IsSame(exp2.Current())) {
-           LV.Append(exp1.Current());
-         }
-       }
+        TopExp_Explorer exp2(F2,TopAbs_EDGE);
+        for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
+          if (exp1.Current().IsSame(exp2.Current())) {
+            LV.Append(exp1.Current());
+          }
+        }
       }
       if ( LV.Extent() == 1) {
-       TopTools_ListOfShape LEdTg;
-       myAnalyse.TangentEdges(TopoDS::Edge(Root1),
-                              TopoDS::Vertex(LV.First()),
-                              LEdTg);
-       TopTools_ListIteratorOfListOfShape it(LEdTg);
-       for (; it.More(); it.Next()) {
-         if ( it.Value().IsSame(Root2)) {
-           B.Continuity(OE,F1,F2,GeomAbs_G1);
-           break;
-         }
-       }
+        TopTools_ListOfShape LEdTg;
+        myAnalyse.TangentEdges(TopoDS::Edge(Root1),
+                               TopoDS::Vertex(LV.First()),
+                               LEdTg);
+        TopTools_ListIteratorOfListOfShape it(LEdTg);
+        for (; it.More(); it.Next()) {
+          if ( it.Value().IsSame(Root2)) {
+            B.Continuity(OE,F1,F2,GeomAbs_G1);
+            break;
+          }
+        }
       }
     }
   }
@@ -3110,7 +3975,7 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
 //=======================================================================
 
 static void UpdateTolerance (TopoDS_Shape& S,
-                            const TopTools_IndexedMapOfShape& Faces)
+                             const TopTools_IndexedMapOfShape& Faces)
 {
   BRep_Builder B;
   TopTools_MapOfShape View;
@@ -3138,15 +4003,15 @@ static 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);
       }
     }
   }