From ca65cf2162d44c59a086bb9b69f2973e859a808f Mon Sep 17 00:00:00 2001 From: "T.Alderighi" Date: Tue, 10 Sep 2019 15:42:41 +0200 Subject: [PATCH] added support for face normals export and import and face (double precision) quality export and import for ply format --- wrap/io_trimesh/export_ply.h | 19 + wrap/io_trimesh/import_ply.h | 2253 +++++++++++++++++----------------- 2 files changed, 1164 insertions(+), 1108 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 1b8d6b8d..1e641a89 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -263,6 +263,14 @@ namespace vcg { ); } + if (HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL)) + { + const char* fntp = vcg::tri::io::Precision::typeName(); + fprintf(fpout, "property %s nx\n", fntp); + fprintf(fpout, "property %s ny\n", fntp); + fprintf(fpout, "property %s nz\n", fntp); + } + if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) { const char* fqtp = vcg::tri::io::Precision::typeName(); @@ -612,6 +620,14 @@ namespace vcg { } } + if( HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL) ) + { + ScalarType t; + t = ScalarType(fp->N()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(fp->N()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(fp->N()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); + } + if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout); @@ -695,6 +711,9 @@ namespace vcg { ); } + if (HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL)) + fprintf(fpout,"%.*g %.*g %.*g " ,DGT, ScalarType(fp->N()[0]),DGT,ScalarType(fp->N()[1]),DGT,ScalarType(fp->N()[2])); + if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) fprintf(fpout,"%.*g ",DGTFQ,fp->Q()); diff --git a/wrap/io_trimesh/import_ply.h b/wrap/io_trimesh/import_ply.h index dfb030d3..75fd59d8 100644 --- a/wrap/io_trimesh/import_ply.h +++ b/wrap/io_trimesh/import_ply.h @@ -56,1126 +56,1163 @@ class ImporterPLY { public: -typedef ::vcg::ply::PropDescriptor PropDescriptor ; -typedef typename OpenMeshType::VertexPointer VertexPointer; -typedef typename OpenMeshType::ScalarType ScalarType; -typedef typename OpenMeshType::VertexType VertexType; -typedef typename OpenMeshType::FaceType FaceType; -typedef typename OpenMeshType::VertexIterator VertexIterator; -typedef typename OpenMeshType::FaceIterator FaceIterator; -typedef typename OpenMeshType::EdgeIterator EdgeIterator; + typedef ::vcg::ply::PropDescriptor PropDescriptor ; + typedef typename OpenMeshType::VertexPointer VertexPointer; + typedef typename OpenMeshType::ScalarType ScalarType; + typedef typename OpenMeshType::VertexType VertexType; + typedef typename VertexType::QualityType VertQualityType; + typedef typename OpenMeshType::FaceType FaceType; + typedef typename FaceType::QualityType FaceQualityType; + + typedef typename OpenMeshType::VertexIterator VertexIterator; + typedef typename OpenMeshType::FaceIterator FaceIterator; + typedef typename OpenMeshType::EdgeIterator EdgeIterator; #define MAX_USER_DATA 256 -// Auxiliary structure for reading ply files -struct LoadPly_FaceAux -{ - unsigned char size; - int v[512]; - int flags; - float q; - float texcoord[32]; - unsigned char ntexcoord; - int texcoordind; - float colors[32]; - unsigned char ncolors; + // Auxiliary structure for reading ply files + template + struct LoadPly_FaceAux + { + unsigned char size; + int v[512]; + int flags; + S n[3]; + S q; + float texcoord[32]; + unsigned char ntexcoord; + int texcoordind; + float colors[32]; + unsigned char ncolors; - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; - unsigned char data[MAX_USER_DATA]; -}; + unsigned char data[MAX_USER_DATA]; + }; -struct LoadPly_TristripAux -{ - int size; - int *v; - unsigned char data[MAX_USER_DATA]; -}; + struct LoadPly_TristripAux + { + int size; + int *v; + unsigned char data[MAX_USER_DATA]; + }; -struct LoadPly_EdgeAux -{ - int v1,v2; - unsigned char data[MAX_USER_DATA]; -}; + struct LoadPly_EdgeAux + { + int v1,v2; + unsigned char data[MAX_USER_DATA]; + }; -// Yet another auxiliary data structure for loading some strange ply files -// the original stanford range data... -struct LoadPly_RangeGridAux { - unsigned char num_pts; - int pts[5]; -}; + // Yet another auxiliary data structure for loading some strange ply files + // the original stanford range data... + struct LoadPly_RangeGridAux { + unsigned char num_pts; + int pts[5]; + }; -// Auxiliary structure to load vertex data -template -struct LoadPly_VertAux -{ - S p[3]; - S n[3]; - int flags; - S q; // the confidence - float intensity; - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - unsigned char data[MAX_USER_DATA]; - float radius; - float u,v,w; -}; + // Auxiliary structure to load vertex data + template + struct LoadPly_VertAux + { + S p[3]; + S n[3]; + int flags; + S q; // the confidence + float intensity; + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + unsigned char data[MAX_USER_DATA]; + float radius; + float u,v,w; + }; -// Auxiliary structure to load the camera -struct LoadPly_Camera -{ - float view_px; - float view_py; - float view_pz; - float x_axisx; - float x_axisy; - float x_axisz; - float y_axisx; - float y_axisy; - float y_axisz; - float z_axisx; - float z_axisy; - float z_axisz; - float focal; - float scalex; - float scaley; - float centerx; - float centery; - int viewportx; - int viewporty; - float k1; - float k2; - float k3; - float k4; -}; + // Auxiliary structure to load the camera + struct LoadPly_Camera + { + float view_px; + float view_py; + float view_pz; + float x_axisx; + float x_axisy; + float x_axisz; + float y_axisx; + float y_axisy; + float y_axisz; + float z_axisx; + float z_axisy; + float z_axisz; + float focal; + float scalex; + float scaley; + float centerx; + float centery; + int viewportx; + int viewporty; + float k1; + float k2; + float k3; + float k4; + }; #define _VERTDESC_LAST_ 32 -static const PropDescriptor &VertDesc(int i) -{ - static const PropDescriptor pv[_VERTDESC_LAST_]={ -/*00*/ {"vertex", "x", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p),0,0,0,0,0 ,0}, -/*01*/ {"vertex", "y", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p) + sizeof(ScalarType),0,0,0,0,0 ,0}, -/*02*/ {"vertex", "z", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, -/*03*/ {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux,flags),0,0,0,0,0 ,0}, -/*04*/ {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,q),0,0,0,0,0 ,0}, -/*05*/ {"vertex", "red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,r),0,0,0,0,0 ,0}, -/*06*/ {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,g),0,0,0,0,0 ,0}, -/*07*/ { "vertex", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,b),0,0,0,0,0 ,0}, -/*08*/ { "vertex", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,a),0,0,0,0,0 ,0}, -/*09*/ {"vertex", "diffuse_red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,r),0,0,0,0,0 ,0}, -/*10*/ {"vertex", "diffuse_green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,g),0,0,0,0,0 ,0}, -/*11*/ {"vertex", "diffuse_blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,b),0,0,0,0,0 ,0}, -/*12*/ {"vertex", "diffuse_alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,a),0,0,0,0,0 ,0}, -/*13*/ {"vertex", "confidence", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,q),0,0,0,0,0 ,0}, -/*14*/ {"vertex", "nx", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,n) ,0,0,0,0,0 ,0}, -/*15*/ {"vertex", "ny", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, -/*16*/ {"vertex", "nz", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, -/*17*/ {"vertex", "radius", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,radius),0,0,0,0,0 ,0}, -/*18*/ {"vertex", "texture_u", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,u),0,0,0,0,0 ,0}, -/*19*/ {"vertex", "texture_v", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,v),0,0,0,0,0 ,0}, -/*20*/ {"vertex", "texture_w", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,w),0,0,0,0,0 ,0}, -/*21*/ {"vertex", "intensity", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,intensity),0,0,0,0,0 ,0}, -/*22*/ {"vertex", "s", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,u),0,0,0,0,0 ,0}, -/*23*/ {"vertex", "t", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,v),0,0,0,0,0 ,0}, -// DOUBLE -/*24*/ {"vertex", "x", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,p),0,0,0,0,0 ,0}, -/*25*/ {"vertex", "y", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,p) + sizeof(ScalarType) ,0,0,0,0,0 ,0}, -/*26*/ {"vertex", "z", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, -/*27*/ {"vertex", "nx", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,n) ,0,0,0,0,0 ,0}, -/*28*/ {"vertex", "ny", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, -/*29*/ {"vertex", "nz", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, -/*30*/ {"vertex", "radius", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,radius),0,0,0,0,0 ,0}, -/*31*/ {"vertex", "quality", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,q),0,0,0,0,0 ,0} - }; - return pv[i]; -} - -#define _FACEDESC_FIRST_ 10 // the first descriptor with possible vertex indices -#define _FACEDESC_LAST_ 22 -static const PropDescriptor &FaceDesc(int i) -{ - static const PropDescriptor qf[_FACEDESC_LAST_]= - { -/* on file on memory on file on memory */ -/* 0 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 1 */ {"face", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,flags), 0,0,0,0,0 ,0}, -/* 2 */ {"face", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,q), 0,0,0,0,0 ,0}, -/* 3 */ {"face", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,texcoord), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux,ntexcoord) ,0}, -/* 4 */ {"face", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,colors), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux,ncolors) ,0}, -/* 5 */ {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,texcoordind), 0,0,0,0,0 ,0}, -/* 6 */ {"face", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,r), 0,0,0,0,0 ,0}, -/* 7 */ {"face", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,g), 0,0,0,0,0 ,0}, -/* 8 */ {"face", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0 ,0}, -/* 9 */ {"face", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,a), 0,0,0,0,0 ,0}, -/* 10 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 11 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 12 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, - -/* 13 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 14 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 15 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 16 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 17 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 18 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_USHORT,ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 19 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 20 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, -/* 21 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, - }; - return qf[i]; -} -static const PropDescriptor &TristripDesc(int i) -{ - static const PropDescriptor qf[1]= - { - {"tristrips","vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_TristripAux,v), 1,1,ply::T_INT,ply::T_INT,offsetof(LoadPly_TristripAux,size) ,0}, - }; - return qf[i]; -} - -static const PropDescriptor &EdgeDesc(int i) -{ - static const PropDescriptor qf[2]= - { - {"edge","vertex1", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v1), 0,0,0,0,0 ,0}, - {"edge","vertex2", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v2), 0,0,0,0,0 ,0}, - }; - return qf[i]; -} - -// Descriptor for the Stanford Data Repository Range Maps. -// In practice a grid with some invalid elements. Coords are saved only for good elements -static const PropDescriptor &RangeDesc(int i) -{ - static const PropDescriptor range_props[1] = { - {"range_grid","vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_RangeGridAux,pts), 1, 0, ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_RangeGridAux,num_pts),0}, - }; - return range_props[i]; -} - - -static const PropDescriptor &CameraDesc(int i) -{ - static const PropDescriptor cad[23] = - { - {"camera","view_px",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_px),0,0,0,0,0 ,0}, - {"camera","view_py",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_py),0,0,0,0,0 ,0}, - {"camera","view_pz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_pz),0,0,0,0,0 ,0}, - {"camera","x_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisx),0,0,0,0,0 ,0}, - {"camera","x_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisy),0,0,0,0,0 ,0}, - {"camera","x_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisz),0,0,0,0,0 ,0}, - {"camera","y_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisx),0,0,0,0,0 ,0}, - {"camera","y_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisy),0,0,0,0,0 ,0}, - {"camera","y_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisz),0,0,0,0,0 ,0}, - {"camera","z_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisx),0,0,0,0,0 ,0}, - {"camera","z_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisy),0,0,0,0,0 ,0}, - {"camera","z_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisz),0,0,0,0,0 ,0}, - {"camera","focal" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,focal ),0,0,0,0,0 ,0}, - {"camera","scalex" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scalex ),0,0,0,0,0 ,0}, - {"camera","scaley" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scaley ),0,0,0,0,0 ,0}, - {"camera","centerx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centerx),0,0,0,0,0 ,0}, - {"camera","centery",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centery),0,0,0,0,0 ,0}, - {"camera","viewportx",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewportx),0,0,0,0,0 ,0}, - {"camera","viewporty",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewporty),0,0,0,0,0 ,0}, - {"camera","k1" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k1 ),0,0,0,0,0 ,0}, - {"camera","k2" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k2 ),0,0,0,0,0 ,0}, - {"camera","k3" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k3 ),0,0,0,0,0 ,0}, - {"camera","k4" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k4 ),0,0,0,0,0 ,0} - }; - return cad[i]; -} -/// Standard call for knowing the meaning of an error code -static const char *ErrorMsg(int error) -{ - static std::vector ply_error_msg; - if(ply_error_msg.empty()) - { - ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS ); - ply_error_msg[ply::E_NOERROR ]="No errors"; - ply_error_msg[ply::E_CANTOPEN ]="Can't open file"; - ply_error_msg[ply::E_NOTHEADER ]="Header not found"; - ply_error_msg[ply::E_UNESPECTEDEOF ]="Eof in header"; - ply_error_msg[ply::E_NOFORMAT ]="Format not found"; - ply_error_msg[ply::E_SYNTAX ]="Syntax error on header"; - ply_error_msg[ply::E_PROPOUTOFELEMENT]="Property without element"; - ply_error_msg[ply::E_BADTYPENAME ]="Bad type name"; - ply_error_msg[ply::E_ELEMNOTFOUND ]="Element not found"; - ply_error_msg[ply::E_PROPNOTFOUND ]="Property not found"; - ply_error_msg[ply::E_BADTYPE ]="Bad type on addtoread"; - ply_error_msg[ply::E_INCOMPATIBLETYPE]="Incompatible type"; - ply_error_msg[ply::E_BADCAST ]="Bad cast"; - - ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found"; - ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found"; - ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof"; - ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices"; - ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face"; - ply_error_msg[PlyInfo::E_BAD_VERT_INDEX_EDGE ]="Bad vertex index in edge"; - ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates"; - ply_error_msg[PlyInfo::E_DIFFER_COLORS ]="Number of color differ from vertices"; - } - - if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error"; - else return ply_error_msg[error].c_str(); -}; - -// to check if a given error is critical or not. -static bool ErrorCritical(int err) -{ - if ((err == ply::E_NOERROR) || (err == PlyInfo::E_NO_FACE)) return false; - return true; -} - - -/// Standard call for reading a mesh, returns 0 on success. -static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0) -{ - PlyInfo pi; - pi.cb=cb; - return Open(m, filename, pi); -} - -/// Read a mesh and store in loadmask the loaded field -/// Note that loadmask is not read! just modified. You cannot specify what fields -/// have to be read. ALL the data for which your mesh HasSomething and are present -/// in the file are read in. -static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0) -{ - PlyInfo pi; - pi.cb=cb; - int r = Open(m, filename,pi); - loadmask=pi.mask; - return r; -} - - -/// read a mesh with all the possible option specified in the PlyInfo obj, returns 0 on success. -static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi ) -{ - assert(filename!=0); - std::vector index; - LoadPly_FaceAux fa; - LoadPly_EdgeAux ea; - LoadPly_TristripAux tsa; - LoadPly_VertAux va; - - LoadPly_RangeGridAux rga; - std::vector RangeGridAuxVec; - int RangeGridCols=0; - int RangeGridRows=0; - - - pi.mask = 0; - bool hasIntensity = false; // the intensity is a strange way to code single channel color used sometimes in rangemap. it is a kind of color. so it do not need another entry in the IOM mask. - bool multit = false; // true if texture has a per face int spec the texture index - - va.flags = 42; - - pi.status = ::vcg::ply::E_NOERROR; - - /* - // TO BE REMOVED: tv not used AND "spurious" vertex declaration causes error if ocf - - // init defaults - VertexType tv; - //tv.ClearFlags(); - - if (vcg::tri::HasPerVertexQuality(m)) tv.Q() = (typename OpenMeshType::VertexType::QualityType)1.0; - if (vcg::tri::HasPerVertexColor (m)) tv.C() = Color4b(Color4b::White); - */ - - // Descrittori delle strutture - - //bool isvflags = false; // Il file contiene i flags - - - // The main descriptor of the ply file - vcg::ply::PlyFile pf; - - // Open the file and parse the header - if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) - { - pi.status = pf.GetError(); - return pi.status; - } - pi.header = pf.GetHeader(); - - // Descrittori della camera - { // Check that all the camera properties are present. - bool found = true; - for(int i=0;i<23;++i) - { - if( pf.AddToRead(CameraDesc(i))==-1 ) { - found = false; - break; - } - } - if(found) pi.mask |= Mask::IOM_CAMERA; - } - - // Standard data desciptors (vertex coord and faces) - if( pf.AddToRead(VertDesc(0))==-1 && pf.AddToRead(VertDesc(24)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; } - if( pf.AddToRead(VertDesc(1))==-1 && pf.AddToRead(VertDesc(25)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; } - if( pf.AddToRead(VertDesc(2))==-1 && pf.AddToRead(VertDesc(26)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; } - if( pf.AddToRead(FaceDesc(0))==-1 ) // Se fallisce si prova anche la sintassi di rapidform con index al posto di indices - { - int ii; - for (ii=_FACEDESC_FIRST_;ii< _FACEDESC_LAST_;++ii) - if( pf.AddToRead(FaceDesc(ii))!=-1 ) break; - - if (ii==_FACEDESC_LAST_) - if(pf.AddToRead(TristripDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono tristrip alla levoy. - if(pf.AddToRead(RangeDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono rangemap alla levoy. - { - pi.status = PlyInfo::E_NO_FACE; - //return pi.status; no face is not a critical error. let's continue. - } - - } - // Optional flag descriptors - if(pf.AddToRead(EdgeDesc(0) )!= -1 && pf.AddToRead(EdgeDesc(1)) != -1 ) - pi.mask |= Mask::IOM_EDGEINDEX; - - if(vcg::tri::HasPerVertexFlags(m) && pf.AddToRead(VertDesc(3))!=-1 ) - pi.mask |= Mask::IOM_VERTFLAGS; - - if( vcg::tri::HasPerVertexNormal(m) ) - { - if( pf.AddToRead(VertDesc(14))!=-1 && pf.AddToRead(VertDesc(15))!=-1 && pf.AddToRead(VertDesc(16))!=-1 ) - pi.mask |= Mask::IOM_VERTNORMAL; - else // try also for Normals stored with doubles - if( pf.AddToRead(VertDesc(27))!=-1 && pf.AddToRead(VertDesc(28))!=-1 && pf.AddToRead(VertDesc(29))!=-1 ) - pi.mask |= Mask::IOM_VERTNORMAL; - - } - - if( vcg::tri::HasPerVertexQuality(m) ) - { - if( pf.AddToRead(VertDesc(4))!=-1 || - pf.AddToRead(VertDesc(13))!=-1 ) - pi.mask |= Mask::IOM_VERTQUALITY; - else - if (pf.AddToRead(VertDesc(31))!=-1) - pi.mask |= Mask::IOM_VERTQUALITY; - } - - if(vcg::tri::HasPerVertexColor(m) ) - { - if( pf.AddToRead(VertDesc(5))!=-1 ) - { - pf.AddToRead(VertDesc(6)); - pf.AddToRead(VertDesc(7)); - pf.AddToRead(VertDesc(8)); - pi.mask |= Mask::IOM_VERTCOLOR; - } - if( pf.AddToRead(VertDesc(9))!=-1 ) - { - pf.AddToRead(VertDesc(10)); - pf.AddToRead(VertDesc(11)); - pf.AddToRead(VertDesc(12)); - pi.mask |= Mask::IOM_VERTCOLOR; - } - if( pf.AddToRead(VertDesc(21))!=-1 ) - { - hasIntensity = true; - pi.mask |= Mask::IOM_VERTCOLOR; - } - - } - if( tri::HasPerVertexTexCoord(m) ) - { - if(( pf.AddToRead(VertDesc(22))!=-1 )&& (pf.AddToRead(VertDesc(23))!=-1)) - { - pi.mask |= Mask::IOM_VERTTEXCOORD; - } - if(( pf.AddToRead(VertDesc(18))!=-1 )&& (pf.AddToRead(VertDesc(19))!=-1)) - { - pi.mask |= Mask::IOM_VERTTEXCOORD; - } - } - if(tri::HasPerVertexRadius(m)) - { - if( pf.AddToRead(VertDesc(17))!=-1 ) - pi.mask |= Mask::IOM_VERTRADIUS; - else if( pf.AddToRead(VertDesc(30))!=-1 ) - pi.mask |= Mask::IOM_VERTRADIUS; - } - // se ci sono i flag per vertice ci devono essere anche i flag per faccia - if( pf.AddToRead(FaceDesc(1))!=-1 ) - pi.mask |= Mask::IOM_FACEFLAGS; - - if( vcg::tri::HasPerFaceQuality(m) ) - { - if( pf.AddToRead(FaceDesc(2))!=-1 ) - pi.mask |= Mask::IOM_FACEQUALITY; - } - - if( vcg::tri::HasPerFaceColor(m) ) - { - if( pf.AddToRead(FaceDesc(6))!=-1 ) - { - pf.AddToRead(FaceDesc(7)); - pf.AddToRead(FaceDesc(8)); - pf.AddToRead(FaceDesc(9)); - pi.mask |= Mask::IOM_FACECOLOR; - } - } - - - if( vcg::tri::HasPerWedgeTexCoord(m) ) - { - if( pf.AddToRead(FaceDesc(3))!=-1 ) - { - if(pf.AddToRead(FaceDesc(5))==0) { - multit=true; // try to read also the multi texture indicies - pi.mask |= Mask::IOM_WEDGTEXMULTI; - } - pi.mask |= Mask::IOM_WEDGTEXCOORD; - } - } - - if( vcg::tri::HasPerFaceColor(m) || vcg::tri::HasPerVertexColor(m) || vcg::tri::HasPerWedgeColor(m) ) - { - if( pf.AddToRead(FaceDesc(4))!=-1 ) - { - pi.mask |= Mask::IOM_WEDGCOLOR; - } - } - - // User defined descriptors - std::vector VPV(pi.VertDescriptorVec.size()); // property descriptor relative al tipo LoadPly_VertexAux - std::vector FPV(pi.FaceDescriptorVec.size()); // property descriptor relative al tipo LoadPly_FaceAux - if(pi.VertDescriptorVec.size()>0){ - // Compute the total size needed to load additional per vertex data. - size_t totsz=0; - for(size_t i=0;i,data)+totsz; - totsz+=pi.VertDescriptorVec[i].memtypesize(); - if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; } - } - if(totsz > MAX_USER_DATA) - { - pi.status = vcg::ply::E_BADTYPE; - return pi.status; - } - } - if(pi.FaceDescriptorVec.size()>0){ - size_t totsz=0; - for(size_t i=0;i MAX_USER_DATA) - { - pi.status = vcg::ply::E_BADTYPE; - return pi.status; - } - } - - /**************************************************************/ - /* Main Reading Loop */ - /**************************************************************/ - m.Clear(); - for(size_t i=0;i( ca.view_px,ca.view_py,ca.view_pz)); - - // axis (i.e. rotation). - Matrix44 rm; - rm.SetIdentity(); - rm[0][0] = ca.x_axisx; - rm[0][1] = ca.x_axisy; - rm[0][2] = ca.x_axisz; - - rm[1][0] = ca.y_axisx; - rm[1][1] = ca.y_axisy; - rm[1][2] = ca.y_axisz; - - rm[2][0] = ca.z_axisx; - rm[2][1] = ca.z_axisy; - rm[2][2] = ca.z_axisz; - - m.shot.Extrinsics.SetRot(rm); - - //intrinsic - m.shot.Intrinsics.FocalMm = ca.focal; - m.shot.Intrinsics.PixelSizeMm[0] = ca.scalex; - m.shot.Intrinsics.PixelSizeMm[1] = ca.scaley; - m.shot.Intrinsics.CenterPx[0] = ca.centerx; - m.shot.Intrinsics.CenterPx[1] = ca.centery; - m.shot.Intrinsics.ViewportPx[0] = ca.viewportx; - m.shot.Intrinsics.ViewportPx[1] = ca.viewporty; - m.shot.Intrinsics.k[0] = ca.k1; - m.shot.Intrinsics.k[1] = ca.k2; - m.shot.Intrinsics.k[2] = ca.k3; - m.shot.Intrinsics.k[3] = ca.k4; - - } - } - else if( !strcmp( pf.ElemName(i),"vertex" ) ) - { - int j; - - pf.SetCurElement(i); - VertexIterator vi=Allocator::AddVertices(m,n); - - for(j=0;j0) )/******************** EDGE READING *******************************/ - { - assert( pi.mask & Mask::IOM_EDGEINDEX ); - EdgeIterator ei=Allocator::AddEdges(m,n); - pf.SetCurElement(i); - for(int j=0;j=m.vn || ea.v2>=m.vn) - { - pi.status = PlyInfo::E_BAD_VERT_INDEX_EDGE; - return pi.status; - } - (*ei).V(0) = index[ ea.v1 ]; - (*ei).V(1) = index[ ea.v2 ]; - ++ei; - } - } - else if( !strcmp( pf.ElemName(i),"face") && (n>0) )/******************** FACE READING ****************************************/ - { - int j; - - FaceIterator fi=Allocator::AddFaces(m,n); - pf.SetCurElement(i); - - for(j=0;j=m.vn ) - { - pi.status = PlyInfo::E_BAD_VERT_INDEX; - return pi.status; - } - (*fi).V(k) = index[ fa.v[k] ]; - } - fi++; - continue; - } - - /// Now the temporary struct 'fa' is ready to be copied into the real face '*fi' - /// This loop - for(k=0;k<3;++k) - { - if( fa.v[k]<0 || fa.v[k]>=m.vn ) - { - pi.status = PlyInfo::E_BAD_VERT_INDEX; - return pi.status; - } - (*fi).V(k) = index[ fa.v[k] ]; - } - - // tag faux vertices of first face - if (fa.size>3) fi->SetF(2); - - for(size_t k=0;k3) - { - int curpos=int(fi-m.face.begin()); - Allocator::AddFaces(m,fa.size-3); - fi=m.face.begin()+curpos; - pi.mask |= Mask::IOM_BITPOLYGONAL; - } - for(int qq=0;qq=m.vn ) - { - pi.status = PlyInfo::E_BAD_VERT_INDEX; - return pi.status; - } - (*fi).V(k) = index[ fa.v[1+qq+k] ]; - - } - if( pi.mask & Mask::IOM_FACEQUALITY ) - (*fi).Q() = (typename OpenMeshType::FaceType::QualityType) - fa.q; - if( pi.mask & Mask::IOM_FACECOLOR ) - (*fi).C() = Color4b(fa.r,fa.g,fa.b,255); - // tag faux vertices of extra faces - fi->SetF(0); - if(qq<(fa.size-4)) fi->SetF(2); - - for(size_t k=0;k=numvert_tmp ) { - pi.status = PlyInfo::E_BAD_VERT_INDEX; - return pi.status; - } - if(tsa.v[k+2]==-1) - { - k+=2; - if(k%2) remainder=0; - else remainder=1; - continue; - } - Allocator::AddFaces(m,1); - FaceType &tf =m.face.back(); - tf.V(0) = index[ tsa.v[k+0] ]; - tf.V(1) = index[ tsa.v[k+1] ]; - tf.V(2) = index[ tsa.v[k+2] ]; - if((k+remainder)%2) std::swap (tf.V(0), tf.V(1) ); - } - } - } - else if( !strcmp( pf.ElemName(i),"range_grid") )//////////////////// LETTURA RANGEMAP DI STANFORD - { - //qDebug("Starting Reading of Range Grid"); - if(RangeGridCols==0) // not initialized. - { - for(size_t co=0;co< pf.comments.size();++co) - { - std::string num_cols = "num_cols"; - std::string num_rows = "num_rows"; - std::string &c = pf.comments[co]; - std::string bufstr,bufclean; - if( num_cols == c.substr(0,num_cols.length()) ) - { - bufstr = c.substr(num_cols.length()+1); - RangeGridCols = atoi(bufstr.c_str()); - } - if( num_rows == c.substr(0,num_cols.length()) ) - { - bufstr = c.substr(num_rows.length()+1); - RangeGridRows = atoi(bufstr.c_str()); - } - } - //qDebug("Rows %i Cols %i",RangeGridRows,RangeGridCols); - } - int totPnt = RangeGridCols*RangeGridRows; - // standard reading; - pf.SetCurElement(i); - for(int j=0;j(bufstr.length()); - for(int i=0;i32 && bufstr[i]<125 ) bufclean.push_back(bufstr[i]); - - char buf2[255]; - ply::interpret_texture_name( bufclean.c_str(),filename,buf2 ); - m.textures.push_back( std::string(buf2) ); - } - /*if( !strncmp(c,NFILE,strlen(NFILE)) ) - { - strcpy(buf,c+strlen(NFILE)+1); - n = strlen(buf); - for(i=j=0;i32 && buf[i]<125 ) buf[j++] = buf[i]; - - buf[j] = 0; - char buf2[255]; - __interpret_texture_name( buf,filename,buf2 ); - m.normalmaps.push_back( string(buf2) ); - }*/ - } - - // vn and fn should be correct but if someone wrongly saved some deleted elements they can be wrong. - m.vn = 0; - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) - if( ! (*vi).IsD() ) - ++m.vn; - - m.fn = 0; - for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) - if( ! (*fi).IsD() ) - ++m.fn; - - tri::UpdateBounding::Box(m); - return 0; -} - - -// Caricamento camera da un ply -int LoadCamera(const char * filename) -{ - vcg::ply::PlyFile pf; - if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) - { - this->pi.status = pf.GetError(); - return this->pi.status; - } - - - bool found = true; - for(int i=0;i<23;++i) - { - if( pf.AddToRead(CameraDesc(i))==-1 ) - { - found = false; - break; - } - } - - if(!found) - return this->pi.status; - - for(size_t i=0;ipi.status = PlyInfo::E_SHORTFILE; - return this->pi.status; - } - this->camera.valid = true; - this->camera.view_p[0] = ca.view_px; - this->camera.view_p[1] = ca.view_py; - this->camera.view_p[2] = ca.view_pz; - this->camera.x_axis[0] = ca.x_axisx; - this->camera.x_axis[1] = ca.x_axisy; - this->camera.x_axis[2] = ca.x_axisz; - this->camera.y_axis[0] = ca.y_axisx; - this->camera.y_axis[1] = ca.y_axisy; - this->camera.y_axis[2] = ca.y_axisz; - this->camera.z_axis[0] = ca.z_axisx; - this->camera.z_axis[1] = ca.z_axisy; - this->camera.z_axis[2] = ca.z_axisz; - this->camera.f = ca.focal; - this->camera.s[0] = ca.scalex; - this->camera.s[1] = ca.scaley; - this->camera.c[0] = ca.centerx; - this->camera.c[1] = ca.centery; - this->camera.viewport[0] = ca.viewportx; - this->camera.viewport[1] = ca.viewporty; - this->camera.k[0] = ca.k1; - this->camera.k[1] = ca.k2; - this->camera.k[2] = ca.k3; - this->camera.k[3] = ca.k4; - } - break; - } - } - - return 0; -} - - -static bool LoadMask(const char * filename, int &mask) -{ - PlyInfo pi; - return LoadMask(filename, mask,pi); -} -static bool LoadMask(const char * filename, int &mask, PlyInfo &pi) -{ - mask=0; - vcg::ply::PlyFile pf; - if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) - { - pi.status = pf.GetError(); - return false; - } - - if( pf.AddToRead(VertDesc( 0))!=-1 && - pf.AddToRead(VertDesc( 1))!=-1 && - pf.AddToRead(VertDesc( 2))!=-1 ) mask |= Mask::IOM_VERTCOORD; - if( pf.AddToRead(VertDesc(24))!=-1 && - pf.AddToRead(VertDesc(25))!=-1 && - pf.AddToRead(VertDesc(26))!=-1 ) mask |= Mask::IOM_VERTCOORD; - - if( pf.AddToRead(VertDesc(14))!=-1 && - pf.AddToRead(VertDesc(15))!=-1 && - pf.AddToRead(VertDesc(16))!=-1 ) mask |= Mask::IOM_VERTNORMAL; - if( pf.AddToRead(VertDesc(27))!=-1 && - pf.AddToRead(VertDesc(28))!=-1 && - pf.AddToRead(VertDesc(29))!=-1 ) mask |= Mask::IOM_VERTNORMAL; - - if( pf.AddToRead(VertDesc( 3))!=-1 ) mask |= Mask::IOM_VERTFLAGS; - if( pf.AddToRead(VertDesc( 4))!=-1 ) mask |= Mask::IOM_VERTQUALITY; - if( pf.AddToRead(VertDesc(13))!=-1 ) mask |= Mask::IOM_VERTQUALITY; - if( pf.AddToRead(VertDesc(17))!=-1 ) mask |= Mask::IOM_VERTRADIUS; - if( pf.AddToRead(VertDesc(30))!=-1 ) mask |= Mask::IOM_VERTRADIUS; - if( pf.AddToRead(VertDesc(31))!=-1 ) mask |= Mask::IOM_VERTQUALITY; - if( pf.AddToRead(VertDesc( 5))!=-1 && - pf.AddToRead(VertDesc( 6))!=-1 && - pf.AddToRead(VertDesc( 7))!=-1 ) mask |= Mask::IOM_VERTCOLOR; - if( pf.AddToRead(VertDesc( 9))!=-1 && - pf.AddToRead(VertDesc(10))!=-1 && - pf.AddToRead(VertDesc(11))!=-1 ) mask |= Mask::IOM_VERTCOLOR; - if( pf.AddToRead(VertDesc(21))!=-1 ) mask |= Mask::IOM_VERTCOLOR; - - if( pf.AddToRead(VertDesc(22))!=-1 && - pf.AddToRead(VertDesc(23))!=-1) mask |= Mask::IOM_VERTTEXCOORD; - - if( pf.AddToRead(VertDesc(18))!=-1 && - pf.AddToRead(VertDesc(19))!=-1) mask |= Mask::IOM_VERTTEXCOORD; - - if( pf.AddToRead(FaceDesc(0))!=-1 ) mask |= Mask::IOM_FACEINDEX; - if( pf.AddToRead(FaceDesc(1))!=-1 ) mask |= Mask::IOM_FACEFLAGS; - - if( pf.AddToRead(FaceDesc(2))!=-1 ) mask |= Mask::IOM_FACEQUALITY; - if( pf.AddToRead(FaceDesc(3))!=-1 ) mask |= Mask::IOM_WEDGTEXCOORD; - if( pf.AddToRead(FaceDesc(5))!=-1 ) mask |= Mask::IOM_WEDGTEXMULTI; - if( pf.AddToRead(FaceDesc(4))!=-1 ) mask |= Mask::IOM_WEDGCOLOR; - if( pf.AddToRead(FaceDesc(6))!=-1 && - pf.AddToRead(FaceDesc(7))!=-1 && - pf.AddToRead(FaceDesc(8))!=-1 ) mask |= Mask::IOM_FACECOLOR; - - return true; -} + static const PropDescriptor &VertDesc(int i) + { + static const PropDescriptor pv[_VERTDESC_LAST_]={ + /*00*/ {"vertex", "x", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p),0,0,0,0,0 ,0}, + /*01*/ {"vertex", "y", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p) + sizeof(ScalarType),0,0,0,0,0 ,0}, + /*02*/ {"vertex", "z", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, + /*03*/ {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux,flags),0,0,0,0,0 ,0}, + /*04*/ {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,q),0,0,0,0,0 ,0}, + /*05*/ {"vertex", "red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,r),0,0,0,0,0 ,0}, + /*06*/ {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,g),0,0,0,0,0 ,0}, + /*07*/ { "vertex", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,b),0,0,0,0,0 ,0}, + /*08*/ { "vertex", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,a),0,0,0,0,0 ,0}, + /*09*/ {"vertex", "diffuse_red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,r),0,0,0,0,0 ,0}, + /*10*/ {"vertex", "diffuse_green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,g),0,0,0,0,0 ,0}, + /*11*/ {"vertex", "diffuse_blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,b),0,0,0,0,0 ,0}, + /*12*/ {"vertex", "diffuse_alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,a),0,0,0,0,0 ,0}, + /*13*/ {"vertex", "confidence", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,q),0,0,0,0,0 ,0}, + /*14*/ {"vertex", "nx", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,n) ,0,0,0,0,0 ,0}, + /*15*/ {"vertex", "ny", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, + /*16*/ {"vertex", "nz", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, + /*17*/ {"vertex", "radius", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,radius),0,0,0,0,0 ,0}, + /*18*/ {"vertex", "texture_u", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,u),0,0,0,0,0 ,0}, + /*19*/ {"vertex", "texture_v", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,v),0,0,0,0,0 ,0}, + /*20*/ {"vertex", "texture_w", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,w),0,0,0,0,0 ,0}, + /*21*/ {"vertex", "intensity", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,intensity),0,0,0,0,0 ,0}, + /*22*/ {"vertex", "s", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,u),0,0,0,0,0 ,0}, + /*23*/ {"vertex", "t", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,v),0,0,0,0,0 ,0}, + // DOUBLE + /*24*/ {"vertex", "x", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,p),0,0,0,0,0 ,0}, + /*25*/ {"vertex", "y", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,p) + sizeof(ScalarType) ,0,0,0,0,0 ,0}, + /*26*/ {"vertex", "z", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, + /*27*/ {"vertex", "nx", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,n) ,0,0,0,0,0 ,0}, + /*28*/ {"vertex", "ny", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, + /*29*/ {"vertex", "nz", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, + /*30*/ {"vertex", "radius", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_VertAux,radius),0,0,0,0,0 ,0}, + /*31*/ {"vertex", "quality", ply::T_DOUBLE, ply::T_DOUBLE,offsetof(LoadPly_VertAux,q),0,0,0,0,0 ,0} + }; + return pv[i]; + } + +#define _FACEDESC_FIRST_ 13 // the first descriptor with possible vertex indices +#define _FACEDESC_LAST_ 29 + static const PropDescriptor &FaceDesc(int i) + { + static const PropDescriptor qf[_FACEDESC_LAST_]= + { + /* on file on memory on file on memory */ + /* 0 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 1 */ {"face", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,flags), 0,0,0,0,0 ,0}, + /* 2 */ {"face", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,q), 0,0,0,0,0 ,0}, + /* 3 */ {"face", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,texcoord), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux,ntexcoord) ,0}, + /* 4 */ {"face", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,colors), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux,ncolors) ,0}, + /* 5 */ {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,texcoordind), 0,0,0,0,0 ,0}, + /* 6 */ {"face", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,r), 0,0,0,0,0 ,0}, + /* 7 */ {"face", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,g), 0,0,0,0,0 ,0}, + /* 8 */ {"face", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0 ,0}, + /* 9 */ {"face", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,a), 0,0,0,0,0 ,0}, + /* 10 */ {"face", "nx", ply::T_FLOAT, PlyType(),offsetof(LoadPly_FaceAux,n) ,0,0,0,0,0 ,0}, + /* 11 */ {"face", "ny", ply::T_FLOAT, PlyType(),offsetof(LoadPly_FaceAux,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, + /* 12 */ {"face", "nz", ply::T_FLOAT, PlyType(),offsetof(LoadPly_FaceAux,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, + /* 13 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 14 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 15 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + + /* 16 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 17 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 18 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 19 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 20 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 21 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_USHORT,ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 22 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 23 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + /* 24 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}, + // DOUBLE + /* 25 */ {"face", "quality", ply::T_DOUBLE, ply::T_DOUBLE, offsetof(LoadPly_FaceAux,q), 0,0,0,0,0 ,0}, + /* 26 */ {"face", "nx", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_FaceAux,n) ,0,0,0,0,0 ,0}, + /* 27 */ {"face", "ny", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_FaceAux,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, + /* 28 */ {"face", "nz", ply::T_DOUBLE, PlyType(),offsetof(LoadPly_FaceAux,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0} + + }; + return qf[i]; + } + static const PropDescriptor &TristripDesc(int i) + { + static const PropDescriptor qf[1]= + { + {"tristrips","vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_TristripAux,v), 1,1,ply::T_INT,ply::T_INT,offsetof(LoadPly_TristripAux,size) ,0}, + }; + return qf[i]; + } + + static const PropDescriptor &EdgeDesc(int i) + { + static const PropDescriptor qf[2]= + { + {"edge","vertex1", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v1), 0,0,0,0,0 ,0}, + {"edge","vertex2", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v2), 0,0,0,0,0 ,0}, + }; + return qf[i]; + } + + // Descriptor for the Stanford Data Repository Range Maps. + // In practice a grid with some invalid elements. Coords are saved only for good elements + static const PropDescriptor &RangeDesc(int i) + { + static const PropDescriptor range_props[1] = { + {"range_grid","vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_RangeGridAux,pts), 1, 0, ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_RangeGridAux,num_pts),0}, + }; + return range_props[i]; + } + + + static const PropDescriptor &CameraDesc(int i) + { + static const PropDescriptor cad[23] = + { + {"camera","view_px",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_px),0,0,0,0,0 ,0}, + {"camera","view_py",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_py),0,0,0,0,0 ,0}, + {"camera","view_pz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_pz),0,0,0,0,0 ,0}, + {"camera","x_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisx),0,0,0,0,0 ,0}, + {"camera","x_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisy),0,0,0,0,0 ,0}, + {"camera","x_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisz),0,0,0,0,0 ,0}, + {"camera","y_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisx),0,0,0,0,0 ,0}, + {"camera","y_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisy),0,0,0,0,0 ,0}, + {"camera","y_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisz),0,0,0,0,0 ,0}, + {"camera","z_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisx),0,0,0,0,0 ,0}, + {"camera","z_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisy),0,0,0,0,0 ,0}, + {"camera","z_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisz),0,0,0,0,0 ,0}, + {"camera","focal" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,focal ),0,0,0,0,0 ,0}, + {"camera","scalex" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scalex ),0,0,0,0,0 ,0}, + {"camera","scaley" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scaley ),0,0,0,0,0 ,0}, + {"camera","centerx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centerx),0,0,0,0,0 ,0}, + {"camera","centery",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centery),0,0,0,0,0 ,0}, + {"camera","viewportx",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewportx),0,0,0,0,0 ,0}, + {"camera","viewporty",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewporty),0,0,0,0,0 ,0}, + {"camera","k1" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k1 ),0,0,0,0,0 ,0}, + {"camera","k2" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k2 ),0,0,0,0,0 ,0}, + {"camera","k3" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k3 ),0,0,0,0,0 ,0}, + {"camera","k4" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k4 ),0,0,0,0,0 ,0} + }; + return cad[i]; + } + /// Standard call for knowing the meaning of an error code + static const char *ErrorMsg(int error) + { + static std::vector ply_error_msg; + if(ply_error_msg.empty()) + { + ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS ); + ply_error_msg[ply::E_NOERROR ]="No errors"; + ply_error_msg[ply::E_CANTOPEN ]="Can't open file"; + ply_error_msg[ply::E_NOTHEADER ]="Header not found"; + ply_error_msg[ply::E_UNESPECTEDEOF ]="Eof in header"; + ply_error_msg[ply::E_NOFORMAT ]="Format not found"; + ply_error_msg[ply::E_SYNTAX ]="Syntax error on header"; + ply_error_msg[ply::E_PROPOUTOFELEMENT]="Property without element"; + ply_error_msg[ply::E_BADTYPENAME ]="Bad type name"; + ply_error_msg[ply::E_ELEMNOTFOUND ]="Element not found"; + ply_error_msg[ply::E_PROPNOTFOUND ]="Property not found"; + ply_error_msg[ply::E_BADTYPE ]="Bad type on addtoread"; + ply_error_msg[ply::E_INCOMPATIBLETYPE]="Incompatible type"; + ply_error_msg[ply::E_BADCAST ]="Bad cast"; + + ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found"; + ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found"; + ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof"; + ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices"; + ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face"; + ply_error_msg[PlyInfo::E_BAD_VERT_INDEX_EDGE ]="Bad vertex index in edge"; + ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates"; + ply_error_msg[PlyInfo::E_DIFFER_COLORS ]="Number of color differ from vertices"; + } + + if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error"; + else return ply_error_msg[error].c_str(); + }; + + // to check if a given error is critical or not. + static bool ErrorCritical(int err) + { + if ((err == ply::E_NOERROR) || (err == PlyInfo::E_NO_FACE)) return false; + return true; + } + + + /// Standard call for reading a mesh, returns 0 on success. + static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0) + { + PlyInfo pi; + pi.cb=cb; + return Open(m, filename, pi); + } + + /// Read a mesh and store in loadmask the loaded field + /// Note that loadmask is not read! just modified. You cannot specify what fields + /// have to be read. ALL the data for which your mesh HasSomething and are present + /// in the file are read in. + static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0) + { + PlyInfo pi; + pi.cb=cb; + int r = Open(m, filename,pi); + loadmask=pi.mask; + return r; + } + + + /// read a mesh with all the possible option specified in the PlyInfo obj, returns 0 on success. + static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi ) + { + assert(filename!=0); + std::vector index; + LoadPly_FaceAux fa; + LoadPly_EdgeAux ea; + LoadPly_TristripAux tsa; + LoadPly_VertAux va; + + LoadPly_RangeGridAux rga; + std::vector RangeGridAuxVec; + int RangeGridCols=0; + int RangeGridRows=0; + + + pi.mask = 0; + bool hasIntensity = false; // the intensity is a strange way to code single channel color used sometimes in rangemap. it is a kind of color. so it do not need another entry in the IOM mask. + bool multit = false; // true if texture has a per face int spec the texture index + + va.flags = 42; + + pi.status = ::vcg::ply::E_NOERROR; + + /* + // TO BE REMOVED: tv not used AND "spurious" vertex declaration causes error if ocf + + // init defaults + VertexType tv; + //tv.ClearFlags(); + + if (vcg::tri::HasPerVertexQuality(m)) tv.Q() = (typename OpenMeshType::VertexType::QualityType)1.0; + if (vcg::tri::HasPerVertexColor (m)) tv.C() = Color4b(Color4b::White); + */ + + // Descrittori delle strutture + + //bool isvflags = false; // Il file contiene i flags + + + // The main descriptor of the ply file + vcg::ply::PlyFile pf; + + // Open the file and parse the header + if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) + { + pi.status = pf.GetError(); + return pi.status; + } + pi.header = pf.GetHeader(); + + // Descrittori della camera + { // Check that all the camera properties are present. + bool found = true; + for(int i=0;i<23;++i) + { + if( pf.AddToRead(CameraDesc(i))==-1 ) { + found = false; + break; + } + } + if(found) pi.mask |= Mask::IOM_CAMERA; + } + + // Standard data desciptors (vertex coord and faces) + if( pf.AddToRead(VertDesc(0))==-1 && pf.AddToRead(VertDesc(24)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; } + if( pf.AddToRead(VertDesc(1))==-1 && pf.AddToRead(VertDesc(25)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; } + if( pf.AddToRead(VertDesc(2))==-1 && pf.AddToRead(VertDesc(26)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; } + if( pf.AddToRead(FaceDesc(0))==-1 ) // Se fallisce si prova anche la sintassi di rapidform con index al posto di indices + { + int ii; + for (ii=_FACEDESC_FIRST_;ii< _FACEDESC_LAST_;++ii) + if( pf.AddToRead(FaceDesc(ii))!=-1 ) break; + + if (ii==_FACEDESC_LAST_) + if(pf.AddToRead(TristripDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono tristrip alla levoy. + if(pf.AddToRead(RangeDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono rangemap alla levoy. + { + pi.status = PlyInfo::E_NO_FACE; + //return pi.status; no face is not a critical error. let's continue. + } + + } + // Optional flag descriptors + if(pf.AddToRead(EdgeDesc(0) )!= -1 && pf.AddToRead(EdgeDesc(1)) != -1 ) + pi.mask |= Mask::IOM_EDGEINDEX; + + if(vcg::tri::HasPerVertexFlags(m) && pf.AddToRead(VertDesc(3))!=-1 ) + pi.mask |= Mask::IOM_VERTFLAGS; + + if( vcg::tri::HasPerVertexNormal(m) ) + { + if( pf.AddToRead(VertDesc(14))!=-1 && pf.AddToRead(VertDesc(15))!=-1 && pf.AddToRead(VertDesc(16))!=-1 ) + pi.mask |= Mask::IOM_VERTNORMAL; + else // try also for Normals stored with doubles + if( pf.AddToRead(VertDesc(27))!=-1 && pf.AddToRead(VertDesc(28))!=-1 && pf.AddToRead(VertDesc(29))!=-1 ) + pi.mask |= Mask::IOM_VERTNORMAL; + + } + + if( vcg::tri::HasPerVertexQuality(m) ) + { + if( pf.AddToRead(VertDesc(4))!=-1 || + pf.AddToRead(VertDesc(13))!=-1 ) + pi.mask |= Mask::IOM_VERTQUALITY; + else + if (pf.AddToRead(VertDesc(31))!=-1) + pi.mask |= Mask::IOM_VERTQUALITY; + } + + if(vcg::tri::HasPerVertexColor(m) ) + { + if( pf.AddToRead(VertDesc(5))!=-1 ) + { + pf.AddToRead(VertDesc(6)); + pf.AddToRead(VertDesc(7)); + pf.AddToRead(VertDesc(8)); + pi.mask |= Mask::IOM_VERTCOLOR; + } + if( pf.AddToRead(VertDesc(9))!=-1 ) + { + pf.AddToRead(VertDesc(10)); + pf.AddToRead(VertDesc(11)); + pf.AddToRead(VertDesc(12)); + pi.mask |= Mask::IOM_VERTCOLOR; + } + if( pf.AddToRead(VertDesc(21))!=-1 ) + { + hasIntensity = true; + pi.mask |= Mask::IOM_VERTCOLOR; + } + + } + if( tri::HasPerVertexTexCoord(m) ) + { + if(( pf.AddToRead(VertDesc(22))!=-1 )&& (pf.AddToRead(VertDesc(23))!=-1)) + { + pi.mask |= Mask::IOM_VERTTEXCOORD; + } + if(( pf.AddToRead(VertDesc(18))!=-1 )&& (pf.AddToRead(VertDesc(19))!=-1)) + { + pi.mask |= Mask::IOM_VERTTEXCOORD; + } + } + if(tri::HasPerVertexRadius(m)) + { + if( pf.AddToRead(VertDesc(17))!=-1 ) + pi.mask |= Mask::IOM_VERTRADIUS; + else if( pf.AddToRead(VertDesc(30))!=-1 ) + pi.mask |= Mask::IOM_VERTRADIUS; + } + // se ci sono i flag per vertice ci devono essere anche i flag per faccia + if( pf.AddToRead(FaceDesc(1))!=-1 ) + pi.mask |= Mask::IOM_FACEFLAGS; + + if (vcg::tri::HasPerFaceNormal(m)) + { + if (pf.AddToRead(FaceDesc(10)) != -1 && pf.AddToRead(FaceDesc(11)) != -1 && pf.AddToRead(FaceDesc(12)) != -1) + pi.mask |= Mask::IOM_FACENORMAL; + else if (pf.AddToRead(FaceDesc(26)) != -1 && pf.AddToRead(FaceDesc(27)) != -1 && pf.AddToRead(FaceDesc(28)) != -1) + pi.mask |= Mask::IOM_FACENORMAL; + } + + if( vcg::tri::HasPerFaceQuality(m) ) + { + if( pf.AddToRead(FaceDesc(2))!=-1 ) + pi.mask |= Mask::IOM_FACEQUALITY; + else if (pf.AddToRead(FaceDesc(25)) != -1) + pi.mask |= Mask::IOM_FACEQUALITY; + } + + if( vcg::tri::HasPerFaceColor(m) ) + { + if( pf.AddToRead(FaceDesc(6))!=-1 ) + { + pf.AddToRead(FaceDesc(7)); + pf.AddToRead(FaceDesc(8)); + pf.AddToRead(FaceDesc(9)); + pi.mask |= Mask::IOM_FACECOLOR; + } + } + + + if( vcg::tri::HasPerWedgeTexCoord(m) ) + { + if( pf.AddToRead(FaceDesc(3))!=-1 ) + { + if(pf.AddToRead(FaceDesc(5))==0) { + multit=true; // try to read also the multi texture indicies + pi.mask |= Mask::IOM_WEDGTEXMULTI; + } + pi.mask |= Mask::IOM_WEDGTEXCOORD; + } + } + + if( vcg::tri::HasPerFaceColor(m) || vcg::tri::HasPerVertexColor(m) || vcg::tri::HasPerWedgeColor(m) ) + { + if( pf.AddToRead(FaceDesc(4))!=-1 ) + { + pi.mask |= Mask::IOM_WEDGCOLOR; + } + } + + // User defined descriptors + std::vector VPV(pi.VertDescriptorVec.size()); // property descriptor relative al tipo LoadPly_VertexAux + std::vector FPV(pi.FaceDescriptorVec.size()); // property descriptor relative al tipo LoadPly_FaceAux + if(pi.VertDescriptorVec.size()>0){ + // Compute the total size needed to load additional per vertex data. + size_t totsz=0; + for(size_t i=0;i,data)+totsz; + totsz+=pi.VertDescriptorVec[i].memtypesize(); + if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; } + } + if(totsz > MAX_USER_DATA) + { + pi.status = vcg::ply::E_BADTYPE; + return pi.status; + } + } + if(pi.FaceDescriptorVec.size()>0){ + size_t totsz=0; + for(size_t i=0;i,data)+totsz; + totsz+=pi.FaceDescriptorVec[i].memtypesize(); + if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; } + } + if(totsz > MAX_USER_DATA) + { + pi.status = vcg::ply::E_BADTYPE; + return pi.status; + } + } + + /**************************************************************/ + /* Main Reading Loop */ + /**************************************************************/ + m.Clear(); + for(size_t i=0;i( ca.view_px,ca.view_py,ca.view_pz)); + + // axis (i.e. rotation). + Matrix44 rm; + rm.SetIdentity(); + rm[0][0] = ca.x_axisx; + rm[0][1] = ca.x_axisy; + rm[0][2] = ca.x_axisz; + + rm[1][0] = ca.y_axisx; + rm[1][1] = ca.y_axisy; + rm[1][2] = ca.y_axisz; + + rm[2][0] = ca.z_axisx; + rm[2][1] = ca.z_axisy; + rm[2][2] = ca.z_axisz; + + m.shot.Extrinsics.SetRot(rm); + + //intrinsic + m.shot.Intrinsics.FocalMm = ca.focal; + m.shot.Intrinsics.PixelSizeMm[0] = ca.scalex; + m.shot.Intrinsics.PixelSizeMm[1] = ca.scaley; + m.shot.Intrinsics.CenterPx[0] = ca.centerx; + m.shot.Intrinsics.CenterPx[1] = ca.centery; + m.shot.Intrinsics.ViewportPx[0] = ca.viewportx; + m.shot.Intrinsics.ViewportPx[1] = ca.viewporty; + m.shot.Intrinsics.k[0] = ca.k1; + m.shot.Intrinsics.k[1] = ca.k2; + m.shot.Intrinsics.k[2] = ca.k3; + m.shot.Intrinsics.k[3] = ca.k4; + + } + } + else if( !strcmp( pf.ElemName(i),"vertex" ) ) + { + int j; + + pf.SetCurElement(i); + VertexIterator vi=Allocator::AddVertices(m,n); + + for(j=0;j0) )/******************** EDGE READING *******************************/ + { + assert( pi.mask & Mask::IOM_EDGEINDEX ); + EdgeIterator ei=Allocator::AddEdges(m,n); + pf.SetCurElement(i); + for(int j=0;j=m.vn || ea.v2>=m.vn) + { + pi.status = PlyInfo::E_BAD_VERT_INDEX_EDGE; + return pi.status; + } + (*ei).V(0) = index[ ea.v1 ]; + (*ei).V(1) = index[ ea.v2 ]; + ++ei; + } + } + else if( !strcmp( pf.ElemName(i),"face") && (n>0) )/******************** FACE READING ****************************************/ + { + int j; + + FaceIterator fi=Allocator::AddFaces(m,n); + pf.SetCurElement(i); + + for(j=0;j=m.vn ) + { + pi.status = PlyInfo::E_BAD_VERT_INDEX; + return pi.status; + } + (*fi).V(k) = index[ fa.v[k] ]; + } + fi++; + continue; + } + + /// Now the temporary struct 'fa' is ready to be copied into the real face '*fi' + /// This loop + for(k=0;k<3;++k) + { + if( fa.v[k]<0 || fa.v[k]>=m.vn ) + { + pi.status = PlyInfo::E_BAD_VERT_INDEX; + return pi.status; + } + (*fi).V(k) = index[ fa.v[k] ]; + } + + // tag faux vertices of first face + if (fa.size>3) fi->SetF(2); + + for(size_t k=0;k3) + { + int curpos=int(fi-m.face.begin()); + Allocator::AddFaces(m,fa.size-3); + fi=m.face.begin()+curpos; + pi.mask |= Mask::IOM_BITPOLYGONAL; + } + for(int qq=0;qq=m.vn ) + { + pi.status = PlyInfo::E_BAD_VERT_INDEX; + return pi.status; + } + (*fi).V(k) = index[ fa.v[1+qq+k] ]; + + } + if( pi.mask & Mask::IOM_FACEQUALITY ) + (*fi).Q() = (typename OpenMeshType::FaceType::QualityType) + fa.q; + if( pi.mask & Mask::IOM_FACECOLOR ) + (*fi).C() = Color4b(fa.r,fa.g,fa.b,255); + // tag faux vertices of extra faces + fi->SetF(0); + if(qq<(fa.size-4)) fi->SetF(2); + + for(size_t k=0;k=numvert_tmp ) { + pi.status = PlyInfo::E_BAD_VERT_INDEX; + return pi.status; + } + if(tsa.v[k+2]==-1) + { + k+=2; + if(k%2) remainder=0; + else remainder=1; + continue; + } + Allocator::AddFaces(m,1); + FaceType &tf =m.face.back(); + tf.V(0) = index[ tsa.v[k+0] ]; + tf.V(1) = index[ tsa.v[k+1] ]; + tf.V(2) = index[ tsa.v[k+2] ]; + if((k+remainder)%2) std::swap (tf.V(0), tf.V(1) ); + } + } + } + else if( !strcmp( pf.ElemName(i),"range_grid") )//////////////////// LETTURA RANGEMAP DI STANFORD + { + //qDebug("Starting Reading of Range Grid"); + if(RangeGridCols==0) // not initialized. + { + for(size_t co=0;co< pf.comments.size();++co) + { + std::string num_cols = "num_cols"; + std::string num_rows = "num_rows"; + std::string &c = pf.comments[co]; + std::string bufstr,bufclean; + if( num_cols == c.substr(0,num_cols.length()) ) + { + bufstr = c.substr(num_cols.length()+1); + RangeGridCols = atoi(bufstr.c_str()); + } + if( num_rows == c.substr(0,num_cols.length()) ) + { + bufstr = c.substr(num_rows.length()+1); + RangeGridRows = atoi(bufstr.c_str()); + } + } + //qDebug("Rows %i Cols %i",RangeGridRows,RangeGridCols); + } + int totPnt = RangeGridCols*RangeGridRows; + // standard reading; + pf.SetCurElement(i); + for(int j=0;j(bufstr.length()); + for(int i=0;i32 && bufstr[i]<125 ) bufclean.push_back(bufstr[i]); + + char buf2[255]; + ply::interpret_texture_name( bufclean.c_str(),filename,buf2 ); + m.textures.push_back( std::string(buf2) ); + } + /*if( !strncmp(c,NFILE,strlen(NFILE)) ) + { + strcpy(buf,c+strlen(NFILE)+1); + n = strlen(buf); + for(i=j=0;i32 && buf[i]<125 ) buf[j++] = buf[i]; + + buf[j] = 0; + char buf2[255]; + __interpret_texture_name( buf,filename,buf2 ); + m.normalmaps.push_back( string(buf2) ); + }*/ + } + + // vn and fn should be correct but if someone wrongly saved some deleted elements they can be wrong. + m.vn = 0; + for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) + if( ! (*vi).IsD() ) + ++m.vn; + + m.fn = 0; + for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) + if( ! (*fi).IsD() ) + ++m.fn; + + tri::UpdateBounding::Box(m); + return 0; + } + + + // Caricamento camera da un ply + int LoadCamera(const char * filename) + { + vcg::ply::PlyFile pf; + if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) + { + this->pi.status = pf.GetError(); + return this->pi.status; + } + + + bool found = true; + for(int i=0;i<23;++i) + { + if( pf.AddToRead(CameraDesc(i))==-1 ) + { + found = false; + break; + } + } + + if(!found) + return this->pi.status; + + for(size_t i=0;ipi.status = PlyInfo::E_SHORTFILE; + return this->pi.status; + } + this->camera.valid = true; + this->camera.view_p[0] = ca.view_px; + this->camera.view_p[1] = ca.view_py; + this->camera.view_p[2] = ca.view_pz; + this->camera.x_axis[0] = ca.x_axisx; + this->camera.x_axis[1] = ca.x_axisy; + this->camera.x_axis[2] = ca.x_axisz; + this->camera.y_axis[0] = ca.y_axisx; + this->camera.y_axis[1] = ca.y_axisy; + this->camera.y_axis[2] = ca.y_axisz; + this->camera.z_axis[0] = ca.z_axisx; + this->camera.z_axis[1] = ca.z_axisy; + this->camera.z_axis[2] = ca.z_axisz; + this->camera.f = ca.focal; + this->camera.s[0] = ca.scalex; + this->camera.s[1] = ca.scaley; + this->camera.c[0] = ca.centerx; + this->camera.c[1] = ca.centery; + this->camera.viewport[0] = ca.viewportx; + this->camera.viewport[1] = ca.viewporty; + this->camera.k[0] = ca.k1; + this->camera.k[1] = ca.k2; + this->camera.k[2] = ca.k3; + this->camera.k[3] = ca.k4; + } + break; + } + } + + return 0; + } + + + static bool LoadMask(const char * filename, int &mask) + { + PlyInfo pi; + return LoadMask(filename, mask,pi); + } + static bool LoadMask(const char * filename, int &mask, PlyInfo &pi) + { + mask=0; + vcg::ply::PlyFile pf; + if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) + { + pi.status = pf.GetError(); + return false; + } + + if( pf.AddToRead(VertDesc( 0))!=-1 && + pf.AddToRead(VertDesc( 1))!=-1 && + pf.AddToRead(VertDesc( 2))!=-1 ) mask |= Mask::IOM_VERTCOORD; + if( pf.AddToRead(VertDesc(24))!=-1 && + pf.AddToRead(VertDesc(25))!=-1 && + pf.AddToRead(VertDesc(26))!=-1 ) mask |= Mask::IOM_VERTCOORD; + + if( pf.AddToRead(VertDesc(14))!=-1 && + pf.AddToRead(VertDesc(15))!=-1 && + pf.AddToRead(VertDesc(16))!=-1 ) mask |= Mask::IOM_VERTNORMAL; + if( pf.AddToRead(VertDesc(27))!=-1 && + pf.AddToRead(VertDesc(28))!=-1 && + pf.AddToRead(VertDesc(29))!=-1 ) mask |= Mask::IOM_VERTNORMAL; + + if( pf.AddToRead(VertDesc( 3))!=-1 ) mask |= Mask::IOM_VERTFLAGS; + if( pf.AddToRead(VertDesc( 4))!=-1 ) mask |= Mask::IOM_VERTQUALITY; + if( pf.AddToRead(VertDesc(13))!=-1 ) mask |= Mask::IOM_VERTQUALITY; + if( pf.AddToRead(VertDesc(17))!=-1 ) mask |= Mask::IOM_VERTRADIUS; + if( pf.AddToRead(VertDesc(30))!=-1 ) mask |= Mask::IOM_VERTRADIUS; + if( pf.AddToRead(VertDesc(31))!=-1 ) mask |= Mask::IOM_VERTQUALITY; + if( pf.AddToRead(VertDesc( 5))!=-1 && + pf.AddToRead(VertDesc( 6))!=-1 && + pf.AddToRead(VertDesc( 7))!=-1 ) mask |= Mask::IOM_VERTCOLOR; + if( pf.AddToRead(VertDesc( 9))!=-1 && + pf.AddToRead(VertDesc(10))!=-1 && + pf.AddToRead(VertDesc(11))!=-1 ) mask |= Mask::IOM_VERTCOLOR; + if( pf.AddToRead(VertDesc(21))!=-1 ) mask |= Mask::IOM_VERTCOLOR; + + if( pf.AddToRead(VertDesc(22))!=-1 && + pf.AddToRead(VertDesc(23))!=-1) mask |= Mask::IOM_VERTTEXCOORD; + + if( pf.AddToRead(VertDesc(18))!=-1 && + pf.AddToRead(VertDesc(19))!=-1) mask |= Mask::IOM_VERTTEXCOORD; + + if( pf.AddToRead(FaceDesc(0))!=-1 ) mask |= Mask::IOM_FACEINDEX; + if( pf.AddToRead(FaceDesc(1))!=-1 ) mask |= Mask::IOM_FACEFLAGS; + if( pf.AddToRead(FaceDesc(10))!=-1 && + pf.AddToRead(FaceDesc(11))!=-1 && + pf.AddToRead(FaceDesc(12))!=-1 ) mask |= Mask::IOM_FACENORMAL; + if( pf.AddToRead(FaceDesc(26))!=-1 && + pf.AddToRead(FaceDesc(27))!=-1 && + pf.AddToRead(FaceDesc(28))!=-1 ) mask |= Mask::IOM_FACENORMAL; + if( pf.AddToRead(FaceDesc(2))!=-1 ) mask |= Mask::IOM_FACEQUALITY; + if( pf.AddToRead(FaceDesc(25))!=-1 ) mask |= Mask::IOM_FACEQUALITY; + if( pf.AddToRead(FaceDesc(3))!=-1 ) mask |= Mask::IOM_WEDGTEXCOORD; + if( pf.AddToRead(FaceDesc(5))!=-1 ) mask |= Mask::IOM_WEDGTEXMULTI; + if( pf.AddToRead(FaceDesc(4))!=-1 ) mask |= Mask::IOM_WEDGCOLOR; + if( pf.AddToRead(FaceDesc(6))!=-1 && + pf.AddToRead(FaceDesc(7))!=-1 && + pf.AddToRead(FaceDesc(8))!=-1 ) mask |= Mask::IOM_FACECOLOR; + + return true; + } }; // end class