OpenWalnut  1.4.0
WTransferFunction.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 WTRANSFERFUNCTION_H
26 #define WTRANSFERFUNCTION_H
27 
28 #include <iosfwd>
29 #include <vector>
30 
31 #include "WColor.h"
32 
33 /**
34  * A class that stores a 1D transfer function which consists
35  * of a linear interpolation of alpha and color values.
36  */
37 class WTransferFunction // NOLINT problem with macro
38 {
39 public:
40  /**
41  * Default constructor of a meaningless transfer function
42  */
44  {
45  }
46 
47  /**
48  * Deep copy constructor.
49  *
50  * \param rhs the value to histogram
51  */
54  {
55  }
56 
57  /**
58  * Deep copy operator
59  *
60  * \param rhs the value to copy
61  * \returns reference to current object
62  * \returns reference to current object
63  */
65  {
66  this->m_colors = rhs.m_colors;
67  this->m_alphas = rhs.m_alphas;
68  this->m_isomin = rhs.m_isomin;
69  this->m_isomax = rhs.m_isomax;
70  this->m_histogram = rhs.m_histogram;
71  return ( *this );
72  }
73 
74  /**
75  * Check equivalence of two transfer functions.
76  *
77  * \returns true if this object contains exactly the same
78  * data as rhs
79  * \param rhs object to compare with
80  */
81  bool operator==( const WTransferFunction &rhs ) const;
82 
83  /**
84  * Check equivalence of two transfer functions.
85  *
86  * \returns negated result of operator==
87  * \param rhs the value to compare with
88  */
89  bool operator!=( const WTransferFunction &rhs ) const;
90 
91  /**
92  * Default destuctor.
93  */
95  {
96  }
97 
98  /**
99  * Get the number of alphas
100  *
101  * \returns the number of alpha points
102  */
103  size_t numAlphas() const
104  {
105  return m_alphas.size();
106  }
107 
108  /**
109  * Get the number of colors.
110  *
111  * \returns the number of color points
112  */
113  size_t numColors() const
114  {
115  return m_colors.size();
116  }
117 
118  /**
119  * Get the isovalue at a given index in the alpha values.
120  *
121  * \param i the index of the point to query
122  * \returns the alpha values position/isovalue at index i
123  */
124  double getAlphaIsovalue( size_t i ) const
125  {
126  return m_alphas.at( i ).iso;
127  }
128 
129  /**
130  * The isovalue of the color at a given index.
131  *
132  * \param i the index of the point to query.
133  * \returns the color values position/isovalue at index i
134  */
135  double getColorIsovalue( size_t i ) const
136  {
137  return m_colors.at( i ).iso;
138  }
139 
140  /**
141  * Get alpha at given index.
142  *
143  * \param i the index to query
144  * \returns the alpha value at index i
145  */
146  double getAlpha( size_t i ) const
147  {
148  return m_alphas.at( i ).alpha;
149  }
150 
151  /**
152  * Get color at given index.
153  *
154  * \param i the index to query
155  * \returns the color at index i
156  */
157  const WColor& getColor( size_t i ) const
158  {
159  return m_colors.at( i ).color;
160  }
161 
162  /**
163  * Insert a new color point.
164  *
165  * \param iso the new iso value
166  * \param color the new color at the given iso value
167  */
168  void addColor( double iso, const WColor& color );
169 
170  /**
171  * Insert a new alpha point.
172  *
173  * \param iso the new iso value
174  * \param alpha the new alpha value at the given iso value
175  */
176  void addAlpha( double iso, double alpha );
177 
178  /**
179  * Set the histogram going along with the transfer function
180  *
181  * This should be changed in the future to be handled in a different
182  * way. A good option would be to introduce an object encapsulating
183  * a transfer function and histogram information.
184  *
185  * \param data the histogram data between m_isomin and m_isomax
186  */
187  void setHistogram( std::vector< double > & data )
188  {
189  m_histogram.swap( data );
190  }
191 
192  /**
193  * Clears the histogram data so the gui won't show any
194  */
196  {
197  m_histogram.clear();
198  }
199 
200  /**
201  * Returns the histogram.
202  *
203  * \returns a reference to the internal representation of the histogram
204  */
205  const std::vector< double >& getHistogram() const
206  {
207  return m_histogram;
208  }
209 
210  /**
211  * sample/render the transfer function linearly between min and max in an RGBA texture.
212  * \param array pointer to an allocated data structure
213  * \param width is the number of RGBA samples.
214  * \param min the lowest value to be sampled
215  * \param max the hightes value to be sampled
216  * \post array contains the sampled data
217  * \pre array is allocated and has space for width elements
218  */
219  void sample1DTransferFunction( unsigned char*array, int width, double min, double max ) const;
220 
221  /**
222  * Try to estimate a transfer function from an RGBA image.
223  *
224  * \param rgba: values between 0 and 255 representing the red, green, and blue channel
225  * \param size: number of color entries in rgba
226  * \returns approximated transfer function
227  */
228  static WTransferFunction createFromRGBA( unsigned char const * const rgba, size_t size );
229 private:
230  /**
231  * Prototype for a storage element
232  */
233  struct Entry
234  {
235  /**
236  * Default constructor
237  * \param iso the iso value
238  */
239  explicit Entry( double iso ) : iso( iso )
240  {
241  }
242 
243  /**
244  * comparison by isovalue
245  * \param rhs entry to compare t
246  * \returns true if this->iso <= rhs.iso
247  */
248  bool operator <= ( const Entry &rhs ) const
249  {
250  return iso <= rhs.iso;
251  }
252 
253  /** the isovalue */
254  double iso;
255  };
256 
257  /**
258  * Color entries are linearly interpolated colors along isovalues
259  */
260  struct ColorEntry : public Entry
261  {
262  /** default constructor
263  * \param iso the isovalue
264  * \param color the color at the isovalue
265  */
266  ColorEntry( double iso, WColor color ) : Entry( iso ), color( color )
267  {
268  }
269 
270  /**
271  * comparison operator to check for changes
272  * \param rhs ColorEntry to compare to
273  * \returns true if rhs equals this
274  */
275  bool operator==( const ColorEntry& rhs ) const
276  {
277  return iso == rhs.iso && color == rhs.color;
278  }
279 
280  /** holds the current color at isovalue Entry::iso */
281  WColor color;
282  };
283 
284  /**
285  * Alpha entries represent linearly interpolated transparency values
286  * along the isovalue scale. Alpha is in the range [ 0...1 ] where
287  * 1 signifies entirely opaque ( which makes it more an opacity value instead
288  * of alpha, but I use the commonly used language here )
289  */
290  struct AlphaEntry : public Entry
291  {
292  /** default constructor
293  * \param iso the isovalue
294  * \param alpha the alpha at the isovalue in the range from 0 = transparent to 1 = opaque
295  */
296  AlphaEntry( double iso, double alpha ) : Entry( iso ), alpha( alpha )
297  {
298  }
299 
300  /**
301  * comparison operator to check for changes
302  * \param rhs AlphaEntry to compare to
303  * \returns true if rhs is equal to this
304  */
305  bool operator==( const AlphaEntry& rhs ) const
306  {
307  return iso == rhs.iso && alpha == rhs.alpha;
308  }
309 
310  /** holds the current alpha at isovalue Entry::iso */
311  double alpha;
312  };
313 
314  /**
315  * Templatized comparison predicate for internal searching
316  */
317  template<typename T>
318  struct LessPred
319  {
320  /** constructs a predicate that compares for less than iso
321  * \param iso: used iso value
322  */
323  explicit LessPred( double iso ) : iso( iso )
324  {
325  }
326 
327  /** isovalue-based comparison
328  * \param t the object to compare to
329  * \returns true if iso is less than t.iso
330  */
331  bool operator()( const T& t )
332  {
333  return iso < t.iso;
334  }
335 
336  /** the isovalue to compare to */
337  double iso;
338  };
339 
340  /**
341  * Sorted list of colors
342  */
343  std::vector<ColorEntry> m_colors;
344 
345  /**
346  * Sorted list of alpha values.
347  */
348  std::vector<AlphaEntry> m_alphas;
349 
350  /**
351  * The smallest used iso value.
352  */
353  double m_isomin;
354 
355  /**
356  * The largest used iso value.
357  */
358  double m_isomax;
359 
360  /**
361  * Sores a histogram. This is used for property-handling only
362  * and does not change the transfer function at all.
363  */
364  std::vector< double > m_histogram;
365 
366  friend std::ostream& operator << ( std::ostream& out, const WTransferFunction& tf );
367 };
368 
369 /**
370  * Default output operator. Currently stores values the same way as it is done in the properties.
371  * This code should only be used for debugging and you should not rely on the interface.
372  *
373  * \param tf The transfer function to output
374  * \param out The stream to which we write
375  *
376  * \returns reference to out
377  */
378 std::ostream& operator << ( std::ostream& out, const WTransferFunction& tf );
379 
380 #endif // WTRANSFERFUNCTION_H