From 8ec98b9440cdb18c16f74e3ff30850e4b9c2a911 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Mon, 6 Jul 2009 05:44:25 +0000
Subject: [PATCH] ported Triangulate plugin to new API

---
 Plugin/Triangulate.cpp | 124 +++++++++++++++++++++++++----------------
 doc/VERSIONS.txt       |   4 +-
 2 files changed, 79 insertions(+), 49 deletions(-)

diff --git a/Plugin/Triangulate.cpp b/Plugin/Triangulate.cpp
index 1dacf34ec0..ff91d953c9 100644
--- a/Plugin/Triangulate.cpp
+++ b/Plugin/Triangulate.cpp
@@ -59,7 +59,20 @@ void GMSH_TriangulatePlugin::catchErrorMessage(char *errorMessage) const
   strcpy(errorMessage, "Triangulate failed...");
 }
 
-static void Project(MVertex *v, double mat[3][3])
+class PointData : public MVertex {
+ public:
+  std::vector<double> v;
+  PointData(double x, double y, double z, int numVal)
+    : MVertex(x, y, z)
+  { 
+    v.resize(3 + numVal); 
+    v[0] = x;
+    v[1] = y;
+    v[2] = z;
+  }
+};
+
+static void project(MVertex *v, double mat[3][3])
 {
   double X = v->x() * mat[0][0] + v->y() * mat[0][1] + v->z() * mat[0][2];
   double Y = v->x() * mat[1][0] + v->y() * mat[1][1] + v->z() * mat[1][2];
@@ -69,24 +82,47 @@ static void Project(MVertex *v, double mat[3][3])
   v->z() = Z;
 }
 
-static void Triangulate(int nbIn, std::vector<double> &inList, 
-                        int *nbOut, std::vector<double> &outList,
-                        int nbTimeStep, int nbComp)
+PView *GMSH_TriangulatePlugin::execute(PView *v)
 {
-  if(nbIn < 3) return;
+  int iView = (int)TriangulateOptions_Number[0].def;
 
-  // project points onto plane
+  PView *v1 = getView(iView, v);
+  if(!v1) return v;
+  PViewData *data1 = v1->getData();
+
+  if(data1->hasMultipleMeshes()){
+    Msg::Error("Triangulate plugin cannot be applied to multi-mesh views");
+    return v1;
+  }
+
+  PView *v2 = new PView();
+  PViewDataList *data2 = getDataList(v2);
+
+  // create list of points with associated data
   std::vector<MVertex*> points;
-  int nb = inList.size() / nbIn;
-  for(unsigned int i = 0; i < inList.size(); i += nb){
-    double *p = &inList[i];
-    points.push_back(new MVertex(p[0], p[1], p[2]));
+  int numSteps = 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;
+      if(data1->getNumNodes(0, ent, ele) != 1) continue;
+      int numComp = data1->getNumComponents(0, ent, ele);
+      double x, y, z;
+      data1->getNode(0, ent, ele, 0, x, y, z);
+      PointData *v = new PointData(x, y, z, numComp * numSteps);
+      for(int step = 0; step < numSteps; step++)
+        for(int comp = 0; comp < numComp; comp++)
+          data1->getValue(step, ent, ele, 0, comp, v->v[3 + numComp * step + comp]);
+      points.push_back(v);
+    }
   }
-  discreteFace *s = new discreteFace(GModel::current(), GModel::current()->getNumFaces() + 1);
+
+  // project points onto plane
+  discreteFace *s = new discreteFace
+    (GModel::current(), GModel::current()->getNumFaces() + 1);
   s->computeMeanPlane(points);
   double plan[3][3];
   s->getMeanPlaneData(plan);
-  for(unsigned int i = 0; i < points.size(); i++) Project(points[i], plan);
+  for(unsigned int i = 0; i < points.size(); i++) project(points[i], plan);
   delete s;
 
   // get lc
@@ -102,8 +138,7 @@ static void Triangulate(int nbIn, std::vector<double> &inList,
     doc.points[i].where.h = points[i]->x() + XX;
     doc.points[i].where.v = points[i]->y() + YY;
     doc.points[i].adjacent = NULL;
-    doc.points[i].data = (void*)&inList[i * nb]; 
-    delete points[i];
+    doc.points[i].data = (void*)points[i]; 
   }
 
   // triangulate
