]> OCCT Git - occt-copy.git/commitdiff
0032098: Bad tolerance of result of BRepOffset_MakeOffset CR32098
authorjgv <jgv@opencascade.com>
Fri, 20 Nov 2020 04:10:19 +0000 (07:10 +0300)
committerjgv <jgv@opencascade.com>
Fri, 29 Jan 2021 13:55:50 +0000 (16:55 +0300)
Some changes in BRepOffset_MakeOffset

108 files changed:
src/BRepAlgo/BRepAlgo_Loop.cxx
src/BRepAlgo/BRepAlgo_Loop.hxx
src/BRepOffset/BRepOffset_Analyse.cxx
src/BRepOffset/BRepOffset_Analyse.hxx
src/BRepOffset/BRepOffset_DataMapOfFaceMapEE.hxx [new file with mode: 0644]
src/BRepOffset/BRepOffset_Inter2d.cxx
src/BRepOffset/BRepOffset_Inter2d.hxx
src/BRepOffset/BRepOffset_Inter3d.cxx
src/BRepOffset/BRepOffset_Inter3d.hxx
src/BRepOffset/BRepOffset_MakeLoops.cxx
src/BRepOffset/BRepOffset_MakeLoops.hxx
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepOffset/BRepOffset_MakeOffset.hxx
src/BRepOffset/BRepOffset_MakeOffset_1.cxx
src/BRepOffset/BRepOffset_SequenceOfIndexedMapOfShape.hxx [new file with mode: 0644]
src/BRepOffset/BRepOffset_Tool.cxx
src/BRepOffset/BRepOffset_Tool.hxx
src/BRepOffset/FILES
src/BRepTest/BRepTest_FeatureCommands.cxx
src/BiTgte/BiTgte_Blend.cxx
src/Geom/Geom_OffsetSurface.cxx
src/QABugs/QABugs_20.cxx
tests/bugs/modalg_7/bug31735_1 [deleted file]
tests/bugs/modalg_7/bug31735_2 [deleted file]
tests/offset/bugs/bug27913
tests/offset/bugs/bug31735_1 [new file with mode: 0644]
tests/offset/bugs/bug31735_2 [new file with mode: 0644]
tests/offset/bugs/bug31845_1 [new file with mode: 0644]
tests/offset/bugs/bug31845_2 [new file with mode: 0644]
tests/offset/bugs/bug31845_3 [new file with mode: 0644]
tests/offset/bugs/bug31845_4 [new file with mode: 0644]
tests/offset/bugs/bug31845_f [new file with mode: 0644]
tests/offset/bugs/bug31845_h [new file with mode: 0644]
tests/offset/bugs/bug31845_i [new file with mode: 0644]
tests/offset/compshape/A1
tests/offset/compshape/A4
tests/offset/faces_type_i/C8
tests/offset/faces_type_i/D4
tests/offset/shape/A1
tests/offset/shape_type_i/A5
tests/offset/shape_type_i/A7
tests/offset/shape_type_i/A9
tests/offset/shape_type_i/B2
tests/offset/shape_type_i/B4
tests/offset/shape_type_i/B6
tests/offset/shape_type_i/B7
tests/offset/shape_type_i/B8
tests/offset/shape_type_i/C7
tests/offset/shape_type_i/C8
tests/offset/with_intersect_20/C4
tests/offset/with_intersect_20/G7
tests/offset/with_intersect_20/L3
tests/offset/with_intersect_20/L4
tests/offset/with_intersect_20/L6
tests/offset/with_intersect_20/L9
tests/offset/with_intersect_20/M5
tests/offset/with_intersect_20/M9
tests/offset/with_intersect_20/N1
tests/offset/with_intersect_80/B5
tests/offset/with_intersect_80/D2
tests/offset/with_intersect_80/D3
tests/offset/with_intersect_80/D4
tests/offset/with_intersect_80/D5
tests/offset/with_intersect_80/D6
tests/offset/with_intersect_80/D7
tests/offset/with_intersect_80/D9
tests/offset/with_intersect_80/E4
tests/offset/with_intersect_80/F2
tests/offset/with_intersect_80/F4
tests/offset/with_intersect_80/F5
tests/offset/with_intersect_80/F6
tests/offset/with_intersect_80/F7
tests/offset/with_intersect_80/F8
tests/offset/with_intersect_80/F9
tests/offset/with_intersect_80/G1
tests/offset/with_intersect_80/G2
tests/offset/with_intersect_80/G4
tests/offset/with_intersect_80/G6
tests/offset/with_intersect_80/G9
tests/offset/with_intersect_80/H3
tests/offset/with_intersect_80/H6
tests/offset/with_intersect_80/I6
tests/offset/with_intersect_80/I8
tests/offset/with_intersect_80/J2
tests/offset/with_intersect_80/J3
tests/offset/with_intersect_80/J4
tests/offset/with_intersect_80/K1
tests/offset/with_intersect_80/K2
tests/offset/with_intersect_80/L1
tests/offset/with_intersect_80/L2
tests/offset/with_intersect_80/L3
tests/offset/with_intersect_80/L4
tests/offset/with_intersect_80/L5
tests/offset/with_intersect_80/L6
tests/offset/with_intersect_80/L7
tests/offset/with_intersect_80/L8
tests/offset/with_intersect_80/L9
tests/offset/with_intersect_80/M1
tests/offset/with_intersect_80/M3
tests/offset/with_intersect_80/M4
tests/offset/with_intersect_80/M5
tests/offset/with_intersect_80/M6
tests/offset/with_intersect_80/M7
tests/offset/with_intersect_80/M8
tests/offset/with_intersect_80/M9
tests/offset/with_intersect_80/N1
tests/offset/with_intersect_80/N5
tests/offset/with_intersect_80/N7

index f79b096f7941e5a3da0512f435cf99a6d2928cfb..f80e64e8a441e673148186786c5a6cecb8686cd4 100644 (file)
@@ -74,6 +74,7 @@ void BRepAlgo_Loop::Init(const TopoDS_Face& F)
 {
   myConstEdges.Clear(); 
   myEdges     .Clear();
+  myNewEdges     .Clear();
   myVerOnEdges.Clear();
   myNewWires  .Clear();
   myNewFaces  .Clear();
@@ -140,7 +141,7 @@ void BRepAlgo_Loop::AddEdge (TopoDS_Edge&                E,
 
 
 //=======================================================================
-//function : AddConstEdges
+//function : AddConstEdge
 //purpose  : 
 //=======================================================================
 
@@ -149,6 +150,16 @@ void BRepAlgo_Loop::AddConstEdge (const TopoDS_Edge& E)
   myConstEdges.Append(E);
 }
 
+//=======================================================================
+//function : AddNewEdge
+//purpose  : 
+//=======================================================================
+
+void BRepAlgo_Loop::AddNewEdge (const TopoDS_Edge& theEdge)
+{
+  myNewEdges.Append(theEdge);
+}
+
 //=======================================================================
 //function : AddConstEdges
 //purpose  : 
@@ -429,64 +440,66 @@ static void StoreInMVE (const TopoDS_Face&                  F,
                        TopoDS_Edge&                  E,
                        TopTools_IndexedDataMapOfShapeListOfShape& MVE,
                        Standard_Boolean&                   YaCouture,
-                       TopTools_DataMapOfShapeShape& VerticesForSubstitute )
+                       TopTools_DataMapOfShapeShape& /*VerticesForSubstitute*/ )
 {      
   TopoDS_Vertex V1, V2, V;
   TopTools_ListOfShape Empty;
-  
+
+  /*
   Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
 //  gp_Pnt P1, P2, P;
   gp_Pnt P1, P;
   BRep_Builder BB;
   for (Standard_Integer iV = 1; iV <= MVE.Extent(); iV++)
+  {
+    V = TopoDS::Vertex(MVE.FindKey(iV));
+    P = BRep_Tool::Pnt( V );
+    TopTools_ListOfShape VList;
+    TopoDS_Iterator VerExp( E );
+    for (; VerExp.More(); VerExp.Next())
+      VList.Append( VerExp.Value() );
+    TopTools_ListIteratorOfListOfShape itl( VList );
+    for (; itl.More(); itl.Next())
     {
-      V = TopoDS::Vertex(MVE.FindKey(iV));
-      P = BRep_Tool::Pnt( V );
-      TopTools_ListOfShape VList;
-      TopoDS_Iterator VerExp( E );
-      for (; VerExp.More(); VerExp.Next())
-       VList.Append( VerExp.Value() );
-      TopTools_ListIteratorOfListOfShape itl( VList );
-      for (; itl.More(); itl.Next())
-       {
-         V1 = TopoDS::Vertex( itl.Value() );
-         P1 = BRep_Tool::Pnt( V1 );
-         if (P.IsEqual( P1, Tol ) && !V.IsSame(V1))
-           {
-             V.Orientation( V1.Orientation() );
-             if (VerticesForSubstitute.IsBound( V1 ))
-               {
-                 TopoDS_Shape OldNewV = VerticesForSubstitute( V1 );
-                 if (! OldNewV.IsSame( V ))
-                   {
-                     VerticesForSubstitute.Bind( OldNewV, V );
-                     VerticesForSubstitute( V1 ) = V;
-                   }
-               }
-             else
-               {
-                 if (VerticesForSubstitute.IsBound( V ))
-                   {
-                     TopoDS_Shape NewNewV = VerticesForSubstitute( V );
-                     if (! NewNewV.IsSame( V1 ))
-                       VerticesForSubstitute.Bind( V1, NewNewV );
-                   }
-                 else
-                   {
-                     VerticesForSubstitute.Bind( V1, V );
-                     TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( VerticesForSubstitute );
-                     for (; mapit.More(); mapit.Next())
-                       if (mapit.Value().IsSame( V1 ))
-                         VerticesForSubstitute( mapit.Key() ) = V;
-                   }
-               }
-             E.Free( Standard_True );
-             BB.Remove( E, V1 );
-             BB.Add( E, V );
-           }
-       }
+      V1 = TopoDS::Vertex( itl.Value() );
+      P1 = BRep_Tool::Pnt( V1 );
+      if (P.IsEqual( P1, Tol ) && !V.IsSame(V1))
+      {
+        V.Orientation( V1.Orientation() );
+        if (VerticesForSubstitute.IsBound( V1 ))
+        {
+          TopoDS_Shape OldNewV = VerticesForSubstitute( V1 );
+          if (! OldNewV.IsSame( V ))
+          {
+            VerticesForSubstitute.Bind( OldNewV, V );
+            VerticesForSubstitute( V1 ) = V;
+          }
+        }
+        else
+        {
+          if (VerticesForSubstitute.IsBound( V ))
+          {
+            TopoDS_Shape NewNewV = VerticesForSubstitute( V );
+            if (! NewNewV.IsSame( V1 ))
+              VerticesForSubstitute.Bind( V1, NewNewV );
+          }
+          else
+          {
+            VerticesForSubstitute.Bind( V1, V );
+            TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( VerticesForSubstitute );
+            for (; mapit.More(); mapit.Next())
+              if (mapit.Value().IsSame( V1 ))
+                VerticesForSubstitute( mapit.Key() ) = V;
+          }
+        }
+        E.Free( Standard_True );
+        BB.Remove( E, V1 );
+        BB.Add( E, V );
+      }
     }
-
+  }
+  */
+  
   TopExp::Vertices(E,V1,V2);
   if( V1.IsNull() && V2.IsNull() ){ YaCouture = Standard_False; return; }
   if (!MVE.Contains(V1)) {
@@ -494,10 +507,10 @@ static void StoreInMVE (const TopoDS_Face&                  F,
   }
   MVE.ChangeFromKey(V1).Append(E);
   if (!V1.IsSame(V2)) {
-     if (!MVE.Contains(V2)) {
-       MVE.Add(V2,Empty);
-     }
-     MVE.ChangeFromKey(V2).Append(E);
+    if (!MVE.Contains(V2)) {
+      MVE.Add(V2,Empty);
+    }
+    MVE.ChangeFromKey(V2).Append(E);
   }
   TopLoc_Location L ;
   Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
@@ -546,51 +559,67 @@ void BRepAlgo_Loop::Perform()
     }
   }
 #endif
-  //------------------------------------------------
-  // Cut edges
-  //------------------------------------------------
-  for (itl.Initialize(myEdges); itl.More(); itl.Next())
+
+  TopTools_IndexedDataMapOfShapeListOfShape MVE;
+  
+  if (myNewEdges.IsEmpty())
   {
-    const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
-    TopTools_ListOfShape LCE;
-    const TopTools_ListOfShape* pVertices = myVerOnEdges.Seek (anEdge);
-    if (pVertices)
+    //------------------------------------------------
+    // Cut edges
+    //------------------------------------------------
+    for (itl.Initialize(myEdges); itl.More(); itl.Next())
     {
-      CutEdge (anEdge, *pVertices, LCE);
-      myCutEdges.Bind(anEdge, LCE);
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+      TopTools_ListOfShape LCE;
+      const TopTools_ListOfShape* pVertices = myVerOnEdges.Seek (anEdge);
+      if (pVertices)
+      {
+        CutEdge (anEdge, *pVertices, LCE);
+        myCutEdges.Bind(anEdge, LCE);
+      }
     }
-  }
-  //-----------------------------------
-  // Construction map vertex => edges
-  //-----------------------------------
-  TopTools_IndexedDataMapOfShapeListOfShape MVE;
-
-  // add cut edges.
-  TopTools_MapOfShape Emap;
-  for (itl.Initialize(myEdges); itl.More(); itl.Next())
-  {
-    const TopTools_ListOfShape* pLCE = myCutEdges.Seek (itl.Value());
-    if (pLCE)
+    //-----------------------------------
+    // Construction map vertex => edges
+    //-----------------------------------
+    
+    // add cut edges.
+    TopTools_MapOfShape Emap;
+    for (itl.Initialize(myEdges); itl.More(); itl.Next())
     {
-      for (itl1.Initialize(*pLCE); itl1.More(); itl1.Next()) {
-        TopoDS_Edge& E = TopoDS::Edge(itl1.Value());
-        if (!Emap.Add(E))
-          continue;
-        StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
+      const TopTools_ListOfShape* pLCE = myCutEdges.Seek (itl.Value());
+      if (pLCE)
+      {
+        for (itl1.Initialize(*pLCE); itl1.More(); itl1.Next()) {
+          TopoDS_Edge& E = TopoDS::Edge(itl1.Value());
+          if (!Emap.Add(E))
+            continue;
+          StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
+        }
       }
     }
+    
+    // add const edges
+    // Sewn edges can be doubled or not in myConstEdges
+    // => call only once StoreInMVE which should double them
+    TopTools_MapOfShape DejaVu;
+    for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
+      TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+      if (DejaVu.Add(E))
+        StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
+    }
+  } //if (myNewEdges.IsEmpty())
+  else
+  {
+    TopTools_MapOfShape Emap;
+    for (itl.Initialize(myNewEdges); itl.More(); itl.Next())
+    {
+      TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+      if (!Emap.Add(anEdge))
+        continue;
+      StoreInMVE(myFace,anEdge,MVE,YaCouture,myVerticesForSubstitute);
+    }
   }
   
-  // add const edges
-  // Sewn edges can be doubled or not in myConstEdges
-  // => call only once StoreInMVE which should double them
-  TopTools_MapOfShape DejaVu;
-  for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
-    TopoDS_Edge& E = TopoDS::Edge(itl.Value());
-    if (DejaVu.Add(E))
-      StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
-  }
-
 #ifdef DRAW
   if (AffichLoop) {
     std::cout <<"NewLoop"<<std::endl;
@@ -711,22 +740,22 @@ void BRepAlgo_Loop::Perform()
 #endif
   }
   
-  PurgeNewEdges(myCutEdges,UsedEdges);
+  //PurgeNewEdges(myCutEdges,UsedEdges);
 }
 
 //=======================================================================
-//function : CutEdges
+//function : CutEdge
 //purpose  : 
 //=======================================================================
 
 void BRepAlgo_Loop::CutEdge (const TopoDS_Edge&          E,
                             const TopTools_ListOfShape& VOnE,
-                                    TopTools_ListOfShape& NE   ) const 
+                             TopTools_ListOfShape& NE   ) const 
 {
   TopoDS_Shape aLocalE  = E.Oriented(TopAbs_FORWARD);
   TopoDS_Edge WE = TopoDS::Edge(aLocalE);
 
-  Standard_Real                      U1,U2;
+  //Standard_Real                      U1,U2;
   TopoDS_Vertex                      V1,V2;
   TopTools_SequenceOfShape           SV;
   TopTools_ListIteratorOfListOfShape it(VOnE);
@@ -793,6 +822,44 @@ void BRepAlgo_Loop::CutEdge (const TopoDS_Edge&          E,
     if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
   }
 
+  //Split the edge
+  TopoDS_Vertex aFirstVertex = TopoDS::Vertex(SV(1)), aLastVertex;
+  for (Standard_Integer ii = 2; ii <= SV.Length(); ii++)
+  {
+    aLastVertex = TopoDS::Vertex(SV(ii));
+    aFirstVertex.Orientation(TopAbs_FORWARD);
+    aLastVertex.Orientation(TopAbs_REVERSED);
+
+    TopoDS_Edge aNewEdge = TopoDS::Edge(WE.EmptyCopied());
+    B.Add (aNewEdge, aFirstVertex);
+    B.Add (aNewEdge, aLastVertex);
+
+    aFirstVertex.Orientation(TopAbs_INTERNAL);
+    aLastVertex.Orientation(TopAbs_INTERNAL);
+
+    Standard_Real aFirst, aLast;
+    if (aFirstVertex.IsSame(VF))
+      aFirst = f;
+    else
+      aFirst = BRep_Tool::Parameter(aFirstVertex, WE);
+    if (aLastVertex.IsSame(VL))
+      aLast = l;
+    else
+      aLast = BRep_Tool::Parameter(aLastVertex, WE);
+
+    if (aLast - aFirst > Precision::Confusion())
+    {
+      B.Range (aNewEdge, aFirst, aLast);
+      NE.Append(aNewEdge.Oriented(E.Orientation()));
+      aFirstVertex = aLastVertex;
+    }
+    else
+    {
+      std::cout <<"!!!"<<std::endl;
+    }
+  }
+  
+  /*
   while (!SV.IsEmpty()) {
     while (!SV.IsEmpty() && 
           SV.First().Orientation() != TopAbs_FORWARD) {
@@ -844,28 +911,31 @@ void BRepAlgo_Loop::CutEdge (const TopoDS_Edge&          E,
       NE.Append(NewEdge.Oriented(E.Orientation()));
     }
   }
+  */
 
   //Remove edges with size <= tolerance
+  /*
   Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
   it.Initialize(NE);
   while (it.More())
+  {
+    // skl : I change "E" to "EE"
+    TopoDS_Edge EE = TopoDS::Edge( it.Value() );
+    Standard_Real fpar, lpar;
+    BRep_Tool::Range( EE, fpar, lpar );
+    if (lpar - fpar <= Precision::Confusion())
+      NE.Remove(it);
+    else
     {
-      // skl : I change "E" to "EE"
-      TopoDS_Edge EE = TopoDS::Edge( it.Value() );
-      Standard_Real fpar, lpar;
-      BRep_Tool::Range( EE, fpar, lpar );
-      if (lpar - fpar <= Precision::Confusion())
-       NE.Remove(it);
+      gp_Pnt2d pf, pl;
+      BRep_Tool::UVPoints( EE, myFace, pf, pl );
+      if (pf.Distance(pl) <= Tol && !BRep_Tool::IsClosed(EE))
+        NE.Remove(it);
       else
-       {
-         gp_Pnt2d pf, pl;
-         BRep_Tool::UVPoints( EE, myFace, pf, pl );
-         if (pf.Distance(pl) <= Tol && !BRep_Tool::IsClosed(EE))
-           NE.Remove(it);
-         else
-           it.Next();
-       }
+        it.Next();
     }
+  }
+  */
 }
 
 //=======================================================================
index 316a9d7e64ece4af279f58141d56a059f809bbc9..d36ab996d803a83d1c83c47ad51f96bc40aee553 100644 (file)
@@ -52,12 +52,21 @@ public:
   //! Add <E> as const edge, E can be in the result.
   Standard_EXPORT void AddConstEdge (const TopoDS_Edge& E);
   
+  //! Add a new edge
+  Standard_EXPORT void AddNewEdge (const TopoDS_Edge& theEdge);
+  
   //! Add <LE> as a set of const edges.
   Standard_EXPORT void AddConstEdges (const TopTools_ListOfShape& LE);
   
   //! Sets the Image Vertex - Vertex
   Standard_EXPORT void SetImageVV (const BRepAlgo_Image& theImageVV);
   
+  //! Returns TRUE if new edges are not empty
+  Standard_EXPORT Standard_Boolean HasNewEdges ()
+  {
+    return (!myNewEdges.IsEmpty());
+  }
+  
   //! Make loops.
   Standard_EXPORT void Perform();
   
@@ -105,6 +114,7 @@ private:
   TopoDS_Face myFace;
   TopTools_ListOfShape myConstEdges;
   TopTools_ListOfShape myEdges;
+  TopTools_ListOfShape myNewEdges;
   TopTools_DataMapOfShapeListOfShape myVerOnEdges;
   TopTools_ListOfShape myNewWires;
   TopTools_ListOfShape myNewFaces;
index 20bfba9a865d2d3cae198af419723cc48416058b..259f5643dc72a5427c9c1bf5443ce6c8627a6610 100644 (file)
@@ -28,6 +28,7 @@
 #include <BRepOffset_Tool.hxx>
 #include <BRepPrimAPI_MakePrism.hxx>
 #include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
@@ -48,6 +49,7 @@
 #include <TopoDS_Vertex.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <ChFi3d.hxx>
 
 static void CorrectOrientationOfTangent(gp_Vec& TangVec,
@@ -58,6 +60,24 @@ static void CorrectOrientationOfTangent(gp_Vec& TangVec,
   if (aVertex.IsSame(Vlast))
     TangVec.Reverse();
 }
+
+static Standard_Boolean IsTangentEdges(const TopoDS_Vertex& theVertex,
+                                       const TopoDS_Edge&   theEdge1,
+                                       const TopoDS_Edge&   theEdge2,
+                                       const Standard_Real  theAngle)
+{
+  Standard_Real aParOnEdge1 = BRep_Tool::Parameter(theVertex, theEdge1);
+  Standard_Real aParOnEdge2 = BRep_Tool::Parameter(theVertex, theEdge2);
+  BRepAdaptor_Curve aBAcurve1(theEdge1), aBAcurve2(theEdge2);
+  gp_Vec aVec1, aVec2;
+  aVec1 = aBAcurve1.DN(aParOnEdge1, 1);
+  CorrectOrientationOfTangent(aVec1, theVertex, theEdge1);
+  aVec2 = aBAcurve2.DN(aParOnEdge2, 1);
+  CorrectOrientationOfTangent(aVec2, theVertex, theEdge2);
+  Standard_Boolean IsOpposite = aVec2.IsOpposite(aVec1, theAngle);
+  return IsOpposite;
+}
+
 //=======================================================================
 //function : BRepOffset_Analyse
 //purpose  : 
@@ -83,12 +103,15 @@ BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S,
 //function : EdgeAnlyse
 //purpose  : 
 //=======================================================================
-static void EdgeAnalyse(const TopoDS_Edge&         E,
-                                         const TopoDS_Face&         F1,
-                                         const TopoDS_Face&         F2,
-                                         const Standard_Real        SinTol,
-                                               BRepOffset_ListOfInterval& LI)
+Standard_Boolean BRepOffset_Analyse::EdgeAnalyse(const TopoDS_Edge&         E,
+                                                 const TopoDS_Face&         F1,
+                                                 const TopoDS_Face&         F2,
+                                                 const Standard_Real        SinTol)
 {
+  BRepOffset_ListOfInterval& LI = myMapEdgeType (E);
+  
+  Standard_Boolean IsSmooth = Standard_False;
+  
   Standard_Real   f,l;
   BRep_Tool::Range(E, F1, f, l);
   BRepOffset_Interval I;
@@ -111,16 +134,98 @@ static void EdgeAnalyse(const TopoDS_Edge&         E,
     else
       ConnectType = ChFi3d::DefineConnectType(E, F1, F2, SinTol, Standard_False);
   }
-  else
+  else if (myJoinType == GeomAbs_Arc/* || myIsOpenShell*/)
   {
     if (ChFi3d::IsTangentFaces(E, F1, F2)) //weak condition
       ConnectType = ChFiDS_Tangential;
     else
       ConnectType = ChFi3d::DefineConnectType(E, F1, F2, SinTol, Standard_False);
   }
+  else //join type in Intersection
+  {
+    ConnectType = ChFi3d::DefineConnectType(E, F1, F2, SinTol, Standard_False);
+
+    Standard_Boolean IsEdgeNearSingularity = Standard_False;
+    TopoDS_Face FF [2] = {F1, F2};
+    TopoDS_Vertex aV [2];
+    TopExp::Vertices(E, aV[0], aV[1]);
+    for (Standard_Integer ii = 0; ii < 2; ii++)
+    {
+      TopExp_Explorer anExplo (FF[ii], TopAbs_EDGE);
+      for (; anExplo.More(); anExplo.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(anExplo.Current());
+        if (BRep_Tool::Degenerated(anEdge))
+        {
+          TopoDS_Vertex aVdeg1, aVdeg2;
+          TopExp::Vertices(anEdge, aVdeg1, aVdeg2);
+          if (aVdeg1.IsSame(aV[0]) || aVdeg1.IsSame(aV[1]) ||
+              aVdeg2.IsSame(aV[0]) || aVdeg2.IsSame(aV[1]))
+          {
+            IsEdgeNearSingularity = Standard_True;
+            break;
+          }
+        }
+      }
+    }
+    Standard_Boolean IsChain = Standard_False;
+    TopTools_IndexedDataMapOfShapeListOfShape aVEmap;
+    TopExp::MapShapesAndUniqueAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aVEmap);
+    for (Standard_Integer ii = 0; ii < 2; ii++)
+    {
+      const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aV[ii]);
+      TopTools_ListIteratorOfListOfShape itl(aElist);
+      for (; itl.More(); itl.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+        if (anEdge.IsSame(E))
+          continue;
+        if (F1.IsSame(F2))
+          IsChain = BRepTools::IsReallyClosed(anEdge, F1);
+        else
+        {
+          TopExp_Explorer anExplo(F2, TopAbs_EDGE);
+          for (; anExplo.More(); anExplo.Next())
+          {
+            const TopoDS_Shape& anEdgeOnF2 = anExplo.Current();
+            if (anEdge.IsSame(anEdgeOnF2))
+            {
+              IsChain = Standard_True;
+              break;
+            }
+          }
+        }
+      }
+      if (IsChain)
+        break;
+    }
+
+    //Temporary
+    Standard_Boolean IsTang = Standard_False;
+    if (ConnectType == ChFiDS_Tangential)
+    {
+      IsTang = Standard_True;
+#ifdef OCCT_DEBUG
+      std::cout <<"edge is tangent"<<std::endl;
+#endif 
+    }
+    ///////////
+
+    if (ConnectType != ChFiDS_Tangential &&
+        ChFi3d::IsTangentFaces(E, F1, F2)) //weak condition
+      IsSmooth = Standard_True;
+
+    if (IsSmooth && (IsEdgeNearSingularity || IsChain))
+    {
+      ConnectType = ChFiDS_Tangential;
+      IsSmooth = Standard_False;
+    }
+  }
    
   I.Type(ConnectType);
   LI.Append(I);
+
+  return IsSmooth;
 }
 
 //=======================================================================
