gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_MESH.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 <stdlib.h>
7 #include <string.h>
8 #include "GModel.h"
9 #include "OS.h"
10 #include "MLine.h"
11 #include "MTriangle.h"
12 #include "MQuadrangle.h"
13 #include "MTetrahedron.h"
14 #include "MHexahedron.h"
15 #include "Context.h"
16 
17 static bool getMeshVertices(int num, int *indices, std::vector<MVertex *> &vec,
18  std::vector<MVertex *> &vertices)
19 {
20  for(int i = 0; i < num; i++) {
21  if(indices[i] < 0 || indices[i] > (int)(vec.size() - 1)) {
22  Msg::Error("Wrong node index %d", indices[i]);
23  return false;
24  }
25  else
26  vertices.push_back(vec[indices[i]]);
27  }
28  return true;
29 }
30 
31 int GModel::readMESH(const std::string &name)
32 {
33  FILE *fp = Fopen(name.c_str(), "r");
34  if(!fp) {
35  Msg::Error("Unable to open file '%s'", name.c_str());
36  return 0;
37  }
38 
39  char buffer[256];
40  if(!fgets(buffer, sizeof(buffer), fp)) {
41  fclose(fp);
42  return 0;
43  }
44 
45  char str[256];
46  int format;
47  sscanf(buffer, "%s %d", str, &format);
48  if(format == 3) {
49  Msg::Error("Medit mesh import only available for ASCII files");
50  fclose(fp);
51  return 0;
52  }
53 
54  std::vector<MVertex *> vertexVector;
55  std::map<int, std::vector<MElement *> > elements[5];
56 
57  int Dimension = 3;
58 
59  while(!feof(fp)) {
60  if(!fgets(buffer, 256, fp)) break;
61  if(buffer[0] != '#') { // skip comments and empty lines
62  str[0] = '\0';
63  sscanf(buffer, "%s", str);
64  if(!strncmp(buffer, "Dimension 3", 11)) {
65  // alternative single-line 'Dimension' field used by CGAL
66  }
67  else if(!strncmp(buffer, "Dimension 2", 11)) {
68  Dimension = 2;
69  }
70  else if(!strcmp(str, "Dimension")) {
71  if(!fgets(buffer, sizeof(buffer), fp)) break;
72  }
73  else if(!strcmp(str, "Vertices")) {
74  if(!fgets(buffer, sizeof(buffer), fp)) break;
75  int nbv;
76  sscanf(buffer, "%d", &nbv);
77  Msg::Info("%d nodes", nbv);
78  vertexVector.resize(nbv);
79  for(int i = 0; i < nbv; i++) {
80  if(!fgets(buffer, sizeof(buffer), fp)) break;
81  int dum;
82  double x, y, z = 0.;
83  if (Dimension == 3)
84  sscanf(buffer, "%lf %lf %lf %d", &x, &y, &z, &dum);
85  else
86  sscanf(buffer, "%lf %lf %d", &x, &y, &dum);
87  vertexVector[i] = new MVertex(x, y, z);
88  }
89  }
90  else if(!strcmp(str, "Edges")) {
91  if(!fgets(buffer, sizeof(buffer), fp)) break;
92  int nbe;
93  sscanf(buffer, "%d", &nbe);
94  Msg::Info("%d edges", nbe);
95  for(int i = 0; i < nbe; i++) {
96  if(!fgets(buffer, sizeof(buffer), fp)) break;
97  int n[2], cl;
98  sscanf(buffer, "%d %d %d", &n[0], &n[1], &cl);
99  for(int j = 0; j < 2; j++) n[j]--;
100  std::vector<MVertex *> vertices;
101  if(!getMeshVertices(2, n, vertexVector, vertices)) {
102  fclose(fp);
103  return 0;
104  }
105  elements[0][cl].push_back(new MLine(vertices));
106  }
107  }
108  else if(!strcmp(str, "EdgesP2")) {
109  if(!fgets(buffer, sizeof(buffer), fp)) break;
110  int nbe;
111  sscanf(buffer, "%d", &nbe);
112  Msg::Info("%d edges", nbe);
113  for(int i = 0; i < nbe; i++) {
114  if(!fgets(buffer, sizeof(buffer), fp)) break;
115  int n[3], cl;
116  sscanf(buffer, "%d %d %d %d", &n[0], &n[1], &n[2], &cl);
117  for(int j = 0; j < 3; j++) n[j]--;
118  std::vector<MVertex *> vertices;
119  if(!getMeshVertices(3, n, vertexVector, vertices)) {
120  fclose(fp);
121  return 0;
122  }
123  elements[0][cl].push_back(new MLine3(vertices));
124  }
125  }
126  else if(!strcmp(str, "Triangles")) {
127  if(!fgets(buffer, sizeof(buffer), fp)) break;
128  int nbe;
129  sscanf(buffer, "%d", &nbe);
130  Msg::Info("%d triangles", nbe);
131  for(int i = 0; i < nbe; i++) {
132  if(!fgets(buffer, sizeof(buffer), fp)) break;
133  int n[3], cl;
134  sscanf(buffer, "%d %d %d %d", &n[0], &n[1], &n[2], &cl);
135  for(int j = 0; j < 3; j++) n[j]--;
136  std::vector<MVertex *> vertices;
137  if(!getMeshVertices(3, n, vertexVector, vertices)) {
138  fclose(fp);
139  return 0;
140  }
141  elements[1][cl].push_back(new MTriangle(vertices));
142  }
143  }
144  else if(!strcmp(str, "TrianglesP2")) {
145  if(!fgets(buffer, sizeof(buffer), fp)) break;
146  int nbe;
147  sscanf(buffer, "%d", &nbe);
148  Msg::Info("%d triangles", nbe);
149  for(int i = 0; i < nbe; i++) {
150  if(!fgets(buffer, sizeof(buffer), fp)) break;
151  int n[6], cl;
152  sscanf(buffer, "%d %d %d %d %d %d %d", &n[0], &n[1], &n[2], &n[3],
153  &n[4], &n[5], &cl);
154  for(int j = 0; j < 6; j++) n[j]--;
155  std::vector<MVertex *> vertices;
156  if(!getMeshVertices(6, n, vertexVector, vertices)) {
157  fclose(fp);
158  return 0;
159  }
160  elements[1][cl].push_back(new MTriangle6(vertices));
161  }
162  }
163  else if(!strcmp(str, "Quadrilaterals")) {
164  if(!fgets(buffer, sizeof(buffer), fp)) break;
165  int nbe;
166  sscanf(buffer, "%d", &nbe);
167  Msg::Info("%d quadrangles", nbe);
168  for(int i = 0; i < nbe; i++) {
169  if(!fgets(buffer, sizeof(buffer), fp)) break;
170  int n[4], cl;
171  sscanf(buffer, "%d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &cl);
172  for(int j = 0; j < 4; j++) n[j]--;
173  std::vector<MVertex *> vertices;
174  if(!getMeshVertices(4, n, vertexVector, vertices)) {
175  fclose(fp);
176  return 0;
177  }
178  elements[2][cl].push_back(new MQuadrangle(vertices));
179  }
180  }
181  else if(!strcmp(str, "Tetrahedra")) {
182  if(!fgets(buffer, sizeof(buffer), fp)) break;
183  int nbe;
184  sscanf(buffer, "%d", &nbe);
185  Msg::Info("%d tetrahedra", nbe);
186  for(int i = 0; i < nbe; i++) {
187  if(!fgets(buffer, sizeof(buffer), fp)) break;
188  int n[4], cl;
189  sscanf(buffer, "%d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &cl);
190  for(int j = 0; j < 4; j++) n[j]--;
191  std::vector<MVertex *> vertices;
192  if(!getMeshVertices(4, n, vertexVector, vertices)) {
193  fclose(fp);
194  return 0;
195  }
196  elements[3][cl].push_back(new MTetrahedron(vertices));
197  }
198  }
199  else if(!strcmp(str, "TetrahedraP2")) {
200  if(!fgets(buffer, sizeof(buffer), fp)) break;
201  int nbe;
202  sscanf(buffer, "%d", &nbe);
203  Msg::Info("%d tetrahedra", nbe);
204  for(int i = 0; i < nbe; i++) {
205  if(!fgets(buffer, sizeof(buffer), fp)) break;
206  int n[10], cl;
207  sscanf(buffer, "%d %d %d %d %d %d %d %d %d %d %d", &n[0], &n[1],
208  &n[2], &n[3], &n[4], &n[5], &n[6], &n[7], &n[9], &n[8], &cl);
209  for(int j = 0; j < 10; j++) n[j]--;
210  std::vector<MVertex *> vertices;
211  if(!getMeshVertices(10, n, vertexVector, vertices)) {
212  fclose(fp);
213  return 0;
214  }
215  elements[3][cl].push_back(new MTetrahedron10(vertices));
216  }
217  }
218  else if(!strcmp(str, "Hexahedra")) {
219  if(!fgets(buffer, sizeof(buffer), fp)) break;
220  int nbe;
221  sscanf(buffer, "%d", &nbe);
222  Msg::Info("%d hexahedra", nbe);
223  for(int i = 0; i < nbe; i++) {
224  if(!fgets(buffer, sizeof(buffer), fp)) break;
225  int n[8], cl;
226  sscanf(buffer, "%d %d %d %d %d %d %d %d %d", &n[0], &n[1], &n[2],
227  &n[3], &n[4], &n[5], &n[6], &n[7], &cl);
228  for(int j = 0; j < 8; j++) n[j]--;
229  std::vector<MVertex *> vertices;
230  if(!getMeshVertices(8, n, vertexVector, vertices)) {
231  fclose(fp);
232  return 0;
233  }
234  elements[4][cl].push_back(new MHexahedron(vertices));
235  }
236  }
237  }
238  }
239 
240  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
241  _storeElementsInEntities(elements[i]);
243  _storeVerticesInEntities(vertexVector);
244 
245  fclose(fp);
246  return 1;
247 }
248 
249 int GModel::writeMESH(const std::string &name, int elementTagType, bool saveAll,
250  double scalingFactor)
251 {
252  FILE *fp = Fopen(name.c_str(), "w");
253  if(!fp) {
254  Msg::Error("Unable to open file '%s'", name.c_str());
255  return 0;
256  }
257 
258  if(noPhysicalGroups()) saveAll = true;
259 
260  int numVertices = indexMeshVertices(saveAll);
261 
262  fprintf(fp, " MeshVersionFormatted 2\n");
263  fprintf(fp, " Dimension\n");
264  fprintf(fp, " 3\n");
265 
266  fprintf(fp, " Vertices\n");
267  fprintf(fp, " %d\n", numVertices);
268  std::vector<GEntity *> entities;
269  getEntities(entities);
270  for(std::size_t i = 0; i < entities.size(); i++)
271  for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
272  entities[i]->mesh_vertices[j]->writeMESH(fp, scalingFactor);
273 
274  int numEdges = 0, numTriangles = 0, numQuadrangles = 0;
275  int numTetrahedra = 0, numHexahedra = 0;
276  for(auto it = firstEdge(); it != lastEdge(); ++it) {
277  if(saveAll || (*it)->physicals.size()) { numEdges += (*it)->lines.size(); }
278  }
279  for(auto it = firstFace(); it != lastFace(); ++it) {
280  if(saveAll || (*it)->physicals.size()) {
281  numTriangles += (*it)->triangles.size();
282  numQuadrangles += (*it)->quadrangles.size();
283  }
284  }
285  for(auto it = firstRegion(); it != lastRegion(); ++it) {
286  if(saveAll || (*it)->physicals.size()) {
287  numTetrahedra += (*it)->tetrahedra.size();
288  numHexahedra += (*it)->hexahedra.size();
289  }
290  }
291 
292  if(numEdges) {
293  if(CTX::instance()->mesh.order == 2) // FIXME (check getPolynomialOrder())
294  fprintf(fp, " EdgesP2\n");
295  else
296  fprintf(fp, " Edges\n");
297  fprintf(fp, " %d\n", numEdges);
298  for(auto it = firstEdge(); it != lastEdge(); ++it) {
299  int numPhys = (*it)->physicals.size();
300  if(saveAll || numPhys) {
301  for(std::size_t i = 0; i < (*it)->lines.size(); i++)
302  (*it)->lines[i]->writeMESH(fp, elementTagType, (*it)->tag(),
303  numPhys ? (*it)->physicals[0] : 0);
304  }
305  }
306  }
307  if(numTriangles) {
308  if(CTX::instance()->mesh.order == 2) // FIXME (check getPolynomialOrder())
309  fprintf(fp, " TrianglesP2\n");
310  else
311  fprintf(fp, " Triangles\n");
312  fprintf(fp, " %d\n", numTriangles);
313  for(auto it = firstFace(); it != lastFace(); ++it) {
314  int numPhys = (*it)->physicals.size();
315  if(saveAll || numPhys) {
316  for(std::size_t i = 0; i < (*it)->triangles.size(); i++)
317  (*it)->triangles[i]->writeMESH(fp, elementTagType, (*it)->tag(),
318  numPhys ? (*it)->physicals[0] : 0);
319  }
320  }
321  }
322  if(numQuadrangles) {
323  fprintf(fp, " Quadrilaterals\n");
324  fprintf(fp, " %d\n", numQuadrangles);
325  for(auto it = firstFace(); it != lastFace(); ++it) {
326  int numPhys = (*it)->physicals.size();
327  if(saveAll || numPhys) {
328  for(std::size_t i = 0; i < (*it)->quadrangles.size(); i++)
329  (*it)->quadrangles[i]->writeMESH(fp, elementTagType, (*it)->tag(),
330  numPhys ? (*it)->physicals[0] : 0);
331  }
332  }
333  }
334  if(numTetrahedra) {
335  if(CTX::instance()->mesh.order == 2)
336  fprintf(fp, " TetrahedraP2\n"); // FIXME (check getPolynomialOrder())
337  else
338  fprintf(fp, " Tetrahedra\n");
339  fprintf(fp, " %d\n", numTetrahedra);
340  for(auto it = firstRegion(); it != lastRegion(); ++it) {
341  int numPhys = (*it)->physicals.size();
342  if(saveAll || numPhys) {
343  for(std::size_t i = 0; i < (*it)->tetrahedra.size(); i++)
344  (*it)->tetrahedra[i]->writeMESH(fp, elementTagType, (*it)->tag(),
345  numPhys ? (*it)->physicals[0] : 0);
346  }
347  }
348  }
349  if(numHexahedra) {
350  fprintf(fp, " Hexahedra\n");
351  fprintf(fp, " %d\n", numHexahedra);
352  for(auto it = firstRegion(); it != lastRegion(); ++it) {
353  int numPhys = (*it)->physicals.size();
354  if(saveAll || numPhys) {
355  for(std::size_t i = 0; i < (*it)->hexahedra.size(); i++)
356  (*it)->hexahedra[i]->writeMESH(fp, elementTagType, (*it)->tag(),
357  numPhys ? (*it)->physicals[0] : 0);
358  }
359  }
360  }
361 
362  fprintf(fp, " End\n");
363 
364  fclose(fp);
365  return 1;
366 }
MTriangle.h
GModel::firstEdge
eiter firstEdge()
Definition: GModel.h:356
MTetrahedron
Definition: MTetrahedron.h:34
MLine3
Definition: MLine.h:128
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
OS.h
MVertex
Definition: MVertex.h:24
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
contextMeshOptions::order
int order
Definition: Context.h:35
GModel::_storeElementsInEntities
void _storeElementsInEntities(std::map< int, std::vector< MElement * > > &map)
Definition: GModel.cpp:2273
MTetrahedron10
Definition: MTetrahedron.h:233
MLine.h
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
MLine
Definition: MLine.h:21
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
MHexahedron.h
GModel::vertices
std::set< GVertex *, GEntityPtrLessThan > vertices
Definition: GModel.h:146
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
MHexahedron
Definition: MHexahedron.h:28
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
getMeshVertices
static bool getMeshVertices(int num, int *indices, std::vector< MVertex * > &vec, std::vector< MVertex * > &vertices)
Definition: GModelIO_MESH.cpp:17
MTriangle
Definition: MTriangle.h:26
GModel::firstRegion
riter firstRegion()
Definition: GModel.h:354
GModel::lastRegion
riter lastRegion()
Definition: GModel.h:358
Context.h
MTetrahedron.h
MTriangle6
Definition: MTriangle.h:191
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MQuadrangle.h
GModel::writeMESH
int writeMESH(const std::string &name, int elementTagType=1, bool saveAll=false, double scalingFactor=1.0)
Definition: GModelIO_MESH.cpp:249
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
GModel::readMESH
int readMESH(const std::string &name)
Definition: GModelIO_MESH.cpp:31
GModel::lastEdge
eiter lastEdge()
Definition: GModel.h:360
GModel.h
GModel::_storeVerticesInEntities
void _storeVerticesInEntities(std::map< int, MVertex * > &vertices)
Definition: GModel.cpp:2496
GModel::_associateEntityWithMeshVertices
void _associateEntityWithMeshVertices()
Definition: GModel.cpp:2470
MQuadrangle
Definition: MQuadrangle.h:26
GModel::indexMeshVertices
std::size_t indexMeshVertices(bool all, int singlePartition=0, bool renumber=true)
Definition: GModel.cpp:2135