From 0ffbe362ef2c8593bfc48424108a24cce1935c7b Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 20 Feb 2004 17:58:01 +0000
Subject: [PATCH] More "airplane" work...

- rewrote the way we handle lights: glEnable(GL_LIGHTING) is now used
  at the lowest level, where it belongs. This fixes many lighting
  glitches, and should make the whole stuff much more predictable;

- simplified the display modes for geometry and mesh: the choice
  between wireframe/solid is now independent of the choice of
  lighting/no lighting (and there is a new "Enable lighting" option
  for the geometry, too--even if it does only affect things like
  normals/tangents at the moment);

- brand new code to draw really nice (shaded) 3D arrows + 3 options
  that fully parameterize them (they can degenerate into pyramids,
  cones, w/ or w/o stems, etc.);

- new options so that we can also use the new arrows outside the
  post-processing module (e.g. for tangents/normals).

- "alt+d" now simply switches between solid and wireframe mode;

- new shortcut "alt+w" to switch the lighting mode for all the modules
  (geo/mesh + all post views) at once.
---
 Common/CommandLine.cpp        |   4 +-
 Common/Context.h              |   8 +-
 Common/DefaultOptions.h       |  31 ++-
 Common/Options.cpp            | 171 ++++++++++-----
 Common/Options.h              |  12 +-
 Common/Views.cpp              |   5 +-
 Common/Views.h                |   7 +-
 Fltk/Callbacks.cpp            |  54 +++--
 Fltk/GUI.cpp                  |  72 +++++--
 Fltk/GUI.h                    |   1 +
 Fltk/Opengl_Window.cpp        |   3 +-
 Graphics/Draw.cpp             |  22 +-
 Graphics/Draw.h               |  20 +-
 Graphics/Entity.cpp           | 395 ++++++++++++++++------------------
 Graphics/Geom.cpp             | 198 +++++++----------
 Graphics/Mesh.cpp             | 108 +++-------
 Graphics/Post.cpp             |  12 +-
 Graphics/PostElement.cpp      |  46 ++--
 Makefile                      |   6 +-
 TODO                          |   6 +-
 doc/CREDITS                   |  14 +-
 doc/VERSIONS                  |   9 +-
 doc/gmsh.html                 |   2 +-
 doc/texinfo/opt_general.texi  |  22 +-
 doc/texinfo/opt_geometry.texi |  10 +-
 doc/texinfo/opt_mesh.texi     |  15 +-
 doc/texinfo/opt_view.texi     |  19 +-
 doc/texinfo/shortcuts.texi    |  23 +-
 28 files changed, 675 insertions(+), 620 deletions(-)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 320638e3fe..a56f2aa3fb 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -1,4 +1,4 @@
-// $Id: CommandLine.cpp,v 1.28 2004-02-07 01:40:16 geuzaine Exp $
+// $Id: CommandLine.cpp,v 1.29 2004-02-20 17:57:59 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -48,7 +48,7 @@ char *TheBgmFileName = NULL, *TheOptString = NULL;
 // *INDENT-OFF*
 
 char gmsh_progname[]  = "This is Gmsh" ;
-char gmsh_copyright[] = "Copyright (C) 1997-2004 Jean-Francois Remacle and Christophe Geuzaine";
+char gmsh_copyright[] = "Copyright (C) 1997-2004 Christophe Geuzaine and Jean-Francois Remacle";
 char gmsh_version[]   = "Version        : " ;
 char gmsh_license[]   = "License        : " GMSH_SHORT_LICENSE;
 char gmsh_gui[]       = "GUI toolkit    : " ;
diff --git a/Common/Context.h b/Common/Context.h
index 5462898ef2..1815a994ba 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -133,6 +133,10 @@ public :
   int color_scheme ;          // general color scheme
   int quadric_subdivisions;   // nb of subdivisions for gluQuadrics (spheres/cylinders)
   int visibility_mode ;       // VIS_GEOM, VIS_MESH, ...
+  int vector_type;            // default vector display type (for normals, etc.)
+  double arrow_rel_head_radius;  // relative radius of arrow head
+  double arrow_rel_stem_radius;  // relative radius of arrow stem
+  double arrow_rel_stem_length;  // relative length of arrow stem
 
   // geometry options 
   struct{
@@ -141,7 +145,7 @@ public :
     int points_num, lines_num, surfaces_num, volumes_num;
     double point_size, line_width, point_sel_size, line_sel_width;
     int point_type, line_type; // flat or 3D
-    int hidden, shade;
+    int light;
     int highlight;
     int level, old_circle, circle_points, circle_warning;
     int extrude_spline_points, old_newreg;
@@ -164,7 +168,7 @@ public :
     double gamma_inf, gamma_sup, radius_inf, radius_sup;
     double scaling_factor, lc_factor, rand_factor;
     int dual, interactive;
-    int hidden, shade;
+    int solid, light;
     int format, nb_smoothing, algo, order;
     int point_insertion, speed_max, min_circ_points, constrained_bgmesh;
     int histogram, initial_only;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 2572c1562b..48823cfd19 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -363,6 +363,12 @@ StringXString PrintOptions_String[] = {
 StringXNumber GeneralOptions_Number[] = {
   { F|O, "AlphaBlending" , opt_general_alpha_blending , 1. ,
     "Enable alpha blending (transparency) in post-processing views" },
+  { F|O, "ArrowHeadRadius" , opt_general_arrow_head_radius , 0.12 ,
+    "Relative radius of arrow head" },
+  { F|O, "ArrowStemLength" , opt_general_arrow_stem_length , 0.56 ,
+    "Relative length of arrow stem" },
+  { F|O, "ArrowStemRadius" , opt_general_arrow_stem_radius , 0.02 ,
+    "Relative radius of arrow stem" },
   { F|O, "Axes" , opt_general_axes , 1. ,
     "Display the axes linked to the model" },
 
@@ -535,7 +541,7 @@ StringXNumber GeneralOptions_Number[] = {
   { F|O, "PointSize" , opt_general_point_size , 3. , 
     "Display size of points (in pixels)" },
 
-  { F|O, "QuadricSubdivisions" , opt_general_quadric_subdivisions, 10. ,
+  { F|O, "QuadricSubdivisions" , opt_general_quadric_subdivisions, 8. ,
     "Number of subdivisions used to draw points or lines as spheres or cylinders" },
 
   { F,   "RotationX" , opt_general_rotation0 , 0.0 , 
@@ -608,7 +614,8 @@ StringXNumber GeneralOptions_Number[] = {
   { F,   "TranslationZ" , opt_general_translation2 , 0.0 , 
     "Z-axis translation (in model units)" },
 
-
+  { F|O, "VectorType" , opt_general_vector_type , DRAW_POST_ARROW ,
+    "Default vector display type (for normals, etc.)" },
   { F|O, "Verbosity" , opt_general_verbosity , 2. ,
     "Level of information printed during processing (0=no information)" },
   { F|S, "VisibilityMode" , opt_general_visibility_mode , 0. , 
@@ -625,8 +632,6 @@ StringXNumber GeneralOptions_Number[] = {
 } ;
 
 StringXNumber GeometryOptions_Number[] = {
-  { F|O, "Aspect" , opt_geometry_aspect , 0. , 
-    "Not used" },
   { F|O, "AutoCoherence" , opt_geometry_auto_coherence , 1. , 
     "Should all duplicate entities be automatically removed?" }, 
 
@@ -643,6 +648,8 @@ StringXNumber GeometryOptions_Number[] = {
   { F|O, "Highlight" , opt_geometry_highlight , 1. , 
     "Not used" },
 
+  { F|O, "Light" , opt_geometry_light , 0. , 
+    "Enable lighting for the geometry" },
   { F|O, "Lines" , opt_geometry_lines , 1. , 
     "Display geometry curves?" },
   { F|O, "LinesNumbers" , opt_geometry_lines_num , 0. , 
@@ -696,8 +703,6 @@ StringXNumber MeshOptions_Number[] = {
     "2D mesh algorithm (1=isotropic, 2=anisotropic, 3=triangle)" }, 
   { F,   "AllowDegeneratedExtrude" , opt_mesh_allow_degenerated_extrude , 0. , 
     "Allow the generation of degenerated hexahedra or prisms during extrusion" },
-  { F|O, "Aspect" , opt_mesh_aspect , 0. , 
-    "Mesh aspect (0=wireframe, 1=hidden lines, 2=solid)" },
 
   { F|O, "CharacteristicLengthFactor" , opt_mesh_lc_factor , 1.0 ,
     "Factor applied to all characteristic lengths (and background meshes)" },
@@ -741,6 +746,8 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "Interactive" , opt_mesh_interactive , 0. ,
     "Show the construction of the 2D mesh in real time (only with the 2D anisotropic algorithm)" },
 
+  { F|O, "Light" , opt_mesh_light , 0. , 
+    "Enable lighting for the mesh" },
   { F|O, "Lines" , opt_mesh_lines , 1. , 
     "Display mesh vertices on curves?" },
   { F|O, "LinesNumbers" , opt_mesh_lines_num , 0. , 
@@ -799,6 +806,8 @@ StringXNumber MeshOptions_Number[] = {
     "Global scaling factor applied to the saved mesh" },
   { F|O, "Smoothing" , opt_mesh_nb_smoothing , 0. ,
     "Number of smoothing steps applied to the final mesh" },
+  { F|O, "Solid" , opt_mesh_solid , 0. , 
+    "Draw mesh as solid (1) or wireframe (0)?" },
   { F|O, "SpeedMax" , opt_mesh_speed_max , 0. ,
     "Disable dubious point insertion tests" },
   { F|O, "Surfaces" , opt_mesh_surfaces , 1. , 
@@ -889,10 +898,16 @@ StringXNumber ViewOptions_Number[] = {
     "Global alpha channel value (used only if != 1)" },
   { F|O, "AngleSmoothNormals" , opt_view_angle_smooth_normals , 15. ,
     "Threshold angle below which normals are not smoothed" },
+  { F|O, "ArrowHeadRadius" , opt_view_arrow_head_radius , 0.12 ,
+    "Relative radius of arrow head" },
   { F|O, "ArrowLocation" , opt_view_arrow_location , DRAW_POST_LOCATE_COG , 
     "Arrow location (1=cog, 2=vertex)" },
   { F|O, "ArrowSize" , opt_view_arrow_size , 50. ,
     "Size of vectors arrows (in pixels)" },
+  { F|O, "ArrowStemLength" , opt_view_arrow_stem_length , 0.56 ,
+    "Relative length of arrow stem" },
+  { F|O, "ArrowStemRadius" , opt_view_arrow_stem_radius , 0.02 ,
+    "Relative radius of arrow stem" },
   { F|O, "AutoPosition" , opt_view_auto_position , 1. , 
     "Position the scale or the 2D graph automatically to avoid overlaps" }, 
 
@@ -944,7 +959,7 @@ StringXNumber ViewOptions_Number[] = {
     "Type of interval display (1=iso, 2=continuous, 3=discrete, 4=numeric)" },
 
   { F|O, "Light" , opt_view_light , 0. ,
-    "Enable light sources?" },
+    "Enable lighting for the view" },
   { F|O, "LineType" , opt_view_line_type , 0. , 
     "Display lines as solid color segments (0) or 3D cylinders (1)" },
   { F|O, "LineWidth" , opt_view_line_width , 1.0 , 
@@ -1009,7 +1024,7 @@ StringXNumber ViewOptions_Number[] = {
     "Type of graph (1=3D, 2=2D-space, 3=2D-time)" },
 
   { F|O, "VectorType" , opt_view_vector_type , DRAW_POST_ARROW ,
-    "Vector display type (1=segment, 2=arrow, 3=pyramid, 4=cone, 5=displacement)" },
+    "Vector display type (1=segment, 2=arrow, 3=pyramid, 4=3D arrow, 5=displacement)" },
   { F,   "Visible" , opt_view_visible , 1. ,
     "Is the view visible?" },
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 4effea02cd..7d9f69554c 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.134 2004-02-07 01:28:50 geuzaine Exp $
+// $Id: Options.cpp,v 1.135 2004-02-20 17:57:59 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -2214,6 +2214,62 @@ double opt_general_alpha_blending(OPT_ARGS_NUM)
   return CTX.alpha;
 }
 
+double opt_general_vector_type(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.vector_type = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI)){
+    switch (CTX.vector_type) {
+    case DRAW_POST_SEGMENT:
+      WID->gen_choice[0]->value(0);
+      break;
+    case DRAW_POST_ARROW:
+      WID->gen_choice[0]->value(1);
+      break;
+    case DRAW_POST_PYRAMID:
+      WID->gen_choice[0]->value(2);
+      break;
+    case DRAW_POST_ARROW3D:
+    default:
+      WID->gen_choice[0]->value(3);
+      break;
+    }
+  }
+#endif
+  return CTX.vector_type;
+}
+
+double opt_general_arrow_head_radius(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET){
+    if(val < 0.) val = 0.;
+    if(val > 1.) val = 1.;
+    CTX.arrow_rel_head_radius = val;
+  }
+  return CTX.arrow_rel_head_radius;
+}
+
+double opt_general_arrow_stem_length(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET){
+    if(val < 0.) val = 0.;
+    if(val > 1.) val = 1.;
+    CTX.arrow_rel_stem_length = val;
+  }
+  return CTX.arrow_rel_stem_length;
+}
+
+double opt_general_arrow_stem_radius(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET){
+    if(val < 0.) val = 0.;
+    if(val > 1.) val = 1.;
+    CTX.arrow_rel_stem_radius = val;
+  }
+  return CTX.arrow_rel_stem_radius;
+}
+
 double opt_general_color_scheme(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
@@ -2856,29 +2912,16 @@ double opt_geometry_line_type(OPT_ARGS_NUM)
   return CTX.geom.line_type;
 }
 
-double opt_geometry_aspect(OPT_ARGS_NUM)
+double opt_geometry_light(OPT_ARGS_NUM)
 {
-  if(action & GMSH_SET) {
-    switch ((int)val) {
-    case 1:
-      CTX.geom.hidden = 1;
-      CTX.geom.shade = 0;
-      break;
-    case 2:
-      CTX.geom.hidden = 1;
-      CTX.geom.shade = 1;
-      break;
-    default:
-      CTX.geom.hidden = CTX.geom.shade = 0;
-      break;
-    }
+  if(action & GMSH_SET)
+    CTX.geom.light = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI)) {
+    WID->geo_butt[9]->value(CTX.geom.light);
   }
-  if(CTX.geom.hidden && !CTX.geom.shade)
-    return 1;
-  else if(CTX.geom.hidden && CTX.geom.shade)
-    return 2;
-  else
-    return 0;
+#endif
+  return CTX.geom.light;
 }
 
 double opt_geometry_highlight(OPT_ARGS_NUM)
@@ -3236,37 +3279,28 @@ double opt_mesh_line_type(OPT_ARGS_NUM)
   return CTX.mesh.line_type;
 }
 
-double opt_mesh_aspect(OPT_ARGS_NUM)
+double opt_mesh_solid(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    switch ((int)val) {
-    case 1:
-      CTX.mesh.hidden = 1;
-      CTX.mesh.shade = 0;
-      break;
-    case 2:
-      CTX.mesh.hidden = 1;
-      CTX.mesh.shade = 1;
-      break;
-    default:
-      CTX.mesh.hidden = CTX.mesh.shade = 0;
-      break;
-    }
+    CTX.mesh.solid = (int)val;
     CTX.mesh.changed = 1;
   }
 #if defined(HAVE_FLTK)
-  if(WID && (action & GMSH_GUI)) {
-    WID->mesh_butt[14]->value(!CTX.mesh.hidden && !CTX.mesh.shade);
-    WID->mesh_butt[15]->value(CTX.mesh.hidden && !CTX.mesh.shade);
-    WID->mesh_butt[16]->value(CTX.mesh.hidden && CTX.mesh.shade);
-  }
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_butt[14]->value(CTX.mesh.solid);
 #endif
-  if(CTX.mesh.hidden && !CTX.mesh.shade)
-    return 1;
-  else if(CTX.mesh.hidden && CTX.mesh.shade)
-    return 2;
-  else
-    return 0;
+  return CTX.mesh.solid;
+}
+
+double opt_mesh_light(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.mesh.light = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_butt[15]->value(CTX.mesh.light);
+#endif
+  return CTX.mesh.light;
 }
 
 double opt_mesh_format(OPT_ARGS_NUM)
@@ -3903,6 +3937,42 @@ double opt_view_arrow_size(OPT_ARGS_NUM)
   return v->ArrowSize;
 }
 
+double opt_view_arrow_head_radius(OPT_ARGS_NUM)
+{
+  GET_VIEW(0.);
+  if(action & GMSH_SET){
+    if(val < 0.) val = 0.;
+    if(val > 1.) val = 1.;
+    v->ArrowRelHeadRadius = val;
+    v->Changed = 1;
+  }
+  return v->ArrowRelHeadRadius;
+}
+
+double opt_view_arrow_stem_length(OPT_ARGS_NUM)
+{
+  GET_VIEW(0.);
+  if(action & GMSH_SET){
+    if(val < 0.) val = 0.;
+    if(val > 1.) val = 1.;
+    v->ArrowRelStemLength = val;
+    v->Changed = 1;
+  }
+  return v->ArrowRelStemLength;
+}
+
+double opt_view_arrow_stem_radius(OPT_ARGS_NUM)
+{
+  GET_VIEW(0.);
+  if(action & GMSH_SET){
+    if(val < 0.) val = 0.;
+    if(val > 1.) val = 1.;
+    v->ArrowRelStemRadius = val;
+    v->Changed = 1;
+  }
+  return v->ArrowRelStemRadius;
+}
+
 double opt_view_displacement_factor(OPT_ARGS_NUM)
 {
   GET_VIEW(0.);
@@ -4518,12 +4588,13 @@ double opt_view_vector_type(OPT_ARGS_NUM)
     case DRAW_POST_PYRAMID:
       WID->view_choice[2]->value(2);
       break;
-    case DRAW_POST_CONE:
-      WID->view_choice[2]->value(3);
-      break;
     case DRAW_POST_DISPLACEMENT:
       WID->view_choice[2]->value(4);
       break;
+    case DRAW_POST_ARROW3D:
+    default:
+      WID->view_choice[2]->value(3);
+      break;
     }
   }
 #endif
