From e12bb2a589b8dc7965a58c2cc5c8969d5ebe1f2a Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Sun, 5 Jul 2009 06:40:27 +0000 Subject: [PATCH] ported Skin plugin to the new API --- Plugin/ExtractEdges.cpp | 5 +- Plugin/Skin.cpp | 318 ++++++++++++++++++---------------------- Plugin/Skin.h | 12 -- doc/TODO.txt | 8 +- 4 files changed, 149 insertions(+), 194 deletions(-) diff --git a/Plugin/ExtractEdges.cpp b/Plugin/ExtractEdges.cpp index fd0896b5ad..8a6749d4e8 100644 --- a/Plugin/ExtractEdges.cpp +++ b/Plugin/ExtractEdges.cpp @@ -64,13 +64,10 @@ PView *GMSH_ExtractEdgesPlugin::execute(PView *v) 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; //BDS_Mesh bds; //bds.import_view(v1, CTX::instance()->lc * 1.e-12); diff --git a/Plugin/Skin.cpp b/Plugin/Skin.cpp index a5a7478209..214505816e 100644 --- a/Plugin/Skin.cpp +++ b/Plugin/Skin.cpp @@ -3,17 +3,10 @@ // See the LICENSE.txt file for license information. Please report all // bugs and problems to <gmsh@geuz.org>. +#include <set> #include "Skin.h" -#include "MallocUtils.h" #include "Context.h" -std::vector<double> *GMSH_SkinPlugin::_list = 0; -Tree_T *GMSH_SkinPlugin::_skin = 0; -int *GMSH_SkinPlugin::_nbList = 0; -int GMSH_SkinPlugin::_nbNod = 0; -int GMSH_SkinPlugin::_nbComp = 0; -int GMSH_SkinPlugin::_nbTimeStep = 0; - StringXNumber SkinOptions_Number[] = { {GMSH_FULLRC, "iView", NULL, -1.} }; @@ -58,87 +51,99 @@ void GMSH_SkinPlugin::catchErrorMessage(char *errorMessage) const strcpy(errorMessage, "Skin failed..."); } -int GMSH_SkinPlugin::fcmpElm(const void *a, const void *b) -{ - Elm *e1 = (Elm *)a, *e2 = (Elm *)b; - double s1, s2, TOL = CTX::instance()->lc * 1.e-12; - int i; - - s1 = s2 = 0.0; - for(i = 0; i < _nbNod; i++) { - s1 += e1->coord[i]; - s2 += e2->coord[i]; - } - if(s1 - s2 > TOL) - return 1; - else if(s1 - s2 < -TOL) - return -1; - s1 = s2 = 0.0; - for(i = 0; i < _nbNod; i++) { - s1 += e1->coord[_nbNod + i]; - s2 += e2->coord[_nbNod + i]; +class ElmData { + public: + int numComp; + std::vector<double> x, y, z; + std::vector<double> v; + ElmData(int n) : numComp(n) {} + SPoint3 barycenter() const + { + SPoint3 p(0., 0., 0.); + int N = x.size(); + for(int i = 0; i < N; i++){ + p[0] += x[i]; + p[1] += y[i]; + p[2] += z[i]; + } + p[0] /= (double)N; + p[1] /= (double)N; + p[2] /= (double)N; + return p; } - if(s1 - s2 > TOL) - return 1; - else if(s1 - s2 < -TOL) - return -1; - s1 = s2 = 0.0; - for(i = 0; i < _nbNod; i++) { - s1 += e1->coord[2 * _nbNod + i]; - s2 += e2->coord[2 * _nbNod + i]; + void addInView(PViewDataList *data) const + { + std::vector<double> *vec = 0; + switch(x.size()){ + case 1: + if (numComp == 1){ data->NbSP++; vec = &data->SP; break; } + else if(numComp == 3){ data->NbVP++; vec = &data->VP; break; } + else if(numComp == 9){ data->NbTP++; vec = &data->TP; break; } + break; + case 2: + if (numComp == 1){ data->NbSL++; vec = &data->SL; break; } + else if(numComp == 3){ data->NbVL++; vec = &data->VL; break; } + else if(numComp == 9){ data->NbTL++; vec = &data->TL; break; } + break; + case 3: + if (numComp == 1){ data->NbST++; vec = &data->ST; break; } + else if(numComp == 3){ data->NbVT++; vec = &data->VT; break; } + else if(numComp == 9){ data->NbTT++; vec = &data->TT; break; } + break; + case 4: + if (numComp == 1){ data->NbSQ++; vec = &data->SQ; break; } + else if(numComp == 3){ data->NbVQ++; vec = &data->VQ; break; } + else if(numComp == 9){ data->NbTQ++; vec = &data->TQ; break; } + break; + } + if(!vec) return; + for(unsigned int i = 0; i < x.size(); i++) vec->push_back(x[i]); + for(unsigned int i = 0; i < y.size(); i++) vec->push_back(y[i]); + for(unsigned int i = 0; i < z.size(); i++) vec->push_back(z[i]); + for(unsigned int i = 0; i < v.size(); i++) vec->push_back(v[i]); } - if(s1 - s2 > TOL) - return 1; - else if(s1 - s2 < -TOL) - return -1; - - return 0; -} +}; -void GMSH_SkinPlugin::addInView(void *a, void *b) -{ - Elm *e = (Elm *)a; +class ElmDataLessThan{ + public: + static double tolerance; + bool operator()(const ElmData &e1, const ElmData &e2) const + { + SPoint3 p1 = e1.barycenter(); + SPoint3 p2 = e2.barycenter(); + if(p1.x() - p2.x() > tolerance) return true; + if(p1.x() - p2.x() < -tolerance) return false; + if(p1.y() - p2.y() > tolerance) return true; + if(p1.y() - p2.y() < -tolerance) return false; + if(p1.z() - p2.z() > tolerance) return true; + return false; + } +}; - for(int i = 0; i < 3 * _nbNod; i++) - _list->push_back(e->coord[i]); - for(int ts = 0; ts < _nbTimeStep; ts++) - for(int k = 0; k < _nbNod * _nbComp; k++) - _list->push_back(e->val[_nbNod * _nbComp * ts + k]); - Free(e->val); - (*_nbList)++; -} +double ElmDataLessThan::tolerance = 1.e-12; -void GMSH_SkinPlugin::skinList(std::vector<double> &inList, int inNbList, - int inNbNod, int inNbFac, int fxn[6][4]) +static int getBoundary(int numEdges, const int (**boundary)[6][4]) { - if(!inNbList) - return; - - int nb = inList.size() / inNbList; - for(unsigned int i = 0; i < inList.size(); i += nb) { - double *coord = &inList[i]; - double *val = &inList[i + 3 * inNbNod]; - for(int j = 0; j < inNbFac; j++) { - Elm e, *pe; - for(int k = 0; k < _nbNod; k++) { - e.coord[k] = coord[fxn[j][k]]; // x - e.coord[_nbNod + k] = coord[inNbNod + fxn[j][k]]; // y - e.coord[2 * _nbNod + k] = coord[2 * inNbNod + fxn[j][k]]; // z - } - if(!(pe = (Elm *)Tree_PQuery(_skin, &e))) { - e.val = (double *)Malloc(_nbNod * _nbComp * _nbTimeStep * sizeof(double)); - for(int k = 0; k < _nbNod; k++) - for(int ts = 0; ts < _nbTimeStep; ts++) - for(int n = 0; n < _nbComp; n++) - e.val[_nbNod * _nbComp * ts + _nbComp * k + n] = - val[inNbNod * _nbComp * ts + _nbComp * fxn[j][k] + n]; - Tree_Add(_skin, &e); - } - else { - Free(pe->val); - Tree_Suppress(_skin, pe); - } - } + static const int tri[6][4] = + {{0,1,-1,-1}, {1,2,-1,-1}, {2,0,-1,-1}}; + static const int qua[6][4] = + {{0,1,-1,-1}, {1,2,-1,-1}, {2,3,-1,-1}, {3,0,-1,-1}}; + static const int tet[6][4] = + {{0,1,3,-1}, {0,2,1,-1}, {0,3,2,-1}, {1,2,3,-1}}; + static const int hex[6][4] = + {{0,1,5,4}, {0,3,2,1}, {0,4,7,3}, {1,2,6,5}, {2,3,7,6}, {4,5,6,7}}; + static const int pri[6][4] = + {{0,1,4,3}, {0,3,5,2}, {1,2,5,4}, {0,2,1,-1}, {3,4,5,-1}}; + static const int pyr[6][4] = + {{0,3,2,1}, {0,1,4,-1}, {0,4,3,-1}, {1,2,4,-1}, {2,3,4,-1}}; + switch(numEdges){ + case 3: *boundary = &tri; return 3; + case 4: *boundary = &qua; return 4; + case 6: *boundary = &tet; return 4; + case 12: *boundary = &hex; return 6; + case 9: *boundary = &pri; return 5; + case 8: *boundary = &pyr; return 5; + default : return 0; } } @@ -148,106 +153,65 @@ PView *GMSH_SkinPlugin::execute(PView *v) PView *v1 = getView(iView, v); if(!v1) return v; + PViewData *data1 = v1->getData(); - PViewDataList *data1 = getDataList(v1); - if(!data1) return v; + if(data1->hasMultipleMeshes()){ + Msg::Error("Skin plugin cannot be applied to multi-mesh views"); + return v; + } PView *v2 = new PView(); - PViewDataList *data2 = getDataList(v2); - if(!data2) return v; - _nbTimeStep = data1->getNumTimeSteps(); - - int skinTri[6][4] = {{0,1,-1,-1}, {1,2,-1,-1}, {2,0,-1,-1}}; - int skinQua[6][4] = {{0,1,-1,-1}, {1,2,-1,-1}, {2,3,-1,-1}, {3,0,-1,-1}}; - int skinTet[6][4] = {{0,1,3,-1}, {0,2,1,-1}, {0,3,2,-1}, {1,2,3,-1}}; - int skinHex[6][4] = {{0,1,5,4}, {0,3,2,1}, {0,4,7,3}, - {1,2,6,5}, {2,3,7,6}, {4,5,6,7}}; - int skinPri1[6][4] = {{0,1,4,3}, {0,3,5,2}, {1,2,5,4}}; - int skinPri2[6][4] = {{0,2,1,-1}, {3,4,5,-1}}; - int skinPyr1[6][4] = {{0,3,2,1}}; - int skinPyr2[6][4] = {{0,1,4,-1}, {0,4,3,-1}, {1,2,4,-1}, {2,3,4,-1}}; - - // Generate lines - _nbNod = 2; - // scalar - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->SL; _nbList = &data2->NbSL; _nbComp = 1; - skinList(data1->ST, data1->NbST, 3, 3, skinTri); - skinList(data1->SQ, data1->NbSQ, 4, 4, skinQua); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - // vector - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->VL; _nbList = &data2->NbVL; _nbComp = 3; - skinList(data1->VT, data1->NbVT, 3, 3, skinTri); - skinList(data1->VQ, data1->NbVQ, 4, 4, skinQua); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - // tensor - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->TL; _nbList = &data2->NbTL; _nbComp = 9; - skinList(data1->TT, data1->NbTT, 3, 3, skinTri); - skinList(data1->TQ, data1->NbTQ, 4, 4, skinQua); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - - // Generate triangles - _nbNod = 3; - // scalar - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->ST; _nbList = &data2->NbST; _nbComp = 1; - skinList(data1->SS, data1->NbSS, 4, 4, skinTet); - skinList(data1->SI, data1->NbSI, 6, 2, skinPri2); - skinList(data1->SY, data1->NbSY, 5, 4, skinPyr2); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - // vector - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->VT; _nbList = &data2->NbVT; _nbComp = 3; - skinList(data1->VS, data1->NbVS, 4, 4, skinTet); - skinList(data1->VI, data1->NbVI, 6, 2, skinPri2); - skinList(data1->VY, data1->NbVY, 5, 4, skinPyr2); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - // tensor - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->TT; _nbList = &data2->NbTT; _nbComp = 9; - skinList(data1->TS, data1->NbTS, 4, 4, skinTet); - skinList(data1->TI, data1->NbTI, 6, 2, skinPri2); - skinList(data1->TY, data1->NbTY, 5, 4, skinPyr2); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - - // Generate quads - _nbNod = 4; - // scalar - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->SQ; _nbList = &data2->NbSQ; _nbComp = 1; - skinList(data1->SH, data1->NbSH, 8, 6, skinHex); - skinList(data1->SI, data1->NbSI, 6, 3, skinPri1); - skinList(data1->SY, data1->NbSY, 5, 1, skinPyr1); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - // vector - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->VQ; _nbList = &data2->NbVQ; _nbComp = 3; - skinList(data1->VH, data1->NbVH, 8, 6, skinHex); - skinList(data1->VI, data1->NbVI, 6, 3, skinPri1); - skinList(data1->VY, data1->NbVY, 5, 1, skinPyr1); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); - // tensor - _skin = Tree_Create(sizeof(Elm), fcmpElm); - _list = &data2->TQ; _nbList = &data2->NbTQ; _nbComp = 9; - skinList(data1->TH, data1->NbTH, 8, 6, skinHex); - skinList(data1->TI, data1->NbTI, 6, 3, skinPri1); - skinList(data1->TY, data1->NbTY, 5, 1, skinPyr1); - Tree_Action(_skin, addInView); - Tree_Delete(_skin); + std::set<ElmData, ElmDataLessThan> skin; + ElmDataLessThan::tolerance = CTX::instance()->lc * 1.e-12; + + 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 numComp = data1->getNumComponents(0, ent, ele); + int numEdges = data1->getNumEdges(0, ent, ele); + const int (*boundary)[6][4]; + int numBoundary = getBoundary(numEdges, &boundary); + if(!numBoundary) continue; + for(int i = 0; i < numBoundary; i++){ + ElmData e(numComp); + for(int j = 0; j < 4; j++){ + int nod = (*boundary)[i][j]; + if(nod < 0) continue; + double x, y, z; + data1->getNode(0, ent, ele, nod, x, y, z); + e.x.push_back(x); + e.y.push_back(y); + e.z.push_back(z); + } + std::set<ElmData, ElmDataLessThan>::iterator it = skin.find(e); + if(it == skin.end()){ + for(int step = 0; step < data1->getNumTimeSteps(); step++){ + for(int j = 0; j < 4; j++){ + int nod = (*boundary)[i][j]; + if(nod < 0) continue; + double v; + for(int comp = 0; comp < numComp; comp++){ + data1->getValue(step, ent, ele, nod, comp, v); + e.v.push_back(v); + } + } + } + skin.insert(e); + } + else + skin.erase(it); + } + } + } - data2->Time = data1->Time; + for(std::set<ElmData, ElmDataLessThan>::iterator it = skin.begin(); + it != skin.end(); it++) + it->addInView(data2); + + for(int i = 0; i < data1->getNumTimeSteps(); i++) + data2->Time.push_back(data1->getTime(i)); data2->setName(data1->getName() + "_Skin"); data2->setFileName(data1->getName() + "_Skin.pos"); data2->finalize(); diff --git a/Plugin/Skin.h b/Plugin/Skin.h index db9c35b836..f7082cf5ff 100644 --- a/Plugin/Skin.h +++ b/Plugin/Skin.h @@ -7,7 +7,6 @@ #define _SKIN_H_ #include "Plugin.h" -#include "TreeUtils.h" extern "C" { @@ -16,17 +15,6 @@ extern "C" class GMSH_SkinPlugin : public GMSH_PostPlugin { - typedef struct{ - double coord[12]; - double *val; - } Elm; - static std::vector<double> *_list; - static Tree_T *_skin; - static int *_nbList, _nbNod, _nbComp, _nbTimeStep; - static int fcmpElm(const void *a, const void *b); - static void addInView(void *a, void *b); - void skinList(std::vector<double> &inList, int inNbList, - int inNbNod, int inNbFac, int fxn[6][4]); public: GMSH_SkinPlugin(){} void getName(char *name) const; diff --git a/doc/TODO.txt b/doc/TODO.txt index f4d0cca910..294d9f3556 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -1,4 +1,10 @@ -$Id: TODO.txt,v 1.29 2009-06-28 16:06:04 geuzaine Exp $ +$Id: TODO.txt,v 1.30 2009-07-05 06:40:27 geuzaine Exp $ + +******************************************************************** + +replace last uses of shapeFunctions.h with MElement.h (might want to +create a pool of MVertices to speed up temp element creation in +plugins) ******************************************************************** -- GitLab