gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_OFF.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 <stdio.h>
7 #include <string>
8 #include "GModel.h"
9 #include "MTriangle.h"
10 #include "MQuadrangle.h"
11 #include "OS.h"
12 #include "discreteFace.h"
13 
14 int GModel::readOFF(const std::string &name)
15 {
16  FILE *fp = Fopen(name.c_str(), "r");
17  if(!fp) {
18  Msg::Error("Unable to open file '%s'", name.c_str());
19  return 0;
20  }
21 
22  int numVertices, numFaces, numEdges;
23  if(fscanf(fp, "OFF %d %d %d", &numVertices, &numFaces, &numEdges) != 3) {
24  Msg::Error("Invalid OFF header");
25  return 0;
26  }
27 
28  if(!numVertices || !numFaces) {
29  Msg::Info("Empty OFF mesh");
30  return 1;
31  }
32 
33  GFace *gf = new discreteFace(this, getMaxElementaryNumber(2) + 1);
34  add(gf);
35 
36  std::vector<MVertex*> vertices(numVertices);
37  for(int i = 0; i < numVertices; i++) {
38  double x, y, z;
39  if(fscanf(fp, "%lf %lf %lf", &x, &y, &z) != 3) {
40  Msg::Error("Could not read vertex");
41  return 0;
42  }
43  vertices[i] = new MVertex(x, y, z, gf);
44  }
45 
46  for(int i = 0; i < numFaces; i++) {
47  int n;
48  if(fscanf(fp, "%d", &n) != 1) {
49  Msg::Error("Could not read face");
50  }
51  int v[4] = {-1, -1, -1, -1};
52  if(n == 3) {
53  if(fscanf(fp, "%d %d %d", &v[0], &v[1], &v[2]) != 3) {
54  Msg::Error("Could not read face");
55  return 0;
56  }
57  gf->triangles.push_back(new MTriangle(vertices[v[0]], vertices[v[1]],
58  vertices[v[2]]));
59  }
60  else if(n == 4) {
61  if(fscanf(fp, "%d %d %d %d", &v[0], &v[1], &v[2], &v[3]) != 4) {
62  Msg::Error("Could not read face");
63  return 0;
64  }
65  gf->quadrangles.push_back(new MQuadrangle(vertices[v[0]], vertices[v[1]],
66  vertices[v[2]], vertices[v[3]]));
67  }
68  else{
69  char buffer[4096];
70  if(!fgets(buffer, sizeof(buffer), fp))
71  Msg::Error("Could not read line");
72  Msg::Warning("Ignoring %d-node face", n);
73  continue;
74  }
75  }
76 
78  _storeVerticesInEntities(vertices); // will delete unused vertices
79  fclose(fp);
80  return 1;
81 }
82 
83 int GModel::writeOFF(const std::string &name, bool saveAll, double scalingFactor)
84 {
85  FILE *fp = Fopen(name.c_str(), "w");
86  if(!fp) {
87  Msg::Error("Unable to open file '%s'", name.c_str());
88  return 0;
89  }
90 
91  if(noPhysicalGroups()) saveAll = true;
92  int numVertices = indexMeshVertices(saveAll);
93  int numFaces = 0;
94  for(auto it = faces.begin(); it != faces.end(); ++it) {
95  GFace *gf = *it;
96  if(saveAll || gf->physicals.size())
97  numFaces += gf->getNumMeshElements();
98  }
99 
100  fprintf(fp, "OFF %d %d 0\n", numVertices, numFaces);
101 
102  std::vector<GEntity *> entities;
103  getEntities(entities);
104  for(std::size_t i = 0; i < entities.size(); i++)
105  for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
106  entities[i]->mesh_vertices[j]->writeOFF(fp, scalingFactor);
107 
108  for(auto it = faces.begin(); it != faces.end(); ++it) {
109  GFace *gf = *it;
110  if(saveAll || gf->physicals.size()) {
111  for(std::size_t i = 0; i < gf->triangles.size(); i++)
112  fprintf(fp, "3 %d %d %d\n",
113  (int)gf->triangles[i]->getVertex(0)->getIndex() - 1,
114  (int)gf->triangles[i]->getVertex(1)->getIndex() - 1,
115  (int)gf->triangles[i]->getVertex(2)->getIndex() - 1);
116  for(std::size_t i = 0; i < gf->quadrangles.size(); i++)
117  fprintf(fp, "4 %d %d %d %d\n",
118  (int)gf->quadrangles[i]->getVertex(0)->getIndex() - 1,
119  (int)gf->quadrangles[i]->getVertex(1)->getIndex() - 1,
120  (int)gf->quadrangles[i]->getVertex(2)->getIndex() - 1,
121  (int)gf->quadrangles[i]->getVertex(3)->getIndex() - 1);
122  }
123  }
124 
125  fclose(fp);
126  return 1;
127 }
MTriangle.h
GModel::getMaxElementaryNumber
int getMaxElementaryNumber(int dim)
Definition: GModel.cpp:817
GFace
Definition: GFace.h:33
GFace::triangles
std::vector< MTriangle * > triangles
Definition: GFace.h:428
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GModel::writeOFF
int writeOFF(const std::string &name, bool saveAll=false, double scalingFactor=1.0)
Definition: GModelIO_OFF.cpp:83
OS.h
MVertex
Definition: MVertex.h:24
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GEntity::physicals
std::vector< int > physicals
Definition: GEntity.h:65
GFace::quadrangles
std::vector< MQuadrangle * > quadrangles
Definition: GFace.h:429
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
GModel::vertices
std::set< GVertex *, GEntityPtrLessThan > vertices
Definition: GModel.h:146
GModel::add
bool add(GRegion *r)
Definition: GModel.h:394
discreteFace.h
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
GModel::readOFF
int readOFF(const std::string &name)
Definition: GModelIO_OFF.cpp:14
MTriangle
Definition: MTriangle.h:26
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MQuadrangle.h
GModel::faces
std::set< GFace *, GEntityPtrLessThan > faces
Definition: GModel.h:144
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
GModel.h
GModel::_storeVerticesInEntities
void _storeVerticesInEntities(std::map< int, MVertex * > &vertices)
Definition: GModel.cpp:2496
GFace::getNumMeshElements
std::size_t getNumMeshElements() const
Definition: GFace.cpp:181
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
discreteFace
Definition: discreteFace.h:18