Commit b50f7b2c authored by Kenneth Vanhoey's avatar Kenneth Vanhoey

binary import/export for SLF

parent a2de5a56
......@@ -455,6 +455,142 @@ bool exportPlySLFgeneric(typename PFP::MAP& map, const typename PFP::TVEC3& posi
return true ;
}
template <typename PFP>
bool exportPlySLFgenericBin(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
typedef typename PFP::TVEC3 TVEC3;
typedef typename PFP::REAL REAL;
typedef typename PFP::TREAL TREAL;
std::ofstream out(filename, std::ios::out | std::ios::binary) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
return false ;
}
AutoAttributeHandler<unsigned int> tableVertLab(map, VERTEX);
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 markV(map, VERTEX);
TraversorF<MAP> t(map, good) ;
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.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;
}
TVEC3 frame[3] ;
std::vector<TVEC3> coefs ;
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") ;
unsigned int i = 0 ;
do {
std::stringstream name ;
name << "SLFcoefs_" << i++ ;
coefs.push_back(map.template getAttribute<VEC3>(VERTEX, name.str())) ;
} while (coefs[i-1].isValid()) ;
const unsigned int nbCoefs = i - 1 ; // last valid one is i-2
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
assert(coefs[coefI].isValid()) ;
std::string file(filename) ;
size_t pos = file.rfind(".") ; // position of "." in filename
std::string extension = file.substr(pos) ;
std::stringstream header ;
header << "ply" << std::endl ;
header << "format binary_little_endian 1.0" << std::endl ;
header << "comment ply SLF (K. Vanhoey generic format): SLF_" << ((extension == ".plyPTMext") ? "PTMext" : "SHreal") << std::endl ;
header << "element vertex " << vertices.size() << std::endl ;
header << "property float x" << std::endl ;
header << "property float y" << std::endl ;
header << "property float z" << std::endl ;
header << "property float tx" << std::endl ;
header << "property float ty" << std::endl ;
header << "property float tz" << std::endl ;
header << "property float bx" << std::endl ;
header << "property float by" << std::endl ;
header << "property float bz" << std::endl ;
header << "property float nx" << std::endl ;
header << "property float ny" << std::endl ;
header << "property float nz" << std::endl ;
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
header << "property float C0_" << coefI << std::endl ;
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
header << "property float C1_" << coefI << std::endl ;
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
header << "property float C2_" << coefI << std::endl ;
header << "element face " << nbf << std::endl ;
header << "property list uchar int vertex_indices" << std::endl ;
header << "end_header" << std::endl ;
size_t nbCharsOfHeader = header.str().size() ;
out.write((char*)nbCharsOfHeader, sizeof(size_t)) ;
out.write((char*)(header.str().c_str()), nbCharsOfHeader*sizeof(char)) ;
for(unsigned int i = 0; i < vertices.size(); ++i)
{
unsigned int vi = vertices[i];
// position
for(unsigned int coord = 0 ; coord < 3 ; ++coord)
out.write((char*)(&(position[vi][coord])), sizeof(float)) ;
// frame
for(unsigned int axis = 0 ; axis < 3 ; ++axis)
for (unsigned int coord = 0 ; coord < 3 ; ++coord)
out.write((char*)(&(frame[axis][vi][coord])), sizeof(float)) ;
// coefficients
for (unsigned int channel = 0 ; channel < 3 ; ++channel)
for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
out.write((char*)(&(coefs[vi][coefI])), sizeof(float)) ;
}
std::vector<unsigned int>::iterator it = faces.begin();
while (it != faces.end())
{
unsigned int nbe = *it++;
out.write((char*)nbe, sizeof(unsigned int)) ;
for(unsigned int j = 0; j < nbe; ++j)
out.write((char*)(*it++), sizeof(unsigned int)) ;
}
out.close() ;
return true ;
}
template <typename PFP>
bool exportPLYPTM(typename PFP::MAP& map, const char* filename, const typename PFP::TVEC3& position, const typename PFP::TVEC3 frame[3], const typename PFP::TVEC3 colorPTM[6], const FunctorSelect& good)
......
......@@ -52,7 +52,7 @@ namespace Import
namespace ImportSurfacique
{
enum ImportType { UNKNOWNSURFACE, TRIAN, TRIANBGZ, MESHBIN, PLY, PLYPTM, PLYSLFgeneric, OFF, OBJ, VRML, AHEM };
enum ImportType { UNKNOWNSURFACE, TRIAN, TRIANBGZ, MESHBIN, PLY, PLYPTM, PLYSLFgeneric, PLYSLFgenericBin, OFF, OBJ, VRML, AHEM };
}
namespace ImportVolumique
......@@ -117,6 +117,7 @@ public:
bool importPlyPTM(const std::string& filename, std::vector<std::string>& attrNames);
bool importPlySLFgeneric(const std::string& filename, std::vector<std::string>& attrNames);
bool importPlySLFgenericBin(const std::string& filename, std::vector<std::string>& attrNames);
#ifdef WITH_ASSIMP
bool importASSIMP(const std::string& filename, std::vector<std::string>& attrNames);
......
......@@ -61,6 +61,9 @@ ImportSurfacique::ImportType MeshTablesSurface<PFP>::getFileType(const std::stri
if ((filename.rfind(".plyPTMext")!=std::string::npos) || (filename.rfind(".plySHreal")!=std::string::npos))
return ImportSurfacique::PLYSLFgeneric;
if ((filename.rfind(".plyPTMextBin")!=std::string::npos) || (filename.rfind(".plySHrealBin")!=std::string::npos))
return ImportSurfacique::PLYSLFgeneric;
if ((filename.rfind(".ply")!=std::string::npos) || (filename.rfind(".PLY")!=std::string::npos))
return ImportSurfacique::PLY;
......@@ -114,6 +117,11 @@ bool MeshTablesSurface<PFP>::importMesh(const std::string& filename, std::vector
CGoGNout << "TYPE: PLYSLFgeneric" << CGoGNendl;
return importPlySLFgeneric(filename, attrNames);
break;
case ImportSurfacique::PLYSLFgenericBin:
CGoGNout << "TYPE: PLYSLFgenericBin" << CGoGNendl;
return importPlySLFgenericBin(filename, attrNames);
break;
case ImportSurfacique::OBJ:
CGoGNout << "TYPE: OBJ" << CGoGNendl;
return importObj(filename, attrNames);
......@@ -785,6 +793,163 @@ bool MeshTablesSurface<PFP>::importPlySLFgeneric(const std::string& filename, st
return true ;
}
template <typename PFP>
bool MeshTablesSurface<PFP>::importPlySLFgenericBin(const std::string& filename, std::vector<std::string>& attrNames)
{
// Open file
std::ifstream fp(filename.c_str(), std::ios::in | std::ios::binary) ;
if (!fp.good())
{
CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
return false ;
}
// read CHNum
unsigned int CHNum ;
fp.read((char*)&CHNum, sizeof(unsigned int)) ;
char* headerTab = new char[CHNum] ;
fp.read(headerTab, CHNum) ;
std::stringstream header(headerTab) ;
// Read quantities : #vertices, #faces, #properties, degree of polynomials
std::string tag ;
header >> tag;
if (tag != std::string("ply")) // verify file type
{
CGoGNerr << filename << " is not a ply file !" << CGoGNout ;
return false ;
}
do // go to #vertices
{
header >> tag ;
} while (tag != std::string("vertex")) ;
unsigned int nbVertices ;
header >> nbVertices ; // Read #vertices
bool position = false ;
bool tangent = false ;
bool binormal = false ;
bool normal = false ;
unsigned int nbProps = 0 ; // # properties
unsigned int nbCoefsPerPol = 0 ; // # coefficients per polynomial
do // go to #faces and count #properties
{
header >> tag ;
if (tag == std::string("property"))
++nbProps ;
if (tag == std::string("x") || tag == std::string("y") || tag == std::string("z"))
position = true ;
else if (tag == std::string("tx") || tag == std::string("ty") || tag == std::string("tz"))
tangent = true ;
else if (tag == std::string("bx") || tag == std::string("by") || tag == std::string("bz"))
binormal = true ;
else if (tag == std::string("nx") || tag == std::string("ny") || tag == std::string("nz"))
normal = true ;
if (tag.substr(0,1) == std::string("C") && tag.substr(2,1) == std::string("_"))
++nbCoefsPerPol ;
} while (tag != std::string("face")) ;
unsigned int nbRemainders = nbProps ; // # remaining properties
nbRemainders -= nbCoefsPerPol + 3*(position==true) + 3*(tangent==true) + 3*(binormal==true) + 3*(normal==true) ;
nbCoefsPerPol /= 3 ;
header >> m_nbFaces ; // Read #vertices
do // go to end of header
{
header >> tag ;
} while (tag != std::string("end_header")) ;
std::cout << header.str() << std::endl ;
/*
// Define containers
AttributeHandler<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
if (!positions.isValid())
positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
attrNames.push_back(positions.name()) ;
AttributeHandler<typename PFP::VEC3> *frame = new AttributeHandler<typename PFP::VEC3>[3] ;
frame[0] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_T") ; // Tangent
frame[1] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_B") ; // Bitangent
frame[2] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_N") ; // Normal
attrNames.push_back(frame[0].name()) ;
attrNames.push_back(frame[1].name()) ;
attrNames.push_back(frame[2].name()) ;
AttributeHandler<typename PFP::VEC3> *SLFcoefs = new AttributeHandler<typename PFP::VEC3>[nbCoefsPerPol] ;
for (unsigned int i = 0 ; i < nbCoefsPerPol ; ++i)
{
std::stringstream name ;
name << "SLFcoefs_" << i ;
SLFcoefs[i] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, name.str()) ;
attrNames.push_back(SLFcoefs[i].name()) ;
}
AttributeHandler<typename PFP::REAL> *remainders = new AttributeHandler<typename PFP::REAL>[nbRemainders] ;
for (unsigned int i = 0 ; i < nbRemainders ; ++i)
{
std::stringstream name ;
name << "remainderNo" << i ;
remainders[i] = m_map.template addAttribute<typename PFP::REAL>(VERTEX, name.str()) ;
attrNames.push_back(remainders[i].name()) ;
}
// Read vertices
std::vector<unsigned int> verticesID ;
verticesID.reserve(nbVertices) ;
float* properties = new float[nbProps] ;
AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
for (unsigned int i = 0 ; i < nbVertices ; ++i) // Read and store properties for current vertex
{
unsigned int id = container.insertLine() ;
verticesID.push_back(id) ;
for (unsigned int j = 0 ; j < nbProps ; ++j) // get all properties
fp >> properties[j] ;
positions[id] = VEC3(properties[0],properties[1],properties[2]) ; // position
for (unsigned int k = 0 ; k < 3 ; ++k) // frame
for (unsigned int l = 0 ; l < 3 ; ++l)
frame[k][id][l] = properties[3+(3*k+l)] ;
for (unsigned int k = 0 ; k < 3 ; ++k) // coefficients
for (unsigned int l = 0 ; l < nbCoefsPerPol ; ++l)
SLFcoefs[l][id][k] = properties[12+(nbCoefsPerPol*k+l)] ;
unsigned int cur = 12+3*nbCoefsPerPol ;
for (unsigned int k = 0 ; k < nbRemainders ; ++k) // remaining data
remainders[k][id] = properties[cur + k] ;
}
m_nbVertices = verticesID.size() ;
delete[] properties ;
// Read faces index
m_nbEdges.reserve(m_nbFaces) ;
m_emb.reserve(3 * m_nbFaces) ;
for (unsigned int i = 0 ; i < m_nbFaces ; ++i)
{
// read the indices of vertices for current face
int nbEdgesForFace ;
fp >> nbEdgesForFace ;
m_nbEdges.push_back(nbEdgesForFace);
int vertexID ;
for (int j=0 ; j < nbEdgesForFace ; ++j)
{
fp >> vertexID ;
m_emb.push_back(verticesID[vertexID]);
}
}
// Close file
fp.close() ;
*/
return true ;
}
/**
* Import plyPTM (F Larue format).
* It handles only 2nd degree polynomials
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment