00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "vertexBufferRoot.h"
00024 #include "vertexBufferState.h"
00025 #include "vertexData.h"
00026 #include <string>
00027 #include <sstream>
00028 #include <fcntl.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #ifndef _WIN32
00032 # include <sys/mman.h>
00033 #endif
00034
00035 using namespace std;
00036
00037 namespace mesh
00038 {
00039
00040
00041 void VertexBufferRoot::setupTree( VertexData& data )
00042 {
00043
00044 _data.clear();
00045
00046 const Axis axis = data.getLongestAxis( 0, data.triangles.size() );
00047
00048 VertexBufferNode::setupTree( data, 0, data.triangles.size(),
00049 axis, 0, _data );
00050 VertexBufferNode::updateBoundingSphere();
00051 VertexBufferNode::updateRange();
00052 }
00053
00054
00055
00056 void VertexBufferRoot::beginRendering( VertexBufferState& state ) const
00057 {
00058 switch( state.getRenderMode() )
00059 {
00060 #ifdef GL_ARB_vertex_buffer_object
00061 case RENDER_MODE_BUFFER_OBJECT:
00062 glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
00063 glEnableClientState( GL_VERTEX_ARRAY );
00064 glEnableClientState( GL_NORMAL_ARRAY );
00065 if( state.useColors() )
00066 glEnableClientState( GL_COLOR_ARRAY );
00067 #endif
00068 case RENDER_MODE_DISPLAY_LIST:
00069 case RENDER_MODE_IMMEDIATE:
00070 default:
00071 ;
00072 }
00073 }
00074
00075
00076
00077 void VertexBufferRoot::render( VertexBufferState& state ) const
00078 {
00079 VertexBufferNode::render( state );
00080 }
00081
00082
00083
00084 void VertexBufferRoot::endRendering( VertexBufferState& state ) const
00085 {
00086 switch( state.getRenderMode() )
00087 {
00088 #ifdef GL_ARB_vertex_buffer_object
00089 case RENDER_MODE_BUFFER_OBJECT:
00090 {
00091
00092 #define glewGetContext state.glewGetContext
00093 glBindBuffer( GL_ARRAY_BUFFER_ARB, 0);
00094 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
00095 glPopClientAttrib();
00096 }
00097 #endif
00098 case RENDER_MODE_DISPLAY_LIST:
00099 case RENDER_MODE_IMMEDIATE:
00100 default:
00101 ;
00102 }
00103 }
00104
00105
00106
00107 size_t getArchitectureBits()
00108 {
00109 return ( sizeof( void* ) * 8 );
00110 }
00111
00112
00113
00114 bool isArchitectureLittleEndian()
00115 {
00116 unsigned char test[2] = { 1, 0 };
00117 short x = *( reinterpret_cast< short* >( test ) );
00118 return ( x == 1 );
00119 }
00120
00121
00122
00123 string getArchitectureFilename( const std::string& filename )
00124 {
00125 ostringstream oss;
00126 oss << filename << ( isArchitectureLittleEndian() ? ".le" : ".be" );
00127 oss << getArchitectureBits() << ".bin";
00128 return oss.str();
00129 }
00130
00131
00132
00133 bool VertexBufferRoot::_constructFromPly( const std::string& filename )
00134 {
00135 MESHINFO << "Constructing new from PLY file." << endl;
00136
00137 VertexData data;
00138 if( _invertFaces )
00139 data.useInvertedFaces();
00140 if( !data.readPlyFile( filename ) )
00141 {
00142 MESHERROR << "Unable to load PLY file." << endl;
00143 return false;
00144 }
00145
00146 data.calculateNormals();
00147 data.scale( 2.0f );
00148 setupTree( data );
00149 if( !writeToFile( filename ))
00150 MESHWARN << "Unable to write binary representation." << endl;
00151
00152 return true;
00153 }
00154
00155 bool VertexBufferRoot::_readBinary( const std::string& filename )
00156 {
00157 #ifdef WIN32
00158
00159 HANDLE file = CreateFile( filename.c_str(), GENERIC_READ, FILE_SHARE_READ,
00160 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
00161 if( file == INVALID_HANDLE_VALUE )
00162 return false;
00163
00164 MESHINFO << "Reading cached binary representation." << endl;
00165
00166
00167 HANDLE map = CreateFileMapping( file, 0, PAGE_READONLY, 0, 0,
00168 filename.c_str( ));
00169 CloseHandle( file );
00170 if( !map )
00171 {
00172 MESHERROR << "Unable to read binary file, file mapping failed."
00173 << endl;
00174 return false;
00175 }
00176
00177
00178 char* addr = static_cast< char* >( MapViewOfFile( map, FILE_MAP_READ, 0,
00179 0, 0 ) );
00180 bool result = false;
00181
00182 if( addr )
00183 {
00184 try
00185 {
00186 fromMemory( addr );
00187 result = true;
00188 }
00189 catch( exception& e )
00190 {
00191 MESHERROR << "Unable to read binary file, an exception occured: "
00192 << e.what() << endl;
00193 }
00194 UnmapViewOfFile( addr );
00195 }
00196 else
00197 {
00198 MESHERROR << "Unable to read binary file, memory mapping failed."
00199 << endl;
00200 return false;
00201 }
00202
00203 CloseHandle( map );
00204 return result;
00205
00206 #else
00207
00208 int fd = open( filename.c_str(), O_RDONLY );
00209 if( fd < 0 )
00210 return false;
00211
00212 MESHINFO << "Reading cached binary representation." << endl;
00213
00214
00215 struct stat status;
00216 fstat( fd, &status );
00217
00218
00219 char* addr = static_cast< char* >( mmap( 0, status.st_size, PROT_READ,
00220 MAP_SHARED, fd, 0 ) );
00221 bool result = false;
00222 if( addr != MAP_FAILED )
00223 {
00224 try
00225 {
00226 fromMemory( addr );
00227 result = true;
00228 }
00229 catch( exception& e )
00230 {
00231 MESHERROR << "Unable to read binary file, an exception occured: "
00232 << e.what() << endl;
00233 }
00234 munmap( addr, status.st_size );
00235 }
00236 else
00237 {
00238 MESHERROR << "Unable to read binary file, memory mapping failed."
00239 << endl;
00240 }
00241
00242 close( fd );
00243 return result;
00244 #endif
00245 }
00246
00247
00248
00249 bool VertexBufferRoot::readFromFile( const std::string& filename )
00250 {
00251 if( _readBinary( getArchitectureFilename( filename )))
00252 {
00253 _name = filename;
00254 return true;
00255 }
00256 if( _constructFromPly( filename ))
00257 {
00258 _name = filename;
00259 return true;
00260 }
00261 return false;
00262 }
00263
00264
00265 bool VertexBufferRoot::writeToFile( const std::string& filename )
00266 {
00267 bool result = false;
00268
00269 ofstream output( getArchitectureFilename( filename ).c_str(),
00270 ios::out | ios::binary );
00271 if( output )
00272 {
00273
00274 output.exceptions( ofstream::failbit | ofstream::badbit );
00275 try
00276 {
00277 toStream( output );
00278 result = true;
00279 }
00280 catch( exception& e )
00281 {
00282 MESHERROR << "Unable to write binary file, an exception "
00283 << "occured: " << e.what() << endl;
00284 }
00285 output.close();
00286 }
00287 else
00288 {
00289 MESHERROR << "Unable to create binary file." << endl;
00290 }
00291
00292 return result;
00293 }
00294
00295
00296
00297 void VertexBufferRoot::fromMemory( char* start )
00298 {
00299 char** addr = &start;
00300 size_t version;
00301 memRead( reinterpret_cast< char* >( &version ), addr, sizeof( size_t ) );
00302 if( version != FILE_VERSION )
00303 throw MeshException( "Error reading binary file. Version in file "
00304 "does not match the expected version." );
00305 size_t nodeType;
00306 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
00307 if( nodeType != ROOT_TYPE )
00308 throw MeshException( "Error reading binary file. Expected the root "
00309 "node, but found something else instead." );
00310 _data.fromMemory( addr );
00311 VertexBufferNode::fromMemory( addr, _data );
00312 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
00313 if( nodeType != ROOT_TYPE )
00314 throw MeshException( "Error reading binary file. Expected a custom "
00315 "EOF marker, but found something else instead." );
00316 }
00317
00318
00319
00320 void VertexBufferRoot::toStream( std:: ostream& os )
00321 {
00322 size_t version = FILE_VERSION;
00323 os.write( reinterpret_cast< char* >( &version ), sizeof( size_t ) );
00324 size_t nodeType = ROOT_TYPE;
00325 os.write( reinterpret_cast< char* >( &nodeType ), sizeof( size_t ) );
00326 _data.toStream( os );
00327 VertexBufferNode::toStream( os );
00328 os.write( reinterpret_cast< char* >( &nodeType ), sizeof( size_t ) );
00329 }
00330
00331 }