OpenWalnut  1.3.1
WGEColormapping.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 WGECOLORMAPPING_H
26 #define WGECOLORMAPPING_H
27 
28 #include <map>
29 #include <string>
30 #include <algorithm>
31 #include <functional>
32 #include <vector>
33 
34 #include <boost/signals2/signal.hpp>
35 #include <boost/function.hpp>
36 
37 #include <osg/Node>
38 
39 #include "../common/WBoundingBox.h"
40 #include "../common/WSharedSequenceContainer.h"
41 #include "../common/WSharedAssociativeContainer.h"
42 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
43 
44 #include "callbacks/WGEFunctorCallback.h"
45 
46 #include "WGETexture.h"
47 #include "shaders/WGEShader.h"
48 
49 
50 /**
51  * Class implements a manager for multiple 3D textures. They can be applied to arbitrary osg::Node. This allows very comfortable use of dataset
52  * based colormapping. The only requirement is that your geometry/node needs to specify texture coordinates in Object Space. That means: the
53  * texture coordinates equal the regular 3D grid of the texture.
54  */
55 class WGEColormapping // NOLINT
56 {
57 public:
58  /**
59  * The alias for a shared container.
60  */
62 
63  /**
64  * Iterator to access the texture list.
65  */
67 
68  /**
69  * Const iterator to access the texture list.
70  */
72 
73  /**
74  * The type of handler used for being notified about added textures.
75  */
76  typedef boost::function< void ( osg::ref_ptr< WGETexture3D > ) > TextureRegisterHandler;
77 
78  /**
79  * The type of handler used for being notified about removed textures.
80  */
82 
83  /**
84  * The type of handler used for being notified about replaced textures.
85  */
86  typedef boost::function< void ( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > TextureReplaceHandler;
87 
88  /**
89  * The type of handler called whenever the texture list got resorted.
90  */
91  typedef boost::function< void ( void ) > TextureSortHandler;
92 
93  /**
94  * Destructor.
95  */
96  virtual ~WGEColormapping();
97 
98  /**
99  * Returns instance of the module factory to use to create modules.
100  *
101  * \return the running module factory.
102  */
103  static boost::shared_ptr< WGEColormapping > instance();
104 
105  /**
106  * a bunch of nodes.
107  */
108  typedef std::vector< osg::ref_ptr< osg::Node > > NodeList;
109 
110  /**
111  * Apply the colormapping to the specified node.
112  *
113  * \param node the node.
114  * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
115  * specified, a default shader is used.
116  * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
117  * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
118  * \param startTexUnit the first texture unit allowed to be used
119  */
120  static void apply( osg::ref_ptr< osg::Node > node, WMatrix4d preTransform = WMatrix4d::identity(),
121  osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
122 
123  /**
124  * Apply the colormapping to a list of nodes using the same shader.
125  *
126  * \param nodes the node-list.
127  * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
128  * specified, a default shader is used.
129  * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
130  * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
131  * \param startTexUnit the first texture unit allowed to be used
132  */
133  static void apply( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(),
134  osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
135 
136  /**
137  * Apply the colormapping to the specified node.
138  *
139  * \param node the node.
140  * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
141  * specified, a default shader is used.
142  * \param startTexUnit the first texture unit allowed to be used
143  */
144  static void apply( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
145 
146  /**
147  * Apply the colormapping to a list of nodes which all use the same shader.
148  *
149  * \param nodes the node list.
150  * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
151  * specified, a default shader is used.
152  * \param startTexUnit the first texture unit allowed to be used
153  */
154  static void apply( NodeList nodes,
155  osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
156 
157  /**
158  * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping.
159  * The texture gets inserted at the beginning of the texture list.
160  *
161  * \param texture the texture to add
162  * \param name the name of the texture to add
163  */
164  static void registerTexture( osg::ref_ptr< WGETexture3D > texture, std::string name = "" );
165 
166  /**
167  * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping. If the
168  * texture is not in the list, nothing happens.
169  *
170  * \param texture the texture to remove
171  */
172  static void deregisterTexture( osg::ref_ptr< WGETexture3D > texture );
173 
174  /**
175  * Replaces the specified texture with the given new one. If the old texture does not exist, the new one gets inserted at the front of the
176  * list as \ref registerTexture does.
177  *
178  * \param old the texture to remove
179  * \param newTex the new texture to put at the position of the old one
180  * \param name the name of the texture.
181  */
182  static void replaceTexture( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" );
183 
184  /**
185  * Resorts the texture list using the specified comparator.
186  *
187  * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator().
188  * \param comp the comparator
189  */
190  template < typename Comparator >
191  void sort( Comparator comp );
192 
193  /**
194  * Move the specified texture one item up in the list. Causes the sort signal to fire.
195  *
196  * \param texture the texture swapped with its ascendant
197  * \return true if swap was successful. False if not (texture not found, texture already at beginning).
198  */
199  bool moveUp( osg::ref_ptr< WGETexture3D > texture );
200 
201  /**
202  * Move the specified texture one item down in the list. Causes the sort signal to fire.
203  *
204  * \param texture the texture swapped with its descendant
205  * \return true if swap was successful. False if not (texture not found, texture already at end).
206  */
207  bool moveDown( osg::ref_ptr< WGETexture3D > texture );
208 
209  /**
210  * Counts the number of textures in the colormapper.
211  *
212  * \return the number of textures.
213  */
214  size_t size() const;
215 
216  /**
217  * Possible signals that can be subscribed for being notified about texture list changes.
218  */
219  typedef enum
220  {
221  Registered = 0, //!< texture got added
222  Deregistered, //!< texture got removed
223  Replaced, //!< texture got replaced
224  Sorted //!< texture list was resorted
225  }
227 
228  /**
229  * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning.
230  *
231  * \param signal the signal to subscribe
232  * \param notifier the notifier
233  *
234  * \return the connection. Keep this and disconnect it properly!
235  */
236  boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureRegisterHandler notifier );
237 
238  /**
239  * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning.
240  *
241  * \param signal the signal to subscribe
242  * \param notifier the notifier
243  *
244  * \return the connection. Keep this and disconnect it properly!
245  */
246  boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureReplaceHandler notifier );
247 
248  /**
249  * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning.
250  *
251  * \param signal the signal to subscribe
252  * \param notifier the notifier
253  *
254  * \return the connection. Keep this and disconnect it properly!
255  */
256  boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureSortHandler notifier );
257 
258  /**
259  * Returns a read ticket to the texture array. Useful to iterate the textures.
260  *
261  * \return the read ticket
262  */
264 
265  /**
266  * This returns the bounding box of all the data textures. This is very useful if you implement an universal color-mapped exploration tool.
267  * It returns a copy of the current bounding box. Please note that this can change any moment.
268  *
269  * \return the bounding box.
270  */
272 
273  /**
274  * Returns the condition firing if the texture list changes (sort, replace, add or remove). If you are interested in a certain event only,
275  * use \ref subscribeSignal.
276  *
277  * \return the change condition
278  */
280 
281 protected:
282  /**
283  * Default constructor.
284  */
285  WGEColormapping();
286 
287  /**
288  * Apply the colormapping to the specified nodes.
289  *
290  * \param nodes the nodes.
291  * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
292  * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
293  * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
294  * specified, a default shader is used.
295  * \param startTexUnit the first texture unit allowed to be used
296  */
297  void applyInst( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(),
298  osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
299 
300  /**
301  * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping.
302  *
303  * \param texture the texture to add
304  * \param name the name of the texture.
305  */
306  void registerTextureInst( osg::ref_ptr< WGETexture3D > texture, std::string name );
307 
308  /**
309  * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping.
310  *
311  * \param texture the texture to remove
312  */
313  void deregisterTextureInst( osg::ref_ptr< WGETexture3D > texture );
314 
315  /**
316  * Replaces the specified texture with the given new one. If the old texture does not exist, the new one gets inserted at the front of the
317  * list as \ref registerTexture does.
318  *
319  * \param old the texture to remove
320  * \param newTex the new texture to put at the position of the old one
321  * \param name the name of the texture.
322  */
323  void replaceTextureInst( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" );
324 
325  /**
326  * This callback handles all the updates needed. It is called by the callback instance every update cycle for each node using this
327  * WGEColormapping instance.
328  *
329  * \param node
330  */
331  void callback( osg::Node* node );
332 
333  /**
334  * Called whenever the texture list is updated.
335  */
336  void textureUpdate();
337 
338 private:
339  /**
340  * Singleton instance of WGEColormapping
341  */
342  static boost::shared_ptr< WGEColormapping > m_instance;
343 
344  /**
345  * The textures managed by this instance.
346  */
348 
349  /**
350  * Simple structure to store some additional node-related info like texture units and so on.
351  */
352  struct NodeInfo
353  {
354  bool m_rebind; //!< true if the node has not been callback'ed before
355  size_t m_texUnitStart; //!< the start index of the texture unit to use
356  WMatrix4d m_preTransform; //!< matrix used for transforming arbitrary texture coordinates to the proper space.
357  };
358 
359  /**
360  * The alias for a shared container with a set of node-nodeInfo pairs
361  */
363 
364  /**
365  * This map is needed to keep track of several node specific settings
366  */
368 
369  /**
370  * Called whenever a texture got registered.
371  */
372  boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_registerSignal;
373 
374  /**
375  * Called whenever a texture got removed.
376  */
377  boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_deregisterSignal;
378 
379  /**
380  * Called whenever a texture got replaced.
381  */
382  boost::signals2::signal< void( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > m_replaceSignal;
383 
384  /**
385  * Called whenever the texture list got resorted
386  */
387  boost::signals2::signal< void( void ) > m_sortSignal;
388 
389  /**
390  * The bounding box of all the textures.
391  */
393 
394  /**
395  * Updates the bounding box information. This is called for every write-update in m_textures.
396  */
397  void updateBounds();
398 };
399 
400 template < typename Comparator >
401 void WGEColormapping::sort( Comparator comp )
402 {
403  m_textures.sort< Comparator >( comp );
404 }
405 
406 #endif // WGECOLORMAPPING_H
407