From 594e59c02a013dbd7b688a889e7a3830a7aa9ad5 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Wed, 31 Mar 2010 15:42:31 +0000
Subject: [PATCH] refactor incrementList + add option to extract visible
 elements in Plugin(ExtractElements)

---
 Plugin/Curl.cpp            |  17 +----
 Plugin/Divergence.cpp      |  17 +----
 Plugin/Eigenvalues.cpp     |  21 +-----
 Plugin/Eigenvectors.cpp    |  21 +-----
 Plugin/ExtractElements.cpp | 141 +++++++++++++++----------------------
 Plugin/Gradient.cpp        |  33 +--------
 Plugin/HarmonicToTime.cpp  |  50 +------------
 Plugin/MathEval.cpp        |  68 +++---------------
 Post/PViewDataList.cpp     |  47 +++++++++++++
 Post/PViewDataList.h       |   1 +
 10 files changed, 123 insertions(+), 293 deletions(-)

diff --git a/Plugin/Curl.cpp b/Plugin/Curl.cpp
index fdb3f66d57..9959d725c1 100644
--- a/Plugin/Curl.cpp
+++ b/Plugin/Curl.cpp
@@ -37,21 +37,6 @@ StringXNumber *GMSH_CurlPlugin::getOption(int iopt)
   return &CurlOptions_Number[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data2, int type)
