diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp
index 86afd52ec3d0bf05e8925cdb39ae5ce73c8130e0..f75eb1c4712b8a264d15c9e5013993e7b222e04a 100644
--- a/Post/PViewDataGModel.cpp
+++ b/Post/PViewDataGModel.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewDataGModel.cpp,v 1.26 2008-03-12 21:28:53 geuzaine Exp $
+// $Id: PViewDataGModel.cpp,v 1.27 2008-03-13 22:02:08 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -41,8 +41,8 @@ PViewDataGModel::PViewDataGModel(GModel *model)
 
 PViewDataGModel::~PViewDataGModel()
 {
-  for(unsigned int i = 0; i < _nodeData.size(); i++)
-    if(_nodeData[i]) delete _nodeData[i];
+  for(unsigned int i = 0; i < _nodeData.size(); i++) delete _nodeData[i];
+  for(unsigned int i = 0; i < _elementData.size(); i++) delete _elementData[i];  
 }
 
 bool PViewDataGModel::finalize()
@@ -50,10 +50,8 @@ bool PViewDataGModel::finalize()
   _min = VAL_INF;
   _max = -VAL_INF;
   for(unsigned int i = 0; i < _nodeData.size(); i++){
-    if(_nodeData[i]){
-      _min = std::min(_min, _nodeData[i]->min);
-      _max = std::max(_max, _nodeData[i]->max);
-    }
+    _min = std::min(_min, _nodeData[i]->getMin());
+    _max = std::max(_max, _nodeData[i]->getMax());
   }
   setDirty(false);
   return true;
@@ -66,22 +64,22 @@ int PViewDataGModel::getNumTimeSteps()
 
 double PViewDataGModel::getTime(int step)
 {
-  if(step < (int)_nodeData.size() && _nodeData[step])
-    return _nodeData[step]->time;
+  if(step < (int)_nodeData.size())
+    return _nodeData[step]->getTime();
   return 0.;
 }
 
 double PViewDataGModel::getMin(int step)
 {
   if(step < 0) return _min;
-  if(step < (int)_nodeData.size() && _nodeData[step]) return _nodeData[step]->min;
+  if(step < (int)_nodeData.size()) return _nodeData[step]->getMin();
   return 0.;
 }
 
 double PViewDataGModel::getMax(int step)
 {
   if(step < 0) return _max;
-  if(step < (int)_nodeData.size() && _nodeData[step]) return _nodeData[step]->max;
+  if(step < (int)_nodeData.size()) return _nodeData[step]->getMax();
   return 0.;
 }
 
