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