diff --git a/wrap/callback.h b/wrap/callback.h new file mode 100644 index 00000000..8bbd087c --- /dev/null +++ b/wrap/callback.h @@ -0,0 +1,46 @@ +/**************************************************************************** +* 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_CALLBACK +#define __VCGLIB_CALLBACK + +namespace vcg { +// Generic Callback function: +// Used to make algorithms interumpable +// Return value: true continue, false break +// The second callback is to know where we are (useful for progress bar) +typedef bool CallBack( const char * str ); +typedef bool CallBackPos(const int pos, const char * str ); + +inline bool DummyCallBack( const char * ) {return true;} +inline bool DummyCallBackPos(const int pos, const char * ) {return true;} + +} // End namespace + + +#endif \ No newline at end of file diff --git a/wrap/io_trimesh/import_ply.h b/wrap/io_trimesh/import_ply.h new file mode 100644 index 00000000..edd3ef5d --- /dev/null +++ b/wrap/io_trimesh/import_ply.h @@ -0,0 +1,851 @@ +/**************************************************************************** +* 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 $ +****************************************************************************/ + +/** +@name Load and Save in Ply format +*/ +//@{ +#include +#include +#include + + +namespace vcg { +namespace tri { +namespace io { + +template +int PlyType () { return 0;} + +//template +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; } + +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::FaceType FaceType; +typedef typename OpenMeshType::VertexIterator VertexIterator; +typedef typename OpenMeshType::FaceIterator FaceIterator; + +class PlyInfo +{ +public: + PlyInfo() + { + status=0; + mask=0; + cb=0; + vdn=fdn=0; + VertexData=FaceData=0; + } + int status; + int mask; // it overwritten by Open and used by Save + CallBackPos *cb; + + int vdn; + PropDescriptor *VertexData; + int fdn; + PropDescriptor *FaceData; + std::string header; +}; + +enum Error +{ + + // Funzioni superiori + E_NO_VERTEX, // 14 + E_NO_FACE, // 15 + E_SHORTFILE, // 16 + E_NO_3VERTINFACE, // 17 + E_BAD_VERT_INDEX, // 18 + E_NO_6TCOORD, // 19 + E_DIFFER_COLORS, // 20 +}; + +//template int PlyType () { assert(0); return 0;} + +// Si occupa di convertire da un tipo all'altro. +// usata nella saveply per matchare i tipi tra stotype e memtype. +// Ad es se in memoria c'e' un int e voglio salvare un float +// src sara in effetti un puntatore a int il cui valore deve +// essere convertito al tipo di ritorno desiderato (stotype) + +template +void PlyConv(int mem_type, void *src, StoType &dest) +{ +// float tf; int ti;short ts; char tc; + switch (mem_type){ + case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break; + case T_DOUBLE : dest = (StoType) (* ((double *) src)); break; + case T_INT : dest = (StoType) (* ((int *) src)); break; + case T_SHORT : dest = (StoType) (* ((short *) src)); break; + case T_CHAR : dest = (StoType) (* ((char *) src)); break; + case T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break; + default : assert(0); + } +} +#define MAX_USER_DATA 256 +// Struttura ausiliaria per la lettura del file ply +struct LoadPly_FaceAux +{ + 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 &FaceDesc(int i) +{ + const static PropDescriptor qf[10]= + { + {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_FaceAux,size) }, + {"face", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,flags), 0,0,0,0,0}, + {"face", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,q), 0,0,0,0,0}, + {"face", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,tcoord), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_FaceAux,ntcoord) }, + {"face", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,colors), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_FaceAux,ncolors) }, + {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,tcoordind), 0,0,0,0,0}, + {"face", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,r), 0,0,0,0,0}, + {"face", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,g), 0,0,0,0,0}, + {"face", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0}, + {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR,ply::T_CHAR,offsetof(LoadPly_FaceAux,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]; +} + + + +static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0) +{ + PlyInfo pi; + pi.cb=cb; + return Open(m, filename, pi); +} + +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; +} + + +static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi ) +{ + assert(filename!=0); + vector index; + LoadPly_FaceAux 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); + + FaceType 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 |= PLYMask::PM_CAMERA; + } + + // Descrittori dati standard (vertex coord e faces) + if( pf.AddToRead(VertDesc(0))==-1 ) { pi.status = E_NO_VERTEX; return -1; } + if( pf.AddToRead(VertDesc(1))==-1 ) { pi.status = E_NO_VERTEX; return -1; } + if( pf.AddToRead(VertDesc(2))==-1 ) { pi.status = E_NO_VERTEX; return -1; } + if( pf.AddToRead(FaceDesc(0))==-1 ) // Se fallisce si prova anche la sintassi di rapidform con index al posto di indices + if( pf.AddToRead(FaceDesc(9))==-1 ) + if(pf.AddToRead(TristripDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono tristrip alla levoy. + { pi.status = E_NO_FACE; return -1; } + + // Descrittori facoltativi dei flags + if( pf.AddToRead(VertDesc(3))!=-1 ) + pi.mask |= PLYMask::PM_VERTFLAGS; + + if( VertexType::HasQuality() ) + { + if( pf.AddToRead(VertDesc(4))!=-1 || + pf.AddToRead(VertDesc(8))!=-1 ) + pi.mask |= PLYMask::PM_VERTQUALITY; + } + + if( VertexType::HasColor() ) + { + if( pf.AddToRead(VertDesc(5))!=-1 ) + { + pf.AddToRead(VertDesc(6)); + pf.AddToRead(VertDesc(7)); + pi.mask |= PLYMask::PM_VERTCOLOR; + } + } + + // se ci sono i flag per vertice ci devono essere anche i flag per faccia + if( pf.AddToRead(FaceDesc(1))!=-1 ) + pi.mask |= PLYMask::PM_FACEFLAGS; + + if( FaceType::HasFaceQuality()) + { + if( pf.AddToRead(FaceDesc(2))!=-1 ) + pi.mask |= PLYMask::PM_FACEQUALITY; + } + + if( FaceType::HasFaceColor() ) + { + if( pf.AddToRead(FaceDesc(6))!=-1 ) + { + pf.AddToRead(FaceDesc(7)); + pf.AddToRead(FaceDesc(8)); + pi.mask |= PLYMask::PM_FACECOLOR; + } + } + + + if( FaceType::HasWedgeTexture() ) + { + if( pf.AddToRead(FaceDesc(3))!=-1 ) + { + if(pf.AddToRead(FaceDesc(5))==0) { + multit=true; // try to read also the multi texture indicies + pi.mask |= PLYMask::PM_WEDGTEXMULTI; + } + pi.mask |= PLYMask::PM_WEDGTEXCOORD; + } + } + + if( FaceType::HasWedgeColor() || FaceType::HasFaceColor() || VertexType::HasColor()) + { + if( pf.AddToRead(FaceDesc(4))!=-1 ) + { + pi.mask |= 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::AddFaces(m,n); + pf.SetCurElement(i); + + for(j=0;j=m.vn ) + { + pi.status = E_BAD_VERT_INDEX; + return -1; + } + (*fi).V(k) = index[ fa.v[k] ]; + } + + if( pi.mask & PLYMask::PM_FACEFLAGS ) + { + (*fi).UberFlags() = fa.flags; + } + + if( pi.mask & PLYMask::PM_FACEQUALITY ) + { + (*fi).Q() = fa.q; + } + + if( pi.mask & PLYMask::PM_FACECOLOR ) + { + (*fi).C()[0] = fa.r; + (*fi).C()[1] = fa.g; + (*fi).C()[2] = fa.b; + (*fi).C()[3] = 255; + } + + if( pi.mask & PLYMask::PM_WEDGTEXCOORD ) + { + for(int k=0;k<3;++k) + { + (*fi).WT(k).u() = fa.tcoord[k*2+0]; + (*fi).WT(k).v() = fa.tcoord[k*2+1]; + if(multit) (*fi).WT(k).n() = fa.tcoordind; + } + } + + if( pi.mask & PLYMask::PM_WEDGCOLOR ) + { + if(FaceType::HasWedgeColor()){ + for(int k=0;k<3;++k) + { + (*fi).WC(k)[0] = (unsigned char)(fa.colors[k*3+0]*255); + (*fi).WC(k)[1] = (unsigned char)(fa.colors[k*3+1]*255); + (*fi).WC(k)[2] = (unsigned char)(fa.colors[k*3+2]*255); + } + } + if(FaceType::HasFaceColor()){ + { + (*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 = 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.fn = 0; + FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi) + if( ! (*fi).IsD() ) + ++m.fn; + + return 0; +} + + + // Caricamento camera da un ply +int LoadCamera(const char * filename) +{ + PlyFile pf; + if( pf.Open(filename,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 +#include + +namespace vcg { +namespace tri { +namespace io { + + +class PLYMask +{ +public: + + /* + Bitmask for specifying what data has to be loaded or saved or it is present in a given plyfile; +*/ + +enum { + PM_NONE = 0x0000, + + PM_VERTCOORD = 0x0001, + PM_VERTFLAGS = 0x0002, + PM_VERTCOLOR = 0x0004, + PM_VERTQUALITY = 0x0008, + PM_VERTNORMAL = 0x0010, + PM_VERTTEXCOORD = 0x0020, + + PM_FACEINDEX = 0x0040, + PM_FACEFLAGS = 0x0080, + PM_FACECOLOR = 0x0100, + PM_FACEQUALITY = 0x0200, + PM_FACENORMAL = 0x0400, + PM_WEDGCOLOR = 0x0800, + PM_WEDGTEXCOORD = 0x1000, + PM_WEDGTEXMULTI = 0x2000, // Se ha anche l'indice di texture esplicito + PM_WEDGNORMAL = 0x4000, + + PM_CAMERA = 0x8000, + + PM_FLAGS = PM_VERTFLAGS + PM_FACEFLAGS, + + PM_ALL = 0xFFFF +}; + + +static void SMFlags2String( int mask, char str[] ) +{ + str[0] = 0; + + strcat(str,"V:"); + if( mask & PM_VERTFLAGS ) strcat(str,"flag,"); + if( mask & PM_VERTCOLOR ) strcat(str,"color,"); + if( mask & PM_VERTQUALITY ) strcat(str,"quality,"); + if( mask & PM_VERTTEXCOORD ) strcat(str,"tcoord,"); + if( mask & PM_VERTNORMAL ) strcat(str,"normal,"); + + strcat(str," F:"); + if( mask & PM_FACEFLAGS ) strcat(str,"mask,"); + if( mask & PM_FACECOLOR ) strcat(str,"color,"); + if( mask & PM_FACEQUALITY ) strcat(str,"quality,"); + if( mask & PM_FACENORMAL ) strcat(str,"normal,"); + + strcat(str," W:"); + if( mask & PM_WEDGCOLOR ) strcat(str,"color,"); + if( mask & PM_WEDGTEXCOORD ) strcat(str,"tcoord,"); + if( mask & PM_WEDGNORMAL ) strcat(str,"normal,"); + + if( mask & PM_CAMERA ) strcat(str," camera"); +} + +}; // end class +} // end namespace tri +} // end namespace io +} // end namespace vcg diff --git a/wrap/ply/plylib.cpp b/wrap/ply/plylib.cpp new file mode 100644 index 00000000..d60aedba --- /dev/null +++ b/wrap/ply/plylib.cpp @@ -0,0 +1,3617 @@ +/**************************************************************************** +* 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. * +* * +****************************************************************************/ +/**************************************************************************** +Acknowlegments +Portions of this file were based on the original code of the Ply library +of Greg Turk and on the work of Claudio Rocchini + +****************************************************************************/ + +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +****************************************************************************/ + + + +#ifdef WIN32 +#define LITTLE_MACHINE +#define assert ASSERT +#pragma warning( disable : 4267 ) +#else +#include +#endif + +#ifdef WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "plylib.h" +using namespace std; +namespace vcg{ + namespace ply{ +typedef unsigned short ushort; +typedef unsigned long ulong; +typedef unsigned char uchar; +typedef unsigned int uint; + +//#ifdef USE_ZLIB +//#include +//#define XFILE void +//#define pb_fclose gzclose +//#define pb_fopen gzopen +//#define pb_fgets(s,n,f) gzgets(f,s,n) +//#define pb_fread(b,s,n,f) gzread(f,b,(s)*(n)) +//#else +#define XFILE FILE +#define pb_fclose fclose +#define pb_fopen fopen +#define pb_fgets(s,n,f) fgets(s,n,f) +#define pb_fread(b,s,n,f) fread(b,s,n,f) +//#endif + +//#ifdef WIN32 + +#define pb_mkdir(n) _mkdir(n) +#define pb_access _access +#define pb_stat _stat +#define pb_open _open +#define pb_close _close + +/* +#else + +#define pb_mkdir(n) mkdir(n,0) +#define pb_access access +#define pb_stat stat +#define pb_open open +#define pb_close close + +#endif +*/ + // Stringhe per la cache +const char * cachedir = "vcg_cache"; +const char * bboxcacheext = ".bbox_cache"; +const char * bboxheader = "BBOXCACH"; + +const char * ply_error_msg[] = +{ + "No errors", + "Can't open file", + "Header not found", + "Eof in header", + "Format not found", + "Syntax error on header", + "Property without element", + "Bad type name", + "Element not found", + "Property not found", + "Bad type on addtoread", + "Incompatible type", + "Bad cast", + "No vertex field found", + "No face field found", + "Unespected eof", + "Face with more than 3 vertices", + "Bad vertex index in face", + "Face with no 6 texture coordinates", + "Number of color differ from vertices" +}; + + + + // Funzioni statiche per la lettura di un elemento +int ReadBin ( XFILE * fp, const PlyProperty * pr, void * mem, int fmt ); +int ReadAscii( XFILE * fp, const PlyProperty * pr, void * mem, int fmt ); + + + const char * ::vcg::ply::PlyFile::typenames[9]= +{ + "none", + "char", + "short", + "int", + "uchar", + "ushort", + "uint", + "float", + "double" +}; +const char * PlyFile::newtypenames[9]= +{ + "none", + "int8", + "int16", + "int32", + "uint8", + "uint16", + "uint32", + "float32", + "float64" +}; + +static int TypeSize[] = { + 0, 1, 2, 4, 1, 2, 4, 4, 8 +}; + +size_t PropDescriptor::memtypesize() const {return TypeSize[memtype1];} +size_t PropDescriptor::stotypesize() const {return TypeSize[stotype1];} +const char *PropDescriptor::memtypename() const {return PlyFile::typenames[memtype1];} +const char *PropDescriptor::stotypename() const {return PlyFile::typenames[stotype1];} + +static char CrossType[9][9]= +{ + {0,0,0,0,0,0,0,0,0}, + {0,1,1,1,1,1,1,0,0}, + {0,0,1,1,0,1,1,0,0}, + {0,0,0,1,0,0,1,0,0}, + {0,1,1,1,1,1,1,0,0}, + {0,0,1,1,0,1,1,0,0}, + {0,0,0,1,0,0,1,0,0}, + {0,0,0,0,0,0,0,1,1}, + {0,0,0,0,0,0,0,1,1} +}; + +// ****************************************************** + // Funzioni di supporto per la lettura/scrittura dei dati + // ****************************************************** + + // Big-little endian + +static inline void SwapShort( ushort * s ) +{ + assert(s); + *s = ushort( (int(*s)>>8) | (int(*s)<<8) ); +} + + +static inline void SwapInt( uint * x ) +{ + assert(x); + *x = + ( ((*x)>>24) & 0x000000FF ) | + ( ((*x)>> 8) & 0x0000FF00 ) | + ( ((*x)<< 8) & 0x00FF0000 ) | + ( ((*x)<<24) & 0xFF000000 ) ; +} + + +static inline void SwapDouble( double * /*d*/ ) +{ + // Come si fa? + assert(0); +} + + + // Lettura tipi binari + +static inline int ReadCharB( XFILE * fp, char * c, int /*format*/ ) +{ + assert(fp); + assert(c); + + return pb_fread(c,1,1,fp); +} + + +static inline int ReadShortB( XFILE * fp, short * s, int format ) +{ + assert(fp); + assert(s); + + int r; + r = pb_fread(s,sizeof(short),1,fp); + +#ifdef LITTLE_MACHINE + if(format==F_BINBIG) +#else + if(format==F_BINLITTLE) +#endif + SwapShort((ushort *)s); + + return r; +} + + +static inline int ReadIntB( XFILE * fp, int * i, int format ) +{ + assert(fp); + assert(i); + + int r; + r = pb_fread(i,sizeof(int),1,fp); + +#ifdef LITTLE_MACHINE + if(format==F_BINBIG) +#else + if(format==F_BINLITTLE) +#endif + SwapInt((uint *)i); + + return r; +} + + +static inline int ReadUCharB( XFILE * fp, uchar * uc, int /*format*/ ) +{ + assert(fp); + assert(uc); + + return pb_fread(uc,1,1,fp); +} + + +static inline int ReadUShortB( XFILE * fp, ushort * us, int format ) +{ + assert(fp); + assert(us); + + int r; + r = pb_fread(us,sizeof(ushort),1,fp); + +#ifdef LITTLE_MACHINE + if(format==F_BINBIG) +#else + if(format==F_BINLITTLE) +#endif + SwapShort(us); + + return r; +} + + +static inline int ReadUIntB( XFILE * fp, uint * ui, int format ) +{ + assert(fp); + assert(ui); + + int r; + r = pb_fread(ui,sizeof(uint),1,fp); + +#ifdef LITTLE_MACHINE + if(format==F_BINBIG) +#else + if(format==F_BINLITTLE) +#endif + SwapInt(ui); + + return r; +} + + +static inline int ReadFloatB( XFILE * fp, float * f, int format ) +{ + assert(fp); + assert(f); + + int r; + r = pb_fread(f,sizeof(float),1,fp); + +#ifdef LITTLE_MACHINE + if(format==F_BINBIG) +#else + if(format==F_BINLITTLE) +#endif + SwapInt((uint *)f); + + return r; +} + + +static inline int ReadDoubleB( XFILE * fp, double * d, int format ) +{ + assert(fp); + assert(d); + + int r; + r = pb_fread(d,sizeof(double),1,fp); + +#ifdef LITTLE_MACHINE + if(format==F_BINBIG) +#else + if(format==F_BINLITTLE) +#endif + SwapDouble(d); + + return r; +} + + // --- simulazione di scanf ------ + +//static bool sbuffer_ok = false; +//static const int SBUFFERSIZE = 4096; +//static char sbuffer[SBUFFERSIZE]; +//static const char * separators = " \t,\n\r\f"; + +static void InitSBuffer() +{ + //sbuffer_ok = false; +} + +static inline int ReadInt( XFILE * fp, int & t ) +{ + /* + char * p; + + if(!sbuffer_ok) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + sbuffer_ok = true; + } + else p = strtok(0,separators); + + if(p==0) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + } + + t = atoi(p); + return 1; + */ + int r = fscanf(fp,"%d",&t); + if(r==EOF) r = 0; + return r; +} + + +static inline int ReadUInt( XFILE * fp, unsigned int & t ) +{ + /* + char * p; + + if(!sbuffer_ok) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + sbuffer_ok = true; + } + else p = strtok(0,separators); + + if(p==0) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + } + + t = atoi(p); + return 1; + */ + int r = fscanf(fp,"%u",&t); + if(r==EOF) r = 0; + return r; +} + + +static inline int ReadFloat( XFILE * fp, float & f ) +{ + /* + char * p; + + if(!sbuffer_ok) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + sbuffer_ok = true; + } + else p = strtok(0,separators); + + if(p==0) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + } + + f = atof(p); + return 1; + */ + int r = fscanf(fp,"%f",&f); + if(r==EOF) r = 0; + return r; +} + +static inline int ReadDouble( XFILE * fp, double & d ) +{ + /* + char * p; + + if(!sbuffer_ok) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + sbuffer_ok = true; + } + else p = strtok(0,separators); + + if(p==0) + { + pb_fgets(sbuffer,SBUFFERSIZE,fp); + p = strtok(sbuffer,separators); + } + + d = atof(p); + return 1; + */ + int r = fscanf(fp,"%lf",&d); + if(r==EOF) r = 0; + return r; +} + + + // Lettura tipi ascii + +static inline int ReadCharA( XFILE * fp, char * c ) +{ + assert(fp); + assert(c); + + int r,t; + r = ReadInt(fp,t); + *c = (char)t; + return r; +} + + +static inline int ReadShortA( XFILE * fp, short * s ) +{ + assert(fp); + assert(s); + + int r,t; + r = ReadInt(fp,t); + *s = (short)t; + return r; +} + + +static inline int ReadIntA( XFILE * fp, int * i ) +{ + assert(fp); + assert(i); + + return ReadInt(fp,*i); +} + +static inline int ReadUCharA( XFILE * fp, uchar * uc ) +{ + assert(fp); + assert(uc); + + int r; + uint t; + r = ReadUInt(fp,t); + *uc = (uchar)t; + return r; +} + + +static inline int ReadUShortA( XFILE * fp, ushort * us ) +{ + assert(fp); + assert(us); + + int r; + uint t; + r = ReadUInt(fp,t); + *us = (ushort)t; + return r; +} + + +static inline int ReadUIntA( XFILE * fp, uint * ui ) +{ + assert(fp); + assert(ui); + + return ReadUInt(fp,*ui); +} + +static inline int ReadFloatA( XFILE * fp, float * f ) +{ + assert(fp); + assert(f); + + return ReadFloat(fp,*f); +} + + +static inline int ReadDoubleA( XFILE * fp, double * d ) +{ + assert(fp); + assert(d); + + return ReadDouble(fp,*d); +} + + + + // Memorizza il valore val nella variabile mem di tipo tm + +static inline void StoreInt( void * mem, const int tm, const int val ) +{ + assert(mem); + + switch(tm) + { + case T_CHAR: *(char *)mem = (char )val; break; + case T_SHORT: *(short *)mem = (short )val; break; + case T_INT: *(int *)mem = (int )val; break; + case T_UCHAR: *(uchar *)mem = (uchar )val; break; + case T_USHORT: *(ushort *)mem = (ushort)val; break; + case T_UINT: *(uint *)mem = (uint )val; break; + case T_FLOAT: *(float *)mem = (float )val; break; + case T_DOUBLE: *(double *)mem = (double)val; break; + default: assert(0); + } +} + + // Salta un valore nel file + +static inline int SkipScalarA( XFILE * fp, const int tf ) +{ + int t; + float f; + + assert(fp); + + switch(tf) + { + case T_CHAR: + case T_SHORT: + case T_INT: + case T_UCHAR: + case T_USHORT: + case T_UINT: + return ReadInt(fp,t); + case T_FLOAT: + case T_DOUBLE: + return ReadFloat(fp,f); + default: + assert(0); + return 0; + } +} + + + +static inline int SkipScalarB( XFILE * fp, const int tf) +{ + static char dummy[8]; + + assert(fp); + return pb_fread(dummy,1,TypeSize[tf],fp); +} + +static int ReadScalarB( XFILE * fp, void * mem, const int tf, const int tm, int fmt ) +{ + static char ch; + static short sh; + static int in; + static uchar uc; + static ushort us; + static uint ui; + static float fl; + static double dd; + + int r = 0; + + switch(tf) + { + case T_CHAR: //================== Lettura char + r = ReadCharB(fp,&ch,fmt); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )ch; break; + case T_SHORT: *(short *)mem = (short )ch; break; + case T_INT: *(int *)mem = (int )ch; break; + case T_UCHAR: *(uchar *)mem = (uchar )ch; break; + case T_USHORT: *(ushort *)mem = (ushort)ch; break; + case T_UINT: *(uint *)mem = (uint )ch; break; + case T_FLOAT: *(float *)mem = (float )ch; break; + case T_DOUBLE: *(double *)mem = (double)ch; break; + default: assert(0); + } + break; + case T_SHORT: //================== Lettura short + r = ReadShortB(fp,&sh,fmt); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )sh; break; + case T_SHORT: *(short *)mem = (short )sh; break; + case T_INT: *(int *)mem = (int )sh; break; + case T_UCHAR: *(uchar *)mem = (uchar )sh; break; + case T_USHORT: *(ushort *)mem = (ushort)sh; break; + case T_UINT: *(uint *)mem = (uint )sh; break; + case T_FLOAT: *(float *)mem = (float )sh; break; + case T_DOUBLE: *(double *)mem = (double)sh; break; + default: assert(0); + } + break; + case T_INT: //================== Lettura int + r = ReadIntB(fp,&in,fmt); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )in; break; + case T_SHORT: *(short *)mem = (short )in; break; + case T_INT: *(int *)mem = (int )in; break; + case T_UCHAR: *(uchar *)mem = (uchar )in; break; + case T_USHORT: *(ushort *)mem = (ushort)in; break; + case T_UINT: *(uint *)mem = (uint )in; break; + case T_FLOAT: *(float *)mem = (float )in; break; + case T_DOUBLE: *(double *)mem = (double)in; break; + default: assert(0); + } + break; + case T_UCHAR: //================== Lettura uchar + r = ReadUCharB(fp,&uc,fmt); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )uc; break; + case T_SHORT: *(short *)mem = (short )uc; break; + case T_INT: *(int *)mem = (int )uc; break; + case T_UCHAR: *(uchar *)mem = (uchar )uc; break; + case T_USHORT: *(ushort *)mem = (ushort)uc; break; + case T_UINT: *(uint *)mem = (uint )uc; break; + case T_FLOAT: *(float *)mem = (float )uc; break; + case T_DOUBLE: *(double *)mem = (double)uc; break; + default: assert(0); + } + break; + case T_USHORT: //================== Lettura ushort + r = ReadUShortB(fp,&us,fmt); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )us; break; + case T_SHORT: *(short *)mem = (short )us; break; + case T_INT: *(int *)mem = (int )us; break; + case T_UCHAR: *(uchar *)mem = (uchar )us; break; + case T_USHORT: *(ushort *)mem = (ushort)us; break; + case T_UINT: *(uint *)mem = (uint )us; break; + case T_FLOAT: *(float *)mem = (float )us; break; + case T_DOUBLE: *(double *)mem = (double)us; break; + default: assert(0); + } + break; + case T_UINT: //================== Lettura uint + r = ReadUIntB(fp,&ui,fmt); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )ui; break; + case T_SHORT: *(short *)mem = (short )ui; break; + case T_INT: *(int *)mem = (int )ui; break; + case T_UCHAR: *(uchar *)mem = (uchar )ui; break; + case T_USHORT: *(ushort *)mem = (ushort)ui; break; + case T_UINT: *(uint *)mem = (uint )ui; break; + case T_FLOAT: *(float *)mem = (float )ui; break; + case T_DOUBLE: *(double *)mem = (double)ui; break; + default: assert(0); + } + break; + case T_FLOAT: //================== Lettura float + r = ReadFloatB(fp,&fl,fmt); + switch(tm) + { + case T_FLOAT: *(float *)mem = fl; break; + case T_DOUBLE: *(double *)mem = fl; break; + default: assert(0); + } + break; + case T_DOUBLE: //================== Lettura double + r = ReadDoubleB(fp,&dd,fmt); + switch(tm) + { + case T_FLOAT: *(float *)mem = (float)dd; break; + case T_DOUBLE: *(double *)mem = dd; break; + default: assert(0); + } + break; + default: + assert(0); + } + + return r; +} + + // Legge un valore di tipo tf e lo memorizza col tipo tm + +static int ReadScalarA( XFILE * fp, void * mem, const int tf, const int tm ) +{ + static char ch; + static short sh; + static int in; + static uchar uc; + static ushort us; + static uint ui; + static float fl; + static double dd; + + int r = 0; + + switch(tf) + { + case T_CHAR: //================== Lettura char + r = ReadCharA(fp,&ch); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )ch; break; + case T_SHORT: *(short *)mem = (short )ch; break; + case T_INT: *(int *)mem = (int )ch; break; + case T_UCHAR: *(uchar *)mem = (uchar )ch; break; + case T_USHORT: *(ushort *)mem = (ushort)ch; break; + case T_UINT: *(uint *)mem = (uint )ch; break; + case T_FLOAT: *(float *)mem = (float )ch; break; + case T_DOUBLE: *(double *)mem = (double)ch; break; + default: assert(0); + } + break; + case T_SHORT: //================== Lettura short + r = ReadShortA(fp,&sh); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )sh; break; + case T_SHORT: *(short *)mem = (short )sh; break; + case T_INT: *(int *)mem = (int )sh; break; + case T_UCHAR: *(uchar *)mem = (uchar )sh; break; + case T_USHORT: *(ushort *)mem = (ushort)sh; break; + case T_UINT: *(uint *)mem = (uint )sh; break; + case T_FLOAT: *(float *)mem = (float )sh; break; + case T_DOUBLE: *(double *)mem = (double)sh; break; + default: assert(0); + } + break; + case T_INT: //================== Lettura int + r = ReadIntA(fp,&in); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )in; break; + case T_SHORT: *(short *)mem = (short )in; break; + case T_INT: *(int *)mem = (int )in; break; + case T_UCHAR: *(uchar *)mem = (uchar )in; break; + case T_USHORT: *(ushort *)mem = (ushort)in; break; + case T_UINT: *(uint *)mem = (uint )in; break; + case T_FLOAT: *(float *)mem = (float )in; break; + case T_DOUBLE: *(double *)mem = (double)in; break; + default: assert(0); + } + break; + case T_UCHAR: //================== Lettura uchar + r = ReadUCharA(fp,&uc); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )uc; break; + case T_SHORT: *(short *)mem = (short )uc; break; + case T_INT: *(int *)mem = (int )uc; break; + case T_UCHAR: *(uchar *)mem = (uchar )uc; break; + case T_USHORT: *(ushort *)mem = (ushort)uc; break; + case T_UINT: *(uint *)mem = (uint )uc; break; + case T_FLOAT: *(float *)mem = (float )uc; break; + case T_DOUBLE: *(double *)mem = (double)uc; break; + default: assert(0); + } + break; + case T_USHORT: //================== Lettura ushort + r = ReadUShortA(fp,&us); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )us; break; + case T_SHORT: *(short *)mem = (short )us; break; + case T_INT: *(int *)mem = (int )us; break; + case T_UCHAR: *(uchar *)mem = (uchar )us; break; + case T_USHORT: *(ushort *)mem = (ushort)us; break; + case T_UINT: *(uint *)mem = (uint )us; break; + case T_FLOAT: *(float *)mem = (float )us; break; + case T_DOUBLE: *(double *)mem = (double)us; break; + default: assert(0); + } + break; + case T_UINT: //================== Lettura uint + r = ReadUIntA(fp,&ui); + switch(tm) + { + case T_CHAR: *(char *)mem = (char )ui; break; + case T_SHORT: *(short *)mem = (short )ui; break; + case T_INT: *(int *)mem = (int )ui; break; + case T_UCHAR: *(uchar *)mem = (uchar )ui; break; + case T_USHORT: *(ushort *)mem = (ushort)ui; break; + case T_UINT: *(uint *)mem = (uint )ui; break; + case T_FLOAT: *(float *)mem = (float )ui; break; + case T_DOUBLE: *(double *)mem = (double)ui; break; + default: assert(0); + } + break; + case T_FLOAT: //================== Lettura float + r = ReadFloatA(fp,&fl); + switch(tm) + { + case T_FLOAT: *(float *)mem = fl; break; + case T_DOUBLE: *(double *)mem = fl; break; + default: assert(0); + } + break; + case T_DOUBLE: //================== Lettura double + r = ReadDoubleA(fp,&dd); + switch(tm) + { + case T_FLOAT: *(float *)mem = (float)dd; break; + case T_DOUBLE: *(double *)mem = dd; break; + default: assert(0); + } + break; + default: + assert(0); + } + + return r; +} + +//####################### Classe PlyElement + + +void PlyElement::AddProp( const char * na, int ti, int isl, int t2 ) +{ + assert(na); + assert(ti>0); + assert(ti0 || (t2==0 && isl==0)); + assert(t2::iterator i; + + for(i=props.begin();i!=props.end();++i) + if( i->name == na ) + return &*i; + return 0; +} + +int PlyElement::AddToRead( + const char * propname, + int stotype1, + int memtype1, + int offset1, + int islist, + int alloclist, + int stotype2, + int memtype2, + int offset2 + ) // Vedi struttura PropDescriptor +{ + assert(propname); + + PlyProperty * p = FindProp(propname); + if(p==0) + { + return E_PROPNOTFOUND; + } + + if( stotype1<1 || stotype1>=T_MAXTYPE || + memtype1<1 || memtype1>=T_MAXTYPE ) + { + return E_BADTYPE; + } + + if( islist && (stotype2<1 || stotype2>=T_MAXTYPE || + memtype2<1 || memtype2>=T_MAXTYPE ) ) + { + return E_BADTYPE; + } + + if( islist!= p->islista || stotype1 != p->tipo || + ( islist && stotype2!=p->tipoindex) ) + { + return E_INCOMPATIBLETYPE; + } + + if( !CrossType[p->tipo][stotype1] || + (islist && !CrossType[p->tipoindex][stotype2] ) ) + { + return E_BADCAST; + } + + p->bestored = 1; + + p->desc.stotype1 = stotype1; + p->desc.memtype1 = memtype1; + p->desc.offset1 = offset1; + p->desc.islist = islist; + p->desc.alloclist = alloclist; + p->desc.stotype2 = stotype2; + p->desc.memtype2 = memtype2; + p->desc.offset2 = offset2; + + + return E_NOERROR; +} + + + +//####################### Classe PlyFile + +PlyFile::PlyFile( void ) +{ + gzfp = 0; + version = 0.0f; + error = E_NOERROR; + format = F_UNSPECIFIED; + cure = 0; + ReadCB = 0; + InitSBuffer(); +} + +PlyFile::~PlyFile( void ) +{ + Destroy(); +} + +int PlyFile::Open( const char * filename, int mode ) +{ + if(filename==0 || (mode!=MODE_READ && mode!=MODE_WRITE) ) + { + error = E_CANTOPEN; + return -1; + } + if(mode==MODE_READ) + return OpenRead(filename); + else + return OpenWrite(filename); +} + +void PlyFile::Destroy( void ) +{ + if(gzfp!=0) + { + pb_fclose(gzfp); + gzfp = 0; + } + + ReadCB = 0; +} + +int PlyFile::OpenRead( const char * filename ) +{ + // Tokens dell'intestazione + + static const char * SEP = " \t\n\r"; + static const char * HEADER = "ply"; + static const char * FORMAT = "format"; + static const char * TASCII = "ascii"; + static const char * TBINBIG = "binary_big_endian"; + static const char * TBINLITTLE = "binary_little_endian"; + static const char * COMMENT = "comment"; + static const char * OBJ_INFO = "obj_info"; + static const char * ELEMENT = "element"; + static const char * PROPERTY = "property"; + static const char * ENDHEADER = "end_header"; + static const char * LIST = "list"; + + const int MAXB = 512; + char buf[MAXB]; + char * token; + PlyElement * curelement; + + // Predistruzione + + Destroy(); + + // Apertura file + + gzfp = pb_fopen(filename,"rb"); + if(gzfp==0) + { + error = E_CANTOPEN; + goto error; + } + + header[0] = 0; + + // ********* Parsing header *********** + + // Controllo header + if( pb_fgets(buf,MAXB-1,gzfp)==0 ) + { + error = E_UNESPECTEDEOF; + goto error; + } + strcat(header,buf); + if( strncmp(buf,HEADER,strlen(HEADER)) ) + { + error = E_NOTHEADER; + goto error; + } + + + // Lettura tipo e versione + + if( pb_fgets(buf,MAXB-1,gzfp)==0 ) + { + error = E_UNESPECTEDEOF; + goto error; + } + strcat(header,buf); + token = strtok(buf,SEP); + if(token==0) + { + error = E_UNESPECTEDEOF; + goto error; + } + if( strcmp(token,FORMAT) ) + { + error = E_NOFORMAT; + goto error; + } + token = strtok(0,SEP); + if(token==0) + { + error = E_UNESPECTEDEOF; + goto error; + } + if( !strcmp(token,TASCII) ) + format = F_ASCII; + else if( !strcmp(token,TBINBIG) ) + format = F_BINBIG; + else if( !strcmp(token,TBINLITTLE) ) + format = F_BINLITTLE; + else + { + error = E_NOFORMAT; + goto error; + } + token = strtok(0,SEP); + if(token==0) + { + error = E_UNESPECTEDEOF; + goto error; + } + version = float(atof(token)); + + //************* Ciclo lettura elementi **************** + + curelement = 0; + for(;;) + { + if( pb_fgets(buf,MAXB-1,gzfp)==0 ) + { + error = E_UNESPECTEDEOF; + goto error; + } + strcat(header,buf); + + token = strtok(buf,SEP); + if(token==0) + { + error = E_UNESPECTEDEOF; + goto error; + } + + if( !strcmp(token,COMMENT) ) + { + comments.push_back( string(token+strlen(token)+1) ); + //AddComment( token+strlen(token)+1 ); + } + else if( !strcmp(token,OBJ_INFO) ) + { + comments.push_back( string(token+strlen(token)+1) ); + //AddComment( token+strlen(token)+1 ); + } + else if( !strcmp(token,ENDHEADER) ) + { + break; + } + else if( !strcmp(token,ELEMENT) ) + { + // Lettura nome elemento + char * name = strtok(0,SEP); + if(name==0) + { + error = E_SYNTAX; + goto error; + } + // Lettura numero di elementi + token = strtok(0,SEP); + if(name==0) + { + error = E_SYNTAX; + goto error; + } + int number = atoi(token); + + PlyElement t(name,number); + elements.push_back(t); + curelement = &(elements.back()); + } + else if( !strcmp(token,PROPERTY) ) + { + if(curelement==0) + { + error = E_PROPOUTOFELEMENT; + goto error; + } + token = strtok(0,SEP); + if(token==0) + { + error = E_SYNTAX; + goto error; + } + if( !strcmp(token,LIST) ) + { + token = strtok(0,SEP); + if(token==0) + { + error = E_SYNTAX; + goto error; + } + int t2 = FindType(token); + if(t2==-1) + { + error = E_BADTYPENAME; + goto error; + } + token = strtok(0,SEP); + if(token==0) + { + error = E_SYNTAX; + goto error; + } + int t1 = FindType(token); + if(t1==-1) + { + error = E_BADTYPENAME; + goto error; + } + token = strtok(0,SEP); + if(token==0) + { + error = E_SYNTAX; + goto error; + } + //curelement->AddProp(token,t1,1,t2); prima del 5/9/03 era cosi' ma swappava i due tipi. + curelement->AddProp(token,t1,1,t2); + } + else + { + int t1 = FindType(token); + if(t1==-1) + { + error = E_BADTYPENAME; + goto error; + } + token = strtok(0,SEP); + if(token==0) + { + error = E_SYNTAX; + goto error; + } + curelement->AddProp(token,t1,0,T_NOTYPE); + } + } + else + { + error = E_SYNTAX; + goto error; + } + + } + + if(format==F_ASCII) + ReadCB = ReadAscii; + else + ReadCB = ReadBin; + + return 0; + +error: + Destroy(); + return -1; +} + + +int PlyFile::OpenWrite( const char * /*filename*/ ) +{ + // Per ora non implementato + assert(0); + return -1; +} + + +//################# Funzioni di supporto + +int PlyFile::FindType( const char * name ) const +{ + int i; + assert(name); + + for(i=1;i<9;++i) + if( !strcmp(name,typenames[i]) || !strcmp(name,newtypenames[i])) + return i; + return -1; +} + +PlyElement * PlyFile::FindElement( const char * na ) +{ + assert(na); + vector::iterator i; + + for(i=elements.begin();i!=elements.end();++i) + if( i->name == na ) + return &*i; + return 0; +} + +int PlyFile::AddToRead( + const char * elemname, + const char * propname, + int stotype1, + int memtype1, + int offset1, + int islist, + int alloclist, + int stotype2, + int memtype2, + int offset2 + ) // Vedi struttura PropDescriptor +{ + assert(elemname); + PlyElement * e = FindElement(elemname); + if(e==0) + { + error = E_ELEMNOTFOUND; + return -1; + } + + int r = e->AddToRead(propname,stotype1,memtype1,offset1,islist, + alloclist,stotype2,memtype2,offset2 ); + + if(r==E_NOERROR) + return 0; + else + { + error = r; + return -1; + } +} + +const char * PlyFile::ElemName( int i ) +{ + if(i<0 || i>=int(elements.size())) + return 0; + else + return elements[i].name.c_str(); +} + +int PlyFile::ElemNumber( int i ) const +{ + if(i<0 || i>=int(elements.size())) + return 0; + else + return elements[i].number; +} + + // *** callbacks *** + +static bool cb_skip_bin1( GZFILE fp, void * /*mem*/, PropDescriptor * /*d*/ ) +{ + static char dummy[1]; + + assert(fp); + return pb_fread(dummy,1,1,fp)!=0; +} + +static bool cb_skip_bin2( GZFILE fp, void * /*mem*/, PropDescriptor * /*d*/ ) +{ + static char dummy[2]; + + assert(fp); + return pb_fread(dummy,1,2,fp)!=0; +} + +static bool cb_skip_bin4( GZFILE fp, void * /*mem*/, PropDescriptor * /*d*/ ) +{ + static char dummy[4]; + + assert(fp); + return pb_fread(dummy,1,4,fp)!=0; +} + +static bool cb_skip_bin8( GZFILE fp, void * /*mem*/, PropDescriptor * /*d*/ ) +{ + static char dummy[8]; + + assert(fp); + return pb_fread(dummy,1,8,fp)!=0; +} + +static bool cb_skip_float_ascii( GZFILE fp, void * /*mem*/, PropDescriptor * /*d*/ ) +{ + static float dummy; + + assert(fp); + return fscanf(fp,"%f",&dummy)!=EOF; +} + +static bool cb_skip_int_ascii( GZFILE fp, void * /*mem*/, PropDescriptor * /*d*/ ) +{ + static int dummy; + + assert(fp); + return fscanf(fp,"%d",&dummy)!=EOF; +} + + +static bool cb_read_chch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + return pb_fread( ((char *)mem)+d->offset1,1,1,fp)!=0; +} + +static bool cb_read_chsh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(short *)(((char *)mem)+d->offset1) = short(c); + return true; +} + +static bool cb_read_chin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(int *)(((char *)mem)+d->offset1) = int(c); + return true; +} + +static bool cb_read_chuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(uchar *)(((char *)mem)+d->offset1) = uchar(c); + return true; +} + +static bool cb_read_chus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(ushort *)(((char *)mem)+d->offset1) = ushort(c); + return true; +} + +static bool cb_read_chui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(uint *)(((char *)mem)+d->offset1) = uint(c); + return true; +} + +static bool cb_read_chfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_chdo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + char c; + if( pb_fread(&c,1,1,fp)==0) return false; + return true; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + +static bool cb_read_shch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(char *)(((char *)mem)+d->offset1) = char(c); + return true; +} + +static bool cb_read_shsh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(short *)(((char *)mem)+d->offset1) = short(c); + return true; +} + +static bool cb_read_shin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(int *)(((char *)mem)+d->offset1) = int(c); + return true; +} + +static bool cb_read_shuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(uchar *)(((char *)mem)+d->offset1) = uchar(c); + return true; +} + +static bool cb_read_shus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(ushort *)(((char *)mem)+d->offset1) = ushort(c); + return true; +} + +static bool cb_read_shui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(uint *)(((char *)mem)+d->offset1) = uint(c); + return true; +} + +static bool cb_read_shfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_shdo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + short c; if( ReadShortB(fp,&c,d->format)==0) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + + +static bool cb_read_inch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(char *)(((char *)mem)+d->offset1) = char(c); + return true; +} + +static bool cb_read_insh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(short *)(((char *)mem)+d->offset1) = short(c); + return true; +} + +static bool cb_read_inin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(int *)(((char *)mem)+d->offset1) = int(c); + return true; +} + +static bool cb_read_inuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(uchar *)(((char *)mem)+d->offset1) = uchar(c); + return true; +} + +static bool cb_read_inus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(ushort *)(((char *)mem)+d->offset1) = ushort(c); + return true; +} + +static bool cb_read_inui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(uint *)(((char *)mem)+d->offset1) = uint(c); + return true; +} + +static bool cb_read_infl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_indo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + int c; if( ReadIntB(fp,&c,d->format)==0 ) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + +static bool cb_read_ucch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(char *)(((char *)mem)+d->offset1) = char(c); + return true; +} + +static bool cb_read_ucsh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(short *)(((char *)mem)+d->offset1) = short(c); + return true; +} + +static bool cb_read_ucin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(int *)(((char *)mem)+d->offset1) = int(c); + return true; +} + +static bool cb_read_ucuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(uchar *)(((char *)mem)+d->offset1) = uchar(c); + return true; +} + +static bool cb_read_ucus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(ushort *)(((char *)mem)+d->offset1) = ushort(c); + return true; +} + +static bool cb_read_ucui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(uint *)(((char *)mem)+d->offset1) = uint(c); + return true; +} + +static bool cb_read_ucfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_ucdo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar c; if( pb_fread(&c,1,1,fp)==0 ) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + + +static bool cb_read_usch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(char *)(((char *)mem)+d->offset1) = char(c); + return true; +} + +static bool cb_read_ussh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(short *)(((char *)mem)+d->offset1) = short(c); + return true; +} + +static bool cb_read_usin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(int *)(((char *)mem)+d->offset1) = int(c); + return true; +} + +static bool cb_read_usuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(uchar *)(((char *)mem)+d->offset1) = uchar(c); + return true; +} + +static bool cb_read_usus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(ushort *)(((char *)mem)+d->offset1) = ushort(c); + return true; +} + +static bool cb_read_usui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(uint *)(((char *)mem)+d->offset1) = uint(c); + return true; +} + +static bool cb_read_usfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_usdo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + ushort c; if( ReadUShortB(fp,&c,d->format)==0) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + + +static bool cb_read_uich( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(char *)(((char *)mem)+d->offset1) = char(c); + return true; +} + +static bool cb_read_uish( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(short *)(((char *)mem)+d->offset1) = short(c); + return true; +} + +static bool cb_read_uiin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(int *)(((char *)mem)+d->offset1) = int(c); + return true; +} + +static bool cb_read_uiuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(uchar *)(((char *)mem)+d->offset1) = uchar(c); + return true; +} + +static bool cb_read_uius( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(ushort *)(((char *)mem)+d->offset1) = ushort(c); + return true; +} + +static bool cb_read_uiui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(uint *)(((char *)mem)+d->offset1) = uint(c); + return true; +} + +static bool cb_read_uifl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_uido( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uint c; if( ReadUIntB(fp,&c,d->format)==0 ) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + +static bool cb_read_flfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + float c; if( ReadFloatB(fp,&c,d->format)==0 ) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_fldo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + float c; if( ReadFloatB(fp,&c,d->format)==0 ) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + +static bool cb_read_dofl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + double c; if( ReadDoubleB(fp,&c,d->format)==0 ) return false; + + *(float *)(((char *)mem)+d->offset1) = float(c); + return true; +} + +static bool cb_read_dodo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + double c; if( ReadDoubleB(fp,&c,d->format)==0 ) return false; + + *(double *)(((char *)mem)+d->offset1) = double(c); + return true; +} + + + // NON OTTIMIZZATO!! +static bool cb_read_ascii( GZFILE fp, void * mem, PropDescriptor * d ) +{ + return ReadScalarA(fp, ((char *)mem)+d->offset1, d->stotype1, d->memtype1)!=0; +} + + +const int SKIP_MAX_BUF = 512; +static char skip_buf[SKIP_MAX_BUF]; + +static bool cb_skip_list_bin1( GZFILE fp, void * /*mem*/, PropDescriptor * d ) +{ + uchar n; + // Solo indici uchar + if( pb_fread(&n,1,1,fp)==0 ) return false; + + if( pb_fread(skip_buf,1,n,fp)==0) return false; + return true; +} + +static bool cb_skip_list_bin2( GZFILE fp, void * /*mem*/, PropDescriptor * d ) +{ + uchar n; + // Solo indici uchar + if( pb_fread(&n,1,1,fp)==0 ) return false; + + if( pb_fread(skip_buf,2,n,fp)==0) return false; + return true; +} + +static bool cb_skip_list_bin4( GZFILE fp, void * /*mem*/, PropDescriptor * d ) +{ + uchar n; + // Solo indici uchar + if( pb_fread(&n,1,1,fp)==0 ) return false; + + if( pb_fread(skip_buf,4,n,fp)==0) return false; + return true; +} + +static bool cb_skip_list_bin8( GZFILE fp, void * /*mem*/, PropDescriptor * d ) +{ + uchar n; + // Solo indici uchar + if( pb_fread(&n,1,1,fp)==0 ) return false; + + if( pb_fread(skip_buf,8,n,fp)==0) return false; + return true; +} + +static bool cb_skip_list_ascii ( GZFILE fp, void * /*mem*/, PropDescriptor * d ) +{ + int i,n; + + if( !ReadScalarA(fp,&n,T_INT, T_INT) )return false; + for(i=0;ioffset2, d->memtype2, n); + // Determinazione memoria vettore + if(d->alloclist) + { + store = (char *)calloc(n,TypeSize[d->memtype1]); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + { + store = ((char *)mem)+d->offset1; + } + + for(i=0;imemtype1], + d->stotype1, + d->memtype1 + ) ) + return 0; + } + return true; +} +// + + +static bool cb_read_list_chch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(char)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(short)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(int)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uchar)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(ushort)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uint)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(char)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(char *)(store+i*sizeof(char)) = char(c); + } + return true; +} + +static bool cb_read_list_shsh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(short)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(short *)(store+i*sizeof(short)) = short(c); + } + return true; +} + +static bool cb_read_list_shin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(int)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(int *)(store+i*sizeof(int)) = int(c); + } + return true; +} + +static bool cb_read_list_shuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uchar)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(uchar *)(store+i*sizeof(uchar)) = uchar(c); + } + return true; +} + +static bool cb_read_list_shus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(ushort)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(ushort *)(store+i*sizeof(ushort)) = ushort(c); + } + return true; +} + +static bool cb_read_list_shui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uint)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(uint *)(store+i*sizeof(uint)) = uint(c); + } + return true; +} + +static bool cb_read_list_shfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(float *)(store+i*sizeof(float)) = float(c); + } + return true; +} + +static bool cb_read_list_shdo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(double *)(store+i*sizeof(double)) = double(c); + } + return true; +} + + + + +static bool cb_read_list_inch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(char)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(char *)(store+i*sizeof(char)) = char(c); + } + return true; +} + +static bool cb_read_list_insh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(short)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(short *)(store+i*sizeof(short)) = short(c); + } + return true; +} + +static bool cb_read_list_inin( GZFILE fp, void * mem, PropDescriptor * d ) +{ +// uchar n,i; prima del 5/9/03 era cosi' +// if( pb_fread(&n,1,1,fp)==0 ) return false; + int n,i; + switch(d->stotype2) + { + case T_CHAR : { char val; if( ReadCharB(fp,&val,d->format)==0 ) return false; n=val; } break; + case T_UCHAR : { uchar val; if( ReadUCharB(fp,&val,d->format)==0 ) return false; n=val; } break; + case T_SHORT : { short val; if( ReadShortB(fp,&val,d->format)==0 ) return false; n=val; } break; + case T_UINT : { uint val; if( ReadUIntB(fp,&val,d->format)==0 ) return false; n=val; } break; + case T_INT : { int val; if( ReadIntB(fp,&val,d->format)==0 ) return false; n=val; } break; + default: assert(0); + } + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(int)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + } + return true; +} + +static bool cb_read_list_inuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uchar)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(uchar *)(store+i*sizeof(uchar)) = uchar(c); + } + return true; +} + +static bool cb_read_list_inus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(ushort)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(ushort *)(store+i*sizeof(ushort)) = ushort(c); + } + return true; +} + +static bool cb_read_list_inui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uint)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(uint *)(store+i*sizeof(uint)) = uint(c); + } + return true; +} + +static bool cb_read_list_infl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(float *)(store+i*sizeof(float)) = float(c); + } + return true; +} + +static bool cb_read_list_indo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(double *)(store+i*sizeof(double)) = double(c); + } + return true; +} + + + +static bool cb_read_list_ucch( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(char)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(short)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(int)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uchar)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(ushort)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uint)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;ioffset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(char)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(char *)(store+i*sizeof(char)) = char(c); + } + return true; +} + +static bool cb_read_list_ussh( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(short)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(short *)(store+i*sizeof(short)) = short(c); + } + return true; +} + +static bool cb_read_list_usin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(int)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(int *)(store+i*sizeof(int)) = int(c); + } + return true; +} + +static bool cb_read_list_usuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uchar)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(uchar *)(store+i*sizeof(uchar)) = uchar(c); + } + return true; +} + +static bool cb_read_list_usus( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(ushort)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(ushort *)(store+i*sizeof(ushort)) = ushort(c); + } + return true; +} + +static bool cb_read_list_usui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uint)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(uint *)(store+i*sizeof(uint)) = uint(c); + } + return true; +} + +static bool cb_read_list_usfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(float *)(store+i*sizeof(float)) = float(c); + } + return true; +} + +static bool cb_read_list_usdo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0) return false; + *(double *)(store+i*sizeof(double)) = double(c); + } + return true; +} + + + + +static bool cb_read_list_uich( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(char)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(char *)(store+i*sizeof(char)) = char(c); + } + return true; +} + +static bool cb_read_list_uish( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(short)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(short *)(store+i*sizeof(short)) = short(c); + } + return true; +} + +static bool cb_read_list_uiin( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(int)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(int *)(store+i*sizeof(int)) = int(c); + } + return true; +} + +static bool cb_read_list_uiuc( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uchar)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(uchar *)(store+i*sizeof(uchar)) = uchar(c); + } + return true; +} + +static bool cb_read_list_uius( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(ushort)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(ushort *)(store+i*sizeof(ushort)) = ushort(c); + } + return true; +} + +static bool cb_read_list_uiui( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(uint)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(uint *)(store+i*sizeof(uint)) = uint(c); + } + return true; +} + +static bool cb_read_list_uifl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(float *)(store+i*sizeof(float)) = float(c); + } + return true; +} + +static bool cb_read_list_uido( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(double *)(store+i*sizeof(double)) = double(c); + } + return true; +} + + + +static bool cb_read_list_flfl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(float *)(store+i*sizeof(float)) = float(c); + } + return true; +} + +static bool cb_read_list_fldo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(double *)(store+i*sizeof(double)) = double(c); + } + return true; +} + +static bool cb_read_list_dofl( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(float)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(float *)(store+i*sizeof(float)) = float(c); + } + return true; +} + +static bool cb_read_list_dodo( GZFILE fp, void * mem, PropDescriptor * d ) +{ + uchar n,i; + if( pb_fread(&n,1,1,fp)==0 ) return false; + char * store; + StoreInt( ((char *)mem)+d->offset2, d->memtype2, int(n)); + if(d->alloclist) + { + store = (char *)calloc(n,sizeof(double)); + assert(store); + *(char **)(((char *)mem)+d->offset1) = store; + } + else + store = ((char *)mem)+d->offset1; + + for(i=0;iformat)==0 ) return false; + *(double *)(store+i*sizeof(double)) = double(c); + } + return true; +} + + + +void PlyFile::compile( PlyProperty * p ) +{ + p->desc.format = format; // copiatura formato + + if(format==F_ASCII) + { + if(p->islista) + { + if(p->bestored) + p->cb = cb_read_list_ascii; + else + p->cb = cb_skip_list_ascii; + } + else + { + if(p->bestored) + { + p->cb = cb_read_ascii; + } + else + { + switch(p->tipo) + { + case T_CHAR: + case T_SHORT: + case T_INT: + case T_UCHAR: + case T_USHORT: + case T_UINT: + p->cb = cb_skip_int_ascii; + break; + case T_FLOAT: + case T_DOUBLE: + p->cb = cb_skip_float_ascii; + break; + default: p->cb = 0; assert(0); break; + } + } + } + } + else + { + if(p->islista) + { + if(p->bestored) + { + switch(p->desc.stotype1) + { + case T_CHAR: //================== Lettura char + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_list_chch; break; + case T_SHORT: p->cb = cb_read_list_chsh; break; + case T_INT: p->cb = cb_read_list_chin; break; + case T_UCHAR: p->cb = cb_read_list_chuc; break; + case T_USHORT: p->cb = cb_read_list_chus; break; + case T_UINT: p->cb = cb_read_list_chui; break; + case T_FLOAT: p->cb = cb_read_list_chfl; break; + case T_DOUBLE: p->cb = cb_read_list_chdo; break; + default: assert(0); + } + break; + case T_SHORT: //================== Lettura short + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_list_shch; break; + case T_SHORT: p->cb = cb_read_list_shsh; break; + case T_INT: p->cb = cb_read_list_shin; break; + case T_UCHAR: p->cb = cb_read_list_shuc; break; + case T_USHORT: p->cb = cb_read_list_shus; break; + case T_UINT: p->cb = cb_read_list_shui; break; + case T_FLOAT: p->cb = cb_read_list_shfl; break; + case T_DOUBLE: p->cb = cb_read_list_shdo; break; + default: assert(0); + } + break; + case T_INT: //================== Lettura int + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_list_inch; break; + case T_SHORT: p->cb = cb_read_list_insh; break; + case T_INT: p->cb = cb_read_list_inin; break; + case T_UCHAR: p->cb = cb_read_list_inuc; break; + case T_USHORT: p->cb = cb_read_list_inus; break; + case T_UINT: p->cb = cb_read_list_inui; break; + case T_FLOAT: p->cb = cb_read_list_infl; break; + case T_DOUBLE: p->cb = cb_read_list_indo; break; + default: assert(0); + } + break; + case T_UCHAR: //================== Lettura uchar + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_list_ucch; break; + case T_SHORT: p->cb = cb_read_list_ucsh; break; + case T_INT: p->cb = cb_read_list_ucin; break; + case T_UCHAR: p->cb = cb_read_list_ucuc; break; + case T_USHORT: p->cb = cb_read_list_ucus; break; + case T_UINT: p->cb = cb_read_list_ucui; break; + case T_FLOAT: p->cb = cb_read_list_ucfl; break; + case T_DOUBLE: p->cb = cb_read_list_ucdo; break; + default: assert(0); + } + break; + case T_USHORT: //================== Lettura ushort + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_list_usch; break; + case T_SHORT: p->cb = cb_read_list_ussh; break; + case T_INT: p->cb = cb_read_list_usin; break; + case T_UCHAR: p->cb = cb_read_list_usuc; break; + case T_USHORT: p->cb = cb_read_list_usus; break; + case T_UINT: p->cb = cb_read_list_usui; break; + case T_FLOAT: p->cb = cb_read_list_usfl; break; + case T_DOUBLE: p->cb = cb_read_list_usdo; break; + default: assert(0); + } + break; + case T_UINT: //================== Lettura uint + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_list_uich; break; + case T_SHORT: p->cb = cb_read_list_uish; break; + case T_INT: p->cb = cb_read_list_uiin; break; + case T_UCHAR: p->cb = cb_read_list_uiuc; break; + case T_USHORT: p->cb = cb_read_list_uius; break; + case T_UINT: p->cb = cb_read_list_uiui; break; + case T_FLOAT: p->cb = cb_read_list_uifl; break; + case T_DOUBLE: p->cb = cb_read_list_uido; break; + default: assert(0); + } + break; + case T_FLOAT: //================== Lettura float + switch(p->desc.memtype1) + { + case T_FLOAT: p->cb = cb_read_list_flfl; break; + case T_DOUBLE: p->cb = cb_read_list_fldo; break; + default: assert(0); + } + break; + case T_DOUBLE: //================== Lettura double + switch(p->desc.memtype1) + { + case T_FLOAT: p->cb = cb_read_list_dofl; break; + case T_DOUBLE: p->cb = cb_read_list_dodo; break; + default: assert(0); + } + break; + default: + assert(0); + } + } + else + { + switch(TypeSize[p->tipo]) + { + case 1: p->cb = cb_skip_list_bin1; break; + case 2: p->cb = cb_skip_list_bin2; break; + case 4: p->cb = cb_skip_list_bin4; break; + case 8: p->cb = cb_skip_list_bin4; break; + default:p->cb = 0; assert(0); break; + } + } + } + else + { + if(p->bestored) + { + switch(p->desc.stotype1) + { + case T_CHAR: //================== Lettura char + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_chch; break; + case T_SHORT: p->cb = cb_read_chsh; break; + case T_INT: p->cb = cb_read_chin; break; + case T_UCHAR: p->cb = cb_read_chuc; break; + case T_USHORT: p->cb = cb_read_chus; break; + case T_UINT: p->cb = cb_read_chui; break; + case T_FLOAT: p->cb = cb_read_chfl; break; + case T_DOUBLE: p->cb = cb_read_chdo; break; + default: assert(0); + } + break; + case T_SHORT: //================== Lettura short + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_shch; break; + case T_SHORT: p->cb = cb_read_shsh; break; + case T_INT: p->cb = cb_read_shin; break; + case T_UCHAR: p->cb = cb_read_shuc; break; + case T_USHORT: p->cb = cb_read_shus; break; + case T_UINT: p->cb = cb_read_shui; break; + case T_FLOAT: p->cb = cb_read_shfl; break; + case T_DOUBLE: p->cb = cb_read_shdo; break; + default: assert(0); + } + break; + case T_INT: //================== Lettura int + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_inch; break; + case T_SHORT: p->cb = cb_read_insh; break; + case T_INT: p->cb = cb_read_inin; break; + case T_UCHAR: p->cb = cb_read_inuc; break; + case T_USHORT: p->cb = cb_read_inus; break; + case T_UINT: p->cb = cb_read_inui; break; + case T_FLOAT: p->cb = cb_read_infl; break; + case T_DOUBLE: p->cb = cb_read_indo; break; + default: assert(0); + } + break; + case T_UCHAR: //================== Lettura uchar + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_ucch; break; + case T_SHORT: p->cb = cb_read_ucsh; break; + case T_INT: p->cb = cb_read_ucin; break; + case T_UCHAR: p->cb = cb_read_ucuc; break; + case T_USHORT: p->cb = cb_read_ucus; break; + case T_UINT: p->cb = cb_read_ucui; break; + case T_FLOAT: p->cb = cb_read_ucfl; break; + case T_DOUBLE: p->cb = cb_read_ucdo; break; + default: assert(0); + } + break; + case T_USHORT: //================== Lettura ushort + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_usch; break; + case T_SHORT: p->cb = cb_read_ussh; break; + case T_INT: p->cb = cb_read_usin; break; + case T_UCHAR: p->cb = cb_read_usuc; break; + case T_USHORT: p->cb = cb_read_usus; break; + case T_UINT: p->cb = cb_read_usui; break; + case T_FLOAT: p->cb = cb_read_usfl; break; + case T_DOUBLE: p->cb = cb_read_usdo; break; + default: assert(0); + } + break; + case T_UINT: //================== Lettura uint + switch(p->desc.memtype1) + { + case T_CHAR: p->cb = cb_read_uich; break; + case T_SHORT: p->cb = cb_read_uish; break; + case T_INT: p->cb = cb_read_uiin; break; + case T_UCHAR: p->cb = cb_read_uiuc; break; + case T_USHORT: p->cb = cb_read_uius; break; + case T_UINT: p->cb = cb_read_uiui; break; + case T_FLOAT: p->cb = cb_read_uifl; break; + case T_DOUBLE: p->cb = cb_read_uido; break; + default: assert(0); + } + break; + case T_FLOAT: //================== Lettura float + switch(p->desc.memtype1) + { + case T_FLOAT: p->cb = cb_read_flfl; break; + case T_DOUBLE: p->cb = cb_read_fldo; break; + default: assert(0); + } + break; + case T_DOUBLE: //================== Lettura double + switch(p->desc.memtype1) + { + case T_FLOAT: p->cb = cb_read_dofl; break; + case T_DOUBLE: p->cb = cb_read_dodo; break; + default: assert(0); + } + break; + default: + assert(0); + } + } + else + { + switch(TypeSize[p->tipo]) + { + case 1: p->cb = cb_skip_bin1; break; + case 2: p->cb = cb_skip_bin2; break; + case 4: p->cb = cb_skip_bin4; break; + case 8: p->cb = cb_skip_bin8; break; + default:p->cb = 0; assert(0); break; + } + } + } + } +} + +void PlyFile::compile( PlyElement * e ) +{ + vector::iterator i; + for(i=e->props.begin();i!=e->props.end();++i) + compile(&*i); +} + + + + + // Funzioni statiche per la lettura di un elemento +int ReadBin ( XFILE * fp, const PlyProperty * pr, void * mem, int fmt ) +{ + assert(pr); + + // Lettura di una lista + if(pr->islista) + { + int i,n; + + if( !ReadScalarB(fp,&n,pr->tipoindex, T_INT, fmt) ) + return 0; + + assert(n<12); // Valore abbastanza aleatorio + + // Lettura con memorizzazione + if(pr->bestored) + { + char * store; + + StoreInt( ((char *)mem)+pr->desc.offset2, pr->desc.memtype2, n); + // Determinazione memoria vettore + if(pr->desc.alloclist) + { + store = (char *)calloc(n,TypeSize[pr->desc.memtype1]); + assert(store); + *(char **)(((char *)mem)+pr->desc.offset1) = store; + } + else + { + store = ((char *)mem)+pr->desc.offset1; + } + + for(i=0;idesc.memtype1], + pr->desc.stotype1, + pr->desc.memtype1, + fmt + ) ) + return 0; + } + } + // Lettura senza memorizzazione + else + { + for(i=0;itipo) ) + return 0; + } + } + // Lettura di uno scalare + else + { + // Lettura con memorizzazione + if(pr->bestored) + return ReadScalarB( + fp, + ((char *)mem)+pr->desc.offset1, + pr->desc.stotype1, pr->desc.memtype1, + fmt + ); + // Lettura senza memorizzazione + else + return SkipScalarB(fp,pr->tipo); + } + + return 1; +} + + +int ReadAscii( XFILE * fp, const PlyProperty * pr, void * mem, int /*fmt*/ ) +{ + assert(pr); + assert(mem); + + + // Lettura di una lista + if(pr->islista) + { + int i,n; + + if( !ReadScalarA(fp,&n,pr->tipoindex, T_INT) ) + return 0; + + assert(n<12); // Valore abbastanza aleatorio + + // Lettura con memorizzazione + if(pr->bestored) + { + char * store; + + StoreInt( ((char *)mem)+pr->desc.offset2, pr->desc.memtype2, n); + // Determinazione memoria vettore + if(pr->desc.alloclist) + { + store = (char *)calloc(n,TypeSize[pr->desc.memtype1]); + assert(store); + *(char **)(((char *)mem)+pr->desc.offset1) = store; + } + else + { + store = ((char *)mem)+pr->desc.offset1; + } + + for(i=0;idesc.memtype1], + pr->desc.stotype1, + pr->desc.memtype1 + ) ) + return 0; + } + } + // Lettura senza memorizzazione + else + { + for(i=0;itipo) ) + return 0; + } + } + // Lettura scalare + else + { + // Lettura con memorizzazione + if(pr->bestored) + return ReadScalarA( + fp, + ((char *)mem)+pr->desc.offset1, + pr->desc.stotype1, pr->desc.memtype1 + ); + // Lettura senza memorizzazione + else + return SkipScalarA(fp,pr->tipo); + } + return 1; +} + + + // Finally! the main function + +int PlyFile::Read( void * mem ) +{ + assert(cure); + assert(ReadCB); + + vector::iterator i; + + for(i=cure->props.begin();i!=cure->props.end();++i) + { + if( ! i->cb(gzfp,mem,&(i->desc)) ) return -1; + /* + int r = ReadCB(gzfp,i,mem,format); + if(!r) + return -1; + */ + } + + return 0; +} + +} +} diff --git a/wrap/ply/plylib.h b/wrap/ply/plylib.h new file mode 100644 index 00000000..d6164819 --- /dev/null +++ b/wrap/ply/plylib.h @@ -0,0 +1,312 @@ +/**************************************************************************** +* 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. * +* * +****************************************************************************/ +/**************************************************************************** +Acknowlegments +Portions of this file were based on the original code of the Ply library +of Greg Turk and on the work of Claudio Rocchini + +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +****************************************************************************/ + +#ifndef __VCG_PLYLIB +#define __VCG_PLYLIB + +#include +#include +#include + +namespace vcg { +namespace ply { +// Temporaneo + + // Tipi di dato Supportati dal formato ply +enum PlyTypes { + T_NOTYPE, + T_CHAR, + T_SHORT, + T_INT, + T_UCHAR, + T_USHORT, + T_UINT, + T_FLOAT, + T_DOUBLE, + T_MAXTYPE +}; + + // Codici di errore riportati da GetError +enum PlyError { + E_NOERROR, // 0 + // Errori di open + E_CANTOPEN, // 1 + E_NOTHEADER, // 2 + E_UNESPECTEDEOF, // 3 + E_NOFORMAT, // 4 + E_SYNTAX, // 5 + E_PROPOUTOFELEMENT, // 6 + E_BADTYPENAME, // 7 + // Errori di addtoread + E_ELEMNOTFOUND, // 8 + E_PROPNOTFOUND, // 9 + E_BADTYPE, // 10 + E_INCOMPATIBLETYPE, // 11 + E_BADCAST, // 12 + E_MAXPLYERRORS +}; + + // Tipi di formato di file +enum PlyFormat { + F_UNSPECIFIED, + F_ASCII, + F_BINLITTLE, + F_BINBIG +}; + + +#ifdef USE_ZLIB +typedef void * GZFILE; +#else +typedef FILE * GZFILE; +#endif + + + // Messaggio di errore +extern const char * ply_error_msg[]; + + // TIPO FILE + + + // Descrittore esterno di propieta' +class PropDescriptor +{ +public: + char * elemname; // Nome dell'elemento + char * propname; // Nome della propieta' + int stotype1; // Tipo dell'elemento su file (se lista tipo degli elementi della lista) + int memtype1; // Tipo dell'elemento in memoria (se lista tipo degli elementi della lista) + int offset1; // Offset del valore in memoria + int islist; // 1 se lista, 0 altrimenti + int alloclist; // 1 se alloca lista, 0 se preallocata + int stotype2; // Tipo del numero di elementi della lista su file + int memtype2; // Tipo del numero di elementi della lista in memoria + int offset2; // Offset valore memoria + + int format; // duplicazione del formato + + size_t stotypesize() const; // per sapere quanto e'grande un dato descrittore sul file + size_t memtypesize() const; // per sapere quanto e'grande un dato descrittore in memoria + const char *memtypename() const; + const char *stotypename() const; +}; + + // Callback di lettura +typedef bool (* readelemcb) ( GZFILE fp, void * mem, PropDescriptor * p ); + +class PlyProperty +{ +public: + inline PlyProperty() + { + tipo = 0; + islista = 0; + tipoindex = 0; + bestored = 0; + } + + inline PlyProperty( const char * na, int ti, int isl, int t2 ) + { + assert(na); + assert(ti>0); + assert(ti0 || (t2==0 && isl==0) ); + assert(t2=0); + + name = std::string(na); + number = nu; + } + + + inline void SetName( const char * na ) + { + name = std::string(na); + } + + inline void SetNumbert( int nu ) + { + assert(nu>0); + number = nu; + } + + void AddProp( const char * na, int ti, int isl, int t2 ); + + int AddToRead( + const char * propname, + int stotype1, + int memtype1, + int offset1, + int islist, + int alloclist, + int stotype2, + int memtype2, + int offset2 + ); // Vedi struttura PropDescriptor + + PlyProperty * FindProp( const char * name ); + + std::string name; // Nome dell'elemento + int number; // Numero di elementi di questo tipo + + std::vector props; // Vettore dinamico delle property +}; + + +class PlyFile +{ +private: + void compile( PlyElement * e ); + void compile( PlyProperty * p ); + +public: + // Modi di apertura + enum { + MODE_READ, + MODE_WRITE + }; + + PlyFile(); + ~PlyFile(); + + // Apre un file ply + int Open( const char * filename, int mode ); + // Chiude un file e disalloca la memoria + void Destroy(); + // Ritorna il codice dell'ultimo errore + inline int GetError() const { return error; } + // Definizione di lettura (Vedi struttura PropDescriptor) + int AddToRead( + const char * elemname, + const char * propname, + int stotype1, + int memtype1, + int offset1, + int islist, + int alloclist, + int stotype2, + int memtype2, + int offset2 + ); + // Come sopra ma con descrittore + inline int AddToRead( const PropDescriptor & p ) + { + return AddToRead(p.elemname,p.propname,p.stotype1, + p.memtype1,p.offset1,p.islist,p.alloclist,p.stotype2, + p.memtype2,p.offset2 + ); + } + + // Ritorna il numero di oggetti di un tipo di elemento + const char * ElemName( int i ); + + int ElemNumber( int i ) const; + // Setta il tipo di elemento corrente per effetture + // la lettura + inline void SetCurElement( int i ) + { + if(i<0 || i>=int(elements.size())) cure = 0; + else + { + cure = &(elements[i]); + compile(cure); + } + } + // Lettura du un elemento + int Read( void * mem ); + + std::vector elements; // Vettore degli elementi + std::vector comments; // Vettore dei commenti + static const char * typenames[9]; + static const char * newtypenames[9]; + + inline const char * GetHeader() const { return header; } +protected: + + GZFILE gzfp; + + float version; // Versione del file + int error; // Errore corrente (vedi enum) + int format; // Formato del file (vedi enum ) + + char header[4096]; // Testo dell'header + + PlyElement * cure; // Elemento da leggere + + // Callback di lettura: vale ReadBin o ReadAcii + int (* ReadCB)( GZFILE fp, const PlyProperty * r, void * mem, int fmt ); + + int OpenRead( const char * filename ); + int OpenWrite( const char * filename ); + + PlyElement * AddElement( const char * name, int number ); + int FindType( const char * name ) const; + PlyElement * FindElement( const char * name ); +}; + +} +} +#endif diff --git a/wrap/ply/plystuff.h b/wrap/ply/plystuff.h new file mode 100644 index 00000000..e5d2b33b --- /dev/null +++ b/wrap/ply/plystuff.h @@ -0,0 +1,340 @@ +//****************** Gestione cache ***************** + +const int MAXBPATH = 256; + +static bool GetDirFromPath( const char * path, char * dir, char * name ) +{ + strcpy(dir,path); + char * p; + + p = strrchr(dir,'\\'); + if(p==0) p=strrchr(dir,'/'); + if(p==0) + { + dir[0] = 0; + strcpy(name,path); + } + else + { + strcpy(name,p+1); + *p = 0; + } + return true; +} + + +static bool CheckCacheDirectory( const char * dir ) +{ + if( pb_access(dir,0)!=0 ) + { + if( pb_mkdir(dir)==-1 ) + return false; + } + return true; +} + + +bool CheckCacheTime( const char * fname, const char * cname ) +{ + + if( pb_access(fname,4)==-1 ) return false; + if( pb_access(cname,4)==-1 ) return false; + + int h,r; + struct pb_stat st; + time_t ft,bt; + + h = pb_open(fname,_O_BINARY|_O_RDONLY); + if(h==0) return false; + r = _fstat(h,&st); + pb_close(h); + if(r==-1) return false; + ft = st.st_mtime; + + h = pb_open(cname,_O_BINARY|_O_RDONLY); + if(h==0) return false; + r = _fstat(h,&st); + //_read(h,&box,sizeof(box)); + pb_close(h); + if(r==-1) return false; + bt = st.st_mtime; + + if( difftime(bt,ft)>=0 ) return true; + else return false; +} + +// restituisce true se il file con la cache del bbox della mesh e' piu' recente del file ply +// se fname2 != 0, allora deve essere piu recente anche di fname2. +static bool CheckBBoxCache( const char * fname, Box3d & box, char *fname2=0 ) +{ + char d[MAXBPATH]; + char n[MAXBPATH]; + char h[8]; + + // Estrazione dati + if( ! GetDirFromPath(fname,d,n) ) return false; + + // Controllo esistenza directory delle cache + if(d[0]!=0) + strcat(d,"\\"); + strcat(d,cachedir); + if( !CheckCacheDirectory(d) ) return false; + + // Controllo esistenza e data file cache + strcat(d,"\\"); + strcat(d,n); + strcat(d,bboxcacheext); + if( CheckCacheTime(fname,d) && + (fname2==0 || CheckCacheTime(fname2,d)) ) + { + // Lettura bbox e controllo + FILE * fp = fopen(d,"rb"); + if(fp==0) return false; + if( fread(h,1,8,fp)!=8 ) + { + fclose(fp); + return false; + } + if( fread(&box,sizeof(Box3d),1,fp)!=1 ) + { + fclose(fp); + return false; + } + fclose(fp); + if( strncmp(h,bboxheader,8) ) + return false; + else + return true; + } + else + return false; +} + + +bool GetCacheName( const char * fname, const char * ext_name, char * cname ) +{ + static char n[MAXBPATH]; + + // Estrazione dati + if( ! GetDirFromPath(fname,cname,n) ) return false; + + // Controllo esistenza directory delle cache + if(cname[0]!=0) + strcat(cname,"\\"); + strcat(cname,cachedir); + if( !CheckCacheDirectory(cname) ) return false; + + strcat(cname,"\\"); + strcat(cname,n); + strcat(cname,ext_name); + return true; +} + + +static bool SaveBBoxCache( const char * fname, const Box3d & box ) +{ + char d[MAXBPATH]; + + if( !GetCacheName(fname,bboxcacheext,d) ) + return false; + + // Lettura bbox e controllo + FILE * fp = fopen(d,"wb"); + if(fp==0) return false; + if( fwrite(bboxheader,1,8,fp)!=8 ) + { + fclose(fp); + return false; + } + if( fwrite(&box,sizeof(Box3d),1,fp)!=1 ) + { + fclose(fp); + return false; + } + fclose(fp); + return true; +} + +struct PlyPoint3d +{ + double x; + double y; + double z; +}; + + + // Calcola il bbox di un file ply + +bool ScanBBox( const char * fname, Box3d & box, bool use_cache ) +{ + + if(use_cache) + { + if( CheckBBoxCache(fname,box) ) + return true; + } + + static const PropDescriptor pv[3]= + { + {"vertex","x",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,x),0,0,0,0,0}, + {"vertex","y",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,y),0,0,0,0,0}, + {"vertex","z",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,z),0,0,0,0,0}, + }; + + + PlyFile pf; + + if( pf.Open(fname,PlyFile::MODE_READ)==-1 ) + { + fprintf(stderr,"Warning: File %s not found\n",fname); + return false; + } + + if( pf.AddToRead(pv[0])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; } + if( pf.AddToRead(pv[1])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; } + if( pf.AddToRead(pv[2])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; } + + box.SetNull(); + char dummyspace[1024]; // sperando basti... + + for(int i=0;iia+5) { + if ( ( (a[ia+1]=='t') || (a[ia+1]=='T') ) && + ( (a[ia+2]=='h') || (a[ia+2]=='H') ) && + ( (a[ia+3]=='i') || (a[ia+3]=='I') ) && + ( (a[ia+4]=='s') || (a[ia+4]=='S') ) && + ( a[ia+5]=='>' ) ) + { + // substitute "" with filename: + // 1) remove path from filename + int lastbar=0; + int ifn=0; + while (fn[ifn]!=0) { if ((fn[ifn]=='/') || (fn[ifn]=='\\')) lastbar=ifn+1; ifn++;} + ifn=lastbar; + char fn2[255]; + while (fn[ifn]!=0) { fn2[ifn-lastbar]=fn[ifn]; ifn++;} + fn2[ifn-lastbar]=0; + + // 2) remove ".ply" extention from filename + int l=ifn-lastbar; + if ((fn2[l-4]=='.') + && ((fn2[l-3]=='P') || (fn2[l-3]=='p')) + && ((fn2[l-2]=='L') || (fn2[l-2]=='l')) + && ((fn2[l-1]=='Y') || (fn2[l-1]=='y')) ) + fn2[l-4]=0; + + // 3) append + output[io]=0; + sprintf(output,"%s%s",output,fn2); + io=strlen(output); + ia+=6; //skip the "" + continue; + }; + } + } + output[io++]=a[ia++]; + }; + output[io]=0; +}; + +