Commit 2a9159c7 authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[MERGE]

parents acf4ade0 6207f4f8
......@@ -84,8 +84,19 @@ void WMEEGView::connectors()
void WMEEGView::properties()
{
// m_active gets initialized in WModule and is available for all modules. Overwrite activate() to have a special callback for m_active
// changes or add a callback manually.
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
m_drawElektrodes = m_properties2->addProperty( "Draw Elektrodes",
"Draw the 3D positions of the elektrodes.",
true,
m_propCondition );
m_drawHeadSurface = m_properties2->addProperty( "Draw Head Surface",
"Draw the head surface between the elektrodes.",
true,
m_propCondition );
m_drawLabels = m_properties2->addProperty( "Draw Labels",
"Draw the labels of the elektrodes at their 3D positions.",
true,
m_propCondition );
}
void WMEEGView::notifyConnectionEstablished(
......@@ -107,6 +118,7 @@ void WMEEGView::moduleMain()
m_moduleState.setResetable( true, true );
m_moduleState.add( m_dataChanged.getCondition() );
m_moduleState.add( m_active->getCondition() );
m_moduleState.add( m_propCondition );
{
// create color map
......@@ -163,6 +175,63 @@ void WMEEGView::moduleMain()
}
}
// draw elektrodes property changed?
if( m_drawElektrodes->changed() )
{
if( m_elektrodesNode.valid() )
{
m_rootNode3d->remove( m_elektrodesNode );
}
if( m_drawElektrodes->get( true ) && m_eeg.get() )
{
m_elektrodesNode = drawElektrodes();
m_rootNode3d->insert( m_elektrodesNode );
}
else
{
m_elektrodesNode = NULL;
}
}
// draw head surface property changed?
if( m_drawHeadSurface->changed() )
{
if( m_headSurfaceNode.valid() )
{
m_rootNode3d->remove( m_headSurfaceNode );
}
if( m_drawHeadSurface->get( true ) && m_eeg.get() )
{
m_headSurfaceNode = drawHeadSurface();
m_rootNode3d->insert( m_headSurfaceNode );
}
else
{
m_headSurfaceNode = NULL;
}
}
// draw labels property changed?
if( m_drawLabels->changed() )
{
if( m_labelsNode.valid() )
{
m_rootNode3d->remove( m_labelsNode );
}
if( m_drawLabels->get( true ) && m_eeg.get() )
{
m_labelsNode = drawLabels();
m_rootNode3d->insert( m_labelsNode );
}
else
{
m_labelsNode = NULL;
}
}
// "active" property changed?
bool isActive = m_active->get();
if( isActive != m_wasActive )
......@@ -265,11 +334,6 @@ void WMEEGView::redraw()
const double xOffset = 0.0;
const unsigned int spacing = 16;
const float sphereSize = 4.0f;
const osg::Vec3 text3dOffset( 0.0, 0.0, sphereSize );
const double text3dSize = 32.0;
const osg::Vec4 text3dColor( 0.0, 0.0, 0.0, 1.0 );
m_rootNode2d = new WGEGroupNode;
osg::StateSet* stateset = m_rootNode2d->getOrCreateStateSet();
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
......@@ -352,68 +416,35 @@ void WMEEGView::redraw()
m_event.setNode( NULL );
}
// draw 3d positions
for( size_t channel = 0; channel < nbChannels; ++channel )
if( m_drawElektrodes->get( true ) )
{
osg::Vec3 pos = wge::osgVec3( m_eeg->getChannelPosition( channel ) );
// create sphere geode on electrode position
osg::ShapeDrawable* shape = new osg::ShapeDrawable( new osg::Sphere( pos, sphereSize ) );
shape->setUpdateCallback( new UpdateColorOfShapeDrawableCallback( channel, &m_event, m_eeg, m_colorMap ) );
osg::Geode* sphereGeode = new osg::Geode;
sphereGeode->addDrawable( shape );
m_rootNode3d->addChild( sphereGeode );
// create text geode for the channel label
osgText::Text* text = new osgText::Text;
text->setText( m_eeg->getChannelLabel( channel ) );
text->setPosition( pos + text3dOffset );
text->setAlignment( osgText::Text::CENTER_BOTTOM );
text->setAxisAlignment( osgText::Text::SCREEN );
text->setCharacterSize( text3dSize );
text->setCharacterSizeMode( osgText::Text::SCREEN_COORDS );
text->setColor( text3dColor );
osg::Geode* textGeode = new osg::Geode;
textGeode->addDrawable( text );
m_rootNode3d->addChild( textGeode );
m_elektrodesNode = drawElektrodes();
m_rootNode3d->addChild( m_elektrodesNode );
}
// draw head surface
std::vector< wmath::WPosition > positions;
positions.reserve( nbChannels );
for( size_t channel = 0; channel < nbChannels; ++channel )
else
{
positions.push_back( m_eeg->getChannelPosition( channel ) );
m_elektrodesNode = NULL;
}
WTriangleMesh mesh = wge::triangulate( positions );
osg::ref_ptr< osg::Geometry > geometry = wge::convertToOsgGeometry( &mesh, true );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
osg::LightModel* lightModel = new osg::LightModel;
lightModel->setTwoSided( true );
osg::StateSet* state = geometry->getOrCreateStateSet();
state->setAttributeAndModes( lightModel );
state->setTextureAttributeAndModes( 0, m_colorMapTexture );
osg::FloatArray* texCoords = new osg::FloatArray;
texCoords->reserve( nbChannels );
for( size_t channelID = 0; channelID < nbChannels; ++channelID )
if( m_drawHeadSurface->get( true ) )
{
texCoords->push_back( 0.5f );
m_headSurfaceNode = drawHeadSurface();
m_rootNode3d->addChild( m_headSurfaceNode );
}
else
{
m_headSurfaceNode = NULL;
}
geometry->setTexCoordArray( 0, texCoords );
geometry->setUpdateCallback( new UpdateColorOfGeometryCallback( &m_event, m_eeg ) );
osg::Geode* geode = new osg::Geode;
geode->addDrawable( geometry );
m_rootNode3d->addChild( geode );
if( m_drawLabels->get( true ) )
{
m_labelsNode = drawLabels();
m_rootNode3d->addChild( m_labelsNode );
}
else
{
m_labelsNode = NULL;
}
// add rootNode to scene
if( m_wasActive )
......@@ -428,9 +459,109 @@ void WMEEGView::redraw()
{
m_rootNode2d = NULL;
m_rootNode3d = NULL;
m_event.setTime( -1.0 );
m_event.setNode( NULL );
m_elektrodesNode = NULL;
m_headSurfaceNode = NULL;
m_labelsNode = NULL;
}
}
osg::ref_ptr< osg::Node > WMEEGView::drawElektrodes()
{
// draw 3d positions of elektrodes
const float sphereSize = 4.0f;
osg::ref_ptr< osg::Group > elektrodes( new osg::Group );
for( size_t channel = 0; channel < m_eeg->getNumberOfChannels(); ++channel )
{
osg::Vec3 pos = wge::osgVec3( m_eeg->getChannelPosition( channel ) );
// create sphere geode on electrode position
osg::ShapeDrawable* shape = new osg::ShapeDrawable( new osg::Sphere( pos, sphereSize ) );
shape->setUpdateCallback( new UpdateColorOfShapeDrawableCallback( channel, &m_event, m_eeg, m_colorMap ) );
osg::Geode* sphereGeode = new osg::Geode;
sphereGeode->addDrawable( shape );
elektrodes->addChild( sphereGeode );
}
return elektrodes;
}
osg::ref_ptr< osg::Node > WMEEGView::drawHeadSurface()
{
// draw head surface
size_t nbChannels = m_eeg->getNumberOfChannels();
std::vector< wmath::WPosition > positions;
positions.reserve( nbChannels );
for( size_t channel = 0; channel < nbChannels; ++channel )
{
positions.push_back( m_eeg->getChannelPosition( channel ) );
}
WTriangleMesh mesh = wge::triangulate( positions );
osg::ref_ptr< osg::Geometry > geometry = wge::convertToOsgGeometry( &mesh, true );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
osg::LightModel* lightModel = new osg::LightModel;
lightModel->setTwoSided( true );
osg::StateSet* state = geometry->getOrCreateStateSet();
state->setAttributeAndModes( lightModel );
state->setTextureAttributeAndModes( 0, m_colorMapTexture );
osg::FloatArray* texCoords = new osg::FloatArray;
texCoords->reserve( nbChannels );
for( size_t channelID = 0; channelID < nbChannels; ++channelID )
{
texCoords->push_back( 0.5f );
}
geometry->setTexCoordArray( 0, texCoords );
geometry->setUpdateCallback( new UpdateColorOfGeometryCallback( &m_event, m_eeg ) );
osg::ref_ptr< osg::Geode > surface( new osg::Geode );
surface->addDrawable( geometry );
return surface;
}
osg::ref_ptr< osg::Node > WMEEGView::drawLabels()
{
// draw elektrode labels in 3d
const float sphereSize = 4.0f;
const osg::Vec3 text3dOffset( 0.0, 0.0, sphereSize );
const double text3dSize = 32.0;
const osg::Vec4 text3dColor( 0.0, 0.0, 0.0, 1.0 );
osg::ref_ptr< osg::Group > labels( new osg::Group );
for( size_t channel = 0; channel < m_eeg->getNumberOfChannels(); ++channel )
{
osg::Vec3 pos = wge::osgVec3( m_eeg->getChannelPosition( channel ) );
// create text geode for the channel label
osgText::Text* text = new osgText::Text;
text->setText( m_eeg->getChannelLabel( channel ) );
text->setPosition( pos + text3dOffset );
text->setAlignment( osgText::Text::CENTER_BOTTOM );
text->setAxisAlignment( osgText::Text::SCREEN );
text->setCharacterSize( text3dSize );
text->setCharacterSizeMode( osgText::Text::SCREEN_COORDS );
text->setColor( text3dColor );
osg::Geode* textGeode = new osg::Geode;
textGeode->addDrawable( text );
labels->addChild( textGeode );
}
return labels;
}
void WMEEGView::updateEvent( WEvent* event, double time )
......
......@@ -78,13 +78,6 @@ public:
*/
virtual const std::string getDescription() const;
/**
* Determine what to do if a property was changed.
*
* \param propertyName Name of the property.
*/
void slotPropertyChanged( std::string propertyName );
virtual const char** getXPMIcon() const;
protected:
......@@ -123,6 +116,26 @@ private:
*/
boost::shared_ptr< WModuleInputData< WEEG > > m_input;
/**
* A condition used to notify about changes in several properties.
*/
boost::shared_ptr< WCondition > m_propCondition;
/**
* Property determining whether elekrode positions should be drawn.
*/
WPropBool m_drawElektrodes;
/**
* Property determining whether the head surface should be drawn.
*/
WPropBool m_drawHeadSurface;
/**
* Property determining whether elekrode labels should be drawn.
*/
WPropBool m_drawLabels;
/**
* Pointer to the loaded EEG dataset
*/
......@@ -145,6 +158,21 @@ private:
*/
osg::ref_ptr< WGEGroupNode > m_rootNode3d;
/**
* OSG node for the 3D display of the elektrode positions
*/
osg::ref_ptr< osg::Node > m_elektrodesNode;
/**
* OSG node for the 3D display of the head surface
*/
osg::ref_ptr< osg::Node > m_headSurfaceNode;
/**
* OSG node for the 3D display of the elektrode labels
*/
osg::ref_ptr< osg::Node > m_labelsNode;
/**
* Bool flag which gets set when the data was changed.
* The module threads waits for this flag and performs a redraw.
......@@ -191,11 +219,32 @@ private:
void closeCustomWidget();
/**
* Removes all Nodes from m_rootNode and adds new ones based on the current
* data stored in m_eeg.
* Removes all Nodes from m_rootNode2d and m_rootNode3d and adds new ones
* based on the current data stored in m_eeg.
*/
void redraw();
/**
* Draw the elektrode positions in 3D.
*
* \return an OSG Node containing the elektrode positions
*/
osg::ref_ptr< osg::Node > drawElektrodes();
/**
* Draw the head surface in 3D.
*
* \return an OSG Node containing the head surface
*/
osg::ref_ptr< osg::Node > drawHeadSurface();
/**
* Draw the elektrode labels in 3D.
*
* \return an OSG Node containing the elektrode labels
*/
osg::ref_ptr< osg::Node > drawLabels();
/**
* Changes an WEvent to the given time position
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment