OpenWalnut  1.5.0dev
WMIsosurface.cpp
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 #include <fstream>
26 #include <iostream>
27 #include <limits>
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 #include <osg/Geode>
33 #include <osg/Geometry>
34 #include <osg/LightModel>
35 #include <osg/Material>
36 #include <osg/PolygonMode>
37 #include <osg/StateAttribute>
38 #include <osg/StateSet>
39 #include <osgDB/WriteFile>
40 
41 #include "WMIsosurface.h"
42 #include "WMIsosurface.xpm"
43 #include "core/common/WAssert.h"
44 #include "core/common/WLimits.h"
45 #include "core/common/WPathHelper.h"
46 #include "core/common/WProgress.h"
47 #include "core/common/algorithms/WMarchingCubesAlgorithm.h"
48 #include "core/common/algorithms/WMarchingLegoAlgorithm.h"
49 #include "core/common/math/WLinearAlgebraFunctions.h"
50 #include "core/common/math/WMath.h"
51 #include "core/dataHandler/WDataHandler.h"
52 #include "core/dataHandler/WSubject.h"
53 #include "core/graphicsEngine/WGEColormapping.h"
54 #include "core/graphicsEngine/WGEUtils.h"
55 #include "core/graphicsEngine/callbacks/WGEFunctorCallback.h"
56 #include "core/graphicsEngine/postprocessing/WGEPostprocessingNode.h"
57 #include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
58 #include "core/graphicsEngine/shaders/WGEShaderPropertyDefine.h"
59 #include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
60 #include "core/kernel/WKernel.h"
61 #include "core/kernel/WSelectionManager.h"
62 
63 // This line is needed by the module loader to actually find your module.
64 W_LOADABLE_MODULE( WMIsosurface )
65 
67  WModule(),
68  m_recompute( std::shared_ptr< WCondition >( new WCondition() ) ),
69  m_dataSet(),
70  m_moduleNodeInserted( false ),
71  m_surfaceGeode( 0 )
72 {
73  // WARNING: initializing connectors inside the constructor will lead to an exception.
74  // Implement WModule::initializeConnectors instead.
75 }
76 
78 {
79  // cleanup
81 }
82 
83 std::shared_ptr< WModule > WMIsosurface::factory() const
84 {
85  return std::shared_ptr< WModule >( new WMIsosurface() );
86 }
87 
88 const char** WMIsosurface::getXPMIcon() const
89 {
90  return iso_surface_xpm;
91 }
92 
93 const std::string WMIsosurface::getName() const
94 {
95  return "Isosurface";
96 }
97 
98 const std::string WMIsosurface::getDescription() const
99 {
100  return "This module implements the marching cubes"
101 " algorithm with a consistent triangulation. It allows one to compute isosurfaces"
102 " for a given isovalue on data given on a grid only consisting of cubes. It yields"
103 " the surface as triangle soup.";
104 }
105 
107 {
108  // use the m_input "data changed" flag
109  m_moduleState.setResetable( true, true );
110  m_moduleState.add( m_input->getDataChangedCondition() );
112 
113  // create the post-processing node which actually does the nice stuff to the rendered image
114  osg::ref_ptr< WGEPostprocessingNode > postNode = new WGEPostprocessingNode(
115  WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getCamera()
116  );
117  // provide the properties of the post-processor to the user
118  m_properties->addProperty( postNode->getProperties() );
119 
120  // add to scene
121  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( postNode );
122 
123  // signal ready state
124  ready();
125 
126  // create shader
127  m_shader = osg::ref_ptr< WGEShader >( new WGEShader( "WMIsosurface", m_localPath ) );
128  m_shader->addPreprocessor( WGEShaderPreprocessor::SPtr(
129  new WGEShaderPropertyDefineOptions< WPropBool >( m_useTextureProp, "COLORMAPPING_DISABLED", "COLORMAPPING_ENABLED" ) )
130  );
131 
133  m_moduleNode->getOrCreateStateSet()->addUniform( new WGEPropertyUniform< WPropInt >( "u_opacity", m_opacityProp ) );
134 
135  // add it to postproc node and register shader
136  postNode->insert( m_moduleNode, m_shader );
137 
138  // loop until the module container requests the module to quit
139  while( !m_shutdownFlag() )
140  {
141  debugLog() << "Waiting ...";
143 
144  // woke up since the module is requested to finish?
145  if( m_shutdownFlag() )
146  {
147  break;
148  }
149 
150  // query changes in data and data validity
151  bool dataChanged = m_input->handledUpdate();
152  std::shared_ptr< WDataSetScalar > incomingDataSet = m_input->getData();
153  bool propChanged = m_useMarchingLego->changed() || m_isoValueProp->changed();
154  if( !incomingDataSet )
155  {
156  // OK, the output has not yet sent data
157  debugLog() << "Waiting for data ...";
158  continue;
159  }
160 
161  // new data available?
162  if( dataChanged )
163  {
164  // acquire data from the input connector
165  m_dataSet = m_input->getData();
166 
167  // set appropriate constraints for properties
168  m_isoValueProp->setMin( m_dataSet->getMin() );
169  m_isoValueProp->setMax( m_dataSet->getMax() );
170 
171  if( m_isoValueProp->get() >= m_dataSet->getMax() || m_isoValueProp->get() <= m_dataSet->getMin() )
172  {
173  m_isoValueProp->set( 0.5 * ( m_dataSet->getMax() + m_dataSet->getMin() ), true );
174  }
175  }
176 
177  // if nothing has changed, continue waiting
178  if( !propChanged && !dataChanged )
179  {
180  continue;
181  }
182 
183  // update isosurface
184  debugLog() << "Computing surface ...";
185 
186  std::shared_ptr< WProgress > progress( new WProgress( "Marching Cubes", 2 ) );
187  m_progress->addSubProgress( progress );
188 
189  generateSurfacePre( m_isoValueProp->get( true ) );
190 
191  ++*progress;
192  debugLog() << "Rendering surface ...";
193 
194  renderMesh();
195  m_output->updateData( m_triMesh );
196 
197  debugLog() << "Done!";
198  progress->finish();
199  }
200 
201  WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getScene()->remove( postNode );
202 }
203 
205 {
206  // initialize connectors
207  m_input = std::shared_ptr< WModuleInputData < WDataSetScalar > >(
208  new WModuleInputData< WDataSetScalar >( shared_from_this(),
209  "values", "Dataset to compute isosurface for." )
210  );
211 
212  // add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
214 
215  m_output = std::shared_ptr< WModuleOutputData< WTriangleMesh > >(
216  new WModuleOutputData< WTriangleMesh >( shared_from_this(), "surface mesh", "The mesh representing the isosurface." ) );
217 
219 
220  // call WModules initialization
222 }
223 
225 {
226  m_nbTriangles = m_infoProperties->addProperty( "Triangles", "The number of triangles in the produced mesh.", 0 );
227  m_nbTriangles->setMax( std::numeric_limits< int >::max() );
228 
229  m_nbVertices = m_infoProperties->addProperty( "Vertices", "The number of vertices in the produced mesh.", 0 );
230  m_nbVertices->setMax( std::numeric_limits< int >::max() );
231 
232  m_isoValueProp = m_properties->addProperty( "Iso value", "The surface will show the area that has this value.", 100., m_recompute );
235 
236  m_opacityProp = m_properties->addProperty( "Opacity %", "Opaqueness of surface.", 100 );
237  m_opacityProp->setMin( 0 );
238  m_opacityProp->setMax( 100 );
239 
240  m_useTextureProp = m_properties->addProperty( "Use texture", "Use texturing of the surface?", false );
241 
242  m_surfaceColor = m_properties->addProperty( "Surface color", "Description.", WColor( 1.0, 1.0, 1.0, 1.0 ) );
243 
244  m_useMarchingLego = m_properties->addProperty( "Voxel surface", "Not interpolated surface", false, m_recompute );
245 
247 }
248 
249 namespace
250 {
251  /**
252  * A template-less base class to combine both Marching-Cube-like algorithms using one interface
253  */
254  struct MCBase
255  {
256  virtual ~MCBase()
257  {
258  }
259 
260  virtual std::shared_ptr< WTriangleMesh > execute( size_t x, size_t y, size_t z,
261  const WMatrix<double>& matrix,
262  std::shared_ptr<WValueSetBase> valueSet,
263  double isoValue,
264  std::shared_ptr<WProgressCombiner> ) = 0;
265  };
266 
267  /**
268  * Base class templetized by the algorithm used, i.e., real marching cubes or lego bricks
269  * This class enhances the interface of the MC algorithm by the new execute function.
270  */
271  template<class AlgoBase>
272  struct MCAlgoMapperBase : public AlgoBase, public MCBase
273  {
274  virtual ~MCAlgoMapperBase()
275  {
276  }
277  };
278 
279  /**
280  * this class matches a data type and an algorithm type
281  *
282  * It is a helper class that converts the type to call the appropriate function in the MC code
283  * in the original algorithm.
284  *
285  * \param AlgoBase
286  * AlgoBase is the algorithm that will be called and must implement
287  * AlgoBase::generateSurface( x,y,z, matrix, vals_raw_ptr, isoValue, progress )
288  */
289  template<class AlgoBase, typename T>
290  struct MCAlgoMapper : public MCAlgoMapperBase<AlgoBase>
291  {
292  virtual ~MCAlgoMapper()
293  {
294  }
295 
296  virtual std::shared_ptr< WTriangleMesh > execute( size_t x, size_t y, size_t z,
297  const WMatrix<double>& matrix,
298  std::shared_ptr<WValueSetBase> valueSet,
299  double isoValue,
300  std::shared_ptr<WProgressCombiner> progress )
301  {
302  std::shared_ptr< WValueSet< T > > vals(
303  std::dynamic_pointer_cast< WValueSet< T > >( valueSet ) );
304  WAssert( vals, "Data type and data type indicator must fit." );
305  return AlgoBase::generateSurface( x, y, z, matrix, vals->rawDataVectorPointer(), isoValue, progress );
306  }
307  };
308 
309  /**
310  * Function to create the appropriate algorithm code for the data type.
311  * The selection is done based on a list of valid types.
312  * New data types for this module have to be added here ( and only here ).
313  *
314  * \param AlgoBase
315  * AlgoBase is the algorithm that will be called and must implement
316  * AlgoBase::generateSurface( x,y,z, matrix, vals_raw_ptr, isoValue, progress )
317  *
318  * \param enum_type the OpenWalnut type enum of the data on which the isosurface should be computed.
319  */
320  template<typename AlgoBase>
321  std::shared_ptr<MCAlgoMapperBase<AlgoBase> > createAlgo( int enum_type )
322  {
323 #define CASE( enum_type ) \
324  case enum_type:\
325  return std::shared_ptr<MCAlgoMapperBase<AlgoBase> >( new MCAlgoMapper<AlgoBase, DataTypeRT< enum_type >::type >() )
326 
327  switch( enum_type )
328  {
329  //CASE( W_DT_BINARY ); // the cast operation DataTypeRT is not implemented for binaries, so far
330  CASE( W_DT_UNSIGNED_CHAR );
331  CASE( W_DT_INT8 );
332  CASE( W_DT_SIGNED_SHORT ); // INT16
333  CASE( W_DT_SIGNED_INT ); // INT32
334  CASE( W_DT_FLOAT );
335  CASE( W_DT_DOUBLE );
336  CASE( W_DT_UINT16 );
337  CASE( W_DT_UINT32 );
338  CASE( W_DT_INT64 );
339  CASE( W_DT_UINT64 );
340  CASE( W_DT_FLOAT128 );
341  // no complex 128 or complex 256, no rgba
342  default:
343  WAssert( false, "Data type not implemented because it is not a scalar or just not implemented, yet" );
344  }
345  return std::shared_ptr<MCAlgoMapperBase<AlgoBase> >(); // something went wrong, we got an unreasonable type
346 #undef CASE
347  }
348 } // namespace
349 
350 void WMIsosurface::generateSurfacePre( double isoValue )
351 {
352  debugLog() << "Isovalue: " << isoValue;
353  WAssert( ( *m_dataSet ).getValueSet()->order() == 0, "This module only works on scalars." );
354 
356  WMarchingLegoAlgorithm mlAlgo;
357  std::shared_ptr< WGridRegular3D > gridRegular3D = std::dynamic_pointer_cast< WGridRegular3D >( ( *m_dataSet ).getGrid() );
358  WAssert( gridRegular3D, "Grid is not of type WGridRegular3D." );
359  m_grid = gridRegular3D;
360 
361  std::shared_ptr< WValueSetBase > valueSet( m_dataSet->getValueSet() );
362 
363  std::shared_ptr<MCBase> algo;
364  if( m_useMarchingLego->get( true ) )
365  {
366  algo = createAlgo<WMarchingLegoAlgorithm>( valueSet->getDataType() );
367  }
368  else
369  {
370  algo = createAlgo<WMarchingCubesAlgorithm>( valueSet->getDataType() );
371  }
372 
373  if( algo )
374  {
375  m_triMesh = algo->execute( m_grid->getNbCoordsX(), m_grid->getNbCoordsY(), m_grid->getNbCoordsZ(),
376  m_grid->getTransformationMatrix(),
377  valueSet,
378  isoValue, m_progress );
379 
380  // Set the info properties
381  m_nbTriangles->set( m_triMesh->triangleSize() );
382  m_nbVertices->set( m_triMesh->vertSize() );
383  }
384 }
385 
387 {
388  {
389  // Remove the previous node in a thread safe way.
390  std::unique_lock< std::shared_mutex > lock;
391  lock = std::unique_lock< std::shared_mutex >( m_updateLock );
392 
393  m_moduleNode->remove( m_surfaceGeode );
394 
395  lock.unlock();
396  }
397 
398  osg::ref_ptr< osg::Geometry > surfaceGeometry( new osg::Geometry() );
399  m_surfaceGeode = osg::ref_ptr< osg::Geode >( new osg::Geode );
400 
401  m_surfaceGeode->setName( "iso surface" );
402 
403  surfaceGeometry->setVertexArray( m_triMesh->getVertexArray() );
404  osg::ref_ptr< osg::DrawElementsUInt > surfaceElement( new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 ) );
405 
406  std::vector< size_t > tris = m_triMesh->getTriangles();
407  surfaceElement->reserve( tris.size() );
408 
409  for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
410  {
411  surfaceElement->push_back( tris[vertId] );
412  }
413  surfaceGeometry->addPrimitiveSet( surfaceElement );
414 
415  // ------------------------------------------------
416  // normals
417  surfaceGeometry->setNormalArray( m_triMesh->getVertexNormalArray() );
418  surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
419 
420  m_surfaceGeode->addDrawable( surfaceGeometry );
421  osg::ref_ptr< osg::StateSet > state = m_surfaceGeode->getOrCreateStateSet();
422 
423  // ------------------------------------------------
424  // colors
425  osg::ref_ptr< osg::Vec4Array > colors( new osg::Vec4Array );
426 
427  colors->push_back( m_surfaceColor->get( true ) );
428  surfaceGeometry->setColorArray( colors );
429  surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
430 
431  osg::ref_ptr<osg::LightModel> lightModel( new osg::LightModel() );
432  lightModel->setTwoSided( true );
433  state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
434  {
435  osg::ref_ptr< osg::Material > material( new osg::Material() );
436  material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
437  material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
438  material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
439  material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
440  material->setShininess( osg::Material::FRONT, 25.0 );
441  state->setAttribute( material );
442  }
443 
444  surfaceGeometry->setUseDisplayList( false );
445  surfaceGeometry->setUseVertexBufferObjects( true );
446 
447  m_shader->apply( m_surfaceGeode );
448 
449  // enable transparency
451 
452  // Colormapping
454 
455  m_moduleNode->insert( m_surfaceGeode );
456  m_moduleNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMIsosurface::updateGraphicsCallback, this ) ) );
457 }
458 
460 {
461  std::unique_lock< std::shared_mutex > lock;
462  lock = std::unique_lock< std::shared_mutex >( m_updateLock );
463 
464  if( m_surfaceColor->changed() )
465  {
466  osg::ref_ptr< osg::Vec4Array > colors( new osg::Vec4Array );
467 
468  colors->push_back( m_surfaceColor->get( true ) );
469  m_surfaceGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors );
470  m_surfaceGeode->getDrawable( 0 )->asGeometry()->setColorBinding( osg::Geometry::BIND_OVERALL );
471  }
472 
473  lock.unlock();
474 }
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
static void apply(osg::ref_ptr< osg::Node > node, WMatrix4d preTransform=WMatrix4d::identity(), osg::ref_ptr< WGEShader > shader=osg::ref_ptr< WGEShader >(), size_t startTexUnit=0)
Apply the colormapping to the specified node.
This callback allows you a simple usage of callbacks in your module.
This class adds some convenience methods to WGEGroupNode.
This class enables you to add arbitrary nodes that get post-processed in screen space.
Class implementing a uniform which can be controlled by a property instance.
std::shared_ptr< WGEShaderPreprocessor > SPtr
Shared pointer for this class.
This is a WGEShaderDefineOptions class which additionally uses a property to automatically control th...
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
Definition: WGEShader.h:48
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
Definition: WKernel.cpp:117
std::shared_ptr< WGraphicsEngine > getGraphicsEngine() const
Returns pointer to currently running instance of graphics engine.
Definition: WKernel.cpp:122
Module implementing the marching cubes algorithm with consistent triangulation for data given on regu...
Definition: WMIsosurface.h:51
void updateGraphicsCallback()
updates textures and shader parameters when called (usually from the callback)
WPropInt m_nbVertices
Info-property showing the number of vertices in the mesh.
Definition: WMIsosurface.h:131
virtual void moduleMain()
Entry point after loading the module.
osg::ref_ptr< osg::Geode > m_surfaceGeode
Pointer to geode containing the surface.
Definition: WMIsosurface.h:162
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_input
Input connector required by this module.
Definition: WMIsosurface.h:146
virtual const std::string getName() const
Gives back the name of this module.
std::shared_mutex m_updateLock
Lock to prevent concurrent threads trying to update the osg node.
Definition: WMIsosurface.h:128
osg::ref_ptr< WGEManagedGroupNode > m_moduleNode
Pointer to the module's group node. We need it to be able to update it for callback.
Definition: WMIsosurface.h:159
void renderMesh()
Prepares and commits everything for rendering with the OSG.
std::shared_ptr< WCondition > m_recompute
This condition denotes whether we need to recompute the surface.
Definition: WMIsosurface.h:143
WPropBool m_useMarchingLego
Property indicating whether to use interpolated or non interpolated triangulation.
Definition: WMIsosurface.h:138
std::shared_ptr< const WDataSetScalar > m_dataSet
pointer to dataSet to be able to access it throughout the whole module.
Definition: WMIsosurface.h:154
virtual void properties()
Initialize the properties for this module.
WMIsosurface()
Standard constructor.
virtual const std::string getDescription() const
Gives back a description of this module.
virtual void connectors()
Initialize the connectors this module is using.
std::shared_ptr< WTriangleMesh > m_triMesh
This triangle mesh is provided as output through the connector.
Definition: WMIsosurface.h:149
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
std::shared_ptr< WModuleOutputData< WTriangleMesh > > m_output
Input connector required by this module.
Definition: WMIsosurface.h:147
std::shared_ptr< WGridRegular3D > m_grid
pointer to grid, because we need to access the grid for the dimensions of the texture.
Definition: WMIsosurface.h:155
osg::ref_ptr< WGEShader > m_shader
The shader.
Definition: WMIsosurface.h:167
WPropInt m_nbTriangles
Info-property showing the number of triangles in the mesh.
Definition: WMIsosurface.h:130
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
void generateSurfacePre(double isoValue)
Kind of a convenience function for generate surface.
WPropColor m_surfaceColor
Property determining the color for the surface if no textures are displayed.
Definition: WMIsosurface.h:136
WPropBool m_useTextureProp
Property indicating whether to use texturing with scalar data sets.
Definition: WMIsosurface.h:135
~WMIsosurface()
Destructor.
WPropInt m_opacityProp
Property holding the opacity valueassigned to the surface.
Definition: WMIsosurface.h:134
WPropDouble m_isoValueProp
Property holding the iso value.
Definition: WMIsosurface.h:133
This class does the actual computation of marching cubes.
Creates a non interpolated triangulation of an isosurface.
Class offering an instantiate-able data connection between modules.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
boost::filesystem::path m_localPath
The path where the module binary resides in.
Definition: WModule.h:734
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void removeConnectors()
Removes all connectors properly.
Definition: WModule.cpp:194
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
Definition: WModule.cpp:108
std::shared_ptr< WProperties > m_properties
The property object for the module.
Definition: WModule.h:640
std::shared_ptr< WProperties > m_infoProperties
The property object for the module containing only module whose purpose is "PV_PURPOSE_INFORMNATION".
Definition: WModule.h:647
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
WPropBool m_active
True whenever the module should be active.
Definition: WModule.h:723
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
Definition: WModule.h:652
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
Class managing progress inside of modules.
Definition: WProgress.h:42
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
Base Class for all value set types.
Definition: WValueSet.h:47
void enableTransparency(osg::ref_ptr< osg::Node > node)
Enable transparency for the given node.
Definition: WGEUtils.cpp:215
const double MAX_DOUBLE
Maximum double value.
Definition: WLimits.cpp:31
const double MIN_DOUBLE
Positive minimum double value.
Definition: WLimits.cpp:36