@@ -143,6 +248,8 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
                                   const Standard_Real Angle)
 {
   myShape = S;
+  myIsOpenShell = Standard_False;
+  mySmoothEdges.Clear();
   myNewFaces .Clear();
   myGenerated.Clear();
   myReplacement.Clear();
@@ -154,7 +261,25 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
   // Build ancestors.
   BuildAncestors (S,myAncestors);
 
-  TopTools_ListOfShape aLETang;
+  //Define status of boundary
+  TopTools_IndexedDataMapOfShapeListOfShape aEFmap;
+  TopExp::MapShapesAndAncestors (S, TopAbs_EDGE, TopAbs_FACE, aEFmap);
+  for (Standard_Integer ii = 1; ii <= aEFmap.Extent(); ii++)
+  {
+    const TopTools_ListOfShape& aElist = aEFmap(ii);
+    if (aElist.Extent() == 1)
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(aEFmap.FindKey(ii));
+      if (!BRep_Tool::Degenerated(anEdge))
+      {
+        myIsOpenShell = Standard_True;
+        break;
+      }
+    }
+  }
+
+  //TopTools_ListOfShape aLETang;
+  TopTools_SequenceOfShape aSeqEtang;
 
   TopExp_Explorer Exp(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
   for ( ; Exp.More(); Exp.Next()) {
@@ -170,12 +295,18 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
       if (L.Extent() == 2) {
         const TopoDS_Face& F1 = TopoDS::Face (L.First());
         const TopoDS_Face& F2 = TopoDS::Face (L.Last());
-        EdgeAnalyse (E, F1, F2, SinTol, myMapEdgeType (E));
+        Standard_Boolean IsSmooth = EdgeAnalyse (E, F1, F2, SinTol);
 
-        // For tangent faces add artificial perpendicular face
-        // to close the gap between them (if they have different offset values)
-        if (myMapEdgeType(E).Last().Type() == ChFiDS_Tangential)
-          aLETang.Append (E);
+        if (IsSmooth)
+          mySmoothEdges.Add(E);
+        else
+        {
+          // For tangent faces add artificial perpendicular face
+          // to close the gap between them (if they have different offset values)
+          if (myMapEdgeType(E).Last().Type() == ChFiDS_Tangential)
+            aSeqEtang.Append (E);
+            //aLETang.Append (E);
+        }
       }
       else if (L.Extent() == 1) {
         Standard_Real U1, U2;
@@ -196,7 +327,228 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
     }
   }
 
-  TreatTangentFaces (aLETang);
+  //Propagate tangent edges
+  Standard_Real anAngularTol = (myAngle < M_PI/4)? myAngle : 1.e-5;
+
+  TopExp_Explorer anExplo (S, TopAbs_FACE);
+  for (; anExplo.More(); anExplo.Next())
+  {
+    const TopoDS_Face& aFace = TopoDS::Face(anExplo.Current());
+    TopTools_IndexedDataMapOfShapeListOfShape aVEmap;
+    TopExp::MapShapesAndAncestors (aFace, TopAbs_VERTEX, TopAbs_EDGE, aVEmap);
+    
+    TopoDS_Iterator itw(aFace);
+    for (; itw.More(); itw.Next())
+    {
+      const TopoDS_Wire& aWire = TopoDS::Wire(itw.Value());
+      BRepTools_WireExplorer wexp(aWire, aFace);
+      for (; wexp.More(); wexp.Next())
+      {
+        const TopoDS_Edge& aCurEdge = wexp.Current();
+        if (BRep_Tool::Degenerated (aCurEdge) ||
+            BRepTools::IsReallyClosed (aCurEdge, aFace))
+          continue;
+        
+        const BRepOffset_ListOfInterval& aListInterv = Type(aCurEdge);
+        if (!aListInterv.IsEmpty() && aListInterv.First().Type() == ChFiDS_Tangential)
+        {
+          TopoDS_Vertex aVV [2];
+          TopExp::Vertices (aCurEdge, aVV[0], aVV[1]);
+          for (Standard_Integer ii = 0; ii < 2; ii++)
+          {
+            TopoDS_Edge aNeighbor;
+            const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aVV[ii]);
+            TopTools_ListIteratorOfListOfShape itl(aElist);
+            for (; itl.More(); itl.Next())
+            {
+              const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+              if (!anEdge.IsSame(aCurEdge))
+              {
+                aNeighbor = anEdge;
+                break;
+              }
+            }
+            if (!aNeighbor.IsNull())
+            {
+              BRepOffset_ListOfInterval& aListIntervLocal = myMapEdgeType (aNeighbor);
+              if (!aListIntervLocal.IsEmpty() &&
+                  aListIntervLocal.First().Type() != ChFiDS_Tangential)
+              {
+                Standard_Boolean IsTangent = IsTangentEdges (aVV[ii], aCurEdge, aNeighbor,
+                                                             anAngularTol);
+                if (IsTangent)
+                {
+                  aSeqEtang.Append(aNeighbor);
+                  aListIntervLocal.First().Type(ChFiDS_Tangential);
+                  mySmoothEdges.Remove(aNeighbor);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  TopTools_IndexedMapOfShape aVmap;
+  TopExp::MapShapes(S, TopAbs_VERTEX, aVmap);
+  for (Standard_Integer ii = 1; ii <= aVmap.Extent(); ii++)
+  {
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVmap(ii));
+    const TopTools_ListOfShape& aElist = Ancestors(aVertex);
+    if (aElist.Extent() != 4)
+      continue;
+
+    TopoDS_Edge aEtang;
+    Standard_Integer NbTangEdges = 0;
+    Standard_Boolean isFreeBoundFound = Standard_False;
+    TopTools_ListIteratorOfListOfShape anItlEE(aElist);
+    for (; anItlEE.More(); anItlEE.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(anItlEE.Value());
+      const BRepOffset_ListOfInterval& aListInterv = Type(anEdge);
+      if (!aListInterv.IsEmpty())
+      {
+        if (aListInterv.First().Type() == ChFiDS_Tangential)
+        {
+          aEtang = anEdge;
+          NbTangEdges++;
+        }
+        else if (aListInterv.First().Type() == ChFiDS_FreeBound)
+          isFreeBoundFound = Standard_True;
+      }
+    }
+    if (aEtang.IsNull() || NbTangEdges == 4 || isFreeBoundFound)
+      continue;
+
+    const TopTools_ListOfShape& aFF = Ancestors(aEtang);
+    const TopoDS_Face& aF1 = TopoDS::Face (aFF.First());
+    const TopoDS_Face& aF2 = TopoDS::Face (aFF.Last());
+    
+    TopoDS_Edge aEopposite, aEadjacent1, aEadjacent2;
+    for (anItlEE.Initialize(aElist); anItlEE.More(); anItlEE.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(anItlEE.Value());
+      if (anEdge.IsSame(aEtang))
+        continue;
+
+      const TopTools_ListOfShape& aFlist = Ancestors(anEdge);
+      TopTools_ListIteratorOfListOfShape anItlFF(aFlist);
+      for (; anItlFF.More(); anItlFF.Next())
+      {
+        const TopoDS_Shape& aFace = anItlFF.Value();
+        if (aFace.IsSame(aF1) || aFace.IsSame(aF2))
+        {
+          if (aEadjacent1.IsNull())
+            aEadjacent1 = anEdge;
+          else
+            aEadjacent2 = anEdge;
+        }
+      }
+    }
+    for (anItlEE.Initialize(aElist); anItlEE.More(); anItlEE.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(anItlEE.Value());
+      if (!anEdge.IsSame(aEtang) && !anEdge.IsSame(aEadjacent1) && !anEdge.IsSame(aEadjacent2))
+      {
+        aEopposite = anEdge;
+        break;
+      }
+    }
+
+    if (aEopposite.IsNull() || aEadjacent1.IsNull() || aEadjacent2.IsNull())
+      continue;
+
+    BRepOffset_ListOfInterval& aListInterv = myMapEdgeType (aEopposite);
+    if (!aListInterv.IsEmpty() && aListInterv.First().Type() != ChFiDS_Tangential)
+    {
+      Standard_Boolean IsTangentWithOpposite =
+        IsTangentEdges(aVertex, aEtang, aEopposite, anAngularTol);
+      
+      if (IsTangentWithOpposite)
+      {
+        aListInterv.First().Type(ChFiDS_Tangential);
+        aSeqEtang.Append(aEopposite);
+        mySmoothEdges.Remove(aEopposite);
+      }
+    }
+
+    aListInterv = myMapEdgeType (aEopposite);
+    if (!aListInterv.IsEmpty() &&
+        aListInterv.First().Type() == ChFiDS_Tangential &&
+        IsTangentEdges(aVertex, aEtang, aEopposite, anAngularTol))
+    {
+      BRepOffset_ListOfInterval& aListInterv1 = myMapEdgeType (aEadjacent1);
+      BRepOffset_ListOfInterval& aListInterv2 = myMapEdgeType (aEadjacent2);
+      ChFiDS_TypeOfConcavity Type1 = aListInterv1.First().Type();
+      ChFiDS_TypeOfConcavity Type2 = aListInterv2.First().Type();
+      if (Type1 != ChFiDS_Tangential || Type2 != ChFiDS_Tangential)
+      {
+        Standard_Boolean IsTangentAdjacents = IsTangentEdges(aVertex, aEadjacent1, aEadjacent2,
+                                                             anAngularTol);
+        if (IsTangentAdjacents)
+        {
+          if (Type1 != ChFiDS_Tangential)
+            aSeqEtang.Append(aEadjacent1);
+          aListInterv1.First().Type(ChFiDS_Tangential);
+          mySmoothEdges.Remove(aEadjacent1);
+          
+          if (Type2 != ChFiDS_Tangential)
+            aSeqEtang.Append(aEadjacent2);
+          aListInterv2.First().Type(ChFiDS_Tangential);
+          mySmoothEdges.Remove(aEadjacent2);
+        }
+      }
+    }
+
+    //Check cases of 3 tangents of 4
+    NbTangEdges = 0;
+    TopoDS_Edge anEdgeNotTangent;
+    for (anItlEE.Initialize(aElist); anItlEE.More(); anItlEE.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(anItlEE.Value());
+      const BRepOffset_ListOfInterval& aListIntervLocal = Type(anEdge);
+      if (!aListIntervLocal.IsEmpty())
+      {
+        if (aListIntervLocal.First().Type() == ChFiDS_Tangential)
+          NbTangEdges++;
+        else
+          anEdgeNotTangent = anEdge;
+      }
+    }
+    if (NbTangEdges == 3)
+    {
+      aSeqEtang.Append(anEdgeNotTangent);
+      BRepOffset_ListOfInterval& aListIntervLocal = myMapEdgeType (anEdgeNotTangent);
+      aListIntervLocal.First().Type(ChFiDS_Tangential);
+      mySmoothEdges.Remove(anEdgeNotTangent);
+    }
+    else
+    {
+      //Check cases of 3 smooths of 4
+      Standard_Integer NbSmoothEdges = 0;
+      TopoDS_Edge anEdgeNotSmooth;
+      for (anItlEE.Initialize(aElist); anItlEE.More(); anItlEE.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(anItlEE.Value());
+        const BRepOffset_ListOfInterval& aListIntervLocal = Type(anEdge);
+        if (!aListIntervLocal.IsEmpty())
+        {
+          if (aListIntervLocal.First().Type() == ChFiDS_Tangential ||
+              IsEdgeSmooth(anEdge))
+            NbSmoothEdges++;
+          else
+            anEdgeNotSmooth = anEdge;
+        }
+      }
+      if (NbSmoothEdges == 3)
+      {
+        mySmoothEdges.Add(anEdgeNotSmooth);
+      }
+    }
+  }
+
+  TreatTangentFaces (aSeqEtang);
   myDone = Standard_True;
 }
 
@@ -204,9 +556,9 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
 //function : Generated
 //purpose  : 
 //=======================================================================
-void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
+void BRepOffset_Analyse::TreatTangentFaces (const TopTools_SequenceOfShape& theEdges)
 {
-  if (theLE.IsEmpty() || myFaceOffsetMap.IsEmpty())
+  if (theEdges.IsEmpty() || myFaceOffsetMap.IsEmpty())
   {
     // Noting to do: either there are no tangent faces in the shape or
     //               the face offset map has not been provided
@@ -221,9 +573,10 @@ void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
   // Bind vertices of the tangent edges with connected edges
   // of the face with smaller offset value
   TopTools_DataMapOfShapeShape aDMVEMin;
-  for (TopTools_ListOfShape::Iterator it (theLE); it.More(); it.Next())
+  
+  for (Standard_Integer ii = 1; ii <= theEdges.Length(); ii++)
   {
-    const TopoDS_Shape& aE = it.Value();
+    const TopoDS_Shape& aE = theEdges(ii);
     const TopTools_ListOfShape& aLA = Ancestors (aE);
 
     const TopoDS_Shape& aF1 = aLA.First(), aF2 = aLA.Last();
@@ -266,9 +619,9 @@ void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
   // Create map of Face ancestors for the vertices on tangent edges
   TopTools_DataMapOfShapeListOfShape aDMVFAnc;
 
-  for (TopTools_ListOfShape::Iterator itE (theLE); itE.More(); itE.Next())
+  for (Standard_Integer ii = 1; ii <= theEdges.Length(); ii++)
   {
-    const TopoDS_Shape& aE = itE.Value();
+    const TopoDS_Shape& aE = theEdges(ii);
     if (!anEdgeOffsetMap.IsBound (aE))
       continue;
 
@@ -427,7 +780,7 @@ void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
 
         myMapEdgeType (aE).Clear();
         // Analyze edge again
-        EdgeAnalyse (aE, TopoDS::Face (aFOpposite), aFNew,  aSinTol, myMapEdgeType (aE));
+        EdgeAnalyse (aE, TopoDS::Face (aFOpposite), aFNew, aSinTol);
 
         // Analyze vertices
         TopTools_MapOfShape aFNewEdgeMap;
@@ -510,8 +863,7 @@ void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
           myMapEdgeType.Bind (aEG, BRepOffset_ListOfInterval());
           if (aLEGA.Extent() == 2)
           {
-            EdgeAnalyse (aEG, TopoDS::Face (aLEGA.First()), TopoDS::Face (aLEGA.Last()),
-                         aSinTol, myMapEdgeType (aEG));
+            EdgeAnalyse (aEG, TopoDS::Face (aLEGA.First()), TopoDS::Face (aLEGA.Last()), aSinTol);
           }
         }
 
@@ -545,7 +897,7 @@ void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
         aLFOpposite.Append (aFToRemove);
         myAncestors.Add (aEOpposite, aLFOpposite);
         myMapEdgeType.Bind (aEOpposite, BRepOffset_ListOfInterval());
-        EdgeAnalyse (aEOpposite, aFNew, TopoDS::Face (aFToRemove), aSinTol, myMapEdgeType (aEOpposite));
+        EdgeAnalyse (aEOpposite, aFNew, TopoDS::Face (aFToRemove), aSinTol);
 
         TopTools_DataMapOfShapeShape* pEEMap = myReplacement.ChangeSeek (aFToRemove);
         if (!pEEMap)
index 51e319d2514b7dca805b3ba04eedbb354c445053..5b7f8d1998acb7174a44da35bc711185096be7d8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <Standard_Boolean.hxx>
 #include <TopoDS_Shape.hxx>
+#include <GeomAbs_JoinType.hxx>
 #include <BRepOffset_DataMapOfShapeListOfInterval.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <Standard_Real.hxx>
@@ -33,6 +34,7 @@
 #include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 class TopoDS_Shape;
 class TopoDS_Edge;
 class TopoDS_Vertex;
@@ -90,6 +92,12 @@ public: //! @name Results
                                      const TopoDS_Vertex& theVertex,
                                      TopTools_ListOfShape& theEdges) const;
 
+  //! returns TRUE if theEdge is smooth but not tangent
+  Standard_EXPORT Standard_Boolean IsEdgeSmooth (const TopoDS_Shape& theEdge) const
+  {
+    return mySmoothEdges.Contains(theEdge);
+  }
+
   //! Checks if the given shape has ancestors
   Standard_Boolean HasAncestor (const TopoDS_Shape& theS) const
   {
@@ -128,6 +136,11 @@ public: //! @name Results
                                  const ChFiDS_TypeOfConcavity theType1,
                                  const ChFiDS_TypeOfConcavity theType2) const;
 
+  void SetJoinType (const GeomAbs_JoinType theJoinType)
+  {
+    myJoinType = theJoinType;
+  }
+
   void SetOffsetValue (const Standard_Real theOffset)
   {
     myOffset = theOffset;
@@ -171,14 +184,22 @@ private: //! @name Treatment of tangential cases
 
   //! Treatment of the tangential cases.
   //! @param theEdges List of edges connecting tangent faces
-  Standard_EXPORT void TreatTangentFaces (const TopTools_ListOfShape& theEdges);
+  Standard_EXPORT void TreatTangentFaces (const TopTools_SequenceOfShape& theEdges);
+
+  //! Defines types of edge <E>
+  Standard_Boolean EdgeAnalyse(const TopoDS_Edge&         E,
+                               const TopoDS_Face&         F1,
+                               const TopoDS_Face&         F2,
+                               const Standard_Real        SinTol);
 
 private: //! @name Fields
 
   // Inputs
   TopoDS_Shape myShape;  //!< Input shape to analyze
   Standard_Real myAngle; //!< Criteria angle to check tangency
+  Standard_Boolean myIsOpenShell; //!< Flag indicating whether the shape is an open shell
 
+  GeomAbs_JoinType myJoinType;
   Standard_Real myOffset;                      //!< Offset value
   TopTools_DataMapOfShapeReal myFaceOffsetMap; //!< Map to store offset values for the faces.
                                                //!  Should be set by the calling algorithm.
@@ -196,6 +217,9 @@ private: //! @name Fields
 
   TopTools_ListOfShape myNewFaces; //!< New faces generated to close the gaps between adjacent
                                    //!  tangential faces having different offset values
+  
+  TopTools_MapOfShape mySmoothEdges; //!< Edges that are not tangential but smooth
+
   TopTools_DataMapOfShapeShape myGenerated; //!< Binding between edge and face generated from the edge
 };
 
diff --git a/src/BRepOffset/BRepOffset_DataMapOfFaceMapEE.hxx b/src/BRepOffset/BRepOffset_DataMapOfFaceMapEE.hxx
new file mode 100644 (file)
index 0000000..29601a8
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef BRepOffset_DataMapOfFaceMapEE_HeaderFile
+#define BRepOffset_DataMapOfFaceMapEE_HeaderFile
+
+#include <TopoDS_Face.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+
+typedef NCollection_DataMap<TopoDS_Face, TopTools_DataMapOfShapeListOfShape, TopTools_ShapeMapHasher> BRepOffset_DataMapOfFaceMapEE;
+
+#endif
index 63917e18096d6aaec566a0e6a93f29c3ec018b23..b2b882e9fa5344b984d66c523f4d340d320fb62a 100644 (file)
@@ -40,6 +40,7 @@
 #include <BRepOffset_Analyse.hxx>
 #include <BRepOffset_Offset.hxx>
 #include <BRepOffset_Tool.hxx>
+#include <BRepOffset_MakeOffset.hxx>
 #include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <Geom2d_BezierCurve.hxx>
@@ -58,6 +59,8 @@
 #include <Geom_TrimmedCurve.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_Interpolate.hxx>
+#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
 #include <GeomLib.hxx>
 #include <GeomProjLib.hxx>
@@ -79,7 +82,9 @@
 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
-#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_DataMapOfOrientedShapeShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfOrientedShapeShape.hxx>
+#include <ElCLib.hxx>
 
 #include <stdio.h>
 #ifdef DRAW 
@@ -95,6 +100,37 @@ static Standard_Integer NbE2d = 0;
 static Standard_Integer NbNewVertices  = 0;
 #endif
 
+static Standard_Boolean ExtendPCurve(Handle(Geom2d_Curve)& thePCurve,
+                                     Standard_Real         theFirstOnEdge,
+                                     Standard_Real         theLastOnEdge,
+                                     Standard_Real         theFirstPar,
+                                     Standard_Real         theLastPar,
+                                     Standard_Real         theDelta);
+
+static Standard_Boolean ComputeEndOfExtension(const Handle(Geom_Surface)&  theSurf,
+                                              const gp_Pnt2d&              theStartPoint,
+                                              const gp_Dir2d&              theTangent,
+                                              const Standard_Real          the2Offset,
+                                              //gp_Pnt2d&                   theEndPoint,
+                                              Standard_Real&               theParamOnEnd,
+                                              Standard_Real&               theLenToEnd,
+                                              Handle(Geom2d_TrimmedCurve)& theSegment);
+
+static void AddEdgeWithFaceToMap(const TopoDS_Edge& theEdge,
+                                 const TopoDS_Face& theFace,
+                                 TopTools_IndexedDataMapOfShapeListOfShape& theEFmap);
+
+static Standard_Boolean OrientationInEdge(const TopoDS_Vertex& theVertex,
+                                          const TopoDS_Edge&   theEdge,
+                                          TopAbs_Orientation&  theOr);
+
+static void GetEdgesOrientedInFace(const TopoDS_Shape& theShape,
+                                   const TopoDS_Face&  theFace,
+                                   const Handle(BRepAlgo_AsDes)& theAsDes,
+                                   TopTools_SequenceOfShape&     theSeqEdges);
+
+static Standard_Integer DefineClosedness(const TopoDS_Face& theFace);
+
 //=======================================================================
 //function : CommonVertex
 //purpose  : 
@@ -115,154 +151,49 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
   return V;
 }
 
-static Standard_Integer DefineClosedness(const TopoDS_Face& theFace)
+static TopAbs_Orientation DefineOrientationOfVertexOnEdge(const TopoDS_Vertex&      theVertex,
+                                                          const TopoDS_Edge&        theEdge,
+                                                          const BRepOffset_Analyse& theAnalyse)
 {
-  TopExp_Explorer anExplo (theFace, TopAbs_EDGE);
-  for (; anExplo.More(); anExplo.Next())
+  TopAbs_Orientation anOr = TopAbs_EXTERNAL;
+  
+  const BRepOffset_ListOfInterval& aListInterv = theAnalyse.Type(theEdge);
+  if (!aListInterv.IsEmpty() &&
+      ((aListInterv.First().Type() != ChFiDS_Concave &&
+        aListInterv.First().Type() != ChFiDS_Convex) ||
+       theAnalyse.IsEdgeSmooth(theEdge)))
   {
-    const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
-    if (BRepTools::IsReallyClosed(anEdge, theFace))
-    {
-      Standard_Real fpar, lpar;
-      Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
-      gp_Vec2d aTangent = aPCurve->DN(fpar, 1);
-      Standard_Real aCrossProd1 = aTangent ^ gp::DX2d();
-      Standard_Real aCrossProd2 = aTangent ^ gp::DY2d();
-      if (Abs(aCrossProd2) < Abs(aCrossProd1)) //pcurve is parallel to OY
-        return 1;
-      else
-        return 2;
-    }
+    TopoDS_Vertex aV1, aV2;
+    TopExp::Vertices(theEdge, aV1, aV2);
+    if (!aV1.IsSame(aV2))
+      anOr = (aV1.IsSame(theVertex))? aV1.Orientation() : aV2.Orientation();
   }
 
-  return 0;
+  return anOr;
 }
 
-static void GetEdgesOrientedInFace(const TopoDS_Shape& theShape,
-                                   const TopoDS_Face&  theFace,
-                                   const Handle(BRepAlgo_AsDes)& theAsDes,
-                                   TopTools_SequenceOfShape&     theSeqEdges)
+static Standard_Boolean IsOrientationChanged(TopTools_IndexedMapOfShape& theMap,
+                                             const TopoDS_Edge& theEdge)
 {
-  const TopTools_ListOfShape& aEdges = theAsDes->Descendant (theFace);
-
-  TopExp_Explorer anExplo (theShape, TopAbs_EDGE);
-  for (; anExplo.More(); anExplo.Next())
-  {
-    const TopoDS_Shape& anEdge = anExplo.Current();
-    TopTools_ListIteratorOfListOfShape itl (aEdges);
-    for (; itl.More(); itl.Next())
-    {
-      const TopoDS_Shape& anEdgeInFace = itl.Value();
-      if (anEdgeInFace.IsSame(anEdge))
-      {
-        theSeqEdges.Append (anEdgeInFace);
-        break;
-      }
-    }
-  }
-
-  if (theSeqEdges.Length() == 1)
-    return;
-
-  TopTools_IndexedDataMapOfShapeListOfShape aVEmap;
-  for (Standard_Integer ii = 1; ii <= theSeqEdges.Length(); ii++)
-    TopExp::MapShapesAndAncestors (theSeqEdges(ii), TopAbs_VERTEX, TopAbs_EDGE, aVEmap);
-
-  TopoDS_Vertex aFirstVertex;
-  TopoDS_Edge aFirstEdge;
-  for (Standard_Integer ii = 1; ii <= aVEmap.Extent(); ii++)
-  {
-    const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVEmap.FindKey(ii));
-    const TopTools_ListOfShape& aElist = aVEmap(ii);
-    if (aElist.Extent() == 1)
-    {
-      const TopoDS_Edge& anEdge = TopoDS::Edge(aElist.First());
-      TopoDS_Vertex aV1, aV2;
-      TopExp::Vertices(anEdge, aV1, aV2, Standard_True); //with orientation
-      if (aV1.IsSame(aVertex))
-      {
-        aFirstVertex = aVertex;
-        aFirstEdge = anEdge;
-        break;
-      }
-    }
-  }
-
-  if (aFirstEdge.IsNull()) //closed set of edges
+  Standard_Boolean IsOrChanged = Standard_False;
+  
+  if (!theMap.Contains(theEdge))
+    theMap.Add(theEdge);
+  else
   {
-    //Standard_Real aPeriod = 0.;
-    Standard_Integer IndCoord = DefineClosedness (theFace);
-    /*
-    BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
-    if (IndCoord == 1)
-      aPeriod = aBAsurf.LastUParameter() - aBAsurf.FirstUParameter();
-    else if (IndCoord == 2)
-      aPeriod = aBAsurf.LastVParameter() - aBAsurf.FirstVParameter();
-    */
-    
-    if (IndCoord != 0)
+    Standard_Integer anInd = theMap.FindIndex(theEdge);
+    const TopoDS_Shape& anEdge = theMap(anInd);
+    if (theEdge.Orientation() != anEdge.Orientation())
     {
-      Standard_Real aMaxDelta = 0.;
-      for (Standard_Integer ii = 1; ii <= aVEmap.Extent(); ii++)
-      {
-        const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVEmap.FindKey(ii));
-        const TopTools_ListOfShape& aElist = aVEmap(ii);
-        const TopoDS_Edge& anEdge1 = TopoDS::Edge(aElist.First());
-        const TopoDS_Edge& anEdge2 = TopoDS::Edge(aElist.Last());
-        Standard_Real aParam1 = BRep_Tool::Parameter(aVertex, anEdge1);
-        Standard_Real aParam2 = BRep_Tool::Parameter(aVertex, anEdge2);
-        BRepAdaptor_Curve2d aBAcurve1 (anEdge1, theFace);
-        BRepAdaptor_Curve2d aBAcurve2 (anEdge2, theFace);
-        gp_Pnt2d aPnt1 = aBAcurve1.Value(aParam1);
-        gp_Pnt2d aPnt2 = aBAcurve2.Value(aParam2);
-        Standard_Real aDelta = Abs(aPnt1.Coord(IndCoord) - aPnt2.Coord(IndCoord));
-        if (aDelta > aMaxDelta)
-        {
-          aMaxDelta = aDelta;
-          aFirstVertex = aVertex;
-        }
-      }
-      const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aFirstVertex);
-      TopTools_ListIteratorOfListOfShape itl (aElist);
-      for (; itl.More(); itl.Next())
-      {
-        const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
-        TopoDS_Vertex aV1, aV2;
-        TopExp::Vertices(anEdge, aV1, aV2, Standard_True); //with orientation
-        if (aV1.IsSame(aFirstVertex))
-        {
-          aFirstEdge = anEdge;
-          break;
-        }
-      }
+      theMap.Substitute( anInd, theEdge );
+      IsOrChanged = Standard_True;
     }
   }
 
-  Standard_Integer aNbEdges = theSeqEdges.Length();
-  theSeqEdges.Clear();
-  theSeqEdges.Append (aFirstEdge);
-  TopoDS_Edge anEdge = aFirstEdge;
-  for (;;)
-  {
-    TopoDS_Vertex aLastVertex = TopExp::LastVertex (anEdge, Standard_True); //with orientation
-    if (aLastVertex.IsSame(aFirstVertex))
-      break;
-    
-    const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aLastVertex);
-    if (aElist.Extent() == 1)
-      break;
-    
-    if (aElist.First().IsSame(anEdge))
-      anEdge = TopoDS::Edge(aElist.Last());
-    else
-      anEdge = TopoDS::Edge(aElist.First());
-
-    theSeqEdges.Append (anEdge);
-    if (theSeqEdges.Length() == aNbEdges)
-      break;
-  }
+  return IsOrChanged;
 }
 
+
 //=======================================================================
 //function : Store
 //purpose  : Store the vertices <theLV> into AsDes for the edge <theEdge>.
@@ -654,7 +585,11 @@ static void RefEdgeInter(const TopoDS_Face&              F,
                          const TopoDS_Vertex&            theVref,
                          BRepAlgo_Image&                 theImageVV,
                          TopTools_IndexedDataMapOfShapeListOfShape& aDMVV,
-                         Standard_Boolean&               theCoincide)
+                         Standard_Boolean&               theCoincide,
+                         TopoDS_Vertex&                  theVertexForE1,
+                         TopoDS_Vertex&                  theVertexForE2,
+                         Standard_Real&                  theParamForE1,
+                         Standard_Real&                  theParamForE2)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -678,6 +613,9 @@ static void RefEdgeInter(const TopoDS_Face&              F,
   //BRep_Tool::Range(E1, f[1], l[1]);
   //BRep_Tool::Range(E2, f[2], l[2]);
 
+  TopTools_DataMapOfShapeReal aVerParOnE1map;
+  TopTools_DataMapOfShapeReal aVerParOnE2map;
+
   BRepAdaptor_Curve CE1(E1,F);
   BRepAdaptor_Curve CE2(E2,F);
 
@@ -727,13 +665,13 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       return;
     }
   }
-  
+
   Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
   //
   if (!Inter2d.IsDone() || !Inter2d.NbPoints()) {
     theCoincide = (Inter2d.NbSegments() &&
-                   (GAC1.GetType() == GeomAbs_Line) &&
-                   (GAC2.GetType() == GeomAbs_Line));
+                  (GAC1.GetType() == GeomAbs_Line) &&
+                  (GAC2.GetType() == GeomAbs_Line));
     return;
   }
   //
@@ -769,6 +707,8 @@ static void RefEdgeInter(const TopoDS_Face&              F,
     aNewVertex.Orientation(TopAbs_INTERNAL);
     B.UpdateVertex( aNewVertex, aT1, E1, Tol );
     B.UpdateVertex( aNewVertex, aT2, E2, Tol );
+    aVerParOnE1map.Bind (aNewVertex, aT1);
+    aVerParOnE2map.Bind (aNewVertex, aT2);
     gp_Pnt P1 = CE1.Value(aT1);
     gp_Pnt P2 = CE2.Value(aT2);
     Standard_Real dist1, dist2, dist3;
@@ -845,6 +785,7 @@ static void RefEdgeInter(const TopoDS_Face&              F,
   TopExp::Vertices(E2,V2[0],V2[1]);
 
   Standard_Integer j;
+  /*
   for (j = 0; j < 2; j++) {
     if (V1[j].IsNull()) continue;
     for (Standard_Integer k = 0; k < 2; k++) {
@@ -870,6 +811,7 @@ static void RefEdgeInter(const TopoDS_Face&              F,
       }
     }
   }
+  */
 
   Standard_Boolean AffichPurge = Standard_False;
 
@@ -948,6 +890,11 @@ static void RefEdgeInter(const TopoDS_Face&              F,
     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
     TolStore = Max (TolStore, Tol);
     Store (E1,E2,LV1,LV2,TolStore,AsDes, aDMVV);
+    
+    theVertexForE1 = TopoDS::Vertex(LV1.First());
+    theVertexForE2 = TopoDS::Vertex(LV2.First());
+    theParamForE1 = aVerParOnE1map(theVertexForE1);
+    theParamForE2 = aVerParOnE2map(theVertexForE2);
   }
 }
 
@@ -994,35 +941,37 @@ static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
   Standard_Real FirstPar = NewPCurve->FirstParameter();
   Standard_Real LastPar  = NewPCurve->LastParameter();
 
+  /*
   if (NewPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
       (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
+  {
+    if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
     {
-      if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
-        {
-          Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast (NewPCurve);
-          if (aBezier->NbPoles() == 2)
-            {
-              TColgp_Array1OfPnt2d thePoles(1,2);
-              aBezier->Poles(thePoles);
-              gp_Vec2d aVec(thePoles(1), thePoles(2));
-              NewPCurve = new Geom2d_Line(thePoles(1), aVec);
-              return Standard_True;
-            }
-        }
-      else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
-        {
-          Handle(Geom2d_BSplineCurve) aBSpline = Handle(Geom2d_BSplineCurve)::DownCast (NewPCurve);
-          if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
-            {
-              TColgp_Array1OfPnt2d thePoles(1,2);
-              aBSpline->Poles(thePoles);
-              gp_Vec2d aVec(thePoles(1), thePoles(2));
-              NewPCurve = new Geom2d_Line(thePoles(1), aVec);
-              return Standard_True;
-            }
-        }
+      Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast (NewPCurve);
+      if (aBezier->NbPoles() == 2)
+      {
+        TColgp_Array1OfPnt2d thePoles(1,2);
+        aBezier->Poles(thePoles);
+        gp_Vec2d aVec(thePoles(1), thePoles(2));
+        NewPCurve = new Geom2d_Line(thePoles(1), aVec);
+        return Standard_True;
+      }
     }
-
+    else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
+    {
+      Handle(Geom2d_BSplineCurve) aBSpline = Handle(Geom2d_BSplineCurve)::DownCast (NewPCurve);
+      if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
+      {
+        TColgp_Array1OfPnt2d thePoles(1,2);
+        aBSpline->Poles(thePoles);
+        gp_Vec2d aVec(thePoles(1), thePoles(2));
+        NewPCurve = new Geom2d_Line(thePoles(1), aVec);
+        return Standard_True;
+      }
+    }
+  }
+  */
+  
   FirstPar = aPCurve->FirstParameter();
   LastPar  = aPCurve->LastParameter();
   Handle(Geom2d_TrimmedCurve) aTrCurve = 
@@ -1038,7 +987,8 @@ static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
   Handle(Geom2d_TrimmedCurve)           aSegment;
   Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
   Standard_Real                         aTol = Precision::Confusion();
-  Standard_Real                         aDelta = Max(a2Offset, 1.);
+  //Standard_Real                         aDelta = Max(a2Offset, 1.);
+  Standard_Real                         aDelta = a2Offset;
   
   if (FirstPar > anEf - a2Offset) {
     aPCurve->D1(FirstPar, aPBnd, aVBnd);
@@ -1070,444 +1020,454 @@ static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
 //purpose  : 
 //=======================================================================
 
-//  Modified by skv - Fri Dec 26 17:00:55 2003 OCC4455 Begin
-//static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE) 
-Standard_Boolean BRepOffset_Inter2d::ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real theOffset)
+Standard_Boolean BRepOffset_Inter2d::ExtentEdge(const TopoDS_Edge&     E,
+                                                TopoDS_Edge&           NE,
+                                                const Standard_Real    theOffset,
+                                                const Standard_Boolean theToProlongBefore,
+                                                const Standard_Boolean theToProlongAfter)
 {
-  //BRepLib::BuildCurve3d(E);
+  const Standard_Integer NCONTROL = 23;
+  Standard_Real aTolEdge = BRep_Tool::Tolerance(E);
 
   TopoDS_Shape  aLocalShape = E.EmptyCopied();
   Standard_Real anEf;
   Standard_Real anEl;
   Standard_Real a2Offset = 2.*Abs(theOffset);
   BRep_Builder BB;
-  Standard_Integer i, j;
 
   BRep_Tool::Range(E, anEf, anEl);
-  NE = TopoDS::Edge(aLocalShape); 
-//  NE = TopoDS::Edge(E.EmptyCopied()); 
-  // Enough for analytic edges, for general case reconstruct the
-  // geometry of the edge recalculating the intersection of surfaces.
-
-  //BRepLib::BuildCurve3d(E);
+  NE = TopoDS::Edge(aLocalShape);
 
   Standard_Integer NbPCurves = 0;
-  Standard_Real FirstParOnPC = RealFirst(), LastParOnPC = RealLast();
-  Handle(Geom2d_Curve) MinPC;
-  Handle(Geom_Surface) MinSurf;
-  TopLoc_Location      MinLoc;
+  Standard_Boolean IsSeam = Standard_False;
 
   BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves() );
   for (; itr.More(); itr.Next())
+  {
+    Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
+    if (CurveRep->IsCurveOnSurface())
     {
-      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++;
+      if (CurveRep->IsCurveOnClosedSurface())
+        IsSeam = Standard_True;
     }
+  }
 
-  Standard_Real f, l;
-  Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, f, l );
-  if (NbPCurves)
-    {
-      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();
-#ifdef OCCT_DEBUG
-                  else
-                    std::cout<<"ProjectPointOnCurve not done"<<std::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();
-#ifdef OCCT_DEBUG
-                  else
-                    std::cout<<"ProjectPointOnCurve not done"<<std::endl;
-#endif
-                }
-            }
-          BB.Range( NE, f, l );
-          if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
-            BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-        }
-      else if (!BRep_Tool::Degenerated(E)) //no 3d curve
-        {
-          MinSurf = Handle(Geom_Surface)::DownCast
-            (MinSurf->Transformed(MinLoc.Transformation()));
-          Standard_Real max_deviation = 0.;
-          if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
-            {
-              if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
-                {
-                  Standard_Boolean IsLine = Standard_False;
-                  if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
-                    IsLine = Standard_True;
-                  else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
-                           MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
-                    {
-                      Handle(Geom2d_Line) theLine = Handle(Geom2d_Line)::DownCast (MinPC);
-                      gp_Dir2d LineDir = theLine->Direction();
-                      if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
-                        IsLine = Standard_True;
-                    }
-                  if (IsLine)
-                    {
-                      gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
-                      gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
-                      gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
-                      gp_Vec aVec(P1, P2);
-                      C3d = new Geom_Line( P1, aVec );
-                    }
-                }
-            }
-          else
-            {
-              Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
-              GeomAdaptor_Surface GAsurf( MinSurf );
-              Handle(Geom2dAdaptor_Curve) HC2d  = new Geom2dAdaptor_Curve( AC2d );
-              Handle(GeomAdaptor_Surface) HSurf = new GeomAdaptor_Surface( GAsurf );
-              Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
-              Standard_Real /*max_deviation,*/ average_deviation;
-              GeomAbs_Shape Continuity = GeomAbs_C1;
-              Standard_Integer MaxDegree = 14;
-              Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
-              GeomLib::BuildCurve3d(Precision::Confusion(),
-                                    ConS, FirstParOnPC, LastParOnPC,
-                                    C3d, max_deviation, average_deviation,
-                                    Continuity, MaxDegree, MaxSegment);
-            }
-          BB.UpdateEdge( NE, C3d, max_deviation );
-          //BB.Range( NE, FirstParOnPC, LastParOnPC );
-          Standard_Boolean ProjectionSuccess = Standard_True;
-          if (NbPCurves > 1)
-            //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-            for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
-                 itr.More();
-                 itr.Next())
-              {
-                Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
-                Standard_Real FirstPar, LastPar;
-                if (CurveRep->IsCurveOnSurface())
-                  {
-                    Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
-                    Handle(Geom_Surface) theSurf  = CurveRep->Surface();
-                    TopLoc_Location      theLoc   = CurveRep->Location();
-                    if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
-                      continue;
-                    FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
-                    LastPar  = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
-                    if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
-                        Abs(LastPar  - LastParOnPC)  > Precision::PConfusion())
-                      {
-                        theLoc = E.Location() * theLoc;
-                        theSurf = Handle(Geom_Surface)::DownCast
-                          (theSurf->Transformed(theLoc.Transformation()));
-
-                        if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
-                            theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
-                          {
-                            gp_Dir2d theDir = Handle(Geom2d_Line)::DownCast (theCurve)->Direction();
-                            if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
-                                theDir.IsParallel(gp::DY2d(), Precision::Angular()))
-                              {
-                                Standard_Real U1, U2, V1, V2;
-                                theSurf->Bounds(U1, U2, V1, V2);
-                                gp_Pnt2d Origin = Handle(Geom2d_Line)::DownCast (theCurve)->Location();
-                                if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
-                                    Abs(Origin.X()-U2) <= Precision::Confusion() ||
-                                    Abs(Origin.Y()-V1) <= Precision::Confusion() ||
-                                    Abs(Origin.Y()-V2) <= Precision::Confusion())
-                                  {
-                                    BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
-                                    break;
-                                  }
-                              }
-                          }
-                        if (!C3d.IsNull() && FirstParOnPC < LastParOnPC)
-                        {
-                          Handle(Geom2d_Curve) ProjPCurve =
-                            GeomProjLib::Curve2d(C3d, FirstParOnPC, LastParOnPC, theSurf);
-                          if (ProjPCurve.IsNull())
-                            ProjectionSuccess = Standard_False;
-                          else
-                            CurveRep->PCurve(ProjPCurve);
-                        }
-                        else
-                        {
-                          return Standard_False;
-                        }
-                      }
-                  }
-              }
-          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
+  if (IsSeam)
+  {
+    Standard_Real fpar, lpar;
+    Handle(Geom_Curve) C3d = BRep_Tool::Curve (NE, fpar, lpar);
+
+    if (!C3d.IsNull())
     {
+      if (C3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+        C3d = (Handle(Geom_TrimmedCurve)::DownCast(C3d))->BasisCurve();
+      
       Standard_Real FirstPar = C3d->FirstParameter();
       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 Standard_True;
-          }
-          
-          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 Standard_True;
-          }
-          
-          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;
-        }
-      else if (C3d->IsClosed())
-        LastPar -= 0.05*(LastPar - FirstPar);
-      
-      BB.Range( NE, FirstPar, LastPar );
+      if (Precision::IsInfinite(FirstPar) && Precision::IsInfinite(LastPar))
+      {
+        BB.Range (NE, FirstPar, LastPar);
+        return Standard_True;
+      }
     }
