diff --git a/Mesh/meshRecombine2D.cpp b/Mesh/meshRecombine2D.cpp
index 799b2f711b645cde5f61ee0f05b88124d9dab5ef..ac9a18f2e332f38115e1cf6fe202d357dcfd9e3b 100644
--- a/Mesh/meshRecombine2D.cpp
+++ b/Mesh/meshRecombine2D.cpp
@@ -26,6 +26,11 @@ Recombine2D::Recombine2D(GFace *gf, int horizon)
 {
   if (_horizon < 1) _horizon = 1;
   
+  //return;
+  
+  laplaceSmoothing(gf,100);
+  gf->model()->writeMSH("befSquare.msh");
+  
   Msg::Info("Branching with horizon %d", _horizon = HORIZ);
   
   _haveParam = gf->geomType() != GEntity::DiscreteSurface || gf->getCompound();
@@ -60,7 +65,7 @@ Recombine2D::Recombine2D(GFace *gf, int horizon)
     }
   }
   
-  std::map<MElement*, int>::iterator itt;
+  /*std::map<MElement*, int>::iterator itt;
   
   for (itt = boundaryTriangle.begin(); itt != boundaryTriangle.end(); ++itt) {
     RecombTriangle *rt;
@@ -75,7 +80,7 @@ Recombine2D::Recombine2D(GFace *gf, int horizon)
       ret = _pairs.insert(rt);
     }
     _possibleRecomb[itt->first].insert(rt);
-  }
+  }*/
   
   Msg::Info("poss %d", _possibleRecomb.size());
   Msg::Info("pairs %d", _pairs.size());
