Commit 9238a53c authored by Sylvain Thery's avatar Sylvain Thery

binary vtu

parent 2175919d
......@@ -106,6 +106,8 @@ bool exportVTU(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
template <typename PFP>
bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename);
template <typename PFP>
bool exportVTUBinary(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename);
template <typename PFP>
class VTUExporter
......@@ -133,6 +135,27 @@ protected:
std::vector<Dart> bufferQuad;
std::vector<Dart> bufferOther;
bool binaryMode;
std::ofstream f_tempoBin_out ;
template<typename T>
void addBinaryVertexAttributeScal(const VertexAttribute<T>& attrib, const std::string& vtkType, const std::string& name="");
template<typename T>
void addBinaryVertexAttributeVect(const VertexAttribute<T>& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name="");
void endBinaryVertexAttributes();
template<typename T>
void addBinaryFaceAttributeScal(const FaceAttribute<T>& attrib, const std::string& vtkType, const std::string& name="");
template<typename T>
void addBinaryFaceAttributeVect(const FaceAttribute<T>& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name="");
void endBinaryFaceAttributes();
bool binaryClose();
public:
......@@ -145,7 +168,7 @@ public:
* @param filename
* @return true if ok
*/
bool init(const char* filename);
bool init(const char* filename, bool bin=false);
/**
......
......@@ -1193,6 +1193,210 @@ bool exportVTU(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
return true;
}
template <typename PFP>
bool exportVTUBinary(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
{
if (map.dimension() != 2)
{
CGoGNerr << "Surface::Export::exportVTU works only with map of dimension 2"<< CGoGNendl;
return false;
}
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
// open file
std::ofstream fout ;
fout.open(filename, std::ios_base::out | std::ios_base::trunc) ;
if (!fout.good())
{
CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
return false ;
}
VertexAutoAttribute<unsigned int> indices(map,"indices_vert");
unsigned int count=0;
for (unsigned int i = position.begin(); i != position.end(); position.next(i))
{
indices[i] = count++;
}
std::vector<unsigned int> triangles;
std::vector<unsigned int> quads;
std::vector<unsigned int> others;
std::vector<unsigned int> others_begin;
triangles.reserve(2048);
quads.reserve(2048);
others.reserve(2048);
others_begin.reserve(2048);
TraversorF<MAP> trav(map) ;
for(Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
unsigned int degree = map.faceDegree(d);
Dart f=d;
switch(degree)
{
case 3:
triangles.push_back(indices[f]); f = map.phi1(f);
triangles.push_back(indices[f]); f = map.phi1(f);
triangles.push_back(indices[f]);
break;
case 4:
quads.push_back(indices[f]); f = map.phi1(f);
quads.push_back(indices[f]); f = map.phi1(f);
quads.push_back(indices[f]); f = map.phi1(f);
quads.push_back(indices[f]);
break;
default:
others_begin.push_back(others.size());
do
{
others.push_back(indices[f]); f = map.phi1(f);
} while (f!=d);
break;
}
}
others_begin.push_back(others.size());
unsigned int nbtotal = triangles.size()/3 + quads.size()/4 + others_begin.size()-1;
fout << "<?xml version=\"1.0\"?>" << std::endl;
fout << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
fout << "<UnstructuredGrid>" << std::endl;
fout << "<Piece NumberOfPoints=\"" << position.nbElements() << "\" NumberOfCells=\""<< nbtotal << "\">" << std::endl;
fout << "<Points>" << std::endl;
fout << "<DataArray type =\"Float32\" Name =\"Position\" NumberOfComponents =\"3\" format =\"appended\" offset =\"0\"/>" << std::endl;
unsigned int offsetAppend = position.nbElements() * 3 * sizeof(float) + sizeof(unsigned int); // Data + sz of blk
fout << "</Points>" << std::endl;
fout << "<Cells>" << std::endl;
std::vector<int> bufferInt;
bufferInt.reserve(triangles.size()+quads.size()+others.size());
for (unsigned int i=0; i<triangles.size(); i+=3)
{
bufferInt.push_back(triangles[i]);
bufferInt.push_back(triangles[i+1]);
bufferInt.push_back(triangles[i+2]);
}
for (unsigned int i=0; i<quads.size(); i+=4)
{
bufferInt.push_back(quads[i]);
bufferInt.push_back(quads[i+1]);
bufferInt.push_back(quads[i+2]);
bufferInt.push_back(quads[i+3]);
}
for (unsigned int i=1; i<others_begin.size(); ++i)
{
unsigned int beg = others_begin[i-1];
unsigned int end = others_begin[i];
for (unsigned int j=beg; j<end; ++j)
bufferInt.push_back(others[j]);
}
fout << "<DataArray type =\"Int32\" Name =\"connectivity\" format =\"appended\" offset =\""<<offsetAppend<<"\"/>" << std::endl;
offsetAppend +=bufferInt.size() * sizeof(unsigned int) + sizeof(unsigned int);
fout << "<DataArray type =\"Int32\" Name =\"offsets\" format =\"appended\" offset =\""<<offsetAppend<<"\"/>" << std::endl;
offsetAppend += (triangles.size()/3 + quads.size()/4 + others_begin.size()-1) * sizeof(unsigned int) + sizeof(unsigned int);
fout << "<DataArray type =\"UInt8\" Name =\"types\" format =\"appended\" offset =\""<<offsetAppend<<"\"/>" << std::endl;
// offsetAppend += (triangles.size() + quads.size() + others_begin.size()) * sizeof(unsigned char) + sizeof(unsigned int);
fout << "</Cells>" << std::endl;
fout << "</Piece>" << std::endl;
fout << "</UnstructuredGrid>" << std::endl;
fout << "<AppendedData encoding=\"raw\">" << std::endl << "_";
fout.close();
fout.open(filename, std::ios_base::binary | std::ios_base::ate | std::ios_base::app);
unsigned int lengthBuff=0;
// bufferize and save position
{
std::vector<VEC3> bufferV3;
bufferV3.reserve(position.nbElements());
for (unsigned int i = position.begin(); i != position.end(); position.next(i))
bufferV3.push_back(position[i]);
lengthBuff = bufferV3.size()*sizeof(VEC3);
fout.write((char*)&lengthBuff,sizeof(unsigned int));
fout.write((char*)&bufferV3[0],lengthBuff);
}
// save already buffrized indices of primitives
lengthBuff = bufferInt.size()*sizeof(unsigned int);
fout.write((char*)&lengthBuff,sizeof(unsigned int));
fout.write((char*)&(bufferInt[0]),lengthBuff);
// bufferize and save offsets of primitives
bufferInt.clear();
unsigned int offset = 0;
for (unsigned int i=0; i<triangles.size(); i+=3)
{
offset += 3;
bufferInt.push_back(offset);
}
for (unsigned int i=0; i<quads.size(); i+=4)
{
offset += 4;
bufferInt.push_back(offset);
}
for (unsigned int i=1; i<others_begin.size(); ++i)
{
unsigned int length = others_begin[i] - others_begin[i-1];
offset += length;
bufferInt.push_back(offset);
}
lengthBuff = bufferInt.size()*sizeof(unsigned int);
fout.write((char*)&lengthBuff,sizeof(unsigned int));
fout.write((char*)&(bufferInt[0]), lengthBuff);
// bufferize and save types of primitives
std::vector<unsigned char> bufferUC;
bufferUC.reserve(triangles.size()/3 + quads.size()/4 + others_begin.size());
for (unsigned int i=0; i<triangles.size(); i+=3)
bufferUC.push_back((unsigned char)5);
for (unsigned int i=0; i<quads.size(); i+=4)
bufferUC.push_back((unsigned char)9);
for (unsigned int i=1; i<others_begin.size(); ++i)
bufferUC.push_back((unsigned char)7);
lengthBuff = bufferUC.size()*sizeof(unsigned char);
fout.write((char*)&lengthBuff,sizeof(unsigned int));
fout.write((char*)&(bufferUC[0]), lengthBuff);
fout.close();
fout.open(filename, std::ios_base::ate | std::ios_base::app);
fout << std::endl << "</AppendedData>" << std::endl;
fout << "</VTKFile>" << std::endl;
fout.close();
return true;
}
template <typename PFP>
bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
......@@ -1271,7 +1475,7 @@ bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename
fout << "<UnstructuredGrid>" << std::endl;
fout << "<Piece NumberOfPoints=\"" << position.nbElements() << "\" NumberOfCells=\""<< nbtotal << "\">" << std::endl;
fout << "<Points>" << std::endl;
fout << "<DataArray type=\"Float32\" NumberOfComponents=\"3\" Format=\"ascii\">" << std::endl;
fout << "<DataArray type=\"Float32\" NumberOfComponents=\"3\" Format=\"binary\">" << std::endl;
{
std::vector<VEC3> bufferV3;
......@@ -1284,7 +1488,7 @@ bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename
fout << "</DataArray>" << std::endl;
fout << "</Points>" << std::endl;
fout << "<Cells>" << std::endl;
fout << "<DataArray type=\"Int32\" Name=\"connectivity\" Format=\"ascii\">" << std::endl;
fout << "<DataArray type=\"Int32\" Name=\"connectivity\" Format=\"binary\">" << std::endl;
std::vector<int> bufferInt;
bufferInt.reserve(triangles.size()+quads.size()+others.size());
......@@ -1315,7 +1519,7 @@ bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename
Utils::zlibWriteCompressed((unsigned char*)(&bufferInt[0]),bufferInt.size()*sizeof(int), fout);
fout << "</DataArray>" << std::endl;
fout << "<DataArray type=\"Int32\" Name=\"offsets\" Format=\"ascii\">" ;
fout << "<DataArray type=\"Int32\" Name=\"offsets\" Format=\"binary\">" ;
bufferInt.clear();
......@@ -1341,7 +1545,7 @@ bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename
Utils::zlibWriteCompressed((unsigned char*)(&bufferInt[0]),bufferInt.size()*sizeof(int), fout);
fout << std::endl << "</DataArray>" << std::endl;
fout << "<DataArray type=\"UInt8\" Name=\"types\" Format=\"ascii\">";
fout << "<DataArray type=\"UInt8\" Name=\"types\" Format=\"binary\">";
for (unsigned int i=0; i<triangles.size(); i+=3)
bufferInt.push_back(5);
......@@ -1370,7 +1574,7 @@ bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute<typename
template <typename PFP>
VTUExporter<PFP>::VTUExporter(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position):
m_map(map),m_position(position),
nbtotal(0),noPointData(true),noCellData(true),closed(false)
nbtotal(0),noPointData(true),noCellData(true),closed(false),binaryMode(false)
{
if (map.dimension() != 2)
{
......@@ -1380,7 +1584,7 @@ VTUExporter<PFP>::VTUExporter(typename PFP::MAP& map, const VertexAttribute<type
}
template <typename PFP>
bool VTUExporter<PFP>::init(const char* filename)
bool VTUExporter<PFP>::init(const char* filename, bool bin)
{
// open file
......@@ -1450,6 +1654,12 @@ bool VTUExporter<PFP>::init(const char* filename)
fout << "<UnstructuredGrid>" << std::endl;
fout << "<Piece NumberOfPoints=\"" << m_position.nbElements() << "\" NumberOfCells=\""<< nbtotal << "\">" << std::endl;
if (bin)
{
binaryMode = true;
f_tempoBin_out.open(filename+"bin_tempo_", std::ios_base::binary);
}
return true;
}
......@@ -1527,8 +1737,6 @@ void VTUExporter<PFP>::endVertexAttributes()
}
template <typename PFP>
template<typename T>
void VTUExporter<PFP>::addFaceAttributeScal(const FaceAttribute<T>& attrib, const std::string& vtkType, const std::string& name)
......@@ -1728,6 +1936,286 @@ bool VTUExporter<PFP>::close()
return true;
}
// BINARY VERSION
template <typename PFP>
template<typename T>
void VTUExporter<PFP>::addBinaryVertexAttributeScal(const VertexAttribute<T>& attrib, const std::string& vtkType, const std::string& name)
{
if (!noCellData)
{
CGoGNerr << "VTUExporter<PFP>::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl;
return;
}
if (noPointData)
{
fout << "<PointData Scalars=\"scalars\">" << std::endl;
noPointData = false;
}
if (name.size() != 0)
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<name<<"\" Format=\"ascii\">" << std::endl;
else
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<attrib.name()<<"\" Format=\"ascii\">" << std::endl;
for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i))
fout << attrib[i] << std::endl;
fout << "</DataArray>" << std::endl;
}
template <typename PFP>
template<typename T>
void VTUExporter<PFP>::addBinaryVertexAttributeVect(const VertexAttribute<T>& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name)
{
if (!noCellData)
{
CGoGNerr << "VTUExporter<PFP>::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl;
return;
}
if (noPointData)
{
fout << "<PointData Scalars=\"scalars\">" << std::endl;
noPointData = false;
}
if (nbComp==0)
nbComp = sizeof(T)/(unsigned int)(2*(vtkType[vtkType.size()-1]-'0')); // Float32 -> 2*2=4 bytes Int64 -> 8 bytes
if (name.size() != 0)
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<name<<"\" NumberOfComponents=\""<< nbComp <<"\" Format=\"ascii\">" << std::endl;
else
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<attrib.name()<<"\" NumberOfComponents=\""<< nbComp <<"\" Format=\"ascii\">" << std::endl;
for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i))
{
const T& a = attrib[i];
for (unsigned int j=0;j<nbComp;++j)
fout << a[j]<< " ";
fout << std::endl;
}
fout << "</DataArray>" << std::endl;
}
template <typename PFP>
void VTUExporter<PFP>::endBinaryVertexAttributes()
{
if (!noPointData)
fout << "</PointData>" << std::endl;
noPointData = true;
}
template <typename PFP>
template<typename T>
void VTUExporter<PFP>::addBinaryFaceAttributeScal(const FaceAttribute<T>& attrib, const std::string& vtkType, const std::string& name)
{
if (!noPointData)
{
CGoGNerr << "VTUExporter<PFP>::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl;
return;
}
if (noCellData)
{
fout << "<CellData Scalars=\"scalars\">" << std::endl;
noCellData = false;
}
if (name.size() != 0)
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<name<<"\" Format=\"ascii\">" << std::endl;
else
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<attrib.name()<<"\" Format=\"ascii\">" << std::endl;
for (typename std::vector<Dart>::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it)
fout << attrib[*it] << std::endl;
for (typename std::vector<Dart>::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it)
fout << attrib[*it] << std::endl;
for (typename std::vector<Dart>::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it)
fout << attrib[*it] << std::endl;
fout << "</DataArray>" << std::endl;
}
template <typename PFP>
template<typename T>
void VTUExporter<PFP>::addBinaryFaceAttributeVect(const FaceAttribute<T>& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name)
{
if (!noPointData)
{
CGoGNerr << "VTUExporter<PFP>::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl;
return;
}
if (noCellData)
{
fout << "<CellData Scalars=\"scalars\">" << std::endl;
noCellData = false;
}
if (nbComp==0)
nbComp = sizeof(T)/(unsigned int)(2*(vtkType[vtkType.size()-1]-'0')); // Float32 -> 2*2=4 bytes Int64 -> 8 bytes
if (name.size() != 0)
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<name<<"\" NumberOfComponents=\""<< nbComp <<"\" Format=\"ascii\">" << std::endl;
else
fout << "<DataArray type=\""<< vtkType <<"\" Name=\""<<attrib.name()<<"\" NumberOfComponents=\""<< nbComp <<"\" Format=\"ascii\">" << std::endl;
for (typename std::vector<Dart>::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it)
{
const T& a = attrib[*it];
for (unsigned int j=0;j<nbComp;++j)
fout << a[j]<< " ";
fout << std::endl;
}
for (typename std::vector<Dart>::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it)
{
const T& a = attrib[*it];
for (unsigned int j=0;j<nbComp;++j)
fout << a[j]<< " ";
fout << std::endl;
}
for (typename std::vector<Dart>::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it)
{
const T& a = attrib[*it];
for (unsigned int j=0;j<nbComp;++j)
fout << a[j]<< " ";
fout << std::endl;
}
fout << " </DataArray>" << std::endl;
}
template <typename PFP>
void VTUExporter<PFP>::endBinaryFaceAttributes()
{
if (!noCellData)
fout << "</CellData>" << std::endl;
noCellData = true;
}
template <typename PFP>
bool VTUExporter<PFP>::binaryClose()
{
if (!noPointData)
endVertexAttributes();
if (!noCellData)
endFaceAttributes();
fout << "<Points>" << std::endl;
fout << "<DataArray type=\"Float32\" NumberOfComponents=\"3\" Format=\"ascii\">" << std::endl;
for (unsigned int i = m_position.begin(); i != m_position.end(); m_position.next(i))
{
const VEC3& P = m_position[i];
fout << P[0]<< " " << P[1]<< " " << P[2] << std::endl;
}
fout << "</DataArray>" << std::endl;
fout << "</Points>" << std::endl;
fout << "<Cells>" << std::endl;
fout << "<DataArray type=\"Int32\" Name=\"connectivity\" Format=\"ascii\">" << std::endl;
for (unsigned int i=0; i<triangles.size(); i+=3)
{
fout << triangles[i] << " " << triangles[i+1] << " " << triangles[i+2] << std::endl;
}
for (unsigned int i=0; i<quads.size(); i+=4)
{
fout << quads[i] << " " << quads[i+1] << " " << quads[i+2] << " " << quads[i+3]<< std::endl;
}
for (unsigned int i=1; i<others_begin.size(); ++i)
{
unsigned int beg = others_begin[i-1];
unsigned int end = others_begin[i];
for (unsigned int j=beg; j<end; ++j)
{
fout << others[j] << " ";
}
fout << std::endl;
}
fout << "</DataArray>" << std::endl;
fout << "<DataArray type=\"Int32\" Name=\"offsets\" Format=\"ascii\">" ;
unsigned int offset = 0;
for (unsigned int i=0; i<triangles.size(); i+=3)
{
offset += 3;
if (i%60 ==0)
fout << std::endl;
fout << " " << offset;
}
for (unsigned int i=0; i<quads.size(); i+=4)
{
offset += 4;
if (i%80 ==0)
fout << std::endl;
fout << " "<< offset;
}
for (unsigned int i=1; i<others_begin.size(); ++i)
{
unsigned int length = others_begin[i] - others_begin[i-1];
offset += length;
if (i%20 ==0)
fout << std::endl;
fout << " "<< offset;
}
fout << std::endl << "</DataArray>" << std::endl;
fout << "<DataArray type=\"UInt8\" Name=\"types\" Format=\"ascii\">";
for (unsigned int i=0; i<triangles.size(); i+=3)
{
if (i%60 ==0)
fout << std::endl;
fout << " 5";
}
for (unsigned int i=0; i<quads.size(); i+=4)
{
if (i%80 ==0)
fout << std::endl;
fout << " 9";
}
for (unsigned int i=1; i<others_begin.size(); ++i)
{
if (i%20 ==0)
fout << std::endl;
fout << " 7";
}
fout << std::endl << "</DataArray>" << std::endl;
fout << "</Cells>" << std::endl;
fout << "</Piece>" << std::endl;
fout << "</UnstructuredGrid>" << std::endl;
fout << "</VTKFile>" << std::endl;
fout.close();
closed=true;
return true;
}