diff --git a/Common/Makefile b/Common/Makefile
index a62b654e4829c963c7078f3915cc6560ee902e17..c8f9f6631d198c1e528c0997d88ca621d76c7073 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.136 2007-08-24 20:14:17 geuzaine Exp $
+# $Id: Makefile,v 1.137 2007-08-27 13:46:21 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -73,15 +73,15 @@ OctreeInternals.o: OctreeInternals.cpp Message.h OctreeInternals.h
 Options.o: Options.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h GmshUI.h GmshDefines.h \
-  ../Graphics/Draw.h ../Mesh/Generator.h Context.h Options.h \
-  ../Mesh/BackgroundMesh.h ../Plugin/PluginManager.h ../Plugin/Plugin.h \
-  ../Common/Options.h ../Common/Message.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Common/SmoothData.h ../Numeric/Numeric.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Fltk/Solvers.h \
-  ../Fltk/GUI.h ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h \
-  ../Common/GmshUI.h ../Fltk/Popup_Button.h \
-  ../Fltk/SpherePosition_Widget.h
+  ../Graphics/Draw.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Mesh/Generator.h Context.h Options.h ../Mesh/BackgroundMesh.h \
+  ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Common/Options.h \
+  ../Common/Message.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Common/SmoothData.h ../Numeric/Numeric.h ../Post/AdaptiveViews.h \
+  ../Common/GmshMatrix.h ../Fltk/Solvers.h ../Fltk/GUI.h \
+  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h ../Common/GmshUI.h \
+  ../Fltk/Popup_Button.h ../Fltk/SpherePosition_Widget.h
 CommandLine.o: CommandLine.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h GmshUI.h GmshDefines.h \
diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp
index 005a56ac86b22c3f2361b8b278dc6b8acf111b99..f154ec80312ea42476bc38041ab8a960deeb3916 100644
--- a/Common/VertexArray.cpp
+++ b/Common/VertexArray.cpp
@@ -1,4 +1,4 @@
-// $Id: VertexArray.cpp,v 1.20 2007-08-25 22:18:06 geuzaine Exp $
+// $Id: VertexArray.cpp,v 1.21 2007-08-27 13:46:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -97,8 +97,10 @@ void VertexArray::add(double *x, double *y, double *z, SVector3 *n,
   }
 
   for(int i = 0; i < npe; i++){
-    if(n) add(x[i], y[i], z[i], n[i].x(), n[i].y(), n[i].z(), col[i], ele);
-    else add(x[i], y[i], z[i], col[i], ele);
+    if(n) 
+      add(x[i], y[i], z[i], n[i].x(), n[i].y(), n[i].z(), col[i], ele);
+    else
+      add(x[i], y[i], z[i], 0., 0., 1., col[i], ele);
   }
 }
 
