Commit b9a8ea7a authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] Now the probability and vectors are shown on a coronal slice again.

parent f09c25ef
......@@ -25,6 +25,8 @@
#include <string>
#include <osg/Geometry>
#include <osg/MatrixTransform>
// #include <osg/Vec3>
#include "core/dataHandler/WDataSetFibers.h"
#include "core/dataHandler/WDataSetScalar.h"
......@@ -36,11 +38,27 @@
#include "WMFiberStipples.h"
#include "WMFiberStipples.xpm"
#include "core/common/math/WMath.h"
#include "core/common/WPropertyHelper.h"
#include "core/graphicsEngine/callbacks/WGELinearTranslationCallback.h"
#include "core/graphicsEngine/callbacks/WGENodeMaskCallback.h"
#include "core/graphicsEngine/callbacks/WGEPropertyUniformCallback.h"
#include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
#include "core/graphicsEngine/shaders/WGEShader.h"
#include "core/graphicsEngine/shaders/WGEShaderDefineOptions.h"
#include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
#include "core/graphicsEngine/WGEColormapping.h"
#include "core/graphicsEngine/WGEGeodeUtils.h"
#include "core/graphicsEngine/WGraphicsEngine.h"
#include "core/kernel/WSelectionManager.h"
// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
W_LOADABLE_MODULE( WMFiberStipples )
WMFiberStipples::WMFiberStipples()
: WModule()
: WModule(),
m_first( true )
{
}
......@@ -82,7 +100,7 @@ void WMFiberStipples::properties()
{
// m_sliceGroup = m_properties->addPropertyGroup( "Slices", "Slice based probabilistic tractogram display." );
//
// m_slicePos[ 0 ] = m_sliceGroup->addProperty( "Sagittal Position", "Slice X position.", 0.0, m_sliceChanged );
m_Pos = m_properties->addProperty( "Slice position", "Slice position.", 0.0 );
// m_slicePos[ 1 ] = m_sliceGroup->addProperty( "Coronal Position", "Slice Y position.", 0.0, m_sliceChanged );
// m_slicePos[ 2 ] = m_sliceGroup->addProperty( "Axial Position", "Slice Z position.", 0.0, m_sliceChanged );
//
......@@ -144,14 +162,61 @@ void WMFiberStipples::properties()
WModule::properties();
}
osg::ref_ptr< WGEManagedGroupNode > WMFiberStipples::initOSG()
void WMFiberStipples::initOSG()
{
debugLog() << "Init OSG";
osg::ref_ptr< WGEManagedGroupNode > rootNode( new WGEManagedGroupNode( m_active ) );
rootNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( rootNode );
return rootNode;
m_output->clear();
// no colormaps -> no slices
bool empty = !WGEColormapping::instance()->size();
if( empty )
{
// hide the slider properties.
m_Pos->setHidden();
return;
}
// grab the current bounding box for computing the size of the slice
WBoundingBox bb = WGEColormapping::instance()->getBoundingBox();
WVector3d minV = bb.getMin();
WVector3d maxV = bb.getMax();
WVector3d sizes = ( maxV - minV );
WVector3d midBB = minV + ( sizes * 0.5 );
// update the properties
m_Pos->setMin( minV[1] );
m_Pos->setMax( maxV[1] );
m_Pos->setHidden( false );
// if this is done the first time, set the slices to the center of the dataset
if( m_first )
{
m_first = false;
m_Pos->set( midBB[1] );
}
// create a new geode containing the slices
osg::ref_ptr< osg::Node > slice = wge::genFinitePlane( minV, osg::Vec3( sizes[0], 0.0, 0.0 ),
osg::Vec3( 0.0, 0.0, sizes[2] ) );
slice->setName( "Coronal Slice" );
osg::Uniform* sliceUniform = new osg::Uniform( "u_WorldTransform", osg::Matrix::identity() );
slice->getOrCreateStateSet()->addUniform( sliceUniform );
slice->setCullingActive( false );
// each slice is child of an transformation node
osg::ref_ptr< osg::MatrixTransform > mT = new osg::MatrixTransform();
mT->addChild( slice );
// Control transformation node by properties. We use an additional uniform here to provide the shader
// the transformation matrix used to translate the slice.
mT->addUpdateCallback( new WGELinearTranslationCallback< WPropDouble >( osg::Vec3( 0.0, 1.0, 0.0 ), m_Pos, sliceUniform ) );
m_output->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
m_output->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
m_output->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
m_output->insert( mT );
m_output->dirtyBound();
}
void WMFiberStipples::moduleMain()
......@@ -163,7 +228,12 @@ void WMFiberStipples::moduleMain()
ready();
m_output = initOSG();
// graphics setup
m_output = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
initOSG();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_output );
osg::ref_ptr< WGEShader > shader = new WGEShader( "WFiberStipples", m_localPath );
WGEColormapping::apply( m_output, shader ); // this automatically applies the shader
// main loop
while( !m_shutdownFlag() )
......@@ -177,98 +247,22 @@ void WMFiberStipples::moduleMain()
break;
}
// bool dataUpdated = m_vectorIC->handledUpdate() || m_tractsIC->handledUpdate(); // this call must be made befor getData() on the ICs
// bool probDataValid = false;
//
// boost::shared_ptr< WDataSetVector > vectors = m_vectorIC->getData();
// boost::shared_ptr< WDataSetFibers > detTracts = m_tractsIC->getData();
// boost::shared_ptr< WGridRegular3D > grid;
// probTracts.clear(); // discard all prob tracts so far
//
// for( size_t i = 0; i < NUM_ICS; ++i )
// {
// dataUpdated = dataUpdated || m_probICs[i]->handledUpdate();
// probDataValid = probDataValid || m_probICs[i]->getData(); // at least one probabilistic tract must be there
// if( m_probICs[i]->getData() )
// {
// probTracts.push_back( m_probICs[i]->getData() );
// }
// }
// bool dataValid = ( detTracts || vectors ) && probDataValid;
//
// if( dataValid )
// {
// grid = boost::shared_dynamic_cast< WGridRegular3D >( probTracts.front()->getGrid() ); // assume all grids are the same and get the first
// if( !grid )
// {
// errorLog() << "A grid beside WGridRegular3D was used, aborting...";
// continue;
// }
// }
// else
// {
// m_output->clear();
// builder.reset();
// continue;
// }
//
// if( dataUpdated || m_drawAlgorithm->changed() )
// {
// infoLog() << "Handling data update..";
// checkProbabilityRanges( probTracts );
//
// if( grid->getNbCoordsX() > 0 && grid->getNbCoordsY() > 0 && grid->getNbCoordsZ() > 0 )
// {
// resetSlicePos( grid );
// }
// else
// {
// warnLog() << "Invalid grid: at least one dimension is not greater zero.";
// continue;
// }
//
// WItemSelector algo = m_drawAlgorithm->get( true );
// if( algo.at( 0 )->getName() == std::string( "With largest eigen vectors" ) )
// {
// m_vectorGroup->setHidden( false );
// m_tractGroup->setHidden( true );
// if( !vectors )
// {
// errorLog() << "No vector dataset available, but selected method needs one. Please connect one!";
// continue;
// }
// else
// {
// builder = boost::shared_ptr< WSPSliceBuilderVectors >( new WSPSliceBuilderVectors( probTracts, m_sliceGroup, m_colorMap,
// vectors, m_vectorGroup, m_localPath ) );
// }
// }
// else if( algo.at( 0 )->getName() == std::string( "With deterministic tracts" ) )
// {
// m_vectorGroup->setHidden( true );
// m_tractGroup->setHidden( false );
// if( !detTracts )
// {
// errorLog() << "No deterministic tracts on the connector present, but selected method needs one. Please connect one!";
// continue;
// }
// else
// {
// builder = boost::shared_ptr< WSPSliceBuilderTracts >( new WSPSliceBuilderTracts( probTracts, m_sliceGroup, m_colorMap, detTracts,
// m_tractGroup ) );
// }
// }
// else
// {
// throw WNotImplemented( "Invalid method: Either \"With largest eigen vectors\" or \"With deterministic tracts\" expected." );
// }
// }
//
// // NOTE: we know that we could arrange much more specific updates here, just update the slice that has changed, but this is too complex to
// // consider also color, m_delta, etc. changes..., and ofcourse: we have the time to calc that every loop-cycle again and again, it does
// // not really matter
// debugLog() << "Building the geodes...";
// updateSlices( builder );
// save data behind connectors since it might change during processing
boost::shared_ptr< WDataSetVector > vectors = m_vectorIC->getData();
boost::shared_ptr< WDataSetScalar > probTract = m_probIC->getData();
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( probTract->getGrid() );
if( !( vectors && probTract ) || !grid )// if data valid
{
continue;
}
initOSG();
wge::bindTexture( m_output, vectors->getTexture(), 0, "u_vectors" );
wge::bindTexture( m_output, probTract->getTexture(), 1, "u_probTract" );
// TODO(math): unbind textures, so we have a clean OSG root node for this module again
}
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_output );
......
......@@ -100,10 +100,8 @@ protected:
private:
/**
* Initialize OSG root node for this module. All other nodes from this module should be attached to this root node.
*
* \return Pointer to the root node.
*/
osg::ref_ptr< WGEManagedGroupNode > initOSG();
void initOSG();
/**
* The probabilistic tractogram input connector.
......@@ -119,6 +117,16 @@ private:
* The OSG root node for this module. All other geodes or OSG nodes will be attached on this single node.
*/
osg::ref_ptr< WGEManagedGroupNode > m_output;
/**
* Controls the slice position, only back and forth will be possible.
*/
WPropDouble m_Pos;
/**
* For initial slice positioning we need to control if the module is in intial state or not.
*/
bool m_first;
};
#endif // WMFIBERSTIPPLES_H
......@@ -24,35 +24,49 @@
#version 120
uniform float u_glyphThickness;
uniform float u_glyphSize;
#include "WGETextureTools.glsl"
varying vec4 v_middlePoint;
uniform sampler3D u_vectorsSampler;
uniform sampler3D u_probTractSampler;
float minimum_distance( vec3 v, vec3 w, vec3 p )
{
// Return minimum distance between line segment vw and point p
float len = length( v - w );
if( len == 0.0 ) // v == w case
{
return distance( p, v );
}
// Consider the line extending the segment, parameterized as v + t (w - v).
// We find projection of point p onto the line.
// It falls where t = [(p-v) . (w-v)] / |w-v|^2
float t = dot( p - v, w - v ) / ( len * len );
if( t < 0.0 ) // Beyond the 'v' end of the segment
{
return distance( p, v );
}
else if( t > 1.0 ) // Beyond the 'w' end of the segment
{
return distance( p, w );
}
vec3 projection = v + t * ( w - v ); // Projection falls on the segment
return distance( p, projection );
}
/**
* These two uniforms are needed to transform the vectors out of their texture back to their original form
* as they are stored in RBGA (for example allowing only values between 0..1 for components but no negative
* ones).
*/
uniform float u_vectorsMin;
uniform float u_vectorsScale;
//uniform float u_glyphThickness;
//uniform float u_glyphSize;
//
//varying vec4 v_middlePoint;
//
//float minimum_distance( vec3 v, vec3 w, vec3 p )
//{
// // Return minimum distance between line segment vw and point p
// float len = length( v - w );
// if( len == 0.0 ) // v == w case
// {
// return distance( p, v );
// }
// // Consider the line extending the segment, parameterized as v + t (w - v).
// // We find projection of point p onto the line.
// // It falls where t = [(p-v) . (w-v)] / |w-v|^2
// float t = dot( p - v, w - v ) / ( len * len );
//
// if( t < 0.0 ) // Beyond the 'v' end of the segment
// {
// return distance( p, v );
// }
// else if( t > 1.0 ) // Beyond the 'w' end of the segment
// {
// return distance( p, w );
// }
// vec3 projection = v + t * ( w - v ); // Projection falls on the segment
// return distance( p, projection );
//}
......@@ -91,24 +105,24 @@ void main()
// // Scalar values for zoom pansen
// float magicZoom = length( ( gl_ModelViewMatrix * normalize( vec4( 1.0, 1.0, 1.0, 0.0 ) ) ).xyz );
float area = u_glyphSize * u_glyphSize / 10.0; // 10 * u_glyphThickness * 1.0 / (2 * u_glyphSize) * optArea;
// generally the area of a line stipple is a circle with radius R (each half for the endings of the line stipple) plus
// a quad with height 2R and width length of the focalPoints v and w. hence we have this equation in R to solve:
//
// R^2*PI + 2R*length(v, w) - A = 0
//
// where A is the area to fill.
float l = distance( 0.8 * gl_TexCoord[1].xyz, 0.8 * gl_TexCoord[2].xyz );
float p2 = -l / 3.14159265;
float q = area / 3.14159265;
float r1 = p2 + sqrt( p2 * p2 + q );
float r2 = p2 - sqrt( p2 * p2 + q );
float radius = max( r1, r2 );
vec3 focalPoint1 = 0.8 * gl_TexCoord[1].xyz;
vec3 focalPoint2 = 0.8 * gl_TexCoord[2].xyz;
// float area = u_glyphSize * u_glyphSize / 10.0; // 10 * u_glyphThickness * 1.0 / (2 * u_glyphSize) * optArea;
//
// // generally the area of a line stipple is a circle with radius R (each half for the endings of the line stipple) plus
// // a quad with height 2R and width length of the focalPoints v and w. hence we have this equation in R to solve:
// //
// // R^2*PI + 2R*length(v, w) - A = 0
// //
// // where A is the area to fill.
//
// float l = distance( 0.8 * gl_TexCoord[1].xyz, 0.8 * gl_TexCoord[2].xyz );
// float p2 = -l / 3.14159265;
// float q = area / 3.14159265;
// float r1 = p2 + sqrt( p2 * p2 + q );
// float r2 = p2 - sqrt( p2 * p2 + q );
// float radius = max( r1, r2 );
//
// vec3 focalPoint1 = 0.8 * gl_TexCoord[1].xyz;
// vec3 focalPoint2 = 0.8 * gl_TexCoord[2].xyz;
// vec3 focalPoint1 = gl_TexCoord[1].xyz - normalize( gl_TexCoord[1].xyz ) * radius;
// vec3 focalPoint2 = gl_TexCoord[2].xyz - normalize( gl_TexCoord[2].xyz ) * radius;
......@@ -119,29 +133,39 @@ void main()
// float f_r2 = p2 - sqrt( p2 * p2 + q );
// float f_radius = max( r1, r2 );
// if( minimum_distance( gl_TexCoord[1].xyz, gl_TexCoord[2].xyz, gl_TexCoord[0].xyz ) < radius )
if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[0].xyz ) < u_glyphThickness * radius )
{
gl_FragColor = gl_Color;
}
else
{
// if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[0].xyz ) < u_glyphThickness * ( radius + 0.01 ) )
// {
// gl_FragColor = vec4( 1.0, 1.0, 1.0, gl_Color.w );
// }
discard;
// // Draw quad and inner cricle
//
// gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
// float lp = length( gl_TexCoord[0].xyz );
// if( lp >= ( u_glyphSize / 2.0 ) )
// {
// gl_FragColor = vec4( 0.7, 0.7, 1.0, 1.0 ); // discard;
// }
}
vec4 direction = abs( texture3DUnscaled( u_vectorsSampler, gl_TexCoord[0].xyz, u_vectorsMin, u_vectorsScale ) );
vec4 probRGBA = texture3D( u_probTractSampler, gl_TexCoord[0].xyz );
probRGBA.a = 1.0; // set alpha explicity to 1
// vec4 value = texture3D( u_probTractSampler, vec3(gl_TexCoord[0].x, gl_TexCoord[0].y, gl_TexCoord[0].z) );
// gl_FragColor = vec4( gl_TexCoord[0].xyz, 1.0 ); // vec4( value, 1.0, 0.0, 1.0 );
// gl_FragColor = vec4( value, 0.0, 0.0, 1.0 );
gl_FragColor = 0.8 * probRGBA + 0.2 * direction;
// // if( minimum_distance( gl_TexCoord[1].xyz, gl_TexCoord[2].xyz, gl_TexCoord[0].xyz ) < radius )
// if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[0].xyz ) < u_glyphThickness * radius )
// {
// gl_FragColor = gl_Color;
// }
// else
// {
// // if( minimum_distance( focalPoint1, focalPoint2, gl_TexCoord[0].xyz ) < u_glyphThickness * ( radius + 0.01 ) )
// // {
// // gl_FragColor = vec4( 1.0, 1.0, 1.0, gl_Color.w );
// // }
//
// discard;
//
// // // Draw quad and inner cricle
// //
// // gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
// // float lp = length( gl_TexCoord[0].xyz );
// // if( lp >= ( u_glyphSize / 2.0 ) )
// // {
// // gl_FragColor = vec4( 0.7, 0.7, 1.0, 1.0 ); // discard;
// // }
// }
// // display middle point
// if( length( gl_TexCoord[0].xyz ) <= 0.01 )
......
......@@ -24,18 +24,23 @@
#version 120
uniform float u_glyphSize;
varying vec4 v_middlePoint;
/**
* The matrix describes the transformation of gl_Vertex to OpenWalnut Scene Space
*/
uniform mat4 u_WorldTransform;
uniform int u_probTractSizeY;
/**
* Vertex Main. Simply transforms the geometry. The work is done per fragment.
*/
void main()
{
gl_TexCoord[0] = u_glyphSize * gl_MultiTexCoord0;
gl_TexCoord[1] = u_glyphSize * gl_MultiTexCoord1;
gl_TexCoord[2] = u_glyphSize * gl_MultiTexCoord2;
vec4 v = gl_Vertex + vec4( gl_TexCoord[0].xyz, 0.0 );
v_middlePoint = gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[0].y = ( u_WorldTransform[3] / u_probTractSizeY ).y;
// transform position
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
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