diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 8df9c44fadda98dd5aa323c11d98855cb3edfc15..05140a58bba945c6b89c535cc66a5ee901f02bcf 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -423,7 +423,7 @@ StringXNumber GeneralOptions_Number[] = {
   { F|O, "ArrowStemRadius" , opt_general_arrow_stem_radius , 0.02 ,
     "Relative radius of arrow stem" },
   { F|O, "Axes" , opt_general_axes , 0. ,
-    "Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid)" },
+    "Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid, 5=ruler)" },
   { F|O, "AxesAutoPosition" , opt_general_axes_auto_position , 1. , 
     "Position the axes automatically" }, 
   { F|O, "AxesMaxX" , opt_general_axes_xmax , 1. , 
@@ -1054,7 +1054,7 @@ StringXNumber ViewOptions_Number[] = {
   { F|O, "AutoPosition" , opt_view_auto_position , 1. , 
     "Position the scale or 2D plot automatically" }, 
   { F|O, "Axes" , opt_view_axes , 0 ,
-    "Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid)" },
+    "Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid, 5=ruler)" },
   { F|O, "AxesAutoPosition" , opt_view_axes_auto_position , 1. , 
     "Position the axes automatically" }, 
   { F|O, "AxesMaxX" , opt_view_axes_xmax , 1. , 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index ca38caf3ce66f434846eb94e0c83eb8472fe6845..a5861ee9218559e48a29b9646b8401e51a785ef2 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.232 2005-03-12 20:17:41 geuzaine Exp $
+// $Id: Options.cpp,v 1.233 2005-03-13 05:32:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -2640,7 +2640,7 @@ double opt_general_axes(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
     CTX.axes = (int)val;
-    if(CTX.axes < 0 || CTX.axes > 4)
+    if(CTX.axes < 0 || CTX.axes > 5)
       CTX.axes = 0;
   }
 #if defined(HAVE_FLTK)
@@ -5395,7 +5395,7 @@ double opt_view_axes(OPT_ARGS_NUM)
   GET_VIEW(0.);
   if(action & GMSH_SET) {
     v->Axes = (int)val;
-    if(v->Axes < 0 || v->Axes > 4)
+    if(v->Axes < 0 || v->Axes > 5)
       v->Axes = 0;
   }
 #if defined(HAVE_FLTK)
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index ffe80c906e65e6fa9c2b3db4ea6a38891e8b5f8e..3ab611ab2c7d307093d54be2a2e7028efa6b8094 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.427 2005-03-12 22:25:24 geuzaine Exp $
+// $Id: GUI.cpp,v 1.428 2005-03-13 05:32:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -396,6 +396,7 @@ static Fl_Menu_Item menu_axes_mode[] = {
   {"Box", 0, 0, 0},
   {"Full grid", 0, 0, 0},
   {"Open grid", 0, 0, 0},
+  {"Ruler", 0, 0, 0},
   {0}
 };
 
diff --git a/Graphics/Entity.cpp b/Graphics/Entity.cpp
index 809b106f372f00a371751267086f17bada447c08..f3c1cf5a4b0a75ec15e53f4a6a5093922f5823d4 100644
--- a/Graphics/Entity.cpp
+++ b/Graphics/Entity.cpp
@@ -1,4 +1,4 @@
-// $Id: Entity.cpp,v 1.59 2005-03-12 07:52:56 geuzaine Exp $
+// $Id: Entity.cpp,v 1.60 2005-03-13 05:32:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -604,7 +604,10 @@ int Draw_Tics(int comp, int n, char *format, char *label,
     }
 
     char str[256];
-    sprintf(str, format, p[comp]);
+    if(comp < 0) // display the length (ruler)
+      sprintf(str, format, d);
+    else // display the coordinate
+      sprintf(str, format, p[comp]);
     double winp[3], winr[3];
     World2Viewport(p, winp);
     World2Viewport(r, winr);
