From 1ef74ab5733ee26dc6460148acc7befccc65fc3f Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sun, 13 Nov 2016 11:43:15 +0000
Subject: [PATCH] - removed Mesh.ReverseAllNormals option (it's for display
 only, and is confusing) - disable LightTwoSides by default (it's slow) - use
 GL_RESCALE_NORMAL instead of GL_NORMALIZE (it's faster)

---
 Common/CommandLine.cpp   |  1 -
 Common/Context.cpp       |  4 +-
 Common/Context.h         |  2 +-
 Common/DefaultOptions.h  | 10 ++---
 Common/Options.cpp       | 15 --------
 Common/Options.h         |  1 -
 Fltk/FlGui.cpp           |  5 ---
 Fltk/optionWindow.cpp    | 19 +++-------
 Geo/MFace.cpp            | 81 ++++++++--------------------------------
 Graphics/drawContext.cpp | 13 ++++---
 Graphics/drawGeom.cpp    | 38 ++++++++++++++-----
 Graphics/drawMesh.cpp    | 21 ++++++++---
 Graphics/drawPost.cpp    | 11 +++---
 13 files changed, 84 insertions(+), 137 deletions(-)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index f53fdae39d..109fb4e92d 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -240,7 +240,6 @@ std::vector<std::pair<std::string, std::string> > GetShortcutsUsage(const std::s
   s.push_back(mp("Alt+Shift+s",    "Hide/show mesh surface edges"));
   s.push_back(mp("Alt+Shift+t",    "Same as Alt+t, but with numeric mode included"));
   s.push_back(mp("Alt+Shift+v",    "Hide/show mesh volume edges"));
-  s.push_back(mp("Alt+Shift+w",    "Reverse all mesh normals"));
   s.push_back(mp("Alt+Shift+x",    "Set -X view"));
   s.push_back(mp("Alt+Shift+y",    "Set -Y view"));
   s.push_back(mp("Alt+Shift+z",    "Set -Z view"));
diff --git a/Common/Context.cpp b/Common/Context.cpp
index b5c3cadb15..ccc00fb65e 100644
--- a/Common/Context.cpp
+++ b/Common/Context.cpp
@@ -86,7 +86,7 @@ CTX::CTX() : gamepad(0)
   mesh.prisms = mesh.pyramids = mesh.hexahedra = mesh.trihedra = 0;
   mesh.volumesEdges = mesh.volumesFaces = mesh.surfacesEdges = mesh.surfacesFaces = 0;
   mesh.volumesFaces = mesh.surfacesEdges = mesh.surfacesFaces = 0;
-  mesh.hoOptimize = mesh.smoothNormals = mesh.reverseAllNormals = 0;
+  mesh.hoOptimize = mesh.smoothNormals = 0;
   mesh.explode = mesh.angleSmoothNormals = 0.;
   mesh.numSubEdges = 0;
   mesh.colorCarousel = 0;
@@ -107,7 +107,7 @@ CTX::CTX() : gamepad(0)
   mesh.minCircPoints = mesh.order = 0;
   mesh.secondOrderLinear = mesh.secondOrderIncomplete = 0;
   mesh.preserveNumberingMsh2 = 1;
-  mesh.lightLines = 1;
+  mesh.lightLines = 2;
 }
 
 CTX::~CTX()
diff --git a/Common/Context.h b/Common/Context.h
index 973fb709ed..9f4a7da2f5 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -50,7 +50,7 @@ struct contextMeshOptions {
   int hoOptimize, hoNLayers, hoOptPrimSurfMesh;
   double hoThresholdMin, hoThresholdMax, hoPoissonRatio;
   int saveAll, saveTri, saveGroupsOfNodes, binary, bdfFieldFormat, saveParametric;
-  int smoothNormals, reverseAllNormals, zoneDefinition, clip;
+  int smoothNormals, zoneDefinition, clip;
   int saveElementTagType;
   int switchElementTags;
   int multiplePasses;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 47063de79c..60e90fce83 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -835,7 +835,7 @@ StringXNumber GeometryOptions_Number[] = {
     "Type of entity label (1=elementary number, 2=physical number)" },
   { F|O, "Light" , opt_geometry_light , 1. ,
     "Enable lighting for the geometry" },
-  { F|O, "LightTwoSide" , opt_geometry_light_two_side , 1. ,
+  { F|O, "LightTwoSide" , opt_geometry_light_two_side , 0. ,
     "Light both sides of surfaces (leads to slower rendering)" },
   { F|O, "Lines" , opt_geometry_lines , 1. ,
     "Display geometry curves?" },
@@ -1081,9 +1081,9 @@ StringXNumber MeshOptions_Number[] = {
     "Accuracy of evaluation of the LC field for 1D mesh generation" },
   { F|O, "Light" , opt_mesh_light , 1. ,
     "Enable lighting for the mesh" },
-  { F|O, "LightLines" , opt_mesh_light_lines , 1. ,
+  { F|O, "LightLines" , opt_mesh_light_lines , 2. ,
     "Enable lighting for mesh edges (0=no, 1=surfaces, 2=surfaces+volumes" },
-  { F|O, "LightTwoSide" , opt_mesh_light_two_side , 1. ,
+  { F|O, "LightTwoSide" , opt_mesh_light_two_side , 0. ,
     "Light both sides of surfaces (leads to slower rendering)" },
   { F|O, "Lines" , opt_mesh_lines , 0. ,
     "Display mesh lines (1D elements)?" },
@@ -1224,8 +1224,6 @@ StringXNumber MeshOptions_Number[] = {
     "7=conformal_fe" },
   { F|O, "RefineSteps" , opt_mesh_refine_steps , 10 ,
     "Number of refinement steps in the MeshAdapt-based 2D algorithms" },
-  { F|O, "ReverseAllNormals" , opt_mesh_reverse_all_normals , 0. ,
-    "Reverse all the mesh normals (for display)" },
 
   { F,   "SaveAll" , opt_mesh_save_all , 0. ,
     "Ignore Physical definitions and save all elements" },
@@ -1532,7 +1530,7 @@ StringXNumber ViewOptions_Number[] = {
     "Enable lighting for the view" },
   { F|O, "LightLines" , opt_view_light_lines , 1. ,
     "Light element edges" },
-  { F|O, "LightTwoSide" , opt_view_light_two_side , 1. ,
+  { F|O, "LightTwoSide" , opt_view_light_two_side , 0. ,
     "Light both sides of surfaces (leads to slower rendering)" },
   { F|O, "LineType" , opt_view_line_type , 0. ,
     "Display lines as solid color segments (0) or 3D cylinders (1)" },
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 0da0f579a8..d6593ca86d 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5530,21 +5530,6 @@ double opt_mesh_label_sampling(OPT_ARGS_NUM)
   return CTX::instance()->mesh.labelSampling;
 }
 
-double opt_mesh_reverse_all_normals(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET) {
-    if(CTX::instance()->mesh.reverseAllNormals != val)
-      CTX::instance()->mesh.changed |= (ENT_SURFACE | ENT_VOLUME);
-    CTX::instance()->mesh.reverseAllNormals = (int)val;
-  }
-#if defined(HAVE_FLTK)
-  if(FlGui::available() && (action & GMSH_GUI))
-    FlGui::instance()->options->mesh.butt[0]->value
-      (CTX::instance()->mesh.reverseAllNormals);
-#endif
-  return CTX::instance()->mesh.reverseAllNormals;
-}
-
 double opt_mesh_smooth_normals(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
diff --git a/Common/Options.h b/Common/Options.h
index d337f7e8dc..7fedde7665 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -446,7 +446,6 @@ double opt_mesh_volumes_num(OPT_ARGS_NUM);
 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_reverse_all_normals(OPT_ARGS_NUM);
 double opt_mesh_smooth_normals(OPT_ARGS_NUM);
 double opt_mesh_smooth_ratio(OPT_ARGS_NUM);
 double opt_mesh_angle_smooth_normals(OPT_ARGS_NUM);
diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index a3b94ee77e..9d4a4b5b04 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -693,11 +693,6 @@ int FlGui::testGlobalShortcuts(int event)
           (i, GMSH_SET | GMSH_GUI, !opt_view_light(i, GMSH_GET, 0));
     status = 2;
   }
-  else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'w')) {
-    opt_mesh_reverse_all_normals
-      (0, GMSH_SET | GMSH_GUI, !opt_mesh_reverse_all_normals(0, GMSH_GET, 0));
-    status = 2;
-  }
   else if(Fl::test_shortcut(FL_ALT + 'x') ||
           Fl::test_shortcut(FL_ALT + FL_SHIFT + 'x')) {
     status_xyz1p_cb(0, (void *)"x");
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 9e5808ccfd..8756a4a3e2 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -475,7 +475,6 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data)
   optionWindow *o = FlGui::instance()->options;
   o->activate((const char*)data);
 
-  opt_mesh_reverse_all_normals(0, GMSH_SET, o->mesh.butt[0]->value());
   opt_mesh_lc_from_curvature(0, GMSH_SET, o->mesh.butt[1]->value());
   opt_mesh_lc_from_points(0, GMSH_SET, o->mesh.butt[5]->value());
   opt_mesh_lc_extend_from_boundary(0, GMSH_SET, o->mesh.butt[16]->value());
@@ -2644,19 +2643,13 @@ optionWindow::optionWindow(int deltaFontSize)
       mesh.butt[18]->type(FL_TOGGLE_BUTTON);
       mesh.butt[18]->callback(mesh_options_ok_cb);
 
-      mesh.butt[0] = new Fl_Check_Button
-        (L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Reverse all normals");
-      mesh.butt[0]->tooltip("(Alt+Shift+w)");
-      mesh.butt[0]->type(FL_TOGGLE_BUTTON);
-      mesh.butt[0]->callback(mesh_options_ok_cb);
-
       mesh.butt[19] = new Fl_Check_Button
-        (L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Smooth normals");
+        (L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Smooth normals");
       mesh.butt[19]->type(FL_TOGGLE_BUTTON);
       mesh.butt[19]->callback(mesh_options_ok_cb);
 
       mesh.value[18] = new Fl_Value_Input
-        (L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Smoothing threshold angle");
+        (L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Smoothing threshold angle");
       mesh.value[18]->minimum(0.);
       mesh.value[18]->maximum(180.);
       mesh.value[18]->step(1.);
@@ -2672,17 +2665,17 @@ optionWindow::optionWindow(int deltaFontSize)
         {0}
       };
       mesh.choice[4] = new Fl_Choice
-        (L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Coloring mode");
+        (L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Coloring mode");
       mesh.choice[4]->menu(menu_mesh_color);
       mesh.choice[4]->align(FL_ALIGN_RIGHT);
       mesh.choice[4]->callback(mesh_options_ok_cb);
 
       Fl_Scroll *s = new Fl_Scroll
-        (L + 2 * WB, 3 * WB + 8 * BH, IW + 20, height - 5 * WB - 8 * BH);
+        (L + 2 * WB, 3 * WB + 7 * BH, IW + 20, height - 5 * WB - 7 * BH);
       int i = 0;
       while(MeshOptions_Color[i].str) {
         mesh.color[i] = new Fl_Button
-          (L + 2 * WB, 3 * WB + (8 + i) * BH, IW, BH, MeshOptions_Color[i].str);
+          (L + 2 * WB, 3 * WB + (7 + i) * BH, IW, BH, MeshOptions_Color[i].str);
         mesh.color[i]->callback(color_cb, (void *)MeshOptions_Color[i].function);
         i++;
       }
@@ -3986,14 +3979,12 @@ void optionWindow::activate(const char *what)
       mesh.butt[18]->activate();
       mesh.butt[19]->activate();
       mesh.choice[10]->activate();
-      mesh.butt[0]->activate();
       mesh.value[18]->activate();
     }
     else{
       mesh.butt[18]->deactivate();
       mesh.butt[19]->deactivate();
       mesh.choice[10]->deactivate();
-      mesh.butt[0]->deactivate();
       mesh.value[18]->deactivate();
     }
   }
diff --git a/Geo/MFace.cpp b/Geo/MFace.cpp
index b7a0d72254..077247038a 100644
--- a/Geo/MFace.cpp
+++ b/Geo/MFace.cpp
@@ -8,19 +8,18 @@
 #include "GmshConfig.h"
 #include "MFace.h"
 #include "Numeric.h"
-#include "Context.h"
 
-bool compare (MVertex* v0, MVertex* v1) {return v0->getNum() < v1->getNum();}
+bool compare(MVertex* v0, MVertex* v1){ return v0->getNum() < v1->getNum(); }
 
 void sortVertices(const std::vector<MVertex*> &v, std::vector<char> &s)
 {
   if (v.size() == 3){
-    s.resize(3); 
-    if (v[0]->getNum() < v[1]->getNum() && 
+    s.resize(3);
+    if (v[0]->getNum() < v[1]->getNum() &&
 	v[0]->getNum() < v[2]->getNum() ){
       s[0] = 0; s[1] = 1; s[2] = 2;
     }
-    else if (v[1]->getNum() < v[0]->getNum() && 
+    else if (v[1]->getNum() < v[0]->getNum() &&
 	     v[1]->getNum() < v[2]->getNum() ){
       s[0] = 1; s[1] = 0; s[2] = 2;
     }
@@ -30,75 +29,27 @@ void sortVertices(const std::vector<MVertex*> &v, std::vector<char> &s)
 
     if (v[s[2]]->getNum() < v[s[1]]->getNum()){
       char temp = s[1];
-      s[1]=s[2];
-      s[2]=temp;
+      s[1] = s[2];
+      s[2] = temp;
     }
-    return;    
+    return;
   }
 
-  
   std::vector<MVertex*> sorted = v;
   std::sort(sorted.begin(), sorted.end(), compare);
   for(unsigned int i = 0; i < sorted.size(); i++)
     s.push_back(std::distance(v.begin(), std::find(v.begin(), v.end(), sorted[i])));
 }
 
-MFace::MFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3) 
+MFace::MFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3)
 {
   _v.push_back(v0);
-  if(CTX::instance()->mesh.reverseAllNormals){
-    // Note that we cannot simply change the normal computation,
-    // since OpenGL wants the normal to a polygon to be coherent
-    // with the ordering of its vertices
-    if(v3) _v.push_back(v3);
-    _v.push_back(v2);
-    _v.push_back(v1);
-  }
-  else{
-    _v.push_back(v1);
-    _v.push_back(v2);
-    if(v3) _v.push_back(v3);
-  }
+  _v.push_back(v1);
+  _v.push_back(v2);
+  if(v3) _v.push_back(v3);
   sortVertices(_v, _si);
-  /*// This is simply an unrolled insertion sort (hopefully fast).  Note that if
-  // _v[3] == 0, _v[3] is not sorted.
-  if(_v[1] < _v[0]) {
-    _si[0] = 1;
-    _si[1] = 0;
-  }
-  else {
-    _si[0] = 0;
-    _si[1] = 1;
-  }
-  if(_v[2] < _v[int(_si[1])]) {
-    _si[2] = _si[1];
-    if(_v[2] < _v[int(_si[0])]) {
-      _si[1] = _si[0];
-      _si[0] = 2;
-    }
-    else
-      _si[1] = 2;
-  }
-  else
-    _si[2] = 2;
-  if( _v[3] && _v[3] < _v[int(_si[2])]) {
-    _si[3] = _si[2];
-    if(_v[3] < _v[int(_si[1])]) {
-      _si[2] = _si[1];
-      if(_v[3] < _v[int(_si[0])]) {
-        _si[1] = _si[0];
-        _si[0] = 3;
-      }
-      else
-        _si[1] = 3;
-    }
-    else
-      _si[2] = 3;
-  }
-  else
-    _si[3] = 3;*/
-    
 }
+
 MFace::MFace(std::vector<MVertex*> v)
 {
   for(unsigned int i = 0; i < v.size(); i++)
@@ -115,13 +66,13 @@ SVector3 MFace::normal() const
   return SVector3(n[0], n[1], n[2]);
 }
 
-bool MFace::computeCorrespondence(const MFace &other, 
-                                  int &rotation, 
+bool MFace::computeCorrespondence(const MFace &other,
+                                  int &rotation,
                                   bool &swap) const
 {
   rotation = 0;
   swap = false;
-  
+
   if (*this == other) {
     for (int i = 0; i < getNumVertices(); i++) {
       if (_v[0] == other.getVertex(i)) {
@@ -135,5 +86,3 @@ bool MFace::computeCorrespondence(const MFace &other,
   }
   return false;
 }
-
-  
diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp
index 4734f2471b..09752f732f 100644
--- a/Graphics/drawContext.cpp
+++ b/Graphics/drawContext.cpp
@@ -720,12 +720,13 @@ void drawContext::initRenderModel()
 
   glShadeModel(GL_SMOOTH);
 
-  // Normalize the normals automatically. We could use the more efficient
-  // glEnable(GL_RESCALE_NORMAL) instead (since we initially specify unit
-  // normals), but GL_RESCALE_NORMAL does only work with isotropic scalings (and
-  // we allow anistotropic scalings in myZoom). Note that GL_RESCALE_NORMAL is
-  // only available in GL_VERSION_1_2.
-  glEnable(GL_NORMALIZE);
+  // Normalize the normals automatically. Using glEnable(GL_RESCALE_NORMAL)
+  // instead of glEnable(GL_NORMALIZE) (since we initially specify unit normals)
+  // is more efficient, but will only work with isotropic scalings (and we allow
+  // anistotropic scalings in myZoom...). Note that GL_RESCALE_NORMAL is only
+  // available in GL_VERSION_1_2.
+  //glEnable(GL_NORMALIZE);
+  glEnable(GL_RESCALE_NORMAL);
 
   // lighting is enabled/disabled for each particular primitive later
   glDisable(GL_LIGHTING);
diff --git a/Graphics/drawGeom.cpp b/Graphics/drawGeom.cpp
index dc5081a027..3b4af79d85 100644
--- a/Graphics/drawGeom.cpp
+++ b/Graphics/drawGeom.cpp
@@ -53,6 +53,8 @@ class drawGVertex {
       glPushName(v->tag());
     }
 
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     double ps = CTX::instance()->geom.pointSize;
     double sps = CTX::instance()->geom.selectedPointSize;
     if(_ctx->isHighResolution()){
@@ -122,7 +124,7 @@ class drawGEdge {
     if(e->geomType() == GEntity::DiscreteCurve) return;
     if(e->geomType() == GEntity::PartitionCurve) return;
     if(e->geomType() == GEntity::BoundaryLayerCurve) return;
-    //    if(e->geomType() == GEntity::CompoundCurve) return;
+    // if(e->geomType() == GEntity::CompoundCurve) return;
 
     bool select = (_ctx->render_mode == drawContext::GMSH_SELECT &&
                    e->model() == GModel::current());
@@ -131,6 +133,8 @@ class drawGEdge {
       glPushName(e->tag());
     }
 
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     if(e->getSelection()) {
       glLineWidth((float)CTX::instance()->geom.selectedLineWidth);
       gl2psLineWidth((float)(CTX::instance()->geom.selectedLineWidth *
@@ -232,8 +236,9 @@ class drawGFace {
       glNormalPointer(GL_BYTE, 0, va->getNormalArray());
       glEnableClientState(GL_NORMAL_ARRAY);
     }
-    else
+    else{
       glDisableClientState(GL_NORMAL_ARRAY);
+    }
     if(forceColor){
       glDisableClientState(GL_COLOR_ARRAY);
       glColor4ubv((GLubyte *) & color);
@@ -242,11 +247,19 @@ class drawGFace {
       glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
       glEnableClientState(GL_COLOR_ARRAY);
     }
-    if(CTX::instance()->polygonOffset) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(CTX::instance()->geom.surfaceType > 1)
+    if(CTX::instance()->polygonOffset)
+      glEnable(GL_POLYGON_OFFSET_FILL);
+    if(CTX::instance()->geom.surfaceType > 1){
+      if(CTX::instance()->geom.lightTwoSide)
+        glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+      else
+        glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    else
+    }
+    else{
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    }
     glDrawArrays(GL_TRIANGLES, 0, va->getNumVertices());
     glDisable(GL_POLYGON_OFFSET_FILL);
     glDisable(GL_LIGHTING);
@@ -449,6 +462,11 @@ class drawGFace {
       glColor4ubv((GLubyte *) & CTX::instance()->color.geom.surface);
     }
 
+    if(CTX::instance()->geom.lightTwoSide)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+    else
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     if(f->geomType() == GEntity::CompoundSurface)
       _drawCompoundGFace(f);
     else if(f->geomType() == GEntity::Plane)
@@ -479,6 +497,11 @@ class drawGRegion {
       glPushName(r->tag());
     }
 
+    if(CTX::instance()->geom.lightTwoSide)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+    else
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     if(r->getSelection())
       glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection);
     else
@@ -510,11 +533,6 @@ void drawContext::drawGeom()
 {
   if(!CTX::instance()->geom.draw) return;
 
-  if(CTX::instance()->geom.lightTwoSide)
-    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-  else
-    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-
   for(int i = 0; i < 6; i++)
     if(CTX::instance()->geom.clip & (1 << i))
       glEnable((GLenum)(GL_CLIP_PLANE0 + i));
diff --git a/Graphics/drawMesh.cpp b/Graphics/drawMesh.cpp
index 4e03ad8042..eecb73db08 100644
--- a/Graphics/drawMesh.cpp
+++ b/Graphics/drawMesh.cpp
@@ -420,6 +420,8 @@ class drawMeshGVertex {
       glPushName(v->tag());
     }
 
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     if(CTX::instance()->mesh.points || CTX::instance()->mesh.pointsNum)
       drawVerticesPerEntity(_ctx, v);
 
@@ -454,6 +456,8 @@ class drawMeshGEdge {
       glPushName(e->tag());
     }
 
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     if(CTX::instance()->mesh.lines)
       drawArrays(_ctx, e, e->va_lines, GL_LINES, false);
 
@@ -501,9 +505,15 @@ class drawMeshGFace {
       glPushName(f->tag());
     }
 
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     drawArrays(_ctx, f, f->va_lines, GL_LINES,
                CTX::instance()->mesh.light && CTX::instance()->mesh.lightLines,
                CTX::instance()->mesh.surfacesFaces, CTX::instance()->color.mesh.line);
+
+    if(CTX::instance()->mesh.lightTwoSide)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+
     drawArrays(_ctx, f, f->va_triangles, GL_TRIANGLES, CTX::instance()->mesh.light);
 
     if(CTX::instance()->mesh.surfacesNum) {
@@ -569,9 +579,15 @@ class drawMeshGRegion {
       glPushName(r->tag());
     }
 
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     drawArrays(_ctx, r, r->va_lines, GL_LINES, CTX::instance()->mesh.light &&
                (CTX::instance()->mesh.lightLines > 1), CTX::instance()->mesh.volumesFaces,
                CTX::instance()->color.mesh.line);
+
+    if(CTX::instance()->mesh.lightTwoSide)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+
     drawArrays(_ctx, r, r->va_triangles, GL_TRIANGLES, CTX::instance()->mesh.light);
 
     if(CTX::instance()->mesh.volumesNum) {
@@ -675,11 +691,6 @@ void drawContext::drawMesh()
   gl2psLineWidth((float)(CTX::instance()->mesh.lineWidth *
                          CTX::instance()->print.epsLineWidthFactor));
 
-  if(CTX::instance()->mesh.lightTwoSide)
-    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-  else
-    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-
   if(!CTX::instance()->clipWholeElements){
     for(int i = 0; i < 6; i++)
       if(CTX::instance()->mesh.clip & (1 << i))
diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp
index b35bffe084..9a13e32886 100644
--- a/Graphics/drawPost.cpp
+++ b/Graphics/drawPost.cpp
@@ -427,11 +427,6 @@ class drawPView {
     gl2psLineWidth((float)(opt->lineWidth *
                            CTX::instance()->print.epsLineWidthFactor));
 
-    if(opt->lightTwoSide)
-      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-    else
-      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-
     if(opt->axes && opt->type == PViewOptions::Plot3D){
       glColor4ubv((GLubyte *) & opt->color.axes);
       glLineWidth((float)CTX::instance()->lineWidth);
@@ -491,8 +486,14 @@ class drawPView {
     }
 
     // draw all the vertex arrays
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
     drawArrays(_ctx, p, p->va_points, GL_POINTS, false);
     drawArrays(_ctx, p, p->va_lines, GL_LINES, opt->light && opt->lightLines);
+
+    if(opt->lightTwoSide)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+
     drawArrays(_ctx, p, p->va_triangles, GL_TRIANGLES, opt->light);
 
     // draw the "pseudo" vertex arrays for vectors
-- 
GitLab