diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index fe7d2bf6b6b1e7221fcb5ee5c0a966e64981827d..8762efc0d71c8e99b2396c4d6fad72f25c1794cd 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -875,9 +875,9 @@ void GetOptions(int argc, char *argv[])
         i++;
         CTX::instance()->mesh.recombinationTestNoGreedyStrat = 1;
       }
-      else if(!strcmp(argv[i] + 1, "newstrat")) {
+      else if(!strcmp(argv[i] + 1, "meshdiscrete")) {
         i++;
-        CTX::instance()->mesh.recombinationTestNewStrat = 1;
+        CTX::instance()->meshDiscrete = 1;
       }
       else if(!strcmp(argv[i] + 1, "format") || !strcmp(argv[i] + 1, "f")) {
         i++;
diff --git a/Common/Context.cpp b/Common/Context.cpp
index 8da9ca1132b09c6442f5339a9beca92f754f8d6f..c51fe053896cddec207a0f2dcef231661e17c5e6 100644
--- a/Common/Context.cpp
+++ b/Common/Context.cpp
@@ -41,6 +41,7 @@ CTX::CTX() : gamepad(0)
     homeDir += "/";
 
   batch = batchAfterMesh = 0;
+  meshDiscrete=0;
   outputFileName = "";
   bgmFileName = "";
   createAppendMeshStatReport = 0;
diff --git a/Common/Context.h b/Common/Context.h
index 0be231c191aba8f171498228f838f4a744deb96c..a0f6c10930f300fe0e181db8f58c84dddca5b495 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -138,6 +138,8 @@ class CTX {
   int batch;
   // batch operations to apply after meshing (1: partition mesh)
   int batchAfterMesh;
+  // mesh discrete faces / edges
+  int meshDiscrete;
   // initial menu (0: automatic, 1: geom, 2: mesh, 3: solver, 4: post)
   int initialContext;
   // never popup dialogs in scripts (use default values instead)?
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index bd1b1b1424f206d90c0461903105547591eff3eb..4d3736589b84c6736cb0f41bd1fb0a0f9968d650 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1208,8 +1208,6 @@ StringXNumber MeshOptions_Number[] = {
     "Depth start" },
   { F|O, "RecombinationTestNoGreedyStrat" , opt_mesh_recombination_no_greedy_strat , 0 ,
     "No greedy (global) strategies" },
-  { F|O, "RecombinationTestNewStrat" , opt_mesh_recombination_new_strat , 0 ,
-    "New strategies" },
   { F|O, "RemeshAlgorithm" , opt_mesh_remesh_algo , 0 ,
     "Remeshing algorithm (0=no split, 1=automatic, 2=automatic only with metis)" },
   { F|O, "RemeshParametrization" , opt_mesh_remesh_param , 4 ,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index d03c46c379d19fc0c64e84dab1549fc14f0f258d..2b85b0ef08015558e324fbd472f73967664c0650 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5885,14 +5885,6 @@ double opt_mesh_recombination_no_greedy_strat(OPT_ARGS_NUM)
   return CTX::instance()->mesh.recombinationTestNoGreedyStrat;
 }
 
-double opt_mesh_recombination_new_strat(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET){
-    CTX::instance()->mesh.recombinationTestNewStrat = (int)val;
-  }
-  return CTX::instance()->mesh.recombinationTestNewStrat;
-}
-
 double opt_mesh_remesh_algo(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
diff --git a/Common/Options.h b/Common/Options.h
index 1757b6b53d05fa296b130ee5a0b64f2b069b456d..e2ad04ad598f277ba95dab40fd0aeae6d7f9883a 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -480,7 +480,6 @@ double opt_mesh_flexible_transfinite(OPT_ARGS_NUM);
 double opt_mesh_do_recombination_test(OPT_ARGS_NUM);
 double opt_mesh_recombination_test_start(OPT_ARGS_NUM);
 double opt_mesh_recombination_no_greedy_strat(OPT_ARGS_NUM);
-double opt_mesh_recombination_new_strat(OPT_ARGS_NUM);
 double opt_mesh_remesh_algo(OPT_ARGS_NUM);
 double opt_mesh_remesh_param(OPT_ARGS_NUM);
 double opt_mesh_algo_subdivide(OPT_ARGS_NUM);
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index c3bbcf902223147ed2603fa2e5ed768893761950..7e8347dc917ff708c4251b46aca77375a89e346f 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1271,20 +1271,29 @@ static void _associateEntityWithElementVertices(GEntity *ge, std::vector<T*> &el
     for(int j = 0; j < elements[i]->getNumVertices(); j++){
       if (force || !elements[i]->getVertex(j)->onWhat() ||
           elements[i]->getVertex(j)->onWhat()->dim() > ge->dim())
-        elements[i]->getVertex(j)->setEntity(ge);
+	elements[i]->getVertex(j)->setEntity(ge);
     }
   }
 }
 
 void GModel:: _createGeometryOfDiscreteEntities() {
-  for(eiter it = firstEdge(); it != lastEdge(); ++it){
-    if((*it)->geomType() == GEntity::DiscreteCurve) {
-      discreteEdge *de = dynamic_cast<discreteEdge*> (*it);
-      if (!de)Msg::Fatal("no fun");
-      de->createGeometry();
+  if (CTX::instance()->meshDiscrete){
+    Msg::Info("creating the geometry of discrete curves");
+    for(eiter it = firstEdge(); it != lastEdge(); ++it){
+      if((*it)->geomType() == GEntity::DiscreteCurve) {
+	discreteEdge *de = dynamic_cast<discreteEdge*> (*it);
+	if (!de)Msg::Fatal("no fun");
+	de->createGeometry();
+      }
+    }
+    Msg::Info("creating the geometry of discrete surfaces");
+    for(fiter it = firstFace(); it != lastFace(); ++it){
+      if((*it)->geomType() == GEntity::DiscreteSurface) {
+	discreteFace *df = dynamic_cast<discreteFace*> (*it);
+	if (!df)Msg::Fatal("no fun");
+	df->createGeometry();
+      }
     }
-  }
-  for(fiter it = firstFace(); it != lastFace(); ++it){
   }
 }
 
diff --git a/Geo/GModelIO_MSH.cpp b/Geo/GModelIO_MSH.cpp
index 1115b54deaef1d71d0cefe1c9a32e8852dc4c0c1..4c986a60a48c28d16c47a79612f1e42f9e799b72 100644
--- a/Geo/GModelIO_MSH.cpp
+++ b/Geo/GModelIO_MSH.cpp
@@ -159,6 +159,7 @@ int GModel::readMSH(const std::string &name)
 
   char str[256] = "";
 
+
   // detect prehistoric MSH files
   if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; }
   if(!strncmp(&str[1], "NOD", 3) || !strncmp(&str[1], "NOE", 3)){
@@ -353,7 +354,6 @@ int GModel::readMSH(const std::string &name)
         _vertexMapCache.clear();
       }
     }
-
     // $Elements section
     else if(!strncmp(&str[1], "Elements", 8)) {
       if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; }
@@ -439,7 +439,7 @@ int GModel::readMSH(const std::string &name)
   // entity does not exist, create a new (discrete) one.
   for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
     _storeElementsInEntities(elements[i]);
-
+  
   // associate the correct geometrical entity with each mesh vertex
   _associateEntityWithMeshVertices();
 
@@ -450,6 +450,7 @@ int GModel::readMSH(const std::string &name)
     _storeVerticesInEntities(_vertexMapCache);
 
   _createGeometryOfDiscreteEntities() ;
+
   fclose(fp);
 
   return postpro ? 2 : 1;
diff --git a/Geo/discreteDiskFace.cpp b/Geo/discreteDiskFace.cpp
index 355e81eb9bba0c696388265095e1141c1b32df0b..810db951197b9700f93bf99452e618ee4898f02b 100644
--- a/Geo/discreteDiskFace.cpp
+++ b/Geo/discreteDiskFace.cpp
@@ -11,6 +11,7 @@
 #include "GmshMessage.h"
 #include "Octree.h"
 #include "discreteDiskFace.h"
+#include "discreteEdge.h"
 #include "MTriangle.h"
 #include "MEdge.h"
 #include "Geo.h"
@@ -116,6 +117,13 @@ discreteDiskFace::discreteDiskFace(GFace *gf, std::vector<MTriangle*> &mesh) :
 	}
 	else vs[j] = it->second;
       }
