diff --git a/Mesh/meshRecombine2D.cpp b/Mesh/meshRecombine2D.cpp
index fc535af1096ab06552d44253bda56b5e1115f7bc..799b2f711b645cde5f61ee0f05b88124d9dab5ef 100644
--- a/Mesh/meshRecombine2D.cpp
+++ b/Mesh/meshRecombine2D.cpp
@@ -9,21 +9,20 @@
 
 #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 = 25;
+static int HORIZ = 20;
 
-static int NUM_NEW = 0;
-static int NEW_REC = 0;
 static int NEW_NODE = 0;
-static int NEW_QUAD = 0;
-
-static int NUM_DEL = 0;
-static int DEL_REC = 0;
 static int DEL_NODE = 0;
-static int DEL_QUAD = 0;
 
 Recombine2D::Recombine2D(GFace *gf, int horizon)
-    : _horizon(horizon), _gf(gf), _benef(.0), _applied(false)
+: _horizon(horizon), _gf(gf), _benef(.0), _applied(true)
 {
   if (_horizon < 1) _horizon = 1;
   
@@ -45,12 +44,11 @@ Recombine2D::Recombine2D(GFace *gf, int horizon)
   for (e2t_cont::iterator it = adj.begin(); it != adj.end(); ++it) {
     if (it->second.second) {
       RecombTriangle *rt = new RecombTriangle(it->first, it->second.first, it->second.second);
-NUM_NEW++;
-NEW_REC++;
-      do {
+      ret = _pairs.insert(rt);
+      while (ret.second == false) {
         rt->touch();
         ret = _pairs.insert(rt);
-      } while (ret.second == false);
+      }
       _possibleRecomb[it->second.first].insert(rt);
       _possibleRecomb[it->second.second].insert(rt);
     }
@@ -70,8 +68,6 @@ NEW_REC++;
       rt = new RecombTriangle(itt->first, -100);
     else
       rt = new RecombTriangle(itt->first, -200);
-NUM_NEW++;
-NEW_REC++;
     
     ret = _pairs.insert(rt);
     while (!ret.second) {
@@ -87,18 +83,16 @@ NEW_REC++;
   
   _recombine();
   
-  Msg::Info("new %d = %d + %d + %d", NUM_NEW, NEW_REC, NEW_NODE, NEW_QUAD);
-  Msg::Info("del %d = %d + %d + %d", NUM_DEL, DEL_REC, DEL_NODE, DEL_QUAD);
+  Msg::Info("new %d ", NEW_NODE);
+  Msg::Info("del %d ", DEL_NODE);
+  _applied = false;
 }
 
 Recombine2D::~Recombine2D()
 {
   if (!_applied)
-  for (int i = 0; i < _quads.size(); i++) {
+  for (int i = 0; i < _quads.size(); i++)
     delete _quads[i];
-NUM_DEL++;
-DEL_QUAD++;
-  }
 }
 
 template <class E>
@@ -121,17 +115,53 @@ void Recombine2D::_buildEdgeToElement(std::vector<E*> &elements, e2t_cont &adj)
 
 void Recombine2D::_recombine()
 {
+  SetBoundingBox();
+  
   int i = 0;
   while ((!_pairs.empty() || !_lastRecomb.empty()) && i < 1000) {
     Msg::Info("%d",i);
     Set_Recomb::iterator it = _bestNextRecombination();
+    
+    if (it != _pairs.begin()) {
+      std::set<MElement*> isolatedCP(_isolated);
+      _isolated.clear();
+      Set_Recomb::iterator itnp = _pairs.begin();
+      int n = 0;
+      while (itnp != it) {
+        n++;
+        for (int k = 0; k < (*itnp)->numTriangles(); k++){
+          Msg::Info("recomb[%d] %d : %d", n, k+1, (*itnp)->triangle(k)->getNum());
+          _isolated.insert((*itnp)->triangle(k));
+        }
+        itnp++;
+      }
+      Msg::Info("%d triangles et %d quads", _gf->triangles.size(), _gf->quadrangles.size());
+      _applied = false;
+      apply();
+      _applied = false;
+      CTX::instance()->mesh.changed = (ENT_ALL);
+      drawContext::global()->draw();
+      FlGui::instance()->check();
+      drawContext::global()->draw();
+      if (!Msg::GetAnswer("Continue ?", 1, "no", "yes"))
+        Msg::Info("I continue anyway :p");
+      _isolated = isolatedCP;
+    }
+    
     _benef += (*it)->getBenef();
     if ((*it)->isQuad())
       _quads.push_back((*it)->createQuad());
     else
-      for (int i = 0; i < (*it)->numTriangles(); i++)
-        _isolated.insert((*it)->triangle(i));
+    for (int i = 0; i < (*it)->numTriangles(); i++)
+      _isolated.insert((*it)->triangle(i));
+    
+    /*Set_Recomb::iterator itmp = _pairs.begin();
+    while (itmp != it) {
+      _rmRT(*itmp);
+      itmp = _pairs.begin();
+    }*/
     _removeImpossible(it);
+    
     i++;
   }
   Msg::Info("Done %d (%d)", i, _pairs.size());
@@ -142,18 +172,17 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination()
   if (!_lastRecomb.empty())
     return _lastRecomb.begin();
   
-  int h = 0, nSkip = 0;
-  double maxBenef = _horizon * -200.;
-  
   
   Map_Tri_Node touched;
-  std::vector<Node*> nodes(_horizon);
+  std::vector<Recomb2D_Node*> nodes(_horizon);
   Set_Recomb::iterator it = _pairs.begin(), itmax = _pairs.begin();
   
-  bool end = false;
+  int h = 0, nSkip = 0;
+  double maxBenef = _horizon * -200.;
+  bool haveOptimal = false;
   
   int numb = 0;
-  while (!end) {
+  while (!haveOptimal) {
     numb++;
     while (h < _horizon && it != _pairs.end()) {
       bool possible = true;
@@ -168,20 +197,21 @@ Set_Recomb::iterator Recombine2D::_bestNextRecombination()
       }
         
       if (possible) {
-        if (h == 0) nodes[h] = new Node(it, touched, nSkip);
-        else        nodes[h] = new Node(it, touched, nSkip, nodes[h-1]->getTotBenef());
-NUM_NEW++;
+        if (h == 0) nodes[h] = new Recomb2D_Node(it, nSkip, _horizon, touched);
+        else        nodes[h] = new Recomb2D_Node(it, nSkip, nodes[h-1]);
 NEW_NODE++;
         h++;
         nSkip = 0;
+        if (h >= _horizon || nodes[h - 1]->getBound() < maxBenef)
+          break;
       }
-      else
-        nSkip++;
       
       it++;
     }
     
-    if (nodes[--h]->getTotBenef() > maxBenef) {
+    if (--h < 0) haveOptimal = true;
+    
+    if (nodes[h]->getTotBenef() > maxBenef) {
       maxBenef = nodes[h]->getTotBenef();
       itmax = nodes[0]->getItRecomb();
     }
@@ -197,22 +227,19 @@ NEW_NODE++;
            nodes[h]->getnSkip() >= 2 * (_horizon - h))
       nodes[h--]->erase();*/
     delete nodes[h];
-NUM_DEL++;
 DEL_NODE++;
     while (--h >= 0 &&
            (nodes[h]->isBetter() ||
-            nodes[h]->getnSkip() >= 2 * (_horizon - h))){
-NUM_DEL++;
+            nodes[h]->getnSkip() >= 2 * (_horizon - h) - 1)){
 DEL_NODE++;
       delete nodes[h];
     }
     
-    if (h < 0) end = true;
+    if (h < 0) haveOptimal = true;
     else {
       it = ++nodes[h]->getItRecomb();
       nSkip = nodes[h]->getnSkip() + 1;
       delete nodes[h];
-NUM_DEL++;
 DEL_NODE++;
     }
   }
@@ -230,18 +257,13 @@ void Recombine2D::_removeImpossible(Set_Recomb::iterator it)
   Map_Tri_Recomb::iterator itm;
   std::set<RecombTriangle*>::iterator itrt;
   
-  for (int i = 0; i < t.size(); i++) {
-    
-    itm = _possibleRecomb.find(t[i]);
-    if (itm == _possibleRecomb.end())
-      Msg::Info("not _possibleRecomb");
-    else {
-      itrt = itm->second.begin();
-      while (itrt != itm->second.end()) { // loop over unusable RecombTriangle
-        if (*itrt != *it)
-          _rmRT(*itrt, t[i]);
-        itrt++;
-      }
+  for (int i = 0; i < t.size(); i++) // loop over touched triangles
+  if ((itm = _possibleRecomb.find(t[i])) != _possibleRecomb.end()) {
+    itrt = itm->second.begin();
+    while (itrt != itm->second.end()) { // loop over incompatible RecombTriangle
+      if (*itrt != *it)
+        _rmRT(*itrt, t[i]);
+      itrt++;
     }
     _possibleRecomb.erase(itm);
   }
@@ -250,8 +272,6 @@ void Recombine2D::_removeImpossible(Set_Recomb::iterator it)
   if (!_lastRecomb.erase(*it))
     _pairs.erase(it);
   delete rt;
-NUM_DEL++;
-DEL_REC++;
 }
 
 void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el)
@@ -260,39 +280,34 @@ void Recombine2D::_rmRT(RecombTriangle *rt, MElement *el)
   Map_Tri_Recomb::iterator itmtri;
   
   for (int i = 0; i < rt->numTriangles(); i++)
-  if ((tri = rt->triangle(i)) != el) {
-    itmtri = _possibleRecomb.find(tri);
-    if (itmtri == _possibleRecomb.end())
-      Msg::Info("-not _possibleRecomb");
-    else {
+  if ((tri = rt->triangle(i)) != el &&
+      (itmtri = _possibleRecomb.find(tri)) != _possibleRecomb.end()) {
     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);
         _possibleRecomb.erase(itmtri);
       default :;
     }
-    }
   }
+  
   _pairs.erase(rt);
   _lastRecomb.erase(rt);
   delete rt;
-NUM_DEL++;
-DEL_REC++;
 }
 
 int Recombine2D::apply()
 {
-  if (!_haveParam && !_applied) return 0;
+  if (!_haveParam || _applied) return 0;
   
   std::vector<MTriangle*> triangles2;
   for (int i = 0; i < _gf->triangles.size(); i++) {
     if (_isolated.find(_gf->triangles[i]) == _isolated.end())
-      delete _gf->triangles[i];
+      ;//delete _gf->triangles[i];
     else
       triangles2.push_back(_gf->triangles[i]);
   }
@@ -304,12 +319,13 @@ int Recombine2D::apply()
 }
 
 RecombTriangle::RecombTriangle(const MEdge &me, MElement *t1, MElement *t2)
