Commit 264221f0 by schurade

[ADD] possibility to map a scalar dataset onto fibers

parent 8653f3c1
......@@ -32,6 +32,9 @@
#include "../../common/WColor.h"
#include "../../common/WLogger.h"
#include "../../dataHandler/WDataHandler.h"
#include "../../dataHandler/WDataTexture3D.h"
#include "../../dataHandler/WSubject.h"
#include "../../graphicsEngine/WGEUtils.h"
#include "../../graphicsEngine/WROIBox.h"
#include "../../kernel/WKernel.h"
......@@ -43,7 +46,9 @@ WMFiberDisplay::WMFiberDisplay()
m_noData( new WCondition, true ),
m_osgNode( osg::ref_ptr< osg::Group >() )
{
m_shader = osg::ref_ptr< WShader > ( new WShader( "fake-tubes" ) );
m_shaderTubes = osg::ref_ptr< WShader > ( new WShader( "fake-tubes" ) );
m_shaderTexturedFibers = osg::ref_ptr< WShader > ( new WShader( "texturedFibers" ) );
m_textureChanged = true;
}
WMFiberDisplay::~WMFiberDisplay()
......@@ -66,6 +71,11 @@ void WMFiberDisplay::moduleMain()
m_moduleState.setResetable( true, true );
m_moduleState.add( m_fiberInput->getDataChangedCondition() );
// now, to watch changing/new textures use WSubject's change condition
boost::signals2::connection con = WDataHandler::getDefaultSubject()->getChangeCondition()->subscribeSignal(
boost::bind( &WMFiberDisplay::notifyTextureChange, this )
);
ready();
while ( !m_shutdownFlag() ) // loop until the module container requests the module to quit
......@@ -135,11 +145,6 @@ void WMFiberDisplay::update()
}
}
if ( WKernel::getRunningKernel()->getRoiManager()->isDirty() )
{
//m_tubeDrawable->dirtyDisplayList();
}
slock.unlock();
}
......@@ -170,6 +175,9 @@ void WMFiberDisplay::create()
m_osgNode = osgNodeNew;
activate();
osg::StateSet* rootState = m_osgNode->getOrCreateStateSet();
initUniforms( rootState );
}
void WMFiberDisplay::connectors()
......@@ -206,6 +214,7 @@ void WMFiberDisplay::properties()
m_coloring = m_properties->addProperty( "Global or Local Coloring", "Switches the coloring between global and local.", true );
m_useTubesProp = m_properties->addProperty( "Use Tubes", "Draw fiber tracts as fake tubes.", false );
m_useTextureProp = m_properties->addProperty( "Use Texture", "Texture fibers with the texture on top of the list.", false );
m_tubeThickness = m_properties->addProperty( "Tube Thickness", "Adjusts the thickness of the tubes.", 50.,
boost::bind( &WMFiberDisplay::adjustTubes, this ) );
m_tubeThickness->setMin( 0 );
......@@ -216,27 +225,45 @@ void WMFiberDisplay::properties()
void WMFiberDisplay::toggleTubes()
{
if( m_useTubesProp->changed() )
osg::StateSet* rootState = m_osgNode->getOrCreateStateSet();
if ( m_textureChanged )
{
m_textureChanged = false;
updateTexture();
}
if( m_useTubesProp->changed() || m_useTextureProp->changed() )
{
if ( m_useTubesProp->get( true ) )
{
m_useTextureProp->get( true );
m_tubeDrawable->setUseTubes( true );
m_tubeDrawable->dirtyDisplayList();
m_shader->apply( m_osgNode );
m_shaderTubes->apply( m_osgNode );
osg::ref_ptr<osg::Uniform>( new osg::Uniform( "globalColor", 1 ) );
osg::StateSet* rootState = m_osgNode->getOrCreateStateSet();
rootState->addUniform( osg::ref_ptr<osg::Uniform>( new osg::Uniform( "globalColor", 1 ) ) );
m_uniformTubeThickness = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "u_thickness", static_cast<float>( m_tubeThickness->get() ) ) );
rootState->addUniform( m_uniformTubeThickness );
}
else if ( m_useTextureProp->get( true ) && !m_useTubesProp->get( true ) )
{
m_tubeDrawable->setUseTubes( false );
updateTexture();
m_shaderTubes->deactivate( m_osgNode );
m_shaderTexturedFibers->apply( m_osgNode );
}
else
{
m_tubeDrawable->setUseTubes( false );
m_tubeDrawable->dirtyDisplayList();
m_shader->deactivate( m_osgNode );
m_shaderTubes->deactivate( m_osgNode );
m_shaderTexturedFibers->deactivate( m_osgNode );
}
}
if ( !m_useTextureProp->get( true ) && !m_useTubesProp->get( true ) )
{
rootState->setTextureMode( 0, GL_TEXTURE_3D, osg::StateAttribute::OFF );
}
}
void WMFiberDisplay::toggleColoring()
......@@ -261,3 +288,63 @@ void WMFiberDisplay::saveSelected()
boost::shared_ptr< std::vector< bool > > active = WKernel::getRunningKernel()->getRoiManager()->getBitField();
m_dataset->saveSelected( m_saveFileName->getAsString(), active );
}
void WMFiberDisplay::updateTexture()
{
osg::StateSet* rootState = m_osgNode->getOrCreateStateSet();
// grab a list of data textures
std::vector< boost::shared_ptr< WDataTexture3D > > tex = WDataHandler::getDefaultSubject()->getDataTextures();
if ( tex.size() > 0 )
{
osg::ref_ptr<osg::Texture3D> texture3D = tex[0]->getTexture();
if ( tex[0]->isInterpolated() )
{
texture3D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
texture3D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
}
else
{
texture3D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST );
texture3D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST );
}
rootState->setTextureAttributeAndModes( 0, texture3D, osg::StateAttribute::ON );
m_uniformType->set( tex[0]->getDataType() );
m_uniformThreshold->set( static_cast<float>( tex[0]->getThreshold() / 100. ) );
m_uniformsColorMap->set( tex[0]->getSelectedColormap() );
m_uniformDimX->set( static_cast<int>( tex[0]->getGrid()->getNbCoordsX() ) );
m_uniformDimY->set( static_cast<int>( tex[0]->getGrid()->getNbCoordsY() ) );
m_uniformDimZ->set( static_cast<int>( tex[0]->getGrid()->getNbCoordsZ() ) );
}
}
void WMFiberDisplay::initUniforms( osg::StateSet* rootState )
{
m_uniformSampler = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "tex", 0 ) );
m_uniformType = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "type", 0 ) );
m_uniformThreshold = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "threshold", 0.0f ) );
m_uniformsColorMap = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "cMap", 0 ) );
m_uniformDimX = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "dimX", 1 ) );
m_uniformDimY = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "dimY", 1 ) );
m_uniformDimZ = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "dimZ", 1 ) );
rootState->addUniform( m_uniformSampler );
rootState->addUniform( m_uniformType );
rootState->addUniform( m_uniformThreshold );
rootState->addUniform( m_uniformsColorMap );
rootState->addUniform( m_uniformDimX );
rootState->addUniform( m_uniformDimY );
rootState->addUniform( m_uniformDimZ );
}
void WMFiberDisplay::notifyTextureChange()
{
m_textureChanged = true;
}
......@@ -112,10 +112,16 @@ protected:
*/
void create();
/**
* Used as callback which simply sets m_textureChanged to true. Called by WSubject whenever the datasets change.
*/
void notifyTextureChange();
private:
WPropBool m_coloring; //!< Enable/Disable global (true) or local (false) coloring of the fiber tracts
WPropBool m_customColoring; //!< Enable/Disable custom colors
WPropBool m_useTubesProp; //!< Property indicating whether to use tubes for the fibers tracts.
WPropBool m_useTextureProp; //!< Property indicating whether to use tubes for the fibers tracts.
WPropDouble m_tubeThickness; //!< Property determining the thickness of tubes .
WPropBool m_save; //!< this should be a button
WPropFilename m_saveFileName; //!< the filename for saving
......@@ -149,13 +155,47 @@ private:
boost::shared_mutex m_updateLock;
/**
* the shader object for this module
* the shader object for rendering tubes
*/
osg::ref_ptr< WShader >m_shader;
osg::ref_ptr< WShader >m_shaderTubes;
/**
* the shader object for rendering textured lines
*/
osg::ref_ptr< WShader >m_shaderTexturedFibers;
osg::ref_ptr<osg::Uniform> m_uniformTubeThickness; //!< tube thickness
/**
* True when textures have changed.
*/
bool m_textureChanged;
/**
* uniform for type of texture
*/
osg::ref_ptr<osg::Uniform> m_uniformType;
/**
* threshold for texture
*/
osg::ref_ptr<osg::Uniform>m_uniformThreshold;
/**
* color map for the texture
*/
osg::ref_ptr<osg::Uniform> m_uniformsColorMap;
/**
* vector of samplers
*/
osg::ref_ptr<osg::Uniform> m_uniformSampler;
osg::ref_ptr<osg::Uniform> m_uniformDimX; //!< x dimension of the dataset for calculating the texture coord in the shader
osg::ref_ptr<osg::Uniform> m_uniformDimY; //!< y dimension of the dataset for calculating the texture coord in the shader
osg::ref_ptr<osg::Uniform> m_uniformDimZ; //!< z dimension of the dataset for calculating the texture coord in the shader
/**
* switches between fiber display and tube representation
*/
void toggleTubes();
......@@ -176,6 +216,17 @@ private:
void saveSelected();
/**
* creates and initializes the uniform parameters for the shader
* \param rootState The uniforms will be applied to this state.
*/
void initUniforms( osg::StateSet* rootState );
/**
* updates textures and shader parameters
*/
void updateTexture();
/**
* Node callback to handle updates properly
*/
class fdNodeCallback : public osg::NodeCallback
......
varying vec4 myColor;
varying vec4 VaryingTexCoord0;
uniform int dimX, dimY, dimZ;
uniform sampler3D tex;
uniform int type;
uniform float threshold;
uniform int cMap;
#include "colorMaps.fs"
float lookupTex()
{
vec3 v = VaryingTexCoord0.xyz;
v.x = v.x / ( float( dimX ) );
v.y = v.y / ( float( dimY ) );
v.z = v.z / ( float( dimZ ) );
vec3 col1;
col1.r = clamp( texture3D( tex, v ).r, 0.0, 1.0 );
if ( col1.r < threshold )
{
discard;
}
else
return col1.r;
}
/*
* simple fragment shader that uses a texture on fibers
*/
void main()
{
vec4 color = vec4( 1.0 );
float value = lookupTex();
colorMap(color.rgb, value, cMap );
color.a = 1.0;
gl_FragColor = color;
}
varying vec4 myColor;
varying vec4 VaryingTexCoord0;
void main()
{
VaryingTexCoord0 = gl_Vertex;
myColor = gl_Color;
gl_Position = ftransform(); //< store final 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