|
[Sponsors] |
April 3, 2024, 12:10 |
Paraview .vtr files in binary
|
#1 |
New Member
djr4cfd
Join Date: Jan 2018
Posts: 13
Rep Power: 8 |
Dear all,
I am trying to write my output files in vtr format and the following gives me a correct output file in ASCII. Code:
#include <iostream> #include <fstream> #include <cmath> // Function to calculate phi = sin(x) * cos(y) double phi(double x, double y) { return sin(x) * cos(y); } int main() { int n = 10; // Size of the mesh (10x10) double step = 1.0 / (n - 1); // Step size std::ofstream outfile("output.vtr"); // Writing the header outfile << "<?xml version=\"1.0\"?>\n"; outfile << "<VTKFile type=\"RectilinearGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"; outfile << "<RectilinearGrid WholeExtent=\"0 " << n-1 << " 0 " << n-1 << " 0 0\">\n"; outfile << "<Piece Extent=\"0 " << n-1 << " 0 " << n-1 << " 0 0\">\n"; // Writing the scalar data (phi) outfile << "<PointData>\n"; outfile << "<DataArray type=\"Float64\" Name=\"phi\" NumberOfComponents=\"1\" format=\"ascii\">\n"; for (int j = 0; j < n; ++j) { for (int i = 0; i < n; ++i) { double x = i * step; double y = j * step; outfile << phi(x, y) << " "; } } outfile << "\n</DataArray>\n"; outfile << "</PointData>\n"; // Writing the coordinates outfile << "<Coordinates>\n"; outfile << "<DataArray type=\"Float64\" Name=\"X_COORDINATES\" NumberOfComponents=\"1\" format=\"ascii\">\n"; for (int i = 0; i < n; ++i) { outfile << i * step << " "; } outfile << "\n</DataArray>\n"; outfile << "<DataArray type=\"Float64\" Name=\"Y_COORDINATES\" NumberOfComponents=\"1\" format=\"ascii\">\n"; for (int j = 0; j < n; ++j) { outfile << j * step << " "; } outfile << "\n</DataArray>\n"; outfile << "<DataArray type=\"Float64\" Name=\"Z_COORDINATES\" NumberOfComponents=\"1\" format=\"ascii\">\n"; outfile << "0.0 \n"; outfile << "</DataArray>\n"; outfile << "</Coordinates>\n"; // Closing tags outfile << "</Piece>\n"; outfile << "</RectilinearGrid>\n"; outfile << "</VTKFile>\n"; outfile.close(); std::cout << "Output file generated: output.vtr\n"; return 0; } To get output file in BINARY, I tried the following: Code:
#include <iostream> #include <fstream> #include <cmath> // Function to calculate phi = sin(x) * cos(y) double phi(double x, double y) { return sin(x) * cos(y); } int main() { int n = 10; // Size of the mesh (10x10) double step = 1.0 / (n - 1); // Step size std::ofstream outfile("output.vtr"); double A[n][n]; double xx[n]; double yy[n]; for (int j = 0; j < n; ++j) { for (int i = 0; i < n; ++i) { double x = i * step; double y = j * step; //outfile << phi(x, y) << " "; A[i][j]= phi(x, y); } } for (int i = 0; i < n; ++i) { xx[i] =i * step; } for (int j = 0; j < n; ++j) { yy[j] =j * step; } // Writing the header outfile << "<?xml version=\"1.0\"?>\n"; outfile << "<VTKFile type=\"RectilinearGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"; outfile << "<RectilinearGrid WholeExtent=\"0 " << n-1 << " 0 " << n-1 << " 0 0\">\n"; outfile << "<Piece Extent=\"0 " << n-1 << " 0 " << n-1 << " 0 0\">\n"; // Writing the scalar data (phi) outfile << "<PointData>\n"; outfile << "<DataArray type=\"Int64\" Name=\"phi\" NumberOfComponents=\"1\" format=\"binary\">\n"; for (int j = 0; j < n; ++j) { for (int i = 0; i < n; ++i) { outfile.write(reinterpret_cast<const char*>(&A[i][j]), sizeof(double)); } } outfile << "\n</DataArray>\n"; outfile << "</PointData>\n"; // Writing the coordinates outfile << "<Coordinates>\n"; outfile << "<DataArray type=\"Int64\" Name=\"X_COORDINATES\" NumberOfComponents=\"1\" format=\"binary\">\n"; for (int i = 0; i < n; ++i) { outfile.write(reinterpret_cast<const char*>(&xx[i]), sizeof(double)); } outfile << "\n</DataArray>\n"; outfile << "<DataArray type=\"Int64\" Name=\"Y_COORDINATES\" NumberOfComponents=\"1\" format=\"binary\">\n"; for (int j = 0; j < n; ++j) { outfile.write(reinterpret_cast<const char*>(&yy[j]), sizeof(double)); } outfile << "\n</DataArray>\n"; outfile << "<DataArray type=\"Int64\" Name=\"Z_COORDINATES\" NumberOfComponents=\"1\" format=\"binary\">\n"; double z =0.0; outfile.write(reinterpret_cast<const char*>(&z), sizeof(double)); //outfile << "0.0 \n"; outfile << "\n</DataArray>\n"; outfile << "</Coordinates>\n"; // Closing tags outfile << "</Piece>\n"; outfile << "</RectilinearGrid>\n"; outfile << "</VTKFile>\n"; outfile.close(); std::cout << "Output file generated: output.vtr\n"; return 0; } ERROR: In /builds/gitlab-kitware-sciviz-ci/build/superbuild/paraview/src/VTK/IO/XMLParser/vtkXMLParser.cxx, line 379 vtkXMLDataParser (0x1659c570): Error parsing XML in stream at line 7, column 0, byte index 255: not well-formed (invalid token) ERROR: In /builds/gitlab-kitware-sciviz-ci/build/superbuild/paraview/src/VTK/IO/XML/vtkXMLReader.cxx, line 521 vtkXMLRectilinearGridReader (0x17dda5a0): Error parsing input file. ReadXMLInformation aborting. I am using a Ubuntu system; byte_order is LittleEndian and using g++ compiler. Paraview version is 5.10.1. Can anyone help me fix this. A similar example for writing binary vtr files using c++ will also help. |
|
April 7, 2024, 03:12 |
Successfully ported to legacy VTK. But xml vtk binary is still unaccomplished
|
#2 |
New Member
djr4cfd
Join Date: Jan 2018
Posts: 13
Rep Power: 8 |
Hi all,
I have successfully implemented the output file writing in binary using the legacy vtk format. For this, I had to use byte swap to BigEndian. The code is as follows. Code:
#include <iostream> #include <fstream> #include <cmath> template <typename T> void SwapEnd(T& var) { char* varArray = reinterpret_cast<char*>(&var); for(long i = 0; i < static_cast<long>(sizeof(var)/2); i++) std::swap(varArray[sizeof(var) - 1 - i],varArray[i]); } int main() { int n = 10; // Size of the mesh (10x10) double step = 1.0 / (n - 1); // Step size double A[n][n]; double xx[n]; double yy[n]; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { double x = i * step; double y = j * step; A[i][j]= sin(x) * cos(y); } } for (int i = 0; i < n; i++) { xx[i] =i * step; } for (int j = 0; j < n; j++) { yy[j] =j * step; } std::ofstream vtkstream; vtkstream.open("outputBinary.vtk", std::ios::out | std::ios::binary); if (vtkstream) { vtkstream<<"# vtk DataFile Version 2.0"<<"\n"; vtkstream<<"Phi=sin(x)"<<"\n"; vtkstream<<"BINARY"<<"\n"; vtkstream<<"DATASET RECTILINEAR_GRID"<<std::endl; vtkstream<<"DIMENSIONS " << n << " " << n << " 1"<<std::endl; vtkstream<<"X_COORDINATES " << n << " double"<<std::endl; //for (int i = 0; i < n; i++) { for (unsigned int i = 0; i < n; i++) { SwapEnd(xx[i]); vtkstream.write((char*)&xx[i], sizeof(double)); //vtkstream<< xx[i] << " "; } vtkstream<<"\nY_COORDINATES " << n << " double"<<std::endl; //for (int j = 0; j < n; j++) { for (unsigned int j = 0; j < n; j++) { SwapEnd(yy[j]); vtkstream.write((char*)&yy[j], sizeof(double)); //vtkstream<< yy[j] << " "; } vtkstream<<"\nZ_COORDINATES " << 1 << " double"<<std::endl; double zz = 0.0; SwapEnd(zz); vtkstream.write((char*)&zz, sizeof(double)); //vtkstream<< "0.0" << "\n"; vtkstream<<"POINT_DATA " << n*n << std::endl; vtkstream<<"SCALARS " << "Phi " << " double 1" <<std::endl; vtkstream<<"LOOKUP_TABLE default" <<std::endl; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { SwapEnd(A[i][j]); vtkstream.write((char*)&A[i][j], sizeof(double)); } } vtkstream.close(); } else { std::cout<<"ERROR"<<std::endl; } return 0; } I desperately want to convert this to XML VTK in binary. Specifically, I wish to understand the following. 1. format ="binary" This involves base64 encoding. But I am not able to understand how to do this in c++ for an array of double. 2. format="appended" < AppendedData encoding="raw"> _NNNNData </AppendedData> Here I am not understanding how to specify NNNN. Experts, please help me with this. |
|
April 8, 2024, 03:50 |
Working code in c++ to generate xml vtk files in appended raw binary
|
#3 |
New Member
djr4cfd
Join Date: Jan 2018
Posts: 13
Rep Power: 8 |
After lots and lots of effort, I found out how to write in binary.
Some reverse engineering helped me. We can load ascii files in paraview and use file>save data to generate binary files. I am sharing the code below. Code:
#include <iostream> #include <fstream> #include <cmath> int main() { int n = 10; // Size of the mesh (10x10) double step = 1.0 / (n - 1); // Step size double A[n][n]; double xx[n]; double yy[n]; for (int i = 0; i < n; i++) { xx[i] =i * step; } for (int j = 0; j < n; j++) { yy[j] =j * step; } double zz =0.0; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { A[i][j]= sin(xx[i]) * cos(yy[j]); } } // Size of each array int N1 = n*n*sizeof(double); // size of A in bytes int N2 = n*sizeof(double); // size of xx in bytes int N3 = n*sizeof(double); // size of yy in bytes int N4 = 1*sizeof(double); // size of zz in bytes // Offsets int offset1 = 0; int offset2 = offset1 + sizeof(double) + N1; int offset3 = offset2 + sizeof(double) + N2; int offset4 = offset3 + sizeof(double) + N3; std::ofstream outfile("output_binaryAppended.vtr", std::ios::out | std::ios::binary); if (outfile) { // Writing the header outfile << "<?xml version=\"1.0\"?>\n"; outfile << "<VTKFile type=\"RectilinearGrid\" version=\"1.0\" header_type=\"UInt64\" byte_order=\"LittleEndian\">\n"; outfile << "<RectilinearGrid WholeExtent=\"0 " << n-1 << " 0 " << n-1 << " 0 0\">\n"; outfile << "<Piece Extent=\"0 " << n-1 << " 0 " << n-1 << " 0 0\">\n"; // Writing the scalar data (phi) outfile << "<PointData>\n"; outfile << "<DataArray type=\"Float64\" Name=\"phi\" format=\"appended\" offset=\"" << offset1 <<"\">\n"; outfile << "</DataArray>\n"; outfile << "</PointData>\n"; // Writing the coordinates outfile << "<Coordinates>\n"; outfile << "<DataArray type=\"Float64\" Name=\"X_COORDINATES\" format=\"appended\" offset=\"" << offset2 <<"\">\n"; outfile << "</DataArray>\n"; outfile << "<DataArray type=\"Float64\" Name=\"Y_COORDINATES\" format=\"appended\" offset=\"" << offset3 <<"\">\n"; outfile << "</DataArray>\n"; outfile << "<DataArray type=\"Float64\" Name=\"Z_COORDINATES\" format=\"appended\" offset=\"" << offset4 <<"\">\n"; outfile << "</DataArray>\n"; outfile << "</Coordinates>\n"; // Closing tags outfile << "</Piece>\n"; outfile << "</RectilinearGrid>\n"; // Appended Data outfile << "<AppendedData encoding=\"raw\">\n"; outfile << "_"; outfile.write((char*)&N1, sizeof(double)); for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { outfile.write((char*)&A[i][j], sizeof(double)); } } outfile.write((char*)&N2, sizeof(double)); for (int i = 0; i < n; i++) { outfile.write((char*)&xx[i], sizeof(double)); } outfile.write((char*)&N3, sizeof(double)); for (int j = 0; j < n; j++) { outfile.write((char*)&yy[j], sizeof(double)); } outfile.write((char*)&N4, sizeof(double)); outfile.write((char*)&zz, sizeof(double)); outfile << "\n</AppendedData>\n"; // Final closing tags outfile << "</VTKFile>\n"; outfile.close(); } else { std::cout<<"ERROR"<<std::endl; } std::cout << "Output file generated: output_binaryAppended.vtr\n"; return 0; } |
|
Tags |
binary, littleendian, paraview, vtk file, xml vtk |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Converting vtk files in a single binary file | raviramesh10 | SU2 | 0 | May 18, 2021 05:50 |
[General] Problem with reading in multiple grouped Ensight .case files into paraview | scro1022 | ParaView | 0 | November 27, 2020 09:00 |
Generating binary data files in fortran to read in paraview | nadeem_malik | Main CFD Forum | 6 | May 24, 2017 08:47 |
[OpenFOAM] ParaView 3.6.1 & 3.7.0: Can't view STL files | johannes | ParaView | 2 | December 3, 2009 15:07 |
Results saving in CFD | hawk | Main CFD Forum | 16 | July 21, 2005 21:51 |