OpenWalnut  1.4.0
WValueSet.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WVALUESET_H
26 #define WVALUESET_H
27 
28 #include <cmath>
29 #include <cstddef>
30 #include <limits>
31 #include <vector>
32 
33 #include <boost/shared_ptr.hpp>
34 
35 #include "../common/math/linearAlgebra/WVectorFixed.h"
36 #include "../common/math/WValue.h"
37 #include "../common/WAssert.h"
38 #include "../common/WLimits.h"
39 #include "WDataHandlerEnums.h"
40 #include "WValueSetBase.h"
41 
42 /**
43  * Base Class for all value set types.
44  * \ingroup dataHandler
45  */
46 template< typename T > class WValueSet : public WValueSetBase
47 {
48 /**
49  * Only UnitTests are allowed to be friends
50  */
51 friend class WValueSetTest;
52 
53 public:
54  /**
55  * The type of the single value in this value set.
56  */
57  typedef T ValueT;
58 
59  /**
60  * \class SubArray
61  *
62  * A helper class granting safe access to a certain part of the valueset.
63  */
64  class SubArray
65  {
66  public:
67  //! make the valueset a friend
68  friend class WValueSet;
69 
70  /**
71  * Destructor.
72  */
74  {
75  }
76 
77  /**
78  * Safe access. Only the const version is allowed.
79  *
80  * \param i The relative position of the element in the subarray's range.
81  *
82  * \note If i is not in ( 0, size - 1 ), the first element will be returned.
83  *
84  * \return the value
85  */
86  T const& operator[] ( std::size_t i ) const
87  {
88  return *( m_ptr + i * static_cast< std::size_t >( i < m_size ) );
89  }
90 
91  // use the standard copy constructor and operator
92  private:
93  /**
94  * Construct an object that allows safe access.
95  * (no access to elements not in the subarray's range).
96  * Only a valueset may construct a SubArray.
97  *
98  * \param p A pointer to the first element.
99  * \param size The size of the subarray.
100  */
101  SubArray( T const* const p, std::size_t size )
102  : m_ptr( p ),
103  m_size( size )
104  {
105  }
106 
107  //! the pointer to the first element
108  T const* const m_ptr;
109 
110  //! the size of the subarray
111  std::size_t const m_size;
112  };
113 
114  /**
115  * Constructs a value set with values of type T. Sets order and dimension
116  * to allow to interpret the values as tensors of a certain order and dimension.
117  * \param order tensor order of values stored in the value set
118  * \param dimension tensor dimension of values stored in the value set
119  * \param data the vector holding the raw data
120  * \param inDataType indicator telling us which dataType comes in
121  */
122  WValueSet( size_t order, size_t dimension, const boost::shared_ptr< std::vector< T > > data, dataType inDataType )
123  : WValueSetBase( order, dimension, inDataType ),
124  m_data( data )
125  {
126  // calculate min and max
127  // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ...
128  m_minimum = std::numeric_limits< T >::max();
129  m_maximum = std::numeric_limits< T >::min();
130  for( typename std::vector< T >::const_iterator iter = data->begin(); iter != data->end(); ++iter )
131  {
132  m_minimum = m_minimum > *iter ? *iter : m_minimum;
133  m_maximum = m_maximum < *iter ? *iter : m_maximum;
134  }
135  }
136 
137  /**
138  * Constructs a value set with values of type T. Sets order and dimension
139  * to allow to interpret the values as tensors of a certain order and dimension.
140  * \param order tensor order of values stored in the value set
141  * \param dimension tensor dimension of values stored in the value set
142  * \param data the vector holding the raw data
143  */
144  WValueSet( size_t order, size_t dimension, const boost::shared_ptr< std::vector< T > > data )
145  : WValueSetBase( order, dimension, DataType< T >::type ),
146  m_data( data )
147  {
148  // calculate min and max
149  // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ...
150  m_minimum = std::numeric_limits< T >::max();
151  m_maximum = std::numeric_limits< T >::min();
152  for( typename std::vector< T >::const_iterator iter = data->begin(); iter != data->end(); ++iter )
153  {
154  m_minimum = m_minimum > *iter ? *iter : m_minimum;
155  m_maximum = m_maximum < *iter ? *iter : m_maximum;
156  }
157  }
158 
159  /**
160  * \return The number of tensors stored in this set.
161  */
162  virtual size_t size() const
163  {
164  switch( m_order )
165  {
166  case 0 : // scalar
167  WAssert( m_dimension == 1, "Although order zero, (dimension != 1) was found." );
168  return rawSize();
169  case 1 : // vector
170  WAssert( rawSize() % m_dimension == 0, "Raw size and dimension don't fit." );
171  return rawSize() / m_dimension;
172  case 2 : // matrix
173  WAssert( rawSize() % ( m_dimension * m_dimension ) == 0, "Raw size and dimension don't fit." );
174  return rawSize() / ( m_dimension * m_dimension );
175  default : // other
176  WAssert( false, "Unsupported tensor order." );
177  return 0;
178  }
179  }
180 
181  /**
182  * \return The number of integral types stored in this set.
183  */
184  virtual size_t rawSize() const
185  {
186  return (*m_data.get()).size();
187  }
188 
189  /**
190  * \param i id of the scalar to retrieve
191  * \return The i-th scalar stored in this value set. There are rawSize() such scalars.
192  */
193  virtual T getScalar( size_t i ) const
194  {
195  return (*m_data.get())[i];
196  }
197 
198  /**
199  * \param i id of the scalar to retrieve
200  * \return The i-th scalar stored in this value set. There are rawSize() such scalars.
201  */
202  virtual double getScalarDouble( size_t i ) const
203  {
204  return static_cast< double >( (*m_data.get())[i] );
205  }
206 
207  /**
208  * \param i id of the WValue to retrieve
209  * \return The i-th WValue stored in this value set. There are size() such scalars.
210  */
211  virtual WValue< double > getWValueDouble( size_t i ) const
212  {
213  return WValue< double >( getWValue( i ) );
214  }
215 
216  /**
217  * Get the i'th vector
218  *
219  * \param index the index number of the vector
220  *
221  * \return the vector
222  */
223  WVector3d getVector3D( size_t index ) const;
224 
225 
226  /**
227  * Get the i'th WValue with the dimension of WValueSet
228  *
229  * \param index the index number of the WValue
230  *
231  * \return a WValue with the dimension WValueSet
232  */
233  WValue< T > getWValue( size_t index ) const;
234 
235  /**
236  * Sometimes we need raw access to the data array, for e.g. OpenGL.
237  *
238  * \return the raw data pointer
239  */
240  const T * rawData() const
241  {
242  return &(*m_data.get())[0];
243  }
244 
245  /**
246  * Sometimes we need raw access to the data vector.
247  *
248  * \return the data vector
249  */
250  const std::vector< T >* rawDataVectorPointer() const
251  {
252  return &(*m_data.get());
253  }
254 
255  /**
256  * Request (read-) access object to a subarray of this valueset.
257  * The object returned by this function can be used as an array
258  * ( starting at index 0 ), whose elements are the data elements
259  * at positions start to ( including ) start + size - 1 of the valueset.
260  *
261  * \param start The position of the first element of the subarray.
262  * \param size The number of elements in the subarray.
263  * \return The subarray.
264  */
265  SubArray const getSubArray( std::size_t start, std::size_t size ) const
266  {
267  WAssert( start + size <= rawSize(), "" );
268  WAssert( size != 0, "" );
269  return SubArray( rawData() + start, size );
270  }
271 
272  /**
273  * This method returns the smallest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
274  * smallest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
275  *
276  * \return the smallest value in the data.
277  */
278  virtual double getMinimumValue() const
279  {
280  return m_minimum;
281  }
282 
283  /**
284  * This method returns the largest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
285  * largest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
286  *
287  * \return the largest value in the data.
288  */
289  virtual double getMaximumValue() const
290  {
291  return m_maximum;
292  }
293 
294  /**
295  * Calculates the needed number of integral values for a valueset with specified order and dimension for one voxel. The whole dataset will
296  * then be as large as the number of voxels multiplied by this value.
297  *
298  * \param oder desired tensor order.
299  * \param dimension desired dimension.
300  *
301  * \return the number of values needed
302  */
303  static size_t getRequiredRawSizePerVoxel( size_t oder, size_t dimension );
304 protected:
305  /**
306  * The smallest value in m_data.
307  */
309 
310  /**
311  * The largest value in m_data.
312  */
314 
315 private:
316  /**
317  * Stores the values of type T as simple array which never should be modified.
318  */
319  const boost::shared_ptr< std::vector< T > > m_data; // WARNING: don't remove constness since &m_data[0] won't work anymore!
320 
321  /**
322  * Get a variant reference to this valueset (the reference is stored in the variant).
323  * \note Use this as a temporary object inside a function or something like that.
324  * \return var A variant reference.
325  */
326  virtual WValueSetVariant const getVariant() const
327  {
328  return WValueSetVariant( this );
329  }
330 };
331 
332 template< typename T > WVector3d WValueSet< T >::getVector3D( size_t index ) const
333 {
334  WAssert( m_order == 1 && m_dimension == 3, "WValueSet<T>::getVector3D only implemented for order==1, dim==3 value sets" );
335  WAssert( ( index + 1 ) * 3 <= m_data->size(), "index in WValueSet<T>::getVector3D too big" );
336  size_t offset = index * 3;
337  return WVector3d( ( *m_data )[offset], ( *m_data )[offset + 1], ( *m_data )[offset + 2] );
338 }
339 
340 template< typename T > WValue< T > WValueSet< T >::getWValue( size_t index ) const
341 {
342  WAssert( m_order == 1, "WValueSet<T>::getWValue only implemented for order==1 value sets" );
343  WAssert( ( index + 1 ) * m_dimension <= m_data->size(), "index in WValueSet<T>::getWValue too big" );
344 
345  size_t offset = index * m_dimension;
346 
347  WValue< T > result( m_dimension );
348 
349  // copying values
350  for( std::size_t i = 0; i < m_dimension; i++ )
351  result[i] = ( *m_data )[offset+i];
352 
353  return result;
354 }
355 
356 template< typename T >
358 {
359  // NOTE: std::pow works only for floating point types
360  size_t pow = 1;
361  for( size_t v = 0; v < oder; ++v )
362  {
363  pow *= dimension;
364  }
365 
366  return pow;
367 }
368 
369 #endif // WVALUESET_H