diff --git a/Common/Options.h b/Common/Options.h
index 74bc269015..f5941bd458 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -247,6 +247,10 @@ double opt_general_small_axes_position1(OPT_ARGS_NUM);
 double opt_general_quadric_subdivisions(OPT_ARGS_NUM);
 double opt_general_double_buffer(OPT_ARGS_NUM);
 double opt_general_alpha_blending(OPT_ARGS_NUM);
+double opt_general_vector_type(OPT_ARGS_NUM);
+double opt_general_arrow_head_radius(OPT_ARGS_NUM);
+double opt_general_arrow_stem_length(OPT_ARGS_NUM);
+double opt_general_arrow_stem_radius(OPT_ARGS_NUM);
 double opt_general_trackball(OPT_ARGS_NUM);
 double opt_general_rotation_center_cg(OPT_ARGS_NUM);
 double opt_general_zoom_factor(OPT_ARGS_NUM);
@@ -323,7 +327,7 @@ double opt_geometry_point_type(OPT_ARGS_NUM);
 double opt_geometry_line_width(OPT_ARGS_NUM);
 double opt_geometry_line_sel_width(OPT_ARGS_NUM);
 double opt_geometry_line_type(OPT_ARGS_NUM);
-double opt_geometry_aspect(OPT_ARGS_NUM);
+double opt_geometry_light(OPT_ARGS_NUM);
 double opt_geometry_highlight(OPT_ARGS_NUM);
 double opt_geometry_old_circle(OPT_ARGS_NUM);
 double opt_geometry_old_newreg(OPT_ARGS_NUM);
@@ -355,7 +359,8 @@ double opt_mesh_point_size(OPT_ARGS_NUM);
 double opt_mesh_point_type(OPT_ARGS_NUM);
 double opt_mesh_line_width(OPT_ARGS_NUM);
 double opt_mesh_line_type(OPT_ARGS_NUM);
-double opt_mesh_aspect(OPT_ARGS_NUM);
+double opt_mesh_solid(OPT_ARGS_NUM);
+double opt_mesh_light(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);
@@ -424,6 +429,9 @@ double opt_view_raise0(OPT_ARGS_NUM);
 double opt_view_raise1(OPT_ARGS_NUM);
 double opt_view_raise2(OPT_ARGS_NUM);
 double opt_view_arrow_size(OPT_ARGS_NUM);
+double opt_view_arrow_head_radius(OPT_ARGS_NUM);
+double opt_view_arrow_stem_length(OPT_ARGS_NUM);
+double opt_view_arrow_stem_radius(OPT_ARGS_NUM);
 double opt_view_displacement_factor(OPT_ARGS_NUM);
 double opt_view_explode(OPT_ARGS_NUM);
 double opt_view_visible(OPT_ARGS_NUM);
diff --git a/Common/Views.cpp b/Common/Views.cpp
index 576c3a3914..6f0c49efcd 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.114 2004-02-07 01:40:17 geuzaine Exp $
+// $Id: Views.cpp,v 1.115 2004-02-20 17:57:59 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -620,6 +620,9 @@ void CopyViewOptions(Post_View * src, Post_View * dest)
   dest->Raise[1] = src->Raise[1];
   dest->Raise[2] = src->Raise[2];
   dest->ArrowSize = src->ArrowSize;
+  dest->ArrowRelHeadRadius = src->ArrowRelHeadRadius;
+  dest->ArrowRelStemLength = src->ArrowRelStemLength;
+  dest->ArrowRelStemRadius = src->ArrowRelStemRadius;
   dest->DisplacementFactor = src->DisplacementFactor;
   dest->Explode = src->Explode;
   dest->Visible = src->Visible;
diff --git a/Common/Views.h b/Common/Views.h
index f1d6ea14ac..157cd7561c 100644
--- a/Common/Views.h
+++ b/Common/Views.h
@@ -62,7 +62,8 @@ class Post_View{
   int Type, Position[2], AutoPosition, Size[2];
   char   Format[256], AbscissaFormat[256];
   double CustomMin, CustomMax;
-  double Offset[3], Raise[3], ArrowSize, DisplacementFactor, Explode;
+  double Offset[3], Raise[3], DisplacementFactor, Explode;
+  double ArrowSize, ArrowRelHeadRadius, ArrowRelStemRadius, ArrowRelStemLength;
   int Visible, IntervalsType, NbIso, NbAbscissa, Light, SmoothNormals ;
   double AngleSmoothNormals, AlphaChannel;
   int SaturateValues;
@@ -115,10 +116,8 @@ class Post_View{
 #define DRAW_POST_SEGMENT      1
 #define DRAW_POST_ARROW        2
 #define DRAW_POST_PYRAMID      3
-#define DRAW_POST_CONE         4
+#define DRAW_POST_ARROW3D      4
 #define DRAW_POST_DISPLACEMENT 5
-#define DRAW_POST_ARROW3D      6
-#define DRAW_POST_CONE3D       7
 
 // ArrowLocation
 #define DRAW_POST_LOCATE_COG     1
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 66530cf947..d79dcc529c 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.203 2004-02-07 01:28:50 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.204 2004-02-20 17:57:59 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -984,6 +984,23 @@ void general_options_ok_cb(CALLBACK_ARGS)
   opt_general_options_filename(0, GMSH_SET, (char *)WID->gen_input[3]->value());
   opt_general_editor(0, GMSH_SET, (char *)WID->gen_input[4]->value());
   opt_general_web_browser(0, GMSH_SET, (char *)WID->gen_input[5]->value());
+
+  int val;
+  switch (WID->gen_choice[0]->value()) {
+  case 0:
+    val = DRAW_POST_SEGMENT;
+    break;
+  case 1:
+    val = DRAW_POST_ARROW;
+    break;
+  case 2:
+    val = DRAW_POST_PYRAMID;
+    break;
+  default:
+    val = DRAW_POST_ARROW3D;
+    break;
+  }
+  opt_general_vector_type(0, GMSH_SET, val);
 }
 
 // Geometry options
@@ -1010,6 +1027,7 @@ void geometry_options_ok_cb(CALLBACK_ARGS)
   opt_geometry_surfaces_num(0, GMSH_SET, WID->geo_butt[6]->value());
   opt_geometry_volumes_num(0, GMSH_SET, WID->geo_butt[7]->value());
   opt_geometry_auto_coherence(0, GMSH_SET, WID->geo_butt[8]->value());
+  opt_geometry_light(0, GMSH_SET, WID->geo_butt[9]->value());
 
   opt_geometry_normals(0, GMSH_SET, WID->geo_value[0]->value());
   opt_geometry_tangents(0, GMSH_SET, WID->geo_value[1]->value());
@@ -1051,9 +1069,8 @@ void mesh_options_ok_cb(CALLBACK_ARGS)
   opt_mesh_lines_num(0, GMSH_SET, WID->mesh_butt[11]->value());
   opt_mesh_surfaces_num(0, GMSH_SET, WID->mesh_butt[12]->value());
   opt_mesh_volumes_num(0, GMSH_SET, WID->mesh_butt[13]->value());
-  opt_mesh_aspect(0, GMSH_SET,
-                  WID->mesh_butt[14]->value()? 0 :
-                  WID->mesh_butt[15]->value()? 1 : 2);
+  opt_mesh_solid(0, GMSH_SET, WID->mesh_butt[14]->value());
+  opt_mesh_light(0, GMSH_SET, WID->mesh_butt[15]->value());
   opt_mesh_color_carousel(0, GMSH_SET,
 			  WID->mesh_butt[17]->value()? 0 :
 			  WID->mesh_butt[18]->value()? 1 : 2);
@@ -1469,30 +1486,31 @@ void help_short_cb(CALLBACK_ARGS)
   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+c         alternate between predefined color schemes");
-  Msg(DIRECT, "  Alt+d         alternate between mesh wire frame, hidden lines and shading modes");
+  Msg(DIRECT, "  Alt+c         loop through predefined color schemes");
+  Msg(DIRECT, "  Alt+d         change mesh display mode (solid/wireframe)");
   Msg(DIRECT, "  Shift+d       decrease animation delay");
   Msg(DIRECT, "  "XX"+Shift+d  increase animation delay");
-  Msg(DIRECT, "  Alt+f         toggle redraw mode (fast/full)"); 
+  Msg(DIRECT, "  Alt+f         change redraw mode (fast/full)"); 
   Msg(DIRECT, "  Alt+h         hide/show all post-processing views"); 
   Msg(DIRECT, "  Alt+l         hide/show geometry lines");
   Msg(DIRECT, "  Alt+Shift+l   hide/show mesh lines");
-  Msg(DIRECT, "  Alt+m         toggle visibility of all mesh entities");
-  Msg(DIRECT, "  Alt+o         change projection mode");
+  Msg(DIRECT, "  Alt+m         change visibility of all mesh entities");
+  Msg(DIRECT, "  Alt+o         change projection mode (ortho/perspective)");
   Msg(DIRECT, "  Alt+p         hide/show geometry points");
   Msg(DIRECT, "  Alt+Shift+p   hide/show mesh points");
   Msg(DIRECT, "  Alt+s         hide/show geometry surfaces");
   Msg(DIRECT, "  Alt+Shift+s   hide/show mesh surfaces");
-  Msg(DIRECT, "  Alt+t         alternate intervals mode for visible post-processing views"); 
+  Msg(DIRECT, "  Alt+t         loop through interval modes for all post-processing views"); 
   Msg(DIRECT, "  Alt+v         hide/show geometry volumes");
   Msg(DIRECT, "  Alt+Shift+v   hide/show mesh volumes");
+  Msg(DIRECT, "  Alt+w         enable/disable all lighting");
   Msg(DIRECT, "  Alt+x         set X view"); 
   Msg(DIRECT, "  Alt+y         set Y view"); 
   Msg(DIRECT, "  Alt+z         set Z view"); 
-  Msg(DIRECT, "  Left arrow    previous time step"); 
-  Msg(DIRECT, "  Right arrow   next time step"); 
-  Msg(DIRECT, "  Up arrow      previous view"); 
-  Msg(DIRECT, "  Down arrow    next view"); 
+  Msg(DIRECT, "  Left arrow    go to previous time step"); 
+  Msg(DIRECT, "  Right arrow   go to next time step"); 
+  Msg(DIRECT, "  Up arrow      make previous view visible"); 
+  Msg(DIRECT, "  Down arrow    make next view visible"); 
   Msg(DIRECT, "");
   // *INDENT-ON*
   WID->create_message_window();
@@ -3194,11 +3212,11 @@ void view_options_ok_cb(CALLBACK_ARGS)
         case 2:
           val = DRAW_POST_PYRAMID;
           break;
-        case 3:
-          val = DRAW_POST_CONE;
-          break;
-        default:
+        case 4:
           val = DRAW_POST_DISPLACEMENT;
+	  break;
+	default: // 3
+          val = DRAW_POST_ARROW3D;
           break;
         }
         opt_view_vector_type(i, GMSH_SET, val);
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index a7112c477a..21b7bcc0a5 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.270 2004-02-07 01:39:37 geuzaine Exp $
+// $Id: GUI.cpp,v 1.271 2004-02-20 17:57:59 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -544,8 +544,19 @@ int GUI::global_shortcuts(int event)
     return 1;
   }
   else if(Fl::test_shortcut(FL_ALT + 'd')) {
-    opt_mesh_aspect(0, GMSH_SET | GMSH_GUI,
-                    opt_mesh_aspect(0, GMSH_GET, 0) + 1);
+    opt_mesh_solid(0, GMSH_SET | GMSH_GUI,
+		   !opt_mesh_solid(0, GMSH_GET, 0));
+    redraw_opengl();
+    return 1;
+  }
+  else if(Fl::test_shortcut(FL_ALT + 'w')) {
+    opt_geometry_light(0, GMSH_SET | GMSH_GUI,
+		       !opt_geometry_light(0, GMSH_GET, 0));
+    opt_mesh_light(0, GMSH_SET | GMSH_GUI,
+		   !opt_mesh_light(0, GMSH_GET, 0));
+    for(i = 0; i < List_Nbr(CTX.post.list); i++)
+      opt_view_light(i, GMSH_SET | GMSH_GUI,
+		     !opt_view_light(i, GMSH_GET, 0));
     redraw_opengl();
     return 1;
   }
