diff --git a/Common/Context.h b/Common/Context.h
index d295c34d4cd1a9e960c0ef2ad9540404e93bd7bf..aed74f6e147a558cb833f5c75d8bca420f6b0eb4 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -178,7 +178,7 @@ public :
     double quality;
     int quality_type, label_type;
     double quality_inf, quality_sup, radius_inf, radius_sup;
-    double scaling_factor, lc_factor, rand_factor;
+    double scaling_factor, lc_factor, rand_factor,nb_elem_per_rc;
     int dual, interactive;
     int light, light_two_side;
     int format, nbPartitions,nb_smoothing, algo2d, algo3d, order,algo_recombine;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index e1bbd3d088d14f43c7b71725f4db2a94bb1744ba..bf41ca3072c17150a94ccba7e188ea7c83cf7c1d 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -897,6 +897,8 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "MshFileVersion" , opt_mesh_msh_file_version , 1.0 , 
     "Version of the `msh' file format to use" },
 
+  { F|O, "NbElemsPerRadiusOfCurv" , opt_mesh_nb_elem_per_rc, 5. ,
+    "Number of elements per radius of curvature in the remesher" },
   { F, "NbHexahedra" , opt_mesh_nb_hexahedra , 0. , 
     "Number of hexahedra in the current mesh (read-only)" },
   { F, "NbNodes" , opt_mesh_nb_nodes , 0. , 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index ec9d5a66ea04b78b86ee96a909317bd9ef515ef0..a83e217bc1949d800e04f63b05595f44c4ee4540 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.256 2005-09-07 14:36:45 remacle Exp $
+// $Id: Options.cpp,v 1.257 2005-09-21 15:03:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -4378,6 +4378,18 @@ double opt_mesh_format(OPT_ARGS_NUM)
   return CTX.mesh.format;
 }
 
+
+double opt_mesh_nb_elem_per_rc(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.mesh.nb_elem_per_rc = (double)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->swiz_value[4]->value(CTX.mesh.nb_elem_per_rc);
+#endif
+  return CTX.mesh.nb_elem_per_rc;
+}
+
 double opt_mesh_msh_file_version(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index b8db3c4166c36a59380333c47e669f2dec4b774c..620583e06cedf4857fdcca6341ba119a4bcaa524 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -439,6 +439,7 @@ double opt_mesh_light_two_side(OPT_ARGS_NUM);
 double opt_mesh_format(OPT_ARGS_NUM);
 double opt_mesh_msh_file_version(OPT_ARGS_NUM);
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM);
+double opt_mesh_nb_elem_per_rc(OPT_ARGS_NUM);
 double opt_mesh_nb_partitions(OPT_ARGS_NUM);
 double opt_mesh_algo2d(OPT_ARGS_NUM);
 double opt_mesh_recombine_algo(OPT_ARGS_NUM);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 5cc545ca0159e611d6bc4f038d8a6e86d0cc9f89..a64c2e47bb896e3f4979ce031ca154a282f3c57c 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.368 2005-08-31 21:44:44 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.369 2005-09-21 15:03:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -840,13 +840,6 @@ void wizard_update_edges_cb(CALLBACK_ARGS)
 	const int nb       = (int) WID->swiz_value[3]->value();
 	THEM->bds->classify (angle, nb);
 	BDS_To_Mesh (THEM); 
-	char a[25];
-	sprintf(a,"%d",Tree_Nbr(THEM->Points));
-	WID->swiz_output[1]->value(a);
-	sprintf(a,"%d",Tree_Nbr(THEM->Curves));
-	WID->swiz_output[2]->value(a);
-	sprintf(a,"%d",Tree_Nbr(THEM->Surfaces));
-	WID->swiz_output[3]->value(a);
 	Draw();
     }
 }
@@ -935,9 +928,6 @@ void wizard_update_tolerance_cb(CALLBACK_ARGS)
 	char a[25];
 	sprintf(a,"%d",THEM->bds->points.size());
 	WID->swiz_output[0]->value(a);
-	WID->swiz_output[1]->value("0");
-	WID->swiz_output[2]->value("0");
-	WID->swiz_output[3]->value("0");
 	Draw();
     }
 }
@@ -1165,7 +1155,7 @@ void mesh_options_ok_cb(CALLBACK_ARGS)
   opt_mesh_light(0, GMSH_SET, WID->mesh_butt[17]->value());
   opt_mesh_light_two_side(0, GMSH_SET, WID->mesh_butt[18]->value());
   opt_mesh_smooth_normals(0, GMSH_SET, WID->mesh_butt[19]->value());