@@ -116,18 +114,16 @@ void PViewDataGModel::getNode(int ent, int ele, int nod, double &x, double &y, d
 
 int PViewDataGModel::getNumComponents(int ent, int ele, int step)
 {
-  MVertex *v = _entities[ent]->getMeshElement(ele)->getVertex(0);
-  int index = v->getDataIndex();
-  // no range check here: we assume this call is guarded by skipElement()
-  return _nodeData[step]->values[index].size();
+  // no range check here: we assume this is guarded by skipElement()
+  return _nodeData[step]->getNumComp();
 }
 
 void PViewDataGModel::getValue(int ent, int ele, int nod, int comp, int step, double &val)
 {
   MVertex *v = _entities[ent]->getMeshElement(ele)->getVertex(nod);
   int index = v->getDataIndex();
-  // no range check here: we assume this call is guarded by skipElement()
-  val = _nodeData[step]->values[index][comp];
+  // no range check here: we assume this is guarded by skipElement()
+  val = _nodeData[step]->getData(index)[comp];
 }
 
 int PViewDataGModel::getNumEdges(int ent, int ele)
@@ -142,21 +138,21 @@ bool PViewDataGModel::skipEntity(int ent)
 
 bool PViewDataGModel::skipElement(int ent, int ele, int step)
 {
-  if(step >= (int)_nodeData.size() || !_nodeData[step]) return true;
+  if(step >= (int)_nodeData.size() || !_nodeData[step]->getNumData()) return true;
   MElement *e = _entities[ent]->getMeshElement(ele);
   if(!e->getVisibility()) return true;
   for(int i = 0; i < e->getNumVertices(); i++){
     int index = e->getVertex(i)->getDataIndex();
-    if(index < 0 || index >= (int)_nodeData[step]->values.size()) return true;
-    if(_nodeData[step]->values[index].empty()) return true;
+    if(index < 0 || index >= (int)_nodeData[step]->getNumData()) return true;
+    if(!_nodeData[step]->getData(index)) return true;
   }
   return false;
 }
 
 bool PViewDataGModel::hasTimeStep(int step)
 {
-  if(step < (int)_nodeData.size() && _nodeData[step]) return true;
-  if(step < (int)_elementData.size() && _elementData[step]) return true;
+  if(step < (int)_nodeData.size() && _nodeData[step]->getNumData()) return true;
+  if(step < (int)_elementData.size() && _elementData[step]->getNumData()) return true;
   return false;
 }
 
diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h
index 4447e860c61354f312a4bbf5af013b860d2cd8d1..af4d2067719d676b26f6745b7b8106718aa8a302 100644
--- a/Post/PViewDataGModel.h
+++ b/Post/PViewDataGModel.h
@@ -27,17 +27,62 @@
 
 template<class real>
 class stepData{
- public:
+ private:
   // the file the data was read from
-  std::string fileName;
+  std::string _fileName;
   // the index in the file
-  int fileIndex;
-  // the value of the time step and associated min/max
-  double time, min, max;
-  // the vector of data, indexed by dataIndex
-  std::vector<std::vector<real> > values;
-  stepData() : fileIndex(-1), time(0.), min(VAL_INF), max(-VAL_INF){}
-  ~stepData() {}
+  int _fileIndex;
+  // the value of the time step and value min/max
+  double _time, _min, _max;
+  // the number of components in the data (stepData only contain a
+  // single field type!)
+  int _numComp;
+  // the values, indexed by dataIndex in MVertex or MElement
+  std::vector<real*> *_data;
+ public:
+  stepData(int numComp, std::string fileName="", int fileIndex=-1, double time=0.,
+	   double min=VAL_INF, double max=-VAL_INF) 
+    : _numComp(numComp), _fileName(fileName), _fileIndex(fileIndex), _time(time), 
+      _min(min), _max(max), _data(0)
+  {
+  }
+  ~stepData(){ destroyData(); }
+  int getNumComp(){ return _numComp; }
+  std::string getFileName(){ return _fileName; }
+  void setFileName(std::string name){ _fileName = name; }
+  int getFileIndex(){ return _fileIndex; }
+  void setFileIndex(int index){ _fileIndex = index; }
+  double getTime(){ return _time; }
+  void setTime(double time){ _time = time; }
+  double getMin(){ return _min; }
+  void setMin(double min ){ _min = min; }
+  double getMax(){ return _max; }
+  void setMax(double max){ _max = max; }
+  int getNumData()
+  {
+    if(!_data) return 0;
+    return _data->size();
+  }
+  void resizeData(int n)
+  {  
+    if(!_data) _data = new std::vector<real*>(n, (real*)0);
+    if(n < _data->size()) _data->resize(n, (real*)0);
+  }
+  real *getData(int index, bool allocIfNeeded=false)
+  {
+    if(!_data || index >= _data->size()) resizeData(index + 100); // optimize this
+    if(allocIfNeeded && !(*_data)[index]) (*_data)[index] = new real[_numComp];
+    return (*_data)[index];
+  }
+  void destroyData()
+  {
+    if(_data){
+      for(unsigned int i = 0; i < _data->size(); i++)
+	if((*_data)[i]) delete [] (*_data)[i];
+      delete _data;
+    }
+    _data = 0;
+  }
 };
 
 // data container using elements from a GModel
diff --git a/Post/PViewDataGModelIO.cpp b/Post/PViewDataGModelIO.cpp
index 7ad18cac200b1a0afc9eed4278dee4ebc9709c60..65e9d97b2c0896a34df3dfdc0a8886ebcde03349 100644
--- a/Post/PViewDataGModelIO.cpp
+++ b/Post/PViewDataGModelIO.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewDataGModelIO.cpp,v 1.7 2008-03-12 21:28:53 geuzaine Exp $
+// $Id: PViewDataGModelIO.cpp,v 1.8 2008-03-13 22:02:08 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -29,18 +29,6 @@
 #include "Numeric.h"
 #include "StringUtils.h"
 
-// Todo: slightly change this as follows:
-// - always populate the _dataXX vector with stepData (for all time steps)
-// - make the actual data allocatable (e.g. ptr to vector<vector>>)
-// - only alloc data if...
-//     - e.g. only alloc data for first time step
-// in "skipElement": if no data, read it from file (using fileName/Index info
-// in stepData) and free another if...
-//
-// usage should be as simple as: "gmsh *.pos". This would not load all
-// time steps by default: only the 1st one(s). Then load/cache the
-// others as needed on the fly.
-
 bool PViewDataGModel::readMSH(std::string fileName, int fileIndex, FILE *fp,
 			      bool binary, bool swap, int timeStep, double time, 
 			      int partition, int numComp, int numNodes)
@@ -48,16 +36,20 @@ bool PViewDataGModel::readMSH(std::string fileName, int fileIndex, FILE *fp,
   Msg(INFO, "Reading step %d (time %g) partition %d: %d nodes", 
       timeStep, time, partition, numNodes);
 
-  while(timeStep >= (int)_nodeData.size()) _nodeData.push_back(0);
-
-  if(!_nodeData[timeStep]) _nodeData[timeStep] = new stepData<double>();
+  while(timeStep >= (int)_nodeData.size())
+    _nodeData.push_back(new stepData<double>(numComp));
+  
+  _nodeData[timeStep]->setFileName(fileName);
+  _nodeData[timeStep]->setFileIndex(fileIndex);
+  _nodeData[timeStep]->setTime(time);
 
-  _nodeData[timeStep]->fileName = fileName;
-  _nodeData[timeStep]->fileIndex = fileIndex;
-  _nodeData[timeStep]->time = time;
-  _nodeData[timeStep]->values.resize(numNodes);
+  // if we already have maxSteps for this view, return
+  int numSteps = 0, maxSteps = 1000000000;
+  for(unsigned int i = 0; i < _nodeData.size(); i++)
+    numSteps += _nodeData[i]->getNumData() ? 1 : 0;
+  if(numSteps > maxSteps) return true;
 
-  std::vector<double> tmp(numComp, 0.);
+  _nodeData[timeStep]->resizeData(numNodes);
 
   for(int i = 0; i < numNodes; i++){
     int num;
@@ -79,21 +71,18 @@ bool PViewDataGModel::readMSH(std::string fileName, int fileIndex, FILE *fp,
       v->setDataIndex(max + 1);
     }
     int index = v->getDataIndex();
-    if(index >= (int)_nodeData[timeStep]->values.size())
-      _nodeData[timeStep]->values.resize(index + 100); // optimize this
+    double *d = _nodeData[timeStep]->getData(index, true);
     if(binary){
-      if((int)fread(&tmp[0], sizeof(double), numComp, fp) != numComp) return false;
-      if(swap) swapBytes((char*)&tmp[0], sizeof(double), numComp);
+      if((int)fread(d, sizeof(double), numComp, fp) != numComp) return false;
+      if(swap) swapBytes((char*)d, sizeof(double), numComp);
     }
     else{
       for(int j = 0; j < numComp; j++)
-	if(fscanf(fp, "%lf", &tmp[j]) != 1) return false;
+	if(fscanf(fp, "%lf", &d[j]) != 1) return false;
     }
-    for(int j = 0; j < numComp; j++)
-      _nodeData[timeStep]->values[index].push_back(tmp[j]);
-    double s = ComputeScalarRep(numComp, &_nodeData[timeStep]->values[index][0]);
-    _nodeData[timeStep]->min = std::min(_nodeData[timeStep]->min, s);
-    _nodeData[timeStep]->max = std::max(_nodeData[timeStep]->max, s);
+    double s = ComputeScalarRep(numComp, d);
+    _nodeData[timeStep]->setMin(std::min(_nodeData[timeStep]->getMin(), s));
+    _nodeData[timeStep]->setMax(std::max(_nodeData[timeStep]->getMax(), s));
   }
 
   _partitions.insert(partition);
@@ -125,29 +114,25 @@ bool PViewDataGModel::writeMSH(std::string name, bool binary)
     }
   }
 
