diff --git a/Common/Views.cpp b/Common/Views.cpp
index ed1bd35e9dc597c65983858a210b1ef41345e55b..ab3d3ef00993894d162b065854fda23fe7447b65 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.25 2001-01-25 21:36:58 remacle Exp $
+// $Id: Views.cpp,v 1.26 2001-01-29 22:33:41 remacle Exp $
 
 #include <set>
 #include "Gmsh.h"
@@ -91,6 +91,7 @@ void BeginView(int allocate){
   ActualView->NbTimeStep = 0;
   ActualView->CT.size = 255;
   ActualView->CT.ipar[COLORTABLE_MODE] = COLORTABLE_RGB;
+  ActualView->normals = 0;
   ColorTable_InitParam(1, &ActualView->CT, 1, 1);
   ColorTable_Recompute(&ActualView->CT, 1, 1);
 }
@@ -325,7 +326,7 @@ void FreeView(Post_View *v){
     List_Delete(v->ST); List_Delete(v->VT); List_Delete(v->TT);
     List_Delete(v->SS); List_Delete(v->VS); List_Delete(v->TS);
   }
-
+  v->reset_normals();
 }
 
 void CopyViewOptions(Post_View *src, Post_View *dest){
@@ -682,6 +683,9 @@ void xyzv::update (int n, double *v)
     {
       throw n;
     }
+
+  //  if(n==3)printf("val(%d,%f,%f,%f) = %f %f %f\n",nboccurences,x,y,z,v[0],v[1],v[2]);
+
   double x1 = (double)(nboccurences)/ (double)(nboccurences + 1);
   double x2 = 1./(double)(nboccurences + 1);
   for(i=0;i<nbvals;i++)vals[i] = (x1 * vals[i] + x2 * v[i]);
@@ -702,80 +706,133 @@ struct lessthanxyzv
   }
 };
 
+typedef set<xyzv,lessthanxyzv> mycont;
+typedef mycont::const_iterator iter;
 
