From 21473056e6a0fbe5a56c329e616aaab0dbe98386 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 1 Jan 2005 18:59:07 +0000
Subject: [PATCH] - More intelligent way to detect if we need to apply a
 polygon offset or not.

- better computation of translation coef in Draw2D
---
 Common/Context.h             |  1 +
 Common/DefaultOptions.h      |  2 ++
 Common/Options.cpp           | 14 +++++++++++-
 Common/Options.h             |  1 +
 Fltk/Callbacks.cpp           |  5 +++--
 Fltk/GUI.cpp                 | 21 +++++++++++-------
 Graphics/Draw.cpp            | 42 ++++++++++++++++++++++++++++++------
 Graphics/Geom.cpp            | 14 +++++-------
 Graphics/Mesh.cpp            | 41 ++++++++++++-----------------------
 Graphics/Post.cpp            |  5 ++---
 Graphics/PostElement.cpp     | 20 ++++++-----------
 Plugin/StructuralSolver.cpp  | 12 ++++-------
 doc/VERSIONS                 | 21 ++++++++++--------
 doc/texinfo/gmsh.texi        | 16 +++++++-------
 doc/texinfo/opt_general.texi |  5 +++++
 15 files changed, 126 insertions(+), 94 deletions(-)

diff --git a/Common/Context.h b/Common/Context.h
index 1be0f9e5b1..25a4525c7b 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -132,6 +132,7 @@ public :
   int render_mode;            // GMSH_RENDER, GMSH_SELECT, GMSH_FEEDBACK 
   int clip[6];                // status of clip planes (bit arrays)
   double clip_plane[6][4];    // clip planes 
+  int polygon_offset, polygon_offset_always; // polygon offset control
   double polygon_offset_factor, polygon_offset_units; // params for glPolygonOffset
   double pixel_equiv_x, pixel_equiv_y ; 
                               // approximative equivalent model length of a pixel 
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 65bed6af2e..42c6ca6219 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -594,6 +594,8 @@ StringXNumber GeneralOptions_Number[] = {
 
   { F|O, "PointSize" , opt_general_point_size , 3. , 
     "Display size of points (in pixels)" },
+  { F|O, "PolygonOffsetAlwaysOn" , opt_general_polygon_offset_always , 0. , 
+    "Always apply polygon offset, instead of trying to detect when it is required" },
   { F|O, "PolygonOffsetFactor" , opt_general_polygon_offset_factor , 1. , 
     "Polygon offset factor (offset = factor * DZ + r * units)" },
   { F|O, "PolygonOffsetUnits" , opt_general_polygon_offset_units , 1. , 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 7fb46e30e4..98643f94f5 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.221 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: Options.cpp,v 1.222 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -126,6 +126,7 @@ void Init_Options(int num)
   CTX.vxmin = CTX.vymin = CTX.vxmax = CTX.vymax = 0.;
   CTX.render_mode = GMSH_RENDER;
   CTX.pixel_equiv_x = CTX.pixel_equiv_y = 0.;
+  CTX.polygon_offset = 0;
   CTX.geom.vis_type = 0;
   CTX.geom.level = ELEMENTARY;
   CTX.mesh.vis_type = 0;
@@ -1954,6 +1955,17 @@ double opt_general_viewport3(OPT_ARGS_NUM)
   return CTX.viewport[3];
 }
 
+double opt_general_polygon_offset_always(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.polygon_offset_always = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->gen_butt[4]->value(CTX.polygon_offset_always);
+#endif
+  return CTX.polygon_offset_always;
+}
+
 double opt_general_polygon_offset_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index 13b430a93b..ad4ccdc2bd 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -216,6 +216,7 @@ double opt_general_file_chooser_position0(OPT_ARGS_NUM);
 double opt_general_file_chooser_position1(OPT_ARGS_NUM);
 double opt_general_viewport2(OPT_ARGS_NUM);
 double opt_general_viewport3(OPT_ARGS_NUM);
+double opt_general_polygon_offset_always(OPT_ARGS_NUM);
 double opt_general_polygon_offset_factor(OPT_ARGS_NUM);
 double opt_general_polygon_offset_units(OPT_ARGS_NUM);
 double opt_general_menu_position0(OPT_ARGS_NUM);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 576114c6f0..6d5a7537cc 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.323 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.324 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -651,7 +651,8 @@ void general_options_ok_cb(CALLBACK_ARGS)
   opt_general_confirm_overwrite(0, GMSH_SET, WID->gen_butt[14]->value());
   opt_general_rotation_center_cg(0, GMSH_SET, WID->gen_butt[15]->value());
   opt_general_draw_bounding_box(0, GMSH_SET, WID->gen_butt[6]->value());
-
+  opt_general_polygon_offset_always(0, GMSH_SET, WID->gen_butt[4]->value());
+  
   opt_general_shine(0, GMSH_SET, WID->gen_value[1]->value());
   opt_general_shine_exponent(0, GMSH_SET, WID->gen_value[0]->value());
   opt_general_light00(0, GMSH_SET, WID->gen_value[2]->value());
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 180d5cd92e..368291820f 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.406 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: GUI.cpp,v 1.407 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1755,19 +1755,24 @@ void GUI::create_option_window()
       gen_value[16]->step(0.01);
       gen_value[16]->align(FL_ALIGN_RIGHT);
 
-      gen_value[11] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Number of quadric subdivisions");
+      gen_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Always apply polygon offset");
+      gen_butt[4]->type(FL_TOGGLE_BUTTON);
+      gen_butt[4]->down_box(GMSH_TOGGLE_BOX);
+      gen_butt[4]->selection_color(GMSH_TOGGLE_COLOR);
+
+      gen_value[11] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Number of quadric subdivisions");
       gen_value[11]->minimum(3);
       gen_value[11]->maximum(30);
       gen_value[11]->step(1);
       gen_value[11]->align(FL_ALIGN_RIGHT);
 
-      gen_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Point size");
+      gen_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Point size");
       gen_value[6]->minimum(0.1);
       gen_value[6]->maximum(50);
       gen_value[6]->step(0.1);
       gen_value[6]->align(FL_ALIGN_RIGHT);
 
-      gen_value[7] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Line width");
+      gen_value[7] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Line width");
       gen_value[7]->minimum(0.1);
       gen_value[7]->maximum(50);
       gen_value[7]->step(0.1);
@@ -1780,18 +1785,18 @@ void GUI::create_option_window()
 	{"3D arrow", 0, 0, 0},
 	{0}
       };
