Commit 0c1647ba authored by Sylvain Thery's avatar Sylvain Thery

export vtu binary with attributes for 2/3 maps

parent 9238a53c
......@@ -93,144 +93,6 @@ template <typename PFP>
bool exportTrian(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& 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 <typename PFP>
bool exportVTU(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename);
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
{
protected:
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
typename PFP::MAP& m_map;
const VertexAttribute<typename PFP::VEC3>& m_position;
unsigned int nbtotal;
bool noPointData;
bool noCellData;
bool closed;
std::ofstream fout ;
std::vector<unsigned int> triangles;
std::vector<unsigned int> quads;
std::vector<unsigned int> others;
std::vector<unsigned int> others_begin;
std::vector<Dart> bufferTri;
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:
VTUExporter(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& 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<typename T>
void addVertexAttributeScal(const VertexAttribute<T>& 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<typename T>
void addVertexAttributeVect(const VertexAttribute<T>& 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<typename T>
void addFaceAttributeScal(const FaceAttribute<T>& 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<typename T>
void addFaceAttributeVect(const FaceAttribute<T>& 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).
......
......@@ -1020,1211 +1020,6 @@ bool exportChoupi(typename PFP::MAP& map, const AttributeHandler<typename PFP::V
template <typename PFP>
bool exportVTU(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::out) ;
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=\"BigEndian\">" << std::endl;
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;
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 << "</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;
}
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();
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)
{
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<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);