-void Post_View :: smooth ()
+class smooth_container 
 {
-  int i,nb,j;
-  xyzv::eps = CTX.lc * 1.e-6;
+public :
+  mycont c;
+};
+
+void smooth_list (List_T *SS ,
+		  int NbTimeStep,
+		  int nbvert,
+		  int nb, 
+		  mycont & connectivities)
+{
+  double *x,*y,*z,*v;
+  int i,j,k;
+  double *vals = new double[NbTimeStep];
+  for(i = 0 ; i < List_Nbr(SS) ; i+=nb)
+    {
+      x = (double*)List_Pointer_Fast(SS,i);
+      y = (double*)List_Pointer_Fast(SS,i+nbvert);
+      z = (double*)List_Pointer_Fast(SS,i+2*nbvert);
+      v = (double*)List_Pointer_Fast(SS,i+3*nbvert);
+      
+      for(j=0;j<nbvert;j++)
+	{
+	  for(k=0;k<NbTimeStep;k++)vals[k] = v[j+k*8];
+	  xyzv x(x[j],y[j],z[j]);
+	  iter it = connectivities.find(x);
+	  if(it == connectivities.end())
+	    {
+	      x.update(NbTimeStep,vals);
+	      connectivities.insert(x);
+	    }
+	  else
+	    {
+	      xyzv *xx = (xyzv*) &(*it); // a little weird ... becaus we know that 
+	      // this will not destroy the set ordering
+	      xx->update(NbTimeStep,vals);
+	    }
+	}
+    }   
+  
+  for(i = 0 ; i < List_Nbr(SS) ; i+=nb)
+    {
+      x = (double*)List_Pointer_Fast(SS,i);
+      y = (double*)List_Pointer_Fast(SS,i+nbvert);
+      z = (double*)List_Pointer_Fast(SS,i+2*nbvert);
+      v = (double*)List_Pointer_Fast(SS,i+3*nbvert);
+      for(j=0;j<nbvert;j++)
+	{
+	  xyzv xyz(x[j],y[j],z[j]);
+	  //double l = sqrt((x[j])*(x[j]) + y[j]*y[j] + z[j] * z[j]);
+	  iter it = connectivities.find(xyz);
+	  for(k=0;k<NbTimeStep;k++)v[j+k*8] = (*it).vals[k];
+	  //for(k=0;k<NbTimeStep;k++)v[j+k*8] = l;
 
-  typedef set<xyzv,lessthanxyzv> mycont;
-  typedef mycont::const_iterator iter;
 
-  mycont connectivities;
+	}
+    } 
+  delete [] vals;
+}
+
+void Post_View :: smooth ()
+{
+  xyzv::eps = CTX.lc * 1.e-6;
+  int nb;
 
-  double *x,*y,*z,*v;
   if(NbSS){
-    Msg(INFO,"Smoothing the view (%d) ...",NbTimeStep);
+    mycont conSS;
+    Msg(INFO,"Smoothing SS vector in a view ...");
     nb = List_Nbr(SS) / NbSS ;
-
-    double *vals = new double[NbTimeStep];
-
-    for(i = 0 ; i < List_Nbr(SS) ; i+=nb)
-      {
-	x = (double*)List_Pointer_Fast(SS,i);
-	y = (double*)List_Pointer_Fast(SS,i+4);
-	z = (double*)List_Pointer_Fast(SS,i+8);
-	v = (double*)List_Pointer_Fast(SS,i+12);
-	
-	for(j=0;j<4;j++)
-	  {
-	    for(int k=0;k<NbTimeStep;k++)vals[k] = v[j+k*8];
-	    xyzv x(x[j],y[j],z[j]);
-	    iter it = connectivities.find(x);
-	    if(it == connectivities.end())
-	      {
-		x.update(NbTimeStep,vals);
-		connectivities.insert(x);
-	      }
-	    else
-	      {
-		xyzv *xx = (xyzv*) &(*it); // a little weird ... becaus we know that 
-		                           // this will not destroy the set ordering
-		xx->update(NbTimeStep,vals);
-	      }
-	  }
-      } 
-
-    int n1 = 0;
-    int n2 = 0;
-    int n3 = 0;
-    for(i = 0 ; i < List_Nbr(SS) ; i+=nb)
-      {
-	x = (double*)List_Pointer_Fast(SS,i);
-	y = (double*)List_Pointer_Fast(SS,i+4);
-	z = (double*)List_Pointer_Fast(SS,i+8);
-	v = (double*)List_Pointer_Fast(SS,i+12);
-	for(j=0;j<4;j++)
-	  {
-	    xyzv xyz(x[j],y[j],z[j]);
-	    iter it = connectivities.find(xyz);
-	    if(it == connectivities.end())
-	      {
-		n3++;
-	      }
-	    else
-	      {
-		n1++;
-		n2 += (*it).nboccurences;
-		// test
-		// double val = sqrt ((x[j]-1) * (x[j]-1) + y[j] * y[j] + z[j] * z[j]);
-		//for(int k=0;k<NbTimeStep;k++)v[j+k*8] = val;
-		for(int k=0;k<NbTimeStep;k++)v[j+k*8] = (*it).vals[k];
-	      }
-	  }
-      } 
-
-    Msg(INFO,"nbpoints = %d  mean = %d size = %d miss %d\n",n1,n2/n1,connectivities.size(),n3);
-    delete [] vals;
+    smooth_list (SS , NbTimeStep, 4, nb, conSS);
+    Msg(INFO,"...done");
+  }
+  if(NbST){
+    mycont conST;
+    Msg(INFO,"Smoothing ST vector in a view ...");
+    nb = List_Nbr(ST) / NbST ;
+    smooth_list (ST , NbTimeStep, 3, nb, conST);
+    Msg(INFO,"...done");
   }
+  
+}
+
+/*
+  Another util to smooth normals
+*/
+
+void Post_View :: reset_normals()
+{
+  if(normals)delete normals;
+  normals  = 0;
+}
+
+void Post_View :: add_normal(double x, double y, double z, 
+			     double nx, double ny, double nz)
+{
+  if(!normals)normals = new smooth_container;
+  xyzv xyz(x,y,z);
+  double n[3] = {nx,ny,nz};
+  iter it = normals->c.find(xyz);
+  if(it == normals->c.end())
+    {
+      xyz.update(3,n);
+      normals->c.insert(xyz);
+    }
+  else
+    {
+      xyzv *xx = (xyzv*) &(*it); 
+      xx->update(3,n);
+    }
 }