-  return Standard_True;
-}
-//  Modified by skv - Fri Dec 26 17:00:57 2003 OCC4455 End
+    
+    Handle(Geom2d_Curve) aPCurve, aPCurve2;
+    Handle(Geom_Surface) aSurf;
+    TopLoc_Location aLoc;
+    BRep_Tool::CurveOnSurface(E, aPCurve,  aSurf, aLoc, fpar, lpar, 1);
+    BRep_Tool::CurveOnSurface(E, aPCurve2, aSurf, aLoc, fpar, lpar, 2);
+    if (aPCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+      aPCurve = (Handle(Geom2d_TrimmedCurve)::DownCast(aPCurve))->BasisCurve();
+    if (aPCurve2->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+      aPCurve2 = (Handle(Geom2d_TrimmedCurve)::DownCast(aPCurve2))->BasisCurve();
+
+    Standard_Real FirstPar = aPCurve->FirstParameter();
+    Standard_Real LastPar  = aPCurve->LastParameter();
+    Standard_Real FirstPar2 = aPCurve2->FirstParameter();
+    Standard_Real LastPar2  = aPCurve2->LastParameter();
+
+    Standard_Real aFirstPar = Min(FirstPar, FirstPar2);
+    Standard_Real aLastPar  = Max(LastPar, LastPar2);
+
+    gp_Pnt2d aPnt2d;
+    gp_Vec2d aTangent;
+    aPCurve->D1(fpar, aPnt2d, aTangent);
+    gp_Dir2d aTangDir = aTangent;
+    Standard_Real aCrossProd1 = aTangent ^ gp::DX2d(),
+      aCrossProd2 = aTangent ^ gp::DY2d();
+    GeomAdaptor_Surface aGAsurf(aSurf);
+    Standard_Boolean IsParallelDX = (Abs(aCrossProd1) < Abs(aCrossProd2));
+    Standard_Real anOffset2d = IsParallelDX ?
+      aGAsurf.UResolution(a2Offset) : aGAsurf.VResolution(a2Offset);
+
+    Standard_Boolean IsFirstPCurveBounded =
+      (aPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
+       (FirstPar > anEf - anOffset2d || LastPar < anEl + anOffset2d));
+    
+    Standard_Boolean IsSecondPCurveBounded =
+      (aPCurve2->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
+       (FirstPar2 > anEf - anOffset2d || LastPar2 < anEl + anOffset2d));
 
+    if (IsFirstPCurveBounded && IsSecondPCurveBounded)
+    {
+      gp_Pnt2d aPnt2d2 = aPCurve2->Value(fpar);
+      gp_Vec2d aTranslation (aPnt2d, aPnt2d2);
+      ExtendPCurve (aPCurve, anEf, anEl, FirstPar, LastPar, anOffset2d);
+      aPCurve2 = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
+      aPCurve2->Translate (aTranslation);
+      BB.UpdateEdge (NE, aPCurve, aPCurve2, aSurf, aLoc, Precision::Confusion());
+      aFirstPar = aPCurve->FirstParameter();
+      aLastPar  = aPCurve->LastParameter();
+    }
 
-//=======================================================================
-//function : UpdateVertex
-//purpose  : 
-//=======================================================================
+    if (Precision::IsInfinite(aFirstPar) || Precision::IsInfinite(aLastPar))
+    {
+      Standard_Real aUmin, aUmax, aVmin, aVmax;
+      aSurf->Bounds(aUmin, aUmax, aVmin, aVmax);
+      gp_Pnt2d FirstOrigin(aUmin, aVmin);
+      gp_Pnt2d LastOrigin = IsParallelDX ? gp_Pnt2d(aUmax, aVmin) : gp_Pnt2d(aUmin, aVmax);
+      gp_Dir2d aDir = IsParallelDX ? gp::DY2d() : gp::DX2d();
+
+      Handle(Geom2d_Line) BoundLine [2];
+      BoundLine[0] = new Geom2d_Line(FirstOrigin, aDir);
+      BoundLine[1] = new Geom2d_Line(LastOrigin, aDir);
+
+      Geom2dAdaptor_Curve aGAcurve(aPCurve, aFirstPar, aLastPar);
+      Standard_Real NewPar [2];
+      NewPar[0] = Precision::Infinite();
+      NewPar[1] = Precision::Infinite();
+      for (Standard_Integer ii = 0; ii < 2; ii++)
+      {
+        Geom2dAdaptor_Curve aGAbound (BoundLine[ii]);
+        Geom2dInt_GInter anInter2d (aGAcurve, aGAbound,
+                                    Precision::Confusion(), Precision::Confusion());
+        if (anInter2d.IsDone() && anInter2d.NbPoints() > 0)
+          NewPar[ii] = anInter2d.Point(1).ParamOnFirst();
+      }
+      //Temporary
+      aFirstPar = Min(NewPar[0], NewPar[1]);
+      aLastPar  = Max(NewPar[0], NewPar[1]);
+      ///////////
+
+      Standard_Real aDelta = 0.;
+      if (IsParallelDX && aSurf->IsUClosed())
+        aDelta = ((aUmax - aUmin) - (anEl - anEf))*0.5;
+      else if (!IsParallelDX && aSurf->IsVClosed())
+        aDelta = ((aVmax - aVmin) - (anEl - anEf))*0.5;
+      if (aDelta != 0.)
+      {
+        aDelta *= 0.95;
+        aFirstPar = anEf - aDelta;
+        aLastPar  = anEl + aDelta;
+      }
+    }
+    
+    BB.Range (NE, aFirstPar, aLastPar);
 
-static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
-                                      TopoDS_Edge&  OE,
+    return Standard_True;
+  } //if (IsSeam)
+
+  if (BRep_Tool::Degenerated(E))
+  {
+    Handle(Geom2d_Curve) aPCurve;
+    Handle(Geom_Surface) aSurf;
+    TopLoc_Location aLoc;
+    Standard_Real fpar, lpar;
+    BRep_Tool::CurveOnSurface(E, aPCurve, aSurf, aLoc, fpar, lpar, 1);
+    if (aPCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+      aPCurve = (Handle(Geom2d_TrimmedCurve)::DownCast(aPCurve))->BasisCurve();
+
+    Standard_Real FirstPar = aPCurve->FirstParameter();
+    Standard_Real LastPar  = aPCurve->LastParameter();
+
+    gp_Pnt2d aPnt2d;
+    gp_Vec2d aTangent;
+    aPCurve->D1(fpar, aPnt2d, aTangent);
+    gp_Dir2d aTangDir = aTangent;
+    Standard_Real aCrossProd1 = aTangent ^ gp::DX2d(),
+      aCrossProd2 = aTangent ^ gp::DY2d();
+    Standard_Boolean IsParallelDX = (Abs(aCrossProd1) < Abs(aCrossProd2));
+    GeomAdaptor_Surface aGAsurf(aSurf);
+    Standard_Real anOffset2d = IsParallelDX ?
+      aGAsurf.UResolution(a2Offset) : aGAsurf.VResolution(a2Offset);
+  
+    if (aPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
+        (FirstPar > anEf - anOffset2d || LastPar < anEl + anOffset2d))
+    {
+      ExtendPCurve(aPCurve, anEf, anEl, FirstPar, LastPar, anOffset2d);
+      FirstPar = aPCurve->FirstParameter();
+      LastPar  = aPCurve->LastParameter();
+      BB.UpdateEdge (NE, aPCurve, aSurf, aLoc, Precision::Confusion());
+    }
+    
+    if (Precision::IsInfinite(FirstPar) || Precision::IsInfinite(LastPar))
+    {
+      Standard_Real aUmin, aUmax, aVmin, aVmax;
+      aSurf->Bounds(aUmin, aUmax, aVmin, aVmax);
+      gp_Pnt2d FirstOrigin(aUmin, aVmin);
+      gp_Pnt2d LastOrigin = IsParallelDX ? gp_Pnt2d(aUmax, aVmin) : gp_Pnt2d(aUmin, aVmax);
+      gp_Dir2d aDir = IsParallelDX ? gp::DY2d() : gp::DX2d();
+
+      Handle(Geom2d_Line) BoundLine [2];
+      BoundLine[0] = new Geom2d_Line(FirstOrigin, aDir);
+      BoundLine[1] = new Geom2d_Line(LastOrigin, aDir);
+
+      Geom2dAdaptor_Curve aGAcurve(aPCurve, FirstPar, LastPar);
+      Standard_Real NewPar [2];
+      NewPar[0] = Precision::Infinite();
+      NewPar[1] = Precision::Infinite();
+      for (Standard_Integer ii = 0; ii < 2; ii++)
+      {
+        Geom2dAdaptor_Curve aGAbound (BoundLine[ii]);
+        Geom2dInt_GInter anInter2d (aGAcurve, aGAbound,
+                                    Precision::Confusion(), Precision::Confusion());
+        if (anInter2d.IsDone() && anInter2d.NbPoints() > 0)
+          NewPar[ii] = anInter2d.Point(1).ParamOnFirst();
+      }
+      //Temporary
+      FirstPar = Min(NewPar[0], NewPar[1]);
+      LastPar  = Max(NewPar[0], NewPar[1]);
+      ///////////
+    }
+    BB.Range (NE, FirstPar, LastPar);
+
+    return Standard_True;
+  } //if (BRep_Tool::Degenerated(E))
+  
+  Standard_Real fpar, lpar;
+  Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, fpar, lpar );
+
+  Handle(Geom2d_Curve) NullPCurve;
+
+  Standard_Boolean aToProlongBefore = theToProlongBefore,
+    aToProlongAfter = theToProlongAfter;
+  Standard_Real anExtensionBefore = a2Offset, anExtensionAfter = a2Offset;
+  Standard_Integer anIndPCurve = 0;
+  for (;;)
+  {
+    anIndPCurve++;
+    Handle(Geom2d_Curve) aPCurve;
+    Handle(Geom_Surface) aSurf;
+    TopLoc_Location aLoc;
+    //Standard_Real fpar, lpar;
+    BRep_Tool::CurveOnSurface(E, aPCurve, aSurf, aLoc, fpar, lpar, anIndPCurve);
+    if (aPCurve.IsNull())
+      break;
+
+    Handle(Geom2d_TrimmedCurve) aTrCurve = new Geom2d_TrimmedCurve(aPCurve, fpar, lpar);
+    //Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
+    //Standard_Real aTol = Precision::Confusion();
+    
+    gp_Pnt2d aP2d;
+    gp_Vec2d aVec2d;
+    gp_Dir2d aTangent;
+    Handle(Geom2d_TrimmedCurve) aSegment;
+    if (aToProlongBefore)
+    {
+      aPCurve->D1 (fpar, aP2d, aVec2d);
+      aVec2d.Reverse();
+      aTangent = aVec2d;
+      Standard_Real aLenToPnt = -1, aParamOnLine;
+      Standard_Boolean IsFitted = ComputeEndOfExtension(aSurf, aP2d, aTangent, a2Offset,
+                                                        aParamOnLine, aLenToPnt, aSegment);
+      if (aLenToPnt == 0.)
+        aToProlongBefore = Standard_False;
+      
+      else if (aLenToPnt != -1 && !IsFitted &&
+               aLenToPnt < anExtensionBefore)
+        anExtensionBefore = aLenToPnt;
+      //aCompCurve.Add(aSegment, aTol);
+    }
+    if (aToProlongAfter)
+    {
+      aPCurve->D1 (lpar, aP2d, aVec2d);
+      aTangent = aVec2d;
+      Standard_Real aLenToPnt = -1, aParamOnLine;
+      Standard_Boolean IsFitted = ComputeEndOfExtension(aSurf, aP2d, aTangent, a2Offset,
+                                                        aParamOnLine, aLenToPnt, aSegment);
+      if (aLenToPnt == 0.)
+        aToProlongAfter = Standard_False;
+      
+      else if (aLenToPnt != -1 && !IsFitted &&
+               aLenToPnt < anExtensionAfter)
+        anExtensionAfter = aLenToPnt;
+      //aCompCurve.Add(aSegment, aTol);
+    }
+    /*
+    Handle(Geom2d_Curve) aNewPCurve = aCompCurve.BSplineCurve();
+    fpar = aNewPCurve->FirstParameter();
+    lpar = aNewPCurve->LastParameter();
+    
+    Handle(TColgp_HArray1OfPnt)   aPntArray = new TColgp_HArray1OfPnt(1, NCONTROL);
+    Handle(TColStd_HArray1OfReal) aParArray = new TColStd_HArray1OfReal(1, NCONTROL);
+    Standard_Real aDelta = (lpar - fpar)/(NCONTROL-1);
+    for (Standard_Integer ii = 0; ii < NCONTROL; ii++)
+    {
+      Standard_Real aPar = fpar + ii*aDelta;
+      aParArray->SetValue(ii+1, aPar);
+      gp_Pnt2d aPnt2d = aNewPCurve->Value(aPar);
+      gp_Pnt aPnt = aSurf->Value(aPnt2d.X(), aPnt2d.Y());
+      if (!aLoc.IsIdentity())
+        aPnt.Transform(aLoc.Transformation());
+      aPntArray->SetValue(ii+1, aPnt);
+    }
+    GeomAPI_Interpolate anInterp(aPntArray, aParArray, Standard_False, Precision::Confusion());
+    anInterp.Perform();
+    C3d = anInterp.Curve();
+
+    BB.UpdateEdge (NE, C3d, aTolEdge);
+    BB.UpdateEdge (NE, aNewPCurve, aSurf, aLoc, aTolEdge);
+    BB.Range (NE, fpar, lpar);
+    return Standard_True;
+    */
+  } //for (;;)
+  
+  if (C3d.IsNull())
+  {
+    Handle(Geom2d_Curve) aPCurve;
+    Handle(Geom_Surface) aSurf;
+    TopLoc_Location aLoc;
+    //Standard_Real fpar, lpar;
+    BRep_Tool::CurveOnSurface(E, aPCurve, aSurf, aLoc, fpar, lpar, 1);
+
+    Handle(TColgp_HArray1OfPnt)   aPntArray = new TColgp_HArray1OfPnt(1, NCONTROL);
+    Handle(TColStd_HArray1OfReal) aParArray = new TColStd_HArray1OfReal(1, NCONTROL);
+    Standard_Real aDelta = (lpar - fpar)/(NCONTROL-1);
+    for (Standard_Integer ii = 0; ii < NCONTROL; ii++)
+    {
+      Standard_Real aPar = fpar + ii*aDelta;
+      aParArray->SetValue(ii+1, aPar);
+      gp_Pnt2d aPnt2d = aPCurve->Value(aPar);
+      gp_Pnt aPnt = aSurf->Value(aPnt2d.X(), aPnt2d.Y());
+      if (!aLoc.IsIdentity())
+        aPnt.Transform(aLoc.Transformation());
+      aPntArray->SetValue(ii+1, aPnt);
+    }
+    GeomAPI_Interpolate anInterp(aPntArray, aParArray, Standard_False, Precision::Confusion());
+    anInterp.Perform();
+    C3d = anInterp.Curve();
+    /*
+    Geom2dAdaptor_Curve AC2d (aPCurve, fpar, lpar);
+    GeomAdaptor_Surface GAsurf (aSurf);
+    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, fpar, lpar,
+                          C3d, max_deviation, average_deviation,
+                          Continuity, MaxDegree, MaxSegment);
+    BB.UpdateEdge (NE, C3d, max_deviation);
+    */
+    BB.UpdateEdge (NE, C3d, aTolEdge);
+  }
+
+  if (C3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+    C3d = (Handle(Geom_TrimmedCurve)::DownCast(C3d))->BasisCurve();
+  
+  Standard_Real FirstPar = C3d->FirstParameter();
+  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.);
+    //Standard_Real                       aDelta = a2Offset;
+    
+    if (aToProlongBefore &&
+        FirstPar > anEf - a2Offset)
+    {
+      Standard_Real aDelta = anExtensionBefore;
+      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 Standard_True;
+    }
+    
+    if (aToProlongAfter &&
+        LastPar < anEl + a2Offset)
+    {
+      Standard_Real aDelta = anExtensionAfter;
+      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 Standard_True;
+    }
+    
+    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;
+  }
+  else if (C3d->IsClosed())
+    LastPar -= 0.05*(LastPar - FirstPar);
+  
+  BB.Range (NE, FirstPar, LastPar);
+  if (Precision::IsInfinite(FirstPar) && Precision::IsInfinite(LastPar))
+    return Standard_True;
+  
+  for (Standard_Integer ii = 1; ii <= NbPCurves; ii++)
+  {
+    Handle(Geom2d_Curve) aPCurve;
+    Handle(Geom_Surface) aSurf;
+    TopLoc_Location aLoc;
+    //Standard_Real fpar, lpar;
+    BRep_Tool::CurveOnSurface(E, aPCurve, aSurf, aLoc, fpar, lpar, ii);
+    GeomAdaptor_Surface aGAsurf(aSurf);
+    if (aGAsurf.GetType() == GeomAbs_Plane)
+      BB.UpdateEdge (NE, NullPCurve, aSurf, aLoc, 0.);
+    else
+    {
+      ShapeConstruct_ProjectCurveOnSurface aToolProj;
+      aToolProj.Init(aSurf, aTolEdge);
+      Handle(Geom2d_Curve) aNewPCurve;
+      aToolProj.Perform(C3d, FirstPar, LastPar, aNewPCurve);
+      BB.UpdateEdge (NE, aNewPCurve, aSurf, aLoc, 0.);
+    }
+  }
+  
+  return Standard_True;
+}
+
+//=======================================================================
+//function : UpdateVertex
+//purpose  : 
+//=======================================================================
+
+static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
+                                      TopoDS_Edge&  OE,
                                       TopoDS_Edge&  NE,
                                       Standard_Real TolConf)
 {
@@ -1579,7 +1539,19 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
   //-----------------------------------------------
   // Intersection of edges 2*2.
   //-----------------------------------------------
-  const TopTools_ListOfShape&        LE = AsDes->Descendant(F);
+  TopTools_ListOfShape& LE = AsDes->ChangeDescendant(F);
+  it1LE.Initialize(LE);
+  while (it1LE.More())
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge(it1LE.Value());
+    Standard_Real aFirst, aLast;
+    Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, F, aFirst, aLast);
+    if (aPCurve.IsNull())
+      LE.Remove(it1LE);
+    else
+      it1LE.Next();
+  }
+  
   TopoDS_Vertex                      V1,V2;
   Standard_Integer                   j, i = 1;
   BRepAdaptor_Surface BAsurf(F);
@@ -1654,27 +1626,37 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
   TopTools_IndexedMapOfShape&   FacesWithVerts,
   BRepAlgo_Image&               theImageVV,
   TopTools_DataMapOfShapeListOfShape& theEdgeIntEdges,
-  TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
+  TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+  BRepOffset_DataMapOfFaceMapEE& theFaceEdgeEdge,
+  TopTools_IndexedDataMapOfShapeListOfShape& theEFmap)
 {  
-
-  TopTools_DataMapOfShapeListOfShape MVE;
-  BRepOffset_Tool::MapVertexEdges(FI,MVE);
+  //TopTools_DataMapOfShapeListOfShape MVE;
+  //BRepOffset_Tool::MapVertexEdges(FI,MVE);
+  TopTools_IndexedDataMapOfShapeListOfShape MVE;
+  TopExp::MapShapesAndUniqueAncestors (FI, TopAbs_VERTEX, TopAbs_EDGE, MVE);
 
   //---------------------
   // Extension of edges.
   //---------------------
   TopoDS_Edge  NE;
-  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
-  for  ( ; it.More(); it.Next()) {
-    const TopTools_ListOfShape&  L = it.Value();
+  //TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
+  //for  ( ; it.More(); it.Next()) {
+  for (Standard_Integer ii = 1; ii <= MVE.Extent(); ii++) {
+    //Temporary
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex(MVE.FindKey(ii));
+    ///////////
+    const TopTools_ListOfShape& aEdges = MVE(ii); //it.Value();
     Standard_Boolean   YaBuild = 0;
-    TopTools_ListIteratorOfListOfShape itL(L);
-    for (; itL.More(); itL.Next()) {
-      YaBuild = Build.IsBound(itL.Value());
+    TopTools_ListIteratorOfListOfShape itL (aEdges);
+    for (; itL.More(); itL.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itL.Value());
+      YaBuild = Build.IsBound(anEdge);
       if (YaBuild) break;
     }
-    if (YaBuild) {
-      for (itL.Initialize(L); itL.More(); itL.Next()) {
+    if (YaBuild)
+    {
+      for (itL.Initialize(aEdges); itL.More(); itL.Next()) {
         const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
         if (EI.Orientation() != TopAbs_FORWARD &&
             EI.Orientation() != TopAbs_REVERSED)
@@ -1682,7 +1664,29 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
         TopoDS_Shape aLocalShape = OFI.Generated(EI);
         const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
         if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
-          if (!ExtentEdge(OE, NE, Offset))
+          Standard_Boolean ToProlong [2] = {Standard_True, Standard_True};
+          TopoDS_Vertex aVV [2];
+          TopExp::Vertices (EI, aVV[0], aVV[1]);
+          for (Standard_Integer ind = 0; ind < 2; ind++)
+          {
+            const TopTools_ListOfShape& aElist = MVE.FindFromKey(aVV[ind]);
+            Standard_Boolean aBuildFound = Standard_False;
+            
+            TopTools_ListIteratorOfListOfShape anItl(aElist);
+            for (; anItl.More(); anItl.Next())
+            {
+              const TopoDS_Edge& anEdge = TopoDS::Edge(anItl.Value());
+              if (anEdge.IsSame(EI))
+                continue;
+              if (BRep_Tool::Degenerated(anEdge))
+                ToProlong[ind] = Standard_False;
+              else if (Build.IsBound(anEdge))
+                aBuildFound = Standard_True;
+            }
+            if (!aBuildFound)
+              ToProlong[ind] = Standard_False;
+          }
+          if (!ExtentEdge(OE, NE, Offset, ToProlong[0], ToProlong[1]))
           {
             return Standard_False;
           }
@@ -1696,10 +1700,21 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
   if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
   //
   BRepAdaptor_Surface BAsurf(FIO);
-  
+  BRep_Builder aBB;
+
+  TopTools_DataMapOfShapeListOfShape aEdgeElistMap;
+
   TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
   for (; exp.More(); exp.Next()) {
     const TopoDS_Wire&     W = TopoDS::Wire(exp.Current());
+
+    TopTools_DataMapOfShapeShape aEdgeNewEdgeMap;
+    TopTools_DataMapOfShapeShape aEEmap;
+    TopTools_DataMapOfShapeShape anEdgeVer1map;
+    TopTools_DataMapOfShapeShape anEdgeVer2map;
+    TopTools_DataMapOfShapeReal  anEdgePar1map;
+    TopTools_DataMapOfShapeReal  anEdgePar2map;
+    
     BRepTools_WireExplorer wexp;
     Standard_Boolean       end = Standard_False ;
     TopoDS_Edge            FirstE,CurE,NextE;
@@ -1720,7 +1735,8 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
       else {
         NextE = FirstE; end = Standard_True;
       }
-      if (CurE.IsSame(NextE)) continue;
+      if (CurE.IsSame(NextE))
+        continue;
 
       TopoDS_Vertex Vref = CommonVertex(CurE, NextE); 
 
@@ -1739,8 +1755,9 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
       TopoDS_Shape         NE1,NE2;
       TopTools_SequenceOfShape NE1seq, NE2seq;
       TopAbs_Orientation   anOr1 = TopAbs_EXTERNAL, anOr2 = TopAbs_EXTERNAL;
-      
+
       Standard_Integer aChoice = 0;
+      TopoDS_Edge InitE2;
       if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
         aChoice = 1;
         NE1 = Build(CurE );
@@ -1749,6 +1766,8 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
         GetEdgesOrientedInFace (NE2, FIO, theAsDes, NE2seq);
         anOr1 = TopAbs_REVERSED;
         anOr2 = TopAbs_FORWARD;
+        //anOr1 = anOrVonEcur;
+        //anOr2 = anOrVonEnext;
       }
       else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
         aChoice = 2;
@@ -1757,8 +1776,12 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
         NE2.Orientation (NextE.Orientation());
         GetEdgesOrientedInFace (NE1, FIO, theAsDes, NE1seq);
         NE2seq.Append (NE2);
+        InitE2 = NEO;
+        InitE2.Orientation (NextE.Orientation());
         anOr1 = TopAbs_REVERSED;
         anOr2 = TopAbs_FORWARD;
+        //anOr1 = anOrVonEcur;
+        //anOr2 = anOrVonEnext;
       }
       else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
         aChoice = 3;
@@ -1767,8 +1790,12 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
         NE2.Orientation (CurE.Orientation());
         GetEdgesOrientedInFace (NE1, FIO, theAsDes, NE1seq);
         NE2seq.Append (NE2);
+        InitE2 = CEO;
+        InitE2.Orientation (CurE.Orientation());
         anOr1 = TopAbs_FORWARD;
         anOr2 = TopAbs_REVERSED;
+        //anOr1 = anOrVonEnext;
+        //anOr2 = anOrVonEcur;
       }
       else {
         DoInter = 0;
@@ -1789,15 +1816,30 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
           aE1 = TopoDS::Edge (NE1seq.First());
           aE2 = TopoDS::Edge (NE2seq.Last());
         }
+        
+        //Correct orientation of edges
+        /*
+        if (ToReverse1)
+          aE1.Reverse();
+        if (ToReverse2)
+          aE2.Reverse();
+        */
+        //////////////////////////////
+        
+        AddEdgeWithFaceToMap(aE1, FIO, theEFmap);
+        AddEdgeWithFaceToMap(aE2, FIO, theEFmap);
 
         if (aE1.Orientation() == TopAbs_REVERSED)
           anOr1 = TopAbs::Reverse(anOr1);
         if (aE2.Orientation() == TopAbs_REVERSED)
           anOr2 = TopAbs::Reverse(anOr2);
-
+        
+        TopoDS_Vertex aVforE1, aVforE2;
+        Standard_Real aParForE1, aParForE2;
         RefEdgeInter(FIO, BAsurf, aE1, aE2, anOr1, anOr2, AsDes2d,
-                     Tol, Standard_True, Vref, theImageVV, theDMVV, bCoincide);
-
+                     Tol, Standard_True, Vref, theImageVV, theDMVV, bCoincide,
+                     aVforE1, aVforE2, aParForE1, aParForE2);
+        
         if (theEdgeIntEdges.IsBound(aE1))
           theEdgeIntEdges(aE1).Append(aE2);
         else
@@ -1815,6 +1857,89 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
           theEdgeIntEdges.Bind (aE2, aElist);
         }
         
+        TopoDS_Edge aNewE1, aNewE2;
+        
+        //Process new edge for <aE1>
+        if (aEEmap.IsBound(aE1))
+          aNewE1 = TopoDS::Edge(aEEmap(aE1));
+        else
+        {
+          aNewE1 = TopoDS::Edge(aE1.EmptyCopied());
+          aNewE1.Orientation(TopAbs_FORWARD);
+          aEEmap.Bind(aE1, aNewE1);
+        }
+        if (aVforE1.Orientation() == TopAbs_FORWARD)
+        {
+          anEdgeVer1map.Bind (aNewE1, aVforE1);
+          anEdgePar1map.Bind (aNewE1, aParForE1);
+        }
+        else
+        {
+          anEdgeVer2map.Bind (aNewE1, aVforE1);
+          anEdgePar2map.Bind (aNewE1, aParForE1);
+        }
+        if (NE1seq.Length() > 1)
+        {
+          //must add constant vertex
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices (aE1, aV1, aV2);
+          Standard_Real aFpar, aLpar;
+          BRep_Tool::Range (aE1, aFpar, aLpar);
+          if (aVforE1.Orientation() == TopAbs_FORWARD)
+          {
+            anEdgeVer2map.Bind (aNewE1, aV2);
+            anEdgePar2map.Bind (aNewE1, aLpar);
+          }
+          else
+          {
+            anEdgeVer1map.Bind (aNewE1, aV1);
+            anEdgePar1map.Bind (aNewE1, aFpar);
+          }
+        }
+        aEdgeNewEdgeMap.Bind(aE1, aNewE1);
+        
+        //Process new edge for <aE2>
+        if (aEEmap.IsBound(aE2))
+          aNewE2 = TopoDS::Edge(aEEmap(aE2));
+        else
+        {
+          aNewE2 = TopoDS::Edge(aE2.EmptyCopied());
+          aNewE2.Orientation(TopAbs_FORWARD);
+          aEEmap.Bind(aE2, aNewE2);
+        }
+        if (!InitE2.IsNull())
+        {
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices (InitE2, aV1, aV2);
+          Standard_Real aFpar, aLpar;
+          BRep_Tool::Range (InitE2, aFpar, aLpar);
+          
+          if (aVforE2.Orientation() == TopAbs_FORWARD &&
+              !anEdgeVer2map.IsBound(aNewE2))
+          {
+            anEdgeVer2map.Bind (aNewE2, aV2);
+            anEdgePar2map.Bind (aNewE2, aLpar);
+          }
+          else if (aVforE2.Orientation() == TopAbs_REVERSED &&
+                   !anEdgeVer1map.IsBound(aNewE2))
+          {
+            anEdgeVer1map.Bind (aNewE2, aV1);
+            anEdgePar1map.Bind (aNewE2, aFpar);
+          }
+        }
+        if (aVforE2.Orientation() == TopAbs_FORWARD)
+        {
+          anEdgeVer1map.Bind (aNewE2, aVforE2);
+          anEdgePar1map.Bind (aNewE2, aParForE2);
+        }
+        else
+        {
+          anEdgeVer2map.Bind (aNewE2, aVforE2);
+          anEdgePar2map.Bind (aNewE2, aParForE2);
+        }
+        aEdgeNewEdgeMap.Bind(aE2, aNewE2);
+        
+
         //
         // check if some of the offset edges have been
         // generated out of the common vertex
@@ -1834,11 +1959,111 @@ Standard_Boolean BRepOffset_Inter2d::ConnexIntByInt
             UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
             AsDes2d->Add    (MES(NEO),V);
           }
+
+          Standard_Real fpar1, lpar1, fpar2, lpar2;
+          BRep_Tool::Range(CEO, fpar1, lpar1);
+          BRep_Tool::Range(NEO, fpar2, lpar2);
+
+          TopoDS_Vertex aV1, aV2;
+          TopExp::Vertices (CEO, aV1, aV2);
+          if (aV1.IsSame(aV2)) //CEO is closed
+          {
+            anEdgeVer1map.Bind (CEO, V.Oriented(TopAbs_FORWARD));
+            anEdgeVer2map.Bind (CEO, V.Oriented(TopAbs_REVERSED));
+            if (CEO.Orientation() == TopAbs_FORWARD)
+              anEdgePar2map.Bind (CEO, lpar1);
+            else
+              anEdgePar1map.Bind (CEO, fpar1);
+          }
+          else
+          {
+            if (CEO.Orientation() == TopAbs_FORWARD)
+            {
+              anEdgeVer2map.Bind (CEO, V.Oriented(TopAbs_REVERSED));
+              anEdgePar2map.Bind (CEO, lpar1);
+            }
+            else
+            {
+              anEdgeVer1map.Bind (CEO, V.Oriented(TopAbs_FORWARD));
+              anEdgePar1map.Bind (CEO, fpar1);
+            }
+          }
+
+          TopExp::Vertices (NEO, aV1, aV2);
+          if (aV1.IsSame(aV2)) //NEO is closed
+          {
+            anEdgeVer1map.Bind (NEO, V.Oriented(TopAbs_FORWARD));
+            anEdgeVer2map.Bind (NEO, V.Oriented(TopAbs_REVERSED));
+            if (NEO.Orientation() == TopAbs_FORWARD)
+              anEdgePar1map.Bind (NEO, fpar2);
+            else
+              anEdgePar2map.Bind (NEO, lpar2);
+          }
+          else
+          {
+            if (NEO.Orientation() == TopAbs_FORWARD)
+            {
+              anEdgeVer1map.Bind (NEO, V.Oriented(TopAbs_FORWARD));
+              anEdgePar1map.Bind (NEO, fpar2);
+            }
+            else
+            {
+              anEdgeVer2map.Bind (NEO, V.Oriented(TopAbs_REVERSED));
+              anEdgePar2map.Bind (NEO, lpar2);
+            }
+          }
+          
+          aEdgeNewEdgeMap.Bind(CEO, CEO);
+          aEdgeNewEdgeMap.Bind(NEO, NEO);
         }
       }
       CurE = wexp.Current();
+      //ToReverse1 = ToReverse2;
     }
