OpenWalnut  1.5.0dev
WMFiberDisplay.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 <limits>
26 #include <memory>
27 #include <string>
28 #include <vector>
29 
30 #include <osg/Depth>
31 #include <osg/Drawable>
32 #include <osg/Geode>
33 #include <osg/Geometry>
34 #include <osg/Hint>
35 #include <osg/LineWidth>
36 #include <osg/Point>
37 #include <osg/PointSprite>
38 #include <osgDB/Export>
39 #include <osgDB/Registry>
40 #include <osgDB/WriteFile>
41 
42 #include "WMFiberDisplay.h"
43 #include "core/common/WPropertyHelper.h"
44 #include "core/common/WPropertyObserver.h"
45 #include "core/dataHandler/WDataHandler.h"
46 #include "core/dataHandler/WDataSetFiberClustering.h"
47 #include "core/dataHandler/WDataSetFibers.h"
48 #include "core/graphicsEngine/WGEColormapping.h"
49 #include "core/graphicsEngine/WGEGeodeUtils.h"
50 #include "core/graphicsEngine/WGEUtils.h"
51 #include "core/graphicsEngine/callbacks/WGEFunctorCallback.h"
52 #include "core/graphicsEngine/callbacks/WGENodeMaskCallback.h"
53 #include "core/graphicsEngine/postprocessing/WGEPostprocessingNode.h"
54 #include "core/graphicsEngine/shaders/WGEShader.h"
55 #include "core/graphicsEngine/shaders/WGEShaderDefineOptions.h"
56 #include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
57 #include "core/kernel/WKernel.h"
58 
59 // This line is needed by the module loader to actually find your module. You need to add this to your module too. Do NOT add a ";" here.
60 W_LOADABLE_MODULE( WMFiberDisplay )
61 
63  WModule()
64 {
65 }
66 
68 {
69  // Cleanup!
70 }
71 
72 std::shared_ptr< WModule > WMFiberDisplay::factory() const
73 {
74  return std::shared_ptr< WModule >( new WMFiberDisplay() );
75 }
76 
77 const std::string WMFiberDisplay::getName() const
78 {
79  return "Fiber Display";
80 }
81 
82 const std::string WMFiberDisplay::getDescription() const
83 {
84  return "Display fibers. This module allows filtering by ROIs and provides full fletched graphical output.";
85 }
86 
88 {
89  m_fiberInput = WModuleInputData < WDataSetFibers >::createAndAdd( shared_from_this(), "fibers", "The fiber dataset to color" );
91  "Optional input to filter the fibers using a clustering." );
92 
94 }
95 
97 {
98  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
99 
100  // Info properties
101  m_nbVertices = m_infoProperties->addProperty( "Points", "The number of points in the visualized data set.", 0 );
102  m_nbVertices->setMax( std::numeric_limits< int >::max() );
103  m_nbFibers = m_infoProperties->addProperty( "Fibers", "The number of fibers in the visualized data set.", 0 );
104  m_nbFibers->setMax( std::numeric_limits< int >::max() );
105 
106  // Other roperties
107  m_roiFiltering = m_properties->addProperty( "ROI Filtering", "When active, you can use the ROI mechanism to filter fibers.", true );
108  m_roiFilterColors = m_properties->addProperty( "ROI Coloring", "When active, you will see the coloring specified by the ROI branches.", true );
109 
110  m_coloringGroup = m_properties->addPropertyGroup( "Coloring", "Options for defining the coloring of the lines." );
111  m_illuminationEnable = m_coloringGroup->addProperty( "Illumination", "Enable line illumination.", true );
112  m_plainColorMode = m_coloringGroup->addProperty( "Use plain color",
113  "When activated, the specified color is used for the lines instead of the dataset colors.", false, m_propCondition );
114  m_plainColor = m_coloringGroup->addProperty( "Color", "Choose how to color the lines.", defaultColor::WHITE, m_propCondition );
115 
116  m_colormapEnabled = m_coloringGroup->addProperty( "Enable colormapping", "Check this to enable colormapping. On large data, this can cause "
117  "massive FPS drop.", false );
118  m_colormapRatio = m_coloringGroup->addProperty( "Colormap Ratio", "Defines the ratio between colormap and line color.", 0.5 );
119  m_colormapRatio->setMin( 0.0 );
120  m_colormapRatio->setMax( 1.0 );
121 
122  m_clipPlaneGroup = m_properties->addPropertyGroup( "Clipping", "Clip the fiber data basing on an arbitrary plane." );
123  m_clipPlaneEnabled = m_clipPlaneGroup->addProperty( "Enabled", "If set, clipping of fibers is done using an arbitrary plane and plane distance.",
124  false );
125  m_clipPlaneShowPlane = m_clipPlaneGroup->addProperty( "Show Clip Plane", "If set, the clipping plane will be shown.", false );
126  m_clipPlanePoint = m_clipPlaneGroup->addProperty( "Plane point", "An point on the plane.", WPosition( 0.0, 0.0, 0.0 ) );
127  m_clipPlaneVector = m_clipPlaneGroup->addProperty( "Plane normal", "The normal of the plane.", WPosition( 1.0, 0.0, 0.0 ) );
128  m_clipPlaneDistance= m_clipPlaneGroup->addProperty( "Clip distance", "The distance from the plane where fibers get clipped.", 10.0 );
129  //m_clipPlaneDistance->removeConstraint( m_clipPlaneDistance->getMax() ); // there simply is no max.
130  m_clipPlaneDistance->setMin( 0.0 );
131  m_clipPlaneDistance->setMax( 1000.0 );
132 
133  m_lineGroup = m_properties->addPropertyGroup( "Line Rendering", "Line rendering specific options." );
134  m_lineWidth = m_lineGroup->addProperty( "Line width", "The line width.", 1.0 );
135  m_lineWidth->setMin( 1.0 );
136  m_lineWidth->setMax( 10.0 );
137  m_lineSmooth = m_lineGroup->addProperty( "Anti-Alias", "Anti-aliased line rendering. This can be slow!", false );
138 
139  m_tubeGroup = m_properties->addPropertyGroup( "Tube Rendering", "Tube rendering specific options." );
140  m_tubeEnable = m_tubeGroup->addProperty( "Enable Tubes", "If set, fake-tube rendering is used.", false, m_propCondition );
141  m_tubeEndCapsEnable = m_tubeGroup->addProperty( "Use end caps", "If set, fake-tube ends are rendered using another quad simulation a proper"
142  " ending.", true );
143  m_tubeRibbon = m_tubeGroup->addProperty( "Ribbon mode", "If set, the tubes look like flat ribbons.", false );
144  m_tubeZoomable = m_tubeGroup->addProperty( "Zoomable", "If set, fake-tube get thicker when zoomed in. If not set, they always keep the same "
145  "size in screen-space. This emulates standard OpenGL lines.", true );
146  m_tubeSize = m_tubeGroup->addProperty( "Width", "The size of the tubes.", 2.0 );
147  m_tubeSize->setMin( 0.10 );
148  m_tubeSize->setMax( 25.0 );
149 
150  // call WModule's initialization
152 }
153 
154 /**
155  * Enables everything which is needed for proper transparency.
156  *
157  * \param state the state of the node
158  */
159 void enableTransparency( osg::StateSet* state )
160 {
161  // NOTE: this does not en/disable blending. This is always on.
162  state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
163 
164  // Enable depth test so that an opaque polygon will occlude a transparent one behind it.
165  state->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );
166 
167  // Conversely, disable writing to depth buffer so that a transparent polygon will allow polygons behind it to shine through.
168  // OSG renders transparent polygons after opaque ones.
169 
170  // This code is commented out so the postprecessing filters work (They need depth write)
171  // osg::Depth* depth = new osg::Depth;
172  // depth->setWriteMask( false );
173  // state->setAttributeAndModes( depth, osg::StateAttribute::ON );
174 
175  // disable light for this geode as lines can't be lit properly
176  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
177 }
178 
179 /**
180  * Disables everything which is needed for proper transparency.
181  *
182  * \param state the state of the node
183  */
184 void disableTransparency( osg::StateSet* state )
185 {
186  // TODO(ebaum): this transparency is problematic. Depth write is on because we need the depth buffer for post-processing
187  // Enable depth test so that an opaque polygon will occlude a transparent one behind it.
188  state->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );
189 
190  // disable light for this geode as lines can't be lit properly
191  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
192 }
193 
195 {
196  m_shader = osg::ref_ptr< WGEShader > ( new WGEShader( "WMFiberDisplay", m_localPath ) );
197 
198  // this shader also includes a geometry shader, so set some needed options
199  m_endCapShader = osg::ref_ptr< WGEShader > ( new WGEShader( "WMFiberDisplay-EndCap", m_localPath ) );
200  m_endCapShader->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, 4 );
201  m_endCapShader->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_POINTS );
202  m_endCapShader->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP );
203 
204  // initialize illumination shader
206  new WGEShaderPropertyDefineOptions< WPropBool >( m_illuminationEnable, "ILLUMINATION_DISABLED", "ILLUMINATION_ENABLED" ) );
207  m_shader->addPreprocessor( defineTmp );
208  m_endCapShader->addPreprocessor( defineTmp );
209 
210  // initialize clipping shader
211  osg::ref_ptr< WGEPropertyUniform< WPropPosition > > clipPlanePointUniform = new WGEPropertyUniform< WPropPosition >( "u_planePoint",
213  osg::ref_ptr< WGEPropertyUniform< WPropPosition > > clipPlaneVectorUniform = new WGEPropertyUniform< WPropPosition >( "u_planeVector",
215  osg::ref_ptr< WGEPropertyUniform< WPropDouble > > clipPlaneDistanceUniform = new WGEPropertyUniform< WPropDouble >( "u_distance",
217  defineTmp = WGEShaderPreprocessor::SPtr(
218  new WGEShaderPropertyDefineOptions< WPropBool >( m_clipPlaneEnabled, "CLIPPLANE_DISABLED", "CLIPPLANE_ENABLED" ) );
219  m_shader->addPreprocessor( defineTmp );
220  m_endCapShader->addPreprocessor( defineTmp );
221 
222  // init tube shader
223  defineTmp = WGEShaderPreprocessor::SPtr(
224  new WGEShaderPropertyDefineOptions< WPropBool >( m_tubeEnable, "TUBE_DISABLED", "TUBE_ENABLED" ) );
225  m_shader->addPreprocessor( defineTmp );
226  m_endCapShader->addPreprocessor( defineTmp );
227 
228  defineTmp = WGEShaderPreprocessor::SPtr(
229  new WGEShaderPropertyDefineOptions< WPropBool >( m_tubeZoomable, "ZOOMABLE_DISABLED", "ZOOMABLE_ENABLED" ) );
230  m_shader->addPreprocessor( defineTmp );
231  m_endCapShader->addPreprocessor( defineTmp );
232 
233  defineTmp = WGEShaderPreprocessor::SPtr(
234  new WGEShaderPropertyDefineOptions< WPropBool >( m_tubeRibbon, "RIBBON_DISABLED", "RIBBON_ENABLED" ) );
235  m_shader->addPreprocessor( defineTmp );
236  m_endCapShader->addPreprocessor( defineTmp );
237 
238  defineTmp = WGEShaderPreprocessor::SPtr(
239  new WGEShaderPropertyDefineOptions< WPropBool >( m_tubeEndCapsEnable, "ENDCAPS_DISABLED", "ENDCAPS_ENABLED" ) );
240  m_endCapShader->addPreprocessor( defineTmp );
241 
243  new WGEShaderDefineOptions( "CLUSTER_FILTER_ENABLED" )
244  );
245  clusterFilterOption->deactivateAllOptions();
246  m_shader->addPreprocessor( clusterFilterOption );
247  m_endCapShader->addPreprocessor( clusterFilterOption );
248 
249  osg::ref_ptr< WGEPropertyUniform< WPropDouble > > tubeSizeUniform = new WGEPropertyUniform< WPropDouble >( "u_tubeSize", m_tubeSize );
250  osg::ref_ptr< WGEPropertyUniform< WPropDouble > > colormapRationUniform =
251  new WGEPropertyUniform< WPropDouble >( "u_colormapRatio", m_colormapRatio );
252  m_shader->addPreprocessor( WGEShaderPreprocessor::SPtr(
253  new WGEShaderPropertyDefineOptions< WPropBool >( m_colormapEnabled, "COLORMAPPING_DISABLED", "COLORMAPPING_ENABLED" ) )
254  );
255 
256  // ROI Filter support:
257  defineTmp = WGEShaderPreprocessor::SPtr(
258  new WGEShaderPropertyDefineOptions< WPropBool >( m_roiFiltering, "BITFIELD_DISABLED", "BITFIELD_ENABLED" ) );
259  m_shader->addPreprocessor( defineTmp );
260  m_endCapShader->addPreprocessor( defineTmp );
261 
262  // ROI Filter color support
263  defineTmp = WGEShaderPreprocessor::SPtr(
264  new WGEShaderPropertyDefineOptions< WPropBool >( m_roiFilterColors, "SECONDARY_COLORING_DISABLED", "SECONDARY_COLORING_ENABLED" ) );
265  m_shader->addPreprocessor( defineTmp );
266  m_endCapShader->addPreprocessor( defineTmp );
267 
268  m_shader->addBindAttribLocation( "a_bitfield", 6 );
269  m_endCapShader->addBindAttribLocation( "a_bitfield", 6 );
270 
271  // get notified about data changes
272  m_moduleState.setResetable( true, true );
273  m_moduleState.add( m_fiberInput->getDataChangedCondition() );
274  m_moduleState.add( m_fiberClusteringInput->getDataChangedCondition() );
275  // Remember the condition provided to some properties in properties()? The condition can now be used with this condition set.
277 
278  // create the post-processing node which actually does the nice stuff to the rendered image
279  osg::ref_ptr< WGEPostprocessingNode > postNode = new WGEPostprocessingNode(
280  WKernel::getRunningKernel()->getGraphicsEngine()->getViewer()->getCamera()
281  );
282  postNode->addUpdateCallback( new WGENodeMaskCallback( m_active ) ); // disable the postNode with m_active
283  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( postNode );
284  // provide the properties of the post-processor to the user
285  m_properties->addProperty( postNode->getProperties() );
286 
287  // do not forget to add the uniforms
288  osg::StateSet* rootState = postNode->getOrCreateStateSet();
289  rootState->addUniform( clipPlanePointUniform );
290  rootState->addUniform( clipPlaneVectorUniform );
291  rootState->addUniform( clipPlaneDistanceUniform );
292  rootState->addUniform( tubeSizeUniform );
293  rootState->addUniform( colormapRationUniform );
294 
295  // we need another uniform for turning on/off the ROI - coloring when no fibers are filtered out (no branches/no ROIs). In these cases, the
296  // m_roiFilterColors might still be true, but we need to turn off coloring though.
297  // NOTE: 1.0 means the ROI colors are used.
298  m_roiFilterColorsOverride = new osg::Uniform( "u_roiFilterColorOverride", 0.0f );
299  rootState->addUniform( m_roiFilterColorsOverride );
300  ready();
301 
302  // needed to observe the properties of the input connector data
303  std::shared_ptr< WPropertyObserver > propObserver = WPropertyObserver::create();
304  m_moduleState.add( propObserver );
305 
307 
308  // main loop
309  while( !m_shutdownFlag() )
310  {
311  debugLog() << "Waiting ...";
313 
314  // woke up since the module is requested to finish?
315  if( m_shutdownFlag() )
316  {
317  break;
318  }
319 
320  //////////////////////////////////////////////////////////////////////////////////////////
321  // Get and check data
322  //////////////////////////////////////////////////////////////////////////////////////////
323 
324  // changed? And set new current data pointers
325  bool fibersUpdated = m_fiberInput->updated();
326  bool clusteringUpdated = m_fiberClusteringInput->updated();
327 
328  // To query whether an input was updated, simply ask the input:
329  std::shared_ptr< WDataSetFibers > fibers = m_fiberInput->getData();
330  std::shared_ptr< WDataSetFiberClustering > fiberClustering = m_fiberClusteringInput->getData();
331 
332  bool dataValid = ( fibers != NULL );
333  bool dataPropertiesUpdated = propObserver->updated();
334  bool propertiesUpdated = m_tubeEnable->changed() || m_plainColorMode->changed() || m_plainColor->changed();
335 
336  // reset graphics if noting is on the input
337  if( !dataValid )
338  {
339  debugLog() << "Resetting.";
340  // remove geode if no valid data is available
341  postNode->clear();
342 
343  // remove the fib's properties from my props
344  m_coloringGroup->removeProperty( m_fibProps );
345  m_fibProps.reset();
346  }
347 
348  // something happened we are interested in?
349  if( !( dataValid && ( propertiesUpdated || dataPropertiesUpdated || fibersUpdated || clusteringUpdated ) ) )
350  {
351  debugLog() << "Nothing to do.";
352  continue;
353  }
354 
355  if( clusteringUpdated && ( fiberClustering != m_fiberClustering ) )
356  {
357  debugLog() << "Clustering updated.";
358  m_fiberClustering = fiberClustering;
359  // also inform the shader to use cluster filter stuff
360  if( m_fiberClustering )
361  {
362  clusterFilterOption->activateOption( 0 );
363  }
364  else
365  {
366  clusterFilterOption->deactivateOption( 0 );
367  }
369  }
370 
371  if( fibersUpdated || dataPropertiesUpdated || propertiesUpdated )
372  {
373  debugLog() << "Fibers updated.";
374 
375  {
376  std::unique_lock< boost::mutex > lock( m_mutex );
377 
378  m_fibers = fibers;
379 
380  // get a new fiber selector
381  m_fiberSelector = std::shared_ptr<WFiberSelector>( new WFiberSelector( fibers ) );
382  }
383 
384  m_nbFibers->set( m_fibers->size() );
385  m_nbVertices->set( m_fibers->getNbVertices() );
386 
387  // update the prop observer if new data is available
388  m_coloringGroup->removeProperty( m_fibProps );
389  m_fibProps = fibers->getProperties();
390  propObserver->observe( m_fibProps );
391  propObserver->handled();
392  // also add the fib props to own props. This allows the user to modify the fib props directly
393  m_coloringGroup->addProperty( m_fibProps );
394 
395  //////////////////////////////////////////////////////////////////////////////////////////
396  // Create new rendering
397  //////////////////////////////////////////////////////////////////////////////////////////
398 
399  // add geode to module node
400  postNode->clear();
401 
402  // register dirty notifier
403  m_roiUpdateConnection.disconnect();
404  m_roiUpdateConnection = m_fiberSelector->getDirtyCondition()->subscribeSignal(
405  boost::bind( &WMFiberDisplay::roiUpdate, this )
406  );
407 
408  // we force the module to check if we need to enable normal colormapping even if ROI coloring is set
409  roiUpdate();
410 
411  // create the fiber geode
412  osg::ref_ptr< osg::Geode > geode = new osg::Geode();
413  osg::ref_ptr< osg::Geode > endCapGeode = new osg::Geode();
414 
415  // this avoids that the pick handler tries to pick in millions if lines and quads
416  geode->setName( "_Line Geode" );
417  endCapGeode->setName( "_Tube Cap Geode" );
418  geode->setNodeMask( 0x0000000F );
419  endCapGeode->setNodeMask( 0x0000000F );
420 
421  createFiberGeode( fibers, geode, endCapGeode );
422 
423  // Apply the shader. This is for clipping.
424  m_shader->apply( geode );
425  m_endCapShader->apply( endCapGeode );
426  // apply colormapping
428  WGEColormapping::apply( endCapGeode, m_endCapShader );
429 
430  // for line smoothing and width features
431  osg::ref_ptr< osg::StateSet > state = geode->getOrCreateStateSet();
432  state->setUpdateCallback( new WGEFunctorCallback< osg::StateSet >(
433  boost::bind( &WMFiberDisplay::lineGeodeStateCallback, this, boost::placeholders::_1 ) )
434  );
435 
436  // set attributes
437  state->setAttributeAndModes( new osg::LineWidth( m_lineWidth->get( true ) ), osg::StateAttribute::ON );
438 
439  osg::StateAttribute::GLModeValue onoff = m_lineSmooth->get() ? osg::StateAttribute::ON : osg::StateAttribute::OFF;
440  state->setAttributeAndModes( new osg::Hint( GL_LINE_SMOOTH_HINT, GL_NICEST ), onoff );
441  state->setMode( GL_LINE_SMOOTH, onoff );
442  state->setMode( GL_BLEND, osg::StateAttribute::ON );
443 
444  // Add geometry
445  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_plane );
446 
448  postNode->insert( geode, m_shader );
449  postNode->insert( endCapGeode, m_endCapShader );
450  }
451  }
452 
453  // At this point, the container managing this module signalled to shutdown. The main loop has ended and you should clean up. Always remove
454  // allocated memory and remove all OSG nodes.
455  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( postNode );
456 }
457 
458 void WMFiberDisplay::clipPlaneCallback( osg::Node* node ) const
459 {
460  // NOTE: this callback is only executed if the plane is enabled since the NodeMaskCallback ensures proper activation of the node
461  osg::MatrixTransform* transform = static_cast< osg::MatrixTransform* >( node );
462 
463  WPosition v = m_clipPlaneVector->get();
464  WPosition p = m_clipPlanePoint->get();
465 
466  // the point p can be interpreted as translation:
467  osg::Matrix translation = osg::Matrix::translate( p.as< osg::Vec3d >() );
468 
469  // the geometry that was specified has the normal ( 1.0, 0.0, 0.0 ). So it is possible to interpret any other normal as a rotation
470  osg::Matrix rotation = osg::Matrix::rotate( osg::Vec3d( 1.0, 0.0, 0.0 ), v );
471 
472  transform->setMatrix( rotation * translation );
473 }
474 
475 osg::ref_ptr< osg::Node > WMFiberDisplay::createClipPlane() const
476 {
477  // add the clipping plane
478  osg::ref_ptr< osg::Geode > planeGeode = new osg::Geode();
479  osg::ref_ptr< osg::MatrixTransform > planeTransform = new osg::MatrixTransform();
480  osg::ref_ptr< osg::Vec3Array > planeVertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
481  osg::ref_ptr< osg::Vec4Array > planeColor = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
482  osg::ref_ptr< osg::Geometry > planeGeometry = osg::ref_ptr< osg::Geometry >( new osg::Geometry );
483 
484  // the plane vertices
485  planeColor->push_back( osg::Vec4( 1.0, 0.0, 0.0, 0.125 ) );
486  planeVertices->push_back( osg::Vec3( 0.0, -100.0, -100.0 ) );
487  planeVertices->push_back( osg::Vec3( 0.0, -100.0, 100.0 ) );
488  planeVertices->push_back( osg::Vec3( 0.0, 100.0, 100.0 ) );
489  planeVertices->push_back( osg::Vec3( 0.0, 100.0, -100.0 ) );
490 
491  // build geometry
492  planeGeometry->setVertexArray( planeVertices );
493  planeGeometry->setColorArray( planeColor );
494  planeGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
495  planeGeometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
496  planeGeode->addDrawable( planeGeometry );
497 
498  enableTransparency( planeGeode->getOrCreateStateSet() );
499  planeGeode->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
500 
501  // add a callback for showing and hiding the plane
502  planeTransform->addUpdateCallback( new WGENodeMaskCallback( m_clipPlaneShowPlane ) );
503  // add a callback which actually moves, scales and rotates the plane according to the plane parameter
504  planeTransform->addUpdateCallback( new WGEFunctorCallback< osg::Node >(
505  boost::bind( &WMFiberDisplay::clipPlaneCallback, this, boost::placeholders::_1 ) )
506  );
507 
508  // add the geode to the root and provide an callback
509  planeTransform->addChild( planeGeode );
510 
511  return planeTransform;
512 }
513 
514 void WMFiberDisplay::createFiberGeode( std::shared_ptr< WDataSetFibers > fibers, osg::ref_ptr< osg::Geode > fibGeode,
515  osg::ref_ptr< osg::Geode > endCapGeode )
516 {
517  // geode and geometry
518  osg::StateSet* state = fibGeode->getOrCreateStateSet();
519  osg::StateSet* endState = endCapGeode->getOrCreateStateSet();
520 
521  // disable light for this geode as lines can't be lit properly
522  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
523 
524  // create everything needed for the line_strip drawable
525  osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
526  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
527  osg::ref_ptr< osg::Vec3Array > tangents = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
528  osg::ref_ptr< osg::FloatArray > texcoords = osg::ref_ptr< osg::FloatArray >( new osg::FloatArray );
529  osg::ref_ptr< osg::Geometry > geometry = osg::ref_ptr< osg::Geometry >( new osg::Geometry );
530 
531  // new attribute array
532  m_bitfieldAttribs = new osg::FloatArray( m_fibers->getLineStartIndexes()->size() );
533  m_secondaryColor = new osg::Vec3Array( m_fibers->getLineStartIndexes()->size() );
534 
535  // this is needed for the end- sprites
536  osg::ref_ptr< osg::Vec3Array > endVertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
537  osg::ref_ptr< osg::Vec4Array > endColors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
538  osg::ref_ptr< osg::Vec3Array > endTangents = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
539  osg::ref_ptr< osg::Geometry > endGeometry = osg::ref_ptr< osg::Geometry >( new osg::Geometry );
540 
541  // this is needed for the end- sprites
542  // NOTE: we handle start caps and end caps separately here since the vertex attributes are per line so we need to have one cap per line.
543  osg::ref_ptr< osg::Vec3Array > startVertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
544  osg::ref_ptr< osg::Vec4Array > startColors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
545  osg::ref_ptr< osg::Vec3Array > startTangents = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
546  osg::ref_ptr< osg::Geometry > startGeometry = osg::ref_ptr< osg::Geometry >( new osg::Geometry );
547 
548 
549  // needed arrays for iterating the fibers
550  WDataSetFibers::IndexArray fibStart = fibers->getLineStartIndexes();
551  WDataSetFibers::LengthArray fibLen = fibers->getLineLengths();
552  WDataSetFibers::VertexArray fibVerts = fibers->getVertices();
553  WDataSetFibers::TangentArray fibTangents = fibers->getTangents();
554 
555  // get current color scheme - the mode is important as it defines the number of floats in the color array per vertex.
556  WDataSetFibers::ColorScheme::ColorMode fibColorMode = fibers->getColorScheme()->getMode();
557  debugLog() << "Color mode is " << fibColorMode << ".";
558  WDataSetFibers::ColorArray fibColors = fibers->getColorScheme()->getColor();
559  bool usePlainColor = m_plainColorMode->get( true );
560  WColor plainColor = m_plainColor->get( true );
561 
562  // enable blending, select transparent bin
563  // Either we use the fiber colors or the plain color
564  if( ( !usePlainColor && ( fibColorMode == WDataSetFibers::ColorScheme::RGBA ) ) ||
565  ( usePlainColor && ( plainColor.a() != 1.0 ) ) )
566  {
567  enableTransparency( state );
568  enableTransparency( endState );
569  }
570  else
571  {
572  disableTransparency( state );
573  disableTransparency( endState );
574  }
575  // blending is always needed for the filter attributes
576  state->setMode( GL_BLEND, osg::StateAttribute::ON );
577  // NOTE: this must be turned on in any case as it is used to discard some caps
578  endState->setMode( GL_BLEND, osg::StateAttribute::ON );
579 
580  // progress indication
581  std::shared_ptr< WProgress > progress1( new WProgress( "Adding fibers to geode", fibStart->size() ) );
582  m_progress->addSubProgress( progress1 );
583 
584  // for each fiber:
585  debugLog() << "Iterating over " << fibStart->size() << " fibers.";
586  debugLog() << "Number of vertices: " << fibVerts->size() / 3;
587  size_t currentStart = 0;
588  bool tubeMode = m_tubeEnable->get( true );
589  for( size_t fidx = 0; fidx < fibStart->size() ; ++fidx )
590  {
591  ++*progress1;
592 
593  // the start vertex index
594  size_t sidx = fibStart->at( fidx ) * 3;
595  size_t csidx = fibStart->at( fidx ) * fibColorMode;
596 
597  // the length of the fiber
598  size_t len = fibLen->at( fidx );
599 
600  // also initialize the ROI filter bitfield
601  ( *m_bitfieldAttribs )[ fidx ] = m_fiberSelector->getBitfield()->at( fidx );
602  // NOTE: secondary color arrays only support RGB colors
603  WColor c = m_fiberSelector->getFiberColor( fidx );
604  ( *m_secondaryColor )[ fidx ] = osg::Vec3( c.r(), c.g(), c.b() );
605 
606  // a line needs 2 verts at least
607  if( len < 2 )
608  {
609  continue;
610  }
611 
612  // provide tangents and vertices for the end-caps
613  if( tubeMode )
614  {
615  // NOTE: we could also use the tangents stored in the tangents array but we cannot ensure they are oriented always outwards.
616  // grab first and second vertex.
617  osg::Vec3 firstVert = osg::Vec3( fibVerts->at( ( 3 * 0 ) + sidx ),
618  fibVerts->at( ( 3 * 0 ) + sidx + 1 ),
619  fibVerts->at( ( 3 * 0 ) + sidx + 2 ) );
620  osg::Vec3 secondVert = osg::Vec3( fibVerts->at( ( 3 * 1 ) + sidx ),
621  fibVerts->at( ( 3 * 1 ) + sidx + 1 ),
622  fibVerts->at( ( 3 * 1 ) + sidx + 2 ) );
623  osg::Vec3 lastVert = osg::Vec3( fibVerts->at( ( 3 * ( len - 1 ) ) + sidx ),
624  fibVerts->at( ( 3 * ( len - 1 ) ) + sidx + 1 ),
625  fibVerts->at( ( 3 * ( len - 1 ) ) + sidx + 2 ) );
626  osg::Vec3 secondLastVert = osg::Vec3( fibVerts->at( ( 3 * ( len - 2 ) ) + sidx ),
627  fibVerts->at( ( 3 * ( len - 2 ) ) + sidx + 1 ),
628  fibVerts->at( ( 3 * ( len - 2 ) ) + sidx + 2 ) );
629  osg::Vec3 startNormal = firstVert - secondVert;
630  osg::Vec3 endNormal = lastVert - secondLastVert;
631  startTangents->push_back( startNormal );
632  startVertices->push_back( firstVert );
633  endTangents->push_back( endNormal );
634  endVertices->push_back( lastVert );
635  }
636 
637  // walk along the fiber
638  for( size_t k = 0; k < len; ++k )
639  {
640  osg::Vec3 vert = osg::Vec3( fibVerts->at( ( 3 * k ) + sidx ),
641  fibVerts->at( ( 3 * k ) + sidx + 1 ),
642  fibVerts->at( ( 3 * k ) + sidx + 2 ) );
643 
644  osg::Vec3 tangent = osg::Vec3( fibTangents->at( ( 3 * k ) + sidx ),
645  fibTangents->at( ( 3 * k ) + sidx + 1 ),
646  fibTangents->at( ( 3 * k ) + sidx + 2 ) );
647  tangent.normalize();
648 
649  osg::Vec4 color = plainColor;
650  if( !usePlainColor )
651  {
652  color = osg::Vec4( fibColors->at( ( fibColorMode * k ) + csidx + ( 0 % fibColorMode ) ),
653  fibColors->at( ( fibColorMode * k ) + csidx + ( 1 % fibColorMode ) ),
654  fibColors->at( ( fibColorMode * k ) + csidx + ( 2 % fibColorMode ) ),
655  ( fibColorMode == WDataSetFibers::ColorScheme::RGBA ) ?
656  fibColors->at( ( fibColorMode * k ) + csidx + ( 3 % fibColorMode ) ) : 1.0 );
657  }
658 
659  vertices->push_back( vert );
660  colors->push_back( color );
661  tangents->push_back( tangent );
662 
663  if( tubeMode )
664  {
665  // if in tube-mode, some final sprites are needed to provide some kind of ending for the tube
666  if( k == 0 )
667  {
668  startColors->push_back( color );
669  }
670  if( k == len - 1 )
671  {
672  endColors->push_back( color );
673  }
674 
675  vertices->push_back( vert );
676  colors->push_back( color );
677  tangents->push_back( tangent );
678 
679  // tex coords are only needed for fake-tubes
680  // NOTE: another possibility to transport the information of top and bottom vertex is to use the sign of tangent.x for example.
681  // This saves some mem.
682  texcoords->push_back( 1.0 );
683  texcoords->push_back( -1.0 );
684  }
685  }
686 
687  // add the above line-strip
688  if( m_tubeEnable->get() )
689  {
690  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUAD_STRIP, 2 * currentStart, 2 * len ) );
691  }
692  else
693  {
694  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, currentStart, len ) );
695  }
696 
697  currentStart += len;
698  }
699 
700  // combine these arrays to the geometry
701  geometry->setVertexArray( vertices );
702  geometry->setColorArray( colors );
703  geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
704  geometry->setNormalArray( tangents );
705  geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
706  if( tubeMode ) // tex coords are only needed for fake-tubes
707  {
708  geometry->setTexCoordArray( 0, texcoords );
709 
710  // also create the end-sprite geometry
711  endGeometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::POINTS, 0, endVertices->size() ) );
712  endGeometry->setVertexArray( endVertices );
713  endGeometry->setColorArray( endColors );
714  endGeometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
715  endGeometry->setNormalArray( endTangents );
716  endGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
717 
718  startGeometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::POINTS, 0, startVertices->size() ) );
719  startGeometry->setVertexArray( startVertices );
720  startGeometry->setColorArray( startColors );
721  startGeometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
722  startGeometry->setNormalArray( startTangents );
723  startGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
724 
725  endCapGeode->addDrawable( startGeometry );
726  endCapGeode->addDrawable( endGeometry );
727 
728  endState->setAttribute( new osg::Point( 1.0f ), osg::StateAttribute::ON );
729  }
730  // enable VBO
731  geometry->setUseDisplayList( false );
732  geometry->setUseVertexBufferObjects( true );
733  startGeometry->setUseDisplayList( false );
734  startGeometry->setUseVertexBufferObjects( true );
735  endGeometry->setUseDisplayList( false );
736  endGeometry->setUseVertexBufferObjects( true );
737 
738  // bind the attribute
739  geometry->setVertexAttribArray( 6, m_bitfieldAttribs );
740  geometry->setSecondaryColorArray( m_secondaryColor );
741  // the attributes are define per line strip, thus we bind the array accordingly
742  geometry->setVertexAttribBinding( 6, osg::Geometry::BIND_PER_PRIMITIVE_SET );
743  geometry->setSecondaryColorBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );
744 
745  if( tubeMode )
746  {
747  // we have one vertex per line, so bind the attribute array per vertex
748  startGeometry->setVertexAttribArray( 6, m_bitfieldAttribs );
749  startGeometry->setVertexAttribBinding( 6, osg::Geometry::BIND_PER_PRIMITIVE_SET );
750  endGeometry->setVertexAttribArray( 6, m_bitfieldAttribs );
751  endGeometry->setVertexAttribBinding( 6, osg::Geometry::BIND_PER_PRIMITIVE_SET );
752 
753  startGeometry->setSecondaryColorArray( m_secondaryColor );
754  startGeometry->setSecondaryColorBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );
755  endGeometry->setSecondaryColorArray( m_secondaryColor );
756  endGeometry->setSecondaryColorBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );
757  }
758 
759  // add an update callback which later handles several things like the filter attribute array
760  geometry->setUpdateCallback( new WGEFunctorCallback< osg::Drawable >( boost::bind( &WMFiberDisplay::geometryUpdate,
761  this,
762  boost::placeholders::_1 ) ) );
763 
764  // set drawable
765  fibGeode->addDrawable( geometry );
766 
767  debugLog() << "Iterating over all fibers: done!";
768  progress1->finish();
769 }
770 
771 void WMFiberDisplay::geometryUpdate( osg::Drawable* geometry )
772 {
774  {
775  std::unique_lock< boost::mutex > lock( m_mutex );
776 
777  bool overrideROIFiltering = m_fiberSelector->isNothingFiltered();
778  m_roiFilterColorsOverride->set( overrideROIFiltering ? 1.0f : 0.0f );
779 
780  m_fiberSelectorChanged = false;
781  // now initialize attribute array
782  for( size_t fidx = 0; fidx < m_fibers->getLineStartIndexes()->size() ; ++fidx )
783  {
784  ( *m_bitfieldAttribs )[ fidx ] = overrideROIFiltering | m_fiberSelector->getBitfield()->at( fidx );
785  WColor c = m_fiberSelector->getFiberColor( fidx );
786  ( *m_secondaryColor )[ fidx ] = osg::Vec3( c.r(), c.g(), c.b() );
787  }
788  m_bitfieldAttribs->dirty();
789  m_secondaryColor->dirty();
790  }
791 
793  {
794  m_fiberClusteringUpdate = false;
795  size_t maxFibIdx = m_fibers->getLineStartIndexes()->size() - 1;
796  osg::ref_ptr< osg::Vec3Array > attribs = new osg::Vec3Array( maxFibIdx + 1 );
797  // now initialize attribute array
798  for( size_t fidx = 0; fidx < m_fibers->getLineStartIndexes()->size() ; ++fidx )
799  {
800  ( *attribs)[ fidx ] = osg::Vec3( 0.0, 0.0, 0.0 );
801  }
802 
803  // go through each of the clusters
804  for( WDataSetFiberClustering::ClusterMap::const_iterator iter = m_fiberClustering->begin(); iter != m_fiberClustering->end(); ++iter )
805  {
806  // for each of the fiber IDs:
807  const WFiberCluster::IndexList& ids = ( *iter ).second->getIndices();
808  for( WFiberCluster::IndexList::const_iterator fibIter = ids.begin(); fibIter != ids.end(); ++fibIter )
809  {
810  // be nice here. If the clustering contains some invalid IDs, ignore it.
811  if( *fibIter > maxFibIdx )
812  {
813  continue;
814  }
815  // set the color
816  ( *attribs)[ *fibIter ] = osg::Vec3(
817  ( *iter ).second->getColor().r(),
818  ( *iter ).second->getColor().g(),
819  ( *iter ).second->getColor().b()
820  );
821  }
822  }
823  static_cast< osg::Geometry* >( geometry )->setSecondaryColorArray( attribs );
824  static_cast< osg::Geometry* >( geometry )->setSecondaryColorBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );
825  }
826 }
827 
828 void WMFiberDisplay::lineGeodeStateCallback( osg::StateSet* state )
829 {
830  if( m_lineWidth->changed() )
831  {
832  state->setAttributeAndModes( new osg::LineWidth( m_lineWidth->get( true ) ), osg::StateAttribute::ON );
833  }
834 
835  if( m_lineSmooth->changed( true ) )
836  {
837  // Line smoothing. Will be very slow!
838  osg::StateAttribute::GLModeValue onoff = m_lineSmooth->get() ? osg::StateAttribute::ON : osg::StateAttribute::OFF;
839  state->setAttributeAndModes( new osg::Hint( GL_LINE_SMOOTH_HINT, GL_NICEST ), onoff );
840  state->setMode( GL_LINE_SMOOTH, onoff );
841 
842  // always keep blending enabled
843  state->setMode( GL_BLEND, osg::StateAttribute::ON );
844  }
845 }
846 
848 {
849  m_fiberSelectorChanged = true;
850 }
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
ColorMode
different kinds of color arrays can be used in this class.
std::shared_ptr< std::vector< size_t > > IndexArray
Index list indexing fibers in VertexArray in terms of vertex numbers.
std::shared_ptr< std::vector< float > > ColorArray
Colors for each vertex in VertexArray.
std::shared_ptr< std::vector< float > > TangentArray
Tangents at each vertex in VertexArray.
std::shared_ptr< std::vector< size_t > > LengthArray
Lengths of fibers in terms of vertices.
std::shared_ptr< std::vector< float > > VertexArray
List of vertex coordinates in term of components of vertices.
std::list< size_t > IndexList
This is the list of indices of fibers.
Definition: WFiberCluster.h:61
Adaptor class between the roi manager and the fiber display.
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 callback is useful to en-/disable nodes using the node mask based on properties.
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.
This GLSL preprocessor is able to set one define from a list of defines depending on the active optio...
std::shared_ptr< WGEShaderDefineOptions > SPtr
Shared pointer for this class.
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
This modules takes a dataset and equalizes its histogram.
std::shared_ptr< WModuleInputData< WDataSetFiberClustering > > m_fiberClusteringInput
An optional fiber clustering can be specified to filter in m_fiberInput.
WPropBool m_lineSmooth
Line smoothing.
osg::ref_ptr< WGEShader > m_endCapShader
The shader used for drawing end cap sprites if in tube mode.
WPropBool m_clipPlaneShowPlane
Property for en-/disabling of the clip plane plane.
bool m_fiberClusteringUpdate
If true, the geometryUpdate() callback will upload a new filter attribute array.
WPropBool m_tubeEndCapsEnable
Property denoting whether to use end-caps on tubes.
WDataSetFibers::SPtr m_fibers
The current fiber data.
bool m_fiberSelectorChanged
Is true when received a change signal from m_fiberSelector.
void geometryUpdate(osg::Drawable *geometry)
Geometry update callback.
boost::mutex m_mutex
A mutex used to atomically update the fibers and their selector.
void lineGeodeStateCallback(osg::StateSet *state)
Callback for the line geode to allow interactive modification of line smooth and width states.
osg::ref_ptr< osg::Vec3Array > m_secondaryColor
Contains the ROI color map for live branch coloring.
virtual ~WMFiberDisplay()
Destructor.
WPropDouble m_colormapRatio
The ratio between colormap and fiber color.
boost::signals2::connection m_roiUpdateConnection
Connection to the roi dirty signal.
osg::ref_ptr< osg::Node > createClipPlane() const
Creates the clip plane with corresponding callbacks.
osg::ref_ptr< osg::FloatArray > m_bitfieldAttribs
Contains the ROI bitfield.
WPropGroup m_clipPlaneGroup
A property group for all the clipping related props.
WPropInt m_nbVertices
Info-property showing the number of vertices in the fiber data set.
virtual const std::string getDescription() const
Gives back a description of this module.
osg::ref_ptr< osg::Uniform > m_roiFilterColorsOverride
Ratio between dataset color and ROI color.
WPropBool m_tubeZoomable
Prop denoting whether tubes can be zoomed or not.
WPropBool m_clipPlaneEnabled
Property for en-/disable clipping.
WPropBool m_colormapEnabled
True if colormapping should be used.
osg::ref_ptr< WGEShader > m_shader
The shader used for actually drawing the fake tubes or lines.
WPropBool m_roiFiltering
Allow disabling ROI filter mode.
WPropDouble m_clipPlaneDistance
Distance from plane.
WPropBool m_illuminationEnable
Illumination.
WPropBool m_tubeEnable
Prop denoting whether to use tubes or line strips.
std::shared_ptr< WFiberSelector > m_fiberSelector
Point to a fiber selector, which is an adapter between the ROI manager and the this module.
virtual void properties()
Initialize the properties for this module.
virtual void connectors()
Initialize the connectors this module is using.
virtual void moduleMain()
Entry point after loading the module.
void clipPlaneCallback(osg::Node *node) const
Update the transform node to provide an cue were the plane actually is.
WPropDouble m_lineWidth
Line width.
WMFiberDisplay()
Default constructor.
WProperties::SPtr m_fibProps
The properties of the fiber dataset.
WPropInt m_nbFibers
Info-property showing the number of fibers in the fiber data set.
WPropBool m_plainColorMode
Define whether to use a single color or the dataset color.
WPropPosition m_clipPlanePoint
Point on the plane.
WPropPosition m_clipPlaneVector
Vector of the plane.
void createFiberGeode(std::shared_ptr< WDataSetFibers > fibers, osg::ref_ptr< osg::Geode > fibGeode, osg::ref_ptr< osg::Geode > endCapGeode)
Creates a geode containing the fiber geometry.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
WPropBool m_tubeRibbon
Creates a ribbon-like appearance.
WDataSetFiberClustering::SPtr m_fiberClustering
The current fiber clustering.
void roiUpdate()
Called when updating the selection.
WPropBool m_roiFilterColors
Use coloring defined by the roi branches.
WPropColor m_plainColor
Define a color to use if in plain color mode.
WPropDouble m_tubeSize
The size.
std::shared_ptr< WModuleInputData< WDataSetFibers > > m_fiberInput
The fiber dataset which is going to be filtered.
WPropGroup m_tubeGroup
Group containing tube specific properties.
virtual const std::string getName() const
Gives back the name of this module.
WPropGroup m_lineGroup
Group containing line specific properties.
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...
WPropGroup m_coloringGroup
Group containing several coloring options.
osg::ref_ptr< osg::Node > m_plane
The plane node.
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
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
This only is a 3d double vector.
Class managing progress inside of modules.
Definition: WProgress.h:42
static std::shared_ptr< WPropertyObserver > create()
Creates a new instance of WPropertyObserver.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.