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 #ifndef __VCGLIB_TETRAIMPORTERPLY
00032 #define __VCGLIB_TETRAIMPORTERPLY
00033
00034 #include<wrap/callback.h>
00035 #include<wrap/ply/plylib.h>
00036 #include<wrap/ply/io_mask.h>
00037 #include<wrap/io_tetramesh/io_ply.h>
00038 #include<vcg/complex/tetramesh/allocate.h>
00039
00040
00041
00042 namespace vcg {
00043 namespace tetra {
00044 namespace io {
00045
00046 template <class TYPE>
00047 int PlyType () { return 0;}
00048
00049 template <> int PlyType <float >() { return ply::T_FLOAT; }
00050 template <> int PlyType <double>() { return ply::T_DOUBLE; }
00051 template <> int PlyType <int >() { return ply::T_INT; }
00052 template <> int PlyType <short >() { return ply::T_SHORT; }
00053 template <> int PlyType <unsigned char >() { return ply::T_UCHAR; }
00054
00059 template <class OpenMeshType>
00060 class ImporterPLY
00061 {
00062 public:
00063
00064 typedef ::vcg::ply::PropDescriptor PropDescriptor ;
00065 typedef typename OpenMeshType::VertexPointer VertexPointer;
00066 typedef typename OpenMeshType::ScalarType ScalarType;
00067 typedef typename OpenMeshType::VertexType VertexType;
00068 typedef typename OpenMeshType::TetraType TetraType;
00069 typedef typename OpenMeshType::VertexIterator VertexIterator;
00070 typedef typename OpenMeshType::TetraIterator TetraIterator;
00071
00072
00073
00074 #define MAX_USER_DATA 256
00075
00076 struct LoadPly_TetraAux
00077 {
00078 unsigned char size;
00079 int v[512];
00080 int flags;
00081 float q;
00082 float texcoord[32];
00083 unsigned char ntexcoord;
00084 int texcoordind;
00085 float colors[32];
00086 unsigned char ncolors;
00087
00088 unsigned char r;
00089 unsigned char g;
00090 unsigned char b;
00091
00092 unsigned char data[MAX_USER_DATA];
00093 };
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 template<class S>
00104 struct LoadPly_VertAux
00105 {
00106 S p[3];
00107 int flags;
00108 float q;
00109 unsigned char r;
00110 unsigned char g;
00111 unsigned char b;
00112 unsigned char data[MAX_USER_DATA];
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 static const PropDescriptor &VertDesc(int i)
00144 {
00145 const static PropDescriptor pv[9]={
00146 {"vertex", "x", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p[0]),0,0,0,0,0},
00147 {"vertex", "y", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p[1]),0,0,0,0,0},
00148 {"vertex", "z", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p[2]),0,0,0,0,0},
00149 {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux<ScalarType>,flags),0,0,0,0,0},
00150 {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0},
00151 {"vertex", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0},
00152 {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0},
00153 {"vertex", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0},
00154 {"vertex", "confidence",ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0},
00155 };
00156 return pv[i];
00157 }
00158
00159
00160 static const PropDescriptor &TetraDesc(int i)
00161 {
00162 const static PropDescriptor qf[10]=
00163 {
00164 {"tetra", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,v), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,size) },
00165 {"tetra", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,flags), 0,0,0,0,0},
00166 {"tetra", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,q), 0,0,0,0,0},
00167 {"tetra", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,texcoord), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ntexcoord) },
00168 {"tetra", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,colors), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ncolors) },
00169 {"tetra", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,texcoordind), 0,0,0,0,0},
00170 {"tetra", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,r), 0,0,0,0,0},
00171 {"tetra", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,g), 0,0,0,0,0},
00172 {"tetra", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,b), 0,0,0,0,0},
00173 {"tetra", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,v), 1,0,ply::T_UCHAR,ply::T_CHAR,offsetof(LoadPly_TetraAux,size) },
00174 };
00175 return qf[i];
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00220 static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0)
00221 {
00222 PlyInfo pi;
00223 pi.cb=cb;
00224 return Open(m, filename, pi);
00225 }
00226
00228 static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0)
00229 {
00230 PlyInfo pi;
00231 pi.mask=loadmask;
00232 return Open(m, filename,pi);
00233 loadmask=pi.mask;
00234 }
00235
00236
00238 static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
00239 {
00240 assert(filename!=0);
00241 vector<VertexPointer> index;
00242 LoadPly_TetraAux fa;
00243
00244 LoadPly_VertAux<ScalarType> va;
00245
00246 pi.mask = 0;
00247 bool multit = false;
00248
00249 va.flags = 42;
00250
00251 pi.status = ::vcg::ply::E_NOERROR;
00252
00253
00254 VertexType tv;
00255 tv.UberFlags() = 0;
00256 if( VertexType::HasQuality() ) tv.Q()=1.0;
00257 if( VertexType::HasColor() ) tv.C()=Color4b(Color4b::White);
00258
00259 TetraType tf;
00260 tf.UberFlags() = 0;
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 vcg::ply::PlyFile pf;
00271
00272
00273 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00274 {
00275 pi.status = pf.GetError();
00276 return -1;
00277 }
00278 pi.header = pf.GetHeader();
00279
00280
00281 {
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 }
00292
00293
00294 if( pf.AddToRead(VertDesc(0))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00295 if( pf.AddToRead(VertDesc(1))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00296 if( pf.AddToRead(VertDesc(2))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00297 if( pf.AddToRead(TetraDesc(0))==-1 ){ pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00298
00299
00300
00301
00302
00303
00304
00305
00306 if( pf.AddToRead(VertDesc(3))!=-1 )
00307 pi.mask |= ply::PLYMask::PM_VERTFLAGS;
00308
00309 if( VertexType::HasQuality() )
00310 {
00311 if( pf.AddToRead(VertDesc(4))!=-1 ||
00312 pf.AddToRead(VertDesc(8))!=-1 )
00313 pi.mask |= ply::PLYMask::PM_VERTQUALITY;
00314 }
00315
00316 if( VertexType::HasColor() )
00317 {
00318 if( pf.AddToRead(VertDesc(5))!=-1 )
00319 {
00320 pf.AddToRead(VertDesc(6));
00321 pf.AddToRead(VertDesc(7));
00322 pi.mask |= ply::PLYMask::PM_VERTCOLOR;
00323 }
00324 }
00325
00326
00327 if( pf.AddToRead(TetraDesc(1))!=-1 )
00328 pi.mask |= ply::PLYMask::PM_TETRAFLAGS;
00329
00330 if( TetraType::HasTetraQuality())
00331 {
00332 if( pf.AddToRead(TetraDesc(2))!=-1 )
00333 pi.mask |= ply::PLYMask::PM_TETRAQUALITY;
00334 }
00335
00336 if( TetraType::HasTetraColor() )
00337 {
00338 if( pf.AddToRead(TetraDesc(6))!=-1 )
00339 {
00340 pf.AddToRead(TetraDesc(7));
00341 pf.AddToRead(TetraDesc(8));
00342 pi.mask |= ply::PLYMask::PM_TETRACOLOR;
00343 }
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 vector<PropDescriptor> VPV(pi.vdn);
00357 vector<PropDescriptor> FPV(pi.fdn);
00358 if(pi.vdn>0){
00359
00360 size_t totsz=0;
00361 for(int i=0;i<pi.vdn;i++){
00362 VPV[i] = pi.VertexData[i];
00363 VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
00364 totsz+=pi.VertexData[i].memtypesize();
00365 if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return -1; }
00366 }
00367 if(totsz > MAX_USER_DATA)
00368 {
00369 pi.status = vcg::ply::E_BADTYPE;
00370 return -1;
00371 }
00372 }
00373 if(pi.fdn>0){
00374 size_t totsz=0;
00375 for(int i=0;i<pi.fdn;i++){
00376 FPV[i] = pi.TetraData[i];
00377 FPV[i].offset1=offsetof(LoadPly_TetraAux,data)+totsz;
00378 totsz+=pi.TetraData[i].memtypesize();
00379 if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return -1; }
00380 }
00381 if(totsz > MAX_USER_DATA)
00382 {
00383 pi.status = vcg::ply::E_BADTYPE;
00384 return -1;
00385 }
00386 }
00387
00388
00389
00390
00391 m.Clear();
00392 for(int i=0;i<int(pf.elements.size());i++)
00393 {
00394 int n = pf.ElemNumber(i);
00395
00396 if( !strcmp( pf.ElemName(i),"camera" ) )
00397 {
00398 pf.SetCurElement(i);
00399
00400
00401
00402 for(int j=0;j<n;++j)
00403 {
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 }
00434 }
00435 else if( !strcmp( pf.ElemName(i),"vertex" ) )
00436 {
00437 int j;
00438
00439 pf.SetCurElement(i);
00440 VertexIterator vi=Allocator<OpenMeshType>::AddVertices(m,n);
00441
00442 for(j=0;j<n;++j)
00443 {
00444 if(pi.cb && (j%1000)==0) pi.cb(j*50/n,"Vertex Loading");
00445 (*vi).UberFlags()=0;
00446 if( pf.Read( (void *)&(va) )==-1 )
00447 {
00448 pi.status = PlyInfo::E_SHORTFILE;
00449 return -1;
00450 }
00451
00452 (*vi).P()[0] = va.p[0];
00453 (*vi).P()[1] = va.p[1];
00454 (*vi).P()[2] = va.p[2];
00455
00456 if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
00457 (*vi).UberFlags() = va.flags;
00458
00459 if( pi.mask & ply::PLYMask::PM_VERTQUALITY )
00460 (*vi).Q() = va.q;
00461
00462 if( pi.mask & ply::PLYMask::PM_VERTCOLOR )
00463 {
00464 (*vi).C()[0] = va.r;
00465 (*vi).C()[1] = va.g;
00466 (*vi).C()[2] = va.b;
00467 (*vi).C()[3] = 255;
00468 }
00469
00470
00471 for(int k=0;k<pi.vdn;k++)
00472 memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
00473 (char *)(&va) + VPV[k].offset1,
00474 VPV[k].memtypesize());
00475 ++vi;
00476 }
00477
00478 index.resize(n);
00479 for(j=0,vi=m.vert.begin();j<n;++j,++vi)
00480 index[j] = &*vi;
00481 }
00482 else if( !strcmp( pf.ElemName(i),"tetra") )
00483 {
00484 int j;
00485 int k;
00486 TetraIterator fi=Allocator<OpenMeshType>::AddTetra(m,n);
00487 pf.SetCurElement(i);
00488
00489 for(j=0;j<n;++j)
00490 {
00491
00492
00493 if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tetra Loading");
00494 if( pf.Read(&fa)==-1 )
00495 {
00496 pi.status = PlyInfo::E_SHORTFILE;
00497 return -1;
00498 }
00499 if(fa.size!=4)
00500 {
00501 pi.status = PlyInfo::E_NO_3VERTINFACE;
00502 return -1;
00503 }
00504
00505 for(k=0;k<4;++k)
00506 {
00507 if( fa.v[k]<0 || fa.v[k]>=m.vn )
00508 {
00509 pi.status = PlyInfo::E_BAD_VERT_INDEX;
00510 return -1;
00511 }
00512 (*fi).V(k) = index[ fa.v[k] ];
00513 }
00514
00515 if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
00516 {
00517 (*fi).UberFlags() = fa.flags;
00518 }
00519
00520 if( pi.mask & ply::PLYMask::PM_TETRAQUALITY )
00521 {
00522 (*fi).Q() = fa.q;
00523 }
00524
00525 if( pi.mask & ply::PLYMask::PM_TETRACOLOR )
00526 {
00527 (*fi).C()[0] = fa.r;
00528 (*fi).C()[1] = fa.g;
00529 (*fi).C()[2] = fa.b;
00530 (*fi).C()[3] = 255;
00531 }
00532
00533 if(TetraType::HasTetraColor()){
00534 {
00535 (*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);
00536 (*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);
00537 (*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);
00538 }
00539 }
00540 }
00541
00542 for(k=0;k<pi.fdn;k++)
00543 memcpy((char *)(&(*fi)) + pi.TetraData[k].offset1,
00544 (char *)(&fa) + FPV[k].offset1,
00545 FPV[k].memtypesize());
00546 ++fi;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 else
00588 {
00589
00590 int n = pf.ElemNumber(i);
00591 pf.SetCurElement(i);
00592
00593 for(int j=0;j<n;j++)
00594 {
00595 if( pf.Read(0)==-1)
00596 {
00597 pi.status = PlyInfo::E_SHORTFILE;
00598 return -1;
00599 }
00600 }
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 m.vn = 0;
00644 VertexIterator vi;
00645 for(vi=m.vert.begin();vi!=m.vert.end();++vi)
00646 if( ! (*vi).IsD() )
00647 ++m.vn;
00648
00649 m.tn = 0;
00650 TetraIterator fi;
00651 for(fi=m.tetra.begin();fi!=m.tetra.end();++fi)
00652 if( ! (*fi).IsD() )
00653 ++m.tn;
00654
00655 return 0;
00656 }
00657
00658
00659
00660 int LoadCamera(const char * filename)
00661 {
00662 vcg::ply::PlyFile pf;
00663 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00664 {
00665 pi.status = pf.GetError();
00666 return -1;
00667 }
00668
00669
00670 bool found = true;
00671 int i;
00672 for(i=0;i<23;++i)
00673 {
00674 if( pf.AddToRead(CameraDesc(i))==-1 )
00675 {
00676 found = false;
00677 break;
00678 }
00679 }
00680
00681 if(!found)
00682 return -1;
00683
00684 for(i=0;i<int(pf.elements.size());i++)
00685 {
00686 int n = pf.ElemNumber(i);
00687
00688 if( !strcmp( pf.ElemName(i),"camera" ) )
00689 {
00690 pf.SetCurElement(i);
00691
00692
00693
00694 for(int j=0;j<n;++j)
00695 {
00696 if( pf.Read( (void *)&(ca) )==-1 )
00697 {
00698 pi.status = PlyInfo::E_SHORTFILE;
00699 return -1;
00700 }
00701 camera.valid = true;
00702 camera.view_p[0] = ca.view_px;
00703 camera.view_p[1] = ca.view_py;
00704 camera.view_p[2] = ca.view_pz;
00705 camera.x_axis[0] = ca.x_axisx;
00706 camera.x_axis[1] = ca.x_axisy;
00707 camera.x_axis[2] = ca.x_axisz;
00708 camera.y_axis[0] = ca.y_axisx;
00709 camera.y_axis[1] = ca.y_axisy;
00710 camera.y_axis[2] = ca.y_axisz;
00711 camera.z_axis[0] = ca.z_axisx;
00712 camera.z_axis[1] = ca.z_axisy;
00713 camera.z_axis[2] = ca.z_axisz;
00714 camera.f = ca.focal;
00715 camera.s[0] = ca.scalex;
00716 camera.s[1] = ca.scaley;
00717 camera.c[0] = ca.centerx;
00718 camera.c[1] = ca.centery;
00719 camera.viewport[0] = ca.viewportx;
00720 camera.viewport[1] = ca.viewporty;
00721 camera.k[0] = ca.k1;
00722 camera.k[1] = ca.k2;
00723 camera.k[2] = ca.k3;
00724 camera.k[3] = ca.k4;
00725 }
00726 break;
00727 }
00728 }
00729
00730 return 0;
00731 }
00732
00733
00734 bool LoadMask(const char * filename, int &mask)
00735 {
00736 mask=0;
00737 vcg::ply::PlyFile pf;
00738 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00739 {
00740 pi.status = pf.GetError();
00741 return false;
00742 }
00743
00744 if( pf.AddToRead(VertDesc(0))!=-1 &&
00745 pf.AddToRead(VertDesc(1))!=-1 &&
00746 pf.AddToRead(VertDesc(2))!=-1 ) mask |= ply::PLYMask::PM_VERTCOORD;
00747
00748 if( pf.AddToRead(VertDesc(3))!=-1 ) mask |= ply::PLYMask::PM_VERTFLAGS;
00749 if( pf.AddToRead(VertDesc(4))!=-1 ) mask |= ply::PLYMask::PM_VERTQUALITY;
00750 if( pf.AddToRead(VertDesc(8))!=-1 ) mask |= ply::PLYMask::PM_VERTQUALITY;
00751 if( ( pf.AddToRead(VertDesc(5))!=-1 ) &&
00752 ( pf.AddToRead(VertDesc(6))!=-1 ) &&
00753 ( pf.AddToRead(VertDesc(7))!=-1 ) ) mask |= ply::PLYMask::PM_VERTCOLOR;
00754
00755 if( pf.AddToRead(TetraDesc(0))!=-1 ) mask |= ply::PLYMask::PM_TETRAINDEX;
00756 if( pf.AddToRead(TetraDesc(1))!=-1 ) mask |= ply::PLYMask::PM_TETRAFLAGS;
00757
00758 if( pf.AddToRead(TetraDesc(2))!=-1 ) mask |= ply::PLYMask::PM_TETRAQUALITY;
00759
00760
00761 if( pf.AddToRead(TetraDesc(4))!=-1 ) mask |= ply::PLYMask::PM_WEDGCOLOR;
00762 if( ( pf.AddToRead(TetraDesc(6))!=-1 ) &&
00763 ( pf.AddToRead(TetraDesc(7))!=-1 ) &&
00764 ( pf.AddToRead(TetraDesc(8))!=-1 ) ) mask |= ply::PLYMask::PM_TETRACOLOR;
00765
00766
00767 return true;
00768 }
00769
00770
00771 };
00772
00773
00774
00775 }
00776 }
00777 }
00778
00779 #endif