+
+    //Update Edge-EdgeList map
+    TopTools_DataMapIteratorOfDataMapOfShapeShape itmap(aEdgeNewEdgeMap);
+    for (; itmap.More(); itmap.Next())
+    {
+      const TopoDS_Shape& anEdge = itmap.Key();
+      TopoDS_Edge aNewEdge = TopoDS::Edge(itmap.Value());
+      if (anEdgeVer1map.IsBound(aNewEdge) &&
+          anEdgeVer2map.IsBound(aNewEdge))
+      {
+        Standard_Integer NbVer = 0;
+        TopoDS_Iterator itv(aNewEdge);
+        for (; itv.More(); itv.Next())
+          NbVer++;
+        if (NbVer < 2)
+        {
+          TopoDS_Vertex aV1 = TopoDS::Vertex(anEdgeVer1map(aNewEdge));
+          TopoDS_Vertex aV2 = TopoDS::Vertex(anEdgeVer2map(aNewEdge));
+          aBB.Add (aNewEdge, aV1);
+          aBB.Add (aNewEdge, aV2);
+          Standard_Real aFpar = anEdgePar1map(aNewEdge);
+          Standard_Real aLpar = anEdgePar2map(aNewEdge);
+          aBB.Range (aNewEdge, aFpar, aLpar);
+        }
+
+        TopTools_ListOfShape aElist;
+        aElist.Append(aNewEdge);
+        aEdgeElistMap.Bind (anEdge, aElist);
+      }
+    }
+
+    //Create a new wire
+    /*
+    TopoDS_Wire aNewWire;
+    aBB.MakeWire(aNewWire);
+    TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap(aEdgeElistMap);
+    for (; itmap.More(); itmap.Next())
+      aBB.Add (aNewWire, itmap.Value().First());
+    aNewWire.Orientation (W.Orientation());
+    */
   }
+
+  theFaceEdgeEdge.Bind(FIO, aEdgeElistMap);
+  
   return Standard_True;
 }
 
@@ -1944,8 +2169,11 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
         for (Exp1.Init(NE1, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
           const TopoDS_Edge& aE1 = TopoDS::Edge(Exp1.Current());
           BRepAlgo_Image anEmptyImage;
+          TopoDS_Vertex aVforE1, aVforE2;
+          Standard_Real aParForE1, aParForE2;
           RefEdgeInter(FIO, BAsurf, aE1, aE3, anOr1, anOr2, AsDes2d,
-                       Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide);
+                       Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide,
+                       aVforE1, aVforE2, aParForE1, aParForE2);
           if (bCoincide) {
             // in case of coincidence trim the edge E3 the same way as E1
             Store(aE3, AsDes2d->Descendant(aE1), Tol, Standard_True, AsDes2d, theDMVV);
@@ -1956,8 +2184,11 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
         for (Exp1.Init(NE2, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
           const TopoDS_Edge& aE2 = TopoDS::Edge(Exp1.Current());
           BRepAlgo_Image anEmptyImage;
+          TopoDS_Vertex aVforE1, aVforE2;
+          Standard_Real aParForE1, aParForE2;
           RefEdgeInter(FIO, BAsurf, aE2, aE3, anOr1, anOr2, AsDes2d,
-                       Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide);
+                       Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide,
+                       aVforE1, aVforE2, aParForE1, aParForE2);
           if (bCoincide) {
             // in case of coincidence trim the edge E3 the same way as E2
             Store(aE3, AsDes2d->Descendant(aE2), Tol, Standard_True, AsDes2d, theDMVV);
@@ -1976,8 +2207,11 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
           const TopoDS_Edge& aE3Next = TopoDS::Edge(Exp1.Current());
           if (aME.Contains(aE3Next)) {
             BRepAlgo_Image anEmptyImage;
+            TopoDS_Vertex aVforE1, aVforE2;
+            Standard_Real aParForE1, aParForE2;
             RefEdgeInter(FIO, BAsurf, aE3Next, aE3, anOr1, anOr2, AsDes2d,
-                         Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide);
+                         Tol, Standard_True, Vref, anEmptyImage, theDMVV, bCoincide,
+                         aVforE1, aVforE2, aParForE1, aParForE2);
           }
         }
       }
@@ -2049,7 +2283,38 @@ Standard_Boolean BRepOffset_Inter2d::FuseVertices (const TopTools_IndexedDataMap
         Standard_Real aT; 
         if (!BRep_Tool::Parameter(aVOldInt, aE, aT))
         {
-          return Standard_False;
+          BRepAdaptor_Curve aBAcurve(aE);
+          gp_Pnt aPnt = BRep_Tool::Pnt(aVOldInt);
+          Extrema_ExtPC aProjector(aPnt, aBAcurve, Precision::Confusion());
+          gp_Pnt aPnt1, aPnt2;
+          Standard_Real aSqDist [4];
+          Standard_Real aParams [4];
+          aParams[1] = aBAcurve.FirstParameter();
+          aParams[2] = aBAcurve.LastParameter();
+          aProjector.TrimmedSquareDistances(aSqDist[1], aSqDist[2], aPnt1, aPnt2);
+          aSqDist[3] = RealLast();
+          if (aProjector.IsDone())
+          {
+            for (Standard_Integer ind = 1; ind <= aProjector.NbExt(); ind++)
+            {
+              Standard_Real aProjSqDist = aProjector.SquareDistance(ind);
+              if (aProjSqDist < aSqDist[3])
+              {
+                aSqDist[3] = aProjSqDist;
+                aParams[3] = aProjector.Point(ind).Parameter();
+              }
+            }
+          }
+          Standard_Real aMinSqDist = RealLast();
+          for (Standard_Integer ii = 1; ii <= 3; ii++)
+            if (aSqDist[ii] < aMinSqDist)
+            {
+              aMinSqDist = aSqDist[ii];
+              aT = aParams[ii];
+            }
+
+          if (aMinSqDist > aTolE)
+            return Standard_False;
         }
         aBB.UpdateVertex(aVNewInt, aT, aE, aTolE);
       }
@@ -2064,3 +2329,343 @@ Standard_Boolean BRepOffset_Inter2d::FuseVertices (const TopTools_IndexedDataMap
   }
   return Standard_True;
 }
+
+static Standard_Boolean ExtendPCurve(Handle(Geom2d_Curve)& thePCurve,
+                                     Standard_Real         theFirstOnEdge,
+                                     Standard_Real         theLastOnEdge,
+                                     Standard_Real         theFirstPar,
+                                     Standard_Real         theLastPar,
+                                     Standard_Real         theDelta)
+{
+  Handle(Geom2d_TrimmedCurve) aTrPCurve = 
+    new Geom2d_TrimmedCurve(thePCurve, theFirstPar, theLastPar);
+  
+  // The curve is not prolonged on begin or end.
+  // Trying to prolong it adding a segment to its bound.
+  gp_Pnt2d                              aPBnd;
+  gp_Vec2d                              aVBnd;
+  gp_Pnt2d                              aPBeg;
+  gp_Dir2d                              aDBnd;
+  Handle(Geom2d_Line)                   aLin;
+  Handle(Geom2d_TrimmedCurve)           aSegment;
+  Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrPCurve, Convert_RationalC1);
+  Standard_Real                         aTol = Precision::Confusion();
+  //Standard_Real                       aDelta = Max(a2Offset, 1.);
+  //Standard_Real                       aDelta = anOffset2d;
+  
+  if (theFirstPar > theFirstOnEdge - theDelta) {
+    thePCurve->D1 (theFirstPar, aPBnd, aVBnd);
+    aDBnd.SetXY (aVBnd.XY());
+    aPBeg    = aPBnd.Translated (gp_Vec2d(-theDelta*aDBnd.XY()));
+    aLin     = new Geom2d_Line (aPBeg, aDBnd);
+    aSegment = new Geom2d_TrimmedCurve (aLin, 0, theDelta);
+    
+    if (!aCompCurve.Add(aSegment, aTol))
+      return Standard_False;
+  }
+  
+  if (theLastPar < theLastOnEdge + theDelta) {
+    thePCurve->D1 (theLastPar, aPBeg, aVBnd);
+    aDBnd.SetXY (aVBnd.XY());
+    aLin     = new Geom2d_Line (aPBeg, aDBnd);
+    aSegment = new Geom2d_TrimmedCurve (aLin, 0, theDelta);
+    
+    if (!aCompCurve.Add (aSegment, aTol))
+      return Standard_False;
+  }
+  
+  thePCurve = aCompCurve.BSplineCurve();
+  return Standard_True;
+}
+
+static Standard_Boolean ComputeEndOfExtension(const Handle(Geom_Surface)&  theSurf,
+                                              const gp_Pnt2d&              theStartPoint,
+                                              const gp_Dir2d&              theTangent,
+                                              const Standard_Real          the2Offset,
+                                              //gp_Pnt2d&                   theEndPoint,
+                                              Standard_Real&               theParamOnEnd,
+                                              Standard_Real&               theLenToEnd,
+                                              Handle(Geom2d_TrimmedCurve)& theSegment)
+{
+  Standard_Real aUmin, aUmax, aVmin, aVmax;
+  theSurf->Bounds(aUmin, aUmax, aVmin, aVmax);
+
+  Handle(Geom2d_Line) aLine;
+  Handle(Geom2d_Curve) BoundLines [4];
+  if (!Precision::IsInfinite(aUmin) && !Precision::IsInfinite(aVmin) &&
+      !Precision::IsInfinite(aUmax) && !Precision::IsInfinite(aVmax))
+  {
+    gp_Pnt2d anOrigin(aUmin, aVmin);
+    aLine = new Geom2d_Line(anOrigin, gp::DX2d());
+    BoundLines[0] = new Geom2d_TrimmedCurve(aLine, 0., aUmax-aUmin);
+    aLine = new Geom2d_Line(anOrigin, gp::DY2d());
+    BoundLines[1] = new Geom2d_TrimmedCurve(aLine, 0., aVmax-aVmin);
+    aLine = new Geom2d_Line(gp_Pnt2d(aUmin, aVmax), gp::DX2d());
+    BoundLines[2] = new Geom2d_TrimmedCurve(aLine, 0., aUmax-aUmin);
+    aLine = new Geom2d_Line(gp_Pnt2d(aUmax, aVmin), gp::DY2d());
+    BoundLines[3] = new Geom2d_TrimmedCurve(aLine, 0., aVmax-aVmin);
+  }
+  else
+    return Standard_True; //infinite case
+
+  Standard_Real aMaxSize = Max(aUmax - aUmin, aVmax - aVmin);
+  aMaxSize *= 2;
+  aLine = new Geom2d_Line(theStartPoint, theTangent);
+  //Handle(Geom_Curve) anExtension = new Geom2d_TrimmedCurve(aLine, 0., aMaxSize);
+  Geom2dAdaptor_Curve aGAextension(aLine, 0., aMaxSize);
+
+  gp_Pnt2d aPointOnBound;
+  Standard_Real anEndParam = Precision::Infinite();
+  for (Standard_Integer ii = 0; ii < 4; ii++)
+  {
+    Geom2dAdaptor_Curve aGAbound(BoundLines[ii]);
+    Geom2dInt_GInter Inters(aGAextension, aGAbound, Precision::PConfusion(), Precision::PConfusion());
+    if (Inters.IsDone() && !Inters.IsEmpty())
+    {
+      if (Inters.NbPoints() == 0) //coincidense
+      {
+        gp_Vec2d aVec = BoundLines[ii]->DN(0., 1);
+        gp_Dir2d aDir = aVec;
+        Standard_Real aScalProd = theTangent * aVec;
+        if (aScalProd > 0)
+          aPointOnBound = BoundLines[ii]->Value(BoundLines[ii]->LastParameter());
+        else
+          aPointOnBound = BoundLines[ii]->Value(BoundLines[ii]->FirstParameter());
+        gp_Ax2d anAxis(theStartPoint, theTangent);
+        anEndParam = ElCLib::LineParameter (anAxis, aPointOnBound);
+      }
+      else
+      {
+        const IntRes2d_IntersectionPoint& anIntPoint = Inters.Point(1);
+        aPointOnBound = anIntPoint.Value();
+        anEndParam = anIntPoint.ParamOnFirst();
+      }
+      break;
+    }
+  }
+
+  Standard_Boolean IsFitted = Standard_False;
+  theLenToEnd = 0.;
+
+  if (anEndParam < Precision::Confusion())
+    return IsFitted;
+  
+  const Standard_Integer NCONTROL = 23;
+  Standard_Real aDelta = anEndParam / (NCONTROL-1);
+  gp_Pnt aPrevPnt;
+  for (Standard_Integer ii = 0; ii < NCONTROL; ii++)
+  {
+    //Standard_Real aPar = ii*aDelta;
+    theParamOnEnd = ii*aDelta;
+    gp_Pnt2d aPnt2d = aLine->Value(theParamOnEnd);
+    gp_Pnt aPnt = theSurf->Value(aPnt2d.X(), aPnt2d.Y());
+    if (ii > 0)
+    {
+      theLenToEnd += aPrevPnt.Distance(aPnt);
+      if (theLenToEnd >= the2Offset)
+      {
+        IsFitted = Standard_True;
+        break;
+      }
+    }
+    aPrevPnt = aPnt;
+  }
+
+  theSegment = new Geom2d_TrimmedCurve(aLine, 0., theParamOnEnd);
+  return IsFitted;
+}
+
+static void AddEdgeWithFaceToMap(const TopoDS_Edge& theEdge,
+                                 const TopoDS_Face& theFace,
+                                 TopTools_IndexedDataMapOfShapeListOfShape& theEFmap)
+{
+  if (theEFmap.Contains(theEdge))
+  {
+    TopTools_ListOfShape& aFlist = theEFmap.ChangeFromKey(theEdge);
+    TopTools_ListIteratorOfListOfShape itface(aFlist);
+    Standard_Boolean IsFaceNew = Standard_True;
+    for (; itface.More(); itface.Next())
+      if (theFace.IsSame(itface.Value()))
+        IsFaceNew = Standard_False;
+    if (IsFaceNew)
+      aFlist.Append(theFace);
+  }
+  else
+  {
+    TopTools_ListOfShape aFlist;
+    aFlist.Append(theFace);
+    theEFmap.Add(theEdge, aFlist);
+  }
+}
+
+static Standard_Boolean OrientationInEdge(const TopoDS_Vertex& theVertex,
+                                          const TopoDS_Edge&   theEdge,
+                                          TopAbs_Orientation&  theOr)
+{
+  theOr = TopAbs_EXTERNAL;
+  
+  TopoDS_Edge anEdge = theEdge;
+  anEdge.Orientation(TopAbs_FORWARD);
+
+  Standard_Integer NbFound = 0;
+  TopoDS_Iterator itv(anEdge);
+  for (; itv.More(); itv.Next())
+  {
+    const TopoDS_Shape& aVertex = itv.Value();
+    if (aVertex.IsSame(theVertex))
+    {
+      theOr = aVertex.Orientation();
+      NbFound++;
+    }
+  }
+
+  return (NbFound == 1);
+}
+
+static Standard_Integer DefineClosedness(const TopoDS_Face& theFace)
+{
+  TopExp_Explorer anExplo (theFace, TopAbs_EDGE);
+  for (; anExplo.More(); anExplo.Next())
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+    if (BRepTools::IsReallyClosed(anEdge, theFace))
+    {
+      Standard_Real fpar, lpar;
+      Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
+      gp_Vec2d aTangent = aPCurve->DN(fpar, 1);
+      Standard_Real aCrossProd1 = aTangent ^ gp::DX2d();
+      Standard_Real aCrossProd2 = aTangent ^ gp::DY2d();
+      if (Abs(aCrossProd2) < Abs(aCrossProd1)) //pcurve is parallel to OY
+        return 1;
+      else
+        return 2;
+    }
+  }
+
+  return 0;
+}
+
+static void GetEdgesOrientedInFace(const TopoDS_Shape& theShape,
+                                   const TopoDS_Face&  theFace,
+                                   const Handle(BRepAlgo_AsDes)& theAsDes,
+                                   TopTools_SequenceOfShape&     theSeqEdges)
+{
+  const TopTools_ListOfShape& aEdges = theAsDes->Descendant (theFace);
+
+  TopExp_Explorer anExplo (theShape, TopAbs_EDGE);
+  for (; anExplo.More(); anExplo.Next())
+  {
+    const TopoDS_Shape& anEdge = anExplo.Current();
+    TopTools_ListIteratorOfListOfShape itl (aEdges);
+    for (; itl.More(); itl.Next())
+    {
+      const TopoDS_Shape& anEdgeInFace = itl.Value();
+      if (anEdgeInFace.IsSame(anEdge))
+      {
+        theSeqEdges.Append (anEdgeInFace);
+        break;
+      }
+    }
+  }
+
+  if (theSeqEdges.Length() == 1)
+    return;
+
+  TopTools_IndexedDataMapOfShapeListOfShape aVEmap;
+  for (Standard_Integer ii = 1; ii <= theSeqEdges.Length(); ii++)
+    TopExp::MapShapesAndAncestors (theSeqEdges(ii), TopAbs_VERTEX, TopAbs_EDGE, aVEmap);
+
+  TopoDS_Vertex aFirstVertex;
+  TopoDS_Edge aFirstEdge;
+  for (Standard_Integer ii = 1; ii <= aVEmap.Extent(); ii++)
+  {
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVEmap.FindKey(ii));
+    const TopTools_ListOfShape& aElist = aVEmap(ii);
+    if (aElist.Extent() == 1)
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(aElist.First());
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices(anEdge, aV1, aV2, Standard_True); //with orientation
+      if (aV1.IsSame(aVertex))
+      {
+        aFirstVertex = aVertex;
+        aFirstEdge = anEdge;
+        break;
+      }
+    }
+  }
+
+  if (aFirstEdge.IsNull()) //closed set of edges
+  {
+    //Standard_Real aPeriod = 0.;
+    Standard_Integer IndCoord = DefineClosedness (theFace);
+    /*
+    BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
+    if (IndCoord == 1)
+      aPeriod = aBAsurf.LastUParameter() - aBAsurf.FirstUParameter();
+    else if (IndCoord == 2)
+      aPeriod = aBAsurf.LastVParameter() - aBAsurf.FirstVParameter();
+    */
+    
+    if (IndCoord != 0)
+    {
+      Standard_Real aMaxDelta = 0.;
+      for (Standard_Integer ii = 1; ii <= aVEmap.Extent(); ii++)
+      {
+        const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVEmap.FindKey(ii));
+        const TopTools_ListOfShape& aElist = aVEmap(ii);
+        const TopoDS_Edge& anEdge1 = TopoDS::Edge(aElist.First());
+        const TopoDS_Edge& anEdge2 = TopoDS::Edge(aElist.Last());
+        Standard_Real aParam1 = BRep_Tool::Parameter(aVertex, anEdge1);
+        Standard_Real aParam2 = BRep_Tool::Parameter(aVertex, anEdge2);
+        BRepAdaptor_Curve2d aBAcurve1 (anEdge1, theFace);
+        BRepAdaptor_Curve2d aBAcurve2 (anEdge2, theFace);
+        gp_Pnt2d aPnt1 = aBAcurve1.Value(aParam1);
+        gp_Pnt2d aPnt2 = aBAcurve2.Value(aParam2);
+        Standard_Real aDelta = Abs(aPnt1.Coord(IndCoord) - aPnt2.Coord(IndCoord));
+        if (aDelta > aMaxDelta)
+        {
+          aMaxDelta = aDelta;
+          aFirstVertex = aVertex;
+        }
+      }
+      const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aFirstVertex);
+      TopTools_ListIteratorOfListOfShape itl (aElist);
+      for (; itl.More(); itl.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+        TopoDS_Vertex aV1, aV2;
+        TopExp::Vertices(anEdge, aV1, aV2, Standard_True); //with orientation
+        if (aV1.IsSame(aFirstVertex))
+        {
+          aFirstEdge = anEdge;
+          break;
+        }
+      }
+    }
+  }
+
+  Standard_Integer aNbEdges = theSeqEdges.Length();
+  theSeqEdges.Clear();
+  theSeqEdges.Append (aFirstEdge);
+  TopoDS_Edge anEdge = aFirstEdge;
+  for (;;)
+  {
+    TopoDS_Vertex aLastVertex = TopExp::LastVertex (anEdge, Standard_True); //with orientation
+    if (aLastVertex.IsSame(aFirstVertex))
+      break;
+    
+    const TopTools_ListOfShape& aElist = aVEmap.FindFromKey(aLastVertex);
+    if (aElist.Extent() == 1)
+      break;
+    
+    if (aElist.First().IsSame(anEdge))
+      anEdge = TopoDS::Edge(aElist.Last());
+    else
+      anEdge = TopoDS::Edge(aElist.First());
+
+    theSeqEdges.Append (anEdge);
+    if (theSeqEdges.Length() == aNbEdges)
+      break;
+  }
+}
index 850a674c2009e38987abb7bb180df3b5a345a61c..163f02c7ef3417af0c1be598af20f2d8aec46852 100644 (file)
@@ -21,7 +21,8 @@
 #include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-
+#include <TopTools_IndexedDataMapOfShapeShape.hxx>
+#include <BRepOffset_DataMapOfFaceMapEE.hxx>
 class BRepAlgo_AsDes;
 class BRepAlgo_Image;
 class BRepOffset_Analyse;
@@ -68,7 +69,9 @@ public:
                                                           TopTools_IndexedMapOfShape& FacesWithVerts,
                                                           BRepAlgo_Image& theImageVV,
                                                           TopTools_DataMapOfShapeListOfShape& theEdgeIntEdges,
-                                                          TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
+                                                          TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+                                                          BRepOffset_DataMapOfFaceMapEE& theFaceEdgeEdge,
+                                                          TopTools_IndexedDataMapOfShapeListOfShape& theEFmap);
 
   //! Computes the intersection between the offset edges generated
   //! from vertices and stored into AsDes as descendants of the <FI>.
@@ -94,9 +97,11 @@ public:
                                                         BRepAlgo_Image&               theImageVV);
                                                         
   //! extents the edge
-  Standard_EXPORT static Standard_Boolean ExtentEdge (const TopoDS_Edge& E,
-                                                      TopoDS_Edge& NE,
-                                                      const Standard_Real theOffset);
+  Standard_EXPORT static Standard_Boolean ExtentEdge (const TopoDS_Edge&     E,
+                                                      TopoDS_Edge&           NE,
+                                                      const Standard_Real    theOffset,
+                                                      const Standard_Boolean theToProlongBefore = Standard_True,
+                                                      const Standard_Boolean theToProlongAfter = Standard_True);
 
 };
 
index 9f1ceb951d9e70dc270f6c47c23916ec39be1299..b767ebc13de83e5adf3bffa5a48d3fdd6f0c31c8 100644 (file)
 //function : BRepOffset_Inter3d
 //purpose  : 
 //=======================================================================
-BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes, 
-                                       const TopAbs_State            Side ,
-                                       const Standard_Real           Tol)
-:myAsDes(AsDes),
-mySide(Side),
-myTol(Tol)
+BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& theAsDes, 
+                                       const TopAbs_State            theSide,
+                                       const Standard_Real           theOffset,
+                                       const Standard_Real           theTol)
+  : myAsDes(theAsDes),
+    mySide(theSide),
+    myOffset(theOffset),
+    myTol(theTol)
 {
 }
 
@@ -222,11 +224,11 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
           if (BRepOffset_Tool::FindCommonShapes(TopoDS::Face(InitF1),
                                                 TopoDS::Face(InitF2),LE,LV)) {
             if (!LE.IsEmpty()) {
-              BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
+              BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,myOffset,NullEdge,NullFace,NullFace);
             }
           }
           else {
-            BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
+            BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,myOffset,NullEdge,NullFace,NullFace);
           }
         }
       }
@@ -237,7 +239,7 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
       BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
     }
     else {
-      BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
+      BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,myOffset,NullEdge,NullFace,NullFace);
     }
   }
   Store (F1,F2,LInt1,LInt2);
@@ -275,13 +277,23 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
       //-----------------------------------------------------------
       const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
       if (Anc.Extent() == 2) {
-        
+        Standard_Boolean IsEsmooth = Analyse.IsEdgeSmooth(E);
+        //Temporary
+        if (IsEsmooth)
+          continue;
+        ///////////
         const TopoDS_Face& InitF1 = TopoDS::Face(Anc.First());
         const TopoDS_Face& InitF2 = TopoDS::Face(Anc.Last());
         F1 = TopoDS::Face(InitOffsetFace.Image(InitF1).First());
         F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
+
+        TopTools_ListOfShape LE,LV;
+        if (BRepOffset_Tool::FindCommonShapes(F1,F2,LE,LV) &&
+            !LE.IsEmpty())
+          continue;
+        
         if (!IsDone(F1,F2)) {
-          BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,InitF1,InitF2);
+          BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,myOffset,E,InitF1,InitF2,IsEsmooth);
           Store (F1,F2,LInt1,LInt2);
         }
       }          
@@ -366,7 +378,7 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
                 if (!TangentFaces) {
                   F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
                   if (!IsDone(F1,F2)) {
-                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
+                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,myOffset,NullEdge,NullFace,NullFace);
                     Store (F1,F2,LInt1,LInt2);
                   }
                 }
@@ -376,7 +388,7 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces
                 if (!TangentFaces) {
                   F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
                   if (!IsDone(F1,F2)) {
-                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
+                    BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,myOffset,NullEdge,NullFace,NullFace);
                     Store (F1,F2,LInt1,LInt2);
                   }
                 }
@@ -617,10 +629,13 @@ void BRepOffset_Inter3d::ConnexIntByInt
       OF1 = TopoDS::Face(MapSF(F1).Face());
       OF2 = TopoDS::Face(MapSF(F2).Face());
       if (!MES.IsBound(OF1)) {
-        Standard_Boolean enlargeU = Standard_True;
+        Standard_Boolean enlargeUfirst = Standard_True, enlargeUlast = 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);
+        BRepOffset_Tool::CheckBounds( F1, Analyse,
+                                      enlargeUfirst, enlargeUlast,
+                                      enlargeVfirst, enlargeVlast );
+        BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,
+                                     enlargeUfirst,enlargeUlast,enlargeVfirst,enlargeVlast);
         MES.Bind(OF1,NF1);
       }
       else {
@@ -628,10 +643,13 @@ void BRepOffset_Inter3d::ConnexIntByInt
       }
       //
       if (!MES.IsBound(OF2)) {
-        Standard_Boolean enlargeU = Standard_True;
+        Standard_Boolean enlargeUfirst = Standard_True, enlargeUlast = 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);
+        BRepOffset_Tool::CheckBounds( F2, Analyse,
+                                      enlargeUfirst, enlargeUlast,
+                                      enlargeVfirst, enlargeVlast );
+        BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,
+                                     enlargeUfirst,enlargeUlast,enlargeVfirst,enlargeVlast);
         MES.Bind(OF2,NF2); 
       }
       else {
@@ -640,7 +658,8 @@ void BRepOffset_Inter3d::ConnexIntByInt
       //
       if (!IsDone(NF1,NF2)) {
         TopTools_ListOfShape LInt1,LInt2;
-        BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,F1,F2);
+        Standard_Boolean IsEsmooth = Analyse.IsEdgeSmooth(E);
+        BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,myOffset,E,F1,F2,IsEsmooth);
         SetDone(NF1,NF2);
         if (!LInt1.IsEmpty()) {
           Store (NF1,NF2,LInt1,LInt2);
@@ -1039,7 +1058,7 @@ void BRepOffset_Inter3d::ContextIntByInt
           TopTools_ListOfShape LInt1,LInt2;
           TopTools_ListOfShape LOE;
           LOE.Append(OE);
-          BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,CF,F);
+          BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,myOffset,E,CF,F);
           SetDone(NF,CF);
           if (!LInt1.IsEmpty()) {
             Store (CF,NF,LInt1,LInt2);
@@ -1084,14 +1103,14 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
                                                BRepAlgo_Image&             InitOffsetEdge)
 
 { 
-  TopTools_ListOfShape                      LInt1,LInt2;
-  TopTools_MapOfShape                       MV;
-  TopExp_Explorer                           exp;
-  TopoDS_Face                               OF1,OF2;
-  TopoDS_Edge                               OE;
-  BRep_Builder                              B;  
-  TopoDS_Edge                               NullEdge;
-  TopoDS_Face                               NullFace;                  
+  TopTools_ListOfShape LInt1,LInt2;
+  TopTools_MapOfShape  MV;
+  TopExp_Explorer      exp;
+  TopoDS_Face          OF1,OF2;
+  TopoDS_Edge          OE;
+  BRep_Builder         B;  
+  TopoDS_Edge          NullEdge;
+  TopoDS_Face          NullFace;                  
   Standard_Integer j;
 
   for (j = 1; j <= ContextFaces.Extent(); j++) {
@@ -1261,7 +1280,7 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte
             // If no trace try intersection.
             //-------------------------------------------------------
             if (LInt1.IsEmpty()) {
-              BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
+              BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,myOffset,NullEdge,NullFace,NullFace);
             }
             Store (CF,OF1,LInt1,LInt2);
           }
index e9607c89c5fefb47a8c05043507cb2f6817a236a..87f18dfa1871adc5989ba37177ab84d20b79e555 100644 (file)
@@ -45,19 +45,45 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  Standard_EXPORT BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes, const TopAbs_State Side, const Standard_Real Tol);
+  Standard_EXPORT BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& theAsDes,
+                                     const TopAbs_State  theSide,
+                                     const Standard_Real theOffset,
+                                     const Standard_Real theTol);
   
-  Standard_EXPORT void CompletInt (const TopTools_ListOfShape& SetOfFaces, const BRepAlgo_Image& InitOffsetFace);
+  Standard_EXPORT void CompletInt (const TopTools_ListOfShape& SetOfFaces,
+                                   const BRepAlgo_Image& InitOffsetFace);
   
-  Standard_EXPORT void FaceInter (const TopoDS_Face& F1, const TopoDS_Face& F2, const BRepAlgo_Image& InitOffsetFace);
+  Standard_EXPORT void FaceInter (const TopoDS_Face& F1,
+                                  const TopoDS_Face& F2,
+                                  const BRepAlgo_Image& InitOffsetFace);
   
-  Standard_EXPORT void ConnexIntByArc (const TopTools_ListOfShape& SetOfFaces, const TopoDS_Shape& ShapeInit, const BRepOffset_Analyse& Analyse, const BRepAlgo_Image& InitOffsetFace);
+  Standard_EXPORT void ConnexIntByArc (const TopTools_ListOfShape& SetOfFaces,
+                                       const TopoDS_Shape& ShapeInit,
+                                       const BRepOffset_Analyse& Analyse,
+                                       const BRepAlgo_Image& InitOffsetFace);
   
-  Standard_EXPORT void ConnexIntByInt (const TopoDS_Shape& SI, const BRepOffset_DataMapOfShapeOffset& MapSF, const BRepOffset_Analyse& A, TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& Build, TopTools_ListOfShape& Failed, const Standard_Boolean bIsPlanar = Standard_False);
+  Standard_EXPORT void ConnexIntByInt (const TopoDS_Shape& SI,
+                                       const BRepOffset_DataMapOfShapeOffset& MapSF,
+                                       const BRepOffset_Analyse& A,
+                                       TopTools_DataMapOfShapeShape& MES,
+                                       TopTools_DataMapOfShapeShape& Build,
+                                       TopTools_ListOfShape& Failed,
+                                       const Standard_Boolean bIsPlanar = Standard_False);
   
-  Standard_EXPORT void ContextIntByInt (const TopTools_IndexedMapOfShape& ContextFaces, const Standard_Boolean ExtentContext, const BRepOffset_DataMapOfShapeOffset& MapSF, const BRepOffset_Analyse& A, TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& Build, TopTools_ListOfShape& Failed, const Standard_Boolean bIsPlanar = Standard_False);
+  Standard_EXPORT void ContextIntByInt (const TopTools_IndexedMapOfShape& ContextFaces,
+                                        const Standard_Boolean ExtentContext,
+                                        const BRepOffset_DataMapOfShapeOffset& MapSF,
+                                        const BRepOffset_Analyse& A,
+                                        TopTools_DataMapOfShapeShape& MES,
+                                        TopTools_DataMapOfShapeShape& Build,
+                                        TopTools_ListOfShape& Failed,
+                                        const Standard_Boolean bIsPlanar = Standard_False);
   
-  Standard_EXPORT void ContextIntByArc (const TopTools_IndexedMapOfShape& ContextFaces, const Standard_Boolean ExtentContext, const BRepOffset_Analyse& Analyse, const BRepAlgo_Image& InitOffsetFace, BRepAlgo_Image& InitOffsetEdge);
+  Standard_EXPORT void ContextIntByArc (const TopTools_IndexedMapOfShape& ContextFaces,
+                                        const Standard_Boolean ExtentContext,
+                                        const BRepOffset_Analyse& Analyse,
+                                        const BRepAlgo_Image& InitOffsetFace,
+                                        BRepAlgo_Image& InitOffsetEdge);
   
   Standard_EXPORT void AddCommonEdges (const TopTools_ListOfShape& SetOfFaces);
   
@@ -91,6 +117,7 @@ private:
   TopTools_DataMapOfShapeListOfShape myDone;
   TopTools_IndexedMapOfShape myNewEdges;
   TopAbs_State mySide;
+  Standard_Real myOffset;
   Standard_Real myTol;
 
 
