OpenWalnut 1.3.1
WGEColormapping.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGECOLORMAPPING_H
00026 #define WGECOLORMAPPING_H
00027 
00028 #include <map>
00029 #include <string>
00030 #include <algorithm>
00031 #include <functional>
00032 #include <vector>
00033 
00034 #include <boost/signals2/signal.hpp>
00035 #include <boost/function.hpp>
00036 
00037 #include <osg/Node>
00038 
00039 #include "../common/WBoundingBox.h"
00040 #include "../common/WSharedSequenceContainer.h"
00041 #include "../common/WSharedAssociativeContainer.h"
00042 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00043 
00044 #include "callbacks/WGEFunctorCallback.h"
00045 
00046 #include "WGETexture.h"
00047 #include "shaders/WGEShader.h"
00048 
00049 
00050 /**
00051  * Class implements a manager for multiple 3D textures. They can be applied to arbitrary osg::Node. This allows very comfortable use of dataset
00052  * based colormapping. The only requirement is that your geometry/node needs to specify texture coordinates in Object Space. That means: the
00053  * texture coordinates equal the regular 3D grid of the texture.
00054  */
00055 class WGEColormapping // NOLINT
00056 {
00057 public:
00058     /**
00059      * The alias for a shared container.
00060      */
00061     typedef WSharedSequenceContainer< std::vector< osg::ref_ptr< WGETexture3D > > > TextureContainerType;
00062 
00063     /**
00064      * Iterator to access the texture list.
00065      */
00066     typedef TextureContainerType::Iterator TextureIterator;
00067 
00068     /**
00069      * Const iterator to access the texture list.
00070      */
00071     typedef TextureContainerType::ConstIterator TextureConstIterator;
00072 
00073     /**
00074      * The type of handler used for being notified about added textures.
00075      */
00076     typedef boost::function< void ( osg::ref_ptr< WGETexture3D > ) > TextureRegisterHandler;
00077 
00078     /**
00079      * The type of handler used for being notified about removed textures.
00080      */
00081     typedef TextureRegisterHandler TextureDeregisterHandler;
00082 
00083     /**
00084      * The type of handler used for being notified about replaced textures.
00085      */
00086     typedef boost::function< void ( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > TextureReplaceHandler;
00087 
00088     /**
00089      * The type of handler called whenever the texture list got resorted.
00090      */
00091     typedef boost::function< void ( void ) > TextureSortHandler;
00092 
00093     /**
00094      * Destructor.
00095      */
00096     virtual ~WGEColormapping();
00097 
00098     /**
00099      * Returns instance of the module factory to use to create modules.
00100      *
00101      * \return the running module factory.
00102      */
00103     static boost::shared_ptr< WGEColormapping > instance();
00104 
00105     /**
00106      * a bunch of nodes.
00107      */
00108     typedef std::vector< osg::ref_ptr< osg::Node > > NodeList;
00109 
00110     /**
00111      * Apply the colormapping to the specified node.
00112      *
00113      * \param node the node.
00114      * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
00115      * specified, a default shader is used.
00116      * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
00117      * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
00118      * \param startTexUnit the first texture unit allowed to be used
00119      */
00120     static void apply( osg::ref_ptr< osg::Node > node, WMatrix4d preTransform = WMatrix4d::identity(),
00121                        osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
00122 
00123     /**
00124      * Apply the colormapping to a list of nodes using the same shader.
00125      *
00126      * \param nodes the node-list.
00127      * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
00128      * specified, a default shader is used.
00129      * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
00130      * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
00131      * \param startTexUnit the first texture unit allowed to be used
00132      */
00133     static void apply( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(),
00134                        osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
00135 
00136     /**
00137      * Apply the colormapping to the specified node.
00138      *
00139      * \param node the node.
00140      * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
00141      * specified, a default shader is used.
00142      * \param startTexUnit the first texture unit allowed to be used
00143      */
00144     static void apply( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
00145 
00146     /**
00147      * Apply the colormapping to a list of nodes which all use the same shader.
00148      *
00149      * \param nodes the node list.
00150      * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
00151      * specified, a default shader is used.
00152      * \param startTexUnit the first texture unit allowed to be used
00153      */
00154     static void apply( NodeList nodes,
00155                        osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
00156 
00157     /**
00158      * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping.
00159      * The texture gets inserted at the beginning of the texture list.
00160      *
00161      * \param texture the texture to add
00162      * \param name the name of the texture to add
00163      */
00164     static void registerTexture( osg::ref_ptr< WGETexture3D > texture, std::string name = "" );
00165 
00166     /**
00167      * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping. If the
00168      * texture is not in the list, nothing happens.
00169      *
00170      * \param texture the texture to remove
00171      */
00172     static void deregisterTexture( osg::ref_ptr< WGETexture3D > texture );
00173 
00174     /**
00175      * 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
00176      * list as \ref registerTexture does.
00177      *
00178      * \param old the texture to remove
00179      * \param newTex the new texture to put at the position of the old one
00180      * \param name the name of the texture.
00181      */
00182     static void replaceTexture( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" );
00183 
00184     /**
00185      * Resorts the texture list using the specified comparator.
00186      *
00187      * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator().
00188      * \param comp the comparator
00189      */
00190     template < typename Comparator >
00191     void sort( Comparator comp );
00192 
00193     /**
00194      * Move the specified texture one item up in the list. Causes the sort signal to fire.
00195      *
00196      * \param texture the texture swapped with its ascendant
00197      * \return true if swap was successful. False if not (texture not found, texture already at beginning).
00198      */
00199     bool moveUp( osg::ref_ptr< WGETexture3D > texture );
00200 
00201     /**
00202      * Move the specified texture one item down in the list. Causes the sort signal to fire.
00203      *
00204      * \param texture the texture swapped with its descendant
00205      * \return true if swap was successful. False if not (texture not found, texture already at end).
00206      */
00207     bool moveDown( osg::ref_ptr< WGETexture3D > texture );
00208 
00209     /**
00210      * Counts the number of textures in the colormapper.
00211      *
00212      * \return the number of textures.
00213      */
00214     size_t size() const;
00215 
00216     /**
00217      * Possible signals that can be subscribed for being notified about texture list changes.
00218      */
00219     typedef enum
00220     {
00221         Registered = 0, //!< texture got added
00222         Deregistered,   //!< texture got removed
00223         Replaced,       //!< texture got replaced
00224         Sorted          //!< texture list was resorted
00225     }
00226     TextureListSignal;
00227 
00228     /**
00229      * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning.
00230      *
00231      * \param signal the signal to subscribe
00232      * \param notifier the notifier
00233      *
00234      * \return the connection. Keep this and disconnect it properly!
00235      */
00236     boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureRegisterHandler notifier );
00237 
00238     /**
00239      * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning.
00240      *
00241      * \param signal the signal to subscribe
00242      * \param notifier the notifier
00243      *
00244      * \return the connection. Keep this and disconnect it properly!
00245      */
00246     boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureReplaceHandler notifier );
00247 
00248     /**
00249      * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning.
00250      *
00251      * \param signal the signal to subscribe
00252      * \param notifier the notifier
00253      *
00254      * \return the connection. Keep this and disconnect it properly!
00255      */
00256     boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureSortHandler notifier );
00257 
00258     /**
00259      * Returns a read ticket to the texture array. Useful to iterate the textures.
00260      *
00261      * \return the read ticket
00262      */
00263     TextureContainerType::ReadTicket getReadTicket();
00264 
00265     /**
00266      * This returns the bounding box of all the data textures. This is very useful if you implement an universal color-mapped exploration tool.
00267      * It returns a copy of the current bounding box. Please note that this can change any moment.
00268      *
00269      * \return the bounding box.
00270      */
00271     WBoundingBox getBoundingBox() const;
00272 
00273     /**
00274      * Returns the condition firing if the texture list changes (sort, replace, add or remove). If you are interested in a certain event only,
00275      * use \ref subscribeSignal.
00276      *
00277      * \return the change condition
00278      */
00279     WCondition::SPtr getChangeCondition() const;
00280 
00281 protected:
00282     /**
00283      * Default constructor.
00284      */
00285     WGEColormapping();
00286 
00287     /**
00288      * Apply the colormapping to the specified nodes.
00289      *
00290      * \param nodes the nodes.
00291      * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to
00292      * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space.
00293      * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not
00294      * specified, a default shader is used.
00295      * \param startTexUnit the first texture unit allowed to be used
00296      */
00297     void applyInst( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(),
00298                     osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 );
00299 
00300     /**
00301      * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping.
00302      *
00303      * \param texture the texture to add
00304      * \param name the name of the texture.
00305      */
00306     void registerTextureInst( osg::ref_ptr< WGETexture3D > texture, std::string name );
00307 
00308     /**
00309      * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping.
00310      *
00311      * \param texture the texture to remove
00312      */
00313     void deregisterTextureInst( osg::ref_ptr< WGETexture3D > texture );
00314 
00315     /**
00316      * 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
00317      * list as \ref registerTexture does.
00318      *
00319      * \param old the texture to remove
00320      * \param newTex the new texture to put at the position of the old one
00321      * \param name the name of the texture.
00322      */
00323     void replaceTextureInst( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" );
00324 
00325     /**
00326      * This callback handles all the updates needed. It is called by the callback instance every update cycle for each node using this
00327      * WGEColormapping instance.
00328      *
00329      * \param node
00330      */
00331     void callback( osg::Node* node );
00332 
00333     /**
00334      * Called whenever the texture list is updated.
00335      */
00336     void textureUpdate();
00337 
00338 private:
00339     /**
00340      * Singleton instance of WGEColormapping
00341      */
00342     static boost::shared_ptr< WGEColormapping > m_instance;
00343 
00344     /**
00345      * The textures managed by this instance.
00346      */
00347     TextureContainerType m_textures;
00348 
00349     /**
00350      * Simple structure to store some additional node-related info like texture units and so on.
00351      */
00352     struct NodeInfo
00353     {
00354         bool   m_rebind;        //!< true if the node has not been callback'ed before
00355         size_t m_texUnitStart;  //!< the start index of the texture unit to use
00356         WMatrix4d m_preTransform; //!< matrix used for transforming arbitrary texture coordinates to the proper space.
00357     };
00358 
00359     /**
00360      * The alias for a shared container with a set of node-nodeInfo pairs
00361      */
00362     typedef WSharedAssociativeContainer< std::map< osg::Node*, NodeInfo*, std::less< osg::Node* > > > NodeInfoContainerType;
00363 
00364     /**
00365      * This map is needed to keep track of several node specific settings
00366      */
00367     NodeInfoContainerType m_nodeInfo;
00368 
00369     /**
00370      * Called whenever a texture got registered.
00371      */
00372     boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_registerSignal;
00373 
00374     /**
00375      * Called whenever a texture got removed.
00376      */
00377     boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_deregisterSignal;
00378 
00379     /**
00380      * Called whenever a texture got replaced.
00381      */
00382     boost::signals2::signal< void( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > m_replaceSignal;
00383 
00384     /**
00385      * Called whenever the texture list got resorted
00386      */
00387     boost::signals2::signal< void( void ) > m_sortSignal;
00388 
00389     /**
00390      * The bounding box of all the textures.
00391      */
00392     WSharedObject< WBoundingBox > m_boundingBox;
00393 
00394     /**
00395      * Updates the bounding box information. This is called for every write-update in m_textures.
00396      */
00397     void updateBounds();
00398 };
00399 
00400 template < typename Comparator >
00401 void WGEColormapping::sort( Comparator comp )
00402 {
00403     m_textures.sort< Comparator >( comp );
00404 }
00405 
00406 #endif  // WGECOLORMAPPING_H
00407