WValueSet.h 9.71 KB
Newer Older
1 2
//---------------------------------------------------------------------------
//
3
// Project: OpenWalnut ( http://www.openwalnut.org )
4
//
5 6
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
//
// 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 <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#ifndef WVALUESET_H
#define WVALUESET_H

#include <cstddef>
#include <vector>

31
#include "../common/math/WValue.h"
32 33
#include "../common/math/WVector3D.h"
#include "../common/WAssert.h"
34
#include "../common/WLimits.h"
35 36
#include "WDataHandlerEnums.h"
#include "WValueSetBase.h"
37 38 39

/**
 * Base Class for all value set types.
40
 * \ingroup dataHandler
41 42 43 44 45 46 47 48 49
 */
template< typename T > class WValueSet : public WValueSetBase
{
/**
 * Only UnitTests are allowed to be friends
 */
friend class WValueSetTest;

public:
50 51 52 53 54
    /**
     * The type of the single value in this value set.
     */
    typedef T ValueT;

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    /**
     * \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.
Alexander Wiebel's avatar
Alexander Wiebel committed
93
         * \param size The size of the subarray.
94 95 96 97 98 99 100 101 102 103 104 105 106 107
         */
        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;
    };

108
    /**
109 110
     * 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.
111 112 113 114
     * \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
115
     */
116
    WValueSet( size_t order, size_t dimension, const std::vector< T > data, dataType inDataType )
117
        : WValueSetBase( order, dimension, inDataType ),
118 119
          m_data( data )
    {
120 121 122 123 124 125 126 127 128
        // 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;
        }
129 130 131 132 133 134 135 136 137
    }

    /**
     * \return The number of tensors stored in this set.
     */
    virtual size_t size() const
    {
        switch( m_order )
        {
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
138
            case 0  :  // scalar
139 140
                WAssert( m_dimension == 1, "Although order zero, (dimension != 1) was found." );
                return rawSize();
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
141
            case 1  :  // vector
142 143
                WAssert( rawSize() % m_dimension == 0, "Raw size and dimension don't fit." );
                return rawSize() / m_dimension;
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
144
            case 2  :  // matrix
145 146
                WAssert( rawSize() % ( m_dimension * m_dimension ) == 0, "Raw size and dimension don't fit." );
                return rawSize() / ( m_dimension * m_dimension );
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
147
            default :  // other
148 149
                WAssert( false, "Unsupported tensor order." );
                return 0;
150 151 152 153
        }
    }

    /**
Alexander Wiebel's avatar
Alexander Wiebel committed
154
     * \return The number of integral types stored in this set.
155 156 157 158 159 160
     */
    virtual size_t rawSize() const
    {
        return m_data.size();
    }

161
    /**
162
     * \param i id of the scalar to retrieve
Alexander Wiebel's avatar
Alexander Wiebel committed
163
     * \return The i-th scalar stored in this value set. There are rawSize() such scalars.
164 165 166 167 168 169
     */
    virtual T getScalar( size_t i ) const
    {
        return m_data[i];
    }

170 171 172 173 174 175 176 177 178
    /**
     * \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] );
    }

179 180 181 182 183 184 185 186 187
    /**
     * \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 ) );
    }

188 189 190 191 192 193 194 195 196
    /**
     * Get the i'th vector
     *
     * \param index the index number of the vector
     *
     * \return the vector
     */
    wmath::WVector3D getVector3D( size_t index ) const;

Stefan Philips's avatar
Added:  
Stefan Philips committed
197 198 199 200 201 202 203 204 205 206

    /**
     * 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;

207 208 209
    /**
     * Sometimes we need raw access to the data array, for e.g. OpenGL.
     */
210
    const T * rawData() const
211 212 213 214
    {
        return &m_data[0];
    }

215 216 217 218 219 220 221 222
    /**
     * Sometimes we need raw access to the data vector.
     */
    const std::vector< T >* rawDataVectorPointer() const
    {
        return &m_data;
    }

223 224
    /**
     * Request (read-) access object to a subarray of this valueset.
reichenbach's avatar
reichenbach committed
225 226 227 228 229 230 231
     * 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.
232 233 234 235 236 237 238
     */
    SubArray const getSubArray( std::size_t start, std::size_t size ) const
    {
        WAssert( start + size <= rawSize(), "" );
        WAssert( size != 0, "" );
        return SubArray( rawData() + start, size );
    }
239

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
    /**
     * 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;
    }

262
protected:
263 264 265 266 267 268 269 270 271 272
    /**
     * The smallest value in m_data.
     */
    T m_minimum;

    /**
     * The largest value in m_data.
     */
    T m_maximum;

273 274 275 276 277
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!
278 279 280 281 282 283 284 285 286 287

    /**
     * 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 );
    }
288 289
};

290 291 292
template< typename T > wmath::WVector3D WValueSet< T >::getVector3D( size_t index ) const
{
    WAssert( m_order == 1 && m_dimension == 3, "WValueSet<T>::getVector3D only implemented for order==1, dim==3 value sets" );
Stefan Philips's avatar
Stefan Philips committed
293
    WAssert( ( index + 1 ) * 3 <= m_data.size(), "index in WValueSet<T>::getVector3D too big" );
294 295 296 297
    size_t offset = index * 3;
    return wmath::WVector3D( m_data[ offset ], m_data[ offset + 1 ], m_data[ offset + 2 ] );
}

Stefan Philips's avatar
Added:  
Stefan Philips committed
298 299 300
template< typename T > wmath::WValue< T > WValueSet< T >::getWValue( size_t index ) const
{
    WAssert( m_order == 1, "WValueSet<T>::getWValue only implemented for order==1 value sets" );
Stefan Philips's avatar
Stefan Philips committed
301
    WAssert( ( index + 1 ) * m_dimension <= m_data.size(), "index in WValueSet<T>::getWValue too big" );
Stefan Philips's avatar
Added:  
Stefan Philips committed
302 303 304 305 306 307

    size_t offset = index * m_dimension;

    wmath::WValue< T > result( m_dimension );

    // copying values
308
    for ( std::size_t i = 0; i < m_dimension; i++ )
Stefan Philips's avatar
Added:  
Stefan Philips committed
309 310 311 312 313
      result[i] = m_data[ offset+i ];

    return result;
}

314
#endif  // WVALUESET_H