index de5eb39747575ab94f5f58270deaf324a8846b3f..ae577f26fbcb4dfbebea52f85a3d2400f634aa61 100644 (file)
@@ -62,6 +62,7 @@ void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape&   LF,
 
   for (; it.More(); it.Next()) {
     const TopoDS_Face& F = TopoDS::Face(it.Value());
+
     //---------------------------
     // Initialization of Loops.
     //---------------------------
@@ -74,6 +75,7 @@ void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape&   LF,
 
     for (itl.Initialize(LE); itl.More(); itl.Next()) {
       TopoDS_Edge E = TopoDS::Edge(itl.Value());
+
       if (Image.HasImage(E)) {
        //-------------------------------------------
        // E was already cut in another face.
@@ -164,6 +166,146 @@ void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape&   LF,
     }
 }
 
+//=======================================================================
+//function : Build
+//purpose  : 
+//=======================================================================
+
+void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape&   LF, 
+                                const Handle(BRepAlgo_AsDes)& AsDes, 
+                                BRepAlgo_Image&               Image,
+                                 BRepOffset_DataMapOfFaceMapEE& theFaceEdgeEdge)
+{
+  TopTools_ListIteratorOfListOfShape    it(LF);
+  TopTools_ListIteratorOfListOfShape    itl,itLCE;
+  BRepAlgo_Loop                       Loops;
+  Loops.VerticesForSubstitute( myVerVerMap );
+
+  for (; it.More(); it.Next()) {
+    const TopoDS_Face& F = TopoDS::Face(it.Value());
+
+    const TopTools_DataMapOfShapeListOfShape& aEEmap = theFaceEdgeEdge(F);
+    
+    //---------------------------
+    // Initialization of Loops.
+    //---------------------------
+    Loops.Init(F);
+    //-----------------------------
+    // return edges of F.
+    //-----------------------------
+    const TopTools_ListOfShape& LE = AsDes->Descendant(F);
+    TopTools_ListOfShape        AddedEdges;
+
+    for (itl.Initialize(LE); itl.More(); itl.Next()) {
+      TopoDS_Edge E = TopoDS::Edge(itl.Value());
+
+      if (aEEmap.IsBound(E))
+      {
+        const TopTools_ListOfShape& aElist = aEEmap(E);
+        TopTools_ListIteratorOfListOfShape anItl(aElist);
+        for (; anItl.More(); anItl.Next())
+        {
+          TopoDS_Edge aNewEdge = TopoDS::Edge(anItl.Value());
+          aNewEdge.Orientation (E.Orientation());
+          Loops.AddNewEdge(aNewEdge);
+        }
+      }
+      else
+      {
+        if (Image.HasImage(E)) {
+          //-------------------------------------------
+          // E was already cut in another face.
+          // Return the cut edges reorientate them as E.
+          // See pb for the edges that have disappeared?
+          //-------------------------------------------
+          const TopTools_ListOfShape& LCE = Image.Image(E);
+          for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
+            TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation()); 
+            Loops.AddConstEdge(TopoDS::Edge(CE));
+          }
+        }
+        else {
+          Loops     .AddEdge(E, AsDes->Descendant(E));
+          AddedEdges.Append (E);
+        }
+      }
+    }
+    //------------------------
+    // Unwind.
+    //------------------------
+    Loops.Perform();
+    Loops.WiresToFaces();      
+    //------------------------
+    // MAJ SD.
+    //------------------------
+    const TopTools_ListOfShape&  NF = Loops.NewFaces();
+    //-----------------------
+    // F => New faces;
+    //-----------------------
+    Image.Bind(F,NF);
+
+    if (!Loops.HasNewEdges())
+    {
+      TopTools_ListIteratorOfListOfShape itAdded;
+      for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
+        const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
+        //-----------------------
+        //  E => New edges;
+        //-----------------------
+        const TopTools_ListOfShape& LoopNE = Loops.NewEdges(E);
+        if (Image.HasImage(E)) {
+          Image.Add(E,LoopNE);
+        }
+        else {
+          Image.Bind(E,LoopNE);
+        }
+      }
+    }
+  }
+  Loops.GetVerticesForSubstitute( myVerVerMap );
+  if (myVerVerMap.IsEmpty())
+    return;
+  BRep_Builder BB;
+  for (it.Initialize( LF ); it.More(); it.Next())
+    {
+      TopoDS_Shape F = it.Value();
+      TopTools_ListOfShape LIF;
+      Image.LastImage( F, LIF );
+      for (itl.Initialize(LIF); itl.More(); itl.Next())
+       {
+         const TopoDS_Shape& IF = itl.Value();
+         TopExp_Explorer EdExp( IF, TopAbs_EDGE );
+         for (; EdExp.More(); EdExp.Next())
+           {
+             TopoDS_Shape E = EdExp.Current();
+             TopTools_ListOfShape VList;
+             TopoDS_Iterator VerExp( E );
+             for (; VerExp.More(); VerExp.Next())
+               VList.Append( VerExp.Value() );
+             TopTools_ListIteratorOfListOfShape itlv( VList );
+             for (; itlv.More(); itlv.Next())
+               {
+                 const TopoDS_Shape& V = itlv.Value();
+                 if (myVerVerMap.IsBound( V ))
+                   {
+                     TopoDS_Shape NewV = myVerVerMap( V );
+                     E.Free( Standard_True );
+                     NewV.Orientation( V.Orientation() );
+                     Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
+                     Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
+                     if (TV->Tolerance() > NewTV->Tolerance())
+                       NewTV->Tolerance( TV->Tolerance() );
+                     NewTV->ChangePoints().Append( TV->ChangePoints() );
+                     AsDes->Replace( V, NewV );
+                     BB.Remove( E, V );
+                     BB.Add( E, NewV );
+                   }
+               }
+           }
+       }
+    }
+}
+
 //=======================================================================
 //function : IsBetweenCorks
 //purpose  : 
@@ -175,6 +317,12 @@ static Standard_Boolean IsBetweenCorks(const TopoDS_Shape& E,
 {
   if (!AsDes->HasAscendant(E)) return 1;
   const TopTools_ListOfShape& LF = AsDes->Ascendant(E);
+
+  //Temporary
+  if (LF.Extent() == 1)
+    return 0;
+  ///////////
+  
   TopTools_ListIteratorOfListOfShape it;
   for (it.Initialize(LF); it.More(); it.Next()) {
     const TopoDS_Shape& S = it.Value();
index 7caf1b3fe657e23a9114608804852e5e90d51820..9ac0742f42af9eedf754cc2d11d67800b353a903 100644 (file)
@@ -24,6 +24,7 @@
 #include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <Standard_Boolean.hxx>
+#include <BRepOffset_DataMapOfFaceMapEE.hxx>
 class BRepAlgo_AsDes;
 class BRepAlgo_Image;
 class BRepOffset_Analyse;
@@ -44,10 +45,16 @@ public:
                               BRepAlgo_Image& Image,
                               BRepAlgo_Image& theImageVV);
   
+  Standard_EXPORT void Build (const TopTools_ListOfShape& LF,
+                              const Handle(BRepAlgo_AsDes)& AsDes,
+                              BRepAlgo_Image& Image,
+                              BRepOffset_DataMapOfFaceMapEE& theFaceEdgeEdge);
+  
   Standard_EXPORT void BuildOnContext (const TopTools_ListOfShape& LContext,
                                        const BRepOffset_Analyse& Analyse,
                                        const Handle(BRepAlgo_AsDes)& AsDes,
                                        BRepAlgo_Image& Image,
+                                       //BRepOffset_DataMapOfFaceMapEE& theFaceEdgeEdge,
                                        const Standard_Boolean InSide);
   
   Standard_EXPORT void BuildFaces (const TopTools_ListOfShape& LF,
index 2c5fe795f3f622145fa4562ce71ad4881c7b6c8e..abaeefeb950fc67882d300648b114bf466c4f71a 100644 (file)
@@ -44,6 +44,7 @@
 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
 #include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
 #include <BRepOffset_DataMapOfShapeOffset.hxx>
+#include <BRepOffset_SequenceOfIndexedMapOfShape.hxx>
 #include <BRepOffset_Inter2d.hxx>
 #include <BRepOffset_Inter3d.hxx>
 #include <BRepOffset_Interval.hxx>
   char name[100];
 
 
-
-
 //=======================================================================
 //function :  DEBVerticesControl
 //purpose  : 
@@ -245,6 +244,20 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 //=======================================================================
 // static methods
 //=======================================================================
+
+static Standard_Integer FindIndex(const Standard_Integer* theArray,
+                                  const Standard_Integer  theIndex);
+
+static void SplitIntersectionEdges(const TopoDS_Edge&            theEdge1,
+                                   const TopoDS_Edge&            theEdge2,
+                                   TopTools_ListOfShape&         theNewEdgesForF1,
+                                   TopTools_ListOfShape&         theNewEdgesForF2,
+                                   BRepOffset_SequenceOfIndexedMapOfShape& theVsets);
+
+static void AddVerticesToSets(const TopoDS_Shape& theVertex1,
+                              const TopoDS_Shape& theVertex2,
+                              BRepOffset_SequenceOfIndexedMapOfShape& theVsets);
+
 static
   void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
                         const BRepOffset_DataMapOfShapeOffset& theMapSF,
@@ -659,6 +672,7 @@ void BRepOffset_MakeOffset::Clear()
   myEdgeIntEdges   .Clear();
   myAsDes          ->Clear();
   myDone     = Standard_False;
+  myFaceEdgeEdge.Clear();
   myGenerated.Clear();
   myResMap.Clear();
 }
@@ -874,6 +888,12 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   // There are possible second variant: analytical continuation of arcsin.
   Standard_Real TolAngleCoeff = Min(myTol / (Abs(myOffset * 0.5) + Precision::Confusion()), 1.0);
   Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
+  //Standard_Real TolAngleForEdges = TolAngle;
+
+  if (myJoin == GeomAbs_Intersection)
+    TolAngle = Precision::Angular(); //Precision::Confusion(); //0.0001;
+
+  myAnalyse.SetJoinType(myJoin);
   if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar)
   {
     myAnalyse.SetOffsetValue (myOffset);
@@ -903,7 +923,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   //-----------------
   // Intersection 3d .
   //-----------------
-  BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
+  BRepOffset_Inter3d Inter(myAsDes,Side,myOffset,myTol);
   Intersection3D (Inter);
   //-----------------
   // Intersection2D
@@ -982,6 +1002,16 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
     MakeSolid();
   }
 
+  /*
+  if (myOffsetShape.IsNull())
+  {
+    TopoDS_Compound aCompound;
+    BRep_Builder aBB;
+    aBB.MakeCompound (aCompound);
+    myOffsetShape = aCompound;
+  }
+  */
+  
   myDone = Standard_True;
 }
 
@@ -1210,7 +1240,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   Standard_Boolean  ExtentContext = 0;
   if (myOffset > 0) ExtentContext = 1;
 
-  BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
+  BRepOffset_Inter3d Inter3 (AsDes,Side,myOffset,myTol);
   // Intersection between parallel faces
   Inter3.ConnexIntByInt(myFaceComp,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
   // Intersection with caps.
@@ -1291,6 +1321,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   }
   else {
     myMakeLoops.Build(LFE, AsDes, IMOE, myImageVV);
+    //myMakeLoops.Build(LFE, AsDes, IMOE, myFaceEdgeEdge);
   }
   //
 #ifdef OCCT_DEBUG
@@ -1324,6 +1355,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
             const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
             
             myAsDes->Add (OFE,COE);
+
+            //jgv
+            /*
+            const TopoDS_Face& aOFE = TopoDS::Face(OFE);
+            if (myFaceEdgeEdge.IsBound(aOFE))
+            {
+              const TopTools_DataMapOfShapeListOfShape& aEEmap = myFaceEdgeEdge(aOFE);
+              const TopTools_ListOfShape& aElist = aEEmap(COE);
+              myAsDes->Add (OFE, aElist.First());
+            }
+            */
+            /////
 #ifdef DRAW
             if (AffichInt2d) {
               sprintf(name,"AE_%d",NbAE++);
@@ -2052,6 +2095,8 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
       for (i = 1; i <= Emap.Extent(); i++)
       {
         TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
+        if (!myInitOffsetEdge.IsImage(anEdge))
+          continue;
         //Standard_Real f, l;
         //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
         //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
@@ -2584,6 +2629,7 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
 
   Standard_Boolean   InSide = 1;
   if (myOffset > 0 ) InSide = 0;
+  //myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,myFaceEdgeEdge,InSide);
   myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
 
 #ifdef OCCT_DEBUG
@@ -2714,15 +2760,19 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
       {
         gp_Pnt aPntF = BRep_Tool::Pnt(V1);
         gp_Pnt aPntL = BRep_Tool::Pnt(V2);
-        Standard_Real aDistE = aPntF.SquareDistance(aPntL);
-        if ( aDistE < Precision::SquareConfusion())
+        Standard_Real aSqDistE = aPntF.SquareDistance(aPntL);
+        if ( aSqDistE < Precision::SquareConfusion())
         {
           // Bad case: non closed, but vertexes mapped to same 3d point.
           continue;
         }
 
         Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
-        if (aDistE < anEdgeTol)
+        Standard_Real aSqEdgeTol = anEdgeTol*anEdgeTol;
+        Standard_Real aTolV1 = BRep_Tool::Tolerance(V1),
+          aTolV2 = BRep_Tool::Tolerance(V2);
+        Standard_Real aSqSumTolVV = (aTolV1+aTolV2)*(aTolV1+aTolV2);
+        if (aSqDistE < aSqEdgeTol || aSqDistE < aSqSumTolVV)
         {
           // Potential problems not detected via checkshape.
           gp_Pnt aPntOF = BRep_Tool::Pnt(V4);
@@ -3165,11 +3215,39 @@ void BRepOffset_MakeOffset::MakeShells ()
   }
   //
   if (!bDone) {
-    BRepTools_Quilt Glue;
+
+    BRepBuilderAPI_Sewing aSewer;
     TopTools_ListIteratorOfListOfShape aItLS(aLSF);
-    for (; aItLS.More(); aItLS.Next()) {
-      Glue.Add(aItLS.Value());
+    for (; aItLS.More(); aItLS.Next())
+    {
+      const TopoDS_Shape& aFace = aItLS.Value();
+      TopExp_Explorer anExplo(aFace, TopAbs_EDGE);
+      for (; anExplo.More(); anExplo.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(anExplo.Current());
+        BRepLib::BuildCurve3d(anEdge);
+      }
+      aSewer.Add(aFace);
+    }
+    
+    aSewer.Perform();
+    myOffsetShape = aSewer.SewedShape();
+    if (myOffsetShape.ShapeType() == TopAbs_FACE)
+    {
+      TopoDS_Shell aShell;
+      BRep_Builder aBB;
+      aBB.MakeShell(aShell);
+      aBB.Add(aShell, myOffsetShape);
+      myOffsetShape = aShell;
     }
+
+    TopTools_IndexedMapOfShape aFmap;
+    TopExp::MapShapes (myOffsetShape, TopAbs_FACE, aFmap);
+    BRepTools_Quilt Glue;
+    //for (aItLS.Initialize(aLSF); aItLS.More(); aItLS.Next()) {
+    for (Standard_Integer ii = 1; ii <= aFmap.Extent(); ii++)
+      Glue.Add(aFmap(ii));
+      //Glue.Add(aItLS.Value());
     myOffsetShape = Glue.Shells();
   }
   //
@@ -3998,17 +4076,140 @@ void BRepOffset_MakeOffset::IntersectEdges(const TopTools_ListOfShape& theFaces,
   TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
   // intersect edges created from edges
   TopTools_IndexedMapOfShape aMFV;
+  TopTools_IndexedDataMapOfShapeListOfShape aEFmap;
   for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
   {
     const TopoDS_Face& aF  = TopoDS::Face (it.Value());
     aTolF = BRep_Tool::Tolerance (aF);
-    if (!BRepOffset_Inter2d::ConnexIntByInt(aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d,
-                                            myOffset, aTolF, myAnalyse, aMFV, myImageVV, myEdgeIntEdges, aDMVV))
+    if (!BRepOffset_Inter2d::ConnexIntByInt(aF, theMapSF(aF), theMES, theBuild,
+                                            theAsDes, theAsDes2d,
+                                            myOffset, aTolF, myAnalyse,
+                                            aMFV, myImageVV, myEdgeIntEdges, aDMVV, myFaceEdgeEdge, aEFmap))
     {
       myError = BRepOffset_CannotExtentEdge;
       return;
     }
   }
+
+  //Split intersection edges
+  BRepOffset_SequenceOfIndexedMapOfShape aVsets;
+  for (Standard_Integer ii = 1; ii <= aEFmap.Extent(); ii++)
+  {
+    const TopoDS_Shape& anEdge = aEFmap.FindKey(ii);
+    const TopTools_ListOfShape& aFlist = aEFmap(ii);
+    if (aFlist.Extent() == 2)
+    {
+      const TopoDS_Face& aFace1 = TopoDS::Face(aFlist.First());
+      const TopoDS_Face& aFace2 = TopoDS::Face(aFlist.Last());
+      TopTools_DataMapOfShapeListOfShape* aEEmap1 = myFaceEdgeEdge.ChangeSeek(aFace1);
+      TopTools_DataMapOfShapeListOfShape* aEEmap2 = myFaceEdgeEdge.ChangeSeek(aFace2);
+      TopTools_ListOfShape* aElist1 = aEEmap1->ChangeSeek(anEdge);
+      TopTools_ListOfShape* aElist2 = aEEmap2->ChangeSeek(anEdge);
+      TopoDS_Edge anEdgeOnF1 = TopoDS::Edge(aElist1->First());
+      TopoDS_Edge anEdgeOnF2 = TopoDS::Edge(aElist2->First());
+      anEdgeOnF1.Orientation(TopAbs_FORWARD);
+      anEdgeOnF2.Orientation(TopAbs_FORWARD);
+
+      TopTools_ListOfShape aNElistForF1, aNElistForF2;
+      SplitIntersectionEdges(anEdgeOnF1, anEdgeOnF2, aNElistForF1, aNElistForF2, aVsets);
+      *aElist1 = aNElistForF1;
+      *aElist2 = aNElistForF2;
+    }
+  }
+  //Build VV map
+  TopTools_DataMapOfShapeShape aVVmap;
+  for (Standard_Integer ii = 1; ii <= aVsets.Length(); ii++)
+  {
+    const TopTools_IndexedMapOfShape& aVmap = aVsets(ii);
+    TopoDS_Vertex aCommonVertex;
+    Standard_Real aMaxTol = 0.;
+    for (Standard_Integer jj = 1; jj <= aVmap.Extent(); jj++)
+    {
+      const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVmap(jj));
+      Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
+      if (aTol > aMaxTol)
+      {
+        aMaxTol = aTol;
+        aCommonVertex = aVertex;
+      }
+    }
+    for (Standard_Integer jj = 1; jj <= aVmap.Extent(); jj++)
+    {
+      const TopoDS_Shape& aVertex = aVmap(jj);
+      if (!aVertex.IsSame(aCommonVertex))
+        aVVmap.Bind(aVertex, aCommonVertex);
+    }
+  }
+  
+  //Update vertices
+  BRep_Builder aBB;
+  for (Standard_Integer ii = 1; ii <= aEFmap.Extent(); ii++)
+  {
+    const TopoDS_Shape& anEdge = aEFmap.FindKey(ii);
+    const TopTools_ListOfShape& aFlist = aEFmap(ii);
+    TopTools_ListIteratorOfListOfShape itface(aFlist);
+    TopTools_MapOfShape aNEmap;
+    for (; itface.More(); itface.Next())
+    {
+      const TopoDS_Face& aFace = TopoDS::Face(itface.Value());
+      const TopTools_DataMapOfShapeListOfShape& aEEmap = myFaceEdgeEdge(aFace);
+      const TopTools_ListOfShape& aElist = aEEmap(anEdge);
+      TopTools_ListIteratorOfListOfShape itedge(aElist);
+      for (; itedge.More(); itedge.Next())
+      {
+        TopoDS_Edge aNewEdge = TopoDS::Edge(itedge.Value());
+        if (!aNEmap.Add(aNewEdge))
+          continue;
+        
+        aNewEdge.Orientation(TopAbs_FORWARD);
+        TopoDS_Vertex aV1, aV2;
+        TopExp::Vertices(aNewEdge, aV1, aV2);
+        if (aVVmap.IsBound(aV1))
+        {
+          TopoDS_Shape aNewV = aVVmap(aV1);
+          aNewV.Orientation(TopAbs_FORWARD);
+          aNewEdge.Free(Standard_True);
+          aBB.Remove(aNewEdge, aV1);
+          aBB.Add(aNewEdge, aNewV);
+
+          if (aV2.IsSame(aV1))
+          {
+            aNewV.Orientation(TopAbs_REVERSED);
+            aBB.Remove(aNewEdge, aV2);
+            aBB.Add(aNewEdge, aNewV);
+          }
+        }
+        if (!aV2.IsSame(aV1) && aVVmap.IsBound(aV2))
+        {
+          TopoDS_Shape aNewV = aVVmap(aV2);
+          aNewV.Orientation(TopAbs_REVERSED);
+          aNewEdge.Free(Standard_True);
+          aBB.Remove(aNewEdge, aV2);
+          aBB.Add(aNewEdge, aNewV);
+        }
+      }
+    }
+  }
+
+  //Temporary
+  /*
+  BRepBuilderAPI_Sewing aSewer;
+  for (Standard_Integer ii = 1; ii < myFaceFaceMap.Extent(); ii++)
+  {
+    const TopoDS_Shape& aFace = myFaceFaceMap(ii);
+    TopExp_Explorer anExplo(aFace, TopAbs_EDGE);
+    for (; anExplo.More(); anExplo.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(anExplo.Current());
+      BRepLib::BuildCurve3d(anEdge);
+    }
+    aSewer.Add(aFace);
+  }
+  aSewer.Perform();
+  TopoDS_Shape aTmpRes = aSewer.SewedShape();
+  */
+  ///////////
+  
   // intersect edges created from vertices
   Standard_Integer i, aNbF = aMFV.Extent();
   for (i = 1; i <= aNbF; ++i) {
@@ -4209,9 +4410,14 @@ Standard_Boolean TrimEdge(TopoDS_Edge&                  NE,
         GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
         if (Projector.NbPoints() == 0)
         {
-          return Standard_False;
+          gp_Pnt aFirstPnt = theCurve->Value(f);
+          gp_Pnt aLastPnt  = theCurve->Value(l);
+          Standard_Real aDistToFirst = thePoint.SquareDistance(aFirstPnt);
+          Standard_Real aDistToLast  = thePoint.SquareDistance(aLastPnt);
+          U = (aDistToFirst < aDistToLast)? f : l;
         }
-        U = Projector.LowerDistanceParameter();
+        else
+          U = Projector.LowerDistanceParameter();
       }
       if (U < UMin) {
         UMin = U; V1   = V;
@@ -4766,3 +4972,181 @@ void AppendToList(TopTools_ListOfShape& theList,
   }
   theList.Append(theShape);
 }
+
+Standard_Integer FindIndex(const Standard_Integer* theArray,
+                           const Standard_Integer  theIndex)
+{
+  Standard_Integer ii;
+  for (ii = 0; ii < 4; ii++)
+    if (theArray[ii] == theIndex)
+      break;
+  return ii;
+}
+
+//=======================================================================
+//function : SplitIntersectionEdges
+//purpose  : 
+//=======================================================================
+
+void SplitIntersectionEdges(const TopoDS_Edge&            theEdge1,
+                            const TopoDS_Edge&            theEdge2,
+                            TopTools_ListOfShape&         theNewEdgesForF1,
+                            TopTools_ListOfShape&         theNewEdgesForF2,
+                            BRepOffset_SequenceOfIndexedMapOfShape& theVsets)
+{
+  Standard_Real aParams [4];
+  TopoDS_Vertex aVV [4];
+  BRep_Tool::Range(theEdge1, aParams[0], aParams[1]);
+  BRep_Tool::Range(theEdge2, aParams[2], aParams[3]);
+  TopExp::Vertices(theEdge1, aVV[0], aVV[1]);
+  TopExp::Vertices(theEdge2, aVV[2], aVV[3]);
+  Standard_Integer aIndices [4] = {0, 1, 2, 3};
+
+  for (Standard_Integer ii = 0; ii < 3; ii++)
+    for (Standard_Integer jj = ii+1; jj <= 3; jj++)
+      if (aParams[jj] < aParams[ii])
+      {
+        Standard_Real aTmp = aParams[ii];
+        aParams[ii] = aParams[jj];
+        aParams[jj] = aTmp;
+        TopoDS_Vertex aVertex = aVV[ii];
+        aVV[ii] = aVV[jj];
+        aVV[jj] = aVertex;
+        Standard_Integer anInd =  aIndices[ii];
+        aIndices[ii] = aIndices[jj];
+        aIndices[jj] = anInd;
+      }
+
+  Standard_Real aFpar, aLpar;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge1, aFpar, aLpar);
+  if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+    aCurve = (Handle(Geom_TrimmedCurve)::DownCast(aCurve))->BasisCurve();
+
+  Standard_Integer NCONTROL = 10;
+  for (Standard_Integer ii = 0; ii < 3; ii++)
+  {
+    Standard_Real aTolV1 = BRep_Tool::Tolerance(aVV[ii]);
+    Standard_Real aTolV2 = BRep_Tool::Tolerance(aVV[ii+1]);
+    Standard_Real aSqTolV1 = aTolV1*aTolV1;
+    Standard_Real aSqTolV2 = aTolV2*aTolV2;
+    gp_Pnt aPnt1 = BRep_Tool::Pnt(aVV[ii]);
+    gp_Pnt aPnt2 = BRep_Tool::Pnt(aVV[ii+1]);
+    
+    Standard_Boolean IsConfused = Standard_False;
+    if (aParams[ii+1] - aParams[ii] <= Precision::Confusion())
+      IsConfused = Standard_True;
+    else
+    {
+      Standard_Boolean IsBiggerThanTol = Standard_False;
+      Standard_Real aDelta = (aParams[ii+1] - aParams[ii])/NCONTROL;
+      for (Standard_Integer jj = 0; jj <= NCONTROL; jj++)
+      {
+        Standard_Real aPar = aParams[ii] + jj*aDelta;
+        gp_Pnt aPnt = aCurve->Value(aPar);
+        Standard_Real aSqDist1 = aPnt1.SquareDistance(aPnt);
+        Standard_Real aSqDist2 = aPnt2.SquareDistance(aPnt);
+        if (aSqDist1 > aSqTolV1 && aSqDist2 > aSqTolV2)
+        {
+          IsBiggerThanTol = Standard_True;
+          break;
+        }
+      }
+      IsConfused = !IsBiggerThanTol;
+    }
+
+    if (IsConfused)
+    {
+      //theVVmap.Bind(aVV[ii+1].Oriented(TopAbs_FORWARD), aVV[ii].Oriented(TopAbs_FORWARD));
+      AddVerticesToSets(aVV[ii+1].Oriented(TopAbs_FORWARD),
+                        aVV[ii].Oriented(TopAbs_FORWARD),
+                        theVsets);
+      aVV[ii+1] = aVV[ii];
+      aParams[ii+1] = aParams[ii];
+    }
+  }
+
+  //Build new edges
+  Standard_Real aMaxTol = Max(BRep_Tool::Tolerance(theEdge1), BRep_Tool::Tolerance(theEdge2));
+
+  TopTools_SequenceOfShape aEseq;
+  TopoDS_Vertex aFirstVertex = aVV[0];
+  Standard_Real aFirstPar = aParams[0];
+  BRep_Builder aBB;
+  for (Standard_Integer ii = 1; ii <= 3; ii++)
+  {
+    TopoDS_Vertex aLastVertex = aVV[ii];
+    Standard_Real aLastPar = aParams[ii];
+    if (aFirstPar == aLastPar)
+      continue;
+    
+    aFirstVertex.Orientation(TopAbs_FORWARD);
+    aLastVertex.Orientation(TopAbs_REVERSED);
+    
+    TopoDS_Edge aNewEdge = TopoDS::Edge(theEdge1.EmptyCopied());
+    aBB.Add(aNewEdge, aFirstVertex);
+    aBB.Add(aNewEdge, aLastVertex);
+    aBB.Range(aNewEdge, aFirstPar, aLastPar);
+    aBB.UpdateEdge(aNewEdge, aMaxTol);
+    
+    aEseq.Append(aNewEdge);
+    aFirstVertex = aLastVertex;
+    aFirstPar = aLastPar;
+  }
+
+  TopTools_ListOfShape* aNElist [2] = { &theNewEdgesForF1, &theNewEdgesForF2 };
+
+  for (Standard_Integer anIndList = 0; anIndList < 2; anIndList++)
+  {  
+    Standard_Integer anIndV1forE1 = FindIndex(aIndices, anIndList*2); // 0 or 2
+    Standard_Integer anIndV2forE1 = FindIndex(aIndices, anIndList*2 + 1); // 1 or 3
+    Standard_Real aParamFirstForE1 = aParams[anIndV1forE1];
+    Standard_Real aParamLastForE1  = aParams[anIndV2forE1];
+    
+    for (Standard_Integer ii = 1; ii <= aEseq.Length(); ii++)
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(aEseq(ii));
+      Standard_Real fpar, lpar;
+      BRep_Tool::Range(anEdge, fpar, lpar);
+      if (fpar >= aParamFirstForE1 && lpar <= aParamLastForE1)
+        aNElist[anIndList]->Append(anEdge);
+    }
+  }
+}
+
+void AddVerticesToSets(const TopoDS_Shape& theVertex1,
+                       const TopoDS_Shape& theVertex2,
+                       BRepOffset_SequenceOfIndexedMapOfShape& theVsets)
+{
+  Standard_Integer anIndexOfV1 = 0, anIndexOfV2 = 0;
+  
+  for (Standard_Integer ii = 1; ii <= theVsets.Length(); ii++)
+  {
+    const TopTools_IndexedMapOfShape& aVmap = theVsets(ii);
+    if (aVmap.Contains(theVertex1))
+      anIndexOfV1 = ii;
+    if (aVmap.Contains(theVertex2))
+      anIndexOfV2 = ii;
+  }
+
+  if (anIndexOfV1 == 0 && anIndexOfV2 == 0)
+  {
+    TopTools_IndexedMapOfShape aVmap;
+    aVmap.Add(theVertex1);
+    aVmap.Add(theVertex2);
+    theVsets.Append(aVmap);
+  }
+  else if ((anIndexOfV1 != 0 && anIndexOfV2 == 0) ||
+           (anIndexOfV1 == 0 && anIndexOfV2 != 0))
+  {
+    Standard_Integer anIndex = (anIndexOfV1 == 0)? anIndexOfV2 : anIndexOfV1;
+    theVsets(anIndex).Add(theVertex1);
+    theVsets(anIndex).Add(theVertex2);
+  }
+  else if (anIndexOfV1 != anIndexOfV2)
+  {
+    theVsets(anIndexOfV2).RemoveKey(theVertex2);
+    theVsets(anIndexOfV1).Add(theVertex2);
+    if (theVsets(anIndexOfV2).IsEmpty())
+      theVsets.Remove(anIndexOfV2);
+  }
+}
index 61bba23bb78b36d8979d1e16067ac542e152cb02..b604e3abb6428f80b698d671e57fc5891b6592e9 100644 (file)
 #include <GeomAbs_JoinType.hxx>
 #include <TopTools_DataMapOfShapeReal.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeShape.hxx>
 #include <BRepOffset_Analyse.hxx>
 #include <BRepAlgo_Image.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <BRepOffset_Error.hxx>
 #include <BRepOffset_MakeLoops.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopTools_DataMapOfOrientedShapeShape.hxx>
 #include <BRepOffset_DataMapOfShapeOffset.hxx>
+#include <BRepOffset_DataMapOfFaceMapEE.hxx>
 class BRepAlgo_AsDes;
 class TopoDS_Shape;
 class TopoDS_Face;
@@ -43,8 +46,6 @@ class BRepOffset_Analyse;
 class BRepAlgo_Image;
 class BRepOffset_Inter3d;
 
-
-
 class BRepOffset_MakeOffset 
 {
 public:
@@ -259,6 +260,8 @@ private:
   Standard_Boolean myIsPerformSewing; // Handle bad walls in thicksolid mode.
   Standard_Boolean myIsPlanar;
   TopoDS_Shape myBadShape;
+  //TopTools_IndexedDataMapOfShapeShape myFaceFaceMap;
+  BRepOffset_DataMapOfFaceMapEE myFaceEdgeEdge;
   TopTools_DataMapOfShapeShape myFacePlanfaceMap;
   TopTools_ListOfShape myGenerated;
   TopTools_MapOfShape myResMap;
index ac615955e449083473acb4e6f52c22afc1609730..8c83ba64965d843a22d9baedf9304a7080fb4a7a 100644 (file)
@@ -5679,7 +5679,7 @@ void IntersectFaces(const TopoDS_Shape& theFInv,
   TopTools_ListOfShape aLInt1, aLInt2;
   TopoDS_Edge aNullEdge;
   TopoDS_Face aNullFace;
-  BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide,
+  BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide, 0.,
                            aNullEdge, aNullFace, aNullFace);
   //
   if (aLInt1.IsEmpty()) {
diff --git a/src/BRepOffset/BRepOffset_SequenceOfIndexedMapOfShape.hxx b/src/BRepOffset/BRepOffset_SequenceOfIndexedMapOfShape.hxx
new file mode 100644 (file)
index 0000000..aeb247b
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef BRepOffset_SequenceOfIndexedMapOfShape_HeaderFile
+#define BRepOffset_SequenceOfIndexedMapOfShape_HeaderFile
+
+typedef NCollection_Sequence<TopTools_IndexedMapOfShape> BRepOffset_SequenceOfIndexedMapOfShape;
+
+#endif
index e3e1b2360a67d5513326eabc488d558f4c201799..0ff45f63f1c0a54e72ae8318aa8b29a6a69dd2d4 100644 (file)
@@ -51,6 +51,7 @@
 #include <ElSLib.hxx>
 #include <Extrema_ExtPC.hxx>
 #include <Extrema_ExtPC2d.hxx>
+#include <Extrema_ExtPS.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
 #include <GCPnts_AbscissaPoint.hxx>
 #include <GCPnts_QuasiUniformDeflection.hxx>
@@ -68,6 +69,7 @@
 #include <Geom2dConvert_ApproxCurve.hxx>
 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
 #include <Geom2dInt_GInter.hxx>
+#include <IntCurvesFace_Intersector.hxx>
 #include <Geom_BezierSurface.hxx>
 #include <Geom_BSplineCurve.hxx>
 #include <Geom_BSplineSurface.hxx>
 #include <GeomAPI.hxx>
 #include <GeomAPI_ExtremaCurveCurve.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_Interpolate.hxx>
+#include <Geom2dAPI_Interpolate.hxx>
 #include <GeomConvert_ApproxCurve.hxx>
+#include <GeomConvert_ApproxSurface.hxx>
 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
 #include <GeomInt_IntSS.hxx>
 #include <GeomLib.hxx>
 #include <ShapeCustom_Curve2d.hxx>
 #include <Standard_ConstructionError.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
+#include <TColgp_SequenceOfPnt2d.hxx>
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
@@ -158,6 +164,18 @@ static
 
 static void UpdateVertexTolerances(const TopoDS_Face& theFace);
 
+static TopoDS_Edge ProjectEdgeOntoTwoFaces(const TopoDS_Edge&  theRefEdge,
+                                           const TopoDS_Face&  theRefFace1,
+                                           const TopoDS_Face&  theRefFace2,
+                                           const TopoDS_Face&  theFace1,
+                                           const TopoDS_Face&  theFace2,
+                                           const Standard_Real theOffset);
+
+static gp_Vec ComputeNormal(const BRepAdaptor_Surface& theBAsurf,
+                            const gp_Pnt2d&            thePnt2d,
+                            const Standard_Real        theTolLen,
+                            gp_Pnt&                    thePnt);
+
 inline
   Standard_Boolean IsInf(const Standard_Real theVal);
 
@@ -472,6 +490,61 @@ static void BuildPCurves (const TopoDS_Edge&  E,
   }
 }
 
+//=======================================================================
+//function : ComputeEndOfExtension
+//purpose  : 
+//=======================================================================
+
+static void ComputeEndOfExtension (const TopoDS_Face& theFace,
+                                   const gp_Pnt2d&    theEndPoint,
+                                   const gp_Dir2d&    theEndTangent,
+                                   gp_Pnt2d&          thePointOnBound,
+                                   TopoDS_Edge&       theEdge,
+                                   Standard_Real&     theLenToEnd)
+{
+  BRepAdaptor_Surface aBAsurf(theFace, Standard_False);
+  Standard_Real Umin, Umax, Vmin, Vmax;
+  BRepTools::UVBounds(theFace, Umin, Umax, Vmin, Vmax);
+  Standard_Real aMaxSize = Max((Umax - Umin), (Vmax - Vmin));
+
+  Handle(Geom2d_Line) aLine = new Geom2d_Line(theEndPoint, theEndTangent);
+  Geom2dAdaptor_Curve aGAline(aLine, 0., aMaxSize);
+
+  Standard_Real anEndParam = 0.;
+  TopExp_Explorer anExplo(theFace, TopAbs_EDGE);
+  for (; anExplo.More(); anExplo.Next())
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge(anExplo.Current());
+    BRepAdaptor_Curve2d aBAcurve(anEdge, theFace);
+    Geom2dInt_GInter Inters(aGAline, aBAcurve, Precision::PConfusion(), Precision::PConfusion());
+    if (Inters.IsDone() && !Inters.IsEmpty())
+    {
+      const IntRes2d_IntersectionPoint& anIntPoint = Inters.Point(1);
+      thePointOnBound = anIntPoint.Value();
+      theEdge = anEdge;
+      anEndParam = anIntPoint.ParamOnFirst();
+      break;
+    }
+  }
+
+  theLenToEnd = 0.;
+  if (anEndParam != 0.)
+  {
+    const Standard_Integer NCONTROL = 23;
+    Standard_Real aDelta = anEndParam / (NCONTROL-1);
+    gp_Pnt aPrevPnt;
+    for (Standard_Integer ii = 0; ii < NCONTROL; ii++)
+    {
+      Standard_Real aPar = ii*aDelta;
+      gp_Pnt2d aPnt2d = aLine->Value(aPar);
+      gp_Pnt aPnt = aBAsurf.Value(aPnt2d.X(), aPnt2d.Y());
+      if (ii > 0)
+        theLenToEnd += aPrevPnt.Distance(aPnt);
+      aPrevPnt = aPnt;
+    }
+  }
+}
+
 //=======================================================================
 //function : OriSect
 //purpose  : 
@@ -513,11 +586,19 @@ void BRepOffset_Tool::OrientSection (const TopoDS_Edge&  E,
   gp_Vec   D1U,D1V;
   
   S1->D1(P.X(),P.Y(),P3,D1U,D1V);
+  //Temporary
+  D1U.Normalize();
+  D1V.Normalize();
+  ///////////
   gp_Vec DN1(D1U^D1V);
   if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
   
   P = C2->Value(ParOnC);
   S2->D1(P.X(),P.Y(),P3,D1U,D1V);
+  //Temporary
+  D1U.Normalize();
+  D1V.Normalize();
+  ///////////
   gp_Vec DN2(D1U^D1V);
   if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
   
@@ -1399,9 +1480,11 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
                              TopTools_ListOfShape& L1,
                              TopTools_ListOfShape& L2,
                              const TopAbs_State    Side,
+                              const Standard_Real   theOffset,
                              const TopoDS_Edge&    RefEdge,
                               const TopoDS_Face&    theRefFace1,
-                              const TopoDS_Face&    theRefFace2)
+                              const TopoDS_Face&    theRefFace2,
+                              const Standard_Boolean theIsEdgeSmooth)
 {
 #ifdef DRAW
   if (AffichInter) {
@@ -1428,429 +1511,452 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
       }
     }
   }
-  
+
   // create 3D curves on faces
   BRepLib::BuildCurves3d(F1);
   BRepLib::BuildCurves3d(F2);
   UpdateVertexTolerances(F1);
   UpdateVertexTolerances(F2);
  
-  BOPAlgo_PaveFiller aPF;
-  TopTools_ListOfShape aLS;
-  aLS.Append(F1);
-  aLS.Append(F2);
-  aPF.SetArguments(aLS);
-  //
-  aPF.Perform();
-  
-  TopTools_IndexedMapOfShape TrueEdges;
-  if (!RefEdge.IsNull())
-    CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
-
-  Standard_Boolean addPCurve1 = 1;
-  Standard_Boolean addPCurve2 = 1;
-  
-  const BOPDS_PDS& pDS = aPF.PDS();
-  BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
-  Standard_Integer aNb = aFFs.Length();
-  Standard_Integer i = 0, j = 0, k;
-  // Store Result
-  L1.Clear(); L2.Clear();
   TopAbs_Orientation O1,O2;
-  BRep_Builder BB;
-  //
-  const Handle(IntTools_Context)& aContext = aPF.Context();
-  //
-  for (i = 0; i < aNb; i++) {
-    BOPDS_InterfFF& aFFi=aFFs(i);
-    const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
-        
-    Standard_Integer aNbCurves = aBCurves.Length();
-      
-    for (j = 0; j < aNbCurves; j++) {
-      const BOPDS_Curve& aBC=aBCurves(j);
-      const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
+  if (theIsEdgeSmooth && !RefEdge.IsNull() && !theRefFace1.IsNull() && !theRefFace2.IsNull())
+  {
+    //projection in middle direction of RefEdge onto NF1 and NF2
+    TopoDS_Edge aNewEdge = ProjectEdgeOntoTwoFaces(RefEdge, theRefFace1, theRefFace2,
+                                                   F1, F2, theOffset);
+    /*
+    OrientSection (aNewEdge, F1, F2, O1, O2);
+    if (Side == TopAbs_OUT)
+    {
+      O1 = TopAbs::Reverse(O1);
+      O2 = TopAbs::Reverse(O2);
+    }
+    */
+
+    O1 = BRepTools::OriEdgeInFace(RefEdge, theRefFace1);
+    O2 = BRepTools::OriEdgeInFace(RefEdge, theRefFace2);
+    
+    L1.Append (aNewEdge.Oriented(O1));
+    L2.Append (aNewEdge.Oriented(O2));
+  }
+  else //general case: boolean operation between faces
+  {
+    BOPAlgo_PaveFiller aPF;
+    TopTools_ListOfShape aLS;
+    aLS.Append(F1);
+    aLS.Append(F2);
+    aPF.SetArguments(aLS);
+    //
+    aPF.Perform();
+    
+    TopTools_IndexedMapOfShape TrueEdges;
+    if (!RefEdge.IsNull())
+      CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
+    
+    Standard_Boolean addPCurve1 = 1;
+    Standard_Boolean addPCurve2 = 1;
+    
+    const BOPDS_PDS& pDS = aPF.PDS();
+    BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
+    Standard_Integer aNb = aFFs.Length();
+    Standard_Integer i = 0, j = 0, k;
+    // Store Result
+    L1.Clear(); L2.Clear();
+    BRep_Builder BB;
+    //
+    const Handle(IntTools_Context)& aContext = aPF.Context();
+    //
+    for (i = 0; i < aNb; i++) {
+      BOPDS_InterfFF& aFFi=aFFs(i);
+      const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
       
-      BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
-      aPBIt.Initialize(aSectEdges);
+      Standard_Integer aNbCurves = aBCurves.Length();
       
-      for (; aPBIt.More(); aPBIt.Next()) {
-        const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
-        Standard_Integer nSect = aPB->Edge();
-        const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
-       if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
-         continue;
+      for (j = 0; j < aNbCurves; j++) {
+        const BOPDS_Curve& aBC=aBCurves(j);
+        const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
         
-        Standard_Real f, l;
-       const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
-       Handle(Geom_TrimmedCurve) aC3DETrim;
-           
-       if(!aC3DE.IsNull()) 
-            aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
+        BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
+        aPBIt.Initialize(aSectEdges);
         
-       Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
-               
-        if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
-          Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
-          if(!aC3DETrim.IsNull()) {
-            Handle(Geom2d_Curve) aC2dNew;
-            
-            if(aC3DE->IsPeriodic()) {
-              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l,  aC2d, aC2dNew, aContext);
-            }
-            else {
-              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext); 
+        for (; aPBIt.More(); aPBIt.Next()) {
+          const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
+          Standard_Integer nSect = aPB->Edge();
+          const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
+          if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
+            continue;
+          
+          Standard_Real f, l;
+          const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
+          Handle(Geom_TrimmedCurve) aC3DETrim;
+          
+          if(!aC3DE.IsNull()) 
+            aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
+          
+          Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
+          
+          if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
+            Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
+            if(!aC3DETrim.IsNull()) {
+              Handle(Geom2d_Curve) aC2dNew;
+              
+              if(aC3DE->IsPeriodic()) {
+                BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l,  aC2d, aC2dNew, aContext);
+              }
+              else {
+                BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext); 
+              }
+              aC2d = aC2dNew;
             }
-            aC2d = aC2dNew;
+            BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
           }
-          BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
-        }
-        
-        if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
-          Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
-          if(!aC3DETrim.IsNull()) {
-            Handle(Geom2d_Curve) aC2dNew;
-            
-            if(aC3DE->IsPeriodic()) {
-              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l,  aC2d, aC2dNew, aContext);
-            }
-            else {
-              BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext); 
+          
+          if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
+            Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
+            if(!aC3DETrim.IsNull()) {
+              Handle(Geom2d_Curve) aC2dNew;
+              
+              if(aC3DE->IsPeriodic()) {
+                BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l,  aC2d, aC2dNew, aContext);
+              }
+              else {
+                BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext); 
+              }
+              aC2d = aC2dNew;
             }
-            aC2d = aC2dNew;
+            BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
           }
-          BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
-        }
-         
-        OrientSection (anEdge, F1, F2, O1, O2);
-        if (Side == TopAbs_OUT) {
-          O1 = TopAbs::Reverse(O1);
-          O2 = TopAbs::Reverse(O2);
-        }
-        
-        L1.Append (anEdge.Oriented(O1));
-        L2.Append (anEdge.Oriented(O2));
-        
+          
+          OrientSection (anEdge, F1, F2, O1, O2);
+          if (Side == TopAbs_OUT) {
+            O1 = TopAbs::Reverse(O1);
+            O2 = TopAbs::Reverse(O2);
+          }
+          
+          L1.Append (anEdge.Oriented(O1));
+          L2.Append (anEdge.Oriented(O2));
+          
 #ifdef DRAW
