diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 5228cbb403136e61ca71b85acfad931dda121fdc..cee24db57163bcc41532b2534fffa5d8606654ee 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.658 2008-02-23 15:30:06 geuzaine Exp $
+// $Id: GUI.cpp,v 1.659 2008-02-24 14:55:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -3474,8 +3474,7 @@ void GUI::update_view_window(int num)
     view_value[34]->deactivate();
   }
 
-  if(data->getNumElements(PViewData::Point) ||
-     data->getNumElements(PViewData::Line)){
+  if(data->getNumPoints() || data->getNumLines()){
     ((Fl_Menu_Item*)view_choice[13]->menu())[1].activate();
     ((Fl_Menu_Item*)view_choice[13]->menu())[2].activate();
   }
diff --git a/Geo/GEntity.h b/Geo/GEntity.h
index 541d6850de780c4c58aff2c4a95425ff971e9420..38774fbbcb89ec730118477fdabbf79df5eec80e 100644
--- a/Geo/GEntity.h
+++ b/Geo/GEntity.h
@@ -34,6 +34,7 @@ class GEdge;
 class GFace;
 class GRegion;
 class MVertex;
+class MElement;
 class VertexArray;
 
 // A geometric model entity.
@@ -232,6 +233,12 @@ class GEntity {
   // Resets the mesh attributes to default values
   virtual void resetMeshAttributes() { return; }
 
+  // Gets the number of mesh elements in the entity
+  virtual unsigned int getNumMeshElements() { throw; }
+
+  // Gets the element at the given index
+  virtual MElement *getMeshElement(unsigned int index) { throw; }
+
   // Get/set all mesh element visibility flag
   bool getAllElementsVisible(){ return _allElementsVisible ? true : false; }
   void setAllElementsVisible(bool val){ _allElementsVisible = val ? 1 : 0; }
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index bb08cc8fcd5d79f865362148e9de69c45470f6b4..b33f25bc73bba616361407962ae32fb8c2572304 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1,4 +1,4 @@
-// $Id: GModel.cpp,v 1.66 2008-02-22 21:09:00 geuzaine Exp $
+// $Id: GModel.cpp,v 1.67 2008-02-24 14:55:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -93,7 +93,8 @@ void GModel::destroy()
   if(normals) delete normals;
   normals = 0;
 
-  invalidateMeshVertexCache();
+  _vertexVectorCache.clear();
+  _vertexMapCache.clear();
 
   MVertex::resetGlobalNumber();
   MElement::resetGlobalNumber();
@@ -376,19 +377,13 @@ int GModel::getNumMeshVertices()
 
 int GModel::getNumMeshElements()
 {
-  int n = 0;
+  unsigned int n = 0;
   for(eiter it = firstEdge(); it != lastEdge(); ++it)
-    n += (*it)->lines.size();
-  for(fiter it = firstFace(); it != lastFace(); ++it){
-    n += (*it)->triangles.size();
-    n += (*it)->quadrangles.size();
-  }
-  for(riter it = firstRegion(); it != lastRegion(); ++it){
-    n += (*it)->tetrahedra.size();
-    n += (*it)->hexahedra.size();
-    n += (*it)->prisms.size();
-    n += (*it)->pyramids.size();
-  }
+    n += (*it)->getNumMeshElements();
+  for(fiter it = firstFace(); it != lastFace(); ++it)
+    n += (*it)->getNumMeshElements();
+  for(riter it = firstRegion(); it != lastRegion(); ++it)
+    n += (*it)->getNumMeshElements();
   return n;
 }
 
@@ -399,46 +394,36 @@ static void insertMeshVertices(std::vector<MVertex*> &vertices, T &container)
     container[vertices[i]->getNum()] = vertices[i];
 }
 
-void GModel::buildMeshVertexCache()
+MVertex *GModel::getMeshVertexByTag(int n)
 {
-  _vertexVectorCache.clear();
-  _vertexMapCache.clear();
-  bool dense = (getNumMeshVertices() == MVertex::getGlobalNumber());
-
-  if(dense){
-    _vertexVectorCache.resize(MVertex::getGlobalNumber());
-    for(viter it = firstVertex(); it != lastVertex(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
-    for(eiter it = firstEdge(); it != lastEdge(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
-    for(fiter it = firstFace(); it != lastFace(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
-    for(riter it = firstRegion(); it != lastRegion(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
-  }
-  else{
-    for(viter it = firstVertex(); it != lastVertex(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
-    for(eiter it = firstEdge(); it != lastEdge(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
-    for(fiter it = firstFace(); it != lastFace(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
-    for(riter it = firstRegion(); it != lastRegion(); ++it)
-      insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
+  if(_vertexVectorCache.empty() && _vertexMapCache.empty()){
+    Msg(DEBUG, "Rebuilding mesh vertex cache");
+    _vertexVectorCache.clear();
+    _vertexMapCache.clear();
+    bool dense = (getNumMeshVertices() == MVertex::getGlobalNumber());
+    if(dense){
+      _vertexVectorCache.resize(MVertex::getGlobalNumber());
+      for(viter it = firstVertex(); it != lastVertex(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
+      for(eiter it = firstEdge(); it != lastEdge(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
+      for(fiter it = firstFace(); it != lastFace(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
+      for(riter it = firstRegion(); it != lastRegion(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexVectorCache);
+    }
+    else{
+      for(viter it = firstVertex(); it != lastVertex(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
+      for(eiter it = firstEdge(); it != lastEdge(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
+      for(fiter it = firstFace(); it != lastFace(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
+      for(riter it = firstRegion(); it != lastRegion(); ++it)
+	insertMeshVertices((*it)->mesh_vertices, _vertexMapCache);
+    }
   }
-}
 
-void GModel::invalidateMeshVertexCache()
-{
-  _vertexVectorCache.clear();
-  _vertexMapCache.clear();
-}
-
-MVertex *GModel::getMeshVertexByTag(int n)
-{
-  if(n < 0) return 0;
-  if(_vertexVectorCache.empty() && _vertexMapCache.empty())
-    buildMeshVertexCache();
   if(n < (int)_vertexVectorCache.size())
     return _vertexVectorCache[n];
   else
@@ -516,7 +501,8 @@ void GModel::associateEntityWithMeshVertices()
 
 int GModel::renumberMeshVertices(bool saveAll)
 {
-  invalidateMeshVertexCache();
+  _vertexVectorCache.clear();
+  _vertexMapCache.clear();
 
   // tag all mesh vertices with -1 (negative vertices will not be
   // saved)
diff --git a/Geo/GModel.h b/Geo/GModel.h
index c18b419ef55b0c99a7ec88a520a99c860e7e8ebf..14f6c67422fdf4416f357dee41245632fda8df14 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -37,8 +37,8 @@ class smooth_normals;
 class GModel
 {
  private:
-  // A vertex cache to speed-up direct access by vertex number (used
-  // for post-processing I/O)
+  // Vertex cache to speed-up direct access by vertex number (used for
+  // post-processing I/O)
   std::vector<MVertex*> _vertexVectorCache;
   std::map<int, MVertex*> _vertexMapCache;
 
@@ -147,15 +147,11 @@ class GModel
   // Returns the mesh status for the entire model
   int getMeshStatus(bool countDiscrete=true);
 
-  // Returns the total number of vertices in the mesh
-  int getNumMeshVertices();
-
   // Returns the total number of elements in the mesh
   int getNumMeshElements();
 
-  // Invalidate/Rebuild the vertex cache
-  void invalidateMeshVertexCache();
-  void buildMeshVertexCache();
+  // Returns the total number of vertices in the mesh
+  int getNumMeshVertices();
 
   // Access a mesh vertex by tag, using the vertex cache
   MVertex *getMeshVertexByTag(int n);
diff --git a/Geo/MVertex.h b/Geo/MVertex.h
index 39ccda4aec5b0f4175bbae1462ea2d793652de4b..1ed03d5361b538478ff9cc90eee655c30c8a561b 100644
--- a/Geo/MVertex.h
+++ b/Geo/MVertex.h
@@ -42,11 +42,11 @@ class MVertex{
   char _visible, _order;
   double _x, _y, _z;
   GEntity *_ge;
-  void *_data;
+  int _dataIndex;
 
  public :
   MVertex(double x, double y, double z, GEntity *ge=0, int num=0) 
-    : _visible(true), _order(1), _x(x), _y(y), _z(z), _ge(ge), _data(0)
+    : _visible(true), _order(1), _x(x), _y(y), _z(z), _ge(ge), _dataIndex(-1)
   {
     if(num){
       _num = num;
@@ -87,9 +87,9 @@ class MVertex{
   inline int getNum() const { return _num; }
   inline void setNum(int num) { _num = num; }
 
-  // get/set the data
-  inline void *getData() { return _data; }
-  inline void setData(void *data) { _data = data; }
+  // get/set the data index
+  inline int getDataIndex() { return _dataIndex; }
+  inline void setDataIndex(int index) { _dataIndex = index; }
 
   // get/set ith parameter
   virtual bool getParameter(int i, double &par) const{ return false; }
diff --git a/Graphics/Graph2D.cpp b/Graphics/Graph2D.cpp
index 073c6304a3ce59451700804d964ceaf352feb6c3..98b06a49803b72cfcf16460d934939093850180f 100644
--- a/Graphics/Graph2D.cpp
+++ b/Graphics/Graph2D.cpp
@@ -1,4 +1,4 @@
-// $Id: Graph2D.cpp,v 1.73 2008-02-23 15:30:07 geuzaine Exp $
+// $Id: Graph2D.cpp,v 1.74 2008-02-24 14:55:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -77,8 +77,9 @@ static bool getGraphData(PView *p, std::vector<double> &x, double &xmin,
   }
   else if(opt->Type == PViewOptions::Plot2DTime){
     numy = 0;
-    for(int i = 0; i < data->getNumElements(); i++)
-      if(data->getDimension(i) < 2) numy++;
+    for(int ent = 0; ent < data->getNumEntities(); ent++)
+      for(int i = 0; i < data->getNumElements(ent); i++)
+	if(data->getDimension(ent, i) < 2) numy++;
   }
   
   if(!numy) return false;
@@ -89,36 +90,38 @@ static bool getGraphData(PView *p, std::vector<double> &x, double &xmin,
   SPoint3 p0(0., 0., 0.);
 
   numy = 0;
-  for(int i = 0; i < data->getNumElements(); i++){
-    int dim = data->getDimension(i);
-    if(dim < 2){
-      int numNodes = data->getNumNodes(i);
-      int numComp = data->getNumComponents(i);
-      for(int ts = space ? opt->TimeStep : 0; ts < opt->TimeStep + 1; ts++){
-	for(int j = 0; j < numNodes; j++){
-	  double val[9], xyz[3];
-	  data->getNode(i, j, xyz[0], xyz[1], xyz[2]);
-	  for(int k = 0; k < numComp; k++)
-	    data->getValue(i, j, k, ts, val[k]);
-	  double vy = ComputeScalarRep(numComp, val);
-	  if(space){
-	    // store offset to origin + distance to first point
-	    if(x.empty()){
-	      p0 = SPoint3(xyz[0], xyz[1], xyz[2]);
-	      x.push_back(ComputeScalarRep(3, xyz));
+  for(int ent = 0; ent < data->getNumEntities(); ent++){
+    for(int i = 0; i < data->getNumElements(ent); i++){
+      int dim = data->getDimension(ent, i);
+      if(dim < 2){
+	int numNodes = data->getNumNodes(ent, i);
+	int numComp = data->getNumComponents(ent, i);
+	for(int ts = space ? opt->TimeStep : 0; ts < opt->TimeStep + 1; ts++){
+	  for(int j = 0; j < numNodes; j++){
+	    double val[9], xyz[3];
+	    data->getNode(ent, i, j, xyz[0], xyz[1], xyz[2]);
+	    for(int k = 0; k < numComp; k++)
+	      data->getValue(ent, i, j, k, ts, val[k]);
+	    double vy = ComputeScalarRep(numComp, val);
+	    if(space){
+	      // store offset to origin + distance to first point
+	      if(x.empty()){
+		p0 = SPoint3(xyz[0], xyz[1], xyz[2]);
+		x.push_back(ComputeScalarRep(3, xyz));
+	      }
+	      else{
+		x.push_back(x[0] + p0.distance(SPoint3(xyz[0], xyz[1], xyz[2])));
+	      }
+	      y[0].push_back(vy);
 	    }
 	    else{
-	      x.push_back(x[0] + p0.distance(SPoint3(xyz[0], xyz[1], xyz[2])));
+	      if(!numy) x.push_back(data->getTime(ts));
+	      y[numy].push_back(vy);
 	    }
-	    y[0].push_back(vy);
-	  }
-	  else{
-	    if(!numy) x.push_back(data->getTime(ts));
-	    y[numy].push_back(vy);
 	  }
 	}
+	numy++;
       }
-      numy++;
     }
   }
 
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 4158065b1b58d0833848fddb84ad79750120d5b0..89c70a9b7ea2213ee9c2c60cdcbfaa7a5965a525 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.151 2008-02-23 15:30:07 geuzaine Exp $
+// $Id: Post.cpp,v 1.152 2008-02-24 14:55:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -122,7 +122,7 @@ void getLineNormal(PView *p, double x[2], double y[2], double z[2],
   }
 }
 
-bool getExternalValues(PView *p, int index, int iele, int numNodes,
+bool getExternalValues(PView *p, int index, int ient, int iele, int numNodes, 
 		       int numComp, double val[NMAX][9], 
 		       int &numComp2, double val2[NMAX][9])
 {
@@ -141,12 +141,12 @@ bool getExternalValues(PView *p, int index, int iele, int numNodes,
   PView *p2 = PView::list[index];
   PViewData *data2 = p2->getData();
 
-  if(opt->TimeStep < data2->getNumTimeSteps() && iele < data2->getNumElements()){
-    if(data2->getNumNodes(iele) == numNodes){
-      numComp2 = data2->getNumComponents(iele);
+  if(opt->TimeStep < data2->getNumTimeSteps() && iele < data2->getNumElements(ient)){
+    if(data2->getNumNodes(ient, iele) == numNodes){
+      numComp2 = data2->getNumComponents(ient, iele);
       for(int i = 0; i < numNodes; i++)
 	for(int j = 0; j < numComp2; j++)
-	  data2->getValue(iele, i, j, opt->TimeStep, val2[i][j]);
+	  data2->getValue(ient, iele, i, j, opt->TimeStep, val2[i][j]);
       if(opt->RangeType == PViewOptions::Custom){
 	opt->ExternalMin = opt->CustomMin;
 	opt->ExternalMax = opt->CustomMax;
@@ -193,7 +193,7 @@ void applyGeneralRaise(PView *p, int numNodes, int numComp,
   }
 }
 
-void changeCoordinates(PView *p, int iele, int numNodes, int numEdges, 
+void changeCoordinates(PView *p, int ient, int iele, int numNodes, int numEdges, 
 		       int numComp, double xyz[NMAX][3], double val[NMAX][9])
 {
   PViewOptions *opt = p->getOptions();
@@ -270,7 +270,7 @@ void changeCoordinates(PView *p, int iele, int numNodes, int numEdges,
   if(opt->UseGenRaise){
     int numComp2;
     double val2[NMAX][9];
-    getExternalValues(p, opt->ViewIndexForGenRaise, iele, numNodes, 
+    getExternalValues(p, opt->ViewIndexForGenRaise, ient, iele, numNodes, 
 		      numComp, val, numComp2, val2);
     applyGeneralRaise(p, numNodes, numComp2, val2, xyz);
   }
@@ -771,7 +771,7 @@ void addScalarElement(PView *p, int numEdges, double xyz[NMAX][3],
   }
 }
 
-void addVectorElement(PView *p, int iele, int numNodes, int numEdges, 
+void addVectorElement(PView *p, int ient, int iele, int numNodes, int numEdges, 
 		      double xyz[NMAX][3], double val[NMAX][9], bool pre)
 {
   PViewData *data = p->getData();
@@ -779,7 +779,7 @@ void addVectorElement(PView *p, int iele, int numNodes, int numEdges,
 
   int numComp2;
   double val2[NMAX][9];
-  getExternalValues(p, opt->ExternalViewIndex, iele, numNodes, 
+  getExternalValues(p, opt->ExternalViewIndex, ient, iele, numNodes, 
 		    3, val, numComp2, val2);
 
   if(opt->VectorType == PViewOptions::Displacement){
@@ -799,9 +799,9 @@ void addVectorElement(PView *p, int iele, int numNodes, int numEdges,
       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]);
+	  data->getNode(ient, iele, 0, xyz0[0], xyz0[1], xyz0[2]);
+	  data->getValue(ient, iele, 0, j, ts, dxyz[j][0]);
+	  data->getValue(ient, iele, 0, j, ts + 1, dxyz[j][1]);
 	}
 	unsigned int col[2];
 	double norm[2];
@@ -908,31 +908,33 @@ void addElementsInArrays(PView *p, bool preprocessNormalsOnly)
   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 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, numEdges, 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, preprocessNormalsOnly);
-
-    if(opt->IntervalsType != PViewOptions::Numeric){
-      if(numComp == 1 && opt->DrawScalars)
-	addScalarElement(p, numEdges, xyz, val, preprocessNormalsOnly);
-      else if(numComp == 3 && opt->DrawVectors)
-	addVectorElement(p, i, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
-      else if(numComp == 9 && opt->DrawTensors)
-	addTensorElement(p, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
+  for(int ent = 0; ent < data->getNumEntities(); ent++){
+    for(int i = 0; i < data->getNumElements(ent); i++){
+      int numEdges = data->getNumEdges(ent, i);
+      if(skipElement(p, numEdges)) continue;
+      int numComp = data->getNumComponents(ent, i);
+      int numNodes = data->getNumNodes(ent, i);
+      for(int j = 0; j < numNodes; j++){
+	data->getNode(ent, i, j, xyz[j][0], xyz[j][1], xyz[j][2]);
+	for(int k = 0; k < numComp; k++)
+	  data->getValue(ent, i, j, k, opt->TimeStep, val[j][k]);
+      }
+      changeCoordinates(p, ent, i, numNodes, numEdges, 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, preprocessNormalsOnly);
+      
+      if(opt->IntervalsType != PViewOptions::Numeric){
+	if(numComp == 1 && opt->DrawScalars)
+	  addScalarElement(p, numEdges, xyz, val, preprocessNormalsOnly);
+	else if(numComp == 3 && opt->DrawVectors)
+	  addVectorElement(p, ent, i, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
+	else if(numComp == 9 && opt->DrawTensors)
+	  addTensorElement(p, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
+      }
     }
   }
 }
@@ -1143,25 +1145,26 @@ void drawGlyphs(PView *p)
   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]);
+  for(int ent = 0; ent < data->getNumEntities(); ent++){
+    for(int i = 0; i < data->getNumElements(ent); i++){
+      int numEdges = data->getNumEdges(ent, i);
+      if(skipElement(p, numEdges)) continue;
+      int dim = data->getDimension(ent, i);
+      int numComp = data->getNumComponents(ent, i);
+      int numNodes = data->getNumNodes(ent, i);
+      for(int j = 0; j < numNodes; j++){
+	data->getNode(ent, i, j, xyz[j][0], xyz[j][1], xyz[j][2]);
+	for(int k = 0; k < numComp; k++)
+	  data->getValue(ent, i, j, k, opt->TimeStep, val[j][k]);
+      }
+      changeCoordinates(p, ent, i, numNodes, numEdges, numComp, xyz, val);
+      if(opt->IntervalsType == PViewOptions::Numeric)
+	drawNumberGlyphs(p, numNodes, numComp, xyz, val);
+      if(dim == 2 && opt->Normals)
+	drawNormalVectorGlyphs(p, numNodes, xyz, val);
+      else if(dim == 1 && opt->Tangents)
+	drawTangentVectorGlyphs(p, numNodes, xyz, val);  
     }
-    changeCoordinates(p, i, numNodes, numEdges, numComp, xyz, val);
-    if(opt->IntervalsType == PViewOptions::Numeric)
-      drawNumberGlyphs(p, numNodes, numComp, xyz, val);
-    if(dim == 2 && opt->Normals)
-      drawNormalVectorGlyphs(p, numNodes, xyz, val);
-    else if(dim == 1 && opt->Tangents)
-      drawTangentVectorGlyphs(p, numNodes, xyz, val);  
   }
 }
 
@@ -1173,25 +1176,25 @@ class initPView {
   int _estimateNumPoints(PView *p)
   {
     PViewData *data = p->getData();
-    int heuristic = data->getNumElements(PViewData::Point);
+    int heuristic = data->getNumPoints();
     return heuristic + 10000;
   }
   int _estimateNumLines(PView *p)
   {
     PViewData *data = p->getData();
-    int heuristic = data->getNumElements(PViewData::Line);
+    int heuristic = data->getNumLines();
     return heuristic + 10000;
   }
   int _estimateNumTriangles(PView *p)
   {
     PViewData *data = p->getData();
     PViewOptions *opt = p->getOptions();
-    int tris = data->getNumElements(PViewData::Triangle);
-    int quads = data->getNumElements(PViewData::Quadrangle);
-    int tets = data->getNumElements(PViewData::Tetrahedron);
-    int prisms = data->getNumElements(PViewData::Prism);
-    int pyrs = data->getNumElements(PViewData::Pyramid);
-    int hexas = data->getNumElements(PViewData::Hexahedron);
+    int tris = data->getNumTriangles();
+    int quads = data->getNumQuadrangles();
+    int tets = data->getNumTetrahedra();
+    int prisms = data->getNumPrisms();
+    int pyrs = data->getNumPyramids();
+    int hexas = data->getNumHexahedra();
     int heuristic = 0;
     if(opt->IntervalsType == PViewOptions::Iso)
       heuristic = (tets + prisms + pyrs + hexas) / 10;
diff --git a/Makefile b/Makefile
index 9ab61cccfdb1c62c667ca1ee061fa1a8920f9f1d..704f513fbda45f5d72ea2bb49228c6054f74aba8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.470 2008-02-23 20:56:36 geuzaine Exp $
+# $Id: Makefile,v 1.471 2008-02-24 14:55:36 geuzaine Exp $
 #
 # Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 #
@@ -23,7 +23,7 @@ include variables
 
 GMSH_MAJOR_VERSION = 2
 GMSH_MINOR_VERSION = 1
-GMSH_PATCH_VERSION = 0
+GMSH_PATCH_VERSION = 1
 GMSH_EXTRA_VERSION = 
 
 GMSH_VERSION = ${GMSH_MAJOR_VERSION}.${GMSH_MINOR_VERSION}.${GMSH_PATCH_VERSION}${GMSH_EXTRA_VERSION}
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 6bf77a53598ffa046eac7bc747afbbdc314af2ca..eda50762e47a2c31a765af6a9c8e697cfeba8af4 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.136 2008-02-20 09:20:45 geuzaine Exp $
+// $Id: Generator.cpp,v 1.137 2008-02-24 14:55:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -133,14 +133,14 @@ void GetStatistics(double stat[50], double quality[3][100])
   stat[26] = PView::list.size();
   for(unsigned int i = 0; i < PView::list.size(); i++) {
     PViewData *data = PView::list[i]->getData();
-    stat[27] += data->getNumElements(PViewData::Point);
-    stat[28] += data->getNumElements(PViewData::Line);
-    stat[29] += data->getNumElements(PViewData::Triangle);
-    stat[30] += data->getNumElements(PViewData::Quadrangle);
-    stat[31] += data->getNumElements(PViewData::Tetrahedron);
-    stat[32] += data->getNumElements(PViewData::Hexahedron);
-    stat[33] += data->getNumElements(PViewData::Prism);
-    stat[34] += data->getNumElements(PViewData::Pyramid);
+    stat[27] += data->getNumPoints();
+    stat[28] += data->getNumLines();
+    stat[29] += data->getNumTriangles();
+    stat[30] += data->getNumQuadrangles();
+    stat[31] += data->getNumTetrahedra();
+    stat[32] += data->getNumHexahedra();
+    stat[33] += data->getNumPrisms();
+    stat[34] += data->getNumPyramids();
     stat[35] += data->getNumStrings2D() + data->getNumStrings3D();
   }
 }
diff --git a/Post/PViewData.h b/Post/PViewData.h
index 29327cc0110a32d7b5305c22204918d85eacc72f..aff85a8ba659d04590d317f2686e7612222d3d86 100644
--- a/Post/PViewData.h
+++ b/Post/PViewData.h
@@ -38,16 +38,6 @@ class PViewData {
   // index of the view in the file
   int _fileIndex;
  public:
-  enum ElementType {
-    Point=1,
-    Line=2,
-    Triangle=3,
-    Quadrangle=4,
-    Tetrahedron=5,
-    Hexahedron=6,
-    Prism=7,
-    Pyramid=8
-  };
   PViewData();
   virtual ~PViewData(){}
   virtual bool getDirty(){ return _dirty; }
@@ -67,14 +57,38 @@ class PViewData {
   virtual int getNumScalars(){ return 0; }
   virtual int getNumVectors(){ return 0; }
   virtual int getNumTensors(){ return 0; }
-  virtual int getNumElements(int type=0) = 0;
-  virtual int getDimension(int ele) = 0;
-  virtual int getEntity(int ele){ return 0; }
-  virtual int getNumNodes(int ele) = 0;
-  virtual void getNode(int ele, int nod, double &x, double &y, double &z) = 0;
-  virtual int getNumComponents(int ele) = 0;
-  virtual void getValue(int ele, int node, int comp, int step, double &val) = 0;
-  virtual int getNumEdges(int ele) = 0;
+  virtual int getNumPoints(){ return 0; }
+  virtual int getNumLines(){ return 0; }
+  virtual int getNumTriangles(){ return 0; }
+  virtual int getNumQuadrangles(){ return 0; }
+  virtual int getNumTetrahedra(){ return 0; }
+  virtual int getNumHexahedra(){ return 0; }
+  virtual int getNumPrisms(){ return 0; }
+  virtual int getNumPyramids(){ return 0; }
+  // Returns the number of geometrical entities in the view
+  virtual int getNumEntities() = 0;
+  // Returns the number of elements in the ent-th entity, or the total
+  // number of elements if ent < 0
+  virtual int getNumElements(int ent=-1) = 0;
+  // Returns the geometrical dimension of the ele-th element in the
+  // ent-th entity
+  virtual int getDimension(int ent, int ele) = 0;
+  // Returns the number of nodes of the ele-th element in the ent-th
+  // entity
+  virtual int getNumNodes(int ent, int ele) = 0;
+  // Returns the coordinates of the nod-th node from the ele-th element
+  // in the ent-th entity
+  virtual void getNode(int ent, int ele, int nod, double &x, double &y, double &z) = 0;
+  // Returns the number of componts available for the ele-th element
+  // in the ent-th entity
+  virtual int getNumComponents(int ent, int ele) = 0;
+  // Returns the comp-th component (at the step-th time step)
+  // associated with the node-th node from the ele-th element in the
+  // ent-th entity
+  virtual void getValue(int ent, int ele, int node, int comp, int step, double &val) = 0;
+  // Returns the number of edges of the ele-th element in the ent-th
+  // entity
+  virtual int getNumEdges(int ent, int ele) = 0;
   virtual int getNumStrings2D(){ return 0; }
   virtual int getNumStrings3D(){ return 0; }
   virtual void getString2D(int i, int step, std::string &str, 
diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp
index 8ed9ad62589a834389549b1584cd528f792ef6e1..9e4952d66eb49e6b32c576adcec41d3722da846c 100644
--- a/Post/PViewDataGModel.cpp
+++ b/Post/PViewDataGModel.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewDataGModel.cpp,v 1.13 2008-02-22 21:09:02 geuzaine Exp $
+// $Id: PViewDataGModel.cpp,v 1.14 2008-02-24 14:55:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,63 @@
 #include "PViewDataGModel.h"
 #include "Message.h"
 
+double PViewDataGModel::getTime(int step)
+{
+  return 0;
+}
+
+double PViewDataGModel::getMin(int step)
+{
+  return 0;
+}
+
+double PViewDataGModel::getMax(int step)
+{
+  return 1;
+}
+
+int PViewDataGModel::getNumEntities()
+{
+  return 0;
+}
+
+int PViewDataGModel::getNumElements(int ent)
+{
+  if(ent < 0)
+    return _model->getNumMeshElements(); 
+  else
+    return 0; // TODO
+}
+
+int PViewDataGModel::getDimension(int ent, int ele)
+{
+  return 0; 
+}
+
+int PViewDataGModel::getNumNodes(int ent, int ele)
+{
+  return 0; 
+}
+
+void PViewDataGModel::getNode(int ent, int ele, int nod, double &x, double &y, double &z)
+{
+}
+
+int PViewDataGModel::getNumComponents(int ent, int ele)
+{
+  return 1; 
+}
+
+void PViewDataGModel::getValue(int ent, int ele, int node, int comp, int step, double &val)
+{
+
+}
+
+int PViewDataGModel::getNumEdges(int ent, int ele)
+{ 
+  return 0; 
+}
+
 bool PViewDataGModel::readMSH(FILE *fp)
 {
   Msg(INFO, "Filling PViewDataGModel...");
diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h
index e54cdd3ced6310bf445ab93eeec9a6da93b88f0e..ba3139d09c9db2d16a050fe5e942adae6c3a8138 100644
--- a/Post/PViewDataGModel.h
+++ b/Post/PViewDataGModel.h
@@ -34,16 +34,18 @@ class PViewDataGModel : public PViewData {
   PViewDataGModel(GModel *model) : _model(model) {}
   ~PViewDataGModel(){}
   int getNumTimeSteps(){ return 1; }
-  double getMin(int step=-1){ return 0.; }
-  double getMax(int step=-1){ return 1.; }
-  SBoundingBox3d getBoundingBox(){ return SBoundingBox3d(); }
-  int getNumElements(int type=0){ return _model->getNumMeshElements(); }
-  int getDimension(int ele){ return 0; }
-  int getNumNodes(int ele){ return 0; }
-  void getNode(int ele, int nod, double &x, double &y, double &z){}
-  int getNumComponents(int ele){ return 1; }
-  void getValue(int ele, int node, int comp, int step, double &val){}
-  int getNumEdges(int ele){ return 0; }
+  double getTime(int step);
+  double getMin(int step=-1);
+  double getMax(int step=-1);
+  SBoundingBox3d getBoundingBox(){ return _model->bounds(); }
+  int getNumEntities();
+  int getNumElements(int ent=-1);
+  int getDimension(int ent, int ele);
+  int getNumNodes(int ent, int ele);
+  void getNode(int ent, int ele, int nod, double &x, double &y, double &z);
+  int getNumComponents(int ent, int ele);
+  void getValue(int ent, int ele, int node, int comp, int step, double &val);
+  int getNumEdges(int ent, int ele);
 
   // I/O routines
   bool readMSH(FILE *fp);
diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp
index a9fb8f2db155566f0b5b4b2dfcbcc71e644492a9..126bd9fa0ee3117f96fd8f4773935eefb66e2699 100644
--- a/Post/PViewDataList.cpp
+++ b/Post/PViewDataList.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewDataList.cpp,v 1.12 2008-02-17 08:48:08 geuzaine Exp $
+// $Id: PViewDataList.cpp,v 1.13 2008-02-24 14:55:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -165,22 +165,8 @@ int PViewDataList::getNumTensors()
   return NbTP + NbTL + NbTT + NbTQ + NbTS + NbTH + NbTI + NbTY; 
 }
 
-int PViewDataList::getNumElements(int type)
+int PViewDataList::getNumElements(int ent)
 {
-  if(type){
-    switch(type){
-    case Point: return NbSP + NbVP + NbTP;
-    case Line: return NbSL + NbVL + NbTL;
-    case Triangle: return NbST + NbVT + NbTT;
-    case Quadrangle: return NbSQ + NbVQ + NbTQ;
-    case Tetrahedron: return NbSS + NbVS + NbTS;
-    case Hexahedron: return NbSH + NbVH + NbTH;
-    case Prism: return NbSI + NbVI + NbTI;
-    case Pyramid: return NbSY + NbVY + NbTY;
-    default: Msg(GERROR, "Unknown element type"); return 0;
-    }
-  }
-
   return getNumScalars() + getNumVectors() + getNumTensors();
 }
 
@@ -341,19 +327,19 @@ void PViewDataList::_setLast(int ele)
   }
 }
 
-int PViewDataList::getDimension(int ele)
+int PViewDataList::getDimension(int ent, int ele)
 {
   if(ele != _lastElement) _setLast(ele);
   return _lastDimension;
 }
 
-int PViewDataList::getNumNodes(int ele)
+int PViewDataList::getNumNodes(int ent, int ele)
 {
   if(ele != _lastElement) _setLast(ele);
   return _lastNumNodes;
 }
 
-void PViewDataList::getNode(int ele, int nod, double &x, double &y, double &z)
+void PViewDataList::getNode(int ent, int ele, int nod, double &x, double &y, double &z)
 {
   if(ele != _lastElement) _setLast(ele);
   x = _lastXYZ[nod];
@@ -361,13 +347,13 @@ void PViewDataList::getNode(int ele, int nod, double &x, double &y, double &z)
   z = _lastXYZ[2 * _lastNumNodes + nod];
 }
 
-int PViewDataList::getNumComponents(int ele)
+int PViewDataList::getNumComponents(int ent, int ele)
 {
   if(ele != _lastElement) _setLast(ele);
   return _lastNumComponents;
 }
 
-void PViewDataList::getValue(int ele, int nod, int comp, int step, double &val)
+void PViewDataList::getValue(int ent, int ele, int nod, int comp, int step, double &val)
 {
   if(ele != _lastElement) _setLast(ele);
   val = _lastVal[step * _lastNumNodes  * _lastNumComponents + 
@@ -375,7 +361,7 @@ void PViewDataList::getValue(int ele, int nod, int comp, int step, double &val)
 		 comp];
 }
 
-int PViewDataList::getNumEdges(int ele)
+int PViewDataList::getNumEdges(int ent, int ele)
 {
   if(ele != _lastElement) _setLast(ele);
   return _lastNumEdges;
diff --git a/Post/PViewDataList.h b/Post/PViewDataList.h
index 8675548a6d6b16f579334d626f22eeb890f4884c..e860d57503047a88ee08a44ca6cc7a2b7330ff51 100644
--- a/Post/PViewDataList.h
+++ b/Post/PViewDataList.h
@@ -84,13 +84,22 @@ class PViewDataList : public PViewData {
   int getNumScalars();
   int getNumVectors();
   int getNumTensors();
-  int getNumElements(int type=0);
-  int getDimension(int ele);
-  int getNumNodes(int ele);
-  void getNode(int ele, int nod, double &x, double &y, double &z);
-  int getNumComponents(int ele);
-  void getValue(int ele, int node, int comp, int step, double &val);
-  int getNumEdges(int ele);
+  int getNumPoints(){ return NbSP + NbVP + NbTP; }
+  int getNumLines(){ return NbSL + NbVL + NbTL; }
+  int getNumTriangles(){ return NbST + NbVT + NbTT; }
+  int getNumQuadrangles(){ return NbSQ + NbVQ + NbTQ; }
+  int getNumTetrahedra(){ return NbSS + NbVS + NbTS; }
+  int getNumHexahedra(){ return NbSH + NbVH + NbTH; }
+  int getNumPrisms(){ return NbSI + NbVI + NbTI; }
+  int getNumPyramids(){ return NbSY + NbVY + NbTY; }
+  int getNumEntities(){ return 1; }
+  int getNumElements(int ent=-1);
+  int getDimension(int ent, int ele);
+  int getNumNodes(int ent, int ele);
+  void getNode(int ent, int ele, int nod, double &x, double &y, double &z);
+  int getNumComponents(int ent, int ele);
+  void getValue(int ent, int ele, int node, int comp, int step, double &val);
+  int getNumEdges(int ent, int ele);
   int getNumStrings2D(){ return NbT2; }
   int getNumStrings3D(){ return NbT3; }
   void getString2D(int i, int step, std::string &str,