-
+  opt_mesh_nb_elem_per_rc(0, GMSH_SET, WID->swiz_value[4]->value());
   opt_mesh_nb_smoothing(0, GMSH_SET, WID->mesh_value[0]->value());
   opt_mesh_scaling_factor(0, GMSH_SET, WID->mesh_value[1]->value());
   opt_mesh_lc_factor(0, GMSH_SET, WID->mesh_value[2]->value());
@@ -2817,6 +2807,13 @@ void mesh_3d_cb(CALLBACK_ARGS)
   Msg(STATUS3N, "Ready");
 }
 
+void mesh_remesh(CALLBACK_ARGS)
+{
+  ReMesh(THEM);
+  Draw();
+  Msg(STATUS3N, "Ready");
+}
+
 void mesh_degree_cb(CALLBACK_ARGS)
 {
   switch ((long)data) {
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index cb77b1b4b15dfac20af8804f346b9c9366d88a31..14205348d1ef3fff2bdb967f05e83e1a90600c49 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -270,6 +270,7 @@ void mesh_define_cb(CALLBACK_ARGS);
 void mesh_1d_cb(CALLBACK_ARGS);
 void mesh_2d_cb(CALLBACK_ARGS); 
 void mesh_3d_cb(CALLBACK_ARGS); 
+void mesh_remesh(CALLBACK_ARGS); 
 void mesh_degree_cb(CALLBACK_ARGS); 
 void mesh_optimize_cb(CALLBACK_ARGS); 
 void mesh_define_length_cb (CALLBACK_ARGS);
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index f567abe040b10f2138441563c88a48c5c263bfac..c992ea5d7b0e24bcefaa49ed032ffe21607a4ba6 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.456 2005-08-30 12:52:50 geuzaine Exp $
+// $Id: GUI.cpp,v 1.457 2005-09-21 15:03:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -324,6 +324,7 @@ Context_Item menu_mesh[] = {
   { "1D",     (Fl_Callback *)mesh_1d_cb } ,
   { "2D",     (Fl_Callback *)mesh_2d_cb } , 
   { "3D",     (Fl_Callback *)mesh_3d_cb } , 
+  { "remesh", (Fl_Callback *)mesh_remesh } , 
   { "First order",  (Fl_Callback *)mesh_degree_cb, (void*)1 } , 
   { "Second order", (Fl_Callback *)mesh_degree_cb, (void*)2 } , 
 #if defined(HAVE_NETGEN)
@@ -904,9 +905,6 @@ GUI::GUI(int argc, char **argv)
   }
   call_for_solver_plugin(-1);
 
-  // create the surface mesh wizard
-  create_surface_mesh_wizard();
-
   // Draw the scene
   g_opengl_window->redraw();
 }
@@ -1618,146 +1616,6 @@ void GUI::reset_external_view_list()
   }
 }
 
