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