@@ -1539,6 +1550,19 @@ void GUI::create_option_window()
       for(i = 6; i <= 7; i++) {
         gen_value[i]->align(FL_ALIGN_RIGHT);
       }
+
+      static Fl_Menu_Item menu_genvectype[] = {
+	{"Line", 0, 0, 0},
+	{"Arrow", 0, 0, 0},
+	{"Pyramid", 0, 0, 0},
+	{"3D Arrow", 0, 0, 0},
+	{0}
+      };
+      gen_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 5 * BH, IW, BH, "Vector display");
+      gen_choice[0]->menu(menu_genvectype);
+      gen_choice[0]->align(FL_ALIGN_RIGHT);
+      gen_choice[0]->callback(set_changed_cb, 0);
+
       o->end();
     }
     {
@@ -1639,25 +1663,32 @@ void GUI::create_option_window()
     {
       Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect");
       o->hide();
-      geo_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 1 * BH, IW, BH, "Point display");
+
+      geo_butt[9] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable lighting");
+      geo_butt[9]->type(FL_TOGGLE_BUTTON);
+      geo_butt[9]->down_box(TOGGLE_BOX);
+      geo_butt[9]->selection_color(TOGGLE_COLOR);
+      geo_butt[9]->callback(set_changed_cb, 0);
+
+      geo_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 2 * BH, IW, BH, "Point display");
       geo_choice[0]->menu(menu_point_display);
       geo_choice[0]->align(FL_ALIGN_RIGHT);
 
-      geo_value[3] = new Fl_Value_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Point size");
+      geo_value[3] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Point size");
       geo_value[3]->minimum(0.1);
       geo_value[3]->maximum(50);
       geo_value[3]->step(0.1);
 
-      geo_value[5] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Highlighted point size");
+      geo_value[5] = new Fl_Value_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Highlighted point size");
       geo_value[5]->minimum(0.1);
       geo_value[5]->maximum(50);
       geo_value[5]->step(0.1);
 
-      geo_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 4 * BH, IW, BH, "Line display");
+      geo_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 5 * BH, IW, BH, "Line display");
       geo_choice[1]->menu(menu_line_display);
       geo_choice[1]->align(FL_ALIGN_RIGHT);
 
-      geo_value[4] = new Fl_Value_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
+      geo_value[4] = new Fl_Value_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Line width");
       geo_value[4]->minimum(0.1);
       geo_value[4]->maximum(50);
       geo_value[4]->step(0.1);
@@ -1805,23 +1836,23 @@ void GUI::create_option_window()
     {
       Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect");
       o->hide();
-      mesh_butt[14] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, BW, BH, "Wireframe");
-      mesh_butt[15] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, BW, BH, "Hidden lines");
-      mesh_butt[16] = new Fl_Check_Button(2 * WB, 2 * WB + 3 * BH, BW, BH, "Solid");
-      for(i = 14; i < 17; i++) {
-        mesh_butt[i]->type(FL_RADIO_BUTTON);
-        mesh_butt[i]->down_box(RADIO_BOX);
+      mesh_butt[14] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, BW, BH, "Draw as solid (hidden surfaces)");
+      mesh_butt[15] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, BW, BH, "Enable lighting");
+      for(i = 14; i < 16; i++) {
+        mesh_butt[i]->type(FL_TOGGLE_BUTTON);
+        mesh_butt[i]->down_box(TOGGLE_BOX);
+	mesh_butt[i]->selection_color(TOGGLE_COLOR);
         mesh_butt[i]->selection_color(RADIO_COLOR);
       }
-      mesh_value[9] = new Fl_Value_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Explode elements");
+      mesh_value[9] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Explode elements");
       mesh_value[9]->minimum(0);
       mesh_value[9]->maximum(1);
       mesh_value[9]->step(0.01);
-      mesh_value[10] = new Fl_Value_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Point size");
+      mesh_value[10] = new Fl_Value_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Point size");
       mesh_value[10]->minimum(0.1);
       mesh_value[10]->maximum(50);
       mesh_value[10]->step(0.1);
-      mesh_value[11] = new Fl_Value_Input(2 * WB, 2 * WB + 8 * BH, IW, BH, "Line width");
+      mesh_value[11] = new Fl_Value_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Line width");
       mesh_value[11]->minimum(0.1);
       mesh_value[11]->maximum(50);
       mesh_value[11]->step(0.1);
@@ -1829,13 +1860,14 @@ void GUI::create_option_window()
         mesh_value[i]->align(FL_ALIGN_RIGHT);
       }
 
-      mesh_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 5 * BH, IW, BH, "Point display");
+      mesh_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 4 * BH, IW, BH, "Point display");
       mesh_choice[0]->menu(menu_point_display);
       mesh_choice[0]->align(FL_ALIGN_RIGHT);
 
-      mesh_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 7 * BH, IW, BH, "Line display");
+      mesh_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 6 * BH, IW, BH, "Line display");
       mesh_choice[1]->menu(menu_line_display);
       mesh_choice[1]->align(FL_ALIGN_RIGHT);
+      mesh_choice[1]->deactivate(); // don't give false hopes, as it's not used anywhere right now
 
       o->end();
     }
@@ -2206,7 +2238,7 @@ void GUI::create_option_window()
           {"Line", 0, 0, 0},
           {"Arrow", 0, 0, 0},
           {"Pyramid", 0, 0, 0},
-          {"Cone", 0, 0, 0},
+          {"3D Arrow", 0, 0, 0},
           {"Displacement", 0, 0, 0},
           {0}
         };
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index aa08177219..09ea9f3a9f 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -160,6 +160,7 @@ public:
   Fl_Value_Input   *gen_value[20] ;
   Fl_Button        *gen_col[50] ;
   Fl_Input         *gen_input[20] ;
+  Fl_Choice        *gen_choice[20] ;
 
   // geometry options
   Fl_Window        *geo_window ;
diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp
index 3844994395..2173303e91 100644
--- a/Fltk/Opengl_Window.cpp
+++ b/Fltk/Opengl_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl_Window.cpp,v 1.32 2004-02-07 01:40:17 geuzaine Exp $
+// $Id: Opengl_Window.cpp,v 1.33 2004-02-20 17:57:59 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -82,7 +82,6 @@ void Opengl_Window::draw()
   else {
     glPopMatrix();
     glDisable(GL_DEPTH_TEST);
-    glDisable(GL_LIGHTING);
     glMatrixMode(GL_PROJECTION);
     glPushMatrix();
     glLoadIdentity();
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index a2756b70d0..f94a9ad0db 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.46 2004-02-07 01:40:19 geuzaine Exp $
+// $Id: Draw.cpp,v 1.47 2004-02-20 17:58:00 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -35,8 +35,6 @@ extern Mesh M;
 
 void Draw3d(void)
 {
-  int i;
-
   if(CTX.alpha) {
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glEnable(GL_BLEND);
@@ -48,7 +46,7 @@ void Draw3d(void)
   }
   glPolygonOffset(1.0, 1.0);
 
-  for(i = 0; i < 6; i++)
+  for(int i = 0; i < 6; i++)
     if(CTX.clip[i])
       glEnable((GLenum) (GL_CLIP_PLANE0 + i));
 
@@ -64,13 +62,11 @@ void Draw3d(void)
 
 void Draw2d(void)
 {
-  int i;
-
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_LIGHTING);
   glShadeModel(GL_FLAT);
 
-  for(i = 0; i < 6; i++)
+  for(int i = 0; i < 6; i++)
     glDisable((GLenum) (GL_CLIP_PLANE0 + i));
 
   glMatrixMode(GL_PROJECTION);
@@ -185,18 +181,10 @@ void InitRenderModel(void)
   specular[2] = CTX.shine;
   specular[3] = 1.0;
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
-}
-
-void InitShading()
-{
-  glEnable(GL_LIGHTING);
   glEnable(GL_NORMALIZE);
   glEnable(GL_COLOR_MATERIAL);
-}
-
-
-void InitNoShading(void)
-{
+  // disable lighting by default (we enable it for each particular
+  // case in the drawing routines)
   glDisable(GL_LIGHTING);
 }
 
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 9fdd0e0bdf..df4c4c709a 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -32,9 +32,7 @@
 
 void InitOpengl(void);
 void InitOverlay(void);
-void InitShading(void);
 void InitRenderModel(void);
-void InitNoShading(void);
 void InitPosition(void);
 
 void Orthogonalize(int x, int y);
@@ -73,18 +71,18 @@ void Draw_Text2D3D(int dim, int timestep, int nb, List_T *td, List_T *tc);
 void Draw_Scales(void);
 void Draw_Axes (double s);
 void Draw_SmallAxes(void);
-void Draw_Sphere(double size, double x, double y, double z);
-void Draw_Cylinder (double width, double *x, double *y, double *z);
-void Draw_Point(int type, double size, double *x, double *y, double *z, double Raise[3][8]);
-void Draw_Line (int type, double width, double *x, double *y, double *z, double Raise[3][8]);
+void Draw_Sphere(double size, double x, double y, double z, int light);
+void Draw_Cylinder (double width, double *x, double *y, double *z, int light);
+void Draw_Point(int type, double size, double *x, double *y, double *z, double Raise[3][8], int light);
+void Draw_Line (int type, double width, double *x, double *y, double *z, double Raise[3][8], int light);
 void Draw_Triangle (double *x, double *y, double *z,double *n,
-                    double Raise[3][8], int shade);
+                    double Raise[3][8], int light);
 void Draw_Quadrangle (double *x, double *y, double *z, double *n,
-                      double Raise[3][8], int shade);
+                      double Raise[3][8], int light);
 void Draw_Vector (int Type, int Fill,
-                  double x, double y, double z,
-                  double d, double dx, double dy, double dz,
-                  double Raise[3][8]);
+		  double relHeadRadius, double relStemLength, double relStemRadius,
+                  double x, double y, double z, double dx, double dy, double dz,
+                  double Raise[3][8], int light);
 
 void Draw_Mesh_Volumes(void *a, void *b);
 void Draw_Mesh_Surfaces(void *a, void *b);
