From 6269177e34fae9072dbc3aeeba0bda7332fbe7c1 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Fri, 5 Apr 2013 07:42:11 +0000 Subject: [PATCH] Plugin(Skin) can now also compute the boundary from a mesh --- Geo/discreteEdge.h | 7 +-- Plugin/Skin.cpp | 106 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 95 insertions(+), 18 deletions(-) diff --git a/Geo/discreteEdge.h b/Geo/discreteEdge.h index 7050b0feaf..24ec3ade89 100644 --- a/Geo/discreteEdge.h +++ b/Geo/discreteEdge.h @@ -23,13 +23,14 @@ class discreteEdge : public GEdge { virtual GPoint point(double p) const; virtual SVector3 firstDer(double par) const; virtual double curvature(double par) const; - virtual double curvatures(const double par, SVector3 *dirMax, SVector3 *dirMin, double *curvMax, double *curvMin) const; + virtual double curvatures(const double par, SVector3 *dirMax, SVector3 *dirMin, + double *curvMax, double *curvMin) const; virtual bool haveParametrization(){ return !_pars.empty(); } virtual Range<double> parBounds(int) const; bool getLocalParameter(const double &t, int &iEdge, double &tLoc) const; - void parametrize(std::map<GFace*, std::map<MVertex*, MVertex*, - std::less<MVertex*> > > &face2Verts, + void parametrize(std::map<GFace*, std::map<MVertex*, MVertex*, + std::less<MVertex*> > > &face2Verts, std::map<GRegion*, std::map<MVertex*, MVertex*, std::less<MVertex*> > > ®ion2Vert); void orderMLines(); diff --git a/Plugin/Skin.cpp b/Plugin/Skin.cpp index 8303a95a43..9306623590 100644 --- a/Plugin/Skin.cpp +++ b/Plugin/Skin.cpp @@ -7,9 +7,17 @@ #include "Skin.h" #include "Context.h" #include "GmshDefines.h" +#include "MTriangle.h" +#include "MQuadrangle.h" +#include "MLine.h" +#include "MFace.h" +#include "MEdge.h" +#include "discreteFace.h" +#include "discreteEdge.h" StringXNumber SkinOptions_Number[] = { {GMSH_FULLRC, "Visible", NULL, 1.}, + {GMSH_FULLRC, "FromMesh", NULL, 0.}, {GMSH_FULLRC, "View", NULL, -1.} }; @@ -23,11 +31,12 @@ extern "C" std::string GMSH_SkinPlugin::getHelp() const { - return "Plugin(Skin) extracts the boundary (skin) of " - "the view `View'. If `Visible' is set, the plugin only " - "extracts the skin of visible entities.\n\n" - "If `View' < 0, the plugin is run on the current view.\n\n" - "Plugin(Skin) creates one new view."; + return "Plugin(Skin) extracts the boundary (skin) of the current " + "mesh (if `FromMesh' = 1), or from the the view `View' (in which " + "case it creates a new view). If `View' < 0 and `FromMesh' = 0, " + "the plugin is run on the current view.\n" + "If `Visible' is set, the plugin only extracts the skin of visible " + "entities."; } int GMSH_SkinPlugin::getNbOptions() const @@ -74,12 +83,12 @@ class ElmData { else if(numComp == 3){ data->NbVL++; vec = &data->VL; break; } else if(numComp == 9){ data->NbTL++; vec = &data->TL; break; } break; - case 3: + 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: + 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; } @@ -113,17 +122,17 @@ double ElmDataLessThan::tolerance = 1.e-12; static int getBoundary(int type, const int (**boundary)[6][4]) { - static const int tri[6][4] = + static const int tri[6][4] = {{0,1,-1,-1}, {1,2,-1,-1}, {2,0,-1,-1}}; - static const int qua[6][4] = + 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] = + 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] = + 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] = + 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] = + 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(type){ case TYPE_TRI: *boundary = &tri; return 3; @@ -136,11 +145,76 @@ static int getBoundary(int type, const int (**boundary)[6][4]) } } +static void getBoundaryFromMesh(GModel *m, int visible) +{ + int dim = m->getDim(); + std::vector<GEntity*> entities; + m->getEntities(entities); + std::set<MFace, Less_Face> bndFaces; + std::set<MEdge, Less_Edge> bndEdges; + for(unsigned int i = 0; i < entities.size(); i++){ + GEntity *ge = entities[i]; + if(ge->dim() != dim) continue; + if(visible && !ge->getVisibility()) continue; + for(unsigned int j = 0; j < ge->getNumMeshElements(); j++){ + MElement *e = ge->getMeshElement(j); + if(dim == 2){ + for(int i = 0; i < e->getNumEdges(); i++){ + MEdge f = e->getEdge(i); + if(bndEdges.find(f) == bndEdges.end()) + bndEdges.insert(f); + else + bndEdges.erase(f); + } + } + else if(dim == 3){ + for(int i = 0; i < e->getNumFaces(); i++){ + MFace f = e->getFace(i); + if(bndFaces.find(f) == bndFaces.end()) + bndFaces.insert(f); + else + bndFaces.erase(f); + } + } + } + } + + if(dim == 2){ + discreteEdge *e = new discreteEdge(m, m->getMaxElementaryNumber(1) + 1, 0, 0); + m->add(e); + for(std::set<MEdge, Less_Edge>::iterator it = bndEdges.begin(); + it != bndEdges.end(); it++){ + e->lines.push_back(new MLine(it->getVertex(0), it->getVertex(1))); + } + } + else if(dim == 3){ + discreteFace *f = new discreteFace(m, m->getMaxElementaryNumber(2) + 1); + m->add(f); + for(std::set<MFace, Less_Face>::iterator it = bndFaces.begin(); + it != bndFaces.end(); it++){ + if(it->getNumVertices() == 3) + f->triangles.push_back(new MTriangle(it->getVertex(0), it->getVertex(1), + it->getVertex(2))); + else if(it->getNumVertices() == 4) + f->quadrangles.push_back(new MQuadrangle(it->getVertex(0), it->getVertex(1), + it->getVertex(2), it->getVertex(3))); + } + } +} + PView *GMSH_SkinPlugin::execute(PView *v) { int visible = (int)SkinOptions_Number[0].def; - int iView = (int)SkinOptions_Number[1].def; + int fromMesh = (int)SkinOptions_Number[1].def; + int iView = (int)SkinOptions_Number[2].def; + // compute boundary of current mesh + if(fromMesh){ + getBoundaryFromMesh(GModel::current(), visible); + return v; + } + + // compute boundary of post-processing data set PView *v1 = getView(iView, v); if(!v1) return v; PViewData *data1 = getPossiblyAdaptiveData(v1); @@ -150,6 +224,8 @@ PView *GMSH_SkinPlugin::execute(PView *v) return v; } + Msg::Info("Extracting boundary from View[%d]", v1->getIndex()); + PView *v2 = new PView(); PViewDataList *data2 = getDataList(v2); @@ -203,7 +279,7 @@ PView *GMSH_SkinPlugin::execute(PView *v) for(std::set<ElmData, ElmDataLessThan>::iterator it = skin.begin(); it != skin.end(); it++) it->addInView(data2); - + for(int i = 0; i < data1->getNumTimeSteps(); i++) if(data1->hasTimeStep(i)) data2->Time.push_back(data1->getTime(i)); -- GitLab