+
+bool Post_View :: get_normal(double x, double y, double z, 
+			     double &nx, double &ny, double &nz)
+{
+  if(!normals)
+    return false;
+  xyzv xyz(x,y,z);
+  iter it = normals->c.find(xyz);
+  if(it == normals->c.end())return false;
+  nx = (*it).vals[0];
+  ny = (*it).vals[1];
+  nz = (*it).vals[2];
+  return true;
+}
+
+
diff --git a/Common/Views.h b/Common/Views.h
index afc260a847dee02c77615c91656f4fead72efa18..ecdb9bee7b05540fd03d633c9837875acec8add9 100644
--- a/Common/Views.h
+++ b/Common/Views.h
@@ -4,7 +4,10 @@
 #include "Const.h"
 #include "ColorTable.h"
 
-typedef struct{
+class smooth_container;
+
+class Post_View{
+  public :
   // intrinsic to a view
   int Num, Changed, DuplicateOf, Links;
   char FileName[NAME_STR_L], Name[NAME_STR_L];
@@ -39,7 +42,14 @@ typedef struct{
   int (*GIFV) (double min, double max, int nb, double value);
   // smooth the view
   void smooth();
-}Post_View;
+  // smooth the normals
+  smooth_container *normals;
+  void reset_normals();
+  void add_normal(double x, double y, double z, 
+		  double nx, double ny, double nz);
+  bool get_normal(double x, double y, double z, 
+		  double &nx, double &ny, double &nz);
+};
 
 // The static list with pointers to all views
 
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 923cf1dd7871d00b49611f762b1e36772399a4e3..b8a15310c415fff5bfa13f2d8781196d3246c215 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.19 2001-01-29 08:43:44 geuzaine Exp $
+// $Id: Draw.cpp,v 1.20 2001-01-29 22:33:41 remacle Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -32,12 +32,10 @@ void Draw3d(void){
   for(i = 0 ; i < 6 ; i++)
     if(CTX.clip[i]) glEnable((GLenum)(GL_CLIP_PLANE0 + i));
 
-  /* This is sufficient, since we NEVER give different normals to nodes of one polygon */
-  glShadeModel(GL_FLAT);   //glShadeModel(GL_SMOOTH);
+  glShadeModel(GL_SMOOTH);
   glDepthFunc(GL_LESS);
   glEnable(GL_DEPTH_TEST);
-
-  /* glEnable(GL_CULL_FACE); */
+  glDisable(GL_CULL_FACE); 
 
   glPushMatrix();
   Draw_Mesh(&M);
@@ -131,37 +129,41 @@ void Orthogonalize(int x, int y){
 /*  i n i t                                                                 */
 /* ------------------------------------------------------------------------ */
 
-void InitShading(void){
+
+void InitRenderModel(void)
+{
   int i;
-  float ambient[] = {0.1745, 0.01175, 0.01175};
-  float diffuse[] = {0.61424, 0.04136, 0.04136};
+  float ambient[] = {0.5, 0.5, 0.5};
+  float diffuse[] = {0.4, 0.4, 0.4};
   float specular[4];
 
-  glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
-  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
-  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
 
-  glEnable(GL_LIGHTING);
-  glEnable(GL_NORMALIZE);
   for(i = 0 ; i < 6 ; i++){
     if(CTX.light[i]){
       glLightfv((GLenum)(GL_LIGHT0 + i), GL_POSITION, CTX.light_position[i]);
+      glLightfv((GLenum)(GL_LIGHT0 + i), GL_AMBIENT, ambient);
+      glLightfv((GLenum)(GL_LIGHT0 + i), GL_DIFFUSE, diffuse);
       glEnable((GLenum)(GL_LIGHT0 + i));
     }
   }
-
-  /* simple color commands will automatically create appropriate materials */
   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
-  glEnable(GL_COLOR_MATERIAL);
-
-  /* let's add some shininess to all these automatically created materials */
-  glMaterialf(GL_FRONT, GL_SHININESS, 40.);
+  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.);
   glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+  /* let's add some shininess to all these automatically created materials */
   specular[0] = CTX.shine;
   specular[1] = CTX.shine;
   specular[2] = CTX.shine;
   specular[3] = 1.0;
-  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
+}
+
+void InitShading()
+{
+  glEnable(GL_LIGHTING);
+  glEnable(GL_NORMALIZE);
+  glEnable(GL_COLOR_MATERIAL);
 }
 
 
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index d7f12c2661669e8dc8b441c6007913d128ed7430..6e7406b08ed9084384d4c3407ab1896cb3eb1e9d 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -13,6 +13,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);
@@ -51,9 +52,9 @@ void Draw_Point(double *x, double *y, double *z,
                 double *Offset, double Raise[3][5]);
 void Draw_Line (double *x, double *y, double *z,
                 double *Offset, double Raise[3][5]);
-void Draw_Triangle (double *x, double *y, double *z,
+void Draw_Triangle (double *x, double *y, double *z,double *n,
                     double *Offset, double Raise[3][5], int shade);
-void Draw_Quadrangle (double *x, double *y, double *z,
+void Draw_Quadrangle (double *x, double *y, double *z, double *n,
                       double *Offset, double Raise[3][5], int shade);
 void Draw_Polygon (int n, double *x, double *y, double *z,
                    double *Offset, double Raise[3][5]);
@@ -100,6 +101,7 @@ 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,
 			    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 7a3eb9faad2909e21a958e381f37f916d1fb5b8a..682f8fe751263b28345c661b584577df576cdc5d 100644
--- a/Graphics/Entity.cpp
+++ b/Graphics/Entity.cpp
@@ -1,4 +1,4 @@
-// $Id: Entity.cpp,v 1.6 2001-01-19 22:32:31 remacle Exp $
+// $Id: Entity.cpp,v 1.7 2001-01-29 22:33:41 remacle Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -41,31 +41,50 @@ void Draw_Line (double *x, double *y, double *z,
 /*  D r a w _ T r i a n g l e                                               */
 /* ------------------------------------------------------------------------ */
 
-void Draw_Triangle (double *x, double *y, double *z,
+void Draw_Triangle (double *x, double *y, double *z, double *n,
                     double *Offset, double Raise[3][5], int shade){
 
   double x1x0, y1y0, z1z0, x2x0, y2y0, z2z0, nn[3];
 
   glBegin(GL_TRIANGLES);
   if (shade){
-    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);
+    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)
+      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){
+    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){
+    glNormal3dv(&n[6]);
+  }
+
   glVertex3d(x[2]+Offset[0]+Raise[0][2],
              y[2]+Offset[1]+Raise[1][2],
              z[2]+Offset[2]+Raise[2][2]);
@@ -77,19 +96,35 @@ void Draw_Triangle (double *x, double *y, double *z,
 /*  D r a w _ Q u a d r a n g l e                                           */
 /* ------------------------------------------------------------------------ */
 
-void Draw_Quadrangle (double *x, double *y, double *z,
+void Draw_Quadrangle (double *x, double *y, double *z, double *n,
                       double *Offset, double Raise[3][5], int shade){
 
   /*
     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);
+    }
+  else
+    Draw_Triangle(x2,y2,z2,n,Offset,Raise,shade);
 
-  Draw_Triangle(x,y,z,Offset,Raise,shade);
-  Draw_Triangle(x2,y2,z2,Offset,Raise,shade);
 
   return;
 }
diff --git a/Graphics/Iso.cpp b/Graphics/Iso.cpp
index c8dfe260a20b247fb4619e45396b4084deae5f7b..9fe7c8ff833459456c9d8d5de36da523eef86c9b 100644
--- a/Graphics/Iso.cpp
+++ b/Graphics/Iso.cpp
@@ -1,4 +1,4 @@
-// $Id: Iso.cpp,v 1.6 2001-01-25 21:36:59 remacle Exp $
+// $Id: Iso.cpp,v 1.7 2001-01-29 22:33:41 remacle Exp $
 
 #include "Gmsh.h"
 #include "Mesh.h"
@@ -11,7 +11,7 @@ void RaiseFill(int i, double Val, double ValMin, double Raise[3][5]);
 /*  I n t e r p o l a t e                                                   */
 /* ------------------------------------------------------------------------ */
 
-void Interpolate(double *X, double *Y, double *Z, 
+void InterpolateIso(double *X, double *Y, double *Z, 
                  double *Val, double V, int I1, int I2, 
                  double *XI, double *YI ,double *ZI){
   
@@ -27,139 +27,6 @@ void Interpolate(double *X, double *Y, double *Z,
   }
 }
 
-/* ------------------------------------------------------------------------ */
-/*  S i m p l e x                                                           */
-/* ------------------------------------------------------------------------ */
-
-void IsoSimplex(double *X, double *Y, double *Z, double *Val, 
-                double V, double Vmin, double Vmax, 
-                double *Offset, double Raise[3][5], int shade){
-  int    nb,i;
-  int    ed[6] = {0,0,0,0,0,0};
-  double Xp[6],Yp[6],Zp[6];
-  double Xpi[6],Ypi[6],Zpi[6];
-
-  if(V != Vmax){
-    nb = 0;
-    if((Val[0] > V && Val[1] <= V) || (Val[1] > V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,1,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[0]++;
-    }
-    if((Val[0] > V && Val[2] <= V) || (Val[2] > V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,2,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[1]++;
-    }
-    if((Val[0] > V && Val[3] <= V) || (Val[3] > V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,3,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[2]++;
-    }
-    if((Val[1] > V && Val[2] <= V) || (Val[2] > V && Val[1] <= V)){
-      Interpolate(X,Y,Z,Val,V,1,2,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[3]++;
-    }
-    if((Val[1] > V && Val[3] <= V) || (Val[3] > V && Val[1] <= V)){
-      Interpolate(X,Y,Z,Val,V,1,3,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[4]++;
-    }
-    if((Val[2] > V && Val[3] <= V) || (Val[3] > V && Val[2] <= V)){
-      Interpolate(X,Y,Z,Val,V,2,3,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[5]++;
-    }
-  }
-  else{
-    nb=0;
-    if((Val[0] < V && Val[1] <= V) || (Val[1] < V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,1,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[0]++;
-    }
-    if((Val[0] < V && Val[2] <= V) || (Val[2] < V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,2,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[1]++;
-    }
-    if((Val[0] < V && Val[3] <= V) || (Val[3] < V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,3,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[2]++;
-    }
-    if((Val[1] < V && Val[2] <= V) || (Val[2] < V && Val[1] <= V)){
-      Interpolate(X,Y,Z,Val,V,1,2,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[3]++;
-    }
-    if((Val[1] < V && Val[3] <= V) || (Val[3] < V && Val[1] <= V)){
-      Interpolate(X,Y,Z,Val,V,1,3,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[4]++;
-    }
-    if((Val[2] < V && Val[3] <= V) || (Val[3] < V && Val[2] <= V)){
-      Interpolate(X,Y,Z,Val,V,2,3,&Xp[nb],&Yp[nb],&Zp[nb]); nb++;ed[5]++;
-    }
-  }
-
-  /*
-    3 possibilities for quads
-      -) 0,2,5,3
-      -) 0,1,5,4
-      -) 1,2,4,3
-      in all cases, simply invert the 2 last ones
-      for having the quads ordered      
-   */
-
-  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
-    n = normal to the polygon
-    v = unknown field we wanna draw
-   */
-
-  if(nb > 2)
-    {
-      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 n[3];
-      prodve(v1,v2,n);
-      //test 
-
-      // now get the gradient (simplified version of course)
-      
-      double xx = 0.0;
-      if(Val[2] != Val[1])
-	{
-	  double gr[3] = {X[2]-X[1],Y[2]-Y[1],Z[2]-Z[1]};
-	  double xx = gr[0] * n[0] + gr[1] * n[1] + gr[2] + n[2];
-	  if(Val[2] > Val[1]) xx = -xx;
-	}
-      if(Val[2] != Val[0])
-	{
-	  double gr[3] = {X[2]-X[0],Y[2]-Y[0],Z[2]-Z[0]};
-	  double xx = gr[0] * n[0] + gr[1] * n[1] + gr[2] + n[2];
-	  if(Val[2] > Val[0]) xx = -xx;
-	}      
-
-      // test
-
-      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];	      
-	    }
-	}
-    }
-
-  if(nb == 3) 
-    Draw_Triangle(Xp,Yp,Zp,Offset,Raise,shade);
-  else if(nb == 4)
-    Draw_Quadrangle(Xp,Yp,Zp,Offset,Raise,shade);
-
-}
-
 /* ------------------------------------------------------------------------ */
 /*  T r i a n g l e                                                         */
 /* ------------------------------------------------------------------------ */
@@ -171,25 +38,25 @@ void CutTriangle1D(double *X, double *Y, double *Z, double *Val,
   if(V != Vmax){
     *nb = 0;
     if((Val[0] > V && Val[1] <= V) || (Val[1] > V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,1,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
+      InterpolateIso(X,Y,Z,Val,V,0,1,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
     }
     if((Val[0] > V && Val[2] <= V) || (Val[2] > V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
+      InterpolateIso(X,Y,Z,Val,V,0,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
     }
     if((Val[1] > V && Val[2] <= V) || (Val[2] > V && Val[1] <= V)){
-      Interpolate(X,Y,Z,Val,V,1,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
+      InterpolateIso(X,Y,Z,Val,V,1,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
     }
   }
   else{
     *nb = 0;
     if((Val[0] < V && Val[1] >= V) || (Val[1] < V && Val[0] >= V)){
-      Interpolate(X,Y,Z,Val,V,0,1,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
+      InterpolateIso(X,Y,Z,Val,V,0,1,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
     }
     if((Val[0] < V && Val[2] >= V) || (Val[2] < V && Val[0] >= V)){
-      Interpolate(X,Y,Z,Val,V,0,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
+      InterpolateIso(X,Y,Z,Val,V,0,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
     }       
     if((Val[1] < V && Val[2] >= V) || (Val[2] < V && Val[1] >= V)){
-      Interpolate(X,Y,Z,Val,V,1,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
+      InterpolateIso(X,Y,Z,Val,V,1,2,&Xp[*nb],&Yp[*nb],&Zp[*nb]); (*nb)++;
     }
   }
 
@@ -240,15 +107,15 @@ void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
   }
   else if(Val[io[0]] < V1 && V1 <= Val[io[1]]){
     Vp[Np] = V1;
-    Interpolate(X,Y,Z,Val,V1,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++; 
+    InterpolateIso(X,Y,Z,Val,V1,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++; 
     Vp[Np] = V1;
-    Interpolate(X,Y,Z,Val,V1,io[0],io[1],&Xp[Np],&Yp[Np],&Zp[Np]); Np++; Fl = 1;
+    InterpolateIso(X,Y,Z,Val,V1,io[0],io[1],&Xp[Np],&Yp[Np],&Zp[Np]); Np++; Fl = 1;
   }
   else {
     Vp[Np] = V1;
-    Interpolate(X,Y,Z,Val,V1,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
+    InterpolateIso(X,Y,Z,Val,V1,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
     Vp[Np] = V1;
-    Interpolate(X,Y,Z,Val,V1,io[1],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++; Fl = 0;
+    InterpolateIso(X,Y,Z,Val,V1,io[1],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++; Fl = 0;
   }    
 
   if(V2 == Val[io[0]]){
@@ -256,9 +123,9 @@ void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
   }
   else if((Val[io[0]]<V2) && ( V2 < Val[io[1]])){
     Vp[Np] = V2;
-    Interpolate(X,Y,Z,Val,V2,io[0],io[1],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
+    InterpolateIso(X,Y,Z,Val,V2,io[0],io[1],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
     Vp[Np] = V2;
-    Interpolate(X,Y,Z,Val,V2,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
+    InterpolateIso(X,Y,Z,Val,V2,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
   }
   else if(V2 < Val[io[2]]){
     if(Fl){
@@ -269,9 +136,9 @@ void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
       Np++;
     }
     Vp[Np] = V2;
-    Interpolate(X,Y,Z,Val,V2,io[1],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
+    InterpolateIso(X,Y,Z,Val,V2,io[1],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
     Vp[Np] = V2;
-    Interpolate(X,Y,Z,Val,V2,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
+    InterpolateIso(X,Y,Z,Val,V2,io[0],io[2],&Xp[Np],&Yp[Np],&Zp[Np]); Np++;
   }
   else{
     if(Fl){
@@ -322,12 +189,12 @@ void CutLine0D(double *X, double *Y, double *Z, double *Val,
 
   if(V != Vmax){
     if((Val[0] > V && Val[1] <= V) || (Val[1] > V && Val[0] <= V)){
-      Interpolate(X,Y,Z,Val,V,0,1,Xp,Yp,Zp); *nb = 1;
+      InterpolateIso(X,Y,Z,Val,V,0,1,Xp,Yp,Zp); *nb = 1;
     }
   }
   else{
     if((Val[0] < V && Val[1] >= V) || (Val[1] < V && Val[0] >= V)){
-      Interpolate(X,Y,Z,Val,V,0,1,Xp,Yp,Zp); *nb = 1;
+      InterpolateIso(X,Y,Z,Val,V,0,1,Xp,Yp,Zp); *nb = 1;
     }
   }
 }
@@ -372,7 +239,7 @@ void CutLine1D(double *X, double *Y, double *Z, double *Val,
   }
   else{
     Vp2[0] = V1;
-    Interpolate(X,Y,Z,Val,V1,io[0],io[1],&Xp2[0],&Yp2[0],&Zp2[0]);
+    InterpolateIso(X,Y,Z,Val,V1,io[0],io[1],&Xp2[0],&Yp2[0],&Zp2[0]);
   }
 
   if(V2>=Val[io[1]]){
@@ -383,7 +250,7 @@ void CutLine1D(double *X, double *Y, double *Z, double *Val,
   }
   else{
     Vp2[1] = V2;
-    Interpolate(X,Y,Z,Val,V2,io[0],io[1],&Xp2[1],&Yp2[1],&Zp2[1]);
+    InterpolateIso(X,Y,Z,Val,V2,io[0],io[1],&Xp2[1],&Yp2[1],&Zp2[1]);
   }
 
 }
diff --git a/Graphics/Iso.h b/Graphics/Iso.h
index 22777aa1b34cc2bec6ae81200bfec3d08658b041..e5d5444794e6af7bad5f2c6243f1296992935bd0 100644
--- a/Graphics/Iso.h
+++ b/Graphics/Iso.h
@@ -1,10 +1,6 @@
 #ifndef _ISO_H_
 #define _ISO_H_
 
-void IsoSimplex (double *X, double *Y, double *Z, double *Val,
-                 double V, double Vmin, double Vmax,
-                 double *Offset, double Raise[3][5], int shade);
-
 void CutTriangle1D (double *X, double *Y, double *Z, double *Val,
                     double V, double Vmin, double Vmax,
                     double *Xp, double *Yp, double *Zp, int *nb);
@@ -23,4 +19,8 @@ void CutLine1D (double *X, double *Y, double *Z, double *Val,
                 double *Xp, double *Yp, double *Zp, int *nb,
                 double *value);
 
+void InterpolateIso(double *X, double *Y, double *Z, 
+		    double *Val, double V, int I1, int I2, 
+		    double *XI, double *YI ,double *ZI);
+  
 #endif
diff --git a/Graphics/Makefile b/Graphics/Makefile
index 7f5a993c6acd36044f3242550a3cdddca25186f8..85fd7b13d3e00ef3b3e46c0957a66902d5a17177 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.14 2001-01-13 17:08:41 geuzaine Exp $
+# $Id: Makefile,v 1.15 2001-01-29 22:33:41 remacle Exp $
 #
 # Makefile for "libGraphics.a"
 #
@@ -30,6 +30,7 @@ SRC = Draw.cpp \
       Post.cpp \
       PostSimplex.cpp \
       Iso.cpp \
+      IsoSimplex.cpp \
       Entity.cpp \
       Scale.cpp \
       Axes.cpp \
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 84e7c9af2beae4b0397013ad579d40f3ed579d10..9fc7ffc351580be751ba1e2467258ec722bfb724 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.18 2001-01-29 08:43:44 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.19 2001-01-29 22:33:41 remacle Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -53,6 +53,8 @@ static int DrawVertexSupp ;
 void Draw_Mesh (Mesh *M) {
   int i;
 
+  InitRenderModel();
+
   if(CTX.mesh.shade)
     InitShading();
   else
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 5b6dfdafb059ca31a840bb49f3995ff75655c6ca..c29750d21f3ec4d55c2c8e50abcdd67c7e0faec8 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.11 2001-01-12 13:28:58 geuzaine Exp $
+// $Id: Post.cpp,v 1.12 2001-01-29 22:33:41 remacle Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -232,11 +232,26 @@ void Draw_Post (void) {
 	}
 	
 	// Tetrahedra
+
+	/*
+	  Modif Jf :
+	  
+	     IsoSurfaces are really better rendered with smooth shading.
+	     My idea is first to transform the scalar simplex map on a
+	     scalar triangle map. This map has to be changed each time 
+	     the number of iso-surfaces is changed.
+	 */
 	
 	if(v->NbSS){
 	  nb = List_Nbr(v->SS) / v->NbSS ;
 	  for(i = 0 ; i < List_Nbr(v->SS) ; i+=nb)
-	    Draw_ScalarTetrahedron(v, ValMin, ValMax, Raise,
+	    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),
diff --git a/Graphics/PostSimplex.cpp b/Graphics/PostSimplex.cpp
index bef6923b9fa1cd25c79e1fbd5735db01ac4188d7..e03a27df529ed8aed54de955359b4a37993706c4 100644
--- a/Graphics/PostSimplex.cpp
+++ b/Graphics/PostSimplex.cpp
@@ -1,4 +1,4 @@
-// $Id: PostSimplex.cpp,v 1.10 2001-01-08 08:05:43 geuzaine Exp $
+// $Id: PostSimplex.cpp,v 1.11 2001-01-29 22:33:41 remacle Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -6,6 +6,7 @@
 #include "Mesh.h"
 #include "Draw.h"
 #include "Iso.h"
+#include "IsoSimplex.h"
 #include "Context.h"
 
 extern Context_T   CTX;
@@ -433,15 +434,22 @@ void Draw_TensorTriangle(Post_View *View,
 /*  T e t r a h e d r a                                                     */
 /* ------------------------------------------------------------------------ */
 
-void Draw_ScalarTetrahedron(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,
+			    double ValMin, 
+			    double ValMax, 
+			    double Raise[3][5],
+			    double *X, 
+			    double *Y, 
+			    double *Z, 
+			    double *V){
 
   int     k;
 
   for(k=0 ; k<View->NbIso ; k++){
-    Palette(View,View->NbIso,k);
-    IsoSimplex(X, Y, Z, &V[4*View->TimeStep],
+    if(!preproNormals)Palette(View,View->NbIso,k);
+    IsoSimplex(View,preproNormals,
+	       X, Y, Z, &V[4*View->TimeStep],
 	       View->GVFI(ValMin,ValMax,View->NbIso,k), 
 	       ValMin, ValMax, View->Offset, Raise, View->Light);
   }
diff --git a/Makefile b/Makefile
index bc4f2e52baa2b6fa9a1632e6dea1f44235b9dc98..ca24beb7bafe0c52a024b13bf3cded8d8dea9208 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.44 2001-01-29 08:43:44 geuzaine Exp $
+# $Id: Makefile,v 1.45 2001-01-29 22:33:41 remacle Exp $
 # ----------------------------------------------------------------------
 #  Makefile for Gmsh  
 # ----------------------------------------------------------------------
@@ -24,8 +24,8 @@ OPENGL_MOTIF_LIB = -lGLw
  MESA_STATIC_LIB = $(HOME)/SOURCES/Mesa-static/lib/libGLU.a\
                    $(HOME)/SOURCES/Mesa-static/lib/libGL.a
 MESA_MOTIF_STATIC_LIB = $(HOME)/SOURCES/Mesa-static/lib/libGLw.a
-#     XMOTIF_LIB = /usr/local/lib/libXm.so.2 -L/usr/X11R6/lib -lXt -lX11 -lXext
-      XMOTIF_LIB = -L/usr/local/lib -L/usr/X11R6/LessTif/Motif1.2/lib -lXm\
+     XMOTIF_LIB = /usr/local/lib/libXm.so.2 -L/usr/X11R6/lib -lXt -lX11 -lXext
+#      XMOTIF_LIB = -L/usr/local/lib -L/usr/X11R6/LessTif/Motif1.2/lib -lXm\
                    -L/usr/X11R6/lib -lXt -lX11 -lXext 
         FLTK_LIB = -L$(HOME)/SOURCES/fltk/lib -lfltk\
                    -L/usr/X11R6/lib -lXext -lX11