plystuff.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *   
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 /****************************************************************************
00024 Acknowlegments
00025 Portions of this file were based on the original code of the Ply library 
00026 of Greg Turk and on the work of Claudio Rocchini
00027 
00028 ****************************************************************************/
00029 
00030 /****************************************************************************
00031   History
00032 
00033 $Log: not supported by cvs2svn $
00034 Revision 1.6  2007/06/25 15:24:00  cignoni
00035 removed a possibly useless static kw
00036 
00037 Revision 1.5  2006/04/11 09:48:04  zifnab1974
00038 changes needed for compilation on linux 64b with gcc 3.4.5
00039 
00040 Revision 1.4  2005/12/02 00:00:53  cignoni
00041 Moved and corrected interpret_texture_name from plystuff.h to plylib.cpp
00042 
00043 Revision 1.3  2005/03/18 00:14:40  cignoni
00044 removed small gcc compiling issues
00045 
00046 Revision 1.2  2005/03/15 11:46:52  cignoni
00047 Cleaning of the automatic bbox caching support for ply files. First working version.
00048 
00049 
00050 */
00051 
00052 //****************** Gestione cache *****************
00053 
00054 #ifndef __VCG_PLYLIB_STUFF
00055 #define __VCG_PLYLIB_STUFF 
00056 
00057 #include <sys/types.h>
00058 #include <sys/stat.h>
00059 #include <fcntl.h> 
00060 #ifdef WIN32
00061 #include <io.h>
00062 #endif
00063 
00064 #include <vcg/space/box3.h>
00065 #include <wrap/ply/plylib.h>
00066 using namespace vcg;
00067 
00068 #ifdef WIN32
00069 #include <direct.h>
00070 #define pb_mkdir(n)  _mkdir(n)
00071 #define pb_access _access
00072 #define pb_stat   _stat
00073 #define pb_fstat   _fstat
00074 #define pb_open   _open
00075 #define pb_close  _close
00076 #define DIR_SEP "\\"
00077 #else
00078 #define pb_mkdir(n)  mkdir(n,0755)
00079 #define pb_access access
00080 #define pb_stat   stat
00081 #define pb_fstat   fstat
00082 #define pb_open   open
00083 #define pb_close  close
00084 #define _O_BINARY 0 // Does not exist on Unix
00085 #define _O_RDONLY O_RDONLY
00086 #define DIR_SEP "/"
00087 #endif
00088 
00089 
00090 namespace vcg {
00091 namespace ply {
00092 
00093 const int MAXBPATH = 256;
00094 
00095         // Stringhe per la cache
00096 const char * cachedir = "vcg_cache";
00097 const char * bboxcacheext = ".bbox_cache";
00098 const char * bboxheader = "BBOXCACH";
00099 
00100 bool GetDirFromPath( const char * path, char * dir, char * name )
00101 {
00102         strcpy(dir,path);
00103         char * p;
00104         
00105         p = strrchr(dir,'\\');
00106         if(p==0) p=strrchr(dir,'/');
00107         if(p==0)
00108         {
00109                 dir[0] = 0;
00110                 strcpy(name,path);
00111         }
00112         else
00113         {
00114                 strcpy(name,p+1);
00115                 *p = 0;
00116         }
00117         return true;
00118 }
00119 
00120 
00121 static bool CheckCacheDirectory( const char * dir )
00122 {
00123         if( pb_access(dir,0)!=0 )
00124         {
00125                 if( pb_mkdir(dir)==-1 )
00126                         return false;
00127         }
00128         return true;
00129 }
00130 
00131 
00132 bool CheckCacheTime( const char * fname, const char * cname )
00133 {
00134 
00135         if( pb_access(fname,4)==-1 ) return false;
00136         if( pb_access(cname,4)==-1 ) return false;
00137 
00138         int h,r;
00139         struct pb_stat st;
00140         time_t ft,bt;
00141 
00142         h = pb_open(fname,_O_BINARY|_O_RDONLY);
00143         if(h==0) return false;
00144         r = pb_fstat(h,&st);
00145         pb_close(h);
00146         if(r==-1) return false;
00147         ft = st.st_mtime;
00148 
00149         h = pb_open(cname,_O_BINARY|_O_RDONLY);
00150         if(h==0) return false;
00151         r = pb_fstat(h,&st);
00152         //_read(h,&box,sizeof(box));
00153         pb_close(h);
00154         if(r==-1) return false;
00155         bt = st.st_mtime;
00156 
00157         if( difftime(bt,ft)>=0 ) return true;
00158         else                             return false;
00159 }
00160 
00161 // restituisce true se il file con la cache del bbox della mesh e' piu' recente del file ply
00162 // se fname2 != 0, allora deve essere piu recente anche di fname2.
00163 template<class ScalarType>
00164         static bool CheckBBoxCache( const char * fname, Box3<ScalarType> & box, const char *fname2=0 )
00165 {
00166         char d[MAXBPATH];
00167         char n[MAXBPATH];
00168         char h[8];
00169 
00170                 // Estrazione dati
00171         if( ! GetDirFromPath(fname,d,n) ) return false;
00172 
00173                 // Controllo esistenza directory delle cache
00174         if(d[0]!=0)
00175                 strcat(d,DIR_SEP);
00176         strcat(d,cachedir);
00177         if( !CheckCacheDirectory(d) ) return false;
00178 
00179                 // Controllo esistenza e data file cache
00180         strcat(d,DIR_SEP);
00181         strcat(d,n);
00182         strcat(d,bboxcacheext);
00183         if( CheckCacheTime(fname,d)  &&
00184                  (fname2==0 || CheckCacheTime(fname2,d)) )
00185         {
00186                         // Lettura bbox e controllo
00187         Box3d readBB;
00188                 FILE * fp = fopen(d,"rb");
00189                 if(fp==0) return false;
00190                 if( fread(h,1,8,fp)!=8 )
00191                 {
00192                         fclose(fp);
00193                         return false;
00194                 }
00195         if( fread(&readBB,sizeof(Box3d),1,fp)!=1 )
00196                 {
00197                         fclose(fp);
00198                         return false;
00199                 }
00200                 fclose(fp);
00201         box.Import(readBB);
00202                 if( strncmp(h,bboxheader,8) )
00203                         return false;
00204                 else
00205                         return true;
00206         }
00207         else
00208                 return false;
00209 }
00210 
00211 
00212 bool GetCacheName( const char * fname, const char * ext_name, char * cname )
00213 {
00214         static char n[MAXBPATH];
00215 
00216                 // Estrazione dati
00217         if( ! GetDirFromPath(fname,cname,n) ) return false;
00218 
00219                 // Controllo esistenza directory delle cache
00220         if(cname[0]!=0)
00221                 strcat(cname,DIR_SEP);
00222         strcat(cname,cachedir);
00223         if( !CheckCacheDirectory(cname) ) return false;
00224 
00225         strcat(cname,DIR_SEP);
00226         strcat(cname,n);
00227         strcat(cname,ext_name);
00228         return true;
00229 }
00230 
00231 
00232 template <class ScalarType>
00233 static bool SaveBBoxCache( const char * fname, const Box3<ScalarType> & boxOut )
00234 {
00235         char d[MAXBPATH];
00236 
00237     Box3d box;
00238     box.Import(boxOut);
00239         if( !GetCacheName(fname,bboxcacheext,d) )
00240                 return false;
00241 
00242                 // Lettura bbox e controllo
00243         FILE * fp = fopen(d,"wb");
00244         if(fp==0) return false;
00245         if( fwrite(bboxheader,1,8,fp)!=8 )
00246         {
00247                 fclose(fp);
00248                 return false;
00249         }
00250         if( fwrite(&box,sizeof(Box3d),1,fp)!=1 )
00251         {
00252                 fclose(fp);
00253                 return false;
00254         }
00255         fclose(fp);
00256         return true;
00257 }
00258 
00259 struct PlyPoint3d
00260 {
00261         double x;
00262         double y;
00263         double z;
00264 };
00265 
00266 
00267         // Calcola il bbox di un file ply
00268 template <class ScalarType>
00269 bool ScanBBox( const char * fname, Box3<ScalarType> & box, bool use_cache=true )
00270 {
00271 
00272         if(use_cache)
00273         {
00274                 if( CheckBBoxCache(fname,box) )
00275                         return true;
00276         }
00277 
00278         static const PropDescriptor pv[3]=
00279         {
00280                 {"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)
00281                 {"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)
00282                 {"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)
00283         };
00284 
00285 
00286         PlyFile pf;
00287 
00288         if( pf.Open(fname,PlyFile::MODE_READ)==-1 )
00289         {
00290                 fprintf(stderr,"Warning: File %s not found\n",fname);
00291                 return false;
00292         }
00293 
00294         if( pf.AddToRead(pv[0])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; }
00295         if( pf.AddToRead(pv[1])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; }
00296         if( pf.AddToRead(pv[2])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; }
00297 
00298         box.SetNull();
00299         char dummyspace[1024]; // sperando basti...
00300 
00301         for(int i=0;i<int(pf.elements.size());++i)
00302         {
00303                 int n = pf.ElemNumber(i);
00304                 pf.SetCurElement(i);
00305                         
00306                 if( !strcmp( pf.ElemName(i),"vertex" ) )
00307                 {
00308                         for(int j=0;j<n;++j)
00309                         {
00310                                 PlyPoint3d t;
00311 
00312                                 pf.Read( (void *)(&t) );
00313                                 box.Add( Point3<ScalarType>(t.x,t.y,t.z) );
00314                         }
00315                 }
00316                 else
00317                 {
00318                         for(int j=0;j<n;++j)
00319                                 //pf.Read( 0 ); // prima era cosi' e faceva un'assert e scrivema plausibilimente a caso in mem
00320                                 pf.Read( dummyspace );
00321                 }
00322         }
00323 
00324         if(use_cache)
00325         {
00326                 SaveBBoxCache(fname,box);
00327         }
00328 
00329         return true;
00330 }
00331 
00332 // Come la precedente ma applica la matrice m ai punti prima di calcolare il bbox.
00333 // Visto che la matrice di solito e' tenuta in un qualche file, se si vuole usare la cache 
00334 // si puo' passare anche un'altro filename da controllare
00335 template <class ScalarType>
00336 bool ScanBBox( const char * fname, Box3<ScalarType> & box, const Matrix44<ScalarType> & m, bool use_cache, const char *matrixfname)
00337 {
00338 
00339         if(use_cache)
00340         {
00341                 if ( CheckBBoxCache(fname,box,matrixfname) ) return true;
00342         }
00343 
00344         static const PropDescriptor pv[3]=
00345         {
00346                 {"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)
00347                 {"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)
00348                 {"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)
00349         };
00350 
00351 
00352         PlyFile pf;
00353 
00354         if( pf.Open(fname,PlyFile::MODE_READ)==-1 )
00355         {
00356                 fprintf(stderr,"Warning: File %s not found\n",fname);
00357                 return false;
00358         }
00359 
00360         if( pf.AddToRead(pv[0])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; }
00361         if( pf.AddToRead(pv[1])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; }
00362         if( pf.AddToRead(pv[2])==-1 ) { fprintf(stderr,"Warning: Read error\n"); return false; }
00363 
00364         box.SetNull();
00365         char dummyspace[1024]; // sperando basti...
00366 
00367         for(int i=0;i<int(pf.elements.size());++i)
00368         {
00369                 int n = pf.ElemNumber(i);
00370                 pf.SetCurElement(i);
00371                         
00372                 if( !strcmp( pf.ElemName(i),"vertex" ) )
00373                 {
00374                         for(int j=0;j<n;++j)
00375                         {
00376                                 PlyPoint3d t;
00377 
00378                                 pf.Read( (void *)(&t) );
00379                 box.Add( m*Point3<ScalarType>(t.x,t.y,t.z) );
00380                         }
00381                 }
00382                 else
00383                 {
00384                         for(int j=0;j<n;++j)
00385                                 //pf.Read( 0 ); // prima era cosi' e faceva un'assert e scrivema plausibilimente a caso in mem
00386                                 pf.Read( dummyspace );
00387                 }
00388         }
00389 
00390         if(use_cache)
00391         {
00392                 SaveBBoxCache(fname,box);
00393         }
00394 
00395         return true;
00396 }
00397 
00398 } // end namespace ply
00399 } // end namespace vcg
00400 #endif
00401 


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:34:12