diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f7e8d7f92b205a37ed6e8e956846fce92f35577..f3b5ce203dfdde2d3a9eccc891ece9979f6bea24 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,7 @@ option(ENABLE_PLUGINS "Build the post-processing plugins" ON)
 option(ENABLE_POST "Build the post-processing module" ON)
 option(ENABLE_QT "Build QT GUI" OFF)
 option(ENABLE_READLINE "Enable Readline in Lua prompt" ON)
+option(ENABLE_SALOME "Enable Salome routines for CAD healing" ON)
 option(ENABLE_SLEPC "Enable SLEPc eigensolvers" ON)
 option(ENABLE_SOLVER "Enable solver components" ON)
 option(ENABLE_SWIG "Enable swig" ON)
@@ -722,6 +723,12 @@ if(ENABLE_OCC)
       endif(NOT OCC_CONFIG_H)
     endif(OCC_INC)
   endif(NUM_OCC_LIBS EQUAL NUM_OCC_LIBS_REQUIRED)
+  if(HAVE_OCC AND ENABLE_SALOME)
+    add_subdirectory(contrib/Salome)
+    include_directories(contrib/Salome)
+    add_definitions(-DOCCGEOMETRY)
+    set_config_option(HAVE_SALOME "Salome")
+  endif(HAVE_OCC AND ENABLE_SALOME)
 endif(ENABLE_OCC)
 
 if(ENABLE_ACIS)
@@ -892,6 +899,8 @@ target_link_libraries(shared ${LINK_LIBRARIES})
 # binary targets
 if(HAVE_FLTK)
   add_executable(gmsh WIN32 Fltk/Main.cpp ${GMSH_SRC})
+  add_executable(gmsh_dynamic EXCLUDE_FROM_ALL Fltk/Main.cpp)
+  target_link_libraries(gmsh_dynamic shared)
 elseif(HAVE_QT)
   qt4_wrap_cpp(GMSH_MOC_SRC ${GMSH_MOC_HDR})
   add_executable(gmsh WIN32 Qt/Main.cpp ${GMSH_SRC} ${GMSH_MOC_SRC})
@@ -900,9 +909,6 @@ else(HAVE_FLTK)
 endif(HAVE_FLTK)
 target_link_libraries(gmsh ${LINK_LIBRARIES})
 
-add_executable(gmsh_dynamic EXCLUDE_FROM_ALL Fltk/Main.cpp)
-target_link_libraries(gmsh_dynamic shared)
-
 # increase stack to 16Mb on Windows to avoid overflows in recursive
 # tet classification for large 3D Delaunay grids + force static
 # linking of system libraries with cygwin/mingw (to ease distribution 
diff --git a/Common/GmshConfig.h.in b/Common/GmshConfig.h.in
index 020e34a45059e94cb1dd728c3fdb4953645938d0..0b6e218679788eecc14d30b026fcc88d989c59b5 100644
--- a/Common/GmshConfig.h.in
+++ b/Common/GmshConfig.h.in
@@ -47,6 +47,7 @@
 #cmakedefine HAVE_QT
 #cmakedefine HAVE_READLINE
 #cmakedefine HAVE_SLEPC
+#cmakedefine HAVE_SALOME
 #cmakedefine HAVE_SOLVER
 #cmakedefine HAVE_TAUCS
 #cmakedefine HAVE_TETGEN
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 07b7159db1a06bf9af495eeea3fc81ddb8a3f8cf..2573a9dbd884518adfdd9fc5c32d0fc35c7fc48a 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -1785,7 +1785,7 @@ optionWindow::optionWindow(int deltaFontSize)
       b->labeltype(FL_NO_LABEL);
 
       Fl_Box *b2 = new Fl_Box
-        (FL_NO_BOX, L + 2 * WB, 2 * WB + 3 * BH + 1, IW, BH, "Open CASCADE model healing options:");
+        (FL_NO_BOX, L + 2 * WB, 2 * WB + 3 * BH + 1, IW, BH, "Open CASCADE model healing options (experimental):");
       b2->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
 
       geo.butt[11] = new Fl_Check_Button
@@ -1794,17 +1794,17 @@ optionWindow::optionWindow(int deltaFontSize)
       geo.butt[11]->callback(geometry_options_ok_cb);
 
       geo.butt[12] = new Fl_Check_Button
