added support for face normals export and import and face (double precision) quality export and import for ply format

This commit is contained in:
T.Alderighi 2019-09-10 15:42:41 +02:00
parent d46c581ffb
commit ca65cf2162
2 changed files with 1164 additions and 1108 deletions

View File

@ -263,6 +263,14 @@ namespace vcg {
); );
} }
if (HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL))
{
const char* fntp = vcg::tri::io::Precision<typename SaveMeshType::ScalarType>::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) ) if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
{ {
const char* fqtp = vcg::tri::io::Precision<typename SaveMeshType::FaceType::QualityType>::typeName(); const char* fqtp = vcg::tri::io::Precision<typename SaveMeshType::FaceType::QualityType>::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) ) if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout); 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) ) if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
fprintf(fpout,"%.*g ",DGTFQ,fp->Q()); fprintf(fpout,"%.*g ",DGTFQ,fp->Q());

View File

@ -56,23 +56,28 @@ class ImporterPLY
{ {
public: public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ; typedef ::vcg::ply::PropDescriptor PropDescriptor ;
typedef typename OpenMeshType::VertexPointer VertexPointer; typedef typename OpenMeshType::VertexPointer VertexPointer;
typedef typename OpenMeshType::ScalarType ScalarType; typedef typename OpenMeshType::ScalarType ScalarType;
typedef typename OpenMeshType::VertexType VertexType; typedef typename OpenMeshType::VertexType VertexType;
typedef typename OpenMeshType::FaceType FaceType; typedef typename VertexType::QualityType VertQualityType;
typedef typename OpenMeshType::VertexIterator VertexIterator; typedef typename OpenMeshType::FaceType FaceType;
typedef typename OpenMeshType::FaceIterator FaceIterator; typedef typename FaceType::QualityType FaceQualityType;
typedef typename OpenMeshType::EdgeIterator EdgeIterator;
typedef typename OpenMeshType::VertexIterator VertexIterator;
typedef typename OpenMeshType::FaceIterator FaceIterator;
typedef typename OpenMeshType::EdgeIterator EdgeIterator;
#define MAX_USER_DATA 256 #define MAX_USER_DATA 256
// Auxiliary structure for reading ply files // Auxiliary structure for reading ply files
struct LoadPly_FaceAux template<class S>
{ struct LoadPly_FaceAux
{
unsigned char size; unsigned char size;
int v[512]; int v[512];
int flags; int flags;
float q; S n[3];
S q;
float texcoord[32]; float texcoord[32];
unsigned char ntexcoord; unsigned char ntexcoord;
int texcoordind; int texcoordind;
@ -85,33 +90,33 @@ struct LoadPly_FaceAux
unsigned char a; unsigned char a;
unsigned char data[MAX_USER_DATA]; unsigned char data[MAX_USER_DATA];
}; };
struct LoadPly_TristripAux struct LoadPly_TristripAux
{ {
int size; int size;
int *v; int *v;
unsigned char data[MAX_USER_DATA]; unsigned char data[MAX_USER_DATA];
}; };
struct LoadPly_EdgeAux struct LoadPly_EdgeAux
{ {
int v1,v2; int v1,v2;
unsigned char data[MAX_USER_DATA]; unsigned char data[MAX_USER_DATA];
}; };
// Yet another auxiliary data structure for loading some strange ply files // Yet another auxiliary data structure for loading some strange ply files
// the original stanford range data... // the original stanford range data...
struct LoadPly_RangeGridAux { struct LoadPly_RangeGridAux {
unsigned char num_pts; unsigned char num_pts;
int pts[5]; int pts[5];
}; };
// Auxiliary structure to load vertex data // Auxiliary structure to load vertex data
template<class S> template<class S>
struct LoadPly_VertAux struct LoadPly_VertAux
{ {
S p[3]; S p[3];
S n[3]; S n[3];
int flags; int flags;
@ -124,11 +129,11 @@ struct LoadPly_VertAux
unsigned char data[MAX_USER_DATA]; unsigned char data[MAX_USER_DATA];
float radius; float radius;
float u,v,w; float u,v,w;
}; };
// Auxiliary structure to load the camera // Auxiliary structure to load the camera
struct LoadPly_Camera struct LoadPly_Camera
{ {
float view_px; float view_px;
float view_py; float view_py;
float view_pz; float view_pz;
@ -152,114 +157,123 @@ struct LoadPly_Camera
float k2; float k2;
float k3; float k3;
float k4; float k4;
}; };
#define _VERTDESC_LAST_ 32 #define _VERTDESC_LAST_ 32
static const PropDescriptor &VertDesc(int i) static const PropDescriptor &VertDesc(int i)
{ {
static const PropDescriptor pv[_VERTDESC_LAST_]={ static const PropDescriptor pv[_VERTDESC_LAST_]={
/*00*/ {"vertex", "x", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0 ,0}, /*00*/ {"vertex", "x", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0 ,0},
/*01*/ {"vertex", "y", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType),0,0,0,0,0 ,0}, /*01*/ {"vertex", "y", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType),0,0,0,0,0 ,0},
/*02*/ {"vertex", "z", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, /*02*/ {"vertex", "z", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
/*03*/ {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux<ScalarType>,flags),0,0,0,0,0 ,0}, /*03*/ {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux<ScalarType>,flags),0,0,0,0,0 ,0},
/*04*/ {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0}, /*04*/ {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<float>,q),0,0,0,0,0 ,0},
/*05*/ {"vertex", "red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0 ,0}, /*05*/ {"vertex", "red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0 ,0},
/*06*/ {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0 ,0}, /*06*/ {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0 ,0},
/*07*/ { "vertex", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0 ,0}, /*07*/ { "vertex", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0 ,0},
/*08*/ { "vertex", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a),0,0,0,0,0 ,0}, /*08*/ { "vertex", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a),0,0,0,0,0 ,0},
/*09*/ {"vertex", "diffuse_red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0 ,0}, /*09*/ {"vertex", "diffuse_red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0 ,0},
/*10*/ {"vertex", "diffuse_green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0 ,0}, /*10*/ {"vertex", "diffuse_green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0 ,0},
/*11*/ {"vertex", "diffuse_blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0 ,0}, /*11*/ {"vertex", "diffuse_blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0 ,0},
/*12*/ {"vertex", "diffuse_alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a),0,0,0,0,0 ,0}, /*12*/ {"vertex", "diffuse_alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a),0,0,0,0,0 ,0},
/*13*/ {"vertex", "confidence", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0}, /*13*/ {"vertex", "confidence", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0},
/*14*/ {"vertex", "nx", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0}, /*14*/ {"vertex", "nx", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0},
/*15*/ {"vertex", "ny", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, /*15*/ {"vertex", "ny", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0},
/*16*/ {"vertex", "nz", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, /*16*/ {"vertex", "nz", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
/*17*/ {"vertex", "radius", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0}, /*17*/ {"vertex", "radius", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0},
/*18*/ {"vertex", "texture_u", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0 ,0}, /*18*/ {"vertex", "texture_u", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0 ,0},
/*19*/ {"vertex", "texture_v", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0 ,0}, /*19*/ {"vertex", "texture_v", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0 ,0},
/*20*/ {"vertex", "texture_w", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,w),0,0,0,0,0 ,0}, /*20*/ {"vertex", "texture_w", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,w),0,0,0,0,0 ,0},
/*21*/ {"vertex", "intensity", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,intensity),0,0,0,0,0 ,0}, /*21*/ {"vertex", "intensity", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,intensity),0,0,0,0,0 ,0},
/*22*/ {"vertex", "s", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0 ,0}, /*22*/ {"vertex", "s", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0 ,0},
/*23*/ {"vertex", "t", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0 ,0}, /*23*/ {"vertex", "t", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0 ,0},
// DOUBLE // DOUBLE
/*24*/ {"vertex", "x", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0 ,0}, /*24*/ {"vertex", "x", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0 ,0},
/*25*/ {"vertex", "y", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType) ,0,0,0,0,0 ,0}, /*25*/ {"vertex", "y", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType) ,0,0,0,0,0 ,0},
/*26*/ {"vertex", "z", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, /*26*/ {"vertex", "z", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
/*27*/ {"vertex", "nx", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0}, /*27*/ {"vertex", "nx", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0},
/*28*/ {"vertex", "ny", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0}, /*28*/ {"vertex", "ny", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0},
/*29*/ {"vertex", "nz", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0}, /*29*/ {"vertex", "nz", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
/*30*/ {"vertex", "radius", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0}, /*30*/ {"vertex", "radius", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0},
/*31*/ {"vertex", "quality", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0} /*31*/ {"vertex", "quality", ply::T_DOUBLE, ply::T_DOUBLE,offsetof(LoadPly_VertAux<double>,q),0,0,0,0,0 ,0}
}; };
return pv[i]; return pv[i];
} }
#define _FACEDESC_FIRST_ 10 // the first descriptor with possible vertex indices #define _FACEDESC_FIRST_ 13 // the first descriptor with possible vertex indices
#define _FACEDESC_LAST_ 22 #define _FACEDESC_LAST_ 29
static const PropDescriptor &FaceDesc(int i) static const PropDescriptor &FaceDesc(int i)
{ {
static const PropDescriptor qf[_FACEDESC_LAST_]= static const PropDescriptor qf[_FACEDESC_LAST_]=
{ {
/* on file on memory on file on memory */ /* 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}, /* 0 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 1 */ {"face", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,flags), 0,0,0,0,0 ,0}, /* 1 */ {"face", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 2 */ {"face", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 3 */ {"face", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux<ScalarType>,texcoord), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 4 */ {"face", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux<ScalarType>,colors), 1,0,ply::T_UCHAR, ply::T_UCHAR,offsetof(LoadPly_FaceAux<ScalarType>,ncolors) ,0},
/* 5 */ {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,texcoordind), 0,0,0,0,0 ,0}, /* 5 */ {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 6 */ {"face", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 7 */ {"face", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 8 */ {"face", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 9 */ {"face", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux<ScalarType>,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}, /* 10 */ {"face", "nx", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_FaceAux<ScalarType>,n) ,0,0,0,0,0 ,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}, /* 11 */ {"face", "ny", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_FaceAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,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}, /* 12 */ {"face", "nz", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_FaceAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
/* 13 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 14 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 15 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 16 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 17 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 18 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 19 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 20 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 21 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_USHORT,ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 22 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 23 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
/* 24 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux<ScalarType>,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux<ScalarType>,size) ,0},
// DOUBLE
/* 25 */ {"face", "quality", ply::T_DOUBLE, ply::T_DOUBLE, offsetof(LoadPly_FaceAux<double>,q), 0,0,0,0,0 ,0},
/* 26 */ {"face", "nx", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_FaceAux<ScalarType>,n) ,0,0,0,0,0 ,0},
/* 27 */ {"face", "ny", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_FaceAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0},
/* 28 */ {"face", "nz", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_FaceAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,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]; return qf[i];
} }
static const PropDescriptor &TristripDesc(int i) static const PropDescriptor &TristripDesc(int i)
{ {
static const PropDescriptor qf[1]= 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}, {"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]; return qf[i];
} }
static const PropDescriptor &EdgeDesc(int i) static const PropDescriptor &EdgeDesc(int i)
{ {
static const PropDescriptor qf[2]= static const PropDescriptor qf[2]=
{ {
{"edge","vertex1", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v1), 0,0,0,0,0 ,0}, {"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}, {"edge","vertex2", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v2), 0,0,0,0,0 ,0},
}; };
return qf[i]; return qf[i];
} }
// Descriptor for the Stanford Data Repository Range Maps. // Descriptor for the Stanford Data Repository Range Maps.
// In practice a grid with some invalid elements. Coords are saved only for good elements // In practice a grid with some invalid elements. Coords are saved only for good elements
static const PropDescriptor &RangeDesc(int i) static const PropDescriptor &RangeDesc(int i)
{ {
static const PropDescriptor range_props[1] = { 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}, {"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]; return range_props[i];
} }
static const PropDescriptor &CameraDesc(int i) static const PropDescriptor &CameraDesc(int i)
{ {
static const PropDescriptor cad[23] = 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_px",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_px),0,0,0,0,0 ,0},
@ -287,10 +301,10 @@ static const PropDescriptor &CameraDesc(int i)
{"camera","k4" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k4 ),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]; return cad[i];
} }
/// Standard call for knowing the meaning of an error code /// Standard call for knowing the meaning of an error code
static const char *ErrorMsg(int error) static const char *ErrorMsg(int error)
{ {
static std::vector<std::string> ply_error_msg; static std::vector<std::string> ply_error_msg;
if(ply_error_msg.empty()) if(ply_error_msg.empty())
{ {
@ -321,44 +335,44 @@ static const char *ErrorMsg(int error)
if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error"; if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error";
else return ply_error_msg[error].c_str(); else return ply_error_msg[error].c_str();
}; };
// to check if a given error is critical or not. // to check if a given error is critical or not.
static bool ErrorCritical(int err) static bool ErrorCritical(int err)
{ {
if ((err == ply::E_NOERROR) || (err == PlyInfo::E_NO_FACE)) return false; if ((err == ply::E_NOERROR) || (err == PlyInfo::E_NO_FACE)) return false;
return true; return true;
} }
/// Standard call for reading a mesh, returns 0 on success. /// Standard call for reading a mesh, returns 0 on success.
static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0) static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0)
{ {
PlyInfo pi; PlyInfo pi;
pi.cb=cb; pi.cb=cb;
return Open(m, filename, pi); return Open(m, filename, pi);
} }
/// Read a mesh and store in loadmask the loaded field /// Read a mesh and store in loadmask the loaded field
/// Note that loadmask is not read! just modified. You cannot specify what fields /// 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 /// have to be read. ALL the data for which your mesh HasSomething and are present
/// in the file are read in. /// in the file are read in.
static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0) static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0)
{ {
PlyInfo pi; PlyInfo pi;
pi.cb=cb; pi.cb=cb;
int r = Open(m, filename,pi); int r = Open(m, filename,pi);
loadmask=pi.mask; loadmask=pi.mask;
return r; return r;
} }
/// read a mesh with all the possible option specified in the PlyInfo obj, returns 0 on success. /// 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 ) static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
{ {
assert(filename!=0); assert(filename!=0);
std::vector<VertexPointer> index; std::vector<VertexPointer> index;
LoadPly_FaceAux fa; LoadPly_FaceAux<ScalarType> fa;
LoadPly_EdgeAux ea; LoadPly_EdgeAux ea;
LoadPly_TristripAux tsa; LoadPly_TristripAux tsa;
LoadPly_VertAux<ScalarType> va; LoadPly_VertAux<ScalarType> va;
@ -508,10 +522,20 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
if( pf.AddToRead(FaceDesc(1))!=-1 ) if( pf.AddToRead(FaceDesc(1))!=-1 )
pi.mask |= Mask::IOM_FACEFLAGS; 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( vcg::tri::HasPerFaceQuality(m) )
{ {
if( pf.AddToRead(FaceDesc(2))!=-1 ) if( pf.AddToRead(FaceDesc(2))!=-1 )
pi.mask |= Mask::IOM_FACEQUALITY; pi.mask |= Mask::IOM_FACEQUALITY;
else if (pf.AddToRead(FaceDesc(25)) != -1)
pi.mask |= Mask::IOM_FACEQUALITY;
} }
if( vcg::tri::HasPerFaceColor(m) ) if( vcg::tri::HasPerFaceColor(m) )
@ -568,7 +592,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
size_t totsz=0; size_t totsz=0;
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++){ for(size_t i=0;i<pi.FaceDescriptorVec.size();i++){
FPV[i] = pi.FaceDescriptorVec[i]; FPV[i] = pi.FaceDescriptorVec[i];
FPV[i].offset1=offsetof(LoadPly_FaceAux,data)+totsz; FPV[i].offset1=offsetof(LoadPly_FaceAux<ScalarType>,data)+totsz;
totsz+=pi.FaceDescriptorVec[i].memtypesize(); totsz+=pi.FaceDescriptorVec[i].memtypesize();
if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; } if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
} }
@ -664,7 +688,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
(*vi).Flags() = va.flags; (*vi).Flags() = va.flags;
if( pi.mask & Mask::IOM_VERTQUALITY ) if( pi.mask & Mask::IOM_VERTQUALITY )
(*vi).Q() = (typename OpenMeshType::VertexType::QualityType)va.q; (*vi).Q() = (VertQualityType)va.q;
if( pi.mask & Mask::IOM_VERTNORMAL ) if( pi.mask & Mask::IOM_VERTNORMAL )
{ {
@ -763,6 +787,13 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
(*fi).Flags() = fa.flags; (*fi).Flags() = fa.flags;
} }
if (pi.mask & Mask::IOM_FACENORMAL)
{
(*fi).N()[0] = fa.n[0];
(*fi).N()[1] = fa.n[1];
(*fi).N()[2] = fa.n[2];
}
if( pi.mask & Mask::IOM_FACEQUALITY ) if( pi.mask & Mask::IOM_FACEQUALITY )
{ {
(*fi).Q() = (typename OpenMeshType::FaceType::QualityType) fa.q; (*fi).Q() = (typename OpenMeshType::FaceType::QualityType) fa.q;
@ -1037,12 +1068,12 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
tri::UpdateBounding<OpenMeshType>::Box(m); tri::UpdateBounding<OpenMeshType>::Box(m);
return 0; return 0;
} }
// Caricamento camera da un ply // Caricamento camera da un ply
int LoadCamera(const char * filename) int LoadCamera(const char * filename)
{ {
vcg::ply::PlyFile pf; vcg::ply::PlyFile pf;
if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
{ {
@ -1111,16 +1142,16 @@ int LoadCamera(const char * filename)
} }
return 0; return 0;
} }
static bool LoadMask(const char * filename, int &mask) static bool LoadMask(const char * filename, int &mask)
{ {
PlyInfo pi; PlyInfo pi;
return LoadMask(filename, mask,pi); return LoadMask(filename, mask,pi);
} }
static bool LoadMask(const char * filename, int &mask, PlyInfo &pi) static bool LoadMask(const char * filename, int &mask, PlyInfo &pi)
{ {
mask=0; mask=0;
vcg::ply::PlyFile pf; vcg::ply::PlyFile pf;
if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
@ -1165,8 +1196,14 @@ static bool LoadMask(const char * filename, int &mask, PlyInfo &pi)
if( pf.AddToRead(FaceDesc(0))!=-1 ) mask |= Mask::IOM_FACEINDEX; if( pf.AddToRead(FaceDesc(0))!=-1 ) mask |= Mask::IOM_FACEINDEX;
if( pf.AddToRead(FaceDesc(1))!=-1 ) mask |= Mask::IOM_FACEFLAGS; 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(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(3))!=-1 ) mask |= Mask::IOM_WEDGTEXCOORD;
if( pf.AddToRead(FaceDesc(5))!=-1 ) mask |= Mask::IOM_WEDGTEXMULTI; if( pf.AddToRead(FaceDesc(5))!=-1 ) mask |= Mask::IOM_WEDGTEXMULTI;
if( pf.AddToRead(FaceDesc(4))!=-1 ) mask |= Mask::IOM_WEDGCOLOR; if( pf.AddToRead(FaceDesc(4))!=-1 ) mask |= Mask::IOM_WEDGCOLOR;
@ -1175,7 +1212,7 @@ static bool LoadMask(const char * filename, int &mask, PlyInfo &pi)
pf.AddToRead(FaceDesc(8))!=-1 ) mask |= Mask::IOM_FACECOLOR; pf.AddToRead(FaceDesc(8))!=-1 ) mask |= Mask::IOM_FACECOLOR;
return true; return true;
} }
}; // end class }; // end class