From bf29e24c390cff1a6c6826d060ba9525d39ba3f4 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Wed, 1 Sep 2004 20:23:50 +0000
Subject: [PATCH] For all our mechanical engineering friends out there, I just
 cleaned up the stuff I did with Sean last year, i.e., allow to draw a vector
 field as a displacement map, with another scalar field displayed instead of
 the displacement norm.

It's basically the same as Plugin(DisplacementRaise), but it does not modify the
actual data inside the view (so e.g. you cannot save it). Instead, it's implemented
as an alternative "Vector display" mode. This allows to easily animate deformed meshed
with arbitrary scalar fields drawn on them. (The GUI for this is kinda lame, but
it works: just select Vector display->Raised scalar view, select the scalar view
number, et voila.)

I also generalized the smooth normal code path a little, so that we can have smooth
normals for vector-as-displacement and tensor-as-von-mises plots, too.
---
 Common/DefaultOptions.h  |   4 +-
 Common/Options.cpp       |  42 +++++++----
 Common/Options.h         |   1 +
 Common/Views.cpp         |   3 +-
 Common/Views.h           |  16 +++--
 Fltk/Callbacks.cpp       |  32 +++++----
 Fltk/GUI.cpp             |  29 +++++---
 Graphics/Draw.h          |  32 ++++-----
 Graphics/Post.cpp        | 152 ++++++++++++++++++---------------------
 Graphics/PostElement.cpp | 152 ++++++++++++++++++++++++++++-----------
 Graphics/Scale.cpp       |  36 ++++++----
 TODO                     |   6 +-
 doc/VERSIONS             |   7 +-
 doc/gmsh.html            |   8 +--
 14 files changed, 317 insertions(+), 203 deletions(-)

diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index f495a48caf..d3493b4216 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1015,6 +1015,8 @@ StringXNumber ViewOptions_Number[] = {
   { F|O, "PositionY" , opt_view_position1 , 50. , 
     "Vertical position (in pixels) of the upper left corner of the scale or 2D graph" }, 
 
+  { F|O, "RaisedScalarView" , opt_view_raised_scalar_view , 0. ,
+    "Index of the scalar view raised by the displacement field" },
   { F,   "RaiseX" , opt_view_raise0 , 0. , 
     "Elevation of the view along X-axis (in model coordinates)" },
   { F,   "RaiseY" , opt_view_raise1 , 0. , 
@@ -1046,7 +1048,7 @@ StringXNumber ViewOptions_Number[] = {
     "Type of graph (1=3D, 2=2D-space, 3=2D-time)" },
 
   { F|O, "VectorType" , opt_view_vector_type , DRAW_POST_ARROW3D ,
-    "Vector display type (1=segment, 2=arrow, 3=pyramid, 4=3D arrow, 5=displacement)" },
+    "Vector display type (1=segment, 2=arrow, 3=pyramid, 4=3D arrow, 5=displacement, 6=raised scalar view)" },
   { F,   "Visible" , opt_view_visible , 1. ,
     "Is the view visible?" },
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 777667fd8e..f5a3c1e20a 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.179 2004-08-16 17:52:58 remacle Exp $
+// $Id: Options.cpp,v 1.180 2004-09-01 20:23:49 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -4929,19 +4929,19 @@ double opt_view_tensor_type(OPT_ARGS_NUM)
     v->TensorType = (int)val;
     v->Changed = 1;
   }
-#if defined(HAVE_FLTK)
-  if(_gui_action_valid(action, num)) {
-    switch (v->TensorType) {
-    case DRAW_POST_EIGENVECTORS:
-      WID->view_choice[4]->value(1);
-      break;
-    case DRAW_POST_VONMISES:
-    default:
-      WID->view_choice[4]->value(0);
-      break;
-    }
-  }
-#endif
+// #if defined(HAVE_FLTK)
+//   if(_gui_action_valid(action, num)) {
+//     switch (v->TensorType) {
+//     case DRAW_POST_EIGENVECTORS:
+//       WID->view_choice[4]->value(1);
+//       break;
+//     case DRAW_POST_VONMISES:
+//     default:
+//       WID->view_choice[4]->value(0);
+//       break;
+//     }
+//   }
+// #endif
   return v->TensorType;
 }
 
@@ -5066,6 +5066,20 @@ double opt_view_alpha_channel(OPT_ARGS_NUM)
   return v->AlphaChannel;
 }
 
+double opt_view_raised_scalar_view(OPT_ARGS_NUM)
+{
+  GET_VIEW(0.);
+  if(action & GMSH_SET) {
+    v->RaisedScalarView = (int)val;
+    v->Changed = 1;
+  }
+#if defined(HAVE_FLTK)
+  if(_gui_action_valid(action, num))
+    WID->view_value[64]->value(v->RaisedScalarView);
+#endif
+  return v->RaisedScalarView;
+}
+
 double opt_print_format(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index fa26a6296a..c77df8a3df 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -447,6 +447,7 @@ double opt_view_visible(OPT_ARGS_NUM);
 double opt_view_intervals_type(OPT_ARGS_NUM);
 double opt_view_saturate_values(OPT_ARGS_NUM);
 double opt_view_alpha_channel(OPT_ARGS_NUM);
+double opt_view_raised_scalar_view(OPT_ARGS_NUM);
 double opt_view_type(OPT_ARGS_NUM);
 double opt_view_grid(OPT_ARGS_NUM);
 double opt_view_position0(OPT_ARGS_NUM);
diff --git a/Common/Views.cpp b/Common/Views.cpp
index aeb9813311..5343d98448 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.126 2004-07-16 18:02:19 geuzaine Exp $
+// $Id: Views.cpp,v 1.127 2004-09-01 20:23:49 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -650,6 +650,7 @@ void CopyViewOptions(Post_View * src, Post_View * dest)
   dest->PointType = src->PointType;
   dest->LineType = src->LineType;
   dest->Grid = src->Grid;
+  dest->RaisedScalarView = src->RaisedScalarView;
   ColorTable_Copy(&src->CT);
   ColorTable_Paste(&dest->CT);
 }