-        (L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Remove small faces (experimental)");
+        (L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Remove small faces");
       geo.butt[12]->type(FL_TOGGLE_BUTTON);
       geo.butt[12]->callback(geometry_options_ok_cb);
 
       geo.butt[13] = new Fl_Check_Button
-        (L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Sew faces (experimental)");
+        (L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Sew faces");
       geo.butt[13]->type(FL_TOGGLE_BUTTON);
       geo.butt[13]->callback(geometry_options_ok_cb);
 
       geo.butt[15] = new Fl_Check_Button
-        (L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Cut and merge faces (experimental)");
+        (L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Cut and merge faces");
       geo.butt[15]->type(FL_TOGGLE_BUTTON);
       geo.butt[15]->callback(geometry_options_ok_cb);
 
diff --git a/Geo/CMakeLists.txt b/Geo/CMakeLists.txt
index ac5d5e25af266c28ce9a02d70005f263db56e1ca..6c6d16f45df13f6a6eef51b2a21e45da719090f5 100644
--- a/Geo/CMakeLists.txt
+++ b/Geo/CMakeLists.txt
@@ -21,7 +21,6 @@ set(SRC
     GModelIO_Mesh.cpp
     GModelIO_OCC.cpp
     GModelIO_ACIS.cpp
-      OCC_Connect.cpp
     GModelIO_Fourier.cpp
     GModelIO_CGNS.cpp
     GModelIO_MED.cpp
diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp
index 5fcec7c8cb3b1460797887f9d72508f31ac0c2bb..563843c90aebe26048752a2eb0d30aba4a873a00 100644
--- a/Geo/GFace.cpp
+++ b/Geo/GFace.cpp
@@ -238,7 +238,6 @@ void GFace::setVisibility(char val, bool recursive)
     std::list<GEdge*>::iterator it = l_edges.begin();
     while (it != l_edges.end()){
       (*it)->setVisibility(val, recursive);
-
       ++it;
     }
   }
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index a14f35175b0c02b1107dfb841cfb1e52b50df407..74580be408dccc54ffe0f0959c94f49db5144705 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -14,10 +14,13 @@
 #include "MElement.h"
 #include "MLine.h"
 #include "OpenFile.h"
-#include "OCC_Connect.h"
 
 #if defined(HAVE_OCC)
 
+#if defined(HAVE_SALOME)
+#include "Partition_Spliter.hxx"
+#endif
+
 void addSimpleShapes(TopoDS_Shape theShape, TopTools_ListOfShape &theList);
 
 void OCC_Internals::buildLists()
@@ -39,8 +42,8 @@ void OCC_Internals::buildShapeFromLists(TopoDS_Shape _shape)
 
   TopTools_ListOfShape theList;
   addSimpleShapes(_shape, theList);
-  TopTools_ListIteratorOfListOfShape itSub1 (theList);
-  for (; itSub1.More(); itSub1.Next()) B.Add(C,itSub1.Value());
+  TopTools_ListIteratorOfListOfShape itSub1(theList);
+  for (; itSub1.More(); itSub1.Next()) B.Add(C, itSub1.Value());
 
   for(int i = 1; i <= vmap.Extent(); i++) B.Add(C, vmap(i));
   for(int i = 1; i <= emap.Extent(); i++) B.Add(C, emap(i));
@@ -49,34 +52,34 @@ void OCC_Internals::buildShapeFromLists(TopoDS_Shape _shape)
   for(int i = 1; i <= shmap.Extent(); i++) B.Add(C, shmap(i));
   for(int i = 1; i <= somap.Extent(); i++) B.Add(C, somap(i));
   shape = C;
-
 }
 
 void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
 {
+  // Solids
   TopExp_Explorer exp0, exp1, exp2, exp3, exp4, exp5;
   for(exp0.Init(_shape, TopAbs_SOLID); exp0.More(); exp0.Next()){
     TopoDS_Solid solid = TopoDS::Solid(exp0.Current());
-    if(somap.FindIndex(TopoDS::Solid(exp0.Current())) < 1){
-      somap.Add(TopoDS::Solid(exp0.Current()));
+    if(somap.FindIndex(solid) < 1){
+      somap.Add(solid);
 
-      for(exp1.Init(exp0.Current(), TopAbs_SHELL); exp1.More(); exp1.Next()){
-        TopoDS_Shell shell = TopoDS::Shell(exp1.Current().Composed(exp0.Current().Orientation()));
+      for(exp1.Init(solid, TopAbs_SHELL); exp1.More(); exp1.Next()){
+        TopoDS_Shell shell = TopoDS::Shell(exp1.Current());
         if(shmap.FindIndex(shell) < 1){
           shmap.Add(shell);
 
           for(exp2.Init(shell, TopAbs_FACE); exp2.More(); exp2.Next()){
-            TopoDS_Face face = TopoDS::Face(exp2.Current().Composed(shell.Orientation()));
+            TopoDS_Face face = TopoDS::Face(exp2.Current());
             if(fmap.FindIndex(face) < 1){
               fmap.Add(face);
 
               for(exp3.Init(exp2.Current(), TopAbs_WIRE); exp3.More(); exp3.Next()){
-                TopoDS_Wire wire = TopoDS::Wire(exp3.Current().Composed(face.Orientation()));
+                TopoDS_Wire wire = TopoDS::Wire(exp3.Current());
                 if(wmap.FindIndex(wire) < 1){
                   wmap.Add(wire);
 
                   for(exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More(); exp4.Next()){
-                    TopoDS_Edge edge = TopoDS::Edge(exp4.Current().Composed(wire.Orientation()));
+                    TopoDS_Edge edge = TopoDS::Edge(exp4.Current());
                     if(emap.FindIndex(edge) < 1){
                       emap.Add(edge);
 
@@ -98,12 +101,12 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
   
   // Free Shells
   for(exp1.Init(exp0.Current(), TopAbs_SHELL, TopAbs_SOLID); exp1.More(); exp1.Next()){
-    TopoDS_Shape shell = exp1.Current().Composed(exp0.Current().Orientation());
+    TopoDS_Shape shell = exp1.Current();
     if(shmap.FindIndex(shell) < 1){
       shmap.Add(shell);
 
       for(exp2.Init(shell, TopAbs_FACE); exp2.More(); exp2.Next()){
-        TopoDS_Face face = TopoDS::Face(exp2.Current().Composed(shell.Orientation()));
+        TopoDS_Face face = TopoDS::Face(exp2.Current());
         if(fmap.FindIndex(face) < 1){
           fmap.Add(face);
                   
@@ -207,61 +210,155 @@ void OCC_Internals::healGeometry(double tolerance, bool fixsmalledges,
                                  bool fixspotstripfaces, bool sewfaces, 
                                  bool makesolids, bool connect)
 {
+  buildLists();
+  TopExp_Explorer exp0, exp1;
   int nrc = 0, nrcs = 0;
+  int nrso = somap.Extent(), nrsh = shmap.Extent(), nrf = fmap.Extent();
+  int nrw = wmap.Extent(), nre = emap.Extent(), nrv = vmap.Extent();
+  for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++;
+  for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++;
 
-  TopExp_Explorer e;
-  for(e.Init(shape, TopAbs_COMPOUND); e.More(); e.Next()) nrc++;
-  for(e.Init(shape, TopAbs_COMPSOLID); e.More(); e.Next()) nrcs++;
+  Msg::Info("Starting geometry healing procedure (tolerance: %g)", tolerance);
 
-  double surfacecont = 0;
+  {
+    Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
+    rebuild->Apply(shape);
+    for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
+      TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
+      if(BRep_Tool::Degenerated(edge))
+        rebuild->Remove(edge, false);
+    }
+    shape = rebuild->Apply(shape);
+  }
+  buildLists();
 
-  for(int i = 1; i <= fmap.Extent(); i++){
+  double surfacecont = 0;
+  for (exp0.Init(shape, TopAbs_FACE); exp0.More(); exp0.Next()){
+    TopoDS_Face face = TopoDS::Face(exp0.Current());
     GProp_GProps system;
-    BRepGProp::LinearProperties(fmap(i), system);
+    BRepGProp::SurfaceProperties(face, system);
     surfacecont += system.Mass();
   }
 
-  Msg::Info("Healing geometry (tolerance=%g)", tolerance);
+  {
+    Msg::Info("- repairing faces");
 
-  if(fixsmalledges){
-    Msg::Info("- fixing small edges");
+    Handle(ShapeFix_Face) sff;
+    Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
+    rebuild->Apply(shape);
+
+    for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
+      TopoDS_Face face = TopoDS::Face(exp0.Current());
 
+      sff = new ShapeFix_Face (face);
+      sff->FixAddNaturalBoundMode() = Standard_True;
+      sff->FixSmallAreaWireMode() = Standard_True;
+      sff->Perform();
+      
+      if(sff->Status(ShapeExtend_DONE1) ||
+         sff->Status(ShapeExtend_DONE2) ||
+         sff->Status(ShapeExtend_DONE3) ||
+         sff->Status(ShapeExtend_DONE4) ||
+         sff->Status(ShapeExtend_DONE5))
+        {
+          Msg::Info("  repaired face %d", fmap.FindIndex(face));
+          if(sff->Status(ShapeExtend_DONE1))
+            Msg::Info("  (some wires are fixed)");
+          else if(sff->Status(ShapeExtend_DONE2))
+            Msg::Info("  (orientation of wires fixed)");
+          else if(sff->Status(ShapeExtend_DONE3))
+            Msg::Info("  (missing seam added)");
+          else if(sff->Status(ShapeExtend_DONE4))
+            Msg::Info("  (small area wire removed)");
+          else if(sff->Status(ShapeExtend_DONE5))
+            Msg::Info("  (natural bounds added)");
+          TopoDS_Face newface = sff->Face();
+          
+          rebuild->Replace(face, newface, Standard_False);
+        }
+    }
+    shape = rebuild->Apply(shape);
+  }
+  
+  {
+    Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
+    rebuild->Apply(shape);
+    for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
+      TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
+      if ( BRep_Tool::Degenerated(edge) )
+        rebuild->Remove(edge, false);
+    }
+    shape = rebuild->Apply(shape);
+  }
+  
+  if (fixsmalledges){
+    Msg::Info("- fixing small edges");
+    
     Handle(ShapeFix_Wire) sfw;
     Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
     rebuild->Apply(shape);
     
-    for(int i = 1; i <= fmap.Extent(); i++){
-      TopExp_Explorer exp1;
-      for(exp1.Init(fmap(i), TopAbs_WIRE); exp1.More(); exp1.Next()){
+    for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
+      TopoDS_Face face = TopoDS::Face(exp0.Current());
+      
+      for (exp1.Init (face, TopAbs_WIRE); exp1.More(); exp1.Next()){
         TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current());
-        sfw = new ShapeFix_Wire(oldwire, TopoDS::Face(fmap(i)), tolerance);
+        sfw = new ShapeFix_Wire (oldwire, face ,tolerance);
         sfw->ModifyTopologyMode() = Standard_True;
         
-        if(sfw->FixSmall(false, tolerance)){
-          Msg::Info("Fixed small edge in wire %d", wmap.FindIndex(oldwire));
+        sfw->ClosedWireMode() = Standard_True;
+        
+        bool replace = false;
+        replace = sfw->FixReorder() || replace;
+        replace = sfw->FixConnected() || replace;
+        
+        if (sfw->FixSmall(Standard_False, tolerance) && 
+            ! (sfw->StatusSmall(ShapeExtend_FAIL1) ||
+               sfw->StatusSmall(ShapeExtend_FAIL2) ||
+               sfw->StatusSmall(ShapeExtend_FAIL3))){
+          Msg::Info("  fixed small edge in wire %d", wmap.FindIndex(oldwire));
+          replace = true;
+        }
+        else if (sfw->StatusSmall(ShapeExtend_FAIL1))
+          Msg::Warning("Failed to fix small edge in wire %d, edge cannot be checked "
+                       "(no 3d curve and no pcurve)", wmap.FindIndex(oldwire));
+        else if (sfw->StatusSmall(ShapeExtend_FAIL2))
+          Msg::Warning("Failed to fix small edge in wire %d, "
+                       "edge is null-length and has different vertives at begin and "
+                       "end, and lockvtx is True or ModifiyTopologyMode is False",
+                       wmap.FindIndex(oldwire));
+        else if (sfw->StatusSmall(ShapeExtend_FAIL3))
+          Msg::Warning("Failed to fix small edge in wire, CheckConnected has failed",
+                       wmap.FindIndex(oldwire));
+        
+        replace = sfw->FixEdgeCurves() || replace;
+        replace = sfw->FixDegenerated() || replace;
+        replace = sfw->FixSelfIntersection() || replace;
+        replace = sfw->FixLacking(Standard_True) || replace;
+        if(replace){
           TopoDS_Wire newwire = sfw->Wire();
           rebuild->Replace(oldwire, newwire, Standard_False);
         }
-        if((sfw->StatusSmall(ShapeExtend_FAIL1)) ||
-           (sfw->StatusSmall(ShapeExtend_FAIL2)) ||
-           (sfw->StatusSmall(ShapeExtend_FAIL3)))
-          Msg::Info("Failed to fix small edge in wire %d",  wmap.FindIndex(oldwire));
       }
     }
+    
     shape = rebuild->Apply(shape);
     
     {
+      buildLists();
       Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
       rebuild->Apply(shape);
-      TopExp_Explorer exp1;
-      for(exp1.Init(shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
+      
+      for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
         TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
-        if(vmap.FindIndex(TopExp::FirstVertex(edge)) == 
-           vmap.FindIndex(TopExp::LastVertex(edge))){
+        if (vmap.FindIndex(TopExp::FirstVertex (edge)) ==
+            vmap.FindIndex(TopExp::LastVertex (edge))){
           GProp_GProps system;
           BRepGProp::LinearProperties(edge, system);
-          if(system.Mass() < tolerance){
-            Msg::Info("removing degenerated edge %d", emap.FindIndex(edge));
+          if (system.Mass() < tolerance){
+            Msg::Info("  removing degenerated edge %d from vertex %d to vertex %d",
+                      emap.FindIndex(edge), vmap.FindIndex(TopExp::FirstVertex(edge)),
+                      vmap.FindIndex(TopExp::LastVertex(edge)));
             rebuild->Remove(edge, false);
           }
         }
@@ -269,116 +366,179 @@ void OCC_Internals::healGeometry(double tolerance, bool fixsmalledges,
       shape = rebuild->Apply(shape);
     }
     
+    {
+      Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
+      rebuild->Apply(shape);
+      for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
+        TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
+        if(BRep_Tool::Degenerated(edge) )
+          rebuild->Remove(edge, false);
+      }
+      shape = rebuild->Apply(shape);
+    }
+    
     Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe;
     sfwf->SetPrecision(tolerance);
-    sfwf->Load(shape);
+    sfwf->Load (shape);
+    sfwf->ModeDropSmallEdges() = Standard_True;
     
-    if(sfwf->FixSmallEdges()){
-      Msg::Info("- fixing wire frames");
-      if(sfwf->StatusSmallEdges(ShapeExtend_OK)) 
-        Msg::Info("no small edges found");
-      if(sfwf->StatusSmallEdges(ShapeExtend_DONE1))
-        Msg::Info("some small edges fixed");
-      if(sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) 
-        Msg::Info("failed to fix some small edges");
-    }
-  
-    if(sfwf->FixWireGaps()){
+    if (sfwf->FixWireGaps()){
       Msg::Info("- fixing wire gaps");
-      if(sfwf->StatusWireGaps(ShapeExtend_OK))
-        Msg::Info("no gaps found");
-      if(sfwf->StatusWireGaps(ShapeExtend_DONE1))
-        Msg::Info("some 2D gaps fixed");
-      if(sfwf->StatusWireGaps(ShapeExtend_DONE2))
-        Msg::Info("some 3D gaps fixed");
-      if(sfwf->StatusWireGaps(ShapeExtend_FAIL1))
-        Msg::Info("failed to fix some 2D gaps");
-      if(sfwf->StatusWireGaps(ShapeExtend_FAIL2))
-        Msg::Info("failed to fix some 3D gaps");
+      if (sfwf->StatusWireGaps(ShapeExtend_OK)) 
+        Msg::Info("  no gaps found");
+      if (sfwf->StatusWireGaps(ShapeExtend_DONE1))
+        Msg::Info("  some 2D gaps fixed");
+      if (sfwf->StatusWireGaps(ShapeExtend_DONE2)) 
+        Msg::Info("  some 3D gaps fixed");
+      if (sfwf->StatusWireGaps(ShapeExtend_FAIL1)) 
+        Msg::Info("  failed to fix some 2D gaps");
+      if (sfwf->StatusWireGaps(ShapeExtend_FAIL2))
+        Msg::Info("  failed to fix some 3D gaps");
+    }
+    
+    sfwf->SetPrecision(tolerance);
+    
+    if (sfwf->FixSmallEdges()){
+      Msg::Info("- fixing wire frames");
+      if (sfwf->StatusSmallEdges(ShapeExtend_OK)) 
+        Msg::Info("  no small edges found");
+      if (sfwf->StatusSmallEdges(ShapeExtend_DONE1))
+        Msg::Info("  some small edges fixed");
+      if (sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) 
+        Msg::Info("  failed to fix some small edges");
     }
     
     shape = sfwf->Shape();
   }
-  
-  if(fixspotstripfaces){
+
+  if (fixspotstripfaces){
     Msg::Info("- fixing spot and strip faces");
-    Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace;
-    sffsm->Init(shape);
-    sffsm->SetPrecision(tolerance);
-    sffsm->Perform();
+    Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace();
+    sffsm -> Init (shape);
+    sffsm -> SetPrecision (tolerance);
+    sffsm -> Perform();
     
-    shape = sffsm->FixShape();
+    shape = sffsm -> FixShape();
   }
-  
-  if(sewfaces){
-    Msg::Info("- sewing faces");
 
-    TopExp_Explorer exp0;
+  if (sewfaces){
+    Msg::Info("- sewing faces");
     
     BRepOffsetAPI_Sewing sewedObj(tolerance);
     
-    for(exp0.Init(shape, TopAbs_FACE); exp0.More(); exp0.Next()){
-      TopoDS_Face face = TopoDS::Face(exp0.Current());
-      sewedObj.Add(face);
+    for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
+      TopoDS_Face face = TopoDS::Face (exp0.Current());
+      sewedObj.Add (face);
     }
     
     sewedObj.Perform();
     
-    if(!sewedObj.SewedShape().IsNull())
+    if (!sewedObj.SewedShape().IsNull())
       shape = sewedObj.SewedShape();
     else
-      Msg::Info(" not possible");
+      Msg::Info("  not possible");
   }
   
-  if(makesolids){  
+  {
+    Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
+    rebuild->Apply(shape);
+    for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
+      TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
+      if ( BRep_Tool::Degenerated(edge) )
+        rebuild->Remove(edge, false);
+    }
+    shape = rebuild->Apply(shape);
+  }
+  
+  if (makesolids){
     Msg::Info("- making solids");
     
-    TopExp_Explorer exp0;
-    
     BRepBuilderAPI_MakeSolid ms;
     int count = 0;
-    for(exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()){
+    for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()){
       count++;
-      ms.Add(TopoDS::Shell(exp0.Current()));
+      ms.Add (TopoDS::Shell(exp0.Current()));
     }
     
-    if(!count){
-      Msg::Info(" not possible (no shells)");
+    if (!count){
+      Msg::Info("  not possible (no shells)");
     }
     else{
       BRepCheck_Analyzer ba(ms);
-      if(ba.IsValid()){
+      if (ba.IsValid ()){
         Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
-        sfs->Init(ms);
+        sfs->Init (ms);
         sfs->SetPrecision(tolerance);
         sfs->SetMaxTolerance(tolerance);
         sfs->Perform();
         shape = sfs->Shape();
         
-        for(exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()){
+        for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()){
           TopoDS_Solid solid = TopoDS::Solid(exp0.Current());
           TopoDS_Solid newsolid = solid;
-          BRepLib::OrientClosedSolid(newsolid);
+          BRepLib::OrientClosedSolid (newsolid);
           Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
-          // rebuild->Apply(shape);
+          //		  rebuild->Apply(shape);
           rebuild->Replace(solid, newsolid, Standard_False);
-          TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_COMPSOLID, 1);
-          // TopoDS_Shape newshape = rebuild->Apply(shape);
+          TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_COMPSOLID);//, 1);
+          //		  TopoDS_Shape newshape = rebuild->Apply(shape);
           shape = newshape;
         }
       }
       else
-        Msg::Info(" not possible");
+        Msg::Info("  not possible");
     }
   }
 
-  if(connect) {
-    OCC_Connect connect; 
-    for(TopExp_Explorer p(shape,TopAbs_SOLID); p.More(); p.Next())
-        connect.Add(p.Current()); 
-    connect.Connect();
-    shape=connect;
+  if (connect){
+#if defined(HAVE_SALOME)
+    Msg::Info("- running SALOME partition splitter");
+    TopExp_Explorer e2;
+    Partition_Spliter ps;
+    int count = 0;
+    
+    for (e2.Init(shape, TopAbs_SOLID); e2.More(); e2.Next()){
+      count++;
+      ps.AddShape(e2.Current());
+    }
+    
+    ps.Compute();
+    shape = ps.Shape();
+    
+    Msg::Info("  before: %d solids", count);
+    
+    count = 0;
+    for (e2.Init (shape, TopAbs_SOLID); e2.More(); e2.Next()) count++;
+    Msg::Info("  after : %d solids", count);
+#endif
   }
+  
+  double newsurfacecont = 0;
+  for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
+    TopoDS_Face face = TopoDS::Face(exp0.Current());
+    GProp_GProps system;
+    BRepGProp::SurfaceProperties(face, system);
+    newsurfacecont += system.Mass();
+  }
+
+  buildLists();
+  int nnrc = 0, nnrcs = 0;
+  int nnrso = somap.Extent(), nnrsh = shmap.Extent(), nnrf = fmap.Extent();
+  int nnrw = wmap.Extent(), nnre = emap.Extent(), nnrv = vmap.Extent();
+  for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nnrc++;
+  for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nnrcs++;
+  
+  Msg::Info("-----------------------------------");
+  Msg::Info("Compounds          : %d (%d)", nnrc, nrc);
+  Msg::Info("Composite solids   : %d (%d)", nnrcs, nrcs);
+  Msg::Info("Solids             : %d (%d)", nnrso, nrso);
+  Msg::Info("Shells             : %d (%d)", nnrsh, nrsh);
+  Msg::Info("Wires              : %d (%d)", nnrw, nrw);
+  Msg::Info("Faces              : %d (%d)", nnrf, nrf);
+  Msg::Info("Edges              : %d (%d)", nnre, nre);
+  Msg::Info("Vertices           : %d (%d)", nnrv, nrv );
+  Msg::Info("Totol surface area : %g (%g)", newsurfacecont, surfacecont);
+  Msg::Info("-----------------------------------");
 }
 
 void OCC_Internals::loadBREP(const char *fn)
@@ -480,7 +640,8 @@ GEdge *OCC_Internals::addEdgeToModel(GModel *model, TopoDS_Edge edge)
   return getOCCEdgeByNativePtr(model,edge);
 }
 
-GFace* OCC_Internals::addFaceToModel(GModel *model, TopoDS_Face face){
+GFace* OCC_Internals::addFaceToModel(GModel *model, TopoDS_Face face)
+{
   GFace *gf = getOCCFaceByNativePtr(model,face);
   if (gf) return gf;
   addShapeToLists(face);
@@ -489,8 +650,8 @@ GFace* OCC_Internals::addFaceToModel(GModel *model, TopoDS_Face face){
   return getOCCFaceByNativePtr(model,face);
 }
 
-GRegion* OCC_Internals::addRegionToModel(GModel *model, TopoDS_Solid region){
-  
+GRegion* OCC_Internals::addRegionToModel(GModel *model, TopoDS_Solid region)
+{
   GRegion *gr  = getOCCRegionByNativePtr(model,region);
   if (gr) return gr;
   addShapeToLists(region);
@@ -563,7 +724,6 @@ void addSimpleShapes(TopoDS_Shape theShape, TopTools_ListOfShape &theList)
   }
 }
 
-
 void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperator &op)
 {
   if (tool.IsNull()) return;
diff --git a/Geo/OCC_Connect.cpp b/Geo/OCC_Connect.cpp
deleted file mode 100644
index c34686ef84756558bd10e1456a9a09252a4001b3..0000000000000000000000000000000000000000
--- a/Geo/OCC_Connect.cpp
+++ /dev/null
@@ -1,1069 +0,0 @@
-// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
-//
-// See the LICENSE.txt file for license information. Please report all
-// bugs and problems to <gmsh@geuz.org>.
-//
-// Contributed by Mark van Doesburg, Technolution B.V.
-
-#include "OCC_Connect.h"
-
-#include <vector>
-#include <list>
-#include <deque>
-#include <iostream>
-#include <iterator>
-
-#if defined(HAVE_OCC)
-
-#include <Standard_Version.hxx>
-
-#include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Solid.hxx>
-#include <TopoDS_Compound.hxx>
-
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopOpeBRep_Point2d.hxx>
-#include <TopOpeBRep_ShapeIntersector.hxx>
-#include <TopTools.hxx>
-
-#include <BRepTools.hxx>
-#include <BRepTools_ReShape.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-#include <BRepBuilderAPI_MakeWire.hxx>
-#include <BRepExtrema_ExtCC.hxx>
-#include <BRepExtrema_ExtCF.hxx>
-#include <BRepExtrema_ExtFF.hxx>
-#include <BRepExtrema_ExtPF.hxx>
-#include <BRepExtrema_ExtPC.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepClass_FaceClassifier.hxx>
-
-#include <IntTools_Context.hxx>
-
-#include <BRepExtrema_DistShapeShape.hxx>
-#include <BRepOffsetAPI_NormalProjection.hxx>
-#include <BRepTopAdaptor_FClass2d.hxx>
-#include <BRepTools_Substitution.hxx>
-#include <BRepAlgo_Loop.hxx>
-
-#include <BRep_TEdge.hxx>
-#include <TopoDS_TShape.hxx>
-#include <ShapeFix_Edge.hxx>
-#include <Geom_Surface.hxx>
-#include <gce_MakeScale.hxx>
-#include <BRepBuilderAPI_GTransform.hxx>
-#include <BRepBuilderAPI_Transform.hxx>
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Printing routines
-////////////////////////////////////////////////////////////////////////////////
-
-static inline ostream &operator <<(ostream &o,const TopAbs_ShapeEnum &A)
-{
-    switch(A) {
-    case TopAbs_COMPOUND: return o << "COMPOUND";
-    case TopAbs_COMPSOLID: return o << "COMPSOLID";
-    case TopAbs_SOLID: return o << "SOLID";
-    case TopAbs_SHELL: return o << "SHELL";
-    case TopAbs_FACE: return o << "FACE";
-    case TopAbs_WIRE: return o << "WIRE";
-    case TopAbs_EDGE: return o << "EDGE";
-    case TopAbs_VERTEX: return o << "VERTEX";
-    case TopAbs_SHAPE: return o << "SHAPE";
-    default: return o << "Unknown";
-    }
-}
-
-static inline ostream &operator <<(ostream &o,const TopAbs_State &A)
-{
-    switch(A) {
-    case TopAbs_IN: return o << "IN";
-    case TopAbs_OUT: return o << "OUT";
-    case TopAbs_ON: return o << "ON";
-    case TopAbs_UNKNOWN: return o << "UNKNOWN";
-    default: return o << "Unknown";
-    }
-}
-
-static inline ostream &operator <<(ostream &o,const gp_Pnt &p)
-{
-  return o << "(" << p.Coord(1) << "," << p.Coord(2) << "," << p.Coord(3) << ")";
-}
-
-static inline ostream &operator <<(ostream &o,const TopOpeBRep_P2Dstatus &A)
-{
-    switch(A) {
-    case TopOpeBRep_P2DUNK: return o << "P2DUNK";
-    case TopOpeBRep_P2DINT: return o << "P2DINT";
-    case TopOpeBRep_P2DSGF: return o << "P2DSGF";
-    case TopOpeBRep_P2DSGL: return o << "P2DSGL ";
-    case TopOpeBRep_P2DNEW: return o << "P2DNEW ";
-    default: return o << "Unknown";
-    }
-}
-
-template <typename T>
-static inline std::ostream &operator<<(std::ostream &out, std::set<T> const &a)
-{
-    std::copy(a.begin(),a.end(),std::ostream_iterator<T>(out," "));
-    return out;
-}
-
-bool OCC_Connect::LessThanIntegerSet::operator()(std::set<int> const &a,
-    std::set<int> const &b) const
-{
-    std::set<int>::const_iterator pa=a.begin(), pb=b.begin();
-    for(; pa!=a.end() && pb!=b.end(); pa++, pb++ ) {
-        if(*pa<*pb)
-            return 1;
-        if(*pb<*pa)
-            return 0;
-    }
-    if(pb!=b.end())
-        return 1;
-    return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OCC_Connect
-////////////////////////////////////////////////////////////////////////////////
-
-int OCC_Connect::SaveBRep(char const *name)
-{
-    gp_Pnt center(0,0,0);
-    gce_MakeScale transform(center, 0.001);
-    BRepBuilderAPI_Transform scale(assembly.front(), transform.Value());
-    BRep_Builder BB;
-    TopoDS_Compound compound;
-    BB.MakeCompound(compound);
-    TopTools_ListOfShape p;
-    for(p=scale.Modified(assembly.front());
-        !p.IsEmpty();
-        p.RemoveFirst()
-    )
-        BB.Add(compound,p.First());
-    BRepTools::Write(compound, (char*)name);
-    return 1;
-}
-
-void OCC_Connect::Dump(ostream &out) const
-{
-    BRepTools::Dump(assembly.front(),out);
-}
-
-void OCC_Connect::Connect(void)
-{
-    while(assembly.size()>1) {
-        TopoDS_Compound result;
-        BRep_Builder BB;
-        BB.MakeCompound(result);
-        Intersect(BB,result,assembly.front(),assembly.back());
-        assembly.pop_front();
-        assembly.pop_back();
-        assembly.push_back(result);
-    }
-}
-
-void OCC_Connect::Collect(void)
-{
-    TopoDS_Compound result;
-    BRep_Builder BB;
-    BB.MakeCompound(result);
-    while(assembly.size()>0) {
-        if(verbose&Cutting)
-            cout << "Adding item\n";
-        BB.Add(result,assembly.front());
-        assembly.pop_front();
-    }
-    assembly.push_back(result);
-}
-
-void OCC_Connect::FaceCutters::Add(TopoDS_Edge const &edge)
-{
-    edges.push_back(edge);
-    rebuilt=0;
-}
-
-int OCC_Connect::FaceCutters::FindConnectedEdge(int v,
-    std::vector<int> &done,
-    std::vector<std::vector<int> > &v_edge
-)  {
-    int re_used=-1;
-    for(std::vector<int>::iterator p=v_edge[v].begin();p!=v_edge[v].end(); p++){
-        if(done[*p]) {
-            re_used=*p;
-            continue;
-        }
-        return *p;       // Found an unused edge
-    }
-    return re_used;
-}
-
-void dump(std::vector<std::pair<int,int> > const &e2v, std::ostream &out,
-    const char *name="name")
-{
-    out << "graph " << name << " {\n";
-    for(unsigned int e = 0; e < e2v.size(); e++) {
-      out << "    " << e2v[e].first << " -- " << e2v[e].second << "[label=" << e+1 << "]\n";
-    }
-    out << "}\n";
-}
-
-void FinishEdge(int edge,
-    std::vector<std::set<int> > &v2e,
-    std::vector<std::pair<int,int> > &e2v)
-{
-    int verbose=0;
-    if(verbose)
-      std::cout << "Finishing edge " << edge << "\n";
-
-    int fv=e2v[edge].first;
-    v2e[fv].erase(edge);
-    while(v2e[fv].size()>1) {
-        std::set<int>::iterator e=v2e[fv].begin();
-        int nv=v2e.size();
-        v2e.push_back(std::set<int>());
-        v2e[nv].insert(*e);
-        if(e2v[*e].first==fv)
-            e2v[*e].first=nv;
-        else
-            e2v[*e].second=nv;
-        if(verbose)
-          std::cout << "Created vertex " << nv << "(" << fv << "), edge[" << *e
-                    << "]=" << e2v[*e].first << " " << e2v[*e].second << "\n";
-        v2e[fv].erase(*e);
-    }
-
-    int sv=e2v[edge].second;
-    v2e[sv].erase(edge);
-    while(v2e[sv].size()>1) {
-        std::set<int>::iterator e=v2e[sv].begin();
-        int nv=v2e.size();
-        v2e.push_back(std::set<int>());
-        v2e[nv].insert(*e);
-        if(e2v[*e].first==sv)
-            e2v[*e].first=nv;
-        else
-            e2v[*e].second=nv;
-        if(verbose)
-          std::cout << "Created vertex " << nv << "(" << sv << "), edge[" << *e <<
-            "]=" << e2v[*e].first << " " << e2v[*e].second << "\n";
-        v2e[sv].erase(*e);
-    }
-}
-
-void OCC_Connect::FaceCutters::Build(TopoDS_Face const &face,
-    TopoDS_Shape &result, int verbose)
-{
-    clear();
-
-    /* First we create some data structures to access the topology */
-    TopTools_IndexedMapOfShape vertices;
-    std::vector<std::pair<int,int> > e2v;
-    for(unsigned int i = 0; i < edges.size(); i++) {
-        TopExp::MapShapes(edges[i],TopAbs_VERTEX,vertices);
-        TopoDS_Vertex v1, v2;
-        TopExp::Vertices(edges[i],v1,v2);
-        std::pair<int,int> t(vertices.FindIndex(v1),vertices.FindIndex(v2));
-        e2v.push_back(t);
-    }
-
-    std::vector<std::set<int> > v2e;
-    for(unsigned int e = 0; e < e2v.size(); e++) {
-      if(e2v[e].first >= (int)v2e.size())
-            v2e.resize(e2v[e].first+1);
-        v2e[e2v[e].first].insert(e);
-        if(e2v[e].second >= (int)v2e.size())
-            v2e.resize(e2v[e].second+1);
-        v2e[e2v[e].second].insert(e);
-    }
-
-    std::set<int> open, odd;
-    for(unsigned int i = 0; i < v2e.size(); i++) {
-        if(v2e[i].size()==0)
-            continue;
-        else if(v2e[i].size()==1)
-            open.insert(i);
-        else if(v2e[i].size()&1)
-            odd.insert(i);
-    }
-
-    if(open.size()&1)
-        std::cerr << "Inconsistent open loops\n";
-    if(odd.size()&1)
-        std::cerr << "Inconsistent odd loops\n";
-
-    for(;;) {
-        int open_mode = -1;
-        std::set<int> current_vertices;
-        for(unsigned int start = 0; start < v2e.size(); start++) {
-            if(v2e[start].size()==1) {
-                if(verbose&Cutting)
-                  std::cout << "start open at " << start << "\n";
-                current_vertices.insert(start);
-                open_mode=1;
-                break;
-            }
-        }
-        if(!current_vertices.size()) {
-            for(unsigned int start = 0; start < v2e.size(); start++) {
-                if(v2e[start].size()) {
-                    if(verbose&Cutting)
-                      std::cout << "start closed at " << start << "\n";
-                    current_vertices.insert(start);
-                    open_mode=0;
-                    break;
-                }
-            }
-        }
-        if(!current_vertices.size())
-            break;
-
-        std::map<int,std::deque<int> > wires;
-        std::set<int> processed_edges;
-        do {
-            std::set<int> next_vertices;
-            for(std::set<int>::iterator v=current_vertices.begin();
-                v!=current_vertices.end();
-                v++
-            ) {
-                for(std::set<int>::iterator e=v2e[*v].begin() ;
-                    e!=v2e[*v].end();
-                    e++
-                ) {
-                    if(processed_edges.count(*e))
-                        continue;
-
-                    int other=e2v[*e].first==*v?
-                        e2v[*e].second:e2v[*e].first;
-
-                    if(open_mode) {
-                        if(v2e[other].size()==1) {
-                            // Other is open end too, finish wire.
-                            wires[*v].push_back(*e);
-                            std::deque<int>::const_iterator p;
-                            BRepBuilderAPI_MakeWire wire;
-                            if(verbose&Cutting)
-                                std::cout << "CUT Open wire:";
-                            for(p=wires[*v].begin();
-                                p!=wires[*v].end();
-                                p++
-                            ) {
-                                FinishEdge(*p, v2e, e2v);
-                                wire.Add(edges[*p]);
-                                if(verbose&Cutting)
-                                    std::cout << ' ' << (*p)+1;
-                            }
-                            if(verbose&Cutting)
-                                std::cout << "\n";
-                            push_back(wire);
-                            goto next_vertex;
-                        }
-                    } else {
-                        if( current_vertices.count(other) ||
-                            next_vertices.count(other)
-                        ) {
-                            if(verbose&Cutting)
-                                std::cout << "CUT Closed wire:";
-                            wires[*v].push_back(*e);
-                            while(wires[other].front()
-                                ==wires[*v].front()
-                            ) {
-                                wires[other].pop_front();
-                                wires[*v].pop_front();
-                            }
-
-                            BRepBuilderAPI_MakeWire wire;
-                            std::deque<int>::const_iterator p;
-                            for(p=wires[other].begin();
-                                p!=wires[other].end();
-                                p++
-                            ) {
-                                FinishEdge(*p, v2e, e2v);
-                                wire.Add(edges[*p]);
-                                if(verbose&Cutting)
-                                    std::cout << ' ' << (*p)+1;
-                            }
-                            std::deque<int>::reverse_iterator rp;
-                            for(rp=wires[*v].rbegin();
-                                rp!=wires[*v].rend();
-                                rp++
-                            ) {
-                                FinishEdge(*rp, v2e, e2v);
-                                wire.Add(edges[*rp]);
-                                if(verbose&Cutting)
-                                    std::cout << ' ' << (*rp)+1;
-                            }
-                            if(verbose&Cutting)
-                                std::cout << "\n";
-                            push_back(wire);
-                            goto next_vertex;
-                        }
-                    }
-                    if(current_vertices.count(other)==0) {
-                        wires[other]=wires[*v];
-                        wires[other].push_back(*e);
-                        processed_edges.insert(*e);
-                        next_vertices.insert(other);
-                    }
-                }
-            }
-            current_vertices=next_vertices;
-        } while(current_vertices.size());
-        next_vertex: ;
-    }
-
-    if(size()>1 && verbose&CuttingIntermediate) {
-        if(verbose&Cutting)
-            std::cout << "Saving multiple cuts\n";
-        BRep_Builder BB;
-        TopoDS_Compound compound;
-        BB.MakeCompound(compound);
-        for(unsigned int i = 0; i < edges.size(); i++)
-            BB.Add(compound,edges[i]);
-        BRepTools::Write(compound,"cutter.brep");
-        ofstream out("cutter.dot",ios::trunc|ios::out);
-        dump(e2v,out);
-    }
-}
-
-inline OCC_Connect::cutmap_t OCC_Connect::SelectCuttingEdges(
-    TopTools_IndexedMapOfShape &edges,
-    TopTools_IndexedMapOfShape &faces)
-{
-    cutmap_t cutters;
-    for(int face=1;face<=faces.Extent();face++) {
-        for(int edge=1;edge<=edges.Extent();edge++) {
-            TopoDS_Edge c_edge=TopoDS::Edge(edges(edge));
-            TopoDS_Face c_face=TopoDS::Face(faces(face));
-
-            if(BRep_Tool::Degenerated(c_edge)) {
-                if(verbose&CuttingReject)
-                    cout << "Rejected(" << __LINE__ << ") edge " << edge
-                        << " in face " << face << endl;
-                continue;
-            }
-
-            TopTools_IndexedMapOfShape already_there;
-            TopExp::MapShapes(c_face,TopAbs_EDGE,already_there);
-            if(already_there.Contains(c_edge)) {
-                if(verbose&CuttingReject)
-                    cout << "Rejected(" << __LINE__ << ") edge " << edge
-                        << " in face " << face << endl;
-                continue;
-            }
-
-            BRepExtrema_DistShapeShape dist(c_edge,c_face);
-            double tol=BRep_Tool::Tolerance(c_face);
-            if(dist.Value()>tol) {
-                if(verbose&CuttingReject)
-                    cout << "Rejected(" << __LINE__ << ") edge " << edge
-                        << " in face " << face << endl;
-                continue;
-            }
-
-            Standard_Real s, e;
-            Handle(Geom_Curve) c3d=BRep_Tool::Curve(c_edge,s,e);
-            if(c3d.IsNull()) {
-                if(verbose&CuttingReject)
-                    cout << "Rejected(" << __LINE__ << ") edge " << edge
-                        << " in face " << face << endl;
-                continue;
-            }
-
-            // FIXME, checking only the middle may be a bit optimistic.
-            TopoDS_Vertex vm=BRepBuilderAPI_MakeVertex(c3d->Value((s+e)/2));
-            BRepExtrema_DistShapeShape dist_mf(vm,c_face);
-            if(dist_mf.Value()>tol) {
-                if(verbose&CuttingReject)
-                    cout << "Rejected(" << __LINE__ << ") edge " << edge
-                        << " in face " << face << endl;
-                continue;
-            }
-
-            if(verbose&Cutting)
-                cout << "Accepted edge " << edge << " in face " << face << endl;
-
-            // Add missing PCurve if necessary
-            Handle_Geom2d_Curve c=BRep_Tool::CurveOnSurface(c_edge,c_face,s,e);
-            if(c.IsNull()) {
-                if(verbose&Cutting)
-                    cout << "Adding missing PCurve\n";
-                ShapeFix_Edge().FixAddPCurve(c_edge,c_face,false,1e-7);
-            }
-            cutters[face].Add(c_edge);
-        }
-    }
-    return cutters;
-}
-
-void OCC_Connect::Intersect(BRep_Builder &BB, TopoDS_Shape &target,
-    TopoDS_Shape &shape, TopoDS_Shape &tool)
-{
-    /***************************************************************************
-        We start by splitting edges at all the edge-edge intersections.
-        This may generate new vertices and edges.
-    ***************************************************************************/
-    MergeVertices(shape,tool);
-    LocOpe_SplitShape splitter1(shape);
-    LocOpe_SplitShape splitter2(tool);
-    TopOpeBRep_ShapeIntersector intersector;
-    for(intersector.InitIntersection(shape,tool);
-        intersector.MoreIntersection();
-        intersector.NextIntersection()
-    ) {
-        if(verbose&Cutting) {
-            cout << "++++++++++++++++++++++++++++++++++++++++"
-                "++++++++++++++++++++++++++++++++++++++++\n";
-            intersector.DumpCurrent(1); cout << " --> ";
-            intersector.DumpCurrent(2); cout << '\n';
-        }
-
-        TopOpeBRep_EdgesIntersector &ee=intersector.ChangeEdgesIntersector();
-        if( intersector.CurrentGeomShape(1).ShapeType()==TopAbs_EDGE &&
-            intersector.CurrentGeomShape(2).ShapeType()==TopAbs_EDGE
-        ) {
-            for(ee.InitPoint(); ee.MorePoint(); ee.NextPoint()) {
-                TopOpeBRep_Point2d const &p=ee.Point();
-                if(verbose&Cutting)
-                    cout << "point loop " << p.Parameter(1) << '\n';
-                TopoDS_Vertex vertex;
-                if(p.IsVertex(1))
-                    vertex=p.Vertex(1);
-                else if(p.IsVertex(2))
-                    vertex=p.Vertex(2);
-                else
-                    vertex=BRepBuilderAPI_MakeVertex(p.Value());
-                if(!p.IsVertex(1)) {
-                    TopoDS_Edge edge=TopoDS::Edge(ee.Edge(1));
-                    if(!splitter1.CanSplit(edge)) {
-                        if(verbose&Cutting)
-                            cout << "Cannot split 1\n";;
-                    } else {
-                        if(verbose&Cutting)
-                            cout << "splitting model 1\n";
-                        try { splitter1.Add(vertex,p.Parameter(1),edge); }
-                        catch(Standard_ConstructionError c) {
-                            if(verbose&Cutting)
-                                cout << "Ooops \n";
-                        }
-                    }
-                }
-                if(!p.IsVertex(2)) {
-                    TopoDS_Edge edge=TopoDS::Edge(ee.Edge(2));
-                    if(!splitter2.CanSplit(edge)) {
-                        if(verbose&Cutting)
-                            cout << "Cannot split 2\n";;
-                    } else {
-                        if(verbose&Cutting)
-                            cout << "splitting model 2\n";
-                        try { splitter2.Add(vertex,p.Parameter(2),edge); }
-                        catch(Standard_ConstructionError c) {
-                            if(verbose&Cutting)
-                                cout << "Ooops \n";
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /***************************************************************************
-        Not all intersections seem to be caught, this is an attempt to catch
-        some missing intersections. FIXME, this is almost certainly incomplete.
-    ***************************************************************************/
-    TopTools_IndexedMapOfShape edges, faces, vertices;
-    vertices.Clear();
-    TopExp::MapShapes(shape,TopAbs_VERTEX,vertices);
-    TopExp::MapShapes(tool,TopAbs_VERTEX,vertices);
-
-    edges.Clear();
-    TopExp::MapShapes(shape,TopAbs_EDGE,edges);
-    for(int e=1; e<=edges.Extent(); e++) {
-        TopoDS_Edge edge=TopoDS::Edge(edges(e));
-        TopoDS_Vertex o1, o2;
-        TopExp::Vertices(edge,o1,o2);
-        int skip1=vertices.FindIndex(o1);
-        int skip2=vertices.FindIndex(o2);
-        for(int v=1; v<=vertices.Extent(); v++) {
-            if(v==skip1 || v==skip2)
-                continue;
-            TopoDS_Vertex vertex=TopoDS::Vertex(vertices(v));
-            BRepExtrema_ExtPC distance(vertex,edge);
-            if(!distance.IsDone())
-                continue;
-            double tolerance=std::max(BRep_Tool::Tolerance(edge),
-                                      BRep_Tool::Tolerance(vertex));
-            for(int i=1;i<=distance.NbExt();i++) {
-#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
-              double value = distance.Value(i);
-#else
-              double value = distance.SquareDistance(i);
-#endif
-              if(value<tolerance) {
-                    try {
-                        // No idea why this can fail
-                        splitter1.Add(vertex,distance.Parameter(i),edge);
-                    }
-                    catch(Standard_ConstructionError c) {
-                        if(verbose&Cutting) {
-                            cout << "Adding vertex to edge failed\n";
-                            TopoDS_Vertex v1, v2;
-                            TopExp::Vertices(edge,v1,v2);
-                            if(BRepTools::Compare(v1,vertex))
-                                cout << "Merge v1\n";
-                            if(BRepTools::Compare(v2,vertex))
-                                cout << "Merge v2\n";
-                            double d1=BRep_Tool::Pnt(v1).Distance(
-                                BRep_Tool::Pnt(vertex));
-                            double d2=BRep_Tool::Pnt(v2).Distance(
-                                BRep_Tool::Pnt(vertex));
-                            cout << "Adding " << i << " to edge " << e
-                                << " distance=" << value
-                                << " parameter=" << distance.Parameter(i)
-                                << " point=" << distance.Point(i)
-                                << " dv1=" << d1
-                                << " dv2=" << d2
-                                << endl;
-                            BRepTools::Dump(vertex,cout);
-                            BRepTools::Dump(edge,cout);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    edges.Clear();
-    TopExp::MapShapes(tool,TopAbs_EDGE,edges);
-    for(int e=1; e<=edges.Extent(); e++) {
-        TopoDS_Edge edge=TopoDS::Edge(edges(e));
-        TopoDS_Vertex o1, o2;
-        TopExp::Vertices(edge,o1,o2);
-        int skip1=vertices.FindIndex(o1);
-        int skip2=vertices.FindIndex(o2);
-        for(int v=1; v<=vertices.Extent(); v++) {
-            if(v==skip1 || v==skip2)
-                continue;
-            TopoDS_Vertex vertex=TopoDS::Vertex(vertices(v));
-            BRepExtrema_ExtPC distance(vertex,edge);
-            if(!distance.IsDone())
-                continue;
-            double tolerance=std::max(BRep_Tool::Tolerance(edge),
-                                      BRep_Tool::Tolerance(vertex));
-            for(int i=1;i<=distance.NbExt();i++) {
-#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
-              double value = distance.Value(i);
-#else
-              double value = distance.SquareDistance(i);
-#endif
-              if(value<tolerance) {
-                    try {
-                        splitter2.Add(vertex,distance.Parameter(i),edge);
-                    }
-                    catch(Standard_ConstructionError c) {
-                        if(verbose&Cutting) {
-                            cout << "Adding vertex to edge failed\n";
-                            TopoDS_Vertex v1, v2;
-                            TopExp::Vertices(edge,v1,v2);
-                            if(BRepTools::Compare(v1,vertex))
-                                cout << "Merge v1\n";
-                            if(BRepTools::Compare(v2,vertex))
-                                cout << "Merge v2\n";
-                            double d1=BRep_Tool::Pnt(v1).Distance(
-                                BRep_Tool::Pnt(vertex));
-                            double d2=BRep_Tool::Pnt(v2).Distance(
-                                BRep_Tool::Pnt(vertex));
-                            cout << "Adding " << i << " to edge " << e
-                                << " distance=" << value
-                                << " parameter=" << distance.Parameter(i)
-                                << " point=" << distance.Point(i)
-                                << " dv1=" << d1
-                                << " dv2=" << d2
-                                << endl;
-                            BRepTools::Dump(vertex,cout);
-                            BRepTools::Dump(edge,cout);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /***************************************************************************
-        We need the shapes with all the edge-edge intersections to split
-        all the faces. All vertices and edges which can be merged, will
-        be merged.
-    ***************************************************************************/
-    TopoDS_Compound intermediate1;
-    BB.MakeCompound(intermediate1);
-    for(TopTools_ListIteratorOfListOfShape p(splitter1.DescendantShapes(shape));
-        p.More();
-        p.Next()
-    ) {
-        BB.Add(intermediate1,p.Value());
-    }
-    TopoDS_Compound intermediate2;
-    BB.MakeCompound(intermediate2);
-    for(TopTools_ListIteratorOfListOfShape p(splitter2.DescendantShapes(tool));
-        p.More();
-        p.Next()
-    ) {
-        BB.Add(intermediate2,p.Value());
-    }
-    if(verbose&Cutting) {
-        cout << "Before merging vertices and edges\n";
-        TopoDS_Compound t;
-        BB.MakeCompound(t);
-        BB.Add(t,intermediate1);
-        BB.Add(t,intermediate2);
-        PrintItemCount(t);
-    }
-    MergeVertices(intermediate1,intermediate2);
-    MergeEdges(intermediate1,intermediate2);
-    if(verbose&Cutting) {
-        cout << "After merging vertices and edges\n";
-        TopoDS_Compound t;
-        BB.MakeCompound(t);
-        BB.Add(t,intermediate1);
-        BB.Add(t,intermediate2);
-        PrintItemCount(t);
-    }
-
-    // Create the result
-    TopoDS_Compound result;
-    BB.MakeCompound(result);
-    BB.Add(result,intermediate1);
-    BB.Add(result,intermediate2);
-
-    // Add any missing PCurves
-    for(TopExp_Explorer face(result,TopAbs_FACE); face.More(); face.Next()) {
-        for(TopExp_Explorer edge(face.Current(),TopAbs_EDGE);
-            edge.More();
-            edge.Next()
-        ) {
-            Standard_Real s, e;
-            TopoDS_Edge c_edge=TopoDS::Edge(edge.Current());
-            TopoDS_Face c_face=TopoDS::Face(face.Current());
-            Handle_Geom2d_Curve c=BRep_Tool::CurveOnSurface(c_edge,c_face,s,e);
-            if(c.IsNull()) {
-                if(verbose&Cutting)
-                    cout << "Adding missing PCurve\n";
-                ShapeFix_Edge().FixAddPCurve(c_edge,c_face,false,1e-7);
-            }
-        }
-    }
-
-    /***************************************************************************
-        We determine which edges/wires are going to cut a face. To do this
-        we create a map of FaceCutters which is indexed by the face number
-        in the faces map. The FaceCutters generate the correct cutting wires.
-    ***************************************************************************/
-    int retry;
-do {
-    if(verbose&Cutting)
-        std::cout << "STARTED CUTTING\n";
-    retry=0;
-    edges.Clear(); TopExp::MapShapes(result,TopAbs_EDGE,edges);
-    faces.Clear(); TopExp::MapShapes(result,TopAbs_FACE,faces);
-    cutmap_t cutters=SelectCuttingEdges(edges,faces);
-
-    /***************************************************************************
-        Apply all face splits stored in the map.
-    ***************************************************************************/
-    int cut_count=0;
-    LocOpe_SplitShape splitter(result);
-    for(cutmap_t::iterator f=cutters.begin(); f!=cutters.end(); f++) {
-        TopoDS_Face const &face=TopoDS::Face(faces(f->first));
-        FaceCutters &cutter=f->second;
-        cut_count+=cutter.size();
-        if(verbose&Cutting) {
-            cout << "Cutting face " << f->first << " *************************\n";
-            BRepTools::Dump(face,cout);
-        }
-        cutter.Build(face,result,verbose);
-        for(FaceCutters::iterator p=cutter.begin(); p!=cutter.end(); p++) {
-            TopTools_IndexedMapOfShape edges;
-            TopExp::MapShapes(*p,TopAbs_EDGE,edges);
-            if(edges.Extent()<3 && BRep_Tool::IsClosed(*p)) {
-                // FIXME This doesn't work.
-                cout << "IGNORED Closed wire with less than three edges\n";
-                continue;
-            }
-            //BRepTools::Dump(*p,cout);
-            try {
-                splitter.Add(*p,face);
-            }
-            catch(Standard_ConstructionError c) {
-                cout << "splitting the face failed\n";
-                retry=1;
-            }
-        }
-    }
-    if(verbose&Cutting)
-        cout << cut_count << " cuts in " << cutters.size() << " faces\n";
-
-    // Create the final shape with the cutted faces.
-    TopoDS_Compound cutted;
-    BB.MakeCompound(cutted);
-    int count=0;
-    for(TopTools_ListIteratorOfListOfShape p(splitter.DescendantShapes(result));
-        p.More();
-        p.Next()
-    ) {
-        if(++count==1) {
-            if(verbose&Cutting) {
-                cout << "--------- " << count << " ---------------------------\n";
-                BRepTools::Dump(p.Value(),cout);
-            }
-            BB.Add(cutted,p.Value());
-        }
-    }
-    MergeFaces(cutted);
-    result=cutted;
-} while(0 && retry);
-    target=result;
-}
-
-void OCC_Connect::MergeVertices(TopoDS_Shape &shape1,TopoDS_Shape &shape2) const
-{
-    TopTools_IndexedMapOfShape imap, omap;
-    TopExp::MapShapes(shape1,TopAbs_VERTEX,imap);
-    TopExp::MapShapes(shape2,TopAbs_VERTEX,imap);
-    BRepTools_ReShape replacer;
-    for(int i=0;i<imap.Extent();i++) {
-        for(int j=0;j<omap.Extent();j++) {
-            TopoDS_Vertex orig=TopoDS::Vertex(imap(i+1));
-            TopoDS_Vertex repl=TopoDS::Vertex(omap(j+1));
-            if(BRepTools::Compare(orig,repl)) {
-                repl.Orientation(orig.Orientation());
-                replacer.Replace(orig,repl);
-                // FIXME, tolerance and point should be updated
-                goto skip;
-            }
-        }
-        omap.Add(imap(i+1));
-    skip:;
-    }
-    TopoDS_Shape t=shape1;
-    shape1=replacer.Apply(t);
-    t=shape2;
-    shape2=replacer.Apply(t);
-}
-
-bool OCC_Connect::CanMergeCurve(TopoDS_Edge edge1,TopoDS_Edge edge2) const
-{
-    if(BRep_Tool::Degenerated(edge1) && BRep_Tool::Degenerated(edge2))
-        return 1;
-
-    double tol=1e-7;
-
-    Standard_Real s,e;
-    Handle(Geom_Curve) curve=BRep_Tool::Curve(edge1,s,e);
-    for(Standard_Real i=s;i<=e;i+=(e-s)/10) {
-        TopoDS_Vertex v=BRepBuilderAPI_MakeVertex(curve->Value(i));
-        double dist=BRepExtrema_DistShapeShape(edge2,v).Value();
-        if(dist>tol)
-            return 0;
-    }
-    return 1;
-}
-
-void OCC_Connect::MergeEdges(TopoDS_Shape &shape1, TopoDS_Shape &shape2) const
-{
-    TopTools_IndexedMapOfShape imap, omap;
-    TopExp::MapShapes(shape1,TopAbs_EDGE,imap);
-    TopExp::MapShapes(shape2,TopAbs_EDGE,imap);
-    BRepTools_ReShape replacer;
-    for(int i=0;i<imap.Extent();i++) {
-        for(int j=0;j<omap.Extent();j++) {
-            TopoDS_Edge orig=TopoDS::Edge(imap(i+1));
-            TopoDS_Edge repl=TopoDS::Edge(omap(j+1));
-
-            TopoDS_Vertex o1, o2, r1, r2;
-            TopExp::Vertices(orig,o1,o2,true);
-            TopExp::Vertices(repl,r1,r2,true);
-
-            if(o1.IsSame(o2)) {
-                if(!BRep_Tool::Degenerated(orig)) {
-                    if(verbose&Cutting) {
-                        cout << "Same vertex in edge\n";
-                        BRepTools::Dump(orig,cout);
-                    }
-                    replacer.Remove(orig);
-                    goto skip;
-                } else if(o1.IsSame(r1) && o1.IsSame(r2)
-                    && CanMergeCurve(orig,repl)
-                ) {
-                    if(verbose&Cutting) {
-                        cout << "Degenerated edge, replace " << i+1
-                            << " with " << j+1 << '\n';
-                        BRepTools::Dump(orig,cout);
-                        BRepTools::Dump(repl,cout);
-                    }
-                    // FIXME, update tolerance
-                    BRepTools::Dump(repl.Complemented(),cout);
-                    replacer.Replace(orig,repl.Complemented());
-                    goto skip;
-                }
-                cout << i+1 << " Degenerated\n";
-            }
-            if(o1.IsSame(r1) && o2.IsSame(r2) && CanMergeCurve(orig,repl))  {
-                if(verbose&Cutting) {
-                    cout << "Same order of vertices, replace " << i+1
-                        << " with " << j+1 << '\n';
-                    BRepTools::Dump(orig,cout);
-                    BRepTools::Dump(repl,cout);
-                }
-                // FIXME, update tolerance
-                replacer.Replace(orig,repl);
-                goto skip;
-            }
-            if(o1.IsSame(r2) && o2.IsSame(r1) && CanMergeCurve(orig,repl)) {
-                if(verbose&Cutting) {
-                    cout << "Reversed order of vertices, replace " << i+1
-                        << " with " << j+1 << '\n';
-                    BRepTools::Dump(orig,cout);
-                    BRepTools::Dump(repl,cout);
-                }
-                // FIXME, update tolerance
-                replacer.Replace(orig,repl.Complemented());
-                goto skip;
-            }
-        }
-        if(verbose&Cutting)
-            cout << "Adding " << i+1 << " as " << omap.Extent()+1<<" to keep map\n";
-        omap.Add(imap(i+1));
-    skip:;
-    }
-    TopoDS_Shape t=shape1;
-    shape1=replacer.Apply(t);
-    t=shape2;
-    shape2=replacer.Apply(t);
-}
-
-bool OCC_Connect::CanMergeFace(TopoDS_Face face1,TopoDS_Face face2) const
-{
-    // FIXME, this really does not work.
-    return 1;
-
-    //double tol=1e-7;
-
-    Handle(Geom_Surface) surface=BRep_Tool::Surface(face1);
-    Standard_Real u1, u2, v1, v2;
-    surface->Bounds(u1,u2,v1,v2);
-    cout << "u1=" << u1 << " u2=" << u2 << " v1=" << v1 << " v2=" << v2 << endl;
-    for(Standard_Real u=u1+(u2-u1)/10;u<u2;u+=(u2-u1)/10) {
-        for(Standard_Real v=v1+(v2-v1)/10;v<v2;v+=(v2-v1)/10) {
-            TopoDS_Vertex vtx=BRepBuilderAPI_MakeVertex(surface->Value(u,v));
-            BRepExtrema_DistShapeShape dss(face2,vtx);
-            dss.Perform();
-#if 0
-            double dist=dss.Value();
-            if(dist>tol) {
-                cout << "Distance=" << dist << " v=" << v << " u=" << u
-                    << " pnt=" << surface->Value(u,v) << endl;
-                BRepTools::Dump(face2,cout);
-                return 0;
-            }
-#else
-            dss.Dump(cout);
-#endif
-        }
-    }
-    return 1;
-}
-
-void OCC_Connect::MergeFaces(TopoDS_Shape &shape) const
-{
-    /***************************************************************************
-        We must find faces which are the same. Since all edges are already
-        merged, we know that faces which can be merged have identical edges.
-    ***************************************************************************/
-    TopTools_IndexedMapOfShape faces, edges;
-    TopExp::MapShapes(shape,TopAbs_FACE,faces);
-    TopExp::MapShapes(shape,TopAbs_EDGE,edges);
-    mapping_t mapping;
-    for(int i=0;i<faces.Extent();i++) {
-        std::set<int> face_edges;
-        for(TopExp_Explorer p(faces(i+1),TopAbs_EDGE); p.More(); p.Next()) {
-            int edge=edges.FindIndex(p.Current());
-            if(BRep_Tool::Degenerated(TopoDS::Edge(edges(edge)))) {
-                cout << "Degenerate edge " << edge << " inserted a 0\n";
-                face_edges.insert(0);
-            } else
-                face_edges.insert(edge);
-        }
-        mapping[face_edges].insert(i+1);
-    }
-
-    if(verbose&Cutting) {
-        for(mapping_t::iterator p=mapping.begin(); p!=mapping.end(); p++)
-            cout << "edges [ " << p->first << "] in face"
-                << (p->second.size()<2? " ":"s ") << "[ " << p->second << "]\n";
-    }
-
-    /***************************************************************************
-        If two faces have an identical set of edges, they can be merged
-        when the planes are never seperated by more than the tolerance.
-    ***************************************************************************/
-    BRepTools_ReShape replacer;
-    for(mapping_t::iterator p=mapping.begin(); p!=mapping.end(); p++) {
-        if(p->second.size()<2)
-            continue;
-        std::vector<int> uniq;
-        for(std::set<int>::iterator q=p->second.begin();
-            q!=p->second.end();
-            q++
-        ) {
-            for(std::vector<int>::iterator r=uniq.begin(); r!=uniq.end(); r++) {
-                TopoDS_Face orig=TopoDS::Face(faces(*q));
-                TopoDS_Face repl=TopoDS::Face(faces(*r));
-                if(verbose&Cutting)
-                    cout << "Check face " << *q << " and " << *r << endl;
-                if(CanMergeFace(orig,repl)) {
-                    if(verbose&Cutting) {
-                        cout << "replace face " << *q << " with " << *r << '\n';
-                    }
-                    repl.Orientation(orig.Orientation());
-                    replacer.Replace(orig,repl);
-                    // FIXME, tolerance should be updated
-                    goto skip;
-                }
-            }
-            uniq.push_back(*q);
-        skip:;
-        }
-    }
-
-    TopoDS_Shape t=shape;
-    shape=replacer.Apply(t);
-}
-
-void OCC_Connect::PrintItemCount(TopoDS_Shape const &shape) const
-{
-    TopTools_IndexedMapOfShape imap;
-    TopExp::MapShapes(shape,TopAbs_VERTEX,imap);
-    cout << "Input map contains " << imap.Extent() << " vertices\n";
-    imap.Clear();
-    TopExp::MapShapes(shape,TopAbs_EDGE,imap);
-    cout << "Input map contains " << imap.Extent() << " edges\n";
-    imap.Clear();
-    TopExp::MapShapes(shape,TopAbs_FACE,imap);
-    cout << "Input map contains " << imap.Extent() << " faces\n";
-    imap.Clear();
-    TopExp::MapShapes(shape,TopAbs_SOLID,imap);
-    cout << "Input map contains " << imap.Extent() << " solids\n";
-    imap.Clear();
-    TopExp::MapShapes(shape,TopAbs_COMPSOLID,imap);
-    cout << "Input map contains " << imap.Extent() << " compsolids\n";
-    imap.Clear();
-    TopExp::MapShapes(shape,TopAbs_COMPOUND,imap);
-    cout << "Input map contains " << imap.Extent() << " compounds\n";
-}
-
-#endif
diff --git a/Geo/OCC_Connect.h b/Geo/OCC_Connect.h
deleted file mode 100644
index 1843f20e328d1807281b0b105f17904998bcc85e..0000000000000000000000000000000000000000
--- a/Geo/OCC_Connect.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
-//
-// See the LICENSE.txt file for license information. Please report all
-// bugs and problems to <gmsh@geuz.org>.
-//
-// Contributed by Mark van Doesburg, Technolution B.V.
-
-#ifndef _OCC_CONNECT_H_
-#define _OCC_CONNECT_H_
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <deque>
-#include <map>
-#include <vector>
-#include <set>
-
-#include "GmshConfig.h"
-
-#if defined(HAVE_OCC)
-
-#if !defined(HAVE_NO_OCC_CONFIG_H)
-#include <config.h>
-#endif
-
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Wire.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-
-#include <BRep_Builder.hxx>
-#include <LocOpe_SplitShape.hxx>
-
-////////////////////////////////////////////////////////////////////////////////
-//
-////////////////////////////////////////////////////////////////////////////////
-class OCC_Connect {
-    struct LessThanIntegerSet {
-        bool operator()(std::set<int> const &a, std::set<int> const &b) const;
-    };
-    typedef std::map<std::set<int>,std::set<int>,LessThanIntegerSet> mapping_t;
-
-    class FaceCutters:public std::vector<TopoDS_Wire> {
-        std::vector<TopoDS_Edge> edges;
-        int rebuilt;
-    public:
-        FaceCutters(void) { rebuilt=0; }
-        void Build(TopoDS_Face const &,TopoDS_Shape&,int);
-        void Add(TopoDS_Edge const&);
-    private:
-        int FindConnectedEdge(int v, std::vector<int> &done,
-            std::vector<std::vector<int> > &v_edge);
-    };
-    typedef std::map<int,FaceCutters> cutmap_t;
-
-    std::deque<TopoDS_Shape> assembly;
-protected:
-    int verbose;
-
-public:
-    enum Verbose { Cutting=1, CuttingReject=4, CuttingIntermediate=8 };
-    OCC_Connect(int v=0) { verbose=v; }
-    int SaveBRep(char const *);
-    void Connect(void);
-    void Collect(void);
-    void Add(TopoDS_Shape const &a) { assembly.push_back(a); }
-    void Dump(std::ostream &) const;
-    operator TopoDS_Shape(void) { return assembly.front(); }
-private:
-    void MergeVertices(TopoDS_Shape&,TopoDS_Shape&) const;
-    void MergeEdges(TopoDS_Shape&,TopoDS_Shape&) const;
-    void MergeFaces(TopoDS_Shape&) const;
-    void PerformBoolean(union tree*);
-    void Intersect(BRep_Builder &BB, TopoDS_Shape &target,
-        TopoDS_Shape &shape, TopoDS_Shape &tool);
-    bool CanMergeCurve(TopoDS_Edge edge1,TopoDS_Edge edge2) const;
-    bool CanMergeFace(TopoDS_Face face1,TopoDS_Face face2) const;
-    void PrintItemCount(TopoDS_Shape const &shape) const;
-    cutmap_t SelectCuttingEdges(TopTools_IndexedMapOfShape &edges,
-        TopTools_IndexedMapOfShape &faces);
-};
-
-#endif
-
-#endif
diff --git a/contrib/Salome/CMakeLists.txt b/contrib/Salome/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..578733af52b1a35b35114931c0185d1ba2bc8e42
--- /dev/null
+++ b/contrib/Salome/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  Partition_Inter2d.cxx 
+  Partition_Inter3d.cxx 
+  Partition_Loop.cxx
+  Partition_Loop2d.cxx
+  Partition_Loop3d.cxx
+  Partition_Spliter.cxx
+)
+
+file(GLOB_RECURSE HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.hxx)
+append_gmsh_src(contrib/Salome "${SRC};${HDR}")
diff --git a/contrib/Salome/Partition_Inter2d.cxx b/contrib/Salome/Partition_Inter2d.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4634b32daf1be828659009e20d55840ee5df5edb
--- /dev/null
+++ b/contrib/Salome/Partition_Inter2d.cxx
@@ -0,0 +1,679 @@
+#ifdef OCCGEOMETRY
+
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R& D, LEG, PRINCIPIA R& D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : Partition_Inter2d.cxx
+//  Author : Benedicte MARTIN
+//  Module : GEOM
+//  $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Inter2d.cxx,v 1.5 2008/03/31 14:20:28 wabro Exp $
+
+#include "Partition_Inter2d.ixx"
+
+//#include "utilities.h"
+
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAlgo_AsDes.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Precision.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopOpeBRepDS_Transition.hxx>
+#include <TopOpeBRep_EdgesIntersector.hxx>
+#include <TopOpeBRep_Point2d.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Pnt.hxx>
+
+#ifdef DEB
+static Standard_Boolean TestEdges = 0;
+static Standard_Integer NbF2d = 0;
+static Standard_Integer NbE2d = 0;
+#endif
+
+//=======================================================================
+//function : getOtherShape
+//purpose  :
+//=======================================================================
+
+static TopoDS_Shape getOtherShape(const TopoDS_Shape&         theS,
+                                  const TopTools_ListOfShape& theSList)
+{
+  TopTools_ListIteratorOfListOfShape anIt( theSList );
+  for ( ; anIt.More(); anIt.Next() )
+    if (!theS.IsSame( anIt.Value() ))
+      return anIt.Value();
+
+  return TopoDS_Shape();
+}
+
+//=======================================================================
+//function : findVOnE
+//purpose  : on theE, find a vertex close to theV, such that an edge
+//           passing through it is an itersection of theF1 and theF2.
+//           theE intersects theE2 at theV
+//=======================================================================
+
+static Standard_Boolean findVOnE(const TopoDS_Vertex &         theV,
+                                 const TopoDS_Edge&            theE,
+                                 const TopoDS_Edge&            theE2,
+                                 const TopoDS_Shape&           theF1,
+                                 const TopoDS_Shape&           theF2,
+                                 const Handle(BRepAlgo_AsDes)& theAsDes,
+                                 TopoDS_Vertex &               theFoundV)
+{
+  Standard_Real MinDist2 = ::RealLast();
+  gp_Pnt P;
+
+  // check all vertices on theE
+  const TopTools_ListOfShape& aVList = theAsDes->Descendant( theE );
+  TopTools_ListIteratorOfListOfShape anIt( aVList );
+  if (anIt.More())
+    P = BRep_Tool::Pnt( theV );
+  for ( ; anIt.More(); anIt.Next() )
+  {
+    // check by distance
+    TopoDS_Vertex & V = TopoDS::Vertex( anIt.Value() );
+    Standard_Real dist2 = P.SquareDistance( BRep_Tool::Pnt( V ));
+    if (dist2 < MinDist2)
+      MinDist2 = dist2;
+    else
+      continue;
+
+    // V is a candidate if among edges passing through V there is one
+    // which is an intersection of theF1 and theF2
+    TopTools_ListIteratorOfListOfShape anEIt( theAsDes->Ascendant( V ));
+    Standard_Boolean isOk = Standard_False;
+    for (  ; !isOk && anEIt.More(); anEIt.Next() )
+    {
+      const TopoDS_Shape & E2 = anEIt.Value();
+      if ( theE2.IsSame( E2 ))
+        continue;
+      const TopTools_ListOfShape & aFList = theAsDes->Ascendant( E2 );
+      if (aFList.IsEmpty())
+        continue;
+      if ( theF1.IsSame( aFList.First() ))
+        isOk = theF2.IsSame( aFList.Last() );
+      else
+        isOk = theF2.IsSame( aFList.First() ) && theF1.IsSame( aFList.Last() );
+    }
+    if (isOk)
+      theFoundV = V;
+  }
+
+  if (theFoundV.IsNull())
+    return Standard_False;
+
+  // check that MinDist2 is not too large
+  Standard_Real f, l;
+  TopLoc_Location L;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theE, L, f, l );
+  gp_Pnt P1 = aCurve->Value( f );
+  gp_Pnt P2 = aCurve->Value( 0.3 * f + 0.7 * l );
+  //gp_Pnt P2 = aCurve->Value( 0.5 * ( f + l ));
+  if (MinDist2 > P1.SquareDistance( P2 ))
+    return Standard_False;
+
+#ifdef DEB
+  MESSAGE("findVOnE: found MinDist = " << sqrt (MinDist2));
+#endif
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : AddVonE
+//purpose  : Put V in AsDes as intersection of E1 and E2.
+//           Check that vertex equal to V already exists on one
+//           of edges, in  such  a  case,  V  is  not added but
+//           existing vertex is updated to  be on E1 and E2 and
+//           is returned insead of V.
+//=======================================================================
+
+TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV,
+                                         const TopoDS_Edge&   E1,
+                                         const TopoDS_Edge&   E2,
+                                         const Handle(BRepAlgo_AsDes)& AsDes,
+                                         const TopoDS_Face&   theF)
+
+{
+  //-------------------------------------------------------------
+  // test if the points of intersection already exist. If not,
+  // add as descendants of the edges.
+  // nb: theses points are only vertices of intersection.
+  //-------------------------------------------------------------
+  const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
+  const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
+  gp_Pnt                      P1,P2;
+  TopoDS_Vertex               V1,V2;
+  TopTools_ListIteratorOfListOfShape it;
+  BRep_Builder                       B;
+  TopAbs_Orientation                 O1,O2;
+  Standard_Real                      U1,U2;
+  Standard_Real                      Tol,Tol1,Tol2;
+  Standard_Boolean                   OnE1,OnE2;
+
+  TopoDS_Vertex V    = theV;
+
+  U1 = BRep_Tool::Parameter(V,E1);
+  U2 = BRep_Tool::Parameter(V,E2);
+  O1 = V.Orientation();
+  O2 = O1;
+  P1  = BRep_Tool::Pnt(V);
+  Tol = BRep_Tool::Tolerance( V );
+  OnE1 = OnE2 = Standard_False;
+
+  //-----------------------------------------------------------------
+  // Search if the point of intersection is a vertex of E1.
+  //-----------------------------------------------------------------
+  for (it.Initialize(VOnE1); it.More(); it.Next()) {
+    const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() );
+    if (V.IsSame( CV )) {
+      V1   = V;
+      OnE1 = Standard_True;
+      break;
+    }
+    P2 = BRep_Tool::Pnt( CV );
+    Tol1 = 1.1*(Tol + BRep_Tool::Tolerance( CV ));
+    if (P1.SquareDistance(P2) <= Tol1*Tol1) {
+      V    = CV;
+      V1   = V;
+      OnE1 = Standard_True;
+      break;
+    }
+  }
+  if (OnE1) {
+    //-----------------------------------------------------------------
+    // Search if the vertex found is still on E2.
+    //-----------------------------------------------------------------
+    for (it.Initialize(VOnE2); it.More(); it.Next()) {
+      if (V.IsSame( it.Value() )) {
+        OnE2 = Standard_True;
+        V2   = V;
+        break;
+      }
+    }
+  }
+  if (!OnE2) {
+    for (it.Initialize(VOnE2); it.More(); it.Next()) {
+      //-----------------------------------------------------------------
+      // Search if the point of intersection is a vertex of E2.
+      //-----------------------------------------------------------------
+      const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() );
+      P2 = BRep_Tool::Pnt( CV );
+      Tol2 = 1.1*(Tol + BRep_Tool::Tolerance( CV ));
+      if (P1.SquareDistance(P2) <= Tol2*Tol2) {
+        V  = CV;
+        V2 = V;
+        OnE2 = Standard_True;
+        break;
+      }
+    }
+  }
+
+
+  if (!OnE1 && !OnE2 && !theF.IsNull())
+  {
+    // if 3 faces intersects each others, 3 new edges on them must pass
+    // through one vertex but real intersection points of each
+    // pair of edges are sometimes more far than a tolerance.
+    // Try to analitically find vertices that E1 and E2 must pass trough
+
+    TopoDS_Shape F1 = getOtherShape( theF, AsDes->Ascendant( E1 ));
+    TopoDS_Shape F2 = getOtherShape( theF, AsDes->Ascendant( E2 ));
+    if (!F1.IsNull() && !F2.IsNull() && !F1.IsSame( F2 ))
+    {
+      OnE1 = findVOnE ( theV, E1, E2, F1, F2, AsDes, V1 );
+      OnE2 = findVOnE ( theV, E2, E1, F1, F2, AsDes, V2 );
+      if (OnE2) V = V2;
+      if (OnE1) V = V1;
+    }
+  }
+
+  if (OnE1 && OnE2) {
+    if (!V1.IsSame(V2)) {
+      // replace V1 with V2 on all edges V1 is on
+      Standard_Real UV1;
+      TopoDS_Edge   EWE1;
+      TopoDS_Vertex VI;
+      const TopTools_ListOfShape& EdgeWithV1 = AsDes->Ascendant(V1);
+
+      for (it.Initialize(EdgeWithV1); it.More(); it.Next()) {
+        EWE1  = TopoDS::Edge(it.Value());
+        VI = V1;
+        VI.Orientation(TopAbs_INTERNAL);
+        UV1 = BRep_Tool::Parameter(VI,EWE1);
+        VI = V2;
+        VI.Orientation(TopAbs_INTERNAL);
+        B.UpdateVertex( VI, UV1, EWE1, GetTolerance( VI, UV1, EWE1, AsDes));
+      }
+      AsDes->Replace(V1,V2);
+      V = V2;
+    }
+  }
+
+  // add existing vertices instead of new ones
+  if (!OnE1) {
+    if (OnE2) {
+      V.Orientation(TopAbs_INTERNAL);
+      B.UpdateVertex (V, U1, E1, GetTolerance( V, U1, E1, AsDes));
+    }
+    V.Orientation(O1);
+    AsDes->Add(E1,V);
+  }
+  if (!OnE2) {
+    if (OnE1) {
+      V.Orientation(TopAbs_INTERNAL);
+      B.UpdateVertex (V, U2, E2, GetTolerance( V, U2, E2, AsDes ));
+    }
+    V.Orientation(O2);
+    AsDes->Add(E2,V);
+  }
+
+  return V;
+}
+
+//=======================================================================
+//function : FindEndVertex
+//purpose  : Returns a vertex  from  <VertList> having parameter on
+//           <E>  closest  to  <f>  or  <l>.  <isFirst>  is True if
+//           found vertex is closer  to <f>. <DU> returns parameter
+//           difference.
+//=======================================================================
+
+TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV,
+                                               const Standard_Real f,
+                                               const Standard_Real l,
+                                               const TopoDS_Edge&  E,
+                                               Standard_Boolean&   isFirst,
+                                               Standard_Real&      minDU)
+{
+  TopoDS_Vertex endV;
+  Standard_Real U, endU, min;
+  minDU = 1.e10;
+
+  TopTools_ListIteratorOfListOfShape it;
+  it.Initialize(LV);
+  for (; it.More(); it.Next()) {
+    const TopoDS_Vertex& v = TopoDS::Vertex(it.Value());
+    U = BRep_Tool::Parameter(v, E);
+    min = Min( Abs(U-f), Abs(U-l) );
+    if (min < minDU) {
+      endV = v;
+      endU = U;
+      minDU = min;
+    }
+  }
+  if (Abs(endU-f) < Abs(endU-l))
+    isFirst = Standard_True;
+  else
+    isFirst = Standard_False;
+
+  return endV;
+}
+
+//=======================================================================
+//function : treatClosed
+//purpose  : add second vertex to closed edge. Vertex is one of <LV1>
+//=======================================================================
+
+static void treatClosed (const TopoDS_Edge& E1,
+                          const Standard_Real f,
+                          const Standard_Real l,
+                          TopTools_ListOfShape& LV1,
+                          TopTools_ListOfShape& /*LV2*/)
+{
+  Standard_Boolean isFirst=0;
+  Standard_Real    minDU = 1.e10;
+  TopoDS_Vertex endV;
+  endV = Partition_Inter2d::FindEndVertex(LV1, f,l, E1, isFirst,minDU);
+
+  if (minDU > Precision::PConfusion())
+    return; // not end point
+
+  Standard_Real newU;
+  if (isFirst)
+    newU = f + (l - f);
+  else
+    newU = l - (l - f);
+
+  // update end parameter
+  BRep_Builder B;
+  endV.Orientation(TopAbs_INTERNAL);
+  B.UpdateVertex(endV,newU,E1,BRep_Tool::Tolerance(endV));
+}
+
+//=======================================================================
+//function : EdgesPartition
+//purpose  :
+//=======================================================================
+
+static void EdgesPartition(const TopoDS_Face&            F,
+                           const TopoDS_Edge&            E1,
+                           const TopoDS_Edge&            E2,
+                           const Handle(BRepAlgo_AsDes)& AsDes,
+                           const TopTools_MapOfShape&    NewEdges,
+                           const Standard_Boolean        WithOri)
+{
+
+  Standard_Real f[3],l[3];
+  Standard_Real MilTol2;
+  Standard_Real Tol = Max (BRep_Tool::Tolerance(E1),
+                           BRep_Tool::Tolerance(E2));
+  MilTol2 = Tol * Tol * 10;
+
+  BRep_Tool::Range(E1, f[1], l[1]);
+  BRep_Tool::Range(E2, f[2], l[2]);
+
+  BRepAdaptor_Curve CE1(E1,F);
+  BRepAdaptor_Curve CE2(E2,F);
+
+  TopoDS_Edge                 EI[3]; EI[1] = E1; EI[2] = E2;
+  TopTools_ListOfShape        LV1; // new vertices at intersections on E1
+  TopTools_ListOfShape        LV2; // ... on E2
+  BRep_Builder                B;
+
+  // if E1 and E2 are results of intersection of F and two connex faces then
+  // no need to intersect edges, they can contact by vertices only
+  // (encounted an exception in TopOpeBRep_EdgesIntersector in such a case)
+  Standard_Boolean intersect = Standard_True;
+  TopTools_IndexedMapOfShape ME;
+  TopExp::MapShapes(F, TopAbs_EDGE, ME);
+  if (!ME.Contains(E1) && ! ME.Contains(E2)) { // if E1 and E2 are new on F
+    TopoDS_Shape F1, F2;
+    const TopTools_ListOfShape& LF1 = AsDes->Ascendant( E1 );
+    F1 = F.IsSame( LF1.First() ) ? LF1.Last() : LF1.First();
+    const TopTools_ListOfShape& LF2 = AsDes->Ascendant( E2 );
+    F2 = F.IsSame( LF2.First() ) ? LF2.Last() : LF2.First();
+    if (!F.IsSame(F2) && !F.IsSame(F1) ) {
+      TopExp_Explorer exp(F2, TopAbs_EDGE);
+      TopExp::MapShapes(F1, TopAbs_EDGE, ME);
+      for (; exp.More(); exp.Next()) {
+        if (ME.Contains( exp.Current())) {
+          intersect = Standard_False;
+          break;
+        }
+      }
+    }
+  }
+
+  if (intersect) {
+    //------------------------------------------------------
+    // compute the points of Intersection in 2D
+    //-----------------------------------------------------
+    // i.e. fill LV1 and LV2
+    TopOpeBRep_EdgesIntersector EInter;
+    EInter.SetFaces(F,F);
+    Standard_Real TolDub = 1.e-7;
+    EInter.ForceTolerances(TolDub,TolDub);
+    Standard_Boolean reducesegments = Standard_False;
+    EInter.Perform (E1,E2,reducesegments);
+
+    Standard_Boolean rejectreducedsegmentpoints = Standard_False;
+    EInter.InitPoint(rejectreducedsegmentpoints);
+    for ( ; EInter.MorePoint(); EInter.NextPoint() )
+    {
+      const TopOpeBRep_Point2d& P2D = EInter.Point();
+      const gp_Pnt&    P    = P2D.Value();
+      TopoDS_Vertex    V    = BRepLib_MakeVertex(P);
+
+      //-------------------------
+      // control the point found.
+      //-------------------------
+      gp_Pnt P1 = CE1.Value(P2D.Parameter(1));
+      gp_Pnt P2 = CE2.Value(P2D.Parameter(2));
+      Standard_Real sqd1 = P1.SquareDistance(P);
+      Standard_Real sqd2 = P2.SquareDistance(P);
+      if (sqd1 > MilTol2 || sqd2 > MilTol2  )
+        continue;
+
+      // add a new vertex to the both edges
+      Standard_Real toler = Max( Tol, sqrt( Max( sqd1, sqd2 )));
+      Standard_Integer i;
+      for (i = 1; i <= 2; i++) {
+        Standard_Real U = P2D.Parameter(i);
+        V.Orientation(TopAbs_INTERNAL);
+        B.UpdateVertex( V,U,EI[i], toler);
+        TopAbs_Orientation OO = TopAbs_REVERSED;
+        if (WithOri) {
+          if (P2D.IsVertex(i))
+            OO = P2D.Vertex(i).Orientation();
+          else if (P2D.Transition(i).Before() == TopAbs_OUT) {
+            OO = TopAbs_FORWARD;
+          }
+          V.Orientation(OO);
+          if (i == 1) LV1.Append(V);
+          else        LV2.Append(V);
+        }
+      }
+    }
+  } // if (intersect)
+
+  //----------------------------------
+  // Test the extremities of the edges.
+  //----------------------------------
+  // add to LV* vertices for vertex-vertex closeness
+  Standard_Real U1,U2;
+  Standard_Real TolConf2, TolConf;
+  TopoDS_Vertex V1[2],V2[2];
+  TopExp::Vertices(E1,V1[0],V1[1]);
+  TopExp::Vertices(E2,V2[0],V2[1]);
+
+  Standard_Integer i,j,k;
+  for (j = 0; j < 2; j++) {
+    if (V1[j].IsNull()) continue;
+    for ( k = 0; k < 2; k++) {
+      if (V2[k].IsNull()) continue;
+      gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
+      gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
+      TolConf = BRep_Tool::Tolerance(V1[j]) + BRep_Tool::Tolerance(V2[k]);
+      TolConf = Max (Tol, TolConf);
+      TolConf2 = TolConf * TolConf;
+      if (!intersect)
+        TolConf2 *= 100;
+#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
+      Standard_Real SqDist = P1.Value(P2);
+#else
+      Standard_Real SqDist = P1.SquareDistance(P2);
+#endif
+      if (SqDist <= TolConf2) {
+        TopoDS_Vertex V = BRepLib_MakeVertex(P1);
+        V.Orientation(TopAbs_INTERNAL);
+        U1 = (j == 0) ? f[1] : l[1];
+        U2 = (k == 0) ? f[2] : l[2];
+        B.UpdateVertex(V,U1,E1,TolConf);
+        B.UpdateVertex(V,U2,E2,TolConf);
+        LV1.Prepend(V.Oriented(V1[j].Orientation()));
+        LV2.Prepend(V.Oriented(V2[k].Orientation()));
+      }
+    }
+  }
+
+  Standard_Boolean AffichPurge = Standard_False;
+
+  if ( LV1.IsEmpty()) return;
+
+  //----------------------------------
+  // Purge of all the vertices.
+  //----------------------------------
+  // remove one of close vertices
+  TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
+  gp_Pnt P1,P2;
+  Standard_Boolean Purge = Standard_True;
+
+  while (Purge) {
+    i = 1;
+    Purge = Standard_False;
+    for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
+         it1LV1.More();
+         it1LV1.Next(),it1LV2.Next()) {
+      j = 1;
+      it2LV1.Initialize(LV1);
+      while (j < i) {
+        const TopoDS_Vertex& VE1 = TopoDS::Vertex(it1LV1.Value());
+        const TopoDS_Vertex& VE2 = TopoDS::Vertex(it2LV1.Value());
+        Standard_Real Tol1 = BRep_Tool::Tolerance( VE1 );
+        Standard_Real Tol2 = BRep_Tool::Tolerance( VE2 );
+        P1 = BRep_Tool::Pnt( VE1 );
+        P2 = BRep_Tool::Pnt( VE2 );
+        if (P1.IsEqual(P2, Tol1 + Tol2)) {
+          LV1.Remove(it1LV1);
+          LV2.Remove(it1LV2);
+          Purge = Standard_True;
+          break;
+        }
+        j++;
+        it2LV1.Next();
+      }
+      if (Purge) break;
+      i++;
+    }
+  }
+
+  // care of new closed edges, they always intersect with seam at end
+  if (V1[0].IsSame( V1[1] ) && NewEdges.Contains(E1) )
+    treatClosed (E1, f[1], l[1], LV1, LV2);
+  if (V2[0].IsSame( V2[1] ) && NewEdges.Contains(E2) )
+    treatClosed (E2, f[2], l[2], LV2, LV1);
+
+  //----------------
+  // Stocking vertex
+  //----------------
+
+  for ( it1LV1.Initialize( LV1 ); it1LV1.More(); it1LV1.Next())
+    Partition_Inter2d::AddVonE (TopoDS::Vertex( it1LV1.Value()),
+                                E1, E2, AsDes, F);
+}
+
+//=======================================================================
+//function : CompletPart2d
+//purpose  : Computes the intersections between the edges stored
+//           is AsDes as descendants of <F> . Intersections is computed
+//           between two edges if one of them is bound in NewEdges.
+//=======================================================================
+
+void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)&   AsDes,
+                                       const TopoDS_Face&              F,
+                                       const TopTools_MapOfShape&      NewEdges)
+{
+
+#ifdef DEB
+  NbF2d++;
+  NbE2d = 0;
+#endif
+
+  //Do not intersect the edges of a face
+  TopTools_IndexedMapOfShape EdgesOfFace;
+  TopExp::MapShapes( F, TopAbs_EDGE , EdgesOfFace);
+
+  //-------------------------------------------------------------------
+  // compute the intersection2D on the faces touched by the intersection3D
+  //-------------------------------------------------------------------
+  TopTools_ListIteratorOfListOfShape it1LE ;
+  TopTools_ListIteratorOfListOfShape it2LE ;
+
+  //-----------------------------------------------
+  // Intersection edge-edge.
+  //-----------------------------------------------
+  const TopTools_ListOfShape&        LE = AsDes->Descendant(F);
+  TopoDS_Vertex                      V1,V2;
+  Standard_Integer                   j, i = 1;
+
+  TopoDS_Face FF = F;
+  FF.Orientation(TopAbs_FORWARD);
+
+  for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
+    const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());
+    j = 1;
+    it2LE.Initialize(LE);
+
+    while (j < i && it2LE.More()) {
+      const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
+      //----------------------------------------------------------
+      // Intersections of the new edges obtained by intersection
+      // between them and with the restrictions edges
+      //----------------------------------------------------------
+      if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
+           (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
+        EdgesPartition(FF,E1,E2,AsDes,NewEdges,Standard_True);
+      }
+      it2LE.Next();
+      j++;
+    }
+    i++;
+  }
+}
+
+//=======================================================================
+//function : GetTolerance
+//purpose  : Returns  tolerance  theV   must   have  atfer  its
+//           addition to theE with  theU parameter. theAsDes is
+//           used to find pcurves of theE
+//=======================================================================
+
+Standard_Real Partition_Inter2d::GetTolerance
+                         (const TopoDS_Vertex &         theV,
+                          const Standard_Real           theU,
+                          const TopoDS_Edge &           theE,
+                          const Handle(BRepAlgo_AsDes)& theAsDes)
+{
+  Standard_Real aTol = BRep_Tool::Tolerance( theV );
+  gp_Pnt aPnt = BRep_Tool::Pnt( theV );
+
+  // check point on 3D curve
+  Standard_Real f,l;
+  Handle(Geom_Curve) C = BRep_Tool::Curve( theE, f, l );
+  if (!C.IsNull())
+    aTol = Max ( aTol, aPnt.Distance( C->Value( theU )));
+
+  // check points on pcurves
+  const TopTools_ListOfShape& aFList = theAsDes->Ascendant( theE );
+  TopTools_ListIteratorOfListOfShape aFIt( aFList );
+  for (  ; aFIt.More(); aFIt.Next() )
+  {
+    const TopoDS_Face& F = TopoDS::Face( aFIt.Value() );
+    Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( theE, F, f, l );
+    if (!pcurve.IsNull())
+    {
+      gp_Pnt2d aPnt2d = pcurve->Value( theU );
+      TopLoc_Location L;
+      Handle(Geom_Surface) S = BRep_Tool::Surface( F, L );
+      gp_Pnt aPntOnS = S->Value( aPnt2d.X(), aPnt2d.Y() );
+      if (!L.IsIdentity())
+        aPntOnS.Transform( L.Transformation() );
+      aTol = Max ( aTol, aPnt.Distance( aPntOnS ));
+    }
+  }
+
+  return aTol;
+}
+
+#endif
diff --git a/contrib/Salome/Partition_Inter2d.hxx b/contrib/Salome/Partition_Inter2d.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..cfd4a9ac0aa4db3e23ff3669a99b9546c71138f4
--- /dev/null
+++ b/contrib/Salome/Partition_Inter2d.hxx
@@ -0,0 +1,110 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter2d.hxx
+//  Module : GEOM
+
+#ifndef _Partition_Inter2d_HeaderFile
+#define _Partition_Inter2d_HeaderFile
+
+#ifndef _Handle_BRepAlgo_AsDes_HeaderFile
+#include <Handle_BRepAlgo_AsDes.hxx>
+#endif
+#ifndef _Standard_Real_HeaderFile
+#include <Standard_Real.hxx>
+#endif
+#ifndef _Standard_Boolean_HeaderFile
+#include <Standard_Boolean.hxx>
+#endif
+class BRepAlgo_AsDes;
+class TopoDS_Face;
+class TopTools_MapOfShape;
+class TopoDS_Vertex;
+class TopTools_ListOfShape;
+class TopoDS_Edge;
+
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+
+class Partition_Inter2d  {
+
+public:
+
+   void* operator new(size_t,void* anAddress) 
+   {
+      return anAddress;
+   }
+   void* operator new(size_t size) 
+   { 
+      return Standard::Allocate(size); 
+   }
+   void  operator delete(void *anAddress) 
+   { 
+      if (anAddress) Standard::Free((Standard_Address&)anAddress); 
+   }
+   // Methods PUBLIC
+   // 
+   static  void CompletPart2d(const Handle(BRepAlgo_AsDes)& AsDes,const TopoDS_Face& F,const TopTools_MapOfShape& NewEdges) ;
+   static  TopoDS_Vertex FindEndVertex(const TopTools_ListOfShape& VertList,const Standard_Real f,const Standard_Real l,const TopoDS_Edge& E,Standard_Boolean& First,Standard_Real& DU) ;
+   static  TopoDS_Vertex AddVonE(const TopoDS_Vertex& V,const TopoDS_Edge& E1,const TopoDS_Edge& E2,const Handle(BRepAlgo_AsDes)& AsDes,const TopoDS_Face& F) ;
+   static  Standard_Real GetTolerance(const TopoDS_Vertex& theV,const Standard_Real theU,const TopoDS_Edge& theE,const Handle(BRepAlgo_AsDes)& theAsDes) ;
+
+
+
+
+protected:
+
+   // Methods PROTECTED
+   // 
+
+
+   // Fields PROTECTED
+   //
+
+
+private: 
+
+   // Methods PRIVATE
+   // 
+
+
+   // Fields PRIVATE
+   //
+
+
+};
+
+
+
+
+
+// other Inline functions and methods (like "C++: function call" methods)
+//
+
+
+#endif
diff --git a/contrib/Salome/Partition_Inter2d.ixx b/contrib/Salome/Partition_Inter2d.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..2587287415fe3661a78f06587fb4cf4f3decca80
--- /dev/null
+++ b/contrib/Salome/Partition_Inter2d.ixx
@@ -0,0 +1,37 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter2d.ixx
+//  Module : GEOM
+
+//using namespace std;
+#if !defined(HAVE_NO_OCC_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <climits>
+#include "Partition_Inter2d.jxx"
+
+ 
+
+
diff --git a/contrib/Salome/Partition_Inter2d.jxx b/contrib/Salome/Partition_Inter2d.jxx
new file mode 100644
index 0000000000000000000000000000000000000000..8c3ef7d49501d455279d52a5d6bd9f14ae2824b8
--- /dev/null
+++ b/contrib/Salome/Partition_Inter2d.jxx
@@ -0,0 +1,47 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter2d.jxx
+//  Module : GEOM
+
+#ifndef _BRepAlgo_AsDes_HeaderFile
+#include <BRepAlgo_AsDes.hxx>
+#endif
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _TopTools_MapOfShape_HeaderFile
+#include <TopTools_MapOfShape.hxx>
+#endif
+#ifndef _TopoDS_Vertex_HeaderFile
+#include <TopoDS_Vertex.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopoDS_Edge_HeaderFile
+#include <TopoDS_Edge.hxx>
+#endif
+#ifndef _Partition_Inter2d_HeaderFile
+#include "Partition_Inter2d.hxx"
+#endif
diff --git a/contrib/Salome/Partition_Inter3d.cxx b/contrib/Salome/Partition_Inter3d.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..db6da22ec812c08ef409a108c6ff53c555c4a972
--- /dev/null
+++ b/contrib/Salome/Partition_Inter3d.cxx
@@ -0,0 +1,950 @@
+#ifdef OCCGEOMETRY
+
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter3d.cxx
+//  Author : Benedicte MARTIN
+//  Module : GEOM
+//  $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Inter3d.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $
+
+//using namespace std;
+#if !defined(HAVE_NO_OCC_CONFIG_H)
+#include <config.h>
+#endif
+
+//using namespace std;
+#include <climits>
+
+#include "Partition_Inter2d.hxx"
+#include "Partition_Inter3d.ixx"
+//#include "utilities.h"
+
+#include <BRepAlgo_AsDes.hxx>
+#include <BRepAlgo_Image.hxx>
+#include <BRepLib.hxx>
+#include <BRepOffset_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <TopOpeBRepTool_BoxSort.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+
+#ifdef DEB
+#include <DBRep.hxx>
+#endif
+
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepTools.hxx>
+#include <Extrema_ExtPS.hxx>
+#include <Extrema_POnSurf.hxx>
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Precision.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TopOpeBRepBuild_Builder.hxx>
+#include <TopOpeBRepDS_BuildTool.hxx>
+#include <TopOpeBRepDS_CurveExplorer.hxx>
+#include <TopOpeBRepDS_HDataStructure.hxx>
+#include <TopOpeBRepDS_Interference.hxx>
+#include <TopOpeBRepDS_PointIterator.hxx>
+#include <TopOpeBRepDS_Transition.hxx>
+#include <TopOpeBRepTool_CurveTool.hxx>
+#include <TopOpeBRepTool_GeomTool.hxx>
+#include <TopOpeBRepTool_OutCurveType.hxx>
+#include <TopOpeBRep_DSFiller.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <stdio.h>
+
+//=======================================================================
+//function : Partition_Inter3d
+//purpose  : 
+//=======================================================================
+
+Partition_Inter3d::Partition_Inter3d()
+{
+}
+//=======================================================================
+//function : Partition_Inter3d
+//purpose  : 
+//=======================================================================
+
+Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes)
+  :myAsDes(AsDes)
+{
+  mySectionEdgesAD = new BRepAlgo_AsDes;
+}
+
+//=======================================================================
+//function : CompletPart3d
+//purpose  : FaceShapeMap is just to know the shape a face belongs to
+//=======================================================================
+
+void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,
+				      const TopTools_DataMapOfShapeShape& FaceShapeMap)
+{
+  if (myAsDes.IsNull())
+    myAsDes = new BRepAlgo_AsDes;
+  
+  TopTools_ListIteratorOfListOfShape it;
+
+  //---------------------------------------------------------------
+  // Construction of bounding boxes.
+  //---------------------------------------------------------------
+
+  BRep_Builder B;
+  TopoDS_Compound CompOS;
+  B.MakeCompound(CompOS);
+  for (it.Initialize(SetOfFaces1); it.More(); it.Next())
+    B.Add(CompOS, it.Value());
+    
+  TopOpeBRepTool_BoxSort BOS;
+  BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
+
+  for (it.Initialize(SetOfFaces1); it.More(); it.Next()) {
+    TopoDS_Face F1 = TopoDS::Face(it.Value());
+    
+    // avoid intersecting faces of one shape
+    TopoDS_Shape S1;
+    if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1);
+
+    // to filter faces sharing an edge
+    TopTools_IndexedMapOfShape EM;
+    TopExp::MapShapes( F1, TopAbs_EDGE, EM);
+    
+    TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
+    for (; itLI.More(); itLI.Next()) {
+      TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI));
+      if (F1.IsSame(F2) || IsDone(F1,F2))
+	continue;
+
+      TopoDS_Shape S2;
+      if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2);
+      if (!S1.IsNull() && S1.IsSame(S2))
+	continue; // descendants of one shape
+
+      TopExp_Explorer expE (F2, TopAbs_EDGE);
+      for ( ; expE.More(); expE.Next())
+	if (EM.Contains( expE.Current() ))
+	  break;
+      if (expE.More())
+      {
+        // faces have a common edge, check if they are a tool and a face
+        // generated by the tool in another shape; in that case they are
+        // to be intersected
+        TopLoc_Location L1, L2;
+        Handle(Geom_Surface) S1 = BRep_Tool::Surface( F1, L1 );
+        Handle(Geom_Surface) S2 = BRep_Tool::Surface( F2, L2 );
+        if ( S1 != S2 || L1 != L2 )
+          continue;
+      }
+
+      F1.Orientation(TopAbs_FORWARD);
+      F2.Orientation(TopAbs_FORWARD);
+      FacesPartition(F1,F2);	  
+    }
+
+    // mark as modified a face which has at least one new edge
+    if (!myAsDes->HasDescendant( F1 ))
+      continue;
+    TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 ));
+    for ( ; itE.More(); itE.Next()) {
+      if (myNewEdges.Contains( itE.Value())) {
+	myTouched.Add( F1 );
+	break;
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : PutInBounds
+//purpose  : 
+//=======================================================================
+
+static void PutInBounds (const TopoDS_Face&          F,
+			 const TopoDS_Edge&          E,
+			 Handle(Geom2d_Curve)&       C2d)
+{
+  Standard_Real   umin,umax,vmin,vmax;
+  Standard_Real   f,l;
+  BRep_Tool::Range(E,f,l);
+
+  TopLoc_Location L; // Recup S avec la location pour eviter la copie.
+  Handle (Geom_Surface) S   = BRep_Tool::Surface(F,L);
+
+  if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
+    S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
+  }
+  if (!S->IsUPeriodic() && !S->IsVPeriodic())
+    return;
+
+  BRepTools::UVBounds(F,umin,umax,vmin,vmax);
+
+  gp_Pnt2d Pf = C2d->Value(f);
+  gp_Pnt2d Pl = C2d->Value(l);
+  const Standard_Real Um = 0.34*f + 0.66*l;
+  gp_Pnt2d Pm = C2d->Value( Um );
+
+  // sometimes on shpere, pcurve is out of domain by V though S is
+  // UPeriodic, sometimes it is in domain but nontheless it has
+  // wrong position.
+  // Check pcurve position by 3D point
+  if (S->IsKind(STANDARD_TYPE( Geom_SphericalSurface )))
+  {
+    // get point on the surface
+    gp_Pnt Ps = S->Value( Pm.X(), Pm.Y() );
+    // get point on the edge
+    Handle(Geom_Curve) C = BRep_Tool::Curve( E, f, l );
+    gp_Pnt Pc = C->Value( Um );
+    // compare points
+    Standard_Real TolE = BRep_Tool::Tolerance( E );
+    if ( Pc.SquareDistance( Ps ) * 0.95 < TolE * TolE )
+      return; // OK
+
+    // find good UV for Pc: project Pc on S
+    GeomAdaptor_Surface  SA (S);
+    Extrema_ExtPS anExtPS (Pc, SA,
+                           SA.UResolution( TolE ), SA.VResolution( TolE ));
+    if (anExtPS.IsDone())
+    {
+      Standard_Integer i, nbExt = anExtPS.NbExt();
+      Extrema_POnSurf aPOnSurf;
+      for (i = 1; i <= nbExt; ++i )
+        if (anExtPS.SquareDistance( i ) <= TolE) {
+          aPOnSurf = anExtPS.Point( i );
+          break;
+        }
+      if (i <= nbExt) {
+        // a point found
+        Standard_Real u, v;
+        aPOnSurf.Parameter( u, v );
+        gp_Pnt2d aGoodPm ( u, v );
+        C2d->Translate( Pm , aGoodPm );
+      }
+    }
+  }
+
+  //---------------
+  // Recadre en U.
+  //---------------
+  if (S->IsUPeriodic()) {
+    Standard_Real period  = S->UPeriod();
+    Standard_Real eps     = period*1.e-6;
+    Standard_Real minC    = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
+    Standard_Real maxC    = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
+    Standard_Real du = 0.;
+    if (minC< umin - eps) {
+      du = (int((umin - minC)/period) + 1)*period;
+    }
+    if (minC > umax + eps) {
+      du = -(int((minC - umax)/period) + 1)*period;
+    }
+    if (du != 0) {
+      gp_Vec2d T1(du,0.);
+      C2d->Translate(T1);
+      minC += du; maxC += du;
+    }
+    // Ajuste au mieux la courbe dans le domaine.
+    if (maxC > umax +100*eps) {
+      Standard_Real d1 = maxC - umax;
+      Standard_Real d2 = umin - minC + period;
+      if (d2 < d1) du =-period;
+      if ( du != 0.) {
+	gp_Vec2d T2(du,0.);
+	C2d->Translate(T2);
+      }
+    }
+  }
+  //------------------
+  // Recadre en V.
+  //------------------
+  if (S->IsVPeriodic()) {
+    Standard_Real period  = S->VPeriod();
+    Standard_Real eps     = period*1.e-6;
+    Standard_Real minC    = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
+    Standard_Real maxC    = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
+    Standard_Real dv = 0.;
+    if (minC< vmin - eps) {
+      dv = (int((vmin - minC)/period) + 1)*period;
+    }
+    if (minC > vmax + eps) {
+      dv = -(int((minC - vmax)/period) + 1)*period;
+    }
+    if (dv != 0) {
+      gp_Vec2d T1(0.,dv);
+      C2d->Translate(T1);
+      minC += dv; maxC += dv;
+    }
+    // Ajuste au mieux la courbe dans le domaine.
+    if (maxC > vmax +100*eps) {
+      Standard_Real d1 = maxC - vmax;
+      Standard_Real d2 = vmin - minC + period;
+      if (d2 < d1) dv =-period;
+      if ( dv != 0.) {
+	gp_Vec2d T2(0.,dv);
+	C2d->Translate(T2);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : Inter3D
+//purpose  : 
+//=======================================================================
+
+void Partition_Inter3d::Inter3D(const TopoDS_Face& F1,
+				const TopoDS_Face& F2,
+				TopTools_ListOfShape& L)
+{
+  BRep_Builder B;
+  
+  // fill the data Structure
+  Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure();
+  TopOpeBRep_DSFiller DSFiller;
+  DSFiller.Insert(F1,F2,DatStr);
+
+  // define the GeomTool used by the DSFiller :
+  // compute BSpline of degree 1 on intersection curves.
+  Standard_Real tol3dAPPROX = 1e-7;
+  Standard_Real tol2dAPPROX = 1e-7;
+  TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX);  
+  GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX);
+  TopOpeBRepDS_BuildTool  BT(GT2);
+
+  // Perform Section
+  TopOpeBRepBuild_Builder TopB(BT);
+  TopB.Perform(DatStr);
+
+  // ===============
+  // Store new edges
+  // ===============
+  
+  L.Clear();
+  TopOpeBRepDS_CurveExplorer cex(DatStr->DS());
+  for (; cex.More(); cex.Next()) {
+    const TopOpeBRepDS_Curve& CDS = cex.Curve();
+    Standard_Integer ic = cex.Index();
+    Handle(Geom2d_Curve) pc1 = CDS.Curve1();
+    Handle(Geom2d_Curve) pc2 = CDS.Curve2();
+    
+    TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic);
+    while (itLE.More()) {
+      TopoDS_Edge E = TopoDS::Edge(itLE.Value());
+      
+      PutInBounds (F1,E,pc1);
+      PutInBounds (F2,E,pc2);
+      
+      B.UpdateEdge (E,pc1,F1,0.);
+      B.UpdateEdge (E,pc2,F2,0.);
+      
+      L.Append (E);
+      
+      itLE.Next();
+      if (itLE.More()) {
+	pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy());
+	pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy());
+      }
+    }
+  }
+
+  // ========================
+  // store same domain faces 
+  // ========================
+
+
+  if ( DatStr->HasSameDomain( F1 ))
+  {
+    TopTools_ListOfShape emptyList;
+    if (!mySameDomainFM.IsBound(F1))
+      mySameDomainFM.Bind(F1,emptyList);
+    if (!mySameDomainFM.IsBound(F2))
+      mySameDomainFM.Bind(F2,emptyList);
+    mySameDomainFM(F1).Append(F2);
+    mySameDomainFM(F2).Append(F1);
+  }
+
+  // ====================
+  // Store section edges
+  // ====================
+
+  const TopOpeBRepDS_DataStructure& DS = DatStr->DS();
+  Standard_Integer j,i,nse = DS.NbSectionEdges();
+  if (nse == 0) return;
+
+    
+  TopoDS_Vertex V, sdeV1, sdeV2;
+  TopTools_MapOfShape MV;
+  TopTools_ListOfShape LSE; // list of section edges
+  TopoDS_Face dummyF;
+  
+  for (i = 1; i <= nse; i++)
+  {
+    const TopoDS_Edge & se = DS.SectionEdge(i);
+    if (! TopB.IsSplit(se,TopAbs_ON))
+      continue;
+    LSE.Append( se );
+
+    // add vertices where section edges interferes with other
+    // edges as its descendant in myAsDes
+    
+    TopoDS_Edge sde, oe; // same domain, other edge
+    if (DatStr->HasSameDomain(se)) {
+      sde = TopoDS::Edge( DatStr->SameDomain(se).Value() );
+      TopExp::Vertices( sde, sdeV1, sdeV2);
+    }
+    TColStd_MapOfInteger MIV; // indices of added edges
+    TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se ));
+    itP.SupportKind( TopOpeBRepDS_EDGE );
+    // loop on intersections of se
+    for (; itP.More(); itP.Next()) {
+      oe = TopoDS::Edge( DS.Shape( itP.Support()));
+      if (itP.IsVertex()) {
+        // there is a vertex at intersection
+	if ( !MIV.Add( itP.Current() ))
+	  continue;
+	V = TopoDS::Vertex( DS.Shape( itP.Current()));
+	if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) )
+	  oe = sde;
+	V = ReplaceSameDomainV( V , oe );
+	V.Orientation( TopAbs_INTERNAL);
+	B.UpdateVertex( V, itP.Parameter(), se, 0.); // AddVonE() sets real U
+      }
+      else {
+        // create a new vertex at the intersection point
+	const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current());
+	V = BRepLib_MakeVertex( DSP.Point() );
+	V.Orientation( TopAbs_INTERNAL);
+	B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance());
+	// make V be on the other edge
+	TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe ));
+	for (; itOP.More(); itOP.Next()) {
+	  const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current());
+	  if ( DSP.IsEqual (ODSP)) {
+	    B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance());
+	    break;
+	  }
+	}
+      }
+      // add V on the both intersecting edges
+      TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes,dummyF);
+      if (!addedV.IsSame( V ))
+	mySameDomainVM.Bind (V, addedV); // equal vertex is already there
+
+      MV.Add( addedV ); // to ease storage of vertices of ON splits
+    }
+  }
+
+  // add section edge to the face it intersects and find
+  // splits ON that do not have same domain pair
+  
+  TopB.SplitSectionEdges(); // let TopB find ON splits
+
+  TopTools_MapOfShape SPM; // map of ON splits
+  TopTools_IndexedMapOfShape ME[2];
+  TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]);
+  TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]);
+
+  TopTools_ListIteratorOfListOfShape itSP, itLSE (LSE);
+  while ( itLSE.More() ) {
+
+    TopoDS_Edge se = TopoDS::Edge( itLSE.Value() );
+
+    // move itLSE to the next se
+    Standard_Integer ancRank = DS.AncestorRank(se);
+    if (ME[ancRank-1].Contains( se ))
+    {
+      LSE.Remove( itLSE ); // se is an edge of face it intersects
+      continue;
+    }
+    else
+    {
+      itLSE.Next();
+    }
+
+    const TopoDS_Face& F = (ancRank == 1) ? F2 : F1;
+
+    // add se to face but dont add twice
+    TopTools_ListIteratorOfListOfShape itE( myAsDes->Descendant( F ));
+    if (myAsDes->HasDescendant( F )) {
+      for ( ; itE.More(); itE.Next())
+	if (se.IsSame( itE.Value() ))
+	  break;
+    }
+    if (!itE.More())
+    {
+      myAsDes->Add( F, se );
+
+      // check se pcurve on F
+      Standard_Real tol, f,l, umin=1e100, umax=-1e100;
+      Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l);
+      if (pc.IsNull()) {
+	itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
+	for ( ; itSP.More(); itSP.Next()) {
+	  const TopoDS_Edge& E = TopoDS::Edge ( itSP.Value());
+	  BRep_Tool::Range(E, f, l);
+	  umin = Min( umin, f);
+	  umax = Max( umax, l);
+	}
+	Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l);
+	if (umin < umax) // sometimes umin == umax for closed edge
+	  C3d = new Geom_TrimmedCurve( C3d, umin, umax);
+	pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
+	if (pc.IsNull()) {
+	  //MESSAGE (" CANT BUILD PCURVE ");
+	}
+	B.UpdateEdge( se, pc, F, tol);
+      }
+    }
+
+    // to detect splits that do not have same domain pair
+    // ie which split a face into parts and not pass by its boundary
+    itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
+    for ( ; itSP.More(); itSP.Next()) {
+      const TopoDS_Shape& SP = itSP.Value();
+      if (!SPM.Add( SP ))
+	SPM.Remove( SP );
+    }
+  }
+
+  // store vertices of ON splits and bind section edges to faces
+  
+  for (itLSE.Initialize (LSE); itLSE.More(); itLSE.Next())
+  {
+    const TopoDS_Shape& se = itLSE.Value();
+
+    Standard_Integer ancRank = DS.AncestorRank(se);
+    TopoDS_Face F = (ancRank == 1) ? F2 : F1;
+
+    // add vertices of ON splits which have no same domain pair
+    Standard_Boolean added = Standard_False;
+    itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
+    for ( ; itSP.More(); itSP.Next())
+    {
+      if (!SPM.Contains( itSP.Value() ))
+	continue;
+      
+      const TopoDS_Edge& S = TopoDS::Edge ( itSP.Value());
+
+      added = Standard_True;
+      mySectionEdgesAD->Add( F, se );
+      
+      TopoDS_Vertex VS[2];
+      TopExp::Vertices (S, VS[0], VS[1]);
+      for (j=0; j<2; ++j)
+      {
+	if (mySameDomainVM.IsBound( VS[j] ))
+	  VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] ));
+	if ( !MV.Contains( VS[j] )) {
+	  // find equal vertex on se - point interference
+	  gp_Pnt P1 = BRep_Tool::Pnt( VS[j] );
+	  TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) );
+	  for (; itV.More(); itV.Next()) {
+	    V = TopoDS::Vertex( itV.Value() );
+            if ( V.IsSame( VS[j] ))
+              break;
+	    gp_Pnt P2 = BRep_Tool::Pnt( V );
+	    if (P1.IsEqual( P2, Precision::Confusion())) {
+	      mySameDomainVM.Bind (VS[j], V);
+	      VS[j] = V;
+	      break;
+	    }
+	  }
+	  if (!itV.More())  // no interferences with edges
+	    myAsDes->Add( se, VS[j]);
+	}
+
+        // add ends of ON splits to F in order to detect later
+        // if a split is on face in IsSplitOn()
+	mySectionEdgesAD->Add( F, VS[j]);
+      }
+      // in the descendants of F, first go ends of an ON split and
+      // then a split itself
+      mySectionEdgesAD->Add( F, S );
+    }
+    if (!added)
+      mySectionEdgesAD->Add( F, se );
+    
+    myNewEdges.Add( se );
+  }
+}
+
+//=======================================================================
+//function : FacesPartition
+//purpose  : 
+//=======================================================================
+
+void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1,
+				       const TopoDS_Face& F2)
+     //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/)
+{
+  TopTools_ListOfShape LInt;
+
+  Inter3D (F1,F2,LInt);
+  
+  StorePart3d (F1,F2,LInt);
+}
+
+//=======================================================================
+//function : SetDone
+//purpose  : 
+//=======================================================================
+
+void Partition_Inter3d::SetDone(const TopoDS_Face& F1, 
+				const TopoDS_Face& F2)
+{
+  if (!myDone.IsBound(F1)) {
+    TopTools_ListOfShape emptyList;
+    myDone.Bind(F1,emptyList);
+  }
+  myDone(F1).Append(F2);
+  if (!myDone.IsBound(F2)) {
+    TopTools_ListOfShape emptyList;
+    myDone.Bind(F2,emptyList);
+  }
+  myDone(F2).Append(F1);
+}
+
+//=======================================================================
+//function : IsDone
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1, 
+					   const TopoDS_Face& F2) 
+
+  const 
+{
+  if (myDone.IsBound(F1)) {
+    TopTools_ListIteratorOfListOfShape it (myDone(F1));
+    for (; it.More(); it.Next()) {
+      if (it.Value().IsSame(F2)) return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : StorePart3d
+//purpose  : 
+//=======================================================================
+
+void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1, 
+				    const TopoDS_Face& F2, 
+				    const TopTools_ListOfShape& LInt)
+{
+  if (!LInt.IsEmpty()) {
+    myAsDes->Add( F1,LInt);
+    myAsDes->Add( F2,LInt);
+
+    TopTools_ListIteratorOfListOfShape it(LInt);
+    for (; it.More(); it.Next()) {
+
+      TopoDS_Edge E = TopoDS::Edge(it.Value());
+
+      BRep_Builder B;
+      B.SameParameter(E,Standard_False);
+      BRepLib::SameParameter(E,1.0e-7);
+      
+      myNewEdges.Add(E);
+    }
+  }
+  SetDone(F1,F2);
+}
+
+//=======================================================================
+//function : TouchedFaces
+//purpose  : 
+//=======================================================================
+
+TopTools_MapOfShape& Partition_Inter3d::TouchedFaces()
+{
+  return myTouched;
+}
+
+//=======================================================================
+//function : AsDes
+//purpose  : 
+//=======================================================================
+
+Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const 
+{
+  return myAsDes;
+}
+
+//=======================================================================
+//function : NewEdges
+//purpose  : 
+//=======================================================================
+
+TopTools_MapOfShape& Partition_Inter3d::NewEdges() 
+{
+  return myNewEdges;
+}
+
+//=======================================================================
+//function : Affiche
+//purpose  : 
+//=======================================================================
+
+void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const
+{
+#ifdef DEB
+  char PSection[1024];
+  char *section=PSection;
+  Standard_Integer i = 0;
+  Standard_Real j=1;
+  TopTools_ListOfShape aList;
+  TopTools_ListIteratorOfListOfShape it;
+  for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
+    const TopoDS_Shape& OS = it.Value();
+    aList=myAsDes->Descendant(OS);
+    MESSAGE ( " the number of items stored in the list " << j << " :  " << aList.Extent() )
+    j++;
+    TopTools_ListIteratorOfListOfShape itaList;
+    for (itaList.Initialize(aList); itaList.More(); itaList.Next()) {
+      const TopoDS_Shape& SS = itaList.Value();
+      i++;
+      sprintf(PSection,"section_%d",i);
+      DBRep::Set(section,SS);  
+    }
+  }
+#endif
+}
+
+//=======================================================================
+//function : SameDomain
+//purpose  : 
+//=======================================================================
+
+const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const
+{
+  if (mySameDomainFM.IsBound( F ))
+    return mySameDomainFM (F);
+
+  static TopTools_ListOfShape emptyList;
+  return emptyList;
+}
+
+//=======================================================================
+//function : HasSameDomainF
+//purpose  : Return true if F has same domain faces
+//=======================================================================
+
+Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const
+{
+  return mySameDomainFM.IsBound( F );
+}
+
+//=======================================================================
+//function : IsSameDomain
+//purpose  : Return true if F1 and F2 are same domain faces
+//=======================================================================
+
+Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1,
+						 const TopoDS_Shape& F2) const
+{
+  if (mySameDomainFM.IsBound( F1 )) {
+    TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 ));
+    for (; it.More(); it.Next()) 
+      if (F2.IsSame( it.Value()))
+	return Standard_True;
+  }
+  return F1.IsSame( F2 );
+}
+
+//=======================================================================
+//function : ReplaceSameDomainV
+//purpose  : return same domain vertex of  V if it was replaced
+//           and make this vertex to be on E too, else return V
+//=======================================================================
+
+TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V,
+						    const TopoDS_Edge&   E) const
+{
+  TopoDS_Vertex SDV = V;
+  if (mySameDomainVM.IsBound( V )) {
+
+    TopoDS_Vertex V1,V2;
+    TopExp::Vertices(E,V1,V2);
+    Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1);
+
+    SDV = TopoDS::Vertex( mySameDomainVM(V) );
+    Standard_Real tol = BRep_Tool::Tolerance( V );
+    BRep_Builder B;
+    SDV.Orientation( V.Orientation());
+
+    if (isClosed) {
+      Standard_Real f, l;
+      BRep_Tool::Range (E, f, l);
+      Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f );
+      B.UpdateVertex(SDV, (isFirst ? f : l), E, tol);
+      SDV.Reverse();
+      B.UpdateVertex(SDV, (isFirst ? l : f), E, tol);
+    }
+    else
+      B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol);
+      
+  }
+  return SDV;
+}
+
+//=======================================================================
+//function : SectionEdgesAD
+//purpose  : 
+//=======================================================================
+
+Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const
+{
+  return mySectionEdgesAD;
+}
+
+//=======================================================================
+//function : IsSectionEdge
+//purpose  : return True if  E  is  an  edge  of  a face and it
+//           intersects an other face
+//=======================================================================
+
+Standard_Boolean
+  Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const
+{
+  return mySectionEdgesAD->HasAscendant(E);
+}
+
+//=======================================================================
+//function : HasSectionEdge
+//purpose  : return True if an  edge  of  F intersects an other
+//           face or F is intersected by edge of an other face
+//=======================================================================
+
+Standard_Boolean
+  Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const
+{
+  return mySectionEdgesAD->HasDescendant(F);
+}
+
+//=======================================================================
+//function : IsSplitOn
+//purpose  : return True if NewE is split of OldE on F
+//=======================================================================
+
+Standard_Boolean
+  Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE,
+			       const TopoDS_Edge& OldE,
+			       const TopoDS_Face& F) const
+{
+  if (! mySectionEdgesAD->HasDescendant(F))
+    return Standard_False;
+
+  TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) );
+  for ( ; itE.More(); itE.Next()) {
+    if ( itE.Value().ShapeType() != TopAbs_EDGE ||
+	! OldE.IsSame ( itE.Value() ))
+      continue;
+    // an edge encountered, its vertices and a split come next
+    itE.Next();
+    if (!itE.More()) break;
+    const TopoDS_Shape& V3 = itE.Value();
+    if (V3.ShapeType() != TopAbs_VERTEX) continue;
+    itE.Next();
+    if (!itE.More()) break;
+    const TopoDS_Shape& V4 = itE.Value();
+    if (V4.ShapeType() != TopAbs_VERTEX) continue;
+
+    TopoDS_Vertex V1, V2;
+    TopExp::Vertices( OldE, V1, V2);
+    
+    if ( V1.IsSame(V2) &&
+	(V1.IsSame(V3) || V1.IsSame(V4)) ) {
+      // closed old edge; use the split for the test 
+      itE.Next();
+      if (!itE.More()) break;
+      const TopoDS_Edge& split = TopoDS::Edge( itE.Value() );
+      // check distance at middle point of NewE
+      Standard_Real f1,l1, f2,l2;
+      Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1);
+      if (!PC1.IsNull()) {
+	Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2);
+	gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) );
+	Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1);
+	if (proj.NbPoints() &&
+	    proj.LowerDistance() <= Precision::Confusion())
+	  return Standard_True;
+      }
+      else {
+        Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1);
+	Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE  ,f2,l2);
+	gp_Pnt P = C2->Value( 0.5*(f2+l2) );
+	GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1);
+	if (proj.NbPoints() &&
+	    proj.LowerDistance() <= Precision::Confusion())
+	  return Standard_True;
+      }
+    }
+    else {
+      Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE);
+      Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE);
+
+      Standard_Real f,l, u;
+      BRep_Tool::Range( NewE, f,l);
+      u = 0.5*(f+l);
+      f = Min(u3,u4);
+      l = Max(u3,u4);
+
+      if (u <= l && u >= f)
+        return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : SectionEdgeFaces
+//purpose  : return faces cut by section edge
+//=======================================================================
+
+const TopTools_ListOfShape&
+  Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const
+{
+  return mySectionEdgesAD->Ascendant( SecE );
+}
+
+#endif
diff --git a/contrib/Salome/Partition_Inter3d.hxx b/contrib/Salome/Partition_Inter3d.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..d8be2c59837514d5a5dd8cd0b5846ab8513a4654
--- /dev/null
+++ b/contrib/Salome/Partition_Inter3d.hxx
@@ -0,0 +1,143 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter3d.hxx
+//  Module : GEOM
+
+#ifndef _Partition_Inter3d_HeaderFile
+#define _Partition_Inter3d_HeaderFile
+
+#ifndef _Handle_BRepAlgo_AsDes_HeaderFile
+#include <Handle_BRepAlgo_AsDes.hxx>
+#endif
+#ifndef _TopTools_DataMapOfShapeListOfShape_HeaderFile
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#endif
+#ifndef _TopTools_MapOfShape_HeaderFile
+#include <TopTools_MapOfShape.hxx>
+#endif
+#ifndef _TopTools_DataMapOfShapeShape_HeaderFile
+#include <TopTools_DataMapOfShapeShape.hxx>
+#endif
+#ifndef _Standard_Boolean_HeaderFile
+#include <Standard_Boolean.hxx>
+#endif
+class BRepAlgo_AsDes;
+class TopTools_ListOfShape;
+class TopTools_DataMapOfShapeShape;
+class TopoDS_Face;
+class TopTools_MapOfShape;
+class TopoDS_Shape;
+class TopoDS_Vertex;
+class TopoDS_Edge;
+
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+
+class Partition_Inter3d  {
+
+public:
+
+   void* operator new(size_t,void* anAddress) 
+   {
+      return anAddress;
+   }
+   void* operator new(size_t size) 
+   { 
+      return Standard::Allocate(size); 
+   }
+   void  operator delete(void *anAddress) 
+   { 
+      if (anAddress) Standard::Free((Standard_Address&)anAddress); 
+   }
+   // Methods PUBLIC
+   // 
+   Partition_Inter3d();
+   Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes);
+   void CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,const TopTools_DataMapOfShapeShape& FaceShapeMap) ;
+   void FacesPartition(const TopoDS_Face& F1,const TopoDS_Face& F2) ;
+   Standard_Boolean IsDone(const TopoDS_Face& F1,const TopoDS_Face& F2) const;
+   TopTools_MapOfShape& TouchedFaces() ;
+   Handle_BRepAlgo_AsDes AsDes() const;
+   TopTools_MapOfShape& NewEdges() ;
+   Standard_Boolean HasSameDomainF(const TopoDS_Shape& F) const;
+   Standard_Boolean IsSameDomainF(const TopoDS_Shape& F1,const TopoDS_Shape& F2) const;
+   const TopTools_ListOfShape& SameDomain(const TopoDS_Face& F) const;
+   TopoDS_Vertex ReplaceSameDomainV(const TopoDS_Vertex& V,const TopoDS_Edge& E) const;
+   Handle_BRepAlgo_AsDes SectionEdgesAD() const;
+   Standard_Boolean IsSectionEdge(const TopoDS_Edge& E) const;
+   Standard_Boolean HasSectionEdge(const TopoDS_Face& F) const;
+   Standard_Boolean IsSplitOn(const TopoDS_Edge& NewE,const TopoDS_Edge& OldE,const TopoDS_Face& F) const;
+   const TopTools_ListOfShape& SectionEdgeFaces(const TopoDS_Edge& SecE) const;
+
+
+
+
+
+protected:
+
+   // Methods PROTECTED
+   // 
+
+
+   // Fields PROTECTED
+   //
+
+
+private: 
+
+   // Methods PRIVATE
+   // 
+   void Inter3D(const TopoDS_Face& F1,const TopoDS_Face& F2,TopTools_ListOfShape& LInt) ;
+   void StorePart3d(const TopoDS_Face& F1,const TopoDS_Face& F2,const TopTools_ListOfShape& LInt1) ;
+   void SetDone(const TopoDS_Face& F1,const TopoDS_Face& F2) ;
+   void Affiche(const TopTools_ListOfShape& SetOfFaces) const;
+
+
+   // Fields PRIVATE
+   //
+   Handle_BRepAlgo_AsDes myAsDes;
+   TopTools_DataMapOfShapeListOfShape myDone;
+   TopTools_MapOfShape myTouched;
+   TopTools_MapOfShape myNewEdges;
+   Handle_BRepAlgo_AsDes mySectionEdgesAD;
+   TopTools_DataMapOfShapeListOfShape mySameDomainFM;
+   TopTools_DataMapOfShapeShape mySameDomainVM;
+
+
+};
+
+
+
+
+
+// other Inline functions and methods (like "C++: function call" methods)
+//
+
+
+#endif
diff --git a/contrib/Salome/Partition_Inter3d.ixx b/contrib/Salome/Partition_Inter3d.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..0775cc99c9259f7e8b85677f916546c9fd6aca20
--- /dev/null
+++ b/contrib/Salome/Partition_Inter3d.ixx
@@ -0,0 +1,31 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter3d.ixx
+//  Module : GEOM
+
+#include "Partition_Inter3d.jxx"
+
+ 
+
+
diff --git a/contrib/Salome/Partition_Inter3d.jxx b/contrib/Salome/Partition_Inter3d.jxx
new file mode 100644
index 0000000000000000000000000000000000000000..5804ba81e831c0a636bd6a8965e01f4011455ed6
--- /dev/null
+++ b/contrib/Salome/Partition_Inter3d.jxx
@@ -0,0 +1,53 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Inter3d.jxx
+//  Module : GEOM
+
+#ifndef _BRepAlgo_AsDes_HeaderFile
+#include <BRepAlgo_AsDes.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_DataMapOfShapeShape_HeaderFile
+#include <TopTools_DataMapOfShapeShape.hxx>
+#endif
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _TopTools_MapOfShape_HeaderFile
+#include <TopTools_MapOfShape.hxx>
+#endif
+#ifndef _TopoDS_Shape_HeaderFile
+#include <TopoDS_Shape.hxx>
+#endif
+#ifndef _TopoDS_Vertex_HeaderFile
+#include <TopoDS_Vertex.hxx>
+#endif
+#ifndef _TopoDS_Edge_HeaderFile
+#include <TopoDS_Edge.hxx>
+#endif
+#ifndef _Partition_Inter3d_HeaderFile
+#include "Partition_Inter3d.hxx"
+#endif
diff --git a/contrib/Salome/Partition_Loop.cxx b/contrib/Salome/Partition_Loop.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d293060e82061d969c9d44671f510174227c6fb3
--- /dev/null
+++ b/contrib/Salome/Partition_Loop.cxx
@@ -0,0 +1,478 @@
+#ifdef OCCGEOMETRY
+
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Loop.cxx
+//  Author : Benedicte MARTIN
+//  Module : GEOM
+//  $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $
+
+//using namespace std;
+#if !defined(HAVE_NO_OCC_CONFIG_H)
+#include <config.h>
+#endif
+
+//using namespace std;
+#include <cstdio>
+#include <climits>
+
+#include "Partition_Loop.ixx"
+
+//#include "utilities.h"
+
+#include <BRep_Builder.hxx>
+#include <BRepAlgo_FaceRestrictor.hxx>
+#include <BRep_Tool.hxx>
+
+#include <Geom2d_Curve.hxx>
+#include <Geom_Surface.hxx>
+
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include <Precision.hxx>
+#include <BRep_TVertex.hxx>
+#include <BRep_TEdge.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+static char* name = new char[100];
+static int nbe = 0;
+
+//=======================================================================
+//function : Partition_Loop
+//purpose  : 
+//=======================================================================
+Partition_Loop::Partition_Loop()
+{
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void Partition_Loop::Init(const TopoDS_Face& F)
+{
+  myConstEdges.Clear(); 
+  myNewWires  .Clear();
+  myNewFaces  .Clear();
+  myFace = F;
+}
+
+//=======================================================================
+//function : AddConstEdge
+//purpose  : 
+//=======================================================================
+void Partition_Loop::AddConstEdge (const TopoDS_Edge& E)
+{
+  myConstEdges.Append(E);
+}
+
+
+//=======================================================================
+//function : FindDelta
+//purpose  : 
+//=======================================================================
+static Standard_Real FindDelta(TopTools_ListOfShape& LE,
+			       const TopoDS_Face& F)
+{
+  Standard_Real dist, f, l;
+  Standard_Real d = Precision::Infinite();
+  TopTools_ListIteratorOfListOfShape itl;
+
+  for ( itl.Initialize(LE); itl.More(); itl.Next()) {
+    const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+    Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
+    gp_Pnt2d p = C->Value(f);
+    gp_Pnt2d pp = C->Value(l);
+    Standard_Real d1 = p.Distance(pp);
+    if (d1<d) { d=d1;}
+  }
+  dist = d ;
+  return dist;
+}
+
+//=======================================================================
+//function : SelectEdge
+//purpose  : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
+//           <NE> Is erased  of the list. If <CE> is too in the list <LE> 
+//			 with the same orientation, it's erased of the list 
+//=======================================================================
+static Standard_Boolean  SelectEdge(const TopoDS_Face&    F,
+				    const TopoDS_Edge&    CE,
+				    const TopoDS_Vertex&  CV,
+				    TopoDS_Edge&          NE,
+				    TopTools_ListOfShape& LE)
+{
+  TopTools_ListIteratorOfListOfShape itl;
+  NE.Nullify();
+  for ( itl.Initialize(LE); itl.More(); itl.Next()) {
+    if (itl.Value().IsEqual(CE)) {
+      LE.Remove(itl);
+      break;
+    }
+  }
+
+  if (LE.Extent() > 1) {
+    //--------------------------------------------------------------
+    // Several possible edges.   
+    // - Test the edges differents of CE 
+    //--------------------------------------------------------------
+    Standard_Real   cf, cl, f, l;
+    TopoDS_Face FForward = F;
+    Handle(Geom2d_Curve) Cc, C;
+    FForward.Orientation(TopAbs_FORWARD);
+			
+    Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
+    Standard_Real dist,distmin  = 100*BRep_Tool::Tolerance(CV);
+    Standard_Real uc,u;
+    if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
+    else                                     uc = cf;
+
+    gp_Pnt2d P2,PV = Cc->Value(uc); 
+
+    Standard_Real delta = FindDelta(LE,FForward);
+
+    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+      if (!E.IsSame(CE)) {
+	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
+	if (E.Orientation () == TopAbs_FORWARD) u = f;
+	else                                    u = l;
+	P2 = C->Value(u);
+	dist = PV.Distance(P2);
+	if (dist <= distmin){
+	  distmin = dist;
+	}
+				
+      }
+    }
+
+    Standard_Real anglemax = - PI;
+    TopoDS_Edge   SelectedEdge;	
+    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+      if (!E.IsSame(CE)) {
+	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
+	if (E.Orientation () == TopAbs_FORWARD) u = f;
+	else                                    u = l;
+	P2 = C->Value(u);
+	dist = PV.Distance(P2);
+	if (dist <= distmin + (1./3)*delta){ 
+	  gp_Pnt2d PC, P;
+	  gp_Vec2d CTg1, CTg2, Tg1, Tg2;
+	  Cc->D2(uc, PC, CTg1, CTg2);
+	  C->D2(u, P, Tg1, Tg2);
+
+	  Standard_Real angle;
+
+	  if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
+	    angle = CTg1.Angle(Tg1.Reversed());
+	  }
+	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
+	    angle = (CTg1.Reversed()).Angle(Tg1);
+	  }
+	  else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
+	    angle = CTg1.Angle(Tg1);
+	  }
+	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
+	    angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
+	  }
+	  if (angle >= anglemax) {
+	    anglemax = angle ;
+	    SelectedEdge = E;	
+	  }
+	}
+      }
+    }
+    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+      if (E.IsEqual(SelectedEdge)) {
+	NE = TopoDS::Edge(E);
+	LE.Remove(itl);
+	break;
+      }
+    }					
+  }
+  else if (LE.Extent() == 1) {
+    NE = TopoDS::Edge(LE.First());
+    LE.RemoveFirst();
+  }
+  else {
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : SamePnt2d
+//purpose  : 
+//=======================================================================
+static Standard_Boolean  SamePnt2d(TopoDS_Vertex  V,
+				   TopoDS_Edge&   E1,
+				   TopoDS_Edge&   E2,
+				   TopoDS_Face&   F)
+{
+  Standard_Real   f1,f2,l1,l2;
+  gp_Pnt2d        P1,P2;
+  TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
+  TopoDS_Face FF = TopoDS::Face(aLocalF);
+  Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);  
+  Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);  
+  if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
+  else                                     P1 = C1->Value(l1);
+  
+  if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
+  else                                     P2 = C2->Value(f2);
+  Standard_Real Tol  = 100*BRep_Tool::Tolerance(V);
+  Standard_Real Dist = P1.Distance(P2);
+  return Dist < Tol; 
+}
+
+//=======================================================================
+//function : PurgeNewEdges
+//purpose  : 
+//=======================================================================
+static void  PurgeNewEdges(TopTools_ListOfShape& ConstEdges,
+			   const TopTools_MapOfOrientedShape&          UsedEdges)
+{
+  TopTools_ListIteratorOfListOfShape it(ConstEdges);
+  while ( it.More()) {
+    const TopoDS_Shape& NE = it.Value();
+    if (!UsedEdges.Contains(NE)) {
+      ConstEdges.Remove(it);
+    }
+    else {
+      it.Next();
+    }
+  }  
+}
+
+//=======================================================================
+//function : StoreInMVE
+//purpose  : 
+//=======================================================================
+static void StoreInMVE (const TopoDS_Face& F,
+			TopoDS_Edge& E,
+			TopTools_DataMapOfShapeListOfShape& MVE )
+
+{ 
+  TopoDS_Vertex V1, V2;
+  TopTools_ListOfShape Empty;
+
+  TopExp::Vertices(E,V1,V2);
+  if (!MVE.IsBound(V1)) {
+    MVE.Bind(V1,Empty);
+  }
+  MVE(V1).Append(E);
+	
+  if (!MVE.IsBound(V2)) {
+    MVE.Bind(V2,Empty);
+  }
+  MVE(V2).Append(E);
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void Partition_Loop::Perform()
+{
+
+  TopTools_DataMapOfShapeListOfShape MVE;
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;  
+  TopTools_ListIteratorOfListOfShape                  itl;
+  TopoDS_Vertex                                       V1,V2;
+
+  //-----------------------------------
+  // Construction map vertex => edges
+  //-----------------------------------
+  for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
+    TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+    StoreInMVE(myFace,E,MVE);
+  }
+
+  //----------------------------------------------
+  // Construction of all the wires and of all the new faces. 
+  //----------------------------------------------
+  TopTools_MapOfOrientedShape UsedEdges;
+
+  while (!MVE.IsEmpty()) {
+    TopoDS_Vertex    VF,CV;
+    TopoDS_Edge      CE,NE,EF;
+    TopoDS_Wire      NW;
+    BRep_Builder     B;
+    Standard_Boolean End= Standard_False;
+
+    B.MakeWire(NW);
+    //--------------------------------
+    // EF first edge.
+    //--------------------------------
+    Mapit.Initialize(MVE);
+    EF = CE = TopoDS::Edge(Mapit.Value().First());
+
+    TopExp::Vertices(CE,V1,V2);
+    //--------------------------------
+    // VF first vertex 
+    //--------------------------------
+    if (CE.Orientation() == TopAbs_FORWARD) { 
+      CV = VF = V1;
+    }
+    else  { 
+      CV = VF = V2;
+    }
+    if (!MVE.IsBound(CV)) continue;
+    for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
+      if (itl.Value().IsEqual(CE)) {
+	MVE(CV).Remove(itl);
+	break;
+      }
+    }
+
+    int i = 0;
+    while (!End) { 
+      //-------------------------------
+      // Construction of a wire.
+      //-------------------------------
+      TopExp::Vertices(CE,V1,V2);
+      if (!CV.IsSame(V1)) CV = V1; else CV = V2; 
+      B.Add (NW,CE);
+      UsedEdges.Add(CE);
+
+      //--------------
+      // stop test
+      //--------------			
+      if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
+	if (CV.IsSame(VF)) {
+	  if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
+	  else {
+	    for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
+	      if (itl.Value().IsEqual(CE)) {
+		MVE(CV).Remove(itl);
+		break;
+	      }
+	    }
+	  }
+	}
+	End=Standard_True;
+      } 
+
+      //--------------
+      // select edge
+      //--------------
+      else {
+	Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
+	if (find) {
+	  CE=NE;
+	  if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
+	  if (CE.IsNull() ) {
+	    //MESSAGE ( " CE is  NULL !!! " )
+	    End=Standard_True;
+	  }
+	}
+	else {
+	  //MESSAGE ( " edge doesn't exist " )
+	  End=Standard_True;
+	}
+      }
+    }
+
+    //-----------------------------
+    // Test if the wire is closed  
+    //-----------------------------
+    if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
+    }
+    else{
+      //MESSAGE ( "wire not closed" )
+    }
+    myNewWires.Append (NW);			
+  }
+
+  PurgeNewEdges(myConstEdges,UsedEdges);
+
+}
+
+
+//=======================================================================
+//function : NewWires
+//purpose  : 
+//=======================================================================
+const TopTools_ListOfShape&  Partition_Loop::NewWires() const 
+{  
+  return myNewWires;
+}
+
+//=======================================================================
+//function : NewFaces
+//purpose  : 
+//=======================================================================
+const TopTools_ListOfShape&  Partition_Loop::NewFaces() const 
+{  
+  return myNewFaces;
+}
+ 
+//=======================================================================
+//function : WiresToFaces
+//purpose  : 
+//=======================================================================
+void  Partition_Loop::WiresToFaces() 
+{  
+  if (!myNewWires.IsEmpty()) {
+    BRepAlgo_FaceRestrictor FR;
+
+    TopAbs_Orientation OriF = myFace.Orientation();
+    TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
+
+    FR.Init (TopoDS::Face(aLocalS),Standard_False);
+    TopTools_ListIteratorOfListOfShape it(myNewWires);
+    for (; it.More(); it.Next()) {
+      FR.Add(TopoDS::Wire(it.Value()));
+    }
+
+    FR.Perform();
+    
+    if (FR.IsDone()) {
+      for (; FR.More(); FR.Next()) {
+	myNewFaces.Append(FR.Current().Oriented(OriF));
+      }
+    }
+  }
+}
+
+
+#endif
diff --git a/contrib/Salome/Partition_Loop.hxx b/contrib/Salome/Partition_Loop.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..56e05e260bf5c0486f9e66943f87090800fbf52d
--- /dev/null
+++ b/contrib/Salome/Partition_Loop.hxx
@@ -0,0 +1,118 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Loop.hxx
+//  Module : GEOM
+
+#ifndef _Partition_Loop_HeaderFile
+#define _Partition_Loop_HeaderFile
+
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_DataMapOfShapeListOfShape_HeaderFile
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#endif
+class TopoDS_Face;
+class TopoDS_Edge;
+class TopTools_ListOfShape;
+
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+
+class Partition_Loop  {
+
+public:
+
+   inline void* operator new(size_t,void* anAddress) 
+   {
+      return anAddress;
+   }
+   inline void* operator new(size_t size) 
+   { 
+      return Standard::Allocate(size); 
+   }
+   inline void  operator delete(void *anAddress) 
+   { 
+      if (anAddress) Standard::Free((Standard_Address&)anAddress); 
+   }
+   //    inline void  operator delete(void *anAddress, size_t size) 
+   //      { 
+   //        if (anAddress) Standard::Free((Standard_Address&)anAddress,size); 
+   //      }
+   // Methods PUBLIC
+   // 
+   Partition_Loop();
+   void Init(const TopoDS_Face& F) ;
+   void AddConstEdge(const TopoDS_Edge& E) ;
+   void Perform() ;
+   const TopTools_ListOfShape& NewWires() const;
+   void WiresToFaces() ;
+   const TopTools_ListOfShape& NewFaces() const;
+
+
+
+
+protected:
+
+   // Methods PROTECTED
+   // 
+
+
+   // Fields PROTECTED
+   //
+
+
+private: 
+
+   // Methods PRIVATE
+   // 
+
+
+   // Fields PRIVATE
+   //
+   TopoDS_Face myFace;
+   TopTools_ListOfShape myConstEdges;
+   TopTools_ListOfShape myNewWires;
+   TopTools_ListOfShape myNewFaces;
+
+
+};
+
+
+
+
+
+// other inline functions and methods (like "C++: function call" methods)
+//
+
+
+#endif
diff --git a/contrib/Salome/Partition_Loop.ixx b/contrib/Salome/Partition_Loop.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..1c40e72540c987da0b82df3b8754ea72add677d1
--- /dev/null
+++ b/contrib/Salome/Partition_Loop.ixx
@@ -0,0 +1,31 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Loop.ixx
+//  Module : GEOM
+
+#include "Partition_Loop.jxx"
+
+ 
+
+
diff --git a/contrib/Salome/Partition_Loop.jxx b/contrib/Salome/Partition_Loop.jxx
new file mode 100644
index 0000000000000000000000000000000000000000..dd86f05c3d83bea2f5f581673fa79f67bc153a14
--- /dev/null
+++ b/contrib/Salome/Partition_Loop.jxx
@@ -0,0 +1,41 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Loop.jxx
+//  Module : GEOM
+
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _TopoDS_Edge_HeaderFile
+#include <TopoDS_Edge.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_DataMapOfShapeShape_HeaderFile
+#include <TopTools_DataMapOfShapeShape.hxx>
+#endif
+#ifndef _Partition_Loop_HeaderFile
+#include "Partition_Loop.hxx"
+#endif
diff --git a/contrib/Salome/Partition_Loop2d.cxx b/contrib/Salome/Partition_Loop2d.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..71dcce2919cd892b9d2c85e8cca3f8b53e0bd3e4
--- /dev/null
+++ b/contrib/Salome/Partition_Loop2d.cxx
@@ -0,0 +1,1156 @@
+#ifdef OCCGEOMETRY
+
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R& D
+//
+//
+//
+//  File   : Partition_Loop2d.cxx
+//  Author : Benedicte MARTIN
+//  Module : GEOM
+//  $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop2d.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $
+
+//using namespace std;
+#if !defined(HAVE_NO_OCC_CONFIG_H)
+#include <config.h>
+#endif
+
+//using namespace std;
+#include <climits>
+#include "Partition_Loop2d.ixx"
+
+//#include "utilities.h"
+#include <stdio.h>
+
+#include <BRepAdaptor_Curve2d.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepAlgo_AsDes.hxx>
+#include <BRepAlgo_FaceRestrictor.hxx>
+#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
+#include <BRepOffset_DataMapOfShapeReal.hxx>
+#else
+#include <TopTools_DataMapOfShapeReal.hxx>
+#endif
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom2dInt_GInter.hxx>
+#include <Geom2d_Curve.hxx>
+#include <IntRes2d_IntersectionPoint.hxx>
+#include <Precision.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_SequenceOfReal.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <TopTools_DataMapOfShapeInteger.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+
+//=======================================================================
+//function : Partition_Loop2d
+//purpose  :
+//=======================================================================
+
+Partition_Loop2d::Partition_Loop2d()
+{
+}
+
+//=======================================================================
+//function : Init
+//purpose  : Init with <F> the set of edges must have
+//           pcurves on <F>.
+//=======================================================================
+
+void Partition_Loop2d::Init(const TopoDS_Face& F)
+{
+  myConstEdges.Clear();
+  myNewWires  .Clear();
+  myNewFaces  .Clear();
+  myFace = F;
+  myFaceOri = myFace.Orientation();
+  myFace.Orientation( TopAbs_FORWARD );
+}
+
+//=======================================================================
+//function : AddConstEdge
+//purpose  : Add <E> as unique edge in the result.
+//=======================================================================
+
+void Partition_Loop2d::AddConstEdge (const TopoDS_Edge& E)
+{
+#ifdef DEB
+  Standard_Real f,l;
+  Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l);
+  if (pc.IsNull()) {
+    INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE");
+  } else
+#endif
+  {
+    myConstEdges.Append(E);
+  }
+}
+
+void Partition_Loop2d::AddSectionEdge (const TopoDS_Edge& E)
+{
+#ifdef DEB
+  Standard_Real f,l;
+  Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l);
+  if (pc.IsNull())
+    pc = BRep_Tool::CurveOnSurface( E, myFace, f,l);
+  gp_Vec2d Tg1;
+  gp_Pnt2d PC;
+  pc->D1(0.5*(f+l), PC, Tg1);
+  if (Tg1.Magnitude()  <= gp::Resolution()) {
+    MESSAGE ("");
+  }
+  if (pc.IsNull()) {
+    INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE");
+  } else
+#endif
+  {
+    myConstEdges.Append(E);
+    myConstEdges.Append(E.Reversed());
+    mySectionEdges.Add( E );
+  }
+}
+
+//=======================================================================
+//function : preciseU
+//purpose  : find u such that the 3D point on theE is just out of tolerance
+//           of theV
+//=======================================================================
+
+static Standard_Real preciseU (const BRepAdaptor_Surface&  theSurf,
+                               const TopoDS_Edge&          theE,
+                               const TopoDS_Vertex&        theV,
+                               const Handle(Geom2d_Curve)& theC,
+                               const Standard_Boolean      theFirstEnd)
+{
+  Standard_Boolean isForward = ( theE.Orientation () == TopAbs_FORWARD );
+  if (theFirstEnd) isForward = !isForward;
+
+  // find the first point in 2d and 3d
+  Standard_Real f,l;
+  BRep_Tool::Range( theE, f, l );
+  Standard_Real u0 = isForward ? l : f;
+  gp_Pnt2d aP2d0 = theC->Value( u0 );
+  gp_Pnt aPnt0 = theSurf.Value( aP2d0.X(), aP2d0.Y() );
+
+  // shift in 2d and 3d
+  Standard_Real du = ( l - f ) / 100, du3d = 0;
+  if (isForward)
+    du = -du;
+
+  // target parameter
+  Standard_Real u;
+
+  while (du3d < ::RealSmall())
+  {
+    // u for test
+    u = u0 + du;
+    du *= 10; // for the next iteration: increase du untill du3d is large enough
+
+    // find out how u is far from u0 in 3D
+    gp_Pnt2d aP2d  = theC->Value( u );
+    gp_Pnt aPnt  = theSurf.Value( aP2d.X(), aP2d.Y() );
+    du3d = aPnt0.Distance( aPnt );
+  }
+
+  // find u such that the 3D point is just out of tolerance of theV
+  Standard_Real tolV = BRep_Tool::Tolerance( theV ) + Precision::Confusion();
+  u = u0 + du * tolV / du3d;
+
+  // check that u is within the range
+  if ( isForward ? (u < f) : (u > l) )
+    u = u0 + du;
+
+  return u;
+}
+
+//=======================================================================
+//function : SelectEdge
+//purpose  : Find in the list <LE> the edge <NE> connected with <CE> by
+//           the vertex <CV>.
+//           <NE> is removed from the list. If <CE> is in <LE>
+//           with the same orientation, it's removed from the list
+//=======================================================================
+
+static Standard_Boolean  SelectEdge(const BRepAdaptor_Surface& Surf,
+                                    const TopoDS_Edge&    CE,
+                                    const TopoDS_Vertex&  CV,
+                                    TopoDS_Edge&          NE,
+                                    const TopTools_ListOfShape& LE)
+{
+  NE.Nullify();
+
+  if (LE.Extent() > 1) {
+    //--------------------------------------------------------------
+    // Several possible edges.
+    // - Test the edges differents of CE
+    //--------------------------------------------------------------
+    TopoDS_Face FForward = Surf.Face();
+    TopoDS_Edge aPrevNE;
+
+    gp_Vec2d CTg1, Tg1, CTg2, Tg2;
+    gp_Pnt2d PC, P;
+
+    Standard_Real f, l;
+    Handle(Geom2d_Curve) Cc, C;
+    Cc = BRep_Tool::CurveOnSurface(CE,FForward,f,l);
+
+    Standard_Boolean isForward = ( CE.Orientation () == TopAbs_FORWARD );
+    Standard_Real uc, u, du = Precision::PConfusion();
+    uc = isForward ? ( l - du ) : ( f + du );
+    Cc->D1(uc, PC, CTg1);
+    if (!isForward) CTg1.Reverse();
+
+    Standard_Real anglemin = 3 * PI, tolAng = 1.e-8;
+
+    // select an edge whose first derivative is most left of CTg1
+    // ie an angle between Tg1 and CTg1 is least
+    TopTools_ListIteratorOfListOfShape itl;
+    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+      if (E.IsSame(CE))
+        continue;
+      if (! CV.IsSame( TopExp::FirstVertex( E, Standard_True )))
+        continue;
+
+      isForward = ( E.Orientation () == TopAbs_FORWARD );
+
+      // get E curve
+      C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
+      // get the first derivative Tg1
+      u = isForward ? ( f + du ) : ( l - du );
+      C->D1(u, P, Tg1);
+      if (!isForward) Tg1.Reverse();
+
+      // -PI < angle < PI
+      Standard_Real angle = Tg1.Angle(CTg1);
+
+      if (PI - Abs(angle) <= tolAng)
+      {
+        // an angle is too close to PI; assure that an angle sign really
+        // reflects an edge position: +PI - an edge is worst,
+        // -PI - an edge is best.
+        u = preciseU( Surf, CE, CV, Cc, Standard_False);
+        gp_Vec2d CTg;
+        Cc->D1(u, PC, CTg);
+        if (CE.Orientation() == TopAbs_REVERSED) CTg.Reverse();
+
+        u = preciseU( Surf, E, CV, C, Standard_True);
+        C->D1(u, P, Tg1);
+        if (!isForward) Tg1.Reverse();
+
+        angle = Tg1.Angle(CTg);
+      }
+
+      Standard_Boolean isClose = ( Abs( angle - anglemin ) <= tolAng );
+      if (angle <= anglemin) {
+        if (isClose)
+          aPrevNE = NE;
+        else
+          aPrevNE.Nullify();
+        anglemin = angle ;
+        NE = E;
+      }
+      else
+        if (isClose)
+          aPrevNE = E;
+
+    }
+    if (!aPrevNE.IsNull()) {
+      // select one of close edges, the most left one.
+      Cc = BRep_Tool::CurveOnSurface( NE, FForward, f, l );
+      uc = preciseU( Surf, NE, CV, Cc, Standard_True);
+      Cc->D1(uc, PC, CTg1);
+      if (NE.Orientation() != TopAbs_FORWARD) CTg1.Reverse();
+      
+      u = preciseU( Surf, aPrevNE, CV, C, Standard_True);
+      C->D1(u, P, Tg1);
+      if (aPrevNE.Orientation() != TopAbs_FORWARD) Tg1.Reverse();
+
+      if ( Tg1.Angle(CTg1) < 0)
+        NE = aPrevNE;
+    }
+  }
+  else if (LE.Extent() == 1) {
+    NE = TopoDS::Edge(LE.First());
+  }
+  else {
+    return Standard_False;
+  }
+  return !NE.IsNull();
+}
+
+//=======================================================================
+//function : SamePnt2d
+//purpose  :
+//=======================================================================
+
+static Standard_Boolean  SamePnt2d(const TopoDS_Vertex& V1,
+                                   const TopoDS_Edge&   E1,
+                                   const TopoDS_Vertex& V2,
+                                   const TopoDS_Edge&   E2,
+                                   const TopoDS_Face&   F)
+{
+  Standard_Real   f1,f2,l1,l2;
+  Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,F,f1,l1);
+  Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,F,f2,l2);
+
+  gp_Pnt2d P1 = C1->Value( BRep_Tool::Parameter(V1,E1));
+  gp_Pnt2d P2 = C2->Value( BRep_Tool::Parameter(V2,E2));
+
+  Standard_Real Tol  = 100 * BRep_Tool::Tolerance(V1);
+  Standard_Real Dist = P1.Distance(P2);
+  return Dist < Tol;
+}
+
+
+//=======================================================================
+//function : StoreInMVE
+//purpose  :
+//=======================================================================
+
+static void StoreInMVE (const TopoDS_Face& /*F*/,
+                        TopoDS_Edge& E,
+                        TopTools_DataMapOfShapeListOfShape& MVE )
+
+{
+  TopoDS_Vertex V1, V2;
+  TopTools_ListOfShape Empty;
+
+  TopExp::Vertices(E,V1,V2);
+  if (!MVE.IsBound(V1)) {
+    MVE.Bind(V1,Empty);
+  }
+  MVE(V1).Append(E);
+
+  if (!MVE.IsBound(V2)) {
+    MVE.Bind(V2,Empty);
+  }
+  MVE(V2).Append(E);
+}
+
+//=======================================================================
+//function : RemoveFromMVE
+//purpose  :
+//=======================================================================
+
+static void RemoveFromMVE(const TopoDS_Edge& E,
+                          TopTools_DataMapOfShapeListOfShape& MVE)
+{
+  TopTools_ListIteratorOfListOfShape itl;
+  TopoDS_Vertex  V1,V2;
+  TopExp::Vertices (E,V1,V2);
+  if (MVE.IsBound(V1))
+    for ( itl.Initialize(MVE(V1)); itl.More(); itl.Next()) {
+      if (itl.Value().IsEqual(E)) {
+        MVE(V1).Remove(itl);
+        break;
+      }
+    }
+  if (MVE.IsBound(V2))
+    for ( itl.Initialize(MVE(V2)); itl.More(); itl.Next()) {
+      if (itl.Value().IsEqual(E)) {
+        MVE(V2).Remove(itl);
+        break;
+      }
+    }
+}
+//=======================================================================
+//function : addConnected
+//purpose  : add to <EM> all edges reachable from <E>
+//=======================================================================
+
+static void addConnected(const TopoDS_Shape& E,
+                         TopTools_MapOfShape& EM,
+                         TopTools_MapOfShape& VM,
+                         const TopTools_DataMapOfShapeListOfShape& MVE)
+{
+  // Loop on vertices of E
+  TopoDS_Iterator itV ( E );
+  for ( ; itV.More(); itV.Next()) {
+
+    if ( ! VM.Add ( itV.Value() )) continue;
+
+    // Loop on edges sharing V
+    TopTools_ListIteratorOfListOfShape itE( MVE( itV.Value() ) );
+    for (; itE.More(); itE.Next()) {
+      if ( EM.Add( itE.Value() ))
+        addConnected ( itE.Value(), EM, VM, MVE );
+    }
+  }
+}
+//=======================================================================
+//function : canPassToOld
+//purpose  :
+//=======================================================================
+
+// static Standard_Boolean canPassToOld (const TopoDS_Shape& V,
+//                                    TopTools_MapOfShape& UsedShapesMap,
+//                                    const TopTools_DataMapOfShapeListOfShape& MVE,
+//                                    const TopTools_MapOfShape& SectionEdgesMap)
+// {
+//   TopTools_ListIteratorOfListOfShape itE( MVE(V) );
+//   // Loop on edges sharing V
+//   for (; itE.More(); itE.Next()) {
+//     if ( !UsedShapesMap.Add( itE.Value() ))
+//       continue; // already checked
+
+//     if ( !SectionEdgesMap.Contains( itE.Value() ))
+//       return Standard_True; // WE PASSED
+
+//     TopoDS_Iterator itV( itE.Value() );
+//     // Loop on vertices of an edge
+//     for (; itV.More(); itV.Next()) {
+//       if ( !UsedShapesMap.Add( itV.Value() ))
+//      continue; // already checked
+//       else
+//      return canPassToOld( itV.Value(), UsedShapesMap, MVE, SectionEdgesMap);
+//     }
+//   }
+//   return Standard_False;
+// }
+
+//=======================================================================
+//function : MakeDegenAndSelect
+//purpose  : Find parameter of intersection of <CE> with <DE> and
+//           select an edge with its parameter closest to found one.
+//           Return new degenerated edge trimming <DE> by found parameters
+//=======================================================================
+
+static TopoDS_Edge MakeDegenAndSelect(const TopoDS_Edge& CE,
+                                      const TopoDS_Vertex& CV,
+                                      TopoDS_Edge& NE,
+                                      TopTools_SequenceOfShape& EdgesSeq,
+                                      TColStd_SequenceOfReal& USeq,
+                                      const TopoDS_Edge& DE)
+{
+  if (EdgesSeq.Length() < 3) {
+    if (CE == EdgesSeq.First())
+      NE = TopoDS::Edge( EdgesSeq.Last() );
+    else
+      NE = TopoDS::Edge( EdgesSeq.First() );
+    return DE;
+  }
+
+  // find parameter on DE where it intersects CE
+
+  Standard_Real U1;
+  Standard_Integer i, nb = EdgesSeq.Length();
+  for (i=1; i<= nb; ++i) {
+    if (CE == EdgesSeq(i)) {
+      U1 = USeq(i);
+      break;
+    }
+  }
+
+  // select NE with param closest to U1 thus finding U2 for a new degen edge
+
+  Standard_Real U2, dU, dUmin = 1.e100;
+  Standard_Boolean isReversed = ( DE.Orientation() == TopAbs_REVERSED );
+  for (i=1; i<= nb; ++i) {
+    dU = USeq(i) - U1;
+    if (isReversed ? (dU > 0) : (dU < 0))
+        continue;
+    dU = Abs( dU );
+    if ( dU  > dUmin || IsEqual( dU, 0.))
+      continue;
+    const TopoDS_Edge& E = TopoDS::Edge ( EdgesSeq(i) );
+    if ( ! CV.IsSame( TopExp::FirstVertex( E , Standard_True )))
+      continue;
+    NE = E;
+    dUmin = dU + Epsilon(dU);
+    U2 = USeq(i);
+  }
+
+  // make a new degenerated edge
+  TopoDS_Edge NewDegen = TopoDS::Edge ( DE.EmptyCopied() );
+
+  Standard_Real Tol = BRep_Tool::Tolerance( CV );
+  TopoDS_Vertex V = CV;
+
+  BRep_Builder B;
+  V.Orientation( NewDegen.Orientation() );
+  B.UpdateVertex( V, U1, NewDegen, Tol);
+  B.Add ( NewDegen , V );
+
+  V.Reverse();
+  B.UpdateVertex( V, U2, NewDegen, Tol);
+  B.Add ( NewDegen , V );
+
+  return NewDegen;
+}
+
+//=======================================================================
+//function : prepareDegen
+//purpose  : Intersect <DegEdge> with edges bound to its vertex in <MVE>
+//           and store intersection parameter on <DegEdge> in
+//           <USeq> as well as the edges them-self in <EdgesSeq>.
+//           Bind <DegEdgeIndex> to vertex of <DegEdge> in <MVDEI>
+//=======================================================================
+
+static void prepareDegen (const TopoDS_Edge&                        DegEdge,
+                          const TopoDS_Face&                        F,
+                          const TopTools_DataMapOfShapeListOfShape& MVE,
+                          TopTools_SequenceOfShape&                 EdgesSeq,
+                          TColStd_SequenceOfReal&                   USeq,
+                          TopTools_DataMapOfShapeInteger&           MVDEI,
+                          const Standard_Integer                    DegEdgeIndex)
+{
+  const TopoDS_Vertex& V = TopExp::FirstVertex ( DegEdge );
+  MVDEI.Bind ( V, DegEdgeIndex );
+
+  const TopTools_ListOfShape& EdgesList = MVE ( V );
+  // if only 2 edges come to degenerated one, no pb in selection and
+  // no need to intersect them, just simulate asked data
+  Standard_Boolean doIntersect =  ( EdgesList.Extent() > 2 );
+
+  BRepAdaptor_Curve2d DC, C;
+  Geom2dInt_GInter InterCC;
+  Standard_Real Tol = Precision::PConfusion();
+  if ( doIntersect )
+    DC.Initialize( DegEdge, F );
+
+  // avoid intersecting twice the same edge
+#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
+  BRepOffset_DataMapOfShapeReal EUMap ( EdgesList.Extent() );
+#else
+  TopTools_DataMapOfShapeReal EUMap ( EdgesList.Extent() );
+#endif
+
+  Standard_Real U, f, l;
+  BRep_Tool::Range (DegEdge, f, l);
+
+  TopTools_ListIteratorOfListOfShape itE (EdgesList);
+  for (; itE.More(); itE.Next()) {
+
+    const TopoDS_Edge& E = TopoDS::Edge ( itE.Value() );
+
+    if ( !doIntersect) {
+      U = 0.; // it won't be used
+    }
+    else if ( BRep_Tool::IsClosed( E, F )) {
+      // seam edge: select U among f and l
+      Standard_Boolean first = Standard_True;
+      if ( V.IsSame ( TopExp::FirstVertex( E, Standard_True ) ))
+        first = Standard_False;
+      if ( DegEdge.Orientation() == TopAbs_REVERSED )
+        first = !first;
+      U = first ? f : l;
+    }
+    else if ( EUMap.IsBound( E ) ) {
+      // same edge already bound
+      U = EUMap( E );
+    }
+    else {
+      // intersect 2d curves
+      C.Initialize( E, F );
+      InterCC.Perform ( DC, C , Tol, Tol );
+      if (! InterCC.IsDone() || InterCC.NbPoints() == 0) {
+        //MESSAGE ( "NO 2d INTERSECTION ON DEGENERATED EDGE" );
+        continue;
+      }
+      // hope there is only one point of intersection
+      U = InterCC.Point( 1 ).ParamOnFirst();
+    }
+    USeq.Append ( U );
+    EdgesSeq.Append ( E );
+  }
+}
+//=======================================================================
+//function : Perform
+//purpose  : Make loops.
+//=======================================================================
+
+void Partition_Loop2d::Perform()
+{
+
+  Standard_Integer NbConstEdges = myConstEdges.Extent();
+  TopTools_DataMapOfShapeListOfShape MVE(NbConstEdges) , MVE2(NbConstEdges);
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
+  TopTools_ListIteratorOfListOfShape itl;
+  TopoDS_Vertex V1,V2;
+  BRepAdaptor_Surface Surface ( myFace, Standard_False );
+
+  // degenerated edges and parameters of their 2d intersection with other edges
+  TopoDS_Edge                    DE [2];
+  TopTools_SequenceOfShape       SEID [2]; // seq of edges intersecting degenerated
+  TColStd_SequenceOfReal         SeqU [2]; // n-th U corresponds to n-th edge in SEID
+  TopTools_DataMapOfShapeInteger MVDEI(2); // map vertex - degenerated edge index
+  Standard_Integer               iDeg = 0; // index of degenerated edge [0,1]
+
+  //---------------------------------------------------------
+  // Construction map vertex => edges, find degenerated edges
+  //---------------------------------------------------------
+  for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
+    TopoDS_Edge& E = TopoDS::Edge(itl.Value());
+    if ( BRep_Tool::Degenerated( E )) {
+      if (DE[0].IsNull()) DE[0] = E;
+      else                DE[1] = E;
+    }
+    else
+      StoreInMVE(myFace,E,MVE);
+  }
+
+  // fill data for degenerated edges
+  if ( ! DE[0].IsNull() )
+    prepareDegen ( DE[0], myFace, MVE, SEID[0], SeqU[0], MVDEI, 0);
+  if ( ! DE[1].IsNull() )
+    prepareDegen ( DE[1], myFace, MVE, SEID[1], SeqU[1], MVDEI, 1);
+
+
+  // to detect internal wires
+  Standard_Boolean isInternCW = 0;
+  MVE2 = MVE;
+
+
+  //------------------------------
+  // Construction of all the wires
+  //------------------------------
+  // first, we collect wire edges in WEL list looking for same edges that
+  // will be then removed possibly exploding a wire into parts;
+  // second, build wire(s)
+
+  while (!MVE.IsEmpty()) {
+
+    TopoDS_Vertex    VF,CV;
+    TopoDS_Edge      CE,NE,EF;
+    TopoDS_Wire      NW;
+    BRep_Builder     B;
+    Standard_Boolean End = Standard_False;
+    TopTools_ListOfShape WEL;
+
+    Mapit.Initialize(MVE);
+    if (Mapit.Value().IsEmpty()) {
+      MVE.UnBind(Mapit.Key());
+      continue;
+    }
+
+    // EF first edge.
+    EF = CE = TopoDS::Edge(Mapit.Value().First());
+    // VF first vertex
+    VF = TopExp::FirstVertex( CE, Standard_True);
+
+    isInternCW = Standard_True;
+
+    TopTools_MapOfShape addedEM  (NbConstEdges); // map of edges added to WEL
+    TopTools_MapOfShape doubleEM (NbConstEdges); // edges encountered twice in WEL
+
+    //-------------------------------
+    // Construction of a wire.
+    //-------------------------------
+    while (!End) {
+
+      // only a seam is allowed twice in a wire, the others should be removed
+      if (addedEM.Add ( CE ) || BRep_Tool::IsClosed( CE, myFace ) )
+        WEL.Append( CE );
+      else {
+        doubleEM.Add( CE );
+        RemoveFromMVE (CE,MVE2);
+        TopoDS_Edge CERev = CE;
+        CERev.Reverse();
+        RemoveFromMVE (CERev,MVE2);
+      }
+
+      RemoveFromMVE (CE,MVE);
+
+      CV = TopExp::LastVertex( CE, Standard_True);
+
+      if (isInternCW && !mySectionEdges.Contains(CE))
+        // wire is internal if all edges are section ones
+        isInternCW = Standard_False;
+
+      if (MVDEI.IsBound( CV )) { // CE comes to the degeneration
+        iDeg = MVDEI( CV );
+        TopoDS_Edge NewDegen;
+        NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]);
+        WEL.Append( NewDegen );
+        CE = NE;
+        End = CV.IsSame( VF );
+        continue;
+      }
+
+      //--------------
+      // stop test
+      //--------------
+      if (MVE(CV).IsEmpty()) {
+        End=Standard_True;
+        MVE.UnBind(CV);
+      }
+      else if (CV.IsSame(VF) && SamePnt2d(CV,CE, VF,EF, myFace) ) {
+        End = Standard_True;
+      }
+      else {
+        //----------------------------
+        // select new current edge
+        //----------------------------
+        if (! SelectEdge (Surface,CE,CV,NE,MVE(CV))) {
+          //MESSAGE ( " NOT CLOSED WIRE " );
+          End=Standard_True;
+        }
+        else
+          CE = NE;
+      }
+    } // while ( !End )
+
+
+    // WEL is built, built wire(s)
+
+
+    itl.Initialize( WEL );
+    if ( doubleEM.IsEmpty()) { // no double edges
+      B.MakeWire( NW );
+      for (; itl.More(); itl.Next())
+        B.Add ( NW, itl.Value());
+      if (isInternCW) myInternalWL.Append(NW);
+      else            myNewWires.Append  (NW);
+    }
+
+    else {
+      // remove double and degenerated edges from WEL
+      while (itl.More()) {
+        const TopoDS_Edge& E = TopoDS::Edge ( itl.Value() );
+        if ( doubleEM.Contains( E ) || BRep_Tool::Degenerated( E ))
+          WEL.Remove( itl );
+        else
+           itl.Next();
+      }
+      if ( WEL.IsEmpty())
+        continue;
+      // remove double edges from SEID and SeqU
+      Standard_Integer i,j;
+      for (j=0; j<2; ++j) {
+        for (i=1; i<=SEID[j].Length(); ++i) {
+          if (doubleEM.Contains( SEID[j].Value(i))) {
+            SEID[j].Remove( i );
+            SeqU[j].Remove( i-- );
+          }
+        }
+      }
+      // removal of doulbe edges can explode a wire into parts,
+      // make new wires of them.
+      // A Loop like previous one but without 2d check
+      while ( !WEL.IsEmpty() ) {
+        CE = TopoDS::Edge( WEL.First() );
+        WEL.RemoveFirst();
+        B.MakeWire( NW );
+        VF = TopExp::FirstVertex ( CE, Standard_True);
+
+        End = Standard_False;
+        while ( !End) {
+          B.Add( NW, CE );
+          CV = TopExp::LastVertex  ( CE, Standard_True);
+
+          if (MVDEI.IsBound( CV )) {   // CE comes to the degeneration
+            iDeg = MVDEI( CV );
+            TopoDS_Edge NewDegen;
+            NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]);
+            B.Add( NW, NewDegen );
+            End = CV.IsSame( VF );
+            CE = NE;
+            if (!NE.IsNull()) { // remove NE from WEL
+              for (itl.Initialize( WEL ); itl.More(); itl.Next())
+                if ( NE == itl.Value()) {
+                  WEL.Remove( itl );
+                  break;
+                }
+            }
+          }  // end degeneration
+
+          else {
+            if (CV.IsSame( VF )) {
+              End = Standard_True;
+              continue;
+            }
+            // edges in WEL most often are well ordered
+            // so try to iterate until the End
+            Standard_Boolean add = Standard_False;
+            itl.Initialize(WEL);
+            while ( itl.More() && !End) {
+              NE = TopoDS::Edge( itl.Value() );
+              if ( CV.IsSame( TopExp::FirstVertex( NE, Standard_True ))) {
+                WEL.Remove( itl );
+                if (add)
+                  B.Add( NW, CE );
+                CE = NE;
+                add = Standard_True;
+                CV = TopExp::LastVertex( CE, Standard_True);
+                if (MVDEI.IsBound( CV ) || CV.IsSame( VF ))
+                  break;
+              }
+              else
+                itl.Next();
+            }
+            if (!add)
+              End = Standard_True;
+          }
+        } // !End
+
+        myInternalWL.Append( NW );
+      }
+    } // end building new wire(s) from WEL
+
+  } // end Loop on MVE
+
+  // all wires are built
+
+
+  // ============================================================
+  // select really internal wires i.e. those from which we can`t
+  // pass to an old (not section) edge
+  // ============================================================
+
+  Standard_Integer nbIW = myInternalWL.Extent();
+  if (nbIW == 0)
+    return;
+
+  if ( myNewWires.Extent() != 1 && nbIW > 1) {
+    TopTools_MapOfShape outerEM (NbConstEdges); // edges connected to non-section ones
+    TopTools_MapOfShape visitedVM (NbConstEdges);
+    for ( itl.Initialize( myConstEdges ); itl.More(); itl.Next()) {
+      if ( ! mySectionEdges.Contains( itl.Value() ))
+        addConnected (itl.Value(), outerEM, visitedVM, MVE2);
+    }
+    // if an edge of a wire is in <outerEM>, the wire is not internal
+    TopExp_Explorer expIWE;
+    TopTools_ListIteratorOfListOfShape itIW ( myInternalWL );
+    while (itIW.More()) {
+      expIWE.Init ( itIW.Value() , TopAbs_EDGE );
+      if ( outerEM.Contains( expIWE.Current() )) {
+        myNewWires.Append ( itIW.Value() );
+        myInternalWL.Remove( itIW ); // == itIW.Next()
+      }
+      else
+        itIW.Next();
+    }
+  }
+}
+//=======================================================================
+//function : isHole
+//purpose  :
+//=======================================================================
+
+static Standard_Boolean isHole (const TopoDS_Wire& W,
+                                const TopoDS_Face& F)
+{
+  BRep_Builder B;
+  TopoDS_Shape newFace = F.EmptyCopied();
+  B.Add(newFace,W.Oriented(TopAbs_FORWARD));
+  BRepTopAdaptor_FClass2d classif (TopoDS::Face(newFace),
+                                   Precision::PConfusion());
+  return (classif.PerformInfinitePoint() == TopAbs_IN);
+}
+
+//=======================================================================
+//function : IsInside
+//purpose  : check if W1 is inside W2. Suppose W2 is not a hole !!!!
+//=======================================================================
+
+static Standard_Boolean isInside(const TopoDS_Face& F,
+                                 const TopoDS_Wire& W1,
+                                 const TopoDS_Wire& W2)
+{
+  // make a face with wire W2
+  BRep_Builder B;
+  TopoDS_Shape aLocalShape = F.EmptyCopied();
+  TopoDS_Face newFace = TopoDS::Face(aLocalShape);
+  B.Add(newFace,W2);
+
+  // get any 2d point of W1
+  TopExp_Explorer exp(W1,TopAbs_EDGE);
+  if (BRep_Tool::Degenerated( TopoDS::Edge( exp.Current() )))
+    exp.Next();
+  const TopoDS_Edge& e = TopoDS::Edge(exp.Current());
+  Standard_Real f,l;
+  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(e,F,f,l);
+  gp_Pnt2d pt2d(C2d->Value( 0.5 * ( f + l )));
+
+  BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
+  return (classif.Perform(pt2d) == TopAbs_IN);
+}
+
+//=======================================================================
+//function : NewWires
+//purpose  : Returns the list of wires performed.
+//           can be an empty list.
+//=======================================================================
+
+const TopTools_ListOfShape&  Partition_Loop2d::NewWires() const
+{
+  return myNewWires;
+}
+
+//=======================================================================
+//function : NewFaces
+//purpose  : Returns the list of faces.
+//Warning  : The method <WiresToFaces> as to be called before.
+//           can be an empty list.
+//=======================================================================
+
+const TopTools_ListOfShape&  Partition_Loop2d::NewFaces() const
+{
+  return myNewFaces;
+}
+
+//=======================================================================
+//function : findEqual
+//purpose  : move wires form <WL> to <EqWL> pairs of wires build of the same edges
+//=======================================================================
+
+static void findEqual (TopTools_ListOfShape& WL,
+                       TopTools_DataMapOfShapeShape& EqWM,
+                       const TopoDS_Face& F)
+{
+  TopTools_ListIteratorOfListOfShape it1, it2;
+  Standard_Integer i,j;
+  TColStd_MapOfInteger IndMap;
+  for (it1.Initialize(WL), i=1;  it1.More();  it1.Next(), i++) {
+
+    if (IndMap.Contains(i)) continue;
+    const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value());
+
+    for (it2.Initialize(WL), j=1;  it2.More();  it2.Next(), j++) {
+
+      if (j <= i || IndMap.Contains(j)) continue;
+
+      TopTools_IndexedMapOfShape EdgesMap;
+      TopExp::MapShapes (Wire1, TopAbs_EDGE, EdgesMap);
+
+      const TopoDS_Shape& Wire2 = it2.Value();
+      TopoDS_Iterator itE ( Wire2);
+      for (; itE.More(); itE.Next()) {
+        if ( !EdgesMap.Contains( itE.Value()) )
+          break;
+      }
+      if (!itE.More()) { // all edges are same
+        if (isHole( Wire1, F)) {
+          EqWM.Bind ( Wire1, Wire2 );
+        }
+        else {
+          EqWM.Bind ( Wire2, Wire1 );
+        }
+        IndMap.Add(i);
+        IndMap.Add(j);
+        break;
+      }
+    }
+  }
+  // clear WL
+  it1.Initialize(WL);
+  i=1;
+  while (it1.More()) {
+    if (IndMap.Contains(i))
+      WL.Remove(it1); // next node becomes current and with Next() we would miss it
+    else
+      it1.Next();
+    i++;
+  }
+}
+
+//=======================================================================
+//function : classify
+//purpose  : bind to a wire a list of internal wires
+//=======================================================================
+
+static void classify(const TopTools_DataMapOfShapeShape& EqWM,
+                     BRepAlgo_AsDes& OuterInner,
+                     const TopoDS_Face& F)
+{
+  TopTools_DataMapIteratorOfDataMapOfShapeShape it1, it2;
+
+  for (it1.Initialize(EqWM);  it1.More();  it1.Next()) {
+    // find next after it1.Value()
+    for (it2.Initialize(EqWM);  it2.More();  it2.Next())
+      if (it1.Value().IsSame( it2.Value() ))
+      {
+        it2.Next();
+        break;
+      }
+    for ( ;  it2.More();  it2.Next()) {
+      const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value() );
+      const TopoDS_Wire& Wire2 = TopoDS::Wire( it2.Value() );
+      if (isInside(F, Wire1, Wire2))
+        OuterInner.Add (Wire2, Wire1);
+      else if (isInside(F, Wire2, Wire1))
+        OuterInner.Add (Wire1, Wire2);
+    }
+  }
+}
+//=======================================================================
+//function : WiresToFaces
+//purpose  : Build faces from the wires result.
+//           <EdgeImage> serves to  find  original edge by new
+//           one. <Section> contains edges resulting from face
+//           intersections
+//=======================================================================
+
+void  Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& )
+{
+  Standard_Integer nbW = myNewWires.Extent() + myInternalWL.Extent();
+  if (nbW==0)
+    return;
+
+  BRepAlgo_FaceRestrictor FR;
+  FR.Init (myFace,Standard_False);
+
+  // FaceRestrictor is instable in rather simple cases
+  // (ex. a single face of bellecoque.brep splited by 10 planes:
+  // sometimes 1-2 faces are missing ).
+  // So we use it as less as possible: no holes -> make faces by hands
+
+
+  // are there holes in myFace ?
+  Standard_Boolean hasOldHoles = Standard_False;
+  TopoDS_Iterator itOldW (myFace);
+  if ( itOldW.More()) {
+    const TopoDS_Wire& FirstOldWire = TopoDS::Wire( itOldW.Value() );
+    itOldW.Next();
+    hasOldHoles = itOldW.More() || isHole( FirstOldWire, myFace);
+  }
+  if (myInternalWL.IsEmpty() && !hasOldHoles) {
+    // each wire bounds one face
+    BRep_Builder B;
+    TopTools_ListIteratorOfListOfShape itNW (myNewWires);
+    for (; itNW.More(); itNW.Next()) {
+      TopoDS_Face NF = TopoDS::Face ( myFace.EmptyCopied() );
+      B.Add ( NF, itNW.Value() );
+      NF.Orientation( myFaceOri);
+      myNewFaces.Append ( NF );
+    }
+    return;
+  }
+
+  // FaceRestrictor can't classify wires build on all the same edges
+  // and gives incorrect result in such cases (ex. a plane cut into 2 parts by cylinder)
+  // We must make faces of equal wires separately. One of equal wires makes a
+  // hole in a face and should come together with outer wires of face.
+  // The other of a wires pair bounds a face that may have holes in turn.
+
+  // Find equal wires among internal wires
+  TopTools_DataMapOfShapeShape EqWM; // key is a hole part of a pair of equal wires
+  findEqual (myInternalWL, EqWM, myFace);
+
+  if (!EqWM.IsEmpty()) { // there are equal wires
+
+    if (hasOldHoles)
+      myInternalWL.Append( myNewWires ); // an old wire can be inside an equal wire
+
+    // classify equal wire pairs
+    BRepAlgo_AsDes OuterInner;
+    classify (EqWM,OuterInner,myFace);
+
+    // make face of most internal of equal wires and its inner wires
+    while ( !EqWM.IsEmpty()) {
+
+      TopTools_ListOfShape prevHolesL; // list of hole-part of previous most internal equal wires
+
+      // find most internal wires among pairs (key - hole, value - outer part)
+      TopTools_DataMapIteratorOfDataMapOfShapeShape it(EqWM);
+      Standard_Integer nbEqW = EqWM.Extent(); // protection against infinite loop
+      for ( ; it.More(); it.Next()) {
+
+        TopoDS_Wire outerW = TopoDS::Wire ( it.Value() );
+        if (  OuterInner.HasDescendant( outerW ) && // has internal
+             ! OuterInner.Descendant( outerW ).IsEmpty() )
+          continue;
+
+        FR.Add( outerW );
+
+        // add internal wires that are inside of outerW
+        TopTools_ListIteratorOfListOfShape itIW (myInternalWL);
+        while ( itIW.More()) {
+          TopoDS_Wire IW = TopoDS::Wire ( itIW.Value() );
+          if ( isInside (myFace, IW, outerW)) {
+            FR.Add (IW);
+            myInternalWL.Remove( itIW ); // == itIW.Next() !!!
+          }
+          else
+            itIW.Next();
+        }
+
+        // the hole-part of current pair of equal wires will be in the next new face
+        prevHolesL.Append ( it.Key() );
+
+      } // Loop on map of equal pairs searching for innermost wires
+
+      // make faces
+      FR.Perform();
+      if (FR.IsDone()) {
+        for (; FR.More(); FR.Next())
+          myNewFaces.Append(FR.Current());
+      }
+
+      FR.Clear();
+
+      // add hole-parts to FaceRestrictor,
+      // remove them from the EqWM,
+      // remove found wires as internal of resting classified wires
+      Standard_Boolean clearOuterInner =  ( prevHolesL.Extent() < EqWM.Extent() );
+      TopTools_ListIteratorOfListOfShape itPrev (prevHolesL);
+      for (; itPrev.More(); itPrev.Next()) {
+        TopoDS_Wire& Hole = TopoDS::Wire ( itPrev.Value() );
+        FR.Add ( Hole );
+        if (clearOuterInner) {
+          const TopoDS_Wire& outerW = TopoDS::Wire ( EqWM.Find( Hole ) );
+          // Loop on wires including outerW
+          TopTools_ListIteratorOfListOfShape itO( OuterInner.Ascendant( outerW ));
+          for (; itO.More(); itO.Next()) {
+            TopTools_ListOfShape& innerL = OuterInner.ChangeDescendant( itO.Value() );
+            TopTools_ListIteratorOfListOfShape itI (innerL);
+            // Loop on internal wires of current including wire
+            for (; itI.More(); itI.Next())
+              if ( outerW.IsSame( itI.Value() )) {
+                innerL.Remove( itI );   break;
+              }
+          }
+        }
+        EqWM.UnBind ( Hole );
+      }
+
+      if (nbEqW == EqWM.Extent())
+      {
+        // error: pb with wires classification
+#ifdef DEB
+        MESSAGE("Partition_Loop2d::WiresToFaces(), pb with wires classification");
+#endif
+        break;
+      }
+
+    } // while (!EqWM.IsEmpty)
+
+  } //  if !EqWM.IsEmpty()
+
+  myNewWires.Append ( myInternalWL );
+
+  TopTools_ListIteratorOfListOfShape itW (myNewWires);
+  for (; itW.More(); itW.Next()) {
+    TopoDS_Wire& W = TopoDS::Wire ( itW.Value() );
+    FR.Add(W);
+  }
+  FR.Perform();
+  for (; FR.IsDone() && FR.More(); FR.Next())
+    myNewFaces.Append(FR.Current());
+
+
+  TopTools_ListIteratorOfListOfShape itNF (myNewFaces);
+  for (; itNF.More(); itNF.Next())
+    itNF.Value().Orientation( myFaceOri );
+}
+
+#endif
diff --git a/contrib/Salome/Partition_Loop2d.hxx b/contrib/Salome/Partition_Loop2d.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..bdf1c2531df5ddb654088ca314ff6fe9c13f66db
--- /dev/null
+++ b/contrib/Salome/Partition_Loop2d.hxx
@@ -0,0 +1,106 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop2d.hxx
+//  Module : GEOM
+
+#ifndef _Partition_Loop2d_HeaderFile
+#define _Partition_Loop2d_HeaderFile
+
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _TopAbs_Orientation_HeaderFile
+#include <TopAbs_Orientation.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_MapOfShape_HeaderFile
+#include <TopTools_MapOfShape.hxx>
+#endif
+class TopoDS_Face;
+class TopoDS_Edge;
+class TopTools_ListOfShape;
+class BRepAlgo_Image;
+
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+
+class Partition_Loop2d  {
+
+public:
+
+   void* operator new(size_t,void* anAddress) 
+   {
+      return anAddress;
+   }
+   void* operator new(size_t size) 
+   { 
+      return Standard::Allocate(size); 
+   }
+   void  operator delete(void *anAddress) 
+   { 
+      if (anAddress) Standard::Free((Standard_Address&)anAddress); 
+   }
+   // Methods PUBLIC
+   // 
+   Partition_Loop2d();
+   void Init(const TopoDS_Face& F) ;
+   void AddConstEdge(const TopoDS_Edge& E) ;
+   void AddSectionEdge(const TopoDS_Edge& E) ;
+   void Perform() ;
+   const TopTools_ListOfShape& NewWires() const;
+   void WiresToFaces(const BRepAlgo_Image& EdgeImage) ;
+   const TopTools_ListOfShape& NewFaces() const;
+
+
+
+
+
+protected:
+
+   // Methods PROTECTED
+   // 
+
+
+   // Fields PROTECTED
+   //
+
+
+private: 
+
+   // Methods PRIVATE
+   // 
+
+
+   // Fields PRIVATE
+   //
+   TopoDS_Face myFace;
+   TopAbs_Orientation myFaceOri;
+   TopTools_ListOfShape myConstEdges;
+   TopTools_ListOfShape myNewWires;
+   TopTools_ListOfShape myNewFaces;
+   TopTools_ListOfShape myInternalWL;
+   TopTools_MapOfShape mySectionEdges;
+
+
+};
+
+
+
+
+
+// other Inline functions and methods (like "C++: function call" methods)
+//
+
+
+#endif
diff --git a/contrib/Salome/Partition_Loop2d.ixx b/contrib/Salome/Partition_Loop2d.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..2d35fd5c711b05df86cf40de88ec2d3c356b4998
--- /dev/null
+++ b/contrib/Salome/Partition_Loop2d.ixx
@@ -0,0 +1,14 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop2d.ixx
+//  Module : GEOM
+
+#include "Partition_Loop2d.jxx"
+
+ 
+
+
diff --git a/contrib/Salome/Partition_Loop2d.jxx b/contrib/Salome/Partition_Loop2d.jxx
new file mode 100644
index 0000000000000000000000000000000000000000..555c16c809d26712d52dba2a8ef0523eadf05262
--- /dev/null
+++ b/contrib/Salome/Partition_Loop2d.jxx
@@ -0,0 +1,24 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop2d.jxx
+//  Module : GEOM
+
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _TopoDS_Edge_HeaderFile
+#include <TopoDS_Edge.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _BRepAlgo_Image_HeaderFile
+#include <BRepAlgo_Image.hxx>
+#endif
+#ifndef _Partition_Loop2d_HeaderFile
+#include "Partition_Loop2d.hxx"
+#endif
diff --git a/contrib/Salome/Partition_Loop3d.cxx b/contrib/Salome/Partition_Loop3d.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b58457f7bc58b46f1156ba7cc81291f71224cef8
--- /dev/null
+++ b/contrib/Salome/Partition_Loop3d.cxx
@@ -0,0 +1,360 @@
+#ifdef OCCGEOMETRY
+
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop3d.cxx
+//  Module : GEOM
+
+#if !defined(HAVE_NO_OCC_CONFIG_H)
+#include <config.h>
+#endif
+
+//using namespace std;
+#include <climits>
+#include "Partition_Loop3d.ixx"
+
+#include <TopExp_Explorer.hxx>
+#include <TopExp.hxx>
+#include <BRep_Builder.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <gp_Vec.hxx>
+#include <gp_Pnt.hxx>
+#include <Geom2d_Curve.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec2d.hxx>
+#include <gp_Dir2d.hxx>
+#include <Geom_Curve.hxx>
+
+//=======================================================================
+//function : Partition_Loop3d
+//purpose  : 
+//=======================================================================
+
+Partition_Loop3d::Partition_Loop3d()
+{
+}
+
+//=======================================================================
+//function : AddConstFaces
+//purpose  : Add faces of <S> as unique faces in the result.
+//=======================================================================
+
+void Partition_Loop3d::AddConstFaces(const TopoDS_Shape& S) 
+{
+  TopExp_Explorer FaceExp(S, TopAbs_FACE);
+  for (; FaceExp.More(); FaceExp.Next())
+    myFaces.Append( FaceExp.Current() );
+
+  TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, myEFMap);
+}
+
+//=======================================================================
+//function : AddSectionFaces
+//purpose  : Add faces of <S> as double faces in the result.
+//=======================================================================
+
+void Partition_Loop3d::AddSectionFaces(const TopoDS_Shape& S) 
+{
+  AddConstFaces( S );
+  AddConstFaces( S.Reversed() );
+}
+
+//=======================================================================
+//function : MakeShells
+//purpose  : Make and return shells. 
+//           <AvoidFacesMap> can contain faces that must not be
+//           added to result shells.
+//=======================================================================
+
+const TopTools_ListOfShape&
+  Partition_Loop3d::MakeShells (const TopTools_MapOfOrientedShape& AvoidFacesMap)
+{
+  myNewShells.Clear();
+  
+  BRep_Builder Builder;
+  TopTools_MapOfShape CheckedEdgesMap;
+  TopTools_MapOfOrientedShape AddedFacesMap;
+  
+  TopTools_ListIteratorOfListOfShape itF (myFaces);
+  for (; itF.More(); itF.Next())
+  {
+    const TopoDS_Shape& FF = itF.Value();
+    if (AvoidFacesMap.Contains( FF ) ||
+	! AddedFacesMap.Add( FF ) )
+      continue;
+
+    // make a new shell
+    TopoDS_Shell Shell;
+    Builder.MakeShell(Shell);
+    Builder.Add(Shell,FF);
+
+    // clear the maps from shapes added to previous Shell
+    TopTools_MapIteratorOfMapOfShape itEM (CheckedEdgesMap);
+    for (; itEM.More(); itEM.Next()) {
+      TopTools_ListOfShape& FL = myEFMap.ChangeFromKey( itEM.Key());
+      TopTools_ListIteratorOfListOfShape it (FL);
+      while ( it.More()) {
+        if (AddedFacesMap.Contains( it.Value()))
+          FL.Remove( it );
+        else
+          it.Next();
+      }
+    }
+    CheckedEdgesMap.Clear();
+
+    
+    // loop on faces added to Shell; add their neighbor faces to Shell and so on
+    TopoDS_Iterator itAddedF (Shell);
+    for (; itAddedF.More(); itAddedF.Next())
+    {
+      const TopoDS_Face& F = TopoDS::Face (itAddedF.Value());
+
+      // loop on edges of F; find a good neighbor face of F by E
+      TopExp_Explorer EdgeExp(F, TopAbs_EDGE);
+      for (; EdgeExp.More(); EdgeExp.Next())
+      {
+        const TopoDS_Edge& E = TopoDS::Edge( EdgeExp.Current());
+	if (! CheckedEdgesMap.Add( E ))
+	  continue;
+
+	// candidate faces list
+        const TopTools_ListOfShape& FL = myEFMap.ChangeFromKey(E);
+        if (FL.IsEmpty())
+          continue;
+	// select one of neighbors
+        TopoDS_Face SelF;
+        if (FL.Extent() == 2) {
+          if (! F.IsSame( FL.First() ))
+            SelF = TopoDS::Face( FL.First() );
+          else if (!F.IsSame( FL.Last() ))
+            SelF = TopoDS::Face( FL.Last() );
+        }
+        else {
+          // check if a face already added to Shell shares E
+	  TopTools_ListIteratorOfListOfShape it (FL);
+          Standard_Boolean found = Standard_False;
+          for (; !found && it.More(); it.Next())
+            if (F != it.Value())
+              found = AddedFacesMap.Contains( it.Value() );
+          if (found)
+            continue;
+          // select basing on geometrical check
+          Standard_Boolean GoodOri, inside;
+          Standard_Real dot, MaxDot = -100;
+          TopTools_ListOfShape TangFL; // tangent faces
+          for ( it.Initialize( FL ) ; it.More(); it.Next()) {
+            const TopoDS_Face& NeighborF = TopoDS::Face( it.Value());
+            if (NeighborF.IsSame( F ))
+              continue;
+            inside = Partition_Loop3d::IsInside( E, F, NeighborF, 1, dot, GoodOri);
+            if (!GoodOri)
+              continue;
+            if (!inside)
+              dot = -dot - 3;
+            if (dot < MaxDot)
+              continue;
+            if ( IsEqual( dot, MaxDot))
+              TangFL.Append(SelF);
+            else
+              TangFL.Clear();
+            MaxDot = dot;
+            SelF = NeighborF;
+          }
+          if (!TangFL.IsEmpty()) {
+            for (it.Initialize( TangFL ); it.More(); it.Next()) {
+              const TopoDS_Face& NeighborF = TopoDS::Face( it.Value());
+              if (Partition_Loop3d:: IsInside( E, SelF , NeighborF, 0, dot, GoodOri))
+                SelF = NeighborF;
+            }
+          }
+        }
+        if (!SelF.IsNull() &&
+	    AddedFacesMap.Add( SelF ) &&
+	    !AvoidFacesMap.Contains( SelF )) 
+          Builder.Add( Shell, SelF);
+
+      } // loop on edges of F
+      
+    } // loop on the faces added to Shell
+
+    // Shell is complete
+    myNewShells.Append( Shell );
+
+  } // loop on myFaces
+
+
+  // prepare to the next call
+  myFaces.Clear();
+  myEFMap.Clear();
+
+  return myNewShells;
+}
+
+
+
+//=======================================================================
+//function : Normal
+//purpose  : 
+//=======================================================================
+
+gp_Vec Partition_Loop3d::Normal(const TopoDS_Edge& E,
+				const TopoDS_Face& F)
+{
+  gp_Vec Norm, V1, V2;
+  Standard_Real First, Last;
+  gp_Pnt Ps;
+
+  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last);
+  Handle(Geom_Surface) Sf = BRep_Tool::Surface(F);
+
+  gp_Pnt2d p = C2d->Value( 0.5*(First+Last) );
+  Sf->D1(p.X(), p.Y(), Ps, V1, V2);
+  Norm = V1.Crossed(V2);
+
+  if (F.Orientation() == TopAbs_REVERSED ) 
+    Norm.Reverse();
+
+  return Norm;
+}
+
+//=======================================================================
+//function : NextNormal
+//purpose  : find normal to F at point a little inside F near the middle of E
+//warning  : E must be properly oriented in F.
+//=======================================================================
+
+static gp_Vec NextNormal(const TopoDS_Edge& E,
+			 const TopoDS_Face& F)
+{
+  Standard_Real First, Last;
+
+  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last);
+  Handle(Geom_Surface) Sf = BRep_Tool::Surface(F);
+
+  gp_Pnt2d p;
+  gp_Vec2d v;
+  C2d->D1( 0.5*(First+Last), p, v);
+  if (E.Orientation() != F.Orientation())
+    v.Reverse();
+  gp_Dir2d dir( -v.Y(), v.X() ); // dir inside F
+  
+  Standard_Real duv = 1e-6; // this is not Ok and may give incorrect result if
+  // resolutionUV of compared faces is very different. To have a good result,
+  //it is necessary to get normal to faces at points equidistant from E in 3D
+  
+  p.SetX( p.X() + dir.X()*duv );
+  p.SetY( p.Y() + dir.Y()*duv );
+  
+  gp_Pnt Ps;
+  gp_Vec Norm, V1, V2, VV1, VV2;
+  Sf->D1( p.X(), p.Y(), Ps, V1, V2);
+  Norm = V1.Crossed(V2);
+
+  if (F.Orientation() == TopAbs_REVERSED ) 
+    Norm.Reverse();
+
+  return Norm;
+}
+
+
+//=======================================================================
+//function : FindEinF
+//purpose  : find E in F
+//=======================================================================
+
+static TopoDS_Edge FindEinF(const TopoDS_Edge& E,
+			    const TopoDS_Face& F)
+{
+  TopExp_Explorer expl (F, TopAbs_EDGE);
+  for (; expl.More(); expl.Next()) 
+    if( E.IsSame( expl.Current() ))
+      return TopoDS::Edge(expl.Current());
+  TopoDS_Edge nullE;
+  return nullE;
+}
+
+//=======================================================================
+//function : IsInside
+//purpose  : check if <F2> is inside <F1> by edge <E>.
+//           if <CountDot>, compute <Dot>: scalar production of
+//           normalized  vectors  pointing  inside  faces,  and
+//           check if faces are oriented well for sewing
+//=======================================================================
+
+Standard_Boolean Partition_Loop3d::IsInside(const TopoDS_Edge& E,
+					    const TopoDS_Face& F1,
+					    const TopoDS_Face& F2,
+					    const Standard_Boolean CountDot,
+					    Standard_Real& Dot,
+					    Standard_Boolean& GoodOri) 
+{
+  Standard_Real f, l;
+  gp_Pnt P;
+  gp_Vec Vc1, Vc2, Vin1, Vin2, Nf1, Nf2;
+  Handle(Geom_Curve) Curve = BRep_Tool::Curve(E,f,l);
+  Curve->D1( 0.5*(f + l), P, Vc2);
+  TopoDS_Edge E1, E2 = FindEinF (E, F2);
+  if (E2.Orientation() == TopAbs_REVERSED ) Vc2.Reverse();
+
+  Nf1 = Normal(E,F1);
+  Nf2 = Normal(E,F2);
+
+  Standard_Real sin =
+    Nf1.CrossSquareMagnitude(Nf2) / Nf1.SquareMagnitude() / Nf2.SquareMagnitude();
+  Standard_Boolean tangent = sin < 0.001;
+
+  Standard_Boolean inside = 0;
+  if (tangent) {
+    E1 = FindEinF (E, F1);
+    gp_Vec NNf1 = NextNormal(E1,F1);
+    gp_Vec NNf2 = NextNormal(E2,F2);
+    Vin2 = NNf2.Crossed(Vc2);
+    inside = Vin2 * NNf1 < 0;
+  }
+  else {
+    Vin2 = Nf2.Crossed(Vc2);
+    inside = Vin2 * Nf1 < 0;
+  }
+  
+  if (!CountDot) return inside;
+
+  if (tangent)
+    Vin2 = Nf2.Crossed(Vc2);
+  else
+    E1 = FindEinF (E, F1);
+    
+  Vc1 = Vc2;
+  if (E1.Orientation() != E2.Orientation()) 
+    Vc1.Reverse();
+  Vin1 = Nf1.Crossed(Vc1);
+
+  if (tangent) {
+    Standard_Real N1N2 = Nf1 * Nf2;
+    GoodOri = (Vin2 * Vin1 < 0) ? N1N2 > 0 : N1N2 < 0;
+  }
+  else {
+    Standard_Real V1N2 = Vin1 * Nf2;
+    GoodOri = ( inside ? V1N2 <= 0 : V1N2 >= 0);
+  }
+
+  Vin1.Normalize();
+  Vin2.Normalize();
+  
+  Dot = Vin2 * Vin1;
+  
+  return inside;
+}
+
+
+#endif
diff --git a/contrib/Salome/Partition_Loop3d.hxx b/contrib/Salome/Partition_Loop3d.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..7f08d74eb7ff84cee88a44210db55293bf404ba5
--- /dev/null
+++ b/contrib/Salome/Partition_Loop3d.hxx
@@ -0,0 +1,104 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop3d.hxx
+//  Module : GEOM
+
+#ifndef _Partition_Loop3d_HeaderFile
+#define _Partition_Loop3d_HeaderFile
+
+//using namespace std;
+
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_IndexedDataMapOfShapeListOfShape_HeaderFile
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#endif
+#ifndef _Standard_Boolean_HeaderFile
+#include <Standard_Boolean.hxx>
+#endif
+#ifndef _Standard_Real_HeaderFile
+#include <Standard_Real.hxx>
+#endif
+class TopoDS_Shape;
+class TopTools_ListOfShape;
+class TopTools_MapOfOrientedShape;
+class TopoDS_Edge;
+class TopoDS_Face;
+class gp_Vec;
+
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+
+class Partition_Loop3d  {
+
+public:
+
+   void* operator new(size_t,void* anAddress) 
+   {
+      return anAddress;
+   }
+   void* operator new(size_t size) 
+   { 
+      return Standard::Allocate(size); 
+   }
+   void  operator delete(void *anAddress) 
+   { 
+      if (anAddress) Standard::Free((Standard_Address&)anAddress); 
+   }
+   // Methods PUBLIC
+   // 
+   Partition_Loop3d();
+   void AddConstFaces(const TopoDS_Shape& S) ;
+   void AddSectionFaces(const TopoDS_Shape& S) ;
+   const TopTools_ListOfShape& MakeShells(const TopTools_MapOfOrientedShape& AvoidFacesMap) ;
+   static  Standard_Boolean IsInside(const TopoDS_Edge& E,const TopoDS_Face& F1,const TopoDS_Face& F2,const Standard_Boolean CountDot,Standard_Real& Dot,Standard_Boolean& GoodOri) ;
+   static  gp_Vec Normal(const TopoDS_Edge& E,const TopoDS_Face& F) ;
+
+
+
+
+
+protected:
+
+   // Methods PROTECTED
+   // 
+
+
+   // Fields PROTECTED
+   //
+
+
+private: 
+
+   // Methods PRIVATE
+   // 
+
+
+   // Fields PRIVATE
+   //
+   TopTools_ListOfShape myNewShells;
+   TopTools_ListOfShape myFaces;
+   TopTools_IndexedDataMapOfShapeListOfShape myEFMap;
+
+
+};
+
+
+
+
+
+// other Inline functions and methods (like "C++: function call" methods)
+//
+
+
+#endif
diff --git a/contrib/Salome/Partition_Loop3d.ixx b/contrib/Salome/Partition_Loop3d.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..a661b3242dafae68300a92a3cf42e7074ce5aeb0
--- /dev/null
+++ b/contrib/Salome/Partition_Loop3d.ixx
@@ -0,0 +1,14 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop3d.ixx
+//  Module : GEOM
+
+#include "Partition_Loop3d.jxx"
+
+ 
+
+
diff --git a/contrib/Salome/Partition_Loop3d.jxx b/contrib/Salome/Partition_Loop3d.jxx
new file mode 100644
index 0000000000000000000000000000000000000000..9b654f41bb1a23a11c80d65fe9128e5a5830798d
--- /dev/null
+++ b/contrib/Salome/Partition_Loop3d.jxx
@@ -0,0 +1,30 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Loop3d.jxx
+//  Module : GEOM
+
+#ifndef _TopoDS_Shape_HeaderFile
+#include <TopoDS_Shape.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_MapOfOrientedShape_HeaderFile
+#include <TopTools_MapOfOrientedShape.hxx>
+#endif
+#ifndef _TopoDS_Edge_HeaderFile
+#include <TopoDS_Edge.hxx>
+#endif
+#ifndef _TopoDS_Face_HeaderFile
+#include <TopoDS_Face.hxx>
+#endif
+#ifndef _gp_Vec_HeaderFile
+#include <gp_Vec.hxx>
+#endif
+#ifndef _Partition_Loop3d_HeaderFile
+#include "Partition_Loop3d.hxx"
+#endif
diff --git a/contrib/Salome/Partition_Spliter.cxx b/contrib/Salome/Partition_Spliter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..87639d2b344b41cde3b4449cb00afb91012ce363
--- /dev/null
+++ b/contrib/Salome/Partition_Spliter.cxx
@@ -0,0 +1,2175 @@
+#ifdef OCCGEOMETRY
+
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Spliter.cxx
+//  Author : Benedicte MARTIN
+//  Module : GEOM
+//  $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Spliter.cxx,v 1.7 2008/03/31 14:20:28 wabro Exp $
+
+#if !defined(HAVE_NO_OCC_CONFIG_H)
+#include <config.h>
+#endif
+
+//using namespace std;
+#include <climits>
+#include "Partition_Inter2d.hxx"
+#include "Partition_Inter3d.hxx"
+#include "Partition_Loop2d.hxx"
+#include "Partition_Loop3d.hxx"
+#include "Partition_Spliter.ixx"
+
+//#include "utilities.h"
+
+#include <Precision.hxx>
+#include <TopAbs_Orientation.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+
+#include <Geom2d_Curve.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+
+#include <BRepBndLib.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepLib.hxx>
+#include <BRep_Tool.hxx>
+
+#include <Extrema_ExtPC.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <TopOpeBRepTool_CurveTool.hxx>
+
+#ifdef DEB
+//# define PART_PERF
+#endif
+
+#ifdef PART_PERF
+# include <OSD_Chronometer.hxx>
+#endif
+
+//=======================================================================
+//function : isClosed
+//purpose  : check id a shape is closed, ie is a solid or a closed shell
+//=======================================================================
+
+static Standard_Boolean isClosed(const TopoDS_Shape& theShape)
+{
+  Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
+
+  if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
+    TopTools_IndexedDataMapOfShapeListOfShape MEF;
+    TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
+    for (Standard_Integer i=1;  isClosed && i<=MEF.Extent();  ++i)
+      isClosed = ( MEF(i).Extent() != 1 );
+  }
+  
+  return isClosed;
+}
+
+//=======================================================================
+//function : Partition_Spliter
+//purpose  : constructor
+//=======================================================================
+
+Partition_Spliter::Partition_Spliter()
+{
+  myAsDes = new BRepAlgo_AsDes;
+  Clear();
+}
+
+//=======================================================================
+//function : AddTool
+//purpose  : add cutting tool that will _NOT_ be in result
+//=======================================================================
+
+void Partition_Spliter::AddTool(const TopoDS_Shape& S)
+{
+  if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
+    TopoDS_Iterator it (S);
+    for (; it.More(); it.Next())
+    {
+      AddTool( it.Value());
+      myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape
+    }
+    return;
+  }
+
+  for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next())
+  {
+    myMapTools.Add(exp.Current());
+    myFaceShapeMap.Bind( exp.Current(), S );
+  }
+  if (isClosed( S ))
+    myClosedShapes.Add( S );
+}
+
+//=======================================================================
+//function : AddShape
+//purpose  : add object Shape to be splited
+//=======================================================================
+
+void Partition_Spliter::AddShape(const TopoDS_Shape& S)
+{
+  if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
+    TopoDS_Iterator it (S);
+    for (; it.More(); it.Next())
+    {
+      AddShape( it.Value());
+      myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape
+    }
+    return;
+  }
+
+  TopExp_Explorer exp(S,TopAbs_FACE);
+  if (!exp.More()) { // do not split edges and vertices
+    //myBuilder.Add( myShape, S );
+    return;
+  }
+
+  Standard_Integer nbFacesBefore = myMapFaces.Extent(); // not to add twice the same S
+  for (; exp.More(); exp.Next()) {
+    const TopoDS_Shape & aFace = exp.Current();
+    if ( ! myFaceShapeMap.IsBound( aFace )) // keep shape of tool face added as object
+      myFaceShapeMap.Bind( aFace, S );
+    if (myMapFaces.Add( aFace ))
+      myImagesFaces.SetRoot( aFace );
+  }
+
+  if (nbFacesBefore == myMapFaces.Extent())
+    return;
+
+  // solids must be processed before all
+  if (S.ShapeType() == TopAbs_SOLID)
+    myListShapes.Prepend(S);
+  else
+    myListShapes.Append(S);
+
+  if (isClosed( S ))
+    myClosedShapes.Add( S );
+
+}
+
+//=======================================================================
+//function : Shape
+//purpose  : return resulting compound
+//=======================================================================
+
+TopoDS_Shape Partition_Spliter::Shape() const
+{
+  return myShape;
+}
+
+//=======================================================================
+//function : Clear
+//purpose  : clear fields
+//=======================================================================
+
+void Partition_Spliter::Clear()
+{
+  myDoneStep = TopAbs_SHAPE;
+  
+  myListShapes.Clear();
+  myMapFaces.Clear();
+  myMapTools.Clear();
+  myEqualEdges.Clear();
+  myNewSection.Clear();
+  myClosedShapes.Clear();
+  mySharedFaces.Clear();
+  myWrappingSolid.Clear();
+  myFaceShapeMap.Clear();
+  
+  myInternalFaces.Clear();
+  myIntNotClFaces.Clear();
+  
+  myAsDes->Clear();
+  myImagesFaces.Clear();
+  myImagesEdges.Clear();
+  myImageShape.Clear();
+  
+  //  myInter3d = Partition_Inter3d(myAsDes);
+  Partition_Inter3d hinter3d (myAsDes);
+  myInter3d = hinter3d;
+  
+  myAddedFacesMap.Clear();
+
+}
+
+//=======================================================================
+//function : Compute
+//purpose  : produce a result
+//=======================================================================
+
+void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit)
+{
+  if ((Limit != TopAbs_SHAPE && myDoneStep == Limit) ||
+      (Limit == TopAbs_SHAPE && myDoneStep == TopAbs_SOLID))
+    return;
+  
+  myBuilder.MakeCompound( myShape );
+  
+  TopTools_MapIteratorOfMapOfShape it;
+  TopTools_ListIteratorOfListOfShape itl;
+  TopExp_Explorer exp;
+
+#ifdef PART_PERF
+  OSD_Chronometer aCron;
+#endif
+
+  if (myDoneStep > TopAbs_VERTEX) {
+
+    TopTools_ListOfShape aListFaces;
+    aListFaces = myImagesFaces.Roots();
+    for (it.Initialize(myMapTools); it.More(); it.Next())
+      aListFaces.Append(it.Key());
+
+#ifdef PART_PERF
+    aCron.Start();
+#endif
+
+    //-----------------------------------------------
+    // Intersection between faces
+    //-----------------------------------------------
+    // result is in myAsDes as a map Face - list of new edges;
+    // special care is done for section edges, same domain faces and vertices:
+    // data about them is inside myInter3d
+    myInter3d.CompletPart3d(aListFaces, myFaceShapeMap);
+
+#ifdef PART_PERF
+    MESSAGE("+++ CompletPart3d()");
+    aCron.Show( cout );
+    aCron.Reset();
+    aCron.Start();
+#endif
+    //-----------------------------------------------
+    // Intersection of edges
+    //-----------------------------------------------
+
+    // add tool faces which must be reconstructed to myMapFaces too
+    FindToolsToReconstruct();
+
+#ifdef PART_PERF
+    MESSAGE("+++ FindToolsToReconstruct()");
+    aCron.Show( cout );
+    aCron.Reset();
+    aCron.Start();
+#endif
+
+    // add existing vertices to edges of object faces in myAsDes
+    TopTools_MapOfShape DoneEM;
+    for ( it.Initialize(myMapFaces); it.More(); it.Next()) {
+      const TopoDS_Shape& F  = it.Key();
+      TopoDS_Face FForward = TopoDS::Face(F.Oriented(TopAbs_FORWARD));
+      for (exp.Init(FForward,TopAbs_EDGE); exp.More(); exp.Next()) {
+        const TopoDS_Edge& E = TopoDS::Edge( exp.Current() );
+        myAsDes->Add(FForward,E);
+        if (DoneEM.Add(E)) {
+          TopoDS_Iterator itV(E);
+          for (; itV.More(); itV.Next()) {
+            const TopoDS_Vertex& V = TopoDS::Vertex( itV.Value());
+            myAsDes->Add(E, myInter3d.ReplaceSameDomainV( V, E ));
+          }
+        }
+      }
+    }
+
+    // intersect edges that are descendants of a face in myAsDes
+    TopTools_MapOfShape& Modif = myInter3d.TouchedFaces();
+    for ( it.Initialize(Modif); it.More(); it.Next()) {
+      const TopoDS_Face& F  = TopoDS::Face(it.Key());
+      Partition_Inter2d::CompletPart2d (myAsDes, F, myInter3d.NewEdges());
+    }
+    // now myAsDes contains also new vertices made at edge intersection as
+    // descendant of edges both new and old
+
+    myDoneStep = TopAbs_VERTEX;
+    
+#ifdef PART_PERF
+    MESSAGE("+++ CompletPart2d()");
+    aCron.Show( cout );
+    aCron.Reset();
+    aCron.Start();
+#endif
+  } //   if (myDoneStep > TopAbs_VERTEX)
+  
+  if (Limit == TopAbs_VERTEX) {
+    // add new vertices to myShape
+    for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) {
+      if (! myAsDes->HasDescendant( it.Key() ))
+        continue;
+      itl.Initialize( myAsDes->Descendant( it.Key() ));
+      for (; itl.More(); itl.Next()) 
+        myBuilder.Add ( myShape, itl.Value() );
+    }
+    return;
+  }
+  
+
+  if (myDoneStep > TopAbs_EDGE) {
+
+    //-----------------------------------------------
+    //-----------------------------------------------
+    // ------- Reconstruction of all the edges.------
+    //-----------------------------------------------
+    //-----------------------------------------------
+
+    // ==============
+    // cut new edges
+    // ==============
+    TopTools_ListOfShape LSE; // all edge splits
+    for ( it.Initialize(myInter3d.NewEdges()); it.More(); it.Next()) {
+
+      TopoDS_Vertex V1,V2;
+      TopoDS_Edge EE = TopoDS::Edge(it.Key());
+
+      TopTools_ListOfShape aListV, aListF;
+      aListV = myAsDes->Descendant(EE); // intersection vertices
+      aListF = myAsDes->Ascendant(EE);  // intersected faces
+
+      if (aListV.IsEmpty())
+        continue;  // new edge does not intersect any other edge
+
+      // Add end vertices to new edges only if 
+      // one face is Tool and the other is Shape
+      Standard_Boolean isTool1 = ! myMapFaces.Contains( aListF.First() );
+      Standard_Boolean isTool2 = ! myMapFaces.Contains( aListF.Last() );
+      if (isTool1 || isTool2)
+      {
+        TopExp::Vertices(EE,V1,V2);
+	Standard_Real Tol = Max (BRep_Tool::Tolerance( V1 ),
+				 BRep_Tool::Tolerance( V2 ));
+
+        gp_Pnt P1 = BRep_Tool::Pnt(V1);
+        gp_Pnt P2 = BRep_Tool::Pnt(V2);
+        Standard_Boolean AddV1 = Standard_True;
+        Standard_Boolean AddV2 = Standard_True;
+
+        // add only if there is no intersection at end vertex
+        for (itl.Initialize(aListV); itl.More(); itl.Next()) {
+          const TopoDS_Vertex& Ve = TopoDS::Vertex(itl.Value()) ;
+          Standard_Real Tol2 = Max ( Tol, BRep_Tool::Tolerance( Ve ));
+          Tol2 *= Tol2;
+          gp_Pnt P = BRep_Tool::Pnt(Ve);
+          if (AddV1 && P.SquareDistance(P1) <= Tol2)
+            AddV1 = Standard_False;
+
+          if (AddV2 && P.SquareDistance(P2) <= Tol2) 
+            AddV2 = Standard_False;
+        }
+
+        if (AddV1) {
+          aListV.Append(V1);
+          myAsDes->Add(EE,V1);
+        }
+
+        if (AddV2) {
+          aListV.Append(V2);
+          myAsDes->Add(EE,V2);
+        }
+      }
+
+      // cut new edges
+      Standard_Integer NbV=aListV.Extent() ;
+      if (NbV>1 || (NbV==1 && V1.IsSame(V2)) ) {
+        TopTools_ListOfShape LNE;
+        MakeEdges (EE,aListV, LNE);
+        myImagesEdges.Bind(EE,LNE);
+	LSE.Append( LNE );
+      }
+    }
+
+    // ==============
+    // cut old edges
+    // ==============
+    for ( it.Initialize(myMapFaces); it.More(); it.Next()) {
+      for (exp.Init( it.Key(), TopAbs_EDGE); exp.More(); exp.Next()) {
+        const TopoDS_Edge& EE = TopoDS::Edge( exp.Current() );
+        if ( myImagesEdges.HasImage( EE ))
+          continue;
+        TopTools_ListOfShape  LNE;
+        const TopTools_ListOfShape& aListVV = myAsDes->Descendant(EE);
+        MakeEdges (EE, aListVV, LNE);
+        myImagesEdges.Bind(EE,LNE);
+	LSE.Append( LNE );
+      }
+    }
+#ifdef PART_PERF
+    MESSAGE("+++ Cut Edges");
+    aCron.Show( cout );
+    aCron.Reset();
+    aCron.Start();
+#endif
+
+    // process same domain section edges
+    MergeEqualEdges( LSE );
+    
+    myDoneStep = TopAbs_EDGE;
+    
+#ifdef PART_PERF
+    MESSAGE("+++ MergeEqualEdges()");
+    aCron.Show( cout );
+    aCron.Reset();
+    aCron.Start();
+#endif
+  }  //   if (myDoneStep > TopAbs_EDGE) 
+
+  if (Limit == TopAbs_EDGE) {
+    // add splits of old edges
+    TopTools_ListIteratorOfListOfShape itNE;
+    for (itl.Initialize( myListShapes );itl.More();itl.Next()) {
+      if (myMapTools.Contains( itl.Value() ))
+        continue; // skip tool faces
+      for ( exp.Init( itl.Value(), TopAbs_EDGE ); exp.More(); exp.Next()) {
+	itNE.Initialize( myImagesEdges.Image( exp.Current() ));
+	for ( ; itNE.More(); itNE.Next())
+	  myBuilder.Add ( myShape, itNE.Value() );
+      }
+    }
+    // add splits of new edges
+    for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) {
+      itNE.Initialize( myImagesEdges.Image( it.Key() ));
+      for (; itNE.More(); itNE.Next())
+        myBuilder.Add ( myShape, itNE.Value() );
+    }
+    return;
+  }
+  
+  
+  //-----------------------------------------------
+  // split faces
+  //-----------------------------------------------
+
+  if (myDoneStep > TopAbs_FACE) {
+    
+    for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
+      TopoDS_Shape FacesComp = MakeFaces ( itl.Value());
+      // there is a cunning here: myImagesFaces keeps faces made by Loop2d
+      // but some of them may be replaced with splits of same domain face
+      // and myImageShape keeps ultimate result
+      myImageShape.Bind( itl.Value(), FacesComp );
+    }
+    
+    myDoneStep = TopAbs_FACE;
+#ifdef PART_PERF
+    MESSAGE("+++ MakeFaces()");
+    aCron.Show( cout );
+    aCron.Reset();
+    aCron.Start();
+#endif
+  }
+  
+  if (Limit == TopAbs_WIRE ||
+      Limit == TopAbs_FACE)   {
+    for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
+      if ( myMapTools.Contains( itl.Value() ))
+	continue; // no result needed for a tool face
+      const TopoDS_Shape& FacesComp = myImageShape.Image( itl.Value() ).First();
+      for ( exp.Init( FacesComp, Limit); exp.More(); exp.Next())
+	myBuilder.Add ( myShape, exp.Current());
+    }
+    return;
+  }
+
+  
+  //-----------------------------------------------
+  // split and add solids and shells
+  //-----------------------------------------------
+
+  Standard_Boolean makeSolids = (Limit == TopAbs_SHAPE ||
+				 Limit < TopAbs_SHELL);
+  for (itl.Initialize(myListShapes);itl.More();itl.Next())
+  {
+    const TopoDS_Shape & S = itl.Value();
+    if (S.ShapeType() > TopAbs_SHELL)
+      continue;
+
+    TopTools_ListOfShape NSL; // new shape list
+    MakeShells (S , NSL);
+    if (makeSolids && S.ShapeType() == TopAbs_SOLID )
+      MakeSolids( S, NSL );
+
+    // store new shells or solids
+    TopTools_ListIteratorOfListOfShape itNSL (NSL);
+    for ( ; itNSL.More(); itNSL.Next()) 
+      myBuilder.Add (myShape, itNSL.Value());
+  }
+#ifdef PART_PERF
+    MESSAGE("+++ MakeShells()");
+    aCron.Show( cout );
+#endif
+
+  //-----------------------------------------------
+  // add split faces
+  //-----------------------------------------------
+
+  for (itl.Initialize(myListShapes);itl.More();itl.Next())
+  {
+    const TopoDS_Shape & S = itl.Value();
+    if (S.ShapeType() != TopAbs_FACE ||
+        myMapTools.Contains( S ))
+      continue; 
+    TopoDS_Iterator itS( myImageShape.Image(S).First() );
+    for (; itS.More(); itS.Next())
+      if (! myAddedFacesMap.Contains( itS.Value() ))
+        myBuilder.Add (myShape, itS.Value());
+  }
+
+  myDoneStep = makeSolids ? TopAbs_SOLID : TopAbs_SHELL;
+  
+}
+
+//=======================================================================
+//function : MakeSolids
+//purpose  : make solids out of Shells
+//=======================================================================
+
+void Partition_Spliter::MakeSolids(const TopoDS_Shape &   theSolid,
+                                   TopTools_ListOfShape & theShellList)
+{
+  // for a solid wrapping other shells or solids without intersection,
+  // it is necessary to find shells making holes in it
+
+  TopTools_ListOfShape aNewSolids; // result
+  TopTools_ListOfShape aHoleShells;
+  TopoDS_Shape anInfinitePointShape;
+
+  Standard_Boolean isWrapping = myWrappingSolid.Contains( theSolid );
+  if (!isWrapping && !theShellList.IsEmpty())
+  {
+    // check if theSolid initially has internal shells
+    TopoDS_Iterator aShellExp (theSolid);
+    aShellExp.Next();
+    isWrapping = aShellExp.More();
+  }
+  
+  TopTools_ListIteratorOfListOfShape aShellIt(theShellList);
+  for ( ; aShellIt.More(); aShellIt.Next())
+  {
+    const TopoDS_Shape & aShell = aShellIt.Value();
+
+    // check if a shell is a hole
+    if (isWrapping && IsInside (anInfinitePointShape, aShell))
+      aHoleShells.Append( aShell );
+    else
+    {
+      // make a solid from a shell
+      TopoDS_Solid Solid;
+      myBuilder.MakeSolid( Solid );
+      myBuilder.Add (Solid, aShell);
+
+      aNewSolids.Append (Solid);
+    }
+  }
+
+  // find an outer shell most close to each hole shell
+  TopTools_DataMapOfShapeShape aInOutMap;
+  for (aShellIt.Initialize( aHoleShells ); aShellIt.More(); aShellIt.Next())
+  {
+    const TopoDS_Shape & aHole = aShellIt.Value();
+    TopTools_ListIteratorOfListOfShape aSolisIt (aNewSolids);
+    for ( ; aSolisIt.More(); aSolisIt.Next())
+    {
+      const TopoDS_Shape & aSolid = aSolisIt.Value();
+      if (! IsInside( aHole, aSolid ))
+        continue;
+
+      if ( aInOutMap.IsBound (aHole))
+      {
+        const TopoDS_Shape & aSolid2 = aInOutMap( aHole );
+        if ( IsInside( aSolid, aSolid2 ))
+        {
+          aInOutMap.UnBind( aHole );
+          aInOutMap.Bind ( aHole, aSolid );
+        }
+      }
+      else
+        aInOutMap.Bind ( aHole, aSolid );
+    }
+
+    // add aHole to a solid
+    if (aInOutMap.IsBound( aHole ))
+      myBuilder.Add ( aInOutMap( aHole ), aHole );
+  }
+
+  theShellList.Clear();
+  theShellList.Append( aNewSolids );
+}
+ 
+//=======================================================================
+//function : FindFacesInside
+//purpose  : return compound of faces  of other shapes that are
+//           inside <theShape>. 
+//           <theShape> is an object shape.
+//           <CheckClosed> makes avoid faces that do not form a
+//           closed shell
+//           <All> makes return already added faces
+//=======================================================================
+
+TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape,
+						const Standard_Boolean CheckClosed,
+						const Standard_Boolean All)
+{
+  // ================================================
+  // check if internal faces have been already found
+  // ================================================
+  TopExp_Explorer expl;
+  if (myInternalFaces.IsBound( theShape ))
+  {
+    TopoDS_Shape aIntFComp = myInternalFaces.Find ( theShape );
+    TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find ( theShape );
+
+    expl.Init( aIntRemFComp, TopAbs_FACE);
+    if (CheckClosed || !expl.More())
+      return aIntFComp;
+
+    TopoDS_Compound C;
+    myBuilder.MakeCompound( C );
+    // add removed faces
+    for (; expl.More(); expl.Next())
+      myBuilder.Add( C, expl.Current() );
+    // add good internal faces
+    for (expl.Init( aIntFComp, TopAbs_FACE); expl.More(); expl.Next())
+      myBuilder.Add( C, expl.Current() );
+    return C;
+  }
+
+  // ===================================
+  // get data for internal faces search
+  // ===================================
+
+  // compound of split faces of theShape 
+  const TopoDS_Shape& CSF = myImageShape.Image(theShape).First();
+
+  TopTools_MapOfShape MSE, MFP;
+  TopTools_DataMapOfShapeListOfShape DMSEFP;
+  TopTools_MapIteratorOfMapOfShape itm;
+  TopTools_ListOfShape EmptyL;
+
+  // MSE filling: map of new section edges of CSF
+  for (expl.Init(CSF,TopAbs_EDGE); expl.More(); expl.Next()) {
+    const TopoDS_Shape & resE = expl.Current() ;
+    if (myNewSection.Contains( resE )) // only new edges
+      MSE.Add(resE);
+  }
+
+  // DMEF: map edge of CSF - faces of CSF
+  TopTools_IndexedDataMapOfShapeListOfShape DMEF;
+  TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF);
+
+  // Fill
+  // 1.  MFP - a map of faces to process: map of resulting faces except
+  // those of theShape; we`ll add to C those of them which are inside CSF
+  // 2.  DMSEFP - edge of MSE => faces of MFP
+  TopTools_ListIteratorOfListOfShape itl;
+  for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
+    const TopoDS_Shape& aShape = itl.Value();
+    if ( theShape.IsSame( aShape )) continue;
+    // fill maps
+    // iterate on split faces of aShape
+    TopoDS_Iterator itF ( myImageShape.Image(aShape).First() );
+    for ( ; itF.More(); itF.Next()) {
+      const TopoDS_Shape& sf = itF.Value();
+      MFP.Add(sf);
+      // iterate on edges of split faces of aShape,
+      // add to DMSEFP edges that are new
+      for (expl.Init( sf, TopAbs_EDGE ); expl.More(); expl.Next()) {
+	TopoDS_Shape se = expl.Current();
+	if ( MSE.Contains(se)) {// section edge
+	  if (!DMSEFP.IsBound(se)) 
+	    DMSEFP.Bind(se,EmptyL);
+	  DMSEFP(se).Append(sf);
+	}
+      }
+    }
+  }
+
+  // add tool faces having section edges on faces of theShape to MFP and DMSEFP;
+  // such tool faces need not to be reconstructed and so they are not in myListShapes
+  for (itm.Initialize(myMapTools); itm.More(); itm.Next())
+  {
+    const TopoDS_Shape & aToolFace = itm.Key();
+    if (myMapFaces.Contains( aToolFace ))
+      continue;
+    MFP.Add(aToolFace);
+    for (expl.Init( aToolFace, TopAbs_EDGE ); expl.More(); expl.Next()) {
+      TopoDS_Shape se = expl.Current();
+      if ( MSE.Contains( se )) {// section edge
+        if (!DMSEFP.IsBound( se )) 
+          DMSEFP.Bind( se, EmptyL );
+        DMSEFP( se ).Append( aToolFace );
+      }
+    }
+  }
+  
+
+  // ===========================
+  // find faces inside theShape
+  // ===========================
+
+  Standard_Boolean skipAlreadyAdded = Standard_False;
+  Standard_Boolean GoodOri, inside;
+  Standard_Real dot;
+  TopTools_ListOfShape KeepFaces;
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
+
+  // iterate on section edges, check faces of other shapes
+  // sharing section edges and put internal faces to KeepFaces
+  for (Mapit.Initialize(DMSEFP); Mapit.More() ; Mapit.Next() ) {
+    // a new edge of theShape
+    const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key());
+    // an original edge of which E is a split
+    const TopoDS_Edge& OrigE = TopoDS::Edge ( myImagesEdges.Root( E ));
+    // does OrigE itself splits a face
+    Standard_Boolean isSectionE = myInter3d.IsSectionEdge ( OrigE );
+
+    // split faces of other shapes sharing E
+    TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E);
+    itl.Initialize( LSF );
+    while (itl.More()) {
+      // a split faces of other shape
+      TopoDS_Face aFace1 = TopoDS::Face(itl.Value());
+      // remove aFace1 form DMSEFP and MFP
+      LSF.Remove( itl ); // == itl.Next();
+      if (!MFP.Remove( aFace1 ))
+	continue; // was not is MFP ( i.e already checked)
+      // check if aFace1 was already added to 2 shells
+      if (!All &&
+	  myAddedFacesMap.Contains( aFace1 ) &&
+	  myAddedFacesMap.Contains( aFace1.Reversed() )) {
+	skipAlreadyAdded = Standard_True;
+	continue;
+      }
+
+      // find another face which originates from the same face as aFace1:
+      // usually aFace2 is internal if aFace1 is not and vice versa
+
+      TopoDS_Shape anOrigFace = aFace1;
+      if (myImagesFaces.IsImage(aFace1))
+        anOrigFace = myImagesFaces.Root(aFace1);
+      TopoDS_Shape aFace2;
+      if ( !isSectionE ) {
+        while (itl.More()) {
+          aFace2 = itl.Value();
+          if (!MFP.Contains( aFace2 )) {
+            LSF.Remove( itl );
+            continue;
+          }
+          if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 )))
+            break;
+          itl.Next();
+        }
+        if (itl.More()) { // aFace2 found, remove it from maps
+          LSF.Remove( itl );
+          MFP.Remove(aFace2);
+        }
+        else
+          aFace2.Nullify();
+        itl.Initialize( LSF );
+      }
+
+      // check that anOrigFace is not same domain with CSF faces it intersects
+
+      const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E
+      const TopoDS_Shape& origF1 = myImagesFaces.Root(FL.First());
+      const TopoDS_Shape& origF2 = myImagesFaces.Root(FL.Last());
+      Standard_Boolean sameDom1 = anOrigFace.IsSame( origF1 );
+      Standard_Boolean sameDom2 = anOrigFace.IsSame( origF2 );
+      if (!(sameDom1 || sameDom2) && myInter3d.HasSameDomainF( anOrigFace )) {
+	sameDom1 = myInter3d.IsSameDomainF( anOrigFace, origF1);
+        if (origF1 == origF2)
+          sameDom2 = sameDom1;
+        else
+          myInter3d.IsSameDomainF( anOrigFace, origF2);
+      }
+      if (sameDom1 && sameDom2)
+	continue;
+      if ((sameDom1 || sameDom2)) {
+	inside = Partition_Loop3d::IsInside (E,
+					     TopoDS::Face(FL.First()),
+					     TopoDS::Face(FL.Last()),
+					     1, dot, GoodOri);
+	if (inside || (dot + Precision::Angular() >= 1.0))
+	  continue; // E is convex between origF1 and origF2 or they are tangent
+      }
+
+
+      // keep one of found faces
+
+      //face of CSF sharing E
+      const TopoDS_Shape& aShapeFace = sameDom1 ? FL.Last() : FL.First();
+      // analyse aFace1 state
+      inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace), aFace1,
+					   1, dot, GoodOri);
+      if (inside && isSectionE)
+      {
+        // aFace1 must be tested with both adjacent faces of CSF
+        const TopoDS_Shape& aShapeFace2 = sameDom1 ? FL.First() : FL.Last();
+        if (aShapeFace2 != aShapeFace)
+          inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace2), aFace1,
+                                               1, dot, GoodOri);
+      }
+
+      // store internal face
+      if (inside)
+        KeepFaces.Append(aFace1);
+
+      else if (!aFace2.IsNull())
+      {
+        if (dot + Precision::Angular() >= 1.0)
+        {
+          // aFace2 state is not clear, it will be analysed alone,
+          // put it back to the maps
+          MFP.Add( aFace2 );
+          LSF.Append( aFace2 );
+        }
+        else
+          KeepFaces.Append(aFace2);
+      }
+    }
+  }
+
+  // ===================================================
+  // add not distributed faces connected with KeepFaces
+  // ===================================================
+
+  // ultimate list of internal faces
+  TopTools_ListOfShape KeptFaces;
+
+  // add to MFP not split tool faces as well, they may be connected with
+  // tool faces interfering with theShape
+  for ( itm.Initialize(myMapTools); itm.More(); itm.Next() ) {
+    const TopoDS_Shape& aToolFace = itm.Key();
+    if (!myImageShape.HasImage(aToolFace))
+      MFP.Add (aToolFace);
+  }
+
+  if (MFP.IsEmpty())
+    KeptFaces.Append (KeepFaces);
+
+  while (!KeepFaces.IsEmpty())
+  {
+    // KeepEdges : map of edges of faces kept last time
+    TopTools_IndexedMapOfShape KeepEdges;
+    for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) {
+      TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges);
+      KeptFaces.Append( itl.Value() );
+    }
+
+    KeepFaces.Clear();
+
+    // keep faces connected with already kept faces by KeepEdges
+    for ( itm.Initialize(MFP); itm.More(); itm.Next() ) {
+      const TopoDS_Shape& FP = itm.Key();
+      for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) {
+        const TopoDS_Shape& se = expl.Current();
+        if (!MSE.Contains(se) && KeepEdges.Contains(se) ) {
+          KeepFaces.Append(FP);
+          MFP.Remove(FP);
+          break;
+        }
+      }
+    }
+  }
+
+  // ===============================================================
+  // here MFP contains faces outer of theShape and those of shapes
+  // which do not interfere with theShape at all and between which
+  // there may be those wrapped by theShape and whose faces may be
+  // needed to be returned as well
+  // ===============================================================
+
+  Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID);
+  if (All || isSolid)  // All is for sub-result removal
+  {
+    // loop on not used faces; checked faces will be removed from MFP
+    // during the loop
+    for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) {
+      const TopoDS_Shape & aFace = itm.Key();
+
+      // a shape which aFace originates from
+      TopoDS_Shape anOrigShape = GetOriginalShape( aFace );
+
+      // find out if all split faces of anOrigShape are not in MFP
+      // and by the way remove them from MFP
+      Standard_Boolean isAllOut = Standard_True;
+      TopoDS_Shape aSplitFaces = anOrigShape;
+      if (myImageShape.HasImage(anOrigShape))
+        aSplitFaces = myImageShape.Image(anOrigShape).First();
+
+      TopTools_ListOfShape aSplitFaceL; // faces candidate to be kept
+      for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next())
+      {
+        const TopoDS_Shape & aSpFace = expl.Current();
+        // a tool face which became object has image but the whole tool shape has not
+        if (myImageShape.HasImage( aSpFace ))
+        {
+          TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE );
+          for ( ; exF.More(); exF.Next() )
+          {
+            aSplitFaceL.Append( exF.Current() );
+            if ( ! MFP.Remove( exF.Current() ) && isAllOut )
+              // a shared face might be removed from MFP during a prev loop
+              isAllOut = mySharedFaces.Contains( exF.Current() );
+          }
+        }
+        else
+        {
+          aSplitFaceL.Append( aSpFace );
+          if ( ! MFP.Remove( aSpFace ) && isAllOut)
+            // a shared face might be removed from MFP during a prev loop
+            isAllOut = mySharedFaces.Contains( aSpFace );
+        }
+      }
+      itm.Initialize( MFP ); // iterate remaining faces
+      if ( !isAllOut )
+        continue;
+
+      // classify anOrigShape against theShape
+      if (IsInside (anOrigShape, theShape))
+      {
+        if (isSolid && myClosedShapes.Contains( anOrigShape ))
+          // to make a special care at solid reconstruction
+          myWrappingSolid.Add ( theShape );
+
+        // keep faces of an internal shape anOrigShape
+        KeptFaces.Append( aSplitFaceL );
+      }
+    }
+  }
+
+  // ====================================================
+  // check if kept faces form a shell without free edges
+  // ====================================================
+
+  DMEF.Clear();  // edge - kept faces
+  MFP.Clear(); // reuse it for wrong faces
+  if (CheckClosed) {
+    for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) 
+      TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF);
+
+    Standard_Integer i, nb = DMEF.Extent();
+    Standard_Boolean isClosed = Standard_False;
+    while (!isClosed) {
+      isClosed = Standard_True;
+      for (i=1;  isClosed && i<=nb;  ++i) {
+        const TopoDS_Shape& E = DMEF.FindKey( i );
+        if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) &&
+            ! MSE.Contains( E ))
+          isClosed = ( DMEF(i).Extent() != 1 );
+      }
+      if (!isClosed) {
+        const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face
+        MFP.Add( F ); 
+        // remove bad face from DMEF
+        for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) {
+	  const TopoDS_Shape& E = expl.Current();
+          TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E );
+          for (itl.Initialize( FL ); itl.More(); itl.Next() ) {
+            if ( F.IsSame( itl.Value() )) {
+              FL.Remove( itl );
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // ==============
+  // make a result
+  // ==============
+
+  TopoDS_Compound C;
+  // compound of removed internal faces
+  TopoDS_Compound CNotCl;
+
+  myBuilder.MakeCompound(C);
+  myBuilder.MakeCompound(CNotCl);
+
+  // add to compounds
+  for (itl.Initialize(KeptFaces); itl.More(); itl.Next() )
+  {
+    TopoDS_Shape & aIntFace = itl.Value();
+    if (! MFP.Contains( aIntFace ))
+      myBuilder.Add( C, aIntFace);
+    else
+      myBuilder.Add( CNotCl, aIntFace);
+  }
+
+  if (!skipAlreadyAdded && CheckClosed)
+  {
+    myInternalFaces.Bind( theShape, C );
+    myIntNotClFaces.Bind( theShape, CNotCl );
+  }
+
+  return C;
+}
+
+//=======================================================================
+//function : MakeShell
+//purpose  : split S into compound of shells
+//=======================================================================
+
+void Partition_Spliter::MakeShells(const TopoDS_Shape& S,
+                                   TopTools_ListOfShape& NS)
+{
+  Partition_Loop3d ShellMaker;
+  // get compound of split faces of S
+  const TopoDS_Shape& FacesComp = myImageShape.Image(S).First();
+  ShellMaker.AddConstFaces( FacesComp );
+  // add split faces inside S
+  if (myClosedShapes.Contains( S )) {
+    TopoDS_Shape InternalFacesComp = FindFacesInside(S, Standard_True);
+    ShellMaker.AddSectionFaces( InternalFacesComp );
+  }
+  
+  NS = ShellMaker.MakeShells( myAddedFacesMap );
+
+  // Add faces added to new shell to myAddedFacesMap:
+  // avoid rebuilding twice commont part of 2 solids.
+  TopTools_ListIteratorOfListOfShape itS(NS);
+  while ( itS.More()) {
+    TopExp_Explorer expF (itS.Value(), TopAbs_FACE);
+    for (; expF.More(); expF.Next())
+      myAddedFacesMap.Add (expF.Current());
+    
+    itS.Next();
+  }
+}
+
+//=======================================================================
+//function : findEqual
+//purpose  : compare edges of EL1 against edges of EL2,
+//           Result is in EMM binding EL1 edges to list of equal edges.
+//           Edges are considered equall only if they have same vertices.
+//           <addSame>==True makes consider same edges as equal
+//           Put in <AllEqMap> all equal edges
+//=======================================================================
+
+static void findEqual (const TopTools_ListOfShape& EL1,
+		       const TopTools_ListOfShape& EL2,
+		       const Standard_Boolean addSame,
+		       TopTools_DataMapOfShapeListOfShape& EEM,
+		       TopTools_MapOfShape& AllEqMap)
+{
+  // map vertices to edges for EL2
+  TopTools_DataMapOfShapeListOfShape VEM;
+  TopTools_ListIteratorOfListOfShape itE1, itE2(EL2);
+  TopoDS_Iterator itV;
+  TopTools_ListOfShape emptyL;
+  for (; itE2.More(); itE2.Next()) {
+    for (itV.Initialize( itE2.Value() ); itV.More(); itV.Next()) {
+      const TopoDS_Shape& V = itV.Value(); 
+      if (! VEM.IsBound( V ) )
+	VEM.Bind( V, emptyL);
+      VEM( V ).Append( itE2.Value());
+    }
+  }
+
+  gp_Vec D1, D2;
+  gp_Pnt P;
+  Standard_Real f,l,u,tol;
+  Handle(Geom_Curve) C1, C2;
+  Extrema_ExtPC Extrema;
+  TopoDS_Vertex V1, V2, V3, V4;
+
+  AllEqMap.Clear();
+  
+  for (itE1.Initialize(EL1); itE1.More(); itE1.Next()) {
+    const TopoDS_Edge& E1 = TopoDS::Edge( itE1.Value());
+    if (BRep_Tool::Degenerated( E1 ) || AllEqMap.Contains (E1))
+      continue;
+    TopExp::Vertices( E1, V1, V2 );
+
+    if (VEM.IsBound(V1))
+      itE2.Initialize( VEM(V1) );
+    for (; itE2.More(); itE2.Next()) {
+      const TopoDS_Edge& E2 = TopoDS::Edge( itE2.Value());
+      if (BRep_Tool::Degenerated( E2 ) || AllEqMap.Contains (E2))
+        continue;
+
+      if (E1.IsSame(E2)) {
+	if (!addSame)
+	  continue;
+      }
+      else {
+	TopExp::Vertices( E2, V3, V4);
+	if (!V2.IsSame(V4) && !V2.IsSame(V3))
+	  continue;
+	// E1 and E2 have same vertices
+	// check D1 at end points.
+        C2 = BRep_Tool::Curve( E2, f,l);
+        C1 = BRep_Tool::Curve( E1, f,l);
+	u = BRep_Tool::Parameter(V1,E1);
+        C1->D1(u, P, D1);
+	u = BRep_Tool::Parameter(V1.IsSame(V3) ? V3 : V4, E2);
+	C2->D1(u, P, D2);
+        D1.Normalize(); D2.Normalize();
+        if (Abs(D1*D2) + Precision::Angular() < 1.0)
+          continue;
+	if (! V1.IsSame(V2)) {
+	  u = BRep_Tool::Parameter(V2,E1);
+	  C1->D1(u, P, D1);
+	  u = BRep_Tool::Parameter(V2.IsSame(V3) ? V3 : V4, E2);
+	  C2->D1(u, P, D2);
+	  D1.Normalize(); D2.Normalize();
+	  if (Abs(D1*D2) + Precision::Angular() < 1.0)
+	    continue;
+	}
+        // check distance at a couple of internal points
+        tol = Max(BRep_Tool::Tolerance(E1),
+                  BRep_Tool::Tolerance(E2));
+        GeomAdaptor_Curve AC1(C1);
+        Extrema.Initialize(AC1,f,l);
+	Standard_Boolean ok = Standard_True, hasMin = Standard_False;
+	BRep_Tool::Range( E2, f, l);
+        Standard_Integer i=1, nbi=3;
+        for (; i<nbi && ok; ++i) {
+          Extrema.Perform( C2->Value( f+(l-f)*i/nbi ));
+          Standard_Integer j=1, nbj=Extrema.NbExt();
+          for (; j<=nbj && ok; ++j) {
+            if (Extrema.IsMin(j)) {
+	      hasMin = Standard_True;
+#if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5)
+              ok = Extrema.Value(j) <= tol;
+#else
+              ok = Extrema.SquareDistance(j) <= tol;
+#endif
+	    }
+          }
+        }
+        if ( !hasMin || !ok)
+          continue;
+      }
+      // bind E2 to E1 in EEM
+      if (!EEM.IsBound(E1)) {
+        EEM.Bind (E1, emptyL);
+	AllEqMap.Add (E1);
+      }
+      EEM(E1).Append(E2);
+      AllEqMap.Add (E2);
+    }
+  }
+}
+
+//=======================================================================
+//function : MakeFaces
+//purpose  : split faces of S, return compound of new faces
+//=======================================================================
+
+TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S)
+{
+  TopoDS_Compound C;
+  myBuilder.MakeCompound(C);
+  
+  TopTools_ListIteratorOfListOfShape itl, itNE;
+  
+  TopExp_Explorer exp(S,TopAbs_FACE);
+  for (; exp.More(); exp.Next()) {
+
+    const TopoDS_Face& F = TopoDS::Face(exp.Current());
+
+    TopTools_ListOfShape LNF;
+    
+    if (myImagesFaces.HasImage( F )) {
+      myImagesFaces.LastImage( F, LNF );
+      TopAbs_Orientation oriF = F.Orientation();
+      for ( itl.Initialize( LNF ); itl.More(); itl.Next())
+	itl.Value().Orientation( oriF );
+    }
+    else {
+
+      Partition_Loop2d loops;
+      loops.Init(F);
+
+      TopTools_IndexedMapOfShape EM;
+      TopExp::MapShapes( F, TopAbs_EDGE, EM);
+
+      TopTools_MapOfShape AddedEqualM, EqualSeamM;
+      Standard_Boolean needRebuild = Standard_False;
+
+      // add splits to loops
+
+      // LE: old edges + new not splitted edges
+      const TopTools_ListOfShape& LE = myAsDes->Descendant(F);
+      for (itl.Initialize(LE); itl.More(); itl.Next()) {
+	const TopoDS_Edge& E = TopoDS::Edge( itl.Value() );
+
+	Standard_Boolean isSectionE = myInter3d.IsSectionEdge(E);
+	Standard_Boolean isNewE = !EM.Contains( E );
+
+	// LSE: list of split edges
+	TopTools_ListOfShape LSE;
+	myImagesEdges.LastImage(E,LSE); // splits of E or E itself
+
+	for (itNE.Initialize(LSE); itNE.More(); itNE.Next()) {
+
+	  TopoDS_Edge NE = TopoDS::Edge( itNE.Value() );
+	  Standard_Boolean isSameE = NE.IsSame ( E );
+	  
+	  if ( isNewE || isSectionE || !isSameE) {
+	    if (AddedEqualM.Contains( NE )) {
+              // a seam must be twice in a loop
+              if (!BRep_Tool::IsClosed( E, F ) || !EqualSeamM.Add( NE ))
+                continue;
+            }
+
+	    if (isNewE) {
+	      if (isSectionE) {
+		if ( ! myInter3d.IsSplitOn( NE, E, F) )
+		  continue;
+	      }
+	      else {
+		TopoDS_Vertex V1,V2;
+		TopExp::Vertices(NE,V1,V2);
+		const TopTools_ListOfShape& EL1 = myAsDes->Ascendant(V1);
+		const TopTools_ListOfShape& EL2 = myAsDes->Ascendant(V2);
+		if ( EL1.Extent() < 2 && EL2.Extent() < 2 )
+		  continue;
+	      }
+	    }
+	    else {
+	      NE.Orientation( E.Orientation());
+	      if (!isSameE) {
+		// orient NE because it may be a split of other edge
+		Standard_Real f,l,u;
+		Handle(Geom_Curve) C3d  = BRep_Tool::Curve( E,f,l );
+		Handle(Geom_Curve) NC3d = BRep_Tool::Curve( NE,f,l);
+		if ( C3d != NC3d) {
+		  gp_Vec D1, ND1;  gp_Pnt P;
+		  TopoDS_Vertex V = TopExp::FirstVertex(NE);
+		  u = BRep_Tool::Parameter(V,NE);
+		  NC3d->D1 (u, P, ND1);
+		  u = BRep_Tool::Parameter(V,E);
+		  C3d ->D1 (u, P, D1);
+		  if (ND1.Dot(D1) < 0)
+		    NE.Reverse();
+		}
+	      }
+	    }
+	    if (myEqualEdges.Contains( NE ))
+              AddedEqualM.Add( NE );
+
+	    needRebuild = Standard_True;
+	  }
+
+	  if (isNewE || isSectionE)
+	    myNewSection.Add( NE );
+
+	  if (isNewE) 
+	    loops.AddSectionEdge(NE);
+	  else
+	    loops.AddConstEdge(NE);
+	}
+      }
+
+      //-------------------
+      // Build the faces.
+      //-------------------
+      
+      if (needRebuild) {
+	
+        loops.Perform();
+        loops.WiresToFaces(myImagesEdges);
+
+        LNF = loops.NewFaces();
+
+        myImagesFaces.Bind(F,LNF);
+
+        // replace the result faces that have already been built
+        // during same domain faces reconstruction done earlier
+        if (myInter3d.HasSameDomainF( F ))
+        {
+          // build map edge to same domain faces: EFM
+          TopTools_IndexedDataMapOfShapeListOfShape EFM;
+          TopTools_MapOfShape SDFM; // avoid doubling
+          itl.Initialize( myInter3d.SameDomain( F ));
+          for (; itl.More(); itl.Next()) {
+            if ( !myImagesFaces.HasImage( itl.Value() ))
+              continue;
+            // loop on splits of a SD face
+            TopTools_ListIteratorOfListOfShape itNF;
+            itNF.Initialize (myImagesFaces.Image( itl.Value() ));
+            for ( ; itNF.More(); itNF.Next()) {
+              TopoDS_Shape SDF = itNF.Value();
+              if (myImagesFaces.HasImage( SDF )) // already replaced
+                SDF = myImagesFaces.Image( SDF ).First();
+              if (SDFM.Add (SDF))
+                TopExp::MapShapesAndAncestors(SDF, TopAbs_EDGE, TopAbs_FACE, EFM);
+            }
+          }
+          // do replace faces in the LNF
+          TopTools_ListOfShape LOF;
+          if ( !EFM.IsEmpty() )
+            itl.Initialize( LNF );
+          while (itl.More()) {
+            const TopoDS_Shape& NF = itl.Value();
+            TopExp_Explorer expE ( NF, TopAbs_EDGE );
+            const TopoDS_Edge& E  = TopoDS::Edge (expE.Current());
+            if (EFM.Contains( E )) {
+              const TopTools_ListOfShape& SDFL = EFM.FindFromKey( E );
+              TopoDS_Shape SDF = SDFL.First();
+              Standard_Boolean GoodOri;
+              Standard_Real dot;
+              Partition_Loop3d::IsInside (E, TopoDS::Face(NF), TopoDS::Face(SDF),
+                                          1, dot, GoodOri);
+              if (dot < 0)
+              {
+                // NF and SDF are on different side of E
+                if (SDFL.Extent() == 1) {
+                  itl.Next();
+                  continue;
+                }
+                else
+                  SDF = SDFL.Last(); // next face must be on the same side
+              }
+              gp_Vec V1 = Partition_Loop3d::Normal( E, TopoDS::Face( NF ));
+              gp_Vec V2 = Partition_Loop3d::Normal( E, TopoDS::Face( SDF ));
+              if (V1*V2 < 0)
+                SDF.Reverse();
+
+              if (!myImagesFaces.HasImage( NF ))
+                myImagesFaces.Bind( NF, SDF );
+
+              // mySharedFaces is used in FindFacesInside()
+              mySharedFaces.Add( SDF );
+
+              LOF.Prepend ( SDF );
+              LNF.Remove (itl);
+            }
+            else
+              itl.Next();
+          }
+
+          LNF.Append (LOF);
+        }
+      } // if (needRebuild)
+      
+      else {
+	LNF.Append( F );
+	myImagesFaces.Bind(F,LNF);
+      }
+    } // if (myImagesFaces.HasImage( F ))
+
+    // fill the resulting compound
+    for (itl.Initialize(LNF); itl.More(); itl.Next())
+      myBuilder.Add ( C, itl.Value());
+    
+  } // loop on faces of S
+
+  return C;
+}
+
+
+//=======================================================================
+//function : Tri
+//purpose  : 
+//=======================================================================
+
+static void Tri(const TopoDS_Edge&        E,
+		TopTools_SequenceOfShape& Seq,
+                const Partition_Inter3d & theInter3d)
+{
+  Standard_Boolean Invert   = Standard_True;
+  Standard_Real    U1,U2;
+  TopoDS_Vertex    V1,V2;
+
+  while (Invert) {
+    Invert = Standard_False;
+    for ( Standard_Integer i = 1; i < Seq.Length(); i++) {
+      
+      V1 = TopoDS::Vertex(Seq.Value(i));
+      V2 = TopoDS::Vertex(Seq.Value(i+1));
+      
+      V1.Orientation(TopAbs_INTERNAL);
+      V2.Orientation(TopAbs_INTERNAL);
+      
+      U1 = BRep_Tool::Parameter(V1,E);
+      U2 = BRep_Tool::Parameter(V2,E);
+      
+      if (IsEqual(U1,U2)) {
+        if (theInter3d.ReplaceSameDomainV( V1, E ).IsSame( V1 ))
+          Seq.Remove(i+1); // remove V2
+        else
+          Seq.Remove(i);
+	i--;
+	continue;
+      }
+      if (U2 < U1) {
+	Seq.Exchange(i,i+1);
+	Invert = Standard_True;
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : MakeEdges
+//purpose  : cut E by vertices VOnE, return list of new edges NE
+//=======================================================================
+
+void Partition_Spliter::MakeEdges (const TopoDS_Edge& E,
+                                   const TopTools_ListOfShape& VOnE,
+                                   TopTools_ListOfShape& NE   ) const
+{
+  TopoDS_Edge WE = E;
+  WE.Orientation(TopAbs_FORWARD);
+
+  Standard_Real    U1,U2, f, l;
+  TopoDS_Vertex    V1,V2,VF,VL;
+
+  BRep_Tool::Range(WE,f,l);
+  TopExp::Vertices(WE,VF,VL);
+
+  if (VOnE.Extent() < 3) { // do not rebuild not cut edge
+    if (( VF.IsSame( VOnE.First() ) && VL.IsSame( VOnE.Last() )) ||
+	VL.IsSame( VOnE.First() ) && VF.IsSame( VOnE.Last() )  ) {
+      NE.Append( E );
+      return;
+    }
+  }
+
+  TopTools_SequenceOfShape SV;
+  TopTools_ListIteratorOfListOfShape itv(VOnE);
+  TopTools_MapOfOrientedShape VM( VOnE.Extent() );
+  for (; itv.More(); itv.Next())
+    if ( VM.Add( itv.Value() ))
+      SV.Append(itv.Value());
+
+  Tri( WE, SV, myInter3d );
+
+  if (SV.Length() < 3) { // do not rebuild not cut edge
+    if (( VF.IsSame( SV.First() ) && VL.IsSame( SV.Last() )) ||
+	VL.IsSame( SV.First() ) && VF.IsSame( SV.Last() )  ) {
+      NE.Append( E );
+      return;
+    }
+  }
+
+  Standard_Integer iVer, NbVer = SV.Length();
+
+
+  //----------------------------------------------------------------
+  // Construction of the new edges .
+  //----------------------------------------------------------------
+
+  if (VF.IsSame(VL)) { // closed edge
+    if (NbVer==1) 
+      SV.Append( SV.First() );
+    else if (!SV.First().IsSame(SV.Last())) {
+      Standard_Boolean isFirst=0;
+      Standard_Real    minDU = 1.e10;
+      TopoDS_Vertex endV = Partition_Inter2d::FindEndVertex(VOnE, f,l, E, isFirst,minDU);
+      if (endV.IsSame(SV.First()))
+	SV.Append(endV);
+      else if (endV.IsSame(SV.Last()))
+	SV.Prepend(endV);
+      //else
+	//MESSAGE ("END VERTEX IS IN SEQUNCE MIDDLE");
+    }
+    NbVer = SV.Length();
+  }
+
+  for (iVer=1; iVer < NbVer; iVer++) {
+    V1  = TopoDS::Vertex(SV(iVer));
+    V2  = TopoDS::Vertex(SV(iVer+1));
+    
+    TopoDS_Shape NewEdge = WE.EmptyCopied();
+    V1.Orientation(TopAbs_FORWARD);
+    myBuilder.Add  (NewEdge,V1);
+    V2.Orientation(TopAbs_REVERSED);
+    myBuilder.Add  (NewEdge,V2);
+    
+    if (iVer==1)
+      U1 = f;
+    else 	{
+      V1.Orientation(TopAbs_INTERNAL);
+      U1=BRep_Tool::Parameter(V1,WE);
+    }
+    if (iVer+1 == NbVer)
+      U2 = l;
+    else	{
+      V2.Orientation(TopAbs_INTERNAL);
+      U2=BRep_Tool::Parameter(V2,WE);
+    }
+    if (Abs(U1-U2) <= Precision::PConfusion()) {
+      //MESSAGE( "MakeEdges(), EQUAL PARAMETERS OF DIFFERENT VERTICES");
+      continue;
+    }
+    TopoDS_Edge EE=TopoDS::Edge(NewEdge);
+    myBuilder.Range (EE,U1,U2);
+
+    TopoDS_Edge NEdge = TopoDS::Edge(NewEdge);
+    myBuilder.SameParameter(NEdge,Standard_False);
+
+    Standard_Real tol = 1.0e-2;
+    Standard_Boolean flag = BRep_Tool::SameParameter(NEdge);
+    if (!flag) {
+      BRepLib::SameParameter(NEdge,tol);
+    }
+    NE.Append(NEdge.Oriented(E.Orientation()));
+  }
+}
+
+//=======================================================================
+//function : MergeEqualEdges
+//purpose  : find equal edges,  choose  ones  to  keep and make
+//           them have pcurves on all faces they are shared by
+//=======================================================================
+
+void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE)
+{
+  // find equal edges
+  // map: edge - equal edges
+  TopTools_DataMapOfShapeListOfShape EEM( LSE.Extent() );
+  findEqual (LSE, LSE, 0, EEM, myEqualEdges);
+
+  TopTools_ListOfShape EEL; // list of equal edges
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itM (EEM);
+  for ( ; itM.More(); itM.Next()) {
+    EEL = itM.Value();
+    EEL.Append( itM.Key() );
+
+    // choose an edge to keep, section edges have priority
+    TopoDS_Edge EKeep;
+    TopTools_ListIteratorOfListOfShape itEE (EEL);
+    for (; itEE.More(); itEE.Next()) {
+      EKeep = TopoDS::Edge( itEE.Value() );
+      const TopoDS_Edge& EKeepOrig = TopoDS::Edge( myImagesEdges.Root( EKeep ));
+      if (myInter3d.IsSectionEdge( EKeepOrig ))
+        break;
+    }
+
+    // update edge images and build pcurves
+    Standard_Real f,l, tol;
+    for (itEE.Initialize (EEL); itEE.More(); itEE.Next()) {
+      const TopoDS_Edge& E = TopoDS::Edge( itEE.Value() );
+      if ( E.IsSame( EKeep )) 
+        continue;
+
+      // 1. build pcurves of the kept edge on faces where replaced edges exist
+      const TopoDS_Edge& EReplOrig = TopoDS::Edge( myImagesEdges.Root( E ));
+      TopTools_ListOfShape FL;
+      FL = myAsDes->Ascendant( EReplOrig );
+      Standard_Integer iFace, iFirstSectionFace = FL.Extent() + 1;
+      // add faces where the replaced edge is a section edge
+      if (myInter3d.IsSectionEdge( EReplOrig )) {
+        TopTools_ListIteratorOfListOfShape seIt;
+        seIt.Initialize( myInter3d.SectionEdgeFaces ( EReplOrig ));
+        for ( ; seIt.More(); seIt.Next())
+          FL.Append( seIt.Value() );
+      }
+      // loop on faces
+      TopTools_ListIteratorOfListOfShape itF (FL);
+      for ( iFace = 1 ; itF.More(); itF.Next(), ++iFace ) {
+        const TopoDS_Face& F = TopoDS::Face( itF.Value());
+
+        Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( EKeep, F, f,l);
+        if (pc.IsNull()) {
+          Handle(Geom_Curve) C3d = BRep_Tool::Curve( EKeep, f, l);
+          C3d = new Geom_TrimmedCurve( C3d, f,l);
+          pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
+          if (pc.IsNull()) {
+            //MESSAGE (" CANT BUILD PCURVE ");
+          }
+          myBuilder.UpdateEdge( EKeep, pc, F, tol);
+        }
+
+        if (iFace >= iFirstSectionFace ||
+            !BRep_Tool::IsClosed( EReplOrig, F ))
+          continue;
+
+        // build the second pcurve for a seam
+        TopoDS_Vertex V = TopExp::FirstVertex( EKeep );
+        Standard_Real Ukeep = BRep_Tool::Parameter( V, EKeep );
+        Standard_Real Urepl = BRep_Tool::Parameter( V, E );
+
+        TopoDS_Edge EReplRev = E;
+        EReplRev.Reverse();
+        Handle(Geom2d_Curve) pcRepl1 = BRep_Tool::CurveOnSurface( E, F, f,l);
+        Handle(Geom2d_Curve) pcRepl2 = BRep_Tool::CurveOnSurface( EReplRev, F, f,l);
+
+        gp_Pnt2d p1r, p2r, pk;
+        p1r = pcRepl1->Value( Urepl );
+        p2r = pcRepl2->Value( Urepl );
+        pk  = pc->Value( Ukeep );
+
+        // suppose that pk is equal to either p1r or p2r
+        Standard_Boolean isUPeriod =
+          ( Abs( p1r.X() - p2r.X() ) > Abs( p1r.Y() - p2r.Y() ));
+        Standard_Boolean is1Equal;
+        if (isUPeriod)
+          is1Equal = ( Abs( p1r.X() - pk.X() ) < Abs( p2r.X() - pk.X() ));
+        else
+          is1Equal = ( Abs( p1r.Y() - pk.Y() ) < Abs( p2r.Y() - pk.Y() ));
+
+        Handle(Geom2d_Curve) pc2 = Handle(Geom2d_Curve)::DownCast
+          ( pc->Translated( pk, is1Equal ? p2r : p1r ) );
+
+        if (E.Orientation() == TopAbs_REVERSED)
+          is1Equal = !is1Equal;
+
+        if (is1Equal)
+          myBuilder.UpdateEdge( EKeep, pc, pc2, F, tol);
+        else
+          myBuilder.UpdateEdge( EKeep, pc2, pc, F, tol);
+
+      } // loop on a Faces where a replaced edge exists
+
+
+      // 2. update edge images according to replacement
+      if (myImagesEdges.HasImage( E ))
+        myImagesEdges.Remove( E );
+      myImagesEdges.Bind( E, EKeep );
+
+    } // loop on a list of equal edges EEL
+  } // loop on a map of equal edges EEM
+}
+
+//=======================================================================
+//function : KeepShapesInside
+//purpose  : remove shapes that are outside of S from resul
+//=======================================================================
+
+void Partition_Spliter::KeepShapesInside (const TopoDS_Shape& S)
+{
+  TopoDS_Iterator it;
+  if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
+    for (it.Initialize( S ); it.More(); it.Next())
+      KeepShapesInside( it.Value());
+    return;
+  }
+
+  Standard_Boolean isTool = Standard_False;
+  if (!myImageShape.HasImage( S )) {
+    isTool = CheckTool( S );
+    if (!isTool) return;
+  }
+
+  // build map of internal faces
+  TopTools_IndexedMapOfShape MIF;
+  TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
+  TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF );
+
+  TopoDS_Compound C;
+  myBuilder.MakeCompound(C);
+
+  TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE;
+  if (!MIF.IsEmpty())
+  {
+    // leave in the result only those shapes having a face in MIF
+    for (it.Initialize( myShape ); it.More(); it.Next()) {
+      const TopoDS_Shape & aResShape = it.Value();
+      TopExp_Explorer expResF( aResShape, TopAbs_FACE );
+      for (; expResF.More(); expResF.Next()) {
+        if ( MIF.Contains( expResF.Current())) {
+          myBuilder.Add( C, aResShape );
+          if (aResShape.ShapeType() < anInternalShapeType)
+            anInternalShapeType = aResShape.ShapeType();
+          break;
+        }
+      }
+    }
+  }
+
+  // may be S was not split by internal faces then it is missing
+  // in myShape, add it
+  if (!isTool &&
+      (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID))
+  {
+    TopTools_IndexedMapOfShape MSF; // map of split faces of S
+    TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF);
+
+    // find a shape having all faces in MSF
+    for (it.Initialize( myShape ); it.More(); it.Next()) {
+      TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
+      for (; expResF.More(); expResF.Next()) {
+        if (! MSF.Contains( expResF.Current())) 
+          break;
+      }
+      if (! expResF.More()) {
+        myBuilder.Add( C, it.Value() );
+        break;
+      }
+    }
+  }
+
+  myShape = C;
+}
+
+//=======================================================================
+//function : RemoveShapesInside
+//purpose  : remove shapes that are inside S from resul
+//=======================================================================
+
+void Partition_Spliter::RemoveShapesInside (const TopoDS_Shape& S)
+{
+  TopoDS_Iterator it;
+  if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
+    for (it.Initialize( S ); it.More(); it.Next())
+      RemoveShapesInside( it.Value());
+    return;
+  }
+  Standard_Boolean isTool = Standard_False;
+  if (!myImageShape.HasImage( S )) {
+    isTool = CheckTool( S );
+    if (!isTool) return;
+  }
+
+  TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
+  TopTools_IndexedMapOfShape MIF; // map of internal faces
+  TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF);
+
+  if (MIF.IsEmpty()) return;
+
+  // add to MIF split faces of S
+  if (myImageShape.HasImage(S))
+    TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF);
+
+  // leave in the result only those shapes not having all face in MIF
+  
+  TopoDS_Compound C;
+  myBuilder.MakeCompound(C);
+
+  // RMF : faces of removed shapes that encounter once
+  TopTools_MapOfShape RFM;
+  
+  for (it.Initialize( myShape ); it.More(); it.Next()) {
+    
+    TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
+    for (; expResF.More(); expResF.Next())
+      if (!MIF.Contains( expResF.Current()))
+	break;
+
+    if (expResF.More())
+      // add shape to result
+      myBuilder.Add( C, it.Value() );
+    else 
+      // add faces of a removed shape to RFM
+      for (expResF.ReInit(); expResF.More(); expResF.Next()) {
+	const TopoDS_Shape& F = expResF.Current();
+	if ( ! RFM.Remove ( F ))
+	  RFM.Add( F );
+      }
+  }
+
+  if (!isTool) {
+
+    // rebuild S, it must remain in the result
+
+    Standard_Boolean isClosed = Standard_False;
+    switch (S.ShapeType()) {
+    case TopAbs_SOLID :
+      isClosed = Standard_True; break;
+    case TopAbs_SHELL: {
+      TopTools_IndexedDataMapOfShapeListOfShape MEF;
+      TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
+      Standard_Integer i;
+      for (i=1;  isClosed && i<=MEF.Extent();  ++i) 
+        isClosed = ( MEF(i).Extent() != 1 );
+      break;
+    }
+    default:
+      isClosed = Standard_False;
+    }
+    if (isClosed) {
+
+      // add to a new shape external faces of removed shapes, ie those in RFM
+
+      TopoDS_Shell Shell;
+      myBuilder.MakeShell( Shell );
+
+      // exclude redundant internal face with edges encounterd only once
+      TopTools_IndexedDataMapOfShapeListOfShape MEF;
+      TopTools_MapIteratorOfMapOfShape itF (RFM);
+      for ( ; itF.More(); itF.Next()) 
+        TopExp::MapShapesAndAncestors(itF.Key(), TopAbs_EDGE, TopAbs_FACE, MEF);
+
+      // add only faces forming a closed shell
+      for (itF.Reset() ; itF.More(); itF.Next())
+      {
+        TopExp_Explorer expE (itF.Key(), TopAbs_EDGE);
+        for (; expE.More(); expE.Next())
+          if (MEF.FindFromKey(expE.Current()).Extent() == 1)
+            break;
+        if (!expE.More())
+          myBuilder.Add( Shell, itF.Key());
+      }
+
+      if (S.ShapeType() == TopAbs_SOLID) {
+        TopoDS_Solid Solid;
+        myBuilder.MakeSolid( Solid );
+        myBuilder.Add (Solid, Shell);
+        myBuilder.Add (C, Solid);
+      }
+      else
+        myBuilder.Add (C, Shell);
+    }
+    else {
+      if (myImageShape.HasImage( S )) {
+        for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next())
+          myBuilder.Add (C, it.Value());
+      }
+    }
+  }
+  
+  myShape = C;
+}
+
+//=======================================================================
+//function : CheckTool
+//purpose  : Return True if <S>  is  a tool shape. Prepare tool
+//           faces of <S> for the search of internal faces.
+//=======================================================================
+
+Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S)
+{
+  // suppose S has not an image
+  
+  Standard_Boolean isTool = Standard_False;
+  TopoDS_Compound C;
+  myBuilder.MakeCompound( C );
+
+  TopExp_Explorer expF( S, TopAbs_FACE);
+  for (; expF.More(); expF.Next()) {
+
+    const TopoDS_Face& F = TopoDS::Face( expF.Current() );
+    if (myMapTools.Contains( F ))
+      isTool = Standard_True;
+    else
+      continue;
+
+    if (myImagesFaces.HasImage( F )) {
+      // F has been reconstructed
+      TopAbs_Orientation Fori = F.Orientation();
+      TopTools_ListOfShape LNF;
+      myImagesFaces.LastImage( F, LNF);
+      TopTools_ListIteratorOfListOfShape itF (LNF);
+      for ( ; itF.More(); itF.Next())
+	myBuilder.Add( C, itF.Value().Oriented(Fori) );
+      continue;
+    }
+    
+    Standard_Boolean hasSectionE = myInter3d.HasSectionEdge( F );
+    Standard_Boolean hasNewE     = myAsDes->HasDescendant( F );
+    if (!hasSectionE && !hasNewE)
+    {
+      // F intersects nothing
+      myBuilder.Add( C, F );
+      continue;
+    }
+    
+    // make an image for F
+    
+    TopoDS_Face NF = F;
+    NF.Orientation(TopAbs_FORWARD);
+    NF = TopoDS::Face( NF.EmptyCopied() ); // make a copy
+    TopoDS_Wire NW;
+    myBuilder.MakeWire( NW );
+
+    // add edges, as less as possible
+    TopTools_ListOfShape NEL;
+    TopTools_ListIteratorOfListOfShape itNE;
+    if (hasSectionE) {
+      // add section edges
+      TopExp_Explorer expE;
+      for ( ; expE.More(); expE.Next()) {
+	if (! myImagesEdges.HasImage( expE.Current() ))
+	  continue;
+	myImagesEdges.LastImage( expE.Current(), NEL );
+	for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next())
+	  myBuilder.Add ( NW, itNE.Value());
+      }
+    }
+    if (hasNewE) {
+      // add new adges
+      NEL = myAsDes->Descendant( F );
+      for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) {
+	TopTools_ListOfShape SEL; // splits
+	myImagesEdges.LastImage( itNE.Value(), SEL );
+	TopTools_ListIteratorOfListOfShape itSE (SEL);
+	for ( ; itSE.More(); itSE.Next()) 
+	  myBuilder.Add ( NW, itSE.Value());
+      }
+    }
+    myBuilder.Add( NF, NW );
+    myBuilder.Add (C, NF);
+    
+    NF.Orientation( F.Orientation() ); // NF is most probably invalid
+    myImagesFaces.Bind (F, NF);
+  }
+  if (isTool)
+    myImageShape.Bind (S, C);
+
+  return isTool;
+}
+
+//=======================================================================
+//function : IsInside
+//purpose  : Return True if the first vertex of S1 inside S2.
+//           If S1.IsNull(), check infinite point against S2.
+//=======================================================================
+
+Standard_Boolean Partition_Spliter::IsInside (const TopoDS_Shape& theS1,
+                                              const TopoDS_Shape& theS2)
+{
+  BRepClass3d_SolidClassifier aClassifier( theS2 );
+
+  TopExp_Explorer expl( theS1, TopAbs_VERTEX );
+  if (!expl.More())
+    aClassifier.PerformInfinitePoint( ::RealSmall());
+  else
+  {
+    const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() );
+    aClassifier.Perform (BRep_Tool::Pnt( aVertex ),
+                         BRep_Tool::Tolerance( aVertex ));
+  }
+
+  return ( aClassifier.State() == TopAbs_IN );
+}
+
+//=======================================================================
+//function : GetOriginalShape
+//purpose  : Return the  shape  aShape  originates from. aShape
+//           should be a face or more complex result shape
+//=======================================================================
+
+TopoDS_Shape Partition_Spliter::GetOriginalShape(const TopoDS_Shape& theShape) const
+{
+  TopoDS_Shape anOrigShape;
+
+  TopExp_Explorer expl( theShape, TopAbs_FACE);
+  if (expl.More())
+  {
+
+    TopoDS_Shape aFace = expl.Current();
+    if (myImagesFaces.IsImage( aFace ))
+      aFace = myImagesFaces.Root( aFace );
+    anOrigShape = myFaceShapeMap.Find( aFace );
+  }
+  return anOrigShape;
+}
+
+//=======================================================================
+//function : FindToolsToReconstruct
+//purpose  : find and store  as  objects  tools which interfere
+//           with  solids   or   are   inside   solids  without
+//           an interference
+//=======================================================================
+
+void Partition_Spliter::FindToolsToReconstruct()
+{
+  if (myMapTools.IsEmpty())
+    return;
+
+  Standard_Integer nbFoundTools = 0;
+
+  // build edge - face map in order to detect interference with section edges
+  TopTools_IndexedDataMapOfShapeListOfShape EFM;
+  TopTools_MapIteratorOfMapOfShape aMapIt;
+  for (aMapIt.Initialize(myMapTools); aMapIt.More(); aMapIt.Next())
+    TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM);
+  for (aMapIt.Initialize(myMapFaces); aMapIt.More(); aMapIt.Next())
+    TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM);
+
+  TopTools_MapOfShape aCurrentSolids, aCheckedShapes;
+
+  // faces cut by new edges
+  TopTools_MapOfShape & aSectionFaces = myInter3d.TouchedFaces();
+
+  // keep solids interfering with each other in aCurrentSolids map
+  // and add tool faces intersecting solids as object shapes
+
+  TopTools_ListIteratorOfListOfShape itS, itF, itCF, itE;
+  for (itS.Initialize( myListShapes ); itS.More(); itS.Next()) {
+    TopExp_Explorer expSo (itS.Value(), TopAbs_SOLID);
+    for (; expSo.More(); expSo.Next()) {
+
+      // check if a solid has been already processed
+      const TopoDS_Shape & aSo = expSo.Current();
+      if (!aCheckedShapes.Add( aSo ))
+        continue;
+      aCurrentSolids.Add( aSo );
+
+      // faces to check
+      TopTools_ListOfShape aFacesToCheck;
+      TopExp_Explorer exp( aSo, TopAbs_FACE );
+      for ( ; exp.More(); exp.Next())
+        aFacesToCheck.Append ( exp.Current());
+
+      // add other shapes interefering with a solid.
+      // iterate faces to check while appending new ones
+      for (itCF.Initialize (aFacesToCheck) ; itCF.More(); itCF.Next())
+      {
+        const TopoDS_Shape& aCheckFace = itCF.Value();
+//         if (!aCheckedShapes.Add( aCheckFace ))
+//           continue;
+
+        // find faces interfering with aCheckFace
+        TopTools_ListOfShape anIntFaces;
+
+        // ** 1. faces intersecting aCheckFace with creation of new edges on it
+        if ( myAsDes->HasDescendant( aCheckFace ))
+        {
+          // new edges on aCheckFace
+          const TopTools_ListOfShape& NEL = myAsDes->Descendant( aCheckFace );
+          for (itE.Initialize( NEL); itE.More(); itE.Next())
+          {
+            const TopoDS_Shape & aNewEdge = itE.Value();
+            if (!aCheckedShapes.Add( aNewEdge ))
+              continue;
+
+            // faces interfering by aNewEdge
+            itF.Initialize (myAsDes->Ascendant( aNewEdge ));
+            for (; itF.More(); itF.Next())
+              if (aCheckFace != itF.Value())
+                anIntFaces.Append( itF.Value() );
+
+            // ** 2. faces having section edge aNewEdge on aFacesToCheck
+            if (EFM.Contains( aNewEdge))
+            {
+              itF.Initialize ( EFM.FindFromKey (itE.Value()));
+              for (; itF.More(); itF.Next())
+                if (aCheckFace != itF.Value())
+                  anIntFaces.Append( itF.Value() );
+            }
+          }
+        }
+
+        // ** 3. faces cut by edges of aCheckFace
+        TopExp_Explorer expE (aCheckFace, TopAbs_EDGE);
+        for ( ; expE.More(); expE.Next())
+        {
+          const TopoDS_Shape & aCheckEdge = expE.Current();
+          if (aCheckedShapes.Add( aCheckEdge ) &&
+              myInter3d.IsSectionEdge( TopoDS::Edge( aCheckEdge )))
+          {
+            itF.Initialize( myInter3d.SectionEdgeFaces( TopoDS::Edge( aCheckEdge )));
+            for (; itF.More(); itF.Next()) 
+              if (aCheckFace != itF.Value())
+                anIntFaces.Append( itF.Value() );
+          }
+        }
+
+        // process faces interfering with aCheckFace and shapes they
+        // belong to
+        for (itF.Initialize (anIntFaces); itF.More(); itF.Next())
+        {
+          const TopoDS_Shape & F = itF.Value();
+          if (! aCheckedShapes.Add( F ))
+            continue;
+
+          Standard_Boolean isTool = myMapTools.Contains( F );
+          if (isTool && 
+              myFaceShapeMap( aCheckFace ).ShapeType() == TopAbs_SOLID )
+          {
+            // a tool interfering with a solid
+            if (aSectionFaces.Contains( F ))
+              AddShape( F );
+            ++ nbFoundTools;
+            if (nbFoundTools == myMapTools.Extent())
+              return;
+          }
+
+          const TopoDS_Shape & S = myFaceShapeMap( F );
+          if (aCheckedShapes.Add( S ))
+          {
+            // a new shape interefering with aCurrentSolids is found
+            if (!isTool && S.ShapeType() == TopAbs_SOLID)
+              aCurrentSolids.Add ( S );
+            // add faces to aFacesToCheck list
+            for ( exp.Init( S, TopAbs_FACE ); exp.More(); exp.Next())
+              aFacesToCheck.Append ( exp.Current() );
+          }
+        }
+      } // loop on aFacesToCheck
+
+      // Here aCurrentSolids contains all solids interfering with each other.
+      // aCheckedShapes contains all faces belonging to shapes included
+      // in or interfering with aCurrentSolids or previously checked solids.
+      // Test if tool faces that do not interefere with other shapes are
+      // wrapped by any of aCurrentSolids
+
+      TopTools_MapIteratorOfMapOfShape aSolidIt (aCurrentSolids);
+      for ( ; aSolidIt.More(); aSolidIt.Next())
+      {
+        const TopoDS_Shape & aSolid = aSolidIt.Key();
+        TopTools_MapOfShape aCheckedTools( myMapTools.Extent() );
+
+        TopTools_MapIteratorOfMapOfShape aToolIt (myMapTools);
+        for ( ; aToolIt.More(); aToolIt.Next())
+        {
+          const TopoDS_Shape & aToolFace = aToolIt.Key();
+          if (aCheckedShapes.Contains( aToolFace ) || // already found
+              aCheckedTools.Contains( aToolFace ))    // checked against aSolid
+            continue;
+
+          const TopoDS_Shape & aToolShape = myFaceShapeMap( aToolFace );
+          TopExp_Explorer aToolFaceIt( aToolShape, TopAbs_FACE );
+          
+          Standard_Boolean isInside = IsInside( aToolShape, aSolid );
+          for ( ; aToolFaceIt.More(); aToolFaceIt.Next() )
+          {
+            const TopoDS_Shape & aTool = aToolFaceIt.Current();
+            aCheckedTools.Add( aTool );
+            if (isInside)
+            {
+              if (aSectionFaces.Contains( aTool ))
+                AddShape( aTool );
+              ++ nbFoundTools;
+              if (nbFoundTools == myMapTools.Extent())
+                return;
+              aCheckedShapes.Add( aTool );
+            }
+          }
+        }
+      }
+      
+    } // loop on solid shapes
+  }
+}
+
+#endif
diff --git a/contrib/Salome/Partition_Spliter.hxx b/contrib/Salome/Partition_Spliter.hxx
new file mode 100644
index 0000000000000000000000000000000000000000..f29917a3e144edcf2b8f03d7476b13cb86b3ecdd
--- /dev/null
+++ b/contrib/Salome/Partition_Spliter.hxx
@@ -0,0 +1,150 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : Partition_Spliter.hxx
+//  Module : GEOM
+
+#ifndef _Partition_Spliter_HeaderFile
+#define _Partition_Spliter_HeaderFile
+
+#ifndef _TopAbs_ShapeEnum_HeaderFile
+#include <TopAbs_ShapeEnum.hxx>
+#endif
+#ifndef _TopoDS_Compound_HeaderFile
+#include <TopoDS_Compound.hxx>
+#endif
+#ifndef _BRep_Builder_HeaderFile
+#include <BRep_Builder.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopTools_MapOfShape_HeaderFile
+#include <TopTools_MapOfShape.hxx>
+#endif
+#ifndef _TopTools_DataMapOfShapeShape_HeaderFile
+#include <TopTools_DataMapOfShapeShape.hxx>
+#endif
+#ifndef _Handle_BRepAlgo_AsDes_HeaderFile
+#include <Handle_BRepAlgo_AsDes.hxx>
+#endif
+#ifndef _BRepAlgo_Image_HeaderFile
+#include <BRepAlgo_Image.hxx>
+#endif
+#ifndef _Partition_Inter3d_HeaderFile
+#include "Partition_Inter3d.hxx"
+#endif
+#ifndef _TopTools_MapOfOrientedShape_HeaderFile
+#include <TopTools_MapOfOrientedShape.hxx>
+#endif
+#ifndef _Standard_Boolean_HeaderFile
+#include <Standard_Boolean.hxx>
+#endif
+class BRepAlgo_AsDes;
+class TopoDS_Shape;
+class TopTools_ListOfShape;
+class TopoDS_Edge;
+
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+
+class Partition_Spliter  {
+
+public:
+
+   void* operator new(size_t,void* anAddress) 
+   {
+      return anAddress;
+   }
+   void* operator new(size_t size) 
+   { 
+      return Standard::Allocate(size); 
+   }
+   void  operator delete(void *anAddress) 
+   { 
+      if (anAddress) Standard::Free((Standard_Address&)anAddress); 
+   }
+   // Methods PUBLIC
+   // 
+   Partition_Spliter();
+   void AddShape(const TopoDS_Shape& S) ;
+   void AddTool(const TopoDS_Shape& S) ;
+   void Compute(const TopAbs_ShapeEnum Limit = TopAbs_SHAPE) ;
+   void KeepShapesInside(const TopoDS_Shape& S) ;
+   void RemoveShapesInside(const TopoDS_Shape& S) ;
+   TopoDS_Shape Shape() const;
+   void Clear() ;
+
+
+
+
+
+protected:
+
+   // Methods PROTECTED
+   // 
+
+
+   // Fields PROTECTED
+   //
+
+
+private: 
+
+   // Methods PRIVATE
+   // 
+   void MakeSolids(const TopoDS_Shape& Solid,TopTools_ListOfShape& Shells) ;
+   void MakeShells(const TopoDS_Shape& S,TopTools_ListOfShape& NS) ;
+   TopoDS_Shape MakeFaces(const TopoDS_Shape& S) ;
+   void MakeEdges(const TopoDS_Edge& E,const TopTools_ListOfShape& VOnE,TopTools_ListOfShape& NE) const;
+   TopoDS_Shape FindFacesInside(const TopoDS_Shape& S,const Standard_Boolean CheckClosed = Standard_False,const Standard_Boolean All = Standard_False) ;
+   Standard_Boolean CheckTool(const TopoDS_Shape& S) ;
+   void MergeEqualEdges(const TopTools_ListOfShape& LE) ;
+   static  Standard_Boolean IsInside(const TopoDS_Shape& S1,const TopoDS_Shape& S2) ;
+   TopoDS_Shape GetOriginalShape(const TopoDS_Shape& aShape) const;
+   void FindToolsToReconstruct() ;
+
+
+   // Fields PRIVATE
+   //
+   TopAbs_ShapeEnum myDoneStep;
+   TopoDS_Compound myShape;
+   BRep_Builder myBuilder;
+   TopTools_ListOfShape myListShapes;
+   TopTools_MapOfShape myMapFaces;
+   TopTools_MapOfShape myMapTools;
+   TopTools_MapOfShape myEqualEdges;
+   TopTools_MapOfShape myNewSection;
+   TopTools_MapOfShape myClosedShapes;
+   TopTools_MapOfShape mySharedFaces;
+   TopTools_MapOfShape myWrappingSolid;
+   TopTools_DataMapOfShapeShape myFaceShapeMap;
+   TopTools_DataMapOfShapeShape myInternalFaces;
+   TopTools_DataMapOfShapeShape myIntNotClFaces;
+   Handle_BRepAlgo_AsDes myAsDes;
+   BRepAlgo_Image myImagesFaces;
+   BRepAlgo_Image myImagesEdges;
+   BRepAlgo_Image myImageShape;
+   Partition_Inter3d myInter3d;
+   TopTools_MapOfOrientedShape myAddedFacesMap;
+
+
+};
+
+
+
+
+
+// other Inline functions and methods (like "C++: function call" methods)
+//
+
+
+#endif
diff --git a/contrib/Salome/Partition_Spliter.ixx b/contrib/Salome/Partition_Spliter.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..ee825946855db633d7899ef2c280a9ef1858dab1
--- /dev/null
+++ b/contrib/Salome/Partition_Spliter.ixx
@@ -0,0 +1,31 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Spliter.ixx
+//  Module : GEOM
+
+#include "Partition_Spliter.jxx"
+
+ 
+
+
diff --git a/contrib/Salome/Partition_Spliter.jxx b/contrib/Salome/Partition_Spliter.jxx
new file mode 100644
index 0000000000000000000000000000000000000000..bf8622c93a6b74b3a14c6b91cf438e4d12cb347e
--- /dev/null
+++ b/contrib/Salome/Partition_Spliter.jxx
@@ -0,0 +1,41 @@
+//  GEOM PARTITION : partition algorithm
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Partition_Spliter.jxx
+//  Module : GEOM
+
+#ifndef _BRepAlgo_AsDes_HeaderFile
+#include <BRepAlgo_AsDes.hxx>
+#endif
+#ifndef _TopoDS_Shape_HeaderFile
+#include <TopoDS_Shape.hxx>
+#endif
+#ifndef _TopTools_ListOfShape_HeaderFile
+#include <TopTools_ListOfShape.hxx>
+#endif
+#ifndef _TopoDS_Edge_HeaderFile
+#include <TopoDS_Edge.hxx>
+#endif
+#ifndef _Partition_Spliter_HeaderFile
+#include "Partition_Spliter.hxx"
+#endif