OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 #include "WExportWGE.h"
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 WGE_EXPORT 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  }
226  TextureListSignal;
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  */
263  TextureContainerType::ReadTicket getReadTicket();
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  */
271  WBoundingBox getBoundingBox() const;
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  */
279  WCondition::SPtr getChangeCondition() const;
280 
281 protected:
282 
283  /**
284  * Default constructor.
285  */
286  WGEColormapping();
287 
288  /**
289  * Apply the colormapping to the specified nodes.
290  *
291  * \param nodes the nodes.
292  * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
293  * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
294  * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
295  * specified, a default shader is used.
296  * \param startTexUnit the first texture unit allowed to be used
297  */
298  void applyInst( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(),
299  osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
300 
301  /**
302  * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping.
303  *
304  * \param texture the texture to add
305  * \param name the name of the texture.
306  */
307  void registerTextureInst( osg::ref_ptr< WGETexture3D > texture, std::string name );
308 
309  /**
310  * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping.
311  *
312  * \param texture the texture to remove
313  */
314  void deregisterTextureInst( osg::ref_ptr< WGETexture3D > texture );
315 
316  /**
317  * 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
318  * list as \ref registerTexture does.
319  *
320  * \param old the texture to remove
321  * \param newTex the new texture to put at the position of the old one
322  * \param name the name of the texture.
323  */
324  void replaceTextureInst( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" );
325 
326  /**
327  * This callback handles all the updates needed. It is called by the m_callback instance every update cycle for each node using this
328  * WGEColormapping instance.
329  *
330  * \param node
331  */
332  void callback( osg::Node* node );
333 
334  /**
335  * Called whenever the texture list is updated.
336  */
337  void textureUpdate();
338 
339 private:
340 
341  /**
342  * Singleton instance of WGEColormapping
343  */
344  static boost::shared_ptr< WGEColormapping > m_instance;
345 
346  /**
347  * The textures managed by this instance.
348  */
350 
351  /**
352  * The callback used for all the texture update handling on several nodes.
353  */
354  osg::ref_ptr< WGEFunctorCallback< osg::Node > > m_callback;
355 
356  /**
357  * Simple structure to store some additional node-related info like texture units and so on.
358  */
359  struct NodeInfo
360  {
361  bool m_rebind; //!< true if the node has not been callback'ed before
362  size_t m_texUnitStart; //!< the start index of the texture unit to use
363  WMatrix4d m_preTransform; //!< matrix used for transforming arbitrary texture coordinates to the proper space.
364  };
365 
366  /**
367  * The alias for a shared container with a set of node-nodeInfo pairs
368  */
370 
371  /**
372  * This map is needed to keep track of several node specific settings
373  */
375 
376  /**
377  * Called whenever a texture got registered.
378  */
379  boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_registerSignal;
380 
381  /**
382  * Called whenever a texture got removed.
383  */
384  boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_deregisterSignal;
385 
386  /**
387  * Called whenever a texture got replaced.
388  */
389  boost::signals2::signal< void( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > m_replaceSignal;
390 
391  /**
392  * Called whenever the texture list got resorted
393  */
394  boost::signals2::signal< void( void ) > m_sortSignal;
395 
396  /**
397  * The bounding box of all the textures.
398  */
400 
401  /**
402  * Updates the bounding box information. This is called for every write-update in m_textures.
403  */
404  void updateBounds();
405 };
406 
407 template < typename Comparator >
408 void WGEColormapping::sort( Comparator comp )
409 {
410  m_textures.sort< Comparator >( comp );
411 }
412 
413 #endif // WGECOLORMAPPING_H
414