diff --git a/Common/Views.h b/Common/Views.h
index c503a26c7d..659d51e6f7 100644
--- a/Common/Views.h
+++ b/Common/Views.h
@@ -83,10 +83,15 @@ class Post_View{
   int Boundary, Grid, PointType, LineType;
   double PointSize, LineWidth;
   GmshColorTable CT;
+  int RaisedScalarView;
 
   // dynamic
   double (*GVFI) (double min, double max, int nb, int index);
   int (*GIFV) (double min, double max, int nb, double value);
+  int ElementForDisplacement;
+  Post_View *ViewForDisplacement;
+  double MinForDisplacement, MaxForDisplacement;
+
   // smooth the view
   void smooth();
   // smooth normals
@@ -114,11 +119,12 @@ class Post_View{
 #define DRAW_POST_NUMERIC      4
 
 // VectorType
-#define DRAW_POST_SEGMENT      1
-#define DRAW_POST_ARROW        2
-#define DRAW_POST_PYRAMID      3
-#define DRAW_POST_ARROW3D      4
-#define DRAW_POST_DISPLACEMENT 5
+#define DRAW_POST_SEGMENT               1
+#define DRAW_POST_ARROW                 2
+#define DRAW_POST_PYRAMID               3
+#define DRAW_POST_ARROW3D               4
+#define DRAW_POST_DISPLACEMENT          5
+#define DRAW_POST_DISPLACEMENT_EXTERNAL 6
 
 // ArrowLocation
 #define DRAW_POST_LOCATE_COG     1
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 0db71a88de..1a636869cf 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.265 2004-08-15 02:27:48 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.266 2004-09-01 20:23:49 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -3367,7 +3367,7 @@ void view_options_ok_cb(CALLBACK_ARGS)
   double line_type = opt_view_line_type(current, GMSH_GET, 0);
   double vector_type = opt_view_vector_type(current, GMSH_GET, 0);
   double arrow_location = opt_view_arrow_location(current, GMSH_GET, 0);
-  double tensor_type = opt_view_tensor_type(current, GMSH_GET, 0);
+  //double tensor_type = opt_view_tensor_type(current, GMSH_GET, 0);
   double range_type = opt_view_range_type(current, GMSH_GET, 0);
   double grid = opt_view_grid(current, GMSH_GET, 0);
   double boundary = opt_view_boundary(current, GMSH_GET, 0);
@@ -3406,6 +3406,7 @@ void view_options_ok_cb(CALLBACK_ARGS)
   double timestep = opt_view_timestep(current, GMSH_GET, 0);
   double arrow_size = opt_view_arrow_size(current, GMSH_GET, 0);
   double displacement_factor = opt_view_displacement_factor(current, GMSH_GET, 0);
+  double raised_scalar_view = opt_view_raised_scalar_view(current, GMSH_GET, 0);
   double point_size = opt_view_point_size(current, GMSH_GET, 0);
   double line_width = opt_view_line_width(current, GMSH_GET, 0);
   double explode = opt_view_explode(current, GMSH_GET, 0);
@@ -3490,6 +3491,9 @@ void view_options_ok_cb(CALLBACK_ARGS)
       case 4:
 	val = DRAW_POST_DISPLACEMENT;
 	break;
+      case 5:
+	val = DRAW_POST_DISPLACEMENT_EXTERNAL;
+	break;
       default: // 3
 	val = DRAW_POST_ARROW3D;
 	break;
@@ -3508,16 +3512,16 @@ void view_options_ok_cb(CALLBACK_ARGS)
       if(force || (val != arrow_location))
         opt_view_arrow_location(i, GMSH_SET, val);
 
-      switch (WID->view_choice[4]->value()) {
-      case 0:
-	val = DRAW_POST_VONMISES;
-	break;
-      default:
-	val = DRAW_POST_EIGENVECTORS;
-	break;
-      }
-      if(force || (val != tensor_type))
-        opt_view_tensor_type(i, GMSH_SET, val);
+//     switch (WID->view_choice[4]->value()) {
+//     case 0:
+// 	val = DRAW_POST_VONMISES;
+//      break;
+//     default:
+// 	val = DRAW_POST_EIGENVECTORS;
+// 	break;
+//     }
+//     if(force || (val != tensor_type))
+//       opt_view_tensor_type(i, GMSH_SET, val);
 
       switch (WID->view_choice[7]->value()) {
       case 0:
@@ -3678,6 +3682,10 @@ void view_options_ok_cb(CALLBACK_ARGS)
       if(force || (val != displacement_factor))
         opt_view_displacement_factor(i, GMSH_SET, val);
 
+      val = WID->view_value[64]->value();
+      if(force || (val != raised_scalar_view))
+        opt_view_raised_scalar_view(i, GMSH_SET, val);
+
       val = WID->view_value[61]->value();
       if(force || (val != point_size))
         opt_view_point_size(i, GMSH_SET, val);
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index db0ba2ae0e..8bcbd34dc7 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.336 2004-08-16 17:52:59 remacle Exp $
+// $Id: GUI.cpp,v 1.337 2004-09-01 20:23:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -456,6 +456,7 @@ int GUI::global_shortcuts(int event)
     if(g_window && g_window->shown()) g_window->show();
     if(opt_window && opt_window->shown()) opt_window->show();
     if(vis_window && vis_window->shown()) vis_window->show();
+    if(clip_window && clip_window->shown()) clip_window->show();
     if(stat_window && stat_window->shown()) stat_window->show();
     if(msg_window && msg_window->shown()) msg_window->show();
     if(m_window && m_window->shown()) m_window->show();
@@ -2558,6 +2559,7 @@ void GUI::create_option_window()
           {"Pyramid", 0, 0, 0},
           {"3D arrow", 0, 0, 0},
           {"Displacement", 0, 0, 0},
+          {"Raised scalar view", 0, 0, 0},
           {0}
         };
         view_choice[2] = new Fl_Choice(2 * WB, 2 * WB + 6 * BH, IW, BH, "Vector display");
@@ -2575,23 +2577,29 @@ void GUI::create_option_window()
         view_value[63] = new Fl_Value_Input(2 * WB, 2 * WB + 8 * BH, IW, BH, "Displacement factor");
         view_value[63]->align(FL_ALIGN_RIGHT);
 
+        view_value[64] = new Fl_Value_Input(2 * WB, 2 * WB + 9 * BH, IW, BH, "Raised scalar view number");
+        view_value[64]->minimum(0);
+        view_value[64]->maximum(10);
+        view_value[64]->step(1);
+        view_value[64]->align(FL_ALIGN_RIGHT);
+
         static Fl_Menu_Item menu_vecloc[] = {
           {"Cell centered", 0, 0, 0},
           {"Vertex centered", 0, 0, 0},
           {0}
         };
-        view_choice[3] = new Fl_Choice(2 * WB, 2 * WB + 9 * BH, IW, BH, "Arrow location");
+        view_choice[3] = new Fl_Choice(2 * WB, 2 * WB + 10 * BH, IW, BH, "Arrow location");
         view_choice[3]->menu(menu_vecloc);
         view_choice[3]->align(FL_ALIGN_RIGHT);
 
-        static Fl_Menu_Item menu_tensor[] = {
-          {"Von-Mises", 0, 0, 0},
+        //static Fl_Menu_Item menu_tensor[] = {
+	  //{"Von-Mises", 0, 0, 0},
           //{"Eigenvectors", 0, 0, 0}, //not implemented yet
-          {0}
-        };
-        view_choice[4] = new Fl_Choice(2 * WB, 2 * WB + 10 * BH, IW, BH, "Tensor display");
-        view_choice[4]->menu(menu_tensor);
-        view_choice[4]->align(FL_ALIGN_RIGHT);
+          //{0}
+        //};
+        //view_choice[4] = new Fl_Choice(2 * WB, 2 * WB + 10 * BH, IW, BH, "Tensor display");
+        //view_choice[4]->menu(menu_tensor);
+        //view_choice[4]->align(FL_ALIGN_RIGHT);
 
         view_vector->end();
       }
@@ -2780,8 +2788,9 @@ void GUI::update_view_window(int num)
   opt_view_vector_type(num, GMSH_GUI, 0);
   opt_view_arrow_size(num, GMSH_GUI, 0);
   opt_view_displacement_factor(num, GMSH_GUI, 0);
+  opt_view_raised_scalar_view(num, GMSH_GUI, 0);
   opt_view_arrow_location(num, GMSH_GUI, 0);
-  opt_view_tensor_type(num, GMSH_GUI, 0);
+  //opt_view_tensor_type(num, GMSH_GUI, 0);
   view_push_butt[0]->callback(view_arrow_param_cb, (void*)num);
 
   view_colorbar_window->update(v->Name, v->Min, v->Max, &v->CT, &v->Changed);
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 4563f49407..100d36377c 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -100,73 +100,73 @@ void Draw_PlaneInBoundingBox(double xmin, double ymin, double zmin,
 void Draw_ScalarPoint(Post_View *View, int preproNormals,
 		      double ValMin, double ValMax, 
 		      double *X, double *Y, double *Z, double *V);
-void Draw_VectorPoint(Post_View *View, 
+void Draw_VectorPoint(Post_View *View, int preproNormals,
 		      double ValMin, double ValMax, 
 		      double *X, double *Y, double *Z, double *V);
-void Draw_TensorPoint(Post_View *View, 
+void Draw_TensorPoint(Post_View *View, int preproNormals,
 		      double ValMin, double ValMax, 
 		      double *X, double *Y, double *Z, double *V);
 void Draw_ScalarLine(Post_View *View, int preproNormals,
 		     double ValMin, double ValMax, 
 		     double *X, double *Y, double *Z, double *V);
-void Draw_VectorLine(Post_View *View, 
+void Draw_VectorLine(Post_View *View, int preproNormals,
 		     double ValMin, double ValMax, 
 		     double *X, double *Y, double *Z, double *V);
-void Draw_TensorLine(Post_View *View, 
+void Draw_TensorLine(Post_View *View, int preproNormals,
 		     double ValMin, double ValMax,
 		     double *X, double *Y, double *Z, double *V);
 void Draw_ScalarTriangle(Post_View *View, int preproNormals,
 			 double ValMin, double ValMax,
 			 double *X, double *Y, double *Z, double *V);
-void Draw_VectorTriangle(Post_View *View, 
+void Draw_VectorTriangle(Post_View *View, int preproNormals,
 			 double ValMin, double ValMax,
 			 double *X, double *Y, double *Z, double *V);
-void Draw_TensorTriangle(Post_View *View, 
+void Draw_TensorTriangle(Post_View *View, int preproNormals,
 			 double ValMin, double ValMax,
 			 double *X, double *Y, double *Z, double *V);
 void Draw_ScalarTetrahedron(Post_View *View, int preproNormals,
 			    double ValMin, double ValMax,
 			    double *X, double *Y, double *Z, double *V);
-void Draw_VectorTetrahedron(Post_View *View, 
+void Draw_VectorTetrahedron(Post_View *View, int preproNormals,
 			    double ValMin, double ValMax,
 			    double *X, double *Y, double *Z, double *V);
-void Draw_TensorTetrahedron(Post_View *View, 
+void Draw_TensorTetrahedron(Post_View *View, int preproNormals,
 			    double ValMin, double ValMax,
 			    double *X, double *Y, double *Z, double *V);
 void Draw_ScalarQuadrangle(Post_View *View, int preproNormals,
 			   double ValMin, double ValMax,
 			   double *X, double *Y, double *Z, double *V);
-void Draw_VectorQuadrangle(Post_View *View, 
+void Draw_VectorQuadrangle(Post_View *View, int preproNormals,
 			   double ValMin, double ValMax,
 			   double *X, double *Y, double *Z, double *V);
-void Draw_TensorQuadrangle(Post_View *View, 
+void Draw_TensorQuadrangle(Post_View *View, int preproNormals,
 			   double ValMin, double ValMax,
 			   double *X, double *Y, double *Z, double *V);
 void Draw_ScalarHexahedron(Post_View *View, int preproNormals,
 			   double ValMin, double ValMax,
 			   double *X, double *Y, double *Z, double *V);
-void Draw_VectorHexahedron(Post_View *View, 
+void Draw_VectorHexahedron(Post_View *View, int preproNormals,
 			   double ValMin, double ValMax,
 			   double *X, double *Y, double *Z, double *V);
-void Draw_TensorHexahedron(Post_View *View, 
+void Draw_TensorHexahedron(Post_View *View, int preproNormals,
 			   double ValMin, double ValMax,
 			   double *X, double *Y, double *Z, double *V);
 void Draw_ScalarPrism(Post_View *View, int preproNormals,
 		      double ValMin, double ValMax,
 		      double *X, double *Y, double *Z, double *V);
-void Draw_VectorPrism(Post_View *View, 
+void Draw_VectorPrism(Post_View *View, int preproNormals,
 		      double ValMin, double ValMax,
 		      double *X, double *Y, double *Z, double *V);
-void Draw_TensorPrism(Post_View *View, 
+void Draw_TensorPrism(Post_View *View, int preproNormals,
 		      double ValMin, double ValMax,
 		      double *X, double *Y, double *Z, double *V);
 void Draw_ScalarPyramid(Post_View *View, int preproNormals,
 			double ValMin, double ValMax,
 			double *X, double *Y, double *Z, double *V);
-void Draw_VectorPyramid(Post_View *View, 
+void Draw_VectorPyramid(Post_View *View, int preproNormals,
 			double ValMin, double ValMax,
 			double *X, double *Y, double *Z, double *V);
-void Draw_TensorPyramid(Post_View *View, 
+void Draw_TensorPyramid(Post_View *View, int preproNormals,
 			double ValMin, double ValMax,
 			double *X, double *Y, double *Z, double *V);
 
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 5156b02829..c2beef5f80 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.76 2004-08-28 00:48:37 geuzaine Exp $
+// $Id: Post.cpp,v 1.77 2004-09-01 20:23:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -231,19 +231,23 @@ int compareEye8Nodes(const void *a, const void *b)
 
 // Draw_Post
 
-void Draw_ScalarList(Post_View * v, double ValMin, double ValMax,
-                     List_T * list, int nbelm, int nbnod, int smoothnormals,
-		     void (*draw) (Post_View *, int, double, double, double *, 
-				   double *, double *, double *))
+void Draw_List(Post_View * v, double ValMin, double ValMax,
+	       List_T * list, int nbelm, int nbnod,
+	       void (*draw) (Post_View *, int, double, double, double *, 
+			     double *, double *, double *))
 {
   int i, nb;
   double X[8], Y[8], Z[8];
 
-  if(nbelm && v->DrawScalars) {
+  if(nbelm) {
     nb = List_Nbr(list) / nbelm;
-    if(smoothnormals && v->Light && v->SmoothNormals && v->Changed) {
-      v->reset_normals(); 
+
+    v->ViewForDisplacement = 
+      (Post_View*)List_Pointer_Test(CTX.post.list, v->RaisedScalarView);
+
+    if(v->Light && v->SmoothNormals && v->Changed) {
       Msg(DEBUG, "Preprocessing of normals in View[%d]", v->Index);
+      v->ElementForDisplacement = 0;
       for(i = 0; i < List_Nbr(list); i += nb) {
         Get_Coords(v->Explode, v->Offset, nbnod,
                    (double *)List_Pointer_Fast(list, i),
@@ -251,57 +255,19 @@ void Draw_ScalarList(Post_View * v, double ValMin, double ValMax,
                    (double *)List_Pointer_Fast(list, i + 2 * nbnod), X, Y, Z);
         draw(v, 1, ValMin, ValMax, X, Y, Z,
              (double *)List_Pointer_Fast(list, i + 3 * nbnod));
+	v->ElementForDisplacement++;
       }
     }
-    for(i = 0; i < List_Nbr(list); i += nb) {
-      Get_Coords(v->Explode, v->Offset, nbnod,
-                 (double *)List_Pointer_Fast(list, i),
-                 (double *)List_Pointer_Fast(list, i + nbnod),
-                 (double *)List_Pointer_Fast(list, i + 2 * nbnod), X, Y, Z);
-      draw(v, 0, ValMin, ValMax, X, Y, Z,
-           (double *)List_Pointer_Fast(list, i + 3 * nbnod));
-    }
-  }
-}
-
-void Draw_VectorList(Post_View * v, double ValMin, double ValMax,
-                     List_T * list, int nbelm, int nbnod, 
-                     void (*draw) (Post_View *, double, double,
-                                   double *, double *, double *, double *))
-{
-  int i, nb;
-  double X[8], Y[8], Z[8];
-
-  if(nbelm && v->DrawVectors) {
-    nb = List_Nbr(list) / nbelm;
-    for(i = 0; i < List_Nbr(list); i += nb) {
-      Get_Coords(v->Explode, v->Offset, nbnod,
-                 (double *)List_Pointer_Fast(list, i),
-                 (double *)List_Pointer_Fast(list, i + nbnod),
-                 (double *)List_Pointer_Fast(list, i + 2 * nbnod), X, Y, Z);
-      draw(v, ValMin, ValMax, X, Y, Z,
-           (double *)List_Pointer_Fast(list, i + 3 * nbnod));
-    }
-  }
-}
 
-void Draw_TensorList(Post_View * v, double ValMin, double ValMax,
-                     List_T * list, int nbelm, int nbnod, 
-                     void (*draw) (Post_View *, double, double,
-                                   double *, double *, double *, double *))
-{
-  int i, nb;
-  double X[8], Y[8], Z[8];
-
-  if(nbelm && v->DrawTensors) {
-    nb = List_Nbr(list) / nbelm;
+    v->ElementForDisplacement = 0;
     for(i = 0; i < List_Nbr(list); i += nb) {
       Get_Coords(v->Explode, v->Offset, nbnod,
                  (double *)List_Pointer_Fast(list, i),
                  (double *)List_Pointer_Fast(list, i + nbnod),
                  (double *)List_Pointer_Fast(list, i + 2 * nbnod), X, Y, Z);
-      draw(v, ValMin, ValMax, X, Y, Z,
+      draw(v, 0, ValMin, ValMax, X, Y, Z,
            (double *)List_Pointer_Fast(list, i + 3 * nbnod));
+      v->ElementForDisplacement++;
     }
   }
 }
@@ -406,6 +372,8 @@ void Draw_Post(void)
 	ValMax = v->TimeStepMax[v->TimeStep];
 	break;
       }
+      v->MinForDisplacement = ValMin;
+      v->MaxForDisplacement = ValMax;
       
       switch (v->ScaleType) {
       case DRAW_POST_LINEAR:
@@ -422,6 +390,9 @@ void Draw_Post(void)
 	break;
       }
 
+      if(v->Light && v->SmoothNormals && v->Changed)
+	v->reset_normals();
+
       // initialize alpha blending for transparency
       if(CTX.alpha && ColorTable_IsAlpha(&v->CT)){
 	if(CTX.fake_transparency){
@@ -472,17 +443,22 @@ void Draw_Post(void)
 	  }
 	}
       }
-      
+
       if(v->DrawPoints) {
-	if(v->Type == DRAW_POST_3D)
-	  Draw_ScalarList(v, ValMin, ValMax, v->SP, v->NbSP, 1, 0, Draw_ScalarPoint);
-	Draw_VectorList(v, ValMin, ValMax, v->VP, v->NbVP, 1, Draw_VectorPoint);
-	Draw_TensorList(v, ValMin, ValMax, v->TP, v->NbTP, 1, Draw_TensorPoint);
+	if(v->Type == DRAW_POST_3D && v->DrawScalars)
+	  Draw_List(v, ValMin, ValMax, v->SP, v->NbSP, 1, Draw_ScalarPoint);
+	if(v->DrawVectors)
+	  Draw_List(v, ValMin, ValMax, v->VP, v->NbVP, 1, Draw_VectorPoint);
+	if(v->DrawTensors)
+	  Draw_List(v, ValMin, ValMax, v->TP, v->NbTP, 1, Draw_TensorPoint);
       }
       if(v->DrawLines) {
-	Draw_ScalarList(v, ValMin, ValMax, v->SL, v->NbSL, 2, 0, Draw_ScalarLine);
-	Draw_VectorList(v, ValMin, ValMax, v->VL, v->NbVL, 2, Draw_VectorLine);
-	Draw_TensorList(v, ValMin, ValMax, v->TL, v->NbTL, 2, Draw_TensorLine);
+	if(v->DrawScalars)
+	  Draw_List(v, ValMin, ValMax, v->SL, v->NbSL, 2, Draw_ScalarLine);
+	if(v->DrawVectors)
+	  Draw_List(v, ValMin, ValMax, v->VL, v->NbVL, 2, Draw_VectorLine);
+	if(v->DrawTensors)
+	  Draw_List(v, ValMin, ValMax, v->TL, v->NbTL, 2, Draw_TensorLine);
       }
 
       for(int pass = 0; pass < 2; pass++){
@@ -517,40 +493,52 @@ void Draw_Post(void)
 
       pass_0:
 	if(v->DrawTriangles) {
-	  if(!skip_2d)
-	    Draw_ScalarList(v, ValMin, ValMax, v->ST, v->NbST, 3, 1, Draw_ScalarTriangle);
-	  Draw_VectorList(v, ValMin, ValMax, v->VT, v->NbVT, 3, Draw_VectorTriangle);
-	  Draw_TensorList(v, ValMin, ValMax, v->TT, v->NbTT, 3, Draw_TensorTriangle);
+	  if(!skip_2d && v->DrawScalars)
+	    Draw_List(v, ValMin, ValMax, v->ST, v->NbST, 3, Draw_ScalarTriangle);
+	  if(v->DrawVectors)
+	    Draw_List(v, ValMin, ValMax, v->VT, v->NbVT, 3, Draw_VectorTriangle);
+	  if(v->DrawTensors)
+	    Draw_List(v, ValMin, ValMax, v->TT, v->NbTT, 3, Draw_TensorTriangle);
 	}
 	if(v->DrawQuadrangles) {
-	  if(!skip_2d)
-	    Draw_ScalarList(v, ValMin, ValMax, v->SQ, v->NbSQ, 4, 1, Draw_ScalarQuadrangle);
-	  Draw_VectorList(v, ValMin, ValMax, v->VQ, v->NbVQ, 4, Draw_VectorQuadrangle);
-	  Draw_TensorList(v, ValMin, ValMax, v->TQ, v->NbTQ, 4, Draw_TensorQuadrangle);
+	  if(!skip_2d && v->DrawScalars)
+	    Draw_List(v, ValMin, ValMax, v->SQ, v->NbSQ, 4, Draw_ScalarQuadrangle);
+	  if(v->DrawVectors)
+	    Draw_List(v, ValMin, ValMax, v->VQ, v->NbVQ, 4, Draw_VectorQuadrangle);
+	  if(v->DrawTensors)
+	    Draw_List(v, ValMin, ValMax, v->TQ, v->NbTQ, 4, Draw_TensorQuadrangle);
 	}
 	if(v->DrawTetrahedra) {
-	  if(!skip_3d)
-	    Draw_ScalarList(v, ValMin, ValMax, v->SS, v->NbSS, 4, 1, Draw_ScalarTetrahedron);
-	  Draw_VectorList(v, ValMin, ValMax, v->VS, v->NbVS, 4, Draw_VectorTetrahedron);
-	  Draw_TensorList(v, ValMin, ValMax, v->TS, v->NbTS, 4, Draw_TensorTetrahedron);
+	  if(!skip_3d && v->DrawScalars)
+	    Draw_List(v, ValMin, ValMax, v->SS, v->NbSS, 4, Draw_ScalarTetrahedron);
+	  if(v->DrawVectors)
+	    Draw_List(v, ValMin, ValMax, v->VS, v->NbVS, 4, Draw_VectorTetrahedron);
+	  if(v->DrawTensors)
+	    Draw_List(v, ValMin, ValMax, v->TS, v->NbTS, 4, Draw_TensorTetrahedron);
 	}
 	if(v->DrawHexahedra) {
-	  if(!skip_3d)
-	    Draw_ScalarList(v, ValMin, ValMax, v->SH, v->NbSH, 8, 1, Draw_ScalarHexahedron);
-	  Draw_VectorList(v, ValMin, ValMax, v->VH, v->NbVH, 8, Draw_VectorHexahedron);
-	  Draw_TensorList(v, ValMin, ValMax, v->TH, v->NbTH, 8, Draw_TensorHexahedron);
+	  if(!skip_3d && v->DrawScalars)
+	    Draw_List(v, ValMin, ValMax, v->SH, v->NbSH, 8, Draw_ScalarHexahedron);
+	  if(v->DrawVectors)
+	    Draw_List(v, ValMin, ValMax, v->VH, v->NbVH, 8, Draw_VectorHexahedron);
+	  if(v->DrawTensors)
+	    Draw_List(v, ValMin, ValMax, v->TH, v->NbTH, 8, Draw_TensorHexahedron);
 	}
 	if(v->DrawPrisms) {
-	  if(!skip_3d)
-	    Draw_ScalarList(v, ValMin, ValMax, v->SI, v->NbSI, 6, 1, Draw_ScalarPrism);
-	  Draw_VectorList(v, ValMin, ValMax, v->VI, v->NbVI, 6, Draw_VectorPrism);
-	  Draw_TensorList(v, ValMin, ValMax, v->TI, v->NbTI, 6, Draw_TensorPrism);
+	  if(!skip_3d && v->DrawScalars)
+	    Draw_List(v, ValMin, ValMax, v->SI, v->NbSI, 6, Draw_ScalarPrism);
+	  if(v->DrawVectors)
+	    Draw_List(v, ValMin, ValMax, v->VI, v->NbVI, 6, Draw_VectorPrism);
+	  if(v->DrawTensors)
+	    Draw_List(v, ValMin, ValMax, v->TI, v->NbTI, 6, Draw_TensorPrism);
 	}
 	if(v->DrawPyramids) {
-	  if(!skip_3d)
-	    Draw_ScalarList(v, ValMin, ValMax, v->SY, v->NbSY, 5, 1, Draw_ScalarPyramid);
-	  Draw_VectorList(v, ValMin, ValMax, v->VY, v->NbVY, 5, Draw_VectorPyramid);
-	  Draw_TensorList(v, ValMin, ValMax, v->TY, v->NbTY, 5, Draw_TensorPyramid);
+	  if(!skip_3d && v->DrawScalars)
+	    Draw_List(v, ValMin, ValMax, v->SY, v->NbSY, 5, Draw_ScalarPyramid);
+	  if(v->DrawVectors)
+	    Draw_List(v, ValMin, ValMax, v->VY, v->NbVY, 5, Draw_VectorPyramid);
+	  if(v->DrawTensors)
+	    Draw_List(v, ValMin, ValMax, v->TY, v->NbTY, 5, Draw_TensorPyramid);
 	}
 
       pass_1:
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index fa04e600eb..838d6ac828 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.40 2004-08-07 06:59:16 geuzaine Exp $
+// $Id: PostElement.cpp,v 1.41 2004-09-01 20:23:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -229,7 +229,7 @@ void Draw_ScalarPoint(Post_View * View, int preproNormals,
   double d;
   char Num[100];
 
-  if(View->Boundary > 0)
+  if(View->Boundary > 0 || preproNormals)
     return;
 
   d = V[View->TimeStep];
@@ -269,6 +269,9 @@ void Draw_ScalarLine(Post_View * View, int preproNormals,
   double Xp[5], Yp[5], Zp[5], Vp[5], Val[5];
   char Num[100];
 
+  if(preproNormals)
+    return;
+
   double *vv = &V[2 * View->TimeStep];
 
   if(View->Boundary > 0) {
@@ -858,9 +861,69 @@ void Draw_ScalarPyramid(Post_View * View, int preproNormals,
   View->ShowElement = show;
 }
 
+
+int GetScalarDataFromOtherView(int type, int nbnod, Post_View *v, double *d)
+{
+  static int error1 = -1;
+  static int error2 = -1;
+  Post_View *v2 = v->ViewForDisplacement;
+  int num = v->ElementForDisplacement;
+
+  if(!v2){
+    if(error1 != v->Num){
+      Msg(GERROR, "Non-existent view for displacement plot");
+      error1 = v->Num;
+    }
+    return 0;
+  }
+
+  int nbelm = 0;
+  List_T *l;
+  switch (type) {
+  case POINT: if(v->NbVP == v2->NbSP){ nbelm = v2->NbSP; l = v2->SP; } break;
+  case LINE: if(v->NbVL == v2->NbSL){ nbelm = v2->NbSL; l = v2->SL; } break;
+  case TRIANGLE: if(v->NbVT == v2->NbST){ nbelm = v2->NbST; l = v2->ST; } break;
+  case QUADRANGLE: if(v->NbVQ == v2->NbSQ){ nbelm = v2->NbSQ; l = v2->SQ; } break;
+  case TETRAHEDRON: if(v->NbVS == v2->NbSS){ nbelm = v2->NbSS; l = v2->SS; } break;
+  case HEXAHEDRON: if(v->NbVH == v2->NbSH){ nbelm = v2->NbSH; l = v2->SH; } break;
+  case PRISM: if(v->NbVI == v2->NbSI){ nbelm = v2->NbSI; l = v2->SI; } break;
+  case PYRAMID: if(v->NbVY == v2->NbSY){ nbelm = v2->NbSY; l = v2->SY; } break;
+  }
+
+  if(!nbelm || num < 0 || v2->NbTimeStep != v->NbTimeStep){
+    if(error2 != v->Num){
+      Msg(GERROR, "Incompatible view for displacement plot");
+      error2 = v->Num;
+    }
+    return 0;
+  }
+
+  int nb = List_Nbr(l) / nbelm;
+  double *val = (double *)List_Pointer_Fast(l, num * nb + 3 * nbnod);
+  for(int k = 0; k < nbnod; k++)
+    d[k] = val[nbnod * v->TimeStep + k];
+
+  switch (v->RangeType) {
+  case DRAW_POST_RANGE_DEFAULT:
+    v->MinForDisplacement = v2->Min;
+    v->MaxForDisplacement = v2->Max;
+    break;
+  case DRAW_POST_RANGE_CUSTOM: // yes, take the values from v!
+    v->MinForDisplacement = v->CustomMin;
+    v->MaxForDisplacement = v->CustomMax;
+    break;
+  case DRAW_POST_RANGE_PER_STEP:
+    v->MinForDisplacement = v2->TimeStepMin[v->TimeStep];
+    v->MaxForDisplacement = v2->TimeStepMax[v->TimeStep];
+    break;
+  }
+
+  return 1;
+}
+
 // Vector Elements
 
-void Draw_VectorElement(int type, Post_View * View,
+void Draw_VectorElement(int type, Post_View * View, int preproNormals,
                         double ValMin, double ValMax, 
                         double *X, double *Y, double *Z, double *V)
 {
@@ -888,12 +951,19 @@ void Draw_VectorElement(int type, Post_View * View,
     d[k] = sqrt(Val[k][0] * Val[k][0] + Val[k][1] * Val[k][1] +	Val[k][2] * Val[k][2]);
   }
 
+  if(View->VectorType == DRAW_POST_DISPLACEMENT_EXTERNAL){
+    GetScalarDataFromOtherView(type, nbnod, View, d);
+    ValMin = View->MinForDisplacement;
+    ValMax = View->MaxForDisplacement;
+  }
+
   double Raise[3][8];
   for(int i = 0; i < 3; i++)
     for(int k = 0; k < nbnod; k++)
       Raise[i][k] = View->Raise[i] * d[k];
 
-  if(View->VectorType == DRAW_POST_DISPLACEMENT) {
+  if(View->VectorType == DRAW_POST_DISPLACEMENT ||
+     View->VectorType == DRAW_POST_DISPLACEMENT_EXTERNAL){
 
     fact = View->DisplacementFactor;
     for(int k = 0; k < nbnod; k++) {
@@ -906,7 +976,7 @@ void Draw_VectorElement(int type, Post_View * View,
     View->TimeStep = 0;
     switch (type) {
     case POINT:
-      Draw_ScalarPoint(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarPoint(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       if(ts) {  //draw trajectory
         if(View->LineType) {
           double dx2, dy2, dz2, XX[2], YY[2], ZZ[2];
@@ -950,25 +1020,25 @@ void Draw_VectorElement(int type, Post_View * View,
       }
       break;
     case LINE:
-      Draw_ScalarLine(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarLine(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     case TRIANGLE:
-      Draw_ScalarTriangle(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarTriangle(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     case TETRAHEDRON:
-      Draw_ScalarTetrahedron(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarTetrahedron(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     case QUADRANGLE:
-      Draw_ScalarQuadrangle(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarQuadrangle(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     case HEXAHEDRON:
-      Draw_ScalarHexahedron(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarHexahedron(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     case PRISM:
-      Draw_ScalarPrism(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarPrism(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     case PYRAMID:
-      Draw_ScalarPyramid(View, 0, ValMin, ValMax, xx, yy, zz, d);
+      Draw_ScalarPyramid(View, preproNormals, ValMin, ValMax, xx, yy, zz, d);
       break;
     }
     View->TimeStep = ts;
@@ -1058,55 +1128,55 @@ void Draw_VectorElement(int type, Post_View * View,
   }
 }
 
-#define ARGS Post_View *View, 			\
-             double ValMin, double ValMax, 	\
+#define ARGS Post_View *View, int preproNormals, \
+             double ValMin, double ValMax, 	 \
              double *X, double *Y, double *Z, double *V
 
 void Draw_VectorPoint(ARGS)
 {
-  Draw_VectorElement(POINT, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(POINT, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorLine(ARGS)
 {
-  Draw_VectorElement(LINE, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(LINE, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorTriangle(ARGS)
 {
-  Draw_VectorElement(TRIANGLE, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(TRIANGLE, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorTetrahedron(ARGS)
 {
-  Draw_VectorElement(TETRAHEDRON, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(TETRAHEDRON, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorQuadrangle(ARGS)
 {
-  Draw_VectorElement(QUADRANGLE, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(QUADRANGLE, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorHexahedron(ARGS)
 {
-  Draw_VectorElement(HEXAHEDRON, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(HEXAHEDRON, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorPrism(ARGS)
 {
-  Draw_VectorElement(PRISM, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(PRISM, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_VectorPyramid(ARGS)
 {
-  Draw_VectorElement(PYRAMID, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_VectorElement(PYRAMID, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 #undef ARGS
 
 // Tensor Elements
 
-void Draw_TensorElement(int type, Post_View * View,
+void Draw_TensorElement(int type, Post_View * View, int preproNormals,
                         double ValMin, double ValMax,
                         double *X, double *Y, double *Z, double *V)
 {
@@ -1138,76 +1208,76 @@ void Draw_TensorElement(int type, Post_View * View,
 
   switch (type) {
   case POINT:
-    Draw_ScalarPoint(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarPoint(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case LINE:
-    Draw_ScalarLine(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarLine(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case TRIANGLE:
-    Draw_ScalarTriangle(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarTriangle(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case QUADRANGLE:
-    Draw_ScalarQuadrangle(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarQuadrangle(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case TETRAHEDRON:
-    Draw_ScalarTetrahedron(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarTetrahedron(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case HEXAHEDRON:
-    Draw_ScalarHexahedron(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarHexahedron(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case PRISM:
-    Draw_ScalarPrism(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarPrism(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   case PYRAMID:
-    Draw_ScalarPyramid(View, 0, ValMin, ValMax, X, Y, Z, V_VonMises);
+    Draw_ScalarPyramid(View, preproNormals, ValMin, ValMax, X, Y, Z, V_VonMises);
     break;
   }
 
   View->TimeStep = ts;
 }
 
-#define ARGS Post_View *View, 			\
-             double ValMin, double ValMax, 	\
+#define ARGS Post_View *View, int preproNormals, \
+             double ValMin, double ValMax, 	 \
              double *X, double *Y, double *Z, double *V
 
 void Draw_TensorPoint(ARGS)
 {
-  Draw_TensorElement(POINT, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(POINT, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorLine(ARGS)
 {
-  Draw_TensorElement(LINE, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(LINE, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorTriangle(ARGS)
 {
-  Draw_TensorElement(TRIANGLE, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(TRIANGLE, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorTetrahedron(ARGS)
 {
-  Draw_TensorElement(TETRAHEDRON, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(TETRAHEDRON, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorQuadrangle(ARGS)
 {
-  Draw_TensorElement(QUADRANGLE, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(QUADRANGLE, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorHexahedron(ARGS)
 {
-  Draw_TensorElement(HEXAHEDRON, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(HEXAHEDRON, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorPrism(ARGS)
 {
-  Draw_TensorElement(PRISM, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(PRISM, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 void Draw_TensorPyramid(ARGS)
 {
-  Draw_TensorElement(PYRAMID, View, ValMin, ValMax, X, Y, Z, V);
+  Draw_TensorElement(PYRAMID, View, preproNormals, ValMin, ValMax, X, Y, Z, V);
 }
 
 #undef ARGS
diff --git a/Graphics/Scale.cpp b/Graphics/Scale.cpp
index 7478fa8d00..f69155eccc 100644
--- a/Graphics/Scale.cpp
+++ b/Graphics/Scale.cpp
@@ -1,4 +1,4 @@
-// $Id: Scale.cpp,v 1.43 2004-05-29 10:11:12 geuzaine Exp $
+// $Id: Scale.cpp,v 1.44 2004-09-01 20:23:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -68,20 +68,26 @@ void draw_scale(Post_View * v,
     glEnd();
   }
 
-  switch(v->RangeType){
-  case DRAW_POST_RANGE_CUSTOM:
-    ValMin = v->CustomMin;
-    ValMax = v->CustomMax;
-    break;
-  case DRAW_POST_RANGE_PER_STEP:
-    ValMin = v->TimeStepMin[v->TimeStep];
-    ValMax = v->TimeStepMax[v->TimeStep];
-    break;
-  case DRAW_POST_RANGE_DEFAULT:
-  default:
-    ValMin = v->Min;
-    ValMax = v->Max;
-    break;
+  if(v->VectorType == DRAW_POST_DISPLACEMENT_EXTERNAL){
+    ValMin = v->MinForDisplacement;
+    ValMax = v->MaxForDisplacement;
+  }
+  else{
+    switch(v->RangeType){
+    case DRAW_POST_RANGE_CUSTOM:
+      ValMin = v->CustomMin;
+      ValMax = v->CustomMax;
+      break;
+    case DRAW_POST_RANGE_PER_STEP:
+      ValMin = v->TimeStepMin[v->TimeStep];
+      ValMax = v->TimeStepMax[v->TimeStep];
+      break;
+    case DRAW_POST_RANGE_DEFAULT:
+    default:
+      ValMin = v->Min;
+      ValMax = v->Max;
+      break;
+    }
   }
 
   switch (v->ScaleType) {
diff --git a/TODO b/TODO
index 4cdf10484a..8020a10509 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.60 2004-08-20 17:54:20 geuzaine Exp $
+$Id: TODO,v 1.61 2004-09-01 20:23:49 geuzaine Exp $
 
 add an interactive way to choose the orientation of surfaces in
 surface loops and lines in line loops
@@ -9,6 +9,10 @@ normals...)
 
 ********************************************************************
 
+Raise & offsets should modify the bouding boxes... (maybe?)
+
+********************************************************************
+
 Test and reintroduce the cylindrical surfaces (cylinder, cone, torus)
 
 ********************************************************************
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 8b0976e5a3..8194e7e0b9 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,4 +1,9 @@
-$Id: VERSIONS,v 1.243 2004-08-21 21:10:26 geuzaine Exp $
+$Id: VERSIONS,v 1.244 2004-09-01 20:23:50 geuzaine Exp $
+
+New since 1.55: new post-processing option to draw a scalar view
+raised by a displacement view without using Plugin(DisplacementRaise)
+(makes drawing arbitrary scalar fields on deformed meshes much
+easier); small bug fixes.
 
 New in 1.55: added background mesh support for Triangle; meshes can
 now be displayed using "smoothed" normals (like post-processing
diff --git a/doc/gmsh.html b/doc/gmsh.html
index 0e74e9c47b..0b07a86003 100644
--- a/doc/gmsh.html
+++ b/doc/gmsh.html
@@ -103,10 +103,10 @@ capabilities</a>.
 
 Gmsh is distributed under the terms of the <a
 href="http://www.gnu.org/copyleft/gpl.html">GNU General Public License
-(GPL)</a>. Pre-compiled binaries (dynamically linked with OpenGL<a
-href="#opengl-footnote" name="opengl-footmark"><sup>1</sup></a>) are
-available for Windows, Linux and Mac OS X. The tutorial and demo files
-are included in the archives.
+(GPL)</a>. Pre-compiled binaries<a href="#opengl-footnote"
+name="opengl-footmark"><sup>1</sup></a> are available for Windows,
+Linux and Mac OS X. The tutorial and demo files are included in the
+archives.
 
 <ul>
 <li><a href="/gmsh/bin/Windows/gmsh-1.55.0-Windows.zip">Windows zip archive (95/98/NT/2000/XP)</a>
-- 
GitLab