-        if (AffichInter) {
-         char name[256];
-          sprintf(name,"EI_%d",NbNewEdges++);  
-          DBRep::Set(name,anEdge.Oriented(O1));
-         
-        }
+          if (AffichInter) {
+            char name[256];
+            sprintf(name,"EI_%d",NbNewEdges++);        
+            DBRep::Set(name,anEdge.Oriented(O1));
+            
+          }
 #endif       
+        }
       }
     }
-  }
 
-  Standard_Real aSameParTol = Precision::Confusion();
-  Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
-
-  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
-  if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
-    aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
-  if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
-    addPCurve1 = Standard_False;
-  else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
-    isEl1 = Standard_True;
-
-  aSurf = BRep_Tool::Surface(F2);
-  if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
-    aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
-  if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
-    addPCurve2 = Standard_False;
-  else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
-    isEl2 = Standard_True;
-
-  if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
-  {
-    //remove excess edges that are out of range
-    TopoDS_Vertex aV1, aV2;
-    TopExp::Vertices (RefEdge, aV1, aV2);
-    if (!aV1.IsSame(aV2)) //only if RefEdge is open
+    Standard_Real aSameParTol = Precision::Confusion();
+    Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
+    
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
+    if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
+      aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
+    if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
+      addPCurve1 = Standard_False;
+    else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
+      isEl1 = Standard_True;
+    
+    aSurf = BRep_Tool::Surface(F2);
+    if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
+      aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
+    if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
+      addPCurve2 = Standard_False;
+    else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
+      isEl2 = Standard_True;
+    
+    if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
     {
-      Handle(Geom_Surface) aRefSurf1 = BRep_Tool::Surface (theRefFace1);
-      Handle(Geom_Surface) aRefSurf2 = BRep_Tool::Surface (theRefFace2);
-      if (aRefSurf1->IsUClosed() || aRefSurf1->IsVClosed() ||
-          aRefSurf2->IsUClosed() || aRefSurf2->IsVClosed())
+      //remove excess edges that are out of range
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices (RefEdge, aV1, aV2);
+      if (!aV1.IsSame(aV2)) //only if RefEdge is open
       {
-        TopoDS_Edge MinAngleEdge;
-        Standard_Real MinAngle = Precision::Infinite();
-        BRepAdaptor_Curve aRefBAcurve (RefEdge);
-        gp_Pnt aRefPnt = aRefBAcurve.Value ((aRefBAcurve.FirstParameter() + aRefBAcurve.LastParameter())/2);
-        
-        TopTools_ListIteratorOfListOfShape itl (L1);
-        for (; itl.More(); itl.Next())
+        Handle(Geom_Surface) aRefSurf1 = BRep_Tool::Surface (theRefFace1);
+        Handle(Geom_Surface) aRefSurf2 = BRep_Tool::Surface (theRefFace2);
+        if (aRefSurf1->IsUClosed() || aRefSurf1->IsVClosed() ||
+            aRefSurf2->IsUClosed() || aRefSurf2->IsVClosed())
         {
-          const TopoDS_Edge& anEdge = TopoDS::Edge (itl.Value());
-          
-          BRepAdaptor_Curve aBAcurve (anEdge);
-          gp_Pnt aMidPntOnEdge = aBAcurve.Value ((aBAcurve.FirstParameter() + aBAcurve.LastParameter())/2);
-          gp_Vec RefToMid (aRefPnt, aMidPntOnEdge);
+          TopoDS_Edge MinAngleEdge;
+          Standard_Real MinAngle = Precision::Infinite();
+          BRepAdaptor_Curve aRefBAcurve (RefEdge);
+          gp_Pnt aRefPnt = aRefBAcurve.Value ((aRefBAcurve.FirstParameter() + aRefBAcurve.LastParameter())/2);
           
-          Extrema_ExtPC aProjector (aRefPnt, aBAcurve);
-          if (aProjector.IsDone())
+          TopTools_ListIteratorOfListOfShape itl (L1);
+          for (; itl.More(); itl.Next())
           {
-            Standard_Integer imin = 0;
-            Standard_Real MinSqDist = Precision::Infinite();
-            for (Standard_Integer ind = 1; ind <= aProjector.NbExt(); ind++)
+            const TopoDS_Edge& anEdge = TopoDS::Edge (itl.Value());
+            
+            BRepAdaptor_Curve aBAcurve (anEdge);
+            gp_Pnt aMidPntOnEdge = aBAcurve.Value ((aBAcurve.FirstParameter() + aBAcurve.LastParameter())/2);
+            gp_Vec RefToMid (aRefPnt, aMidPntOnEdge);
+            
+            Extrema_ExtPC aProjector (aRefPnt, aBAcurve);
+            if (aProjector.IsDone())
             {
-              Standard_Real aSqDist = aProjector.SquareDistance(ind);
-              if (aSqDist < MinSqDist)
+              Standard_Integer imin = 0;
+              Standard_Real MinSqDist = Precision::Infinite();
+              for (Standard_Integer ind = 1; ind <= aProjector.NbExt(); ind++)
               {
-                MinSqDist = aSqDist;
-                imin = ind;
+                Standard_Real aSqDist = aProjector.SquareDistance(ind);
+                if (aSqDist < MinSqDist)
+                {
+                  MinSqDist = aSqDist;
+                  imin = ind;
+                }
               }
-            }
-            if (imin != 0)
-            {
-              gp_Pnt aProjectionOnEdge = aProjector.Point(imin).Value();
-              gp_Vec RefToProj (aRefPnt, aProjectionOnEdge);
-              Standard_Real anAngle = RefToProj.Angle(RefToMid);
-              if (anAngle < MinAngle)
+              if (imin != 0)
               {
-                MinAngle = anAngle;
-                MinAngleEdge = anEdge;
+                gp_Pnt aProjectionOnEdge = aProjector.Point(imin).Value();
+                gp_Vec RefToProj (aRefPnt, aProjectionOnEdge);
+                Standard_Real anAngle = RefToProj.Angle(RefToMid);
+                if (anAngle < MinAngle)
+                {
+                  MinAngle = anAngle;
+                  MinAngleEdge = anEdge;
+                }
               }
             }
           }
-        }
-
-        if (!MinAngleEdge.IsNull())
-        {
-          TopTools_ListIteratorOfListOfShape itlist1 (L1);
-          TopTools_ListIteratorOfListOfShape itlist2 (L2);
           
-          while (itlist1.More())
+          if (!MinAngleEdge.IsNull())
           {
-            const TopoDS_Shape& anEdge = itlist1.Value();
-            if (anEdge.IsSame(MinAngleEdge))
-            {
-              itlist1.Next();
-              itlist2.Next();
-            }
-            else
+            TopTools_ListIteratorOfListOfShape itlist1 (L1);
+            TopTools_ListIteratorOfListOfShape itlist2 (L2);
+            
+            while (itlist1.More())
             {
-              L1.Remove(itlist1);
-              L2.Remove(itlist2);
+              const TopoDS_Shape& anEdge = itlist1.Value();
+              if (anEdge.IsSame(MinAngleEdge))
+              {
+                itlist1.Next();
+                itlist2.Next();
+              }
+              else
+              {
+                L1.Remove(itlist1);
+                L2.Remove(itlist2);
+              }
             }
           }
-        }
-      } //if closed
-    } //if (!aV1.IsSame(aV2))
-  } //if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
+        } //if closed
+      } //if (!aV1.IsSame(aV2))
+    } //if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
 
-  if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
-    TopTools_SequenceOfShape eseq;
-    TopTools_SequenceOfShape EdgesForConcat;
-    
-    if (!TrueEdges.IsEmpty())
-    {
-      for (i = TrueEdges.Extent(); i >= 1; i--)
-        EdgesForConcat.Append( TrueEdges(i) );
-      TopoDS_Edge AssembledEdge =
-        AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
-      if (AssembledEdge.IsNull())
+    if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
+      TopTools_SequenceOfShape eseq;
+      TopTools_SequenceOfShape EdgesForConcat;
+      
+      if (!TrueEdges.IsEmpty())
+      {
         for (i = TrueEdges.Extent(); i >= 1; i--)
-          eseq.Append( TrueEdges(i) );
+          EdgesForConcat.Append( TrueEdges(i) );
+        TopoDS_Edge AssembledEdge =
+          AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
+        if (AssembledEdge.IsNull())
+          for (i = TrueEdges.Extent(); i >= 1; i--)
+            eseq.Append( TrueEdges(i) );
+        else
+          eseq.Append(AssembledEdge);
+      }
       else
-        eseq.Append(AssembledEdge);
-    }
-    else
-    {
-      TopTools_SequenceOfShape wseq;
-      TopTools_SequenceOfShape edges;
-      TopTools_ListIteratorOfListOfShape itl(L1);
-      for (; itl.More(); itl.Next())
-        edges.Append( itl.Value() );
-      while (!edges.IsEmpty())
       {
-        TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
-        TopoDS_Wire aWire, resWire;
-        BB.MakeWire(aWire);
-        BB.Add( aWire, anEdge );
-        TColStd_SequenceOfInteger Candidates;
-        for (k = 1; k <= wseq.Length(); k++)
+        TopTools_SequenceOfShape wseq;
+        TopTools_SequenceOfShape edges;
+        TopTools_ListIteratorOfListOfShape itl(L1);
+        for (; itl.More(); itl.Next())
+          edges.Append( itl.Value() );
+        while (!edges.IsEmpty())
         {
-          resWire = TopoDS::Wire(wseq(k));
-          if (AreConnex( resWire, aWire ))
+          TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
+          TopoDS_Wire aWire, resWire;
+          BB.MakeWire(aWire);
+          BB.Add( aWire, anEdge );
+          TColStd_SequenceOfInteger Candidates;
+          for (k = 1; k <= wseq.Length(); k++)
           {
-            Candidates.Append( 1 );
-            break;
+            resWire = TopoDS::Wire(wseq(k));
+            if (AreConnex( resWire, aWire ))
+            {
+              Candidates.Append( 1 );
+              break;
+            }
           }
-        }
-        if (Candidates.IsEmpty())
-        {
-          wseq.Append( aWire );
-          edges.Remove(1);
-        }
-        else
-        {
-          for (j = 2; j <= edges.Length(); j++)
+          if (Candidates.IsEmpty())
           {
-            anEdge = TopoDS::Edge( edges(j) );
-            aWire.Nullify();
-            BB.MakeWire(aWire);
-            BB.Add( aWire, anEdge );
-            if (AreConnex( resWire, aWire ))
-              Candidates.Append( j );
+            wseq.Append( aWire );
+            edges.Remove(1);
           }
-          Standard_Integer minind = 1;
-          if (Candidates.Length() > 1)
+          else
           {
-            Standard_Real MinAngle = RealLast();
-            for (j = 1; j <= Candidates.Length(); j++)
+            for (j = 2; j <= edges.Length(); j++)
+            {
+              anEdge = TopoDS::Edge( edges(j) );
+              aWire.Nullify();
+              BB.MakeWire(aWire);
+              BB.Add( aWire, anEdge );
+              if (AreConnex( resWire, aWire ))
+                Candidates.Append( j );
+            }
+            Standard_Integer minind = 1;
+            if (Candidates.Length() > 1)
             {
-              anEdge = TopoDS::Edge( edges(Candidates(j)) );
-              Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
-              if (anAngle < MinAngle)
+              Standard_Real MinAngle = RealLast();
+              for (j = 1; j <= Candidates.Length(); j++)
               {
-                MinAngle = anAngle;
-                minind = j;
+                anEdge = TopoDS::Edge( edges(Candidates(j)) );
+                Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
+                if (anAngle < MinAngle)
+                {
+                  MinAngle = anAngle;
+                  minind = j;
+                }
               }
             }
+            BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
+            wseq(k) = resWire;
+            edges.Remove(Candidates(minind));
           }
-          BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
-          wseq(k) = resWire;
-          edges.Remove(Candidates(minind));
-        }
-      } //end of while (!edges.IsEmpty())
-      
-      for (i = 1; i <= wseq.Length(); i++)
-      {
-        TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
-        TopTools_SequenceOfShape aLocalEdgesForConcat;
-        if (aWire.Closed())
+        } //end of while (!edges.IsEmpty())
+        
+        for (i = 1; i <= wseq.Length(); i++)
         {
-          TopoDS_Vertex StartVertex;
-          TopoDS_Edge StartEdge;
-          Standard_Boolean StartFound = Standard_False;
-          TopTools_ListOfShape Elist;
-          
-          TopoDS_Iterator itw(aWire);
-          for (; itw.More(); itw.Next())
+          TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
+          TopTools_SequenceOfShape aLocalEdgesForConcat;
+          if (aWire.Closed())
           {
-            TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
-            if (StartFound)
-              Elist.Append(anEdge);
-            else
+            TopoDS_Vertex StartVertex;
+            TopoDS_Edge StartEdge;
+            Standard_Boolean StartFound = Standard_False;
+            TopTools_ListOfShape Elist;
+            
+            TopoDS_Iterator itw(aWire);
+            for (; itw.More(); itw.Next())
             {
-              TopoDS_Vertex V1, V2;
-              TopExp::Vertices( anEdge, V1, V2 );
-              if (!IsAutonomVertex( V1, pDS ))
-              {
-                StartVertex = V2;
-                StartEdge = anEdge;
-                StartFound = Standard_True;
-              }
-              else if (!IsAutonomVertex( V2, pDS ))
+              TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
+              if (StartFound)
+                Elist.Append(anEdge);
+              else
               {
-                StartVertex = V1;
-                StartEdge = anEdge;
-                StartFound = Standard_True;
+                TopoDS_Vertex V1, V2;
+                TopExp::Vertices( anEdge, V1, V2 );
+                if (!IsAutonomVertex( V1, pDS ))
+                {
+                  StartVertex = V2;
+                  StartEdge = anEdge;
+                  StartFound = Standard_True;
+                }
+                else if (!IsAutonomVertex( V2, pDS ))
+                {
+                  StartVertex = V1;
+                  StartEdge = anEdge;
+                  StartFound = Standard_True;
+                }
+                else
+                  Elist.Append(anEdge);
               }
-              else
-                Elist.Append(anEdge);
-            }
-          } //end of for (; itw.More(); itw.Next())
-          if (!StartFound)
-          {
-            itl.Initialize(Elist);
-            StartEdge = TopoDS::Edge(itl.Value());
-            Elist.Remove(itl);
-            TopoDS_Vertex V1, V2;
-            TopExp::Vertices( StartEdge, V1, V2 );
-            StartVertex = V1;
-          }
-          aLocalEdgesForConcat.Append( StartEdge );
-          while (!Elist.IsEmpty())
-          {
-            for (itl.Initialize(Elist); itl.More(); itl.Next())
+            } //end of for (; itw.More(); itw.Next())
+            if (!StartFound)
             {
-              TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+              itl.Initialize(Elist);
+              StartEdge = TopoDS::Edge(itl.Value());
+              Elist.Remove(itl);
               TopoDS_Vertex V1, V2;
-              TopExp::Vertices( anEdge, V1, V2 );
-              if (V1.IsSame(StartVertex))
-              {
-                StartVertex = V2;
-                aLocalEdgesForConcat.Append( anEdge );
-                Elist.Remove(itl);
-                break;
-              }
-              else if (V2.IsSame(StartVertex))
+              TopExp::Vertices( StartEdge, V1, V2 );
+              StartVertex = V1;
+            }
+            aLocalEdgesForConcat.Append( StartEdge );
+            while (!Elist.IsEmpty())
+            {
+              for (itl.Initialize(Elist); itl.More(); itl.Next())
               {
-                StartVertex = V1;
-                aLocalEdgesForConcat.Append( anEdge );
-                Elist.Remove(itl);
-                break;
+                TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+                TopoDS_Vertex V1, V2;
+                TopExp::Vertices( anEdge, V1, V2 );
+                if (V1.IsSame(StartVertex))
+                {
+                  StartVertex = V2;
+                  aLocalEdgesForConcat.Append( anEdge );
+                  Elist.Remove(itl);
+                  break;
+                }
+                else if (V2.IsSame(StartVertex))
+                {
+                  StartVertex = V1;
+                  aLocalEdgesForConcat.Append( anEdge );
+                  Elist.Remove(itl);
+                  break;
+                }
               }
-            }
-          } //end of while (!Elist.IsEmpty())
-        } //end of if (aWire.Closed())
-        else
-        {
-          BRepTools_WireExplorer Wexp( aWire );
-          for (; Wexp.More(); Wexp.Next())
-            aLocalEdgesForConcat.Append( Wexp.Current() );
+            } //end of while (!Elist.IsEmpty())
+          } //end of if (aWire.Closed())
+          else
+          {
+            BRepTools_WireExplorer Wexp( aWire );
+            for (; Wexp.More(); Wexp.Next())
+              aLocalEdgesForConcat.Append( Wexp.Current() );
+          }
+          
+          TopoDS_Edge AssembledEdge =
+            AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
+          if (AssembledEdge.IsNull())
+            for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
+              eseq.Append( aLocalEdgesForConcat(j) );
+          else
+            eseq.Append( AssembledEdge );
         }
-       
-        TopoDS_Edge AssembledEdge =
-          AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
-        if (AssembledEdge.IsNull())
-          for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
-            eseq.Append( aLocalEdgesForConcat(j) );
-        else
-          eseq.Append( AssembledEdge );
-      } //for (i = 1; i <= wseq.Length(); i++)
-    } //end of else (when TrueEdges is empty)
-    
-    if (eseq.Length() < L1.Extent())
-    {
-      L1.Clear();
-      L2.Clear();
-      for (i = 1; i <= eseq.Length(); i++)
+      } //end of else (when TrueEdges is empty)
+      
+      if (eseq.Length() < L1.Extent())
       {
-        TopoDS_Shape aShape = eseq(i);
-        TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
-        BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
-        Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
-#ifdef OCCT_DEBUG
-        std::cout<<"Tolerance of glued E =      "<<EdgeTol<<std::endl;
-#endif
-        if (EdgeTol > 1.e-2)
-          continue;
-        
-        if (EdgeTol >= 1.e-4)
+        L1.Clear();
+        L2.Clear();
+        for (i = 1; i <= eseq.Length(); i++)
         {
-          ReconstructPCurves(anEdge);
+          TopoDS_Shape aShape = eseq(i);
+          TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
           BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
+          Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
 #ifdef OCCT_DEBUG
-          std::cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<std::endl;
+          std::cout<<"Tolerance of glued E =      "<<EdgeTol<<std::endl;
 #endif
+          if (EdgeTol > 1.e-2)
+            continue;
+          
+          if (EdgeTol >= 1.e-4)
+          {
+            ReconstructPCurves(anEdge);
+            BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
+#ifdef OCCT_DEBUG
+            std::cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<std::endl;
+#endif
+          }
+          
+          OrientSection( anEdge, F1, F2, O1, O2 );
+          if (Side == TopAbs_OUT)
+          {
+            O1 = TopAbs::Reverse(O1);
+            O2 = TopAbs::Reverse(O2);
+          }
+          
+          L1.Append( anEdge.Oriented(O1) );
+          L2.Append( anEdge.Oriented(O2) );
         }
-        
-        OrientSection( anEdge, F1, F2, O1, O2 );
-        if (Side == TopAbs_OUT)
-        {
-          O1 = TopAbs::Reverse(O1);
-          O2 = TopAbs::Reverse(O2);
-        }
-        
-        L1.Append( anEdge.Oriented(O1) );
-        L2.Append( anEdge.Oriented(O2) );
       }
-    }
-  } //end of if (L1.Extent() > 1)
-  
-  else
-  {
-    TopTools_ListIteratorOfListOfShape itl(L1);
-    for (; itl.More(); itl.Next())
+    } //end of if (L1.Extent() > 1)
+    
+    else
     {
-      const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
-      BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
+      TopTools_ListIteratorOfListOfShape itl(L1);
+      for (; itl.More(); itl.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
+        BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
+      }
     }
-  }
+  } //end of general case
 }
 
 //=======================================================================
@@ -2740,7 +2846,8 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
                                        const Standard_Real    vf1,
                                        const Standard_Real    vf2,
                                         const Standard_Real    coeff,
-                                       const Standard_Boolean theGlobalEnlargeU,
+                                       const Standard_Boolean theGlobalEnlargeUfirst,
+                                       const Standard_Boolean theGlobalEnlargeUlast,
                                        const Standard_Boolean theGlobalEnlargeVfirst,
                                        const Standard_Boolean theGlobalEnlargeVlast,
                                         const Standard_Real    theLenBeforeUfirst,
@@ -2755,7 +2862,8 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
     Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
     EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
                    uf1,uf2,vf1,vf2,coeff,
-                    theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
+                    theGlobalEnlargeUfirst, theGlobalEnlargeUlast,
+                    theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
                     theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
     if (!theGlobalEnlargeVfirst)
       V1 = vf1;
@@ -2769,10 +2877,25 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
     SurfaceChange = Standard_True;
   }
   else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
+    /*
+    Standard_Real aTol = 1.e-4;
+    GeomAbs_Shape aUCont = GeomAbs_C1, aVCont = GeomAbs_C1;
+    Standard_Integer aDegU = 14, aDegV = 14;
+    Standard_Integer aNmax = 16;
+    Standard_Integer aPrec = 1;
+    GeomConvert_ApproxSurface anApprox(S,aTol,aUCont,aVCont,aDegU,aDegV,aNmax,aPrec);
+    S = anApprox.Surface();
+    SurfaceChange = EnlargeGeometry(S,U1,U2,V1,V2,IsV1degen,IsV2degen,
+                                   uf1,uf2,vf1,vf2,coeff,
+                                    theGlobalEnlargeUfirst, theGlobalEnlargeUlast,
+                                    theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
+                                    theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
+    */
     Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
     SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
                                    uf1,uf2,vf1,vf2,coeff,
-                                    theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
+                                    theGlobalEnlargeUfirst, theGlobalEnlargeUlast,
+                                    theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
                                     theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
     Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
   }
@@ -2783,8 +2906,8 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
       dv_first = 0., dv_last = 0.;
     Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
     Standard_Real u1, u2, v1, v2;
-    Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
-    Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
+    Standard_Boolean enlargeU = Standard_True, enlargeV = Standard_True;
+    Standard_Boolean enlargeUfirst = theGlobalEnlargeUfirst, enlargeUlast = theGlobalEnlargeUlast;
     Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
     S->Bounds( u1, u2, v1, v2 );
     if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
@@ -2839,6 +2962,21 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
         IsV2degen = Standard_True;
       }
     }
+
+    //Temporary
+    //Standard_Real MinVal = Min(du_first, du_last);
+    //MinVal = Min(MinVal, Min(dv_first, dv_last));
+    //du_first = du_last = dv_first = dv_last = MinVal;
+
+    Standard_Real MinVal = RealLast();
+    Standard_Real Values [4] = {du_first, du_last, dv_first, dv_last};
+    for (Standard_Integer ii = 0; ii < 4; ii++)
+      if (Values[ii] != 0. && Values[ii] < MinVal)
+        MinVal = Values[ii];
+    if (Precision::IsInfinite(MinVal))
+      MinVal = 0.;
+    ///////////
+    
     Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
     if (enlargeU)
     {
@@ -2861,8 +2999,8 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
   else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
           S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
   {
-    Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
-    Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
+    Standard_Boolean enlargeU = Standard_True, enlargeV = Standard_True;
+    Standard_Boolean enlargeUfirst = theGlobalEnlargeUfirst, enlargeUlast = theGlobalEnlargeUlast;
     Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
     if (S->IsUClosed())
       enlargeU = Standard_False;
@@ -2923,6 +3061,20 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
       }
     }
     
