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
00034
00035 #ifndef __VCGLIB_TETRAEXPORT_PLY
00036 #define __VCGLIB_TETRAEXPORT_PLY
00037
00038 #include<wrap/ply/io_mask.h>
00039 #include<wrap/io_tetramesh/io_ply.h>
00040
00041 #include <stdio.h>
00042
00043 namespace vcg {
00044 namespace tetra {
00045 namespace io {
00046
00047
00048 template <class SaveMeshType>
00049 class ExporterPLY
00050 {
00051
00052
00053
00054
00055
00056
00057 template <class StoType>
00058 static void PlyConv(int mem_type, void *src, StoType &dest)
00059 {
00060 switch (mem_type){
00061 case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break;
00062 case ply::T_DOUBLE: dest = (StoType) (* ((double *) src)); break;
00063 case ply::T_INT : dest = (StoType) (* ((int *) src)); break;
00064 case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break;
00065 case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break;
00066 case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break;
00067 default : assert(0);
00068 }
00069 }
00070
00071 public:
00072 typedef ::vcg::ply::PropDescriptor PropDescriptor ;
00073 typedef typename SaveMeshType::VertexPointer VertexPointer;
00074 typedef typename SaveMeshType::ScalarType ScalarType;
00075 typedef typename SaveMeshType::VertexType VertexType;
00076 typedef typename SaveMeshType::TetraType TetraType;
00077 typedef typename SaveMeshType::TetraPointer TetraPointer;
00078 typedef typename SaveMeshType::VertexIterator VertexIterator;
00079 typedef typename SaveMeshType::TetraIterator TetraIterator;
00080
00081 static bool Save(SaveMeshType &m, const char * filename, bool binary=true)
00082 {
00083 PlyInfo pi;
00084 return Save(m,filename,binary,pi);
00085 }
00086
00087 static bool Save(SaveMeshType &m, const char * filename, int savemask )
00088 {
00089 PlyInfo pi;
00090 pi.mask=savemask;
00091 return Save(m,filename,true,pi);
00092 }
00093
00094 static bool Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &pi )
00095 {
00096 FILE * fpout;
00097 int i;
00098
00099 const char * hbin = "binary_little_endian";
00100 const char * hasc = "ascii";
00101 const char * h;
00102
00103 bool multit = false;
00104
00105 if(binary) h=hbin;
00106 else h=hasc;
00107
00108 fpout = fopen(filename,"wb");
00109 if(fpout==NULL) {
00110 pi.status=::vcg::ply::E_CANTOPEN;
00111 return false;
00112 }
00113 fprintf(fpout,
00114 "ply\n"
00115 "format %s 1.0\n"
00116 "comment VCGLIB generated\n"
00117 ,h
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
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 fprintf(fpout,
00161 "element vertex %d\n"
00162 "property float x\n"
00163 "property float y\n"
00164 "property float z\n"
00165 ,m.vn
00166 );
00167
00168
00169 if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
00170 {
00171 fprintf(fpout,
00172 "property int flags\n"
00173 );
00174 }
00175
00176 if( m.HasPerVertexColor() && (pi.mask & ply::PLYMask::PM_VERTCOLOR) )
00177 {
00178 fprintf(fpout,
00179 "property uchar red\n"
00180 "property uchar green\n"
00181 "property uchar blue\n"
00182 "property uchar alpha\n"
00183 );
00184 }
00185
00186 if( m.HasPerVertexQuality() && (pi.mask & ply::PLYMask::PM_VERTQUALITY) )
00187 {
00188 fprintf(fpout,
00189 "property float quality\n"
00190 );
00191 }
00192
00193 for(i=0;i<pi.vdn;i++)
00194 fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
00195
00196 fprintf(fpout,
00197 "element tetra %d\n"
00198 "property list uchar int vertex_indices\n"
00199 ,m.tn
00200 );
00201
00202 if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
00203 {
00204 fprintf(fpout,
00205 "property int flags\n"
00206 );
00207 }
00208
00209 if( VertexType::HasTexture() )
00210 {
00211 fprintf(fpout,
00212 "property list uchar float texcoord\n"
00213 );
00214
00215 if(multit)
00216 fprintf(fpout,
00217 "property int texnumber\n"
00218 );
00219 }
00220
00221 if( TetraType::HasTetraColor() && (pi.mask & ply::PLYMask::PM_TETRACOLOR) )
00222 {
00223 fprintf(fpout,
00224 "property uchar red\n"
00225 "property uchar green\n"
00226 "property uchar blue\n"
00227 "property uchar alpha\n"
00228 );
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238 if( m.HasPerTetraQuality() && (pi.mask & ply::PLYMask::PM_TETRAQUALITY) )
00239 {
00240 fprintf(fpout,
00241 "property float quality\n"
00242 );
00243 }
00244
00245 for(i=0;i<pi.fdn;i++)
00246 fprintf(fpout,"property %s %s\n",pi.TetraData[i].stotypename(),pi.TetraData[i].propname);
00247
00248 fprintf(fpout, "end_header\n" );
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 int j;
00316 std::vector<int> FlagV;
00317 VertexPointer vp;
00318 VertexIterator vi;
00319 for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
00320 {
00321 vp=&(*vi);
00322 FlagV.push_back(vp->UberFlags());
00323 if( ! vp->IsD() )
00324 {
00325 if(binary)
00326 {
00327 float t;
00328
00329 t = float(vp->UberP()[0]); fwrite(&t,sizeof(float),1,fpout);
00330 t = float(vp->UberP()[1]); fwrite(&t,sizeof(float),1,fpout);
00331 t = float(vp->UberP()[2]); fwrite(&t,sizeof(float),1,fpout);
00332
00333 if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
00334 fwrite(&(vp->UberFlags()),sizeof(int),1,fpout);
00335
00336 if( m.HasPerVertexColor() && (pi.mask & ply::PLYMask::PM_VERTCOLOR) )
00337 fwrite(&( vp->C() ),sizeof(char),4,fpout);
00338
00339 if( m.HasPerVertexQuality() && (pi.mask & ply::PLYMask::PM_VERTQUALITY) )
00340 fwrite(&( vp->Q() ),sizeof(float),1,fpout);
00341
00342
00343 for(i=0;i<pi.vdn;i++)
00344 {
00345 double td; float tf;int ti;short ts; char tc; unsigned char tuc;
00346 switch (pi.VertexData[i].stotype1)
00347 {
00348 case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
00349 case ply::T_DOUBLE : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
00350 case ply::T_INT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
00351 case ply::T_SHORT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
00352 case ply::T_CHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
00353 case ply::T_UCHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
00354 default : assert(0);
00355 }
00356 }
00357 }
00358 else
00359 {
00360 fprintf(fpout,"%g %g %g " ,vp->P()[0],vp->P()[1],vp->P()[2]);
00361
00362 if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
00363 fprintf(fpout,"%d ",vp->UberFlags());
00364
00365 if( m.HasPerVertexColor() && (pi.mask & ply::PLYMask::PM_VERTCOLOR) )
00366 fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] );
00367
00368 if( m.HasPerVertexQuality() && (pi.mask & ply::PLYMask::PM_VERTQUALITY) )
00369 fprintf(fpout,"%g ",vp->Q());
00370
00371 for(i=0;i<pi.vdn;i++)
00372 {
00373 float tf; double td;
00374 int ti;
00375 switch (pi.VertexData[i].memtype1)
00376 {
00377 case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00378 case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00379 case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00380 case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00381 case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00382 case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00383 default : assert(0);
00384 }
00385 }
00386
00387 fprintf(fpout,"\n");
00388 }
00389
00390 vp->UberFlags()=j;
00391 j++;
00392 }
00393 }
00394 assert(j==m.vn);
00395
00396 char c = 4;
00397 unsigned char b9 = 9;
00398 unsigned char b6 = 6;
00399 TetraPointer fp;
00400 int vv[4];
00401 TetraIterator fi;
00402 int fcnt=0;
00403 for(j=0,fi=m.tetra.begin();fi!=m.tetra.end();++fi)
00404 {
00405 fp=&(*fi);
00406 if( ! fp->IsD() )
00407 { fcnt++;
00408 if(binary)
00409 {
00410 vv[0]=fp->cV(0)->UberFlags();
00411 vv[1]=fp->cV(1)->UberFlags();
00412 vv[2]=fp->cV(2)->UberFlags();
00413 vv[3]=fp->cV(2)->UberFlags();
00414 fwrite(&c,1,1,fpout);
00415 fwrite(vv,sizeof(int),4,fpout);
00416
00417 if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
00418 fwrite(&(fp->Flags()),sizeof(int),1,fpout);
00419
00420 if( m.HasPerVertexTexture() && (pi.mask & ply::PLYMask::PM_VERTTEXCOORD) )
00421 {
00422 fwrite(&b6,sizeof(char),1,fpout);
00423 float t[6];
00424 for(int k=0;k<4;++k)
00425 {
00426 t[k*2+0] = fp->V(k)->T().u();
00427 t[k*2+1] = fp->V(k)->T().v();
00428 }
00429 fwrite(t,sizeof(float),6,fpout);
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 if( TetraType::HasTetraQuality() && (pi.mask & ply::PLYMask::PM_TETRAQUALITY) )
00467 fwrite( &(fp->Q()),sizeof(float),1,fpout);
00468
00469
00470 for(i=0;i<pi.fdn;i++)
00471 {
00472 double td; float tf;int ti;short ts; char tc; unsigned char tuc;
00473 switch (pi.TetraData[i].stotype1){
00474 case ply::T_FLOAT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
00475 case ply::T_DOUBLE : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
00476 case ply::T_INT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
00477 case ply::T_SHORT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
00478 case ply::T_CHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
00479 case ply::T_UCHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
00480 default : assert(0);
00481 }
00482 }
00483 }
00484 else
00485 {
00486 fprintf(fpout,"3 %d %d %d ",
00487 fp->cV(0)->UberFlags(), fp->cV(1)->UberFlags(), fp->cV(2)->UberFlags() );
00488
00489 if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
00490 fprintf(fpout,"%d ",fp->Flags());
00491
00492 if( m.HasPerVertexTexture() && (pi.mask & ply::PLYMask::PM_VERTTEXCOORD) )
00493 {
00494 fprintf(fpout,"6 ");
00495 for(int k=0;k<4;++k)
00496 fprintf(fpout,"%g %g "
00497 ,fp->V(k)->T().u()
00498 ,fp->V(k)->T().v()
00499 );
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 if( TetraType::HasTetraColor() && (pi.mask & ply::PLYMask::PM_TETRACOLOR) )
00517 {
00518 float t[3];
00519 t[0] = float(fp->C()[0])/255;
00520 t[1] = float(fp->C()[1])/255;
00521 t[2] = float(fp->C()[2])/255;
00522 fprintf(fpout,"9 ");
00523 fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
00524 fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
00525 fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 if( m.HasPerTetraQuality() && (pi.mask & ply::PLYMask::PM_TETRAQUALITY) )
00539 fprintf(fpout,"%g ",fp->Q());
00540
00541 for(i=0;i<pi.fdn;i++)
00542 {
00543 float tf; double td;
00544 int ti;
00545 switch (pi.TetraData[i].memtype1)
00546 {
00547 case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00548 case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00549 case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00550 case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00551 case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00552 case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00553 default : assert(0);
00554 }
00555 }
00556
00557 fprintf(fpout,"\n");
00558 }
00559 }
00560 }
00561 assert(fcnt==m.tn);
00562 fclose(fpout);
00563
00564
00565 for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
00566 (*vi).UberFlags()=FlagV[j++];
00567
00568 return 0;
00569 }
00570
00571
00572
00573
00574 };
00575
00576
00577
00578 }
00579 }
00580 }
00581
00582 #endif