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
00126
00127 #ifndef __VCGLIB_EXPORT_PLY
00128 #define __VCGLIB_EXPORT_PLY
00129
00130
00131 #include<wrap/io_trimesh/io_mask.h>
00132 #include<wrap/io_trimesh/io_ply.h>
00133 #include<vcg/container/simple_temporary_data.h>
00134
00135
00136 #include <stdio.h>
00137
00138 namespace vcg {
00139 namespace tri {
00140 namespace io {
00141
00142
00143 template <class SaveMeshType>
00144 class ExporterPLY
00145 {
00146
00147
00148
00149
00150
00151
00152 template <class StoType>
00153 static void PlyConv(int mem_type, void *src, StoType &dest)
00154 {
00155 switch (mem_type){
00156 case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break;
00157 case ply::T_DOUBLE: dest = (StoType) (* ((double *) src)); break;
00158 case ply::T_INT : dest = (StoType) (* ((int *) src)); break;
00159 case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break;
00160 case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break;
00161 case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break;
00162 default : assert(0);
00163 }
00164 }
00165
00166 public:
00167 typedef ::vcg::ply::PropDescriptor PropDescriptor ;
00168 typedef typename SaveMeshType::VertexPointer VertexPointer;
00169 typedef typename SaveMeshType::ScalarType ScalarType;
00170 typedef typename SaveMeshType::VertexType VertexType;
00171 typedef typename SaveMeshType::FaceType FaceType;
00172 typedef typename SaveMeshType::FacePointer FacePointer;
00173 typedef typename SaveMeshType::VertexIterator VertexIterator;
00174 typedef typename SaveMeshType::FaceIterator FaceIterator;
00175
00176 static int Save(SaveMeshType &m, const char * filename, bool binary=true)
00177 {
00178 PlyInfo pi;
00179 return Save(m,filename,binary,pi);
00180 }
00181
00182 static int Save(SaveMeshType &m, const char * filename, int savemask, bool binary = true, CallBackPos *cb=0 )
00183 {
00184 PlyInfo pi;
00185 pi.mask=savemask;
00186 return Save(m,filename,binary,pi,cb);
00187 }
00188
00189 static int Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &pi, CallBackPos *cb=0)
00190 {
00191 FILE * fpout;
00192 int i;
00193
00194 const char * hbin = "binary_little_endian";
00195 const char * hasc = "ascii";
00196 const char * h;
00197
00198 bool multit = false;
00199
00200 if(binary) h=hbin;
00201 else h=hasc;
00202
00203 fpout = fopen(filename,"wb");
00204 if(fpout==NULL) {
00205 pi.status=::vcg::ply::E_CANTOPEN;
00206 return ::vcg::ply::E_CANTOPEN;
00207 }
00208 fprintf(fpout,
00209 "ply\n"
00210 "format %s 1.0\n"
00211 "comment VCGLIB generated\n"
00212 ,h
00213 );
00214
00215 if (((pi.mask & Mask::IOM_WEDGTEXCOORD) != 0) || ((pi.mask & Mask::IOM_VERTTEXCOORD) != 0))
00216 {
00217 const char * TFILE = "TextureFile";
00218
00219 for(i=0; i < static_cast<int>(m.textures.size()); ++i)
00220 fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(m.textures[i].c_str()) );
00221
00222 if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) multit = true;
00223 }
00224
00225 if((pi.mask & Mask::IOM_CAMERA))
00226 {
00227 fprintf(fpout,
00228 "element camera 1\n"
00229 "property float view_px\n"
00230 "property float view_py\n"
00231 "property float view_pz\n"
00232 "property float x_axisx\n"
00233 "property float x_axisy\n"
00234 "property float x_axisz\n"
00235 "property float y_axisx\n"
00236 "property float y_axisy\n"
00237 "property float y_axisz\n"
00238 "property float z_axisx\n"
00239 "property float z_axisy\n"
00240 "property float z_axisz\n"
00241 "property float focal\n"
00242 "property float scalex\n"
00243 "property float scaley\n"
00244 "property float centerx\n"
00245 "property float centery\n"
00246 "property int viewportx\n"
00247 "property int viewporty\n"
00248 "property float k1\n"
00249 "property float k2\n"
00250 "property float k3\n"
00251 "property float k4\n"
00252 );
00253 }
00254
00255 fprintf(fpout,
00256 "element vertex %d\n"
00257 "property float x\n"
00258 "property float y\n"
00259 "property float z\n"
00260 ,m.vn
00261 );
00262
00263 if( HasPerVertexNormal(m) &&( pi.mask & Mask::IOM_VERTNORMAL) )
00264 {
00265 fprintf(fpout,
00266 "property float nx\n"
00267 "property float ny\n"
00268 "property float nz\n"
00269 );
00270 }
00271
00272
00273 if( HasPerVertexFlags(m) &&( pi.mask & Mask::IOM_VERTFLAGS) )
00274 {
00275 fprintf(fpout,
00276 "property int flags\n"
00277 );
00278 }
00279
00280 if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
00281 {
00282 fprintf(fpout,
00283 "property uchar red\n"
00284 "property uchar green\n"
00285 "property uchar blue\n"
00286 "property uchar alpha\n"
00287 );
00288 }
00289
00290 if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
00291 {
00292 fprintf(fpout,
00293 "property float quality\n"
00294 );
00295 }
00296
00297 if( tri::HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) )
00298 {
00299 fprintf(fpout,
00300 "property float radius\n"
00301 );
00302 }
00303 if( ( HasPerVertexTexCoord(m) && pi.mask & Mask::IOM_VERTTEXCOORD ) )
00304 {
00305 fprintf(fpout,
00306 "property float texture_u\n"
00307 "property float texture_v\n"
00308 );
00309 }
00310 for(i=0;i<pi.vdn;i++)
00311 fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
00312
00313 fprintf(fpout,
00314 "element face %d\n"
00315 "property list uchar int vertex_indices\n"
00316 ,m.fn
00317 );
00318
00319 if(HasPerFaceFlags(m) && (pi.mask & Mask::IOM_FACEFLAGS) )
00320 {
00321 fprintf(fpout,
00322 "property int flags\n"
00323 );
00324 }
00325
00326 if( (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m) ) && pi.mask & Mask::IOM_WEDGTEXCOORD )
00327 {
00328 fprintf(fpout,
00329 "property list uchar float texcoord\n"
00330 );
00331
00332 if(multit)
00333 fprintf(fpout,
00334 "property int texnumber\n"
00335 );
00336 }
00337
00338 if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) )
00339 {
00340 fprintf(fpout,
00341 "property uchar red\n"
00342 "property uchar green\n"
00343 "property uchar blue\n"
00344 "property uchar alpha\n"
00345 );
00346 }
00347
00348 if ( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) )
00349 {
00350 fprintf(fpout,
00351 "property list uchar float color\n"
00352 );
00353 }
00354
00355 if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
00356 {
00357 fprintf(fpout,
00358 "property float quality\n"
00359 );
00360 }
00361
00362 for(i=0;i<pi.fdn;i++)
00363 fprintf(fpout,"property %s %s\n",pi.FaceData[i].stotypename(),pi.FaceData[i].propname);
00364
00365 fprintf(fpout, "end_header\n" );
00366
00367
00368 if((pi.mask & Mask::IOM_CAMERA))
00369 {
00370 if(binary)
00371 {
00372 float t[17];
00373
00374 t[ 0] = (float)m.shot.Extrinsics.Tra()[0];
00375 t[ 1] = (float)m.shot.Extrinsics.Tra()[1];
00376 t[ 2] = (float)m.shot.Extrinsics.Tra()[2];
00377 t[ 3] = (float)m.shot.Extrinsics.Rot()[0][0];
00378 t[ 4] = (float)m.shot.Extrinsics.Rot()[0][1];
00379 t[ 5] = (float)m.shot.Extrinsics.Rot()[0][2];
00380 t[ 6] = (float)m.shot.Extrinsics.Rot()[1][0];
00381 t[ 7] = (float)m.shot.Extrinsics.Rot()[1][1];
00382 t[ 8] = (float)m.shot.Extrinsics.Rot()[1][2];
00383 t[ 9] = (float)m.shot.Extrinsics.Rot()[2][0];
00384 t[10] = (float)m.shot.Extrinsics.Rot()[2][1];
00385 t[11] = (float)m.shot.Extrinsics.Rot()[2][2];
00386 t[12] = (float)m.shot.Intrinsics.FocalMm;
00387 t[13] = (float)m.shot.Intrinsics.PixelSizeMm[0];
00388 t[14] = (float)m.shot.Intrinsics.PixelSizeMm[1];
00389 t[15] = (float)m.shot.Intrinsics.CenterPx[0];
00390 t[16] = (float)m.shot.Intrinsics.CenterPx[1];
00391 fwrite(t,sizeof(float),17,fpout);
00392
00393 fwrite( &m.shot.Intrinsics.ViewportPx[0],sizeof(int),2,fpout );
00394
00395 t[ 0] = (float)m.shot.Intrinsics.k[0];
00396 t[ 1] = (float)m.shot.Intrinsics.k[1];
00397 t[ 2] = (float)m.shot.Intrinsics.k[2];
00398 t[ 3] = (float)m.shot.Intrinsics.k[3];
00399 fwrite(t,sizeof(float),4,fpout);
00400 }
00401 else
00402 {
00403 fprintf(fpout,"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d %d %g %g %g %g\n"
00404 ,-m.shot.Extrinsics.Tra()[0]
00405 ,-m.shot.Extrinsics.Tra()[1]
00406 ,-m.shot.Extrinsics.Tra()[2]
00407 ,m.shot.Extrinsics.Rot()[0][0]
00408 ,m.shot.Extrinsics.Rot()[0][1]
00409 ,m.shot.Extrinsics.Rot()[0][2]
00410 ,m.shot.Extrinsics.Rot()[1][0]
00411 ,m.shot.Extrinsics.Rot()[1][1]
00412 ,m.shot.Extrinsics.Rot()[1][2]
00413 ,m.shot.Extrinsics.Rot()[2][0]
00414 ,m.shot.Extrinsics.Rot()[2][1]
00415 ,m.shot.Extrinsics.Rot()[2][2]
00416 ,m.shot.Intrinsics.FocalMm
00417 ,m.shot.Intrinsics.PixelSizeMm[0]
00418 ,m.shot.Intrinsics.PixelSizeMm[1]
00419 ,m.shot.Intrinsics.CenterPx[0]
00420 ,m.shot.Intrinsics.CenterPx[1]
00421 ,m.shot.Intrinsics.ViewportPx[0]
00422 ,m.shot.Intrinsics.ViewportPx[1]
00423 ,m.shot.Intrinsics.k[0]
00424 ,m.shot.Intrinsics.k[1]
00425 ,m.shot.Intrinsics.k[2]
00426 ,m.shot.Intrinsics.k[3]
00427 );
00428 }
00429 }
00430
00431
00432 int j;
00433 std::vector<int> FlagV;
00434 VertexPointer vp;
00435 VertexIterator vi;
00436 SimpleTempData<typename SaveMeshType::VertContainer,int> indices(m.vert);
00437
00438 for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi){
00439 vp=&(*vi);
00440 indices[vi] = j;
00441
00442 if(cb && ((j%1000)==0))(*cb)( (100*j)/(m.vn+m.fn), "Saving Vertices");
00443
00444 if( !HasPerVertexFlags(m) || !vp->IsD() )
00445 {
00446 if(binary)
00447 {
00448 float t;
00449
00450 t = float(vp->P()[0]); fwrite(&t,sizeof(float),1,fpout);
00451 t = float(vp->P()[1]); fwrite(&t,sizeof(float),1,fpout);
00452 t = float(vp->P()[2]); fwrite(&t,sizeof(float),1,fpout);
00453
00454 if( HasPerVertexNormal(m) && (pi.mask & Mask::IOM_VERTNORMAL) )
00455 {
00456 t = float(vp->N()[0]); fwrite(&t,sizeof(float),1,fpout);
00457 t = float(vp->N()[1]); fwrite(&t,sizeof(float),1,fpout);
00458 t = float(vp->N()[2]); fwrite(&t,sizeof(float),1,fpout);
00459 }
00460 if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS) )
00461 fwrite(&(vp->UberFlags()),sizeof(int),1,fpout);
00462
00463 if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
00464 fwrite(&( vp->C() ),sizeof(char),4,fpout);
00465
00466 if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
00467 fwrite(&( vp->Q() ),sizeof(float),1,fpout);
00468
00469 if( HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) )
00470 fwrite(&( vp->R() ),sizeof(float),1,fpout);
00471
00472 if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
00473 {
00474 t = float(vp->T().u()); fwrite(&t,sizeof(float),1,fpout);
00475 t = float(vp->T().v()); fwrite(&t,sizeof(float),1,fpout);
00476 }
00477
00478 for(i=0;i<pi.vdn;i++)
00479 {
00480 double td(0); float tf(0);int ti;short ts; char tc; unsigned char tuc;
00481 switch (pi.VertexData[i].stotype1)
00482 {
00483 case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
00484 case ply::T_DOUBLE : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
00485 case ply::T_INT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
00486 case ply::T_SHORT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
00487 case ply::T_CHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
00488 case ply::T_UCHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
00489 default : assert(0);
00490 }
00491 }
00492 }
00493 else
00494 {
00495 fprintf(fpout,"%g %g %g " ,vp->P()[0],vp->P()[1],vp->P()[2]);
00496
00497 if( HasPerVertexNormal(m) && (pi.mask & Mask::IOM_VERTNORMAL) )
00498 fprintf(fpout,"%g %g %g " ,double(vp->N()[0]),double(vp->N()[1]),double(vp->N()[2]));
00499
00500 if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS))
00501 fprintf(fpout,"%d ",vp->UberFlags());
00502
00503 if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
00504 fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] );
00505
00506 if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
00507 fprintf(fpout,"%g ",vp->Q());
00508
00509 if( HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) )
00510 fprintf(fpout,"%g ",vp->R());
00511
00512 if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
00513 fprintf(fpout,"%g %g",vp->T().u(),vp->T().v());
00514
00515 for(i=0;i<pi.vdn;i++)
00516 {
00517 float tf(0); double td(0);
00518 int ti;
00519 switch (pi.VertexData[i].memtype1)
00520 {
00521 case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00522 case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00523 case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00524 case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00525 case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00526 case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00527 default : assert(0);
00528 }
00529 }
00530
00531 fprintf(fpout,"\n");
00532 }
00533 j++;
00534 }
00535 }
00536
00537 assert(j==m.vn);
00538
00539 char c = 3;
00540 unsigned char b9 = 9;
00541 unsigned char b6 = 6;
00542 FacePointer fp;
00543 int vv[3];
00544 FaceIterator fi;
00545 int fcnt=0;
00546 for(j=0,fi=m.face.begin();fi!=m.face.end();++fi)
00547 {
00548 if(cb && ((j%1000)==0) ) (*cb)( 100*(m.vn+j)/(m.vn+m.fn), "Saving Vertices");
00549
00550 fp=&(*fi);
00551 if( ! fp->IsD() )
00552 { fcnt++;
00553 if(binary)
00554 {
00555 vv[0]=indices[fp->cV(0)];
00556 vv[1]=indices[fp->cV(1)];
00557 vv[2]=indices[fp->cV(2)];
00558 fwrite(&c,1,1,fpout);
00559 fwrite(vv,sizeof(int),3,fpout);
00560
00561 if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS) )
00562 fwrite(&(fp->Flags()),sizeof(int),1,fpout);
00563
00564 if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) )
00565 {
00566 fwrite(&b6,sizeof(char),1,fpout);
00567 float t[6];
00568 for(int k=0;k<3;++k)
00569 {
00570 t[k*2+0] = fp->V(k)->T().u();
00571 t[k*2+1] = fp->V(k)->T().v();
00572 }
00573 fwrite(t,sizeof(float),6,fpout);
00574 }
00575 else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) )
00576 {
00577 fwrite(&b6,sizeof(char),1,fpout);
00578 float t[6];
00579 for(int k=0;k<3;++k)
00580 {
00581 t[k*2+0] = fp->WT(k).u();
00582 t[k*2+1] = fp->WT(k).v();
00583 }
00584 fwrite(t,sizeof(float),6,fpout);
00585 }
00586
00587 if(multit)
00588 {
00589 int t = fp->WT(0).n();
00590 fwrite(&t,sizeof(int),1,fpout);
00591 }
00592
00593 if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) )
00594 fwrite(&( fp->C() ),sizeof(char),4,fpout);
00595
00596
00597 if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) )
00598 {
00599 fwrite(&b9,sizeof(char),1,fpout);
00600 float t[3];
00601 for(int z=0;z<3;++z)
00602 {
00603 t[0] = float(fp->WC(z)[0])/255;
00604 t[1] = float(fp->WC(z)[1])/255;
00605 t[2] = float(fp->WC(z)[2])/255;
00606 fwrite( t,sizeof(float),3,fpout);
00607 }
00608 }
00609
00610 if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
00611 fwrite( &(fp->Q()),sizeof(float),1,fpout);
00612
00613
00614 for(i=0;i<pi.fdn;i++)
00615 {
00616 double td(0); float tf(0);int ti;short ts; char tc; unsigned char tuc;
00617 switch (pi.FaceData[i].stotype1){
00618 case ply::T_FLOAT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
00619 case ply::T_DOUBLE : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
00620 case ply::T_INT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
00621 case ply::T_SHORT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
00622 case ply::T_CHAR : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
00623 case ply::T_UCHAR : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
00624 default : assert(0);
00625 }
00626 }
00627 }
00628 else
00629 {
00630 fprintf(fpout,"3 %d %d %d ",
00631 indices[fp->cV(0)], indices[fp->cV(1)], indices[fp->cV(2)] );
00632
00633 if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS ))
00634 fprintf(fpout,"%d ",fp->Flags());
00635
00636 if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) )
00637 {
00638 fprintf(fpout,"6 ");
00639 for(int k=0;k<3;++k)
00640 fprintf(fpout,"%g %g "
00641 ,fp->V(k)->T().u()
00642 ,fp->V(k)->T().v()
00643 );
00644 }
00645 else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) )
00646 {
00647 fprintf(fpout,"6 ");
00648 for(int k=0;k<3;++k)
00649 fprintf(fpout,"%g %g "
00650 ,fp->WT(k).u()
00651 ,fp->WT(k).v()
00652 );
00653 }
00654
00655 if(multit)
00656 {
00657 fprintf(fpout,"%d ",fp->WT(0).n());
00658 }
00659
00660 if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) )
00661 {
00662 float t[3];
00663 t[0] = float(fp->C()[0])/255;
00664 t[1] = float(fp->C()[1])/255;
00665 t[2] = float(fp->C()[2])/255;
00666 fprintf(fpout,"9 ");
00667 fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
00668 fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
00669 fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
00670 }
00671 else if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) )
00672 {
00673 fprintf(fpout,"9 ");
00674 for(int z=0;z<3;++z)
00675 fprintf(fpout,"%g %g %g "
00676 ,double(fp->WC(z)[0])/255
00677 ,double(fp->WC(z)[1])/255
00678 ,double(fp->WC(z)[2])/255
00679 );
00680 }
00681
00682 if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
00683 fprintf(fpout,"%g ",fp->Q());
00684
00685 for(i=0;i<pi.fdn;i++)
00686 {
00687 float tf(0); double td(0);
00688 int ti;
00689 switch (pi.FaceData[i].memtype1)
00690 {
00691 case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00692 case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%g ",tf); break;
00693 case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00694 case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00695 case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00696 case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
00697 default : assert(0);
00698 }
00699 }
00700
00701 fprintf(fpout,"\n");
00702 }
00703 }
00704 }
00705 assert(fcnt==m.fn);
00706 fclose(fpout);
00707 return 0;
00708 }
00709
00710 static const char *ErrorMsg(int error)
00711 {
00712 static std::vector<std::string> ply_error_msg;
00713 if(ply_error_msg.empty())
00714 {
00715 ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS );
00716 ply_error_msg[ply::E_NOERROR ]="No errors";
00717 ply_error_msg[ply::E_CANTOPEN ]="Can't open file";
00718 ply_error_msg[ply::E_NOTHEADER ]="Header not found";
00719 ply_error_msg[ply::E_UNESPECTEDEOF ]="Eof in header";
00720 ply_error_msg[ply::E_NOFORMAT ]="Format not found";
00721 ply_error_msg[ply::E_SYNTAX ]="Syntax error on header";
00722 ply_error_msg[ply::E_PROPOUTOFELEMENT]="Property without element";
00723 ply_error_msg[ply::E_BADTYPENAME ]="Bad type name";
00724 ply_error_msg[ply::E_ELEMNOTFOUND ]="Element not found";
00725 ply_error_msg[ply::E_PROPNOTFOUND ]="Property not found";
00726 ply_error_msg[ply::E_BADTYPE ]="Bad type on addtoread";
00727 ply_error_msg[ply::E_INCOMPATIBLETYPE]="Incompatible type";
00728 ply_error_msg[ply::E_BADCAST ]="Bad cast";
00729
00730 ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found";
00731 ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found";
00732 ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof";
00733 ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices";
00734 ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face";
00735 ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates";
00736 ply_error_msg[PlyInfo::E_DIFFER_COLORS ]="Number of color differ from vertices";
00737 }
00738
00739 if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error";
00740 else return ply_error_msg[error].c_str();
00741 };
00742
00743 static int GetExportMaskCapability()
00744 {
00745 int capability = 0;
00746 capability |= vcg::tri::io::Mask::IOM_VERTCOORD ;
00747 capability |= vcg::tri::io::Mask::IOM_VERTFLAGS ;
00748 capability |= vcg::tri::io::Mask::IOM_VERTCOLOR ;
00749 capability |= vcg::tri::io::Mask::IOM_VERTQUALITY ;
00750 capability |= vcg::tri::io::Mask::IOM_VERTNORMAL ;
00751 capability |= vcg::tri::io::Mask::IOM_VERTRADIUS ;
00752 capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD ;
00753 capability |= vcg::tri::io::Mask::IOM_FACEINDEX ;
00754 capability |= vcg::tri::io::Mask::IOM_FACEFLAGS ;
00755 capability |= vcg::tri::io::Mask::IOM_FACECOLOR ;
00756 capability |= vcg::tri::io::Mask::IOM_FACEQUALITY ;
00757
00758 capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR ;
00759 capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD ;
00760 capability |= vcg::tri::io::Mask::IOM_WEDGTEXMULTI ;
00761 capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL ;
00762 capability |= vcg::tri::io::Mask::IOM_CAMERA ;
00763 return capability;
00764 }
00765
00766
00767 };
00768
00769
00770
00771 }
00772 }
00773 }
00775 #endif