From b46188c9e947e36093ca343eebd686c460d36bf0 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 18 May 2010 16:02:20 +0000
Subject: [PATCH] better combineTime

---
 Post/PViewDataGModel.cpp | 33 ++++++--------------------------
 Post/PViewDataGModel.h   | 41 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp
index 3e39e6f044..882ba1df48 100644
--- a/Post/PViewDataGModel.cpp
+++ b/Post/PViewDataGModel.cpp
@@ -515,33 +515,12 @@ bool PViewDataGModel::combineTime(nameData &nd)
       for(unsigned int i = 0; i < it->second.size(); i++)
         _interpolation[it->first].push_back(new fullMatrix<double>(*it->second[i]));
 
-  for(unsigned int i = 0; i < data.size(); i++){
-    // FIXME: this is a horrible hack (we copy the data twice, and use
-    // a map!); we need to store the number of values per
-    // node/ele/... in stepData and provide a copy constructor, then
-    // just copy the stepData
-    for(unsigned int j = 0; j < data[i]->_steps.size(); j++){
-      if(data[i]->hasTimeStep(j)){
-        std::map<int, std::vector<double> > datamap;
-        if(getType() == NodeData){
-          stepData<double> *sd = data[i]->_steps[j];
-          for(unsigned int k = 0; k < sd->getNumData(); k++){
-            double *d = sd->getData(k);
-            if(d){
-              for(int l = 0; l < sd->getNumComponents(); l++){
-                datamap[k].push_back(d[l]);
-              }
-            }
-          }
-        }
-        else{
-          Msg::Error("Combine time not ready for non nodal model-based datasets");
-        }
-        addData(data[i]->getModel(j), datamap, i, data[i]->getTime(j), 0, -1);
-      }
-    }
-  }
-
+  // (deep) copy step data
+  for(unsigned int i = 0; i < data.size(); i++)
+    for(unsigned int j = 0; j < data[i]->_steps.size(); j++)
+      if(data[i]->hasTimeStep(j))
+        _steps.push_back(new stepData<double>(*data[i]->_steps[j]));
+  
   std::string tmp;
   if(nd.name == "__all__")
     tmp = "all";
diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h
index 6cf8ae10cc..8a85a462db 100644
--- a/Post/PViewDataGModel.h
+++ b/Post/PViewDataGModel.h
@@ -35,6 +35,11 @@ class stepData{
   // the data and 2) not to store any additional info in MVertex or
   // MElement)
   std::vector<real*> *_data;
+  // a vector containing the multiplying factor allowing to compute
+  // the number of values stored in _data for each index (number of
+  // values = getMult() * getNumComponents()). If _mult is empty, a
+  // default value of "1" is assumed
+  std::vector<int> _mult;
   // a vector, indexed by MSH element type, of Gauss point locations
   // in parametric space
   std::vector<std::vector<double> > _gaussPoints;
@@ -49,12 +54,44 @@ class stepData{
     _model->getEntities(_entities);
     _bbox = _model->bounds();
   }
+  stepData(stepData<real> &other) : _data(0)
+  {
+    _model = other._model;
+    _entities = other._entities;
+    _bbox = other._bbox;
+    _fileName = other._fileName;
+    _fileIndex = other._fileIndex;
+    _time = other._time;
+    _min = other._min;
+    _max = other._max;
+    _numComp = other._numComp;
+    if(other._data){
+      int n = other.getNumData();
+      _data = new std::vector<real*>(n, (real*)0);
+      for(int i = 0; i < n; i++){
+        real *d = other.getData(i);
+        if(d){
+          int m = other.getMult(i) * _numComp;
+          (*_data)[i] = new real[m];
+          for(int j = 0; j < m; j++) (*_data)[i][j] = d[j];
+        }
+      }
+    }
+    _mult = other._mult;
+    _gaussPoints = other._gaussPoints;
+    _partitions = other._partitions;
+  }
   ~stepData(){ destroyData(); }
   GModel *getModel(){ return _model; }
   SBoundingBox3d getBoundingBox(){ return _bbox; }
   int getNumEntities(){ return _entities.size(); }
   GEntity *getEntity(int ent){ return _entities[ent]; }
   int getNumComponents(){ return _numComp; }
+  int getMult(int index)
+  {
+    if(index < 0 || index >= _mult.size()) return 1;
+    return _mult[index];
+  }
   std::string getFileName(){ return _fileName; }
   void setFileName(std::string name){ _fileName = name; }
   int getFileIndex(){ return _fileIndex; }
@@ -83,6 +120,10 @@ class stepData{
         (*_data)[index] = new real[_numComp * mult];
         for(int i = 0; i < _numComp * mult; i++) (*_data)[index][i] = 0.;
       }
+      if(mult > 1){
+        if(index >= _mult.size()) _mult.resize(index + 100, 1); // optimize this
+        _mult[index] = mult;
+      }
     }
     else{
       if(index >= getNumData()) return 0;
-- 
GitLab