gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
BoundaryAngles.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include "GmshConfig.h"
7 #include "Context.h"
8 #include "OS.h"
9 #include "StringUtils.h"
10 #include "PViewOptions.h"
11 #include "BoundaryAngles.h"
12 #include "GModel.h"
13 #include "discreteEdge.h"
14 #include "MLine.h"
15 #include <cstring>
16 #include <algorithm>
17 #include <string>
18 #include <vector>
19 
21  {GMSH_FULLRC, "View", nullptr, -1.},
22  {GMSH_FULLRC, "Save", nullptr, 0.},
23  {GMSH_FULLRC, "Visible", nullptr, 0.},
24  {GMSH_FULLRC, "Remove", nullptr, 0.},
25 };
26 
28  {GMSH_FULLRC, "Filename", nullptr, "Angles_Surface"},
29  {GMSH_FULLRC, "Dir", nullptr, ""},
30 };
31 
32 extern "C" {
34 {
35  return new GMSH_BoundaryAnglesPlugin();
36 }
37 }
38 
40 {
41  return "Plugin(BoundaryAngles) computes the (interior) angles between the "
42  "line elements on the boundary of all surfaces. The angles, computed "
43  "modulo 2*Pi, are stored in a new post-processing view, one for each "
44  "surface. The plugin currently only works for planar surfaces."
45  "Available options:"
46  "- Visible (1=True, 0 = False, Default = 1): Visibility of the Views "
47  "in the GUI "
48  "- Save (1=True, 0 = False, Default = 0): Save the Views on disk ?"
49  "- Remove (1=True, 0 = False, Default = 0): Remove the View from the "
50  "memory after execution?"
51  "- Filename (Default = 'Angles_Surface'): Root name for the Views (in "
52  "case of save / Visibility)"
53  "- Dir (Default = ''): Output directory (possibly nested)";
54 }
55 
57 {
58  return sizeof(BoundaryAnglesOptions_Number) / sizeof(StringXNumber);
59 }
60 
62 {
63  return &BoundaryAnglesOptions_Number[iopt];
64 }
65 
67 {
68  return sizeof(BoundaryAnglesOptions_String) / sizeof(StringXString);
69 }
70 
72 {
73  return &BoundaryAnglesOptions_String[iopt];
74 }
75 
76 struct Less_EdgeEle {
77  bool operator()(const std::pair<MEdge, MElement *> &e1,
78  const std::pair<MEdge, MElement *> &e2) const
79  {
80  MEdgeLessThan le;
81  return le(e1.first, e2.first);
82  }
83 };
84 
86 {
87  int saveOnDisk = (int)BoundaryAnglesOptions_Number[1].def;
88  int viewVisible = (int)BoundaryAnglesOptions_Number[2].def;
89  int removeView = (int)BoundaryAnglesOptions_Number[3].def;
90  std::string opt_filename = BoundaryAnglesOptions_String[0].def;
91  std::string opt_dir = BoundaryAnglesOptions_String[1].def;
92  // get the mesh of the current model, and iterate on the surfaces
93  GModel *m = GModel::current();
94  for(auto it = m->firstFace(); it != m->lastFace(); ++it) {
95  GFace *gf = *it;
96  std::set<std::pair<MEdge, MElement *>, Less_EdgeEle> boundaryEdges;
97  for(std::size_t i = 0; i < gf->getNumMeshElements(); i++) {
98  MElement *e = gf->getMeshElement(i);
99  for(int j = 0; j < e->getNumEdges(); j++) {
100  std::pair<MEdge, MElement *> ed(e->getEdge(j), e);
101  auto it = boundaryEdges.find(ed);
102  if(it == boundaryEdges.end()) { boundaryEdges.insert(ed); }
103  else {
104  boundaryEdges.erase(it);
105  }
106  }
107  }
108  if(boundaryEdges.empty()) continue;
109 
110  PView *view = new PView();
111  PViewDataList *data = getDataList(view);
112  std::vector<MEdge> edges;
113  SVector3 normal(0, 0, 1.);
114  for(auto it = boundaryEdges.begin(); it != boundaryEdges.end(); ++it) {
115  edges.push_back(it->first);
116  if(it == boundaryEdges.begin()) normal = it->second->getFace(0).normal();
117  }
118  std::vector<std::vector<MVertex *> > nodes;
119  if(SortEdgeConsecutive(edges, nodes)) {
120  if(nodes.size() != 1) { Msg::Warning("Non connected boundary!"); }
121  else {
122  // Preserve orientation of the mesh
123  // Algo: Take first edge ; find "it" in the sorted vertices and check
124  // order; reverse if necessary
125  {
126  // First edge (and element) of the boundary
127  auto it2 = boundaryEdges.begin();
128  // Loop on every sorted and consecutive nodes
129  for(int j = 0; j < static_cast<int>(nodes[0].size()) - 1; j++) {
130  // Find the vertex that is the starting point of the edge it2->first
131  if(nodes[0][j]->getNum() == it2->first.getVertex(0)->getNum()) {
132  // Check that next vertex is also the end-point of the edge
133  if(nodes[0][j + 1]->getNum() !=
134  it2->first.getVertex(1)->getNum()) {
135  std::reverse(nodes[0].begin(), nodes[0].end());
136  }
137  break;
138  }
139  }
140  }
141  // Handle last elements
142  nodes[0].push_back(nodes[0][1]);
143  // Compute angle at each point (mod 2pi)
144  for(std::size_t i = 0; i < nodes[0].size() - 2; i++) {
145  SPoint3 p1 = nodes[0][i]->point();
146  SPoint3 p2 = nodes[0][i + 1]->point();
147  SPoint3 p3 = nodes[0][i + 2]->point();
148  SVector3 v1(p2, p1);
149  SVector3 v2(p2, p3);
150  double a = signedAngle(v1, v2, normal);
151  data->SP.push_back(p2.x());
152  data->SP.push_back(p2.y());
153  data->SP.push_back(p2.z());
154  // Choose the angle inside the polygon
155  if(a > 0) a = -(2 * M_PI - a);
156  data->SP.push_back(a);
157  data->NbSP++;
158  }
159  }
160  }
161  // Filename and path
162  std::string currentDir =
163  SplitFileName(GetAbsolutePath(GModel::current()->getFileName()))[0];
164  // Cleaning filename (if needed)
165  std::string rootname = SplitFileName(opt_filename)[1];
166 // Output directory
167 // Add trailing (back)slash if needed
168 #if defined(WIN32)
169  char slash = '\\';
170 #else
171  char slash = '/';
172 #endif
173  if(opt_dir[opt_dir.length() - 1] != slash) opt_dir.push_back(slash);
174  std::string outputdir = currentDir + opt_dir;
175  CreatePath(outputdir);
176  // viewname and filename (=outputdir/viewname.pos)
177  char viewname[500];
178  char filename[500];
179  sprintf(viewname, "%s_%d", rootname.c_str(), gf->tag());
180  sprintf(filename, "%s%s_%d.pos", outputdir.c_str(), rootname.c_str(),
181  gf->tag());
182  data->Time.push_back(0.);
183  data->setName(viewname);
184  data->setFileName(filename);
185  data->finalize();
186  if(!viewVisible) view->getOptions()->visible = 0;
187  if(saveOnDisk) view->write(filename, 0, false);
188  if(removeView) delete view;
189  }
190 
191  return nullptr;
192 }
StringXString
Definition: Options.h:910
GMSH_BoundaryAnglesPlugin::getNbOptionsStr
int getNbOptionsStr() const
Definition: BoundaryAngles.cpp:66
GMSH_BoundaryAnglesPlugin::getOptionStr
StringXString * getOptionStr(int iopt)
Definition: BoundaryAngles.cpp:71
SplitFileName
std::vector< std::string > SplitFileName(const std::string &fileName)
Definition: StringUtils.cpp:93
GMSH_BoundaryAnglesPlugin::getHelp
std::string getHelp() const
Definition: BoundaryAngles.cpp:39
PView
Definition: PView.h:27
GFace
Definition: GFace.h:33
GMSH_RegisterBoundaryAnglesPlugin
GMSH_Plugin * GMSH_RegisterBoundaryAnglesPlugin()
Definition: BoundaryAngles.cpp:33
GMSH_Plugin
Definition: Plugin.h:26
OS.h
PViewDataList
Definition: PViewDataList.h:17
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
PViewDataList::NbSP
int NbSP
Definition: PViewDataList.h:26
SPoint3
Definition: SPoint3.h:14
StringXNumber
Definition: Options.h:918
BoundaryAngles.h
SVector3
Definition: SVector3.h:16
MLine.h
edges
static int edges[6][2]
Definition: meshGRegionLocalMeshMod.cpp:23
MEdgeLessThan
Definition: MEdge.h:122
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
GMSH_BoundaryAnglesPlugin
Definition: BoundaryAngles.h:15
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
MElement::getEdge
virtual MEdge getEdge(int num) const =0
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
SortEdgeConsecutive
bool SortEdgeConsecutive(const std::vector< MEdge > &e, std::vector< std::vector< MVertex * > > &vs)
Definition: MEdge.cpp:68
CreatePath
void CreatePath(const std::string &fullPath)
Definition: OS.cpp:513
GMSH_BoundaryAnglesPlugin::execute
PView * execute(PView *)
Definition: BoundaryAngles.cpp:85
PViewDataList::SP
std::vector< double > SP
Definition: PViewDataList.h:27
GMSH_BoundaryAnglesPlugin::getOption
StringXNumber * getOption(int iopt)
Definition: BoundaryAngles.cpp:61
GMSH_FULLRC
#define GMSH_FULLRC
Definition: Options.h:20
Less_EdgeEle
Definition: BoundaryAngles.cpp:76
GModel
Definition: GModel.h:44
PViewOptions.h
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
PViewDataList::finalize
bool finalize(bool computeMinMax=true, const std::string &interpolationScheme="")
Definition: PViewDataList.cpp:81
PViewData::setName
virtual void setName(const std::string &val)
Definition: PViewData.h:71
StringXString::def
std::string def
Definition: Options.h:914
MElement
Definition: MElement.h:30
GEntity::tag
int tag() const
Definition: GEntity.h:280
GFace::getMeshElement
MElement * getMeshElement(std::size_t index) const
Definition: GFace.cpp:234
StringUtils.h
GMSH_BoundaryAnglesPlugin::getNbOptions
int getNbOptions() const
Definition: BoundaryAngles.cpp:56
BoundaryAnglesOptions_String
StringXString BoundaryAnglesOptions_String[]
Definition: BoundaryAngles.cpp:27
GetAbsolutePath
std::string GetAbsolutePath(const std::string &fileName)
Definition: OS.cpp:454
PView::write
bool write(const std::string &fileName, int format, bool append=false)
Definition: PViewIO.cpp:378
discreteEdge.h
Context.h
BoundaryAnglesOptions_Number
StringXNumber BoundaryAnglesOptions_Number[]
Definition: BoundaryAngles.cpp:20
PViewDataList::Time
std::vector< double > Time
Definition: PViewDataList.h:25
PView::getOptions
PViewOptions * getOptions()
Definition: PView.h:81
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
Less_EdgeEle::operator()
bool operator()(const std::pair< MEdge, MElement * > &e1, const std::pair< MEdge, MElement * > &e2) const
Definition: BoundaryAngles.cpp:77
GModel.h
signedAngle
double signedAngle(const SVector3 &a, const SVector3 &b, const SVector3 &n)
Definition: SVector3.h:164
GFace::getNumMeshElements
std::size_t getNumMeshElements() const
Definition: GFace.cpp:181
MElement::getNumEdges
virtual int getNumEdges() const =0
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
PViewOptions::visible
int visible
Definition: PViewOptions.h:54
GMSH_PostPlugin::getDataList
virtual PViewDataList * getDataList(PView *view, bool showError=true)
Definition: Plugin.cpp:107