diff --git a/Graphics/Entity.cpp b/Graphics/Entity.cpp
index 30b341d241..9ee1a24f5a 100644
--- a/Graphics/Entity.cpp
+++ b/Graphics/Entity.cpp
@@ -1,4 +1,4 @@
-// $Id: Entity.cpp,v 1.29 2004-02-07 01:40:19 geuzaine Exp $
+// $Id: Entity.cpp,v 1.30 2004-02-20 17:58:00 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -29,12 +29,11 @@
 extern Context_T CTX;
 
 void Draw_Point(int type, double size, double *x, double *y, double *z,
-                double Raise[3][8])
+                double Raise[3][8], int light)
 {
-  if(type) {
+  if(type)
     Draw_Sphere(size, x[0] + Raise[0][0], y[0] + Raise[1][0],
-                z[0] + Raise[2][0]);
-  }
+                z[0] + Raise[2][0], light);
   else {
     glBegin(GL_POINTS);
     glVertex3d(x[0] + Raise[0][0], y[0] + Raise[1][0], z[0] + Raise[2][0]);
@@ -42,8 +41,9 @@ void Draw_Point(int type, double size, double *x, double *y, double *z,
   }
 }
 
-void Draw_Sphere(double size, double x, double y, double z)
+void Draw_Sphere(double size, double x, double y, double z, int light)
 {
+  if(light) glEnable(GL_LIGHTING);
   static GLUquadricObj *qua;
   static int first = 1, listnum;
   float s = size * CTX.pixel_equiv_x / CTX.s[0];        // size is in pixels
@@ -60,10 +60,13 @@ void Draw_Sphere(double size, double x, double y, double z)
   glScalef(s, s, s);
   glCallList(listnum);
   glPopMatrix();
+  glDisable(GL_LIGHTING);
 }
 