@@ -117,12 +122,18 @@ void Recombine2D::_recombine()
 {
   SetBoundingBox();
   
+  /*Map_Tri_Recomb::iterator itt;
+  
+  for (itt = _possibleRecomb.begin(); itt != _possibleRecomb.end(); ++itt) {
+    if
+  }*/
+  
   int i = 0;
   while ((!_pairs.empty() || !_lastRecomb.empty()) && i < 1000) {
     Msg::Info("%d",i);
     Set_Recomb::iterator it = _bestNextRecombination();
     
-    if (it != _pairs.begin()) {
+    /*if (it != _pairs.begin()) {
       std::set<MElement*> isolatedCP(_isolated);
       _isolated.clear();
       Set_Recomb::iterator itnp = _pairs.begin();
@@ -146,7 +157,7 @@ void Recombine2D::_recombine()
       if (!Msg::GetAnswer("Continue ?", 1, "no", "yes"))
         Msg::Info("I continue anyway :p");
       _isolated = isolatedCP;
-    }
+    }*/
     
     _benef += (*it)->getBenef();
     if ((*it)->isQuad())
@@ -180,6 +191,7 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination()
   int h = 0, nSkip = 0;
   double maxBenef = _horizon * -200.;
   bool haveOptimal = false;
+  int maxH = 0;
   
   int numb = 0;
   while (!haveOptimal) {
@@ -211,9 +223,10 @@ NEW_NODE++;
     
     if (--h < 0) haveOptimal = true;
     
-    if (nodes[h]->getTotBenef() > maxBenef) {
+    if (nodes[h]->getTotBenef() > maxBenef && h >= maxH) {
       maxBenef = nodes[h]->getTotBenef();
       itmax = nodes[0]->getItRecomb();
+      maxH = h;
     }
     
     /*nSkip = 0;
@@ -226,13 +239,11 @@ NEW_NODE++;
            nodes[h]->beSkipped() &&
            nodes[h]->getnSkip() >= 2 * (_horizon - h))
       nodes[h--]->erase();*/
-    delete nodes[h];
-DEL_NODE++;
-    while (--h >= 0 &&
+    while (h >= 0 &&
            (nodes[h]->isBetter() ||
             nodes[h]->getnSkip() >= 2 * (_horizon - h) - 1)){
 DEL_NODE++;
-      delete nodes[h];
+      delete nodes[h--];
     }
     
     if (h < 0) haveOptimal = true;
@@ -285,8 +296,8 @@ void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el)
     itmtri->second.erase(rt);
     switch (itmtri->second.size()) {
       case 1 :
-        //_pairs.erase(*itmtri->second.begin());
-        //_lastRecomb.insert(*itmtri->second.begin());
+        _pairs.erase(*itmtri->second.begin());
+        _lastRecomb.insert(*itmtri->second.begin());
         break;
       case 0 :
         _isolated.insert(tri);
@@ -315,6 +326,9 @@ int Recombine2D::apply()
   _gf->quadrangles = _quads;
   
   _applied = true;
+  _gf->model()->writeMSH("recSquare.msh");
+  laplaceSmoothing(_gf,100);
+  _gf->model()->writeMSH("aftSquare.msh");
   return 1;
 }
 
diff --git a/Mesh/meshRecombine2D.h b/Mesh/meshRecombine2D.h
index 9b4af90a9db782f468c25e32c3ec68d8656920b9..c441b108db46543422de546ab38b5d1b4217902f 100644
--- a/Mesh/meshRecombine2D.h
+++ b/Mesh/meshRecombine2D.h
@@ -20,6 +20,9 @@
 
 class RecombTriangle;
 class Recomb2D_Node;
+class Rec2d_node;
+class Rec2d_edge;
+class Rec2d_cycle;
 struct lessRecombTri {
   bool operator()(RecombTriangle *rt1, RecombTriangle *rt2) const;
 };
@@ -48,11 +51,17 @@ class Recombine2D {
     
   public :
     Recombine2D(GFace*, int horizon);
+    Recombine2D(GFace*);
     ~Recombine2D();
     
     int apply();
     double getBenef() const {return _benef;}
     int numTriangle() const {return _isolated.size();}
+    
+  private :
+    std::set<Rec2d_node*> _nodes;
+    std::set<Rec2d_edge*> _edges;
+    std::set<Rec2d_cycle*> _cycles;
 };
 
 class RecombTriangle {
@@ -113,4 +122,43 @@ class Recomb2D_Node {
 };
 
 
+class Rec2d_node {
+  private :
+    std::set<Rec2d_edge*> _freeEdges;
+    std::set<Rec2d_cycle*> _cycle3;
+    std::set<Rec2d_cycle*> _cycle4;
+  
+  public :
+    Rec2d_node(){}
+    
+    void addCycle(Rec2d_cycle*, int n = 0);
+    void addEdge(Rec2d_edge*);
+    
+    void print();
+};
+class Rec2d_edge {
+  private :
+    Rec2d_node *_nodes[2];
+    std::set<Rec2d_cycle*> _cycles;
+  
+  public :
+    Rec2d_edge(Rec2d_node*, Rec2d_node*);
+    
+    void addCycle(Rec2d_cycle*);
+    
+    void print();
+};
+class Rec2d_cycle {
+  private :
+    std::set<Rec2d_edge*> _edges;
+  
+  public :
+    Rec2d_cycle(){}
+    void addEdge(Rec2d_edge*);
+    int size() {return _edges.size();}
+    
+    void print();
+};
+
+
 #endif
diff --git a/Mesh/meshRecombine2D_2.cpp b/Mesh/meshRecombine2D_2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8ed74c74205b0bead78408e1962c8bc3582412d5
--- /dev/null
+++ b/Mesh/meshRecombine2D_2.cpp
@@ -0,0 +1,119 @@
+// 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>.
+//
+// Contributor(s):
+//   Amaury Johnen (amjohnen@gmail.com) adapted from meshGFaceOptimize
+//
+
+#include "meshRecombine2D.h"
+#include "GFace.h"
+#include <cmath>
+#include <FL/Fl.H>
+#include "drawContext.h"
+#include "FlGui.h"
+#include "Context.h"
+#include "OpenFile.h"//pas propre
+
+static int HORIZ = 20;
+
+Recombine2D::Recombine2D(GFace *gf)
+: _horizon(0), _gf(gf), _benef(.0), _applied(true)
+{
+  std::map<MEdge, Rec2d_edge*, Less_Edge> mapEdge;
+  std::map<MVertex*, Rec2d_node*> mapNode;
+  
+  for (unsigned int i = 0; i < gf->triangles.size(); i++) {
+    Rec2d_cycle *rc = new Rec2d_cycle();
+    _cycles.insert(rc);
+    MTriangle *t = gf->triangles[i];
+    
+    for (int j = 0; j < 3; j++) {
+      MVertex *v = t->getVertex(j);
+      std::map<MVertex*, Rec2d_node*>::iterator itn = mapNode.find(v);
+      if (itn == mapNode.end()) {
+        Rec2d_node *rn = new Rec2d_node();
+        mapNode[v] = rn;
+        _nodes.insert(rn);
+        rn->addCycle(rc, 3);
+      }
+      else
+        (*itn).second->addCycle(rc, 3);
+    }
+    
+    for (int j = 0; j < 3; j++) {
+      MEdge e = t->getEdge(j);
+      std::map<MEdge, Rec2d_edge*>::iterator ite = mapEdge.find(e);
+      if (ite == mapEdge.end()) {
+        Rec2d_node *n0 = mapNode[e.getVertex(0)];
+        Rec2d_node *n1 = mapNode[e.getVertex(1)];
+        Rec2d_edge *re = new Rec2d_edge(n0, n1);
+        n0->addEdge(re);
+        n1->addEdge(re);
+        mapEdge[e] = re;
+        _edges.insert(re);
+        rc->addEdge(re);
+        re->addCycle(rc);
+      }
+      else {
+        rc->addEdge((*ite).second);
+        (*ite).second->addCycle(rc);
+      }
+    }
+  }
+  }ZzZ
+}
+
+void Rec2d_node::addCycle(Rec2d_cycle *c, int n)
+{
+  if (n == 3) {
+    _cycle3.insert(c);
+    return;
+  }
+  if (n == 4) {
+    _cycle4.insert(c);
+    return;
+  }
+  if (c->size() == 3) {
+    _cycle3.insert(c);
+    return;
+  }
+  if (c->size() == 4) {
+    _cycle4.insert(c);
+    return;
+  }
+  Msg::Error("[Recombine2D] Can't tell if it's a cycle3 or a cycle4");
+}
+void Rec2d_node::addEdge(Rec2d_edge *e)
+{
+  _freeEdges.insert(e); //que faire ?
+}
+void Rec2d_node::print()
+{
+  Msg::Info("Node : %d cycle3, %d cycle4, %d edges", _cycle3.size(), _cycle4.size(), _freeEdges.size());
+}
+
+Rec2d_edge::Rec2d_edge(Rec2d_node *n0, Rec2d_node *n1)
+{
+  _nodes[0] = n0;
+  _nodes[1] = n1;
+}
+void Rec2d_edge::addCycle(Rec2d_cycle *c)
+{
+  _cycles.insert(c);
+}
+void Rec2d_edge::print()
+{
+  Msg::Info("Edge : %d cycles", _cycles.size());
+}
+
+void Rec2d_cycle::addEdge(Rec2d_edge *e)
+{
+  _edges.insert(e);
+}
+void Rec2d_cycle::print()
+{
+  Msg::Info("Cycle : %d edges", _edges.size());
+}
+