/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ /**************************************************************************** History $Log: not supported by cvs2svn $ Revision 1.1 2004/06/03 13:16:32 ganovelli created ****************************************************************************/ #ifndef __VCGLIB_TETRAIMPORTERPLY #define __VCGLIB_TETRAIMPORTERPLY #include<wrap/callback.h> #include<wrap/ply/plylib.h> #include<wrap/ply/io_mask.h> #include<wrap/io_tetramesh/io_ply.h> #include<vcg/complex/tetramesh/allocate.h> namespace vcg { namespace tetra { namespace io { template <class TYPE> int PlyType () { return 0;} template <> int PlyType <float >() { return ply::T_FLOAT; } template <> int PlyType <double>() { return ply::T_DOUBLE; } template <> int PlyType <int >() { return ply::T_INT; } template <> int PlyType <short >() { return ply::T_SHORT; } template <> int PlyType <unsigned char >() { return ply::T_UCHAR; } /** This class encapsulate a filter for opening ply meshes. The ply file format is quite extensible... */ template <class OpenMeshType> class ImporterPLY { public: typedef ::vcg::ply::PropDescriptor PropDescriptor ; typedef typename OpenMeshType::VertexPointer VertexPointer; typedef typename OpenMeshType::ScalarType ScalarType; typedef typename OpenMeshType::VertexType VertexType; typedef typename OpenMeshType::TetraType TetraType; typedef typename OpenMeshType::VertexIterator VertexIterator; typedef typename OpenMeshType::TetraIterator TetraIterator; //template <class T> int PlyType () { assert(0); return 0;} #define MAX_USER_DATA 256 // Struttura ausiliaria per la lettura del file ply struct LoadPly_TetraAux { unsigned char size; int v[512]; int flags; float q; float texcoord[32]; unsigned char ntexcoord; int texcoordind; float colors[32]; unsigned char ncolors; unsigned char r; unsigned char g; unsigned char b; unsigned char data[MAX_USER_DATA]; }; //struct LoadPly_TristripAux //{ // int size; // int *v; // unsigned char data[MAX_USER_DATA]; //}; // Struttura ausiliaria per la lettura del file ply template<class S> struct LoadPly_VertAux { S p[3]; int flags; float q; unsigned char r; unsigned char g; unsigned char b; unsigned char data[MAX_USER_DATA]; }; // Struttura ausiliaria caricamento camera //struct LoadPly_Camera //{ // float view_px; // float view_py; // float view_pz; // float x_axisx; // float x_axisy; // float x_axisz; // float y_axisx; // float y_axisy; // float y_axisz; // float z_axisx; // float z_axisy; // float z_axisz; // float focal; // float scalex; // float scaley; // float centerx; // float centery; // int viewportx; // int viewporty; // float k1; // float k2; // float k3; // float k4; //}; static const PropDescriptor &VertDesc(int i) { const static PropDescriptor pv[9]={ {"vertex", "x", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p[0]),0,0,0,0,0}, {"vertex", "y", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p[1]),0,0,0,0,0}, {"vertex", "z", ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p[2]),0,0,0,0,0}, {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux<ScalarType>,flags),0,0,0,0,0}, {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0}, {"vertex", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0}, {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0}, {"vertex", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0}, {"vertex", "confidence",ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0}, }; return pv[i]; } static const PropDescriptor &TetraDesc(int i) { const static PropDescriptor qf[10]= { {"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) }, {"tetra", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,flags), 0,0,0,0,0}, {"tetra", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,q), 0,0,0,0,0}, {"tetra", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,texcoord), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ntexcoord) }, {"tetra", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,colors), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ncolors) }, {"tetra", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,texcoordind), 0,0,0,0,0}, {"tetra", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,r), 0,0,0,0,0}, {"tetra", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,g), 0,0,0,0,0}, {"tetra", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,b), 0,0,0,0,0}, {"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) }, }; return qf[i]; } //static const PropDescriptor &TristripDesc(int i) //{ // const static PropDescriptor qf[1]= // { // {"tristrips","vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_TristripAux,v), 1,1,ply::T_INT,ply::T_INT,offsetof(LoadPly_TristripAux,size) }, // }; // return qf[i]; //} //static const PropDescriptor &CameraDesc(int i) //{ // const static PropDescriptor cad[23] = // { // {"camera","view_px",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_px),0,0,0,0,0}, // {"camera","view_py",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_py),0,0,0,0,0}, // {"camera","view_pz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_pz),0,0,0,0,0}, // {"camera","x_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisx),0,0,0,0,0}, // {"camera","x_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisy),0,0,0,0,0}, // {"camera","x_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisz),0,0,0,0,0}, // {"camera","y_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisx),0,0,0,0,0}, // {"camera","y_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisy),0,0,0,0,0}, // {"camera","y_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisz),0,0,0,0,0}, // {"camera","z_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisx),0,0,0,0,0}, // {"camera","z_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisy),0,0,0,0,0}, // {"camera","z_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisz),0,0,0,0,0}, // {"camera","focal" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,focal ),0,0,0,0,0}, // {"camera","scalex" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scalex ),0,0,0,0,0}, // {"camera","scaley" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scaley ),0,0,0,0,0}, // {"camera","centerx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centerx),0,0,0,0,0}, // {"camera","centery",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centery),0,0,0,0,0}, // {"camera","viewportx",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewportx),0,0,0,0,0}, // {"camera","viewporty",ply::T_INT,ply::T_INT ,offsetof(LoadPly_Camera,viewporty),0,0,0,0,0}, // {"camera","k1" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k1 ),0,0,0,0,0}, // {"camera","k2" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k2 ),0,0,0,0,0}, // {"camera","k3" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k3 ),0,0,0,0,0}, // {"camera","k4" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k4 ),0,0,0,0,0} // }; // return cad[i]; //} /// Standard call for reading a mesh static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0) { PlyInfo pi; pi.cb=cb; return Open(m, filename, pi); } /// Read a mesh and store in loadmask the loaded field static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0) { PlyInfo pi; pi.mask=loadmask; return Open(m, filename,pi); loadmask=pi.mask; } /// read a mesh with all the possible option specified in the PlyInfo obj. static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi ) { assert(filename!=0); vector<VertexPointer> index; LoadPly_TetraAux fa; // LoadPly_TristripAux tsa; LoadPly_VertAux<ScalarType> va; pi.mask = 0; bool multit = false; // true if texture has a per face int spec the texture index va.flags = 42; pi.status = ::vcg::ply::E_NOERROR; // init defaults VertexType tv; tv.UberFlags() = 0; if( VertexType::HasQuality() ) tv.Q()=1.0; if( VertexType::HasColor() ) tv.C()=Color4b(Color4b::White); TetraType tf; tf.UberFlags() = 0; //if( FaceType::HasFaceQuality() ) tf.Q()=1.0; //if( FaceType::HasWedgeColor() ) tf.WC(0)=tf.WC(1)=tf.WC(2)=Color4b(Color4b::White); //if( FaceType::HasFaceColor() ) tf.C()=Color4b(Color4b::White); // Descrittori delle strutture //bool isvflags = false; // Il file contiene i flags // The main descriptor of the ply file vcg::ply::PlyFile pf; // Open the file and parse the header if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) { pi.status = pf.GetError(); return -1; } pi.header = pf.GetHeader(); // Descrittori della camera { // Check that all the camera properties are present. /* bool found = true; for(int i=0;i<23;++i) { if( pf.AddToRead(CameraDesc(i))==-1 ) { found = false; break; } } if(found) pi.mask |= ply::PLYMask::PM_CAMERA;*/ } // Descrittori dati standard (vertex coord e faces) if( pf.AddToRead(VertDesc(0))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; } if( pf.AddToRead(VertDesc(1))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; } if( pf.AddToRead(VertDesc(2))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return -1; } if( pf.AddToRead(TetraDesc(0))==-1 ){ pi.status = PlyInfo::E_NO_VERTEX; return -1; } // Se fallisce si prova anche la sintassi di rapidform con index al posto di indices // if( pf.AddToRead(TetraDesc(9))==-1 ) // if(pf.AddToRead(TristripDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono tristrip alla levoy. // { pi.status = PlyInfo::E_NO_FACE; return -1; } // Descrittori facoltativi dei flags if( pf.AddToRead(VertDesc(3))!=-1 ) pi.mask |= ply::PLYMask::PM_VERTFLAGS; if( VertexType::HasQuality() ) { if( pf.AddToRead(VertDesc(4))!=-1 || pf.AddToRead(VertDesc(8))!=-1 ) pi.mask |= ply::PLYMask::PM_VERTQUALITY; } if( VertexType::HasColor() ) { if( pf.AddToRead(VertDesc(5))!=-1 ) { pf.AddToRead(VertDesc(6)); pf.AddToRead(VertDesc(7)); pi.mask |= ply::PLYMask::PM_VERTCOLOR; } } // se ci sono i flag per vertice ci devono essere anche i flag per faccia if( pf.AddToRead(TetraDesc(1))!=-1 ) pi.mask |= ply::PLYMask::PM_TETRAFLAGS; if( TetraType::HasTetraQuality()) { if( pf.AddToRead(TetraDesc(2))!=-1 ) pi.mask |= ply::PLYMask::PM_TETRAQUALITY; } if( TetraType::HasTetraColor() ) { if( pf.AddToRead(TetraDesc(6))!=-1 ) { pf.AddToRead(TetraDesc(7)); pf.AddToRead(TetraDesc(8)); pi.mask |= ply::PLYMask::PM_TETRACOLOR; } } // if( FaceType::HasWedgeColor() || FaceType::HasFaceColor() || VertexType::HasColor()) //{ // if( pf.AddToRead(TetraDesc(4))!=-1 ) // { // pi.mask |= ply::PLYMask::PM_WEDGCOLOR; // } //} // Descrittori definiti dall'utente, vector<PropDescriptor> VPV(pi.vdn); // property descriptor relative al tipo LoadPly_VertexAux vector<PropDescriptor> FPV(pi.fdn); // property descriptor relative al tipo LoadPly_FaceAux if(pi.vdn>0){ // Compute the total size needed to load additional per vertex data. size_t totsz=0; for(int i=0;i<pi.vdn;i++){ VPV[i] = pi.VertexData[i]; VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz; totsz+=pi.VertexData[i].memtypesize(); if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return -1; } } if(totsz > MAX_USER_DATA) { pi.status = vcg::ply::E_BADTYPE; return -1; } } if(pi.fdn>0){ size_t totsz=0; for(int i=0;i<pi.fdn;i++){ FPV[i] = pi.TetraData[i]; FPV[i].offset1=offsetof(LoadPly_TetraAux,data)+totsz; totsz+=pi.TetraData[i].memtypesize(); if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return -1; } } if(totsz > MAX_USER_DATA) { pi.status = vcg::ply::E_BADTYPE; return -1; } } /**************************************************************/ /* Main Reading Loop */ /**************************************************************/ m.Clear(); for(int i=0;i<int(pf.elements.size());i++) { int n = pf.ElemNumber(i); if( !strcmp( pf.ElemName(i),"camera" ) ) { pf.SetCurElement(i); // LoadPly_Camera ca; for(int j=0;j<n;++j) { /* if( pf.Read( (void *)&(ca) )==-1 ) { pi.status = PlyInfo::E_SHORTFILE; return -1; } */ //camera.valid = true; //camera.view_p[0] = ca.view_px; //camera.view_p[1] = ca.view_py; //camera.view_p[2] = ca.view_pz; //camera.x_axis[0] = ca.x_axisx; //camera.x_axis[1] = ca.x_axisy; //camera.x_axis[2] = ca.x_axisz; //camera.y_axis[0] = ca.y_axisx; //camera.y_axis[1] = ca.y_axisy; //camera.y_axis[2] = ca.y_axisz; //camera.z_axis[0] = ca.z_axisx; //camera.z_axis[1] = ca.z_axisy; //camera.z_axis[2] = ca.z_axisz; //camera.f = ca.focal; //camera.s[0] = ca.scalex; //camera.s[1] = ca.scaley; //camera.c[0] = ca.centerx; //camera.c[1] = ca.centery; //camera.viewport[0] = ca.viewportx; //camera.viewport[1] = ca.viewporty; //camera.k[0] = ca.k1; //camera.k[1] = ca.k2; //camera.k[2] = ca.k3; //camera.k[3] = ca.k4; } } else if( !strcmp( pf.ElemName(i),"vertex" ) ) { int j; pf.SetCurElement(i); VertexIterator vi=Allocator<OpenMeshType>::AddVertices(m,n); for(j=0;j<n;++j) { if(pi.cb && (j%1000)==0) pi.cb(j*50/n,"Vertex Loading"); (*vi).UberFlags()=0; if( pf.Read( (void *)&(va) )==-1 ) { pi.status = PlyInfo::E_SHORTFILE; return -1; } (*vi).P()[0] = va.p[0]; (*vi).P()[1] = va.p[1]; (*vi).P()[2] = va.p[2]; if( pi.mask & ply::PLYMask::PM_VERTFLAGS ) (*vi).UberFlags() = va.flags; if( pi.mask & ply::PLYMask::PM_VERTQUALITY ) (*vi).Q() = va.q; if( pi.mask & ply::PLYMask::PM_VERTCOLOR ) { (*vi).C()[0] = va.r; (*vi).C()[1] = va.g; (*vi).C()[2] = va.b; (*vi).C()[3] = 255; } for(int k=0;k<pi.vdn;k++) memcpy((char *)(&*vi) + pi.VertexData[k].offset1, (char *)(&va) + VPV[k].offset1, VPV[k].memtypesize()); ++vi; } index.resize(n); for(j=0,vi=m.vert.begin();j<n;++j,++vi) index[j] = &*vi; } else if( !strcmp( pf.ElemName(i),"tetra") )/************************************************************/ { int j; int k; TetraIterator fi=Allocator<OpenMeshType>::AddTetra(m,n); pf.SetCurElement(i); for(j=0;j<n;++j) { if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tetra Loading"); if( pf.Read(&fa)==-1 ) { pi.status = PlyInfo::E_SHORTFILE; return -1; } if(fa.size!=4) { pi.status = PlyInfo::E_NO_3VERTINFACE; return -1; } for(k=0;k<4;++k) { if( fa.v[k]<0 || fa.v[k]>=m.vn ) { pi.status = PlyInfo::E_BAD_VERT_INDEX; return -1; } (*fi).V(k) = index[ fa.v[k] ]; } if( pi.mask & ply::PLYMask::PM_TETRAFLAGS ) { (*fi).UberFlags() = fa.flags; } if( pi.mask & ply::PLYMask::PM_TETRAQUALITY ) { (*fi).Q() = fa.q; } if( pi.mask & ply::PLYMask::PM_TETRACOLOR ) { (*fi).C()[0] = fa.r; (*fi).C()[1] = fa.g; (*fi).C()[2] = fa.b; (*fi).C()[3] = 255; } if(TetraType::HasTetraColor()){ { (*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); (*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); (*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); } } } for(k=0;k<pi.fdn;k++) memcpy((char *)(&(*fi)) + pi.TetraData[k].offset1, (char *)(&fa) + FPV[k].offset1, FPV[k].memtypesize()); ++fi; } // } //else if( !strcmp( pf.ElemName(i),"tristrips") )//////////////////// LETTURA TRISTRIP DI STANFORD // { // int j; // pf.SetCurElement(i); // int numvert_tmp = m.vert.size(); // for(j=0;j<n;++j) // { // int k; // if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tristrip Face Loading"); // if( pf.Read(&tsa)==-1 ) // { // pi.status = PlyInfo::E_SHORTFILE; // return -1; // } // int remainder=0; // //int startface=m.face.size(); // for(k=0;k<tsa.size-2;++k) // { // if(pi.cb && (k%1000)==0) pi.cb(50+k*50/tsa.size,"Tristrip Face Loading"); // if(tsa.v[k]<0 || tsa.v[k]>=numvert_tmp ) { // pi.status = PlyInfo::E_BAD_VERT_INDEX; // return -1; // } // if(tsa.v[k+2]==-1) // { // k+=2; // if(k%2) remainder=0; // else remainder=1; // continue; // } // tf.V(0) = index[ tsa.v[k+0] ]; // tf.V(1) = index[ tsa.v[k+1] ]; // tf.V(2) = index[ tsa.v[k+2] ]; // if((k+remainder)%2) swap (tf.V(0), tf.V(1) ); // m.face.push_back( tf ); // } // } // } else { // Skippaggio elementi non gestiti int n = pf.ElemNumber(i); pf.SetCurElement(i); for(int j=0;j<n;j++) { if( pf.Read(0)==-1) { pi.status = PlyInfo::E_SHORTFILE; return -1; } } } } // // Parsing texture names //textures.clear(); //normalmaps.clear(); //for(int co=0;co<int(pf.comments.size());++co) //{ // const char * TFILE = "TextureFile"; // const char * NFILE = "TextureNormalFile"; // const char * c = pf.comments[co]; // char buf[256]; // int i,j,n; // if( !strncmp(c,TFILE,strlen(TFILE)) ) // { // strcpy(buf,c+strlen(TFILE)+1); // n = strlen(buf); // for(i=j=0;i<n;i++) // if( buf[i]!=' ' && buf[i]!='\t' && buf[i]>32 && buf[i]<125 ) buf[j++] = buf[i]; // // buf[j] = 0; // char buf2[255]; // __interpret_texture_name( buf,filename,buf2 ); // textures.push_back( xstring(buf2) ); // } // if( !strncmp(c,NFILE,strlen(NFILE)) ) // { // strcpy(buf,c+strlen(NFILE)+1); // n = strlen(buf); // for(i=j=0;i<n;i++) // if( buf[i]!=' ' && buf[i]!='\t' && buf[i]>32 && buf[i]<125 ) buf[j++] = buf[i]; // // buf[j] = 0; // char buf2[255]; // __interpret_texture_name( buf,filename,buf2 ); // normalmaps.push_back( xstring(buf2) ); // } //} // vn and fn should be correct but if someone wrongly saved some deleted elements they can be wrong. m.vn = 0; VertexIterator vi; for(vi=m.vert.begin();vi!=m.vert.end();++vi) if( ! (*vi).IsD() ) ++m.vn; m.tn = 0; TetraIterator fi; for(fi=m.tetra.begin();fi!=m.tetra.end();++fi) if( ! (*fi).IsD() ) ++m.tn; return 0; } // Caricamento camera da un ply int LoadCamera(const char * filename) { vcg::ply::PlyFile pf; if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) { pi.status = pf.GetError(); return -1; } bool found = true; int i; for(i=0;i<23;++i) { if( pf.AddToRead(CameraDesc(i))==-1 ) { found = false; break; } } if(!found) return -1; for(i=0;i<int(pf.elements.size());i++) { int n = pf.ElemNumber(i); if( !strcmp( pf.ElemName(i),"camera" ) ) { pf.SetCurElement(i); //LoadPly_Camera ca; for(int j=0;j<n;++j) { if( pf.Read( (void *)&(ca) )==-1 ) { pi.status = PlyInfo::E_SHORTFILE; return -1; } camera.valid = true; camera.view_p[0] = ca.view_px; camera.view_p[1] = ca.view_py; camera.view_p[2] = ca.view_pz; camera.x_axis[0] = ca.x_axisx; camera.x_axis[1] = ca.x_axisy; camera.x_axis[2] = ca.x_axisz; camera.y_axis[0] = ca.y_axisx; camera.y_axis[1] = ca.y_axisy; camera.y_axis[2] = ca.y_axisz; camera.z_axis[0] = ca.z_axisx; camera.z_axis[1] = ca.z_axisy; camera.z_axis[2] = ca.z_axisz; camera.f = ca.focal; camera.s[0] = ca.scalex; camera.s[1] = ca.scaley; camera.c[0] = ca.centerx; camera.c[1] = ca.centery; camera.viewport[0] = ca.viewportx; camera.viewport[1] = ca.viewporty; camera.k[0] = ca.k1; camera.k[1] = ca.k2; camera.k[2] = ca.k3; camera.k[3] = ca.k4; } break; } } return 0; } bool LoadMask(const char * filename, int &mask) { mask=0; vcg::ply::PlyFile pf; if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 ) { pi.status = pf.GetError(); return false; } if( pf.AddToRead(VertDesc(0))!=-1 && pf.AddToRead(VertDesc(1))!=-1 && pf.AddToRead(VertDesc(2))!=-1 ) mask |= ply::PLYMask::PM_VERTCOORD; if( pf.AddToRead(VertDesc(3))!=-1 ) mask |= ply::PLYMask::PM_VERTFLAGS; if( pf.AddToRead(VertDesc(4))!=-1 ) mask |= ply::PLYMask::PM_VERTQUALITY; if( pf.AddToRead(VertDesc(8))!=-1 ) mask |= ply::PLYMask::PM_VERTQUALITY; if( ( pf.AddToRead(VertDesc(5))!=-1 ) && ( pf.AddToRead(VertDesc(6))!=-1 ) && ( pf.AddToRead(VertDesc(7))!=-1 ) ) mask |= ply::PLYMask::PM_VERTCOLOR; if( pf.AddToRead(TetraDesc(0))!=-1 ) mask |= ply::PLYMask::PM_TETRAINDEX; if( pf.AddToRead(TetraDesc(1))!=-1 ) mask |= ply::PLYMask::PM_TETRAFLAGS; if( pf.AddToRead(TetraDesc(2))!=-1 ) mask |= ply::PLYMask::PM_TETRAQUALITY; //if( pf.AddToRead(TetraDesc(3))!=-1 ) mask |= ply::PLYMask::PM_WEDGTEXCOORD; //if( pf.AddToRead(TetraDesc(5))!=-1 ) mask |= ply::PLYMask::PM_WEDGTEXMULTI; if( pf.AddToRead(TetraDesc(4))!=-1 ) mask |= ply::PLYMask::PM_WEDGCOLOR; if( ( pf.AddToRead(TetraDesc(6))!=-1 ) && ( pf.AddToRead(TetraDesc(7))!=-1 ) && ( pf.AddToRead(TetraDesc(8))!=-1 ) ) mask |= ply::PLYMask::PM_TETRACOLOR; return true; } }; // end class } // end namespace tri } // end namespace io } // end namespace vcg #endif