diff --git a/Common/Context.h b/Common/Context.h
index 7acedc5928ee537f2ad517431593d7cc9f441bc0..8d4ab4e8c720eefdd9d32f27c35df9b7ff6ff392 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -125,12 +125,12 @@ public :
     int points, lines, surfaces, volumes;
     int points_num, lines_num, surfaces_num, volumes_num;
     double quality;
-    double limit_gamma, limit_eta, limit_rho;
+    double gamma_inf, gamma_sup, radius_inf, radius_sup;
     double scaling_factor, lc_factor, rand_factor;
     int dual, interactive;
     int hidden, shade;
     int format, nb_smoothing, algo, degree;
-    int point_insertion, speed_max, min_circ_points;
+    int point_insertion, speed_max, min_circ_points, constrained_bgmesh;
     double normals, tangents, explode;
     int color_scheme, color_carousel ;
     int use_cut_plane;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 959ee0ed96100a23dfadcb13e503f60dd1077fc5..c082ac3c2c31ed2042a6bfea7ce7329cbcf8c00f 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -20,17 +20,17 @@ StringXString GeneralOptions_String[] = {
   { F|S, "DefaultFileName" , opt_general_default_filename , "unnamed.geo" ,
     "Default project file name" },
   { F|S, "TmpFileName" , opt_general_tmp_filename , ".gmsh-tmp" ,
-    "Temporary file name (saved in the 'home' directory)" },
+    "Temporary file (created in your home directory)" },
   { F|S, "ErrorFileName" , opt_general_error_filename , ".gmsh-errors" ,
     "File into which the log is saved if a fatal error occurs" },
   { F|S, "OptionsFileName" , opt_general_options_filename , ".gmsh-options" ,
-    "Option file created in the 'home' directory with the 'File->Save Options' menu, and which is read on startup" },
+    "File created in your home directory with 'Options->Save options', and which is read on startup" },
 #ifdef WIN32
   { F|O, "TextEditor" , opt_general_editor , "notepad %s" , 
 #else
   { F|O, "TextEditor" , opt_general_editor , "emacs %s &" ,
 #endif
-    "System command to launch a text editor (may contain '%%s')" },
+    "System command to launch a text editor" },
   { 0, NULL , NULL , NULL , NULL }
 } ;
 
