/**************************************************************************** * 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 $ Revision 1.6 2007/06/25 15:24:00 cignoni removed a possibly useless static kw Revision 1.5 2006/04/11 09:48:04 zifnab1974 changes needed for compilation on linux 64b with gcc 3.4.5 Revision 1.4 2005/12/02 00:00:53 cignoni Moved and corrected interpret_texture_name from plystuff.h to plylib.cpp Revision 1.3 2005/03/18 00:14:40 cignoni removed small gcc compiling issues Revision 1.2 2005/03/15 11:46:52 cignoni Cleaning of the automatic bbox caching support for ply files. First working version. */ //****************** Gestione cache ***************** #ifndef __VCG_PLYLIB_STUFF #define __VCG_PLYLIB_STUFF #include #include #include #ifdef WIN32 #include #endif #include #include using namespace vcg; #ifdef WIN32 #include #define pb_mkdir(n) _mkdir(n) #define pb_access _access #define pb_stat _stat #define pb_fstat _fstat #define pb_open _open #define pb_close _close #define DIR_SEP "\\" #else #define pb_mkdir(n) mkdir(n,0755) #define pb_access access #define pb_stat stat #define pb_fstat fstat #define pb_open open #define pb_close close #define _O_BINARY 0 // Does not exist on Unix #define _O_RDONLY O_RDONLY #define DIR_SEP "/" #endif namespace vcg { namespace ply { const int MAXBPATH = 256; // Stringhe per la cache const char * cachedir = "vcg_cache"; const char * bboxcacheext = ".bbox_cache"; const char * bboxheader = "BBOXCACH"; 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 = pb_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 = pb_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. template static bool CheckBBoxCache( const char * fname, Box3 & box, const 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,DIR_SEP); strcat(d,cachedir); if( !CheckCacheDirectory(d) ) return false; // Controllo esistenza e data file cache strcat(d,DIR_SEP); strcat(d,n); strcat(d,bboxcacheext); if( CheckCacheTime(fname,d) && (fname2==0 || CheckCacheTime(fname2,d)) ) { // Lettura bbox e controllo Box3d readBB; FILE * fp = fopen(d,"rb"); if(fp==0) return false; if( fread(h,1,8,fp)!=8 ) { fclose(fp); return false; } if( fread(&readBB,sizeof(Box3d),1,fp)!=1 ) { fclose(fp); return false; } fclose(fp); box.Import(readBB); 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,DIR_SEP); strcat(cname,cachedir); if( !CheckCacheDirectory(cname) ) return false; strcat(cname,DIR_SEP); strcat(cname,n); strcat(cname,ext_name); return true; } template static bool SaveBBoxCache( const char * fname, const Box3 & boxOut ) { char d[MAXBPATH]; Box3d box; box.Import(boxOut); 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 template bool ScanBBox( const char * fname, Box3 & box, bool use_cache=true ) { 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 ,0}, // TO GET RID OF COMPILER WARNING I ADDED 0 TO INITIALIZE format (MV) {"vertex","y",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,y),0,0,0,0,0 ,0}, // TO GET RID OF COMPILER WARNING I ADDED 0 TO INITIALIZE format (MV) {"vertex","z",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,z),0,0,0,0,0, 0},// TO GET RID OF COMPILER WARNING I ADDED 0 TO INITIALIZE format (MV) }; 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;i(t.x,t.y,t.z) ); } } else { for(int j=0;j bool ScanBBox( const char * fname, Box3 & box, const Matrix44 & m, bool use_cache, const char *matrixfname) { if(use_cache) { if ( CheckBBoxCache(fname,box,matrixfname) ) return true; } static const PropDescriptor pv[3]= { {"vertex","x",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,x),0,0,0,0,0, 0},// TO GET RID OF COMPILER WARNING I ADDED 0 TO INITIALIZE format (MV) {"vertex","y",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,y),0,0,0,0,0, 0},// TO GET RID OF COMPILER WARNING I ADDED 0 TO INITIALIZE format (MV) {"vertex","z",T_FLOAT,T_DOUBLE,offsetof(PlyPoint3d,z),0,0,0,0,0, 0},// TO GET RID OF COMPILER WARNING I ADDED 0 TO INITIALIZE format (MV) }; 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;i(t.x,t.y,t.z) ); } } else { for(int j=0;j