gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_VRML.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 
14 static int skipUntil(FILE *fp, const char *key)
15 {
16  char str[256], key_bracket[256];
17  strcpy(key_bracket, key);
18  strcat(key_bracket, "[");
19  while(fscanf(fp, "%s", str)) {
20  if(!strcmp(str, key)) {
21  while(!feof(fp) && fgetc(fp) != '[') {}
22  return 1;
23  }
24  if(!strcmp(str, key_bracket)) { return 1; }
25  }
26  return 0;
27 }
28 
29 static int readVerticesVRML(FILE *fp, std::vector<MVertex *> &vertexVector,
30  std::vector<MVertex *> &allVertexVector)
31 {
32  double x, y, z;
33  if(fscanf(fp, "%lf %lf %lf", &x, &y, &z) != 3) return 0;
34  vertexVector.push_back(new MVertex(x, y, z));
35  while(fscanf(fp, " , %lf %lf %lf", &x, &y, &z) == 3)
36  vertexVector.push_back(new MVertex(x, y, z));
37  for(std::size_t i = 0; i < vertexVector.size(); i++)
38  allVertexVector.push_back(vertexVector[i]);
39  Msg::Info("%d nodes", vertexVector.size());
40  return 1;
41 }
42 
43 static int readElementsVRML(FILE *fp, std::vector<MVertex *> &vertexVector,
44  int region,
45  std::map<int, std::vector<MElement *> > elements[3],
46  bool strips = false)
47 {
48  int i;
49  std::vector<int> idx;
50  if(fscanf(fp, "%d", &i) != 1) return 0;
51  idx.push_back(i);
52 
53  // check if vertex indices are separated by commas
54  char tmp[256];
55  const char *format;
56  fpos_t position;
57  fgetpos(fp, &position);
58  if(!fgets(tmp, sizeof(tmp), fp)) return 0;
59  fsetpos(fp, &position);
60  if(strstr(tmp, ","))
61  format = " , %d";
62  else
63  format = " %d";
64 
65  while(fscanf(fp, format, &i) == 1) {
66  if(i != -1) { idx.push_back(i); }
67  else {
68  std::vector<MVertex *> vertices;
69  for(std::size_t j = 0; j < idx.size(); j++) {
70  if(idx[j] < 0 || idx[j] > (int)(vertexVector.size() - 1)) {
71  Msg::Error("Wrong node index %d", idx[j]);
72  return 0;
73  }
74  else
75  vertices.push_back(vertexVector[idx[j]]);
76  }
77  idx.clear();
78  if(vertices.size() < 2) {
79  Msg::Info("Skipping %d-node element", (int)vertices.size());
80  }
81  else if(vertices.size() == 2) {
82  elements[0][region].push_back(new MLine(vertices));
83  }
84  else if(vertices.size() == 3) {
85  elements[1][region].push_back(new MTriangle(vertices));
86  }
87  else if(!strips && vertices.size() == 4) {
88  elements[2][region].push_back(new MQuadrangle(vertices));
89  }
90  else if(strips) { // triangle strip
91  for(std::size_t j = 2; j < vertices.size(); j++) {
92  if(j % 2)
93  elements[1][region].push_back(
94  new MTriangle(vertices[j], vertices[j - 1], vertices[j - 2]));
95  else
96  elements[1][region].push_back(
97  new MTriangle(vertices[j - 2], vertices[j - 1], vertices[j]));
98  }
99  }
100  else { // import polygon as triangle fan
101  for(std::size_t j = 2; j < vertices.size(); j++) {
102  elements[1][region].push_back(
103  new MTriangle(vertices[0], vertices[j - 1], vertices[j]));
104  }
105  }
106  }
107  }
108  if(idx.size()) {
109  Msg::Error("Prematured end of VRML file");
110  return 0;
111  }
112  Msg::Info("%d elements", elements[0][region].size() +
113  elements[1][region].size() +
114  elements[2][region].size());
115  return 1;
116 }
117 
118 int GModel::readVRML(const std::string &name)
119 {
120  FILE *fp = Fopen(name.c_str(), "r");
121  if(!fp) {
122  Msg::Error("Unable to open file '%s'", name.c_str());
123  return 0;
124  }
125 
126  // This is by NO means a complete VRML/Inventor parser (but it's
127  // sufficient for reading simple Inventor files... which is all I
128  // need)
129  std::vector<MVertex *> vertexVector, allVertexVector;
130  std::map<int, std::vector<MElement *> > elements[3];
131  int region = getMaxElementaryNumber(-1);
132  char buffer[256], str[256];
133  while(!feof(fp)) {
134  if(!fgets(buffer, sizeof(buffer), fp)) break;
135  if(buffer[0] != '#') { // skip comments
136  sscanf(buffer, "%s", str);
137  if(!strcmp(str, "Coordinate3")) {
138  vertexVector.clear();
139  if(!skipUntil(fp, "point")) break;
140  if(!readVerticesVRML(fp, vertexVector, allVertexVector)) break;
141  }
142  else if(!strcmp(str, "coord")) {
143  region++;
144  vertexVector.clear();
145  if(!skipUntil(fp, "point")) break;
146  if(!readVerticesVRML(fp, vertexVector, allVertexVector)) break;
147  if(!skipUntil(fp, "coordIndex")) break;
148  if(!readElementsVRML(fp, vertexVector, region, elements, true)) break;
149  }
150  else if(!strcmp(str, "IndexedTriangleStripSet")) {
151  region++;
152  vertexVector.clear();
153  if(!skipUntil(fp, "vertex")) break;
154  if(!readVerticesVRML(fp, vertexVector, allVertexVector)) break;
155  if(!skipUntil(fp, "coordIndex")) break;
156  if(!readElementsVRML(fp, vertexVector, region, elements, true)) break;
157  }
158  else if(!strcmp(str, "IndexedFaceSet") ||
159  !strcmp(str, "IndexedLineSet")) {
160  region++;
161  if(!skipUntil(fp, "coordIndex")) break;
162  if(!readElementsVRML(fp, vertexVector, region, elements)) break;
163  }
164  else if(!strcmp(str, "DEF")) {
165  char str1[256], str2[256];
166  if(!sscanf(buffer, "%s %s %s", str1, str2, str)) break;
167  if(!strcmp(str, "Coordinate")) {
168  vertexVector.clear();
169  if(!skipUntil(fp, "point")) break;
170  if(!readVerticesVRML(fp, vertexVector, allVertexVector)) break;
171  }
172  else if(!strcmp(str, "IndexedFaceSet") ||
173  !strcmp(str, "IndexedLineSet")) {
174  region++;
175  if(!skipUntil(fp, "coordIndex")) break;
176  if(!readElementsVRML(fp, vertexVector, region, elements)) break;
177  }
178  }
179  }
180  }
181 
182  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
183  _storeElementsInEntities(elements[i]);
185  _storeVerticesInEntities(allVertexVector);
186 
187  fclose(fp);
188  return 1;
189 }
190 
191 int GModel::writeVRML(const std::string &name, bool saveAll,
192  double scalingFactor)
193 {
194  FILE *fp = Fopen(name.c_str(), "w");
195  if(!fp) {
196  Msg::Error("Unable to open file '%s'", name.c_str());
197  return 0;
198  }
199 
200  if(noPhysicalGroups()) saveAll = true;
201 
202  indexMeshVertices(saveAll);
203 
204  fprintf(fp, "#VRML V1.0 ascii\n");
205  fprintf(fp, "#created by Gmsh\n");
206  fprintf(fp, "Coordinate3 {\n");
207  fprintf(fp, " point [\n");
208 
209  for(auto it = firstVertex(); it != lastVertex(); ++it)
210  for(std::size_t i = 0; i < (*it)->mesh_vertices.size(); i++)
211  (*it)->mesh_vertices[i]->writeVRML(fp, scalingFactor);
212  for(auto it = firstEdge(); it != lastEdge(); ++it)
213  for(std::size_t i = 0; i < (*it)->mesh_vertices.size(); i++)
214  (*it)->mesh_vertices[i]->writeVRML(fp, scalingFactor);
215  for(auto it = firstFace(); it != lastFace(); ++it)
216  for(std::size_t i = 0; i < (*it)->mesh_vertices.size(); i++)
217  (*it)->mesh_vertices[i]->writeVRML(fp, scalingFactor);
218 
219  fprintf(fp, " ]\n");
220  fprintf(fp, "}\n");
221 
222  for(auto it = firstEdge(); it != lastEdge(); ++it) {
223  if(saveAll || (*it)->physicals.size()) {
224  fprintf(fp, "DEF Curve%d IndexedLineSet {\n", (*it)->tag());
225  fprintf(fp, " coordIndex [\n");
226  for(std::size_t i = 0; i < (*it)->lines.size(); i++)
227  (*it)->lines[i]->writeVRML(fp);
228  fprintf(fp, " ]\n");
229  fprintf(fp, "}\n");
230  }
231  }
232 
233  for(auto it = firstFace(); it != lastFace(); ++it) {
234  if(saveAll || (*it)->physicals.size()) {
235  fprintf(fp, "DEF Surface%d IndexedFaceSet {\n", (*it)->tag());
236  fprintf(fp, " coordIndex [\n");
237  for(std::size_t i = 0; i < (*it)->triangles.size(); i++)
238  (*it)->triangles[i]->writeVRML(fp);
239  for(std::size_t i = 0; i < (*it)->quadrangles.size(); i++)
240  (*it)->quadrangles[i]->writeVRML(fp);
241  fprintf(fp, " ]\n");
242  fprintf(fp, "}\n");
243  }
244  }
245 
246  fclose(fp);
247  return 1;
248 }
MTriangle.h
GModel::firstEdge
eiter firstEdge()
Definition: GModel.h:356
readVerticesVRML
static int readVerticesVRML(FILE *fp, std::vector< MVertex * > &vertexVector, std::vector< MVertex * > &allVertexVector)
Definition: GModelIO_VRML.cpp:29
GModel::writeVRML
int writeVRML(const std::string &name, bool saveAll=false, double scalingFactor=1.0)
Definition: GModelIO_VRML.cpp:191
GModel::getMaxElementaryNumber
int getMaxElementaryNumber(int dim)
Definition: GModel.cpp:817
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
skipUntil
static int skipUntil(FILE *fp, const char *key)
Definition: GModelIO_VRML.cpp:14
GModel::_storeElementsInEntities
void _storeElementsInEntities(std::map< int, std::vector< MElement * > > &map)
Definition: GModel.cpp:2273
GModel::firstVertex
viter firstVertex()
Definition: GModel.h:357
MLine.h
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
MLine
Definition: MLine.h:21
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
GModel::lastVertex
viter lastVertex()
Definition: GModel.h:361
GModel::readVRML
int readVRML(const std::string &name)
Definition: GModelIO_VRML.cpp:118
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
readElementsVRML
static int readElementsVRML(FILE *fp, std::vector< MVertex * > &vertexVector, int region, std::map< int, std::vector< MElement * > > elements[3], bool strips=false)
Definition: GModelIO_VRML.cpp:43
MTriangle
Definition: MTriangle.h:26
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MQuadrangle.h
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
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