17 #include "GmshVersion.h"
20 double scalingFactor,
bool bigEndian)
22 FILE *fp =
Fopen(name.c_str(), binary ?
"wb" :
"w");
24 Msg::Error(
"Unable to open file '%s'", name.c_str());
34 fprintf(fp,
"# vtk DataFile Version 2.0\n");
35 fprintf(fp,
"%s, Created by Gmsh %s \n",
getName().c_str(), GMSH_VERSION);
37 fprintf(fp,
"BINARY\n");
39 fprintf(fp,
"ASCII\n");
40 fprintf(fp,
"DATASET UNSTRUCTURED_GRID\n");
43 std::vector<GEntity *> entities;
47 fprintf(fp,
"POINTS %d double\n", numVertices);
48 for(std::size_t i = 0; i < entities.size(); i++)
49 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
50 entities[i]->mesh_vertices[j]->
writeVTK(fp, binary, scalingFactor,
55 int numElements = 0, totalNumInt = 0;
56 for(std::size_t i = 0; i < entities.size(); i++) {
57 if(entities[i]->physicals.size() || saveAll) {
58 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
59 if(entities[i]->getMeshElement(j)->getTypeForVTK()) {
61 totalNumInt += entities[i]->getMeshElement(j)->getNumVertices() + 1;
68 fprintf(fp,
"CELLS %d %d\n", numElements, totalNumInt);
69 for(std::size_t i = 0; i < entities.size(); i++) {
70 if(entities[i]->physicals.size() || saveAll) {
71 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
72 if(entities[i]->getMeshElement(j)->getTypeForVTK())
73 entities[i]->getMeshElement(j)->writeVTK(fp, binary, bigEndian);
79 bool havePhysicals =
false;
80 std::vector<int> physicals;
83 fprintf(fp,
"CELL_TYPES %d\n", numElements);
84 for(std::size_t i = 0; i < entities.size(); i++) {
85 if(entities[i]->physicals.size() || saveAll) {
86 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
87 int type = entities[i]->getMeshElement(j)->getTypeForVTK();
91 if(!bigEndian)
SwapBytes((
char *)&type,
sizeof(
int), 1);
92 fwrite(&type,
sizeof(
int), 1, fp);
95 fprintf(fp,
"%d\n", type);
97 if(entities[i]->physicals.size()) {
98 physicals.push_back(entities[i]->physicals[0]);
102 physicals.push_back(-1);
109 if(havePhysicals && numElements == (
int)physicals.size()) {
111 fprintf(fp,
"CELL_DATA %d\n", numElements);
112 fprintf(fp,
"SCALARS CellEntityIds int 1\n");
113 fprintf(fp,
"LOOKUP_TABLE default\n");
114 for(
int i = 0; i < numElements; i++) {
115 int type = physicals[i];
118 if(!bigEndian)
SwapBytes((
char *)&type,
sizeof(
int), 1);
119 fwrite(&type,
sizeof(
int), 1, fp);
122 fprintf(fp,
"%d\n", type);
133 FILE *fp =
Fopen(name.c_str(),
"rb");
135 Msg::Error(
"Unable to open file '%s'", name.c_str());
139 char buffer[256], buffer2[256];
140 std::map<int, std::map<int, std::string> > physicals[4];
142 if(!fgets(buffer,
sizeof(buffer), fp)) {
146 if(!fgets(buffer,
sizeof(buffer), fp)) {
151 if(fscanf(fp,
"%s", buffer) != 1)
154 if(!strcmp(buffer,
"BINARY")) binary =
true;
156 if(fscanf(fp,
"%s %s", buffer, buffer2) != 2) {
161 bool unstructured =
false;
162 if(!strcmp(buffer,
"DATASET") && !strcmp(buffer2,
"UNSTRUCTURED_GRID"))
165 if((strcmp(buffer,
"DATASET") && strcmp(buffer2,
"UNSTRUCTURED_GRID")) ||
166 (strcmp(buffer,
"DATASET") && strcmp(buffer2,
"POLYDATA"))) {
167 Msg::Error(
"VTK reader can only read unstructured or polydata datasets");
174 if(fscanf(fp,
"%s %d %s", buffer, &numVertices, buffer2) != 3)
return 0;
175 if(strcmp(buffer,
"POINTS") || !numVertices) {
181 if(!strcmp(buffer2,
"double"))
182 datasize =
sizeof(double);
183 else if(!strcmp(buffer2,
"float"))
184 datasize =
sizeof(
float);
186 Msg::Warning(
"VTK reader only accepts float or double datasets");
190 Msg::Info(
"Reading %d points", numVertices);
191 std::vector<MVertex *>
vertices(numVertices);
192 for(
int i = 0; i < numVertices; i++) {
195 if(datasize ==
sizeof(
float)) {
197 if(fread(
f,
sizeof(
float), 3, fp) != 3) {
201 if(!bigEndian)
SwapBytes((
char *)
f,
sizeof(
float), 3);
202 for(
int j = 0; j < 3; j++) xyz[j] =
f[j];
205 if(fread(xyz,
sizeof(
double), 3, fp) != 3) {
209 if(!bigEndian)
SwapBytes((
char *)xyz,
sizeof(
double), 3);
213 if(fscanf(fp,
"%lf %lf %lf", &xyz[0], &xyz[1], &xyz[2]) != 3) {
222 int numElements, totalNumInt;
223 if(fscanf(fp,
"%s %d %d", buffer, &numElements, &totalNumInt) != 3) {
228 bool haveCells =
true;
229 bool haveLines =
false;
230 if(!strcmp(buffer,
"CELLS") && numElements > 0)
231 Msg::Info(
"Reading %d cells", numElements);
232 else if(!strcmp(buffer,
"POLYGONS") && numElements > 0)
233 Msg::Info(
"Reading %d polygons", numElements);
234 else if(!strcmp(buffer,
"LINES") && numElements > 0) {
237 Msg::Info(
"Reading %d lines", numElements);
250 std::map<int, std::vector<MElement *> > elements[8];
253 std::vector<std::vector<MVertex *> > cells(numElements);
254 for(std::size_t i = 0; i < cells.size(); i++) {
255 int numVerts, n[100];
257 if(fread(&numVerts,
sizeof(
int), 1, fp) != 1) {
261 if(!bigEndian)
SwapBytes((
char *)&numVerts,
sizeof(
int), 1);
262 if((
int)fread(n,
sizeof(
int), numVerts, fp) != numVerts) {
266 if(!bigEndian)
SwapBytes((
char *)n,
sizeof(
int), numVerts);
269 if(fscanf(fp,
"%d", &numVerts) != 1) {
273 for(
int j = 0; j < numVerts; j++) {
274 if(fscanf(fp,
"%d", &n[j]) != 1) {
280 for(
int j = 0; j < numVerts; j++) {
281 if(n[j] >= 0 && n[j] < (
int)
vertices.size())
289 if(fscanf(fp,
"%s %d", buffer, &numElements) != 2) {
293 if(strcmp(buffer,
"CELL_TYPES") || numElements != (
int)cells.size()) {
294 Msg::Error(
"No or invalid number of cells types");
298 for(std::size_t i = 0; i < cells.size(); i++) {
301 if(fread(&type,
sizeof(
int), 1, fp) != 1) {
305 if(!bigEndian)
SwapBytes((
char *)&type,
sizeof(
int), 1);
308 if(fscanf(fp,
"%d", &type) != 1) {
314 case 1: elements[0][iPoint++].push_back(
new MPoint(cells[i]));
break;
316 case 3: elements[1][iCurve].push_back(
new MLine(cells[i]));
break;
317 case 5: elements[2][iSurface].push_back(
new MTriangle(cells[i]));
break;
319 elements[3][iSurface].push_back(
new MQuadrangle(cells[i]));
322 elements[4][iVolume].push_back(
new MTetrahedron(cells[i]));
325 elements[5][iVolume].push_back(
new MHexahedron(cells[i]));
327 case 13: elements[6][iVolume].push_back(
new MPrism(cells[i]));
break;
328 case 14: elements[7][iVolume].push_back(
new MPyramid(cells[i]));
break;
330 case 21: elements[1][iCurve].push_back(
new MLine3(cells[i]));
break;
332 elements[2][iSurface].push_back(
new MTriangle6(cells[i]));
335 elements[3][iSurface].push_back(
new MQuadrangle8(cells[i]));
338 elements[3][iSurface].push_back(
new MQuadrangle9(cells[i]));
342 cells[i][0], cells[i][1], cells[i][2], cells[i][3], cells[i][4],
343 cells[i][5], cells[i][6], cells[i][7], cells[i][9], cells[i][8]));
347 cells[i][0], cells[i][1], cells[i][2], cells[i][3], cells[i][4],
348 cells[i][5], cells[i][6], cells[i][7], cells[i][8], cells[i][11],
349 cells[i][13], cells[i][9], cells[i][16], cells[i][18], cells[i][19],
350 cells[i][17], cells[i][10], cells[i][12], cells[i][14],
355 cells[i][0], cells[i][1], cells[i][2], cells[i][3], cells[i][4],
356 cells[i][5], cells[i][6], cells[i][7], cells[i][8], cells[i][11],
357 cells[i][13], cells[i][9], cells[i][16], cells[i][18], cells[i][19],
358 cells[i][17], cells[i][10], cells[i][12], cells[i][14],
359 cells[i][15], cells[i][22], cells[i][23], cells[i][21],
360 cells[i][24], cells[i][20], cells[i][25], cells[i][26]));
363 elements[6][iVolume].push_back(
364 new MPrism15(cells[i][0], cells[i][1], cells[i][2], cells[i][3],
365 cells[i][4], cells[i][5], cells[i][6], cells[i][9],
366 cells[i][7], cells[i][12], cells[i][14], cells[i][13],
367 cells[i][8], cells[i][10], cells[i][11]));
370 elements[6][iVolume].push_back(
new MPrism18(
371 cells[i][0], cells[i][1], cells[i][2], cells[i][3], cells[i][4],
372 cells[i][5], cells[i][6], cells[i][9], cells[i][7], cells[i][12],
373 cells[i][14], cells[i][13], cells[i][8], cells[i][10], cells[i][11],
374 cells[i][15], cells[i][17], cells[i][16]));
376 default:
Msg::Error(
"Unknown type of cell %d", type);
break;
381 for(std::size_t i = 0; i < cells.size(); i++) {
382 int nbNodes = (int)cells[i].size();
384 case 1: elements[0][iPoint++].push_back(
new MPoint(cells[i]));
break;
385 case 2: elements[1][iCurve].push_back(
new MLine(cells[i]));
break;
386 case 3: elements[2][iSurface].push_back(
new MTriangle(cells[i]));
break;
388 elements[3][iSurface].push_back(
new MQuadrangle(cells[i]));
391 Msg::Error(
"Unknown type of mesh element with %d nodes", nbNodes);
400 char line[100000], *p, *pEnd, *pEnd2;
401 for(
int k = 0; k < numElements; k++) {
402 physicals[1][iCurve][1] =
"centerline";
403 if(!fgets(
line,
sizeof(
line), fp)) {
407 v0 = (int)strtol(
line, &pEnd, 10);
408 v0 = (int)strtol(pEnd, &pEnd2, 10);
411 v1 = strtol(p, &pEnd, 10);
421 Msg::Error(
"Line import not done for binary VTK files");
425 for(
int i = 0; i < (int)(
sizeof(elements) /
sizeof(elements[0])); i++)