-      gen_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Vector display");
+      gen_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Vector display");
       gen_choice[0]->menu(menu_genvectype);
       gen_choice[0]->align(FL_ALIGN_RIGHT);
 
-      Fl_Button *b = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 7 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
+      Fl_Button *b = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 8 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
       b->callback(general_arrow_param_cb);
 
-      gen_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Font");
+      gen_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Font");
       gen_choice[1]->menu(menu_font_names);
       gen_choice[1]->align(FL_ALIGN_RIGHT);
 
-      gen_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Font size");
+      gen_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Font size");
       gen_value[12]->minimum(5);
       gen_value[12]->maximum(40);
       gen_value[12]->step(1);
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 44a4ed553f..41377719d6 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.70 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: Draw.cpp,v 1.71 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -34,13 +34,43 @@ extern Mesh M;
 
 // Global Draw functions
 
+int NeedPolygonOffset()
+{
+  if(M.status == 2 &&
+     (CTX.mesh.surfaces_edges || CTX.geom.lines || CTX.geom.surfaces))
+    return 1;
+  if(M.status == 3 && 
+     (CTX.mesh.surfaces_edges || CTX.mesh.volumes_edges))
+    return 1;
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++){
+    Post_View *v = *(Post_View**)List_Pointer(CTX.post.list, i);
+    if(v->Visible){
+      if(v->ShowElement)
+	return 1;
+      if((v->NbST || v->NbSQ) && (v->IntervalsType == DRAW_POST_ISO))
+	return 1;
+    }
+  }
+  return 0;
+}
+
 void Draw3d(void)
 {
-  // offset = factor*DZ+r*units, where DZ is a measurement of the
-  // change in depth relative to the screen area of the polygon, and r
-  // is the smallest value that is guaranteed to produce a resolvable
-  // offset for a given implementation:
+  // We should only enable the polygon offset when there is a mix of
+  // lines and polygons to be drawn; enabling it all the time can lead
+  // to very small but annoying artifacts in the picture. Since there
+  // are so many ways in Gmsh to combine polygons and lines
+  // (geometries + meshes + views...), we do our best here to
+  // automatically detect if we should enable it. Note: the formula
+  // for the offset is "offset = factor*DZ+r*units", where DZ is a
+  // measurement of the change in depth relative to the screen area of
+  // the polygon, and r is the smallest value that is guaranteed to
+  // produce a resolvable offset for a given implementation.
   glPolygonOffset(CTX.polygon_offset_factor, CTX.polygon_offset_units);
+  if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
+    CTX.polygon_offset = CTX.polygon_offset_always ? 1 : NeedPolygonOffset();
+  else
+    CTX.polygon_offset = 0;
 
   glDepthFunc(GL_LESS);
   glEnable(GL_DEPTH_TEST);
@@ -63,7 +93,7 @@ void Draw2d(void)
   glOrtho((double)CTX.viewport[0], (double)CTX.viewport[2],
           (double)CTX.viewport[1], (double)CTX.viewport[3], -1., 1.);
   // hack to make the 2D primitives appear "in front" in GL2PS
-  glTranslated(0.0, 0.0, CTX.clip_factor ? 1./CTX.clip_factor : 0.);
+  glTranslated(0., 0., CTX.clip_factor > 1. ? 1./CTX.clip_factor : CTX.clip_factor);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glPushMatrix();
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index f220852536..b6f5fb8cc7 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.77 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: Geom.cpp,v 1.78 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -324,10 +324,8 @@ void Draw_Triangulated_Surface(Surface * s)
   double *points, *p1, *p2, *p3;
 
   if(CTX.geom.surfaces) {
-    if(CTX.geom.light) 
-      glEnable(GL_LIGHTING);
-    if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-      glEnable(GL_POLYGON_OFFSET_FILL);
+    if(CTX.geom.light) glEnable(GL_LIGHTING);
+    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
     glBegin(GL_TRIANGLES);
     while (k < List_Nbr(s->thePolyRep->polygons)){
       points = (double*)List_Pointer(s->thePolyRep->polygons,k);
@@ -514,10 +512,8 @@ void Draw_NonPlane_Surface(Surface * s)
 {
   if(CTX.geom.surfaces) {
     if(s->Typ == MSH_SURF_NURBS) {
-      if(CTX.geom.light) 
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.geom.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       GLUnurbsObj *nurb;
       nurb = gluNewNurbsRenderer();
 #if defined(GLU_VERSION_1_3)
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 168ef035c0..939ff92484 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.116 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.117 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -707,8 +707,7 @@ void Draw_Mesh_Array(VertexArray *va, int faces, int edges)
       glEnable(GL_LIGHTING);
     else
       glDisableClientState(GL_NORMAL_ARRAY);
-    if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-      glEnable(GL_POLYGON_OFFSET_FILL);
+    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
     glDrawArrays((va->type == 3) ? GL_TRIANGLES : GL_QUADS, 0, va->type * va->num);
     glDisable(GL_POLYGON_OFFSET_FILL);
     glDisable(GL_LIGHTING);
@@ -835,10 +834,8 @@ void Draw_Mesh_Triangle(void *a, void *b)
 
     if(CTX.mesh.surfaces_faces) {
       glColor4ubv((GLubyte *) & col);      
-      if(CTX.mesh.light)
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       if(!s->VSUP) {
 	glBegin(GL_TRIANGLES);
 	_triFace(X[0], Y[0], Z[0], X[1], Y[1], Z[1], X[2], Y[2], Z[2]);
@@ -999,10 +996,8 @@ void Draw_Mesh_Quadrangle(void *a, void *b)
 
     if(CTX.mesh.surfaces_faces) {
       glColor4ubv((GLubyte *) & col);
-      if(CTX.mesh.light) 
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       if(!q->VSUP) {
 	glBegin(GL_QUADS);
 	_quadFace(X, Y, Z, 0, 1, 2, 3);
@@ -1173,10 +1168,8 @@ void Draw_Mesh_Tetrahedron(void *a, void *b)
     
     if(faces){
       glColor4ubv((GLubyte *) & col);
-      if(CTX.mesh.light)
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       if(!s->VSUP){
 	glBegin(GL_TRIANGLES);
 	_triFace(X[0], Y[0], Z[0], X[2], Y[2], Z[2], X[1], Y[1], Z[1]);
@@ -1346,10 +1339,8 @@ void Draw_Mesh_Hexahedron(void *a, void *b)
     
     if(faces){
       glColor4ubv((GLubyte *) & col);
-      if(CTX.mesh.light) 
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       if(!h->VSUP){
 	glBegin(GL_QUADS);
 	_quadFace(X, Y, Z, 0, 3, 2, 1);
@@ -1547,10 +1538,8 @@ void Draw_Mesh_Prism(void *a, void *b)
     
     if(faces){
       glColor4ubv((GLubyte *) & col);
-      if(CTX.mesh.light) 
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       if(!p->VSUP){
 	glBegin(GL_TRIANGLES);
 	_triFace(X[0], Y[0], Z[0], X[2], Y[2], Z[2], X[1], Y[1], Z[1]);
@@ -1743,10 +1732,8 @@ void Draw_Mesh_Pyramid(void *a, void *b)
 
     if(faces){
       glColor4ubv((GLubyte *) & col);
-      if(CTX.mesh.light)
-	glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	glEnable(GL_POLYGON_OFFSET_FILL);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
       if(!p->VSUP){
 	glBegin(GL_QUADS);
 	_quadFace(X, Y, Z, 0, 3, 2, 1);
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index d3343f64a4..400cfc084d 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.89 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: Post.cpp,v 1.90 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -717,8 +717,7 @@ void Draw_Post(void)
 	  glEnable(GL_LIGHTING);
 	else
 	  glDisableClientState(GL_NORMAL_ARRAY);
-	if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	  glEnable(GL_POLYGON_OFFSET_FILL);
+	if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
 	glDrawArrays(GL_TRIANGLES, 0, 3 * v->TriVertexArray->num);
 	glDisable(GL_POLYGON_OFFSET_FILL);
 	glDisable(GL_LIGHTING);
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index 976e45d2e2..3701624b65 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.58 2004-12-31 21:12:40 geuzaine Exp $
+// $Id: PostElement.cpp,v 1.59 2005-01-01 18:59:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -440,10 +440,8 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 	View->TriVertexArray->num++;
       }
       else{
-	if(View->Light) 
-	  glEnable(GL_LIGHTING);
-	if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	  glEnable(GL_POLYGON_OFFSET_FILL);
+	if(View->Light) glEnable(GL_LIGHTING);
+	if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
 	glBegin(GL_TRIANGLES);
 	for(int i = 0; i < 3; i++){
 	  PaletteContinuous(View, ValMin, ValMax, Val[i]);
@@ -489,10 +487,8 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 	  }
 	}
 	else{
-	  if(View->Light) 
-	    glEnable(GL_LIGHTING);
-	  if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	    glEnable(GL_POLYGON_OFFSET_FILL);
+	  if(View->Light) glEnable(GL_LIGHTING);
+	  if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
 	  glBegin(GL_POLYGON);
 	  for(int i = 0; i < nb; i++) {
 	    PaletteContinuous(View, ValMin, ValMax, Vp[i]);
@@ -546,10 +542,8 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 	    }
 	  }
 	  else{
-	    if(View->Light) 
-	      glEnable(GL_LIGHTING);
-	    if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-	      glEnable(GL_POLYGON_OFFSET_FILL);
+	    if(View->Light) glEnable(GL_LIGHTING);
+	    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
 	    glBegin(GL_POLYGON);
 	    for(int i = 0; i < nb; i++){
 	      if(View->Light) glNormal3dv(&norms[3*i]);
diff --git a/Plugin/StructuralSolver.cpp b/Plugin/StructuralSolver.cpp
index b34af7355f..a064d6e780 100644
--- a/Plugin/StructuralSolver.cpp
+++ b/Plugin/StructuralSolver.cpp
@@ -184,10 +184,8 @@ void Structural_BeamSection ::  GL_DrawBeam (double pinit[3], double dir[3], con
   List_T *surfaces = Tree2List (m.Surfaces);
   List_T *curves = Tree2List (m.Curves);
   List_T *points = Tree2List (m.Points);
-  if(CTX.geom.light) 
-    glEnable(GL_LIGHTING);
-  if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-    glEnable(GL_POLYGON_OFFSET_FILL);
+  if(CTX.geom.light) glEnable(GL_LIGHTING);
+  if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
   glEnable( GL_TEXTURE_2D );  
@@ -775,10 +773,8 @@ void Draw_Kinematic_Constraint ( const int type [3],
       return;
     }
 
-  if(CTX.geom.light)
-    glEnable(GL_LIGHTING);
-  if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-    glEnable(GL_POLYGON_OFFSET_FILL);
+  if(CTX.geom.light) glEnable(GL_LIGHTING);
+  if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
 
   glColor3f    (0.8,0.8,0.8);
   
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 628f38ef7d..476d2eb7a3 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,14 +1,17 @@
-$Id: VERSIONS,v 1.294 2005-01-01 02:16:51 geuzaine Exp $
+$Id: VERSIONS,v 1.295 2005-01-01 18:59:07 geuzaine Exp $
 
 New in 1.58: fixed UNIX socket interface on Windows (broken by the TCP
-solver patch in 1.57); new File->Rename menu; new colormaps+improved
-colormap handling; new color+min/max options in views; new GetValue()
-function to ask for values interactively in scripts; generalized
-For/EndFor loops in parser; new plugins (Annotate, Remove, Probe); new
-text attributes in views; renamed some shortcuts; fixed TeX output for
-large scenes; new option dialogs for various output formats; fixed
-many small memory leaks in parser; many small enhancements to polish
-the graphics and the user interface.
+solver patch in 1.57); bumped version number of default
+post-processing file formats to 1.3 (the only small modification is
+the handling of the end-of-string character for text2d and text3d
+objects in the ASCII format); new File->Rename menu; new
+colormaps+improved colormap handling; new color+min/max options in
+views; new GetValue() function to ask for values interactively in
+scripts; generalized For/EndFor loops in parser; new plugins
+(Annotate, Remove, Probe); new text attributes in views; renamed some
+shortcuts; fixed TeX output for large scenes; new option dialogs for
+various output formats; fixed many small memory leaks in parser; many
+small enhancements to polish the graphics and the user interface.
 
 New in 1.57: generalized displacement maps to display arbitrary view
 types; the arrows representing a vector field can now also be colored
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index e06ba28f0a..56790e884a 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -1,5 +1,5 @@
 \input texinfo.tex @c -*-texinfo-*-
-@c $Id: gmsh.texi,v 1.158 2004-12-31 04:04:51 geuzaine Exp $
+@c $Id: gmsh.texi,v 1.159 2005-01-01 18:59:07 geuzaine Exp $
 @c
 @c Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 @c
@@ -2701,9 +2701,9 @@ Pop up menu on post-processing view button
 
 @cindex File formats
 
-This chapter describes the file formats that cannot be modified by the
-user. (These formats have version numbers that are independent of the Gmsh
-version number.)
+This chapter describes Gmsh's native mesh and post-processing file
+formats. (These formats have version numbers that are independent of Gmsh's
+main version number.)
 
 All non-parsed file formats have sections enclosed between @code{$Key} and
 @code{$EndKey} tags.
@@ -3150,7 +3150,7 @@ one or more post-processing views, enclosed between
 
 @example
 $PostFormat
-1.2 @var{file-type} @var{data-size}
+1.3 @var{file-type} @var{data-size}
 $EndPostFormat
 $View
 @var{view-name} @var{nb-time-steps}
@@ -3271,7 +3271,7 @@ the GUI), and whose eight next bits define the text alignment (0=left,
 
 @item @var{text2d-chars}
 is a list of @var{nb-text2d-chars} characters. Substrings are separated with
-the `@code{^}' character (which is a forbidden character in regular strings).
+the null `@code{\0}' character.
 
 @item @var{text3d}
 is a list of 5 double precision numbers
@@ -3288,7 +3288,7 @@ eight lower bits give the font size and whose eight next bits select the font
 
 @item @var{text3d-chars}
 is a list of @var{nb-text3d-chars} chars. Substrings are separated with the
-`@code{^}' character.
+null `@code{\0}' character.
 @end table
 
 @c .........................................................................
@@ -3323,7 +3323,7 @@ Here is a pseudo C code to write a post-processing file in binary format:
 int one = 1;
 
 fprintf(file, "$PostFormat\n");
-fprintf(file, "%g %d %d\n", 1.2, 1, sizeof(double));
+fprintf(file, "%g %d %d\n", 1.3, 1, sizeof(double));
 fprintf(file, "$EndPostFormat\n");
 fprintf(file, "$View\n");
 fprintf(file, "%s %d "
diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi
index 13cdb616d5..e153576cf9 100644
--- a/doc/texinfo/opt_general.texi
+++ b/doc/texinfo/opt_general.texi
@@ -529,6 +529,11 @@ Display size of points (in pixels)@*
 Default value: @code{3}@*
 Saved in: @code{General.OptionsFileName}
 
+@item General.PolygonOffsetAlwaysOn
+Always apply polygon offset, instead of trying to detect when it is required@*
+Default value: @code{0}@*
+Saved in: @code{General.OptionsFileName}
+
 @item General.PolygonOffsetFactor
 Polygon offset factor (offset = factor * DZ + r * units)@*
 Default value: @code{1}@*
-- 
GitLab