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
00248 va.flags = 42;
00249
00250 pi.status = ::vcg::ply::E_NOERROR;
00251
00252
00253 vcg::ply::PlyFile pf;
00254
00255
00256 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00257 {
00258 pi.status = pf.GetError();
00259 return -1;
00260 }
00261 pi.header = pf.GetHeader();
00262
00263
00264 {
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 }
00275
00276
00277 if( pf.AddToRead(VertDesc(0))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00278 if( pf.AddToRead(VertDesc(1))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00279 if( pf.AddToRead(VertDesc(2))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00280 if( pf.AddToRead(TetraDesc(0))==-1 ){ pi.status = PlyInfo::E_NO_VERTEX; return -1; }
00281
00282
00283
00284
00285
00286
00287
00288
00289 if( pf.AddToRead(VertDesc(3))!=-1 )
00290 pi.mask |= ply::PLYMask::PM_VERTFLAGS;
00291
00292 if( VertexType::HasQuality() )
00293 {
00294 if( pf.AddToRead(VertDesc(4))!=-1 ||
00295 pf.AddToRead(VertDesc(8))!=-1 )
00296 pi.mask |= ply::PLYMask::PM_VERTQUALITY;
00297 }
00298
00299 if( VertexType::HasColor() )
00300 {
00301 if( pf.AddToRead(VertDesc(5))!=-1 )
00302 {
00303 pf.AddToRead(VertDesc(6));
00304 pf.AddToRead(VertDesc(7));
00305 pi.mask |= ply::PLYMask::PM_VERTCOLOR;
00306 }
00307 }
00308
00309
00310 if( pf.AddToRead(TetraDesc(1))!=-1 )
00311 pi.mask |= ply::PLYMask::PM_TETRAFLAGS;
00312
00313 if( TetraType::HasTetraQuality())
00314 {
00315 if( pf.AddToRead(TetraDesc(2))!=-1 )
00316 pi.mask |= ply::PLYMask::PM_TETRAQUALITY;
00317 }
00318
00319 if( TetraType::HasTetraColor() )
00320 {
00321 if( pf.AddToRead(TetraDesc(6))!=-1 )
00322 {
00323 pf.AddToRead(TetraDesc(7));
00324 pf.AddToRead(TetraDesc(8));
00325 pi.mask |= ply::PLYMask::PM_TETRACOLOR;
00326 }
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 vector<PropDescriptor> VPV(pi.vdn);
00340 vector<PropDescriptor> FPV(pi.fdn);
00341 if(pi.vdn>0){
00342
00343 size_t totsz=0;
00344 for(int i=0;i<pi.vdn;i++){
00345 VPV[i] = pi.VertexData[i];
00346 VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
00347 totsz+=pi.VertexData[i].memtypesize();
00348 if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return -1; }
00349 }
00350 if(totsz > MAX_USER_DATA)
00351 {
00352 pi.status = vcg::ply::E_BADTYPE;
00353 return -1;
00354 }
00355 }
00356 if(pi.fdn>0){
00357 size_t totsz=0;
00358 for(int i=0;i<pi.fdn;i++){
00359 FPV[i] = pi.TetraData[i];
00360 FPV[i].offset1=offsetof(LoadPly_TetraAux,data)+totsz;
00361 totsz+=pi.TetraData[i].memtypesize();
00362 if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return -1; }
00363 }
00364 if(totsz > MAX_USER_DATA)
00365 {
00366 pi.status = vcg::ply::E_BADTYPE;
00367 return -1;
00368 }
00369 }
00370
00371
00372
00373
00374 m.Clear();
00375 for(int i=0;i<int(pf.elements.size());i++)
00376 {
00377 int n = pf.ElemNumber(i);
00378
00379 if( !strcmp( pf.ElemName(i),"camera" ) )
00380 {
00381 pf.SetCurElement(i);
00382
00383
00384
00385 for(int j=0;j<n;++j)
00386 {
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 }
00417 }
00418 else if( !strcmp( pf.ElemName(i),"vertex" ) )
00419 {
00420 int j;
00421
00422 pf.SetCurElement(i);
00423 VertexIterator vi=Allocator<OpenMeshType>::AddVertices(m,n);
00424
00425 for(j=0;j<n;++j)
00426 {
00427 if(pi.cb && (j%1000)==0) pi.cb(j*50/n,"Vertex Loading");
00428 if( pf.Read( (void *)&(va) )==-1 )
00429 {
00430 pi.status = PlyInfo::E_SHORTFILE;
00431 return -1;
00432 }
00433
00434 (*vi).P()[0] = va.p[0];
00435 (*vi).P()[1] = va.p[1];
00436 (*vi).P()[2] = va.p[2];
00437
00438 if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
00439 (*vi).Flags() = va.flags;
00440
00441 if( pi.mask & ply::PLYMask::PM_VERTQUALITY )
00442 (*vi).Q() = va.q;
00443
00444 if( pi.mask & ply::PLYMask::PM_VERTCOLOR )
00445 {
00446 (*vi).C()[0] = va.r;
00447 (*vi).C()[1] = va.g;
00448 (*vi).C()[2] = va.b;
00449 (*vi).C()[3] = 255;
00450 }
00451
00452
00453 for(int k=0;k<pi.vdn;k++)
00454 memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
00455 (char *)(&va) + VPV[k].offset1,
00456 VPV[k].memtypesize());
00457 ++vi;
00458 }
00459
00460 index.resize(n);
00461 for(j=0,vi=m.vert.begin();j<n;++j,++vi)
00462 index[j] = &*vi;
00463 }
00464 else if( !strcmp( pf.ElemName(i),"tetra") )
00465 {
00466 int j;
00467 int k;
00468 TetraIterator fi=Allocator<OpenMeshType>::AddTetra(m,n);
00469 pf.SetCurElement(i);
00470
00471 for(j=0;j<n;++j)
00472 {
00473
00474
00475 if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tetra Loading");
00476 if( pf.Read(&fa)==-1 )
00477 {
00478 pi.status = PlyInfo::E_SHORTFILE;
00479 return -1;
00480 }
00481 if(fa.size!=4)
00482 {
00483 pi.status = PlyInfo::E_NO_3VERTINFACE;
00484 return -1;
00485 }
00486
00487 for(k=0;k<4;++k)
00488 {
00489 if( fa.v[k]<0 || fa.v[k]>=m.vn )
00490 {
00491 pi.status = PlyInfo::E_BAD_VERT_INDEX;
00492 return -1;
00493 }
00494 (*fi).V(k) = index[ fa.v[k] ];
00495 }
00496
00497 if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
00498 {
00499 (*fi).Flags() = fa.flags;
00500 }
00501
00502 if( pi.mask & ply::PLYMask::PM_TETRAQUALITY )
00503 {
00504 (*fi).Q() = fa.q;
00505 }
00506
00507 if( pi.mask & ply::PLYMask::PM_TETRACOLOR )
00508 {
00509 (*fi).C()[0] = fa.r;
00510 (*fi).C()[1] = fa.g;
00511 (*fi).C()[2] = fa.b;
00512 (*fi).C()[3] = 255;
00513 }
00514
00515 if(TetraType::HasTetraColor()){
00516 {
00517 (*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);
00518 (*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);
00519 (*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);
00520 }
00521 }
00522 }
00523
00524 for(k=0;k<pi.fdn;k++)
00525 memcpy((char *)(&(*fi)) + pi.TetraData[k].offset1,
00526 (char *)(&fa) + FPV[k].offset1,
00527 FPV[k].memtypesize());
00528 ++fi;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 else
00570 {
00571
00572 int n = pf.ElemNumber(i);
00573 pf.SetCurElement(i);
00574
00575 for(int j=0;j<n;j++)
00576 {
00577 if( pf.Read(0)==-1)
00578 {
00579 pi.status = PlyInfo::E_SHORTFILE;
00580 return -1;
00581 }
00582 }
00583 }
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
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 m.vn = 0;
00626 VertexIterator vi;
00627 for(vi=m.vert.begin();vi!=m.vert.end();++vi)
00628 if( ! (*vi).IsD() )
00629 ++m.vn;
00630
00631 m.tn = 0;
00632 TetraIterator fi;
00633 for(fi=m.tetra.begin();fi!=m.tetra.end();++fi)
00634 if( ! (*fi).IsD() )
00635 ++m.tn;
00636
00637 return 0;
00638 }
00639
00640
00641
00642 int LoadCamera(const char * filename)
00643 {
00644 vcg::ply::PlyFile pf;
00645 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00646 {
00647 pi.status = pf.GetError();
00648 return -1;
00649 }
00650
00651
00652 bool found = true;
00653 int i;
00654 for(i=0;i<23;++i)
00655 {
00656 if( pf.AddToRead(CameraDesc(i))==-1 )
00657 {
00658 found = false;
00659 break;
00660 }
00661 }
00662
00663 if(!found)
00664 return -1;
00665
00666 for(i=0;i<int(pf.elements.size());i++)
00667 {
00668 int n = pf.ElemNumber(i);
00669
00670 if( !strcmp( pf.ElemName(i),"camera" ) )
00671 {
00672 pf.SetCurElement(i);
00673
00674
00675
00676 for(int j=0;j<n;++j)
00677 {
00678 if( pf.Read( (void *)&(ca) )==-1 )
00679 {
00680 pi.status = PlyInfo::E_SHORTFILE;
00681 return -1;
00682 }
00683 camera.valid = true;
00684 camera.view_p[0] = ca.view_px;
00685 camera.view_p[1] = ca.view_py;
00686 camera.view_p[2] = ca.view_pz;
00687 camera.x_axis[0] = ca.x_axisx;
00688 camera.x_axis[1] = ca.x_axisy;
00689 camera.x_axis[2] = ca.x_axisz;
00690 camera.y_axis[0] = ca.y_axisx;
00691 camera.y_axis[1] = ca.y_axisy;
00692 camera.y_axis[2] = ca.y_axisz;
00693 camera.z_axis[0] = ca.z_axisx;
00694 camera.z_axis[1] = ca.z_axisy;
00695 camera.z_axis[2] = ca.z_axisz;
00696 camera.f = ca.focal;
00697 camera.s[0] = ca.scalex;
00698 camera.s[1] = ca.scaley;
00699 camera.c[0] = ca.centerx;
00700 camera.c[1] = ca.centery;
00701 camera.viewport[0] = ca.viewportx;
00702 camera.viewport[1] = ca.viewporty;
00703 camera.k[0] = ca.k1;
00704 camera.k[1] = ca.k2;
00705 camera.k[2] = ca.k3;
00706 camera.k[3] = ca.k4;
00707 }
00708 break;
00709 }
00710 }
00711
00712 return 0;
00713 }
00714
00715
00716 bool LoadMask(const char * filename, int &mask)
00717 {
00718 mask=0;
00719 vcg::ply::PlyFile pf;
00720 if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00721 {
00722 pi.status = pf.GetError();
00723 return false;
00724 }
00725
00726 if( pf.AddToRead(VertDesc(0))!=-1 &&
00727 pf.AddToRead(VertDesc(1))!=-1 &&
00728 pf.AddToRead(VertDesc(2))!=-1 ) mask |= ply::PLYMask::PM_VERTCOORD;
00729
00730 if( pf.AddToRead(VertDesc(3))!=-1 ) mask |= ply::PLYMask::PM_VERTFLAGS;
00731 if( pf.AddToRead(VertDesc(4))!=-1 ) mask |= ply::PLYMask::PM_VERTQUALITY;
00732 if( pf.AddToRead(VertDesc(8))!=-1 ) mask |= ply::PLYMask::PM_VERTQUALITY;
00733 if( ( pf.AddToRead(VertDesc(5))!=-1 ) &&
00734 ( pf.AddToRead(VertDesc(6))!=-1 ) &&
00735 ( pf.AddToRead(VertDesc(7))!=-1 ) ) mask |= ply::PLYMask::PM_VERTCOLOR;
00736
00737 if( pf.AddToRead(TetraDesc(0))!=-1 ) mask |= ply::PLYMask::PM_TETRAINDEX;
00738 if( pf.AddToRead(TetraDesc(1))!=-1 ) mask |= ply::PLYMask::PM_TETRAFLAGS;
00739
00740 if( pf.AddToRead(TetraDesc(2))!=-1 ) mask |= ply::PLYMask::PM_TETRAQUALITY;
00741
00742
00743 if( pf.AddToRead(TetraDesc(4))!=-1 ) mask |= ply::PLYMask::PM_WEDGCOLOR;
00744 if( ( pf.AddToRead(TetraDesc(6))!=-1 ) &&
00745 ( pf.AddToRead(TetraDesc(7))!=-1 ) &&
00746 ( pf.AddToRead(TetraDesc(8))!=-1 ) ) mask |= ply::PLYMask::PM_TETRACOLOR;
00747
00748
00749 return true;
00750 }
00751
00752
00753 };
00754
00755
00756
00757 }
00758 }
00759 }
00760
00761 #endif