Commit 8552ddea authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[MERGE]

parents 1b3bfae0 a1b3c79c
......@@ -52,7 +52,11 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_offsetY( offsetY ),
m_offsetZ( offsetZ ),
m_matrix( 4, 4 ),
m_matrixInverse( 3, 3 )
m_matrixOrig( 4, 4 ),
m_matrixInverse( 3, 3 ),
m_translate( 0, 0, 0 ),
m_stretch( 1, 1, 1 ),
m_rotation( 0, 0, 0 )
{
m_matrix( 0, 0 ) = directionX[0];
m_matrix( 0, 1 ) = directionY[0];
......@@ -68,6 +72,7 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_matrix( 2, 3 ) = originZ;
m_matrix( 3, 3 ) = 1.;
m_matrixOrig = m_matrix;
m_matrixInverse = wmath::invertMatrix4x4( m_matrix );
}
......@@ -83,7 +88,11 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_offsetY( offsetY ),
m_offsetZ( offsetZ ),
m_matrix( wmath::WMatrix<double>( mat ) ),
m_matrixInverse( 3, 3 )
m_matrixOrig( 4, 4 ),
m_matrixInverse( 3, 3 ),
m_translate( 0, 0, 0 ),
m_stretch( 1, 1, 1 ),
m_rotation( 0, 0, 0 )
{
WAssert( mat.getNbRows() == 4 && mat.getNbCols() == 4, "Transformation matrix has wrong dimensions." );
// only affine transformations are allowed
......@@ -96,6 +105,7 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_directionZ = WVector3D( mat( 0, 2 ) / mat( 3, 3 ), mat( 1, 2 ) / mat( 3, 3 ), mat( 2, 2 ) / mat( 3, 3 ) );
m_matrix = mat;
m_matrixOrig = m_matrix;
m_matrixInverse = wmath::invertMatrix4x4( m_matrix );
}
......@@ -116,7 +126,11 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_offsetY( offsetY ),
m_offsetZ( offsetZ ),
m_matrix( 4, 4 ),
m_matrixInverse( 3, 3 )
m_matrixOrig( 4, 4 ),
m_matrixInverse( 3, 3 ),
m_translate( 0, 0, 0 ),
m_stretch( 1, 1, 1 ),
m_rotation( 0, 0, 0 )
{
m_matrix( 0, 0 ) = offsetX;
m_matrix( 1, 1 ) = offsetY;
......@@ -126,6 +140,7 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_matrix( 2, 3 ) = originZ;
m_matrix( 3, 3 ) = 1.;
m_matrixOrig = m_matrix;
m_matrixInverse = wmath::invertMatrix4x4( m_matrix );
}
......@@ -145,7 +160,11 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_offsetY( offsetY ),
m_offsetZ( offsetZ ),
m_matrix( 4, 4 ),
m_matrixInverse( 3, 3 )
m_matrixOrig( 4, 4 ),
m_matrixInverse( 3, 3 ),
m_translate( 0, 0, 0 ),
m_stretch( 1, 1, 1 ),
m_rotation( 0, 0, 0 )
{
m_matrix( 0, 0 ) = offsetX;
m_matrix( 1, 1 ) = offsetY;
......@@ -155,6 +174,7 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_matrix( 2, 3 ) = origin[2];
m_matrix( 3, 3 ) = 1.;
m_matrixOrig = m_matrix;
m_matrixInverse = wmath::invertMatrix4x4( m_matrix );
}
......@@ -173,13 +193,18 @@ WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsign
m_offsetY( offsetY ),
m_offsetZ( offsetZ ),
m_matrix( 4, 4 ),
m_matrixInverse( 3, 3 )
m_matrixOrig( 4, 4 ),
m_matrixInverse( 3, 3 ),
m_translate( 0, 0, 0 ),
m_stretch( 1, 1, 1 ),
m_rotation( 0, 0, 0 )
{
m_matrix( 0, 0 ) = offsetX;
m_matrix( 1, 1 ) = offsetY;
m_matrix( 2, 2 ) = offsetZ;
m_matrix( 3, 3 ) = 1.;
m_matrixOrig = m_matrix;
m_matrixInverse = wmath::invertMatrix4x4( m_matrix );
}
......@@ -435,3 +460,58 @@ std::pair< wmath::WPosition, wmath::WPosition > WGridRegular3D::getBoundingBox()
return std::make_pair( minBB, maxBB );
}
void WGridRegular3D::translate( wmath::WPosition translation )
{
m_translate = translation;
doCustomTransformations();
}
void WGridRegular3D::stretch( wmath::WPosition str )
{
m_stretch = str;
doCustomTransformations();
}
void WGridRegular3D::rotate( wmath::WPosition rot )
{
m_rotation = rot;
doCustomTransformations();
}
void WGridRegular3D::doCustomTransformations()
{
m_matrix = m_matrixOrig;
wmath::WMatrix<double> rotmat( 4, 4 );
rotmat.makeIdentity();
rotmat( 1, 1 ) = cos( m_rotation[0] );
rotmat( 1, 2 ) = -sin( m_rotation[0] );
rotmat( 2, 1 ) = sin( m_rotation[0] );
rotmat( 2, 2 ) = cos( m_rotation[0] );
m_matrix = m_matrix * rotmat;
rotmat.makeIdentity();
rotmat( 0, 0 ) = cos( m_rotation[1] );
rotmat( 0, 2 ) = sin( m_rotation[1] );
rotmat( 2, 0 ) = -sin( m_rotation[1] );
rotmat( 2, 2 ) = cos( m_rotation[1] );
m_matrix = m_matrix * rotmat;
rotmat.makeIdentity();
rotmat( 0, 0 ) = cos( m_rotation[2] );
rotmat( 0, 1 ) = -sin( m_rotation[2] );
rotmat( 1, 0 ) = sin( m_rotation[2] );
rotmat( 1, 1 ) = cos( m_rotation[2] );
m_matrix = m_matrix * rotmat;
m_matrix( 0, 3 ) = m_matrix( 0, 3 ) + m_translate[0];
m_matrix( 1, 3 ) = m_matrix( 1, 3 ) + m_translate[1];
m_matrix( 2, 3 ) = m_matrix( 2, 3 ) + m_translate[2];
m_matrix( 0, 0 ) = m_matrix( 0, 0 ) * m_stretch[0];
m_matrix( 1, 1 ) = m_matrix( 1, 1 ) * m_stretch[1];
m_matrix( 2, 2 ) = m_matrix( 2, 2 ) * m_stretch[2];
m_matrixInverse = wmath::invertMatrix4x4( m_matrix );
}
......@@ -393,6 +393,27 @@ public:
*/
bool isNotRotatedOrSheared() const;
/**
* translates the texture along a given vector
*
* \param translation the translation vector
*/
void translate( wmath::WPosition translation );
/**
* stretches the texture
*
* \param str the stretch factors in x,y,z direction
*/
void stretch( wmath::WPosition str );
/**
* rotates the texture around the x,y,z axis
*
* \param rot the angles for each axis
*/
void rotate( wmath::WPosition rot );
protected:
private:
......@@ -408,6 +429,11 @@ private:
*/
int getNVoxelCoord( const wmath::WPosition& pos, size_t axis ) const;
/**
* execute the texture transformation on the original transformation matrix with the stored
* translate, stretch and rotate vectors
*/
void doCustomTransformations();
wmath::WPosition m_origin; //!< Origin of the grid.
......@@ -427,10 +453,27 @@ private:
* Matrix storing the transformation of the grid. This is redundant.
* Please use m_origin and m_direction? for all normal computations.
* Use matrix only where you really need a matrix for multiplication.
*
* This is the matrix we are working with
*/
wmath::WMatrix<double> m_matrix;
/**
* Matrix storing the transformation of the grid. This is redundant.
* Please use m_origin and m_direction? for all normal computations.
* Use matrix only where you really need a matrix for multiplication.
*
* This matrix is used to store the initial value
*/
wmath::WMatrix<double> m_matrixOrig;
wmath::WMatrix<double> m_matrixInverse; //!< Inverse of m_matrix
wmath::WPosition m_translate; //!< stores the translation vector
wmath::WPosition m_stretch; //!< stores the stretch vector
wmath::WPosition m_rotation; //!< stores the rotation vector
};
inline unsigned int WGridRegular3D::getNbCoordsX() const
......
......@@ -164,4 +164,3 @@ boost::shared_ptr< WCondition > WSubject::getListChangeCondition() const
{
return m_listChangeCondition;
}
......@@ -59,7 +59,7 @@ WPropertyDoubleWidget::WPropertyDoubleWidget( WPropDouble property, QGridLayout*
update();
// connect the modification signal of the edit and slider with our callback
connect( &m_slider, SIGNAL( valueChanged( int ) ), this, SLOT( sliderChanged( int ) ) );
connect( &m_slider, SIGNAL( sliderMoved( int ) ), this, SLOT( sliderChanged( int ) ) );
connect( &m_edit, SIGNAL( returnPressed() ), this, SLOT( editChanged() ) );
connect( &m_edit, SIGNAL( textEdited( const QString& ) ), this, SLOT( textEdited( const QString& ) ) );
}
......@@ -170,17 +170,17 @@ void WPropertyDoubleWidget::editChanged()
// set the value in the line edit
bool valid;
double value = m_edit.text().toDouble( &valid );
if ( !valid )
{
invalidate();
return;
}
// set to the property
invalidate( !m_doubleProperty->set( value ) ); // NOTE: set automatically checks the validity of the value
// update slider
m_slider.setValue( toPercent( value ) );
// set to the property
invalidate( !m_doubleProperty->set( value ) ); // NOTE: set automatically checks the validity of the value
}
void WPropertyDoubleWidget::textEdited( const QString& text )
......
......@@ -59,7 +59,7 @@ WPropertyIntWidget::WPropertyIntWidget( WPropInt property, QGridLayout* property
update();
// connect the modification signal of the edit and slider with our callback
connect( &m_slider, SIGNAL( valueChanged( int ) ), this, SLOT( sliderChanged( int ) ) );
connect( &m_slider, SIGNAL( sliderMoved( int ) ), this, SLOT( sliderChanged( int ) ) );
connect( &m_edit, SIGNAL( returnPressed() ), this, SLOT( editChanged() ) );
connect( &m_edit, SIGNAL( textEdited( const QString& ) ), this, SLOT( textEdited( const QString& ) ) );
}
......
......@@ -126,16 +126,20 @@ void WMData::properties()
// use this callback for the other properties
WPropertyBase::PropertyChangeNotifierType propertyCallback = boost::bind( &WMData::propertyChanged, this, _1 );
m_groupTex = m_properties->addPropertyGroup( "Texture Properties", "Properties only related to the texture representation." );
m_groupTexManip = m_properties->addPropertyGroup( "Texture Manipulation", "Properties only related to the texture manipulation." );
// several other properties
m_interpolation = m_properties->addProperty( "Interpolation",
m_interpolation = m_groupTex->addProperty( "Interpolation",
"If active, the boundaries of single voxels"
" will not be visible in colormaps. The transition between"
" them will be smooth by using interpolation then.",
true,
propertyCallback );
m_threshold = m_properties->addProperty( "Threshold", "Values below this threshold will not be "
m_threshold = m_groupTex->addProperty( "Threshold", "Values below this threshold will not be "
"shown in colormaps.", 0., propertyCallback );
m_opacity = m_properties->addProperty( "Opacity %", "The opacity of this data in colormaps combining"
m_opacity = m_groupTex->addProperty( "Opacity %", "The opacity of this data in colormaps combining"
" values from several data sets.", 100, propertyCallback );
m_opacity->setMax( 100 );
m_opacity->setMin( 0 );
......@@ -148,8 +152,38 @@ void WMData::properties()
m_colorMapSelectionsList->addItem( "Atlas", "" );
m_colorMapSelectionsList->addItem( "Blue-Green-Purple", "" );
m_colorMapSelection = m_properties->addProperty( "Colormap", "Colormap type.", m_colorMapSelectionsList->getSelectorFirst(), propertyCallback );
m_colorMapSelection = m_groupTex->addProperty( "Colormap", "Colormap type.", m_colorMapSelectionsList->getSelectorFirst(), propertyCallback );
WPropertyHelper::PC_SELECTONLYONE::addTo( m_colorMapSelection );
m_translationX = m_groupTexManip->addProperty( "X translation", "", 0, propertyCallback );
m_translationX->setMax( 300 );
m_translationX->setMin( -300 );
m_translationY = m_groupTexManip->addProperty( "Y translation", "", 0, propertyCallback );
m_translationY->setMax( 300 );
m_translationY->setMin( -300 );
m_translationZ = m_groupTexManip->addProperty( "Z translation", "", 0, propertyCallback );
m_translationZ->setMax( 300 );
m_translationZ->setMin( -300 );
m_stretchX = m_groupTexManip->addProperty( "voxel size X", "", 1.0, propertyCallback );
m_stretchX->setMax( 10. );
m_stretchX->setMin( 0.1 );
m_stretchY = m_groupTexManip->addProperty( "voxel size Y", "", 1.0, propertyCallback );
m_stretchY->setMax( 10. );
m_stretchY->setMin( 0.1 );
m_stretchZ = m_groupTexManip->addProperty( "voxel size Z", "", 1.0, propertyCallback );
m_stretchZ->setMax( 10. );
m_stretchZ->setMin( 0.1 );
m_rotationX = m_groupTexManip->addProperty( "X rotation", "", 0, propertyCallback );
m_rotationX->setMax( 180 );
m_rotationX->setMin( -180 );
m_rotationY = m_groupTexManip->addProperty( "Y rotation", "", 0, propertyCallback );
m_rotationY->setMax( 180 );
m_rotationY->setMin( -180 );
m_rotationZ = m_groupTexManip->addProperty( "Z rotation", "", 0, propertyCallback );
m_rotationZ->setMax( 180 );
m_rotationZ->setMin( -180 );
}
void WMData::propertyChanged( boost::shared_ptr< WPropertyBase > property )
......@@ -176,6 +210,32 @@ void WMData::propertyChanged( boost::shared_ptr< WPropertyBase > property )
{
m_dataSet->getTexture()->setSelectedColormap( m_colorMapSelection->get( true ).getItemIndexOfSelected( 0 ) );
}
else if ( property == m_translationX || property == m_translationY || property == m_translationZ )
{
boost::shared_ptr< WGridRegular3D > grid = m_dataSet->getTexture()->getGrid();
wmath::WPosition pos( m_translationX->get(), m_translationY->get(), m_translationZ->get() );
grid->translate( pos );
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
}
else if ( property == m_stretchX || property == m_stretchY || property == m_stretchZ )
{
boost::shared_ptr< WGridRegular3D > grid = m_dataSet->getTexture()->getGrid();
wmath::WPosition str( m_stretchX->get(), m_stretchY->get(), m_stretchZ->get() );
grid->stretch( str );
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
}
else if ( property == m_rotationX || property == m_rotationY || property == m_rotationZ )
{
float pi = 3.14159265;
float rotx = static_cast<float>( m_rotationX->get() ) / 180. * pi;
float roty = static_cast<float>( m_rotationY->get() ) / 180. * pi;
float rotz = static_cast<float>( m_rotationZ->get() ) / 180. * pi;
boost::shared_ptr< WGridRegular3D > grid = m_dataSet->getTexture()->getGrid();
wmath::WPosition rot( rotx, roty, rotz );
grid->rotate( rot );
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
}
}
else
{
......@@ -236,11 +296,8 @@ void WMData::moduleMain()
|| suffix == ".edf" )
{
// hide other properties since they make no sense fo these data set types.
m_interpolation->setHidden();
m_threshold->setHidden();
m_opacity->setHidden();
m_active->setHidden();
m_colorMapSelection->setHidden();
m_groupTex->setHidden();
m_groupTexManip->setHidden();
}
if( suffix == ".nii"
......
......@@ -171,6 +171,16 @@ protected:
*/
WPropString m_dataName;
/**
* grouping the texture display properties
*/
WPropGroup m_groupTex;
/**
* grouping the texture manipulation properties
*/
WPropGroup m_groupTexManip;
/**
* Interpolation?
*/
......@@ -196,6 +206,51 @@ protected:
*/
WPropInt m_opacity;
/**
* translation of the texture
*/
WPropInt m_translationX;
/**
* translation of the texture
*/
WPropInt m_translationY;
/**
* translation of the texture
*/
WPropInt m_translationZ;
/**
* voxel size in x direction
*/
WPropDouble m_stretchX;
/**
* voxel size in y direction
*/
WPropDouble m_stretchY;
/**
* voxel size in z direction
*/
WPropDouble m_stretchZ;
/**
* rotation around the x axis
*/
WPropInt m_rotationX;
/**
* rotation around the y axis
*/
WPropInt m_rotationY;
/**
* rotation around the z axis
*/
WPropInt m_rotationZ;
bool m_isTexture; //!< Indicates whether the loaded dataSet will be available as texture.
/**
......
......@@ -749,9 +749,6 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createCrossGeometry( int slice )
void WMNavSlices::updateGeometry()
{
boost::shared_lock<boost::shared_mutex> slock;
slock = boost::shared_lock<boost::shared_mutex>( m_updateLock );
if ( m_textureChanged // Depends on call order of update routines in callback.
|| m_sagittalPos->changed()
|| m_coronalPos->changed()
......@@ -816,8 +813,6 @@ void WMNavSlices::updateGeometry()
{
m_xSliceNode->setNodeMask( 0x0 );
}
slock.unlock();
}
......
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