-  for(unsigned int ts = 0; ts < _nodeData.size(); ts++){
-    if(!_nodeData[ts]) continue;
-    int numNodes = 0, numComp = 100;
-    for(unsigned int i = 0; i < _nodeData[ts]->values.size(); i++){
-      if(_nodeData[ts]->values[i].size()){
-	numComp = std::min(numComp, (int)_nodeData[ts]->values[i].size());
-	numNodes++;
-      }
-    }
-    if(numNodes && numComp){
+  for(unsigned int step = 0; step < _nodeData.size(); step++){
+    int numNodes = 0, numComp = _nodeData[step]->getNumComp();
+    for(unsigned int i = 0; i < _nodeData[step]->getNumData(); i++)
+      if(_nodeData[step]->getData(i)) numNodes++;
+    if(numNodes){
       fprintf(fp, "$NodeData\n");
       fprintf(fp, "\"%s\"\n", getName().c_str());
-      fprintf(fp, "%d %.16g 0 0 %d %d\n", ts, _nodeData[ts]->time, numComp, numNodes);
-      for(unsigned int i = 0; i < _nodeData[ts]->values.size(); i++){
-	if((int)_nodeData[ts]->values[i].size() >= numComp){
+      fprintf(fp, "%d %.16g 0 0 %d %d\n", step, _nodeData[step]->getTime(), 
+	      numComp, numNodes);
+      for(unsigned int i = 0; i < _nodeData[step]->getNumData(); i++){
+	if(_nodeData[step]->getData(i)){
 	  if(binary){
 	    fwrite(&tags[i], sizeof(int), 1, fp);
-	    fwrite(&_nodeData[ts]->values[i][0], sizeof(double), numComp, fp);
+	    fwrite(_nodeData[step]->getData(i), sizeof(double), numComp, fp);
 	  }
 	  else{
 	    fprintf(fp, "%d", tags[i]);
 	    for(int k = 0; k < numComp; k++)
-	      fprintf(fp, " %.16g", _nodeData[ts]->values[i][k]);
+	      fprintf(fp, " %.16g", _nodeData[step]->getData(i)[k]);
 	    fprintf(fp, "\n");
 	  }
 	}