-    : _formingQuad(true)
+: _formingQuad(true)
 {
   _t.push_back(t1);
   _t.push_back(t2);
   _n1 = me.getVertex(0);
   _n2 = me.getVertex(1);
+  _sign = (std::rand() % 2) * 2 - 1;
 
   if(t1->getVertex(0) != _n1 && t1->getVertex(0) != _n2) _n3 = t1->getVertex(0);
   else if(t1->getVertex(1) != _n1 && t1->getVertex(1) != _n2) _n3 = t1->getVertex(1);
@@ -336,23 +352,22 @@ RecombTriangle::RecombTriangle(const MEdge &me, MElement *t1, MElement *t2)
 }
 
 RecombTriangle::RecombTriangle(MElement *t, double a)
-    : _benefit(a), _formingQuad(false) {
+: _benefit(a), _formingQuad(false)
+{
   _t.push_back(t);
+  _sign = (std::rand() % 2) * 2 - 1;
 }
 
 double RecombTriangle::touch()
 {
-  double prec = 1e-10;
-  
-  double a = (double)(rand() - RAND_MAX / 2) / RAND_MAX * prec;
-  _benefit += a;
-  return a;
+  if (_benefit == .0)
+    return _benefit = _sign * std::pow(2., -1022);
+  else    // add smaller possible value
+    return _benefit += _sign * std::pow(2., std::floor(std::log(std::fabs(_benefit))/std::log(2.))-52);
 }
 
 MQuadrangle *RecombTriangle::createQuad() const
 {
-NUM_NEW++;
-NEW_QUAD++;
   switch (_t.size()) {
     case 1 :
     {
@@ -402,30 +417,54 @@ bool lessRecombTri::operator()(RecombTriangle *rt1, RecombTriangle *rt2) const
   return *rt2 < *rt1;
 }
 
-Node::Node(Set_Recomb::iterator it,
-           Map_Tri_Node &touched,
-           int nskp, double ben) : _nskip(nskp), _recomb(it)
+//{Recomb2D_Node::Recomb2D_Node(Set_Recomb::iterator it,
+//           Map_Tri_Node &touched,
+//           int nskp, double ben) : _nskip(nskp), _recomb(it)
+//{
+//  _benef = (*it)->getBenef();
+//  _totBenef = ben + _benef;
+//  for (int i = 0; i < (*it)->numTriangles(); i++)
+//    _vit.push_back(touched.insert( touched.begin(), std::make_pair((*it)->triangle(i), this) ));
+//  _touch = &touched;
+//}
+//}
+
+Recomb2D_Node::Recomb2D_Node(Set_Recomb::iterator it, int nskp, int horiz,
+                             Map_Tri_Node &touched)
+: _nskip(nskp), _recomb(it)
 {
   _benef = (*it)->getBenef();
-  _totBenef = ben + _benef;
+  _totBenef = _benef;
+  _depth = horiz - 1;
   for (int i = 0; i < (*it)->numTriangles(); i++)
     _vit.push_back(touched.insert( touched.begin(), std::make_pair((*it)->triangle(i), this) ));
   _touch = &touched;
 }
 
-Node::~Node()
+Recomb2D_Node::Recomb2D_Node(Set_Recomb::iterator it, int nskp, Recomb2D_Node *n)
+: _nskip(nskp), _recomb(it)
+{
+  _benef = (*it)->getBenef();
+  _totBenef = n->_benef + _benef;
+  _depth = n->_depth - 1;
+  _touch = n->_touch;
+  for (int i = 0; i < (*it)->numTriangles(); i++)
+    _vit.push_back(_touch->insert( _touch->begin(), std::make_pair((*it)->triangle(i), this) ));
+}
+
+Recomb2D_Node::~Recomb2D_Node()
 {
   for (int i = 0; i < _vit.size(); i++)
     _touch->erase(_vit[i]);
 }
 
-void Node::erase()
+void Recomb2D_Node::erase()
 {
   for (int i = 0; i < _vit.size(); i++)
     _touch->erase(_vit[i]);
 }
 
-void Node::blocking(const Map_Tri_Node::iterator &it)
+void Recomb2D_Node::blocking(const Map_Tri_Node::iterator &it)
 {
   for (int i = 0; i < _vit.size(); i++) {
     if (it == _vit[i]) {
diff --git a/Mesh/meshRecombine2D.h b/Mesh/meshRecombine2D.h
index dc216e6f79e2225171c7e0e386ca355a8d5953c5..9b4af90a9db782f468c25e32c3ec68d8656920b9 100644
--- a/Mesh/meshRecombine2D.h
+++ b/Mesh/meshRecombine2D.h
@@ -19,14 +19,14 @@
 #include "meshGFaceOptimize.h"
 
 class RecombTriangle;
-class Node;
+class Recomb2D_Node;
 struct lessRecombTri {
   bool operator()(RecombTriangle *rt1, RecombTriangle *rt2) const;
 };
 
 typedef std::set<RecombTriangle*,lessRecombTri> Set_Recomb;
 typedef std::map<MElement*,std::set<RecombTriangle*> > Map_Tri_Recomb;
-typedef std::map<MElement*,Node*> Map_Tri_Node;
+typedef std::map<MElement*,Recomb2D_Node*> Map_Tri_Node;
 
 class Recombine2D {
   private :
@@ -44,7 +44,7 @@ class Recombine2D {
     void _recombine();
     Set_Recomb::iterator _bestNextRecombination();
     void _removeImpossible(Set_Recomb::iterator);
-    void _rmRT(RecombTriangle *, MElement *);
+    void _rmRT(RecombTriangle *, MElement *e = NULL);
     
   public :
     Recombine2D(GFace*, int horizon);
@@ -62,6 +62,7 @@ class RecombTriangle {
     double _angle;
     double _benefit;
     bool _formingQuad;
+    int _sign;
     
   public :
     RecombTriangle(const MEdge &, MElement *, MElement *);
@@ -85,10 +86,10 @@ class RecombTriangle {
     double compute_alignment(const MEdge&, MElement*, MElement*);
 };
 
-class Node {
+class Recomb2D_Node {
   private :  
     double _benef, _totBenef;
-    int _nskip;
+    int _nskip, _depth;
     Set_Recomb::iterator _recomb;
     Map_Tri_Node *_touch;
     std::vector<Map_Tri_Node::iterator> _vit;
@@ -96,15 +97,19 @@ class Node {
   
   public :
     //Node(){}
-    Node(Set_Recomb::iterator, Map_Tri_Node &, int, double ben = .0);
-    ~Node();
+    //Recomb2D_Node(Set_Recomb::iterator, Map_Tri_Node &, int, double ben = .0);
+    
+    Recomb2D_Node(Set_Recomb::iterator, int nskip, int depth, Map_Tri_Node &);
+    Recomb2D_Node(Set_Recomb::iterator, int nskip, Recomb2D_Node *);
+    ~Recomb2D_Node();
     
     void erase();
     void blocking(const Map_Tri_Node::iterator &);
     bool isBetter() {return _blocking.size() < 2;}
     Set_Recomb::iterator getItRecomb() {return _recomb;}
     double getTotBenef() {return _totBenef;}
-    double getnSkip() {return _nskip;}
+    int getnSkip() {return _nskip;}
+    double getBound() {return _totBenef + _benef * _depth;}
 };