@@ -137,16 +139,16 @@ class AlphaElementLessThan {
 int AlphaElementLessThan::numVertices = 0;
 double AlphaElementLessThan::eye[3] = {0., 0., 0.};
 
-void VertexArray::sort(double eye[3])
+void VertexArray::sort(double x, double y, double z)
 {
   // This simplementation is pretty bad: it copies the whole data
   // twice. We should think about a more efficient way to sort the
   // three arrays in place.
 
   AlphaElementLessThan::numVertices = getNumVerticesPerElement();
-  AlphaElementLessThan::eye[0] = eye[0];
-  AlphaElementLessThan::eye[1] = eye[1];
-  AlphaElementLessThan::eye[2] = eye[2];
+  AlphaElementLessThan::eye[0] = x;
+  AlphaElementLessThan::eye[1] = y;
+  AlphaElementLessThan::eye[2] = z;
 
   int npe = getNumVerticesPerElement();
   int n = getNumVertices() / npe;
diff --git a/Common/VertexArray.h b/Common/VertexArray.h
index 57ff3487798f8f92c8951ba31aa7a11dd85a58fc..b92e9a3b70a354c25793109218845d819cb5319d 100644
--- a/Common/VertexArray.h
+++ b/Common/VertexArray.h
@@ -88,7 +88,7 @@ class VertexArray{
   void add(double *x, double *y, double *z, SVector3 *n, unsigned int *col,
 	   MElement *ele=0, bool unique=true);
   // sorts the elements back to front wrt the eye position
-  void sort(double eye[3]);
+  void sort(double x, double y, double z);
 };
 
 #endif
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 2a67269b5935509a45aa48afe06345967792f66a..b91319a66f5c771e3904fcb90126889341ac3278 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.143 2007-08-24 20:14:18 geuzaine Exp $
+# $Id: Makefile,v 1.144 2007-08-27 13:46:21 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -103,22 +103,23 @@ GUI.o: GUI.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
   ../Common/GmshDefines.h ../Numeric/Numeric.h ../Common/Context.h \
-  ../Common/Options.h ../Graphics/Draw.h GUI.h Opengl_Window.h \
-  Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
-  SpherePosition_Widget.h Callbacks.h Win32Icon.h ../Parser/OpenFile.h \
-  ../Common/CommandLine.h ../Mesh/Generator.h Solvers.h \
-  ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h Shortcut_Window.h
+  ../Common/Options.h ../Graphics/Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h GUI.h Opengl_Window.h Colorbar_Window.h \
+  ../Post/ColorTable.h Popup_Button.h SpherePosition_Widget.h Callbacks.h \
+  Win32Icon.h ../Parser/OpenFile.h ../Common/CommandLine.h \
+  ../Mesh/Generator.h Solvers.h ../Plugin/PluginManager.h \
+  ../Plugin/Plugin.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Common/SmoothData.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
+  Shortcut_Window.h
 GUI_Extras.o: GUI_Extras.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Common/GmshDefines.h File_Picker.h \
   ../Parser/CreateFile.h ../Common/Options.h ../Common/Context.h \
-  ../Graphics/Draw.h GUI.h Opengl_Window.h Colorbar_Window.h \
-  ../Post/ColorTable.h Popup_Button.h SpherePosition_Widget.h \
-  Shortcut_Window.h
+  ../Graphics/Draw.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h GUI.h \
+  Opengl_Window.h Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
+  SpherePosition_Widget.h Shortcut_Window.h
 GUI_Projection.o: GUI_Projection.cpp ../Geo/GModelIO_F.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
@@ -175,20 +176,20 @@ Opengl.o: Opengl.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Numeric/Numeric.h ../Common/Context.h \
-  ../Graphics/Draw.h ../Graphics/SelectBuffer.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
-  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Geo/GFace.h \
-  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
-  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
-  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
-  ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h Opengl_Window.h \
-  Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
+  ../Graphics/Draw.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
+  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/ExtrudeParams.h \
+  ../Common/SmoothData.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
+  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
+  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h \
+  Opengl_Window.h Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
   SpherePosition_Widget.h ../Graphics/gl2ps.h
 Opengl_Window.o: Opengl_Window.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -222,4 +223,5 @@ Solvers.o: Solvers.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   Solvers.h GmshServer.h ../Parser/OpenFile.h ../Common/GmshUI.h GUI.h \
   Opengl_Window.h Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
-  SpherePosition_Widget.h ../Graphics/Draw.h ../Common/Context.h
+  SpherePosition_Widget.h ../Graphics/Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Common/Context.h
diff --git a/Geo/SPoint3.h b/Geo/SPoint3.h
index 27865e97aa5c3959c206014bde6650c117b6d097..0d458518777f0ecb74e8639576172aa2a7706a37 100644
--- a/Geo/SPoint3.h
+++ b/Geo/SPoint3.h
@@ -47,6 +47,7 @@ class SPoint3 {
   void operator/=(double mult);
   SPoint3 operator*(double mult);
   operator double *() { return P; }
+  double distance(const SPoint3 &p);
 };
 
 inline SPoint3 operator + (const SPoint3 &a, const SPoint3 &b)
@@ -97,4 +98,10 @@ inline double &SPoint3::operator[](int i)
 inline double SPoint3::operator[](int i) const
 { return P[i]; }
 
+inline double SPoint3::distance(const SPoint3 &p)
+{ 
+  double x = P[0] - p.P[0], y = P[1] - p.P[1], z = P[2] - p.P[2];
+  return sqrt(x * x + y * y + z * z);
+}
+
 #endif
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 380bdd5ab1897a251fdabbb66542f4ee99d39dde..d64eb0a043caf2b8d8d1c84977ab5fff6f11a8ec 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -22,6 +22,7 @@
 
 #include <vector>
 #include "List.h"
+#include "SBoundingBox3d.h"
 
 class Post_View;
 
@@ -85,6 +86,8 @@ void Draw_PlaneInBoundingBox(double xmin, double ymin, double zmin,
 void Draw_SmallAxes(void);
 void Draw_Axes(int mode, int tics[3], char format[3][256], char label[3][256],
 	       double bbox[6]);
+void Draw_Axes(int mode, int tics[3], char format[3][256], char label[3][256],
+	       SBoundingBox3d &bbox);
 
 #define ARGS Post_View *View, int preproNormals, \
              double ValMin, double ValMax, 	 \
diff --git a/Graphics/Entity.cpp b/Graphics/Entity.cpp
index 1ec70c9cbf2108305248c1c77401e01eea927526..fc7a69ca9d4f80db881d1658dc1ff376776267b2 100644
--- a/Graphics/Entity.cpp
+++ b/Graphics/Entity.cpp
@@ -1,4 +1,4 @@
-// $Id: Entity.cpp,v 1.74 2007-08-24 08:38:24 remacle Exp $
+// $Id: Entity.cpp,v 1.75 2007-08-27 13:46:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -87,6 +87,7 @@ void Draw_Disk(double size, double rint, double x, double y, double z, int light
   glPopMatrix();
   glDisable(GL_LIGHTING);
 }
+
 void Draw_TapCylinder(double width, double val1, double val2, 
 		      double ValMin, double ValMax, 
 		      double *x, double *y, double *z, int light)
@@ -782,6 +783,15 @@ void Draw_GridStipple(int n1, int n2, double p1[3], double p2[3], double p3[3])
   gl2psDisable(GL2PS_LINE_STIPPLE);
 }
 
+void Draw_Axes(int mode, int tics[3], char format[3][256], char label[3][256], 
+	       SBoundingBox3d &bb)
+{
+  double bbox[6] = {bb.min().x(), bb.max().x(),
+		    bb.min().y(), bb.max().y(),
+		    bb.min().z(), bb.max().z()};
+  Draw_Axes(mode, tics, format, label, bbox);
+}
+
 void Draw_Axes(int mode, int tics[3], char format[3][256], char label[3][256], 
 	       double bb[6])
 {
diff --git a/Graphics/Iso.cpp b/Graphics/Iso.cpp
index 2c16aa4542b7964698da8398fcd8fae84110240c..55fb20b46606bbe944ff08f849063c57f8047d57 100644
--- a/Graphics/Iso.cpp
+++ b/Graphics/Iso.cpp
@@ -1,4 +1,4 @@
-// $Id: Iso.cpp,v 1.39 2006-11-27 22:22:14 geuzaine Exp $
+// $Id: Iso.cpp,v 1.40 2007-08-27 13:46:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -28,16 +28,36 @@
 
 extern Context_T CTX;
 
-// Draw an iso-line inside a triangle
+static void affect(double *xi, double *yi, double *zi, int i,
+		   double *xp, double *yp, double *zp, int j)
+{
+  xi[i] = xp[j];
+  yi[i] = yp[j];
+  zi[i] = zp[j];
+}
 
-void IsoTriangle(Post_View * View, double *X, double *Y, double *Z,
-		 double *Val, double V, unsigned int color)
+// Draw an iso-point in a line
+
+int IsoLine(double *X, double *Y, double *Z, double *Val, double V,
+	    double *Xp, double *Yp, double *Zp)
 {
-  // don't draw anything if the value is constant
-  if(Val[0] == Val[1] && Val[0] == Val[2])
-    return;
+  if(Val[0] == Val[1])
+    return 0;
+
+  if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 0, 1, Xp, Yp, Zp);
+    return 1;
+  }
+  return 0;
+}
+
+// Compute an iso-line inside a triangle
+
+int IsoTriangle(double *X, double *Y, double *Z, double *Val, double V, 
+		double *Xp, double *Yp, double *Zp)
+{
+  if(Val[0] == Val[1] && Val[0] == Val[2]) return 0;
 
-  double Xp[3], Yp[3], Zp[3];
   int nb = 0;
   if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
     InterpolateIso(X, Y, Z, Val, V, 0, 1, &Xp[nb], &Yp[nb], &Zp[nb]);
@@ -52,62 +72,208 @@ void IsoTriangle(Post_View * View, double *X, double *Y, double *Z,
     nb++;
   }
   
-  if(nb == 2){
-    if(View->LinVertexArray && View->LinVertexArray->fill && !View->LineType){
-      View->LinVertexArray->add(Xp[0], Yp[0], Zp[0], color);
-      View->LinVertexArray->add(Xp[1], Yp[1], Zp[1], color);
+  if(nb == 2) return 2;
+  return 0;
+}
+
+int IsoSimplex(double *X, double *Y, double *Z, double *Val, double V,
+	       double *Xp, double *Yp, double *Zp, double n[3])
+{
+  if(Val[0] == Val[1] && Val[0] == Val[2] && Val[0] == Val[3])
+    return 0;
+
+  int nb = 0;
+  if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
+    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)) {
+    InterpolateIso(X, Y, Z, Val, V, 0, 2, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
+  }
+  if((Val[0] >= V && Val[3] <= V) || (Val[3] >= V && Val[0] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 0, 3, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
+  }
+  if((Val[1] >= V && Val[2] <= V) || (Val[2] >= V && Val[1] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 1, 2, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
+  }
+  if((Val[1] >= V && Val[3] <= V) || (Val[3] >= V && Val[1] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 1, 3, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
+  }
+  if((Val[2] >= V && Val[3] <= V) || (Val[3] >= V && Val[2] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 2, 3, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
+  }
+
+  // Remove identical nodes (this can happen if an edge belongs to the
+  // zero levelset). We should be doing this even for nb < 4, but it
+  // would slow us down even more (and we don't really care if some
+  // nodes in a postprocessing element are identical)
+  if(nb > 4) {
+    double xi[6], yi[6], zi[6];
+    affect(xi, yi, zi, 0, Xp, Yp, Zp, 0);
+    int ni = 1;
+    for(int j = 1; j < nb; j++) {
+      for(int i = 0; i < ni; i++) {
+	if(fabs(Xp[j] - xi[i]) < 1.e-12 &&
+	   fabs(Yp[j] - yi[i]) < 1.e-12 &&
+	   fabs(Zp[j] - zi[i]) < 1.e-12) {
+	  break;
+	}
+	if(i == ni - 1) {
+	  affect(xi, yi, zi, i + 1, Xp, Yp, Zp, j);
+	  ni++;
+	}
+      }
     }
-    else{
-      glColor4ubv((GLubyte *) & color);
-      Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, View->Light);
+    for(int i = 0; i < ni; i++)
+      affect(Xp, Yp, Zp, i, xi, yi, zi, i);
+    nb = ni;
+  }
+
+  if(nb < 3 || nb > 4)
+    return 0;
+
+  // 3 possible quads at this point: (0,2,5,3), (0,1,5,4) or
+  // (1,2,4,3), so simply invert the 2 last vertices for having the
+  // quad ordered
+  if(nb == 4) {
+    double x = Xp[3], y = Yp[3], z = Zp[3];
+    Xp[3] = Xp[2];
+    Yp[3] = Yp[2];
+    Zp[3] = Zp[2];
+    Xp[2] = x;
+    Yp[2] = y;
+    Zp[2] = z;
+  }
+
+  // to get a nice isosurface, we should have n . grad v > 0, where n
+  // is the normal to the polygon and v is the unknown field we want
+  // to draw
+  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]};
+  prodve(v1, v2, n);
+  norme(n);
+
+  double g[3];
+  gradSimplex(X, Y, Z, Val, g);
+
+  double gdotn;
+  prosca(g, n, &gdotn);
+
+  if(gdotn > 0.) {
+    double Xpi[6], Ypi[6], Zpi[6];
+    for(int i = 0; i < nb; i++) {
+      Xpi[i] = Xp[i];
+      Ypi[i] = Yp[i];
+      Zpi[i] = Zp[i];
     }
+    for(int 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];
   }
+
+  return nb;
 }
 
-// Compute the polygon between the two iso-lines V1 and V2 in a
-// triangle
+// Compute the line between the two iso-points V1 and V2 in a line
 
-void CutTriangle(double *X, double *Y, double *Z, double *Val,
-		 double V1, double V2, double *Xp2, double *Yp2,
-		 double *Zp2, int *Np2, double *Vp2)
+int CutLine(double *X, double *Y, double *Z, double *Val,
+	    double V1, double V2, 
+	    double *Xp2, double *Yp2, double *Zp2, double *Vp2)
 {
-  int i, io[3], j, iot, Np, Fl;
-  double Xp[10], Yp[10], Zp[10], Vp[10];
+  int io[2];
+  if(Val[0] < Val[1]) {
+    io[0] = 0;
+    io[1] = 1;
+  }
+  else {
+    io[0] = 1;
+    io[1] = 0;
+  }
+
+  if(Val[io[0]] > V2 || Val[io[1]] < V1) return 0;
+
+  if(V1 <= Val[io[0]] && Val[io[1]] <= V2) {
+    for(int i = 0; i < 2; i++) {
+      Vp2[i] = Val[i];
+      Xp2[i] = X[i];
+      Yp2[i] = Y[i];
+      Zp2[i] = Z[i];
+    }
+    return 2;
+  }
+
+  if(V1 <= Val[io[0]]) {
+    Vp2[0] = Val[io[0]];
+    Xp2[0] = X[io[0]];
+    Yp2[0] = Y[io[0]];
+    Zp2[0] = Z[io[0]];
+  }
+  else {
+    Vp2[0] = V1;
+    InterpolateIso(X, Y, Z, Val, V1, io[0], io[1], &Xp2[0], &Yp2[0], &Zp2[0]);
+  }
 
-  *Np2 = 0;
+  if(V2 >= Val[io[1]]) {
+    Vp2[1] = Val[io[1]];
+    Xp2[1] = X[io[1]];
+    Yp2[1] = Y[io[1]];
+    Zp2[1] = Z[io[1]];
+  }
+  else {
+    Vp2[1] = V2;
+    InterpolateIso(X, Y, Z, Val, V2, io[0], io[1], &Xp2[1], &Yp2[1], &Zp2[1]);
+  }
 
-  for(i = 0; i < 3; i++)
-    io[i] = i;
+  return 2;
+}
+
+// Compute the polygon between the two iso-lines V1 and V2 in a
+// triangle
 
-  for(i = 0; i < 2; i++) {
-    for(j = i + 1; j < 3; j++) {
+int CutTriangle(double *X, double *Y, double *Z, double *Val,
+		double V1, double V2, 
+		double *Xp2, double *Yp2, double *Zp2, double *Vp2)
+{
+  // fill io so that it contains an indexing of the nodes such that
+  // Val[io[i]] > Val[io[j]] if i > j
+  int io[3] = {0, 1, 2};
+  for(int i = 0; i < 2; i++) {
+    for(int j = i + 1; j < 3; j++) {
       if(Val[io[i]] > Val[io[j]]) {
-        iot = io[i];
+        int iot = io[i];
         io[i] = io[j];
         io[j] = iot;
       }
     }
   }
 
-  // io[] contains an indexing of nodes such that Val[io[i]] > Val[io[j]] if i > j
-
-  if(Val[io[0]] > V2)
-    return;
-  if(Val[io[2]] < V1)
-    return;
+  if(Val[io[0]] > V2 || Val[io[2]] < V1) return 0;
 
   if(V1 <= Val[io[0]] && Val[io[2]] <= V2) {
-    for(i = 0; i < 3; i++) {
+    for(int i = 0; i < 3; i++) {
       Vp2[i] = Val[i];
       Xp2[i] = X[i];
       Yp2[i] = Y[i];
       Zp2[i] = Z[i];
     }
-    *Np2 = 3;
-    return;
+    return 3;
   }
 
-  Np = 0;
+  int Np = 0, Fl = 0;
+  double Xp[10], Yp[10], Zp[10], Vp[10];
+
   if(V1 <= Val[io[0]]) {
     Vp[Np] = Val[io[0]];
     Xp[Np] = X[io[0]];
@@ -136,7 +302,7 @@ void CutTriangle(double *X, double *Y, double *Z, double *Val,
   }
 
   if(V2 == Val[io[0]]) {
-    return;
+    return 0;
   }
   else if((Val[io[0]] < V2) && (V2 < Val[io[1]])) {
     Vp[Np] = V2;
@@ -180,126 +346,119 @@ void CutTriangle(double *X, double *Y, double *Z, double *Val,
   Xp2[0] = Xp[0];
   Yp2[0] = Yp[0];
   Zp2[0] = Zp[0];
-  *Np2 = 1;
-
-  for(i = 1; i < Np; i++) {
-    if((Xp[i] != Xp2[(*Np2) - 1]) || (Yp[i] != Yp2[(*Np2) - 1]) || 
-       (Zp[i] != Zp2[(*Np2) - 1])) {
-      Vp2[*Np2] = Vp[i];
-      Xp2[*Np2] = Xp[i];
-      Yp2[*Np2] = Yp[i];
-      Zp2[*Np2] = Zp[i];
-      (*Np2)++;
+
+  int Np2 = 1;
+
+  for(int i = 1; i < Np; i++) {
+    if((Xp[i] != Xp2[Np2 - 1]) || (Yp[i] != Yp2[Np2 - 1]) || 
+       (Zp[i] != Zp2[Np2 - 1])){
+      Vp2[Np2] = Vp[i];
+      Xp2[Np2] = Xp[i];
+      Yp2[Np2] = Yp[i];
+      Zp2[Np2] = Zp[i];
+      Np2++;
     }
   }
 
-  if(Xp2[0] == Xp2[(*Np2) - 1] && Yp2[0] == Yp2[(*Np2) - 1] && 
-     Zp2[0] == Zp2[(*Np2) - 1]) {
-    (*Np2)--;
+  if(Xp2[0] == Xp2[Np2 - 1] && Yp2[0] == Yp2[Np2 - 1] && 
+     Zp2[0] == Zp2[Np2 - 1]) {
+    Np2--;
   }
 
   // check and fix orientation
-  double in1[3] = { X[1]-X[0], Y[1]-Y[0], Z[1]-Z[0]};
-  double in2[3] = { X[2]-X[0], Y[2]-Y[0], Z[2]-Z[0]};
+  double in1[3] = {X[1] - X[0], Y[1] - Y[0], Z[1] - Z[0]};
+  double in2[3] = {X[2] - X[0], Y[2] - Y[0], Z[2] - Z[0]};
   double inn[3];
   prodve(in1, in2, inn);
-  double out1[3] = { Xp2[1]-Xp2[0], Yp2[1]-Yp2[0], Zp2[1]-Zp2[0]};
-  double out2[3] = { Xp2[2]-Xp2[0], Yp2[2]-Yp2[0], Zp2[2]-Zp2[0]};
+  double out1[3] = {Xp2[1] - Xp2[0], Yp2[1] - Yp2[0], Zp2[1] - Zp2[0]};
+  double out2[3] = {Xp2[2] - Xp2[0], Yp2[2] - Yp2[0], Zp2[2] - Zp2[0]};
   double outn[3];
   prodve(out1, out2, outn);
   double res;
   prosca(inn, outn, &res);
   if(res < 0){
-    for(i = 0; i < *Np2; i++){
-      Vp[i] = Vp2[*Np2-i-1];
-      Xp[i] = Xp2[*Np2-i-1];
-      Yp[i] = Yp2[*Np2-i-1];
-      Zp[i] = Zp2[*Np2-i-1];
+    for(int i = 0; i < Np2; i++){
+      Vp[i] = Vp2[Np2 - i - 1];
+      Xp[i] = Xp2[Np2 - i - 1];
+      Yp[i] = Yp2[Np2 - i - 1];
+      Zp[i] = Zp2[Np2 - i - 1];
     }
-    for(i = 0; i < *Np2; i++){
+    for(int i = 0; i < Np2; i++){
       Vp2[i] = Vp[i];
       Xp2[i] = Xp[i];
       Yp2[i] = Yp[i];
       Zp2[i] = Zp[i];
     }
   }
+
+  return Np2;
 }
 
-// Draw an iso-point in a line
 
-void IsoLine(Post_View *View, double *X, double *Y, double *Z, 
-	     double *Val, double V)
-{
-  double Xp[2], Yp[2], Zp[2];
 
-  // don't draw anything if the value is constant
-  if(Val[0] == Val[1])
-    return;
 
-  if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
-    InterpolateIso(X, Y, Z, Val, V, 0, 1, Xp, Yp, Zp);
-    Draw_Point(View->PointType, View->PointSize, Xp, Yp, Zp, View->Light);
-  }
-}
 
-// Compute the line between the two iso-points V1 and V2 in a line
 
-void CutLine(double *X, double *Y, double *Z, double *Val,
-	     double V1, double V2, double *Xp2, double *Yp2, double *Zp2,
-	     int *Np2, double *Vp2)
-{
-  int i, io[2];
 
-  if(Val[0] < Val[1]) {
-    io[0] = 0;
-    io[1] = 1;
-  }
-  else {
-    io[0] = 1;
-    io[1] = 0;
-  }
 
-  // io[] contains an indexing of nodes such that Val[io[i]] > Val[io[j]] if i > j
+// ****************** FIXME: REMOVE EVERYTHING BELOW THIS LINE ****************
 
-  *Np2 = 0;
 
-  if(Val[io[0]] > V2)
-    return;
-  if(Val[io[1]] < V1)
-    return;
 
-  *Np2 = 2;
 
-  if(V1 <= Val[io[0]] && Val[io[1]] <= V2) {
-    for(i = 0; i < 2; i++) {
-      Vp2[i] = Val[i];
-      Xp2[i] = X[i];
-      Yp2[i] = Y[i];
-      Zp2[i] = Z[i];
-    }
+
+
+
+// Draw an iso-line inside a triangle
+
+void IsoTriangle_Old(Post_View * View, double *X, double *Y, double *Z,
+		     double *Val, double V, unsigned int color)
+{
+  // don't draw anything if the value is constant
+  if(Val[0] == Val[1] && Val[0] == Val[2])
     return;
-  }
 
-  if(V1 <= Val[io[0]]) {
-    Vp2[0] = Val[io[0]];
-    Xp2[0] = X[io[0]];
-    Yp2[0] = Y[io[0]];
-    Zp2[0] = Z[io[0]];
+  double Xp[3], Yp[3], Zp[3];
+  int nb = 0;
+  if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 0, 1, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
   }
-  else {
-    Vp2[0] = V1;
-    InterpolateIso(X, Y, Z, Val, V1, io[0], io[1], &Xp2[0], &Yp2[0], &Zp2[0]);
+  if((Val[0] >= V && Val[2] <= V) || (Val[2] >= V && Val[0] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 0, 2, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
   }
-
-  if(V2 >= Val[io[1]]) {
-    Vp2[1] = Val[io[1]];
-    Xp2[1] = X[io[1]];
-    Yp2[1] = Y[io[1]];
-    Zp2[1] = Z[io[1]];
+  if((Val[1] >= V && Val[2] <= V) || (Val[2] >= V && Val[1] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 1, 2, &Xp[nb], &Yp[nb], &Zp[nb]);
+    nb++;
   }
-  else {
-    Vp2[1] = V2;
-    InterpolateIso(X, Y, Z, Val, V2, io[0], io[1], &Xp2[1], &Yp2[1], &Zp2[1]);
+  
+  if(nb == 2){
+    if(View->LinVertexArray && View->LinVertexArray->fill && !View->LineType){
+      View->LinVertexArray->add(Xp[0], Yp[0], Zp[0], color);
+      View->LinVertexArray->add(Xp[1], Yp[1], Zp[1], color);
+    }
+    else{
+      glColor4ubv((GLubyte *) & color);
+      Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, View->Light);
+    }
+  }
+}
+
+// Draw an iso-point in a line
+
+void IsoLine_Old(Post_View *View, double *X, double *Y, double *Z, 
+		 double *Val, double V)
+{
+  double Xp[2], Yp[2], Zp[2];
+
+  // don't draw anything if the value is constant
+  if(Val[0] == Val[1])
+    return;
+
+  if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
+    InterpolateIso(X, Y, Z, Val, V, 0, 1, Xp, Yp, Zp);
+    Draw_Point(View->PointType, View->PointSize, Xp, Yp, Zp, View->Light);
   }
 }
 
@@ -400,19 +559,11 @@ void EnhanceSimplexPolygon(Post_View * View, int nb,    // nb of points in polyg
   }
 }
 
-static void affect(double *xi, double *yi, double *zi, int i,
-		   double *xp, double *yp, double *zp, int j)
-{
-  xi[i] = xp[j];
-  yi[i] = yp[j];
-  zi[i] = zp[j];
-}
-
 // Draw an iso-surface inside a tetrahedron
 
-void IsoSimplex(Post_View * View, int preproNormals,
-                double *X, double *Y, double *Z, double *Val,
-                double V, unsigned int color)
+void IsoSimplex_Old(Post_View * View, int preproNormals,
+		    double *X, double *Y, double *Z, double *Val,
+		    double V, unsigned int color)
 {
   int nb;
   double Xp[6], Yp[6], Zp[6], PVals[6];
diff --git a/Graphics/Iso.h b/Graphics/Iso.h
index 2fda616f9575142b192d235e4e00fb28dc3f1c6a..ded5a8552e75a7215ad58868f89e073c3acdf238 100644
--- a/Graphics/Iso.h
+++ b/Graphics/Iso.h
@@ -20,25 +20,37 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Views.h"
+int IsoLine(double *X, double *Y, double *Z, double *Val, double V,
+	    double *Xp, double *Yp, double *Zp);
+
+int IsoTriangle(double *X, double *Y, double *Z, double *Val, double V, 
+		double *Xp, double *Yp, double *Zp);
+
+int IsoSimplex(double *X, double *Y, double *Z, double *Val, double V,
+	       double *Xp, double *Yp, double *Zp, double n[3]);
+
+int CutLine(double *x, double *y, double *z, double *v,
+	    double min, double max, 
+	    double *xp, double *yp, double *zp, double *vp);
 
-void CutTriangle(double *X, double *Y, double *Z, double *Val,
-		 double V1, double V2, double *Xp, double *Yp, double *Zp, 
-		 int *nb, double *value);
+int CutTriangle(double *x, double *y, double *z, double *v,
+		double min, double max, 
+		double *xp, double *yp, double *zp, double *vp);
 
-void CutLine(double *X, double *Y, double *Z, double *Val,
-	     double V1, double V2, double *Xp, double *Yp, double *Zp,
-	     int *nb, double *value);
 
-void IsoLine(Post_View *View, double *X, double *Y, double *Z, 
-	     double *Val, double V);
+// ******** FIXME: REMOVE EVERYTHING BELOW THIS LINE ***************
+
+#include "Views.h"
+
+void IsoLine_Old(Post_View *View, double *X, double *Y, double *Z, 
+		 double *Val, double V);
 
-void IsoTriangle(Post_View *View, 
-		 double *X, double *Y, double *Z, double *Val, double V,
-		 unsigned int color);
+void IsoTriangle_Old(Post_View *View, 
+		     double *X, double *Y, double *Z, double *Val, double V,
+		     unsigned int color);
 
-void IsoSimplex(Post_View *View, int preproNormals, 
-		double *X, double *Y, double *Z, double *Val, double V,
-		unsigned int color);
+void IsoSimplex_Old(Post_View *View, int preproNormals, 
+		    double *X, double *Y, double *Z, double *Val, double V,
+		    unsigned int color);
   
 #endif
diff --git a/Graphics/Makefile b/Graphics/Makefile
index c6c42da2a3fc3ba58fdc880ded609ae200f1f2b3..66d678041b44c73997e547101778fc945cd78e25 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.121 2007-08-24 20:14:18 geuzaine Exp $
+# $Id: Makefile,v 1.122 2007-08-27 13:46:22 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -22,8 +22,9 @@
 include ../variables
 
 LIB     = ../lib/libGmshGraphics.a
-INCLUDE = -I../Common -I../DataStr -I../Geo -I../Mesh -I../Post -I../Graphics\
-          -I../Fltk -I../Numeric -I../Parser -I../Plugin -I../contrib/ANN/include
+INCLUDE = -I../Common -I../DataStr -I../Geo -I../Mesh -I../Post\
+          -I../Graphics -I../Fltk -I../Numeric -I../Parser -I../Plugin\
+          -I../contrib/MathEval -I../contrib/ANN/include
 CFLAGS  = ${OPTIM} ${FLAGS} ${INCLUDE}
 
 SRC = Draw.cpp \
@@ -70,21 +71,21 @@ depend:
 Draw.o: Draw.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
-  ../Common/GmshDefines.h Draw.h ../Common/Context.h ../Numeric/Numeric.h \
-  ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
-  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
-  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Geo/GFace.h \
-  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
-  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
-  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
-  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
+  ../Common/GmshDefines.h Draw.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Common/Context.h ../Numeric/Numeric.h ../Geo/GModel.h \
+  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/ExtrudeParams.h \
+  ../Common/SmoothData.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
+  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
+  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
+  ../Geo/SBoundingBox3d.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/VertexArray.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
 Mesh.o: Mesh.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h ../Geo/GModel.h \
@@ -106,9 +107,9 @@ Mesh.o: Mesh.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
 Geom.o: Geom.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h Draw.h \
-  ../Common/Context.h gl2ps.h ../Geo/GModel.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/Context.h gl2ps.h \
+  ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Common/GmshDefines.h \
   ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
   ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
@@ -122,39 +123,56 @@ Geom.o: Geom.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
 Post_Old.o: Post_Old.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Common/Context.h gl2ps.h
-Post.o: Post.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
-  ../Numeric/Numeric.h Draw.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Post/Views.h ../Post/ColorTable.h \
   ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
   ../Common/SmoothData.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
   ../Common/Context.h gl2ps.h
+Post.o: Post.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
+  ../Numeric/Numeric.h Draw.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  Iso.h ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
+  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Post/PView.h \
+  ../Post/AdaptiveViews.h ../Post/PViewData.h ../Geo/GModel.h \
+  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Common/GmshDefines.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Context.h \
+  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
+  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
+  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
+  ../Geo/SBoundingBox3d.h ../Post/PViewOptions.h ../Post/ColorTable.h \
+  gl2ps.h
 PostElement.o: PostElement.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h Draw.h Iso.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Common/SmoothData.h ../Numeric/Numeric.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Common/Context.h
+  ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  Iso.h ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
+  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ../Common/Context.h
 SelectBuffer.o: SelectBuffer.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Common/GmshDefines.h Draw.h ../Common/Context.h \
+  ../Common/GmshUI.h ../Common/GmshDefines.h Draw.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/Context.h \
   SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
-  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
-  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Numeric/Numeric.h ../Geo/ExtrudeParams.h ../Common/SmoothData.h \
-  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h \
-  ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
-  ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h \
   ../Geo/SBoundingBox3d.h ../Geo/MRep.h ../Geo/GEdge.h ../Geo/GFace.h \
@@ -163,17 +181,18 @@ SelectBuffer.o: SelectBuffer.cpp ../Common/Gmsh.h ../Common/Message.h \
 Iso.o: Iso.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h Draw.h \
-  ../Common/Context.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Common/SmoothData.h ../Numeric/Numeric.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/Context.h \
+  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
+  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
 Entity.o: Entity.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Common/Context.h gl2ps.h
+  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Common/SmoothData.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ../Common/Context.h gl2ps.h
 ReadImg.o: ReadImg.cpp ReadImg.h ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -184,45 +203,42 @@ ReadImg.o: ReadImg.cpp ReadImg.h ../Common/Gmsh.h ../Common/Message.h \
 Scale.o: Scale.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Common/Context.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h gl2ps.h
+  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Common/Context.h ../Post/Views.h \
+  ../Post/ColorTable.h ../Common/VertexArray.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
+  ../Common/GmshMatrix.h gl2ps.h
 Graph2D.o: Graph2D.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Common/Context.h ../Numeric/Numeric.h Draw.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h gl2ps.h
-gl2ps.o: gl2ps.cpp gl2ps.h /usr/local/include/FL/images/zlib.h \
-  /usr/local/include/FL/images/zconf.h /usr/local/include/FL/images/png.h \
-  /usr/local/include/FL/images/zlib.h \
-  /usr/local/include/FL/images/pngconf.h
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Post/Views.h \
+  ../Post/ColorTable.h ../Common/VertexArray.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
+  ../Common/GmshMatrix.h gl2ps.h
+gl2ps.o: gl2ps.cpp gl2ps.h
 gl2gif.o: gl2gif.cpp gl2gif.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
 gl2jpeg.o: gl2jpeg.cpp gl2jpeg.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h \
-  /usr/local/include/FL/images/jpeglib.h \
-  /usr/local/include/FL/images/jconfig.h \
-  /usr/local/include/FL/images/jmorecfg.h \
-  /usr/local/include/FL/images/jerror.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
 gl2png.o: gl2png.cpp gl2png.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h \
-  /usr/local/include/FL/images/png.h /usr/local/include/FL/images/zlib.h \
-  /usr/local/include/FL/images/zconf.h \
-  /usr/local/include/FL/images/pngconf.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
 gl2ppm.o: gl2ppm.cpp gl2ppm.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
 gl2yuv.o: gl2yuv.cpp gl2yuv.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index e34a941294b1470e9c09bdbf31de87891df06684..69eb1ea3820627a6ea5451544e56968b1c417d35 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.117 2007-08-25 22:42:28 geuzaine Exp $
+// $Id: Post.cpp,v 1.118 2007-08-27 13:46:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -28,6 +28,10 @@
 #include "Context.h"
 #include "gl2ps.h"
 
+#if defined(HAVE_MATH_EVAL)
+#include "matheval.h"
+#endif
+
 extern Context_T CTX;
 
 #define NMAX 20
@@ -43,27 +47,6 @@ void saturate(int nb, double val[NMAX][9], double vmin, double vmax,
   }
 }
 
-int cutTriangle(double xyz[NMAX][3], double val[NMAX][9], double vmin, double vmax,
-		int i0=0, int i1=1, int i2=2)
-{
-  int id[3] = {i0, i1, i2}, np;
-  double x[NMAX], y[NMAX], z[NMAX], xp[NMAX], yp[NMAX], zp[NMAX], v[NMAX], vp[NMAX];
-  for(int i = 0; i < 3; i++){
-    x[i] = xyz[id[i]][0];
-    y[i] = xyz[id[i]][1];
-    z[i] = xyz[id[i]][2];
-    v[i] = val[id[i]][0];
-  }
-  CutTriangle(x, y, z, v, vmin, vmax, xp, yp, zp, &np, vp);
-  for(int i = 0; i < np; i++){
-    xyz[i][0] = xp[i];
-    xyz[i][1] = yp[i];
-    xyz[i][2] = zp[i];
-    val[i][0] = vp[i];
-  }
-  return np;
-}
-
 SVector3 normal3(double xyz[NMAX][3], int i0=0, int i1=1, int i2=2)
 {
   SVector3 t1(xyz[i1][0] - xyz[i0][0], 
@@ -77,9 +60,90 @@ SVector3 normal3(double xyz[NMAX][3], int i0=0, int i1=1, int i2=2)
   return n;
 }
 
-void changeCoordinates(PView *p, int nbnod, int nbcomp, 
-		       double xyz[NMAX][3], double val[NMAX][9],
-		       bool offset, bool raise, bool transform)
+double normValue(int numComp, double val[9])
+{
+  if(numComp == 1)
+    return val[0];
+  else if(numComp == 3)
+    return sqrt(val[0] * val[0] + val[1] * val[1] + val[2] * val[2]);
+  else if(numComp == 9)
+    return ComputeVonMises(val);
+  return 0.;
+}
+
+bool getExternalValues(PView *p, int index, int iele, int nbnod,
+		       int nbcomp, double val[NMAX][9], 
+		       int &nbcomp2, double val2[NMAX][9])
+{
+  PViewOptions *opt = p->getOptions();
+
+  // use self by default
+  nbcomp2 = nbcomp;
+  for(int i = 0; i < nbnod; i++)
+    for(int j = 0; j < nbcomp; j++)
+      val2[i][j] = val[i][j];
+  opt->ExternalMin = opt->TmpMin;
+  opt->ExternalMax = opt->TmpMax;
+
+  if(index < 0 || index >= PView::list.size()) return false;
+
+  PView *p2 = PView::list[index];
+  PViewData *data2 = p2->getData();
+
+  if(opt->TimeStep < data2->getNumTimeSteps() && iele < data2->getNumElements()){
+    if(data2->getNumNodes(iele) == nbnod){
+      nbcomp2 = data2->getNumComponents(iele);
+      for(int i = 0; i < nbnod; i++)
+	for(int j = 0; j < nbcomp2; j++)
+	  data2->getValue(iele, i, j, opt->TimeStep, val2[i][j]);
+      if(opt->RangeType == PViewOptions::Custom){
+	opt->ExternalMin = opt->CustomMin;
+	opt->ExternalMax = opt->CustomMax;
+      }
+      else if(opt->RangeType == PViewOptions::PerTimeStep){
+	opt->ExternalMin = data2->getMin(opt->TimeStep);
+	opt->ExternalMax = data2->getMax(opt->TimeStep);
+      }
+      else{
+	opt->ExternalMin = data2->getMin();
+	opt->ExternalMax = data2->getMax();
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+void applyGeneralRaise(PView *p, int numNodes, int numComp, 
+		       double vals[NMAX][9], double xyz[NMAX][3])
+{
+  PViewOptions *opt = p->getOptions();
+
+  for(int k = 0; k < numNodes; k++) {
+    double d[9] = {0., 0., 0., 0., 0., 0., 0., 0., 0.};
+    for(int l = 0; l < numComp; l++) d[l] = vals[k][l];
+#if defined(HAVE_MATH_EVAL)
+    char *names[] = { "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8" ,
+		      "x", "y", "z" };
+    double values[] = { d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8],
+			xyz[k][0], xyz[k][1], xyz[k][2] };
+    for(int i = 0; i < 3; i++) {
+      if(opt->GenRaise_f[i])
+        xyz[k][i] += opt->GenRaiseFactor * evaluator_evaluate
+	  (opt->GenRaise_f[i], sizeof(names) / sizeof(names[0]), names, values);
+    }
+#else
+    for(int i = 0; i < 3; i++){
+      int comp = (int)opt->GenRaise_f[i];
+      if(comp >= 0)
+	xyz[k][i] += opt->GenRaiseFactor * d[comp];
+    }
+#endif
+  }
+}
+
+void changeCoordinates(PView *p, int iele, int nbnod, int nbcomp, 
+		       double xyz[NMAX][3], double val[NMAX][9])
 {
   PViewOptions *opt = p->getOptions();
 
@@ -95,7 +159,11 @@ void changeCoordinates(PView *p, int nbnod, int nbcomp,
 	xyz[i][j] = barycenter[j] + opt->Explode * (xyz[i][j] - barycenter[j]);
   }
   
-  if(transform){
+  if(opt->Transform[0][0] != 1. || opt->Transform[0][1] != 0. || 
+     opt->Transform[0][2] != 0. || opt->Transform[1][0] != 0. || 
+     opt->Transform[1][1] != 1. || opt->Transform[1][2] != 0. ||
+     opt->Transform[2][0] != 0. || opt->Transform[2][1] != 0. || 
+     opt->Transform[2][2] != 1.){
     for(int i = 0; i < nbnod; i++) {
       double old[3] = {xyz[i][0], xyz[i][1], xyz[i][2]};
       for(int j = 0; j < 3; j++){
@@ -106,79 +174,143 @@ void changeCoordinates(PView *p, int nbnod, int nbcomp,
     }
   }
   
-  if(offset){
+  if(opt->Offset[0] || opt->Offset[1] || opt->Offset[2]){
     for(int i = 0; i < nbnod; i++)
       for(int j = 0; j < 3; j++)
 	xyz[i][j] += opt->Offset[j];
   }
   
-  if(raise){
+  if(opt->Raise[0] || opt->Raise[1] || opt->Raise[2]){
     for(int i = 0; i < nbnod; i++){
-      double norm = 0.;
-      if(nbcomp == 1)
-	norm = val[i][0];
-      else if(nbcomp == 3)
-	norm = sqrt(val[i][0] * val[i][0] + 
-		    val[i][1] * val[i][1] + 
-		    val[i][2] * val[i][2]);
-      else if(nbcomp == 9)
-	norm = ComputeVonMises(val[i]);
+      double norm = normValue(nbcomp, val[i]);
       for(int j = 0; j < 3; j++)
 	xyz[i][j] += opt->Raise[j] * norm;
     }
   }
 
-  if(opt->UseGenRaise){
-    /* FIXME
-    int ext_nbcomp = nbcomp;
-    double *ext_vals = vals;
-    if(v->ViewIndexForGenRaise >= 0)
-      GetValuesFromExternalView(v, type, nbcomp, &ext_nbcomp, &ext_vals, 
-				v->ViewIndexForGenRaise);
-    ApplyGeneralizedRaise(v, nbnod, ext_nbcomp, ext_vals, x2, y2, z2);
-    */
+  if(nbcomp == 3 && opt->VectorType == PViewOptions::Displacement){
+    for(int i = 0; i < nbnod; i++){
+      for(int j = 0; j < 3; j++)
+	xyz[i][j] += opt->DisplacementFactor * val[i][j];
+    }
   }
 
-  for(int i = 0; i < nbnod; i++)
-    opt->TmpBBox += SPoint3(xyz[i][0], xyz[i][1], xyz[i][2]);
+  if(opt->UseGenRaise){
+    int nbcomp2;
+    double val2[NMAX][9];
+    getExternalValues(p, opt->ViewIndexForGenRaise, iele, nbnod, 
+		      nbcomp, val, nbcomp2, val2);
+    applyGeneralRaise(p, nbnod, nbcomp2, val2, xyz);
+  }
 }
 
 void addOutlinePoint(PView *p, double xyz[NMAX][3], unsigned int color,
 		     bool pre=false, int i0=0)
 {
-  if(!pre)
-    p->va_points->add(&xyz[i0][0], &xyz[i0][1], &xyz[i0][2], 0, &color, 0, true);
+  if(pre) return;
+  p->va_points->add(&xyz[i0][0], &xyz[i0][1], &xyz[i0][2], 0, &color, 0, true);
 }
 
 void addScalarPoint(PView *p, double xyz[NMAX][3], double val[NMAX][9],
 		    bool pre=false, int i0=0, bool unique=false)
 {
-  if(!pre){
-    PViewOptions *opt = p->getOptions();
-    double vmin = opt->TmpMin, vmax = opt->TmpMax;
-    unsigned int col = opt->getColor(val[i0][0], vmin, vmax);
-    p->va_points->add(&xyz[i0][0], &xyz[i0][1], &xyz[i0][2], 0, &col, 0, unique);
-  }
+  if(pre) return;
+
+  PViewOptions *opt = p->getOptions();
+  double vmin = opt->TmpMin, vmax = opt->TmpMax;
+  if(opt->SaturateValues) saturate(1, val, vmin, vmax, i0);
+  unsigned int col = opt->getColor(val[i0][0], vmin, vmax);
+  p->va_points->add(&xyz[i0][0], &xyz[i0][1], &xyz[i0][2], 0, &col, 0, unique);
 }
 
 void addOutlineLine(PView *p, double xyz[NMAX][3], unsigned int color,
 		    bool pre=false, int i0=0, int i1=1)
 {
-  if(!pre){
-    const int in[3] = {i0, i1};
-    unsigned int col[2];
-    double x[2], y[2], z[2];
-    for(int i = 0; i < 2; i++){
-      x[i] = xyz[in[i]][0]; y[i] = xyz[in[i]][1]; z[i] = xyz[in[i]][2]; 
-      col[i] = color;
-    }
-    p->va_lines->add(x, y, z, 0, col, 0, true);
+  if(pre) return;
+
+  const int in[3] = {i0, i1};
+  unsigned int col[2];
+  double x[2], y[2], z[2];
+  for(int i = 0; i < 2; i++){
+    x[i] = xyz[in[i]][0]; y[i] = xyz[in[i]][1]; z[i] = xyz[in[i]][2]; 
+    col[i] = color;
   }
+  p->va_lines->add(x, y, z, 0, col, 0, true);
 }
 
 void addScalarLine(PView *p, double xyz[NMAX][3], double val[NMAX][9], 
 		   bool pre=false, int i0=0, int i1=1, bool unique=false)
 {
+  if(pre) return;
+
+  PViewOptions *opt = p->getOptions();
+
+  if(opt->Boundary > 0){
+    opt->Boundary--;
+    addScalarPoint(p, xyz, val, pre, i0, true);
+    addScalarPoint(p, xyz, val, pre, i1, true);
+    opt->Boundary++;
+    return;
+  }
+
+  double x[2] = {xyz[i0][0], xyz[i1][0]};
+  double y[2] = {xyz[i0][1], xyz[i1][1]};
+  double z[2] = {xyz[i0][2], xyz[i1][2]};
+  double v[2] = {val[i0][0], val[i1][0]};
+
+  double vmin = opt->TmpMin, vmax = opt->TmpMax;
+
+  if(opt->SaturateValues) saturate(2, val, vmin, vmax, i0, i1);
+
+  if(opt->IntervalsType == PViewOptions::Continuous){
+    if(val[i0][0] >= vmin && val[i0][0] <= vmax &&
+       val[i1][0] >= vmin && val[i1][0] <= vmax){
+      unsigned int col[2];
+      for(int i = 0; i < 2; i++)
+	col[i] = opt->getColor(v[i], vmin, vmax);
+      p->va_lines->add(x, y, z, 0, col, 0, unique);
+    }
+    else{
+      double x2[2], y2[2], z2[2], v2[2];
+      int nb = CutLine(x, y, z, v, vmin, vmax, x2, y2, z2, v2);
+      if(nb == 2){
+	unsigned int col[2];
+	for(int i = 0; i < 2; i++)
+	  col[i] = opt->getColor(v2[i], vmin, vmax);
+	p->va_lines->add(x2, y2, z2, 0, col, 0, unique);
+      }
+    }
+  }
+
+  if(opt->IntervalsType == PViewOptions::Discrete){
+    for(int k = 0; k < opt->NbIso; k++){
+      if(vmin == vmax) k = opt->NbIso / 2;
+      double min = opt->getScaleValue(k, opt->NbIso + 1, vmin, vmax);
+      double max = opt->getScaleValue(k + 1, opt->NbIso + 1, vmin, vmax);
+      double x2[2], y2[2], z2[2], v2[2];
+      int nb = CutLine(x, y, z, v, min, max, x2, y2, z2, v2);
+      if(nb == 2){
+	unsigned color = opt->getColor(k, opt->NbIso);
+	unsigned int col[2] = {color, color};
+	p->va_lines->add(x2, y2, z2, 0, col, 0, unique);
+      }
+      if(vmin == vmax) break;
+    }
+  }
+  
+  if(opt->IntervalsType == PViewOptions::Iso){
+    for(int k = 0; k < opt->NbIso; k++) {
+      if(vmin == vmax) k = opt->NbIso / 2;
+      double iso = opt->getScaleValue(k, opt->NbIso, vmin, vmax);
+      double x2[1], y2[1], z2[1], v2[1];
+      int nb = IsoLine(x, y, z, v, iso, x2, y2, z2);
+      if(nb == 1){
+	unsigned int color = opt->getColor(k, opt->NbIso);
+	p->va_points->add(x2, y2, z2, 0, &color, 0, unique);
+      }
+      if(vmin == vmax) break;
+    }
+  }
 }
 
 void addOutlineTriangle(PView *p, double xyz[NMAX][3], unsigned int color,
@@ -188,19 +320,19 @@ void addOutlineTriangle(PView *p, double xyz[NMAX][3], unsigned int color,
 
   const int il[3][2] = {{i0, i1}, {i1, i2}, {i2, i0}};
 
-  unsigned int col[2];
-  SVector3 nfac = normal3(xyz, i0, i1, i2), n[2];
-  double x[2], y[2], z[2];
+  SVector3 nfac = normal3(xyz, i0, i1, i2);
 
   for(int i = 0; i < 3; i++){
-    for(int j = 0; j < 2; j++){
-      x[j] = xyz[il[i][j]][0]; y[j] = xyz[il[i][j]][1]; z[j] = xyz[il[i][j]][2]; 
-      n[j] = nfac;
-      if(opt->SmoothNormals){
+    double x[2] = {xyz[il[i][0]][0], xyz[il[i][1]][0]};
+    double y[2] = {xyz[il[i][0]][1], xyz[il[i][1]][1]};
+    double z[2] = {xyz[il[i][0]][2], xyz[il[i][1]][2]};
+    SVector3 n[2] = {nfac, nfac};
+    unsigned int col[2] = {color, color};
+    if(opt->SmoothNormals){
+      for(int j = 0; j < 2; j++){
 	if(pre) p->normals->add(x[j], y[j], z[j], n[j][0], n[j][1], n[j][2]);
 	else p->normals->get(x[j], y[j], z[j], n[j][0], n[j][1], n[j][2]);
       }
-      col[j] = color;
     }
     if(!pre) p->va_lines->add(x, y, z, n, col, 0, true);
   }
@@ -212,20 +344,23 @@ void addScalarTriangle(PView *p, double xyz[NMAX][3], double val[NMAX][9],
 {
   PViewOptions *opt = p->getOptions();
 
-  const int in[3] = {i0, i1, i2};
   const int il[3][2] = {{i0, i1}, {i1, i2}, {i2, i0}};
 
   if(opt->Boundary > 0){
     opt->Boundary--;
     for(int i = 0; i < 3; i++)
-      addScalarLine(p, xyz, val, il[i][0], il[i][1], true);
+      addScalarLine(p, xyz, val, pre, il[i][0], il[i][1], true);
     opt->Boundary++;
     return;
   }
 
-  unsigned int col[3];
-  SVector3 nfac = normal3(xyz, i0, i1, i2), n[3];
-  double vmin = opt->TmpMin, vmax = opt->TmpMax, x[3], y[3], z[3];
+  double x[3] = {xyz[i0][0], xyz[i1][0], xyz[i2][0]};
+  double y[3] = {xyz[i0][1], xyz[i1][1], xyz[i2][1]};
+  double z[3] = {xyz[i0][2], xyz[i1][2], xyz[i2][2]};
+  double v[3] = {val[i0][0], val[i1][0], val[i2][0]};
+
+  SVector3 nfac = normal3(xyz, i0, i1, i2);
+  double vmin = opt->TmpMin, vmax = opt->TmpMax;
 
   if(opt->SaturateValues) saturate(3, val, vmin, vmax, i0, i1, i2);
 
@@ -233,34 +368,36 @@ void addScalarTriangle(PView *p, double xyz[NMAX][3], double val[NMAX][9],
     if(val[i0][0] >= vmin && val[i0][0] <= vmax &&
        val[i1][0] >= vmin && val[i1][0] <= vmax &&
        val[i2][0] >= vmin && val[i2][0] <= vmax){
-      // full triangle
+      SVector3 n[3] = {nfac, nfac, nfac};
+      unsigned int col[3];
       for(int i = 0; i < 3; i++){
-	x[i] = xyz[in[i]][0]; y[i] = xyz[in[i]][1]; z[i] = xyz[in[i]][2]; 
-	n[i] = nfac;
 	if(opt->SmoothNormals){
 	  if(pre) p->normals->add(x[i], y[i], z[i], n[i][0], n[i][1], n[i][2]);
 	  else p->normals->get(x[i], y[i], z[i], n[i][0], n[i][1], n[i][2]);
 	}
-	col[i] = opt->getColor(val[in[i]][0], vmin, vmax);
+	col[i] = opt->getColor(v[i], vmin, vmax);
       }
       if(!pre) p->va_triangles->add(x, y, z, n, col, 0, unique);
     }
     else{
-      // draw part of the triangle between vmin and vmax
-      int nb = cutTriangle(xyz, val, vmin, vmax, i0, i1, i2);
+      double x2[10], y2[10], z2[10], v2[10];
+      int nb = CutTriangle(x, y, z, v, vmin, vmax, x2, y2, z2, v2);
       if(nb >= 3){
 	for(int j = 2; j < nb; j++){
-	  int id2[3] = {0, j - 1, j};
+	  double x3[3] = {x2[0], x2[j - 1], x2[j]};
+	  double y3[3] = {y2[0], y2[j - 1], y2[j]};
+	  double z3[3] = {z2[0], z2[j - 1], z2[j]};
+	  double v3[3] = {v2[0], v2[j - 1], v2[j]};
+	  SVector3 n[3] = {nfac, nfac, nfac};
+	  unsigned int col[3];
 	  for(int i = 0; i < 3; i++){
-	    x[i] = xyz[id2[i]][0]; y[i] = xyz[id2[i]][1]; z[i] = xyz[id2[i]][2];
-	    n[i] = nfac;
 	    if(opt->SmoothNormals){
-	      if(pre) p->normals->add(x[i], y[i], z[i], n[i][0], n[i][1], n[i][2]);
-	      else p->normals->get(x[i], y[i], z[i], n[i][0], n[i][1], n[i][2]);
+	      if(pre) p->normals->add(x3[i], y3[i], z3[i], n[i][0], n[i][1], n[i][2]);
+	      else p->normals->get(x3[i], y3[i], z3[i], n[i][0], n[i][1], n[i][2]);
 	    }
-	    col[i] = opt->getColor(val[id2[i]][0], vmin, vmax);
+	    col[i] = opt->getColor(v3[i], vmin, vmax);
 	  }
-	  if(!pre) p->va_triangles->add(x, y, z, n, col, 0, unique);
+	  if(!pre) p->va_triangles->add(x3, y3, z3, n, col, 0, unique);
 	}
       }
     }
@@ -269,22 +406,25 @@ void addScalarTriangle(PView *p, double xyz[NMAX][3], double val[NMAX][9],
   if(opt->IntervalsType == PViewOptions::Discrete){
     for(int k = 0; k < opt->NbIso; k++){
       if(vmin == vmax) k = opt->NbIso / 2;
-      double min = 0.;//FIXME View->GVFI(vmin, vmax, p->NbIso + 1, k);
-      double max = 0.;//FIXME View->GVFI(vmin, vmax, p->NbIso + 1, k + 1);
-      int nb = cutTriangle(xyz, val, min, max, i0, i1, i2);
+      double min = opt->getScaleValue(k, opt->NbIso + 1, vmin, vmax);
+      double max = opt->getScaleValue(k + 1, opt->NbIso + 1, vmin, vmax);
+      double x2[10], y2[10], z2[10], v2[10];
+      int nb = CutTriangle(x, y, z, v, min, max, x2, y2, z2, v2);
       if(nb >= 3){
+	unsigned color = opt->getColor(k, opt->NbIso);
+	unsigned int col[3] = {color, color, color};
 	for(int j = 2; j < nb; j++){
-	  int id2[3] = {0, j - 1, j};
-	  for(int i = 0; i < 3; i++){
-	    x[i] = xyz[id2[i]][0]; y[i] = xyz[id2[i]][1]; z[i] = xyz[id2[i]][2];
-	    n[i] = nfac;
-	    if(opt->SmoothNormals){
-	      if(pre) p->normals->add(x[i], y[i], z[i], n[i][0], n[i][1], n[i][2]);
-	      else p->normals->get(x[i], y[i], z[i], n[i][0], n[i][1], n[i][2]);
+	  double x3[3] = {x2[0], x2[j - 1], x2[j]};
+	  double y3[3] = {y2[0], y2[j - 1], y2[j]};
+	  double z3[3] = {z2[0], z2[j - 1], z2[j]};
+	  SVector3 n[3] = {nfac, nfac, nfac};
+	  if(opt->SmoothNormals){
+	    for(int i = 0; i < 3; i++){
+	      if(pre) p->normals->add(x3[i], y3[i], z3[i], n[i][0], n[i][1], n[i][2]);
+	      else p->normals->get(x3[i], y3[i], z3[i], n[i][0], n[i][1], n[i][2]);
 	    }
-	    col[i] = opt->getColor(k, opt->NbIso);
 	  }
-	  if(!pre) p->va_triangles->add(x, y, z, n, col, 0, col);
+	  if(!pre) p->va_triangles->add(x3, y3, z3, n, col, 0, unique);
 	}
       }
       if(vmin == vmax) break;
@@ -294,9 +434,21 @@ void addScalarTriangle(PView *p, double xyz[NMAX][3], double val[NMAX][9],
   if(opt->IntervalsType == PViewOptions::Iso){
     for(int k = 0; k < opt->NbIso; k++) {
       if(vmin == vmax) k = opt->NbIso / 2;
-      //unsigned int col = PaletteDiscrete(View, View->NbIso, k);
-      //IsoTriangle(View, X, Y, Z, Val,
-      //	  View->GVFI(ValMin, ValMax, View->NbIso, k), col);
+      double iso = opt->getScaleValue(k, opt->NbIso, vmin, vmax);
+      double x2[3], y2[3], z2[3], v2[3];
+      int nb = IsoTriangle(x, y, z, v, iso, x2, y2, z2);
+      if(nb == 2){
+	unsigned int color = opt->getColor(k, opt->NbIso);
+	unsigned int col[2] = {color, color};
+	SVector3 n[2] = {nfac, nfac};
+	if(opt->SmoothNormals){
+	  for(int i = 0; i < 2; i++){
+	    if(pre) p->normals->add(x2[i], y2[i], z2[i], n[i][0], n[i][1], n[i][2]);
+	    else p->normals->get(x2[i], y2[i], z2[i], n[i][0], n[i][1], n[i][2]);
+	  }
+	}
+	if(!pre) p->va_lines->add(x2, y2, z2, n, col, 0, unique);
+      }
       if(vmin == vmax) break;
     }
   }
@@ -309,19 +461,19 @@ void addOutlineQuadrangle(PView *p, double xyz[NMAX][3], unsigned int color,
 
   const int il[4][2] = {{i0, i1}, {i1, i2}, {i2, i3}, {i3, i0}};
 
-  unsigned int col[2];
-  SVector3 nfac = normal3(xyz, i0, i1, i2), n[2];
-  double x[2], y[2], z[2];
+  SVector3 nfac = normal3(xyz, i0, i1, i2);
 
   for(int i = 0; i < 4; i++){
-    for(int j = 0; j < 2; j++){
-      x[j] = xyz[il[i][j]][0]; y[j] = xyz[il[i][j]][1]; z[j] = xyz[il[i][j]][2]; 
-      n[j] = nfac;
-      if(opt->SmoothNormals){
+    double x[2] = {xyz[il[i][0]][0], xyz[il[i][1]][0]};
+    double y[2] = {xyz[il[i][0]][1], xyz[il[i][1]][1]};
+    double z[2] = {xyz[il[i][0]][2], xyz[il[i][1]][2]};
+    SVector3 n[2] = {nfac, nfac};
+    unsigned int col[2] = {color, color};
+    if(opt->SmoothNormals){
+      for(int j = 0; j < 2; j++){
 	if(pre) p->normals->add(x[j], y[j], z[j], n[j][0], n[j][1], n[j][2]);
 	else p->normals->get(x[j], y[j], z[j], n[j][0], n[j][1], n[j][2]);
       }
-      col[j] = color;
     }
     if(!pre) p->va_lines->add(x, y, z, n, col, 0, true);
   }
@@ -339,7 +491,7 @@ void addScalarQuadrangle(PView *p, double xyz[NMAX][3], double val[NMAX][9],
   if(opt->Boundary > 0){
     opt->Boundary--;
     for(int i = 0; i < 4; i++)
-      addScalarLine(p, xyz, val, il[i][0], il[i][1], true);
+      addScalarLine(p, xyz, val, pre, il[i][0], il[i][1], true);
     opt->Boundary++;
     return;
   }
@@ -363,7 +515,9 @@ void addScalarTetrahedron(PView *p, double xyz[NMAX][3], double val[NMAX][9],
 
   const int it[4][3] = {{i0, i2, i1}, {i0, i1, i3}, {i0, i3, i2}, {i3, i1, i2}};
 
-  if(opt->Boundary > 0){
+  if(opt->Boundary > 0 ||
+     opt->IntervalsType == PViewOptions::Continuous ||
+     opt->IntervalsType == PViewOptions::Discrete){
     opt->Boundary--;
     for(int i = 0; i < 4; i++)
       addScalarTriangle(p, xyz, val, pre, it[i][0], it[i][1], it[i][2], true);
@@ -371,13 +525,42 @@ void addScalarTetrahedron(PView *p, double xyz[NMAX][3], double val[NMAX][9],
     return;
   }
 
-  if(opt->IntervalsType == PViewOptions::Continuous ||
-     opt->IntervalsType == PViewOptions::Discrete){
-    for(int i = 0; i < 4; i++)
-      addScalarTriangle(p, xyz, val, pre, it[i][0], it[i][1], it[i][2], true);
-  }  
-  
-  // iso XXXXXXXXXXXX
+  double x[4] = {xyz[i0][0], xyz[i1][0], xyz[i2][0], xyz[i3][0]};
+  double y[4] = {xyz[i0][1], xyz[i1][1], xyz[i2][1], xyz[i3][1]};
+  double z[4] = {xyz[i0][2], xyz[i1][2], xyz[i2][2], xyz[i3][2]};
+  double v[4] = {val[i0][0], val[i1][0], val[i2][0], val[i3][0]};
+
+  double vmin = opt->TmpMin, vmax = opt->TmpMax;
+
+  if(opt->SaturateValues) saturate(4, val, vmin, vmax, i0, i1, i2, i3);
+
+  if(opt->IntervalsType == PViewOptions::Iso){
+    for(int k = 0; k < opt->NbIso; k++) {
+      if(vmin == vmax) k = opt->NbIso / 2;
+      double iso = opt->getScaleValue(k, opt->NbIso, vmin, vmax);
+      double x2[NMAX], y2[NMAX], z2[NMAX], v2[NMAX], nn[3];
+      int nb = IsoSimplex(x, y, z, v, iso, x2, y2, z2, nn);
+      if(nb >= 3){
+	unsigned int color = opt->getColor(k, opt->NbIso);
+	unsigned int col[3] = {color, color, color};
+	for(int j = 2; j < nb; j++){
+	  double x3[3] = {x2[0], x2[j - 1], x2[j]};
+	  double y3[3] = {y2[0], y2[j - 1], y2[j]};
+	  double z3[3] = {z2[0], z2[j - 1], z2[j]};
+	  SVector3 n[3];
+	  for(int i = 0; i < 3; i++){
+	    n[i][0] = nn[0]; n[i][1] = nn[1]; n[i][2] = nn[2];
+	    if(opt->SmoothNormals){
+	      if(pre) p->normals->add(x3[i], y3[i], z3[i], n[i][0], n[i][1], n[i][2]);
+	      else p->normals->get(x3[i], y3[i], z3[i], n[i][0], n[i][1], n[i][2]);
+	    }
+	  }
+	  if(!pre) p->va_triangles->add(x3, y3, z3, n, col, 0, false);
+	}
+      }
+      if(vmin == vmax) break;
+    }
+  }
 }
 
 void addOutlineHexahedron(PView *p, double xyz[NMAX][3], unsigned int color,
@@ -385,6 +568,7 @@ void addOutlineHexahedron(PView *p, double xyz[NMAX][3], unsigned int color,
 {
   const int iq[6][4] = {{0, 3, 2, 1}, {0, 1, 5, 4}, {0, 4, 7, 3},
 			{1, 2, 6, 5}, {2, 3, 7, 6}, {4, 5, 6, 7}};
+
   for(int i = 0; i < 6; i++)
     addOutlineQuadrangle(p, xyz, color, pre, iq[i][0], iq[i][1], 
 			 iq[i][2], iq[i][3]);
@@ -397,8 +581,7 @@ void addScalarHexahedron(PView *p, double xyz[NMAX][3], double val[NMAX][9],
 
   const int iq[6][4] = {{0, 3, 2, 1}, {0, 1, 5, 4}, {0, 4, 7, 3},
 			{1, 2, 6, 5}, {2, 3, 7, 6}, {4, 5, 6, 7}};
-  // 6 tet subdivision with matching edges on opposite faces
-  const int it[6][4] = {{0, 1, 3, 7}, {0, 4, 1, 7}, {1, 4, 5, 7},
+  const int is[6][4] = {{0, 1, 3, 7}, {0, 4, 1, 7}, {1, 4, 5, 7},
 			{1, 2, 3, 7}, {1, 6, 2, 7}, {1, 5, 6, 7}};
 
   if(opt->Boundary > 0){
@@ -410,37 +593,73 @@ void addScalarHexahedron(PView *p, double xyz[NMAX][3], double val[NMAX][9],
   }
   
   for(int i = 0; i < 6; i++)
-    addScalarTetrahedron(p, xyz, val, pre, it[i][0], it[i][1], it[i][2], it[i][3]);
+    addScalarTetrahedron(p, xyz, val, pre, is[i][0], is[i][1], is[i][2], is[i][3]);
 }
 
 void addOutlinePrism(PView *p, double xyz[NMAX][3], unsigned int color,
 		     bool pre=false)
 {
-  const int it[2][3] = {{0, 2, 1}, {3, 4, 5}};
   const int iq[3][4] = {{0, 1, 4, 3}, {0, 3, 5, 2}, {1, 2, 5, 4}};
-  for(int i = 0; i < 2; i++)
-    addOutlineTriangle(p, xyz, color, pre, it[i][0], it[i][1], it[i][2]);
+  const int it[2][3] = {{0, 2, 1}, {3, 4, 5}};
+
   for(int i = 0; i < 3; i++)
     addOutlineQuadrangle(p, xyz, color, pre, iq[i][0], iq[i][1], iq[i][2], iq[i][3]);
+  for(int i = 0; i < 2; i++)
+    addOutlineTriangle(p, xyz, color, pre, it[i][0], it[i][1], it[i][2]);
 }
 
 void addScalarPrism(PView *p, double xyz[NMAX][3], double val[NMAX][9],
 		    bool pre=false)
 {
+  PViewOptions *opt = p->getOptions();
+
+  const int iq[3][4] = {{0, 1, 4, 3}, {0, 3, 5, 2}, {1, 2, 5, 4}};
+  const int it[2][3] = {{0, 2, 1}, {3, 4, 5}};
+  const int is[3][4] = {{0, 1, 2, 3}, {3, 4, 5, 2}, {1, 2, 4, 3}};
+
+  if(opt->Boundary > 0){
+    opt->Boundary--;
+    for(int i = 0; i < 3; i++)
+      addScalarQuadrangle(p, xyz, val, iq[i][0], iq[i][1], iq[i][2], iq[i][3], true);
+    for(int i = 0; i < 2; i++)
+      addScalarTriangle(p, xyz, val, it[i][0], it[i][1], it[i][2], true);
+    opt->Boundary++;
+    return;
+  }
+  
+  for(int i = 0; i < 3; i++)
+    addScalarTetrahedron(p, xyz, val, pre, is[i][0], is[i][1], is[i][2], is[i][3]);
 }
 
 void addOutlinePyramid(PView *p, double xyz[NMAX][3], unsigned int color,
 		       bool pre=false)
 {
   const int it[4][3] = {{0, 1, 4}, {3, 0, 4}, {1, 2, 4}, {2, 3, 4}};
+
+  addOutlineQuadrangle(p, xyz, color, pre, 0, 3, 2, 1);
   for(int i = 0; i < 4; i++)
     addOutlineTriangle(p, xyz, color, pre, it[i][0], it[i][1], it[i][2]);
-  addOutlineQuadrangle(p, xyz, color, pre, 0, 3, 2, 1);
 }
 
 void addScalarPyramid(PView *p, double xyz[NMAX][3], double val[NMAX][9],
 		      bool pre=false)
 {
+  PViewOptions *opt = p->getOptions();
+
+  const int it[4][3] = {{0, 1, 4}, {3, 0, 4}, {1, 2, 4}, {2, 3, 4}};
+  const int is[2][4] = {{0, 1, 2, 4}, {2, 3, 0, 4}};
+
+  if(opt->Boundary > 0){
+    opt->Boundary--;
+    addScalarQuadrangle(p, xyz, val, 0, 3, 2, 1, true);
+    for(int i = 0; i < 4; i++)
+      addScalarTriangle(p, xyz, val, it[i][0], it[i][1], it[i][2], true);
+    opt->Boundary++;
+    return;
+  }
+
+  for(int i = 0; i < 2; i++)
+    addScalarTetrahedron(p, xyz, val, pre, is[i][0], is[i][1], is[i][2], is[i][3]);
 }
 
 void addOutlineElement(PView *p, int numEdges, double xyz[NMAX][3], bool pre)
@@ -473,16 +692,64 @@ void addScalarElement(PView *p, int numEdges, double xyz[NMAX][3],
   }
 }
 
-void addVectorElement(PView *p, int numEdges, double xyz[NMAX][3],
-		      double val[NMAX][9], bool pre)
+void addVectorElement(PView *p, int iele, int numNodes, int numEdges, 
+		      double xyz[NMAX][3], double val[NMAX][9], bool pre)
 {
-  // if(displacement) change xyz then call addScalarElement()
-  // ...
+  PViewData *data = p->getData();
+  PViewOptions *opt = p->getOptions();
+
+  if(opt->VectorType == PViewOptions::Displacement){
+    int numComp2;
+    double val2[NMAX][9];
+    getExternalValues(p, opt->ExternalViewIndex, iele, numNodes, 
+		      3, val, numComp2, val2);
+    for(int i = 0; i < numNodes; i++)
+      val2[i][0] = normValue(numComp2, val2[i]);
+
+    // add scalar element with correct min/max
+    double min = opt->TmpMin, max = opt->TmpMax;
+    opt->TmpMin = opt->ExternalMin;
+    opt->TmpMax = opt->ExternalMax;
+    addScalarElement(p, numEdges, xyz, val2, pre);
+    opt->TmpMin = min;
+    opt->TmpMax = max;
+
+    // add point trajectories
+    if(!pre && numNodes == 1 && opt->TimeStep > 0 && opt->LineWidth){
+      for(int ts = 0; ts < opt->TimeStep; ts++){
+	double xyz0[3], dxyz[3][2];
+	for(int j = 0; j < 3; j++){
+	  data->getNode(iele, 0, xyz0[0], xyz0[1], xyz0[2]);
+	  data->getValue(iele, 0, j, ts, dxyz[j][0]);
+	  data->getValue(iele, 0, j, ts + 1, dxyz[j][1]);
+	}
+	unsigned int col[2];
+	for(int i = 0; i < 2; i++){
+	  double norm = sqrt(dxyz[0][i] * dxyz[0][i] + 
+			     dxyz[1][i] * dxyz[1][i] + 
+			     dxyz[2][i] * dxyz[2][i]);
+	  col[i] = opt->getColor(norm, opt->TmpMin, opt->TmpMax);
+	}
+	for(int j = 0; j < 3; j++){	
+	  dxyz[j][0] = xyz0[j] + dxyz[j][0] * opt->DisplacementFactor;
+	  dxyz[j][1] = xyz0[j] + dxyz[j][1] * opt->DisplacementFactor;
+	}
+	p->va_lines->add(dxyz[0], dxyz[1], dxyz[2], 0, col, 0);
+      }
+    }
+  }
 }
 
-void addTensorElement(PView *p, int numEdges, double xyz[NMAX][3],
+void addTensorElement(PView *p, int numNodes, int numEdges, double xyz[NMAX][3],
 		      double val[NMAX][9], bool pre)
 {
+  PViewOptions *opt = p->getOptions();
+
+  if(opt->TensorType == PViewOptions::VonMises){
+    for(int i = 0; i < numNodes; i++)
+      val[i][0] = ComputeVonMises(val[i]);
+    addScalarElement(p, numEdges, xyz, val, pre);
+  }
 }
 
 bool skipElement(PView *p, int numEdges)
@@ -506,7 +773,6 @@ void addElementsInArrays(PView *p, bool preprocessNormalsOnly=false)
   PViewData *data = p->getData();
   PViewOptions *opt = p->getOptions();
   
-  int step = opt->TimeStep;
   int pre = preprocessNormalsOnly;
 
   if(opt->RangeType == PViewOptions::Custom){
@@ -522,41 +788,31 @@ void addElementsInArrays(PView *p, bool preprocessNormalsOnly=false)
     opt->TmpMax = data->getMax();
   }
 
-  // do we need to apply an offset?
-  bool offset = (opt->Offset[0] || opt->Offset[1] || opt->Offset[2]);
-
-  // do we need to apply a simple raise?
-  bool raise = (opt->Raise[0] || opt->Raise[1] || opt->Raise[2]);
-
-  // do we need to apply a general transformation?
-  bool transform = (opt->Transform[0][0] != 1. || opt->Transform[0][1] != 0. || 
-		    opt->Transform[0][2] != 0. || opt->Transform[1][0] != 0. || 
-		    opt->Transform[1][1] != 1. || opt->Transform[1][2] != 0. ||
-		    opt->Transform[2][0] != 0. || opt->Transform[2][1] != 0. || 
-		    opt->Transform[2][2] != 1.);
+  opt->TmpBBox.reset();
 
   double xyz[NMAX][3], val[NMAX][9];
 
   for(int i = 0; i < data->getNumElements(); i++){
     int numEdges = data->getNumEdges(i);
     if(skipElement(p, numEdges)) continue;
-    int dim = data->getDimension(i);
     int numComp = data->getNumComponents(i);
     int numNodes = data->getNumNodes(i);
     for(int j = 0; j < numNodes; j++){
       data->getNode(i, j, xyz[j][0], xyz[j][1], xyz[j][2]);
       for(int k = 0; k < numComp; k++)
-	data->getValue(i, j, k, step, val[j][k]);
+	data->getValue(i, j, k, opt->TimeStep, val[j][k]);
     }
-    changeCoordinates(p, numNodes, numComp, xyz, val, offset, raise, transform);
+    changeCoordinates(p, i, numNodes, numComp, xyz, val);
+    for(int j = 0; j < numNodes; j++)
+      opt->TmpBBox += SPoint3(xyz[j][0], xyz[j][1], xyz[j][2]);
     if(opt->ShowElement) 
       addOutlineElement(p, numEdges, xyz, pre);
     if(numComp == 1 && opt->DrawScalars)
       addScalarElement(p, numEdges, xyz, val, pre);
     else if(numComp == 3 && opt->DrawVectors)
-      addVectorElement(p, numEdges, xyz, val, pre);
+      addVectorElement(p, i, numNodes, numEdges, xyz, val, pre);
     else if(numComp == 9 && opt->DrawTensors)
-      addTensorElement(p, numEdges, xyz, val, pre);
+      addTensorElement(p, numNodes, numEdges, xyz, val, pre);
   }
 }
 
@@ -566,33 +822,216 @@ void drawArrays(PView *p, VertexArray *va, GLint type, bool useNormalArray)
 
   PViewOptions *opt = p->getOptions();
 
-  glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray());
-  glNormalPointer(GL_BYTE, 0, va->getNormalArray());
-  glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
-  
-  glEnableClientState(GL_VERTEX_ARRAY);
+  if(CTX.polygon_offset || opt->ShowElement)
+    glEnable(GL_POLYGON_OFFSET_FILL);
 
-  if(useNormalArray){
-    glEnable(GL_LIGHTING);
-    glEnableClientState(GL_NORMAL_ARRAY);
+  if(type == GL_LINES && opt->LineType > 0){
+    // bypass glDrawArrays and draw cylinders by hand
+  }
+  else if(type == GL_POINTS && opt->PointType > 0){
+    // bypass glDrawArrays and draw spheres by hand
   }
-  else
+  else{
+    glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray());
+    glNormalPointer(GL_BYTE, 0, va->getNormalArray());
+    glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
+    glEnableClientState(GL_VERTEX_ARRAY);
+    if(useNormalArray){
+      glEnable(GL_LIGHTING);
+      glEnableClientState(GL_NORMAL_ARRAY);
+    }
+    else
+      glDisableClientState(GL_NORMAL_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+    Msg(DEBUG, "%d verts in varray", va->getNumVertices());
+    glDrawArrays(type, 0, va->getNumVertices());
+    glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_NORMAL_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+  }
 
-  glEnableClientState(GL_COLOR_ARRAY);
-
-  if(CTX.polygon_offset || opt->ShowElement)
-    glEnable(GL_POLYGON_OFFSET_FILL);
-
-  printf("%d verts in varray\n", va->getNumVertices());
-  glDrawArrays(type, 0, va->getNumVertices());
-  
   glDisable(GL_POLYGON_OFFSET_FILL);
   glDisable(GL_LIGHTING);
+}
+
+std::string stringValue(int numComp, double d[9], double norm, char *format)
+{
+  char label[100];
+  if(numComp == 1)
+    sprintf(label, format, d[0]);
+  else if(numComp == 3){
+    char str[3][32];
+    sprintf(str[0], format, d[0]);
+    sprintf(str[1], format, d[1]);
+    sprintf(str[2], format, d[2]);
+    sprintf(label, "(%s,%s,%s)", str[0], str[1], str[2]);
+  }
+  else if(numComp == 9)
+    sprintf(label, format, norm);
+  return std::string(label);
+}
+
+void drawNumberGlyphs(PView *p, int numNodes, int numComp, 
+		      double xyz[NMAX][3], double val[NMAX][9])
+{
+  PViewOptions *opt = p->getOptions();
+  double d[9] = {0., 0., 0., 0., 0., 0., 0., 0., 0.};
+
+  if(opt->GlyphLocation == PViewOptions::COG){
+    SPoint3 pc(0., 0., 0.);
+    for(int i = 0; i < numNodes; i++){
+      pc += SPoint3(xyz[i][0], xyz[i][1], xyz[i][2]);
+      for(int j = 0; j < numComp; j++) d[j] += val[i][j];
+    }
+    pc /= (double)numNodes;
+    for(int j = 0; j < numComp; j++) d[j] /= (double)numNodes;
+    double norm = normValue(numComp, d);
+    unsigned int col = opt->getColor(norm, opt->TmpMin, opt->TmpMax);
+    glColor4ubv((GLubyte *) & col);
+    glRasterPos3d(pc.x(), pc.y(), pc.z());
+    Draw_String((char*)stringValue(numComp, d, norm, opt->Format).c_str());
+  }
+  else if(opt->GlyphLocation == PViewOptions::Vertex){
+    for(int i = 0; i < numNodes; i++){
+      double norm = normValue(numComp, val[i]);
+      unsigned int col = opt->getColor(norm, opt->TmpMin, opt->TmpMax);
+      glColor4ubv((GLubyte *) & col);
+      glRasterPos3d(xyz[i][0], xyz[i][1], xyz[i][2]);
+      Draw_String((char*)stringValue(numComp, val[i], norm, opt->Format).c_str());
+    }
+  }
+}
+
+void drawVectorGlyphs(PView *p, int iele, int numNodes, 
+		      double xyz[NMAX][3], double val[NMAX][9])
+{
+  PViewOptions *opt = p->getOptions();
+
+  double d[3] = {0., 0., 0.};
+  int numComp2;
+  double val2[NMAX][9], d2[9] = {0., 0., 0., 0., 0., 0., 0., 0., 0.};
+
+  getExternalValues(p, opt->ExternalViewIndex, iele, numNodes,
+		    3, val, numComp2, val2);
   
-  glDisableClientState(GL_VERTEX_ARRAY);
-  glDisableClientState(GL_NORMAL_ARRAY);
-  glDisableClientState(GL_COLOR_ARRAY);
+  if(opt->GlyphLocation == PViewOptions::COG){
+    SPoint3 pc(0., 0., 0.);
+    for(int i = 0; i < numNodes; i++){
+      pc += SPoint3(xyz[i][0], xyz[i][1], xyz[i][2]);
+      for(int j = 0; j < 3; j++) d[j] += val[i][j];
+      for(int j = 0; j < numComp2; j++) d2[j] += val2[i][j];
+    }
+    pc /= (double)numNodes;
+    for(int j = 0; j < 3; j++) d[j] /= (double)numNodes;
+    for(int j = 0; j < numComp2; j++) d2[j] /= (double)numNodes;
+    double norm = normValue(3, d);
+    double norm2 = normValue(numComp2, d2);
+    // need epsilon since we compare computed results (the average)
+    // instead of the raw data used to compute bounds
+    double eps = 1.e-15;
+    if(norm && opt->TmpMax &&
+       norm2 >= opt->ExternalMin * (1. - 1.e-15) &&
+       norm2 <= opt->ExternalMax * (1. + 1.e-15)){
+      unsigned int col = opt->getColor(norm2, opt->ExternalMin, opt->ExternalMax);
+      glColor4ubv((GLubyte *) & col);
+      double f = CTX.pixel_equiv_x / CTX.s[0] * opt->ArrowSize / 
+	(opt->ArrowSizeProportional ? opt->TmpMax : norm);
+      Draw_Vector(opt->VectorType, opt->IntervalsType != PViewOptions::Iso,
+		  opt->ArrowRelHeadRadius, opt->ArrowRelStemLength,
+		  opt->ArrowRelStemRadius, pc[0], pc[1], pc[2],
+		  d[0] * f, d[1] * f, d[2] * f, opt->Light);
+    }
+  }
+  else if(opt->GlyphLocation == PViewOptions::Vertex){
+    for(int i = 0; i < numNodes; i++){
+      double norm = normValue(3, val[i]);
+      double norm2 = normValue(numComp2, val2[i]);
+      if(norm && opt->TmpMax && 
+	 norm2 >= opt->ExternalMin &&
+	 norm2 <= opt->ExternalMax){
+	unsigned int col = opt->getColor(norm2, opt->ExternalMin, opt->ExternalMax);
+	glColor4ubv((GLubyte *) & col);
+	double f = CTX.pixel_equiv_x / CTX.s[0] * opt->ArrowSize / 
+	  (opt->ArrowSizeProportional ? opt->TmpMax : norm);
+	Draw_Vector(opt->VectorType, opt->IntervalsType != PViewOptions::Iso,
+		    opt->ArrowRelHeadRadius, opt->ArrowRelStemLength,
+		    opt->ArrowRelStemRadius, xyz[i][0], xyz[i][1], xyz[i][2],
+		    val[i][0] * f, val[i][1] * f, val[i][2] * f, opt->Light);
+      }
+    }
+  }
+}
+
+void drawNormalVectorGlyphs(PView *p, int numNodes, double xyz[NMAX][3],
+			    double val[NMAX][9])
+{
+  PViewOptions *opt = p->getOptions();
+
+  SPoint3 pc(0., 0., 0.);
+  for(int i = 0; i < numNodes; i++)
+    pc += SPoint3(xyz[i][0], xyz[i][1], xyz[i][2]);
+  pc /= (double)numNodes;
+
+  SVector3 n = normal3(xyz);
+  n.normalize();
+  n[0] *= opt->Normals * CTX.pixel_equiv_x / CTX.s[0];
+  n[1] *= opt->Normals * CTX.pixel_equiv_x / CTX.s[1];
+  n[2] *= opt->Normals * CTX.pixel_equiv_x / CTX.s[2];
+  glColor4ubv((GLubyte *) & opt->color.normals);
+  Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+	      CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius, 
+	      pc[0], pc[1], pc[2], n[0], n[1], n[2], opt->Light);
+}
+
+void drawTangentVectorGlyphs(PView *p, int numNodes, double xyz[NMAX][3],
+			     double val[NMAX][9])
+{
+  PViewOptions *opt = p->getOptions();
+
+  SPoint3 p0(xyz[0][0], xyz[0][1], xyz[0][2]);
+  SPoint3 p1(xyz[1][0], xyz[1][1], xyz[1][2]);
+  SVector3 pc = 0.5 * (p0 + p1);
+  SVector3 t(p0, p1);
+  t.normalize();
+  t[0] *= opt->Tangents * CTX.pixel_equiv_x / CTX.s[0];
+  t[1] *= opt->Tangents * CTX.pixel_equiv_x / CTX.s[1];
+  t[2] *= opt->Tangents * CTX.pixel_equiv_x / CTX.s[2];
+  glColor4ubv((GLubyte *) & opt->color.tangents);
+  Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+	      CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius, 
+	      pc[0], pc[1], pc[2], t[0], t[1], t[2], opt->Light);
+}
+
+void drawGlyphs(PView *p)
+{
+  PViewData *data = p->getData();
+  PViewOptions *opt = p->getOptions();
+
+  Msg(DEBUG, "drawing extra glyphs (this is slow...)");
+
+  double xyz[NMAX][3], val[NMAX][9];
+
+  for(int i = 0; i < data->getNumElements(); i++){
+    int numEdges = data->getNumEdges(i);
+    if(skipElement(p, numEdges)) continue;
+    int dim = data->getDimension(i);
+    int numComp = data->getNumComponents(i);
+    int numNodes = data->getNumNodes(i);
+    for(int j = 0; j < numNodes; j++){
+      data->getNode(i, j, xyz[j][0], xyz[j][1], xyz[j][2]);
+      for(int k = 0; k < numComp; k++)
+	data->getValue(i, j, k, opt->TimeStep, val[j][k]);
+    }
+    changeCoordinates(p, i, numNodes, numComp, xyz, val);
+    if(opt->IntervalsType == PViewOptions::Numeric)
+      drawNumberGlyphs(p, numNodes, numComp, xyz, val);
+    else if(numComp == 3 && opt->VectorType != PViewOptions::Displacement)
+      drawVectorGlyphs(p, i, numNodes, xyz, val);
+    if(dim == 2 && opt->Normals)
+      drawNormalVectorGlyphs(p, numNodes, xyz, val);
+    else if(dim == 1 && opt->Tangents)
+      drawTangentVectorGlyphs(p, numNodes, xyz, val);
+  }
 }
 
 // We try to estimate how many primitives will end up in the vertex
@@ -645,7 +1084,7 @@ static int estimateNumTriangles(PView *p)
   return heuristic + 10000;
 }
 
-class initArraysPView {
+class initPView {
  public :
   void operator () (PView *p)
   {
@@ -664,34 +1103,33 @@ class initArraysPView {
     if(p->normals) delete p->normals;
     p->normals = new smooth_normals(opt->AngleSmoothNormals);
 
+    if(opt->UseGenRaise) opt->createGeneralRaise();
+
     if(opt->SmoothNormals) addElementsInArrays(p, true);
     addElementsInArrays(p);
 
+    if(opt->IntervalsType == PViewOptions::Numeric ||
+       opt->Normals || opt->Tangents ||
+       (data->getNumVectors() && opt->VectorType != PViewOptions::Displacement) ||
+       (data->getNumTensors() && opt->TensorType != PViewOptions::VonMises))
+      p->setGlyphs(true);
+    
     p->setChanged(false);
   }
 };
 
-static double eyeStored[3] = { 0., 0., 0. };
-
-bool eyeChanged()
+bool eyeChanged(PView *p)
 {
   double zeye = 100 * CTX.lc;
-  double tmp[3] = {CTX.rot[2] * zeye, CTX.rot[6] * zeye, CTX.rot[10] * zeye};
-  if(fabs(tmp[0] - eyeStored[0]) > 1.e-3 ||
-     fabs(tmp[1] - eyeStored[1]) > 1.e-3 ||
-     fabs(tmp[2] - eyeStored[2]) > 1.e-3) {
-    eyeStored[0] = tmp[0];
-    eyeStored[1] = tmp[1];
-    eyeStored[2] = tmp[2];
-    Msg(DEBUG, "New eye = (%g %g %g)", tmp[0], tmp[1], tmp[2]);
+  SPoint3 tmp(CTX.rot[2] * zeye, CTX.rot[6] * zeye, CTX.rot[10] * zeye);
+  if(tmp.distance(p->getEye()) > 1.e-3){
+    p->setEye(tmp);
     return true;
   }
   return false;
 }
 
-class drawArraysPView {
- private:
-  static double _storedEye[3];
+class drawPView {
  public:
   void operator () (PView *p)
   {
@@ -717,18 +1155,60 @@ class drawArraysPView {
       else
 	glDisable((GLenum)(GL_CLIP_PLANE0 + i));
     
-    if(CTX.alpha && ColorTable_IsAlpha(&opt->CT) && 
-       !opt->FakeTransparency && (eyeChanged() || p->getChanged())){
-      Msg(DEBUG, "Sorting View[%d] for transparency", p->getIndex());
-      p->va_triangles->sort(eyeStored);
+    if(CTX.alpha && ColorTable_IsAlpha(&opt->CT)){
+      if(opt->FakeTransparency){
+	// simple additive blending "a la xpost":
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE); // glBlendEquation(GL_FUNC_ADD);
+	// maximum intensity projection "a la volsuite":
+	// glBlendFunc(GL_ONE, GL_ONE); // glBlendEquation(GL_MAX);
+	glEnable(GL_BLEND);
+	glDisable(GL_DEPTH_TEST);
+      }
+      else{
+	// real translucent blending (requires back-to-front traversal)
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	// glBlendEquation(GL_FUNC_ADD);
+	glEnable(GL_BLEND);
+	if(eyeChanged(p)){
+	  Msg(DEBUG, "Sorting View[%d] for transparency", p->getIndex());
+	  p->va_triangles->sort(p->getEye().x(), p->getEye().y(), p->getEye().z());
+	}
+      }
     }
-    
+
+    // draw all the vertex arrays
     drawArrays(p, p->va_points, GL_POINTS, false);
     drawArrays(p, p->va_lines, GL_LINES, opt->Light && opt->LightLines);
     drawArrays(p, p->va_triangles, GL_TRIANGLES, opt->Light);
 
-    // then draw everything we cannot put in the arrays: strings,
-    // vectors (for now), ...
+    // then draw all the stuff that we cannot put in vertex arrays
+    if(p->getGlyphs()) drawGlyphs(p);
+
+    if(opt->DrawStrings){
+      glColor4ubv((GLubyte *) & opt->color.text3d);
+      //Draw_Text2D3D(3, opt->TimeStep, data->NbT3, data->T3D, data->T3C);
+    }
+    
+    if(CTX.alpha){
+      glDisable(GL_BLEND);
+      glEnable(GL_DEPTH_TEST);
+    }
+
+    for(int i = 0; i < 6; i++)
+      glDisable((GLenum)(GL_CLIP_PLANE0 + i));
+
+    if(opt->Axes && opt->Type == PViewOptions::Plot3D){
+      glColor4ubv((GLubyte *) & opt->color.axes);
+      glLineWidth(CTX.line_width);
+      gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+      if(!opt->AxesAutoPosition)
+	Draw_Axes(opt->Axes, opt->AxesTics, opt->AxesFormat, opt->AxesLabel,
+		  opt->AxesPosition);
+      else if(!opt->TmpBBox.empty())
+	Draw_Axes(opt->Axes, opt->AxesTics, opt->AxesFormat, opt->AxesLabel,
+		  opt->TmpBBox);
+    }
+    
   }
 };
 
@@ -772,8 +1252,8 @@ void Draw_Post()
 
   if(!CTX.threads_lock){
     CTX.threads_lock = 1;
-    std::for_each(PView::list.begin(), PView::list.end(), initArraysPView());
-    std::for_each(PView::list.begin(), PView::list.end(), drawArraysPView());
+    std::for_each(PView::list.begin(), PView::list.end(), initPView());
+    std::for_each(PView::list.begin(), PView::list.end(), drawPView());
     CTX.threads_lock = 0;
   }
 }
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index da243d1de5bae8c2d080d487608f9bc05f442447..c4248d135eacf00a702a05079d3c9e5a35f9d74c 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.80 2007-08-24 08:38:24 remacle Exp $
+// $Id: PostElement.cpp,v 1.81 2007-08-27 13:46:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -334,10 +334,10 @@ void Draw_ScalarLine(Post_View * View, int preproNormals,
       if(ValMin == ValMax)
 	k = View->NbIso / 2;
       PaletteDiscrete(View, View->NbIso, k);
-      CutLine(X, Y, Z, &Val[0],
-	      View->GVFI(ValMin, ValMax, View->NbIso + 1, k),
-	      View->GVFI(ValMin, ValMax, View->NbIso + 1, k + 1),
-	      Xp, Yp, Zp, &nb, Vp);
+      nb = CutLine(X, Y, Z, &Val[0],
+		   View->GVFI(ValMin, ValMax, View->NbIso + 1, k),
+		   View->GVFI(ValMin, ValMax, View->NbIso + 1, k + 1),
+		   Xp, Yp, Zp, Vp);
       if(nb == 2)
 	Draw_Line(View->LineType, View->LineWidth, Xp, Yp, Zp, View->Light);
       if(ValMin == ValMax)
@@ -350,8 +350,8 @@ void Draw_ScalarLine(Post_View * View, int preproNormals,
       if(ValMin == ValMax)
 	k = View->NbIso / 2;
       PaletteDiscrete(View, View->NbIso, k);
-      IsoLine(View, X, Y, Z, &Val[0],
-	      View->GVFI(ValMin, ValMax, View->NbIso, k));
+      IsoLine_Old(View, X, Y, Z, &Val[0],
+		  View->GVFI(ValMin, ValMax, View->NbIso, k));
       if(ValMin == ValMax)
 	break;
     }
@@ -485,7 +485,7 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
       }
     }
     else {
-      CutTriangle(X, Y, Z, Val, ValMin, ValMax, Xp, Yp, Zp, &nb, Vp);
+      nb = CutTriangle(X, Y, Z, Val, ValMin, ValMax, Xp, Yp, Zp, Vp);
       if(nb >= 3) {
 	if(preproNormals){
 	  for(int i = 0; i < nb; i++)
@@ -539,10 +539,10 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
       if(ValMin == ValMax)
 	k = View->NbIso / 2;
       unsigned int col = PaletteDiscrete(View, View->NbIso, k);
-      CutTriangle(X, Y, Z, Val,
-		  View->GVFI(ValMin, ValMax, View->NbIso + 1, k),
-		  View->GVFI(ValMin, ValMax, View->NbIso + 1, k + 1),
-		  Xp, Yp, Zp, &nb, Vp);
+      nb = CutTriangle(X, Y, Z, Val,
+		       View->GVFI(ValMin, ValMax, View->NbIso + 1, k),
+		       View->GVFI(ValMin, ValMax, View->NbIso + 1, k + 1),
+		       Xp, Yp, Zp, Vp);
       if(nb >= 3) {
 	if(preproNormals){
 	  for(int i = 0; i < nb; i++)
@@ -594,8 +594,8 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
       if(ValMin == ValMax)
 	k = View->NbIso / 2;
       unsigned int col = PaletteDiscrete(View, View->NbIso, k);
-      IsoTriangle(View, X, Y, Z, Val,
-		  View->GVFI(ValMin, ValMax, View->NbIso, k), col);
+      IsoTriangle_Old(View, X, Y, Z, Val,
+		      View->GVFI(ValMin, ValMax, View->NbIso, k), col);
       if(ValMin == ValMax) 
 	break;
     }
@@ -668,8 +668,8 @@ void Draw_ScalarTetrahedron(Post_View * View, int preproNormals,
       if(ValMin == ValMax)
 	k = View->NbIso / 2;
       unsigned int col = PaletteDiscrete(View, View->NbIso, k);
-      IsoSimplex(View, preproNormals, X, Y, Z, Val,
-                 View->GVFI(ValMin, ValMax, View->NbIso, k), col);
+      IsoSimplex_Old(View, preproNormals, X, Y, Z, Val,
+		     View->GVFI(ValMin, ValMax, View->NbIso, k), col);
       if(ValMin == ValMax)
 	break;
     }
diff --git a/Graphics/Post_Old.cpp b/Graphics/Post_Old.cpp
index b1112bbc87d3ae0a9e9534eed5ed8182927dbee4..8612a14f949ba396d24cc3afdb138a7e8fb38bdd 100644
--- a/Graphics/Post_Old.cpp
+++ b/Graphics/Post_Old.cpp
@@ -1,4 +1,4 @@
-// $Id: Post_Old.cpp,v 1.1 2007-08-24 20:14:18 geuzaine Exp $
+// $Id: Post_Old.cpp,v 1.2 2007-08-27 13:46:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -764,7 +764,7 @@ void Draw_Post_Old(void)
 	if(CTX.alpha && ColorTable_IsAlpha(&v->CT) && !v->FakeTransparency &&
 	   (changedEye() || v->Changed)){
 	  Msg(DEBUG, "Sorting View[%d] for transparency (WITH vertex array)", v->Index);
-	  v->TriVertexArray->sort(storedEye);
+	  v->TriVertexArray->sort(storedEye[0], storedEye[1], storedEye[2]);
 	}
 
 	glVertexPointer(3, GL_FLOAT, 0, v->TriVertexArray->getVertexArray());
diff --git a/Plugin/Makefile b/Plugin/Makefile
index 90794f94ebb16ad34350274f676dad8c51a3c4e3..5e16e5f64bbb59ecc501d93ab9504a5bfc1c217a 100644
--- a/Plugin/Makefile
+++ b/Plugin/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.128 2007-08-24 20:14:18 geuzaine Exp $
+# $Id: Makefile,v 1.129 2007-08-27 13:46:22 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -94,13 +94,15 @@ CutPlane.o: CutPlane.cpp CutPlane.h Levelset.h Plugin.h \
   ../Post/ColorTable.h ../DataStr/List.h ../Common/VertexArray.h \
   ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
   ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Context.h ../Common/GmshUI.h ../Graphics/Draw.h
+  ../Common/Context.h ../Common/GmshUI.h ../Graphics/Draw.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h
 CutSphere.o: CutSphere.cpp CutSphere.h Levelset.h Plugin.h \
   ../Common/Options.h ../Common/Message.h ../Post/Views.h \
   ../Post/ColorTable.h ../DataStr/List.h ../Common/VertexArray.h \
   ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
   ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Context.h ../Common/GmshUI.h ../Graphics/Draw.h
+  ../Common/Context.h ../Common/GmshUI.h ../Graphics/Draw.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h
 CutMap.o: CutMap.cpp CutMap.h Levelset.h Plugin.h ../Common/Options.h \
   ../Common/Message.h ../Post/Views.h ../Post/ColorTable.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Geo/SVector3.h \
@@ -117,7 +119,8 @@ CutParametric.o: CutParametric.cpp ../Post/OctreePost.h \
   ../Post/ColorTable.h ../DataStr/List.h ../Common/VertexArray.h \
   ../Geo/SVector3.h ../Geo/SPoint3.h ../Common/SmoothData.h \
   ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Context.h ../Common/GmshUI.h ../Graphics/Draw.h
+  ../Common/Context.h ../Common/GmshUI.h ../Graphics/Draw.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h
 Lambda2.o: Lambda2.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Post/Views.h ../Post/ColorTable.h ../DataStr/List.h \
   ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
@@ -142,14 +145,16 @@ StreamLines.o: StreamLines.cpp ../Post/OctreePost.h ../Common/Octree.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Common/SmoothData.h ../Numeric/Numeric.h \
   ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
-  ../Common/GmshUI.h ../Graphics/Draw.h
+  ../Common/GmshUI.h ../Graphics/Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
 CutGrid.o: CutGrid.cpp ../Post/OctreePost.h ../Common/Octree.h \
   ../Common/OctreeInternals.h CutGrid.h Plugin.h ../Common/Options.h \
   ../Common/Message.h ../Post/Views.h ../Post/ColorTable.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Common/SmoothData.h ../Numeric/Numeric.h \
   ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
-  ../Common/GmshUI.h ../Graphics/Draw.h
+  ../Common/GmshUI.h ../Graphics/Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h
 Transform.o: Transform.cpp Plugin.h ../Common/Options.h \
   ../Common/Message.h ../Post/Views.h ../Post/ColorTable.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Geo/SVector3.h \
@@ -284,7 +289,8 @@ Annotate.o: Annotate.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Common/GmshMatrix.h Annotate.h ../Common/Context.h \
   ../Common/GmshUI.h ../Fltk/GUI.h ../Fltk/Opengl_Window.h \
   ../Fltk/Colorbar_Window.h ../Fltk/Popup_Button.h \
-  ../Fltk/SpherePosition_Widget.h ../Graphics/Draw.h
+  ../Fltk/SpherePosition_Widget.h ../Graphics/Draw.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h
 Remove.o: Remove.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Post/Views.h ../Post/ColorTable.h ../DataStr/List.h \
   ../Common/VertexArray.h ../Geo/SVector3.h ../Geo/SPoint3.h \
@@ -295,8 +301,9 @@ Probe.o: Probe.cpp Probe.h Plugin.h ../Common/Options.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Common/SmoothData.h ../Numeric/Numeric.h \
   ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
-  ../Common/GmshUI.h ../Graphics/Draw.h ../Post/OctreePost.h \
-  ../Common/Octree.h ../Common/OctreeInternals.h
+  ../Common/GmshUI.h ../Graphics/Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Post/OctreePost.h ../Common/Octree.h \
+  ../Common/OctreeInternals.h
 HarmonicToTime.o: HarmonicToTime.cpp Plugin.h ../Common/Options.h \
   ../Common/Message.h ../Post/Views.h ../Post/ColorTable.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Geo/SVector3.h \
diff --git a/Post/Makefile b/Post/Makefile
index c6e40f615df926ec6a46923889ba1f1b9f2072a6..afd24e8b5c07380f84daea95df178e97862025be 100644
--- a/Post/Makefile
+++ b/Post/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.6 2007-08-24 20:14:18 geuzaine Exp $
+# $Id: Makefile,v 1.7 2007-08-27 13:46:22 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -89,7 +89,8 @@ PViewData.o: PViewData.cpp PViewData.h ../Geo/GModel.h ../Geo/GVertex.h \
   ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
   ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h
-PViewOptions.o: PViewOptions.cpp PViewOptions.h ColorTable.h
+PViewOptions.o: PViewOptions.cpp PViewOptions.h ColorTable.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/Message.h
 PViewIO.o: PViewIO.cpp PView.h ../Common/VertexArray.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Common/SmoothData.h ../Numeric/Numeric.h \
   AdaptiveViews.h ../DataStr/List.h ../Common/GmshMatrix.h PViewData.h \
diff --git a/Post/PView.cpp b/Post/PView.cpp
index 4ef6fecfb6a42d6404dc6926e7a86aac152077c3..7e341bc1bbbdb43440cfdc84fe4abd4410bcf41d 100644
--- a/Post/PView.cpp
+++ b/Post/PView.cpp
@@ -1,4 +1,4 @@
-// $Id: PView.cpp,v 1.1 2007-08-21 19:05:43 geuzaine Exp $
+// $Id: PView.cpp,v 1.2 2007-08-27 13:46:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -27,6 +27,17 @@
 
 std::vector<PView*> PView::list;
 
+void PView::setChanged(bool val)
+{ 
+  _changed = val; 
+  // reset the eye position everytime we change the view so that the
+  // arrays get resorted for transparency
+  if(_changed){
+    _eye = SPoint3(0., 0., 0.); 
+    _haveGlyphs = false;
+  }
+}
+
 PView *PView::current()
 { 
   if(list.empty()){
diff --git a/Post/PView.h b/Post/PView.h
index 85587c29600d5e425bc82faaf074d03455f968f9..8a9e6164d97a9b57f3137c87c43e50cf3422cdea 100644
--- a/Post/PView.h
+++ b/Post/PView.h
@@ -37,6 +37,8 @@ class PView{
   int _index;
   // flag to mark that the view has changed
   bool _changed;
+  // flag to mark that the view contains non-optimized glyphs
+  bool _haveGlyphs;
   // flag to mark that the view is an alias of another view
   int _aliasOf;
   // flag to mark that some other views link to this one
@@ -45,15 +47,18 @@ class PView{
   std::string _name;
   // name of the file the view was loaded from
   std::string _filename;
+  // eye position
+  SPoint3 _eye;
   // the options
   PViewOptions *_options;
   // the data
   PViewData *_data;
  public:
   PView(bool allocate=true) :
-    _num(0), _index(0), _changed(true), _aliasOf(-1), _links(false), 
-    _name(""), _filename(""), _options(0), _data(0),
-    va_points(0), va_lines(0), va_triangles(0), normals(0), adaptive(0)
+    _num(0), _index(0), _changed(true), _haveGlyphs(false), _aliasOf(-1), 
+    _links(false), _name(""), _filename(""), _eye(0., 0., 0.),
+    _options(0), _data(0), va_points(0), va_lines(0), va_triangles(0),
+    normals(0), adaptive(0)
   {
     _data = new PViewDataList(allocate);
     _options = new PViewOptions;
@@ -80,7 +85,11 @@ class PView{
   int getIndex(){ return _index; }
   void setIndex(int val){ _index = val; }
   bool getChanged(){ return _changed; }
-  void setChanged(bool val){ _changed = val; }
+  void setChanged(bool val);
+  bool getGlyphs(){ return _haveGlyphs; }
+  void setGlyphs(bool val){ _haveGlyphs = val; }
+  SPoint3 &getEye(){ return _eye; }
+  void setEye(SPoint3 &p){ _eye = p; }
   void setGlobalResolutionLevel(int level)
   {
     //if(adaptive) adaptive->setGlobalResolutionLevel(this, level);
diff --git a/Post/PViewData.cpp b/Post/PViewData.cpp
index 8ba616d748b360636a0a4a810e7012387565294f..2b096f5b9e2e662413a561ec402cf556f122eee0 100644
--- a/Post/PViewData.cpp
+++ b/Post/PViewData.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewData.cpp,v 1.4 2007-08-25 19:19:49 geuzaine Exp $
+// $Id: PViewData.cpp,v 1.5 2007-08-27 13:46:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -27,7 +27,7 @@
 
 PViewDataList::PViewDataList(bool allocate)
   : DataSize(sizeof(double)), NbTimeStep(0), 
-    ScalarOnly(0), TextOnly(0), Min(VAL_INF), Max(-VAL_INF), Time(0),
+    Min(VAL_INF), Max(-VAL_INF), Time(0),
     NbSP(0), SP(0), NbVP(0), VP(0), NbTP(0), TP(0),
     NbSL(0), SL(0), NbVL(0), VL(0), NbTL(0), TL(0),
     NbSL2(0), SL2(0), NbVL2(0), VL2(0), NbTL2(0), TL2(0),
@@ -178,9 +178,6 @@ void PViewDataList::_stat(List_T *list, int nbcomp, int nbelm, int nbnod)
   // compute statistics for element lists
   if(!nbelm) return;
 
-  TextOnly = false;
-  if(nbcomp > 1) ScalarOnly = false;
-  
   int nb = List_Nbr(list) / nbelm;
   for(int i = 0; i < List_Nbr(list); i += nb){
     int N = nb - 3 * nbnod;
diff --git a/Post/PViewData.h b/Post/PViewData.h
index 88c6d3424c46f62cdc4bb03f4c95d1314ac9dfd3..869f5c0b67d3c61180247208a8ede5133e7e6c80 100644
--- a/Post/PViewData.h
+++ b/Post/PViewData.h
@@ -44,6 +44,9 @@ class PViewData {
   virtual double getMin(int step=-1) = 0;
   virtual double getMax(int step=-1) = 0;
   virtual SBoundingBox3d getBoundingBox() = 0;
+  virtual int getNumScalars(){ return 0; }
+  virtual int getNumVectors(){ return 0; }
+  virtual int getNumTensors(){ return 0; }
   virtual int getNumPoints(){ return 0; }
   virtual int getNumLines(){ return 0; }
   virtual int getNumTriangles(){ return 0; }
@@ -69,7 +72,7 @@ class PViewDataList : public PViewData {
   // FIXME: all these members will be made private once the plugins
   // have been rewritten
   int DataSize; // size(double) or sizeof(float)
-  int NbTimeStep, ScalarOnly, TextOnly;
+  int NbTimeStep;
   double Min, Max;
   std::vector<double> TimeStepMin, TimeStepMax;
   SBoundingBox3d BBox;
@@ -112,6 +115,9 @@ class PViewDataList : public PViewData {
   double getMin(int step=-1);
   double getMax(int step=-1);
   SBoundingBox3d getBoundingBox(){ return BBox; }
+  int getNumScalars(){ return NbSP + NbSL + NbST + NbSQ + NbSS + NbSH + NbSI + NbSY; }
+  int getNumVectors(){ return NbVP + NbVL + NbVT + NbVQ + NbVS + NbVH + NbVI + NbVY; }
+  int getNumTensors(){ return NbTP + NbTL + NbTT + NbTQ + NbTS + NbTH + NbTI + NbTY; }
   int getNumPoints(){ return NbSP + NbVP + NbTP; }
   int getNumLines(){ return NbSL + NbVL + NbTL; }
   int getNumTriangles(){ return NbST + NbVT + NbTT; }
diff --git a/Post/PViewOptions.cpp b/Post/PViewOptions.cpp
index 60edeef8f6fd0940e33feca298995997a2f175d2..949b1a87cf29849b2c37ff101039a7b71ab2407b 100644
--- a/Post/PViewOptions.cpp
+++ b/Post/PViewOptions.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewOptions.cpp,v 1.5 2007-08-25 22:42:28 geuzaine Exp $
+// $Id: PViewOptions.cpp,v 1.6 2007-08-27 13:46:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -23,6 +23,11 @@
 // 
 
 #include "PViewOptions.h"
+#include "Message.h"
+
+#if defined(HAVE_MATH_EVAL)
+#include "matheval.h"
+#endif
 
 PViewOptions::PViewOptions()
 {
@@ -30,25 +35,32 @@ PViewOptions::PViewOptions()
   Type = Plot3D;
   AutoPosition = 1;
   strcpy(Format, "%g");
-  Axes = 0;
+  Axes = 1;
+  AxesAutoPosition = 1;
   for(int i = 0; i < 3; i++){
+    AxesTics[i] = 10;
+    strcpy(AxesFormat[i], "%g");
+    strcpy(AxesLabel[i], "");
     Offset[i] = Raise[i] = 0.;
     for(int j = 0; j < 3; j++){
       Transform[i][j] = (i == j) ? 1. : 0.;
     }
   }
-  DisplacementFactor = 0.;
+  DisplacementFactor = 1.;
   Explode = 1.;
   ArrowSize = 50;
   ArrowRelHeadRadius = 0.5;
   ArrowRelStemRadius = 0.2;
   ArrowRelStemLength = 0.7;
-  Normals = Tangents = 0.;
+  Normals = 0.;
+  Tangents = 0.;
   Visible = 1;
   IntervalsType = Continuous;
-  //IntervalsType = Discrete;
+  IntervalsType = Discrete;
+  IntervalsType = Iso;
+  //IntervalsType = Numeric;
   NbIso = 15;
-  ArrowSizeProportional = 0;
+  ArrowSizeProportional = 1;
   Light = LightTwoSide = 1;
   LightLines = 1;
   SmoothNormals = 0;
@@ -57,9 +69,9 @@ PViewOptions::PViewOptions()
   FakeTransparency = 0;
   ShowElement = 0;
   ShowTime = ShowScale = 1;
-  ScaleType = Default;
-  RangeType = Linear;
+  ScaleType = Linear;
   VectorType = Arrow3D;
+  //VectorType = Displacement;
   TensorType = VonMises;
   GlyphLocation = COG;
   TimeStep = 0;
@@ -68,11 +80,15 @@ PViewOptions::PViewOptions()
     DrawScalars = DrawVectors = DrawTensors = 1;
   Boundary = 0;
   PointType = LineType = 0;
-  PointSize = LineWidth = 1;
+  PointSize = 3;
+  LineWidth = 1;
   UseStipple = 0;
   ExternalViewIndex = ViewIndexForGenRaise = -1;
   UseGenRaise = 0;
   GenRaiseFactor = 0.;
+  RangeType = Default;
+  CustomMin = 0;
+  CustomMax = 5.;
 
   color.point = 0;
   color.line = 0;
@@ -92,16 +108,56 @@ PViewOptions::PViewOptions()
   ColorTable_Recompute(&CT);
 }
 
-// val in [min, max]
-unsigned int PViewOptions::getColor(double val, double min, double max)
+PViewOptions::~PViewOptions()
 {
-  //int index = v->GIFV(min, max, v->CT.size, val);
+  destroyGeneralRaise();
+}
 
-  if(CT.size == 1) return CT.table[0];
+double PViewOptions::getScaleValue(int iso, int numIso, double min, double max)
+{
+  if(numIso == 1) return (min + max) / 2.;
+  
+  if(ScaleType == Linear){
+    return min + iso * (max - min) / (numIso - 1.);
+  }
+  else if(ScaleType == Logarithmic){
+    // should translate scale instead, with smallest val an option!
+    if(min < 0.) return 0;
+    return pow(10., log10(min) + iso * (log10(max) - log10(min)) / (numIso - 1.));
+  }
+  else if(ScaleType == DoubleLogarithmic){
+    if(min < 0.) return 0;
+    double iso2 = iso / 2.;
+    double numIso2 = numIso / 2.;
+    return pow(10., log10(min) + iso2 * (log10(max) - log10(min)) / (numIso2 - 1.));
+  }
+  return 0.;
+}
 
-  int index = (min == max) ? CT.size / 2 :
-    (int)((val - min) * (CT.size - 1) / (max - min));
+int PViewOptions::getScaleIndex(double val, int numIso, double min, double max)
+{
+  if(min == max) return numIso / 2;
 
+  if(ScaleType == Linear){
+    return (int)((val - min) * (numIso - 1) / (max - min));
+  }
+  else if(ScaleType == Logarithmic){
+    if(min <= 0.) return 0;
+    return (int)((log10(val) - log10(min)) * (numIso - 1) / (log10(max) - log10(min)));
+  }
+  else if(ScaleType == DoubleLogarithmic){
+    // FIXME
+    if(min <= 0.) return 0;
+    return (int)((log10(val) - log10(min)) * (numIso - 1) / (log10(max) - log10(min)));
+  }
+  return 0;
+}
+
+// val in [min, max]
+unsigned int PViewOptions::getColor(double val, double min, double max)
+{
+  if(CT.size == 1) return CT.table[0];
+  int index = getScaleIndex(val, CT.size, min, max);
   return CT.table[index];
 }
 
@@ -110,6 +166,50 @@ unsigned int PViewOptions::getColor(int i, int nb)
 {
   int index = (nb == 1) ? CT.size / 2 : 
     (int)(i / (double)(nb - 1) * (CT.size - 1) + 0.5);
-
   return CT.table[index];
 }
+
+void PViewOptions::destroyGeneralRaise()
+{
+  for(int i = 0; i < 3; i++){
+#if defined(HAVE_MATH_EVAL)
+    if(GenRaise_f[i])
+      evaluator_destroy(GenRaise_f[i]);
+    GenRaise_f[i] = 0;
+#else
+    GenRaise_f[i] = (void*)-1;
+#endif
+  }
+}
+
+void PViewOptions::createGeneralRaise()
+{
+  destroyGeneralRaise();
+
+  char *expr[3] = {GenRaiseX, GenRaiseY, GenRaiseZ};
+#if defined(HAVE_MATH_EVAL)
+  for(int i = 0; i < 3; i++) {
+    if(strlen(expr[i])) {
+      if(!(GenRaise_f[i] = evaluator_create(expr[i])))
+        Msg(GERROR, "Invalid expression '%s'", expr[i]);
+    }
+  }
+#else
+  for(int i = 0; i < 3; i++) {
+    if(!strcmp(expr[i], "v0")) GenRaise_f[i] = (void*)0;
+    else if(!strcmp(expr[i], "v1")) GenRaise_f[i] = (void*)1;
+    else if(!strcmp(expr[i], "v2")) GenRaise_f[i] = (void*)2;
+    else if(!strcmp(expr[i], "v3")) GenRaise_f[i] = (void*)3;
+    else if(!strcmp(expr[i], "v4")) GenRaise_f[i] = (void*)4;
+    else if(!strcmp(expr[i], "v5")) GenRaise_f[i] = (void*)5;
+    else if(!strcmp(expr[i], "v6")) GenRaise_f[i] = (void*)6;
+    else if(!strcmp(expr[i], "v7")) GenRaise_f[i] = (void*)7;
+    else if(!strcmp(expr[i], "v8")) GenRaise_f[i] = (void*)8;
+    else if(strlen(expr[i])) {
+      Msg(GERROR, "Invalid expression '%s'", expr[i]);
+      return;
+    }
+  }
+#endif
+}
+
diff --git a/Post/PViewOptions.h b/Post/PViewOptions.h
index c35bfdcc8613101a37b7bcf1515525613923cbbf..14eeac7d225b725a43fddb32f43d6ef4cc93141a 100644
--- a/Post/PViewOptions.h
+++ b/Post/PViewOptions.h
@@ -78,7 +78,7 @@ class PViewOptions {
   int Axes, AxesAutoPosition, AxesTics[3];
   char AxesFormat[3][256], AxesLabel[3][256];
   double AxesPosition[6];
-  double CustomMin, CustomMax, TmpMin, TmpMax;
+  double CustomMin, CustomMax, TmpMin, TmpMax, ExternalMin, ExternalMax;
   SBoundingBox3d TmpBBox;
   double Offset[3], Raise[3], Transform[3][3], DisplacementFactor, Explode;
   double ArrowSize, ArrowRelHeadRadius, ArrowRelStemRadius, ArrowRelStemLength;
@@ -115,8 +115,13 @@ class PViewOptions {
   // static reference container that contains default values
   static PViewOptions reference;
   PViewOptions();
+  ~PViewOptions();
+  void createGeneralRaise();
+  void destroyGeneralRaise();
   unsigned int getColor(int i, int nb);
   unsigned int getColor(double val, double min, double max);
+  double getScaleValue(int iso, int numIso, double min, double max);
+  int getScaleIndex(double val, int numIso, double min, double max);
 };
 
 #endif