OpenWalnut 1.3.1
|
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 #ifndef WVALUESET_H 00026 #define WVALUESET_H 00027 00028 #include <cmath> 00029 #include <cstddef> 00030 #include <limits> 00031 #include <vector> 00032 #include <boost/shared_ptr.hpp> 00033 00034 #include "../common/math/WValue.h" 00035 #include "../common/math/linearAlgebra/WLinearAlgebra.h" 00036 #include "../common/WAssert.h" 00037 #include "../common/WLimits.h" 00038 #include "WDataHandlerEnums.h" 00039 #include "WValueSetBase.h" 00040 00041 /** 00042 * Base Class for all value set types. 00043 * \ingroup dataHandler 00044 */ 00045 template< typename T > class WValueSet : public WValueSetBase 00046 { 00047 /** 00048 * Only UnitTests are allowed to be friends 00049 */ 00050 friend class WValueSetTest; 00051 00052 public: 00053 /** 00054 * The type of the single value in this value set. 00055 */ 00056 typedef T ValueT; 00057 00058 /** 00059 * \class SubArray 00060 * 00061 * A helper class granting safe access to a certain part of the valueset. 00062 */ 00063 class SubArray 00064 { 00065 public: 00066 //! make the valueset a friend 00067 friend class WValueSet; 00068 00069 /** 00070 * Destructor. 00071 */ 00072 ~SubArray() 00073 { 00074 } 00075 00076 /** 00077 * Safe access. Only the const version is allowed. 00078 * 00079 * \param i The relative position of the element in the subarray's range. 00080 * 00081 * \note If i is not in ( 0, size - 1 ), the first element will be returned. 00082 * 00083 * \return the value 00084 */ 00085 T const& operator[] ( std::size_t i ) const 00086 { 00087 return *( m_ptr + i * static_cast< std::size_t >( i < m_size ) ); 00088 } 00089 00090 // use the standard copy constructor and operator 00091 private: 00092 /** 00093 * Construct an object that allows safe access. 00094 * (no access to elements not in the subarray's range). 00095 * Only a valueset may construct a SubArray. 00096 * 00097 * \param p A pointer to the first element. 00098 * \param size The size of the subarray. 00099 */ 00100 SubArray( T const* const p, std::size_t size ) 00101 : m_ptr( p ), 00102 m_size( size ) 00103 { 00104 } 00105 00106 //! the pointer to the first element 00107 T const* const m_ptr; 00108 00109 //! the size of the subarray 00110 std::size_t const m_size; 00111 }; 00112 00113 /** 00114 * Constructs a value set with values of type T. Sets order and dimension 00115 * to allow to interpret the values as tensors of a certain order and dimension. 00116 * \param order tensor order of values stored in the value set 00117 * \param dimension tensor dimension of values stored in the value set 00118 * \param data the vector holding the raw data 00119 * \param inDataType indicator telling us which dataType comes in 00120 */ 00121 WValueSet( size_t order, size_t dimension, const boost::shared_ptr< std::vector< T > > data, dataType inDataType ) 00122 : WValueSetBase( order, dimension, inDataType ), 00123 m_data( data ) 00124 { 00125 // calculate min and max 00126 // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ... 00127 m_minimum = std::numeric_limits< T >::max(); 00128 m_maximum = std::numeric_limits< T >::min(); 00129 for( typename std::vector< T >::const_iterator iter = data->begin(); iter != data->end(); ++iter ) 00130 { 00131 m_minimum = m_minimum > *iter ? *iter : m_minimum; 00132 m_maximum = m_maximum < *iter ? *iter : m_maximum; 00133 } 00134 } 00135 00136 /** 00137 * Constructs a value set with values of type T. Sets order and dimension 00138 * to allow to interpret the values as tensors of a certain order and dimension. 00139 * \param order tensor order of values stored in the value set 00140 * \param dimension tensor dimension of values stored in the value set 00141 * \param data the vector holding the raw data 00142 */ 00143 WValueSet( size_t order, size_t dimension, const boost::shared_ptr< std::vector< T > > data ) 00144 : WValueSetBase( order, dimension, DataType< T >::type ), 00145 m_data( data ) 00146 { 00147 // calculate min and max 00148 // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ... 00149 m_minimum = std::numeric_limits< T >::max(); 00150 m_maximum = std::numeric_limits< T >::min(); 00151 for( typename std::vector< T >::const_iterator iter = data->begin(); iter != data->end(); ++iter ) 00152 { 00153 m_minimum = m_minimum > *iter ? *iter : m_minimum; 00154 m_maximum = m_maximum < *iter ? *iter : m_maximum; 00155 } 00156 } 00157 00158 /** 00159 * \return The number of tensors stored in this set. 00160 */ 00161 virtual size_t size() const 00162 { 00163 switch( m_order ) 00164 { 00165 case 0 : // scalar 00166 WAssert( m_dimension == 1, "Although order zero, (dimension != 1) was found." ); 00167 return rawSize(); 00168 case 1 : // vector 00169 WAssert( rawSize() % m_dimension == 0, "Raw size and dimension don't fit." ); 00170 return rawSize() / m_dimension; 00171 case 2 : // matrix 00172 WAssert( rawSize() % ( m_dimension * m_dimension ) == 0, "Raw size and dimension don't fit." ); 00173 return rawSize() / ( m_dimension * m_dimension ); 00174 default : // other 00175 WAssert( false, "Unsupported tensor order." ); 00176 return 0; 00177 } 00178 } 00179 00180 /** 00181 * \return The number of integral types stored in this set. 00182 */ 00183 virtual size_t rawSize() const 00184 { 00185 return (*m_data.get()).size(); 00186 } 00187 00188 /** 00189 * \param i id of the scalar to retrieve 00190 * \return The i-th scalar stored in this value set. There are rawSize() such scalars. 00191 */ 00192 virtual T getScalar( size_t i ) const 00193 { 00194 return (*m_data.get())[i]; 00195 } 00196 00197 /** 00198 * \param i id of the scalar to retrieve 00199 * \return The i-th scalar stored in this value set. There are rawSize() such scalars. 00200 */ 00201 virtual double getScalarDouble( size_t i ) const 00202 { 00203 return static_cast< double >( (*m_data.get())[i] ); 00204 } 00205 00206 /** 00207 * \param i id of the WValue to retrieve 00208 * \return The i-th WValue stored in this value set. There are size() such scalars. 00209 */ 00210 virtual WValue< double > getWValueDouble( size_t i ) const 00211 { 00212 return WValue< double >( getWValue( i ) ); 00213 } 00214 00215 /** 00216 * \param i id of the WVector to retrieve 00217 * \return The i-th WValue (stored in this value set) as WVector. There are size() such scalars. 00218 */ 00219 virtual WVector_2 getWVector( size_t i ) const 00220 { 00221 return ( WValue< double >( getWValue( i ) ) ).toWVector(); 00222 } 00223 00224 /** 00225 * Get the i'th vector 00226 * 00227 * \param index the index number of the vector 00228 * 00229 * \return the vector 00230 */ 00231 WVector3d getVector3D( size_t index ) const; 00232 00233 00234 /** 00235 * Get the i'th WValue with the dimension of WValueSet 00236 * 00237 * \param index the index number of the WValue 00238 * 00239 * \return a WValue with the dimension WValueSet 00240 */ 00241 WValue< T > getWValue( size_t index ) const; 00242 00243 /** 00244 * Sometimes we need raw access to the data array, for e.g. OpenGL. 00245 * 00246 * \return the raw data pointer 00247 */ 00248 const T * rawData() const 00249 { 00250 return &(*m_data.get())[0]; 00251 } 00252 00253 /** 00254 * Sometimes we need raw access to the data vector. 00255 * 00256 * \return the data vector 00257 */ 00258 const std::vector< T >* rawDataVectorPointer() const 00259 { 00260 return &(*m_data.get()); 00261 } 00262 00263 /** 00264 * Request (read-) access object to a subarray of this valueset. 00265 * The object returned by this function can be used as an array 00266 * ( starting at index 0 ), whose elements are the data elements 00267 * at positions start to ( including ) start + size - 1 of the valueset. 00268 * 00269 * \param start The position of the first element of the subarray. 00270 * \param size The number of elements in the subarray. 00271 * \return The subarray. 00272 */ 00273 SubArray const getSubArray( std::size_t start, std::size_t size ) const 00274 { 00275 WAssert( start + size <= rawSize(), "" ); 00276 WAssert( size != 0, "" ); 00277 return SubArray( rawData() + start, size ); 00278 } 00279 00280 /** 00281 * This method returns the smallest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the 00282 * smallest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms). 00283 * 00284 * \return the smallest value in the data. 00285 */ 00286 virtual double getMinimumValue() const 00287 { 00288 return m_minimum; 00289 } 00290 00291 /** 00292 * This method returns the largest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the 00293 * largest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms). 00294 * 00295 * \return the largest value in the data. 00296 */ 00297 virtual double getMaximumValue() const 00298 { 00299 return m_maximum; 00300 } 00301 00302 /** 00303 * Calculates the needed number of integral values for a valueset with specified order and dimension for one voxel. The whole dataset will 00304 * then be as large as the number of voxels multiplied by this value. 00305 * 00306 * \param oder desired tensor order. 00307 * \param dimension desired dimension. 00308 * 00309 * \return the number of values needed 00310 */ 00311 static size_t getRequiredRawSizePerVoxel( size_t oder, size_t dimension ); 00312 protected: 00313 /** 00314 * The smallest value in m_data. 00315 */ 00316 T m_minimum; 00317 00318 /** 00319 * The largest value in m_data. 00320 */ 00321 T m_maximum; 00322 00323 private: 00324 /** 00325 * Stores the values of type T as simple array which never should be modified. 00326 */ 00327 const boost::shared_ptr< std::vector< T > > m_data; // WARNING: don't remove constness since &m_data[0] won't work anymore! 00328 00329 /** 00330 * Get a variant reference to this valueset (the reference is stored in the variant). 00331 * \note Use this as a temporary object inside a function or something like that. 00332 * \return var A variant reference. 00333 */ 00334 virtual WValueSetVariant const getVariant() const 00335 { 00336 return WValueSetVariant( this ); 00337 } 00338 }; 00339 00340 template< typename T > WVector3d WValueSet< T >::getVector3D( size_t index ) const 00341 { 00342 WAssert( m_order == 1 && m_dimension == 3, "WValueSet<T>::getVector3D only implemented for order==1, dim==3 value sets" ); 00343 WAssert( ( index + 1 ) * 3 <= m_data->size(), "index in WValueSet<T>::getVector3D too big" ); 00344 size_t offset = index * 3; 00345 return WVector3d( ( *m_data )[offset], ( *m_data )[offset + 1], ( *m_data )[offset + 2] ); 00346 } 00347 00348 template< typename T > WValue< T > WValueSet< T >::getWValue( size_t index ) const 00349 { 00350 WAssert( m_order == 1, "WValueSet<T>::getWValue only implemented for order==1 value sets" ); 00351 WAssert( ( index + 1 ) * m_dimension <= m_data->size(), "index in WValueSet<T>::getWValue too big" ); 00352 00353 size_t offset = index * m_dimension; 00354 00355 WValue< T > result( m_dimension ); 00356 00357 // copying values 00358 for( std::size_t i = 0; i < m_dimension; i++ ) 00359 result[i] = ( *m_data )[offset+i]; 00360 00361 return result; 00362 } 00363 00364 template< typename T > 00365 size_t WValueSet< T >::getRequiredRawSizePerVoxel( size_t oder, size_t dimension ) 00366 { 00367 // NOTE: std::pow works only for floating point types 00368 size_t pow = 1; 00369 for( size_t v = 0; v < oder; ++v ) 00370 { 00371 pow *= dimension; 00372 } 00373 00374 return pow; 00375 } 00376 00377 #endif // WVALUESET_H