OpenWalnut
1.4.0
|
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 00043 #include "callbacks/WGEFunctorCallback.h" 00044 00045 #include "WGETexture.h" 00046 #include "shaders/WGEShader.h" 00047 00048 00049 /** 00050 * Class implements a manager for multiple 3D textures. They can be applied to arbitrary osg::Node. This allows very comfortable use of dataset 00051 * based colormapping. The only requirement is that your geometry/node needs to specify texture coordinates in Object Space. That means: the 00052 * texture coordinates equal the regular 3D grid of the texture. 00053 */ 00054 class WGEColormapping // NOLINT 00055 { 00056 public: 00057 /** 00058 * The alias for a shared container. 00059 */ 00060 typedef WSharedSequenceContainer< std::vector< osg::ref_ptr< WGETexture3D > > > TextureContainerType; 00061 00062 /** 00063 * Iterator to access the texture list. 00064 */ 00065 typedef TextureContainerType::Iterator TextureIterator; 00066 00067 /** 00068 * Const iterator to access the texture list. 00069 */ 00070 typedef TextureContainerType::ConstIterator TextureConstIterator; 00071 00072 /** 00073 * The type of handler used for being notified about added textures. 00074 */ 00075 typedef boost::function< void ( osg::ref_ptr< WGETexture3D > ) > TextureRegisterHandler; 00076 00077 /** 00078 * The type of handler used for being notified about removed textures. 00079 */ 00080 typedef TextureRegisterHandler TextureDeregisterHandler; 00081 00082 /** 00083 * The type of handler used for being notified about replaced textures. 00084 */ 00085 typedef boost::function< void ( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > TextureReplaceHandler; 00086 00087 /** 00088 * The type of handler called whenever the texture list got resorted. 00089 */ 00090 typedef boost::function< void ( void ) > TextureSortHandler; 00091 00092 /** 00093 * Destructor. 00094 */ 00095 virtual ~WGEColormapping(); 00096 00097 /** 00098 * Returns instance of the module factory to use to create modules. 00099 * 00100 * \return the running module factory. 00101 */ 00102 static boost::shared_ptr< WGEColormapping > instance(); 00103 00104 /** 00105 * a bunch of nodes. 00106 */ 00107 typedef std::vector< osg::ref_ptr< osg::Node > > NodeList; 00108 00109 /** 00110 * Apply the colormapping to the specified node. 00111 * 00112 * \param node the node. 00113 * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not 00114 * specified, a default shader is used. 00115 * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to 00116 * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space. 00117 * \param startTexUnit the first texture unit allowed to be used 00118 */ 00119 static void apply( osg::ref_ptr< osg::Node > node, WMatrix4d preTransform = WMatrix4d::identity(), 00120 osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 ); 00121 00122 /** 00123 * Apply the colormapping to a list of nodes using the same shader. 00124 * 00125 * \param nodes the node-list. 00126 * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not 00127 * specified, a default shader is used. 00128 * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to 00129 * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space. 00130 * \param startTexUnit the first texture unit allowed to be used 00131 */ 00132 static void apply( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(), 00133 osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 ); 00134 00135 /** 00136 * Apply the colormapping to the specified node. 00137 * 00138 * \param node the node. 00139 * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not 00140 * specified, a default shader is used. 00141 * \param startTexUnit the first texture unit allowed to be used 00142 */ 00143 static void apply( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 ); 00144 00145 /** 00146 * Apply the colormapping to a list of nodes which all use the same shader. 00147 * 00148 * \param nodes the node list. 00149 * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not 00150 * specified, a default shader is used. 00151 * \param startTexUnit the first texture unit allowed to be used 00152 */ 00153 static void apply( NodeList nodes, 00154 osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 ); 00155 00156 /** 00157 * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping. 00158 * The texture gets inserted at the beginning of the texture list. 00159 * 00160 * \param texture the texture to add 00161 * \param name the name of the texture to add 00162 */ 00163 static void registerTexture( osg::ref_ptr< WGETexture3D > texture, std::string name = "" ); 00164 00165 /** 00166 * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping. If the 00167 * texture is not in the list, nothing happens. 00168 * 00169 * \param texture the texture to remove 00170 */ 00171 static void deregisterTexture( osg::ref_ptr< WGETexture3D > texture ); 00172 00173 /** 00174 * 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 00175 * list as \ref registerTexture does. 00176 * 00177 * \param old the texture to remove 00178 * \param newTex the new texture to put at the position of the old one 00179 * \param name the name of the texture. 00180 */ 00181 static void replaceTexture( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" ); 00182 00183 /** 00184 * Resorts the texture list using the specified comparator. 00185 * 00186 * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator(). 00187 * \param comp the comparator 00188 */ 00189 template < typename Comparator > 00190 void sort( Comparator comp ); 00191 00192 /** 00193 * Resorts the texture list using the specified comparator using a stable sorting algorithm. 00194 * 00195 * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator(). 00196 * \param comp the comparator 00197 */ 00198 template < typename Comparator > 00199 void stableSort( Comparator comp ); 00200 00201 /** 00202 * Sort the texture list by the indices that have been stored in each texture's sortIndex. 00203 */ 00204 void sortByIndex(); 00205 00206 /** 00207 * This function sets the index of a texture in the list to this texture's WGETexture::sortIndex(). This can be used later using 00208 * sortByIndex(). 00209 */ 00210 void setSortIndices(); 00211 00212 /** 00213 * Reset all sort indices. This can be useful when loading new project files with new sort indices. 00214 */ 00215 void resetSortIndices(); 00216 00217 /** 00218 * Move the specified texture up in the list, directly to the top. Causes the sort signal to fire. 00219 * 00220 * \param texture the texture swapped with its ascendant 00221 * \return true if swap was successful. False if not (texture not found, texture already at beginning). 00222 */ 00223 bool moveToTop( osg::ref_ptr< WGETexture3D > texture ); 00224 00225 /** 00226 * Move the specified texture down in the list, directly to the bottom. Causes the sort signal to fire. 00227 * 00228 * \param texture the texture swapped with its descendant 00229 * \return true if swap was successful. False if not (texture not found, texture already at end). 00230 */ 00231 bool moveToBottom( osg::ref_ptr< WGETexture3D > texture ); 00232 00233 /** 00234 * Move the specified texture one item up in the list. Causes the sort signal to fire. 00235 * 00236 * \param texture the texture swapped with its ascendant 00237 * \return true if swap was successful. False if not (texture not found, texture already at beginning). 00238 */ 00239 bool moveUp( osg::ref_ptr< WGETexture3D > texture ); 00240 00241 /** 00242 * Move the specified texture one item down in the list. Causes the sort signal to fire. 00243 * 00244 * \param texture the texture swapped with its descendant 00245 * 00246 * \return true if swap was successful. False if not (texture not found, texture already at end). 00247 */ 00248 bool moveDown( osg::ref_ptr< WGETexture3D > texture ); 00249 00250 /** 00251 * Move the texture to the specified index. If the texture is not in the list, nothing happens. 00252 * 00253 * \param texture the texture to move 00254 * \param idx the target index 00255 * 00256 * \return true if the operation was successful. 00257 */ 00258 bool moveTo( osg::ref_ptr< WGETexture3D > texture, size_t idx ); 00259 00260 /** 00261 * Counts the number of textures in the colormapper. 00262 * 00263 * \return the number of textures. 00264 */ 00265 size_t size() const; 00266 00267 /** 00268 * Possible signals that can be subscribed for being notified about texture list changes. 00269 */ 00270 typedef enum 00271 { 00272 Registered = 0, //!< texture got added 00273 Deregistered, //!< texture got removed 00274 Replaced, //!< texture got replaced 00275 Sorted //!< texture list was resorted 00276 } 00277 TextureListSignal; 00278 00279 /** 00280 * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning. 00281 * 00282 * \param signal the signal to subscribe 00283 * \param notifier the notifier 00284 * 00285 * \return the connection. Keep this and disconnect it properly! 00286 */ 00287 boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureRegisterHandler notifier ); 00288 00289 /** 00290 * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning. 00291 * 00292 * \param signal the signal to subscribe 00293 * \param notifier the notifier 00294 * 00295 * \return the connection. Keep this and disconnect it properly! 00296 */ 00297 boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureReplaceHandler notifier ); 00298 00299 /** 00300 * Subscribe to the specified signal. See \ref TextureListSignal for details about their meaning. 00301 * 00302 * \param signal the signal to subscribe 00303 * \param notifier the notifier 00304 * 00305 * \return the connection. Keep this and disconnect it properly! 00306 */ 00307 boost::signals2::connection subscribeSignal( TextureListSignal signal, TextureSortHandler notifier ); 00308 00309 /** 00310 * Returns a read ticket to the texture array. Useful to iterate the textures. 00311 * 00312 * \return the read ticket 00313 */ 00314 TextureContainerType::ReadTicket getReadTicket(); 00315 00316 /** 00317 * This returns the bounding box of all the data textures. This is very useful if you implement an universal color-mapped exploration tool. 00318 * It returns a copy of the current bounding box. Please note that this can change any moment. 00319 * 00320 * \return the bounding box. 00321 */ 00322 WBoundingBox getBoundingBox() const; 00323 00324 /** 00325 * Returns the condition firing if the texture list changes (sort, replace, add or remove). If you are interested in a certain event only, 00326 * use \ref subscribeSignal. 00327 * 00328 * \return the change condition 00329 */ 00330 WCondition::SPtr getChangeCondition() const; 00331 00332 protected: 00333 /** 00334 * Default constructor. 00335 */ 00336 WGEColormapping(); 00337 00338 /** 00339 * Apply the colormapping to the specified nodes. 00340 * 00341 * \param nodes the nodes. 00342 * \param preTransform Transformation matrix getting applied to your texture coordinates before applying texture matrices. This allows you to 00343 * specify any kind of texture coordinates as long as you use this matrix to transform them to the right space. 00344 * \param shader the shader to use for colormapping. Provide your own shader here to let WGEColormap set some defines needed. If not 00345 * specified, a default shader is used. 00346 * \param startTexUnit the first texture unit allowed to be used 00347 */ 00348 void applyInst( NodeList nodes, WMatrix4d preTransform = WMatrix4d::identity(), 00349 osg::ref_ptr< WGEShader > shader = osg::ref_ptr< WGEShader >(), size_t startTexUnit = 0 ); 00350 00351 /** 00352 * Register the specified texture to the colormapper. The registered texture is the automatically applied to all users of WGEColormapping. 00353 * 00354 * \param texture the texture to add 00355 * \param name the name of the texture. 00356 */ 00357 void registerTextureInst( osg::ref_ptr< WGETexture3D > texture, std::string name ); 00358 00359 /** 00360 * De-register the specified texture to the colormapper. The texture is the automatically removed from all users of WGEColormapping. 00361 * 00362 * \param texture the texture to remove 00363 */ 00364 void deregisterTextureInst( osg::ref_ptr< WGETexture3D > texture ); 00365 00366 /** 00367 * 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 00368 * list as \ref registerTexture does. 00369 * 00370 * \param old the texture to remove 00371 * \param newTex the new texture to put at the position of the old one 00372 * \param name the name of the texture. 00373 */ 00374 void replaceTextureInst( osg::ref_ptr< WGETexture3D > old, osg::ref_ptr< WGETexture3D > newTex, std::string name = "" ); 00375 00376 /** 00377 * This callback handles all the updates needed. It is called by the callback instance every update cycle for each node using this 00378 * WGEColormapping instance. 00379 * 00380 * \param node 00381 */ 00382 void callback( osg::Node* node ); 00383 00384 /** 00385 * Called whenever the texture list is updated. 00386 */ 00387 void textureUpdate(); 00388 00389 private: 00390 /** 00391 * Singleton instance of WGEColormapping 00392 */ 00393 static boost::shared_ptr< WGEColormapping > m_instance; 00394 00395 /** 00396 * The textures managed by this instance. 00397 */ 00398 TextureContainerType m_textures; 00399 00400 /** 00401 * Simple structure to store some additional node-related info like texture units and so on. 00402 */ 00403 struct NodeInfo 00404 { 00405 bool m_rebind; //!< true if the node has not been callback'ed before 00406 size_t m_texUnitStart; //!< the start index of the texture unit to use 00407 WMatrix4d m_preTransform; //!< matrix used for transforming arbitrary texture coordinates to the proper space. 00408 }; 00409 00410 /** 00411 * The alias for a shared container with a set of node-nodeInfo pairs 00412 */ 00413 typedef WSharedAssociativeContainer< std::map< osg::Node*, NodeInfo*, std::less< osg::Node* > > > NodeInfoContainerType; 00414 00415 /** 00416 * This map is needed to keep track of several node specific settings 00417 */ 00418 NodeInfoContainerType m_nodeInfo; 00419 00420 /** 00421 * Called whenever a texture got registered. 00422 */ 00423 boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_registerSignal; 00424 00425 /** 00426 * Called whenever a texture got removed. 00427 */ 00428 boost::signals2::signal< void( osg::ref_ptr< WGETexture3D > ) > m_deregisterSignal; 00429 00430 /** 00431 * Called whenever a texture got replaced. 00432 */ 00433 boost::signals2::signal< void( osg::ref_ptr< WGETexture3D >, osg::ref_ptr< WGETexture3D > ) > m_replaceSignal; 00434 00435 /** 00436 * Called whenever the texture list got resorted 00437 */ 00438 boost::signals2::signal< void( void ) > m_sortSignal; 00439 00440 /** 00441 * The bounding box of all the textures. 00442 */ 00443 WSharedObject< WBoundingBox > m_boundingBox; 00444 00445 /** 00446 * Updates the bounding box information. This is called for every write-update in m_textures. 00447 */ 00448 void updateBounds(); 00449 }; 00450 00451 template < typename Comparator > 00452 void WGEColormapping::sort( Comparator comp ) 00453 { 00454 m_textures.sort< Comparator >( comp ); 00455 } 00456 00457 template < typename Comparator > 00458 void WGEColormapping::stableSort( Comparator comp ) 00459 { 00460 m_textures.stableSort< Comparator >( comp ); 00461 } 00462 00463 #endif // WGECOLORMAPPING_H 00464