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