+    //Temporary
+    //Standard_Real MinVal = Min(du_first, du_last);
+    //MinVal = Min(MinVal, Min(dv_first, dv_last));
+    //du_first = du_last = dv_first = dv_last = MinVal;
+
+    Standard_Real MinVal = RealLast();
+    Standard_Real Values [4] = {du_first, du_last, dv_first, dv_last};
+    for (Standard_Integer ii = 0; ii < 4; ii++)
+      if (Values[ii] != 0. && Values[ii] < MinVal)
+        MinVal = Values[ii];
+    if (Precision::IsInfinite(MinVal))
+      MinVal = 0.;
+    ///////////
+    
     Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
     if (enlargeU)
     {
@@ -3043,17 +3195,14 @@ static void CompactUVBounds (const TopoDS_Face& F,
 
 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
                                  const BRepOffset_Analyse& Analyse,
-                                 Standard_Boolean& enlargeU,
+                                 Standard_Boolean& enlargeUfirst,
+                                 Standard_Boolean& enlargeUlast,
                                  Standard_Boolean& enlargeVfirst,
                                  Standard_Boolean& enlargeVlast)
 {
-  enlargeU = Standard_True;
+  enlargeUfirst = Standard_True; enlargeUlast = Standard_True;
   enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
 
-  Standard_Integer Ubound = 0, Vbound = 0;
-  Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
-  Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
-
   Standard_Real UF1,UF2,VF1,VF2;
   CompactUVBounds(F,UF1,UF2,VF1,VF2);
 
@@ -3065,82 +3214,60 @@ void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
       theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
       theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
       theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
+  {
+    TopExp_Explorer Explo(F, TopAbs_EDGE);
+    for (; Explo.More(); Explo.Next())
     {
-      TopExp_Explorer Explo(F, TopAbs_EDGE);
-      for (; Explo.More(); Explo.Next())
-       {
-         const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
-         const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
-         if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
-           {
-             ChFiDS_TypeOfConcavity OT = L.First().Type();
-             if (OT == ChFiDS_Tangential || BRep_Tool::Degenerated(anEdge))
-               {
-                 Standard_Real fpar, lpar;
-                 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
-                 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
-                   aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
-                 
-                 Handle(Geom2d_Line) theLine;
-                 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
-                   theLine = Handle(Geom2d_Line)::DownCast (aCurve);
-                 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
-                          aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
-                   {
-                     Standard_Real newFpar, newLpar, deviation;
-                     theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
-                                                                    newFpar, newLpar, deviation);
-                   }
-
-                 if (!theLine.IsNull())
-                   {
-                     gp_Dir2d theDir = theLine->Direction();
-                     if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
-                       {
-                         Vbound++;
-                         if (BRep_Tool::Degenerated(anEdge))
-                           {
-                             if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
-                               enlargeVfirst = Standard_False;
-                             else //theLine->Location().Y() is near VF2
-                               enlargeVlast  = Standard_False;
-                           }
-                         else
-                           {
-                             if (theLine->Location().Y() < Vfirst)
-                               Vfirst = theLine->Location().Y();
-                             if (theLine->Location().Y() > Vlast)
-                               Vlast  = theLine->Location().Y();
-                           }
-                       }
-                     else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
-                       {
-                         Ubound++;
-                         if (theLine->Location().X() < Ufirst)
-                           Ufirst = theLine->Location().X();
-                         if (theLine->Location().X() > Ulast)
-                           Ulast  = theLine->Location().X();
-                       }
-                   }
-               }
-           }
-       }
-    }
-
-  if (Ubound >= 2 || Vbound >= 2)
-    {
-      if (Ubound >= 2 &&
-         Abs(UF1-Ufirst) <= Precision::Confusion() &&
-         Abs(UF2-Ulast)  <= Precision::Confusion())
-       enlargeU = Standard_False;
-      if (Vbound >= 2 &&
-         Abs(VF1-Vfirst) <= Precision::Confusion() &&
-         Abs(VF2-Vlast)  <= Precision::Confusion())
-       {
-         enlargeVfirst = Standard_False;
-         enlargeVlast  = Standard_False;
-       }
+      const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+      const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
+      Standard_Boolean anIsDegeneratedEdge = BRep_Tool::Degenerated(anEdge);
+      ChFiDS_TypeOfConcavity OT = ChFiDS_Other;
+      if (!L.IsEmpty())
+        OT = L.First().Type();
+      
+      if (anIsDegeneratedEdge)
+          // || OT == ChFiDS_FreeBound
+          // || OT == ChFiDS_Tangential)
+      {
+        Standard_Real fpar, lpar;
+        Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
+        if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
+          aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
+        
+        Handle(Geom2d_Line) aLine;
+        if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
+          aLine = Handle(Geom2d_Line)::DownCast (aCurve);
+        else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
+                 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
+        {
+          Standard_Real newFpar, newLpar, deviation;
+          aLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
+                                                       newFpar, newLpar, deviation);
+        }
+        
+        if (!aLine.IsNull())
+        {
+          gp_Dir2d aDir = aLine->Direction();
+          if (aDir.IsParallel( gp::DX2d(), Precision::Angular() ))
+          {
+            Standard_Real aV = aLine->Location().Y();
+            if (Abs(aV - VF1) <= Precision::Confusion())
+              enlargeVfirst = Standard_False;
+            else if (Abs(aV - VF2) <= Precision::Confusion())
+              enlargeVlast  = Standard_False;
+          }
+          else if (aDir.IsParallel( gp::DY2d(), Precision::Angular() ))
+          {
+            Standard_Real aU = aLine->Location().X();
+            if (Abs(aU - UF1) <= Precision::Confusion())
+              enlargeUfirst = Standard_False;
+            else if (Abs(aU - UF2) <= Precision::Confusion())
+              enlargeUlast = Standard_False;
+          }
+        }
+      }
     }
+  }
 }
 
 //=======================================================================
@@ -3153,7 +3280,8 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
  TopoDS_Face&             BF,
  const Standard_Boolean   CanExtentSurface,
  const Standard_Boolean   UpdatePCurve,
- const Standard_Boolean   theEnlargeU,
+ const Standard_Boolean   theEnlargeUfirst,
+ const Standard_Boolean   theEnlargeUlast,
  const Standard_Boolean   theEnlargeVfirst,
  const Standard_Boolean   theEnlargeVlast,
  const Standard_Integer   theExtensionMode,
@@ -3192,18 +3320,29 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
   }
   else
   {
-    Standard_Real FaceDU = UF2 - UF1;
-    Standard_Real FaceDV = VF2 - VF1;
-    UU1 = UF1 - 10*FaceDU;
-    UU2 = UF2 + 10*FaceDU;
-    VV1 = VF1 - 10*FaceDV;
-    VV2 = VF2 + 10*FaceDV;
+    if (theExtensionMode == 2)
+    {
+      Standard_Real FaceDU = UF2 - UF1;
+      Standard_Real FaceDV = VF2 - VF1;
+      UU1 = UF1 - 10*FaceDU;
+      UU2 = UF2 + 10*FaceDU;
+      VV1 = VF1 - 10*FaceDV;
+      VV2 = VF2 + 10*FaceDV;
+    }
+    else
+    {
+      Standard_Real aSize = theLenBeforeUfirst;
+      UU1 = UF1 - aSize;
+      UU2 = UF2 + aSize;
+      VV1 = VF1 - aSize;
+      VV2 = VF2 + aSize;
+    }
     coeff = 1.;
   }
   
   if (CanExtentSurface) {
     SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
-                                    theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
+                                    theEnlargeUfirst, theEnlargeUlast, theEnlargeVfirst, theEnlargeVlast,
                                     theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
   }
   else {
@@ -3255,10 +3394,10 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
        }
     }
 
-  if (!theEnlargeU)
-    {
-      UU1 = UF1; UU2 = UF2;
-    }
+  if (!theEnlargeUfirst)
+    UU1 = UF1;
+  if (!theEnlargeUlast)
+    UU2 = UF2;
   if (!theEnlargeVfirst)
     VV1 = VF1;
   if (!theEnlargeVlast)
@@ -3546,7 +3685,7 @@ void BRepOffset_Tool::ExtentFace (const TopoDS_Face&            F,
       if (ToBuild.IsBound(E)) {
         EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
         TopoDS_Face NullFace;
-        BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,NullFace,NullFace);
+        BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,0.,E,NullFace,NullFace);
         // No intersection, it may happen for example for a chosen (non-offseted) planar face and 
         // its neighbour offseted cylindrical face, if the offset is directed so that 
         // the radius of the cylinder becomes smaller.
@@ -4138,3 +4277,538 @@ static void UpdateVertexTolerances(const TopoDS_Face& theFace)
     }
   }
 }
+
+//=======================================================================
+//function : ProjectEdgeOntoTwoFaces
+//purpose  : 
+//=======================================================================
+
+static TopoDS_Edge ProjectEdgeOntoTwoFaces (const TopoDS_Edge&  theRefEdge,
+                                            const TopoDS_Face&  theRefFace1,
+                                            const TopoDS_Face&  theRefFace2,
+                                            const TopoDS_Face&  theFace1,
+                                            const TopoDS_Face&  theFace2,
+                                            const Standard_Real theOffset)
+{
+  const Standard_Integer NCONTROL = 23;
+  const Standard_Real aTolLen = Precision::Confusion();
+
+  Standard_Real Umin[2], Umax[2], Vmin[2], Vmax[2];
+  CompactUVBounds(theFace1, Umin[0], Umax[0], Vmin[0], Vmax[0]);
+  CompactUVBounds(theFace2, Umin[1], Umax[1], Vmin[1], Vmax[1]);
+
+  BRepTopAdaptor_FClass2d aClassifier0(theFace1, Precision::Confusion());
+  BRepTopAdaptor_FClass2d aClassifier1(theFace2, Precision::Confusion());
+  //BRepTopAdaptor_FClass2d* aClass [2] = {&aClassifier0, &aClassifier1};
+
+  BRepAdaptor_Curve aBAcurve(theRefEdge);
+  BRepAdaptor_Curve2d aBAcurve1(theRefEdge, theRefFace1);
+  BRepAdaptor_Curve2d aBAcurve2(theRefEdge, theRefFace2);
+  BRepAdaptor_Surface aBAsurf1(theRefFace1, Standard_False);
+  BRepAdaptor_Surface aBAsurf2(theRefFace2, Standard_False);
+
+  Standard_Real aDelta = (aBAcurve.LastParameter() - aBAcurve.FirstParameter())/(NCONTROL-1);
+  TColgp_SequenceOfPnt aSeqPnt;
+  TColgp_SequenceOfPnt2d aSeqP2dOnFirst, aSeqP2dOnSecond;
+  TColStd_SequenceOfReal aParameters;
+
+  IntCurvesFace_Intersector Inters1(theFace1, Precision::Confusion());
+  IntCurvesFace_Intersector Inters2(theFace2, Precision::Confusion());
+  Standard_Real aMaxParOnLine = 2*Abs(theOffset);
+
+  for (Standard_Integer ii = 0; ii < NCONTROL; ii++)
+  {
+    Standard_Real aPar = aBAcurve.FirstParameter() + ii*aDelta;
+    gp_Pnt aPnt = aBAcurve.Value(aPar);
+    gp_Pnt2d aP2dOnFirst = aBAcurve1.Value(aPar);
+    gp_Pnt2d aP2dOnSecond = aBAcurve2.Value(aPar);
+
+    gp_Pnt aPntOnFirst, aPntOnSecond;
+    gp_Vec aNormalOnFirst = ComputeNormal (aBAsurf1, aP2dOnFirst, aTolLen, aPntOnFirst);
+    if (theRefFace1.Orientation() == TopAbs_REVERSED)
+      aNormalOnFirst.Reverse();
+    gp_Vec aNormalOnSecond = ComputeNormal (aBAsurf2, aP2dOnSecond, aTolLen, aPntOnSecond);
+    if (theRefFace2.Orientation() == TopAbs_REVERSED)
+      aNormalOnSecond.Reverse();
+    gp_Dir aMidNormal = aNormalOnFirst + aNormalOnSecond;
+    if (theOffset < 0.)
+      aMidNormal.Reverse();
+
+    gp_Lin aLin(aPnt, aMidNormal);
+    Inters1.Perform(aLin, 0., aMaxParOnLine);
+    Inters2.Perform(aLin, 0., aMaxParOnLine);
+    if (!Inters1.IsDone() || Inters1.NbPnt() == 0 ||
+        !Inters2.IsDone() || Inters2.NbPnt() == 0)
+      continue;
+    
+    Standard_Real aU = Inters1.UParameter(1);
+    Standard_Real aV = Inters1.VParameter(1);
+    gp_Pnt     aPnt1 = Inters1.Pnt(1);
+    aSeqP2dOnFirst.Append(gp_Pnt2d(aU, aV));
+
+    aU = Inters2.UParameter(1);
+    aV = Inters2.VParameter(1);
+    gp_Pnt aPnt2 = Inters2.Pnt(1);
+    aSeqP2dOnSecond.Append(gp_Pnt2d(aU, aV));
+
+    gp_Pnt aMidPnt((aPnt1.XYZ() + aPnt2.XYZ())/2);
+
+    if (aParameters.IsEmpty())
+      aParameters.Append(0.);
+    else
+    {
+      Standard_Real aDist = aMidPnt.Distance(aSeqPnt.Last());
+      Standard_Real aParam = aParameters.Last() + aDist;
+      aParameters.Append(aParam);
+    }
+    
+    aSeqPnt.Append(aMidPnt);
+  }
+
+  //Check for closedness
+  Standard_Integer aLen = aSeqP2dOnFirst.Length();
+  BRepAdaptor_Surface aNewBAsurf [2];
+  aNewBAsurf[0].Initialize(theFace1, Standard_False);
+  aNewBAsurf[1].Initialize(theFace2, Standard_False);
+  Standard_Boolean IsUclosed [2], IsVclosed [2];
+  for (Standard_Integer ii = 0; ii < 2; ii++)
+  {
+    IsUclosed[ii] = aNewBAsurf[ii].IsUClosed();
+    IsVclosed[ii] = aNewBAsurf[ii].IsVClosed();
+    TColgp_SequenceOfPnt2d* aSeqP2d = (ii == 0)? &aSeqP2dOnFirst : &aSeqP2dOnSecond;
+    if (IsUclosed[ii] || IsVclosed[ii])
+    {
+      for (Standard_Integer jj = 0; jj < 2; jj++)
+      {
+        Standard_Integer anIndLast = (jj == 0)? 1 : aLen;
+        Standard_Integer anIndPrev = (jj == 0)? anIndLast+1 : anIndLast-1;
+        Standard_Real aUlast = aSeqP2d->Value(anIndLast).X();
+        Standard_Real aVlast = aSeqP2d->Value(anIndLast).Y();
+        Standard_Real aUprev = aSeqP2d->Value(anIndPrev).X();
+        Standard_Real aVprev = aSeqP2d->Value(anIndPrev).Y();
+        if (IsUclosed[ii])
+        {
+          Standard_Real aPeriod = aNewBAsurf[ii].LastUParameter() - aNewBAsurf[ii].FirstUParameter();
+          Standard_Real aDeltaOnU = Abs(aUlast - aUprev);
+          if (aDeltaOnU > aPeriod/2)
+          {
+            if (aUlast > aUprev)
+              aUlast -= aPeriod;
+            else
+              aUlast += aPeriod;
+          }
+        }
+        if (IsVclosed[ii])
+        {
+          Standard_Real aPeriod = aNewBAsurf[ii].LastVParameter() - aNewBAsurf[ii].FirstVParameter();
+          Standard_Real aDeltaOnV = Abs(aVlast - aVprev);
+          if (aDeltaOnV > aPeriod/2)
+          {
+            if (aVlast > aVprev)
+              aVlast -= aPeriod;
+            else
+              aVlast += aPeriod;
+          }
+        }
+        aSeqP2d->ChangeValue(anIndLast) = gp_Pnt2d(aUlast, aVlast);
+      }
+    }
+  }
+
+  gp_Pnt2d EndPoints [2][2], PointsOnBounds [2][2];
+  gp_Dir2d EndTangents [2][2];
+  EndPoints[0][0] = aSeqP2dOnFirst.First();
+  EndPoints[0][1] = aSeqP2dOnFirst.Last();
+  EndPoints[1][0] = aSeqP2dOnSecond.First();
+  EndPoints[1][1] = aSeqP2dOnSecond.Last();
+  //Standard_Integer aLen = aSeqP2dOnFirst.Length();
+  EndTangents[0][0] = gp_Vec2d(aSeqP2dOnFirst(2), aSeqP2dOnFirst(1));
+  EndTangents[0][1] = gp_Vec2d(aSeqP2dOnFirst(aLen-1), aSeqP2dOnFirst(aLen));
+  EndTangents[1][0] = gp_Vec2d(aSeqP2dOnSecond(2), aSeqP2dOnSecond(1));
+  EndTangents[1][1] = gp_Vec2d(aSeqP2dOnSecond(aLen-1), aSeqP2dOnSecond(aLen));
+  TopoDS_Face Faces [2] = {theFace1, theFace2};
+  TopoDS_Edge Edges [2][2];
+  Standard_Real LensToEnds [2][2];
+  for (Standard_Integer ii = 0; ii < 2; ii++)
+    for (Standard_Integer jj = 0; jj < 2; jj++)
+      ComputeEndOfExtension(Faces[ii], EndPoints[ii][jj], EndTangents[ii][jj],
+                            PointsOnBounds[ii][jj], Edges[ii][jj], LensToEnds[ii][jj]);
+
+  //Compute middle points as ends of extension
+  for (Standard_Integer jj = 0; jj < 2; jj++)
+  {
+    gp_Pnt anEndOnFirst, anEndOnSecond;
+    gp_Vec aNormalOnFirst = ComputeNormal (aNewBAsurf[0], PointsOnBounds[0][jj], aTolLen, anEndOnFirst);
+    if (theFace1.Orientation() == TopAbs_REVERSED)
+      aNormalOnFirst.Reverse();
+    gp_Vec aNormalOnSecond = ComputeNormal (aNewBAsurf[1], PointsOnBounds[1][jj], aTolLen, anEndOnSecond);
+    if (theFace2.Orientation() == TopAbs_REVERSED)
+      aNormalOnSecond.Reverse();
+    gp_Dir aMidNormal = aNormalOnFirst + aNormalOnSecond;
+    
+    //gp_Pnt anEnd((anEndOnFirst.XYZ() + anEndOnSecond.XYZ())/2);
+    /*
+    Standard_Real aSqDist = anEndOnFirst.SquareDistance(anEndOnSecond);
+    if (aSqDist > Precision::SquareConfusion())
+    {
+      gp_Lin aLin(anEnd, aMidNormal);
+      Inters1.Perform(aLin, -aMaxParOnLine, aMaxParOnLine);
+      Standard_Real aU = Inters1.UParameter(1);
+      Standard_Real aV = Inters1.VParameter(1);
+      gp_Pnt aPnt1 =  Inters1.Pnt(1);
+      Inters2.Perform(aLin, -aMaxParOnLine, aMaxParOnLine);
+      aU = Inters2.UParameter(1);
+      aV = Inters2.VParameter(1);
+      gp_Pnt aPnt2 = Inters2.Pnt(1);
+      anEnd.SetXYZ((aPnt1.XYZ() + aPnt2.XYZ())/2);
+    }
+    */
+    
+    gp_Pnt anOrigin = (jj == 0)? aSeqPnt.First() : aSeqPnt.Last();
+    Standard_Real aSqDist0 = anOrigin.SquareDistance(anEndOnFirst);
+    Standard_Real aSqDist1 = anOrigin.SquareDistance(anEndOnSecond);
+    if (aSqDist0 <= Precision::SquareConfusion() ||
+        aSqDist1 <= Precision::SquareConfusion())
+      continue;
+
+    Standard_Real aMinLenToEnd = Min(LensToEnds[0][jj], LensToEnds[1][jj]);
+    if (aMinLenToEnd < Precision::Confusion())
+      continue;
+    aMinLenToEnd /= (NCONTROL-1);
+
+    gp_Pnt aFirstPoint = (jj == 0)? aSeqPnt(2) : aSeqPnt(aSeqPnt.Length()-1);
+    gp_Pnt aLastPoint = anOrigin;
+    for (;;)
+    {
+      gp_Dir aDir = gp_Vec(aFirstPoint, aLastPoint);
+      gp_Lin aLin(aLastPoint, aDir);
+      Standard_Real aDist = aFirstPoint.Distance(aLastPoint);
+      if (aDist < aMinLenToEnd)
+        aDist = aMinLenToEnd;
+      gp_Pnt aNextPoint = ElCLib::Value(aDist, aLin);
+      Extrema_ExtPS aProjector [2];
+      Standard_Boolean anIsProjected [2];
+      gp_Pnt aProjPnt [2];
+      gp_Pnt2d aProjP2d [2];
+      for (Standard_Integer ii = 0; ii < 2; ii++)
+      {
+        aProjector[ii].Initialize(aNewBAsurf[ii],
+                                  aNewBAsurf[ii].FirstUParameter(), aNewBAsurf[ii].LastUParameter(),
+                                  aNewBAsurf[ii].FirstVParameter(), aNewBAsurf[ii].LastVParameter(),
+                                  Precision::PConfusion(),
+                                  Precision::PConfusion());
+        aProjector[ii].Perform(aNextPoint);
+        anIsProjected[ii] = (aProjector[ii].IsDone() && aProjector[ii].NbExt() > 0);
+        if (anIsProjected[ii])
+        {
+          Standard_Integer indmin = 1;
+          for (Standard_Integer ind = 2; ind <= aProjector[ii].NbExt(); ind++)
+            if (aProjector[ii].SquareDistance(ind) < aProjector[ii].SquareDistance(indmin))
+              indmin = ind;
+          aProjPnt[ii] = aProjector[ii].Point(indmin).Value();
+          Standard_Real aU, aV;
+          aProjector[ii].Point(indmin).Parameter(aU, aV);
+          aProjP2d[ii].SetCoord(aU, aV);
+          //Check: is it a real normal projection
+          if (aU < Umin[ii] || aU > Umax[ii] ||
+              aV < Vmin[ii] || aV > Vmax[ii])
+            anIsProjected[ii] = Standard_False;
+          else
+          {
+            gp_Vec aVec(aProjPnt[ii], aNextPoint);
+            Standard_Real aMagnitude = aVec.Magnitude();
+            if (aMagnitude > Precision::Confusion())
+            {
+              aVec /= aMagnitude;
+              gp_Vec DU, DV;
+              aNewBAsurf[ii].D1(aU, aV, aProjPnt[ii], DU, DV);
+              DU.Normalize();
+              DV.Normalize();
+              gp_Vec aNormal = DU ^ DV;
+              //Standard_Boolean anIsParallel = aVec.IsParallel(aNormal, Precision::Confusion());
+              Standard_Real aScalProd = aVec * aNormal;
+              if (Abs(aScalProd) < 0.8)
+                anIsProjected[ii] = Standard_False;
+            }
+          }
+        }
+      }
+
+      //Check closedness
+      if (anIsProjected[0] && anIsProjected[1])
+      {
+        Standard_Boolean ToBreak = Standard_False;
+        for (Standard_Integer ii = 0; ii < 2; ii++)
+        {
+          TColgp_SequenceOfPnt2d* aSeqP2d = (ii == 0)? &aSeqP2dOnFirst : &aSeqP2dOnSecond;
+          gp_Pnt2d aP2dPrev = (jj == 0)? aSeqP2d->First() : aSeqP2d->Last();
+          if (IsUclosed[ii])
+          {
+            Standard_Real aPeriod = aNewBAsurf[ii].LastUParameter() - aNewBAsurf[ii].FirstUParameter();
+            Standard_Real aDeltaOnU = Abs(aProjP2d[ii].X() - aP2dPrev.X());
+            if (aDeltaOnU > aPeriod/2)
+            {
+              ToBreak = Standard_True;
+              break;
+            }
+          }
+          if (IsVclosed[ii])
+          {
+            Standard_Real aPeriod = aNewBAsurf[ii].LastVParameter() - aNewBAsurf[ii].FirstVParameter();
+            Standard_Real aDeltaOnV = Abs(aProjP2d[ii].Y() - aP2dPrev.Y());
+            if (aDeltaOnV > aPeriod/2)
+            {
+              ToBreak = Standard_True;
+              break;
+            }
+          }
+        }
+        if (ToBreak)
+          break;
+      }
+      
+      gp_Pnt aMidProjPnt;
+      if (anIsProjected[0] && anIsProjected[1])
+      {
+        aMidProjPnt.SetXYZ((aProjPnt[0].XYZ() + aProjPnt[1].XYZ())/2);
+        if (jj == 0)
+        {
+          aDist = aSeqPnt.First().Distance(aMidProjPnt);
+          Standard_Real aPar = aParameters.First() - aDist;
+          aSeqPnt.Prepend(aMidProjPnt);
+          aSeqP2dOnFirst.Prepend(aProjP2d[0]);
+          aSeqP2dOnSecond.Prepend(aProjP2d[1]);
+          aParameters.Prepend(aPar);
+        }
+        else
+        {
+          aDist = aSeqPnt.Last().Distance(aMidProjPnt);
+          Standard_Real aPar = aParameters.Last() + aDist;
+          aSeqPnt.Append(aMidProjPnt);
+          aSeqP2dOnFirst.Append(aProjP2d[0]);
+          aSeqP2dOnSecond.Append(aProjP2d[1]);
+          aParameters.Append(aPar);
+        }
+      }
+      else
+      {
+        EndPoints[0][jj] = (jj == 0)? aSeqP2dOnFirst.First() : aSeqP2dOnFirst.Last();
+        EndPoints[1][jj] = (jj == 0)? aSeqP2dOnSecond.First() : aSeqP2dOnSecond.Last();
+        TopAbs_State aStatus = aClassifier0.Perform(EndPoints[0][jj]);
+        if (aStatus != TopAbs_IN)
+          break;
+        aStatus = aClassifier1.Perform(EndPoints[1][jj]);
+        if (aStatus != TopAbs_IN)
+          break;
+        
+        aLen = aSeqP2dOnFirst.Length();
+        EndTangents[0][jj] = (jj == 0)? gp_Vec2d(aSeqP2dOnFirst(2), aSeqP2dOnFirst(1)) :
+          gp_Vec2d(aSeqP2dOnFirst(aLen-1), aSeqP2dOnFirst(aLen));
+        EndTangents[1][jj] = (jj == 0)? gp_Vec2d(aSeqP2dOnSecond(2), aSeqP2dOnSecond(1)) :
+          gp_Vec2d(aSeqP2dOnSecond(aLen-1), aSeqP2dOnSecond(aLen));
+        gp_Pnt BndPnts [2];
+        
+        for (Standard_Integer ii = 0; ii < 2; ii++)
+        {
+          if (anIsProjected[ii])
+          {
+            PointsOnBounds[ii][jj] = aProjP2d[ii];
+            BndPnts[ii] = aProjPnt[ii];
+          }
+          else
+          {
+            Standard_Real aLenToEnd;
+            ComputeEndOfExtension(Faces[ii], EndPoints[ii][jj], EndTangents[ii][jj],
+                                  PointsOnBounds[ii][jj], Edges[ii][jj], aLenToEnd);
+            BndPnts[ii] = aNewBAsurf[ii].Value(PointsOnBounds[ii][jj].X(), PointsOnBounds[ii][jj].Y());
+          }
+        }
+
+        gp_Pnt aStartPnt = (jj == 0)? aSeqPnt.First() : aSeqPnt.Last();
+        gp_Lin aLines [2];
+        aLines[0] = gp_Lin(aStartPnt, gp_Vec(aStartPnt, BndPnts[0]));
+        aLines[1] = gp_Lin(aStartPnt, gp_Vec(aStartPnt, BndPnts[1]));
+        aSqDist0 = aStartPnt.SquareDistance(BndPnts[0]);
+        aSqDist1 = aStartPnt.SquareDistance(BndPnts[1]);
+        Standard_Integer anIndOfLin = (aSqDist0 < aSqDist1)? 1 : 0;
+        Standard_Integer anIndOfPnt = 1 - anIndOfLin;
+        Standard_Real aParOnLin = ElCLib::LineParameter(aLines[anIndOfLin].Position(), BndPnts[anIndOfPnt]);
+        gp_Pnt aPntOnLin = ElCLib::Value(aParOnLin, aLines[anIndOfLin]);
+        aProjector[anIndOfLin].Perform(aPntOnLin);
+        Standard_Integer indmin = 1;
+        for (Standard_Integer ind = 2; ind <= aProjector[anIndOfLin].NbExt(); ind++)
+          if (aProjector[anIndOfLin].SquareDistance(ind) < aProjector[anIndOfLin].SquareDistance(indmin))
+            indmin = ind;
+        BndPnts[anIndOfLin] = aProjector[anIndOfLin].Point(indmin).Value();
+        Standard_Real aU, aV;
+        aProjector[anIndOfLin].Point(indmin).Parameter(aU, aV);
+        PointsOnBounds[anIndOfLin][jj].SetCoord(aU, aV);
+
+        aMidProjPnt.SetXYZ((BndPnts[0].XYZ() + BndPnts[1].XYZ())/2);
+        if (jj == 0)
+        {
+          aDist = aSeqPnt.First().Distance(aMidProjPnt);
+          Standard_Real aPar = aParameters.First() - aDist;
+          aSeqPnt.Prepend(aMidProjPnt);
+          aSeqP2dOnFirst.Prepend(PointsOnBounds[0][jj]);
+          aSeqP2dOnSecond.Prepend(PointsOnBounds[1][jj]);
+          aParameters.Prepend(aPar);
+        }
+        else
+        {
+          aDist = aSeqPnt.Last().Distance(aMidProjPnt);
+          Standard_Real aPar = aParameters.Last() + aDist;
+          aSeqPnt.Append(aMidProjPnt);
+          aSeqP2dOnFirst.Append(PointsOnBounds[0][jj]);
+          aSeqP2dOnSecond.Append(PointsOnBounds[1][jj]);
+          aParameters.Append(aPar);
+        }
+        break;
+      }
+      
+      aFirstPoint = aLastPoint;
+      aLastPoint  = aMidProjPnt;
+    } //for (;;)
+
+    //Check two last points: they may be coincident
+    Standard_Integer anIndFirst, anIndMid, anIndLast;
+    aLen = aSeqPnt.Length();
+    if (jj == 0)
+    {
+      anIndFirst = 1; anIndMid = 2; anIndLast = 3;
+    }
+    else
+    {
+      anIndFirst = aLen; anIndMid = aLen - 1; anIndLast = aLen - 2;
+    }
+    Standard_Real aDiffParOnEnd = aParameters(anIndMid) - aParameters(anIndFirst);
+    Standard_Real aDiffParMid = aParameters(anIndLast) - aParameters(anIndMid);
+    if (Abs(aDiffParOnEnd) < Abs(aDiffParMid)/100)
+    {
+      aSeqPnt.Remove(anIndMid);
+      aSeqP2dOnFirst.Remove(anIndMid);
+      aSeqP2dOnSecond.Remove(anIndMid);
+      aParameters.Remove(anIndMid);
+    }
+  } //for (Standard_Integer jj = 0; jj < 2; jj++)
+
+  Handle(TColgp_HArray1OfPnt)   aPntArray  = new TColgp_HArray1OfPnt(1, aSeqPnt.Length());
+  Handle(TColgp_HArray1OfPnt2d) aP2dArray1 = new TColgp_HArray1OfPnt2d(1, aSeqPnt.Length());
+  Handle(TColgp_HArray1OfPnt2d) aP2dArray2 = new TColgp_HArray1OfPnt2d(1, aSeqPnt.Length());
+  Handle(TColStd_HArray1OfReal) aParArray  = new TColStd_HArray1OfReal(1, aSeqPnt.Length());
+  for (Standard_Integer ii = 1; ii <= aSeqPnt.Length(); ii++)
+  {
+    aPntArray->SetValue(ii, aSeqPnt(ii));
+    aP2dArray1->SetValue(ii, aSeqP2dOnFirst(ii));
+    aP2dArray2->SetValue(ii, aSeqP2dOnSecond(ii));
+    //Temporary
+    //Standard_Real aParam = aParameters(ii);
+    //gp_Pnt aPnt = aSeqPnt(ii);
+    ///////////
+    aParArray->SetValue(ii, aParameters(ii));
+  }
+
+  GeomAPI_Interpolate anInterp(aPntArray, aParArray, Standard_False, Precision::Confusion());
+  anInterp.Perform();
+  const Handle(Geom_Curve)& aCurve = anInterp.Curve();
+  Geom2dAPI_Interpolate anInterp2dFirst(aP2dArray1, aParArray, Standard_False, Precision::Confusion());
+  anInterp2dFirst.Perform();
+  const Handle(Geom2d_Curve)& aPCurveOnFirst = anInterp2dFirst.Curve();
+  Geom2dAPI_Interpolate anInterp2dSecond(aP2dArray2, aParArray, Standard_False, Precision::Confusion());
+  anInterp2dSecond.Perform();
+  const Handle(Geom2d_Curve)& aPCurveOnSecond = anInterp2dSecond.Curve();
+
+  TopoDS_Edge aProjEdge = BRepLib_MakeEdge(aCurve);
+  BRep_Builder aBB;
+  aBB.UpdateEdge(aProjEdge, aPCurveOnFirst,  theFace1, Precision::Confusion());
+  aBB.UpdateEdge(aProjEdge, aPCurveOnSecond, theFace2, Precision::Confusion());
+  Standard_Real aTolEdge = BRep_Tool::Tolerance(theRefEdge);
+  TopoDS_Vertex aV1, aV2;
+  TopExp::Vertices(theRefEdge, aV1, aV2);
+  Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1);
+  aTolV1 = Max(aTolEdge, aTolV1);
+  Standard_Real aTolV2 = BRep_Tool::Tolerance(aV2);
+  aTolV2 = Max(aTolEdge, aTolV2);
+  aBB.UpdateEdge(aProjEdge, aTolEdge);
+  TopExp::Vertices(aProjEdge, aV1, aV2);
+  aBB.UpdateVertex(aV1, aTolV1);
+  aBB.UpdateVertex(aV2, aTolV2);
+  return aProjEdge;
+}
+
+static gp_Vec ComputeNormal(const BRepAdaptor_Surface& theBAsurf,
+                            const gp_Pnt2d&            thePnt2d,
+                            const Standard_Real        theTolLen,
+                            gp_Pnt&                    thePnt)
+{
+  gp_Vec aDu, aDv, aNormal;
+  
+  theBAsurf.D1(thePnt2d.X(), thePnt2d.Y(), thePnt, aDu, aDv);
+
+  Standard_Boolean IsNormalDefined = Standard_True;
+  Standard_Boolean ToReverse = Standard_False;
+  
+  Standard_Real aMagnitude = aDu.Magnitude();
+  if (aMagnitude < theTolLen)
+  {
+    //IsNormalDefined = Standard_False;
+    Standard_Real aUmin = theBAsurf.FirstUParameter(), aUmax = theBAsurf.LastUParameter();
+    Standard_Real aU;
+    if (Abs(thePnt2d.X() - aUmin) > Abs(thePnt2d.X() - aUmax))
+    {
+      aU = aUmin;
+      ToReverse = Standard_True;
+    }
+    else
+      aU = aUmax;
+    gp_Pnt aPnt;
+    gp_Vec aDuNext, aDvNext;
+    theBAsurf.D1(aU, thePnt2d.Y(), aPnt, aDuNext, aDvNext);
+    if (aPnt.Distance(thePnt) < theTolLen)
+      aDu = aDvNext.Normalized();
+  }
+  else
+    aDu /= aMagnitude;
+  
+  aMagnitude = aDv.Magnitude();
+  if (aMagnitude < theTolLen)
+  {
+    //IsNormalDefined = Standard_False;
+    Standard_Real aVmin = theBAsurf.FirstVParameter(), aVmax = theBAsurf.LastVParameter();
+    Standard_Real aV;
+    if (Abs(thePnt2d.Y() - aVmin) > Abs(thePnt2d.Y() - aVmax))
+    {
+      aV = aVmin;
+      ToReverse = Standard_True;
+    }
+    else
+      aV = aVmax;
+    gp_Pnt aPnt;
+    gp_Vec aDuNext, aDvNext;
+    theBAsurf.D1(thePnt2d.X(), aV, aPnt, aDuNext, aDvNext);
+    if (aPnt.Distance(thePnt) < theTolLen)
+      aDv = aDuNext.Normalized();
+  }
+  else
+    aDv /= aMagnitude;
+    
+  if (IsNormalDefined)
+  {
+    aNormal = aDu ^ aDv;
+    aMagnitude = aNormal.Magnitude();
+    if (aMagnitude < theTolLen)
+      IsNormalDefined = Standard_False;
+    else
+      aNormal /= aMagnitude;
+    if (ToReverse)
+      aNormal.Reverse();
+  }
+  if (!IsNormalDefined)
+  {
+    //Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface (theBAsurf);
+    //LProp3d_SLProps aProps (aBAHS, thePnt2d.X(), thePnt2d.Y(), 2, theTolLen);
+    //aNormal = aProps.Normal();
+  }
+
+  return aNormal;
+}
index 7287d5c77306de36382908364c0c7c913dc601e1..1943eeb3a34cfad9b7e856c6f6809313f3076bf3 100644 (file)
@@ -88,9 +88,11 @@ public:
                                        TopTools_ListOfShape& LInt1,
                                        TopTools_ListOfShape& LInt2,
                                        const TopAbs_State    Side,