-void Draw_Cylinder(double width, double *x, double *y, double *z)
+void Draw_Cylinder(double width, double *x, double *y, double *z, int light)
 {
+  if(light) glEnable(GL_LIGHTING);
+
   double mat[4][4], r[3];
   static GLUquadricObj *qua;
   static int first = 1;
@@ -111,10 +114,12 @@ void Draw_Cylinder(double width, double *x, double *y, double *z)
   //glCallList(listnum);
   gluCylinder(qua, 1, 1, 1, CTX.quadric_subdivisions, 1);
   glPopMatrix();
+  
+  glDisable(GL_LIGHTING);
 }
 
 void Draw_Line(int type, double width, double *x, double *y, double *z,
-               double Raise[3][8])
+               double Raise[3][8], int light)
 {
   double X[2], Y[2], Z[2];
 
@@ -127,7 +132,7 @@ void Draw_Line(int type, double width, double *x, double *y, double *z,
   Z[1] = z[1] + Raise[2][1];
 
   if(type)
-    Draw_Cylinder(width, X, Y, Z);
+    Draw_Cylinder(width, X, Y, Z, light);
   else {
     glBegin(GL_LINES);
     glVertex3d(X[0], Y[0], Z[0]);
@@ -137,12 +142,14 @@ void Draw_Line(int type, double width, double *x, double *y, double *z,
 }
 
 void Draw_Triangle(double *x, double *y, double *z, double *n,
-                   double Raise[3][8], int shade)
+                   double Raise[3][8], int light)
 {
   double x1x0, y1y0, z1z0, x2x0, y2y0, z2z0, nn[3];
 
+  if(light) glEnable(GL_LIGHTING);
+
   glBegin(GL_TRIANGLES);
-  if(shade) {
+  if(light) {
     if(!n) {
       x1x0 = (x[1] + Raise[0][1]) - (x[0] + Raise[0][0]);
       y1y0 = (y[1] + Raise[1][1]) - (y[0] + Raise[1][0]);
@@ -162,27 +169,28 @@ void Draw_Triangle(double *x, double *y, double *z, double *n,
 
   glVertex3d(x[0] + Raise[0][0], y[0] + Raise[1][0], z[0] + Raise[2][0]);
 
-  if(shade && n)
+  if(light && n)
     glNormal3dv(&n[3]);
 
   glVertex3d(x[1] + Raise[0][1], y[1] + Raise[1][1], z[1] + Raise[2][1]);
 
-  if(shade && n)
+  if(light && n)
     glNormal3dv(&n[6]);
 
   glVertex3d(x[2] + Raise[0][2], y[2] + Raise[1][2], z[2] + Raise[2][2]);
   glEnd();
 
+  glDisable(GL_LIGHTING);
 }
 
 void Draw_Quadrangle(double *x, double *y, double *z, double *n,
-                     double Raise[3][8], int shade)
+                     double Raise[3][8], int light)
 {
   double x2[3] = { x[2], x[3], x[0] };
   double y2[3] = { y[2], y[3], y[0] };
   double z2[3] = { z[2], z[3], z[0] };
 
-  Draw_Triangle(x, y, z, n, Raise, shade);
+  Draw_Triangle(x, y, z, n, Raise, light);
   if(n) {
     double n2[9];
     n2[0] = n[6];
@@ -194,37 +202,19 @@ void Draw_Quadrangle(double *x, double *y, double *z, double *n,
     n2[6] = n[0];
     n2[7] = n[1];
     n2[8] = n[2];
-    Draw_Triangle(x2, y2, z2, n2, Raise, shade);
+    Draw_Triangle(x2, y2, z2, n2, Raise, light);
   }
   else
-    Draw_Triangle(x2, y2, z2, n, Raise, shade);
-
+    Draw_Triangle(x2, y2, z2, n, Raise, light);
 }
 
-void Draw_Vector(int Type, int Fill,
-                 double x, double y, double z,
-                 double d, double dx, double dy, double dz,
-                 double Raise[3][8])
+void Draw_SimpleVector(int arrow, int fill,
+		       double relHeadRadius, double relStemLength, double relStemRadius,
+		       double x, double y, double z,
+		       double dx, double dy, double dz, 
+		       double d)
 {
   double n[3], t[3], u[3];
-  double l, b, c, f1, f2;
-
-  if(d == 0.0)
-    return;
-
-  if(Raise != NULL) {
-    x += Raise[0][0];
-    y += Raise[1][0];
-    z += Raise[2][0];
-  }
-
-  if(Type == DRAW_POST_SEGMENT) {
-    glBegin(GL_LINES);
-    glVertex3d(x, y, z);
-    glVertex3d(x + dx, y + dy, z + dz);
-    glEnd();
-    return;
-  }
 
   n[0] = dx / d;
   n[1] = dy / d;
@@ -242,7 +232,7 @@ void Draw_Vector(int Type, int Fill,
     t[2] = -n[1];
   }
 
-  l = sqrt(t[0] * t[0] + t[1] * t[1] + t[2] * t[2]);
+  double l = sqrt(t[0] * t[0] + t[1] * t[1] + t[2] * t[2]);
   t[0] /= l;
   t[1] /= l;
   t[2] /= l;
@@ -256,189 +246,37 @@ void Draw_Vector(int Type, int Fill,
   u[1] /= l;
   u[2] /= l;
 
-  switch (Type) {
-
-  case DRAW_POST_PYRAMID:
-
-    b = .1333 * d;
-
-    if(Fill) {
-      glBegin(GL_TRIANGLES);
-      glVertex3d(x + dx, y + dy, z + dz);
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-
-      glVertex3d(x + dx, y + dy, z + dz);
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-
-      glVertex3d(x + dx, y + dy, z + dz);
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
+  double b = relHeadRadius * d;
 
-      glVertex3d(x + dx, y + dy, z + dz);
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glEnd();
-    }
-    else {
-      glBegin(GL_LINE_LOOP);
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glEnd();
+  if(arrow){
+    double f1 = relStemLength;
+    double f2 = (1-2.*relStemRadius) * f1; // hack :-)
 
-      glBegin(GL_LINES);
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-      glEnd();
-    }
-    break;
-
-  case DRAW_POST_CONE:
-
-    b = .1333 * d;
-    c = .7071 * b;
-
-    if(Fill) {
-      glBegin(GL_TRIANGLES);
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + c * (t[0] - u[0]), y + c * (t[1] - u[1]),
-                 z + c * (t[2] - u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (t[0] - u[0]), y + c * (t[1] - u[1]),
-                 z + c * (t[2] - u[2]));
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + c * (-t[0] - u[0]), y + c * (-t[1] - u[1]),
-                 z + c * (-t[2] - u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (-t[0] - u[0]), y + c * (-t[1] - u[1]),
-                 z + c * (-t[2] - u[2]));
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + c * (u[0] - t[0]), y + c * (u[1] - t[1]),
-                 z + c * (u[2] - t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (u[0] - t[0]), y + c * (u[1] - t[1]),
-                 z + c * (u[2] - t[2]));
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glVertex3d(x + c * (t[0] + u[0]), y + c * (t[1] + u[1]),
-                 z + c * (t[2] + u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (t[0] + u[0]), y + c * (t[1] + u[1]),
-                 z + c * (t[2] + u[2]));
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-      glEnd();
-    }
-    else {
-      glBegin(GL_LINE_LOOP);
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + c * (t[0] - u[0]), y + c * (t[1] - u[1]),
-                 z + c * (t[2] - u[2]));
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + c * (-t[0] - u[0]), y + c * (-t[1] - u[1]),
-                 z + c * (-t[2] - u[2]));
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + c * (u[0] - t[0]), y + c * (u[1] - t[1]),
-                 z + c * (u[2] - t[2]));
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glVertex3d(x + c * (t[0] + u[0]), y + c * (t[1] + u[1]),
-                 z + c * (t[2] + u[2]));
-      glEnd();
-
-      glBegin(GL_LINES);
-      glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (t[0] - u[0]), y + c * (t[1] - u[1]),
-                 z + c * (t[2] - u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (-t[0] - u[0]), y + c * (-t[1] - u[1]),
-                 z + c * (-t[2] - u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (u[0] - t[0]), y + c * (u[1] - t[1]),
-                 z + c * (u[2] - t[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-
-      glVertex3d(x + c * (t[0] + u[0]), y + c * (t[1] + u[1]),
-                 z + c * (t[2] + u[2]));
-      glVertex3d(x + dx, y + dy, z + dz);
-      glEnd();
-    }
-    break;
-
-  case DRAW_POST_ARROW:
-  default:
-
-    b = 0.0666 * d;
-
-    f1 = 0.85;
-    f2 = 0.8;
-
-
-    b *= 2;
-    f1 /= 1.5;
-    f2 /= 1.5;
-
-    if(Fill) {
+    if(fill) {
       glBegin(GL_LINES);
       glVertex3d(x, y, z);
       glVertex3d(x + dx, y + dy, z + dz);
       glEnd();
-
+      
       glBegin(GL_TRIANGLES);
       glVertex3d(x + dx, y + dy, z + dz);
       glVertex3d(x + f2 * dx + b * (t[0]), y + f2 * dy + b * (t[1]),
-                 z + f2 * dz + b * (t[2]));
+		 z + f2 * dz + b * (t[2]));
       glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
-
+      
       glVertex3d(x + dx, y + dy, z + dz);
       glVertex3d(x + f2 * dx + b * (-t[0]), y + f2 * dy + b * (-t[1]),
-                 z + f2 * dz + b * (-t[2]));
+		 z + f2 * dz + b * (-t[2]));
       glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
-
+      
       glVertex3d(x + dx, y + dy, z + dz);
       glVertex3d(x + f2 * dx + b * (-u[0]), y + f2 * dy + b * (-u[1]),
-                 z + f2 * dz + b * (-u[2]));
+		 z + f2 * dz + b * (-u[2]));
       glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
-
+      
       glVertex3d(x + dx, y + dy, z + dz);
       glVertex3d(x + f2 * dx + b * (u[0]), y + f2 * dy + b * (u[1]),
-                 z + f2 * dz + b * (u[2]));
+		 z + f2 * dz + b * (u[2]));
       glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
       glEnd();
     }
@@ -447,19 +285,156 @@ void Draw_Vector(int Type, int Fill,
       glVertex3d(x, y, z);
       glVertex3d(x + dx, y + dy, z + dz);
       glVertex3d(x + f2 * dx + b * (t[0]), y + f2 * dy + b * (t[1]),
-                 z + f2 * dz + b * (t[2]));
+		 z + f2 * dz + b * (t[2]));
       glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
       glVertex3d(x + f2 * dx + b * (-t[0]), y + f2 * dy + b * (-t[1]),
-                 z + f2 * dz + b * (-t[2]));
+		 z + f2 * dz + b * (-t[2]));
       glVertex3d(x + dx, y + dy, z + dz);
       glVertex3d(x + f2 * dx + b * (-u[0]), y + f2 * dy + b * (-u[1]),
-                 z + f2 * dz + b * (-u[2]));
+		 z + f2 * dz + b * (-u[2]));
       glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
       glVertex3d(x + f2 * dx + b * (u[0]), y + f2 * dy + b * (u[1]),
-                 z + f2 * dz + b * (u[2]));
+		 z + f2 * dz + b * (u[2]));
       glVertex3d(x + dx, y + dy, z + dz);
       glEnd();
     }
+  }
+  else{ // simple pyramid
+    if(fill){
+      glBegin(GL_TRIANGLES);
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      glVertex3d(x+b*(t[0]),  y+b*(t[1]),  z+b*(t[2]));
+      glVertex3d(x+b*(-u[0]), y+b*(-u[1]), z+b*(-u[2]));
+      
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      glVertex3d(x+b*(-u[0]), y+b*(-u[1]), z+b*(-u[2]));
+      glVertex3d(x+b*(-t[0]), y+b*(-t[1]), z+b*(-t[2]));
+      
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      glVertex3d(x+b*(-t[0]), y+b*(-t[1]), z+b*(-t[2]));
+      glVertex3d(x+b*(u[0]),  y+b*(u[1]),  z+b*(u[2]));
+      
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      glVertex3d(x+b*(u[0]),  y+b*(u[1]),  z+b*(u[2]));
+      glVertex3d(x+b*(t[0]),  y+b*(t[1]),  z+b*(t[2]));
+      glEnd();
+    }
+    else{
+      glBegin(GL_LINE_LOOP);
+      glVertex3d(x+b*(t[0]),  y+b*(t[1]),  z+b*(t[2]));
+      glVertex3d(x+b*(-u[0]), y+b*(-u[1]), z+b*(-u[2]));
+      glVertex3d(x+b*(-t[0]), y+b*(-t[1]), z+b*(-t[2]));
+      glVertex3d(x+b*(u[0]),  y+b*(u[1]),  z+b*(u[2]));
+      glEnd();
+      
+      glBegin(GL_LINES);
+      glVertex3d(x+b*(t[0]),  y+b*(t[1]),  z+b*(t[2]));
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      
+      glVertex3d(x+b*(-u[0]), y+b*(-u[1]), z+b*(-u[2]));
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      
+      glVertex3d(x+b*(-t[0]), y+b*(-t[1]), z+b*(-t[2]));
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      
+      glVertex3d (x+b*(u[0]), y+b*(u[1]),  z+b*(u[2]));
+      glVertex3d(x+dx,        y+dy,        z+dz);
+      glEnd();
+    }
+  }
+}
+
+void Draw_3DArrow(double relHeadRadius, double relStemLength, double relStemRadius,
+		  double x, double y, double z, double dx, double dy, double dz,
+		  double length, int light)
+{
+  if(light) glEnable(GL_LIGHTING);
+
+  int subdiv = CTX.quadric_subdivisions;
+  double head_r = relHeadRadius * length;
+  double head_l = (1. - relStemLength) * length;
+  double stem_r = relStemRadius * length;
+  double stem_l = relStemLength * length;
+
+  static int first = 1;
+  static GLUquadricObj *hat;
+  static GLUquadricObj *disk;
+  static GLUquadricObj *stem;
+  static GLUquadricObj *bottom;
+
+  if(first){
+    first = 0;
+    hat = gluNewQuadric();
+    disk = gluNewQuadric();;
+    stem = gluNewQuadric();;
+    bottom = gluNewQuadric();;
+  }
+
+  glPushMatrix();
+
+  double zdir[3] = {0., 0., 1.};
+  double vdir[3] = {dx/length, dy/length, dz/length};
+  double axis[3], cosphi, phi;
+  prodve(zdir, vdir, axis);
+  norme(axis);
+  prosca(zdir, vdir, &cosphi);
+  phi = 180. * acos(cosphi) / M_PI;
+
+  glTranslatef(x, y, z);
+  glRotatef(phi, axis[0], axis[1], axis[2]);
+  
+  if(head_l && head_r){
+    glTranslatef(0., 0., stem_l);
+    gluCylinder(hat, head_r, 0., head_l, subdiv, 1);
+    gluDisk(disk, stem_r, head_r, subdiv, 1);
+    glTranslatef(0., 0., -stem_l);
+  }
+
+  if(stem_l && stem_r){
+    gluCylinder(stem, stem_r, stem_r, stem_l, subdiv, 1);
+    gluDisk(disk, 0, stem_r, subdiv, 1);
+  }
+
+  glPopMatrix();
+
+  glDisable(GL_LIGHTING);
+}
+
+void Draw_Vector(int Type, int Fill,
+		 double relHeadRadius, double relStemLength, double relStemRadius,
+                 double x, double y, double z, double dx, double dy, double dz,
+                 double Raise[3][8], int light)
+{
+  double length = sqrt(dx * dx + dy * dy + dz * dz);
+
+  if(length == 0.0)
+    return;
+
+  if(Raise != NULL) {
+    x += Raise[0][0];
+    y += Raise[1][0];
+    z += Raise[2][0];
+  }
+
+  switch(Type){
+  case DRAW_POST_SEGMENT:
+    glBegin(GL_LINES);
+    glVertex3d(x, y, z);
+    glVertex3d(x + dx, y + dy, z + dz);
+    glEnd();
+    break;
+  case DRAW_POST_ARROW:
+    Draw_SimpleVector(1, Fill, relHeadRadius, relStemLength, relStemRadius,
+		      x, y, z, dx, dy, dz, length);
+    break;
+  case DRAW_POST_PYRAMID:
+    Draw_SimpleVector(0, Fill, relHeadRadius, relStemLength, relStemRadius,
+		      x, y, z, dx, dy, dz, length);
+    break;
+  case DRAW_POST_ARROW3D:
+  default:
+    Draw_3DArrow(relHeadRadius, relStemLength, relStemRadius,
+		 x, y, z, dx, dy, dz, length, light);
     break;
   }
 
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index b93c06bc2e..6a153e15f0 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.48 2004-02-07 01:40:19 geuzaine Exp $
+// $Id: Geom.cpp,v 1.49 2004-02-20 17:58:00 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -71,12 +71,13 @@ void Draw_GeoPoint(void *a, void *b)
   }
 
   if(CTX.geom.points) {
-
     if(CTX.geom.point_type) {
       if(v->Frozen || Highlighted)
-        Draw_Sphere(CTX.geom.point_sel_size, v->Pos.X, v->Pos.Y, v->Pos.Z);
+        Draw_Sphere(CTX.geom.point_sel_size, v->Pos.X, v->Pos.Y, v->Pos.Z, 
+		    CTX.geom.light);
       else
-        Draw_Sphere(CTX.geom.point_size, v->Pos.X, v->Pos.Y, v->Pos.Z);
+        Draw_Sphere(CTX.geom.point_size, v->Pos.X, v->Pos.Y, v->Pos.Z,
+		    CTX.geom.light);
     }
     else {
       glBegin(GL_POINTS);
@@ -96,7 +97,6 @@ void Draw_GeoPoint(void *a, void *b)
   if(CTX.render_mode == GMSH_SELECT) {
     glPopName();
   }
-
 }
 
 // Curves
@@ -104,7 +104,7 @@ void Draw_GeoPoint(void *a, void *b)
 void Draw_Curve(void *a, void *b)
 {
   int i, N;
-  double mod, dd, x[2], y[2], z[2];
+  double mod, x[2], y[2], z[2];
   char Num[100];
   Curve *c;
   Vertex v, dv;
@@ -136,7 +136,6 @@ void Draw_Curve(void *a, void *b)
   }
 
   if(CTX.geom.lines) {
-
     int n = List_Nbr(c->Control_Points);
     switch (c->Typ) {
     case MSH_SEGM_LINE:
@@ -175,7 +174,7 @@ void Draw_Curve(void *a, void *b)
           x[1] = dv.Pos.X;
           y[1] = dv.Pos.Y;
           z[1] = dv.Pos.Z;
-          Draw_Cylinder(CTX.geom.line_width, x, y, z);
+          Draw_Cylinder(CTX.geom.line_width, x, y, z, CTX.geom.light);
         }
       }
       else {
@@ -201,25 +200,20 @@ void Draw_Curve(void *a, void *b)
   if(CTX.geom.tangents) {
     v = InterpolateCurve(c, 0.5, 0);
     dv = InterpolateCurve(c, 0.5, 1);
-    mod =
-      sqrt(dv.Pos.X * dv.Pos.X + dv.Pos.Y * dv.Pos.Y + dv.Pos.Z * dv.Pos.Z);
-    dv.Pos.X =
-      dv.Pos.X / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[0];
-    dv.Pos.Y =
-      dv.Pos.Y / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[1];
-    dv.Pos.Z =
-      dv.Pos.Z / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[2];
-    dd =
-      sqrt(dv.Pos.X * dv.Pos.X + dv.Pos.Y * dv.Pos.Y + dv.Pos.Z * dv.Pos.Z);
+    mod = sqrt(dv.Pos.X * dv.Pos.X + dv.Pos.Y * dv.Pos.Y + dv.Pos.Z * dv.Pos.Z);
+    dv.Pos.X = dv.Pos.X / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[0];
+    dv.Pos.Y = dv.Pos.Y / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[1];
+    dv.Pos.Z = dv.Pos.Z / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[2];
     glColor4ubv((GLubyte *) & CTX.color.geom.tangents);
-    Draw_Vector(DRAW_POST_ARROW, 0, v.Pos.X, v.Pos.Y, v.Pos.Z,
-                dd, dv.Pos.X, dv.Pos.Y, dv.Pos.Z, NULL);
+    Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
+		v.Pos.X, v.Pos.Y, v.Pos.Z,
+                dv.Pos.X, dv.Pos.Y, dv.Pos.Z, NULL, CTX.geom.light);
   }
 
   if(CTX.render_mode == GMSH_SELECT) {
     glPopName();
   }
-
 }
 
 // Surfaces
@@ -276,43 +270,37 @@ int isPointOnPlanarSurface(Surface * S, double X, double Y, double Z,
   if(fabs(Angle) > 6.0 && fabs(Angle) < 7.0)    // Should be 2 * Pi or 0
     return 1;
   return 0;
-
 }
 
 void Draw_Triangulated_Surface(Surface * s)
 {
-  int k=0;
-  double *points;
-  double *p1,*p2,*p3;
-
-  if(!CTX.moving_light)
-    InitRenderModel();
-  InitShading();
-  glEnable(GL_POLYGON_OFFSET_FILL);
+  int k = 0;
+  double *points, *p1, *p2, *p3;
 
   if(CTX.geom.surfaces) {
+    glEnable(GL_POLYGON_OFFSET_FILL);
+    if(CTX.geom.light) glEnable(GL_LIGHTING);
     glBegin(GL_TRIANGLES);
-    while (k < List_Nbr(s->thePolyRep->polygons))
-      {
-	points = (double*)List_Pointer (s->thePolyRep->polygons,k);
-	k+= ((int)points[0] + 1);
-
-	if (points[0] == 3)
-	  {
-	    p1 = (double*)List_Pointer (s->thePolyRep->points_and_normals,6*(int)points[1]);
-	    p2 = (double*)List_Pointer (s->thePolyRep->points_and_normals,6*(int)points[2]);
-	    p3 = (double*)List_Pointer (s->thePolyRep->points_and_normals,6*(int)points[3]);	    
-	    glNormal3dv(&p1[3]);
-	    glVertex3d(p1[0],p1[1],p1[2]);
-	    glNormal3dv(&p2[3]);
-	    glVertex3d(p2[0],p2[1],p2[2]);
-	    glNormal3dv(&p3[3]);
-	    glVertex3d(p3[0],p3[1],p3[2]);
-	  }
+    while (k < List_Nbr(s->thePolyRep->polygons)){
+      points = (double*)List_Pointer (s->thePolyRep->polygons,k);
+      k+= ((int)points[0] + 1);
+      
+      if (points[0] == 3){
+	p1 = (double*)List_Pointer (s->thePolyRep->points_and_normals,6*(int)points[1]);
+	p2 = (double*)List_Pointer (s->thePolyRep->points_and_normals,6*(int)points[2]);
+	p3 = (double*)List_Pointer (s->thePolyRep->points_and_normals,6*(int)points[3]);
+	glNormal3dv(&p1[3]);
+	glVertex3d(p1[0],p1[1],p1[2]);
+	glNormal3dv(&p2[3]);
+	glVertex3d(p2[0],p2[1],p2[2]);
+	glNormal3dv(&p3[3]);
+	glVertex3d(p3[0],p3[1],p3[2]);
       }
+    }
     glEnd();
+    glDisable(GL_POLYGON_OFFSET_FILL); 
+    glDisable(GL_LIGHTING);
   }  
-  glDisable(GL_POLYGON_OFFSET_FILL); 
 }
 
 
@@ -320,15 +308,14 @@ void Draw_Plane_Surface(Surface * s)
 {
   int i, j, k;
   Curve *c;
-  double minx = 0., miny = 0., maxx = 0., maxy = 0., t, n[3], nn;
+  double minx = 0., miny = 0., maxx = 0., maxy = 0., t, n[3];
   Vertex P1, P2, P3, V[4], vv, vv1, vv2;
   char Num[100];
 
-  if (s->thePolyRep)
-    {
-      Draw_Triangulated_Surface(s);
-      return;
-    }
+  if (s->thePolyRep) {
+    Draw_Triangulated_Surface(s);
+    return;
+  }
 
   static List_T *points;
   static int deb = 1;
@@ -486,24 +473,22 @@ void Draw_Plane_Surface(Surface * s)
       n[0] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[0];
       n[1] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[1];
       n[2] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[2];
-      nn = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
       glColor4ubv((GLubyte *) & CTX.color.geom.normals);
-      Draw_Vector(DRAW_POST_ARROW, 0, (vv2.Pos.X + vv1.Pos.X) / 2.,
-                  (vv2.Pos.Y + vv1.Pos.Y) / 2., (vv2.Pos.Z + vv1.Pos.Z) / 2.,
-                  nn, n[0], n[1], n[2], NULL);
+      Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		  CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius, 
+		  (vv2.Pos.X + vv1.Pos.X) / 2., (vv2.Pos.Y + vv1.Pos.Y) / 2., 
+		  (vv2.Pos.Z + vv1.Pos.Z) / 2., n[0], n[1], n[2], NULL, 
+		  CTX.geom.light);
     }
 
   }
-
 }
 
-
-
 void Draw_NonPlane_Surface(Surface * s)
 {
   Vertex v, n1, n2, n3;
   int i, NbTics, N = 0;
-  double u, n[3], nn, nx[3], ny[3];
+  double u, n[3], nx[3], ny[3];
   double tics[20];
   double u0, un, v0, vn;
   int kk;
@@ -520,19 +505,19 @@ void Draw_NonPlane_Surface(Surface * s)
     vn = s->kv[s->OrderV + s->Nv];
     for(i = 0; i < NbTics; i++)
       tics[i] = v0 + ((double)(i + 1) / (double)NbTics) * (vn - v0);
-    if(CTX.geom.shade) {
-      GLUnurbsObj *nurb;
-      nurb = gluNewNurbsRenderer();
-      gluNurbsProperty(nurb, (GLenum) GLU_SAMPLING_TOLERANCE, 50.0);
-      gluNurbsProperty(nurb, (GLenum) GLU_DISPLAY_MODE, GLU_FILL);
-      gluBeginSurface(nurb);
-      gluNurbsSurface(nurb, s->Nu + s->OrderU + 1, s->ku,
-                      s->Nv + s->OrderV + 1, s->kv, 4, 4 * s->Nu, s->cp,
-                      s->OrderU + 1, s->OrderV + 1, GL_MAP2_VERTEX_4);
-      gluEndSurface(nurb);
-      gluDeleteNurbsRenderer(nurb);
-      return;
-    }
+    if(CTX.geom.light) glEnable(GL_LIGHTING);
+    GLUnurbsObj *nurb;
+    nurb = gluNewNurbsRenderer();
+    gluNurbsProperty(nurb, (GLenum) GLU_SAMPLING_TOLERANCE, 50.0);
+    gluNurbsProperty(nurb, (GLenum) GLU_DISPLAY_MODE, GLU_FILL);
+    gluBeginSurface(nurb);
+    gluNurbsSurface(nurb, s->Nu + s->OrderU + 1, s->ku,
+		    s->Nv + s->OrderV + 1, s->kv, 4, 4 * s->Nu, s->cp,
+		    s->OrderU + 1, s->OrderV + 1, GL_MAP2_VERTEX_4);
+    gluEndSurface(nurb);
+    gluDeleteNurbsRenderer(nurb);
+    glDisable(GL_LIGHTING);
+    return;
   }
   else {
     NbTics = 1;
@@ -595,12 +580,12 @@ void Draw_NonPlane_Surface(Surface * s)
     n[0] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[0];
     n[1] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[1];
     n[2] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[2];
-    nn = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
     glColor4ubv((GLubyte *) & CTX.color.geom.normals);
-    Draw_Vector(DRAW_POST_ARROW, 0, n1.Pos.X, n1.Pos.Y, n1.Pos.Z,
-                nn, n[0], n[1], n[2], NULL);
+    Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
+		n1.Pos.X, n1.Pos.Y, n1.Pos.Z, n[0], n[1], n[2], NULL,
+		CTX.geom.light);
   }
