OpenWalnut 1.2.5
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #include <fstream> 00026 #include <stdexcept> 00027 #include <string> 00028 #include <vector> 00029 00030 #include <boost/lexical_cast.hpp> 00031 #include <boost/shared_ptr.hpp> 00032 00033 #include "../../common/WAssert.h" 00034 #include "../../common/WIOTools.h" 00035 #include "../../common/WLogger.h" 00036 #include "../../common/WStringUtils.h" 00037 #include "../exceptions/WDHException.h" 00038 #include "../exceptions/WDHIOFailure.h" 00039 #include "WReader.h" 00040 #include "WReaderMatrixSymVTK.h" 00041 00042 WReaderMatrixSymVTK::WReaderMatrixSymVTK( std::string fname ) 00043 : WReader( fname ) 00044 { 00045 } 00046 00047 void WReaderMatrixSymVTK::readTable( boost::shared_ptr< std::vector< double > > table ) const 00048 { 00049 WAssert( table->size() == 0, "Non-zero size indicates an error, since the vector will be filled IN HERE." ); 00050 00051 // code mainly taken from WLoaderFibers.cpp, and adjusted since I don't 00052 // know how to code this DRY. Any suggestions? 00053 std::ifstream ifs; 00054 ifs.open( m_fname.c_str(), std::ifstream::in | std::ifstream::binary ); 00055 WAssert( ifs && !ifs.bad(), "" ); 00056 00057 std::vector< std::string > header; 00058 std::string line; 00059 try 00060 { 00061 for( int i = 0; i < 4; ++i ) // strip first four lines 00062 { 00063 std::getline( ifs, line ); 00064 if( !ifs.good() ) 00065 { 00066 throw WDHException( std::string( "Unexpected end of file: " + m_fname ) ); 00067 } 00068 header.push_back( line ); 00069 } 00070 } 00071 catch( const std::ios_base::failure &e ) 00072 { 00073 throw WDHIOFailure( std::string( "Reading first 4 lines of '" + m_fname + "': " + e.what() ) ); 00074 } 00075 if( header[0] != "# vtk DataFile Version 3.0" ) 00076 { 00077 wlog::warn( "WReaderMatrixSymVTK" ) << "Wrong version string in file header found, expected: " 00078 "\"# vtk DataFile Version 3.0\" but got: " << header[0]; 00079 } 00080 if( header[2] != "BINARY" ) 00081 { 00082 wlog::error( "WReaderMatrixSymVTK" ) << "Wrong data format: BINARY expected but got: " << header[2]; 00083 throw WDHIOFailure( "Error reading file '" + m_fname + " invalid binary format." ); 00084 } 00085 if( header[3] != "FIELD WMatrixSym 1" ) 00086 { 00087 wlog::error( "WReaderMatrixSymVTK" ) << "Wrong field desc in file header found: " << header[3] << " but expected: \"FIELD WMatrixSym 1\""; 00088 throw WDHIOFailure( "Error reading file '" + m_fname + " invalid VTK field name." ); 00089 } 00090 00091 try 00092 { 00093 std::getline( ifs, line ); // something like this: "DISTANCES 15879430 1 float" expected 00094 } 00095 catch( const std::ios_base::failure &e ) 00096 { 00097 throw WDHIOFailure( std::string( "Error reading ELEMENTS field '" + m_fname + "': " + e.what() ) ); 00098 } 00099 namespace su = string_utils; 00100 size_t numDistances = 0; 00101 std::vector< std::string > tokens = su::tokenize( line ); 00102 if( tokens.size() != 4 || su::toLower( tokens.at( 3 ) ) != "float" ) 00103 { 00104 throw WDHException( std::string( "Invalid ELEMENTS declaration: " + line ) ); 00105 } 00106 try 00107 { 00108 numDistances = boost::lexical_cast< size_t >( tokens.at( 1 ) ); 00109 } 00110 catch( const boost::bad_lexical_cast &e ) 00111 { 00112 throw WDHException( std::string( "Invalid number of elements: " + tokens.at( 1 ) ) ); 00113 } 00114 00115 float *data = new float[ numDistances ]; 00116 try 00117 { 00118 ifs.read( reinterpret_cast< char* >( data ), sizeof( float ) * numDistances ); 00119 } 00120 catch( const std::ios_base::failure &e ) 00121 { 00122 throw WDHIOFailure( std::string( "Error reading elements in VTK ELEMENTS field '" + m_fname + "': " + e.what() ) ); 00123 } 00124 00125 // all 4 bytes of each float are in wrong order we need to reorder them 00126 switchByteOrderOfArray( data, numDistances ); 00127 00128 for( size_t i = 0; i < numDistances; ++i ) 00129 { 00130 table->push_back( static_cast< double >( data[ i ] ) ); 00131 } 00132 00133 delete[] data; 00134 }