+      else if (v->onWhat()->dim() == 1){
+	if (v->onWhat()->geomType() == DiscreteCurve){
+	  discreteEdge *de = dynamic_cast<discreteEdge*> (v->onWhat());
+	  vs[j] = de->getGeometricalVertex(v);
+	}
+	else Msg::Fatal("fatality");
+      }
       else vs[j] = v;
     }
     discrete_triangles.push_back(new MTriangle (vs[0], vs[1], vs[2]));
@@ -449,10 +457,21 @@ SPoint2 discreteDiskFace::parFromVertex(MVertex *v) const
   if(it != coordinates.end()) return SPoint2(it->second.x(),it->second.y());
   // The 1D mesh has been re-done
   if (v->onWhat()->dim()==1){
+    if (v->onWhat()->geomType() == DiscreteCurve){
+      discreteEdge *de = dynamic_cast<discreteEdge*> (v->onWhat());
+      if (de){
+	MVertex *v1,*v2;
+	double xi;
+	de->interpolateInGeometry (v,&v1,&v2,xi);
+	std::map<MVertex*,SPoint3>::iterator it1 = coordinates.find(v1);
+	std::map<MVertex*,SPoint3>::iterator it2 = coordinates.find(v2);
+	if(it1 == coordinates.end()) Msg::Fatal("FIXME TO DO %d %s",__LINE__,__FILE__);
+	if(it2 == coordinates.end()) Msg::Fatal("FIXME TO DO %d %s",__LINE__,__FILE__);
+	return SPoint2(it1->second.x(),it1->second.y()) * (1.-xi) + 
+	  SPoint2(it2->second.x(),it2->second.y()) * xi; 	
+      }
+    }
     Msg::Fatal("FIXME TO DO %d %s",__LINE__,__FILE__);
-    // get the discrete edge on which v is classified
-    // get the two ending vertices A and B on both sides of v    A-------v----------B
-    // interpolate between the two uv coordinates of A and B
   }
   else if (v->onWhat()->dim()==0){
     Msg::Fatal("discreteDiskFace::parFromVertex vertex classified on a model vertex that is not part of the face");
diff --git a/Geo/discreteEdge.cpp b/Geo/discreteEdge.cpp
index 5ccf30023d59d9ba6e58672a9a996f11478f19aa..3b0b037410f47b15ea234241e5bbd6f842158bd2 100644
--- a/Geo/discreteEdge.cpp
+++ b/Geo/discreteEdge.cpp
@@ -23,6 +23,7 @@
 #include "GEdgeCompound.h"
 #if defined(HAVE_MESH)
 #include "meshGEdge.h"
+#include "Context.h"
 #endif
 discreteEdge::discreteEdge(GModel *model, int num, GVertex *_v0, GVertex *_v1)
   : GEdge(model, num, _v0, _v1)
@@ -42,6 +43,7 @@ void discreteEdge::createTopo()
   }
 }
 
