1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
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.
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.
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/>.
23
//---------------------------------------------------------------------------
32
#include <boost/shared_ptr.hpp>
34
#include "WMEffectiveConnectivityCluster.h"
37
#include <osg/Geometry>
38
#include <osgText/Text>
39
#include <osgText/FadeText>
40
#include <osg/StateSet>
41
#include <osg/StateAttribute>
42
#include <osg/PolygonMode>
43
#include <osg/LightModel>
44
#include <osgDB/WriteFile>
46
#include "core/common/WProgress.h"
47
#include "core/common/math/linearAlgebra/WLinearAlgebra.h"
48
#include "core/dataHandler/WSubject.h"
49
#include "core/dataHandler/WGridRegular3D.h"
50
#include "core/dataHandler/datastructures/WFiberCluster.h"
51
#include "core/kernel/WKernel.h"
52
#include "core/kernel/WModuleFactory.h"
53
#include "core/kernel/WModuleOutputData.h"
54
#include "core/graphicsEngine/widgets/labeling/WGEBorderLayout.h"
55
#include "core/graphicsEngine/widgets/labeling/WGELabel.h"
56
#include "core/graphicsEngine/WGraphicsEngine.h"
57
#include "core/graphicsEngine/WGEUtils.h"
59
#include "WMEffectiveConnectivityCluster.xpm"
61
// This line is needed by the module loader to actually find your module.
62
W_LOADABLE_MODULE( WMEffectiveConnectivityCluster )
64
WMEffectiveConnectivityCluster::WMEffectiveConnectivityCluster():
65
WModuleContainer( "Effective Connectivity Cluster", "This module is able to visualize effective connectivity cluster." ),
66
m_labelActive( false ),
67
m_rootNode( new WGEGroupNode() )
69
// WARNING: initializing connectors inside the constructor will lead to an exception.
70
// NOTE: Do not use the module factory inside this constructor. This will cause a dead lock as the module factory is locked
71
// during construction of this instance and can then not be used to create another instance (Isosurface in this case). If you
72
// want to initialize some modules using the module factory BEFORE the moduleMain() call, overwrite WModule::initialize().
75
WMEffectiveConnectivityCluster::~WMEffectiveConnectivityCluster()
81
boost::shared_ptr< WModule > WMEffectiveConnectivityCluster::factory() const
83
return boost::shared_ptr< WModule >( new WMEffectiveConnectivityCluster() );
86
const char** WMEffectiveConnectivityCluster::getXPMIcon() const
88
return WMEffectiveConnectivityCluster_xpm;
91
const std::string WMEffectiveConnectivityCluster::getName() const
93
return WModuleContainer::getName();
96
const std::string WMEffectiveConnectivityCluster::getDescription() const
98
return WModuleContainer::getDescription();
101
void WMEffectiveConnectivityCluster::fiberDataChange( boost::shared_ptr< WModuleConnector > /*input*/,
102
boost::shared_ptr< WModuleConnector > output )
106
m_labelActive = false;
107
m_propCondition->notify();
109
// if the connector gets reset -> ignore this case
113
// cast it to the target type
114
boost::shared_ptr< WModuleOutputData < WFiberCluster > > o = boost::shared_static_cast< WModuleOutputData< WFiberCluster > >( output );
117
errorLog() << "New data is not a WFiberCluster? That should not happen!";
121
boost::shared_ptr< WFiberCluster > fibs = o->getData();
122
boost::shared_ptr< WFiber > lline = fibs->getLongestLine();
124
// the first and the last point of the longest line are required:
125
m_labelPos2 = ( *lline )[ lline->size() - 2 ];
126
m_labelPos1 = ( *lline )[ 1 ];
128
m_labelActive = true;
130
m_propCondition->notify();
133
void WMEffectiveConnectivityCluster::moduleMain()
135
//////////////////////////////////////////////////////////////////////////////////
137
//////////////////////////////////////////////////////////////////////////////////
139
// create an instance using the prototypes
140
m_fiberSelection = WModuleFactory::getModuleFactory()->create( WModuleFactory::getModuleFactory()->getPrototypeByName( "Fiber Selection" ) );
143
add( m_fiberSelection );
145
// now wait for it to be ready
146
m_fiberSelection->isReady().wait();
149
boost::shared_ptr< WProperties > props = m_fiberSelection->getProperties();
150
props->getProperty( "VOI1 threshold" )->toPropDouble()->set( 50.0 );
151
props->getProperty( "VOI2 threshold" )->toPropDouble()->set( 50.0 );
152
props->getProperty( "Cut fibers" )->toPropBool()->set( true );
153
m_properties->addProperty( props->getProperty( "Cut fibers" ) );
154
props->getProperty( "Prefer shortest path" )->toPropBool()->set( false );
155
m_properties->addProperty( props->getProperty( "Prefer shortest path" ) );
157
// as this module needs the centerline / longest line -> subscribe to the output connector DATA_CHANGE signal
158
m_fiberSelection->getOutputConnector( "cluster" )->subscribeSignal( DATA_CHANGED,
159
boost::bind( &WMEffectiveConnectivityCluster::fiberDataChange, this, _1, _2 )
162
//////////////////////////////////////////////////////////////////////
164
//////////////////////////////////////////////////////////////////////
166
// create an instance using the prototypes
167
m_voxelizer = WModuleFactory::getModuleFactory()->create( WModuleFactory::getModuleFactory()->getPrototypeByName( "Voxelizer" ) );
172
// now wait for it to be ready
173
m_voxelizer->isReady().wait();
175
// set/forward some props
176
props = m_voxelizer->getProperties();
177
props->getProperty( "Center line" )->toPropBool()->set( false );
178
props->getProperty( "active" )->toPropBool()->set( false );
179
props->getProperty( "Fiber tracts" )->toPropBool()->set( false );
180
props->getProperty( "Display voxels" )->toPropBool()->set( false );
181
props->getProperty( "Lighting" )->toPropBool()->set( false );
183
// set longest line based parameterization
184
props->getProperty( "Voxels per unit" )->toPropInt()->set( 2 );
185
WItemSelector::IndexList idx;
187
props->getProperty( "Parameterization" )->toPropSelection()->set( props->getProperty( "Parameterization"
188
)->toPropSelection()->get().newSelector( idx ) );
190
m_properties->addProperty( props->getProperty( "Voxels per unit" ) );
192
//////////////////////////////////////////////////////////////////////
193
// Gauss Filter the voxel output
194
//////////////////////////////////////////////////////////////////////
196
// create an instance using the prototypes
197
m_gauss = WModuleFactory::getModuleFactory()->create( WModuleFactory::getModuleFactory()->getPrototypeByName( "Gauss Filtering" ) );
202
// now wait for it to be ready
203
m_gauss->isReady().wait();
205
// set/forward some props
206
props = m_gauss->getProperties();
207
props->getProperty( "Iterations" )->toPropInt()->set( 2 );
209
//////////////////////////////////////////////////////////////////////
211
//////////////////////////////////////////////////////////////////////
213
// create an instance using the prototypes
214
m_animation = WModuleFactory::getModuleFactory()->create(
215
WModuleFactory::getModuleFactory()->getPrototypeByName( "Surface Parameter Animator" )
221
// now wait for it to be ready
222
m_animation->isReady().wait();
224
// set/forward some props
225
props = m_animation->getProperties();
226
props->getProperty( "Isovalue" )->toPropInt()->set( 32 );
227
m_properties->addProperty( props->getProperty( "Isovalue" ) );
228
props->getProperty( "Step count" )->toPropInt()->set( 500 );
229
m_properties->addProperty( props->getProperty( "Step count" ) );
230
props->getProperty( "Iso color" )->toPropColor()->set( WColor( 0.0, 0.5, 1.0, 1.0 ) );
231
m_properties->addProperty( props->getProperty( "Iso color" ) );
232
props->getProperty( "Opacity %" )->toPropInt()->set( 100 );
233
m_properties->addProperty( props->getProperty( "Opacity %" ) );
234
m_properties->addProperty( props->getProperty( "Saturation %" ) );
235
m_properties->addProperty( props->getProperty( "Beam1 size" ) );
236
m_properties->addProperty( props->getProperty( "Beam2 size" ) );
237
m_properties->addProperty( props->getProperty( "Beam1 speed" ) );
238
m_properties->addProperty( props->getProperty( "Beam2 speed" ) );
239
m_properties->addProperty( props->getProperty( "Parameter scale" ) );
242
//////////////////////////////////////////////////////////////////////////////////
243
// Hard wire the modules
244
//////////////////////////////////////////////////////////////////////////////////
246
// Connect voxelizer input with the selected fibers
247
m_voxelizer->getInputConnector( "tractInput" )->connect( m_fiberSelection->getOutputConnector( "cluster" ) );
249
// Connect voxelizer output with the Gauss filter
250
m_gauss->getInputConnector( "in" )->connect( m_voxelizer->getOutputConnector( "voxelOutput" ) );
252
// Connect voxelizer output with the animation
253
m_animation->getInputConnector( "in" )->connect( m_gauss->getOutputConnector( "out" ) );
254
m_animation->getInputConnector( "traces" )->connect( m_voxelizer->getOutputConnector( "parameterizationOutput" ) );
257
m_fiberInput->forward( m_fiberSelection->getInputConnector( "fibers" ) );
258
m_VOI1->forward( m_fiberSelection->getInputConnector( "VOI1" ) );
259
m_VOI2->forward( m_fiberSelection->getInputConnector( "VOI2" ) );
261
// forward some results
262
m_paramOutput->forward( m_voxelizer->getOutputConnector( "parameterizationOutput" ) );
263
m_voxelOutput->forward( m_gauss->getOutputConnector( "out" ) );
264
m_fiberOutput->forward( m_fiberSelection->getOutputConnector( "out" ) );
266
//////////////////////////////////////////////////////////////////////////////////
268
//////////////////////////////////////////////////////////////////////////////////
270
// signal ready state
273
// wake up on property change
274
m_moduleState.setResetable( true, true );
275
m_moduleState.add( m_propCondition );
277
// Signal ready state.
280
// add this module's group node
281
m_rootNode->setNodeMask( m_active->get() ? 0xFFFFFFFF : 0x0 );
282
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode );
285
bool lastLabelActiveState = m_labelActive;
286
while( !m_shutdownFlag() )
288
m_moduleState.wait();
290
// woke up since the module is requested to finish
291
if( m_shutdownFlag() )
295
// has one of the properties changed?
296
if( m_labelActive && (
297
( lastLabelActiveState != m_labelActive ) || m_voi1Name->changed() || m_voi2Name->changed() || m_labelCharacterSize->changed() )
300
lastLabelActiveState = true;
301
osg::ref_ptr< WGEBorderLayout > layouter = new WGEBorderLayout();
303
std::string voi1 = m_voi1Name->get( true );
304
std::string voi2 = m_voi2Name->get( true );
307
osg::ref_ptr< WGELabel > label1 = new WGELabel();
308
label1->setText( voi1 );
309
label1->setAnchor( m_labelPos1 ); // the position relative to the current world coordinate system
310
label1->setCharacterSize( m_labelCharacterSize->get( true ) );
311
layouter->addLayoutable( label1 );
316
osg::ref_ptr< WGELabel > label2 = new WGELabel();
317
label2->setText( voi2 );
318
label2->setAnchor( m_labelPos2 ); // the position relative to the current world coordinate system
319
label2->setCharacterSize( m_labelCharacterSize->get( true ) );
320
layouter->addLayoutable( label2 );
324
m_rootNode->insert( layouter );
327
// remove labels if no dataset is connected anymore
334
// At this point, the container managing this module signalled to shutdown. The main loop has ended and you should clean up. Always remove
335
// allocated memory and remove all OSG nodes.
336
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode );
338
// stop container and the contained modules.
342
void WMEffectiveConnectivityCluster::connectors()
344
// this is the scalar field input
345
m_VOI1 = boost::shared_ptr< WModuleInputForwardData< WDataSetSingle > >(
346
new WModuleInputForwardData< WDataSetSingle >( shared_from_this(),
347
"VOI1", "The first volume of interest." )
350
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
351
addConnector( m_VOI1 );
353
// this is the scalar field input
354
m_VOI2 = boost::shared_ptr< WModuleInputForwardData< WDataSetSingle > >(
355
new WModuleInputForwardData< WDataSetSingle >( shared_from_this(),
356
"VOI2", "The second volume of interest." )
359
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
360
addConnector( m_VOI2 );
362
// this is the scalar field input
363
m_fiberInput = boost::shared_ptr< WModuleInputForwardData< WDataSetFibers > >(
364
new WModuleInputForwardData< WDataSetFibers >( shared_from_this(),
365
"fibers", "The fiber dataset used to find connection path." )
368
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
369
addConnector( m_fiberInput );
371
// forwarder for some results
372
// this is the parameter field
373
m_paramOutput = boost::shared_ptr< WModuleOutputForwardData< WDataSetScalar > >(
374
new WModuleOutputForwardData< WDataSetScalar >( shared_from_this(),
375
"paramOut", "The voxelized fiber parameterization field." )
377
addConnector( m_paramOutput );
379
// this is the voxel field
380
m_voxelOutput = boost::shared_ptr< WModuleOutputForwardData< WDataSetScalar > >(
381
new WModuleOutputForwardData< WDataSetScalar >( shared_from_this(),
382
"voxelsOut", "The voxelized fibers." )
384
addConnector( m_voxelOutput );
386
// these are the fibers
387
m_fiberOutput = boost::shared_ptr< WModuleOutputForwardData< WDataSetFibers > >(
388
new WModuleOutputForwardData< WDataSetFibers >( shared_from_this(),
389
"fibersOut", "The voxelized fibers." )
391
addConnector( m_fiberOutput );
393
// call WModules initialization
394
WModule::connectors();
397
void WMEffectiveConnectivityCluster::properties()
399
// Initialize the properties
400
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
402
m_voi1Name = m_properties->addProperty( "Name of VOI1", "The name of the VOI1.", std::string( "" ), m_propCondition );
403
m_voi2Name = m_properties->addProperty( "Name of VOI2", "The name of the VOI2.", std::string( "" ), m_propCondition );
405
m_labelCharacterSize = m_properties->addProperty( "Font size", "The size of the label fonts.", 20, m_propCondition );
407
WModule::properties();
410
void WMEffectiveConnectivityCluster::activate()
412
m_animation->getProperties()->getProperty( "active" )->toPropBool()->set( m_active->get() );