-
 }
 
 void Draw_Surface(void *a, void *b)
@@ -617,30 +602,25 @@ void Draw_Surface(void *a, void *b)
     glPushName(s->Num);
   }
 
-  if(!CTX.geom.shade) {
-    if(s->ipar[4]) {
-      glLineWidth(CTX.geom.line_sel_width);
-      gl2psLineWidth(CTX.geom.line_sel_width *
-                     CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.surface_sel);
-    }
-    else if(Highlighted) {
-      glLineWidth(CTX.geom.line_sel_width);
-      gl2psLineWidth(CTX.geom.line_sel_width *
-                     CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.surface_hlt);
-    }
-    else {
-      glLineWidth(CTX.geom.line_width);
-      gl2psLineWidth(CTX.geom.line_width * CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.surface);
-    }
-    glEnable(GL_LINE_STIPPLE);
-    glLineStipple(1, 0x0F0F);
+  if(s->ipar[4]) {
+    glLineWidth(CTX.geom.line_sel_width);
+    gl2psLineWidth(CTX.geom.line_sel_width *
+		   CTX.print.eps_line_width_factor);
+    glColor4ubv((GLubyte *) & CTX.color.geom.surface_sel);
+  }
+  else if(Highlighted) {
+    glLineWidth(CTX.geom.line_sel_width);
+    gl2psLineWidth(CTX.geom.line_sel_width *
+		   CTX.print.eps_line_width_factor);
+    glColor4ubv((GLubyte *) & CTX.color.geom.surface_hlt);
   }
   else {
-    ColorSwitch(abs(s->Num));
+    glLineWidth(CTX.geom.line_width);
+    gl2psLineWidth(CTX.geom.line_width * CTX.print.eps_line_width_factor);
+    glColor4ubv((GLubyte *) & CTX.color.geom.surface);
   }
+  glEnable(GL_LINE_STIPPLE);
+  glLineStipple(1, 0x0F0F);
 
   if(s->Typ == MSH_SURF_STL) {
     glDisable(GL_LINE_STIPPLE);
@@ -660,7 +640,6 @@ void Draw_Surface(void *a, void *b)
   }
 
   glDisable(GL_LINE_STIPPLE);
-
 }
 
 // Volumes
@@ -706,13 +685,11 @@ void Draw_Curve_For_Volume(void *a, void *b)
   if(CTX.render_mode == GMSH_SELECT) {
     glPopName();
   }
-
 }
 
 
 void DrawVolumes(Mesh * m)
 {
-
 }
 
 // Draw geometry
@@ -722,25 +699,14 @@ void Draw_Geom(Mesh * m)
   if(m->status == -1)
     return;
 
-  if(CTX.geom.points || CTX.geom.points_num) {
-    if(CTX.geom.point_type)
-      InitShading();
+  if(CTX.geom.points || CTX.geom.points_num)
     Tree_Action(m->Points, Draw_GeoPoint);
-    if(CTX.geom.point_type && !CTX.geom.shade)
-      InitNoShading();
-  }
-  if(CTX.geom.lines || CTX.geom.lines_num) {
-    if(CTX.geom.line_type)
-      InitShading();
+  if(CTX.geom.lines || CTX.geom.lines_num)
     Tree_Action(m->Curves, Draw_Curve);
-    if(CTX.geom.line_type && !CTX.geom.shade)
-      InitNoShading();
-  }
   if(CTX.geom.surfaces || CTX.geom.surfaces_num)
     Tree_Action(m->Surfaces, Draw_Surface);
   if(CTX.geom.volumes || CTX.geom.volumes_num)
     DrawVolumes(m);
-
 }
 
 void ZeroCurve(void *a, void *b)
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 6bfaa73e38..45d4ccf265 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.64 2004-02-07 01:40:19 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.65 2004-02-20 17:58:00 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -56,7 +56,6 @@ void draw_polygon_2d(double r, double g, double b, int n,
   glFlush();
   glDrawBuffer(GL_BACK);
   glEnable(GL_DEPTH_TEST);
-
 }
 
 static DrawingColor theColor;
@@ -73,10 +72,6 @@ void Draw_Mesh(Mesh * M)
   if(!CTX.moving_light)
     InitRenderModel();
 
-  if(CTX.mesh.shade)
-    InitShading();
-  else
-    InitNoShading();
   InitPosition();
 
   if(CTX.moving_light)
@@ -92,7 +87,7 @@ void Draw_Mesh(Mesh * M)
   glLineWidth(CTX.mesh.line_width);
   gl2psLineWidth(CTX.mesh.line_width * CTX.print.eps_line_width_factor);
 
-  if(CTX.mesh.hidden)
+  if(CTX.mesh.solid)
     glEnable(GL_POLYGON_OFFSET_FILL);
 
   // draw the bbox of the mesh in fast redraw mode if there is no geometry
@@ -174,19 +169,16 @@ void Draw_Mesh(Mesh * M)
 
   }
 
-  if(M->status >= 0) {
-    if(!CTX.geom.shade)
-      InitNoShading();
+  if(M->status >= 0)
     Draw_Geom(M);
-  }
 
-  if(CTX.mesh.hidden)
+  if(CTX.mesh.solid)
     glDisable(GL_POLYGON_OFFSET_FILL);
 
   if(CTX.render_mode != GMSH_SELECT) {
     if(CTX.axes)
       Draw_Axes(CTX.lc_middle / 4.);
-    Draw_Post();        // les init de shading se font par view
+    Draw_Post();
   }
 }
 
