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