@@ -318,7 +318,7 @@ StringXNumber GeometryOptions_Number[] = {
 
 StringXNumber MeshOptions_Number[] = {
   { F|O, "Quality" , opt_mesh_quality , 0.0 ,
-    "Only display elements of quality inferior to this factor" },
+    "Target quality for tetrahedral elements (not fully functional)" },
   { F|O, "Normals" , opt_mesh_normals , 0.0 ,
     "Size of the normal vectors" }, 
   { F|O, "Tangents" , opt_mesh_tangents , 0.0 , 
@@ -331,12 +331,14 @@ StringXNumber MeshOptions_Number[] = {
     "Factor applied to all charcteristic lenghts (and background meshes)" },
   { F|O, "RandomFactor" , opt_mesh_rand_factor , 1.e-4 ,
     "Random factor used in 2D and 3D meshing algorithm (test other values when the algorithm fails)" },
-  { F|O, "GammaLimit" , opt_mesh_limit_gamma , 0.0 , 
-    "Target quality for tetrahedral elements (not fully functional)" },
-  { F|O, "EtaLimit" , opt_mesh_limit_eta , 0.0 , 
-    "Target quality for tetrahedral elements (not fully functional)" },
-  { F|O, "RhoLimit" , opt_mesh_limit_rho , 0.0 , 
-    "Target quality for tetrahedral elements (not fully functional)" },
+  { F|O, "GammaInf" , opt_mesh_gamma_inf , 0.0 , 
+    "Only display elements whose Gamma factor is greater than GammaInf" },
+  { F|O, "GammaSup" , opt_mesh_gamma_sup , 0.0 , 
+    "Only display elements whose Gamma factor is smaller than GammaSup" },
+  { F|O, "RadiusInf" , opt_mesh_radius_inf , 0.0 , 
+    "Only display elements whose Radius is greater than RadiusInf" },
+  { F|O, "RadiusSup" , opt_mesh_radius_sup , 0.0 , 
+    "Only display elements whose Radius is smaller than RadiusSup" },
   { F|O, "Points" , opt_mesh_points , 1. , 
     "Display mesh vertices?" },
   { F|O, "Lines" , opt_mesh_lines , 1. , 
@@ -367,6 +369,8 @@ StringXNumber MeshOptions_Number[] = {
     "Disable dubious point insertion tests" },
   { F|O, "MinimumCirclePoints" , opt_mesh_min_circ_points, 7. ,
     "Minimum number of points used to mesh a circle" },
+  { F|O, "ConstrainedBackgroundMesh" , opt_mesh_constrained_bgmesh, 0. ,
+    "Should the background mesh be constrained by the characteristic lengths associated with the geometry?" },
   { F|O, "Degree" , opt_mesh_degree , 1. ,
     "Element order" },
   { F|O, "Dual" , opt_mesh_dual , 0. ,
diff --git a/Common/GetOptions.cpp b/Common/GetOptions.cpp
index 994599d5e3570482dfca5d567a2113c8a65d370a..ba5df5e083e8b68bf7a85549815c53fc4e7add24 100644
--- a/Common/GetOptions.cpp
+++ b/Common/GetOptions.cpp
@@ -1,4 +1,4 @@
-// $Id: GetOptions.cpp,v 1.19 2001-05-17 07:11:49 geuzaine Exp $
+// $Id: GetOptions.cpp,v 1.20 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -42,9 +42,10 @@ void Print_Usage(char *name){
   Msg(DIRECT, "  -clscale float        set characteristic length scaling factor (default: 1.0)");
   Msg(DIRECT, "  -rand float           set random perturbation factor (default: 1.e-4)");
   Msg(DIRECT, "  -bgm file             load backround mesh from file");
+  Msg(DIRECT, "  -constrain            constrain background mesh with characteristic lengths");
 #ifndef _BLACKBOX
   Msg(DIRECT, "  -interactive          display 2D mesh construction interactively");
-  Msg(DIRECT, "Post Processing options:");
+  Msg(DIRECT, "Post-processing options:");
   Msg(DIRECT, "  -dl                   enable display lists");
   Msg(DIRECT, "  -noview               hide all views on startup");
   Msg(DIRECT, "  -link                 link all views on startup");
@@ -54,9 +55,9 @@ void Print_Usage(char *name){
 #ifdef _XMOTIF
   Msg(DIRECT, "  -noov                 disable overlay visual");
   Msg(DIRECT, "  -flash                allow colormap flashing");
-  Msg(DIRECT, "  -samevisual           force same visual for graphics and UI");
+  Msg(DIRECT, "  -samevisual           force same visual for graphics and GUI");
 #else
-  Msg(DIRECT, "  -fontsize int         size of the font for the user interface (default: 12)");
+  Msg(DIRECT, "  -fontsize int         specify the font size for the GUI (default: 12)");
 #endif
   Msg(DIRECT, "  -alpha                enable alpha blending");
   Msg(DIRECT, "  -notrack              don't use trackball mode for rotations");
@@ -64,7 +65,8 @@ void Print_Usage(char *name){
   Msg(DIRECT, "  -perspective          set projection mode to perspective");
 #endif
   Msg(DIRECT, "Other options:");      
-  Msg(DIRECT, "  -a, -g, -m, -s, -p    start in auto, geometry, mesh, solver or post mode (default: auto)");
+  Msg(DIRECT, "  -a, -g, -m, -s, -p    start in automatic, geometry, mesh, solver or");
+  Msg(DIRECT, "                        post-processing mode (default: automatic)");
   Msg(DIRECT, "  -v int                set verbosity level (default: 2)");
 #ifdef _XMOTIF
   Msg(DIRECT, "  -nothreads            disable threads");
@@ -127,6 +129,9 @@ void Get_Options (int argc, char *argv[], int *nbfiles) {
           exit(1);
         }
       }
+      else if(!strcmp(argv[i]+1, "constrain")){ 
+	CTX.mesh.constrained_bgmesh = 1;
+      }
       else if(!strcmp(argv[i]+1, "convert")){ 
 	i++;
 	CTX.terminal = 1;
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 059cbf8e2ecade5eb8dad370410d4ae45f11fe95..73772ed9091a39ba453398953ebdc6adfaabe27d 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.18 2001-05-07 06:25:25 geuzaine Exp $
+// $Id: Options.cpp,v 1.19 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -137,23 +137,27 @@ void Print_Options(int num, int level, char *filename){
 
   if((level & GMSH_SESSIONRC) && file){
     fprintf(file, "// Gmsh Session File\n");
+    fprintf(file, "//\n");
     fprintf(file, "// This file takes session specific info (that is info\n");
     fprintf(file, "// you want to keep between two Gmsh sessions). You are\n");
     fprintf(file, "// not supposed to edit it manually, but of course you\n");
     fprintf(file, "// can do. This file will be entirely rewritten every time\n");
     fprintf(file, "// you quit Gmsh if the option 'General.SaveSession' is\n");
     fprintf(file, "// set. If this file isn't found, defaults are used.\n");
+    fprintf(file, "//\n");
   }
 
   if((level & GMSH_OPTIONSRC) && file){
     fprintf(file, "// Gmsh Option File\n");
-    fprintf(file, "// This file takes configuration options that should\n");
-    fprintf(file, "// be loaded each time Gmsh is launched. You can create\n");
+    fprintf(file, "//\n");
+    fprintf(file, "// This file takes configuration options (preferences) that\n");
+    fprintf(file, "// should be loaded each time Gmsh is launched. You can create\n");
     fprintf(file, "// this file by hand, or let Gmsh generate it for you (with\n");
-    fprintf(file, "// the 'File->Save Options' menu button). This file can\n");
+    fprintf(file, "// the 'Options->Save options' menu button). This file can\n");
     fprintf(file, "// also be automatically regenerated every time you quit\n");
     fprintf(file, "// Gmsh if the option 'General.SaveOptions' is set. If\n");
     fprintf(file, "// this file isn't found, defaults are used.\n");
+    fprintf(file, "//\n");
   }
 
   Print_OptionCategory(level, "General options", file);
@@ -1176,17 +1180,13 @@ double opt_mesh_normals(OPT_ARGS_NUM){
     CTX.mesh.normals = val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_value[5]->value(CTX.mesh.normals);
+    WID->mesh_value[8]->value(CTX.mesh.normals);
 #endif
   return CTX.mesh.normals;
 }
 double opt_mesh_tangents(OPT_ARGS_NUM){
   if(action & GMSH_SET) 
     CTX.mesh.tangents = val;
-#ifdef _FLTK
-  if(WID && (action & GMSH_GUI))
-    WID->mesh_value[1]->value(CTX.mesh.tangents);
-#endif
   return CTX.mesh.tangents;
 }
 double opt_mesh_explode(OPT_ARGS_NUM){
@@ -1194,7 +1194,7 @@ double opt_mesh_explode(OPT_ARGS_NUM){
     CTX.mesh.explode = val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_value[6]->value(CTX.mesh.explode);
+    WID->mesh_value[9]->value(CTX.mesh.explode);
 #endif
   return CTX.mesh.explode;
 }
@@ -1225,31 +1225,48 @@ double opt_mesh_rand_factor(OPT_ARGS_NUM){
 #endif
   return CTX.mesh.rand_factor;
 }
-double opt_mesh_limit_gamma(OPT_ARGS_NUM){
+double opt_mesh_gamma_inf(OPT_ARGS_NUM){
   if(action & GMSH_SET) 
-    CTX.mesh.limit_gamma = val;
+    CTX.mesh.gamma_inf = val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_value[4]->value(CTX.mesh.limit_gamma);
+    WID->mesh_value[4]->value(CTX.mesh.gamma_inf);
 #endif
-  return CTX.mesh.limit_gamma;
+  return CTX.mesh.gamma_inf;
 }
-double opt_mesh_limit_eta(OPT_ARGS_NUM){
+double opt_mesh_gamma_sup(OPT_ARGS_NUM){
   if(action & GMSH_SET) 
-    CTX.mesh.limit_eta = val;
-  return CTX.mesh.limit_eta;
+    CTX.mesh.gamma_sup = val;
+#ifdef _FLTK
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[5]->value(CTX.mesh.gamma_sup);
+#endif
+  return CTX.mesh.gamma_sup;
 }
-double opt_mesh_limit_rho(OPT_ARGS_NUM){
-  if(action & GMSH_SET) 
-    CTX.mesh.limit_rho = val;
-  return CTX.mesh.limit_rho;
+double opt_mesh_radius_inf(OPT_ARGS_NUM){
+  if(action & GMSH_SET)
+    CTX.mesh.radius_inf = val;
+#ifdef _FLTK
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[6]->value(CTX.mesh.radius_inf);
+#endif
+  return CTX.mesh.radius_inf;
+}
+double opt_mesh_radius_sup(OPT_ARGS_NUM){
+  if(action & GMSH_SET)
+    CTX.mesh.radius_sup = val;
+#ifdef _FLTK
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[7]->value(CTX.mesh.radius_sup);
+#endif
+  return CTX.mesh.radius_sup;
 }
 double opt_mesh_points(OPT_ARGS_NUM){
   if(action & GMSH_SET) 
     CTX.mesh.points = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[3]->value(CTX.mesh.points);
+    WID->mesh_butt[4]->value(CTX.mesh.points);
 #endif
   return CTX.mesh.points;
 }
@@ -1258,7 +1275,7 @@ double opt_mesh_lines(OPT_ARGS_NUM){
     CTX.mesh.lines = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[4]->value(CTX.mesh.lines);
+    WID->mesh_butt[5]->value(CTX.mesh.lines);
 #endif
   return CTX.mesh.lines;
 }
@@ -1267,7 +1284,7 @@ double opt_mesh_surfaces(OPT_ARGS_NUM){
     CTX.mesh.surfaces = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[5]->value(CTX.mesh.surfaces);
+    WID->mesh_butt[6]->value(CTX.mesh.surfaces);
 #endif
   return CTX.mesh.surfaces;
 }
@@ -1276,7 +1293,7 @@ double opt_mesh_volumes(OPT_ARGS_NUM){
     CTX.mesh.volumes = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[6]->value(CTX.mesh.volumes);
+    WID->mesh_butt[7]->value(CTX.mesh.volumes);
 #endif
   return CTX.mesh.volumes;
 }
@@ -1285,7 +1302,7 @@ double opt_mesh_points_num(OPT_ARGS_NUM){
     CTX.mesh.points_num = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[7]->value(CTX.mesh.points_num);
+    WID->mesh_butt[8]->value(CTX.mesh.points_num);
 #endif
   return CTX.mesh.points_num;
 }
@@ -1294,7 +1311,7 @@ double opt_mesh_lines_num(OPT_ARGS_NUM){
     CTX.mesh.lines_num = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[8]->value(CTX.mesh.lines_num);
+    WID->mesh_butt[9]->value(CTX.mesh.lines_num);
 #endif
   return CTX.mesh.lines_num;
 }
@@ -1303,7 +1320,7 @@ double opt_mesh_surfaces_num(OPT_ARGS_NUM){
     CTX.mesh.surfaces_num = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[9]->value(CTX.mesh.surfaces_num);
+    WID->mesh_butt[10]->value(CTX.mesh.surfaces_num);
 #endif
   return CTX.mesh.surfaces_num;
 }
@@ -1312,7 +1329,7 @@ double opt_mesh_volumes_num(OPT_ARGS_NUM){
     CTX.mesh.volumes_num = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[10]->value(CTX.mesh.volumes_num);
+    WID->mesh_butt[11]->value(CTX.mesh.volumes_num);
 #endif
   return CTX.mesh.volumes_num;
 }
@@ -1326,9 +1343,9 @@ double opt_mesh_aspect(OPT_ARGS_NUM){
   }
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI)){
-    WID->mesh_butt[11]->value(!CTX.mesh.hidden && !CTX.mesh.shade);
-    WID->mesh_butt[12]->value(CTX.mesh.hidden && !CTX.mesh.shade);
-    WID->mesh_butt[13]->value(CTX.mesh.hidden && CTX.mesh.shade);
+    WID->mesh_butt[12]->value(!CTX.mesh.hidden && !CTX.mesh.shade);
+    WID->mesh_butt[13]->value(CTX.mesh.hidden && !CTX.mesh.shade);
+    WID->mesh_butt[14]->value(CTX.mesh.hidden && CTX.mesh.shade);
   }
 #endif
   if(CTX.mesh.hidden && !CTX.mesh.shade) return 1;
@@ -1373,6 +1390,15 @@ double opt_mesh_min_circ_points(OPT_ARGS_NUM){
     CTX.mesh.min_circ_points = (int)val;
   return CTX.mesh.min_circ_points;
 }
+double opt_mesh_constrained_bgmesh(OPT_ARGS_NUM){
+  if(action & GMSH_SET) 
+    CTX.mesh.constrained_bgmesh = (int)val;
+#ifdef _FLTK
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_butt[3]->value(CTX.mesh.constrained_bgmesh);
+#endif
+  return CTX.mesh.constrained_bgmesh;
+}
 double opt_mesh_degree(OPT_ARGS_NUM){
   if(action & GMSH_SET) 
     CTX.mesh.degree = (int)val;
@@ -1430,7 +1456,7 @@ double opt_mesh_color_scheme(OPT_ARGS_NUM){
   }
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_value[7]->value(CTX.mesh.color_scheme);
+    WID->mesh_value[10]->value(CTX.mesh.color_scheme);
 #endif
   return CTX.mesh.color_scheme;
 }
@@ -1439,7 +1465,7 @@ double opt_mesh_color_carousel(OPT_ARGS_NUM){
     CTX.mesh.color_carousel = (int)val;
 #ifdef _FLTK
   if(WID && (action & GMSH_GUI))
-    WID->mesh_butt[14]->value(CTX.mesh.color_carousel);
+    WID->mesh_butt[15]->value(CTX.mesh.color_carousel);
 #endif
   return CTX.mesh.color_carousel;
 }
diff --git a/Common/Options.h b/Common/Options.h
index 6e0263e4cc0689913804023193dc053688447e16..2c70d3250096532b90e64baaff1c3183ffcec5ef 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -152,9 +152,10 @@ double opt_mesh_explode(OPT_ARGS_NUM);
 double opt_mesh_scaling_factor(OPT_ARGS_NUM);
 double opt_mesh_lc_factor(OPT_ARGS_NUM);
 double opt_mesh_rand_factor(OPT_ARGS_NUM);
-double opt_mesh_limit_gamma(OPT_ARGS_NUM);
-double opt_mesh_limit_eta(OPT_ARGS_NUM);
-double opt_mesh_limit_rho(OPT_ARGS_NUM);
+double opt_mesh_gamma_inf(OPT_ARGS_NUM);
+double opt_mesh_gamma_sup(OPT_ARGS_NUM);
+double opt_mesh_radius_inf(OPT_ARGS_NUM);
+double opt_mesh_radius_sup(OPT_ARGS_NUM);
 double opt_mesh_points(OPT_ARGS_NUM);
 double opt_mesh_lines(OPT_ARGS_NUM);
 double opt_mesh_surfaces(OPT_ARGS_NUM);
@@ -170,6 +171,7 @@ double opt_mesh_algo(OPT_ARGS_NUM);
 double opt_mesh_point_insertion(OPT_ARGS_NUM);
 double opt_mesh_speed_max(OPT_ARGS_NUM);
 double opt_mesh_min_circ_points(OPT_ARGS_NUM);
+double opt_mesh_constrained_bgmesh(OPT_ARGS_NUM);
 double opt_mesh_degree(OPT_ARGS_NUM);
 double opt_mesh_dual(OPT_ARGS_NUM);
 double opt_mesh_interactive(OPT_ARGS_NUM);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 22b6a5984a9a508f76f2ee4ac727e7f185f55d65..4157bee84c9711168cf03552481b97850bb29624 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.55 2001-05-18 11:47:07 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.56 2001-05-20 19:24:53 geuzaine Exp $
 
 #include <sys/types.h>
 #include <signal.h>
@@ -186,14 +186,6 @@ void file_merge_cb(CALLBACK_ARGS) {
     WID->set_context(menu_post, 0);
 }
 
-void file_save_mesh_cb(CALLBACK_ARGS) {
-  Print_Mesh(&M, NULL, CTX.mesh.format);
-}
-
-void file_save_options_cb(CALLBACK_ARGS) {
-  Print_Options(0,GMSH_OPTIONSRC, CTX.optionsrc_filename); 
-}
-
 void file_save_as_auto_cb(CALLBACK_ARGS) {
   char *newfile;
   if((newfile = fl_file_chooser("Save file by extension", "*", NULL)))
@@ -373,34 +365,38 @@ void opt_mesh_show_by_entity_num_cb(CALLBACK_ARGS) {
   opt_geometry_show_by_entity_num_cb(w,data);
 }
 void opt_mesh_color_scheme_cb(CALLBACK_ARGS){
-  opt_mesh_color_scheme(0,GMSH_SET, WID->mesh_value[7]->value());
+  opt_mesh_color_scheme(0,GMSH_SET, WID->mesh_value[10]->value());
   Draw();
 }
 void opt_mesh_ok_cb(CALLBACK_ARGS) {
   opt_mesh_degree(0, GMSH_SET, WID->mesh_butt[0]->value()?2:1);
   opt_mesh_interactive(0, GMSH_SET, WID->mesh_butt[1]->value());
   opt_mesh_algo(0, GMSH_SET, WID->mesh_butt[2]->value()?DELAUNAY_NEWALGO:DELAUNAY_OLDALGO);
-  opt_mesh_points(0, GMSH_SET, WID->mesh_butt[3]->value());
-  opt_mesh_lines(0, GMSH_SET, WID->mesh_butt[4]->value());
-  opt_mesh_surfaces(0, GMSH_SET, WID->mesh_butt[5]->value());
-  opt_mesh_volumes(0, GMSH_SET, WID->mesh_butt[6]->value());
-  opt_mesh_points_num(0, GMSH_SET, WID->mesh_butt[7]->value());
-  opt_mesh_lines_num(0, GMSH_SET, WID->mesh_butt[8]->value());
-  opt_mesh_surfaces_num(0, GMSH_SET, WID->mesh_butt[9]->value());
-  opt_mesh_volumes_num(0, GMSH_SET, WID->mesh_butt[10]->value());
+  opt_mesh_constrained_bgmesh(0, GMSH_SET, WID->mesh_butt[3]->value());
+  opt_mesh_points(0, GMSH_SET, WID->mesh_butt[4]->value());
+  opt_mesh_lines(0, GMSH_SET, WID->mesh_butt[5]->value());
+  opt_mesh_surfaces(0, GMSH_SET, WID->mesh_butt[6]->value());
+  opt_mesh_volumes(0, GMSH_SET, WID->mesh_butt[7]->value());
+  opt_mesh_points_num(0, GMSH_SET, WID->mesh_butt[8]->value());
+  opt_mesh_lines_num(0, GMSH_SET, WID->mesh_butt[9]->value());
+  opt_mesh_surfaces_num(0, GMSH_SET, WID->mesh_butt[10]->value());
+  opt_mesh_volumes_num(0, GMSH_SET, WID->mesh_butt[11]->value());
   opt_mesh_aspect(0, GMSH_SET, 
-		  WID->mesh_butt[11]->value()?0:
-		  WID->mesh_butt[12]->value()?1:
+		  WID->mesh_butt[12]->value()?0:
+		  WID->mesh_butt[13]->value()?1:
 		  2);
-  opt_mesh_color_carousel(0, GMSH_SET, WID->mesh_butt[14]->value());
+  opt_mesh_color_carousel(0, GMSH_SET, WID->mesh_butt[15]->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());
   opt_mesh_rand_factor(0, GMSH_SET, WID->mesh_value[3]->value());
-  opt_mesh_limit_gamma(0, GMSH_SET, WID->mesh_value[4]->value());
-  opt_mesh_normals(0, GMSH_SET, WID->mesh_value[5]->value());
-  opt_mesh_explode(0, GMSH_SET, WID->mesh_value[6]->value());
+  opt_mesh_gamma_inf(0, GMSH_SET, WID->mesh_value[4]->value());
+  opt_mesh_gamma_sup(0, GMSH_SET, WID->mesh_value[5]->value());
+  opt_mesh_radius_inf(0, GMSH_SET, WID->mesh_value[6]->value());
+  opt_mesh_radius_sup(0, GMSH_SET, WID->mesh_value[7]->value());
+  opt_mesh_normals(0, GMSH_SET, WID->mesh_value[8]->value());
+  opt_mesh_explode(0, GMSH_SET, WID->mesh_value[9]->value());
 
   Draw();
 }
@@ -440,6 +436,9 @@ void opt_message_save_cb(CALLBACK_ARGS) {
   if((newfile = fl_file_chooser("Save messages", "*", NULL)))
     WID->save_message(newfile); 
 }
+void opt_save_cb(CALLBACK_ARGS) {
+  Print_Options(0,GMSH_OPTIONSRC, CTX.optionsrc_filename); 
+}
 
 // Help Menu
 
@@ -450,7 +449,7 @@ void help_short_cb(CALLBACK_ARGS){
   Msg(DIRECT, "  move          - highlight the elementary geometrical entity");
   Msg(DIRECT, "                  currently under the mouse pointer and display");
   Msg(DIRECT, "                  its properties in the status bar");
-  Msg(DIRECT, "                - size a rubber zoom started with (Ctrl+mouse1)");
+  Msg(DIRECT, "                - size a rubber zoom started with Ctrl+mouse1");
   Msg(DIRECT, "  mouse1        - rotate");
   Msg(DIRECT, "                - accept a rubber zoom started by Ctrl+mouse1"); 
   Msg(DIRECT, "  Ctrl+mouse1   start (anisotropic) rubber zoom"); 
@@ -460,9 +459,8 @@ void help_short_cb(CALLBACK_ARGS){
   Msg(DIRECT, "  Ctrl+mouse2   orthogonalize display"); 
   Msg(DIRECT, "  mouse3        - pan");
   Msg(DIRECT, "                - cancel a rubber zoom");
-  Msg(DIRECT, "                - pop up menu on module name");
   Msg(DIRECT, "                - pop up menu on post-processing view button");
-  Msg(DIRECT, "  Ctrl+mouse3   reset viewpoint to default");   
+  Msg(DIRECT, "  Ctrl+mouse3   reset to default viewpoint");   
   Msg(DIRECT, "");
   Msg(DIRECT, "Menu bar shortcuts:");
   Msg(DIRECT, "");
@@ -476,11 +474,11 @@ void help_short_cb(CALLBACK_ARGS){
   Msg(DIRECT, "  Ctrl+m        merge file"); 
   Msg(DIRECT, "  Shift+o       show general options"); 
   Msg(DIRECT, "  Ctrl+o        open file"); 
-  Msg(DIRECT, "  p             go to post processor module");
+  Msg(DIRECT, "  p             go to post-processor module");
   Msg(DIRECT, "  Shift+p       show post-processing general options");
   Msg(DIRECT, "  Ctrl+p        save file by extension");
   Msg(DIRECT, "  Ctrl+q        quit");
-  Msg(DIRECT, "  Ctrl+s        save mesh");
+  Msg(DIRECT, "  Ctrl+s        save mesh in default format");
   Msg(DIRECT, "");
   Msg(DIRECT, "Other shortcuts");
   Msg(DIRECT, "");
@@ -490,7 +488,7 @@ void help_short_cb(CALLBACK_ARGS){
   Msg(DIRECT, "  3 or F3       mesh volumes");
   Msg(DIRECT, "  Alt+a         hide/show small axes"); 
   Msg(DIRECT, "  Alt+Shift+a   hide/show big moving axes"); 
-  Msg(DIRECT, "  Alt+b         hide/show all post processing scales");
+  Msg(DIRECT, "  Alt+b         hide/show all post-processing scales");
   Msg(DIRECT, "  Alt+c         alternate between predefined color schemes");
   Msg(DIRECT, "  Alt+d         alternate between mesh wire frame, hidden lines and shading modes");
   Msg(DIRECT, "  Alt+f         toggle redraw mode (fast/full)"); 
@@ -551,6 +549,12 @@ void geometry_elementary_cb(CALLBACK_ARGS){
 void geometry_physical_cb(CALLBACK_ARGS){
   WID->set_context(menu_geometry_physical, 0);
 }
+void geometry_edit_cb(CALLBACK_ARGS){
+  char cmd[1000];
+  sprintf(cmd, CTX.editor, CTX.filename);
+  Msg(INFO, "Starting text editor '%s'", cmd);
+  system(cmd);
+} 
 void geometry_reload_cb(CALLBACK_ARGS){
   OpenProblem(CTX.filename);
   Draw();
@@ -1088,6 +1092,9 @@ void geometry_physical_add_volume_cb (CALLBACK_ARGS){
 
 // Dynamic Mesh Menus
 
+void mesh_save_cb(CALLBACK_ARGS) {
+  Print_Mesh(&M, NULL, CTX.mesh.format);
+}
 void mesh_define_cb(CALLBACK_ARGS){
   WID->set_context(menu_mesh_define, 0);
 }
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 2b96b7e11a3d6dd18970d25673675271e5802769..27e093bb055a9c324f620afcf616e4c4132035fe 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -21,8 +21,6 @@ void status_cancel_cb(CALLBACK_ARGS) ;
 
 void file_open_cb(CALLBACK_ARGS) ;
 void file_merge_cb(CALLBACK_ARGS) ;
-void file_save_mesh_cb(CALLBACK_ARGS) ;
-void file_save_options_cb(CALLBACK_ARGS) ;
 void file_save_as_auto_cb(CALLBACK_ARGS) ;
 void file_save_as_geo_cb(CALLBACK_ARGS) ;
 void file_save_as_geo_options_cb(CALLBACK_ARGS) ;
@@ -75,6 +73,8 @@ void opt_message_cb(CALLBACK_ARGS) ;
 void opt_message_clear_cb(CALLBACK_ARGS) ;
 void opt_message_save_cb(CALLBACK_ARGS) ;
 
+void opt_save_cb(CALLBACK_ARGS) ;
+
 // Help Menu
 
 void help_short_cb(CALLBACK_ARGS) ;
@@ -155,6 +155,7 @@ void     geometry_physical_add_point_cb (CALLBACK_ARGS) ;
 void     geometry_physical_add_curve_cb (CALLBACK_ARGS) ;
 void     geometry_physical_add_surface_cb (CALLBACK_ARGS) ;
 void     geometry_physical_add_volume_cb (CALLBACK_ARGS) ;
+void geometry_edit_cb(CALLBACK_ARGS) ;
 void geometry_reload_cb(CALLBACK_ARGS) ; 
 
 void con_geometry_define_parameter_cb(CALLBACK_ARGS) ;
@@ -166,6 +167,7 @@ void con_geometry_define_symmetry_cb(CALLBACK_ARGS) ;
 
 // Dynamic Mesh Menus
 
+void mesh_save_cb(CALLBACK_ARGS) ;
 void mesh_define_cb(CALLBACK_ARGS) ;
 void mesh_1d_cb(CALLBACK_ARGS) ;
 void mesh_2d_cb(CALLBACK_ARGS) ; 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 21bd1009c88876da7b8d65d5da56738699f4a87c..2b1955a73c3220129fb9f3c64dce007ff155185c 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.77 2001-05-10 12:08:01 geuzaine Exp $
+// $Id: GUI.cpp,v 1.78 2001-05-20 19:24:53 geuzaine Exp $
 
 // To make the interface as visually consistent as possible, please:
 // - use the BH, BW, WB, IW values for button heights/widths, window borders, etc.
@@ -38,38 +38,37 @@ Fl_Menu_Item m_menubar_table[] = {
   {"File", 0, 0, 0, FL_SUBMENU},
     {"Open...",          FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0},
     {"Merge...",         FL_CTRL+'m', (Fl_Callback *)file_merge_cb, 0},
-    {"Save Mesh",        FL_CTRL+'s', (Fl_Callback *)file_save_mesh_cb, 0},
-    {"Save Options",     0,           (Fl_Callback *)file_save_options_cb, 0},
-    {"Save As",          0, 0, 0, FL_MENU_DIVIDER|FL_SUBMENU},
-      {"By extension...",      FL_CTRL+'p', (Fl_Callback *)file_save_as_auto_cb, 0},
-      {"GEO complete options...",  0, (Fl_Callback *)file_save_as_geo_options_cb, 0},
-      {"GEO flattened...",     0, (Fl_Callback *)file_save_as_geo_cb, 0},
-      {"MSH...",               0, (Fl_Callback *)file_save_as_msh_cb, 0},
-      {"UNV...",               0, (Fl_Callback *)file_save_as_unv_cb, 0},
-      {"GREF...",              0, (Fl_Callback *)file_save_as_gref_cb, 0},
-      {"EPS simple sort...",   0, (Fl_Callback *)file_save_as_eps_simple_cb, 0},
-      {"EPS accurate sort...", 0, (Fl_Callback *)file_save_as_eps_accurate_cb, 0},
-      {"JPEG...",              0, (Fl_Callback *)file_save_as_jpeg_cb, 0},
-      {"GIF...",               0, (Fl_Callback *)file_save_as_gif_cb, 0},
-      {"GIF dithered...",      0, (Fl_Callback *)file_save_as_gif_dithered_cb, 0},
-      {"GIF transparent...",   0, (Fl_Callback *)file_save_as_gif_transparent_cb, 0},
-      {"PPM...",               0, (Fl_Callback *)file_save_as_ppm_cb, 0},
-      {"UCB YUV...",           0, (Fl_Callback *)file_save_as_yuv_cb, 0},
+    {"Save as",          0, 0, 0, FL_MENU_DIVIDER|FL_SUBMENU},
+      {"By extension...",        FL_CTRL+'p', (Fl_Callback *)file_save_as_auto_cb, 0, FL_MENU_DIVIDER},
+      {"MSH native mesh format...",       0, (Fl_Callback *)file_save_as_msh_cb, 0},
+      {"UNV universal mesh format...",    0, (Fl_Callback *)file_save_as_unv_cb, 0},
+      {"GREF gref mesh format...",        0, (Fl_Callback *)file_save_as_gref_cb, 0},
+      {"GEO flattened geometry...",       0, (Fl_Callback *)file_save_as_geo_cb, 0},
+      {"GEO complete options...",         0, (Fl_Callback *)file_save_as_geo_options_cb, 0},
+      {"EPS simple sort postscript...",   0, (Fl_Callback *)file_save_as_eps_simple_cb, 0},
+      {"EPS accurate sort postscript...", 0, (Fl_Callback *)file_save_as_eps_accurate_cb, 0},
+      {"JPEG...",                0, (Fl_Callback *)file_save_as_jpeg_cb, 0},
+      {"GIF...",                 0, (Fl_Callback *)file_save_as_gif_cb, 0},
+      {"GIF dithered...",        0, (Fl_Callback *)file_save_as_gif_dithered_cb, 0},
+      {"GIF transparent...",     0, (Fl_Callback *)file_save_as_gif_transparent_cb, 0},
+      {"PPM...",                 0, (Fl_Callback *)file_save_as_ppm_cb, 0},
+      {"UCB YUV...",             0, (Fl_Callback *)file_save_as_yuv_cb, 0},
       {0},
+    {"Messages...",      FL_SHIFT+'l', (Fl_Callback *)opt_message_cb, 0},
+    {"Statistics...",    FL_SHIFT+'i', (Fl_Callback *)opt_statistics_cb, 0, FL_MENU_DIVIDER},
     {"Quit",             FL_CTRL+'q', (Fl_Callback *)file_quit_cb, 0},
     {0},
   {"Options",0,0,0,FL_SUBMENU},
-    {"General...",         FL_SHIFT+'o', (Fl_Callback *)opt_general_cb, 0},
+    {"General...",         FL_SHIFT+'o', (Fl_Callback *)opt_general_cb, 0, FL_MENU_DIVIDER},
     {"Geometry...",        FL_SHIFT+'g', (Fl_Callback *)opt_geometry_cb, 0},
     {"Mesh...",            FL_SHIFT+'m', (Fl_Callback *)opt_mesh_cb, 0},
-    {"Post-Processing...", FL_SHIFT+'p', (Fl_Callback *)opt_post_cb, 0, FL_MENU_DIVIDER},
-    {"Statistics...",      FL_SHIFT+'i', (Fl_Callback *)opt_statistics_cb, 0},
-    {"Message log...",     FL_SHIFT+'l', (Fl_Callback *)opt_message_cb, 0},
+    {"Post-processing...", FL_SHIFT+'p', (Fl_Callback *)opt_post_cb, 0, FL_MENU_DIVIDER},
+    {"Save options",       0,            (Fl_Callback *)opt_save_cb, 0},
     {0},
   {"Help",0,0,0,FL_SUBMENU},
-    {"Shortcuts...",             0, (Fl_Callback *)help_short_cb, 0},
-    {"Command line options...",  0, (Fl_Callback *)help_command_line_cb, 0},
     {"Current options...",       0, (Fl_Callback *)status_xyz1p_cb, (void*)4},
+    {"Shortcuts...",             0, (Fl_Callback *)help_short_cb, 0},
+    {"Command line options...",  0, (Fl_Callback *)help_command_line_cb, 0, FL_MENU_DIVIDER},
     {"About...",                 0, (Fl_Callback *)help_about_cb, 0},
     {0},
   {0}
@@ -79,7 +78,7 @@ Fl_Menu_Item m_module_table[] = {
   {"Geometry",        'g', (Fl_Callback *)mod_geometry_cb, 0},
   {"Mesh",            'm', (Fl_Callback *)mod_mesh_cb, 0},
   {"Solver",          's', (Fl_Callback *)mod_solver_cb, 0},
-  {"Post-Processing", 'p', (Fl_Callback *)mod_post_cb, 0},
+  {"Post-processing", 'p', (Fl_Callback *)mod_post_cb, 0},
   {0}
 };
 
@@ -89,6 +88,7 @@ Context_Item menu_geometry[] =
 { { "0Geometry", NULL } ,
   { "Elementary", (Fl_Callback *)geometry_elementary_cb } ,
   { "Physical",   (Fl_Callback *)geometry_physical_cb } ,
+  { "Edit",       (Fl_Callback *)geometry_edit_cb } , 
   { "Reload",     (Fl_Callback *)geometry_reload_cb } , 
   { NULL }
 };  
@@ -228,6 +228,7 @@ Context_Item menu_mesh[] =
   { "1D",     (Fl_Callback *)mesh_1d_cb } ,
   { "2D",     (Fl_Callback *)mesh_2d_cb } , 
   { "3D",     (Fl_Callback *)mesh_3d_cb } , 
+  { "Save",   (Fl_Callback *)mesh_save_cb } ,
   { NULL } 
 };  
     Context_Item menu_mesh_define[] = 
@@ -251,7 +252,7 @@ Context_Item menu_solver[] =
   { NULL } };
 
 Context_Item menu_post[] = 
-{ { "3Post-Processing", NULL } ,
+{ { "3Post-processing", NULL } ,
   { NULL } };
 
 //********************** Definition of global shortcuts ********************************
@@ -270,18 +271,22 @@ int GUI::global_shortcuts(int event){
   }
   if(Fl::test_shortcut('0') || Fl::test_shortcut(FL_Escape)){
     geometry_reload_cb(0,0);
+    mod_geometry_cb(0,0);
     return 1;
   }
   else if(Fl::test_shortcut('1') || Fl::test_shortcut(FL_F+1)){
     mesh_1d_cb(0,0);
+    mod_mesh_cb(0,0);
     return 1;
   }
   else if(Fl::test_shortcut('2') || Fl::test_shortcut(FL_F+2)){
     mesh_2d_cb(0,0);
+    mod_mesh_cb(0,0);
     return 1;
   }
   else if(Fl::test_shortcut('3') || Fl::test_shortcut(FL_F+3)){
     mesh_3d_cb(0,0);
+    mod_mesh_cb(0,0);
     return 1;
   }
   else if(Fl::test_shortcut('g')){
@@ -301,11 +306,11 @@ int GUI::global_shortcuts(int event){
     return 1;
   }
   else if(Fl::test_shortcut('b')){
-    set_context(NULL, -1);
+    mod_back_cb(0,0);
     return 1;
   }
   else if(Fl::test_shortcut('f')){
-    set_context(NULL, 1);
+    mod_forward_cb(0,0);
     return 1;
   }
   else if(Fl::test_shortcut('e')){
@@ -316,6 +321,10 @@ int GUI::global_shortcuts(int event){
     quit_selection = 1;
     return 1;
   }
+  else if(Fl::test_shortcut(FL_CTRL+'s')){
+    mesh_save_cb(0,0);
+    return 1;
+  }
   else if(Fl::test_shortcut(FL_CTRL+FL_SHIFT+'s')){
     opt_post_anim_delay(0,GMSH_SET|GMSH_GUI,opt_post_anim_delay(0,GMSH_GET,0) + 0.01);
     return 1;
@@ -1173,7 +1182,7 @@ void GUI::create_mesh_options_window(){
     init_mesh_options_window = 1 ;
     
     int width = 25*CTX.fontsize;
-    int height = 5*WB+9*BH ;
+    int height = 5*WB+10*BH ;
     
     mesh_window = new Fl_Window(width,height);
     mesh_window->box(WINDOW_BOX);
@@ -1187,25 +1196,26 @@ void GUI::create_mesh_options_window(){
 	mesh_butt[0] = new Fl_Check_Button(2*WB, 2*WB+1*BH, BW, BH, "Second order elements");
 	mesh_butt[1] = new Fl_Check_Button(2*WB, 2*WB+2*BH, BW, BH, "Interactive");
 	mesh_butt[2] = new Fl_Check_Button(2*WB, 2*WB+3*BH, BW, BH, "Anisotropic");
-	for(i=0 ; i<3 ; i++){
+	mesh_butt[3] = new Fl_Check_Button(2*WB, 2*WB+4*BH, BW, BH, "Constrained background mesh");
+	for(i=0 ; i<4 ; i++){
 	  mesh_butt[i]->type(FL_TOGGLE_BUTTON);
 	  mesh_butt[i]->down_box(FL_DOWN_BOX);
 	  mesh_butt[i]->labelsize(CTX.fontsize);
 	  mesh_butt[i]->selection_color(FL_YELLOW);
 	}
-	mesh_value[0] = new Fl_Value_Input(2*WB, 2*WB+4*BH, IW, BH, "Number of smoothing steps");
+	mesh_value[0] = new Fl_Value_Input(2*WB, 2*WB+5*BH, IW, BH, "Number of smoothing steps");
 	mesh_value[0]->minimum(0);
 	mesh_value[0]->maximum(100); 
 	mesh_value[0]->step(1);
-	mesh_value[1] = new Fl_Value_Input(2*WB, 2*WB+5*BH, IW, BH, "Mesh scaling factor");
+	mesh_value[1] = new Fl_Value_Input(2*WB, 2*WB+6*BH, IW, BH, "Mesh scaling factor");
 	mesh_value[1]->minimum(0.001);
 	mesh_value[1]->maximum(1000); 
 	mesh_value[1]->step(0.001);
-	mesh_value[2] = new Fl_Value_Input(2*WB, 2*WB+6*BH, IW, BH, "Characteristic length factor");
+	mesh_value[2] = new Fl_Value_Input(2*WB, 2*WB+7*BH, IW, BH, "Characteristic length factor");
 	mesh_value[2]->minimum(0.001);
 	mesh_value[2]->maximum(1000); 
 	mesh_value[2]->step(0.001);
-	mesh_value[3] = new Fl_Value_Input(2*WB, 2*WB+7*BH, IW, BH, "Random perturbation factor");
+	mesh_value[3] = new Fl_Value_Input(2*WB, 2*WB+8*BH, IW, BH, "Random perturbation factor");
 	mesh_value[3]->minimum(1.e-6);
 	mesh_value[3]->maximum(1.e-1); 
 	mesh_value[3]->step(1.e-6);
@@ -1220,15 +1230,15 @@ void GUI::create_mesh_options_window(){
       { 
 	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Visibility");
 	o->labelsize(CTX.fontsize);
-	mesh_butt[3] = new Fl_Check_Button(2*WB, 2*WB+1*BH, IW, BH, "Points");
-	mesh_butt[4] = new Fl_Check_Button(2*WB, 2*WB+2*BH, IW, BH, "Curves");
-	mesh_butt[5] = new Fl_Check_Button(2*WB, 2*WB+3*BH, IW, BH, "Surfaces");
-	mesh_butt[6] = new Fl_Check_Button(2*WB, 2*WB+4*BH, IW, BH, "Volumes");
-	mesh_butt[7] = new Fl_Check_Button(width/2, 2*WB+1*BH, IW, BH, "Point Numbers");
-	mesh_butt[8] = new Fl_Check_Button(width/2, 2*WB+2*BH, IW, BH, "Curve Numbers");
-	mesh_butt[9] = new Fl_Check_Button(width/2, 2*WB+3*BH, IW, BH, "Surface Numbers");
-	mesh_butt[10] = new Fl_Check_Button(width/2, 2*WB+4*BH, IW, BH, "Volume Numbers");
-	for(i=3 ; i<11 ; i++){
+	mesh_butt[4] = new Fl_Check_Button(2*WB, 2*WB+1*BH, IW, BH, "Points");
+	mesh_butt[5] = new Fl_Check_Button(2*WB, 2*WB+2*BH, IW, BH, "Curves");
+	mesh_butt[6] = new Fl_Check_Button(2*WB, 2*WB+3*BH, IW, BH, "Surfaces");
+	mesh_butt[7] = new Fl_Check_Button(2*WB, 2*WB+4*BH, IW, BH, "Volumes");
+	mesh_butt[8] = new Fl_Check_Button(width/2, 2*WB+1*BH, IW, BH, "Point Numbers");
+	mesh_butt[9] = new Fl_Check_Button(width/2, 2*WB+2*BH, IW, BH, "Curve Numbers");
+	mesh_butt[10] = new Fl_Check_Button(width/2, 2*WB+3*BH, IW, BH, "Surface Numbers");
+	mesh_butt[11] = new Fl_Check_Button(width/2, 2*WB+4*BH, IW, BH, "Volume Numbers");
+	for(i=4 ; i<12 ; i++){
 	  mesh_butt[i]->type(FL_TOGGLE_BUTTON);
 	  mesh_butt[i]->down_box(FL_DOWN_BOX);
 	  mesh_butt[i]->labelsize(CTX.fontsize);
@@ -1241,15 +1251,23 @@ void GUI::create_mesh_options_window(){
 	mesh_input->callback(opt_mesh_show_by_entity_num_cb);
 	mesh_input->when(FL_WHEN_ENTER_KEY|FL_WHEN_NOT_CHANGED);
 
-	mesh_value[4] = new Fl_Value_Input(2*WB, 2*WB+6*BH, IW, BH, "Show by element quality");
+	mesh_value[4] = new Fl_Value_Input(2*WB, 2*WB+6*BH, IW/2, BH);
 	mesh_value[4]->minimum(0); 
 	mesh_value[4]->maximum(1);
 	mesh_value[4]->step(0.001);
-	mesh_value[5] = new Fl_Value_Input(2*WB, 2*WB+7*BH, IW, BH, "Normals");
+	mesh_value[5] = new Fl_Value_Input(2*WB+IW/2, 2*WB+6*BH, IW/2, BH, "Quality range");
 	mesh_value[5]->minimum(0); 
-	mesh_value[5]->maximum(100);
-	mesh_value[5]->step(1);
-	for(i=4 ; i<6 ; i++){
+	mesh_value[5]->maximum(1);
+	mesh_value[5]->step(0.001);
+
+	mesh_value[6] = new Fl_Value_Input(2*WB, 2*WB+7*BH, IW/2, BH);
+	mesh_value[7] = new Fl_Value_Input(2*WB+IW/2, 2*WB+7*BH, IW/2, BH, "Size range");
+
+	mesh_value[8] = new Fl_Value_Input(2*WB, 2*WB+8*BH, IW, BH, "Normals");
+	mesh_value[8]->minimum(0); 
+	mesh_value[8]->maximum(100);
+	mesh_value[8]->step(1);
+	for(i=4 ; i<9 ; i++){
 	  mesh_value[i]->labelsize(CTX.fontsize);
 	  mesh_value[i]->textsize(CTX.fontsize);
 	  mesh_value[i]->type(FL_HORIZONTAL);
@@ -1261,44 +1279,44 @@ void GUI::create_mesh_options_window(){
 	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Aspect");
 	o->labelsize(CTX.fontsize);
 	o->hide();
-	mesh_butt[11] = new Fl_Check_Button(2*WB, 2*WB+1*BH, BW, BH, "Wireframe");
-	mesh_butt[12] = new Fl_Check_Button(2*WB, 2*WB+2*BH, BW, BH, "Hidden lines");
-	mesh_butt[13] = new Fl_Check_Button(2*WB, 2*WB+3*BH, BW, BH, "Solid");
-	for(i=11 ; i<14 ; i++){
+	mesh_butt[12] = new Fl_Check_Button(2*WB, 2*WB+1*BH, BW, BH, "Wireframe");
+	mesh_butt[13] = new Fl_Check_Button(2*WB, 2*WB+2*BH, BW, BH, "Hidden lines");
+	mesh_butt[14] = new Fl_Check_Button(2*WB, 2*WB+3*BH, BW, BH, "Solid");
+	for(i=12 ; i<15 ; i++){
 	  mesh_butt[i]->type(FL_RADIO_BUTTON);
 	  mesh_butt[i]->down_box(FL_DOWN_BOX);
 	  mesh_butt[i]->labelsize(CTX.fontsize);
 	  mesh_butt[i]->selection_color(FL_YELLOW);
 	}
-	mesh_value[6] = new Fl_Value_Input(2*WB, 2*WB+4*BH, IW, BH, "Explode elements");
-	mesh_value[6]->minimum(0);
-	mesh_value[6]->maximum(1);
-	mesh_value[6]->step(0.01);
-	mesh_value[6]->labelsize(CTX.fontsize);
-	mesh_value[6]->textsize(CTX.fontsize);
-	mesh_value[6]->type(FL_HORIZONTAL);
-	mesh_value[6]->align(FL_ALIGN_RIGHT);
+	mesh_value[9] = new Fl_Value_Input(2*WB, 2*WB+4*BH, IW, BH, "Explode elements");
+	mesh_value[9]->minimum(0);
+	mesh_value[9]->maximum(1);
+	mesh_value[9]->step(0.01);
+	mesh_value[9]->labelsize(CTX.fontsize);
+	mesh_value[9]->textsize(CTX.fontsize);
+	mesh_value[9]->type(FL_HORIZONTAL);
+	mesh_value[9]->align(FL_ALIGN_RIGHT);
 	o->end();
       }
       { 
 	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Colors");
 	o->labelsize(CTX.fontsize);
 	o->hide();
-	mesh_butt[14] = new Fl_Check_Button(2*WB, 2*WB+1*BH, IW, BH, "Switch color by geometrical entity");
-	mesh_butt[14]->type(FL_TOGGLE_BUTTON);
-	mesh_butt[14]->down_box(FL_DOWN_BOX);
-	mesh_butt[14]->labelsize(CTX.fontsize);
-	mesh_butt[14]->selection_color(FL_YELLOW);
-
-	mesh_value[7] = new Fl_Value_Input(2*WB, 2*WB+2*BH, IW, BH, "Predefined color scheme");
-	mesh_value[7]->minimum(0); 
-	mesh_value[7]->maximum(2); 
-	mesh_value[7]->step(1);
-	mesh_value[7]->labelsize(CTX.fontsize);
-	mesh_value[7]->textsize(CTX.fontsize);
-	mesh_value[7]->type(FL_HORIZONTAL);
-	mesh_value[7]->align(FL_ALIGN_RIGHT);
-	mesh_value[7]->callback(opt_mesh_color_scheme_cb);
+	mesh_butt[15] = new Fl_Check_Button(2*WB, 2*WB+1*BH, IW, BH, "Switch color by entity");
+	mesh_butt[15]->type(FL_TOGGLE_BUTTON);
+	mesh_butt[15]->down_box(FL_DOWN_BOX);
+	mesh_butt[15]->labelsize(CTX.fontsize);
+	mesh_butt[15]->selection_color(FL_YELLOW);
+
+	mesh_value[10] = new Fl_Value_Input(2*WB, 2*WB+2*BH, IW, BH, "Predefined color scheme");
+	mesh_value[10]->minimum(0); 
+	mesh_value[10]->maximum(2); 
+	mesh_value[10]->step(1);
+	mesh_value[10]->labelsize(CTX.fontsize);
+	mesh_value[10]->textsize(CTX.fontsize);
+	mesh_value[10]->type(FL_HORIZONTAL);
+	mesh_value[10]->align(FL_ALIGN_RIGHT);
+	mesh_value[10]->callback(opt_mesh_color_scheme_cb);
 
 	Fl_Scroll* s = new Fl_Scroll(2*WB, 3*WB+3*BH, IW+20, height-3*WB-5*BH);
 	i = 0;
@@ -1349,8 +1367,8 @@ void GUI::create_post_options_window(){
   if(!init_post_options_window){
     init_post_options_window = 1 ;
 
-    int width = 17*CTX.fontsize;
-    int height = 5*WB+5*BH ;
+    int width = 20*CTX.fontsize;
+    int height = 5*WB+8*BH ;
 
     post_window = new Fl_Window(width,height);
     post_window->box(WINDOW_BOX);
@@ -1358,16 +1376,22 @@ void GUI::create_post_options_window(){
     { 
       Fl_Tabs* o = new Fl_Tabs(WB, WB, width-2*WB, height-3*WB-BH);
       { 
-	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Links");
+	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Views");
 	o->labelsize(CTX.fontsize);
 	post_butt[0] = new Fl_Check_Button(2*WB, 2*WB+1*BH, BW, BH, "No link between views");
-	post_butt[1] = new Fl_Check_Button(2*WB, 2*WB+2*BH, BW, BH, "Link visible views");
+	post_butt[1] = new Fl_Check_Button(2*WB, 2*WB+2*BH, BW, BH, "Link all visible views");
 	post_butt[2] = new Fl_Check_Button(2*WB, 2*WB+3*BH, BW, BH, "Link all views");
 	for(i=0 ; i<3 ; i++){
 	  post_butt[i]->type(FL_RADIO_BUTTON);
 	  post_butt[i]->labelsize(CTX.fontsize);
 	  post_butt[i]->selection_color(FL_YELLOW);
 	}
+	Fl_Box *text =  new Fl_Box(FL_NO_BOX, 2*WB, 3*WB+4*BH, width-4*WB, 2*BH,
+				   "Individual view options are available "
+				   "by right-clicking on each view button "
+				   "in the post-processing menu");
+	text->align(FL_ALIGN_LEFT|FL_ALIGN_TOP|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+	text->labelsize(CTX.fontsize);
 	o->end();
       }
       { 
diff --git a/Fltk/Message.cpp b/Fltk/Message.cpp
index a1d63182bcf49db659e8669c2b7759a116de92f4..bf730e626a5fae76add2eb5ccea9df0db272ac8b 100644
--- a/Fltk/Message.cpp
+++ b/Fltk/Message.cpp
@@ -1,4 +1,4 @@
-// $Id: Message.cpp,v 1.19 2001-04-22 18:13:02 geuzaine Exp $
+// $Id: Message.cpp,v 1.20 2001-05-20 19:24:53 geuzaine Exp $
 
 #include <signal.h>
 #if !defined(WIN32) || defined(__CYGWIN__)
@@ -145,7 +145,6 @@ void Msg(int level, char *fmt, ...){
 void Free_DisplayLists(void);
 
 void Exit(int level){
-  //if(CTX.display_lists) Free_DisplayLists(); //bug in XFree86?
   if(WID && !CTX.batch){
     if(CTX.session_save){
       CTX.position[0] = WID->m_window->x();
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 9d4bbdf6810d98ec9ef771383978c83790753bff..b55d59fc4f94a960170bfb0d382bea8d804a6622 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.24 2001-04-26 17:58:00 remacle Exp $
+// $Id: Mesh.cpp,v 1.25 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -152,11 +152,9 @@ void Draw_Mesh_Points (void *a, void *b){
 
   v = (Vertex**)a;
 
-
-  if(CTX.mesh.use_cut_plane)
-    {
-      if(CTX.mesh.evalCutPlane((*v)->Pos.X, (*v)->Pos.Y, (*v)->Pos.Z) < 0)return;
-    }
+  if(CTX.mesh.use_cut_plane){
+    if(CTX.mesh.evalCutPlane((*v)->Pos.X, (*v)->Pos.Y, (*v)->Pos.Z) < 0)return;
+  }
   
   if(CTX.render_mode == GMSH_SELECT){
     glLoadName(0);
@@ -195,12 +193,26 @@ void Draw_Mesh_Points (void *a, void *b){
 void Draw_Simplex_Volume (void *a, void *b){
   Simplex **s;
   char Num[100];
-  double X[4],Y[4],Z[4];
+  int fulldraw = 0;
+  double tmp, X[4],Y[4],Z[4];
 
   s = (Simplex**)a;
 
+  if(!(*s)->V[3]) return;
+
   if(!EntiteEstElleVisible((*s)->iEnt)) return;
 
+  if(CTX.mesh.gamma_sup){
+    tmp = (*s)->GammaShapeMeasure();
+    if(tmp < CTX.mesh.gamma_inf || tmp > CTX.mesh.gamma_sup) return;
+    fulldraw = 1;
+  }
+
+  if(CTX.mesh.radius_sup){
+    if((*s)->Radius < CTX.mesh.radius_inf || (*s)->Radius > CTX.mesh.radius_sup) return;
+    fulldraw = 1;
+  }
+
   double Xc = .25 * ((*s)->V[0]->Pos.X + (*s)->V[1]->Pos.X + 
                      (*s)->V[2]->Pos.X + (*s)->V[3]->Pos.X);
   double Yc = .25 * ((*s)->V[0]->Pos.Y + (*s)->V[1]->Pos.Y + 
@@ -208,21 +220,9 @@ void Draw_Simplex_Volume (void *a, void *b){
   double Zc = .25 * ((*s)->V[0]->Pos.Z + (*s)->V[1]->Pos.Z + 
                      (*s)->V[2]->Pos.Z + (*s)->V[3]->Pos.Z);
 
-  if(CTX.mesh.use_cut_plane)
-    {
-      if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0)return;
-    }
-  
-  if(!(*s)->V[3]) return;
-
-  if(CTX.mesh.limit_gamma){
-    if((*s)->GammaShapeMeasure() > CTX.mesh.limit_gamma) return;
-  }
-  if(CTX.mesh.limit_eta){
-    if((*s)->EtaShapeMeasure() > CTX.mesh.limit_eta) return;
-  }
-  if(CTX.mesh.limit_rho){
-    if((*s)->RhoShapeMeasure() > CTX.mesh.limit_rho) return;
+  if(CTX.mesh.use_cut_plane){
+    if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0) return;
+    fulldraw = 1;
   }
 
   if(CTX.mesh.color_carousel)
@@ -287,11 +287,14 @@ void Draw_Simplex_Volume (void *a, void *b){
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
 
-#if 1 /* never here for the moment */
+  if(!fulldraw) return ;
 
   double n[4], x1x0, y1y0, z1z0, x2x0, y2y0, z2z0;
 
-  ColorSwitch((*s)->iEnt);
+  if(CTX.mesh.color_carousel)
+    ColorSwitch((*s)->iEnt);
+  else
+    glColor4ubv((GLubyte*)&CTX.color.mesh.tetrahedron);    
 
   if (CTX.mesh.hidden) {
 
@@ -354,8 +357,6 @@ void Draw_Simplex_Volume (void *a, void *b){
 
   }
 
-#endif
-
 }
 
 
@@ -372,7 +373,7 @@ void Draw_Simplex_Surfaces (void *a, void *b){
   if(!(*s)->V[2]) return ;
 
   if(!EntiteEstElleVisible ((*s)->iEnt)) return;
-  
+
   if((*s)->VSUP) L=1;
   else L=0;
 
@@ -392,10 +393,9 @@ void Draw_Simplex_Surfaces (void *a, void *b){
     Zc = ((*s)->V[0]->Pos.Z + (*s)->V[1]->Pos.Z + (*s)->V[2]->Pos.Z) / 3. ;
   }
 
-  if(CTX.mesh.use_cut_plane)
-    {
-      if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0)return;
-    }
+  if(CTX.mesh.use_cut_plane){
+    if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0)return;
+  }
 
   k=0;
   for (i=0 ; i<K ; i++) {
@@ -560,10 +560,9 @@ void Draw_Hexahedron_Volume (void *a, void *b){
   Zc *= .125 ; 
   Yc *= .125 ; 
 
-  if(CTX.mesh.use_cut_plane)
-    {
-      if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0)return;
-    }
+  if(CTX.mesh.use_cut_plane){
+    if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0)return;
+  }
 
   if(CTX.mesh.color_carousel)
     ColorSwitch((*h)->iEnt+1);  
diff --git a/Mesh/1D_Mesh.cpp b/Mesh/1D_Mesh.cpp
index 24efd9254c3dcc3831f00fa43621e89bd8c14d5e..08dffb1967d20e9af8cba4ebbf1450237e46609d 100644
--- a/Mesh/1D_Mesh.cpp
+++ b/Mesh/1D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 1D_Mesh.cpp,v 1.14 2001-04-25 20:42:39 geuzaine Exp $
+// $Id: 1D_Mesh.cpp,v 1.15 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Const.h"
@@ -79,21 +79,24 @@ double F_Transfini (double t){
 
 double F_Lc (double t){
   Vertex  der, point;
-  double  Lc;
+  double  Lc, d;
 
   if (CTX.mesh.algo == DELAUNAY_OLDALGO && THEM->BGM.Typ == ONFILE){
     der = InterpolateCurve(THEC, t, 1);
     point = InterpolateCurve(THEC, t, 0);  
     Lc = Lc_XYZ(point.Pos.X, point.Pos.Y, point.Pos.Z, THEM);
+    d = sqrt(DSQR(der.Pos.X)+DSQR(der.Pos.Y)+DSQR(der.Pos.Z));
     if(!Lc){
       Msg(GERROR, "Null characteristic length in background mesh");
-      return sqrt(DSQR(der.Pos.X)+DSQR(der.Pos.Y)+DSQR(der.Pos.Z));
+      return d;
     }
-    return sqrt(DSQR(der.Pos.X)+DSQR(der.Pos.Y)+DSQR(der.Pos.Z))/Lc;  
+    if(CTX.mesh.constrained_bgmesh)
+      return MAX(d/Lc,THEM->Metric->getLc(t, THEC));
+    else
+      return d/Lc;
   }
-  else{
+  else
     return THEM->Metric->getLc(t, THEC);
-  }
 }
 
 void Maillage_Curve (void *data, void *dummy){
diff --git a/Mesh/2D_Mesh.cpp b/Mesh/2D_Mesh.cpp
index c2a1b1c1d4bd3900e9d5f95e7f5efab31c374e14..ff7fd2fa83a22d81e24c49089fb6d4528fec60e9 100644
--- a/Mesh/2D_Mesh.cpp
+++ b/Mesh/2D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 2D_Mesh.cpp,v 1.20 2001-04-08 20:36:49 geuzaine Exp $
+// $Id: 2D_Mesh.cpp,v 1.21 2001-05-20 19:24:53 geuzaine Exp $
 
 /*
    Maillage Delaunay d'une surface (Point insertion Technique)
@@ -34,7 +34,7 @@ int LocalNewPoint;
 PointRecord   *gPointArray;
 DocRecord     *BGMESH, *FGMESH;
 double         qual, newqual, L;
-int            is_3D = 0, UseBGMesh;
+int            is_3D = 0;
 double         LC2D ;
 
 static Surface  *THESURFACE, *THESUPPORT;
@@ -432,8 +432,7 @@ Delaunay * testconv (avlptr * root, int *conv, DocRecord * ptr){
 
 
 int mesh_domain (ContourPeek * ListContours, int numcontours,
-                 maillage * mai, int *numpoints, DocRecord * BGMesh,
-                 int OnlyTheInitialMesh){
+                 maillage * mai, int *numpoints, int OnlyTheInitialMesh){
   List_T *kill_L, *del_L ;
   MPoint pt;
   DocRecord docm, *doc;
@@ -495,13 +494,9 @@ int mesh_domain (ContourPeek * ListContours, int numcontours,
   Conversion (doc);
   remove_all_dlist (doc->numPoints, doc->points);
 
-  if (!is_3D){
-    if (UseBGMesh == 1)
-      BGMESH = BGMesh;
-    else{
-      BGMESH = doc;
-      InitBricks (BGMESH);
-    }
+  if (!is_3D || CTX.mesh.constrained_bgmesh){
+    BGMESH = doc;
+    InitBricks (BGMESH);
   }
 
   /* elimination des triangles exterieurs + verification de l'existence
@@ -840,7 +835,6 @@ void Maillage_Automatique_VieuxCode (Surface * pS, Mesh * m, int ori){
 
   if (m->BGM.Typ == WITHPOINTS){
     is_3D = 0;
-    UseBGMesh = 0;
   }
   else{
     is_3D = 1;
@@ -878,9 +872,12 @@ void Maillage_Automatique_VieuxCode (Surface * pS, Mesh * m, int ori){
       cp->oriented_points[j].where.h = v->Pos.X;
       cp->oriented_points[j].where.v = v->Pos.Y;
 
-      cp->perturbations[j].h = CTX.mesh.rand_factor /* /(100*v->lc) */  * LC2D * 
+      // On pourrait imaginer diviser les perturbations par un facteur
+      // dependant de v->lc, mais ca n'a pas l'air d'ameliorer le bignou
+
+      cp->perturbations[j].h = CTX.mesh.rand_factor * LC2D * 
 	(double)rand()/(double)RAND_MAX;
-      cp->perturbations[j].v = CTX.mesh.rand_factor /* /(100.*v->lc) */ * LC2D *
+      cp->perturbations[j].v = CTX.mesh.rand_factor * LC2D *
 	(double)rand()/(double)RAND_MAX;
 
       cp->oriented_points[j].numcontour = i;
@@ -893,7 +890,7 @@ void Maillage_Automatique_VieuxCode (Surface * pS, Mesh * m, int ori){
   }
 
   if (pS->Method)
-    mesh_domain (liste, List_Nbr (pS->Contours), &M, &N, NULL, 0);
+    mesh_domain (liste, List_Nbr (pS->Contours), &M, &N, 0);
 
   for (i = 0; i < M.numpoints; i++){
     if (gPointArray[i].initial < 0){
@@ -990,7 +987,17 @@ void filldel (Delaunay * deladd, int aa, int bb, int cc,
     v = Create_Vertex (-1, pt2.h, pt2.v, 0.0, 0.0, 0.0);
     Calcule_Z_Plan (&v, &dum);
     Projette_Inverse (&v, &dum);
-    newqual = Lc_XYZ (v->Pos.X, v->Pos.Y, v->Pos.Z, THEM);
+    qual = Lc_XYZ (v->Pos.X, v->Pos.Y, v->Pos.Z, THEM);
+    if(CTX.mesh.constrained_bgmesh){
+      if (mesh){
+	newqual = MIN(qual,find_quality (pt2, mesh));
+      }
+      else{
+	newqual = MIN(qual, (points[aa].quality + points[bb].quality + points[cc].quality) / 3.);
+      }
+    }
+    else
+      newqual = qual;
     Free (v);
   }
 
diff --git a/Mesh/2D_Util.cpp b/Mesh/2D_Util.cpp
index 8ed7476e3acdfa09f824aff3974cd2e3ecdbdf56..21e220484c551d5d6bfdbfe95b6b9e94a6372052 100644
--- a/Mesh/2D_Util.cpp
+++ b/Mesh/2D_Util.cpp
@@ -1,10 +1,12 @@
-// $Id: 2D_Util.cpp,v 1.9 2001-04-08 20:36:49 geuzaine Exp $
+// $Id: 2D_Util.cpp,v 1.10 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Const.h"
 #include "Mesh.h"
 #include "2D_Mesh.h"
+#include "Context.h"
 
+extern Context_T     CTX;
 extern int           LocalNewPoint;
 extern PointRecord  *gPointArray;
 extern Mesh         *THEM;
@@ -56,6 +58,7 @@ int Delete_Triangle ( avlstruct **root, Delaunay * del ){
 int Insert_Point (MPoint pt, int *numpoints, int *numalloc, 
                   DocRecord *doc, DocRecord *BGM, int is3d){
   Vertex *v,*dum;
+  double qual;
 
   if ( *numpoints >= *numalloc ) {
     gPointArray = (PointRecord *) Realloc(gPointArray, 
@@ -74,7 +77,11 @@ int Insert_Point (MPoint pt, int *numpoints, int *numalloc,
     v = Create_Vertex (-1,pt.h,pt.v,0.0,0.0,0.0);
     Calcule_Z_Plan(&v, &dum);
     Projette_Inverse(&v, &dum);
-    gPointArray[*numpoints].quality = Lc_XYZ ( v->Pos.X,v->Pos.Y,v->Pos.Z,THEM);
+    qual = Lc_XYZ ( v->Pos.X,v->Pos.Y,v->Pos.Z,THEM) ;
+    if(CTX.mesh.constrained_bgmesh)
+      gPointArray[*numpoints].quality = MIN(find_quality(pt,BGM),qual);
+    else 
+      gPointArray[*numpoints].quality = qual;
     Free(v);
   }
     
diff --git a/Mesh/3D_Mesh.cpp b/Mesh/3D_Mesh.cpp
index 6c9a7d3424e9ecc7b95d9bbbb7765b3f29e57633..6e82ff4e7a57787da67ea772509c6e915e9d392d 100644
--- a/Mesh/3D_Mesh.cpp
+++ b/Mesh/3D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 3D_Mesh.cpp,v 1.16 2001-04-08 20:36:50 geuzaine Exp $
+// $Id: 3D_Mesh.cpp,v 1.17 2001-05-20 19:24:53 geuzaine Exp $
 
 /*
  
@@ -129,8 +129,9 @@ int Pt_In_Volume (double X, double Y, double Z, Mesh * m,
 
   B = LaBrique (&m->Grid, X, Y, Z);
 
-  if (B.N < 0)
+  if (B.N < 0){
     return (0);
+  }
 
   for (i = 0; i < List_Nbr (B.pT); i++){
     List_Read (B.pT, i, &s);
@@ -677,7 +678,7 @@ void add_in_bgm (void *a, void *b){
   List_Add (LLL, S);
 }
 
-void Bgm_With_Points (Mesh * m, Mesh * bgm){
+void Bgm_With_Points (Mesh * bgm){
   int i;
   Simplex *s;
 
@@ -753,7 +754,6 @@ void Maillage_Volume (void *data, void *dum){
     
     Convex_Hull_Mesh (POINTS, LOCAL);
     
-    //if (!Coherence (v, LOCAL)) return;
     while (!Coherence (v, LOCAL));
 
     Link_Simplexes (NULL, LOCAL->Simplexes);
@@ -767,10 +767,8 @@ void Maillage_Volume (void *data, void *dum){
     }
     List_Delete (Suppress);
 
-    /* Suppression des elements dont
-       - le num de vol == 0 (cad qui n'appartiennent a auncun volume defini)
-       - le num de vol == num de vol transfini
-    */
+    /* Suppression des elements dont le num de vol == 0 (cad qui
+       n'appartiennent a auncun volume defini) */
 
     Suppress = List_Create (10, 10, sizeof (Simplex *));
     Tree_Action (v->Simplexes, suppress_simplex);
@@ -787,7 +785,7 @@ void Maillage_Volume (void *data, void *dum){
     
     v->Simplexes = LOCAL->Simplexes;
     
-    Bgm_With_Points (THEM, LOCAL);
+    Bgm_With_Points (LOCAL);
     POINTS_TREE = THEM->Simplexes;
     
     Msg(STATUS2, "Mesh 3D... (final)");
diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp
index 882106f786d9273e9ed7eab516c6554b57ba3f9c..111a97daaffcc9c848e58478f4bebdeaca576f6e 100644
--- a/Mesh/Create.cpp
+++ b/Mesh/Create.cpp
@@ -1,4 +1,4 @@
-// $Id: Create.cpp,v 1.13 2001-05-17 07:11:50 geuzaine Exp $
+// $Id: Create.cpp,v 1.14 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Const.h"
@@ -479,6 +479,7 @@ Curve *Create_Curve (int Num, int Typ, int Order, List_T * Liste,
   }
   else {
     //End_Curve(pC);
+    pC->Control_Points = NULL;
     pC->Extrude = NULL;
     return pC;
   }
diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp
index f911e4688b35d0debb1155cf8fbd4a5cb0df52df..069eda40c0761e3e51f15585569286a4c92a7671 100644
--- a/Mesh/Read_Mesh.cpp
+++ b/Mesh/Read_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Read_Mesh.cpp,v 1.12 2001-04-26 17:58:00 remacle Exp $
+// $Id: Read_Mesh.cpp,v 1.13 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Geo.h"
@@ -43,7 +43,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
   Curve   C , *c , **cc;
   Surface S , *s , **ss;
   Volume  V , *v , **vv;
-
+  
   while (1) {
     do { 
       fgets(String,sizeof(String), File_GEO) ; 
@@ -102,7 +102,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	      c = &C; c->Num = Elementary;
 	      if(!(cc = (Curve**)Tree_PQuery(M->Curves, &c))){
 		c = Create_Curve(Elementary, MSH_SEGM_LINE, 0, NULL,
-				 NULL, 0, 1, 0., 1.);
+				 NULL, -1, -1, 0., 1.);
 		Tree_Add(M->Curves, &c);
 	      }
 	      else
@@ -152,6 +152,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	      simp->iEnt = Elementary ;
 	      Tree_Insert(s->Simplexes, &simp) ;
 	      Tree_Insert(M->Simplexes, &simp) ;
+	      M->Statistics[7]++;
 	      break;
 	    case QUA1:
 	      simp = Create_Quadrangle(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
@@ -159,6 +160,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	      simp->iEnt = Elementary ;
 	      Tree_Insert(s->Simplexes, &simp) ;
 	      Tree_Insert(M->Simplexes, &simp) ;
+	      M->Statistics[8]++;
 	      break;
 	    case TET1:
 	      simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
@@ -166,6 +168,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	      simp->iEnt = Elementary ;
 	      Tree_Insert(v->Simplexes, &simp) ;
 	      Tree_Insert(M->Simplexes, &simp) ;
+	      M->Statistics[9]++;
 	      break;
 	    case HEX1:
 	      hex = Create_Hexahedron(vertsp[0], vertsp[1], vertsp[2], vertsp[3],
@@ -173,6 +176,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	      hex->Num = Num ;
 	      hex->iEnt = Elementary ;
 	      Tree_Insert(v->Hexahedra, &hex) ;
+	      M->Statistics[10]++;
 	      break;
 	    case PRI1:
 	      pri = Create_Prism(vertsp[0], vertsp[1], vertsp[2], 
@@ -180,6 +184,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	      pri->Num = Num ;
 	      pri->iEnt = Elementary ;
 	      Tree_Insert(v->Prisms, &pri) ;
+	      M->Statistics[11]++;
 	      break;
 	    case PNT:
 	      break;
@@ -209,6 +214,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
     M->status = 0 ;
   else
     M->status = -1 ;
+
 }
 
 /* ------------------------------------------------------------------------ */
diff --git a/Mesh/Simplex.cpp b/Mesh/Simplex.cpp
index b5654d71d99c58304e496a4cf84164cf25031aa0..e81969c25d20df850d8393cf29f696b39031fae5 100644
--- a/Mesh/Simplex.cpp
+++ b/Mesh/Simplex.cpp
@@ -1,4 +1,4 @@
-// $Id: Simplex.cpp,v 1.11 2001-04-08 20:36:50 geuzaine Exp $
+// $Id: Simplex.cpp,v 1.12 2001-05-20 19:24:53 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Const.h"
@@ -6,6 +6,9 @@
 #include "Mesh.h"
 #include "Simplex.h"
 #include "Numeric.h"
+#include "Context.h"
+
+extern Context_T   CTX;
 
 int Simplex::TotalAllocated = 0;
 int Simplex::TotalNumber = 0;
@@ -322,17 +325,19 @@ void Simplex::Fourre_Simplexe (Vertex * v1, Vertex * v2, Vertex * v3, Vertex * v
   
   Center_Circum ();
 
-  Quality = (double) N *Radius / (V[0]->lc + V[1]->lc + V[2]->lc
-                                  + ((V[3]) ? V[3]->lc : 0.0));
-
   /*
-     if(LOCAL != NULL){
-     Quality = fabs(Radius) / Lc_XYZ(Center.X, Center.Y, Center.Z, LOCAL);
-     if(Quality < 0.)
-     Quality = N * Radius / (V[0]->lc + V[1]->lc + V[2]->lc
-     +((V[3])? V[3]->lc:0.0));
-     }
-   */
+  extern Mesh *THEM, *LOCAL;
+  if (LOCAL && N == 4 && CTX.mesh.algo == DELAUNAY_OLDALGO && THEM->BGM.Typ == ONFILE){
+    Quality = fabs(Radius) / Lc_XYZ(Center.X, Center.Y, Center.Z, LOCAL);
+    if(Quality < 0.){
+      Msg(WARNING, "Negative simplex quality !?");
+      Quality = 4 * Radius / (V[0]->lc + V[1]->lc + V[2]->lc + V[3]->lc);
+    }
+  }
+  */
+
+  Quality = (double) N * Radius / (V[0]->lc + V[1]->lc + V[2]->lc
+				   + ((V[3]) ? V[3]->lc : 0.0));
 
   for (i = 0; i < N; i++)
     qsort (F[i].V, N - 1, sizeof (Vertex *), compareVertex);
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index f66dc782e8261d00d3a7b373f734f7a4fb12a912..312ac0628210dae6399129baae4605c4c63f7582 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.14 2001-05-01 18:58:24 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.15 2001-05-20 19:24:53 geuzaine Exp $
 #include "Gmsh.h"
 #include "Const.h"
 #include "Context.h"
@@ -131,9 +131,10 @@ void OpenProblem(char *name){
 
   ApplyLcFactor(THEM);
 
-  if(!status) mai3d(THEM,0);  
-
-  Maillage_Dimension_0(&M);
+  if(!status){
+    mai3d(THEM,0);  
+    Maillage_Dimension_0(&M);
+  }
 
 #ifndef _BLACKBOX
   ZeroHighlight(&M); 
diff --git a/doc/VERSIONS b/doc/VERSIONS
index f9978e69fb69e3b8f604df4a961b243c724218a9..803e879b70a91be123e5ffce9aa8a794411a5de6 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,6 +1,8 @@
-$Id: VERSIONS,v 1.16 2001-05-17 07:11:50 geuzaine Exp $
+$Id: VERSIONS,v 1.17 2001-05-20 19:24:53 geuzaine Exp $
 
-New in 1.20: Various bug fixes (Include+Function, ...)
+New in 1.20: Various bug fixes (Includes & Functions, solver
+command...) and small enhancements (menu reorganization, constrained
+background mesh, mesh visibility options, geometry edition, ...)
 
 New in 1.19: Fixed seg. fault for scalar simplex post-processing; new
 Solver menu; interface for GetDP solver through sockets; fixed
diff --git a/tutorial/README b/tutorial/README
index e4739bc6024965071c03292c6d0793444dee4f40..467f88926601e2ffeda5c18adba3a1d494c729f2 100644
--- a/tutorial/README
+++ b/tutorial/README
@@ -1,4 +1,4 @@
-$Id: README,v 1.10 2001-04-25 15:55:51 geuzaine Exp $
+$Id: README,v 1.11 2001-05-20 19:24:53 geuzaine Exp $
 
 Here are the examples in the Gmsh tutorial. These examples are
 commented (both C and C++-style comments can be used in Gmsh input
@@ -26,10 +26,12 @@ required dimension in the context-dependent buttons ('1D' will mesh
 all the curves; '2D' will mesh all the surfaces ---as well as all the
 curves if '1D' was not called before; '3D' will mesh all the volumes
 ---and all the surfaces if '2D' was not called before). To save the
-resulting mesh, select 'File->Save_Mesh' in the menu bar. The default
-mesh file name is based on the name of the first input file on the
-command line (or 'unnamed' if there wasn't any input file given), with
-an appended extension depending on the mesh format.
+resulting mesh in the current mesh format, choose 'Save' in the
+context-dependent buttons, or select the appropriate format with the
+'File->Save as' menu. The default mesh file name is based on the name
+of the first input file on the command line (or 'unnamed' if there
+wasn't any input file given), with an appended extension depending on
+the mesh format.
 
 [NOTE: Nearly all the interactive commands have shortcuts. Select
 'Help->Shortcuts' in the menu bar to learn about these shortcuts.]
@@ -87,15 +89,15 @@ map" and "a vector map". A left mouse click toggles the visibility of
 the selected view. A right mouse click provides access to the view's
 options. If you want the modifications made to one view to affect also
 all the other views, select the 'Link all views' option in the
-'Options->Post-Processing' menu.
+'Options->Post-processing' menu.
 
 [NOTE: All the options specified interactively can also be directly
 specified in the ascii input files. All available options, with their
-current values, can be saved into a file by selecting
-'File->Save_as->GEO complete options', or simply viewed by pressing
-the '?' button in the status bar. To save the current options as the
-default options for all future Gmsh sessions, use the
-'File->Save_Options' menu.]
+current values, can be saved into a file by selecting 'File->Save
+as->GEO complete options', or simply viewed by pressing the '?' button
+in the status bar. To save the current options as your default
+preferences for all future Gmsh sessions, use the 'Options->Save
+options' menu.]
 
 
 OK, that's all, folks. Enjoy the tutorial.
diff --git a/tutorial/t2.geo b/tutorial/t2.geo
index 1cfc91ac22a1a2a4e4d9813812aeaf4a85a07a2c..2284aa9b1a7dfb7c08cb084c367b682f18de7cbc 100644
--- a/tutorial/t2.geo
+++ b/tutorial/t2.geo
@@ -57,7 +57,8 @@ Characteristic Length{6,22,2,3,16,12} = lc * 3 ;
 // If the transformation tools are handy to create complex geometries,
 // it is sometimes useful to generate the flat geometry, consisting
 // only of the explicit list elementary entities. This can be achieved
-// by selecting the 'File->Print->Geo' menu or by typing
+// by selecting the 'File->Save as->GEO flattened geometry' menu or 
+// by typing
 //
 // > gmsh t2.geo -0
 //
diff --git a/tutorial/t3.geo b/tutorial/t3.geo
index 820fbbf3bc32e5cf2da384ae0be409b312c05b5d..4d86a5584acaf000b92d43256370dea3ed53566e 100644
--- a/tutorial/t3.geo
+++ b/tutorial/t3.geo
@@ -60,6 +60,6 @@ Geometry.Color.Surfaces = Geometry.Color.Points;
 
 // A click on the '?'  button in the status bar of the graphic window
 // will dump all current options to the terminal. To save all
-// available options to a file, use the 'File->Save_as->GEO complete
+// available options to a file, use the 'File->Save as->GEO complete
 // options' menu. To save the current options as the default options
-// for all future Gmsh sessions, use the 'File->Save_Options' menu.
+// for all future Gmsh sessions, use the 'Options->Save options' menu.
diff --git a/tutorial/t8.geo b/tutorial/t8.geo
index de481f0e568bcb735be24ae279a88399152b7641..fe7dff2cf382f5ef2c1774b70e3f8faf2c073c39 100644
--- a/tutorial/t8.geo
+++ b/tutorial/t8.geo
@@ -16,7 +16,7 @@ Include "view1.pos" ;
 // Some general options are set (all the options specified
 // interactively can be directly specified in the ascii input
 // files. The current options can be saved into a file by selecting
-// 'File->Save_Options_as')...
+// 'File->Save as->GEO complete options')...
 
 General.Trackball = 0 ;
 General.RotationX = 0 ;
diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html
index 4f0f33614027c499c28092a6d401de62bdfbf2a5..01c19eb4798e110b106394345b8e2934a2374759 100644
--- a/tutorial/tutorial.html
+++ b/tutorial/tutorial.html
@@ -22,7 +22,7 @@
 <H1>README 1/9</H1>
 [<A HREF="#top">top</A>][prev][<A HREF="#file2">next</A>]
 <PRE>
-$Id: tutorial.html,v 1.9 2001-04-25 15:55:51 geuzaine Exp $
+$Id: tutorial.html,v 1.10 2001-05-20 19:24:53 geuzaine Exp $
 
 Here are the examples in the Gmsh tutorial. These examples are
 commented (both C and C++-style comments can be used in Gmsh input
@@ -50,10 +50,12 @@ required dimension in the context-dependent buttons ('1D' will mesh
 all the curves; '2D' will mesh all the surfaces ---as well as all the
 curves if '1D' was not called before; '3D' will mesh all the volumes
 ---and all the surfaces if '2D' was not called before). To save the
-resulting mesh, select 'File-&gt;Save_Mesh' in the menu bar. The default
-mesh file name is based on the name of the first input file on the
-command line (or 'unnamed' if there wasn't any input file given), with
-an appended extension depending on the mesh format.
+resulting mesh in the current mesh format, choose 'Save' in the
+context-dependent buttons, or select the appropriate format with the
+'File-&gt;Save as' menu. The default mesh file name is based on the name
+of the first input file on the command line (or 'unnamed' if there
+wasn't any input file given), with an appended extension depending on
+the mesh format.
 
 [NOTE: Nearly all the interactive commands have shortcuts. Select
 'Help-&gt;Shortcuts' in the menu bar to learn about these shortcuts.]
@@ -111,15 +113,15 @@ map&quot; and &quot;a vector map&quot;. A left mouse click toggles the visibilit
 the selected view. A right mouse click provides access to the view's
 options. If you want the modifications made to one view to affect also
 all the other views, select the 'Link all views' option in the
-'Options-&gt;Post-Processing' menu.
+'Options-&gt;Post-processing' menu.
 
 [NOTE: All the options specified interactively can also be directly
 specified in the ascii input files. All available options, with their
 current values, can be saved into a file by selecting
-'File-&gt;Save_as-&gt;GEO complete options', or simply viewed by pressing
-the '?' button in the status bar. To save the current options as the
-default options for all future Gmsh sessions, use the
-'File-&gt;Save_Options' menu.]
+'File-&gt;Save as-&gt;GEO complete options', or simply viewed by pressing
+the '?' button in the status bar. To save the current options as your
+default preferences for all future Gmsh sessions, use the
+'Options-&gt;Save current options' menu.]
 
 
 OK, that's all, folks. Enjoy the tutorial.
@@ -293,7 +295,8 @@ Characteristic Length{6,22,2,3,16,12} = lc * 3 ;
 <I><FONT COLOR="#B22222">// If the transformation tools are handy to create complex geometries,
 </FONT></I><I><FONT COLOR="#B22222">// it is sometimes useful to generate the flat geometry, consisting
 </FONT></I><I><FONT COLOR="#B22222">// only of the explicit list elementary entities. This can be achieved
-</FONT></I><I><FONT COLOR="#B22222">// by selecting the 'File-&gt;Print-&gt;Geo' menu or by typing
+</FONT></I><I><FONT COLOR="#B22222">// by selecting the 'File-&gt;Save as-&gt;GEO flattened geometry' menu or 
+</FONT></I><I><FONT COLOR="#B22222">// by typing
 </FONT></I><I><FONT COLOR="#B22222">//
 </FONT></I><I><FONT COLOR="#B22222">// &gt; gmsh t2.geo -0
 </FONT></I><I><FONT COLOR="#B22222">//
@@ -387,9 +390,10 @@ Geometry.Color.Surfaces = Geometry.Color.Points;
 </FONT></I>
 <I><FONT COLOR="#B22222">// A click on the '?'  button in the status bar of the graphic window
 </FONT></I><I><FONT COLOR="#B22222">// will dump all current options to the terminal. To save all
-</FONT></I><I><FONT COLOR="#B22222">// available options to a file, use the 'File-&gt;Save_as-&gt;GEO complete
+</FONT></I><I><FONT COLOR="#B22222">// available options to a file, use the 'File-&gt;Save as-&gt;GEO complete
 </FONT></I><I><FONT COLOR="#B22222">// options' menu. To save the current options as the default options
-</FONT></I><I><FONT COLOR="#B22222">// for all future Gmsh sessions, use the 'File-&gt;Save_Options' menu.
+</FONT></I><I><FONT COLOR="#B22222">// for all future Gmsh sessions, use the 'Options-&gt;Save current
+</FONT></I><I><FONT COLOR="#B22222">// options' menu.
 </FONT></I></PRE>
 <HR>
 <A NAME="file5">
@@ -1034,7 +1038,7 @@ Include &quot;view1.pos&quot; ;
 <I><FONT COLOR="#B22222">// Some general options are set (all the options specified
 </FONT></I><I><FONT COLOR="#B22222">// interactively can be directly specified in the ascii input
 </FONT></I><I><FONT COLOR="#B22222">// files. The current options can be saved into a file by selecting
-</FONT></I><I><FONT COLOR="#B22222">// 'File-&gt;Save_Options_as')...
+</FONT></I><I><FONT COLOR="#B22222">// 'File-&gt;Save as-&gt;GEO complete options')...
 </FONT></I>
 General.Trackball = 0 ;
 General.RotationX = 0 ;
@@ -1072,7 +1076,7 @@ For num In {1:255}
 
   t = (View[0].TimeStep &lt; View[0].NbTimeStep-1) ? t+1 : 0 ;
   
-  View[0].RaiseZ += 0.001*t ;
+  View[0].RaiseZ += 0.01*t ;
 
   If (num == 3)
     <I><FONT COLOR="#B22222">// We want to use mpeg_encode to create a nice 320x240 animation