+// FULL OF BUGS !!!!!!
 void discreteEdge::orderMLines()
 {
   //printf("ordering line %d\n", tag());
@@ -143,8 +145,6 @@ void discreteEdge::orderMLines()
         mesh_vertices.end()) mesh_vertices.push_back(v1);
     if (std::find(mesh_vertices.begin(), mesh_vertices.end(), v2) ==  
         mesh_vertices.end()) mesh_vertices.push_back(v2);
-    v1->setEntity(this);
-    v2->setEntity(this);
   }
 
   //special case reverse orientation
@@ -413,7 +413,7 @@ GPoint discreteEdge::point(double par) const
   x = vB->x() + tLoc * (vE->x()- vB->x());
   y = vB->y() + tLoc * (vE->y()- vB->y());
   z = vB->z() + tLoc * (vE->z()- vB->z());
-  return GPoint(x,y,z);
+  return GPoint(x,y,z,this,par);
 }
 
 SVector3 discreteEdge::firstDer(double par) const
@@ -475,12 +475,11 @@ Range<double> discreteEdge::parBounds(int i) const
 
 void discreteEdge::createGeometry(){
   if (discrete_lines.empty()){
-    Msg::Info("creating the geometry of discrete curve %d",tag());
     createTopo();
     // copy the mesh
-    std::map<MVertex*,MVertex*> v2v;
     for (unsigned int i = 0; i < mesh_vertices.size(); i++){
-      MVertex *v   = new MEdgeVertex(mesh_vertices[i]->x(),mesh_vertices[i]->y(),mesh_vertices[i]->z(),this,(double)(i+1));
+      MEdgeVertex *v   = new MEdgeVertex(mesh_vertices[i]->x(),mesh_vertices[i]->y(),mesh_vertices[i]->z(),this,(double)(i+1));
+      //      printf("%3d %p\n",tag(),mesh_vertices[i]);
       v2v  [mesh_vertices[i]] = v;
     }
 
@@ -497,8 +496,6 @@ void discreteEdge::createGeometry(){
 	discrete_lines.push_back(new MLine(v01,v00));
       }
     }
-    
-    
     // compute parameters and recompute the vertices
     _pars.push_back(0.0);
     for (unsigned int i = 1; i < discrete_lines.size(); i++){
@@ -510,13 +507,31 @@ void discreteEdge::createGeometry(){
   }
 }
 
+MVertex * discreteEdge::getGeometricalVertex (MVertex *v){
+  std::map<MVertex*,MVertex*>::const_iterator it = v2v.find(v);
+  if (it == v2v.end()){
+    printf("----> %p %d %d %g %g %g %d %d\n",v,v->getNum(),tag(),v->x(),v->y(),v->z(),v->onWhat()->tag(),v->onWhat()->dim());
+    Msg::Fatal("fatality %ld %ld %ld",v2v.size(),mesh_vertices.size(),discrete_vertices.size());
+  }
+  return it->second;
+}
+
+void discreteEdge::interpolateInGeometry (MVertex *v, MVertex **v1, MVertex **v2, double &xi) const {
+  double t;
+  if (v->onWhat() != this)Msg::Fatal("%s %d",__FILE__,__LINE__);
+  v->getParameter (0,t);
+  int i = (int) t;
+  MLine *l = discrete_lines [i];
+  *v1 = l->getVertex(0);
+  *v2 = l->getVertex(1);
+  xi = t - i;
+  //  Msg::Fatal("fatality...");
+}
+
 
 void discreteEdge::mesh(bool verbose){
 #if defined(HAVE_MESH)
-  // copy the mesh into geometrical entities
-  // FIXME
-  //  return;
-  //  createGeometry();
+  if (!CTX::instance()->meshDiscrete) return;
   meshGEdge mesher;
   mesher(this);
 #endif
diff --git a/Geo/discreteEdge.h b/Geo/discreteEdge.h
index 7ece5ad825eda60dbd0a3c9877642798e8c7138b..a44c18559046c0383cb6700518bcc5e82a551f8b 100644
--- a/Geo/discreteEdge.h
+++ b/Geo/discreteEdge.h
@@ -12,6 +12,7 @@
 
 class discreteEdge : public GEdge {
  protected:
+  std::map<MVertex*,MVertex*> v2v;
   std::vector<double> _pars;
   std::vector<int> _orientation;
   std::map<MVertex*, MLine*> boundv;
@@ -31,6 +32,7 @@ class discreteEdge : public GEdge {
   virtual Range<double> parBounds(int) const;
 
   bool getLocalParameter(const double &t, int &iEdge, double &tLoc) const;
+  void interpolateInGeometry (MVertex *v, MVertex **v1, MVertex **v2, double &xi) const; 
   void parametrize(std::map<GFace*, std::map<MVertex*, MVertex*,
 		   std::less<MVertex*> > > &face2Verts,
 		   std::map<GRegion*, std::map<MVertex*, MVertex*,
@@ -43,6 +45,7 @@ class discreteEdge : public GEdge {
   virtual void mesh(bool) ;
   void writeGEO(FILE *fp);
   int minimumDrawSegments() const {return 2*_pars.size();}
+  MVertex * getGeometricalVertex (MVertex *v);
 };
 
 #endif
diff --git a/Geo/discreteFace.cpp b/Geo/discreteFace.cpp
index d02ebff1e167cc44bc7ac5f04ba53e20517077e2..2e70b3caf90a122b7d5395790f2a0efb2abb2cb4 100644
--- a/Geo/discreteFace.cpp
+++ b/Geo/discreteFace.cpp
@@ -165,8 +165,7 @@ void discreteFace::gatherMeshes() {
 
 void discreteFace::mesh(bool verbose) {
 #if defined(HAVE_ANN) && defined(HAVE_SOLVER) && defined(HAVE_MESH)
-  return;
-  createGeometry();
+  if (!CTX::instance()->meshDiscrete) return;
   for (unsigned int i=0;i<_atlas.size();i++)
     _atlas[i]->mesh(verbose);
   gatherMeshes();
diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp
index 11a23f5a106261ee44fb7f2aa857ac5c9c1be186..6b1d0aa9dd244a5f5d422338cd0e03edb744a4e0 100644
--- a/Mesh/BDS.cpp
+++ b/Mesh/BDS.cpp
@@ -46,11 +46,12 @@ void outputScalarField(std::list<BDS_Face*> t, const char *iii, int param, GFace
                     pts[0]->iD, pts[1]->iD, pts[2]->iD, pts[3]->iD);
           }
           else{
-            fprintf(f, "ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d};\n",
-                    pts[0]->X, pts[0]->Y, pts[0]->Z,
-                    pts[1]->X, pts[1]->Y, pts[1]->Z,
-                    pts[2]->X, pts[2]->Y, pts[2]->Z,
-                    pts[0]->iD, pts[1]->iD, pts[2]->iD);
+	    if (pts[0]->iD >= 0 && pts[1]->iD  >= 0 && pts[2]->iD  >= 0)
+	      fprintf(f, "ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d};\n",
+		      pts[0]->X, pts[0]->Y, pts[0]->Z,
+		      pts[1]->X, pts[1]->Y, pts[1]->Z,
+		      pts[2]->X, pts[2]->Y, pts[2]->Z,
+		      pts[0]->iD, pts[1]->iD, pts[2]->iD);
           }
         }
         else{
diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp
index 8f04b245277c5fc6ce2583268aeb01be450eb3f2..49c1d120f810197f53fb0a39ff030c0c64f6654c 100644
--- a/Mesh/meshGEdge.cpp
+++ b/Mesh/meshGEdge.cpp
@@ -305,11 +305,7 @@ void copyMesh(GEdge *from, GEdge *to, int direction)
 
 void deMeshGEdge::operator() (GEdge *ge)
 {
-  if(ge->geomType() == GEntity::DiscreteCurve) {
-    // FIXME : NOTHING SPECIAL TO DO
-    return;
-  }
-
+  if(ge->geomType() == GEntity::DiscreteCurve && !CTX::instance()->meshDiscrete)return;
   ge->deleteMesh();
   ge->meshStatistics.status = GEdge::PENDING;
   ge->correspondingVertices.clear();
@@ -560,6 +556,7 @@ void meshGEdge::operator() (GEdge *ge)
         const double d = norm(der);
         double lc  = d/(P1.lc + dlc / dp * (d - P1.p));
         GPoint V = ge->point(t);
+	//	printf("%d %g\n",NUMP-1,t);
         mesh_vertices[NUMP - 1] = new MEdgeVertex(V.x(), V.y(), V.z(), ge, t, lc);
         NUMP++;
       }
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 37cf03b57cd193b21470148f65655597960cf8a7..0aceb8e58a472cb24de9a0a3c307fc52f37957f9 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -2368,14 +2368,7 @@ static bool meshGeneratorPeriodic(GFace *gf, bool debug = true)
 
 void deMeshGFace::operator() (GFace *gf)
 {
-  if(gf->geomType() == GEntity::DiscreteSurface) {
-    discreteFace *df = dynamic_cast<discreteFace*> (gf);
-    // copy the mesh and parametrize it to have a "geometry"
-    // of the discrete edge
-    // FIXME
-    return;
-    df->createGeometry();
-  }
+  if(gf->geomType() == GEntity::DiscreteSurface && !CTX::instance()->meshDiscrete)return;
   gf->deleteMesh();
   gf->meshStatistics.status = GFace::PENDING;
   gf->meshStatistics.nbTriangle = gf->meshStatistics.nbEdge = 0;
@@ -2383,7 +2376,7 @@ void deMeshGFace::operator() (GFace *gf)
 }
 
 // for debugging, change value from -1 to -100;
-int debugSurface = -1; //-1;
+int debugSurface = -100; //-1;
 
 void meshGFace::operator() (GFace *gf, bool print)
 {
diff --git a/benchmarks/2d/stator_parametric.geo b/benchmarks/2d/stator_parametric.geo
index c96ba7d3604a1aa00691047b8023de865cc47cc9..2e66d821ee882dbf1ae41c6cc43b2d712351dfb7 100644
--- a/benchmarks/2d/stator_parametric.geo
+++ b/benchmarks/2d/stator_parametric.geo
@@ -1,4 +1,5 @@
-Mesh.Algorithm = 6; // test frontal algorithm
+Mesh.RecombinationAlgorithm=2;
+Mesh.Algorithm = 8; // test frontal algorithm
 
 // Einheiten
 mm = 1.e-3;