diff --git a/Mesh/surfaceFiller.cpp b/Mesh/surfaceFiller.cpp
index 0777ea75e33d3a6f711260103970d4cbefead159..08405e61204fe3d6eab9047457321ace45893257 100644
--- a/Mesh/surfaceFiller.cpp
+++ b/Mesh/surfaceFiller.cpp
@@ -27,10 +27,19 @@
 #include "BackgroundMesh.h"
 #include "intersectCurveSurface.h"
 
+using namespace std;
+
 static const double FACTOR = .71;
+
+
 static const int NUMDIR = 3;
-//static const double DIRS [NUMDIR] = {0.0};
 static const double DIRS [NUMDIR] = {0.0, M_PI/20.,-M_PI/20.};
+//PE MODIF
+//static const int NUMDIR = 1;
+//static const double DIRS [NUMDIR] = {0.0};
+// END PE MODIF
+
+
 
 /// a rectangle in the tangent plane is transformed
 /// into a parallelogram. We define an exclusion zone
@@ -119,6 +128,27 @@ struct my_wrapper {
   my_wrapper (SPoint2 sp) : _tooclose (false), _p(sp) {}
 };
 
+struct smoothness_point_pair{
+  double rank;
+  surfacePointWithExclusionRegion* ptr;
+};
+
+class compareSurfacePointWithExclusionRegionPtr_Smoothness
+{
+  public:
+    inline bool operator () (const smoothness_point_pair &a, const smoothness_point_pair &b)  const
+    {
+      if (a.rank == b.rank){
+        if(a.ptr->_distanceSummed > b.ptr->_distanceSummed) return false;
+        if(a.ptr->_distanceSummed < b.ptr->_distanceSummed) return true;
+        return a.ptr<b.ptr;
+      }
+      // else
+      return (a.rank < b.rank);
+    }
+};
+    
+
 class compareSurfacePointWithExclusionRegionPtr
 {
  public:
@@ -390,10 +420,510 @@ bool compute4neighbors (GFace *gf,   // the surface
 }
 #endif
 
+
+// ---------------------------------------------------------------------------------------------
+
+// recover element around vertex v and interpolate smoothness on this element...
+double get_smoothness(MVertex *v, GFace *gf, const map<MVertex*,double> &vertices2smoothness){
+  // recover element around MVertex v
+  //cout << "Looking for element around point (" << v->x() << "," << v->y() << "," << v->z() << ")" << endl;
+  SPoint3 sp3(v->x(), v->y(), v->z());
+  SPoint2 param_point;
+  reparamMeshVertexOnFace(v, gf, param_point);
+  MElement *elem = backgroundMesh::current()->getMeshElementByCoord(param_point[0], param_point[1], 0.);
+  if (!elem){
+    elem = backgroundMesh::current()->getMeshElementByCoord(param_point[0], param_point[1], 0., false);
+    if (!elem)
+      cout << " ------ WARNING !!! surfaceFiller : get_smoothness : No element found for coordinate (" << sp3.x() << "," << sp3.y() << "," << sp3.z() << ")" << endl;
+  }
+
+  // recover element's vertices:
+  vector<MVertex*> localvertices;
+  for (int ivert=0;ivert<elem->getNumVertices();ivert++){
+    MVertex *temp = elem->getVertex(ivert);
+    localvertices.push_back(temp);
+//    cout << " made of vertex " << temp->x() << "," << temp->y() << "," << temp->z() << endl;
+  }
+
+  // recover parametrisation uvw
+  double uvw[3],xyz[3];
+  xyz[0] = param_point[0];
+  xyz[1] = param_point[1];
+  xyz[2] = 0.;
+  elem->xyz2uvw(xyz, uvw);
+//  cout << "xyz is " << xyz[0] << ","  << xyz[1] << ","  << xyz[2] << endl;
+//  cout << "uvw is " << uvw[0] << ","  << uvw[1] << ","  << uvw[2] << endl;
+
+  // interpolate :
+  double val[3];
+  int i=0;
+  for (vector<MVertex*>::iterator it = localvertices.begin();it!=localvertices.end();it++){
+    MVertex *localv = *it;
+    map<MVertex*,double>::const_iterator itfind = vertices2smoothness.find(localv);
+    if (itfind==vertices2smoothness.end()){
+      cerr << "WARNING: surfaceFiller : get_smoothness : BACKGROUNDMESH VERTEX NOT FOUND IN SMOOTHNESS COMPUTATION !!! ABORTING..." << endl;
+      throw;
+    }
+//    cout << "nodal value: " << itfind->second << endl;
+    val[i++] = itfind->second;
+  }
+//  cout << "uvw is " << uvw[0] << "  " <<  uvw[1] << "  " <<  uvw[2] << endl;
+  double res = elem->interpolate(val, uvw[0], uvw[1], uvw[2]);
+//  cout << " THE VALUE = " << res << endl;
+  return res;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void print_nodal_info_int(string filename, map<MVertex*, int> &mapp){
+  ofstream out(filename.c_str());
+
+  out << "View \"\"{" << endl;
+  for (map<MVertex*, int>::iterator it = mapp.begin();it!=mapp.end();it++){
+    MVertex *v = it->first;
+    out << "SP( " << v->x() << "," << v->y() << "," << v->z() << "){" << it->second << "};" << endl;;
+  }
+  out << "};" << endl;
+
+  out.close();
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void print_nodal_info_double(string filename, map<MVertex*, double> &mapp){
+  ofstream out(filename.c_str());
+
+  out << "View \"\"{" << endl;
+  for (map<MVertex*, double>::iterator it = mapp.begin();it!=mapp.end();it++){
+    MVertex *v = it->first;
+    out << "SP( " << v->x() << "," << v->y() << "," << v->z() << "){" << it->second << "};" << endl;;
+  }
+  out << "};" << endl;
+
+  out.close();
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void export_point(surfacePointWithExclusionRegion *sp, int DIR, FILE *crossf, GFace *gf){
+  // get the unit normal at that point
+  Pair<SVector3, SVector3> der = gf->firstDer(sp->_center);
+  SVector3 s1 = der.first();
+  SVector3 s2 = der.second();
+  SVector3 n = crossprod(s1,s2);
+  n.normalize();
+  SVector3 basis_u = s1; basis_u.normalize();
+  SVector3 basis_v = crossprod(n,basis_u);
+
+  double quadAngle  = backgroundMesh::current()->getAngle (sp->_center[0],sp->_center[1],0) + DIRS[DIR];
+
+  // normalize vector t1 that is tangent to gf at midpoint
+  SVector3 t1 = basis_u * cos (quadAngle) + basis_v * sin (quadAngle) ;
+  t1.normalize();
+
+  // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
+  SVector3 t2 = crossprod(n,t1);
+  t2.normalize();
+
+  //  double scale = DIR+1.;
+  SMetric3 metricField;
+  double L = backgroundMesh::current()->operator()(sp->_center[0],sp->_center[1],0.0);
+  metricField = SMetric3(1./(L*L));
+  FieldManager *fields = gf->model()->getFields();
+  if(fields->getBackgroundField() > 0){
+    Field *f = fields->get(fields->getBackgroundField());
+    if (!f->isotropic()){
+      (*f)(sp->_v->x(),sp->_v->y(),sp->_v->z(), metricField,gf);
+    }
+    else {
+      L = (*f)(sp->_v->x(),sp->_v->y(),sp->_v->z(), gf);
+      metricField = SMetric3(1./(L*L));
+    }
+  }
+  double size_1 = sqrt(1. / dot(t1,metricField,t1));
+  double size_2 = sqrt(1. / dot(t2,metricField,t2));
+
+  //  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),t1.x()*scale,t1.y()*scale,t1.z()*scale);
+  //  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),t2.x()*scale,t2.y()*scale,t2.z()*scale);
+  //  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),-t1.x()*scale,-t1.y()*scale,-t1.z()*scale);
+  //  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),-t2.x()*scale,-t2.y()*scale,-t2.z()*scale);
+  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),t1.x()*size_1,t1.y()*size_1,t1.z()*size_1);
+  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),t2.x()*size_2,t2.y()*size_2,t2.z()*size_2);
+  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),-t1.x()*size_1,-t1.y()*size_1,-t1.z()*size_1);
+  fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",sp->_v->x(),sp->_v->y(),sp->_v->z(),-t2.x()*size_2,-t2.y()*size_2,-t2.z()*size_2);
+}
+
+// ---------------------------------------------------------------------------------------------
+
+bool get_local_sizes_and_directions(const MVertex *v_center, const SPoint2 &midpoint, const int DIR, GFace* gf, double (&covar1)[2], double (&covar2)[2], double &size_param_1, double &size_param_2, double &L, SVector3 &t1, SVector3 &t2, SVector3 &n, FILE *crossf=NULL){
+//bool get_RK_stuff(const MVertex *v_center, const SPoint2 &midpoint, const int DIR, GFace* gf, double (&covar1)[2], double (&covar2)[2], double &size_param_1, double &size_param_2, double &L, SVector3 &t1, SVector3 &t2, SVector3 &n, FILE *crossf, const SVector3 &previous_t1, const SVector3 &previous_t2, bool use_previous_basis=false, bool export_cross=true){
+
+  // !!!!!!!!!!!! check if point is in domain (for RK !!!)
+  if (!backgroundMesh::current()->inDomain(midpoint.x(),midpoint.y(),0)) return false;
+
+  SMetric3 metricField;
+  L = backgroundMesh::current()->operator()(midpoint[0],midpoint[1],0.0);
+  //  printf("L = %12.5E\n",L);
+  metricField = SMetric3(1./(L*L));
+  FieldManager *fields = gf->model()->getFields();
+  if(fields->getBackgroundField() > 0){
+    Field *f = fields->get(fields->getBackgroundField());
+    if (!f->isotropic()){
+      (*f)(v_center->x(),v_center->y(),v_center->z(), metricField,gf);
+    }
+    else {
+      L = (*f)(v_center->x(),v_center->y(),v_center->z(), gf);
+      metricField = SMetric3(1./(L*L));
+    }
+  }
+
+  // get the unit normal at that point
+  Pair<SVector3, SVector3> der = gf->firstDer(SPoint2(midpoint[0],midpoint[1]));
+  SVector3 s1 = der.first();
+  SVector3 s2 = der.second();
+  n = crossprod(s1,s2);
+  n.normalize();
+
+  double M = dot(s1,s1);
+  double N = dot(s2,s2);
+  double E = dot(s1,s2);
+
+  // compute the first fundamental form i.e. the metric tensor at the point
+  // M_{ij} = s_i \cdot s_j
+  double metric[2][2] = {{M,E},{E,N}};
+
+  //  printf("%d %g %g %g\n",gf->tag(),s1.x(),s1.y(),s1.z());
+
+  SVector3 basis_u = s1; basis_u.normalize();
+  SVector3 basis_v = crossprod(n,basis_u);
+
+  double quadAngle  = backgroundMesh::current()->getAngle (midpoint[0],midpoint[1],0) + DIRS[DIR];
+  //double quadAngle  = atan2(midpoint[0],midpoint[1]);
+
+  // normalize vector t1 that is tangent to gf at midpoint
+  t1 = basis_u * cos (quadAngle) + basis_v * sin (quadAngle) ;
+  t1.normalize();
+
+  // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
+  t2 = crossprod(n,t1);
+  t2.normalize();
+
+
+  //  std::cout << std::endl;
+  //  std::cout << "basis uv : (" << basis_u(0) << "," <<  basis_u(1) << ") (" << basis_v(0) << "," << basis_v(1) << std::endl;
+  //  std::cout << "t        : (" << t1(0) << "," <<  t1(1) << ") (" << t2(0) << "," << t2(1) << std::endl;
+
+//  if (use_previous_basis){
+//    std::map<double, double> angles;
+//    SVector3 temp = crossprod(previous_t1, t1);
+//    double a = atan2(dot(t1, previous_t1), sign(dot(temp,n))*temp.norm() );
+//    angles.insert(std::make_pair(abs(a),a));
+//    temp = crossprod(previous_t2, t1);
+//    a = atan2(dot(t1, previous_t2), sign(dot(temp,n))*temp.norm());
+//    angles.insert(std::make_pair(abs(a),a));
+//    temp = crossprod(-1.*previous_t1, t1);
+//    a = atan2(dot(t1, -1.*previous_t1), sign(dot(temp,n))*temp.norm());
+//    angles.insert(std::make_pair(abs(a),a));
+//    temp = crossprod(-1.*previous_t2, t1);
+//    a = atan2(dot(t1, -1.*previous_t2), sign(dot(temp,n))*temp.norm());
+//    angles.insert(std::make_pair(abs(a),a));
+//    //    std::cout << "angles: " << std::endl;
+//    //    for (int i=0;i<4;i++)  std::cout << angles[i] << "  " << std::endl;
+//    double min_angle = -(angles.begin()->second); 
+//    //    std::cout << "min angle = " << min_angle << std::endl;
+//    t1 =  cos(min_angle)*previous_t1 + sin(min_angle)*previous_t2;
+//    t2 = -sin(min_angle)*previous_t1 + cos(min_angle)*previous_t2;
+//    //    std::cout << "new corrected t        : (" << t1(0) << "," <<  t1(1) << ") (" << t2(0) << "," << t2(1) << std::endl;
+//  }
+
+  double size_1 = sqrt(1. / dot(t1,metricField,t1));
+  double size_2 = sqrt(1. / dot(t2,metricField,t2));
+
+
+  if (crossf){
+    if (DIR == 0 && crossf)fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",v_center->x(),v_center->y(),v_center->z(),t1.x()*size_1,t1.y()*size_1,t1.z()*size_1);
+    if (DIR == 0 && crossf)fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",v_center->x(),v_center->y(),v_center->z(),t2.x()*size_2,t2.y()*size_2,t2.z()*size_2);
+    if (DIR == 0 && crossf)fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",v_center->x(),v_center->y(),v_center->z(),-t1.x()*size_1,-t1.y()*size_1,-t1.z()*size_1);
+    if (DIR == 0 && crossf)fprintf(crossf,"VP(%g,%g,%g) {%g,%g,%g};\n",v_center->x(),v_center->y(),v_center->z(),-t2.x()*size_2,-t2.y()*size_2,-t2.z()*size_2);
+  }
+
+  // compute covariant coordinates of t1 and t2
+  // t1 = a s1 + b s2 -->
+  // t1 . s1 = a M + b E
+  // t1 . s2 = a E + b N --> solve the 2 x 2 system
+  // and get covariant coordinates a and b
+  double rhs1[2] = {dot(t1,s1),dot(t1,s2)};
+  bool singular = false;
+  if (!sys2x2(metric,rhs1,covar1)){
+    Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2);
+    covar1[1] = 1.0; covar1[0] = 0.0;
+    singular = true;
+  }
+  double rhs2[2] = {dot(t2,s1),dot(t2,s2)};
+  if (!sys2x2(metric,rhs2,covar2)){
+    Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z());
+    covar2[0] = 1.0; covar2[1] = 0.0;
+    singular = true;
+  }
+
+  // transform the sizes with respect to the metric
+  // consider a vector v of size 1 in the parameter plane
+  // its length is sqrt (v^T M v) --> if I want a real size
+  // of size1 in direction v, it should be sqrt(v^T M v) * size1
+  double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]);
+  double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]);
+
+  covar1[0] /= l1;covar1[1] /= l1;
+  covar2[0] /= l2;covar2[1] /= l2;
+
+  size_param_1  = size_1 / sqrt (  M*covar1[0]*covar1[0]+
+      2*E*covar1[1]*covar1[0]+
+      N*covar1[1]*covar1[1]);
+  size_param_2  = size_2 / sqrt (  M*covar2[0]*covar2[0]+
+      2*E*covar2[1]*covar2[0]+
+      N*covar2[1]*covar2[1]);
+  if (singular){
+    size_param_1 = size_param_2 = std::min (size_param_1,size_param_2);
+  }
+
+
+  return true;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+// using fifo based on smoothness criteria
+void packingOfParallelogramsSmoothness(GFace* gf,  std::vector<MVertex*> &packed, std::vector<SMetric3> &metrics){
+  cout << endl << "------------------------------------------" << endl << "   PACKINGOFPARALLELOGRAMS: NEW ALGO BASED ON SMOOTHNESS" << endl << "------------------------------------------" << endl;
+#if defined(HAVE_RTREE)
+  const bool goNonLinear = true;
+
+  const bool debug = false;
+
+  // build vertex -> neighbors table
+  multimap<MVertex*,MVertex*> vertex2vertex;
+  for (std::vector<MElement*>::iterator it = backgroundMesh::current()->begin_triangles();it!=backgroundMesh::current()->end_triangles();it++){
+    MElement *e = *it;
+    for (int i=0;i<e->getNumVertices();i++){
+      MVertex *current = e->getVertex(i);
+      for (int j=0;j<e->getNumVertices();j++){
+        if (i==j) continue;
+        MVertex *neighbor = e->getVertex(j);
+        vertex2vertex.insert(make_pair(current,neighbor));
+      }
+    }
+  }
+
+  // build table vertex->smoothness
+  map<MVertex*,double> vertices2smoothness;
+  map<MVertex*, double> smoothness_essai;
+  for (std::vector<MVertex*>::iterator it = backgroundMesh::current()->begin_vertices();it!=backgroundMesh::current()->end_vertices();it++){
+    MVertex *v = *it;
+
+    SPoint2 param_point(v->x(),v->y());GPoint gpt = gf->point(param_point); MVertex v_real(gpt.x(),gpt.y(),gpt.z());
+    SVector3 t1,t2,n;double covar1[2],covar2[2],L,size_param_1,size_param_2;
+    get_local_sizes_and_directions(&v_real, param_point, 0, gf, covar1, covar2, size_param_1, size_param_2, L, t1, t2, n);
+
+    // compare to all neighbors...
+    pair<multimap<MVertex*,MVertex*>::iterator, multimap<MVertex*,MVertex*>::iterator> range = vertex2vertex.equal_range(v);
+    SVector3 t1_nb,t2_nb,n_nb;double covar1_nb[2],covar2_nb[2],L_nb,size_param_1_nb,size_param_2_nb;
+    double maxprod,angle=0.;
+    int N=0;
+    for (multimap<MVertex*,MVertex*>::iterator itneighbor = range.first;itneighbor!=range.second;itneighbor++){
+      N++;
+      maxprod=0.;
+      MVertex *v_nb = itneighbor->second;
+      SPoint2 param_point_nb(v_nb->x(),v_nb->y());GPoint gpt_nb = gf->point(param_point_nb); MVertex v_real_nb(gpt_nb.x(),gpt_nb.y(),gpt_nb.z());
+      get_local_sizes_and_directions(&v_real_nb, param_point_nb, 0, gf, covar1_nb, covar2_nb, size_param_1_nb, size_param_2_nb, L_nb, t1_nb, t2_nb, n_nb);
+      // angle comparison...
+      maxprod = fmax(maxprod, fabs(t1[0]*t1_nb[0] + t1[1]*t1_nb[1]));
+      maxprod = fmax(maxprod, fabs(t1[0]*t2_nb[0] + t1[1]*t2_nb[1]));
+      angle += fabs(acos(max(min(maxprod,1.),-1.)));
+    }
+    angle /= N;
+    vertices2smoothness[v] = angle;
+  }
+
+//  if (debug){
+//    stringstream ss;
+//    ss << "backgroundmesh_smoothness_" << gf->tag() << ".pos";
+//    backgroundMesh::current()->print(ss.str().c_str(),gf, vertices2smoothness);
+//  }
+
+
+  // --------------- export de smoothness comme elements.... -----------------------
+  if (debug){
+    stringstream ss;
+    ss << "backgroundmesh_element_smoothness_" << gf->tag() << ".pos";
+    ofstream out(ss.str().c_str());
+    out << "View \"directions\" {" << endl;
+    for (std::vector<MElement*>::iterator it = backgroundMesh::current()->begin_triangles();it!=backgroundMesh::current()->end_triangles();it++){
+      MElement *e = *it;
+      vector<MVertex *> nodes;
+      vector<double> smoothtemp;
+      for (int i=0;i<3;i++){
+        MVertex *v = e->getVertex(i);
+        nodes.push_back(v);
+        smoothtemp.push_back(vertices2smoothness[v]);
+      }
+      out << "ST(";
+      for (int i=0;i<3;i++){
+        GPoint pp = gf->point(SPoint2(nodes[i]->x(),nodes[i]->y()));
+        out << pp.x() << "," << pp.y() << "," << pp.z();
+        if (i!=2) out << ",";
+      }
+      out << "){";
+      for (int i=0;i<3;i++){
+        out << (1.-(smoothtemp[i]/M_PI*4.));
+        if (i!=2) out << ",";
+      }
+      out << "};" << endl;
+
+    }
+    out << "};" << endl;
+    out.close();
+  }
+  //                   --------------- END ----------------
+
+
+  // for debug check...
+  int priority_counter=0;
+  map<MVertex*,int> vert_priority;
+
+  // get all the boundary vertices
+  std::set<MVertex*> bnd_vertices;
+  for(unsigned int i=0;i<gf->getNumMeshElements();i++){
+    MElement* element = gf->getMeshElement(i);
+    for(int j=0;j<element->getNumVertices();j++){
+      MVertex *vertex = element->getVertex(j);
+      if (vertex->onWhat()->dim() < 2)bnd_vertices.insert(vertex);
+    }
+  }
+
+  //  --------- put boundary vertices in a fifo queue ---------------
+  std::set<smoothness_point_pair, compareSurfacePointWithExclusionRegionPtr_Smoothness> fifo;
+  std::vector<surfacePointWithExclusionRegion*> vertices;
+  // put the RTREE
+  RTree<surfacePointWithExclusionRegion*,double,2,double> rtree;
+  SMetric3 metricField(1.0);
+  SPoint2 newp[4][NUMDIR];
+  std::set<MVertex*>::iterator it =  bnd_vertices.begin() ;
+
+  char NAME[345]; sprintf(NAME,"crossReal%d.pos",gf->tag());
+  FILE *crossf=NULL;
+  if (debug){
+    crossf = Fopen (NAME,"w");
+  }
+  if (crossf)fprintf(crossf,"View \"\"{\n");
+  for (; it !=  bnd_vertices.end() ; ++it){
+    SPoint2 midpoint;
+    //compute4neighbors_RK2 (gf, *it, midpoint, goNonLinear, newp, metricField,crossf);
+    compute4neighbors(gf, *it, midpoint, goNonLinear, newp, metricField,crossf);
+    surfacePointWithExclusionRegion *sp =
+      new surfacePointWithExclusionRegion (*it, newp, midpoint,metricField);
+    smoothness_point_pair mp;mp.ptr = sp;mp.rank=get_smoothness(*it,gf,vertices2smoothness);
+    fifo.insert(mp);
+
+    if (debug){
+      smoothness_essai[*it] = mp.rank;
+    }
+
+    vertices.push_back(sp);
+    double _min[2],_max[2];
+    sp->minmax(_min,_max);
+    rtree.Insert(_min,_max,sp);
+    if (crossf) export_point(sp, 0, crossf, gf);
+  }
+
+  // ---------- main loop -----------------
+  while(!fifo.empty()){
+    if (debug) std::cout << " -------- fifo.size() = " << fifo.size() << std::endl;
+
+    surfacePointWithExclusionRegion * parent = (*fifo.begin()).ptr;
+    fifo.erase(fifo.begin());
+    int count_nbaddedpt = 0;
+    for (int dir=0;dir<NUMDIR;dir++){
+      for (int i=0;i<4;i++){
+
+        if (!inExclusionZone (parent->_p[i][dir], rtree, vertices) ){
+          GPoint gp = gf->point(parent->_p[i][dir]);
+          MFaceVertex *v = new MFaceVertex(gp.x(),gp.y(),gp.z(),gf,gp.u(),gp.v());
+          SPoint2 midpoint;
+          //compute4neighbors_RK2 (gf, v, midpoint, goNonLinear, newp, metricField,crossf);
+          compute4neighbors(gf, v, midpoint, goNonLinear, newp, metricField,crossf);
+          surfacePointWithExclusionRegion *sp =
+            new surfacePointWithExclusionRegion (v, newp, midpoint, metricField, parent);
+          smoothness_point_pair mp;mp.ptr = sp;mp.rank=get_smoothness(v,gf,vertices2smoothness);
+
+          if (debug){
+            smoothness_essai[v] = mp.rank;
+            vert_priority[v] = priority_counter++;
+          }
+          fifo.insert(mp);
+          vertices.push_back(sp);
+          double _min[2],_max[2];
+          sp->minmax(_min,_max);
+          rtree.Insert(_min,_max,sp);
+          if (crossf) export_point(sp, dir, crossf, gf);
+
+          if (debug){
+            std::cout << "  adding node (" << sp->_v->x() << "," << sp->_v->y() << "," << sp->_v->z() << ")" << std::endl;
+            std::cout << "    ----------------------------- sub --- fifo.size() = " << fifo.size() << std::endl;
+          }
+          count_nbaddedpt++;
+        }
+      }
+    }
+    if (debug) std::cout << "////////// nbre of added point: " << count_nbaddedpt << std::endl;
+  }
+  if (crossf){
+    fprintf(crossf,"};\n");
+    fclose (crossf);
+  }
+
+
+  if (debug){
+    stringstream ss;
+    ss << "priority_" << gf->tag() << ".pos";
+    print_nodal_info_int(ss.str().c_str(),vert_priority);
+    ss.clear();
+    ss << "smoothness_test_" << gf->tag() << ".pos";
+    print_nodal_info_double(ss.str().c_str(),smoothness_essai);
+  }
+
+
+  // add the vertices as additional vertices in the
+  // surface mesh
+  char ccc[256]; sprintf(ccc,"points%d.pos",gf->tag());
+  FILE *f = Fopen(ccc,"w");
+  fprintf(f,"View \"\"{\n");
+  for (unsigned int i=0;i<vertices.size();i++){
+    vertices[i]->print(f,i);
+    if(vertices[i]->_v->onWhat() == gf) {
+      packed.push_back(vertices[i]->_v);
+      metrics.push_back(vertices[i]->_meshMetric);
+      SPoint2 midpoint;
+      reparamMeshVertexOnFace(vertices[i]->_v, gf, midpoint);
+    }
+    delete  vertices[i];
+  }
+  fprintf(f,"};");
+  fclose(f);
+#endif
+}
+
+
+// ---------------------------------------------------------------------------------------------
+
+
 // fills a surface with points in order to build a nice
 // quad mesh ------------
 void packingOfParallelograms(GFace* gf,  std::vector<MVertex*> &packed, std::vector<SMetric3> &metrics){
-  #if defined(HAVE_RTREE)
+  //PE MODIF
+//  packingOfParallelogramsSmoothness(gf,packed,metrics);
+//  return;
+  // END PE MODIF
+#if defined(HAVE_RTREE)
 
   const bool goNonLinear = true;
 
@@ -450,63 +980,63 @@ void packingOfParallelograms(GFace* gf,  std::vector<MVertex*> &packed, std::vec
       //      printf("dir = %d\n",dir);
       int countOK = 0;
       for (int i=0;i<4;i++){
-	//	printf("i = %d %12.5E %12.5E \n",i,parent._p[i][dir].x(),parent._p[i][dir].y());
-
-	//	if (!w._tooclose){
-	if (!inExclusionZone (parent->_p[i][dir], rtree, vertices) ){
-	  countOK++;
-	  GPoint gp = gf->point(parent->_p[i][dir]);
-	  MFaceVertex *v = new MFaceVertex(gp.x(),gp.y(),gp.z(),gf,gp.u(),gp.v());
-	  //	  	printf(" %g %g %g %g\n",parent._center.x(),parent._center.y(),gp.u(),gp.v());
-	  SPoint2 midpoint;
-	  compute4neighbors (gf, v, midpoint, goNonLinear, newp, metricField,crossf);
-	  surfacePointWithExclusionRegion *sp =
-	    new surfacePointWithExclusionRegion (v, newp, midpoint, metricField, parent);
-	  //	  fifo.push(sp);
-	  fifo.insert(sp);
-	  vertices.push_back(sp);
-	  double _min[2],_max[2];
-	  sp->minmax(_min,_max);
-	  rtree.Insert(_min,_max,sp);
-	}
+        //	printf("i = %d %12.5E %12.5E \n",i,parent._p[i][dir].x(),parent._p[i][dir].y());
+
+        //	if (!w._tooclose){
+        if (!inExclusionZone (parent->_p[i][dir], rtree, vertices) ){
+          countOK++;
+          GPoint gp = gf->point(parent->_p[i][dir]);
+          MFaceVertex *v = new MFaceVertex(gp.x(),gp.y(),gp.z(),gf,gp.u(),gp.v());
+          //	  	printf(" %g %g %g %g\n",parent._center.x(),parent._center.y(),gp.u(),gp.v());
+          SPoint2 midpoint;
+          compute4neighbors (gf, v, midpoint, goNonLinear, newp, metricField,crossf);
+          surfacePointWithExclusionRegion *sp =
+            new surfacePointWithExclusionRegion (v, newp, midpoint, metricField, parent);
+          //	  fifo.push(sp);
+          fifo.insert(sp);
+          vertices.push_back(sp);
+          double _min[2],_max[2];
+          sp->minmax(_min,_max);
+          rtree.Insert(_min,_max,sp);
+        }
       }
       if (countOK)break;
+      }
+      //    printf("%d\n",vertices.size());
     }
