OpenWalnut
1.4.0
|
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/shared_ptr.hpp> 00031 00032 #include "../../common/WAssert.h" 00033 #include "../../common/WIOTools.h" 00034 #include "../../common/WLogger.h" 00035 #include "../../common/WStringUtils.h" 00036 #include "../exceptions/WDHException.h" 00037 #include "../exceptions/WDHIOFailure.h" 00038 #include "WReader.h" 00039 #include "WReaderMatrixSymVTK.h" 00040 00041 WReaderMatrixSymVTK::WReaderMatrixSymVTK( std::string fname ) 00042 : WReader( fname ) 00043 { 00044 } 00045 00046 void WReaderMatrixSymVTK::readTable( boost::shared_ptr< std::vector< double > > table ) const 00047 { 00048 WAssert( table->size() == 0, "Non-zero size indicates an error, since the vector will be filled IN HERE." ); 00049 00050 // code mainly taken from WLoaderFibers.cpp, and adjusted since I don't 00051 // know how to code this DRY. Any suggestions? 00052 std::ifstream ifs; 00053 ifs.open( m_fname.c_str(), std::ifstream::in | std::ifstream::binary ); 00054 WAssert( ifs && !ifs.bad(), "" ); 00055 00056 std::vector< std::string > header; 00057 std::string line; 00058 try 00059 { 00060 for( int i = 0; i < 4; ++i ) // strip first four lines 00061 { 00062 std::getline( ifs, line ); 00063 if( !ifs.good() ) 00064 { 00065 throw WDHException( std::string( "Unexpected end of file: " + m_fname ) ); 00066 } 00067 header.push_back( line ); 00068 } 00069 } 00070 catch( const std::ios_base::failure &e ) 00071 { 00072 throw WDHIOFailure( std::string( "Reading first 4 lines of '" + m_fname + "': " + e.what() ) ); 00073 } 00074 if( header[0] != "# vtk DataFile Version 3.0" ) 00075 { 00076 wlog::warn( "WReaderMatrixSymVTK" ) << "Wrong version string in file header found, expected: " 00077 "\"# vtk DataFile Version 3.0\" but got: " << header[0]; 00078 } 00079 if( header[2] != "BINARY" ) 00080 { 00081 wlog::error( "WReaderMatrixSymVTK" ) << "Wrong data format: BINARY expected but got: " << header[2]; 00082 throw WDHIOFailure( "Error reading file '" + m_fname + " invalid binary format." ); 00083 } 00084 if( header[3] != "FIELD WMatrixSym 1" ) 00085 { 00086 wlog::error( "WReaderMatrixSymVTK" ) << "Wrong field desc in file header found: " << header[3] << " but expected: \"FIELD WMatrixSym 1\""; 00087 throw WDHIOFailure( "Error reading file '" + m_fname + " invalid VTK field name." ); 00088 } 00089 00090 try 00091 { 00092 std::getline( ifs, line ); // something like this: "DISTANCES 15879430 1 float" expected 00093 } 00094 catch( const std::ios_base::failure &e ) 00095 { 00096 throw WDHIOFailure( std::string( "Error reading ELEMENTS field '" + m_fname + "': " + e.what() ) ); 00097 } 00098 namespace su = string_utils; 00099 size_t numDistances = 0; 00100 std::vector< std::string > tokens = su::tokenize( line ); 00101 if( tokens.size() != 4 || su::toLower( tokens.at( 3 ) ) != "float" ) 00102 { 00103 throw WDHException( std::string( "Invalid ELEMENTS declaration: " + line ) ); 00104 } 00105 try 00106 { 00107 numDistances = string_utils::fromString< size_t >( tokens.at( 1 ) ); 00108 } 00109 catch( const std::exception &e ) 00110 { 00111 throw WDHException( std::string( "Invalid number of elements: " + tokens.at( 1 ) ) ); 00112 } 00113 00114 float *data = new float[ numDistances ]; 00115 try 00116 { 00117 ifs.read( reinterpret_cast< char* >( data ), sizeof( float ) * numDistances ); 00118 } 00119 catch( const std::ios_base::failure &e ) 00120 { 00121 throw WDHIOFailure( std::string( "Error reading elements in VTK ELEMENTS field '" + m_fname + "': " + e.what() ) ); 00122 } 00123 00124 // all 4 bytes of each float are in wrong order we need to reorder them 00125 switchByteOrderOfArray( data, numDistances ); 00126 00127 for( size_t i = 0; i < numDistances; ++i ) 00128 { 00129 table->push_back( static_cast< double >( data[ i ] ) ); 00130 } 00131 00132 delete[] data; 00133 }