@@ -275,7 +267,8 @@ void Draw_Mesh_Points(void *a, void *b)
 
   if(CTX.mesh.points) {
     if(CTX.mesh.point_type) {
-      Draw_Sphere(CTX.mesh.point_size, v->Pos.X, v->Pos.Y, v->Pos.Z);
+      Draw_Sphere(CTX.mesh.point_size, v->Pos.X, v->Pos.Y, v->Pos.Z,
+		  CTX.mesh.light);
     }
     else {
       glBegin(GL_POINTS);
@@ -362,10 +355,7 @@ void Draw_Simplex_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (s->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.shade)
-    glDisable(GL_LIGHTING);
-
-  if(CTX.mesh.volumes && !(fulldraw && CTX.mesh.shade)) {
+  if(CTX.mesh.volumes) {
     glBegin(GL_LINES);
     glVertex3d(X[1], Y[1], Z[1]);
     glVertex3d(X[0], Y[0], Z[0]);
@@ -396,7 +386,6 @@ void Draw_Simplex_Volume(void *a, void *b)
     Draw_String(Num);
   }
 
-
   if(CTX.mesh.dual) {
     glColor4ubv((GLubyte *) & CTX.color.fg);
     glEnable(GL_LINE_STIPPLE);
@@ -420,9 +409,6 @@ void Draw_Simplex_Volume(void *a, void *b)
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
 
-  if(CTX.mesh.shade)
-    glEnable(GL_LIGHTING);
-
   if(!fulldraw)
     return;
 
@@ -433,9 +419,11 @@ void Draw_Simplex_Volume(void *a, void *b)
   else
     glColor4ubv((GLubyte *) & CTX.color.mesh.tetrahedron);
 
-  if(CTX.mesh.hidden) {
+  if(CTX.mesh.solid) {
+
+    if(CTX.mesh.light) glEnable(GL_LIGHTING);
 
-    if(CTX.mesh.shade) {
+    if(CTX.mesh.light) {
       x1x0 = X[2] - X[0];
       y1y0 = Y[2] - Y[0];
       z1z0 = Z[2] - Z[0];
@@ -454,7 +442,7 @@ void Draw_Simplex_Volume(void *a, void *b)
     glVertex3d(X[1], Y[1], Z[1]);
     glEnd();
 
-    if(CTX.mesh.shade) {
+    if(CTX.mesh.light) {
       x1x0 = X[1] - X[0];
       y1y0 = Y[1] - Y[0];
       z1z0 = Z[1] - Z[0];
@@ -473,7 +461,7 @@ void Draw_Simplex_Volume(void *a, void *b)
     glVertex3d(X[3], Y[3], Z[3]);
     glEnd();
 
-    if(CTX.mesh.shade) {
+    if(CTX.mesh.light) {
       x1x0 = X[3] - X[0];
       y1y0 = Y[3] - Y[0];
       z1z0 = Z[3] - Z[0];
@@ -492,7 +480,7 @@ void Draw_Simplex_Volume(void *a, void *b)
     glVertex3d(X[2], Y[2], Z[2]);
     glEnd();
 
-    if(CTX.mesh.shade) {
+    if(CTX.mesh.light) {
       x1x0 = X[3] - X[1];
       y1y0 = Y[3] - Y[1];
       z1z0 = Z[3] - Z[1];
@@ -511,8 +499,8 @@ void Draw_Simplex_Volume(void *a, void *b)
     glVertex3d(X[2], Y[2], Z[2]);
     glEnd();
 
+    glDisable(GL_LIGHTING);
   }
-
 }
 
 void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
@@ -524,7 +512,7 @@ void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
   L = (s->VSUP) ? 1 : 0;
   K = (s->V[3]) ? 4 : 3;
 
-  if(CTX.mesh.normals || CTX.mesh.shade) {
+  if(CTX.mesh.normals || CTX.mesh.light) {
     x1x0 = s->V[1]->Pos.X - s->V[0]->Pos.X;
     y1y0 = s->V[1]->Pos.Y - s->V[0]->Pos.Y;
     z1z0 = s->V[1]->Pos.Z - s->V[0]->Pos.Z;
@@ -534,14 +522,12 @@ void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
     n[0] = y1y0 * z2z0 - z1z0 * y2y0;
     n[1] = z1z0 * x2x0 - x1x0 * z2z0;
     n[2] = x1x0 * y2y0 - y1y0 * x2x0;
-  }
-
-  if(CTX.mesh.hidden && CTX.mesh.shade)
     glNormal3dv(n);
+  }
 
   if(CTX.mesh.surfaces && CTX.mesh.lines) {
 
-    if(CTX.mesh.color_carousel && !(CTX.mesh.hidden || CTX.mesh.shade)) {
+    if(CTX.mesh.color_carousel && !CTX.mesh.solid) {
       if(theColor.type)
         glColor4ubv((GLubyte *) & theColor.mesh);
       else
@@ -551,9 +537,6 @@ void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
       glColor4ubv((GLubyte *) & CTX.color.mesh.line);
     }
 
-    if(CTX.mesh.shade)
-      glDisable(GL_LIGHTING);
-
     if(pX && pY && pZ) {        // using precomputed vertices
       glBegin(GL_LINE_LOOP);
       for(i = 0; i < K * (1 + L); i++) {
@@ -579,9 +562,6 @@ void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
       }
     }
 
-    if(CTX.mesh.shade)
-      glEnable(GL_LIGHTING);
-
   }
 
   if(CTX.mesh.color_carousel) {
@@ -597,7 +577,9 @@ void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
       glColor4ubv((GLubyte *) & CTX.color.mesh.quadrangle);
   }
 
-  if(CTX.mesh.surfaces && CTX.mesh.hidden) {
+  if(CTX.mesh.surfaces && CTX.mesh.solid) {
+
+    if(CTX.mesh.light) glEnable(GL_LIGHTING);
 
     if(pX && pY && pZ) {        // using precomputed vertices
       if(L) {
@@ -648,8 +630,8 @@ void Draw_Simplex_Surface_Common(Simplex * s, double *pX, double *pY,
       }
     }
 
+    glDisable(GL_LIGHTING);
   }
-
 }
 
 void Draw_Simplex_Surface_Simple(void *a, void *b)
@@ -673,7 +655,7 @@ void Draw_Simplex_Surface(void *a, void *b)
 {
   Simplex *s;
   double Xc, Yc, Zc, pX[8], pY[8], pZ[8];
-  double n[3], nn;
+  double n[3];
   int i, j, K, L, k;
   char Num[256];
 
@@ -757,18 +739,17 @@ void Draw_Simplex_Surface(void *a, void *b)
     n[0] *= CTX.mesh.normals * CTX.pixel_equiv_x / CTX.s[0];
     n[1] *= CTX.mesh.normals * CTX.pixel_equiv_x / CTX.s[1];
     n[2] *= CTX.mesh.normals * CTX.pixel_equiv_x / CTX.s[2];
-    nn = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
-    Draw_Vector(DRAW_POST_ARROW, 0, Xc, Yc, Zc, nn, n[0], n[1], n[2], NULL);
+    Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
+		Xc, Yc, Zc, n[0], n[1], n[2], NULL, CTX.mesh.light);
   }
-
-
 }
 
 
 void Draw_Simplex_Curves(void *a, void *b)
 {
   Simplex *s;
-  double Xc = 0.0, Yc = 0.0, Zc = 0.0, m[3], mm;
+  double Xc = 0.0, Yc = 0.0, Zc = 0.0, m[3];
   char Num[100];
 
   s = *(Simplex **) a;
@@ -811,9 +792,6 @@ void Draw_Simplex_Curves(void *a, void *b)
   else
     glColor4ubv((GLubyte *) & CTX.color.mesh.line);
 
-  if(CTX.mesh.shade)
-    glDisable(GL_LIGHTING);
-
   if(CTX.mesh.lines) {
     glBegin(GL_LINE_STRIP);
     for(int i = 0; i < N; i++){
@@ -839,13 +817,10 @@ void Draw_Simplex_Curves(void *a, void *b)
     m[0] *= CTX.mesh.tangents * CTX.pixel_equiv_x / CTX.s[0];
     m[1] *= CTX.mesh.tangents * CTX.pixel_equiv_x / CTX.s[1];
     m[2] *= CTX.mesh.tangents * CTX.pixel_equiv_x / CTX.s[2];
-    mm = sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
-    Draw_Vector(DRAW_POST_ARROW, 0, Xc, Yc, Zc, mm, m[0], m[1], m[2], NULL);
+    Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
+		Xc, Yc, Zc, m[0], m[1], m[2], NULL, CTX.mesh.light);
   }
-
-  if(CTX.mesh.shade)
-    glEnable(GL_LIGHTING);
-
 }
 
 void Draw_Hexahedron_Volume(void *a, void *b)
@@ -894,9 +869,6 @@ void Draw_Hexahedron_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (h->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.shade)
-    glDisable(GL_LIGHTING);
-
   glBegin(GL_LINE_LOOP);
   glVertex3d(X[0], Y[0], Z[0]);
   glVertex3d(X[1], Y[1], Z[1]);
@@ -987,10 +959,6 @@ void Draw_Hexahedron_Volume(void *a, void *b)
     glDisable(GL_LINE_STIPPLE);
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
-
-  if(CTX.mesh.shade)
-    glEnable(GL_LIGHTING);
-
 }
 
 void Draw_Prism_Volume(void *a, void *b)
@@ -1039,9 +1007,6 @@ void Draw_Prism_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (p->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.shade)
-    glDisable(GL_LIGHTING);
-
   glBegin(GL_LINE_LOOP);
   glVertex3d(X[0], Y[0], Z[0]);
   glVertex3d(X[1], Y[1], Z[1]);
@@ -1113,10 +1078,6 @@ void Draw_Prism_Volume(void *a, void *b)
     glDisable(GL_LINE_STIPPLE);
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
-
-  if(CTX.mesh.shade)
-    glEnable(GL_LIGHTING);
-
 }
 
 void Draw_Pyramid_Volume(void *a, void *b)
@@ -1165,9 +1126,6 @@ void Draw_Pyramid_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (p->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.shade)
-    glDisable(GL_LIGHTING);
-
   glBegin(GL_LINE_LOOP);
   glVertex3d(X[0], Y[0], Z[0]);
   glVertex3d(X[1], Y[1], Z[1]);
@@ -1191,8 +1149,4 @@ void Draw_Pyramid_Volume(void *a, void *b)
     glRasterPos3d(Xc, Yc, Zc);
     Draw_String(Num);
   }
-
-  if(CTX.mesh.shade)
-    glEnable(GL_LIGHTING);
-
 }
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index b82a4bc7e4..215adc1c3e 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.51 2004-02-07 01:40:20 geuzaine Exp $
+// $Id: Post.cpp,v 1.52 2004-02-20 17:58:00 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -70,7 +70,6 @@ double GiveValueFromIndex_DoubleLog(double ValMin, double ValMax, int NbIso,
   return pow(10.,
              log10(ValMin) + Iso2 * (log10(ValMax) -
                                      log10(ValMin)) / (NbIso2 - 1.));
-
 }
 
 // Give Index From Value
@@ -468,11 +467,6 @@ void Draw_Post(void)
         glLineWidth(v->LineWidth);
         gl2psLineWidth(v->LineWidth * CTX.print.eps_line_width_factor);
 
-        if(v->Light)
-          InitShading();
-        else
-          InitNoShading();
-
         if(v->ShowElement)
           glEnable(GL_POLYGON_OFFSET_FILL);
 
@@ -624,8 +618,4 @@ void Draw_Post(void)
     }
 
   }
-
-  // go back to default shading for the scale
-  InitNoShading();
-
 }
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index df69a4e54e..51e266b14f 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.21 2004-02-07 01:40:20 geuzaine Exp $
+// $Id: PostElement.cpp,v 1.22 2004-02-20 17:58:00 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -55,16 +55,13 @@ void Draw_ElementBoundary(int type, Post_View * View, double *X, double *Y,
   int k;
   double xx[8], yy[8], zz[8];
 
-  if(View->Light)
-    glDisable(GL_LIGHTING);
-
   glColor4ubv((GLubyte *) & CTX.color.fg);
   switch (type) {
   case POINT:
-    Draw_Point(View->PointType, View->PointSize, X, Y, Z, Raise);
+    Draw_Point(View->PointType, View->PointSize, X, Y, Z, Raise, View->Light);
     break;
   case LINE:
-    Draw_Line(0, View->LineWidth, X, Y, Z, Raise);
+    Draw_Line(0, View->LineWidth, X, Y, Z, Raise, View->Light);
     break;
   case TRIANGLE:
     glBegin(GL_LINE_LOOP);
@@ -185,9 +182,6 @@ void Draw_ElementBoundary(int type, Post_View * View, double *X, double *Y,
     glEnd();
     break;
   }
-
-  if(View->Light)
-    glEnable(GL_LIGHTING);
 }
 
 void SaturateValues(int saturate, double min, double max,
@@ -269,7 +263,7 @@ void Draw_ScalarPoint(Post_View * View, int preproNormals,
       Draw_String(Num);
     }
     else
-      Draw_Point(View->PointType, View->PointSize, X, Y, Z, Raise);
+      Draw_Point(View->PointType, View->PointSize, X, Y, Z, Raise, View->Light);
   }
 }
 
@@ -326,7 +320,7 @@ void Draw_ScalarLine(Post_View * View, int preproNormals,
         if(View->LineType) {
           // not perfect...
           Palette2(View, ValMin, ValMax, Val[0]);
-          Draw_Line(View->LineType, View->LineWidth, X, Y, Z, Raise);
+          Draw_Line(View->LineType, View->LineWidth, X, Y, Z, Raise, View->Light);
         }
         else {
           glBegin(GL_LINES);
@@ -355,7 +349,7 @@ void Draw_ScalarLine(Post_View * View, int preproNormals,
           if(nb == 2) {
             for(i = 0; i < 2; i++)
               RaiseFill(i, value[i], ValMin, Raise);
-            Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, Raise);
+            Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, Raise, View->Light);
           }
         }
         else {
@@ -363,14 +357,13 @@ void Draw_ScalarLine(Post_View * View, int preproNormals,
           CutLine0D(X, Y, Z, &Val[0], thev, Xp, Yp, Zp, &nb);
           if(nb) {
             RaiseFill(0, thev, ValMin, Raise);
-            Draw_Point(View->PointType, View->PointSize, Xp, Yp, Zp, Raise);
+            Draw_Point(View->PointType, View->PointSize, Xp, Yp, Zp, Raise, View->Light);
           }
         }
       }
     }
 
   }
-
 }
 
 void Draw_ScalarTriangle(Post_View * View, int preproNormals,
@@ -475,6 +468,8 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
   }
   else {
 
+    if(View->Light) glEnable(GL_LIGHTING);
+
     if(View->IntervalsType == DRAW_POST_CONTINUOUS) {
       if(Val[0] >= ValMin && Val[0] <= ValMax &&
          Val[1] >= ValMin && Val[1] <= ValMax &&
@@ -533,14 +528,14 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
           if(nb == 2) {
             for(i = 0; i < 2; i++)
               RaiseFill(i, thev, ValMin, Raise);
-            Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, Raise);
+            Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, Raise, View->Light);
           }
         }
       }
     }
-
+    
+    glDisable(GL_LIGHTING);
   }
-
 }
 
 void Draw_ScalarTetrahedron(Post_View * View, int preproNormals,
@@ -605,7 +600,6 @@ void Draw_ScalarTetrahedron(Post_View * View, int preproNormals,
     }
 
   }
-
 }
 
 void Draw_ScalarQuadrangle(Post_View * View, int preproNormals,
@@ -840,7 +834,7 @@ void Draw_VectorElement(int type, Post_View * View,
             YY[1] = Y[1] + fact * dy2;
             ZZ[0] = Z[0] + fact * dz;
             ZZ[1] = Z[1] + fact * dz2;
-            Draw_Line(View->LineType, View->LineWidth, XX, YY, ZZ, Raise);
+            Draw_Line(View->LineType, View->LineWidth, XX, YY, ZZ, Raise, View->Light);
           }
         }
         else {
@@ -929,8 +923,9 @@ void Draw_VectorElement(int type, Post_View * View,
         }
         RaiseFill(0, dd, ValMin, Raise);
         Draw_Vector(View->VectorType, View->IntervalsType != DRAW_POST_ISO,
-                    xc, yc, zc, fact * dd, fact * dx, fact * dy, fact * dz,
-                    Raise);
+		    View->ArrowRelHeadRadius, View->ArrowRelStemLength,
+		    View->ArrowRelStemRadius, xc, yc, zc, 
+		    fact * dx, fact * dy, fact * dz, Raise, View->Light);
       }
     }
   }
@@ -951,13 +946,13 @@ void Draw_VectorElement(int type, Post_View * View,
         }
         RaiseFill(0, d[k], ValMin, Raise);
         Draw_Vector(View->VectorType, View->IntervalsType != DRAW_POST_ISO,
-                    X[k], Y[k], Z[k],
-                    fact * d[k], fact * Val[k][0], fact * Val[k][1],
-                    fact * Val[k][2], Raise);
+		    View->ArrowRelHeadRadius, View->ArrowRelStemLength,
+		    View->ArrowRelStemRadius, X[k], Y[k], Z[k], 
+		    fact * Val[k][0], fact * Val[k][1], fact * Val[k][2], 
+		    Raise, View->Light);
       }
     }
   }
-
 }
 
 #define ARGS Post_View *View, 					\
@@ -1078,7 +1073,6 @@ void Draw_TensorElement(int type, Post_View * View,
     Draw_ScalarPyramid(View, 0, ValMin, ValMax, Raise, X, Y, Z, V_VonMises);
     break;
   }
-
 }
 
 #define ARGS Post_View *View, 					\
