00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __VCGLIB_IMPORTERPLY
00024 #define __VCGLIB_IMPORTERPLY
00025
00026 #include <stddef.h>
00027 #include<wrap/callback.h>
00028 #include<wrap/ply/plylib.h>
00029 #include<wrap/io_trimesh/io_mask.h>
00030 #include<wrap/io_trimesh/io_ply.h>
00031 #include<vcg/complex/algorithms/create/platonic.h>
00032
00033 namespace vcg {
00034 namespace tri {
00035 namespace io {
00036
00037 template <class TYPE>
00038 int PlyType () { return 0;}
00039
00040
00041
00042
00043
00044 template <> inline int PlyType <float >() { return ply::T_FLOAT; }
00045 template <> inline int PlyType <double>() { return ply::T_DOUBLE; }
00046 template <> inline int PlyType <int >() { return ply::T_INT; }
00047 template <> inline int PlyType <short >() { return ply::T_SHORT; }
00048 template <> inline int PlyType <unsigned char >() { return ply::T_UCHAR; }
00049
00054 template <class OpenMeshType>
00055 class ImporterPLY
00056 {
00057 public:
00058
00059 typedef ::vcg::ply::PropDescriptor PropDescriptor ;
00060 typedef typename OpenMeshType::VertexPointer VertexPointer;
00061 typedef typename OpenMeshType::ScalarType ScalarType;
00062 typedef typename OpenMeshType::VertexType VertexType;
00063 typedef typename OpenMeshType::FaceType FaceType;
00064 typedef typename OpenMeshType::VertexIterator VertexIterator;
00065 typedef typename OpenMeshType::FaceIterator FaceIterator;
00066 typedef typename OpenMeshType::EdgeIterator EdgeIterator;
00067
00068 #define MAX_USER_DATA 256
00069
00070 struct LoadPly_FaceAux
00071 {
00072 unsigned char size;
00073 int v[512];
00074 int flags;
00075 float q;
00076 float texcoord[32];
00077 unsigned char ntexcoord;
00078 int texcoordind;
00079 float colors[32];
00080 unsigned char ncolors;
00081
00082 unsigned char r;
00083 unsigned char g;
00084 unsigned char b;
00085 unsigned char a;
00086
00087 unsigned char data[MAX_USER_DATA];
00088 };
00089
00090 struct LoadPly_TristripAux
00091 {
00092 int size;
00093 int *v;
00094 unsigned char data[MAX_USER_DATA];
00095 };
00096
00097 struct LoadPly_EdgeAux
00098 {
00099 int v1,v2;
00100 unsigned char data[MAX_USER_DATA];
00101 };
00102
00103
00104
00105 struct LoadPly_RangeGridAux {
00106 unsigned char num_pts;
00107 int pts[5];
00108 };
00109
00110
00111
00112 template<class S>
00113 struct LoadPly_VertAux
00114 {
00115 S p[3];
00116 S n[3];
00117 int flags;
00118 float q;
00119 float intensity;
00120 unsigned char r;
00121 unsigned char g;
00122 unsigned char b;
00123 unsigned char a;
00124 unsigned char data[MAX_USER_DATA];
00125 float radius;
00126 float u,v,w;
00127 };
00128
00129
00130 struct LoadPly_Camera
00131 {
00132 float view_px;
00133 float view_py;
00134 float view_pz;
00135 float x_axisx;
00136 float x_axisy;
00137 float x_axisz;
00138 float y_axisx;
00139 float y_axisy;
00140 float y_axisz;
00141 float z_axisx;
00142 float z_axisy;
00143 float z_axisz;
00144 float focal;
00145 float scalex;
00146 float scaley;
00147 float centerx;
00148 float centery;
00149 int viewportx;
00150 int viewporty;
00151 float k1;
00152 float k2;
00153 float k3;
00154 float k4;
00155 };
00156
00157 #define _VERTDESC_LAST_ 32
00158 static const PropDescriptor &VertDesc(int i)
00159 {
00160 static const PropDescriptor pv[_VERTDESC_LAST_]={
00161 {"vertex", "x", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0 ,0},
00162 {"vertex", "y", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType),0,0,0,0,0 ,0},
00163 {"vertex", "z", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
00164 {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux<ScalarType>,flags),0,0,0,0,0 ,0},
00165 {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0},
00166 {"vertex", "red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0 ,0},
00167 {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0 ,0},
00168 { "vertex", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0 ,0},
00169 { "vertex", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a),0,0,0,0,0 ,0},
00170 {"vertex", "diffuse_red", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0 ,0},
00171 {"vertex", "diffuse_green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0 ,0},
00172 {"vertex", "diffuse_blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0 ,0},
00173 {"vertex", "diffuse_alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a),0,0,0,0,0 ,0},
00174 {"vertex", "confidence", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0},
00175 {"vertex", "nx", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0},
00176 {"vertex", "ny", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0},
00177 {"vertex", "nz", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
00178 {"vertex", "radius", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0},
00179 {"vertex", "texture_u", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0 ,0},
00180 {"vertex", "texture_v", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0 ,0},
00181 {"vertex", "texture_w", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,w),0,0,0,0,0 ,0},
00182 {"vertex", "intensity", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,intensity),0,0,0,0,0 ,0},
00183 {"vertex", "s", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0 ,0},
00184 {"vertex", "t", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0 ,0},
00185
00186 {"vertex", "x", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0 ,0},
00187 {"vertex", "y", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType) ,0,0,0,0,0 ,0},
00188 {"vertex", "z", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
00189 {"vertex", "nx", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0},
00190 {"vertex", "ny", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0},
00191 {"vertex", "nz", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
00192 {"vertex", "radius", ply::T_DOUBLE, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0},
00193 {"vertex", "quality", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0}
00194 };
00195 return pv[i];
00196 }
00197
00198 #define _FACEDESC_FIRST_ 10 // the first descriptor with possible vertex indices
00199 #define _FACEDESC_LAST_ 22
00200 static const PropDescriptor &FaceDesc(int i)
00201 {
00202 static const PropDescriptor qf[_FACEDESC_LAST_]=
00203 {
00204
00205 {"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},
00206 {"face", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,flags), 0,0,0,0,0 ,0},
00207 {"face", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,q), 0,0,0,0,0 ,0},
00208 {"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},
00209 {"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},
00210 {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,texcoordind), 0,0,0,0,0 ,0},
00211 {"face", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,r), 0,0,0,0,0 ,0},
00212 {"face", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,g), 0,0,0,0,0 ,0},
00213 {"face", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0 ,0},
00214 {"face", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,a), 0,0,0,0,0 ,0},
00215 {"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},
00216 {"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},
00217 {"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},
00218
00219 {"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},
00220 {"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},
00221 {"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},
00222 {"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},
00223 {"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},
00224 {"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},
00225 {"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},
00226 {"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},
00227 {"face", "vertex_indices", ply::T_CHAR, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}
00228 };
00229 return qf[i];
00230 }
00231 static const PropDescriptor &TristripDesc(int i)
00232 {
00233 static const PropDescriptor qf[1]=
00234 {
00235 {"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},
00236 };
00237 return qf[i];
00238 }
00239
00240 static const PropDescriptor &EdgeDesc(int i)
00241 {
00242 static const PropDescriptor qf[2]=
00243 {
00244 {"edge","vertex1", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v1), 0,0,0,0,0 ,0},
00245 {"edge","vertex2", ply::T_INT, ply::T_INT, offsetof(LoadPly_EdgeAux,v2), 0,0,0,0,0 ,0},
00246 };
00247 return qf[i];
00248 }
00249
00250
00251
00252 static const PropDescriptor &RangeDesc(int i)
00253 {
00254 static const PropDescriptor range_props[1] = {
00255 {"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},
00256 };
00257 return range_props[i];
00258 }
00259
00260
00261 static const PropDescriptor &CameraDesc(int i)
00262 {
00263 static const PropDescriptor cad[23] =
00264 {
00265 {"camera","view_px",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_px),0,0,0,0,0 ,0},
00266 {"camera","view_py",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_py),0,0,0,0,0 ,0},
00267 {"camera","view_pz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_pz),0,0,0,0,0 ,0},
00268 {"camera","x_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisx),0,0,0,0,0 ,0},
00269 {"camera","x_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisy),0,0,0,0,0 ,0},
00270 {"camera","x_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisz),0,0,0,0,0 ,0},
00271 {"camera","y_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisx),0,0,0,0,0 ,0},
00272 {"camera","y_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisy),0,0,0,0,0 ,0},
00273 {"camera","y_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisz),0,0,0,0,0 ,0},
00274 {"camera","z_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisx),0,0,0,0,0 ,0},
00275 {"camera","z_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisy),0,0,0,0,0 ,0},
00276 {"camera","z_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisz),0,0,0,0,0 ,0},
00277 {"camera","focal" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,focal ),0,0,0,0,0 ,0},
00278 {"camera","scalex" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scalex ),0,0,0,0,0 ,0},
00279 {"camera","scaley" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scaley ),0,0,0,0,0 ,0},
00280 {"camera","centerx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centerx),0,0,0,0,0 ,0},
00281 {"camera","centery",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centery),0,0,0,0,0 ,0},
00282 {"camera","viewportx",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewportx),0,0,0,0,0 ,0},
00283 {"camera","viewporty",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewporty),0,0,0,0,0 ,0},
00284 {"camera","k1" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k1 ),0,0,0,0,0 ,0},
00285 {"camera","k2" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k2 ),0,0,0,0,0 ,0},
00286 {"camera","k3" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k3 ),0,0,0,0,0 ,0},
00287 {"camera","k4" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k4 ),0,0,0,0,0 ,0}
00288 };
00289 return cad[i];
00290 }
00292 static const char *ErrorMsg(int error)
00293 {
00294 static std::vector<std::string> ply_error_msg;
00295 if(ply_error_msg.empty())
00296 {
00297 ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS );
00298 ply_error_msg[ply::E_NOERROR ]="No errors";
00299 ply_error_msg[ply::E_CANTOPEN ]="Can't open file";
00300 ply_error_msg[ply::E_NOTHEADER ]="Header not found";
00301 ply_error_msg[ply::E_UNESPECTEDEOF ]="Eof in header";
00302 ply_error_msg[ply::E_NOFORMAT ]="Format not found";
00303 ply_error_msg[ply::E_SYNTAX ]="Syntax error on header";
00304 ply_error_msg[ply::E_PROPOUTOFELEMENT]="Property without element";
00305 ply_error_msg[ply::E_BADTYPENAME ]="Bad type name";
00306 ply_error_msg[ply::E_ELEMNOTFOUND ]="Element not found";
00307 ply_error_msg[ply::E_PROPNOTFOUND ]="Property not found";
00308 ply_error_msg[ply::E_BADTYPE ]="Bad type on addtoread";
00309 ply_error_msg[ply::E_INCOMPATIBLETYPE]="Incompatible type";
00310 ply_error_msg[ply::E_BADCAST ]="Bad cast";
00311
00312 ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found";
00313 ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found";
00314 ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof";
00315 ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices";
00316 ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face";
00317 ply_error_msg[PlyInfo::E_BAD_VERT_INDEX_EDGE ]="Bad vertex index in edge";
00318 ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates";
00319 ply_error_msg[PlyInfo::E_DIFFER_COLORS ]="Number of color differ from vertices";
00320 }
00321
00322 if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error";
00323 else return ply_error_msg[error].c_str();
00324 };
00325
00326
00327 static bool ErrorCritical(int err)
00328 {
00329 if ((err == ply::E_NOERROR) || (err == PlyInfo::E_NO_FACE)) return false;
00330 return true;
00331 }
00332
00333
00335 static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0)
00336 {
00337 PlyInfo pi;
00338 pi.cb=cb;
00339 return Open(m, filename, pi);
00340 }
00341
00346 static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0)
00347 {
00348 PlyInfo pi;
00349 pi.cb=cb;
00350 int r = Open(m, filename,pi);
00351 loadmask=pi.mask;
00352 return r;
00353 }
00354
00355
00357 static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
00358 {
00359 assert(filename!=0);
00360 std::vector<VertexPointer> index;
00361 LoadPly_FaceAux fa;
00362 LoadPly_EdgeAux ea;
00363 LoadPly_TristripAux tsa;
00364 LoadPly_VertAux<ScalarType> va;
00365
00366 LoadPly_RangeGridAux rga;
00367 std::vector<int> RangeGridAuxVec;
00368 int RangeGridCols=0;
00369 int RangeGridRows=0;
00370
00371
00372 pi.mask = 0;
00373 bool hasIntensity = false;
00374 bool multit = false;
00375
00376 va.flags = 42;
00377
00378 pi.status = ::vcg::ply::E_NOERROR;
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 vcg::ply::PlyFile pf;
00398
00399
00400 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00401 {
00402 pi.status = pf.GetError();
00403 return pi.status;
00404 }
00405 pi.header = pf.GetHeader();
00406
00407
00408 {
00409 bool found = true;
00410 for(int i=0;i<23;++i)
00411 {
00412 if( pf.AddToRead(CameraDesc(i))==-1 ) {
00413 found = false;
00414 break;
00415 }
00416 }
00417 if(found) pi.mask |= Mask::IOM_CAMERA;
00418 }
00419
00420
00421 if( pf.AddToRead(VertDesc(0))==-1 && pf.AddToRead(VertDesc(24)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
00422 if( pf.AddToRead(VertDesc(1))==-1 && pf.AddToRead(VertDesc(25)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
00423 if( pf.AddToRead(VertDesc(2))==-1 && pf.AddToRead(VertDesc(26)) ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
00424 if( pf.AddToRead(FaceDesc(0))==-1 )
00425 {
00426 int ii;
00427 for (ii=_FACEDESC_FIRST_;ii< _FACEDESC_LAST_;++ii)
00428 if( pf.AddToRead(FaceDesc(ii))!=-1 ) break;
00429
00430 if (ii==_FACEDESC_LAST_)
00431 if(pf.AddToRead(TristripDesc(0))==-1)
00432 if(pf.AddToRead(RangeDesc(0))==-1)
00433 {
00434 pi.status = PlyInfo::E_NO_FACE;
00435
00436 }
00437
00438 }
00439
00440 if(pf.AddToRead(EdgeDesc(0) )!= -1 && pf.AddToRead(EdgeDesc(1)) != -1 )
00441 pi.mask |= Mask::IOM_EDGEINDEX;
00442
00443 if(vcg::tri::HasPerVertexFlags(m) && pf.AddToRead(VertDesc(3))!=-1 )
00444 pi.mask |= Mask::IOM_VERTFLAGS;
00445
00446 if( vcg::tri::HasPerVertexNormal(m) )
00447 {
00448 if( pf.AddToRead(VertDesc(14))!=-1 && pf.AddToRead(VertDesc(15))!=-1 && pf.AddToRead(VertDesc(16))!=-1 )
00449 pi.mask |= Mask::IOM_VERTNORMAL;
00450 else
00451 if( pf.AddToRead(VertDesc(27))!=-1 && pf.AddToRead(VertDesc(28))!=-1 && pf.AddToRead(VertDesc(29))!=-1 )
00452 pi.mask |= Mask::IOM_VERTNORMAL;
00453
00454 }
00455
00456 if( vcg::tri::HasPerVertexQuality(m) )
00457 {
00458 if( pf.AddToRead(VertDesc(4))!=-1 ||
00459 pf.AddToRead(VertDesc(13))!=-1 )
00460 pi.mask |= Mask::IOM_VERTQUALITY;
00461 else
00462 if (pf.AddToRead(VertDesc(31))!=-1)
00463 pi.mask |= Mask::IOM_VERTQUALITY;
00464 }
00465
00466 if(vcg::tri::HasPerVertexColor(m) )
00467 {
00468 if( pf.AddToRead(VertDesc(5))!=-1 )
00469 {
00470 pf.AddToRead(VertDesc(6));
00471 pf.AddToRead(VertDesc(7));
00472 pi.mask |= Mask::IOM_VERTCOLOR;
00473 }
00474 if( pf.AddToRead(VertDesc(9))!=-1 )
00475 {
00476 pf.AddToRead(VertDesc(10));
00477 pf.AddToRead(VertDesc(11));
00478 pi.mask |= Mask::IOM_VERTCOLOR;
00479 }
00480 if( pf.AddToRead(VertDesc(21))!=-1 )
00481 {
00482 hasIntensity = true;
00483 pi.mask |= Mask::IOM_VERTCOLOR;
00484 }
00485
00486 }
00487 if( tri::HasPerVertexTexCoord(m) )
00488 {
00489 if(( pf.AddToRead(VertDesc(22))!=-1 )&& (pf.AddToRead(VertDesc(23))!=-1))
00490 {
00491 pi.mask |= Mask::IOM_VERTTEXCOORD;
00492 }
00493 if(( pf.AddToRead(VertDesc(18))!=-1 )&& (pf.AddToRead(VertDesc(19))!=-1))
00494 {
00495 pi.mask |= Mask::IOM_VERTTEXCOORD;
00496 }
00497 }
00498 if(tri::HasPerVertexRadius(m))
00499 {
00500 if( pf.AddToRead(VertDesc(17))!=-1 )
00501 pi.mask |= Mask::IOM_VERTRADIUS;
00502 else if( pf.AddToRead(VertDesc(30))!=-1 )
00503 pi.mask |= Mask::IOM_VERTRADIUS;
00504 }
00505
00506 if( pf.AddToRead(FaceDesc(1))!=-1 )
00507 pi.mask |= Mask::IOM_FACEFLAGS;
00508
00509 if( vcg::tri::HasPerFaceQuality(m) )
00510 {
00511 if( pf.AddToRead(FaceDesc(2))!=-1 )
00512 pi.mask |= Mask::IOM_FACEQUALITY;
00513 }
00514
00515 if( vcg::tri::HasPerFaceColor(m) )
00516 {
00517 if( pf.AddToRead(FaceDesc(6))!=-1 )
00518 {
00519 pf.AddToRead(FaceDesc(7));
00520 pf.AddToRead(FaceDesc(8));
00521 pi.mask |= Mask::IOM_FACECOLOR;
00522 }
00523 }
00524
00525
00526 if( vcg::tri::HasPerWedgeTexCoord(m) )
00527 {
00528 if( pf.AddToRead(FaceDesc(3))!=-1 )
00529 {
00530 if(pf.AddToRead(FaceDesc(5))==0) {
00531 multit=true;
00532 pi.mask |= Mask::IOM_WEDGTEXMULTI;
00533 }
00534 pi.mask |= Mask::IOM_WEDGTEXCOORD;
00535 }
00536 }
00537
00538 if( vcg::tri::HasPerFaceColor(m) || vcg::tri::HasPerVertexColor(m) || vcg::tri::HasPerWedgeColor(m) )
00539 {
00540 if( pf.AddToRead(FaceDesc(4))!=-1 )
00541 {
00542 pi.mask |= Mask::IOM_WEDGCOLOR;
00543 }
00544 }
00545
00546
00547 std::vector<PropDescriptor> VPV(pi.vdn);
00548 std::vector<PropDescriptor> FPV(pi.fdn);
00549 if(pi.vdn>0){
00550
00551 size_t totsz=0;
00552 for(int i=0;i<pi.vdn;i++){
00553 VPV[i] = pi.VertexData[i];
00554 VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
00555 totsz+=pi.VertexData[i].memtypesize();
00556 if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
00557 }
00558 if(totsz > MAX_USER_DATA)
00559 {
00560 pi.status = vcg::ply::E_BADTYPE;
00561 return pi.status;
00562 }
00563 }
00564 if(pi.fdn>0){
00565 size_t totsz=0;
00566 for(int i=0;i<pi.fdn;i++){
00567 FPV[i] = pi.FaceData[i];
00568 FPV[i].offset1=offsetof(LoadPly_FaceAux,data)+totsz;
00569 totsz+=pi.FaceData[i].memtypesize();
00570 if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
00571 }
00572 if(totsz > MAX_USER_DATA)
00573 {
00574 pi.status = vcg::ply::E_BADTYPE;
00575 return pi.status;
00576 }
00577 }
00578
00579
00580
00581
00582 m.Clear();
00583 for(int i=0;i<int(pf.elements.size());i++)
00584 {
00585 int n = pf.ElemNumber(i);
00586
00587 if( !strcmp( pf.ElemName(i),"camera" ) )
00588 {
00589 pf.SetCurElement(i);
00590
00591 LoadPly_Camera ca;
00592
00593 for(int j=0;j<n;++j)
00594 {
00595 if( pf.Read( (void *)&(ca) )==-1 )
00596 {
00597 pi.status = PlyInfo::E_SHORTFILE;
00598 return pi.status;
00599 }
00600
00601
00602
00603 m.shot.Extrinsics.SetIdentity();
00604
00605 m.shot.Extrinsics.SetTra(Point3<ScalarType>( ca.view_px,ca.view_py,ca.view_pz));
00606
00607
00608 Matrix44<ScalarType> rm;
00609 rm.SetIdentity();
00610 rm[0][0] = ca.x_axisx;
00611 rm[0][1] = ca.x_axisy;
00612 rm[0][2] = ca.x_axisz;
00613
00614 rm[1][0] = ca.y_axisx;
00615 rm[1][1] = ca.y_axisy;
00616 rm[1][2] = ca.y_axisz;
00617
00618 rm[2][0] = ca.z_axisx;
00619 rm[2][1] = ca.z_axisy;
00620 rm[2][2] = ca.z_axisz;
00621
00622 m.shot.Extrinsics.SetRot(rm);
00623
00624
00625 m.shot.Intrinsics.FocalMm = ca.focal;
00626 m.shot.Intrinsics.PixelSizeMm[0] = ca.scalex;
00627 m.shot.Intrinsics.PixelSizeMm[1] = ca.scaley;
00628 m.shot.Intrinsics.CenterPx[0] = ca.centerx;
00629 m.shot.Intrinsics.CenterPx[1] = ca.centery;
00630 m.shot.Intrinsics.ViewportPx[0] = ca.viewportx;
00631 m.shot.Intrinsics.ViewportPx[1] = ca.viewporty;
00632 m.shot.Intrinsics.k[0] = ca.k1;
00633 m.shot.Intrinsics.k[1] = ca.k2;
00634 m.shot.Intrinsics.k[2] = ca.k3;
00635 m.shot.Intrinsics.k[3] = ca.k4;
00636
00637 }
00638 }
00639 else if( !strcmp( pf.ElemName(i),"vertex" ) )
00640 {
00641 int j;
00642
00643 pf.SetCurElement(i);
00644 VertexIterator vi=Allocator<OpenMeshType>::AddVertices(m,n);
00645
00646 for(j=0;j<n;++j)
00647 {
00648 if(pi.cb && (j%1000)==0) pi.cb(j*50/n,"Vertex Loading");
00649 if( pf.Read( (void *)&(va) )==-1 )
00650 {
00651 pi.status = PlyInfo::E_SHORTFILE;
00652 return pi.status;
00653 }
00654
00655 (*vi).P()[0] = va.p[0];
00656 (*vi).P()[1] = va.p[1];
00657 (*vi).P()[2] = va.p[2];
00658
00659 if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS) )
00660 (*vi).Flags() = va.flags;
00661
00662 if( pi.mask & Mask::IOM_VERTQUALITY )
00663 (*vi).Q() = (typename OpenMeshType::VertexType::QualityType)va.q;
00664
00665 if( pi.mask & Mask::IOM_VERTNORMAL )
00666 {
00667 (*vi).N()[0]=va.n[0];
00668 (*vi).N()[1]=va.n[1];
00669 (*vi).N()[2]=va.n[2];
00670 }
00671
00672 if( pi.mask & Mask::IOM_VERTTEXCOORD )
00673 {
00674 (*vi).T().P().X() = va.u;
00675 (*vi).T().P().Y() = va.v;
00676 }
00677
00678 if( pi.mask & Mask::IOM_VERTCOLOR )
00679 {
00680 if(hasIntensity)
00681 (*vi).C().SetGrayShade(va.intensity);
00682 else
00683 {
00684 (*vi).C()[0] = va.r;
00685 (*vi).C()[1] = va.g;
00686 (*vi).C()[2] = va.b;
00687 (*vi).C()[3] = va.a;
00688 }
00689 }
00690 if( pi.mask & Mask::IOM_VERTRADIUS )
00691 (*vi).R() = va.radius;
00692
00693
00694 for(int k=0;k<pi.vdn;k++)
00695 memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
00696 (char *)(&va) + VPV[k].offset1,
00697 VPV[k].memtypesize());
00698 ++vi;
00699 }
00700
00701 index.resize(n);
00702 for(j=0,vi=m.vert.begin();j<n;++j,++vi)
00703 index[j] = &*vi;
00704 }
00705 else if( !strcmp( pf.ElemName(i),"edge") && (n>0) )
00706 {
00707 assert( pi.mask & Mask::IOM_EDGEINDEX );
00708 EdgeIterator ei=Allocator<OpenMeshType>::AddEdges(m,n);
00709 pf.SetCurElement(i);
00710 for(int j=0;j<n;++j)
00711 {
00712 if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Edge Loading");
00713 if( pf.Read(&ea)==-1 )
00714 {
00715 pi.status = PlyInfo::E_SHORTFILE;
00716 return pi.status;
00717 }
00718 if( ea.v1<0 || ea.v2<0 || ea.v1>=m.vn || ea.v2>=m.vn)
00719 {
00720 pi.status = PlyInfo::E_BAD_VERT_INDEX_EDGE;
00721 return pi.status;
00722 }
00723 (*ei).V(0) = index[ ea.v1 ];
00724 (*ei).V(1) = index[ ea.v2 ];
00725 ++ei;
00726 }
00727 }
00728 else if( !strcmp( pf.ElemName(i),"face") && (n>0) )
00729 {
00730 int j;
00731
00732 FaceIterator fi=Allocator<OpenMeshType>::AddFaces(m,n);
00733 pf.SetCurElement(i);
00734
00735 for(j=0;j<n;++j)
00736 {
00737 int k;
00738
00739 if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Face Loading");
00740 if( pf.Read(&fa)==-1 )
00741 {
00742 pi.status = PlyInfo::E_SHORTFILE;
00743 return pi.status;
00744 }
00745 if(fa.size!=3)
00746 {
00747 if( ( pi.mask & Mask::IOM_WEDGCOLOR ) || ( pi.mask & Mask::IOM_WEDGTEXCOORD ) )
00748 {
00749 pi.status = PlyInfo::E_NO_3VERTINFACE;
00750 return pi.status;
00751 }
00752 }
00753
00754 if(HasPolyInfo(m)) (*fi).Alloc(3);
00755
00756 if(HasPerFaceFlags(m) &&( pi.mask & Mask::IOM_FACEFLAGS) )
00757 {
00758 (*fi).Flags() = fa.flags;
00759 }
00760
00761 if( pi.mask & Mask::IOM_FACEQUALITY )
00762 {
00763 (*fi).Q() = (typename OpenMeshType::FaceType::QualityType) fa.q;
00764 }
00765
00766 if( pi.mask & Mask::IOM_FACECOLOR )
00767 {
00768 (*fi).C()[0] = fa.r;
00769 (*fi).C()[1] = fa.g;
00770 (*fi).C()[2] = fa.b;
00771 (*fi).C()[3] = 255;
00772 }
00773
00774 if( pi.mask & Mask::IOM_WEDGTEXCOORD )
00775 {
00776 for(int k=0;k<3;++k)
00777 {
00778 (*fi).WT(k).u() = fa.texcoord[k*2+0];
00779 (*fi).WT(k).v() = fa.texcoord[k*2+1];
00780 if(multit) (*fi).WT(k).n() = fa.texcoordind;
00781 else (*fi).WT(k).n()=0;
00782 }
00783 }
00784
00785 if( pi.mask & Mask::IOM_WEDGCOLOR )
00786 {
00787 if(FaceType::HasWedgeColor()){
00788 for(int k=0;k<3;++k)
00789 {
00790 (*fi).WC(k)[0] = (unsigned char)(fa.colors[k*3+0]*255);
00791 (*fi).WC(k)[1] = (unsigned char)(fa.colors[k*3+1]*255);
00792 (*fi).WC(k)[2] = (unsigned char)(fa.colors[k*3+2]*255);
00793 }
00794 }
00795
00796
00797 if(HasPerFaceColor(m)) {
00798 (*fi).C()[0] = (unsigned char)((fa.colors[0*3+0]*255+fa.colors[1*3+0]*255+fa.colors[2*3+0]*255)/3.0f);
00799 (*fi).C()[1] = (unsigned char)((fa.colors[0*3+1]*255+fa.colors[1*3+1]*255+fa.colors[2*3+1]*255)/3.0f);
00800 (*fi).C()[2] = (unsigned char)((fa.colors[0*3+2]*255+fa.colors[1*3+2]*255+fa.colors[2*3+2]*255)/3.0f);
00801 }
00802 }
00805 for(k=0;k<3;++k)
00806 {
00807 if( fa.v[k]<0 || fa.v[k]>=m.vn )
00808 {
00809 pi.status = PlyInfo::E_BAD_VERT_INDEX;
00810 return pi.status;
00811 }
00812 (*fi).V(k) = index[ fa.v[k] ];
00813 }
00814
00815
00816 if (fa.size>3) fi->SetF(2);
00817
00818 for(k=0;k<pi.fdn;k++)
00819 memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
00820 (char *)(&fa) + FPV[k].offset1,
00821 FPV[k].memtypesize());
00822
00823
00824 ++fi;
00825
00826
00827
00828 if(fa.size>3)
00829 {
00830 int curpos=int(fi-m.face.begin());
00831 Allocator<OpenMeshType>::AddFaces(m,fa.size-3);
00832 fi=m.face.begin()+curpos;
00833 pi.mask |= Mask::IOM_BITPOLYGONAL;
00834 }
00835 for(int qq=0;qq<fa.size-3;++qq)
00836 {
00837 (*fi).V(0) = index[ fa.v[0] ];
00838 for(k=1;k<3;++k)
00839 {
00840 if( fa.v[2+qq]<0 || fa.v[2+qq]>=m.vn )
00841 {
00842 pi.status = PlyInfo::E_BAD_VERT_INDEX;
00843 return pi.status;
00844 }
00845 (*fi).V(k) = index[ fa.v[1+qq+k] ];
00846
00847 }
00848 if( pi.mask & Mask::IOM_FACEQUALITY )
00849 (*fi).Q() = (typename OpenMeshType::FaceType::QualityType)
00850 fa.q;
00851 if( pi.mask & Mask::IOM_FACECOLOR )
00852 (*fi).C() = Color4b(fa.r,fa.g,fa.b,255);
00853
00854 fi->SetF(0);
00855 if(qq<(fa.size-4)) fi->SetF(2);
00856
00857 for(k=0;k<pi.fdn;k++)
00858 memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
00859 (char *)(&fa) + FPV[k].offset1, FPV[k].memtypesize());
00860 ++fi;
00861 }
00862
00863 }
00864 }else if( !strcmp( pf.ElemName(i),"tristrips") )
00865 {
00866 int j;
00867 pf.SetCurElement(i);
00868 int numvert_tmp = (int)m.vert.size();
00869 for(j=0;j<n;++j)
00870 {
00871 int k;
00872 if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tristrip Face Loading");
00873 if( pf.Read(&tsa)==-1 )
00874 {
00875 pi.status = PlyInfo::E_SHORTFILE;
00876 return pi.status;
00877 }
00878 int remainder=0;
00879 for(k=0;k<tsa.size-2;++k)
00880 {
00881 if(pi.cb && (k%1000)==0) pi.cb(50+k*50/tsa.size,"Tristrip Face Loading");
00882 if(tsa.v[k]<0 || tsa.v[k]>=numvert_tmp ) {
00883 pi.status = PlyInfo::E_BAD_VERT_INDEX;
00884 return pi.status;
00885 }
00886 if(tsa.v[k+2]==-1)
00887 {
00888 k+=2;
00889 if(k%2) remainder=0;
00890 else remainder=1;
00891 continue;
00892 }
00893 Allocator<OpenMeshType>::AddFaces(m,1);
00894 FaceType &tf =m.face.back();
00895 tf.V(0) = index[ tsa.v[k+0] ];
00896 tf.V(1) = index[ tsa.v[k+1] ];
00897 tf.V(2) = index[ tsa.v[k+2] ];
00898 if((k+remainder)%2) std::swap (tf.V(0), tf.V(1) );
00899 }
00900 }
00901 }
00902 else if( !strcmp( pf.ElemName(i),"range_grid") )
00903 {
00904
00905 if(RangeGridCols==0)
00906 {
00907 for(int co=0;co<int(pf.comments.size());++co)
00908 {
00909 std::string num_cols = "num_cols";
00910 std::string num_rows = "num_rows";
00911 std::string &c = pf.comments[co];
00912 std::string bufstr,bufclean;
00913 if( num_cols == c.substr(0,num_cols.length()) )
00914 {
00915 bufstr = c.substr(num_cols.length()+1);
00916 RangeGridCols = atoi(bufstr.c_str());
00917 }
00918 if( num_rows == c.substr(0,num_cols.length()) )
00919 {
00920 bufstr = c.substr(num_rows.length()+1);
00921 RangeGridRows = atoi(bufstr.c_str());
00922 }
00923 }
00924
00925 }
00926 int totPnt = RangeGridCols*RangeGridRows;
00927
00928 pf.SetCurElement(i);
00929 for(int j=0;j<totPnt;++j)
00930 {
00931 if(pi.cb && (j%1000)==0) pi.cb(50+j*50/totPnt,"RangeMap Face Loading");
00932 if( pf.Read(&rga)==-1 )
00933 {
00934
00935 pi.status = PlyInfo::E_SHORTFILE;
00936 return pi.status;
00937 }
00938 else
00939 {
00940 if(rga.num_pts == 0)
00941 RangeGridAuxVec.push_back(-1);
00942 else
00943 RangeGridAuxVec.push_back(rga.pts[0]);
00944 }
00945 }
00946
00947 tri::FaceGrid(m, RangeGridAuxVec, RangeGridCols,RangeGridRows);
00948 }
00949 else
00950 {
00951
00952 int n = pf.ElemNumber(i);
00953 pf.SetCurElement(i);
00954
00955 for(int j=0;j<n;j++)
00956 {
00957 if( pf.Read(0)==-1)
00958 {
00959 pi.status = PlyInfo::E_SHORTFILE;
00960 return pi.status;
00961 }
00962 }
00963 }
00964 }
00965
00966
00967 m.textures.clear();
00968 m.normalmaps.clear();
00969
00970 for(int co=0;co<int(pf.comments.size());++co)
00971 {
00972 std::string TFILE = "TextureFile";
00973 std::string NFILE = "TextureNormalFile";
00974 std::string &c = pf.comments[co];
00975
00976 std::string bufstr,bufclean;
00977 int i,n;
00978
00979 if( TFILE == c.substr(0,TFILE.length()) )
00980 {
00981 bufstr = c.substr(TFILE.length()+1);
00982 n = static_cast<int>(bufstr.length());
00983 for(i=0;i<n;i++)
00984 if( bufstr[i]!=' ' && bufstr[i]!='\t' && bufstr[i]>32 && bufstr[i]<125 ) bufclean.push_back(bufstr[i]);
00985
00986 char buf2[255];
00987 ply::interpret_texture_name( bufclean.c_str(),filename,buf2 );
00988 m.textures.push_back( std::string(buf2) );
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 }
01003
01004
01005 m.vn = 0;
01006 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
01007 if( ! (*vi).IsD() )
01008 ++m.vn;
01009
01010 m.fn = 0;
01011 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
01012 if( ! (*fi).IsD() )
01013 ++m.fn;
01014
01015 tri::UpdateBounding<OpenMeshType>::Box(m);
01016 return 0;
01017 }
01018
01019
01020
01021 int LoadCamera(const char * filename)
01022 {
01023 vcg::ply::PlyFile pf;
01024 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
01025 {
01026 this->pi.status = pf.GetError();
01027 return this->pi.status;
01028 }
01029
01030
01031 bool found = true;
01032 int i;
01033 for(i=0;i<23;++i)
01034 {
01035 if( pf.AddToRead(CameraDesc(i))==-1 )
01036 {
01037 found = false;
01038 break;
01039 }
01040 }
01041
01042 if(!found)
01043 return this->pi.status;
01044
01045 for(i=0;i<int(pf.elements.size());i++)
01046 {
01047 int n = pf.ElemNumber(i);
01048
01049 if( !strcmp( pf.ElemName(i),"camera" ) )
01050 {
01051 pf.SetCurElement(i);
01052
01053 LoadPly_Camera ca;
01054
01055 for(int j=0;j<n;++j)
01056 {
01057 if( pf.Read( (void *)&(ca) )==-1 )
01058 {
01059 this->pi.status = PlyInfo::E_SHORTFILE;
01060 return this->pi.status;
01061 }
01062 this->camera.valid = true;
01063 this->camera.view_p[0] = ca.view_px;
01064 this->camera.view_p[1] = ca.view_py;
01065 this->camera.view_p[2] = ca.view_pz;
01066 this->camera.x_axis[0] = ca.x_axisx;
01067 this->camera.x_axis[1] = ca.x_axisy;
01068 this->camera.x_axis[2] = ca.x_axisz;
01069 this->camera.y_axis[0] = ca.y_axisx;
01070 this->camera.y_axis[1] = ca.y_axisy;
01071 this->camera.y_axis[2] = ca.y_axisz;
01072 this->camera.z_axis[0] = ca.z_axisx;
01073 this->camera.z_axis[1] = ca.z_axisy;
01074 this->camera.z_axis[2] = ca.z_axisz;
01075 this->camera.f = ca.focal;
01076 this->camera.s[0] = ca.scalex;
01077 this->camera.s[1] = ca.scaley;
01078 this->camera.c[0] = ca.centerx;
01079 this->camera.c[1] = ca.centery;
01080 this->camera.viewport[0] = ca.viewportx;
01081 this->camera.viewport[1] = ca.viewporty;
01082 this->camera.k[0] = ca.k1;
01083 this->camera.k[1] = ca.k2;
01084 this->camera.k[2] = ca.k3;
01085 this->camera.k[3] = ca.k4;
01086 }
01087 break;
01088 }
01089 }
01090
01091 return 0;
01092 }
01093
01094
01095 static bool LoadMask(const char * filename, int &mask)
01096 {
01097 PlyInfo pi;
01098 return LoadMask(filename, mask,pi);
01099 }
01100 static bool LoadMask(const char * filename, int &mask, PlyInfo &pi)
01101 {
01102 mask=0;
01103 vcg::ply::PlyFile pf;
01104 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
01105 {
01106 pi.status = pf.GetError();
01107 return false;
01108 }
01109
01110 if( pf.AddToRead(VertDesc( 0))!=-1 &&
01111 pf.AddToRead(VertDesc( 1))!=-1 &&
01112 pf.AddToRead(VertDesc( 2))!=-1 ) mask |= Mask::IOM_VERTCOORD;
01113 if( pf.AddToRead(VertDesc(24))!=-1 &&
01114 pf.AddToRead(VertDesc(25))!=-1 &&
01115 pf.AddToRead(VertDesc(26))!=-1 ) mask |= Mask::IOM_VERTCOORD;
01116
01117 if( pf.AddToRead(VertDesc(14))!=-1 &&
01118 pf.AddToRead(VertDesc(15))!=-1 &&
01119 pf.AddToRead(VertDesc(16))!=-1 ) mask |= Mask::IOM_VERTNORMAL;
01120 if( pf.AddToRead(VertDesc(27))!=-1 &&
01121 pf.AddToRead(VertDesc(28))!=-1 &&
01122 pf.AddToRead(VertDesc(29))!=-1 ) mask |= Mask::IOM_VERTNORMAL;
01123
01124 if( pf.AddToRead(VertDesc( 3))!=-1 ) mask |= Mask::IOM_VERTFLAGS;
01125 if( pf.AddToRead(VertDesc( 4))!=-1 ) mask |= Mask::IOM_VERTQUALITY;
01126 if( pf.AddToRead(VertDesc(13))!=-1 ) mask |= Mask::IOM_VERTQUALITY;
01127 if( pf.AddToRead(VertDesc(17))!=-1 ) mask |= Mask::IOM_VERTRADIUS;
01128 if( pf.AddToRead(VertDesc(30))!=-1 ) mask |= Mask::IOM_VERTRADIUS;
01129 if( pf.AddToRead(VertDesc(31))!=-1 ) mask |= Mask::IOM_VERTQUALITY;
01130 if( pf.AddToRead(VertDesc( 5))!=-1 &&
01131 pf.AddToRead(VertDesc( 6))!=-1 &&
01132 pf.AddToRead(VertDesc( 7))!=-1 ) mask |= Mask::IOM_VERTCOLOR;
01133 if( pf.AddToRead(VertDesc( 9))!=-1 &&
01134 pf.AddToRead(VertDesc(10))!=-1 &&
01135 pf.AddToRead(VertDesc(11))!=-1 ) mask |= Mask::IOM_VERTCOLOR;
01136 if( pf.AddToRead(VertDesc(21))!=-1 ) mask |= Mask::IOM_VERTCOLOR;
01137
01138 if( pf.AddToRead(VertDesc(22))!=-1 &&
01139 pf.AddToRead(VertDesc(23))!=-1) mask |= Mask::IOM_VERTTEXCOORD;
01140
01141 if( pf.AddToRead(VertDesc(18))!=-1 &&
01142 pf.AddToRead(VertDesc(19))!=-1) mask |= Mask::IOM_VERTTEXCOORD;
01143
01144 if( pf.AddToRead(FaceDesc(0))!=-1 ) mask |= Mask::IOM_FACEINDEX;
01145 if( pf.AddToRead(FaceDesc(1))!=-1 ) mask |= Mask::IOM_FACEFLAGS;
01146
01147 if( pf.AddToRead(FaceDesc(2))!=-1 ) mask |= Mask::IOM_FACEQUALITY;
01148 if( pf.AddToRead(FaceDesc(3))!=-1 ) mask |= Mask::IOM_WEDGTEXCOORD;
01149 if( pf.AddToRead(FaceDesc(5))!=-1 ) mask |= Mask::IOM_WEDGTEXMULTI;
01150 if( pf.AddToRead(FaceDesc(4))!=-1 ) mask |= Mask::IOM_WEDGCOLOR;
01151 if( pf.AddToRead(FaceDesc(6))!=-1 &&
01152 pf.AddToRead(FaceDesc(7))!=-1 &&
01153 pf.AddToRead(FaceDesc(8))!=-1 ) mask |= Mask::IOM_FACECOLOR;
01154
01155 return true;
01156 }
01157
01158
01159 };
01160
01161
01162 }
01163 }
01164 }
01165
01166 #endif
01167