diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 185f59d528b90477b2c64ceb703b09e1650f3303..07ee4658cfd1f70d86642aa2a8771dc886cd3a92 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -455,6 +455,8 @@ StringXNumber ViewOptions_Number[] = {
     "Draw the N-b dimensional boundary of the simplex (N=dimension, b=option value" },
   { F|O, "Light" , opt_view_light , 0. ,
     "Enable light sources?" },
+  { F|O, "SmoothNormals" , opt_view_smooth_normals , 1. ,
+    "Smooth the normals?" },
   { F|O, "ShowElement" , opt_view_show_element , 0. ,
     "Show element boundaries?" },
   { F|O, "ShowTime" , opt_view_show_time , 1. ,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 2fa37877de494bc3560ce620c223532f228834e2..c3e6ac5574fe0e1ff0993eac09b95ee5bfb17742 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.33 2001-07-26 18:47:59 remacle Exp $
+// $Id: Options.cpp,v 1.34 2001-07-30 18:34:26 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -1781,6 +1781,18 @@ double opt_view_light(OPT_ARGS_NUM){
 #endif
   return v->Light;
 }
+double opt_view_smooth_normals(OPT_ARGS_NUM){
+  GET_VIEW(0.) ;
+  if(action & GMSH_SET){
+    v->SmoothNormals = (int)val;
+    v->Changed = 1;
+  }
+#ifdef _FLTK
+  if(WID && (action & GMSH_GUI) && (num == WID->view_number))
+    WID->view_butt[27]->value(v->SmoothNormals);
+#endif
+  return v->SmoothNormals;
+}
 double opt_view_show_element(OPT_ARGS_NUM){
   GET_VIEW(0.) ;
   if(action & GMSH_SET){
diff --git a/Common/Options.h b/Common/Options.h
index 5ece8dc31ca999b0766d25b3c60e3b9f25d3137d..cee1623d93f561a9c3c3b8452557f6c423ebf4c6 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -209,6 +209,7 @@ double opt_view_saturate_values(OPT_ARGS_NUM);
 double opt_view_nb_iso(OPT_ARGS_NUM);
 double opt_view_boundary(OPT_ARGS_NUM);
 double opt_view_light(OPT_ARGS_NUM);
+double opt_view_smooth_normals(OPT_ARGS_NUM);
 double opt_view_show_element(OPT_ARGS_NUM);
 double opt_view_show_time(OPT_ARGS_NUM);
 double opt_view_show_scale(OPT_ARGS_NUM);
diff --git a/Common/Views.cpp b/Common/Views.cpp
index 1aac93252ce7972ef3b3e29954b58f849adcff04..cf70495d9747f87d38b44da88b9940607f8b6c1d 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.42 2001-07-26 21:45:48 remacle Exp $
+// $Id: Views.cpp,v 1.43 2001-07-30 18:34:26 geuzaine Exp $
 
 #include <set>
 #include "Gmsh.h"
@@ -409,6 +409,7 @@ void CopyViewOptions(Post_View *src, Post_View *dest){
   dest->Boundary = src->Boundary ;
   dest->NbIso = src->NbIso;
   dest->Light = src->Light ;
+  dest->SmoothNormals = src->SmoothNormals ;
   dest->ShowElement = src->ShowElement;
   dest->ShowTime = src->ShowTime;
   dest->ShowScale = src->ShowScale;
diff --git a/Common/Views.h b/Common/Views.h
index 895113ae96e3d21400ffeba0d75e92c507b494f3..d4d7d378197f44d0112d46b1414ba381fe3410ab 100644
--- a/Common/Views.h
+++ b/Common/Views.h
@@ -30,7 +30,7 @@ class Post_View{
   char   Format[NAME_STR_L];
   double CustomMin, CustomMax;
   double Offset[3], Raise[3], ArrowScale;
-  int Visible, IntervalsType, NbIso, Light ;
+  int Visible, IntervalsType, NbIso, Light, SmoothNormals ;
   int SaturateValues;
   int ShowElement, ShowTime, ShowScale;
   int TransparentScale, ScaleType, RangeType;
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 7f4de020d2dd135a605164f2006dc2eb40045e52..6076731ffc7a7da85b9f68331e1d88f03f103967 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.65 2001-07-26 18:47:59 remacle Exp $
+// $Id: Callbacks.cpp,v 1.66 2001-07-30 18:34:26 geuzaine Exp $
 
 #include <sys/types.h>
 #include <signal.h>
@@ -1679,6 +1679,7 @@ void view_options_ok_cb(CALLBACK_ARGS){
       opt_view_show_time(i, GMSH_SET, WID->view_butt[15]->value());
       opt_view_transparent_scale(i, GMSH_SET, WID->view_butt[16]->value());
       opt_view_light(i,GMSH_SET,WID->view_butt[17]->value());
+      opt_view_smooth_normals(i,GMSH_SET,WID->view_butt[27]->value());
       opt_view_draw_points(i, GMSH_SET, WID->view_butt[18]->value());
       opt_view_draw_lines(i, GMSH_SET, WID->view_butt[19]->value());
       opt_view_draw_triangles(i, GMSH_SET, WID->view_butt[20]->value());
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index f25c56c6efbd66cdb244a26b149bf79287268ece..b4105c02efac3d353251f2da61013be2e1f27c07 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.92 2001-07-26 21:36:31 remacle Exp $
+// $Id: GUI.cpp,v 1.93 2001-07-30 18:34:26 geuzaine Exp $
 
 // To make the interface as visually consistent as possible, please:
 // - use the BH, BW, WB, IW values for button heights/widths, window borders, etc.
@@ -1899,7 +1899,13 @@ void GUI::create_view_options_window(int num){
         view_butt[14] = new Fl_Check_Button(2*WB, 2*WB+2*BH, BW, BH, "Show color bar");
         view_butt[15] = new Fl_Check_Button(2*WB, 2*WB+3*BH, BW, BH, "Display time");
         view_butt[16] = new Fl_Check_Button(2*WB, 2*WB+4*BH, BW, BH, "Transparent color bar");
-	view_butt[17] = new Fl_Check_Button(2*WB, 2*WB+5*BH, IW, BH, "Enable Lighting");
+	view_butt[17] = new Fl_Check_Button(2*WB, 2*WB+5*BH, BW, BH, "Enable Lighting");
+
+	view_butt[27] = new Fl_Check_Button(2*WB, 2*WB+6*BH, BW, BH, "Smooth normals");	
+	view_butt[27]->type(FL_TOGGLE_BUTTON);
+	view_butt[27]->down_box(FL_DOWN_BOX);
+	view_butt[27]->labelsize(CTX.fontsize);
+	view_butt[27]->selection_color(FL_YELLOW);
 
         view_butt[18] = new Fl_Check_Button(width/2, 2*WB+1*BH, BW, BH, "Draw points");
         view_butt[19] = new Fl_Check_Button(width/2, 2*WB+2*BH, BW, BH, "Draw lines");
@@ -1915,13 +1921,15 @@ void GUI::create_view_options_window(int num){
 	  view_butt[i]->labelsize(CTX.fontsize);
 	  view_butt[i]->selection_color(FL_YELLOW);
 	}
-	view_input[0] = new Fl_Input(2*WB, 2*WB+6*BH, IW, BH, "Name");
-	view_input[1] = new Fl_Input(2*WB, 2*WB+7*BH, IW, BH, "Format");
+
+	view_input[0] = new Fl_Input(2*WB, 2*WB+7*BH, IW, BH, "Name");
+	view_input[1] = new Fl_Input(2*WB, 2*WB+8*BH, IW, BH, "Format");
 	for(i=0 ; i<2 ; i++){
 	  view_input[i]->labelsize(CTX.fontsize);
 	  view_input[i]->textsize(CTX.fontsize);
 	  view_input[i]->align(FL_ALIGN_RIGHT);
 	}
+
         o->end();
       }
       // Range
@@ -2186,6 +2194,7 @@ void GUI::update_view_window(int num){
 
   // light
   opt_view_light(num, GMSH_GUI, 0);
+  opt_view_smooth_normals(num, GMSH_GUI, 0);
 
   // OK
   view_ok->callback(view_options_ok_cb, (void*)num);
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 678fad3abd9a5e5f84706680e3c5df255334cfd5..e269d2647eb21d0db4d8ff1b2329d1975064b231 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -158,7 +158,7 @@ public:
   int init_view_window, view_number ;
   Fl_Window        *view_window ;
   Fl_Group         *view_timestep, *view_vector ;
-  Fl_Check_Button  *view_butt[30] ;
+  Fl_Check_Button  *view_butt[50] ;
   Fl_Value_Input   *view_value[20] ;
   Fl_Input         *view_input[20] ;
   Colorbar_Window  *view_colorbar_window ;
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index e096ba105d79885678cdeb244a1627ee72de034c..8c4a55445b0974dbf9183d17e4764be8f1587bd8 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -94,7 +94,7 @@ void Draw_VectorLine(Post_View *View,
 void Draw_TensorLine(Post_View *View, 
 		     double ValMin, double ValMax, double Raise[3][5],
 		     double *X, double *Y, double *Z, double *V);
-void Draw_ScalarTriangle(Post_View *View, 
+void Draw_ScalarTriangle(Post_View *View, int preproNormals,
 			 double ValMin, double ValMax, double Raise[3][5],
 			 double *X, double *Y, double *Z, double *V);
 void Draw_VectorTriangle(Post_View *View, 
@@ -103,8 +103,7 @@ void Draw_VectorTriangle(Post_View *View,
 void Draw_TensorTriangle(Post_View *View, 
 			 double ValMin, double ValMax, double Raise[3][5],
 			 double *X, double *Y, double *Z, double *V);
-void Draw_ScalarTetrahedron(Post_View *View, 
-			    int preproNormals,
+void Draw_ScalarTetrahedron(Post_View *View, int preproNormals,
 			    double ValMin, double ValMax, double Raise[3][5],
 			    double *X, double *Y, double *Z, double *V);
 void Draw_VectorTetrahedron(Post_View *View, 
diff --git a/Graphics/Entity.cpp b/Graphics/Entity.cpp
index 101ce39cd8e33e30a94b2c9f2ba7d67d786aade6..056b3856d3db2001dc5de3894bce42578bc7e045 100644
--- a/Graphics/Entity.cpp
+++ b/Graphics/Entity.cpp
@@ -1,4 +1,4 @@
-// $Id: Entity.cpp,v 1.8 2001-04-08 20:36:49 geuzaine Exp $
+// $Id: Entity.cpp,v 1.9 2001-07-30 18:34:26 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -48,42 +48,35 @@ void Draw_Triangle (double *x, double *y, double *z, double *n,
 
   glBegin(GL_TRIANGLES);
   if (shade){
-    if(!n)
-      {
-	x1x0 = (x[1]+Raise[0][1]) - (x[0]+Raise[0][0]); 
-	y1y0 = (y[1]+Raise[1][1]) - (y[0]+Raise[1][0]);
-	z1z0 = (z[1]+Raise[2][1]) - (z[0]+Raise[2][0]); 
-	x2x0 = (x[2]+Raise[0][2]) - (x[0]+Raise[0][0]);
-	y2y0 = (y[2]+Raise[1][2]) - (y[0]+Raise[1][0]); 
-	z2z0 = (z[2]+Raise[2][2]) - (z[0]+Raise[2][0]);
-	nn[0]  = y1y0 * z2z0 - z1z0 * y2y0 ;
-	nn[1]  = z1z0 * x2x0 - x1x0 * z2z0 ;
-	nn[2]  = x1x0 * y2y0 - y1y0 * x2x0 ;
-      }
-  }
-
-  if (shade){
-    if(!n)
+    if(!n){
+      x1x0 = (x[1]+Raise[0][1]) - (x[0]+Raise[0][0]); 
+      y1y0 = (y[1]+Raise[1][1]) - (y[0]+Raise[1][0]);
+      z1z0 = (z[1]+Raise[2][1]) - (z[0]+Raise[2][0]); 
+      x2x0 = (x[2]+Raise[0][2]) - (x[0]+Raise[0][0]);
+      y2y0 = (y[2]+Raise[1][2]) - (y[0]+Raise[1][0]); 
+      z2z0 = (z[2]+Raise[2][2]) - (z[0]+Raise[2][0]);
+      nn[0]  = y1y0 * z2z0 - z1z0 * y2y0 ;
+      nn[1]  = z1z0 * x2x0 - x1x0 * z2z0 ;
+      nn[2]  = x1x0 * y2y0 - y1y0 * x2x0 ;
       glNormal3dv(nn);
+    }
     else
       glNormal3dv(&n[0]);
   }
-
+  
   glVertex3d(x[0]+Offset[0]+Raise[0][0],
              y[0]+Offset[1]+Raise[1][0],
              z[0]+Offset[2]+Raise[2][0]);
 
-  if (shade && n){
+  if (shade && n)
     glNormal3dv(&n[3]);
-  }
 
   glVertex3d(x[1]+Offset[0]+Raise[0][1],
              y[1]+Offset[1]+Raise[1][1],
              z[1]+Offset[2]+Raise[2][1]);
 
-  if (shade && n){
+  if (shade && n)
     glNormal3dv(&n[6]);
-  }
 
   glVertex3d(x[2]+Offset[0]+Raise[0][2],
              y[2]+Offset[1]+Raise[1][2],
@@ -103,30 +96,27 @@ void Draw_Quadrangle (double *x, double *y, double *z, double *n,
     I think this gives better results
   */
   
-
   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,Offset,Raise,shade);
-  if (n)
-    {
-      double n2[9]; 
-      n2[0] = n[6];
-      n2[1] = n[7];
-      n2[2] = n[8];
-      n2[3] = n[9];
-      n2[4] = n[10];
-      n2[5] = n[11];
-      n2[6] = n[0];
-      n2[7] = n[1];
-      n2[8] = n[2];
-      Draw_Triangle(x2,y2,z2,n2,Offset,Raise,shade);
-    }
+  if (n){
+    double n2[9]; 
+    n2[0] = n[6];
+    n2[1] = n[7];
+    n2[2] = n[8];
+    n2[3] = n[9];
+    n2[4] = n[10];
+    n2[5] = n[11];
+    n2[6] = n[0];
+    n2[7] = n[1];
+    n2[8] = n[2];
+    Draw_Triangle(x2,y2,z2,n2,Offset,Raise,shade);
+  }
   else
     Draw_Triangle(x2,y2,z2,n,Offset,Raise,shade);
 
-
-  return;
 }
 
 /* ------------------------------------------------------------------------ */
diff --git a/Graphics/IsoSimplex.cpp b/Graphics/IsoSimplex.cpp
index 403841ff35bf00824485aaab852954805b7dfaab..1bd7ee030ba6e4b7d76f7ef8725c1c219d42a96b 100644
--- a/Graphics/IsoSimplex.cpp
+++ b/Graphics/IsoSimplex.cpp
@@ -10,11 +10,9 @@
 
 extern Context_T   CTX;
 
-/*
-  compute the gradient of a linear interpolation in a tetrahedron
-*/
-void gradSimplex (double *x, double *y, double *z, double *v, double *grad)
-{
+// compute the gradient of a linear interpolation in a tetrahedron
+
+void gradSimplex (double *x, double *y, double *z, double *v, double *grad){
   /*
     p = p1 * (1-u-v-w) + p2 u + p3 v + p4 w
    */
@@ -36,10 +34,6 @@ void gradSimplex (double *x, double *y, double *z, double *v, double *grad)
   sys3x3 (mat, b, grad, &det); 
 }
 
-/* ------------------------------------------------------------------------ */
-/*  S i m p l e x                                                           */
-/* ------------------------------------------------------------------------ */
-
 void EnhanceSimplexPolygon (Post_View *View,
 			    int nb, // nb of points in polygon 
 			    double *Xp, // x positions
@@ -52,8 +46,7 @@ void EnhanceSimplexPolygon (Post_View *View,
 			    double *Val, // values at simplex points
 			    double *norms, // output : normals at points
 			    int preproNormals  // do we compute normals or do we get them
-			    )
-{
+			    ){
   /*
     3 possibilities for quads
       -) 0,2,5,3
@@ -65,18 +58,17 @@ void EnhanceSimplexPolygon (Post_View *View,
   int i;
   double Xpi[6],Ypi[6],Zpi[6];
 
-  if(nb == 4)
-    {
-      double xx =  Xp[3];
-      double yy =  Yp[3];
-      double zz =  Zp[3];
-      Xp[3] = Xp[2]; 
-      Yp[3] = Yp[2]; 
-      Zp[3] = Zp[2];
-      Xp[2] = xx;
-      Yp[2] = yy;
-      Zp[2] = zz;
-    }
+  if(nb == 4){
+    double xx =  Xp[3];
+    double yy =  Yp[3];
+    double zz =  Zp[3];
+    Xp[3] = Xp[2]; 
+    Yp[3] = Yp[2]; 
+    Zp[3] = Zp[2];
+    Xp[2] = xx;
+    Yp[2] = yy;
+    Zp[2] = zz;
+  }
 
   /*
     for having a nice isosurface, we should have n . grad v > 0
@@ -84,6 +76,11 @@ void EnhanceSimplexPolygon (Post_View *View,
     v = unknown field we wanna draw
    */
 
+  if(!View->Light){
+    norms = NULL; // we don't need to compute these
+    return;
+  }
+
   double v1[3] = {Xp[2]-Xp[0],Yp[2]-Yp[0],Zp[2]-Zp[0]};
   double v2[3] = {Xp[1]-Xp[0],Yp[1]-Yp[0],Zp[1]-Zp[0]};
   double gr[3];
@@ -93,49 +90,50 @@ void EnhanceSimplexPolygon (Post_View *View,
   gradSimplex(X,Y,Z,Val,gr);      
   prosca(gr,n,&xx);
   
-  if(xx > 0)
-    {
-      for(i=0;i<nb;i++)
-	{
-	  Xpi[i] = Xp[i];
-	  Ypi[i] = Yp[i];
-	  Zpi[i] = Zp[i];
-	}
-      for(i=0;i<nb;i++)
-	{
-	  Xp[i] = Xpi[nb-i-1];
-	  Yp[i] = Ypi[nb-i-1];
-	  Zp[i] = Zpi[nb-i-1];	      
-	}
-    }
-  else
-    {
-      n[0] = -n[0];
-      n[1] = -n[1];
-      n[2] = -n[2];
-    }
-
-  if(preproNormals)
-    {
-      for(i=0;i<nb;i++)
-	{
-	  View->add_normal(Xp[i],Yp[i],Zp[i],n[0],n[1],n[2]);
-	}
+  if(xx > 0){
+    for(i=0;i<nb;i++){
+      Xpi[i] = Xp[i];
+      Ypi[i] = Yp[i];
+      Zpi[i] = Zp[i];
+    }
+    for(i=0;i<nb;i++){
+      Xp[i] = Xpi[nb-i-1];
+      Yp[i] = Ypi[nb-i-1];
+      Zp[i] = Zpi[nb-i-1];	      
+    }
+  }
+  else{
+    n[0] = -n[0];
+    n[1] = -n[1];
+    n[2] = -n[2];
+  }
+  
+  if(View->SmoothNormals){
+    if(preproNormals){
+      for(i=0;i<nb;i++){
+	View->add_normal(Xp[i],Yp[i],Zp[i],n[0],n[1],n[2]);
+      }
       return;
     }
-  else
-    {
-      for(i=0;i<nb;i++)
-	{
-	  if(!View->get_normal(Xp[i],Yp[i],Zp[i],norms[3*i],norms[3*i+1],norms[3*i+2]))
-	    {
-	      //printf("coucou\n");
-	      norms[3*i] = n[0];
-	      norms[3*i+1] = n[1];
-	      norms[3*i+2] = n[2];
-	    }	      
-	}	  
-    }  
+    else{
+      for(i=0;i<nb;i++){
+	if(!View->get_normal(Xp[i],Yp[i],Zp[i],norms[3*i],norms[3*i+1],norms[3*i+2])){
+	  //Msg(WARNING, "Oups, did not find smoothed normal");
+	  norms[3*i] = n[0];
+	  norms[3*i+1] = n[1];
+	  norms[3*i+2] = n[2];
+	}	      
+      }	  
+    }
+  }
+  else{
+    for(i=0;i<nb;i++){
+      norms[3*i] = n[0];
+      norms[3*i+1] = n[1];
+      norms[3*i+2] = n[2];
+    }
+  }
+
 }
 
 
@@ -143,7 +141,7 @@ void IsoSimplex( Post_View *View,
 		 int preproNormals,
 		 double *X, double *Y, double *Z, double *Val, 
 		 double V, double Vmin, double Vmax, 
-		 double *Offset, double Raise[3][5], int shade){
+		 double *Offset, double Raise[3][5]){
   int    nb;
   double Xp[6],Yp[6],Zp[6],PVals[6];
   double norms[12];
@@ -198,8 +196,8 @@ void IsoSimplex( Post_View *View,
   if(preproNormals)return;
 
   if(nb == 3) 
-    Draw_Triangle(Xp,Yp,Zp,norms,Offset,Raise,shade);
+    Draw_Triangle(Xp,Yp,Zp,norms,Offset,Raise,View->Light);
   else if(nb == 4)
-    Draw_Quadrangle(Xp,Yp,Zp,norms,Offset,Raise,shade);  
+    Draw_Quadrangle(Xp,Yp,Zp,norms,Offset,Raise,View->Light);  
 }
 
diff --git a/Graphics/IsoSimplex.h b/Graphics/IsoSimplex.h
index bc76112bc9bb5369c35324add006f7193c23ec1e..79fc9e3f00230e7285d7b7bf8b59a5b099c8c4ee 100644
--- a/Graphics/IsoSimplex.h
+++ b/Graphics/IsoSimplex.h
@@ -6,5 +6,5 @@ void IsoSimplex (Post_View *View,
 		 int preproNormals,
 		 double *X, double *Y, double *Z, double *Val,
                  double V, double Vmin, double Vmax,
-                 double *Offset, double Raise[3][5], int shade);
+                 double *Offset, double Raise[3][5]);
 #endif
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 0c11832ab2c6df07d23c1ce0fc21bbb94d058428..8b1fe07a20001e663a1aa4e27c7dd181d157c82d 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.17 2001-07-26 18:47:59 remacle Exp $
+// $Id: Post.cpp,v 1.18 2001-07-30 18:34:26 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -159,7 +159,7 @@ void Draw_Post (void) {
 
         if(CTX.display_lists){
           if(glIsList(v->Num)) glDeleteLists(v->Num,1);
-          // Msg(STATUS2, "New Display List");
+          Msg(DEBUG, "New Display List");
           glNewList(v->Num, GL_COMPILE_AND_EXECUTE);
         }
 
@@ -274,12 +274,28 @@ void Draw_Post (void) {
 	
 	if(v->NbST && v->DrawTriangles && v->DrawScalars){
 	  nb = List_Nbr(v->ST) / v->NbST ;
-	  for(i = 0 ; i < List_Nbr(v->ST) ; i+=nb)
-	    Draw_ScalarTriangle(v, ValMin, ValMax, Raise,
-				(double*)List_Pointer_Fast(v->ST,i),
-				(double*)List_Pointer_Fast(v->ST,i+3),
-				(double*)List_Pointer_Fast(v->ST,i+6),
-				(double*)List_Pointer_Fast(v->ST,i+9));
+	  if(v->Light && v->SmoothNormals){ //two passes 
+	    for(i = 0 ; i < List_Nbr(v->ST) ; i+=nb)
+	      Draw_ScalarTriangle(v, 1, ValMin, ValMax, Raise,
+				  (double*)List_Pointer_Fast(v->ST,i),
+				  (double*)List_Pointer_Fast(v->ST,i+3),
+				  (double*)List_Pointer_Fast(v->ST,i+6),
+				  (double*)List_Pointer_Fast(v->ST,i+9));
+	    for(i = 0 ; i < List_Nbr(v->ST) ; i+=nb)
+	      Draw_ScalarTriangle(v, 0, ValMin, ValMax, Raise,
+				  (double*)List_Pointer_Fast(v->ST,i),
+				  (double*)List_Pointer_Fast(v->ST,i+3),
+				  (double*)List_Pointer_Fast(v->ST,i+6),
+				  (double*)List_Pointer_Fast(v->ST,i+9));
+	  }
+	  else{
+	    for(i = 0 ; i < List_Nbr(v->ST) ; i+=nb)
+	      Draw_ScalarTriangle(v, 0, ValMin, ValMax, Raise,
+				  (double*)List_Pointer_Fast(v->ST,i),
+				  (double*)List_Pointer_Fast(v->ST,i+3),
+				  (double*)List_Pointer_Fast(v->ST,i+6),
+				  (double*)List_Pointer_Fast(v->ST,i+9));
+	  }
 	}
 	if(v->NbVT && v->DrawTriangles && v->DrawVectors){
 	  nb = List_Nbr(v->VT) / v->NbVT ;
@@ -313,18 +329,28 @@ void Draw_Post (void) {
 	
 	if(v->NbSS && v->DrawTetrahedra && v->DrawScalars){
 	  nb = List_Nbr(v->SS) / v->NbSS ;
-	  for(i = 0 ; i < List_Nbr(v->SS) ; i+=nb)
-	    Draw_ScalarTetrahedron(v, 1, ValMin, ValMax, Raise,
-				   (double*)List_Pointer_Fast(v->SS,i),
-				   (double*)List_Pointer_Fast(v->SS,i+4),
-				   (double*)List_Pointer_Fast(v->SS,i+8),
-				   (double*)List_Pointer_Fast(v->SS,i+12));
-	  for(i = 0 ; i < List_Nbr(v->SS) ; i+=nb)
-	    Draw_ScalarTetrahedron(v, 0, ValMin, ValMax, Raise,
-				   (double*)List_Pointer_Fast(v->SS,i),
-				   (double*)List_Pointer_Fast(v->SS,i+4),
-				   (double*)List_Pointer_Fast(v->SS,i+8),
-				   (double*)List_Pointer_Fast(v->SS,i+12));
+	  if(v->Light && v->SmoothNormals){ //two passes 
+	    for(i = 0 ; i < List_Nbr(v->SS) ; i+=nb)
+	      Draw_ScalarTetrahedron(v, 1, ValMin, ValMax, Raise,
+				     (double*)List_Pointer_Fast(v->SS,i),
+				     (double*)List_Pointer_Fast(v->SS,i+4),
+				     (double*)List_Pointer_Fast(v->SS,i+8),
+				     (double*)List_Pointer_Fast(v->SS,i+12));
+	    for(i = 0 ; i < List_Nbr(v->SS) ; i+=nb)
+	      Draw_ScalarTetrahedron(v, 0, ValMin, ValMax, Raise,
+				     (double*)List_Pointer_Fast(v->SS,i),
+				     (double*)List_Pointer_Fast(v->SS,i+4),
+				     (double*)List_Pointer_Fast(v->SS,i+8),
+				     (double*)List_Pointer_Fast(v->SS,i+12));
+	  }
+	  else{
+	    for(i = 0 ; i < List_Nbr(v->SS) ; i+=nb)
+	      Draw_ScalarTetrahedron(v, 0, ValMin, ValMax, Raise,
+				     (double*)List_Pointer_Fast(v->SS,i),
+				     (double*)List_Pointer_Fast(v->SS,i+4),
+				     (double*)List_Pointer_Fast(v->SS,i+8),
+				     (double*)List_Pointer_Fast(v->SS,i+12));
+	  }
 	}
 	if(v->NbVS && v->DrawTetrahedra && v->DrawVectors){
 	  nb = List_Nbr(v->VS) / v->NbVS ;
diff --git a/Graphics/PostSimplex.cpp b/Graphics/PostSimplex.cpp
index c5b086301340828455a6db1ab64b9c2211ee42e4..7fd02b74b69bab09eb1705e1684b9fe7285d693a 100644
--- a/Graphics/PostSimplex.cpp
+++ b/Graphics/PostSimplex.cpp
@@ -1,4 +1,4 @@
-// $Id: PostSimplex.cpp,v 1.18 2001-07-26 18:47:59 remacle Exp $
+// $Id: PostSimplex.cpp,v 1.19 2001-07-30 18:34:26 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -125,45 +125,35 @@ void Draw_ScalarLine(Post_View *View,
 
 }
 
-void Draw_ScalarTriangle(Post_View *View, 
+void Draw_ScalarTriangle(Post_View *View, int preproNormals,
 			 double ValMin, double ValMax, double Raise[3][5],
 			 double *X, double *Y, double *Z, double *V){
 
   int     i, k, nb=0;
   double  d;
-  double  x1x0, y1y0, z1z0, x2x0, y2y0, z2z0, nn[3];
+  double  x1x0, y1y0, z1z0, x2x0, y2y0, z2z0, nn[3], norms[9];
   double  Xp[5],Yp[5],Zp[5],Val[3],value[5],thev;
   char    Num[100] ;
 
-  /** JF 
-     Saturation of values 
-  */
-  {
-    double *vv = &V[3*View->TimeStep];
-    if(View->SaturateValues)
-      {
-	for(i=0;i<3;i++)
-	  {
-	    
-	    if(vv[i] > ValMax) Val[i] = ValMax;
-	    else if(vv[i] < ValMin) Val[i] = ValMin;
-	    else Val[i] = vv[i];
-	  }
-      }
-    else
-      {
-	for(i=0;i<3;i++)
-	  {	      
-	    Val[i] = vv[i];
-	  }
-      }
+  double *vv = &V[3*View->TimeStep];
+  if(View->SaturateValues){
+    for(i=0;i<3;i++){
+      if(vv[i] > ValMax) Val[i] = ValMax;
+      else if(vv[i] < ValMin) Val[i] = ValMin;
+      else Val[i] = vv[i];
+    }
+  }
+  else{
+    for(i=0;i<3;i++){	      
+      Val[i] = vv[i];
+    }
   }
-  /** - END JF - **/
 
   for(k=0 ; k<3 ; k++)
     RaiseFill(k, Val[k], ValMin, Raise);
 
   if(View->Light){
+
     x1x0 = (X[1]+Raise[0][1]) - (X[0]+Raise[0][0]); 
     y1y0 = (Y[1]+Raise[1][1]) - (Y[0]+Raise[1][0]);
     z1z0 = (Z[1]+Raise[2][1]) - (Z[0]+Raise[2][0]); 
@@ -173,9 +163,39 @@ void Draw_ScalarTriangle(Post_View *View,
     nn[0]  = y1y0 * z2z0 - z1z0 * y2y0 ;
     nn[1]  = z1z0 * x2x0 - x1x0 * z2z0 ;
     nn[2]  = x1x0 * y2y0 - y1y0 * x2x0 ;
+
+    if(View->SmoothNormals){
+      if(preproNormals){
+	for(i=0;i<3;i++){
+	  View->add_normal(X[i]+Raise[0][i],Y[i]+Raise[1][i],Z[i]+Raise[2][i],
+			   nn[0],nn[1],nn[2]);
+	}
+	return;
+      }
+      else{
+	for(i=0;i<3;i++){
+	  if(!View->get_normal(X[i]+Raise[0][i],Y[i]+Raise[1][i],Z[i]+Raise[2][i],
+			       norms[3*i],norms[3*i+1],norms[3*i+2])){
+	    //Msg(WARNING, "Oups, did not find smoothed normal");
+	    norms[3*i] = nn[0];
+	    norms[3*i+1] = nn[1];
+	    norms[3*i+2] = nn[2];
+	  }
+	}
+      }
+    }
+    else{
+      for(i=0;i<3;i++){
+	norms[3*i] = nn[0];
+	norms[3*i+1] = nn[1];
+	norms[3*i+2] = nn[2];
+      }
+    }
     glNormal3dv(nn);
   }
 
+  if(preproNormals) return;
+
   if(View->ShowElement){
     glColor4ubv((GLubyte*)&CTX.color.fg);
     glBegin(GL_LINE_LOOP);
@@ -210,14 +230,17 @@ void Draw_ScalarTriangle(Post_View *View,
          Val[2]>=ValMin && Val[2]<=ValMax){
         glBegin(GL_TRIANGLES);
 	Palette2(View,ValMin,ValMax,Val[0]);
+	glNormal3dv(&norms[0]);
         glVertex3d(X[0]+View->Offset[0]+Raise[0][0],
                    Y[0]+View->Offset[1]+Raise[1][0],
                    Z[0]+View->Offset[2]+Raise[2][0]);
 	Palette2(View,ValMin,ValMax,Val[1]);
+	glNormal3dv(&norms[3]);
         glVertex3d(X[1]+View->Offset[0]+Raise[0][1],
                    Y[1]+View->Offset[1]+Raise[1][1],
                    Z[1]+View->Offset[2]+Raise[2][1]);
 	Palette2(View,ValMin,ValMax,Val[2]);
+	glNormal3dv(&norms[6]);
         glVertex3d(X[2]+View->Offset[0]+Raise[0][2],
                    Y[2]+View->Offset[1]+Raise[1][2],
                    Z[2]+View->Offset[2]+Raise[2][2]);
@@ -271,22 +294,16 @@ void Draw_ScalarTriangle(Post_View *View,
     
 }
 
-void Draw_ScalarTetrahedron(Post_View *View,
-			    int preproNormals,
-			    double ValMin, 
-			    double ValMax, 
-			    double Raise[3][5],
-			    double *X, 
-			    double *Y, 
-			    double *Z, 
-			    double *V){
+void Draw_ScalarTetrahedron(Post_View *View, int preproNormals,
+			    double ValMin, double ValMax, double Raise[3][5],
+			    double *X, double *Y, double *Z, double *V){
 
   int     k,i;
-  double  d, xx[4], yy[4], zz[4], vv[4];
+  double  d, xx[4], yy[4], zz[4];
   char Num[100];
   double Val[4];
 
-  if(View->Boundary == 2){
+  if(!preproNormals && View->Boundary == 2){
     // boundary == 0 should draw the tet
     // boundary == 1 should draw the faces
     // boundary == 2 should draw the edges
@@ -295,46 +312,36 @@ void Draw_ScalarTetrahedron(Post_View *View,
     Draw_ScalarLine(View, ValMin, ValMax, Raise, &X[1], &Y[1], &Z[1], &V[1]);//12
     Draw_ScalarLine(View, ValMin, ValMax, Raise, &X[2], &Y[2], &Z[2], &V[2]);//23
     // beeek...
-    xx[0] = X[0]; yy[0] = Y[0]; zz[0] = Z[0]; vv[0] = V[0];
-    xx[1] = X[2]; yy[1] = Y[2]; zz[1] = Z[2]; vv[1] = V[2];
-    Draw_ScalarLine(View, ValMin, ValMax, Raise, xx, yy, zz, vv);//02
-    xx[1] = X[3]; yy[1] = Y[3]; zz[1] = Z[3]; vv[1] = V[3];
-    Draw_ScalarLine(View, ValMin, ValMax, Raise, xx, yy, zz, vv);//03
-    xx[0] = X[1]; yy[0] = Y[1]; zz[0] = Z[1]; vv[0] = V[1];
-    Draw_ScalarLine(View, ValMin, ValMax, Raise, xx, yy, zz, vv);//13
+    xx[0] = X[0]; yy[0] = Y[0]; zz[0] = Z[0]; Val[0] = V[0];
+    xx[1] = X[2]; yy[1] = Y[2]; zz[1] = Z[2]; Val[1] = V[2];
+    Draw_ScalarLine(View, ValMin, ValMax, Raise, xx, yy, zz, Val);//02
+    xx[1] = X[3]; yy[1] = Y[3]; zz[1] = Z[3]; Val[1] = V[3];
+    Draw_ScalarLine(View, ValMin, ValMax, Raise, xx, yy, zz, Val);//03
+    xx[0] = X[1]; yy[0] = Y[1]; zz[0] = Z[1]; Val[0] = V[1];
+    Draw_ScalarLine(View, ValMin, ValMax, Raise, xx, yy, zz, Val);//13
     return;
   }
 
-  /** JF 
-     Saturation of values 
-  */
-  {
-    double *vv = &V[4*View->TimeStep];
-    if(View->SaturateValues)
-      {
-	for(i=0;i<4;i++)
-	  {
-	    
-	    if(vv[i] > ValMax) Val[i] = ValMax;
-	    else if(vv[i] < ValMin) Val[i] = ValMin;
-	    else Val[i] = vv[i];
-	  }
-      }
-    else
-      {
-	for(i=0;i<4;i++)
-	  {	      
-	    Val[i] = vv[i];
-	  }
-      }
-  }
-  /** - END JF - **/
+  // Saturation of values 
 
+  double *vv = &V[4*View->TimeStep];
+  if(View->SaturateValues){
+    for(i=0;i<4;i++){
+      if(vv[i] > ValMax) Val[i] = ValMax;
+      else if(vv[i] < ValMin) Val[i] = ValMin;
+      else Val[i] = vv[i];
+    }
+  }
+  else{
+    for(i=0;i<4;i++){	      
+      Val[i] = vv[i];
+    }
+  }
 
   for(k=0 ; k<4 ; k++)
     RaiseFill(k, V[4*View->TimeStep+k], ValMin, Raise);
 
-  if(View->ShowElement){
+  if(!preproNormals && View->ShowElement){
     glColor4ubv((GLubyte*)&CTX.color.fg);
     for(k=0 ; k<4 ; k++){
       xx[k] = X[k]+View->Offset[0]+Raise[0][k] ;
@@ -351,7 +358,7 @@ void Draw_ScalarTetrahedron(Post_View *View,
     glEnd();
   }
 
-  if(View->IntervalsType == DRAW_POST_NUMERIC && !preproNormals){
+  if(!preproNormals && View->IntervalsType == DRAW_POST_NUMERIC){
 
     d = 0.25 * (Val[0]  +Val[1]+Val[2] + Val[3]);
     if(d >= ValMin && d <= ValMax){
@@ -369,11 +376,10 @@ void Draw_ScalarTetrahedron(Post_View *View,
   }
   else{
     for(k=0 ; k<View->NbIso ; k++){
-      if(!preproNormals)Palette(View,View->NbIso,k);
-      IsoSimplex(View,preproNormals,
-		 X, Y, Z, Val,
+      if(!preproNormals) Palette(View,View->NbIso,k);
+      IsoSimplex(View, preproNormals, X, Y, Z, Val,
 		 View->GVFI(ValMin,ValMax,View->NbIso,k), 
-		 ValMin, ValMax, View->Offset, Raise, View->Light);
+		 ValMin, ValMax, View->Offset, Raise);
     }
 
   }