/**************************************************************************** * 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 $ ****************************************************************************/ #ifndef __VCGLIB_TETRAIMPORTERPLY #define __VCGLIB_TETRAIMPORTERPLY #include #include #include #include #include namespace vcg { namespace tetra { namespace io { template int PlyType () { return 0;} template <> int PlyType () { return ply::T_FLOAT; } template <> int PlyType () { return ply::T_DOUBLE; } template <> int PlyType () { return ply::T_INT; } template <> int PlyType () { return ply::T_SHORT; } template <> int PlyType () { return ply::T_UCHAR; } /** This class encapsulate a filter for opening ply meshes. The ply file format is quite extensible... */ template 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 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 tcoord[32]; unsigned char ntcoord; int tcoordind; 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 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(),offsetof(LoadPly_VertAux,p[0]),0,0,0,0,0}, {"vertex", "y", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p[1]),0,0,0,0,0}, {"vertex", "z", ply::T_FLOAT, PlyType(),offsetof(LoadPly_VertAux,p[2]),0,0,0,0,0}, {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux,flags),0,0,0,0,0}, {"vertex", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,q),0,0,0,0,0}, {"vertex", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,r),0,0,0,0,0}, {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,g),0,0,0,0,0}, {"vertex", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux,b),0,0,0,0,0}, {"vertex", "confidence",ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_VertAux,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,tcoord), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ntcoord) }, {"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,tcoordind), 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 index; LoadPly_TetraAux fa; // LoadPly_TristripAux tsa; LoadPly_VertAux 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 VPV(pi.vdn); // property descriptor relative al tipo LoadPly_VertexAux vector 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,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 MAX_USER_DATA) { pi.status = vcg::ply::E_BADTYPE; return -1; } } /**************************************************************/ /* Main Reading Loop */ /**************************************************************/ m.Clear(); for(int i=0;i::AddVertices(m,n); for(j=0;j::AddTetra(m,n); pf.SetCurElement(i); for(j=0;j=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=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;j32 && 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;i32 && 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