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