//--------------------------------------------------------------------------- // // Project: OpenWalnut ( http://www.openwalnut.org ) // // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS // For more information see http://www.openwalnut.org/copying // // This file is part of OpenWalnut. // // OpenWalnut is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // OpenWalnut is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with OpenWalnut. If not, see . // //--------------------------------------------------------------------------- #ifndef WVALUESET_H #define WVALUESET_H #include #include #include "../common/math/WValue.h" #include "../common/math/WVector3D.h" #include "../common/WAssert.h" #include "../common/WLimits.h" #include "WDataHandlerEnums.h" #include "WValueSetBase.h" /** * Base Class for all value set types. * \ingroup dataHandler */ template< typename T > class WValueSet : public WValueSetBase { /** * Only UnitTests are allowed to be friends */ friend class WValueSetTest; public: /** * The type of the single value in this value set. */ typedef T ValueT; /** * \class SubArray * * A helper class granting safe access to a certain part of the valueset. */ class SubArray { public: //! make the valueset a friend friend class WValueSet; /** * Destructor. */ ~SubArray() { } /** * Safe access. Only the const version is allowed. * * \param i The relative position of the element in the subarray's range. * * \note If i is not in ( 0, size - 1 ), the first element will be returned. */ T const& operator[] ( std::size_t i ) const { return *( m_ptr + i * static_cast< std::size_t >( i < m_size ) ); } // use the standard copy constructor and operator private: /** * Construct an object that allows safe access. * (no access to elements not in the subarray's range). * Only a valueset may construct a SubArray. * * \param p A pointer to the first element. * \param size The size of the subarray. */ SubArray( T const* const p, std::size_t size ) : m_ptr( p ), m_size( size ) { } //! the pointer to the first element T const* const m_ptr; //! the size of the subarray std::size_t const m_size; }; /** * Constructs a value set with values of type T. Sets order and dimension * to allow to interprete the values as tensors of a certain order and dimension. * \param order tensor order of values stored in the value set * \param dimension tensor dimension of values stored in the value set * \param data the vector holding the raw data * \param inDataType indicator teeling us which dataType comes in */ WValueSet( size_t order, size_t dimension, const std::vector< T > data, dataType inDataType ) : WValueSetBase( order, dimension, inDataType ), m_data( data ) { // calculate min and max // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ... m_minimum = wlimits::MAX_DOUBLE; m_maximum = wlimits::MIN_DOUBLE; for ( typename std::vector< T >::const_iterator iter = data.begin(); iter != data.end(); ++iter ) { m_minimum = m_minimum > *iter ? *iter : m_minimum; m_maximum = m_maximum < *iter ? *iter : m_maximum; } } /** * \return The number of tensors stored in this set. */ virtual size_t size() const { switch( m_order ) { case 0 : // scalar WAssert( m_dimension == 1, "Although order zero, (dimension != 1) was found." ); return rawSize(); case 1 : // vector WAssert( rawSize() % m_dimension == 0, "Raw size and dimension don't fit." ); return rawSize() / m_dimension; case 2 : // matrix WAssert( rawSize() % ( m_dimension * m_dimension ) == 0, "Raw size and dimension don't fit." ); return rawSize() / ( m_dimension * m_dimension ); default : // other WAssert( false, "Unsupported tensor order." ); return 0; } } /** * \return The number of integral types stored in this set. */ virtual size_t rawSize() const { return m_data.size(); } /** * \param i id of the scalar to retrieve * \return The i-th scalar stored in this value set. There are rawSize() such scalars. */ virtual T getScalar( size_t i ) const { return m_data[i]; } /** * \param i id of the scalar to retrieve * \return The i-th scalar stored in this value set. There are rawSize() such scalars. */ virtual double getScalarDouble( size_t i ) const { return static_cast< double >( m_data[i] ); } /** * \param i id of the WValue to retrieve * \return The i-th WValue stored in this value set. There are size() such scalars. */ virtual wmath::WValue< double > getWValueDouble( size_t i ) const { return wmath::WValue< double >( getWValue( i ) ); } /** * Get the i'th vector * * \param index the index number of the vector * * \return the vector */ wmath::WVector3D getVector3D( size_t index ) const; /** * Get the i'th WValue with the dimension of WValueSet * * \param index the index number of the WValue * * \return a WValue with the dimension WValueSet */ wmath::WValue< T > getWValue( size_t index ) const; /** * Sometimes we need raw access to the data array, for e.g. OpenGL. */ const T * rawData() const { return &m_data[0]; } /** * Sometimes we need raw access to the data vector. */ const std::vector< T >* rawDataVectorPointer() const { return &m_data; } /** * Request (read-) access object to a subarray of this valueset. * The object returned by this function can be used as an array * ( starting at index 0 ), whose elements are the data elements * at positions start to ( including ) start + size - 1 of the valueset. * * \param start The position of the first element of the subarray. * \param size The number of elements in the subarray. * \return The subarray. */ SubArray const getSubArray( std::size_t start, std::size_t size ) const { WAssert( start + size <= rawSize(), "" ); WAssert( size != 0, "" ); return SubArray( rawData() + start, size ); } /** * This method returns the smallest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the * smallest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms). * * \return the smallest value in the data. */ virtual double getMinimumValue() const { return m_minimum; } /** * This method returns the largest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the * largest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms). * * \return the largest value in the data. */ virtual double getMaximumValue() const { return m_maximum; } protected: /** * The smallest value in m_data. */ T m_minimum; /** * The largest value in m_data. */ T m_maximum; private: /** * Stores the values of type T as simple array which never should be modified. */ const std::vector< T > m_data; // WARNING: don't remove constness since &m_data[0] won't work anymore! /** * Get a variant reference to this valueset (the reference is stored in the variant). * \note Use this as a temporary object inside a function or something like that. * \return var A variant reference. */ virtual WValueSetVariant const getVariant() const { return WValueSetVariant( this ); } }; template< typename T > wmath::WVector3D WValueSet< T >::getVector3D( size_t index ) const { WAssert( m_order == 1 && m_dimension == 3, "WValueSet::getVector3D only implemented for order==1, dim==3 value sets" ); WAssert( ( index + 1 ) * 3 <= m_data.size(), "index in WValueSet::getVector3D too big" ); size_t offset = index * 3; return wmath::WVector3D( m_data[ offset ], m_data[ offset + 1 ], m_data[ offset + 2 ] ); } template< typename T > wmath::WValue< T > WValueSet< T >::getWValue( size_t index ) const { WAssert( m_order == 1, "WValueSet::getWValue only implemented for order==1 value sets" ); WAssert( ( index + 1 ) * m_dimension <= m_data.size(), "index in WValueSet::getWValue too big" ); size_t offset = index * m_dimension; wmath::WValue< T > result( m_dimension ); // copying values for ( std::size_t i = 0; i < m_dimension; i++ ) result[i] = m_data[ offset+i ]; return result; } #endif // WVALUESET_H