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
//---------------------------------------------------------------------------
30
#include <osg/Geometry>
32
#include <osg/Material>
33
#include <osg/ShapeDrawable>
34
#include <osg/StateAttribute>
36
#include "core/common/exceptions/WTypeMismatch.h"
37
#include "core/common/WColor.h"
38
#include "core/dataHandler/WDataHandlerEnums.h"
39
#include "core/kernel/WKernel.h"
40
#include "core/kernel/WSelectionManager.h"
41
#include "WMVectorPlot.h"
42
#include "WMVectorPlot.xpm"
44
// This line is needed by the module loader to actually find your module.
45
W_LOADABLE_MODULE( WMVectorPlot )
47
WMVectorPlot::WMVectorPlot():
52
WMVectorPlot::~WMVectorPlot()
57
boost::shared_ptr< WModule > WMVectorPlot::factory() const
59
return boost::shared_ptr< WModule >( new WMVectorPlot() );
62
const char** WMVectorPlot::getXPMIcon() const
64
return vectorplot_xpm;
67
const std::string WMVectorPlot::getName() const
72
const std::string WMVectorPlot::getDescription() const
74
return "This module displays vector data as small vector representations on navigation slices and other surfaces.";
77
void WMVectorPlot::connectors()
79
m_input = boost::shared_ptr< WModuleInputData < WDataSetVector > >(
80
new WModuleInputData< WDataSetVector >( shared_from_this(), "in", "The dataset to display" )
83
addConnector( m_input );
85
// call WModules initialization
86
WModule::connectors();
89
void WMVectorPlot::properties()
91
m_xSlice = m_properties->addProperty( "X Pos of the slice", "Description.", 80. );
92
m_ySlice = m_properties->addProperty( "Y Pos of the slice", "Description.", 100. );
93
m_zSlice = m_properties->addProperty( "Z Pos of the slice", "Description.", 80. );
95
// NOTE: min/max of these props are set vy buildPlotSlices
96
m_xSlice->setHidden( true );
97
m_ySlice->setHidden( true );
98
m_zSlice->setHidden( true );
100
m_projectOnSlice = m_properties->addProperty( "Projection",
101
"If active, the vectors are projected into the surface "
102
"used to place them. Thus their "
103
"representation is tangential to the surface.",
105
m_coloringMode = m_properties->addProperty( "Direction coloring",
106
"Draw each vector in a color indicating its direction. ", false );
107
m_aColor = m_properties->addProperty( "Color",
108
"This color is used if direction coloring is deactivated.",
109
WColor( 1.0, 0.0, 0.0, 1.0 ) );
111
m_showOnSagittal = m_properties->addProperty( "Show sagittal", "Show vectors on sagittal slice.", true );
112
m_showOnCoronal = m_properties->addProperty( "Show coronal", "Show vectors on coronal slice.", true );
113
m_showOnAxial = m_properties->addProperty( "Show axial", "Show vectors on axial slice.", true );
115
WModule::properties();
118
void WMVectorPlot::moduleMain()
120
m_moduleState.setResetable( true, true );
121
m_moduleState.add( m_input->getDataChangedCondition() );
125
while( !m_shutdownFlag() )
127
m_moduleState.wait();
129
if( m_shutdownFlag() )
134
boost::shared_ptr< WProgress > progress = boost::shared_ptr< WProgress >( new WProgress( "Vector Plot", 2 ) );
135
m_progress->addSubProgress( progress );
137
boost::shared_ptr< WDataSetVector > newDataSet = m_input->getData();
138
bool dataChanged = ( m_dataSet != newDataSet );
139
bool dataValid = ( newDataSet );
141
if( dataChanged && dataValid )
143
m_dataSet = newDataSet;
146
if( dataValid && dataChanged )
148
debugLog() << "Building Vector Plot";
152
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode );
155
osg::ref_ptr< osg::Geode > newRootNode = new osg::Geode();
156
newRootNode->addDrawable( buildPlotSlices() );
160
m_rootNode = newRootNode;
161
m_rootNode->setNodeMask( m_active->get() ? 0xFFFFFFFF : 0x0 );
162
m_rootNode->addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WMVectorPlot::updateCallback, this ) ) );
164
// no light for lines
165
m_rootNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
167
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode );
172
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode );
175
osg::ref_ptr<osg::Geometry> WMVectorPlot::buildPlotSlices()
177
switch( ( *m_dataSet ).getValueSet()->getDataType() )
179
case W_DT_SIGNED_INT:
180
return buildPlotSlices< DataTypeRT< W_DT_SIGNED_INT >::type >();
182
return buildPlotSlices< DataTypeRT< W_DT_FLOAT >::type >();
184
return buildPlotSlices< DataTypeRT< W_DT_DOUBLE >::type >();
186
return buildPlotSlices< DataTypeRT< W_DT_INT8 >::type >();
188
return buildPlotSlices< DataTypeRT< W_DT_UINT16 >::type >();
190
return buildPlotSlices< DataTypeRT< W_DT_UINT8 >::type >();
192
return buildPlotSlices< DataTypeRT< W_DT_INT16 >::type >();
194
return buildPlotSlices< DataTypeRT< W_DT_UINT32 >::type >();
196
return buildPlotSlices< DataTypeRT< W_DT_INT64 >::type >();
198
return buildPlotSlices< DataTypeRT< W_DT_UINT64 >::type >();
200
throw WTypeMismatch( "Unknown valueset type." );
205
void WMVectorPlot::updateCallback()
207
WPosition current = WKernel::getRunningKernel()->getSelectionManager()->getCrosshair()->getPosition();
209
if( ( m_oldPos != current ) || m_coloringMode->changed() || m_aColor->changed() || m_projectOnSlice->changed() ||
210
m_showOnSagittal->changed() || m_showOnCoronal->changed() || m_showOnAxial->changed() )
212
m_oldPos = current; // for next run
213
osg::ref_ptr<osg::Drawable> old = osg::ref_ptr<osg::Drawable>( m_rootNode->getDrawable( 0 ) );
214
m_rootNode->removeDrawable( old );
215
m_rootNode->addDrawable( buildPlotSlices() );
219
void WMVectorPlot::activate()
221
if( m_rootNode ) // always ensure the root node exists
223
if( m_active->get() )
225
m_rootNode->setNodeMask( 0xFFFFFFFF );
229
m_rootNode->setNodeMask( 0x0 );
233
// Always call WModule's activate!
237
void WMVectorPlot::transformVerts( osg::ref_ptr< osg::Vec3Array > verts )
239
WMatrix< double > mat = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() )->getTransformationMatrix();
241
for( size_t i = 0; i < verts->size(); ++i )
243
std::vector< double > resultPos4D( 4 );
244
resultPos4D[0] = mat( 0, 0 ) * ( *verts )[i][0] + mat( 0, 1 ) * ( *verts )[i][1] + mat( 0, 2 ) * ( *verts )[i][2] + mat( 0, 3 ) * 1;
245
resultPos4D[1] = mat( 1, 0 ) * ( *verts )[i][0] + mat( 1, 1 ) * ( *verts )[i][1] + mat( 1, 2 ) * ( *verts )[i][2] + mat( 1, 3 ) * 1;
246
resultPos4D[2] = mat( 2, 0 ) * ( *verts )[i][0] + mat( 2, 1 ) * ( *verts )[i][1] + mat( 2, 2 ) * ( *verts )[i][2] + mat( 2, 3 ) * 1;
247
resultPos4D[3] = mat( 3, 0 ) * ( *verts )[i][0] + mat( 3, 1 ) * ( *verts )[i][1] + mat( 3, 2 ) * ( *verts )[i][2] + mat( 3, 3 ) * 1;
249
( *verts )[i][0] = resultPos4D[0] / resultPos4D[3];
250
( *verts )[i][1] = resultPos4D[1] / resultPos4D[3];
251
( *verts )[i][2] = resultPos4D[2] / resultPos4D[3];