@@ -669,14 +672,34 @@ void Draw_Axes(int mode, int tics[3], char format[3][256], char label[3][256],
   //      2: box
   //      3: full grid
   //      4: open grid
+  //      5: ruler
 
   if((mode < 1) || (bb[0] == bb[1] && bb[2] == bb[3] && bb[4] == bb[5]))
     return;
-  
+
   double xmin = bb[0], xmax = bb[1];
   double ymin = bb[2], ymax = bb[3];
   double zmin = bb[4], zmax = bb[5];
+  double orig[3] = {xmin, ymin, zmin};
 
+  if(mode == 5){ // draw ruler from xyz_min to xyz_max
+    glBegin(GL_LINES);
+    glVertex3d(xmin, ymin, zmin); glVertex3d(xmax, ymax, zmax);
+    glEnd();
+    double end[3] = {xmax, ymax, zmax};
+    double dir[3] = {xmax-xmin, ymax-ymin, zmax-zmin};
+    double perp[3];
+    if((fabs(dir[0]) >= fabs(dir[1]) && fabs(dir[0]) >= fabs(dir[2])) ||
+       (fabs(dir[1]) >= fabs(dir[0]) && fabs(dir[1]) >= fabs(dir[2]))){
+      perp[0] = dir[1]; perp[1] = -dir[0]; perp[2] = 0.;
+    }
+    else{
+      perp[0] = 0.; perp[1] = dir[2]; perp[2] = -dir[1];
+    }
+    Draw_Tics(-1, tics[0], format[0], label[0], orig, end, perp);
+    return;
+  }
+  
   glBegin(GL_LINES);
   // 3 axes
   glVertex3d(xmin, ymin, zmin); glVertex3d(xmax, ymin, zmin);
@@ -699,7 +722,6 @@ void Draw_Axes(int mode, int tics[3], char format[3][256], char label[3][256],
   }
   glEnd();
 
-  double orig[3] = {xmin, ymin, zmin};
   double xx[3] = {xmax, ymin, zmin};
   double yy[3] = {xmin, ymax, zmin};
   double zz[3] = {xmin, ymin, zmax};
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 37887329ba68af04dd82397d6647fbe211e364e2..0fb46ca97a23cb51434c601d7fa5a2e96b1a7b9a 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,15 +1,15 @@
-$Id: VERSIONS,v 1.319 2005-03-12 00:59:42 geuzaine Exp $
+$Id: VERSIONS,v 1.320 2005-03-13 05:32:44 geuzaine Exp $
 
 New since 1.59: added support for discrete curves; new Window menu on
 Mac OS X; generalized all octree-based plugins (CutGrid, StreamLines,
 Probe, etc.) to handle all element types (and not only scalar and
 vector triangles+tetrahedra); generalized Plugin(Evaluate),
 Plugin(Extract) and Plugin(Annotate); enhanced clipping plane
-interface; new grid/axes for 3D post-processing views (+ renamed the
-AbscissaName, NbAbscissa and AbscissaFormat options in the process);
-better automatic positionning of 2D graphs; new manipulator dialog to
-specify rotations/translations/scalings "by hand"; various small
-enhancements and bug fixes.
+interface; new grid/axes/rulers for 3D post-processing views (renamed
+the AbscissaName, NbAbscissa and AbscissaFormat options to more
+general names in the process); better automatic positionning of 2D
+graphs; new manipulator dialog to specify rotations, translations and
+scalings "by hand"; various small enhancements and bug fixes.
 
 New in 1.59: added support for discrete (triangulated) surfaces,
 either in STL format or with the new "Discrete Surface" command; added
diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi
index f6a5bf0a665d0fe675edb3f6b8723fd788ba10ff..d3a6bc9a9c35c52f931d8519aac0baec318ef93f 100644
--- a/doc/texinfo/opt_general.texi
+++ b/doc/texinfo/opt_general.texi
@@ -100,7 +100,7 @@ Default value: @code{0.02}@*
 Saved in: @code{General.OptionsFileName}
 
 @item General.Axes
-Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid)@*
+Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid, 5=ruler)@*
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
diff --git a/doc/texinfo/opt_view.texi b/doc/texinfo/opt_view.texi
index 092fbf86aa2655540680d8b72a4d25814aad4a7a..c7e5ecf8d7e9f0b817e71b955b25863a4eea1177 100644
--- a/doc/texinfo/opt_view.texi
+++ b/doc/texinfo/opt_view.texi
@@ -100,7 +100,7 @@ Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
 @item View.Axes
-Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid)@*
+Axes (0=none, 1=simple axes, 2=box, 3=full grid, 4=open grid, 5=ruler)@*
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}