-void GUI::create_surface_mesh_wizard(const char *name)
-{
-    if (name)
-	surfmesh_filename = name; 
-
-    int width = 42 * fontsize;
-    int height = 6 * BH + 6 * WB;
-
-    if(swiz_window) {	
-	swiz_window->show();
-	return;
-    }
-    swiz_window = new Dialog_Window(width, height, "Surface Mesh Wizard");
-    swiz_window->box(GMSH_WINDOW_BOX);
-//    swiz_window->set_modal();
-
-    swiz_wiz = new Fl_Wizard(0, 0, width, height, "Surface Mesh Wizard");    
-    {
-//	Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
-	{
-	    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "STL File");
-	    swiz_value[1] = new Fl_Value_Input(2 * WB, 2 * WB + 0 * BH, IW, BH, "Distance Tolerance");
-	    swiz_value[1]->value(5.e-7);
-	    swiz_value[1]->minimum(0);
-	    swiz_value[1]->maximum(1.e-4);
-	    swiz_value[1]->step(1.e-7);
-	    swiz_value[1]->align(FL_ALIGN_RIGHT);
-	    swiz_output[0] = new Fl_Output(2 * WB, 2 * WB + 1 * BH, IW, BH, "Number of Nodes after Merge");
-	    swiz_output[0]->align(FL_ALIGN_RIGHT);
-	    swiz_output[0]->value("0");
-	    {
-		Fl_Return_Button *b = new Fl_Return_Button(width - 4 * BB - 4 * WB, height - BH - WB, BB, BH, "Apply");
-		b->callback(wizard_update_tolerance_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Next");
-		b->callback(wizard_update_next_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Prev");
-		b->callback(wizard_update_prev_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
-		b->callback(cancel_cb, (void *)swiz_window);
-	    }
-	    
-	    o->end();
-	}	
-	{
-	    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Model Edge Detection");
-	    swiz_value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 0 * BH, IW, BH, "Treshold Dihedral Angle");
-	    swiz_value[0]->value(180/8);
-	    swiz_value[0]->minimum(0);
-	    swiz_value[0]->maximum(90);
-	    swiz_value[0]->step(1);
-	    swiz_value[0]->align(FL_ALIGN_RIGHT);
-	    swiz_value[3] = new Fl_Value_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Min nb. of Triangles for plane surface detection");
-	    swiz_value[3]->value(4);
-	    swiz_value[3]->minimum(2);
-	    swiz_value[3]->maximum(30);
-	    swiz_value[3]->step(1);
-	    swiz_value[3]->align(FL_ALIGN_RIGHT);
-	    swiz_output[1] = new Fl_Output(2 * WB, 2 * WB + 2 * BH, IW, BH, "Number of Model Vertices");
-	    swiz_output[1]->align(FL_ALIGN_RIGHT);
-	    swiz_output[1]->value("0");
-	    swiz_output[2] = new Fl_Output(2 * WB, 2 * WB + 3 * BH, IW, BH, "Number of Model Edges");
-	    swiz_output[2]->align(FL_ALIGN_RIGHT);
-	    swiz_output[2]->value("0");
-	    swiz_output[3] = new Fl_Output(2 * WB, 2 * WB + 4 * BH, IW, BH, "Number of Model Faces");
-	    swiz_output[3]->align(FL_ALIGN_RIGHT);
-	    swiz_output[3]->value("0");
-	    {
-		Fl_Return_Button *b = new Fl_Return_Button(width - 4 * BB - 4 * WB, height - BH - WB, BB, BH, "Apply");
-		b->callback(wizard_update_edges_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Next");
-		b->callback(wizard_update_next_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Prev");
-		b->callback(wizard_update_prev_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
-		b->callback(cancel_cb, (void *)swiz_window);
-	    }	    
-	    o->end();
-	}	
-	{ 
-	    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Select More Edges");
-	    swiz_value[2] = new Fl_Value_Input(2 * WB, 2 * WB + 0 * BH, IW, BH, "Treshold Dihedral Angle For Extra Edges");
-	    swiz_value[2]->value(180/8);
-	    swiz_value[2]->minimum(0);
-	    swiz_value[2]->maximum(90);
-	    swiz_value[2]->step(1);
-	    swiz_value[2]->align(FL_ALIGN_RIGHT);
-	    {
-		Fl_Return_Button *b = new Fl_Return_Button(width - 4 * BB - 4 * WB, height - BH - WB, BB, BH, "Apply");
-		b->callback(wizard_update_more_edges_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Next");
-		b->callback(wizard_update_next_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Prev");
-		b->callback(wizard_update_prev_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
-		b->callback(cancel_cb, (void *)swiz_window);
-	    }	    
-	    o->end();
-	}	
-	{
-	    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Mesh Generation");
-	    {
-		Fl_Return_Button *b = new Fl_Return_Button(width - 4 * BB - 4 * WB, height - BH - WB, BB, BH, "Apply");
-		b->callback(wizard_update_edges_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Next");
-		b->callback(wizard_update_next_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Prev");
-		b->callback(wizard_update_prev_cb);
-	    }
-	    {
-		Fl_Button *b = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
-		b->callback(cancel_cb, (void *)swiz_window);
-	    }	    
-	    o->end();
-	}	
-//	o->end();
-    } 
-    swiz_wiz->end();
-}
 
 void GUI::create_option_window()
 {
@@ -2361,6 +2219,58 @@ void GUI::create_option_window()
 
       o->end();
     }
+
+    {
+      Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Remesher");
+      o->hide();
+      // In STL FILES, points have to be merged and a distance tolerance has to be set 
+      swiz_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Distance Tolerance (for STL inputs)");
+      swiz_value[1]->value(5.e-7);
+      swiz_value[1]->minimum(0);
+      swiz_value[1]->maximum(1.e-4);
+      swiz_value[1]->step(1.e-7);
+      swiz_value[1]->align(FL_ALIGN_RIGHT);
+      // when this button is pushed, the STL file is re-loaded
+      mesh_retbutt[0] = new Fl_Return_Button(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Reload");
+      mesh_retbutt[0]->callback(wizard_update_tolerance_cb);
+
+      // The number of nodes after merge is computed 
+      swiz_output[0] = new Fl_Output(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Number of Nodes after Merge");
+      swiz_output[0]->align(FL_ALIGN_RIGHT);
+      swiz_output[0]->value("0");
+      // If no geometry is provided, then the triangulation can be used for computing a discrete geometry
+      // The dihedral angle between neighboring triangles can be used to find model edges.
+      swiz_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Treshold Dihedral Angle");
+      swiz_value[0]->value(180/8);
+      swiz_value[0]->minimum(0);
+      swiz_value[0]->maximum(90);
+      swiz_value[0]->step(1);
+      swiz_value[0]->align(FL_ALIGN_RIGHT);
+      swiz_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Edge prolongation treshold");
+      swiz_value[3]->value(180/8);
+      swiz_value[3]->minimum(0);
+      swiz_value[3]->maximum(90);
+      swiz_value[3]->step(1);
+      swiz_value[3]->align(FL_ALIGN_RIGHT); 
+
+      mesh_retbutt[1] = new Fl_Return_Button(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Re-Classify");
+      mesh_retbutt[1]->callback(wizard_update_edges_cb);
+
+      swiz_value[4] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Number of elements per rad. of curv.");
+      swiz_value[4]->value(5);
+      swiz_value[4]->minimum(1);
+      swiz_value[4]->maximum(10);
+      swiz_value[4]->step(1);
+      swiz_value[4]->align(FL_ALIGN_RIGHT); 
+      swiz_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "LC/Minimum element size");
+      swiz_value[3]->value(500);
+      swiz_value[3]->minimum(10);
+      swiz_value[3]->maximum(10000);
+      swiz_value[3]->step(10);
+      swiz_value[3]->align(FL_ALIGN_RIGHT); 
+      o->end();
+    }
+
     {
       Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Visibility");
 
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 20b73f585a153b0119910aa290484073a9e4446d..f8350a1da45f5b46c65e64ed55b63274b5873930 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -190,6 +190,7 @@ public:
   Fl_Group         *mesh_group ;
   Fl_Group         *mesh_cut_plane ;
   Fl_Check_Button  *mesh_butt[50] ;
+  Fl_Return_Button *mesh_retbutt[50] ;
   Fl_Input         *mesh_input[20] ;
   Fl_Value_Input   *mesh_value[20] ;
   Fl_Button        *mesh_col[50] ;
diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp
index 9b58f9ff7d9bee8b0b6839fcd84769fd822bbd98..0bca7582bd61e8269db061eb2e487cd61be8c25d 100644
--- a/Mesh/BDS.cpp
+++ b/Mesh/BDS.cpp
@@ -656,7 +656,6 @@ void BDS_Mesh :: reverseEngineerCAD ( )
 		}
 		if (!(*it)->surf && pts.size() > 20)
 		{
-		    printf("coucou quadrique\n");
 		    Double_Matrix QUADRIC  ( pts.size() , 9 );
 		    Double_Vector ONES  ( pts.size() );
 		    Double_Vector RSLT  ( 9 );
@@ -1905,17 +1904,12 @@ bool BDS_Mesh ::split_edge ( BDS_Edge *e, double coord, BDS_Mesh *geom )
 
     mid->g = ge;
 
-    if (mid->g->surf)
-    {
-	mid->g->surf->projection ( mid->X,mid->Y,mid->Z,mid->X,mid->Y,mid->Z);
-    }
-
     triangles.push_back(t1); 
     triangles.push_back (t2); 
     triangles.push_back (t3); 
     triangles.push_back (t4); 
 
-    snap_point (mid, geom);
+    if(geom || mid->g->surf)snap_point (mid, geom);
 
     return true;
 }
@@ -2051,47 +2045,47 @@ bool BDS_Mesh ::collapse_edge ( BDS_Edge *e, BDS_Point *p, const double eps)
 
     p->getTriangles (t); 	
     {
-	std::list<BDS_Triangle *>::iterator it = t.begin();
-	std::list<BDS_Triangle *>::iterator ite = t.end();
-
-	while ( it != ite )
+      std::list<BDS_Triangle *>::iterator it = t.begin();
+      std::list<BDS_Triangle *>::iterator ite = t.end();
+      
+      while ( it != ite )
 	{
-	    BDS_Triangle *t = *it;
-//	    print_face(t);
-	    if (t->e1 != e && t->e2 != e && t->e3 != e)
-	      {
-		BDS_Vector n1,n2;
- 		BDS_Point *pts[3];
-		t->getNodes (pts); 
-		p->X = o->X;
-		p->Y = o->Y;
-		p->Z = o->Z;
-		double s_after = surface_triangle (pts[0],pts[1],pts[2]); 
-		n1 = t->N();
-		p->X = X;
-		p->Y = Y;
-		p->Z = Z;
-		n2 = t->N();
-		double s_before = surface_triangle (pts[0],pts[1],pts[2]); 
-		// normals should not be opposed or change too dramatically
-		// this does not concern the triangles with the small edge that
-		// are collapsed too
-		double angle = n1.angle(n2);
-		if (fabs(angle) > M_PI/2 )return false;
-		if (s_after < 1.e-2 * s_before)
+	  BDS_Triangle *t = *it;
+	  //	    print_face(t);
+	  if (t->e1 != e && t->e2 != e && t->e3 != e)
+	    {
+	      BDS_Vector n1,n2;
+	      BDS_Point *pts[3];
+	      t->getNodes (pts); 
+	      p->X = o->X;
+	      p->Y = o->Y;
+	      p->Z = o->Z;
+	      double s_after = surface_triangle (pts[0],pts[1],pts[2]); 
+	      n1 = t->N_on_the_fly();
+	      p->X = X;
+	      p->Y = Y;
+	      p->Z = Z;
+	      n2 = t->N();
+	      double s_before = surface_triangle (pts[0],pts[1],pts[2]); 
+	      // normals should not be opposed or change too dramatically
+	      // this does not concern the triangles with the small edge that
+	      // are collapsed too
+	      double angle = n1.angle(n2);
+	      if (fabs(angle) > M_PI/2 )return false;
+	      if (s_after < 1.e-2 * s_before)
 		{
-		    return false; 
+		  return false; 
 		}
-		gs[nt] = t->g;
-		pt[0][nt]   = (pts[0] == p) ? o->iD : pts[0]->iD ;
-		pt[1][nt]   = (pts[1] == p) ? o->iD : pts[1]->iD ;
-		pt[2][nt++] = (pts[2] == p) ? o->iD : pts[2]->iD ;
-	      }
-	    ++it;
+	      gs[nt] = t->g;
+	      pt[0][nt]   = (pts[0] == p) ? o->iD : pts[0]->iD ;
+	      pt[1][nt]   = (pts[1] == p) ? o->iD : pts[1]->iD ;
+	      pt[2][nt++] = (pts[2] == p) ? o->iD : pts[2]->iD ;
+	    }
+	  ++it;
 	}
     }
-
-
+    
+    
     {
 	std::list<BDS_Triangle *>::iterator it = t.begin();
 	std::list<BDS_Triangle *>::iterator ite = t.end();
@@ -2209,10 +2203,11 @@ void BDS_Mesh :: snap_point ( BDS_Point *p , BDS_Mesh *geom_mesh )
 {
   if (p->g->surf)
     {
-      p->g->surf->projection ( p->X,p->Y,p->Z,p->X,p->Y,p->Z);
+      p->g->surf->projection ( p->X,p->Y,p->Z,p->X,p->Y,p->Z);      
     }
   else if (p->g && p->g->classif_degree == 2 && geom_mesh)
     {
+
       std::list<BDS_Triangle*> l;
       BDS_GeomEntity *gg = geom_mesh->get_geom(p->g->classif_tag,p->g->classif_degree);
       gg->getClosestTriangles (p->X,p->Y,p->Z,l,p->radius_of_curvature);
@@ -2230,7 +2225,7 @@ void BDS_Mesh :: snap_point ( BDS_Point *p , BDS_Mesh *geom_mesh )
     }
   else
     {
-      return;
+      return ;
     }
   
   {
@@ -2266,16 +2261,12 @@ bool BDS_Mesh ::smooth_point ( BDS_Point *p , BDS_Mesh *geom_mesh )
 	++eit;
     }
 
-    X /= p->edges.size();
-    Y /= p->edges.size();
-    Z /= p->edges.size();
-
-    p->X = X;
-    p->Y = Y;
-    p->Z = Z;
+    p->X = X / p->edges.size();
+    p->Y = Y / p->edges.size();
+    p->Z = Z / p->edges.size();
 
     snap_point ( p, geom_mesh );
-
+    
     return true;
 }
 
@@ -2366,21 +2357,16 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
     SNAP_SUCCESS = 0;
     SNAP_FAILURE = 0;
 
-    BDS_Metric metric ( l , LC/500 , LC, 7 );
+    BDS_Metric metric ( l , LC/500 , LC, CTX.mesh.nb_elem_per_rc );
+
+    printf("%g\n",CTX.mesh.nb_elem_per_rc);
+    
     //    �pr�intf("METRIC %g %g %g\n",LC,metric._min,metric._max);
 
     // add initial set of edges in a list
-    std::list<BDS_Edge*> small_to_long;
-    {
-	std::list<BDS_Edge*>::iterator it = edges.begin();
-	std::list<BDS_Edge*>::iterator ite  = edges.end();
-	while (it != ite)
-	{
-	  //	    if ((*it)->numfaces()==1)printf("one face\n");
-	    small_to_long.push_back (*it);  
-	    ++it;
-	}
-    }
+
+    std::list<BDS_Edge*> small_to_long (edges);
+
     // split edges
     {
       std::list<BDS_Edge*>::iterator it = small_to_long.begin();
@@ -2394,6 +2380,7 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 	      double length = (*it)->length();
 	      if (!(*it)->deleted && length > (*it)->target_length / 0.7 ){
 		split_edge (*it, 0.5,geom_mesh );
+		//split_edge (*it, 0.5, 0  );
 		nb_modif++;
 	      }
 	    }
@@ -2403,16 +2390,8 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 
     // re-create small_to_long
     cleanup();    
-    {
-	small_to_long.clear();
-	std::list<BDS_Edge*>::iterator it = edges.begin();
-	std::list<BDS_Edge*>::iterator ite  = edges.end();
-	while (it != ite)
-	{
-	    small_to_long.push_back (*it);  
-	    ++it;
-	}
-    }
+    small_to_long = edges;
+
     // collapse 
     {    	
 	std::list<BDS_Edge*>::iterator it = small_to_long.begin();
@@ -2438,16 +2417,8 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 	}
     }
     cleanup();  
-    {
-	small_to_long.clear();
-	std::list<BDS_Edge*>::iterator it = edges.begin();
-	std::list<BDS_Edge*>::iterator ite  = edges.end();
-	while (it != ite)
-	{
-	    small_to_long.push_back (*it);  
-	    ++it;
-	}
-    }
+    small_to_long = edges;
+
     {    
 	std::list<BDS_Edge*>::iterator it = small_to_long.begin();
 	std::list<BDS_Edge*>::iterator ite  = small_to_long.end();
diff --git a/Mesh/BDS.h b/Mesh/BDS.h
index 6c2aa1f8987847fa3dc065b29efc2e915cbc2bf0..b495245510dc8075bebad650f28a929883f03420 100644
--- a/Mesh/BDS.h
+++ b/Mesh/BDS.h
@@ -381,6 +381,15 @@ public:
 	  n[2] = e2->commonvertex (e3);
 	}
 
+    inline BDS_Vector N_on_the_fly() const 
+      {
+	double nn[3];
+	BDS_Point *pp[3];
+	getNodes(pp);
+	normal_triangle (pp[0], pp[1], pp[2],nn);
+	return BDS_Vector (nn[0],nn[1],nn[2]);
+      }
+
     inline void addtet ( BDS_Tet *t)
 	{
 	  if (!t1) t1 = t;
diff --git a/Mesh/DiscreteSurface.cpp b/Mesh/DiscreteSurface.cpp
index a3804cfebec620e02d8cfc70957974370f82e5ba..42c2385daa4f349857446ccad74d3223777d03ad 100644
--- a/Mesh/DiscreteSurface.cpp
+++ b/Mesh/DiscreteSurface.cpp
@@ -1,4 +1,4 @@
-// $Id: DiscreteSurface.cpp,v 1.25 2005-09-07 17:12:16 remacle Exp $
+// $Id: DiscreteSurface.cpp,v 1.26 2005-09-21 15:03:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -28,6 +28,7 @@
 #include "Interpolation.h"
 #include "Context.h"
 #include "BDS.h"
+#include "PartitionMesh.h"
 
 extern Mesh *THEM;
 extern Context_T CTX;
@@ -333,6 +334,23 @@ void BDS_To_Mesh(Mesh *m)
 
 }
 
+
+int ReMesh(Mesh *M)
+{
+
+  if(M->status != 2) return 0;
+
+  DeleteMesh (M);
+  
+  delete M->bds_mesh;
+  M->bds_mesh = 0;
+  
+  MeshDiscreteSurface ((Surface*)0);
+
+  CTX.mesh.changed = 1;
+  return 1;
+}
+
 // Public interface for discrete surface/curve mesh algo
 
 int MeshDiscreteSurface(Surface *s)
@@ -341,7 +359,6 @@ int MeshDiscreteSurface(Surface *s)
   const int NITER = 10;
   if(THEM->bds){
     Msg(STATUS2, "Discrete Surface Mesh Generator...");
-    // s->bds is the discrete surface that defines the geometry
     if(!THEM->bds_mesh){
       THEM->bds_mesh = new BDS_Mesh (*(THEM->bds));
       int iter = 0;
@@ -357,11 +374,6 @@ int MeshDiscreteSurface(Surface *s)
     }
     return 2;
   }
-  else if(s->Typ == MSH_SURF_DISCRETE){
-    // nothing to do: we suppose that the surface is represented by
-    // a mesh that will not be modified
-    return 2;
-  }
   else
     return 0;
 }
diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h
index 208d016a0fde7745f04319d2566ede8ecf8b5139..0cace55b7bc3c1ab90b44fee635a0bdb0cf194bc 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/Mesh.h
@@ -472,6 +472,7 @@ int MeshParametricSurface(Surface *s);
 int MeshEllipticSurface(Surface *sur);
 int MeshDiscreteSurface(Surface *sur);
 int MeshDiscreteCurve(Curve *c);
+int ReMesh (Mesh *M);
 
 int AlgorithmeMaillage2DAnisotropeModeJF(Surface *s);
 void Maillage_Automatique_VieuxCode(Surface *pS, Mesh *m, int ori);
diff --git a/Mesh/PartitionMesh.h b/Mesh/PartitionMesh.h
index 6e22359f883be9b54bb181313d69f9d907df8125..a0929a189bb950b69ca95ba0b20957cc7e5f1d5d 100644
--- a/Mesh/PartitionMesh.h
+++ b/Mesh/PartitionMesh.h
@@ -2,4 +2,5 @@
 #define _PARTITION_MESH_GMSH__
 void PartitionMesh ( BDS_Mesh *M , int NP);
 void PartitionMesh ( Mesh *M , int NP);
+void DeleteMesh(Mesh * M);
 #endif
diff --git a/Metis/Makefile.in b/Metis/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..d9a7f9cc67fd880c887aac42648ccf8b34f2c12c
--- /dev/null
+++ b/Metis/Makefile.in
@@ -0,0 +1,22 @@
+
+# Which compiler to use
+CC = cc
+
+# What optimization level to use
+OPTFLAGS = -O2 
+
+# What options to be used by the compiler
+COPTIONS = 
+
+# What options to be used by the loader
+LDOPTIONS = 
+
+# What archiving to use
+AR = ar rv
+
+# What to use for indexing the archive
+RANLIB = ranlib
+#RANLIB = ar -ts
+#RANLIB = 
+
+
diff --git a/Metis/Makefile~ b/Metis/Makefile~
new file mode 100644
index 0000000000000000000000000000000000000000..3e962986758569408614fe8700bd99100046c773
--- /dev/null
+++ b/Metis/Makefile~
@@ -0,0 +1,114 @@
+# $Id: Makefile~,v 1.1 2005-09-21 15:03:47 remacle Exp $
+#
+# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+# 
+# Please report all bugs and problems to <gmsh@geuz.org>.
+
+include ../variables
+
+LIB     = ../lib/libGmshANN.a
+INCLUDE = -I../Common -I./include/
+CFLAGS  = ${OPTIM} ${FLAGS} ${INCLUDE} -DNO_PARALLEL_THREADS -UWIN32
+
+SRC = src/ANN.cpp\
+      src/bd_fix_rad_search.cpp\
+src/bd_pr_search.cpp\
+src/bd_search.cpp\
+src/bd_tree.cpp\
+src/brute.cpp\
+src/kd_dump.cpp\
+src/kd_fix_rad_search.cpp\
+src/kd_pr_search.cpp\
+src/kd_search.cpp\
+src/kd_split.cpp\
+src/kd_tree.cpp\
+src/kd_util.cpp\
+src/perf.cpp
+
+OBJ = ${SRC:.cpp=.o}
+
+.SUFFIXES: .o .cpp
+
+${LIB}: ${OBJ} 
+	${AR} ${LIB} ${OBJ} 
+	${RANLIB} ${LIB}
+
+.cpp.o:
+	${CXX} ${CFLAGS} -c $< -o ${<:.cpp=.o}
+
+clean:
+	rm -f src/*.o
+
+depend:
+	(sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \
+	${CXX} -MM ${CFLAGS} ${SRC} \
+	) >Makefile.new
+	cp Makefile Makefile.bak
+	cp Makefile.new Makefile
+	rm -f Makefile.new
+
+# DO NOT DELETE THIS LINE
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+ANN.o: src/ANN.cpp include/ANN/ANNx.h include/ANN/ANN.h \
+  include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+bd_fix_rad_search.o: src/bd_fix_rad_search.cpp src/bd_tree.h \
+  include/ANN/ANNx.h include/ANN/ANN.h src/kd_tree.h \
+  src/kd_fix_rad_search.h src/kd_util.h src/pr_queue_k.h \
+  include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+bd_pr_search.o: src/bd_pr_search.cpp src/bd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h src/kd_tree.h src/kd_pr_search.h src/kd_util.h \
+  src/pr_queue.h include/ANN/ANNperf.h src/pr_queue_k.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+bd_search.o: src/bd_search.cpp src/bd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h src/kd_tree.h src/kd_search.h src/kd_util.h \
+  src/pr_queue_k.h include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+bd_tree.o: src/bd_tree.cpp src/bd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h src/kd_tree.h src/kd_util.h src/kd_split.h \
+  include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+brute.o: src/brute.cpp include/ANN/ANNx.h include/ANN/ANN.h \
+  src/pr_queue_k.h include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_dump.o: src/kd_dump.cpp src/kd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h src/bd_tree.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_fix_rad_search.o: src/kd_fix_rad_search.cpp src/kd_fix_rad_search.h \
+  src/kd_tree.h include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h \
+  src/pr_queue_k.h include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_pr_search.o: src/kd_pr_search.cpp src/kd_pr_search.h src/kd_tree.h \
+  include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h src/pr_queue.h \
+  include/ANN/ANNperf.h src/pr_queue_k.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_search.o: src/kd_search.cpp src/kd_search.h src/kd_tree.h \
+  include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h src/pr_queue_k.h \
+  include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_split.o: src/kd_split.cpp src/kd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h src/kd_util.h src/kd_split.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_tree.o: src/kd_tree.cpp src/kd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h src/kd_split.h src/kd_util.h include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+kd_util.o: src/kd_util.cpp src/kd_util.h src/kd_tree.h include/ANN/ANNx.h \
+  include/ANN/ANN.h include/ANN/ANNperf.h
+# 1 "/Users/geuzaine/.gmsh/ANN//"
+perf.o: src/perf.cpp include/ANN/ANN.h include/ANN/ANNperf.h
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index 24a7cd0f4cc735380a31c06479bfea63479e67cf..b77348318b7000f2a8f8b424390ff505e5d5bd4b 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.82 2005-09-07 14:36:46 remacle Exp $
+// $Id: OpenFile.cpp,v 1.83 2005-09-21 15:03:47 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -287,21 +287,26 @@ int MergeProblem(char *name, int warn_if_missing)
     {
       THEM->bds->read_mesh ( name );
 #if defined(HAVE_FLTK)
-      WID->create_surface_mesh_wizard(name);
+      WID->swiz_value[1]->deactivate();
+      WID->mesh_retbutt[0]->deactivate();
 #endif
     }
     else
     {
+      THEM->bds->read_stl ( name , 5.e-7);
 #if defined(HAVE_FLTK)
-	WID->create_surface_mesh_wizard(name);
 #endif
     }
-
-
-    THEM->bds->save_gmsh_format ( "1.msh" );
+#if defined(HAVE_FLTK)
+    WID->surfmesh_filename = name; 
+#endif
+    //    THEM->bds->save_gmsh_format ( "1.msh" );
     THEM->bds->classify ( M_PI / 8 );
-    THEM->bds->save_gmsh_format ( "2.msh" );
+    //    THEM->bds->save_gmsh_format ( "2.msh" );
     BDS_To_Mesh (THEM);
+    THEM->bds_mesh = new BDS_Mesh (*THEM->bds);
+    BDS_To_Mesh_2(THEM);
+    THEM->status = 2;
     SetBoundingBox();
     status = THEM->status;
   }