-    //    printf("%d\n",vertices.size());
-  }
-  if (crossf){
-    fprintf(crossf,"};\n");
-    fclose (crossf);
-  }
-  //  printf("done\n");
-
-  // add the vertices as additional vertices in the
-  // surface mesh
-  char ccc[256]; sprintf(ccc,"points%d.pos",gf->tag());
-  FILE *f = Fopen(ccc,"w");
-  fprintf(f,"View \"\"{\n");
-  for (unsigned int i=0;i<vertices.size();i++){
-    //    if(vertices[i]->_v->onWhat() != gf)
+    if (crossf){
+      fprintf(crossf,"};\n");
+      fclose (crossf);
+    }
+    //  printf("done\n");
+
+    // add the vertices as additional vertices in the
+    // surface mesh
+    char ccc[256]; sprintf(ccc,"points%d.pos",gf->tag());
+    FILE *f = Fopen(ccc,"w");
+    fprintf(f,"View \"\"{\n");
+    for (unsigned int i=0;i<vertices.size();i++){
+      //    if(vertices[i]->_v->onWhat() != gf)
       vertices[i]->print(f,i);
-    if(vertices[i]->_v->onWhat() == gf) {
-      packed.push_back(vertices[i]->_v);
-      metrics.push_back(vertices[i]->_meshMetric);
-      SPoint2 midpoint;
-      reparamMeshVertexOnFace(vertices[i]->_v, gf, midpoint);
-      //      fprintf(f,"TP(%22.15E,%22.15E,%g){%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E};\n",vertices[i]->_v->x(),vertices[i]->_v->y(),vertices[i]->_v->z(),
-      //	      vertices[i]->_meshMetric(0,0),vertices[i]->_meshMetric(0,1),vertices[i]->_meshMetric(0,2),
-      //	      vertices[i]->_meshMetric(1,0),vertices[i]->_meshMetric(1,1),vertices[i]->_meshMetric(1,2),
-      //	      vertices[i]->_meshMetric(2,0),vertices[i]->_meshMetric(2,1),vertices[i]->_meshMetric(2,2));
-	    //fprintf(f,"SP(%22.15E,%22.15E,%g){1};\n",midpoint.x(),midpoint.y(),0.0);
+      if(vertices[i]->_v->onWhat() == gf) {
+        packed.push_back(vertices[i]->_v);
+        metrics.push_back(vertices[i]->_meshMetric);
+        SPoint2 midpoint;
+        reparamMeshVertexOnFace(vertices[i]->_v, gf, midpoint);
+        //      fprintf(f,"TP(%22.15E,%22.15E,%g){%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E};\n",vertices[i]->_v->x(),vertices[i]->_v->y(),vertices[i]->_v->z(),
+        //	      vertices[i]->_meshMetric(0,0),vertices[i]->_meshMetric(0,1),vertices[i]->_meshMetric(0,2),
+        //	      vertices[i]->_meshMetric(1,0),vertices[i]->_meshMetric(1,1),vertices[i]->_meshMetric(1,2),
+        //	      vertices[i]->_meshMetric(2,0),vertices[i]->_meshMetric(2,1),vertices[i]->_meshMetric(2,2));
+        //fprintf(f,"SP(%22.15E,%22.15E,%g){1};\n",midpoint.x(),midpoint.y(),0.0);
+      }
+      delete  vertices[i];
     }
-    delete  vertices[i];
+    fprintf(f,"};");
+    fclose(f);
+    //  printf("packed.size = %d\n",packed.size());
+    //  delete rtree;
+#endif
   }
-  fprintf(f,"};");
-  fclose(f);
-  //  printf("packed.size = %d\n",packed.size());
-  //  delete rtree;
-  #endif
-}
 
 
 
diff --git a/Mesh/surfaceFiller.h b/Mesh/surfaceFiller.h
index ae20a52b17ae8e5abdbaf0a54c34fe132878af0e..7c1c9c54147f236920b51cffbe8673d42a9a1d4f 100644
--- a/Mesh/surfaceFiller.h
+++ b/Mesh/surfaceFiller.h
@@ -8,4 +8,5 @@
 #include <vector>
 class GFace;
 class MVertex;
+void packingOfParallelogramsSmoothness(GFace* gf, std::vector<MVertex*> &packed, std::vector<SMetric3> &metrics );
 void packingOfParallelograms(GFace* gf, std::vector<MVertex*> &packed, std::vector<SMetric3> &metrics );