Commit 89e3f3c0 authored by Sylvain Thery's avatar Sylvain Thery

first working version of export NAS file

parent 6186932b
......@@ -40,6 +40,14 @@ namespace Volume
namespace Export
{
std::string truncFloatTO8(float f)
{
std::stringstream ss;
ss << f;
std::string res = ss.str();
return res.substr(0,8);
}
template <typename PFP>
bool exportNAS(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
{
......@@ -58,19 +66,26 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
VertexAutoAttribute<unsigned int> indices(map,"indices_vert");
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
fout << "$$ NASTRAN MEsh File Generated by CGoGN (ICube/IGG) $"<< std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
fout << "CEND" << std::endl;;
fout << "BEGIN BULK" << std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
fout << "$$ Vertices position $"<< std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
unsigned int count=1;
fout .width(8);
for (unsigned int i = position.begin(); i != position.end(); position.next(i))
{
const VEC3& P = position[i];
fout << "GRID ";
fout << std::right;
fout.width(8);
fout << count;
fout << " ";
fout << std::left;
fout << P[0] << P[1] << P[2] << std::endl;
fout << std::setw(8)<<truncFloatTO8(P[0]) << std::setw(8)<<truncFloatTO8(P[1]) << std::setw(8)<<truncFloatTO8(P[2]) << std::endl;
indices[i] = count++;
}
......@@ -128,27 +143,41 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
unsigned int countCell=1;
unsigned int nbhexa = hexa.size()/8;
unsigned int nbtetra = tetra.size()/8;
unsigned int nbtetra = tetra.size()/4;
for (unsigned int i=0; i<nbhexa; ++i)
fout << std::right;
if (nbhexa!=0)
{
fout << "CHEXA ";
fout << std::right;
fout << countCell++;
fout << hexa[8*i] << hexa[8*i+1] << hexa[8*i+2] << hexa[8*i+3] << hexa[8*i+4] << hexa[8*i+6] << "+";
fout << "+ " << hexa[8*i+6] << hexa[8*i+7] << std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
fout << "$$ Hexa indices $"<< std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
for (unsigned int i=0; i<nbhexa; ++i)
{
fout << "CHEXA ";
fout << std::setw(8) << countCell++ << std::setw(8)<< 0;
fout << std::setw(8) << hexa[8*i] << std::setw(8) << hexa[8*i+1] << std::setw(8) << hexa[8*i+2];
fout << std::setw(8) << hexa[8*i+3] << std::setw(8) << hexa[8*i+4] << std::setw(8) << hexa[8*i+6] << "+"<< std::endl;
fout << "+ " << std::setw(8) << hexa[8*i+6] << std::setw(8) << hexa[8*i+7] << std::endl;
}
}
for (unsigned int i=0; i<nbtetra; ++i)
if (nbtetra != 0)
{
fout << "CTETRA ";
fout << std::right;
fout << countCell++;
fout << tetra[4*i] << tetra[4*i+1] << tetra[4*i+2] << tetra[4*i+3] << std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
fout << "$$ Tetra indices $"<< std::endl;
fout << "$$ ---------------------------------------------------------------------------- $"<< std::endl;
for (unsigned int i=0; i<nbtetra; ++i)
{
fout << "CTETRA ";
fout << std::setw(8) << countCell++ << std::setw(8)<< 0;
fout << std::setw(8) << tetra[4*i] << std::setw(8) << tetra[4*i+1] << std::setw(8) << tetra[4*i+2] << std::setw(8) << tetra[4*i+3] << std::endl;
}
}
fout << "ENDDATA" << std::endl;
return true;
}
......@@ -215,982 +244,6 @@ bool exportNodeEle(typename PFP::MAP& map, const VertexAttribute<typename PFP::V
}
template <typename PFP>
bool exportPLY(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename, bool binary)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
// open file
std::ofstream out ;
if (!binary)
out.open(filename, std::ios::out) ;
else
out.open(filename, std::ios::out | std::ios::binary) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << CGoGNendl ;
return false ;
}
unsigned int nbDarts = map.getNbDarts() ;
std::vector<unsigned int> facesSize ;
std::vector<std::vector<unsigned int> > facesIdx ;
facesSize.reserve(nbDarts/3) ;
facesIdx.reserve(nbDarts/3) ;
std::map<unsigned int, unsigned int> vIndex ;
unsigned int vCpt = 0 ;
std::vector<unsigned int> vertices ;
vertices.reserve(nbDarts/6) ;
// Go over all faces
CellMarker<VERTEX> markV(map) ;
TraversorF<MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
std::vector<unsigned int> fidx ;
fidx.reserve(8) ;
unsigned int degree = 0 ;
Traversor2FV<typename PFP::MAP> tfv(map, d) ;
for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
{
++degree ;
unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
if(!markV.isMarked(it))
{
markV.mark(it) ;
vIndex[vNum] = vCpt++ ;
vertices.push_back(vNum) ;
}
fidx.push_back(vIndex[vNum]) ;
}
facesSize.push_back(degree) ;
facesIdx.push_back(fidx) ;
}
// Start writing the file
out << "ply" << std::endl ;
// ascii or binary
if (!binary)
out << "format ascii 1.0" << std::endl ;
else
{ // test endianness
union
{
uint32_t i ;
char c[4] ;
} bint = {0x01020304} ;
if (bint.c[0] == 1) // big endian
out << "format binary_big_endian 1.0" << std::endl ;
else
out << "format binary_little_endian 1.0" << std::endl ;
}
out << "comment File generated by the CGoGN library" << std::endl ;
out << "comment See : http://cgogn.unistra.fr/" << std::endl ;
out << "comment or contact : cgogn@unistra.fr" << std::endl ;
// Vertex elements
out << "element vertex " << vertices.size() << std::endl ;
// Position property
if (position.isValid())
{
out << "property " << nameOfTypePly(position[0][0]) << " x" << std::endl ;
out << "property " << nameOfTypePly(position[0][1]) << " y" << std::endl ;
out << "property " << nameOfTypePly(position[0][2]) << " z" << std::endl ;
}
// Face element
out << "element face " << facesSize.size() << std::endl ;
out << "property list uint8 uint" << 8 * sizeof(facesIdx[0][0]) << " vertex_indices" << std::endl ;
out << "end_header" << std::endl ;
if (!binary) // ascii
{
// ascii vertices
for(unsigned int i = 0; i < vertices.size(); ++i)
out << position[vertices[i]] << std::endl ;
// ascii faces
for(unsigned int i = 0; i < facesSize.size(); ++i)
{
out << facesSize[i] ;
for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
out << " " << facesIdx[i][j] ;
out << std::endl ;
}
}
else // binary
{
// binary vertices
for(unsigned int i = 0; i < vertices.size(); ++i)
{
Geom::Vec3f v = position[vertices[i]] ;
out.write((char*)(&(v[0])), sizeof(v)) ;
}
// binary faces
for(unsigned int i = 0; i < facesSize.size(); ++i)
{
unsigned char nbe = facesSize[i] ;
out.write((char*)(&nbe), sizeof(unsigned char)) ;
out.write((char*)(&(facesIdx[i][0])), facesSize[i] * sizeof(facesIdx[i][0])) ;
}
}
out.close() ;
return true ;
}
template <typename PFP>
bool exportPLYnew(typename PFP::MAP& map, const std::vector<VertexAttribute<typename PFP::VEC3>*>& attributeHandlers, const char* filename, bool binary)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
// open file
std::ofstream out ;
if (!binary)
out.open(filename, std::ios::out) ;
else
out.open(filename, std::ios::out | std::ios::binary) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << CGoGNendl ;
return false ;
}
unsigned int nbDarts = map.getNbDarts() ;
std::vector<unsigned int> facesSize ;
std::vector<std::vector<unsigned int> > facesIdx ;
facesSize.reserve(nbDarts/3) ;
facesIdx.reserve(nbDarts/3) ;
std::map<unsigned int, unsigned int> vIndex ;
unsigned int vCpt = 0 ;
std::vector<unsigned int> vertices ;
vertices.reserve(nbDarts/6) ;
// Go over all faces
CellMarker<VERTEX> markV(map) ;
TraversorF<MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
std::vector<unsigned int> fidx ;
fidx.reserve(8) ;
unsigned int degree = 0 ;
Traversor2FV<typename PFP::MAP> tfv(map, d) ;
for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
{
++degree ;
unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
if(!markV.isMarked(it))
{
markV.mark(it) ;
vIndex[vNum] = vCpt++ ;
vertices.push_back(vNum) ;
}
fidx.push_back(vIndex[vNum]) ;
}
facesSize.push_back(degree) ;
facesIdx.push_back(fidx) ;
}
// Start writing the file
out << "ply" << std::endl ;
// ascii or binary
if (!binary)
out << "format ascii 1.0" << std::endl ;
else
{ // test endianness
union
{
uint32_t i ;
char c[4] ;
} bint = {0x01020304} ;
if (bint.c[0] == 1) // big endian
out << "format binary_big_endian 1.0" << std::endl ;
else
out << "format binary_little_endian 1.0" << std::endl ;
}
out << "comment File generated by the CGoGN library" << std::endl ;
out << "comment See : http://cgogn.unistra.fr/" << std::endl ;
out << "comment or contact : cgogn@unistra.fr" << std::endl ;
// Vertex elements
out << "element vertex " << vertices.size() << std::endl ;
for (typename std::vector<VertexAttribute<typename PFP::VEC3>* >::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
{
if ((*attrHandler)->isValid() && ((*attrHandler)->getOrbit() == VERTEX) )
{
if ((*attrHandler)->name().compare("position") == 0) // Vertex position property
{
out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " x" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " y" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " z" << std::endl ;
}
else if ((*attrHandler)->name().compare("normal") == 0) // normal property
{
out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " nx" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " ny" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " nz" << std::endl ;
}
else if ((*attrHandler)->name().compare("color") == 0) // vertex color property
{
out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " r" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " g" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " b" << std::endl ;
}
else // other vertex properties
{
out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " " << (*attrHandler)->name() << "_0" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " " << (*attrHandler)->name() << "_1" << std::endl ;
out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " " << (*attrHandler)->name() << "_2" << std::endl ;
}
}
}
// Face element
out << "element face " << facesSize.size() << std::endl ;
out << "property list uint8 " << nameOfTypePly(facesIdx[0][0]) << " vertex_indices" << std::endl ;
out << "end_header" << std::endl ;
if (!binary) // ascii
{
// ascii vertices
for(unsigned int i = 0; i < vertices.size(); ++i)
{
for (typename std::vector<VertexAttribute<typename PFP::VEC3>* >::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
if ((*attrHandler)->isValid() && (*attrHandler)->getOrbit() == VERTEX)
out << (*(*attrHandler))[vertices[i]] ;
out << std::endl ;
}
// ascii faces
for(unsigned int i = 0; i < facesSize.size(); ++i)
{
out << facesSize[i] ;
for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
out << " " << facesIdx[i][j] ;
out << std::endl ;
}
}
else // binary
{
// binary vertices
for(unsigned int i = 0; i < vertices.size(); ++i)
for (typename std::vector<VertexAttribute<typename PFP::VEC3>*>::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
if ((*attrHandler)->isValid() && (*attrHandler)->getOrbit() == VERTEX)
{
const typename PFP::VEC3& v = (*(*attrHandler))[vertices[i]] ;
out.write((char*)(&(v[0])), sizeof(v)) ;
}
// binary faces
for(unsigned int i = 0; i < facesSize.size(); ++i)
{
uint8_t nbe = facesSize[i] ;
out.write((char*)(&nbe), sizeof(uint8_t)) ;
out.write((char*)(&(facesIdx[i][0])), facesSize[i] * sizeof(facesIdx[i][0])) ;
}
}
out.close() ;
return true ;
}
template <typename PFP>
bool exportOFF(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
std::ofstream out(filename, std::ios::out) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << CGoGNendl ;
return false ;
}
unsigned int nbDarts = map.getNbDarts() ;
std::vector<unsigned int> facesSize ;
std::vector<std::vector<unsigned int> > facesIdx ;
facesSize.reserve(nbDarts/3) ;
facesIdx.reserve(nbDarts/3) ;
std::map<unsigned int, unsigned int> vIndex ;
unsigned int vCpt = 0 ;
std::vector<unsigned int> vertices ;
vertices.reserve(nbDarts/6) ;
CellMarker<VERTEX> markV(map) ;
TraversorF<MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
std::vector<unsigned int> fidx ;
fidx.reserve(8) ;
unsigned int degree = 0 ;
Traversor2FV<typename PFP::MAP> tfv(map, d) ;
for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
{
++degree ;
unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
if(!markV.isMarked(it))
{
markV.mark(it) ;
vIndex[vNum] = vCpt++ ;
vertices.push_back(vNum) ;
}
fidx.push_back(vIndex[vNum]) ;
}
facesSize.push_back(degree) ;
facesIdx.push_back(fidx) ;
}
out << "OFF" << std::endl ;
out << vertices.size() << " " << facesSize.size() << " " << 0 << std::endl ;
for(unsigned int i = 0; i < vertices.size(); ++i)
{
const VEC3& v = position[vertices[i]] ;
out << v[0] << " " << v[1] << " " << v[2] << std::endl ;
}
for(unsigned int i = 0; i < facesSize.size(); ++i)
{
out << facesSize[i] ;
for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
out << " " << facesIdx[i][j] ;
out << std::endl ;
}
out.close() ;
return true ;
}
/*
template <typename PFP>
bool exportOBJ(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
std::ofstream out(filename, std::ios::out) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << CGoGNendl ;
return false ;
}
unsigned int nbDarts = map.getNbDarts() ;
std::vector<unsigned int> facesSize ;
std::vector<std::vector<unsigned int> > facesIdx ;
facesSize.reserve(nbDarts/3) ;
facesIdx.reserve(nbDarts/3) ;
std::map<unsigned int, unsigned int> vIndex ;
unsigned int vCpt = 0 ;
std::vector<unsigned int> vertices ;
vertices.reserve(nbDarts/6) ;
CellMarker<VERTEX> markV(map) ;
TraversorF<MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
std::vector<unsigned int> fidx ;
fidx.reserve(8) ;
Traversor2FV<typename PFP::MAP> tfv(map, d) ;
for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
{
unsigned int vNum = map.getEmbedding(VERTEX, it) ;
if(!markV.isMarked(it))
{
markV.mark(it) ;
vIndex[vNum] = vCpt++ ;
vertices.push_back(vNum) ;
}
fidx.push_back(vIndex[vNum]+1) ;
}
facesIdx.push_back(fidx) ;
}
out << "#OBJ - Export from CGoGN" << std::endl ;
for(unsigned int i = 0; i < vertices.size(); ++i)
{
const VEC3& v = position[vertices[i]] ;
out << "v " << v[0] << " " << v[1] << " " << v[2] << std::endl ;
}
out << std::endl;
for(unsigned int i = 0; i < facesIdx.size(); ++i)
{
out << "f ";
for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
out << " " << facesIdx[i][j] ;
out << std::endl ;
}
out.close() ;
return true ;
}
template <typename PFP>
bool exportPlyPTMgeneric(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
typedef typename PFP::REAL REAL;
std::ofstream out(filename, std::ios::out) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
return false ;
}
VertexAutoAttribute<unsigned int> tableVertLab(map);
unsigned int nbDarts = map.getNbDarts() ;
std::vector<unsigned int> vertices;
std::vector<unsigned int> faces;
vertices.reserve(nbDarts/5); // TODO non optimal reservation
faces.reserve(nbDarts/3);
CellMarker<VERTEX> markV(map);
TraversorF<MAP> t(map) ;
unsigned int lab = 0;
unsigned int nbf = 0;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
std::vector<unsigned int> face ;
Traversor2FV<typename PFP::MAP> tfv(map, d) ;
for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
{
if (!markV.isMarked(it))
{
markV.mark(it);
tableVertLab[it] = lab++;
vertices.push_back(map.template getEmbedding<VERTEX>(it));
}
face.push_back(tableVertLab[it]);
}
faces.push_back(face.size()) ;
for (unsigned int i = 0 ; i < face.size() ; ++i)
faces.push_back(face.at(i)) ;
++nbf;
}
VertexAttribute<VEC3> frame[3] ;
VertexAttribute<VEC3> colorPTM[15] ;
frame[0] = map.template getAttribute<VEC3>(VERTEX, "frame_T") ;
frame[1] = map.template getAttribute<VEC3>(VERTEX, "frame_B") ;
frame[2] = map.template getAttribute<VEC3>(VERTEX, "frame_N") ;
for (unsigned int i = 0 ; i < 15 ; ++i)
{
std::stringstream name ;
name << "colorPTM_a" << i ;
colorPTM[i] = map.template getAttribute<VEC3>(VERTEX,name.str()) ;
}
const unsigned int nbCoefs = colorPTM[14].isValid() ? 15 : (colorPTM[9].isValid() ? 10 : 6) ;
out << "ply" << std::endl ;
out << "format ascii 1.0" << std::endl ;
out << "comment ply PTM (K. Vanhoey generic format)" << std::endl ;
out << "element vertex " << vertices.size() << std::endl ;
out << "property float x" << std::endl ;
out << "property float y" << std::endl ;
out << "property float z" << std::endl ;
out << "property float tx" << std::endl ;
out << "property float ty" << std::endl ;
out << "property float tz" << std::endl ;
out << "property float bx" << std::endl ;
out << "property float by" << std::endl ;
out << "property float bz" << std::endl ;
out << "property float nx" << std::endl ;
out << "property float ny" << std::endl ;
out << "property float nz" << std::endl ;
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
out << "property float C0_a" << coefI << std::endl ;
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
out << "property float C1_a" << coefI << std::endl ;
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
out << "property float C2_a" << coefI << std::endl ;
VertexAttribute<REAL> errL2 = map.template getAttribute<REAL>(VERTEX, "errL2") ;
VertexAttribute<REAL> errLmax = map.template getAttribute<REAL>(VERTEX, "errLmax") ;
VertexAttribute<REAL> stdDev = map.template getAttribute<REAL>(VERTEX, "stdDev") ;
if (errL2.isValid())
out << "property float errL2" << std::endl ;
if (errLmax.isValid())
out << "property float errLmax" << std::endl ;
if (stdDev.isValid())
out << "property float stdDev" << std::endl ;
out << "element face " << nbf << std::endl ;