-{
-  switch(type){
-  case TYPE_PNT: data2->NbVP++; return &data2->VP;
-  case TYPE_LIN: data2->NbVL++; return &data2->VL;
-  case TYPE_TRI: data2->NbVT++; return &data2->VT;
-  case TYPE_QUA: data2->NbVQ++; return &data2->VQ;
-  case TYPE_TET: data2->NbVS++; return &data2->VS;
-  case TYPE_HEX: data2->NbVH++; return &data2->VH;
-  case TYPE_PRI: data2->NbVI++; return &data2->VI;
-  case TYPE_PYR: data2->NbVY++; return &data2->VY;
-  default: return 0;
-  }
-}
-
 PView *GMSH_CurlPlugin::execute(PView *v)
 {
   int iView = (int)CurlOptions_Number[0].def;
@@ -74,7 +59,7 @@ PView *GMSH_CurlPlugin::execute(PView *v)
       int numComp = data1->getNumComponents(0, ent, ele);
       if(numComp != 3) continue;
       int type = data1->getType(0, ent, ele);
-      std::vector<double> *out = incrementList(data2, type);
+      std::vector<double> *out = data2->incrementList(3, type);
       if(!out) continue;
       int numNodes = data1->getNumNodes(0, ent, ele);
       double x[8], y[8], z[8], val[8 * 3];
diff --git a/Plugin/Divergence.cpp b/Plugin/Divergence.cpp
index 0a12010247..d71fa716c5 100644
--- a/Plugin/Divergence.cpp
+++ b/Plugin/Divergence.cpp
@@ -37,21 +37,6 @@ StringXNumber *GMSH_DivergencePlugin::getOption(int iopt)
   return &DivergenceOptions_Number[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data2, int type)
-{
-  switch(type){
-  case TYPE_PNT: data2->NbSP++; return &data2->SP;
-  case TYPE_LIN: data2->NbSL++; return &data2->SL;
-  case TYPE_TRI: data2->NbST++; return &data2->ST;
-  case TYPE_QUA: data2->NbSQ++; return &data2->SQ;
-  case TYPE_TET: data2->NbSS++; return &data2->SS;
-  case TYPE_HEX: data2->NbSH++; return &data2->SH;
-  case TYPE_PRI: data2->NbSI++; return &data2->SI;
-  case TYPE_PYR: data2->NbSY++; return &data2->SY;
-  default: return 0;
-  }
-}
-
 PView *GMSH_DivergencePlugin::execute(PView *v)
 {
   int iView = (int)DivergenceOptions_Number[0].def;
@@ -74,7 +59,7 @@ PView *GMSH_DivergencePlugin::execute(PView *v)
       int numComp = data1->getNumComponents(0, ent, ele);
       if(numComp != 3) continue;
       int type = data1->getType(0, ent, ele);
-      std::vector<double> *out = incrementList(data2, type);
+      std::vector<double> *out = data2->incrementList(1, type);
       if(!out) continue;
       int numNodes = data1->getNumNodes(0, ent, ele);
       double x[8], y[8], z[8], val[8 * 3];
diff --git a/Plugin/Eigenvalues.cpp b/Plugin/Eigenvalues.cpp
index 338aaf20a2..933d91d440 100644
--- a/Plugin/Eigenvalues.cpp
+++ b/Plugin/Eigenvalues.cpp
@@ -37,21 +37,6 @@ StringXNumber *GMSH_EigenvaluesPlugin::getOption(int iopt)
   return &EigenvaluesOptions_Number[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data2, int type)
-{
-  switch(type){
-  case TYPE_PNT: data2->NbSP++; return &data2->SP;
-  case TYPE_LIN: data2->NbSL++; return &data2->SL;
-  case TYPE_TRI: data2->NbST++; return &data2->ST;
-  case TYPE_QUA: data2->NbSQ++; return &data2->SQ;
-  case TYPE_TET: data2->NbSS++; return &data2->SS;
-  case TYPE_HEX: data2->NbSH++; return &data2->SH;
-  case TYPE_PRI: data2->NbSI++; return &data2->SI;
-  case TYPE_PYR: data2->NbSY++; return &data2->SY;
-  default: return 0;
-  }
-}
-
 PView *GMSH_EigenvaluesPlugin::execute(PView *v)
 {
   int iView = (int)EigenvaluesOptions_Number[0].def;
@@ -79,9 +64,9 @@ PView *GMSH_EigenvaluesPlugin::execute(PView *v)
       int numComp = data1->getNumComponents(0, ent, ele);
       if(numComp != 9) continue;
       int type = data1->getType(0, ent, ele);
-      std::vector<double> *outmin = incrementList(dmin, type);
-      std::vector<double> *outmid = incrementList(dmid, type);
-      std::vector<double> *outmax = incrementList(dmax, type);
+      std::vector<double> *outmin = dmin->incrementList(1, type);
+      std::vector<double> *outmid = dmid->incrementList(1, type);
+      std::vector<double> *outmax = dmax->incrementList(1, type);
       if(!outmin || !outmid || !outmax) continue;
       int numNodes = data1->getNumNodes(0, ent, ele);
       double xyz[3][8];
diff --git a/Plugin/Eigenvectors.cpp b/Plugin/Eigenvectors.cpp
index 89024b48b3..0663228db3 100644
--- a/Plugin/Eigenvectors.cpp
+++ b/Plugin/Eigenvectors.cpp
@@ -44,21 +44,6 @@ StringXNumber *GMSH_EigenvectorsPlugin::getOption(int iopt)
   return &EigenvectorsOptions_Number[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data2, int type)
-{
-  switch(type){
-  case TYPE_PNT: data2->NbVP++; return &data2->VP;
-  case TYPE_LIN: data2->NbVL++; return &data2->VL;
-  case TYPE_TRI: data2->NbVT++; return &data2->VT;
-  case TYPE_QUA: data2->NbVQ++; return &data2->VQ;
-  case TYPE_TET: data2->NbVS++; return &data2->VS;
-  case TYPE_HEX: data2->NbVH++; return &data2->VH;
-  case TYPE_PRI: data2->NbVI++; return &data2->VI;
-  case TYPE_PYR: data2->NbVY++; return &data2->VY;
-  default: return 0;
-  }
-}
-
 static int nonzero(double v[3])
 {
   for(int i = 0; i < 3; i++)
@@ -97,9 +82,9 @@ PView *GMSH_EigenvectorsPlugin::execute(PView *v)
       int numComp = data1->getNumComponents(0, ent, ele);
       if(numComp != 9) continue;
       int type = data1->getType(0, ent, ele);
-      std::vector<double> *outmin = incrementList(dmin, type);
-      std::vector<double> *outmid = incrementList(dmid, type);
-      std::vector<double> *outmax = incrementList(dmax, type);
+      std::vector<double> *outmin = dmin->incrementList(3, type);
+      std::vector<double> *outmid = dmid->incrementList(3, type);
+      std::vector<double> *outmax = dmax->incrementList(3, type);
       if(!outmin || !outmid || !outmax) continue;
       int numNodes = data1->getNumNodes(0, ent, ele);
       double xyz[3][8];
diff --git a/Plugin/ExtractElements.cpp b/Plugin/ExtractElements.cpp
index 04f2e02ccc..3c16fe2fe2 100644
--- a/Plugin/ExtractElements.cpp
+++ b/Plugin/ExtractElements.cpp
@@ -6,12 +6,11 @@
 #include "ExtractElements.h"
 #include "Numeric.h"
 
-#define SQU(a)      ((a)*(a))
-
 StringXNumber ExtractElementsOptions_Number[] = {
   {GMSH_FULLRC, "MinVal", NULL, 0.},
-  {GMSH_FULLRC, "MaxVal", NULL, 1.},
+  {GMSH_FULLRC, "MaxVal", NULL, 0.},
   {GMSH_FULLRC, "TimeStep", NULL, 0.},
+  {GMSH_FULLRC, "Visible", NULL, 1.},
   {GMSH_FULLRC, "View", NULL, -1.}
 };
 
@@ -25,10 +24,12 @@ extern "C"
 
 std::string GMSH_ExtractElementsPlugin::getHelp() const
 {
-  return "Plugin(ExtractElements) extracts the elements "
-    "from the view `View' whose `TimeStep'-th values "
-    "(averaged by element) are comprised between "
-    "`MinVal' and `MaxVal'.\n\n"
+  return "Plugin(ExtractElements) extracts some elements "
+    "from the view `View'. If `MinVal' != `MaxVal', it extracts "
+    "the elements whose `TimeStep'-th values (averaged by element) "
+    "are comprised between `MinVal' and `MaxVal'. If `Visible' != 0, "
+    "it extracts visible elements. "
+    "\n\n"
     "If `View' < 0, the plugin is run on the current view.\n\n"
     "Plugin(ExtractElements) creates one new view.";
 }
@@ -43,101 +44,69 @@ StringXNumber *GMSH_ExtractElementsPlugin::getOption(int iopt)
   return &ExtractElementsOptions_Number[iopt];
 }
 
-static void extract(std::vector<double> &inList, int inNb, 
-                    std::vector<double> &outList, int *outNb, 
-                    int timeStep, int nbNod, int nbComp)
+PView *GMSH_ExtractElementsPlugin::execute(PView *v)
 {
-  if(!inNb)
-    return;
-
   double MinVal = ExtractElementsOptions_Number[0].def;
   double MaxVal = ExtractElementsOptions_Number[1].def;
-
-  int nb = inList.size() / inNb;
-  for(unsigned int i = 0; i < inList.size(); i += nb) {
-    double *vals = &inList[i + 3 * nbNod + timeStep * nbNod * nbComp];
-    double d = 0.;
-    for(int k = 0; k < nbNod; k++) {
-      double *v = &vals[nbComp * k];
-      switch(nbComp) {
-      case 1: // scalar
-        d += v[0];
-        break;
-      case 3 : // vector
-        d += sqrt(SQU(v[0]) + SQU(v[1]) + SQU(v[2]));
-        break;
-      case 9 : // tensor
-        d += ComputeVonMises(v);
-        break;
-      }
-    }
-    d /= (double)nbNod;
-    // We use '>=' and '<' so that we can do segmentation without
-    // worrying about roundoff errors
-    if(d >= MinVal && d < MaxVal){
-      for(int j = 0; j < nb; j++)
-        outList.push_back(inList[i + j]);
-      (*outNb)++;
-    }
-  }
-}
-
-PView *GMSH_ExtractElementsPlugin::execute(PView *v)
-{
   int step = (int)ExtractElementsOptions_Number[2].def;
-  int iView = (int)ExtractElementsOptions_Number[3].def;
+  int visible = (int)ExtractElementsOptions_Number[3].def;
+  int iView = (int)ExtractElementsOptions_Number[4].def;
 
   PView *v1 = getView(iView, v);
   if(!v1) return v;
 
-  PViewDataList *data1 = getDataList(v1);
-  if(!data1) return v;
+  PViewData *data1 = v1->getData();
 
-  PView *v2 = new PView();
-
-  PViewDataList *data2 = getDataList(v2);
-  if(!data2) return v;
+  bool checkMinMax = MinVal != MaxVal;
 
   if(step < 0 || step > data1->getNumTimeSteps() - 1){
     Msg::Error("Invalid time step (%d) in View[%d]: using first step instead",
-        step, v1->getIndex());
+               step, v1->getIndex());
     step = 0;
   }
 
-  // points
-  extract(data1->SP, data1->NbSP, data2->SP, &data2->NbSP, step, 1, 1);
-  extract(data1->VP, data1->NbVP, data2->VP, &data2->NbVP, step, 1, 3);
-  extract(data1->TP, data1->NbTP, data2->TP, &data2->NbTP, step, 1, 9);
-  // lines                                              
-  extract(data1->SL, data1->NbSL, data2->SL, &data2->NbSL, step, 2, 1);
-  extract(data1->VL, data1->NbVL, data2->VL, &data2->NbVL, step, 2, 3);
-  extract(data1->TL, data1->NbTL, data2->TL, &data2->NbTL, step, 2, 9);
-  // triangles                                          
-  extract(data1->ST, data1->NbST, data2->ST, &data2->NbST, step, 3, 1);
-  extract(data1->VT, data1->NbVT, data2->VT, &data2->NbVT, step, 3, 3);
-  extract(data1->TT, data1->NbTT, data2->TT, &data2->NbTT, step, 3, 9);
-  // quadrangles                                        
-  extract(data1->SQ, data1->NbSQ, data2->SQ, &data2->NbSQ, step, 4, 1);
-  extract(data1->VQ, data1->NbVQ, data2->VQ, &data2->NbVQ, step, 4, 3);
-  extract(data1->TQ, data1->NbTQ, data2->TQ, &data2->NbTQ, step, 4, 9);
-  // tets                                               
-  extract(data1->SS, data1->NbSS, data2->SS, &data2->NbSS, step, 4, 1);
-  extract(data1->VS, data1->NbVS, data2->VS, &data2->NbVS, step, 4, 3);
-  extract(data1->TS, data1->NbTS, data2->TS, &data2->NbTS, step, 4, 9);
-  // hexas                                              
-  extract(data1->SH, data1->NbSH, data2->SH, &data2->NbSH, step, 8, 1);
-  extract(data1->VH, data1->NbVH, data2->VH, &data2->NbVH, step, 8, 3);
-  extract(data1->TH, data1->NbTH, data2->TH, &data2->NbTH, step, 8, 9);
-  // prisms                                             
-  extract(data1->SI, data1->NbSI, data2->SI, &data2->NbSI, step, 6, 1);
-  extract(data1->VI, data1->NbVI, data2->VI, &data2->NbVI, step, 6, 3);
-  extract(data1->TI, data1->NbTI, data2->TI, &data2->NbTI, step, 6, 9);
-  // pyramids                                           
-  extract(data1->SY, data1->NbSY, data2->SY, &data2->NbSY, step, 5, 1);
-  extract(data1->VY, data1->NbVY, data2->VY, &data2->NbVY, step, 5, 3);
-  extract(data1->TY, data1->NbTY, data2->TY, &data2->NbTY, step, 5, 9);
+  PView *v2 = new PView();
+  PViewDataList *data2 = getDataList(v2);
+
+  for(int ent = 0; ent < data1->getNumEntities(step); ent++){
+    if(visible && data1->skipEntity(step, ent)) continue;
+    for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){
+      if(data1->skipElement(step, ent, ele, visible)) continue;
+      int numNodes = data1->getNumNodes(step, ent, ele);
+      if(checkMinMax){
+        double d = 0.;
+        for(int nod = 0; nod < numNodes; nod++){
+          double val;
+          data1->getScalarValue(step, ent, ele, nod, val);
+          d += val;
+        }
+        d /= (double)numNodes;
+        // use '>=' and '<' so that we can do segmentation without
+        // worrying about roundoff errors
+        if(d < MinVal || d >= MaxVal) continue;
+      }
+      int type = data1->getType(step, ent, ele);
+      int numComp = data1->getNumComponents(step, ent, ele);
+      std::vector<double> *out = data2->incrementList(numComp, type);
+      std::vector<double> x(numNodes), y(numNodes), z(numNodes);
+      std::vector<double> v(numNodes * numComp);
+      for(int nod = 0; nod < numNodes; nod++){
+        data1->getNode(step, ent, ele, nod, x[nod], y[nod], z[nod]);
+        for(int comp = 0; comp < numComp; comp++)
+          data1->getValue(step, ent, ele, nod, comp, v[numComp * nod + comp]);
+      }
+      for(int nod = 0; nod < numNodes; nod++) out->push_back(x[nod]);
+      for(int nod = 0; nod < numNodes; nod++) out->push_back(y[nod]);
+      for(int nod = 0; nod < numNodes; nod++) out->push_back(z[nod]);
+      for(int nod = 0; nod < numNodes; nod++) {
+        for(int comp = 0; comp < numComp; comp++) {
+          out->push_back(v[numComp * nod + comp]);
+        }
+      }
+    }
+  }
 
-  data2->Time = data1->Time;
+  data2->Time.push_back(data1->getTime(step));
   data2->setName(data1->getName() + "_ExtractElements");
   data2->setFileName(data1->getName() + "_ExtractElements.pos");
   data2->finalize();
diff --git a/Plugin/Gradient.cpp b/Plugin/Gradient.cpp
index 7bcce89729..3801292a78 100644
--- a/Plugin/Gradient.cpp
+++ b/Plugin/Gradient.cpp
@@ -37,37 +37,6 @@ StringXNumber *GMSH_GradientPlugin::getOption(int iopt)
   return &GradientOptions_Number[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data2, int numComp, int type)
-{
-  if(numComp == 1){
-    switch(type){
-    case TYPE_PNT: data2->NbVP++; return &data2->VP;
-    case TYPE_LIN: data2->NbVL++; return &data2->VL;
-    case TYPE_TRI: data2->NbVT++; return &data2->VT;
-    case TYPE_QUA: data2->NbVQ++; return &data2->VQ;
-    case TYPE_TET: data2->NbVS++; return &data2->VS;
-    case TYPE_HEX: data2->NbVH++; return &data2->VH;
-    case TYPE_PRI: data2->NbVI++; return &data2->VI;
-    case TYPE_PYR: data2->NbVY++; return &data2->VY;
-    default: return 0;
-    }
-  }
-  else if(numComp == 3){
-    switch(type){
-    case TYPE_PNT: data2->NbTP++; return &data2->TP;
-    case TYPE_LIN: data2->NbTL++; return &data2->TL;
-    case TYPE_TRI: data2->NbTT++; return &data2->TT;
-    case TYPE_QUA: data2->NbTQ++; return &data2->TQ;
-    case TYPE_TET: data2->NbTS++; return &data2->TS;
-    case TYPE_HEX: data2->NbTH++; return &data2->TH;
-    case TYPE_PRI: data2->NbTI++; return &data2->TI;
-    case TYPE_PYR: data2->NbTY++; return &data2->TY;
-    default: return 0;
-    }
-  }
-  return 0;
-}
-
 PView *GMSH_GradientPlugin::execute(PView *v)
 {
   int iView = (int)GradientOptions_Number[0].def;
@@ -90,7 +59,7 @@ PView *GMSH_GradientPlugin::execute(PView *v)
       int numComp = data1->getNumComponents(0, ent, ele);
       if(numComp != 1 && numComp != 3) continue;
       int type = data1->getType(0, ent, ele);
-      std::vector<double> *out = incrementList(data2, numComp, type);
+      std::vector<double> *out = data2->incrementList((numComp == 1) ? 3 : 9, type);
       if(!out) continue;
       int numNodes = data1->getNumNodes(0, ent, ele);
       double x[8], y[8], z[8], val[8 * 3];
diff --git a/Plugin/HarmonicToTime.cpp b/Plugin/HarmonicToTime.cpp
index 77756ae980..67b4b5f498 100644
--- a/Plugin/HarmonicToTime.cpp
+++ b/Plugin/HarmonicToTime.cpp
@@ -43,54 +43,6 @@ StringXNumber *GMSH_HarmonicToTimePlugin::getOption(int iopt)
   return &HarmonicToTimeOptions_Number[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data, int numComp, 
-                                          int type)
-{
-  switch(type){
-  case TYPE_PNT:
-    if     (numComp == 1){ data->NbSP++; return &data->SP; }
-    else if(numComp == 3){ data->NbVP++; return &data->VP; }
-    else if(numComp == 9){ data->NbTP++; return &data->TP; }
-    break;
-  case TYPE_LIN:
-    if     (numComp == 1){ data->NbSL++; return &data->SL; }
-    else if(numComp == 3){ data->NbVL++; return &data->VL; }
-    else if(numComp == 9){ data->NbTL++; return &data->TL; }
-    break;
-  case TYPE_TRI:
-    if     (numComp == 1){ data->NbST++; return &data->ST; }
-    else if(numComp == 3){ data->NbVT++; return &data->VT; }
-    else if(numComp == 9){ data->NbTT++; return &data->TT; }
-    break;
-  case TYPE_QUA:
-    if     (numComp == 1){ data->NbSQ++; return &data->SQ; }
-    else if(numComp == 3){ data->NbVQ++; return &data->VQ; }
-    else if(numComp == 9){ data->NbTQ++; return &data->TQ; }
-    break;
-  case TYPE_TET:
-    if     (numComp == 1){ data->NbSS++; return &data->SS; }
-    else if(numComp == 3){ data->NbVS++; return &data->VS; }
-    else if(numComp == 9){ data->NbTS++; return &data->TS; }
-    break;
-  case TYPE_HEX:
-    if     (numComp == 1){ data->NbSH++; return &data->SH; }
-    else if(numComp == 3){ data->NbVH++; return &data->VH; }
-    else if(numComp == 9){ data->NbTH++; return &data->TH; }
-    break;
-  case TYPE_PRI:
-    if     (numComp == 1){ data->NbSI++; return &data->SI; }
-    else if(numComp == 3){ data->NbVI++; return &data->VI; }
-    else if(numComp == 9){ data->NbTI++; return &data->TI; }
-    break;
-  case TYPE_PYR:
-    if     (numComp == 1){ data->NbSY++; return &data->SY; }
-    else if(numComp == 3){ data->NbVY++; return &data->VY; }
-    else if(numComp == 9){ data->NbTY++; return &data->TY; }
-    break;
-  }
-  return 0;
-}
-
 PView *GMSH_HarmonicToTimePlugin::execute(PView * v)
 {
   int rIndex = (int)HarmonicToTimeOptions_Number[0].def;
@@ -127,7 +79,7 @@ PView *GMSH_HarmonicToTimePlugin::execute(PView * v)
       int numNodes = data1->getNumNodes(0, ent, ele);
       int type = data1->getType(0, ent, ele);
       int numComp = data1->getNumComponents(0, ent, ele);
-      std::vector<double> *out = incrementList(data2, numComp, type);
+      std::vector<double> *out = data2->incrementList(numComp, type);
       std::vector<double> x(numNodes), y(numNodes), z(numNodes);
       std::vector<double> vr(numNodes * numComp), vi(numNodes * numComp);
       for(int nod = 0; nod < numNodes; nod++){
diff --git a/Plugin/MathEval.cpp b/Plugin/MathEval.cpp
index 7b2a5a6d21..44a7c8c28e 100644
--- a/Plugin/MathEval.cpp
+++ b/Plugin/MathEval.cpp
@@ -84,54 +84,6 @@ StringXString *GMSH_MathEvalPlugin::getOptionStr(int iopt)
   return &MathEvalOptions_String[iopt];
 }
 
-static std::vector<double> *incrementList(PViewDataList *data, int numComp, 
-                                          int type)
-{
-  switch(type){
-  case TYPE_PNT:
-    if     (numComp == 1){ data->NbSP++; return &data->SP; }
-    else if(numComp == 3){ data->NbVP++; return &data->VP; }
-    else if(numComp == 9){ data->NbTP++; return &data->TP; }
-    break;
-  case TYPE_LIN:
-    if     (numComp == 1){ data->NbSL++; return &data->SL; }
-    else if(numComp == 3){ data->NbVL++; return &data->VL; }
-    else if(numComp == 9){ data->NbTL++; return &data->TL; }
-    break;
-  case TYPE_TRI:
-    if     (numComp == 1){ data->NbST++; return &data->ST; }
-    else if(numComp == 3){ data->NbVT++; return &data->VT; }
-    else if(numComp == 9){ data->NbTT++; return &data->TT; }
-    break;
-  case TYPE_QUA:
-    if     (numComp == 1){ data->NbSQ++; return &data->SQ; }
-    else if(numComp == 3){ data->NbVQ++; return &data->VQ; }
-    else if(numComp == 9){ data->NbTQ++; return &data->TQ; }
-    break;
-  case TYPE_TET:
-    if     (numComp == 1){ data->NbSS++; return &data->SS; }
-    else if(numComp == 3){ data->NbVS++; return &data->VS; }
-    else if(numComp == 9){ data->NbTS++; return &data->TS; }
-    break;
-  case TYPE_HEX:
-    if     (numComp == 1){ data->NbSH++; return &data->SH; }
-    else if(numComp == 3){ data->NbVH++; return &data->VH; }
-    else if(numComp == 9){ data->NbTH++; return &data->TH; }
-    break;
-  case TYPE_PRI:
-    if     (numComp == 1){ data->NbSI++; return &data->SI; }
-    else if(numComp == 3){ data->NbVI++; return &data->VI; }
-    else if(numComp == 9){ data->NbTI++; return &data->TI; }
-    break;
-  case TYPE_PYR:
-    if     (numComp == 1){ data->NbSY++; return &data->SY; }
-    else if(numComp == 3){ data->NbVY++; return &data->VY; }
-    else if(numComp == 9){ data->NbTY++; return &data->TY; }
-    break;
-  }
-  return 0;
-}
-
 PView *GMSH_MathEvalPlugin::execute(PView *view)
 {
   int timeStep = (int)MathEvalOptions_Number[0].def;
@@ -210,24 +162,24 @@ PView *GMSH_MathEvalPlugin::execute(PView *view)
     timeStep = - data1->getNumTimeSteps();
   }
 
-  for(int ent = 0; ent < data1->getNumEntities(0); ent++){
-    for(int ele = 0; ele < data1->getNumElements(0, ent); ele++){
-      if(data1->skipElement(0, ent, ele)) continue;
-      int numNodes = data1->getNumNodes(0, ent, ele);
-      int type = data1->getType(0, ent, ele);
-      int numComp = data1->getNumComponents(0, ent, ele);
+  int timeBeg = (timeStep < 0) ? 0 : timeStep;
+  int timeEnd = (timeStep < 0) ? -timeStep : timeStep + 1;
+  for(int ent = 0; ent < data1->getNumEntities(timeBeg); ent++){
+    for(int ele = 0; ele < data1->getNumElements(timeBeg, ent); ele++){
+      if(data1->skipElement(timeBeg, ent, ele)) continue;
+      int numNodes = data1->getNumNodes(timeBeg, ent, ele);
+      int type = data1->getType(timeBeg, ent, ele);
+      int numComp = data1->getNumComponents(timeBeg, ent, ele);
       int numCompOther = !dataOther ? 9 : octree ? 9 : 
         dataOther->getNumComponents(otherTimeStep, ent, ele);
-      std::vector<double> *out = incrementList(data2, numComp2, type);
+      std::vector<double> *out = data2->incrementList(numComp2, type);
       std::vector<double> w(std::max(9, numCompOther), 0.);
       std::vector<double> x(numNodes), y(numNodes), z(numNodes);
       for(int nod = 0; nod < numNodes; nod++)
-        data1->getNode(0, ent, ele, nod, x[nod], y[nod], z[nod]);
+        data1->getNode(timeBeg, ent, ele, nod, x[nod], y[nod], z[nod]);
       for(int nod = 0; nod < numNodes; nod++) out->push_back(x[nod]); 
       for(int nod = 0; nod < numNodes; nod++) out->push_back(y[nod]); 
       for(int nod = 0; nod < numNodes; nod++) out->push_back(z[nod]); 
-      int timeBeg = (timeStep < 0) ? 0 : timeStep;
-      int timeEnd = (timeStep < 0) ? -timeStep : timeStep + 1;
       for(int step = timeBeg; step < timeEnd; step++){
         for(int nod = 0; nod < numNodes; nod++){
           std::vector<double> v(std::max(9, numComp), 0.);
diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp
index 4e410b7476..3913a546b9 100644
--- a/Post/PViewDataList.cpp
+++ b/Post/PViewDataList.cpp
@@ -792,3 +792,50 @@ void PViewDataList::setOrder2(int type)
   setInterpolationMatrices(type, fs->coefficients, fs->monomials,
                            fs->coefficients, fs->monomials);
 }
+
+std::vector<double> *PViewDataList::incrementList(int numComp, int type)
+{
+  switch(type){
+  case TYPE_PNT:
+    if     (numComp == 1){ NbSP++; return &SP; }
+    else if(numComp == 3){ NbVP++; return &VP; }
+    else if(numComp == 9){ NbTP++; return &TP; }
+    break;
+  case TYPE_LIN:
+    if     (numComp == 1){ NbSL++; return &SL; }
+    else if(numComp == 3){ NbVL++; return &VL; }
+    else if(numComp == 9){ NbTL++; return &TL; }
+    break;
+  case TYPE_TRI:
+    if     (numComp == 1){ NbST++; return &ST; }
+    else if(numComp == 3){ NbVT++; return &VT; }
+    else if(numComp == 9){ NbTT++; return &TT; }
+    break;
+  case TYPE_QUA:
+    if     (numComp == 1){ NbSQ++; return &SQ; }
+    else if(numComp == 3){ NbVQ++; return &VQ; }
+    else if(numComp == 9){ NbTQ++; return &TQ; }
+    break;
+  case TYPE_TET:
+    if     (numComp == 1){ NbSS++; return &SS; }
+    else if(numComp == 3){ NbVS++; return &VS; }
+    else if(numComp == 9){ NbTS++; return &TS; }
+    break;
+  case TYPE_HEX:
+    if     (numComp == 1){ NbSH++; return &SH; }
+    else if(numComp == 3){ NbVH++; return &VH; }
+    else if(numComp == 9){ NbTH++; return &TH; }
+    break;
+  case TYPE_PRI:
+    if     (numComp == 1){ NbSI++; return &SI; }
+    else if(numComp == 3){ NbVI++; return &VI; }
+    else if(numComp == 9){ NbTI++; return &TI; }
+    break;
+  case TYPE_PYR:
+    if     (numComp == 1){ NbSY++; return &SY; }
+    else if(numComp == 3){ NbVY++; return &VY; }
+    else if(numComp == 9){ NbTY++; return &TY; }
+    break;
+  }
+  return 0;
+}
diff --git a/Post/PViewDataList.h b/Post/PViewDataList.h
index 00b34deb03..9deec5dbe0 100644
--- a/Post/PViewDataList.h
+++ b/Post/PViewDataList.h
@@ -104,6 +104,7 @@ class PViewDataList : public PViewData {
   // specific to list-based data sets
   void getRawData(int type, std::vector<double> **l, int **ne, int *nc, int *nn);
   void setOrder2(int type);
+  std::vector<double> *incrementList(int numComp, int type);
 
   // I/O routines
   bool readPOS(FILE *fp, double version, bool binary);
-- 
GitLab