Skip to content
Snippets Groups Projects
Commit 5f4c855e authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

Merge branch 'master' of https://gitlab.onelab.info/gmsh/gmsh

parents 1fb6573b 0a62cc77
No related branches found
No related tags found
No related merge requests found
...@@ -4,17 +4,26 @@ ...@@ -4,17 +4,26 @@
// issues on https://gitlab.onelab.info/gmsh/gmsh/issues. // issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
// Contributed by Nicolas Marsic. // Contributed by Nicolas Marsic.
#include <sstream>
#include <algorithm>
#include "SpanningTree.h" #include "SpanningTree.h"
#include "GModel.h" #include "GModel.h"
#include "MLine.h" #include "MLine.h"
#include "OS.h" #include "OS.h"
using namespace std;
StringXNumber SpanningTreeOptions_Number[] = { StringXNumber SpanningTreeOptions_Number[] = {
{GMSH_FULLRC, "PhysicalGroup", NULL, -1},
{GMSH_FULLRC, "StartingOn", NULL, -1},
{GMSH_FULLRC, "OutputPhysical", NULL, -1}, {GMSH_FULLRC, "OutputPhysical", NULL, -1},
}; };
StringXString SpanningTreeOptions_String[] = {
{GMSH_FULLRC, "PhysicalVolumes", NULL, ""},
{GMSH_FULLRC, "PhysicalSurfaces", NULL, ""},
{GMSH_FULLRC, "PhysicalCurves", NULL, ""},
};
extern "C" { extern "C" {
GMSH_Plugin *GMSH_RegisterSpanningTreePlugin(void) GMSH_Plugin *GMSH_RegisterSpanningTreePlugin(void)
{ {
...@@ -24,37 +33,42 @@ GMSH_Plugin *GMSH_RegisterSpanningTreePlugin(void) ...@@ -24,37 +33,42 @@ GMSH_Plugin *GMSH_RegisterSpanningTreePlugin(void)
GMSH_SpanningTreePlugin::GMSH_SpanningTreePlugin(void) {} GMSH_SpanningTreePlugin::GMSH_SpanningTreePlugin(void) {}
std::string GMSH_SpanningTreePlugin::getName(void) const string GMSH_SpanningTreePlugin::getName(void) const
{ {
return "SpanningTree"; return "SpanningTree";
} }
std::string GMSH_SpanningTreePlugin::getShortHelp(void) const string GMSH_SpanningTreePlugin::getShortHelp(void) const
{ {
return "Builds a tree spanning every vertex of a mesh"; return "Builds a tree spanning every vertex of a mesh";
} }
std::string GMSH_SpanningTreePlugin::getHelp(void) const string GMSH_SpanningTreePlugin::getHelp(void) const
{ {
return "Plugin(SpanningTree) builds a tree spanning every vertex of a mesh.\n" return "Plugin(SpanningTree) builds a tree spanning every vertex of a mesh "
"Optionally, this tree can be built by starting on a specific part.\n" "and stores it directly in the model.\n"
"The generated tree is stored directly in the model.\n" "The tree is constructed by starting first on the curves, "
"then on the surfaces and finally on the volumes.\n"
"\n" "\n"
"Parameters\n" "Parameters\n"
"- PhysicalGroup: physical group upon which the tree must be built " "- PhysicalVolumes: list of the physical volumes "
"(-1 means the whole mesh).\n" "upon which the tree must be built.\n"
"- StartingOn: physical group used to start the tree construction " "- PhysicalSurfaces: list of the physical surfaces "
"(-1 deactivates this feature).\n" "upon which the tree must be built.\n"
"- PhysicalCurves: list of the physical curves "
"upon which the tree must be built.\n"
"- OutputPhysical: physical tag of the generated tree " "- OutputPhysical: physical tag of the generated tree "
"(-1 will select a new tag automatically).\n" "(-1 will select a new tag automatically).\n"
"\n" "\n"
"Note - Lists must be comma separated integers "
"and spaces are ignored.\n"
"Remark - This plugin does not overwrite a physical group." "Remark - This plugin does not overwrite a physical group."
"Therefore, if an existing physical tag is used in OutputPhysical, " "Therefore, if an existing physical tag is used in OutputPhysical, "
"the edges of the tree will be /added/ to the specified group.\n" "the edges of the tree will be /added/ to the specified group.\n"
"Limitation - Unknown behaviour with curved meshes."; "Limitation - Unknown behaviour with curved meshes.";
} }
std::string GMSH_SpanningTreePlugin::getAuthor(void) const string GMSH_SpanningTreePlugin::getAuthor(void) const
{ {
return "N. Marsic"; return "N. Marsic";
} }
...@@ -69,45 +83,66 @@ StringXNumber *GMSH_SpanningTreePlugin::getOption(int iopt) ...@@ -69,45 +83,66 @@ StringXNumber *GMSH_SpanningTreePlugin::getOption(int iopt)
return &SpanningTreeOptions_Number[iopt]; return &SpanningTreeOptions_Number[iopt];
} }
int GMSH_SpanningTreePlugin::getNbOptionsStr() const
{
return sizeof(SpanningTreeOptions_String) / sizeof(StringXString);
}
StringXString *GMSH_SpanningTreePlugin::getOptionStr(int iopt)
{
return &SpanningTreeOptions_String[iopt];
}
void GMSH_SpanningTreePlugin::run(void) void GMSH_SpanningTreePlugin::run(void)
{ {
// Get data // Get data
double time = Cpu(); double time = Cpu();
int physical = (int)SpanningTreeOptions_Number[0].def; int output = (int)SpanningTreeOptions_Number[0].def;
int startOn = (int)SpanningTreeOptions_Number[1].def; string volume = SpanningTreeOptions_String[0].def;
int output = (int)SpanningTreeOptions_Number[2].def; string surface = SpanningTreeOptions_String[1].def;
string curve = SpanningTreeOptions_String[2].def;
// Parse physical tags
vector<list<int> > physical(3);
curve = parse(curve, physical[0]);
surface = parse(surface, physical[1]);
volume = parse(volume, physical[2]);
// Dimensions
int dim[3] = {1, 2, 3};
// Get model // Get model
GModel *model = GModel::current(); GModel *model = GModel::current();
// Get all elements in physical // Get all elements in physicals for each dimension
ElementSet element; vector<ElementSet> element(3);
getAllMElement(*model, physical, element); for(int i = 0; i < 3; i++)
for(list<int>::iterator j = physical[i].begin(); j!= physical[i].end(); j++)
// Get all elements in startOn (if defined) getAllMElement(*model, *j, dim[i], element[i]);
ElementSet elementStartOn;
if(startOn >= 0) getAllMElement(*model, startOn, elementStartOn);
// Check if we have something // Check if we have something
if(element.empty() && elementStartOn.empty()) { if(element[0].empty() && element[1].empty() && element[2].empty()) {
Msg::Warning("No elements found in physcial %d: abording!", physical); Msg::Warning("No elements found in the given physcials: abording!");
return; return;
} }
// Get all edges from elements // Display physicals (as [poorly] parsed) //
EdgeSet edge; Msg::Info("--> PhysicalVolumes: %s", volume.c_str());
getAllMEdge(element, edge); Msg::Info("--> PhysicalSurfaces: %s", surface.c_str());
Msg::Info("--> PhysicalCurves: %s", curve.c_str());
Msg::Info("--> OutputPhysical: %d", output);
// Get all edges from startOn (if defined) // Get all edges from elements for each dimension
EdgeSet edgeStartOn; vector<EdgeSet> edge(3);
if(startOn >= 0) getAllMEdge(elementStartOn, edgeStartOn); for(int i = 0; i < 3; i++)
getAllMEdge(element[i], edge[i]);
// Build spanning tree and save into the model (begin with startOn if defined) // Build spanning tree (in ascending dimension order) and save into the model
DSU vertex(model->getNumMeshVertices()); DSU vertex(model->getNumMeshVertices());
Tree tree; Tree tree;
if(startOn >= 0) spanningTree(edgeStartOn, vertex, tree); for(int i = 0; i < 3; i++)
spanningTree(edge[i], vertex, tree);
spanningTree(edge, vertex, tree);
addToModel(*model, tree, output); addToModel(*model, tree, output);
// Done // Done
...@@ -132,21 +167,48 @@ void GMSH_SpanningTreePlugin::spanningTree(EdgeSet &edge, DSU &vertex, ...@@ -132,21 +167,48 @@ void GMSH_SpanningTreePlugin::spanningTree(EdgeSet &edge, DSU &vertex,
} }
} }
void GMSH_SpanningTreePlugin::getAllMElement(GModel &model, int physical, string GMSH_SpanningTreePlugin::parse(string str, list<int>& physical)
ElementSet &element)
{ {
std::vector<GEntity *> entities; // Remove spaces //
str.erase(remove(str.begin(), str.end(), ' '), str.end());
// Replace commas by spaces //
replace(str.begin(), str.end(), ',', ' ');
// Init string stream //
stringstream stream;
stream << str;
// Parse stream for integers //
int tag;
string tmp;
while(!stream.eof()){
stream >> tmp; // Take next 'word'
if(sscanf(tmp.c_str(), "%d", &tag) > 0)
physical.push_back(tag);
}
if(physical == -1) { model.getEntities(entities, -1); } // Return modified string //
else { return str;
std::map<int, std::vector<GEntity *> > groups;
model.getPhysicalGroups(-1, groups);
entities = groups[physical];
} }
for(size_t i = 0; i < entities.size(); i++) void GMSH_SpanningTreePlugin::getAllMElement(GModel &model, int physical,
for(size_t j = 0; j < entities[i]->getNumMeshElements(); j++) int dim, ElementSet &element)
element.insert(entities[i]->getMeshElement(j)); {
std::map<int, std::vector<GEntity*> > group;
std::map<int, std::vector<GEntity*> >::iterator entity;
// Get groups //
model.getPhysicalGroups(dim, group);
// Get entities, if any //
entity = group.find(physical);
if(entity == group.end())
return;
for(size_t i = 0; i < entity->second.size(); i++)
for(size_t j = 0; j < entity->second[i]->getNumMeshElements(); j++)
element.insert(entity->second[i]->getMeshElement(j));
} }
void GMSH_SpanningTreePlugin::getAllMEdge(ElementSet &element, EdgeSet &edge) void GMSH_SpanningTreePlugin::getAllMEdge(ElementSet &element, EdgeSet &edge)
......
...@@ -52,12 +52,17 @@ public: ...@@ -52,12 +52,17 @@ public:
int getNbOptions(void) const; int getNbOptions(void) const;
StringXNumber *getOption(int iopt); StringXNumber *getOption(int iopt);
int getNbOptionsStr() const;
StringXString *getOptionStr(int iopt);
void run(void); void run(void);
private: private:
static void spanningTree(EdgeSet &edge, DSU &vertex, Tree &tree); static void spanningTree(EdgeSet &edge, DSU &vertex, Tree &tree);
static void getAllMElement(GModel &model, int physical, ElementSet &element); static std::string parse(std::string str, std::list<int>& physical);
static void getAllMElement(GModel &model, int physical,
int dim, ElementSet &element);
static void getAllMEdge(ElementSet &element, EdgeSet &edge); static void getAllMEdge(ElementSet &element, EdgeSet &edge);
static void addToModel(GModel &model, Tree &tree, int tag); static void addToModel(GModel &model, Tree &tree, int tag);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment