gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_PLY.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 "GmshConfig.h"
9 #include "GModel.h"
10 #include "MTriangle.h"
11 #include "OS.h"
12 #include "StringUtils.h"
13 
14 #if defined(HAVE_POST)
15 #include "PView.h"
16 #include "PViewDataList.h"
17 #endif
18 
19 static bool getMeshVertices(int num, int *indices, std::vector<MVertex *> &vec,
20  std::vector<MVertex *> &vertices)
21 {
22  for(int i = 0; i < num; i++) {
23  if(indices[i] < 0 || indices[i] > (int)(vec.size() - 1)) {
24  Msg::Error("Wrong node index %d", indices[i]);
25  return false;
26  }
27  else
28  vertices.push_back(vec[indices[i]]);
29  }
30  return true;
31 }
32 
33 #if defined(HAVE_POST)
34 static bool getProperties(int num, int *indices, std::vector<double> &vec,
35  std::vector<double> &properties)
36 {
37  for(int i = 0; i < num; i++) {
38  if(indices[i] < 0 || indices[i] > (int)(vec.size() - 1)) {
39  Msg::Error("Wrong node index %d", indices[i]);
40  return false;
41  }
42  else
43  properties.push_back(vec[indices[i]]);
44  }
45  return true;
46 }
47 #endif
48 
49 int GModel::readPLY(const std::string &name)
50 {
51  FILE *fp = Fopen(name.c_str(), "rb");
52  if(!fp) {
53  Msg::Error("Unable to open file '%s'", name.c_str());
54  return 0;
55  }
56 
57  std::vector<MVertex *> vertexVector;
58  std::map<int, std::vector<MElement *> > elements[5];
59  std::map<int, std::vector<double> > properties;
60 
61  char buffer[256], str[256], str2[256], str3[256];
62  std::string s1;
63  int elementary = getMaxElementaryNumber(-1) + 1;
64  int nbv = 0, nbf = 0;
65  int nbprop = 0;
66  int nbView = 0;
67  std::vector<std::string> propName;
68  bool binary = false;
69  bool swap = false;
70  while(!feof(fp)) {
71  if(!fgets(buffer, sizeof(buffer), fp)) break;
72  if(buffer[0] != '#') { // skip comments
73  sscanf(buffer, "%s %s", str, str2);
74  if(!strcmp(str, "element") && !strcmp(str2, "vertex")) {
75  sscanf(buffer, "%s %s %d", str, str2, &nbv);
76  }
77  if(!strcmp(str, "format") && strcmp(str2, "ascii")) {
78  Msg::Warning("Reading binary PLY files is experimental");
79  binary = true;
80  if(!strcmp(str2, "binary_big_endian")) {
81  Msg::Debug("Reading binary PLY file as big-endian");
82  swap = true;
83  }
84  }
85  if(!strcmp(str, "property") && strcmp(str2, "list")) {
86  nbprop++;
87  sscanf(buffer, "%s %s %s", str, str2, str3);
88  if(nbprop > 3) propName.push_back(s1 + str3);
89  }
90  if(!strcmp(str, "element") && !strcmp(str2, "face")) {
91  sscanf(buffer, "%s %s %d", str, str2, &nbf);
92  }
93  if(!strcmp(str, "end_header")) {
94  nbView = nbprop - 3;
95  Msg::Info("%d elements", nbv);
96  Msg::Info("%d triangles", nbf);
97  Msg::Info("%d properties", nbView);
98  vertexVector.resize(nbv);
99  if(!binary) {
100  for(int i = 0; i < nbv; i++) {
101  double x, y, z;
102  char line[10000], *pEnd, *pEnd2, *pEnd3;
103  if(!fgets(line, sizeof(line), fp)) {
104  fclose(fp);
105  return 0;
106  }
107  x = strtod(line, &pEnd);
108  y = strtod(pEnd, &pEnd2);
109  z = strtod(pEnd2, &pEnd3);
110  vertexVector[i] = new MVertex(x, y, z);
111 
112  pEnd = pEnd3;
113  std::vector<double> prop(nbView);
114  for(int k = 0; k < nbView; k++) {
115  prop[k] = strtod(pEnd, &pEnd2);
116  pEnd = pEnd2;
117  properties[k].push_back(prop[k]);
118  }
119  }
120 
121  for(int i = 0; i < nbf; i++) {
122  if(!fgets(buffer, sizeof(buffer), fp)) break;
123  int n[3], nbe;
124  sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]);
125  std::vector<MVertex *> vertices;
126  if(!getMeshVertices(3, n, vertexVector, vertices)) {
127  fclose(fp);
128  return 0;
129  }
130  elements[0][elementary].push_back(new MTriangle(vertices));
131  }
132  }
133  else { // binary
134  std::size_t num_coords = 3 * nbv;
135  std::vector<float> coord(num_coords);
136  if(fread(&coord[0], sizeof(float), num_coords, fp) != num_coords) {
137  return 0;
138  }
139  for(int i = 0; i < nbv; i++) {
140  vertexVector[i] =
141  new MVertex(coord[3 * i], coord[3 * i + 1], coord[3 * i + 2]);
142  }
143  // TODO add properties
144  for(int i = 0; i < nbf; i++) {
145  unsigned char nbe;
146  int n[3]; // only handle triangles
147  if(fread(&nbe, sizeof(char), 1, fp) != 1) {
148  fclose(fp);
149  return 0;
150  }
151  if(fread(n, sizeof(int), 3, fp) != 3) {
152  fclose(fp);
153  return 0;
154  }
155  if(swap) SwapBytes((char *)n, sizeof(int), 3);
156  std::vector<MVertex *> vertices;
157  if(!getMeshVertices(3, n, vertexVector, vertices)) {
158  fclose(fp);
159  return 0;
160  }
161  elements[0][elementary].push_back(new MTriangle(vertices));
162  }
163  }
164  }
165  }
166  }
167 
168  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
169  _storeElementsInEntities(elements[i]);
171  _storeVerticesInEntities(vertexVector);
172 
173 #if defined(HAVE_POST)
174  // create PViews here
175  std::vector<GEntity *> _entities;
176  getEntities(_entities);
177  for(int iV = 0; iV < nbView; iV++) {
178  PView *view = new PView();
179  PViewDataList *data = dynamic_cast<PViewDataList *>(view->getData());
180  for(std::size_t ii = 0; ii < _entities.size(); ii++) {
181  for(std::size_t i = 0; i < _entities[ii]->getNumMeshElements(); i++) {
182  MElement *e = _entities[ii]->getMeshElement(i);
183  int numNodes = e->getNumVertices();
184  std::vector<double> x(numNodes), y(numNodes), z(numNodes);
185  std::vector<double> *out = data->incrementList(1, e->getType());
186  for(int nod = 0; nod < numNodes; nod++)
187  out->push_back((e->getVertex(nod))->x());
188  for(int nod = 0; nod < numNodes; nod++)
189  out->push_back((e->getVertex(nod))->y());
190  for(int nod = 0; nod < numNodes; nod++)
191  out->push_back((e->getVertex(nod))->z());
192  std::vector<double> props;
193  int n[3];
194  n[0] = e->getVertex(0)->getNum() - 1;
195  n[1] = e->getVertex(1)->getNum() - 1;
196  n[2] = e->getVertex(2)->getNum() - 1;
197  if(!getProperties(3, n, properties[iV], props)) {
198  fclose(fp);
199  return 0;
200  }
201  for(int nod = 0; nod < numNodes; nod++) out->push_back(props[nod]);
202  }
203  }
204  data->setName(propName[iV]);
205  data->Time.push_back(0);
206  data->setFileName("property.pos");
207  data->finalize();
208  }
209 #endif
210 
211  fclose(fp);
212 
213  return 1;
214 }
215 
216 int GModel::readPLY2(const std::string &name)
217 {
218  FILE *fp = Fopen(name.c_str(), "r");
219  if(!fp) {
220  Msg::Error("Unable to open file '%s'", name.c_str());
221  return 0;
222  }
223 
224  std::vector<MVertex *> vertexVector;
225  std::map<int, std::vector<MElement *> > elements[5];
226 
227  char buffer[256];
228  int elementary = getMaxElementaryNumber(-1) + 1;
229  int nbv, nbf;
230  while(!feof(fp)) {
231  if(!fgets(buffer, sizeof(buffer), fp)) break;
232  if(buffer[0] != '#') { // skip comments
233  sscanf(buffer, "%d", &nbv);
234  if(!fgets(buffer, sizeof(buffer), fp)) break;
235  sscanf(buffer, "%d", &nbf);
236  Msg::Info("%d nodes", nbv);
237  Msg::Info("%d triangles", nbf);
238  vertexVector.resize(nbv);
239  for(int i = 0; i < nbv; i++) {
240  if(!fgets(buffer, sizeof(buffer), fp)) break;
241  double x, y, z;
242  int nb = sscanf(buffer, "%lf %lf %lf", &x, &y, &z);
243  if(nb != 3) {
244  if(!fgets(buffer, sizeof(buffer), fp)) break;
245  sscanf(buffer, "%lf", &y);
246  if(!fgets(buffer, sizeof(buffer), fp)) break;
247  sscanf(buffer, "%lf", &z);
248  }
249  vertexVector[i] = new MVertex(x, y, z);
250  }
251  for(int i = 0; i < nbf; i++) {
252  if(!fgets(buffer, sizeof(buffer), fp)) break;
253  int n[3], nbe;
254  int nb = sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]);
255  if(nb != 4) {
256  if(!fgets(buffer, sizeof(buffer), fp)) break;
257  sscanf(buffer, "%d", &n[0]);
258  if(!fgets(buffer, sizeof(buffer), fp)) break;
259  sscanf(buffer, "%d", &n[1]);
260  if(!fgets(buffer, sizeof(buffer), fp)) break;
261  sscanf(buffer, "%d", &n[2]);
262  }
263  std::vector<MVertex *> vertices;
264  if(!getMeshVertices(3, n, vertexVector, vertices)) {
265  fclose(fp);
266  return 0;
267  }
268  elements[0][elementary].push_back(new MTriangle(vertices));
269  }
270  }
271  }
272 
273  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
274  _storeElementsInEntities(elements[i]);
276  _storeVerticesInEntities(vertexVector);
277 
278  fclose(fp);
279  return 1;
280 }
281 
282 int GModel::writePLY2(const std::string &name)
283 {
284  FILE *fp = Fopen(name.c_str(), "w");
285  if(!fp) {
286  Msg::Error("Unable to open file '%s'", name.c_str());
287  return 0;
288  }
289 
290  int numVertices = indexMeshVertices(true);
291  int numTriangles = 0;
292  for(auto it = firstFace(); it != lastFace(); ++it) {
293  numTriangles += (*it)->triangles.size();
294  }
295 
296  fprintf(fp, "%d\n", numVertices);
297  fprintf(fp, "%d\n", numTriangles);
298 
299  std::vector<GEntity *> entities;
300  getEntities(entities);
301  for(std::size_t i = 0; i < entities.size(); i++)
302  for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
303  entities[i]->mesh_vertices[j]->writePLY2(fp);
304 
305  for(auto it = firstFace(); it != lastFace(); ++it) {
306  for(std::size_t i = 0; i < (*it)->triangles.size(); i++)
307  (*it)->triangles[i]->writePLY2(fp);
308  }
309 
310  fclose(fp);
311  return 1;
312 }
MTriangle.h
PView
Definition: PView.h:27
GModel::getMaxElementaryNumber
int getMaxElementaryNumber(int dim)
Definition: GModel.cpp:817
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
OS.h
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
PViewDataList
Definition: PViewDataList.h:17
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
PViewDataList::incrementList
std::vector< double > * incrementList(int numComp, int type, int numNodes=0)
Definition: PViewDataList.cpp:1243
MVertex::getNum
std::size_t getNum() const
Definition: MVertex.h:86
GModel::_storeElementsInEntities
void _storeElementsInEntities(std::map< int, std::vector< MElement * > > &map)
Definition: GModel.cpp:2273
PView.h
GModel::writePLY2
int writePLY2(const std::string &name)
Definition: GModelIO_PLY.cpp:282
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
SwapBytes
void SwapBytes(char *array, int size, int n)
Definition: StringUtils.cpp:16
MElement::getType
virtual int getType() const =0
swap
void swap(double &a, double &b)
Definition: meshTriangulation.cpp:27
PView::getData
PViewData * getData(bool useAdaptiveIfAvailable=false)
Definition: PView.cpp:233
GModel::vertices
std::set< GVertex *, GEntityPtrLessThan > vertices
Definition: GModel.h:146
GModel::readPLY2
int readPLY2(const std::string &name)
Definition: GModelIO_PLY.cpp:216
PViewDataList.h
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
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
MElement
Definition: MElement.h:30
GModel::readPLY
int readPLY(const std::string &name)
Definition: GModelIO_PLY.cpp:49
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
MTriangle
Definition: MTriangle.h:26
StringUtils.h
z
const double z
Definition: GaussQuadratureQuad.cpp:56
PViewDataList::Time
std::vector< double > Time
Definition: PViewDataList.h:25
GModel.h
getMeshVertices
static bool getMeshVertices(int num, int *indices, std::vector< MVertex * > &vec, std::vector< MVertex * > &vertices)
Definition: GModelIO_PLY.cpp:19
GModel::_storeVerticesInEntities
void _storeVerticesInEntities(std::map< int, MVertex * > &vertices)
Definition: GModel.cpp:2496
line
Definition: shapeFunctions.h:342
GModel::_associateEntityWithMeshVertices
void _associateEntityWithMeshVertices()
Definition: GModel.cpp:2470
GModel::indexMeshVertices
std::size_t indexMeshVertices(bool all, int singlePartition=0, bool renumber=true)
Definition: GModel.cpp:2135