+                                       const Standard_Real   theOffset,
                                        const TopoDS_Edge&    RefEdge,
                                        const TopoDS_Face&    RefFace1,
-                                       const TopoDS_Face&    RefFace2);
+                                       const TopoDS_Face&    RefFace2,
+                                       const Standard_Boolean theIsEdgeSmooth = Standard_False);
   
   //! Find if the edges <Edges> of the face <F2> are on
   //! the face <F1>.
@@ -124,7 +126,8 @@ public:
   
   Standard_EXPORT static void CheckBounds (const TopoDS_Face& F,
                                            const BRepOffset_Analyse& Analyse,
-                                           Standard_Boolean& enlargeU,
+                                           Standard_Boolean& enlargeUfirst,
+                                           Standard_Boolean& enlargeUlast,
                                            Standard_Boolean& enlargeVfirst,
                                            Standard_Boolean& enlargeVlast);
   
@@ -148,7 +151,8 @@ public:
                                                        TopoDS_Face& NF,
                                                        const Standard_Boolean ChangeGeom,
                                                        const Standard_Boolean UpDatePCurve = Standard_False,
-                                                       const Standard_Boolean enlargeU = Standard_True,
+                                                       const Standard_Boolean enlargeUfirst = Standard_True,
+                                                       const Standard_Boolean enlargeUlast = Standard_True,
                                                        const Standard_Boolean enlargeVfirst = Standard_True,
                                                        const Standard_Boolean enlargeVlast = Standard_True,
                                                        const Standard_Integer theExtensionMode = 1,
index 6a70be1cc8fbad0364c0b109e521c2b0d877f6cc..86b97329b2f79c3fc5eed455722edea0b19af656 100644 (file)
@@ -8,6 +8,8 @@ BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx
 BRepOffset_DataMapOfShapeListOfInterval.hxx
 BRepOffset_DataMapOfShapeMapOfShape.hxx
 BRepOffset_DataMapOfShapeOffset.hxx
+BRepOffset_DataMapOfFaceMapEE.hxx
+BRepOffset_SequenceOfIndexedMapOfShape.hxx
 BRepOffset_Error.hxx
 BRepOffset_Inter2d.cxx
 BRepOffset_Inter2d.hxx
index 3ba46a0a5258239b121fc868bb1c7a6e8045c054..7720cd5f4b409da1f463f6d14e6d11e790692940 100644 (file)
@@ -56,6 +56,7 @@
 
 #include <BRepOffset_MakeOffset.hxx>
 #include <BRepOffset_MakeSimpleOffset.hxx>
+#include <BRepOffsetAPI_MakeThickSolid.hxx>
 #include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
 #include <DBRep.hxx>
@@ -1164,6 +1165,37 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands,
   return 0;
 }
 
+Standard_Integer qqq(Draw_Interpretor& ,
+  Standard_Integer theNArg, const char** a)
+{
+  if (theNArg < 4) return 1;
+  
+  TopoDS_Shape aShape = DBRep::Get(a[2]);
+  if (aShape.IsNull()) return 1;
+  
+  Standard_Real offset = atof(a[3]);
+  Standard_Real tol = Precision::Confusion();
+
+  TopTools_IndexedMapOfShape aMap;
+
+  TopExp::MapShapes(aShape, TopAbs_FACE, aMap);
+
+  TopTools_ListOfShape aList;
+  aList.Append(aMap(5));
+  aList.Append(aMap(6));
+
+  GeomAbs_JoinType join = GeomAbs_Intersection;
+  
+  BRepOffsetAPI_MakeThickSolid hollow1;
+  hollow1.MakeThickSolidByJoin(aShape, aList, offset, tol,
+                               BRepOffset_Skin, Standard_False,
+                               Standard_False, join);
+
+  TopoDS_Shape newShape = hollow1.Shape();
+  
+  DBRep::Set(a[1], newShape);
+  return 0;
+}
 
 //=======================================================================
 //function : ROW
@@ -2525,4 +2557,8 @@ void BRepTest::FeatureCommands(Draw_Interpretor& theCommands)
   theCommands.Add("offsetshapesimple",
     "offsetshapesimple result shape offsetvalue [solid] [tolerance=1e-7]",
     __FILE__, ComputeSimpleOffset);
+
+  theCommands.Add("qqq",
+    "qqq result shape offset",
+    __FILE__, qqq);
 }
index a144269c28a06d5f236fdddbcf60dbf3dce84f4d..5ba421ae65c42e91284edab618f5e45e21ebe990 100644 (file)
@@ -1498,7 +1498,7 @@ void BiTgte_Blend::ComputeCenters()
   // -----------------------
   TopAbs_State       Side = TopAbs_IN;
   if (myRadius < 0.) Side = TopAbs_OUT;
-  BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
+  BRepOffset_Inter3d Inter(myAsDes,Side,myRadius,myTol);
 
   TopTools_DataMapOfShapeBox         MapSBox;
   TopTools_MapOfShape              Done;
index bb11c54962e933c05f3e0695798c2c25863d29bd..fc64f68b243b9073335a413c5f3ec2e7fdb63cc2 100644 (file)
@@ -733,6 +733,18 @@ Standard_Boolean Geom_OffsetSurface::IsUClosed () const
     else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) { 
       UClosed = Standard_True; 
     }
+    else if (SBasis->IsKind (STANDARD_TYPE(Geom_BoundedSurface)))
+    {
+      Standard_Real aU1, aU2, aV1, aV2;
+      Bounds( aU1, aU2, aV1, aV2 );
+      Handle(Geom_Curve) aCUF = UIso( aU1 );
+      Handle(Geom_Curve) aCUL = UIso( aU2 );
+      if(aCUF.IsNull() || aCUL.IsNull())
+        return Standard_False;
+      Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCUF);
+      Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCUL);
+      return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual( aBsL, Precision::Confusion()) ); 
+    }
     else { UClosed = Standard_False; }
   }  
   return UClosed;
@@ -762,6 +774,18 @@ Standard_Boolean Geom_OffsetSurface::IsVClosed () const
     if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
       VClosed = SBasis->IsVClosed();
     }
+    else if (SBasis->IsKind (STANDARD_TYPE(Geom_BoundedSurface)))
+    {
+      Standard_Real aU1, aU2, aV1, aV2;
+      Bounds( aU1, aU2, aV1, aV2 );
+      Handle(Geom_Curve) aCVF = VIso( aV1 );
+      Handle(Geom_Curve) aCVL = VIso( aV2 );
+      if(aCVF.IsNull() || aCVL.IsNull())
+        return Standard_False;
+      Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCVF);
+      Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCVL);
+      return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual(aBsL, Precision::Confusion())); 
+    }
     else { VClosed = Standard_False; }
   }
   return VClosed;
index b0ca49f9cc673bc4e8125b11d79ebd81284d701c..a5f56b47bc3cd83b5c6bb49084853452a5988960 100644 (file)
@@ -2968,7 +2968,8 @@ static Standard_Integer OCC30391(Draw_Interpretor& theDI,
 
   TopoDS_Face Result;
   BRepOffset_Tool::EnLargeFace(aFace, Result,
-                               Standard_True,Standard_True,Standard_True,Standard_True,Standard_True,1,
+                               Standard_True, Standard_True,
+                               Standard_True, Standard_True, Standard_True, Standard_True, 1,
                                aLenBeforeUfirst, aLenAfterUlast,
                                aLenBeforeVfirst, aLenAfterVlast);
 
diff --git a/tests/bugs/modalg_7/bug31735_1 b/tests/bugs/modalg_7/bug31735_1
deleted file mode 100644 (file)
index 8f09145..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-puts "======================================================================"
-puts "OCC31735: BRepOffset_MakeOffset works slowly and produces wrong result"
-puts "======================================================================"
-puts ""
-
-restore [locate_data_file bug31735_1.brep] a
-explode a
-thickshell result a_1 0.02 i
-
-checkshape result
-
-checknbshapes result -t -wire 56 -face 56 -shell 2 -solid 1
-
-set tolres [checkmaxtol result]
-
-if { ${tolres} > 0.001001} {
-   puts "Error: bad tolerance of result"
-}
-
-checkview -display result -2d -path ${imagedir}/${test_image}.png
-
-puts "TEST COMPLETED"
\ No newline at end of file
diff --git a/tests/bugs/modalg_7/bug31735_2 b/tests/bugs/modalg_7/bug31735_2
deleted file mode 100644 (file)
index 00cddc2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-puts "======================================================================"
-puts "OCC31735: BRepOffset_MakeOffset works slowly and produces wrong result"
-puts "======================================================================"
-puts ""
-
-restore [locate_data_file bug31735_2.brep] a
-explode a
-thickshell result a_1 -0.1 i
-
-checkshape result
-
-checknbshapes result -t -wire 18 -face 18 -shell 2 -solid 1
-
-set tolres [checkmaxtol result]
-
-if { ${tolres} > 0.5} {
-   puts "Error: bad tolerance of result"
-}
-
-checkview -display result -2d -path ${imagedir}/${test_image}.png
-
-puts "TEST COMPLETED"
\ No newline at end of file
index aca74b528f06ca1d29ba09629b48d5cca7986c17..7be95c2ff09514ecb084d241f213e212a990a485 100644 (file)
@@ -1,5 +1,5 @@
-puts "TODO OCC26577 All: Error :  is WRONG because number of EDGE entities in shape"
-puts "TODO OCC26577 All: Error :  is WRONG because number of SHELL entities in shape"
+puts "TODO OCC26577 All: Error :  is WRONG because number of WIRE entities in shape"
+puts "TODO OCC26577 All: Error :  is WRONG because number of FACE entities in shape"
 
 
 puts "=============================================================="
@@ -17,4 +17,4 @@ unifysamedom result_unif result
 checkshape result
 checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
 
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
\ No newline at end of file
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
\ No newline at end of file
diff --git a/tests/offset/bugs/bug31735_1 b/tests/offset/bugs/bug31735_1
new file mode 100644 (file)
index 0000000..8f09145
--- /dev/null
@@ -0,0 +1,22 @@
+puts "======================================================================"
+puts "OCC31735: BRepOffset_MakeOffset works slowly and produces wrong result"
+puts "======================================================================"
+puts ""
+
+restore [locate_data_file bug31735_1.brep] a
+explode a
+thickshell result a_1 0.02 i
+
+checkshape result
+
+checknbshapes result -t -wire 56 -face 56 -shell 2 -solid 1
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.001001} {
+   puts "Error: bad tolerance of result"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
+
+puts "TEST COMPLETED"
\ No newline at end of file
diff --git a/tests/offset/bugs/bug31735_2 b/tests/offset/bugs/bug31735_2
new file mode 100644 (file)
index 0000000..00cddc2
--- /dev/null
@@ -0,0 +1,22 @@
+puts "======================================================================"
+puts "OCC31735: BRepOffset_MakeOffset works slowly and produces wrong result"
+puts "======================================================================"
+puts ""
+
+restore [locate_data_file bug31735_2.brep] a
+explode a
+thickshell result a_1 -0.1 i
+
+checkshape result
+
+checknbshapes result -t -wire 18 -face 18 -shell 2 -solid 1
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.5} {
+   puts "Error: bad tolerance of result"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
+
+puts "TEST COMPLETED"
\ No newline at end of file
diff --git a/tests/offset/bugs/bug31845_1 b/tests/offset/bugs/bug31845_1
new file mode 100644 (file)
index 0000000..42f3d3a
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_1.brep] a
+
+offsetparameter 1e-7 c i
+offsetload a 0.2
+offsetperform result
+
+checkshape result
+checkprops result -s 271.847
+checknbshapes result -t -edge 12 -wire 6 -face 6 -shell 1 -solid 1
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/bugs/bug31845_2 b/tests/offset/bugs/bug31845_2
new file mode 100644 (file)
index 0000000..3e49633
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_1.brep] a
+
+offsetparameter 1e-7 c i
+offsetload a -0.2
+offsetperform result
+
+checkshape result
+checkprops result -s 210.825
+checknbshapes result -t -edge 12 -wire 6 -face 6 -shell 1 -solid 1
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/bugs/bug31845_3 b/tests/offset/bugs/bug31845_3
new file mode 100644 (file)
index 0000000..f0caa30
--- /dev/null
@@ -0,0 +1,13 @@
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_1.brep] a
+
+qqq result a 0.2
+
+checkshape result
+checkprops result -s 423.33
+checknbshapes result -t -edge 24 -wire 12 -face 10 -shell 1 -solid 1
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/bugs/bug31845_4 b/tests/offset/bugs/bug31845_4
new file mode 100644 (file)
index 0000000..cf65895
--- /dev/null
@@ -0,0 +1,13 @@
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_1.brep] a
+
+qqq result a -0.2
+
+checkshape result
+checkprops result -s 388.879
+checknbshapes result -t -edge 24 -wire 12 -face 10 -shell 1 -solid 1
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/bugs/bug31845_f b/tests/offset/bugs/bug31845_f
new file mode 100644 (file)
index 0000000..14a3d18
--- /dev/null
@@ -0,0 +1,15 @@
+puts "TODO OCC31845 All: ERROR. offsetperform operation not done."
+puts "TODO OCC31845 All: Error : The offset cannot be built."
+
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_f.brep] a
+explode a f
+
+offsetparameter 1e-7 p i
+offsetload a 0.001 a_4 a_5
+offsetperform result
+
diff --git a/tests/offset/bugs/bug31845_h b/tests/offset/bugs/bug31845_h
new file mode 100644 (file)
index 0000000..5908815
--- /dev/null
@@ -0,0 +1,17 @@
+puts "TODO OCC31845 All: ERROR. offsetperform operation not done."
+puts "TODO OCC31845 All: Error : The offset cannot be built."
+puts "TODO OCC31845 All: Tcl Exception: result is not a topological shape!!!"
+#puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
+#puts "TODO OCC31845 All: Error : The volume of result shape is 0"
+puts "TODO OCC31845 All: FAILED (no final message is found)"
+
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_h.brep] a
+
+offsetparameter 1e-7 p i
+offsetload a -0.01
+offsetperform result
diff --git a/tests/offset/bugs/bug31845_i b/tests/offset/bugs/bug31845_i
new file mode 100644 (file)
index 0000000..dbae528
--- /dev/null
@@ -0,0 +1,14 @@
+puts "TODO OCC31845 All: ERROR. offsetperform operation not done."
+puts "TODO OCC31845 All: Error : The offset cannot be built."
+
+puts "============================================"
+puts "OCC31845: BRepOffsetAPI_MakeThickSolid fails"
+puts "============================================"
+puts ""
+
+restore [locate_data_file bug31845_h.brep] a
+explode a f
+
+offsetparameter 1e-7 p i
+offsetload a 0.001 a_3 a_4
+offsetperform result
index 50e789cc3c1403c64ee433f15f048bbd6c2a5697..1e7d0e5a1862e3ca0010d3f2802251758a4212da 100644 (file)
@@ -1,5 +1,7 @@
 puts "TODO OCC23068 ALL: ERROR. offsetperform operation not done."
 puts "TODO OCC23068 ALL: Error : The volume of result shape "
+puts "TODO OCC23068 ALL: The command cannot be built"
+puts "TODO OCC31845 All: Tcl Exception: result is not a topological shape!!!"
 
 ## ======================================
 ## Grid    : CCV002
index 6811c03cbd21f6be941941e0949e82a2773667a8..df5d281d7df00ed94187067d1c9af58e30bb6efe 100755 (executable)
@@ -5,6 +5,9 @@
 ## ======================================
 
 puts "TODO OCC26556 ALL: ERROR. offsetperform operation not done."
+puts "TODO OCC23068 ALL: The command cannot be built"
+puts "TODO OCC31845 All: Tcl Exception: result is not a topological shape!!!"
+
 restore [locate_data_file CCV_2_d1_gsw.rle] s
 explode s F
 catch {offsetcompshape result s -2 s_17}
index 35d6dc490309ebd03b968c139009db23e6dbcb8f..5c9b3e2e6e44cde651cc5a5373b39b7b514299a3 100644 (file)
@@ -1,6 +1,3 @@
-puts "TODO OCC25406 ALL: Error : The volume of result shape is"
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
-
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
 trotate w1 0 0 0 1 0 0 90
@@ -11,4 +8,4 @@ revol s w 0 0 0 0 0 1 270
 
 OFFSETSHAPE -1 {} $calcul $type
 
-checkprops result -v 0
+checkprops result -v 9306
index 0148a5eb148e42a043a7b7bd32878e001c72aced..4ff28e00ef16af8bebd886f429762e88c5314598 100644 (file)
@@ -1,9 +1,5 @@
-puts "TODO OCC23068 ALL: ERROR. offsetperform operation not done."
-puts "TODO OCC23068 ALL: Error : The offset cannot be built."
-puts "TODO OCC23068 ALL: Error: The command cannot be built"
-
 ptorus s 10 10 0 45
 
 OFFSETSHAPE 1 {s_2} $calcul $type
 
-checkprops result -v 0
+checkprops result -v 2330.58
index 61adf130be017295c64f672d5d573570d602341b..a26a6f67dfeea35d7d52ccca1bc85085f7a48c67 100644 (file)
@@ -1,5 +1,8 @@
 puts "TODO OCC23068 All: ERROR. offsetperform operation not done."
 puts "TODO OCC23068 All: Error : The volume of result shape is"
+puts "TODO OCC23068 ALL: The command cannot be built"
+puts "TODO OCC31845 All: Tcl Exception: result is not a topological shape!!!"
+
 # Original bug : hkg60144
 # Date : 17Juillet98
 
index b7213c3d3dc4833792087103624d47a1ec1c4067..f3dcc983d70aff1518e261d506c2d12ed04d491b 100644 (file)
@@ -1,3 +1,6 @@
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
+puts "TODO OCC31845 All: Error : The volume of result shape is 0"
+
 pcone s 5 0 12 90
 trotate s 0 0 0 0 0 1 90
 
index d3f9f7a6f462991041543ca433e94fae604a8bf0..34e46eebcdbecc0389d64b96a5ff0f7462e95c9d 100644 (file)
@@ -1,5 +1,4 @@
-puts "TODO OCC23068 ALL: Error : The volume of result shape "
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
 
 pcone s 5 0 12 270
 
index ea8ccdb126b971656c665140209318a346251b4a..dd4c66920460437b448051f68de6be173b6fba09 100644 (file)
@@ -1,3 +1,6 @@
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
+puts "TODO OCC31845 All: Error : The volume of result shape is 0"
+
 psphere s 15 -90 60 90
 trotate s 0 0 0 0 0 1 90
 
index afe6c99358464a83d0aaa5eec274a5266f9ededd..095e77d2cdce275436c782fc3ecac37612fae7fa 100644 (file)
@@ -1,5 +1,4 @@
-puts "TODO OCC23068 ALL: Error : The volume of result shape "
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
 
 psphere s 15 -90 60 270
 
index 86be03c08666df25a88413fe763b3744e594b22b..e38321aee5ccac4295cab74769b33139b7102542 100644 (file)
@@ -1,3 +1,6 @@
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
+puts "TODO OCC31845 All: Error : The volume of result shape is 0"
+
 psphere s 15 90
 trotate s 0 0 0 0 0 1 90
 
index fc6d2731d118c7169683588d63d7abd13a75a1b7..e80fc4a7b8fcd27cab39193b37529f165bd8bdfd 100644 (file)
@@ -1,4 +1,5 @@
-puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero."
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
+puts "TODO OCC31845 All: Error : The volume of result shape is 0"
 
 psphere s 15 270
 
index 438d4e60e451bb0501025b6b73057b106b5ed869..3f3b8b80f13463f08c4f9b93c90c0a8459d7d54d 100644 (file)
@@ -1,5 +1,4 @@
-puts "TODO OCC23068 ALL: Error : The volume of result shape"
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
+puts "TODO OCC31845 All: Error : The command is not valid. The volume is 0."
 
 psphere s 15 270
 
index 1b7108ab0be9861831e78358e9f6a1974c2c6f23..6d4b14a2abf891f5cb561c39a5396b6c68128aac 100644 (file)
@@ -1,9 +1,5 @@
-puts "TODO OCC23068 ALL: result is not a topological shape"
-puts "TODO OCC23068 ALL: TEST INCOMPLETE"
-puts "TODO OCC23068 ALL: Error: The command cannot be built"
-
 ptorus s 10 10 0 45
 
 OFFSETSHAPE 1 {} $calcul $type
 
-checkprops result -v 0
+checkprops result -v 11455.3
index 73b22252c90c2ebe0aee575d4950cd34bbf98d2a..3ff78761d477a6ffa92adbfab5030f77442e16be 100755 (executable)
@@ -1,5 +1,7 @@
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
 puts "TODO OCC23068 ALL:Error\\s*:\\s*.*The volume"
+puts "TODO OCC31845 All: Faulty shapes"
+puts "TODO OCC31845 All: Error : The area of face result_"
+
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
 trotate w1 0 0 0 1 0 0 90
index c9bd158b106f6514e0b308dfbb4efbdfe9464e64..78529242a5d7bca6b4b93a3d6d5e815cec8781c9 100644 (file)
@@ -1,6 +1,3 @@
-puts "TODO OCC23068 ALL: Error : The volume of result shape is"
-puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero"
-
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
 trotate w1 0 0 0 1 0 0 90
@@ -11,5 +8,5 @@ revol s w 0 0 0 0 0 1 270
 
 OFFSETSHAPE -1 {} $calcul $type
 
-checkprops result -v 0
+checkprops result -v 9306
 
index 4f17f885540b8a430e2f2d1f9c9bd45def11e6b1..c55d8ccb6b6bc0da51847ddd98eaaf6d3eeeaf68 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_C4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 74941fa146639354a4c0f30d405ba97203857036..ae4b45b882f02d106ec8807a1fe82eef4958f90b 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_G7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 9e27a55b574979e07b44547a29a83acb1e8e3f35..3650aa9930602891fe35678f194d5707c42d9b7d 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index d8d4efb6b7dcfa60d811e3ad81e19ecc08b5e1fe..c0144af66e822966b6c68d52105874c7028bebc5 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index ce85d8006e827caa7d79b1b467f8e460b0fe8382..e9f10335ca9faf46b9f1ca956e437a2280fedcbc 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 11472fd863b0996446a164ea07d7c1d92f5d3f22..61e2bef1d8830f631394749d318c86b2214581ba 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 29eeda657b104f1fc3554a610f55e419d4e9d9dd..77710a16b6d6f39920392e5e9a3fbc64817093f7 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index bfb7cdb4186ef7c627b6db6adb94f4ed4695a687..411f98219394badd2ef97dd8194cc3eb02c62045 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index f893d57cc1075797a58caa7b8976adab28f2572e..720755ca2d59277076dc754f28d55e621fc01a7f 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_N1.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 047227e2f7cf9ee3d9241a87375b49772403a55c..39f2ec0c682734a2849d85979be658cbebdf9626 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_B5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 960385a0036b0ac07779be4f8182c650de88f430..48ea23bf9826a077a04ae31e1749499cd882d8f7 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index eeef81ade61015852d364eed89868db893fdf6a2..5fb7ce7d0857e5eb69c431e7168066f5806503f8 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 3e48b3d3fe78f3ff9216b9f647630158391adeb1..8bd8c25a8ec5f6e7fda8285d56524676a796922c 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index e559fcf7aabf7d95252e2e11befd0c051158bae9..6647a42139826aa96d6f7330b731fc1aade2085a 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index a803938d1f60876be0f9951bb9899c7a95f54143..9faa7cc00aa70e6a1b3c2d556e79319c40361929 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 7300a5243d4d8651e754a699dc074aea76be096e..f429cf37bec469e8800679d5ec33b3153e67a537 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 9742f7f87122be670f691a194d00cd510e61d991..ff5f31e02a208f255db2b2b5952afd3346d222c1 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_D9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 179e7fc0317ac343ffd2a66df1aa3856212f2c86..1f58ff930e073b644fd170b636fd101fefe1cea6 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_E4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 60e40ec6f98e71ebd4055ec26538eec0dc96444d..29cc4c8306a7b8f216e137c6a5bce075c153e4af 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index f894d97e9734ca9ff1a67aa4d0c328cca6ce865e..48681ce53028b1c0e63ad289568e0ab638861610 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index e9e4643ffe26f89dd7d13901fa869247b060a1ff..5527a4a50c87e717d5aa77c60aace01e2ecf7c02 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 694cf2aa879cff415dd1d06a77a334bc8b99bda8..937a79ce5221176746f21d06733dc355f9735a2f 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 5f34207c9b3a42a488f40b8637281cb083e2da20..c443b993fd0a7b378f97b43b8ddfa26ab87596c1 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index f3ed685cb5fda1d9dc8cd4751c3e5f0f2fb5cac5..ba5d99b3b861bcaf233eb2ca7545ba83bab1d31b 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F8.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 91ef98f96816d68493487a0954ca280f955b8f0e..f26e5530cedef5fa50be343ea72b3a87746048f4 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_F9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 5b6dec47836c39fc30a109206a84e896e326c6cd..25c1361fb121834fd0e69a16af41104fddb21152 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_G1.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index ca5f9f2e7600bc805d9e0e48784fd45912a96cd1..3caac88a7bc51b0ae5e8f16280d3423c150f90a9 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_G2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index b80e881b057471f2fb61d66896b50eac7429f387..cb8ccf94ab5cae299656067ddb8b06d66be751e9 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_G4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 15aa85bedf96992dcd79bf87b9e7dd4d5811718e..52bc960a4440399e9f6410f3293a473e6cc3f0bc 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_G6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index e52babee8a7bfdb2d765f05fb45c8e660670ee6e..663506f2a1c0165cf6b288495676611216d32729 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_G9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index e1522d66aa3a17cae834315054d2741650eaa827..fd0b41e01d37620e9075df5e6021ec3b2c5a80be 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_H3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 77f9e877e23c28febdf65ac82064ea00ed9b1efa..379aab4c32358cbe09a3b6042b3924fdee3be86e 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_H6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 494393a8c0edbeb48bc7ea9dec9f1e96496a469c..5756432efb660bf22ab01caae6ea21758f922a71 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_I6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 31bfe46a02178b0ed2f956e802a0d19e17c5a77c..812f09ebed0d5e61ba8dabcc555f2cd0e370adbe 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_I8.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 0f6fefaa9ba2bd62b87765b4dd0f37dc45197007..4c451156d3df59cf9e9c35b7f3eb84e38aa51f3f 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_J2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index b7f5a99cd9c1d12c41a4eff057cadd8179e3d7b8..94b6512b0b3ea9fac05a136ae6ebb4f3a317e85f 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_J3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index d246760004e1dd1e3d9d91e3387b68ca1034c506..6250f4c045909446908c67eac1f88a64ec81b041 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_J4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 98781bb6c7627f80a17a6d5ef9aa1a6c2ef69faa..91bae93d6992869bd503e1332a511033d54d2ff2 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_K1.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 897496fa0c467486b1047e777af874dd998b6a54..1b0e08466a208de91d3a662b1882ac1629809f4d 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_K2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index ca3136ad823e91a740c93e9e3bcb4360b045dead..75411570aed11c2cc3ebc0d6d02f8ccf9741b960 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L1.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index fb39f9d54dc3fa94f731f4e9985401d6940dabe5..f292bb4ca11636bae7eaa98a7f6a7f9a846d2351 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 9e27a55b574979e07b44547a29a83acb1e8e3f35..3650aa9930602891fe35678f194d5707c42d9b7d 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index d8d4efb6b7dcfa60d811e3ad81e19ecc08b5e1fe..c0144af66e822966b6c68d52105874c7028bebc5 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 325bfccc4251ed3458c1a02e9a31d0f92c4d883c..31d1522a72c8f88bd673c5f17b285a48cc7427a5 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 182c84dd64b10599c08d176441f1ba8c591990b4..2acee1c6c82e3e17aff6005c0a17231658dcff40 100644 (file)
@@ -1,7 +1,8 @@
 #puts "TODO OCC26577 All: Error :  is WRONG because number of EDGE entities in shape"
 #puts "TODO OCC26577 All: Error :  is WRONG because number of SHELL entities in shape"
 #puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty"
+
 restore [locate_data_file bug26663_test_offset_L6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index cdba2a0fc7a8c7053a4829d49b02dc5ce414ad45..46c63ad00403a96ef04d36aeb13dc247d085d568 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index c5672c4a93bc33f3328c6f73bd5d8dc37dec3ff9..ae4bca8f2445dd69006631671816c26327475663 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L8.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 11472fd863b0996446a164ea07d7c1d92f5d3f22..61e2bef1d8830f631394749d318c86b2214581ba 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_L9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index ad7da298957e919ec25888dde56dafd2c5256691..6d0c95e565f664fe6ceaf804622e5cd2f0d189f5 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M1.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 01ec4c605452c2d0455fab04cb3ef770f84c300d..3842d05ff5ba16ec51a169afc435b2477333eb5d 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index f587431dc61afd117e2a34c299c1da71a66f5f66..9d6b4e595d2103d07fb858f1b023af2a3c9c42d7 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M4.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 29eeda657b104f1fc3554a610f55e419d4e9d9dd..77710a16b6d6f39920392e5e9a3fbc64817093f7 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 7c775c2df6d910add00eb728424e05b0e86fcd0b..d89c4ffb66a86d01239b8ea88f80ef52fa5423d7 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M6.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 10b29fdb9a934b7ee3a60d8a3c9bd08faa19edab..62905e9c2270189c0d5947c6d47ec5a8e31d4cd5 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index eb6770da80a2870239f85cb9ff55d01a97f6bbae..1a772207194f7cc68502d824c332d32adafbe588 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M8.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index bfb7cdb4186ef7c627b6db6adb94f4ed4695a687..411f98219394badd2ef97dd8194cc3eb02c62045 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_M9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index f893d57cc1075797a58caa7b8976adab28f2572e..720755ca2d59277076dc754f28d55e621fc01a7f 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_N1.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 8028329f1ca5298bde06abe2ee78236f25f9517e..72047839487953361f188470f4b775965fcfa954 100644 (file)
@@ -1,4 +1,4 @@
 restore [locate_data_file bug26663_test_offset_N5.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]
 
index 71fa2ab75af319259d9589de80192ff5fe18ef1c..7b5023063b1b4992542d45eac5261b7b9cdf8069 100644 (file)
@@ -2,5 +2,5 @@
 #puts "TODO OCC26577 All: Error :  is WRONG because number of SHELL entities in shape"
 restore [locate_data_file bug26663_test_offset_N7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
-checknbshapes result -ref [lrange [nbshapes s] 8 19]
+checknbshapes result -ref [lrange [nbshapes s] 9 19]