diff --git a/Makefile b/Makefile
index d94e49c70f..fedb43cc0d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.320 2004-02-07 01:40:16 geuzaine Exp $
+# $Id: Makefile,v 1.321 2004-02-20 17:57:58 geuzaine Exp $
 #
 # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 #
@@ -22,8 +22,8 @@
 include variables
 
 GMSH_MAJOR_VERSION = 1
-GMSH_MINOR_VERSION = 50
-GMSH_PATCH_VERSION = 2
+GMSH_MINOR_VERSION = 51
+GMSH_PATCH_VERSION = 0
 
 GMSH_SHORT_LICENSE = "GNU General Public License"
 
diff --git a/TODO b/TODO
index 218c97c4c2..46254647dc 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.31 2004-01-29 02:52:40 geuzaine Exp $
+$Id: TODO,v 1.32 2004-02-20 17:57:58 geuzaine Exp $
 
 degre2: remove from after each 1d/2d/3d step, and add a global
 "add_degre2_nodes" and "remove_degre2_nodes" menu
@@ -13,10 +13,6 @@ fix drawing of 2nd oder surface elements (subdivide?)
 
 ********************************************************************
 
-add nicer 3d drawing code for arrows (cylinder+cone, with lights)
-
-********************************************************************
-
 Yves Krahenbuhl wrote:
 
 > Lors de la creation des elements du 2eme ordre, et selon la courbure
diff --git a/doc/CREDITS b/doc/CREDITS
index 6a19600686..2d89cbd527 100644
--- a/doc/CREDITS
+++ b/doc/CREDITS
@@ -1,6 +1,6 @@
-$Id: CREDITS,v 1.9 2004-02-07 01:40:32 geuzaine Exp $
+$Id: CREDITS,v 1.10 2004-02-20 17:58:01 geuzaine Exp $
 
-             Gmsh is copyright (c) 1997-2004 
+             Gmsh is copyright (C) 1997-2004 
 
                    Christophe Geuzaine 
               <geuzaine at acm.caltech.edu> 
@@ -11,7 +11,7 @@ $Id: CREDITS,v 1.9 2004-02-07 01:40:32 geuzaine Exp $
                <remacle at gce.ucl.ac.be>
 
 The AVL tree code (DataStr/avl.*) and the YUV image code
-(Graphics/gl2yuv.*) are copyright (c) 1988-1993, 1995 The Regents of
+(Graphics/gl2yuv.*) are copyright (C) 1988-1993, 1995 The Regents of
 the University of California. Permission to use, copy, modify, and
 distribute this software and its documentation for any purpose and
 without fee is hereby granted, provided that the above copyright
@@ -23,7 +23,7 @@ written prior permission.  The University of California makes no
 representations about the suitability of this software for any
 purpose.  It is provided "as is" without express or implied warranty.
 
-The trackball code (Common/Trackball.*) is copyright (c) 1993, 1994,
+The trackball code (Common/Trackball.*) is copyright (C) 1993, 1994,
 Silicon Graphics, Inc.  ALL RIGHTS RESERVED. Permission to use, copy,
 modify, and distribute this software for any purpose and without fee
 is hereby granted, provided that the above copyright notice appear in
@@ -34,7 +34,7 @@ pertaining to distribution of the software without specific, written
 prior permission.
 
 The GIF and PPM routines (Graphics/gl2gif.cpp) are based on code
-copyright (c) 1989, 1991, Jef Poskanzer. Permission to use, copy,
+copyright (C) 1989, 1991, Jef Poskanzer. Permission to use, copy,
 modify, and distribute this software and its documentation for any
 purpose and without fee is hereby granted, provided that the above
 copyright notice appear in all copies and that both that copyright
@@ -43,11 +43,11 @@ This software is provided "as is" without express or implied warranty.
 
 The colorbar widget (Fltk/Colorbar_Window.cpp) was inspired by code
 from the Vis5d program for visualizing five dimensional gridded data
-sets, copyright (c) 1990-1995, Bill Hibbard, Brian Paul, Dave Santek,
+sets, copyright (C) 1990-1995, Bill Hibbard, Brian Paul, Dave Santek,
 and Andre Battaiola.
 
 This version of Gmsh may also contain code (in the Triangle
-subdirectory) copyright (c) 1993, 1995, 1997, 1998, 2002, Jonathan
+subdirectory) copyright (C) 1993, 1995, 1997, 1998, 2002, Jonathan
 Richard Shewchuk: check the configuration options.
 
 Special thanks to David Colignon <David.Colignon at univ.u-3mrs.fr>
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 1ae79039e0..b347d4a3a6 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,12 +1,13 @@
-$Id: VERSIONS,v 1.184 2004-02-06 17:53:19 geuzaine Exp $
+$Id: VERSIONS,v 1.185 2004-02-20 17:58:01 geuzaine Exp $
 
-New since 1.50: initial support for visualizing mesh partitions;
+New in 1.51: initial support for visualizing mesh partitions;
 integrated version 2.0 of the MSH mesh file format; new option to
 compute post-processing ranges (min/max) per time step; Multiple views
 can now be combined into multi time step ones (e.g. for programs that
 generate data one time step at a time); new syntax: #var[] returns the
-size of the list var[]; enhanced "gmsh -convert"; create temporary and
-error files in home directory to avoid file permission issues;
+size of the list var[]; enhanced "gmsh -convert"; temporary and error
+files are now created in home directory to avoid file permission
+issues; new 3D arrows; better lighting support;
 
 New in 1.50: small changes to the visibility browser + made visibility
 scriptable (new Show/Hide commands); fixed (rare) crash when deleting
diff --git a/doc/gmsh.html b/doc/gmsh.html
index f1917a180d..f151b41036 100644
--- a/doc/gmsh.html
+++ b/doc/gmsh.html
@@ -24,7 +24,7 @@ generator with built-in pre- and post-processing facilities</h1>
 <p>
 <h3 align="center">Christophe Geuzaine and Jean-Fran�ois Remacle</h3>
 <p>
-<h3 align=center>Version <a href="doc/VERSIONS">1.51</a>, xx January 2004</h3>
+<h3 align=center>Version <a href="doc/VERSIONS">1.51</a>, xx February 2004</h3>
 <p>
 <center>
   <a href="#Description">Description</a> |
diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi
index 533867476b..8c4741b577 100644
--- a/doc/texinfo/opt_general.texi
+++ b/doc/texinfo/opt_general.texi
@@ -49,6 +49,21 @@ Enable alpha blending (transparency) in post-processing views@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.ArrowHeadRadius
+Relative radius of arrow head@*
+Default value: @code{0.12}@*
+Saved in: @code{General.OptionsFileName}
+
+@item General.ArrowStemLength
+Relative length of arrow stem@*
+Default value: @code{0.56}@*
+Saved in: @code{General.OptionsFileName}
+
+@item General.ArrowStemRadius
+Relative radius of arrow stem@*
+Default value: @code{0.02}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Axes
 Display the axes linked to the model@*
 Default value: @code{1}@*
@@ -456,7 +471,7 @@ Saved in: @code{General.OptionsFileName}
 
 @item General.QuadricSubdivisions
 Number of subdivisions used to draw points or lines as spheres or cylinders@*
-Default value: @code{10}@*
+Default value: @code{8}@*
 Saved in: @code{General.OptionsFileName}
 
 @item General.RotationX
@@ -614,6 +629,11 @@ Z-axis translation (in model units)@*
 Default value: @code{0}@*
 Saved in: @code{-}
 
+@item General.VectorType
+Default vector display type (for normals, etc.)@*
+Default value: @code{2}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.Verbosity
 Level of information printed during processing (0=no information)@*
 Default value: @code{2}@*
diff --git a/doc/texinfo/opt_geometry.texi b/doc/texinfo/opt_geometry.texi
index da0ce701b4..4f84c1600c 100644
--- a/doc/texinfo/opt_geometry.texi
+++ b/doc/texinfo/opt_geometry.texi
@@ -1,9 +1,4 @@
 @ftable @code
-@item Geometry.Aspect
-Not used@*
-Default value: @code{0}@*
-Saved in: @code{General.OptionsFileName}
-
 @item Geometry.AutoCoherence
 Should all duplicate entities be automatically removed?@*
 Default value: @code{1}@*
@@ -34,6 +29,11 @@ Not used@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
+@item Geometry.Light
+Enable lighting for the geometry@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item Geometry.Lines
 Display geometry curves?@*
 Default value: @code{1}@*
diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi
index c03bfd98ae..2d4d75f6dc 100644
--- a/doc/texinfo/opt_mesh.texi
+++ b/doc/texinfo/opt_mesh.texi
@@ -14,11 +14,6 @@ Allow the generation of degenerated hexahedra or prisms during extrusion@*
 Default value: @code{0}@*
 Saved in: @code{-}
 
-@item Mesh.Aspect
-Mesh aspect (0=wireframe, 1=hidden lines, 2=solid)@*
-Default value: @code{0}@*
-Saved in: @code{General.OptionsFileName}
-
 @item Mesh.CharacteristicLengthFactor
 Factor applied to all characteristic lengths (and background meshes)@*
 Default value: @code{1}@*
@@ -109,6 +104,11 @@ Show the construction of the 2D mesh in real time (only with the 2D anisotropic
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
+@item Mesh.Light
+Enable lighting for the mesh@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item Mesh.Lines
 Display mesh vertices on curves?@*
 Default value: @code{1}@*
@@ -239,6 +239,11 @@ Number of smoothing steps applied to the final mesh@*
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
+@item Mesh.Solid
+Draw mesh as solid (1) or wireframe (0)?@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item Mesh.SpeedMax
 Disable dubious point insertion tests@*
 Default value: @code{0}@*
diff --git a/doc/texinfo/opt_view.texi b/doc/texinfo/opt_view.texi
index dd11df51d5..78b43215c7 100644
--- a/doc/texinfo/opt_view.texi
+++ b/doc/texinfo/opt_view.texi
@@ -34,6 +34,11 @@ Threshold angle below which normals are not smoothed@*
 Default value: @code{15}@*
 Saved in: @code{General.OptionsFileName}
 
+@item View.ArrowHeadRadius
+Relative radius of arrow head@*
+Default value: @code{0.12}@*
+Saved in: @code{General.OptionsFileName}
+
 @item View.ArrowLocation
 Arrow location (1=cog, 2=vertex)@*
 Default value: @code{1}@*
@@ -44,6 +49,16 @@ Size of vectors arrows (in pixels)@*
 Default value: @code{50}@*
 Saved in: @code{General.OptionsFileName}
 
+@item View.ArrowStemLength
+Relative length of arrow stem@*
+Default value: @code{0.56}@*
+Saved in: @code{General.OptionsFileName}
+
+@item View.ArrowStemRadius
+Relative radius of arrow stem@*
+Default value: @code{0.02}@*
+Saved in: @code{General.OptionsFileName}
+
 @item View.AutoPosition
 Position the scale or the 2D graph automatically to avoid overlaps@*
 Default value: @code{1}@*
@@ -150,7 +165,7 @@ Default value: @code{2}@*
 Saved in: @code{General.OptionsFileName}
 
 @item View.Light
-Enable light sources?@*
+Enable lighting for the view@*
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
@@ -295,7 +310,7 @@ Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
 @item View.VectorType
-Vector display type (1=segment, 2=arrow, 3=pyramid, 4=cone, 5=displacement)@*
+Vector display type (1=segment, 2=arrow, 3=pyramid, 4=3D arrow, 5=displacement)@*
 Default value: @code{2}@*
 Saved in: @code{General.OptionsFileName}
 
diff --git a/doc/texinfo/shortcuts.texi b/doc/texinfo/shortcuts.texi
index cd7972a084..a6df332aad 100644
--- a/doc/texinfo/shortcuts.texi
+++ b/doc/texinfo/shortcuts.texi
@@ -85,10 +85,10 @@ hide/show big moving axes
 hide/show all post-processing scales
 
 @item Alt+c
-alternate between predefined color schemes
+loop through predefined color schemes
 
 @item Alt+d
-alternate between mesh wire frame, hidden lines and shading modes
+change mesh display mode (solid/wireframe)
 
 @item Shift+d
 decrease animation delay
@@ -97,7 +97,7 @@ decrease animation delay
 increase animation delay
 
 @item Alt+f
-toggle redraw mode (fast/full)
+change redraw mode (fast/full)
 
 @item Alt+h
 hide/show all post-processing views
@@ -109,10 +109,10 @@ hide/show geometry lines
 hide/show mesh lines
 
 @item Alt+m
-toggle visibility of all mesh entities
+change visibility of all mesh entities
 
 @item Alt+o
-change projection mode
+change projection mode (ortho/perspective)
 
 @item Alt+p
 hide/show geometry points
@@ -127,7 +127,7 @@ hide/show geometry surfaces
 hide/show mesh surfaces
 
 @item Alt+t
-alternate intervals mode for visible post-processing views
+loop through interval modes for all post-processing views
 
 @item Alt+v
 hide/show geometry volumes
@@ -135,6 +135,9 @@ hide/show geometry volumes
 @item Alt+Shift+v
 hide/show mesh volumes
 
+@item Alt+w
+enable/disable all lighting
+
 @item Alt+x
 set X view
 
@@ -145,15 +148,15 @@ set Y view
 set Z view
 
 @item Left arrow
-previous time step
+go to previous time step
 
 @item Right arrow
-next time step
+go to next time step
 
 @item Up arrow
-previous view
+make previous view visible
 
 @item Down arrow
-next view
+make next view visible
 
 @end table
-- 
GitLab