@@ -111,44 +146,39 @@ static void Triangulate(int nbIn, std::vector<double> &inList,
 
   // create output (using unperturbed data)
   for(int i = 0; i < doc.numTriangles; i++){
-    double *pa = (double*)doc.points[doc.triangles[i].a].data;
-    double *pb = (double*)doc.points[doc.triangles[i].b].data;
-    double *pc = (double*)doc.points[doc.triangles[i].c].data;
-    for(int j = 0; j < 3; j++) {
-      outList.push_back(pa[j]);
-      outList.push_back(pb[j]);
-      outList.push_back(pc[j]);
+    PointData *p[3];
+    p[0] = (PointData*)doc.points[doc.triangles[i].a].data;
+    p[1] = (PointData*)doc.points[doc.triangles[i].b].data;
+    p[2] = (PointData*)doc.points[doc.triangles[i].c].data;
+    int numComp = 0;
+    std::vector<double> *vec = 0;
+    if(p[0]->v.size() == 3 + 9 * numSteps && 
+       p[1]->v.size() == 3 + 9 * numSteps &&
+       p[2]->v.size() == 3 + 9 * numSteps){
+      numComp = 9; data2->NbTT++; vec = &data2->TT;
+    }
+    else if(p[0]->v.size() == 3 + 3 * numSteps && 
+            p[1]->v.size() == 3 + 3 * numSteps &&
+            p[2]->v.size() == 3 + 3 * numSteps){
+      numComp = 3; data2->NbVT++; vec = &data2->VT;
     }
-    for(int j = 0; j < nbTimeStep; j++) {
-      for(int k = 0; k < nbComp; k++) outList.push_back(pa[3 + j * nbComp + k]);
-      for(int k = 0; k < nbComp; k++) outList.push_back(pb[3 + j * nbComp + k]);
-      for(int k = 0; k < nbComp; k++) outList.push_back(pc[3 + j * nbComp + k]);
+    else{
+      numComp = 1; data2->NbST++; vec = &data2->ST;
     }
-    (*nbOut)++;
+    for(int nod = 0; nod < 3; nod++) vec->push_back(p[nod]->v[0]);
+    for(int nod = 0; nod < 3; nod++) vec->push_back(p[nod]->v[1]);
+    for(int nod = 0; nod < 3; nod++) vec->push_back(p[nod]->v[2]);
+    for(int step = 0; step < numSteps; step++)
+      for(int nod = 0; nod < 3; nod++)
+        for(int comp = 0; comp < numComp; comp++) 
+          vec->push_back(p[nod]->v[3 + numComp * step + comp]);
   }
-}
-
-PView *GMSH_TriangulatePlugin::execute(PView *v)
-{
-  int iView = (int)TriangulateOptions_Number[0].def;
-
-  PView *v1 = getView(iView, v);
-  if(!v1) return v;
-
-  PViewDataList *data1 = getDataList(v1);
-  if(!data1) return v;
-
-  PView *v2 = new PView();
-
-  PViewDataList *data2 = getDataList(v2);
-  if(!data2) return v;
 
-  int nts = data1->getNumTimeSteps();
-  Triangulate(data1->NbSP, data1->SP, &data2->NbST, data2->ST, nts, 1);
-  Triangulate(data1->NbVP, data1->VP, &data2->NbVT, data2->VT, nts, 3);
-  Triangulate(data1->NbTP, data1->TP, &data2->NbTT, data2->TT, nts, 9);
+  for(unsigned int i = 0; i < points.size(); i++)
+    delete points[i];
 
-  data2->Time = data1->Time;
+  for(int i = 0; i < data1->getNumTimeSteps(); i++)
+    data2->Time.push_back(data1->getTime(i));
   data2->setName(data1->getName() + "_Triangulate");
   data2->setFileName(data1->getName() + "_Triangulate.pos");
   data2->finalize();
diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt
index 0fccc3a736..ef0252073a 100644
--- a/doc/VERSIONS.txt
+++ b/doc/VERSIONS.txt
@@ -1,9 +1,9 @@
-$Id: VERSIONS.txt,v 1.46 2009-06-28 15:53:49 geuzaine Exp $
+$Id: VERSIONS.txt,v 1.47 2009-07-06 05:44:25 geuzaine Exp $
 
 2.4.0 (?): optionally copy transfinite mesh contraints during geometry
 transformations; bumped mesh version format to 2.1 (small change in
 the $PhysicalNames section, where the group dimension is now
-required);
+required); ported most plugins to the new post-processing API.
 
 2.3.1 (Mar 18, 2009): removed GSL dependency (Gmsh now simply uses
 Blas and Lapack); new per-window visibility; added support for
-- 
GitLab