/**************************************************************************** * 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.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 #include #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 #else #define pb_mkdir(n) mkdir(n,0) #define pb_access access #define pb_stat stat #define pb_fstat fstat #define pb_open open #define pb_close close #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"; 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 = 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. static bool CheckBBoxCache( const char * fname, Box3d & 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,"\\"); 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=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}, {"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;i