From 0c1647bac28daf91a542ab2daef582e856a72679 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Mon, 27 Jan 2014 17:35:34 +0100 Subject: [PATCH] export vtu binary with attributes for 2/3 maps --- include/Algo/Export/export.h | 138 --- include/Algo/Export/export.hpp | 1205 ------------------- include/Algo/Export/exportVTU.h | 293 +++++ include/Algo/Export/exportVTU.hpp | 1865 +++++++++++++++++++++++++++++ include/Utils/compress.h | 2 +- src/Utils/compress.cpp | 46 +- 6 files changed, 2196 insertions(+), 1353 deletions(-) create mode 100644 include/Algo/Export/exportVTU.h create mode 100644 include/Algo/Export/exportVTU.hpp diff --git a/include/Algo/Export/export.h b/include/Algo/Export/export.h index 49a69bb6..aac23310 100644 --- a/include/Algo/Export/export.h +++ b/include/Algo/Export/export.h @@ -93,144 +93,6 @@ template bool exportTrian(typename PFP::MAP& map, const VertexAttribute& position, char* filename) ; -/** -* export the map into a VTU file (VTK unstructured grid xml format) -* @param map map to be exported -* @param position the position container -* @param filename filename of ply file -* @return true if ok -*/ -template -bool exportVTU(typename PFP::MAP& map, const VertexAttribute& position, const char* filename); - -template -bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute& position, const char* filename); - -template -bool exportVTUBinary(typename PFP::MAP& map, const VertexAttribute& position, const char* filename); - -template -class VTUExporter -{ -protected: - typedef typename PFP::MAP MAP; - typedef typename PFP::VEC3 VEC3; - - typename PFP::MAP& m_map; - const VertexAttribute& m_position; - - unsigned int nbtotal; - bool noPointData; - bool noCellData; - bool closed; - - std::ofstream fout ; - - std::vector triangles; - std::vector quads; - std::vector others; - std::vector others_begin; - - std::vector bufferTri; - std::vector bufferQuad; - std::vector bufferOther; - - bool binaryMode; - - std::ofstream f_tempoBin_out ; - - template - void addBinaryVertexAttributeScal(const VertexAttribute& attrib, const std::string& vtkType, const std::string& name=""); - - template - void addBinaryVertexAttributeVect(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); - - void endBinaryVertexAttributes(); - - template - void addBinaryFaceAttributeScal(const FaceAttribute& attrib, const std::string& vtkType, const std::string& name=""); - - template - void addBinaryFaceAttributeVect(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); - - void endBinaryFaceAttributes(); - - bool binaryClose(); - -public: - - VTUExporter(typename PFP::MAP& map, const VertexAttribute& position); - - ~VTUExporter(); - - /** - * @brief start writing header of vru file - * @param filename - * @return true if ok - */ - bool init(const char* filename, bool bin=false); - - - /** - * @brief add a vertex attribute of type scalar - * @param attrib - * @param vtkType Float32/Int32 - * @param name Data name if none then used Attribute's name - */ - template - void addVertexAttributeScal(const VertexAttribute& attrib, const std::string& vtkType, const std::string& name=""); - - /** - * @brief add a vertex attribute of type vector - * @param attrib - * @param vtkType Float32/Int32 - * @param nbComp number components in attribute (if none comute for size of attribute) - * @param name Data name if none then used Attribute's name - */ - template - void addVertexAttributeVect(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); - - - /** - * @brief finish adding vertex attributes data - */ - void endVertexAttributes(); - - /** - * @brief add a face attribute of type scalar - * @param attrib - * @param vtkType Float32/Int32 - * @param name Data name if none then used Attribute's name - */ - template - void addFaceAttributeScal(const FaceAttribute& attrib, const std::string& vtkType, const std::string& name=""); - - /** - * @brief add a face aatribute of type vector - * @param attrib - * @param vtkType Float32/Int32 - * @param nbComp number components in attribute (if none comute for size of attribute) - * @param name Data name if none then used Attribute's name - */ - template - void addFaceAttributeVect(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); - - - /** - * @brief finish adding face attributes data - */ - void endFaceAttributes(); - - - /** - * @brief finalize file writing & close (automatically called at destruction) - * @return true if ok - */ - bool close(); - -}; - - /** * export the map into a PLYPTMgeneric file (K. Vanhoey generic format). diff --git a/include/Algo/Export/export.hpp b/include/Algo/Export/export.hpp index a57c3ce7..15ff1a57 100644 --- a/include/Algo/Export/export.hpp +++ b/include/Algo/Export/export.hpp @@ -1020,1211 +1020,6 @@ bool exportChoupi(typename PFP::MAP& map, const AttributeHandler -bool exportVTU(typename PFP::MAP& map, const VertexAttribute& 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::out) ; - - if (!fout.good()) - { - CGoGNerr << "Unable to open file " << filename << CGoGNendl ; - return false ; - } - - VertexAutoAttribute 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 triangles; - std::vector quads; - std::vector others; - std::vector others_begin; - triangles.reserve(2048); - quads.reserve(2048); - others.reserve(2048); - others_begin.reserve(2048); - - TraversorF 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 << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - for (unsigned int i = position.begin(); i != position.end(); position.next(i)) - { - const VEC3& P = position[i]; - fout << P[0]<< " " << P[1]<< " " << P[2] << std::endl; - } - - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - for (unsigned int i=0; i" << std::endl; - fout << "" ; - - unsigned int offset = 0; - for (unsigned int i=0; i" << std::endl; - fout << ""; - for (unsigned int i=0; i" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - fout.close(); - return true; -} - -template -bool exportVTUBinary(typename PFP::MAP& map, const VertexAttribute& 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 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 triangles; - std::vector quads; - std::vector others; - std::vector others_begin; - triangles.reserve(2048); - quads.reserve(2048); - others.reserve(2048); - others_begin.reserve(2048); - - TraversorF 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 << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - unsigned int offsetAppend = position.nbElements() * 3 * sizeof(float) + sizeof(unsigned int); // Data + sz of blk - - fout << "" << std::endl; - - fout << "" << std::endl; - - std::vector bufferInt; - bufferInt.reserve(triangles.size()+quads.size()+others.size()); - - for (unsigned int i=0; i" << std::endl; - offsetAppend +=bufferInt.size() * sizeof(unsigned int) + sizeof(unsigned int); - - fout << "" << std::endl; - offsetAppend += (triangles.size()/3 + quads.size()/4 + others_begin.size()-1) * sizeof(unsigned int) + sizeof(unsigned int); - - fout << "" << std::endl; -// offsetAppend += (triangles.size() + quads.size() + others_begin.size()) * sizeof(unsigned char) + sizeof(unsigned int); - - fout << "" << std::endl; - - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << 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 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 bufferUC; - bufferUC.reserve(triangles.size()/3 + quads.size()/4 + others_begin.size()); - - for (unsigned int i=0; i" << std::endl; - fout << "" << std::endl; - - fout.close(); - return true; -} - - - -template -bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute& 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::out) ; - - if (!fout.good()) - { - CGoGNerr << "Unable to open file " << filename << CGoGNendl ; - return false ; - } - - VertexAutoAttribute 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 triangles; - std::vector quads; - std::vector others; - std::vector others_begin; - triangles.reserve(2048); - quads.reserve(2048); - others.reserve(2048); - others_begin.reserve(2048); - - TraversorF 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 << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - { - std::vector bufferV3; - bufferV3.reserve(position.nbElements()); - for (unsigned int i = position.begin(); i != position.end(); position.next(i)) - bufferV3.push_back(position[i]); - Utils::zlibWriteCompressed((unsigned char*)(&bufferV3[0]),bufferV3.size()*sizeof(VEC3), fout); - } - - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - std::vector bufferInt; - bufferInt.reserve(triangles.size()+quads.size()+others.size()); - - for (unsigned int i=0; i" << std::endl; - fout << "" ; - - bufferInt.clear(); - - unsigned int offset = 0; - for (unsigned int i=0; i" << std::endl; - fout << ""; - - for (unsigned int i=0; i" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - fout.close(); - return true; -} - - - - -template -VTUExporter::VTUExporter(typename PFP::MAP& map, const VertexAttribute& position): - m_map(map),m_position(position), - nbtotal(0),noPointData(true),noCellData(true),closed(false),binaryMode(false) -{ - if (map.dimension() != 2) - { - CGoGNerr << "Surface::Export::exportVTU works only with map of dimension 2"<< CGoGNendl; - } - -} - -template -bool VTUExporter::init(const char* filename, bool bin) -{ - - // open file - fout.open(filename, std::ios::out) ; - - if (!fout.good()) - { - CGoGNerr << "Unable to open file " << filename << CGoGNendl ; - return false; - } - - VertexAutoAttribute indices(m_map,"indices_vert"); - - unsigned int count=0; - for (unsigned int i = m_position.begin(); i != m_position.end(); m_position.next(i)) - { - indices[i] = count++; - } - - triangles.reserve(4096); - quads.reserve(4096); - others.reserve(4096); - others_begin.reserve(4096); - - bufferTri.reserve(4096); - bufferQuad.reserve(4096); - bufferOther.reserve(4096); - - TraversorF trav(m_map) ; - for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) - { - unsigned int degree = m_map.faceDegree(d); - Dart f=d; - switch(degree) - { - case 3: - bufferTri.push_back(d); - triangles.push_back(indices[f]); f = m_map.phi1(f); - triangles.push_back(indices[f]); f = m_map.phi1(f); - triangles.push_back(indices[f]); - break; - case 4: - bufferQuad.push_back(d); - quads.push_back(indices[f]); f = m_map.phi1(f); - quads.push_back(indices[f]); f = m_map.phi1(f); - quads.push_back(indices[f]); f = m_map.phi1(f); - quads.push_back(indices[f]); - break; - - default: - bufferOther.push_back(d); - others_begin.push_back(others.size()); - do - { - others.push_back(indices[f]); f = m_map.phi1(f); - - } while (f!=d); - break; - } - } - others_begin.push_back(others.size()); - - nbtotal = triangles.size()/3 + quads.size()/4 + others_begin.size()-1; - - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - if (bin) - { - binaryMode = true; - f_tempoBin_out.open(filename+"bin_tempo_", std::ios_base::binary); - } - - return true; -} - -template -template -void VTUExporter::addVertexAttributeScal(const VertexAttribute& attrib, const std::string& vtkType, const std::string& name) -{ - if (!noCellData) - { - CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; - return; - } - - if (noPointData) - { - fout << "" << std::endl; - noPointData = false; - } - - if (name.size() != 0) - fout << "" << std::endl; - else - fout << "" << std::endl; - - for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i)) - fout << attrib[i] << std::endl; - - fout << "" << std::endl; - -} - -template -template -void VTUExporter::addVertexAttributeVect(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) -{ - if (!noCellData) - { - CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; - return; - } - - if (noPointData) - { - fout << "" << 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 << "" << std::endl; - else - fout << "" << 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" << std::endl; -} - - - -template -void VTUExporter::endVertexAttributes() -{ - if (!noPointData) - fout << "" << std::endl; - - noPointData = true; -} - - -template -template -void VTUExporter::addFaceAttributeScal(const FaceAttribute& attrib, const std::string& vtkType, const std::string& name) -{ - if (!noPointData) - { - CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; - return; - } - - if (noCellData) - { - fout << "" << std::endl; - noCellData = false; - } - - if (name.size() != 0) - fout << "" << std::endl; - else - fout << "" << std::endl; - - - for (typename std::vector::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it) - fout << attrib[*it] << std::endl; - for (typename std::vector::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it) - fout << attrib[*it] << std::endl; - for (typename std::vector::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it) - fout << attrib[*it] << std::endl; - fout << "" << std::endl; - -} - - -template -template -void VTUExporter::addFaceAttributeVect(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) -{ - if (!noPointData) - { - CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; - return; - } - - if (noCellData) - { - fout << "" << 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 << "" << std::endl; - else - fout << "" << std::endl; - - for (typename std::vector::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it) - { - const T& a = attrib[*it]; - for (unsigned int j=0;j::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it) - { - const T& a = attrib[*it]; - for (unsigned int j=0;j::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it) - { - const T& a = attrib[*it]; - for (unsigned int j=0;j" << std::endl; - -} - -template -void VTUExporter::endFaceAttributes() -{ - if (!noCellData) - fout << "" << std::endl; - - noCellData = true; -} - - -template -bool VTUExporter::close() -{ - if (!noPointData) - endVertexAttributes(); - - if (!noCellData) - endFaceAttributes(); - - fout << "" << std::endl; - fout << "" << 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 << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - for (unsigned int i=0; i" << std::endl; - fout << "" ; - - unsigned int offset = 0; - for (unsigned int i=0; i" << std::endl; - fout << ""; - for (unsigned int i=0; i" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - fout.close(); - closed=true; - return true; -} - - - -// BINARY VERSION - -template -template -void VTUExporter::addBinaryVertexAttributeScal(const VertexAttribute& attrib, const std::string& vtkType, const std::string& name) -{ - if (!noCellData) - { - CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; - return; - } - - if (noPointData) - { - fout << "" << std::endl; - noPointData = false; - } - - if (name.size() != 0) - fout << "" << std::endl; - else - fout << "" << std::endl; - - for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i)) - fout << attrib[i] << std::endl; - - fout << "" << std::endl; - -} - -template -template -void VTUExporter::addBinaryVertexAttributeVect(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) -{ - if (!noCellData) - { - CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; - return; - } - - if (noPointData) - { - fout << "" << 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 << "" << std::endl; - else - fout << "" << 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" << std::endl; -} - - - -template -void VTUExporter::endBinaryVertexAttributes() -{ - if (!noPointData) - fout << "" << std::endl; - - noPointData = true; -} - - -template -template -void VTUExporter::addBinaryFaceAttributeScal(const FaceAttribute& attrib, const std::string& vtkType, const std::string& name) -{ - if (!noPointData) - { - CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; - return; - } - - if (noCellData) - { - fout << "" << std::endl; - noCellData = false; - } - - if (name.size() != 0) - fout << "" << std::endl; - else - fout << "" << std::endl; - - - for (typename std::vector::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it) - fout << attrib[*it] << std::endl; - for (typename std::vector::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it) - fout << attrib[*it] << std::endl; - for (typename std::vector::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it) - fout << attrib[*it] << std::endl; - fout << "" << std::endl; - -} - - -template -template -void VTUExporter::addBinaryFaceAttributeVect(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) -{ - if (!noPointData) - { - CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; - return; - } - - if (noCellData) - { - fout << "" << 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 << "" << std::endl; - else - fout << "" << std::endl; - - for (typename std::vector::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it) - { - const T& a = attrib[*it]; - for (unsigned int j=0;j::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it) - { - const T& a = attrib[*it]; - for (unsigned int j=0;j::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it) - { - const T& a = attrib[*it]; - for (unsigned int j=0;j" << std::endl; - -} - -template -void VTUExporter::endBinaryFaceAttributes() -{ - if (!noCellData) - fout << "" << std::endl; - - noCellData = true; -} - - -template -bool VTUExporter::binaryClose() -{ - if (!noPointData) - endVertexAttributes(); - - if (!noCellData) - endFaceAttributes(); - - fout << "" << std::endl; - fout << "" << 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 << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - for (unsigned int i=0; i" << std::endl; - fout << "" ; - - unsigned int offset = 0; - for (unsigned int i=0; i" << std::endl; - fout << ""; - for (unsigned int i=0; i" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - fout << "" << std::endl; - - fout.close(); - closed=true; - return true; -} - - - - -template -VTUExporter::~VTUExporter() -{ - if (!closed) - close(); - closed = true; -} - - } // namespace Export } diff --git a/include/Algo/Export/exportVTU.h b/include/Algo/Export/exportVTU.h new file mode 100644 index 00000000..5cb96f09 --- /dev/null +++ b/include/Algo/Export/exportVTU.h @@ -0,0 +1,293 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __EXPORT_VTU_H__ +#define __EXPORT_VTU_H__ + +#include "Topology/generic/attributeHandler.h" +#include "Algo/Import/importFileTypes.h" + + +#include + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Surface +{ + +namespace Export +{ + + +/** +* simple export of the geometry of map into a VTU file (VTK unstructured grid xml format) +* @param map map to be exported +* @param position the position container +* @param filename filename of ply file +* @return true if ok +*/ +template +bool exportVTU(typename PFP::MAP& map, const VertexAttribute& position, const char* filename); + +/** +* simple export of the geometry of map into a binary VTU file (VTK unstructured grid xml format) +* @param map map to be exported +* @param position the position container +* @param filename filename of ply file +* @return true if ok +*/ +template +bool exportVTUBinary(typename PFP::MAP& map, const VertexAttribute& position, const char* filename); + +//template +//bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute& position, const char* filename); + +/** + * class that allow the export of VTU file (ascii or binary) + * with vertex and face attributes + */ +template +class VTUExporter +{ +protected: + typedef typename PFP::MAP MAP; + typedef typename PFP::VEC3 VEC3; + + typename PFP::MAP& m_map; + const VertexAttribute& m_position; + + unsigned int nbtotal; + bool noPointData; + bool noCellData; + bool closed; + + std::ofstream fout ; + + std::vector triangles; + std::vector quads; + std::vector others; + std::vector others_begin; + + std::vector bufferTri; + std::vector bufferQuad; + std::vector bufferOther; + + std::string m_filename; + bool binaryMode; + unsigned int offsetAppend; + + FILE* f_tempoBin_out ; + + + template + void addBinaryVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + template + void addBinaryFaceAttribute(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + bool binaryClose(); + +public: + + VTUExporter(typename PFP::MAP& map, const VertexAttribute& position); + + ~VTUExporter(); + + /** + * @brief start writing header of vtu file + * @param filename + * @param bin true if binray mode wanted + * @return true if ok + */ + bool init(const char* filename, bool bin=false); + + + + /** + * @brief add a vertex attribute + * @param attrib vertex attribute + * @param vtkType Float32/Int32/.. + * @param nbComp number of components in attribute (if none computed from size of attribute divide bye the vtkType) + * @param name data name, if none then used attribute's name + */ + template + void addVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + + /** + * @brief finish adding vertex attributes data + */ + void endVertexAttributes(); + + /** + * @brief add a face attribute + * @param attrib vertex attribute + * @param vtkType Float32/Int32/.. + * @param nbComp number of components in attribute (if none computed from size of attribute divide bye the vtkType) + * @param name data name, if none then used attribute's name + */ + template + void addFaceAttribute(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + + /** + * @brief finish adding face attributes data + */ + void endFaceAttributes(); + + + /** + * @brief finalize file writing & close (automatically called at destruction of not yet done) + * @return true if ok + */ + bool close(); + +}; + +} // namespace Export + +} // Surface + +namespace Volume +{ +namespace Export +{ + +/** + * class that allow the export of VTU file (ascii or binary) + * with vertex and volume attributes + */ +template +class VTUExporter +{ +protected: + typedef typename PFP::MAP MAP; + typedef typename PFP::VEC3 VEC3; + + typename PFP::MAP& m_map; + const VertexAttribute& m_position; + + unsigned int nbtotal; + bool noPointData; + bool noCellData; + bool closed; + + std::ofstream fout ; + + std::vector tetras; + std::vector hexas; + + std::vector bufferTetra; + std::vector bufferHexa; + + std::string m_filename; + bool binaryMode; + unsigned int offsetAppend; + + FILE* f_tempoBin_out ; + + template + void addBinaryVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + template + void addBinaryVolumeAttribute(const VolumeAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + bool binaryClose(); + +public: + + VTUExporter(typename PFP::MAP& map, const VertexAttribute& position); + + ~VTUExporter(); + + /** + * @brief start writing header of vtu file + * @param filename + * @param bin true if binray mode wanted + * @return true if ok + */ + bool init(const char* filename, bool bin=false); + + + + /** + * @brief add a vertex attribute + * @param attrib vertex attribute + * @param vtkType Float32/Int32/.. + * @param nbComp number of components in attribute (if none computed from size of attribute divide bye the vtkType) + * @param name data name, if none then used attribute's name + */ + template + void addVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + + /** + * @brief finish adding vertex attributes data + */ + void endVertexAttributes(); + + /** + * @brief add a volume attribute + * @param attrib vertex attribute + * @param vtkType Float32/Int32/.. + * @param nbComp number of components in attribute (if none computed from size of attribute divide bye the vtkType) + * @param name data name, if none then used attribute's name + */ + template + void addVolumeAttribute(const VolumeAttribute& attrib, const std::string& vtkType, unsigned int nbComp=0, const std::string& name=""); + + + /** + * @brief finish adding volume attributes data + */ + void endVolumeAttributes(); + + + /** + * @brief finalize file writing & close (automatically called at destruction of not yet done) + * @return true if ok + */ + bool close(); + +}; + +} // namespace Export + +} // Volume + + + + + +} // namespace Algo + +} // namespace CGoGN + +#include "Algo/Export/exportVTU.hpp" + +#endif diff --git a/include/Algo/Export/exportVTU.hpp b/include/Algo/Export/exportVTU.hpp new file mode 100644 index 00000000..35ae08df --- /dev/null +++ b/include/Algo/Export/exportVTU.hpp @@ -0,0 +1,1865 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Topology/generic/attributeHandler.h" +#include "Topology/generic/autoAttributeHandler.h" +#include "Topology/generic/traversorCell.h" +#include "Topology/generic/traversor2.h" +#include "Topology/generic/cellmarker.h" + +#include "Utils/compress.h" + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Surface +{ + +namespace Export +{ + +template +bool exportVTU(typename PFP::MAP& map, const VertexAttribute& 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::out) ; + + if (!fout.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl ; + return false ; + } + + VertexAutoAttribute 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 triangles; + std::vector quads; + std::vector others; + std::vector others_begin; + triangles.reserve(2048); + quads.reserve(2048); + others.reserve(2048); + others_begin.reserve(2048); + + TraversorF 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 << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + for (unsigned int i = position.begin(); i != position.end(); position.next(i)) + { + const VEC3& P = position[i]; + fout << P[0]<< " " << P[1]<< " " << P[2] << std::endl; + } + + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + for (unsigned int i=0; i" << std::endl; + fout << "" ; + + unsigned int offset = 0; + for (unsigned int i=0; i" << std::endl; + fout << ""; + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + fout.close(); + return true; +} + + + +template +bool exportVTUBinary(typename PFP::MAP& map, const VertexAttribute& 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 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 triangles; + std::vector quads; + std::vector others; + std::vector others_begin; + triangles.reserve(2048); + quads.reserve(2048); + others.reserve(2048); + others_begin.reserve(2048); + + TraversorF 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 << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + unsigned int offsetAppend = position.nbElements() * 3 * sizeof(float) + sizeof(unsigned int); // Data + sz of blk + + fout << "" << std::endl; + + fout << "" << std::endl; + + std::vector bufferInt; + bufferInt.reserve(triangles.size()+quads.size()+others.size()); + + for (unsigned int i=0; i" << std::endl; + offsetAppend +=bufferInt.size() * sizeof(unsigned int) + sizeof(unsigned int); + + fout << "" << std::endl; + offsetAppend += (triangles.size()/3 + quads.size()/4 + others_begin.size()-1) * sizeof(unsigned int) + sizeof(unsigned int); + + fout << "" << std::endl; + + fout << "" << std::endl; + + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << 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 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 bufferUC; + bufferUC.reserve(triangles.size()/3 + quads.size()/4 + others_begin.size()); + + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + + fout.close(); + return true; +} + + + +/* +template +bool exportVTUCompressed(typename PFP::MAP& map, const VertexAttribute& 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 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 triangles; + std::vector quads; + std::vector others; + std::vector others_begin; + triangles.reserve(2048); + quads.reserve(2048); + others.reserve(2048); + others_begin.reserve(2048); + + TraversorF 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 << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + unsigned int offsetAppend = position.nbElements() * 3 * sizeof(float) + sizeof(unsigned int); // Data + sz of blk + + fout << "" << std::endl; + + fout << "" << std::endl; + + std::vector bufferInt; + bufferInt.reserve(triangles.size()+quads.size()+others.size()); + + for (unsigned int i=0; i" << std::endl; + offsetAppend +=bufferInt.size() * sizeof(unsigned int) + sizeof(unsigned int); + + fout << "" << std::endl; + offsetAppend += (triangles.size()/3 + quads.size()/4 + others_begin.size()-1) * sizeof(unsigned int) + sizeof(unsigned int); + + fout << "" << std::endl; + + fout << "" << std::endl; + + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << 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 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)); + + Utils::zlibVTUWriteCompressed((unsigned char*)&bufferV3[0], lengthBuff, fout); +// 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)); + + Utils::zlibVTUWriteCompressed((unsigned char*)&(bufferInt[0]), lengthBuff, fout); +// fout.write((char*)&(bufferInt[0]),lengthBuff); + + + // bufferize and save offsets of primitives + bufferInt.clear(); + unsigned int offset = 0; + for (unsigned int i=0; i bufferUC; + bufferUC.reserve(triangles.size()/3 + quads.size()/4 + others_begin.size()); + + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + + fout.close(); + return true; +} + +*/ + + + + +// COMPLETE VERSION + +template +VTUExporter::VTUExporter(typename PFP::MAP& map, const VertexAttribute& position): + m_map(map),m_position(position), + nbtotal(0),noPointData(true),noCellData(true),closed(false),binaryMode(false),f_tempoBin_out(NULL) +{ + if (map.dimension() != 2) + { + CGoGNerr << "Surface::Export::exportVTU works only with map of dimension 2"<< CGoGNendl; + } + +} + +template +bool VTUExporter::init(const char* filename, bool bin) +{ + // save filename for close open ? + m_filename = std::string(filename); + + // open file + fout.open(filename, std::ios::out) ; + + if (!fout.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl ; + return false; + } + + VertexAutoAttribute indices(m_map,"indices_vert"); + + unsigned int count=0; + for (unsigned int i = m_position.begin(); i != m_position.end(); m_position.next(i)) + { + indices[i] = count++; + } + + triangles.reserve(4096); + quads.reserve(4096); + others.reserve(4096); + others_begin.reserve(4096); + + bufferTri.reserve(4096); + bufferQuad.reserve(4096); + bufferOther.reserve(4096); + + TraversorF trav(m_map) ; + for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + unsigned int degree = m_map.faceDegree(d); + Dart f=d; + switch(degree) + { + case 3: + bufferTri.push_back(d); + triangles.push_back(indices[f]); f = m_map.phi1(f); + triangles.push_back(indices[f]); f = m_map.phi1(f); + triangles.push_back(indices[f]); + break; + case 4: + bufferQuad.push_back(d); + quads.push_back(indices[f]); f = m_map.phi1(f); + quads.push_back(indices[f]); f = m_map.phi1(f); + quads.push_back(indices[f]); f = m_map.phi1(f); + quads.push_back(indices[f]); + break; + + default: + bufferOther.push_back(d); + others_begin.push_back(others.size()); + do + { + others.push_back(indices[f]); f = m_map.phi1(f); + + } while (f!=d); + break; + } + } + others_begin.push_back(others.size()); + + nbtotal = triangles.size()/3 + quads.size()/4 + others_begin.size()-1; + + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + if (bin) + { + binaryMode = true; + f_tempoBin_out = tmpfile(); + offsetAppend = 0; + } + + return true; +} + + +template +template +void VTUExporter::addVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (binaryMode) + return addBinaryVertexAttribute(attrib,vtkType,nbComp,name); + + if (!noCellData) + { + CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; + return; + } + + if (noPointData) + { + fout << "" << std::endl; + noPointData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 (Float32) + nbComp = sizeof(T)/4; + break; + case '4': // 64 (Int64) + nbComp = sizeof(T)/8; + break; + case '8': // 8 (Uint8) + nbComp = sizeof(T); + break; + case '6': // 16 (Int16) + nbComp = sizeof(T)/2; + break; + default: + break; + } + + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + // assume that std::cout of attribute is "c0 c1 c2 ..." + for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i)) + fout << attrib[i] << std::endl; + + fout << "" << std::endl; +} + + + +template +void VTUExporter::endVertexAttributes() +{ + if (!noPointData) + fout << "" << std::endl; + + noPointData = true; +} + + + +template +template +void VTUExporter::addFaceAttribute(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (binaryMode) + return addBinaryFaceAttribute(attrib,vtkType,nbComp,name); + + + if (!noPointData) + { + CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; + return; + } + + if (noCellData) + { + fout << "" << std::endl; + noCellData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 (Float32) + nbComp = sizeof(T)/4; + break; + case '4': // 64 (Int64) + nbComp = sizeof(T)/8; + break; + case '8': // 8 (Uint8) + nbComp = sizeof(T); + break; + case '6': // 16 (Int16) + nbComp = sizeof(T)/2; + break; + default: + break; + } + + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + // assume that std::cout of attribute is "c0 c1 c2 ..." + for (typename std::vector::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it) + fout << attrib[*it] << std::endl; + for (typename std::vector::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it) + fout << attrib[*it] << std::endl; + for (typename std::vector::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it) + fout << attrib[*it] << std::endl; + + fout << "" << std::endl; + +} + +template +void VTUExporter::endFaceAttributes() +{ + if (!noCellData) + fout << "" << std::endl; + + noCellData = true; +} + + +template +bool VTUExporter::close() +{ + if (binaryMode) + return binaryClose(); + + if (!noPointData) + endVertexAttributes(); + + if (!noCellData) + endFaceAttributes(); + + fout << "" << std::endl; + fout << "" << 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 << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + for (unsigned int i=0; i" << std::endl; + fout << "" ; + + unsigned int offset = 0; + for (unsigned int i=0; i" << std::endl; + fout << ""; + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + fout.close(); + closed=true; + return true; +} + + + +// BINARY FUCNTION + + +template +template +void VTUExporter::addBinaryVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (!noCellData) + { + CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; + return; + } + + if (noPointData) + { + fout << "" << std::endl; + noPointData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 (Float32) + nbComp = sizeof(T)/4; + break; + case '4': // 64 (Int64) + nbComp = sizeof(T)/8; + break; + case '8': // 8 (Uint8) + nbComp = sizeof(T); + break; + case '6': // 16 (Int16) + nbComp = sizeof(T)/2; + break; + default: + break; + } + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + std::vector buffer; + buffer.reserve(attrib.nbElements()); + + for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i)) + buffer.push_back(attrib[i]); + + unsigned int sz = buffer.size()*sizeof(T); + + fwrite(&sz, sizeof(unsigned int), 1, f_tempoBin_out); // size of block + fwrite(&buffer[0], sizeof(T), buffer.size(), f_tempoBin_out); // block + + offsetAppend += sizeof(T) * buffer.size() + sizeof(unsigned int); +} + + +template +template +void VTUExporter::addBinaryFaceAttribute(const FaceAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (!noPointData) + { + CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; + return; + } + + if (noCellData) + { + fout << "" << std::endl; + noCellData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 + nbComp = sizeof(T)/4; + break; + case '4': // 64 + nbComp = sizeof(T)/8; + break; + case '8': // 8 + nbComp = sizeof(T); + break; + case '6': // 16 + nbComp = sizeof(T)/2; + break; + } + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + std::vector buffer; + buffer.reserve(bufferTri.size() + bufferQuad.size() + bufferOther.size()); + + for (typename std::vector::iterator it = bufferTri.begin(); it != bufferTri.end(); ++it) + buffer.push_back(attrib[*it]); + for (typename std::vector::iterator it = bufferQuad.begin(); it != bufferQuad.end(); ++it) + buffer.push_back(attrib[*it]); + for (typename std::vector::iterator it = bufferOther.begin(); it != bufferOther.end(); ++it) + buffer.push_back(attrib[*it]); + + unsigned int sz = buffer.size()*sizeof(T); + fwrite(&sz, sizeof(unsigned int), 1, f_tempoBin_out); // size of block + fwrite(&buffer[0], sizeof(T), buffer.size(), f_tempoBin_out); // block + + offsetAppend += sizeof(T) * buffer.size() + sizeof(unsigned int); +} + + +template +bool VTUExporter::binaryClose() +{ + if (!noPointData) + endVertexAttributes(); + + if (!noCellData) + endFaceAttributes(); + + { // just for scope of std::vector (free memory) + fout << "" << std::endl; + fout << "" << std::endl; + + std::vector buffer; + buffer.reserve(m_position.nbElements()); + + for (unsigned int i = m_position.begin(); i != m_position.end(); m_position.next(i)) + buffer.push_back(m_position[i]); + + unsigned int sz = buffer.size()*sizeof(VEC3); + + offsetAppend += sz + sizeof(unsigned int); + + fwrite(&sz, sizeof(unsigned int), 1, f_tempoBin_out); // size of block + fwrite(&buffer[0], sizeof(VEC3), buffer.size(), f_tempoBin_out); // block + + fout << "" << std::endl; + } + + { // just for scope of std::vector (free memory) + + fout << "" << std::endl; + fout << "" << std::endl; + + std::vector bufferInt; + bufferInt.reserve(triangles.size()+quads.size()+others.size()); + + for (unsigned int i=0; i" << std::endl; + + bufferInt.clear(); + unsigned int offset = 0; + for (unsigned int i=0; i" << std::endl; + std::vector bufferUC; + bufferUC.reserve(triangles.size()/3 + quads.size()/4 + others_begin.size()); + + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl << "_"; + + fout.close(); + fout.open(m_filename.c_str(), std::ios_base::binary | std::ios_base::ate | std::ios_base::app); + + // copy data from tempo file to final file ! + + long int binLength = ftell(f_tempoBin_out); + rewind (f_tempoBin_out); + + const unsigned int blksz = 1024*1024; + char* buffer = new char[blksz]; + + while (binLength > blksz) + { + fread ( buffer, 1, blksz, f_tempoBin_out); + fout.write((char*)buffer,blksz); + binLength -= blksz; + } + + fread ( buffer, 1, binLength, f_tempoBin_out); + fout.write((char*)buffer,binLength); + + delete[] buffer; + fclose(f_tempoBin_out); + + fout.close(); + fout.open(m_filename.c_str(), std::ios_base::ate | std::ios_base::app); + fout << std::endl << "" << std::endl; + fout << "" << std::endl; + + fout.close(); + closed=true; + return true; +} + + + + +template +VTUExporter::~VTUExporter() +{ + if (!closed) + close(); + closed = true; +} + + +} // namespace Export + +} // namespace Surface + + + +namespace Volume +{ +namespace Export +{ + +template +VTUExporter::VTUExporter(typename PFP::MAP& map, const VertexAttribute& position): + m_map(map),m_position(position), + nbtotal(0),noPointData(true),noCellData(true),closed(false),binaryMode(false),f_tempoBin_out(NULL) +{ + if (map.dimension() != 3) + { + CGoGNerr << "Volume::Export::exportVTU works only with map of dimension 3"<< CGoGNendl; + } + +} + +template +bool VTUExporter::init(const char* filename, bool bin) +{ + // save filename for close open ? + m_filename = std::string(filename); + + // open file + fout.open(filename, std::ios::out) ; + + if (!fout.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl ; + return false; + } + + VertexAutoAttribute indices(m_map,"indices_vert"); + + unsigned int count=0; + for (unsigned int i = m_position.begin(); i != m_position.end(); m_position.next(i)) + { + indices[i] = count++; + } + + tetras.reserve(4096); + hexas.reserve(4096); + + bufferTetra.reserve(4096); + bufferHexa.reserve(4096); + + TraversorW trav(m_map) ; + for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + unsigned int degree = 0 ; + + Traversor3WV twv(m_map, d) ; + for(Dart it = twv.begin(); it != twv.end(); it = twv.next()) + { + degree++; + } + + if (degree == 8) + { + //CAS HEXAEDRIQUE (ordre 2 quad superposes, le premier en CW) + bufferHexa.push_back(d); + Dart e = d; + Dart f = m_map.template phi<21121>(d); + hexas.push_back(indices[f]); + f = m_map.phi_1(f); + hexas.push_back(indices[f]); + f = m_map.phi_1(f); + hexas.push_back(indices[f]); + f = m_map.phi_1(f); + hexas.push_back(indices[f]); + hexas.push_back(indices[e]); + e = m_map.phi1(e); + hexas.push_back(indices[e]); + e = m_map.phi1(e); + hexas.push_back(indices[e]); + e = m_map.phi1(e); + hexas.push_back(indices[e]); + } + if (degree == 4) + { + //CAS TETRAEDRIQUE + bufferTetra.push_back(d); + Dart e = d; + tetras.push_back(indices[e]); + e = m_map.phi1(e); + tetras.push_back(indices[e]); + e = m_map.phi1(e); + tetras.push_back(indices[e]); + e = m_map.template phi<211>(e); + tetras.push_back(indices[e]); + } + } + + nbtotal = tetras.size()/4 + hexas.size()/8; + + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + if (bin) + { + binaryMode = true; + f_tempoBin_out = tmpfile(); + offsetAppend = 0; + } + + return true; +} + + +template +template +void VTUExporter::addVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (binaryMode) + return addBinaryVertexAttribute(attrib,vtkType,nbComp,name); + + if (!noCellData) + { + CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; + return; + } + + if (noPointData) + { + fout << "" << std::endl; + noPointData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 (Float32) + nbComp = sizeof(T)/4; + break; + case '4': // 64 (Int64) + nbComp = sizeof(T)/8; + break; + case '8': // 8 (Uint8) + nbComp = sizeof(T); + break; + case '6': // 16 (Int16) + nbComp = sizeof(T)/2; + break; + default: + break; + } + + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + // assume that std::cout of attribute is "c0 c1 c2 ..." + for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i)) + fout << attrib[i] << std::endl; + + fout << "" << std::endl; +} + + + +template +void VTUExporter::endVertexAttributes() +{ + if (!noPointData) + fout << "" << std::endl; + + noPointData = true; +} + + + +template +template +void VTUExporter::addVolumeAttribute(const VolumeAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (binaryMode) + return addBinaryVolumeAttribute(attrib,vtkType,nbComp,name); + + + if (!noPointData) + { + CGoGNerr << "VTUExporter::addVolumeAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; + return; + } + + if (noCellData) + { + fout << "" << std::endl; + noCellData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 (Float32) + nbComp = sizeof(T)/4; + break; + case '4': // 64 (Int64) + nbComp = sizeof(T)/8; + break; + case '8': // 8 (Uint8) + nbComp = sizeof(T); + break; + case '6': // 16 (Int16) + nbComp = sizeof(T)/2; + break; + default: + break; + } + + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + // assume that std::cout of attribute is "c0 c1 c2 ..." + for (typename std::vector::iterator it = bufferTetra.begin(); it != bufferTetra.end(); ++it) + fout << attrib[*it] << std::endl; + for (typename std::vector::iterator it = bufferHexa.begin(); it != bufferHexa.end(); ++it) + fout << attrib[*it] << std::endl; + + fout << "" << std::endl; + +} + +template +void VTUExporter::endVolumeAttributes() +{ + if (!noCellData) + fout << "" << std::endl; + + noCellData = true; +} + + +template +bool VTUExporter::close() +{ + if (binaryMode) + return binaryClose(); + + if (!noPointData) + endVertexAttributes(); + + if (!noCellData) + endVolumeAttributes(); + + fout << "" << std::endl; + fout << "" << 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 << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + for (unsigned int i=0; i" << std::endl; + fout << "" ; + + unsigned int offset = 0; + for (unsigned int i=0; i" << std::endl; + fout << ""; + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + + fout.close(); + closed=true; + return true; +} + + + +// BINARY FUCNTION + +template +template +void VTUExporter::addBinaryVertexAttribute(const VertexAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (!noCellData) + { + CGoGNerr << "VTUExporter::addVertexAttribute: endFaceAttributes before adding VertexAttribute"<< CGoGNendl; + return; + } + + if (noPointData) + { + fout << "" << std::endl; + noPointData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 (Float32) + nbComp = sizeof(T)/4; + break; + case '4': // 64 (Int64) + nbComp = sizeof(T)/8; + break; + case '8': // 8 (Uint8) + nbComp = sizeof(T); + break; + case '6': // 16 (Int16) + nbComp = sizeof(T)/2; + break; + default: + break; + } + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + std::vector buffer; + buffer.reserve(attrib.nbElements()); + + for (unsigned int i = attrib.begin(); i != attrib.end(); attrib.next(i)) + buffer.push_back(attrib[i]); + + unsigned int sz = buffer.size()*sizeof(T); + + fwrite(&sz, sizeof(unsigned int), 1, f_tempoBin_out); // size of block + fwrite(&buffer[0], sizeof(T), buffer.size(), f_tempoBin_out); // block + + offsetAppend += sizeof(T) * buffer.size() + sizeof(unsigned int); +} + + +template +template +void VTUExporter::addBinaryVolumeAttribute(const VolumeAttribute& attrib, const std::string& vtkType, unsigned int nbComp, const std::string& name) +{ + if (!noPointData) + { + CGoGNerr << "VTUExporter::addFaceAttribute: endVertexAttributes before adding FaceAttribute"<< CGoGNendl; + return; + } + + if (noCellData) + { + fout << "" << std::endl; + noCellData = false; + } + + if (nbComp==0) + switch(vtkType[vtkType.size()-1]) + { + case '2': // 32 + nbComp = sizeof(T)/4; + break; + case '4': // 64 + nbComp = sizeof(T)/8; + break; + case '8': // 8 + nbComp = sizeof(T); + break; + case '6': // 16 + nbComp = sizeof(T)/2; + break; + } + + if (name.size() != 0) + fout << "" << std::endl; + else + fout << "" << std::endl; + + std::vector buffer; + buffer.reserve(bufferTetra.size() + bufferHexa.size()); + + for (typename std::vector::iterator it = bufferTetra.begin(); it != bufferTetra.end(); ++it) + buffer.push_back(attrib[*it]); + for (typename std::vector::iterator it = bufferHexa.begin(); it != bufferHexa.end(); ++it) + buffer.push_back(attrib[*it]); + + + unsigned int sz = buffer.size()*sizeof(T); + fwrite(&sz, sizeof(unsigned int), 1, f_tempoBin_out); // size of block + fwrite(&buffer[0], sizeof(T), buffer.size(), f_tempoBin_out); // block + + offsetAppend += sizeof(T) * buffer.size() + sizeof(unsigned int); +} + + +template +bool VTUExporter::binaryClose() +{ + if (!noPointData) + endVertexAttributes(); + + if (!noCellData) + endVolumeAttributes(); + + { // just for scope of std::vector (free memory) + fout << "" << std::endl; + fout << "" << std::endl; + + std::vector buffer; + buffer.reserve(m_position.nbElements()); + + for (unsigned int i = m_position.begin(); i != m_position.end(); m_position.next(i)) + buffer.push_back(m_position[i]); + + unsigned int sz = buffer.size()*sizeof(VEC3); + + offsetAppend += sz + sizeof(unsigned int); + + fwrite(&sz, sizeof(unsigned int), 1, f_tempoBin_out); // size of block + fwrite(&buffer[0], sizeof(VEC3), buffer.size(), f_tempoBin_out); // block + + fout << "" << std::endl; + } + + { // just for scope of std::vector (free memory) + + fout << "" << std::endl; + fout << "" << std::endl; + + std::vector bufferInt; + bufferInt.reserve(tetras.size()+hexas.size()); + + for (unsigned int i=0; i" << std::endl; + + bufferInt.clear(); + unsigned int offset = 0; + for (unsigned int i=0; i" << std::endl; + std::vector bufferUC; + bufferUC.reserve(tetras.size()/3 + hexas.size()/4); + + for (unsigned int i=0; i" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl; + fout << "" << std::endl << "_"; + + fout.close(); + fout.open(m_filename.c_str(), std::ios_base::binary | std::ios_base::ate | std::ios_base::app); + + // copy data from tempo file to final file ! + + long int binLength = ftell(f_tempoBin_out); + rewind (f_tempoBin_out); + + const unsigned int blksz = 1024*1024; + char* buffer = new char[blksz]; + + while (binLength > blksz) + { + fread ( buffer, 1, blksz, f_tempoBin_out); + fout.write((char*)buffer,blksz); + binLength -= blksz; + } + + fread ( buffer, 1, binLength, f_tempoBin_out); + fout.write((char*)buffer,binLength); + + delete[] buffer; + fclose(f_tempoBin_out); + + fout.close(); + fout.open(m_filename.c_str(), std::ios_base::ate | std::ios_base::app); + fout << std::endl << "" << std::endl; + fout << "" << std::endl; + + fout.close(); + closed=true; + return true; +} + + + + +template +VTUExporter::~VTUExporter() +{ + if (!closed) + close(); + closed = true; +} + + + + + +} +} + + +} // namespace Algo + +} // namespace CGoGN diff --git a/include/Utils/compress.h b/include/Utils/compress.h index 392482cf..3b8b89ae 100644 --- a/include/Utils/compress.h +++ b/include/Utils/compress.h @@ -33,7 +33,7 @@ namespace CGoGN namespace Utils { -void zlibWriteCompressed( unsigned char* input, unsigned int nbBytes, std::ofstream& fout); +void zlibVTUWriteCompressed( unsigned char* input, unsigned int nbBytes, std::ofstream& fout); } } diff --git a/src/Utils/compress.cpp b/src/Utils/compress.cpp index 9a892f64..3d1a7354 100644 --- a/src/Utils/compress.cpp +++ b/src/Utils/compress.cpp @@ -26,17 +26,23 @@ #include "Utils/compress.h" #include "zlib.h" +#include +#include +#include + namespace CGoGN { namespace Utils { -void zlibWriteCompressed( unsigned char* input, unsigned int nbBytes, std::ofstream& fout) +void zlibVTUWriteCompressed( unsigned char* input, unsigned int nbBytes, std::ofstream& fout) { - const int CHUNK=16384; + + std::cout << "Compressor Block " << std::endl; + + const int CHUNK=1024*256; int level = 6; // compression level - unsigned char* out = new unsigned char[CHUNK]; z_stream strm; strm.zalloc = Z_NULL; @@ -45,6 +51,13 @@ void zlibWriteCompressed( unsigned char* input, unsigned int nbBytes, std::ofstr int ret = deflateInit(&strm, level); assert(ret == Z_OK); + unsigned char* bufferOut = new unsigned char[nbBytes]; + unsigned char* ptrBufferOut = bufferOut; + + std::vector header; + header.reserve(1024); + header.resize(3); + unsigned char* ptrData = input; int remain = nbBytes; @@ -52,28 +65,43 @@ void zlibWriteCompressed( unsigned char* input, unsigned int nbBytes, std::ofstr { strm.avail_in = std::min(remain,CHUNK); // taille buffer strm.next_in = ptrData; // ptr buffer - do { strm.avail_out = CHUNK; - strm.next_out = out; + strm.next_out = ptrBufferOut; if (remain>= CHUNK) ret = deflate(&strm, 0); else ret = deflate(&strm, 1); assert(ret != Z_STREAM_ERROR); unsigned int have = CHUNK - strm.avail_out; - fout.write((char*)out, have); + ptrBufferOut+=have; + header.push_back(have); } while (strm.avail_out == 0); remain -= CHUNK; ptrData += CHUNK; } - -// assert(ret == Z_STREAM_END); deflateEnd(&strm); - delete[] out; + + header[0] = header.size()-3; + header[1] = CHUNK; + if (remain != 0) + header[2] = remain +CHUNK; + else header[2] = 0; + + std::cout << "HEADER "<< std::endl; + for (unsigned int i=0; i