Commit 05409210 authored by schurade's avatar schurade

[CHANGE] improved the texture painting

parent ba8c0b46
...@@ -39,7 +39,9 @@ using wmath::WMatrix; ...@@ -39,7 +39,9 @@ using wmath::WMatrix;
WSelectionManager::WSelectionManager() : WSelectionManager::WSelectionManager() :
m_paintMode( PAINTMODE_NONE ) m_paintMode( PAINTMODE_NONE ),
m_textureOpacity( 1.0 ),
m_useTexture( false )
{ {
m_crosshair = boost::shared_ptr< WCrosshair >( new WCrosshair() ); m_crosshair = boost::shared_ptr< WCrosshair >( new WCrosshair() );
} }
...@@ -124,3 +126,48 @@ WPaintMode WSelectionManager::getPaintMode() ...@@ -124,3 +126,48 @@ WPaintMode WSelectionManager::getPaintMode()
return m_paintMode; return m_paintMode;
} }
void WSelectionManager::setTexture( osg::ref_ptr< osg::Texture3D > texture, boost::shared_ptr< WGridRegular3D >grid )
{
m_texture = texture;
m_textureGrid = grid;
}
osg::ref_ptr< osg::Texture3D > WSelectionManager::getTexture()
{
return m_texture;
}
boost::shared_ptr< WGridRegular3D >WSelectionManager::getGrid()
{
return m_textureGrid;
}
void WSelectionManager::setUseTexture( bool flag )
{
m_useTexture = flag;
}
bool WSelectionManager::getUseTexture()
{
return m_useTexture;
}
float WSelectionManager::getTextureOpacity()
{
return m_textureOpacity;
}
void WSelectionManager::setTextureOpacity( float value )
{
if ( value < 0.0 )
{
value = 0.0;
}
if ( value > 1.0 )
{
value = 1.0;
}
m_textureOpacity = value;
}
...@@ -80,11 +80,76 @@ public: ...@@ -80,11 +80,76 @@ public:
*/ */
WPaintMode getPaintMode(); WPaintMode getPaintMode();
/**
* setter for texture and grid
*
* \param texture
* \param grid
*/
void setTexture( osg::ref_ptr< osg::Texture3D > texture, boost::shared_ptr< WGridRegular3D >grid );
/**
* getter
* \return texture
*/
osg::ref_ptr< osg::Texture3D > getTexture();
/**
* getter
* \return grid
*/
boost::shared_ptr< WGridRegular3D >getGrid();
/**
* setter
* \param flag
*/
void setUseTexture( bool flag = true );
/**
* getter
* \return flag
*/
bool getUseTexture();
/**
* getter
* \return the opacity
*/
float getTextureOpacity();
/**
* setter
* \param value the new opacity to use with the texture
*/
void setTextureOpacity( float value );
protected: protected:
private: private:
boost::shared_ptr< WCrosshair >m_crosshair; //!< stores pointer to crosshair boost::shared_ptr< WCrosshair >m_crosshair; //!< stores pointer to crosshair
WPaintMode m_paintMode; //!< stores the currently selected paint mode WPaintMode m_paintMode; //!< stores the currently selected paint mode
/**
* stores a pointer to a texture 3d, this is used to provide a faster texture generation process
* than creating a new dataset for every texture change
*/
osg::ref_ptr< osg::Texture3D > m_texture;
/**
* stores a pointer to the grid to be used together with the texture
*/
boost::shared_ptr< WGridRegular3D >m_textureGrid;
/**
* the texture opacity
*/
float m_textureOpacity;
/**
* flag indicating if this additional texture should be used.
*/
bool m_useTexture;
}; };
#endif // WSELECTIONMANAGER_H #endif // WSELECTIONMANAGER_H
...@@ -581,6 +581,20 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createGeometry( int slice ) ...@@ -581,6 +581,20 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createGeometry( int slice )
sliceGeometry->setVertexArray( sliceVertices ); sliceGeometry->setVertexArray( sliceVertices );
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
boost::shared_ptr< WGridRegular3D > grid = WKernel::getRunningKernel()->getSelectionManager()->getGrid();
osg::Vec3Array* texCoords = new osg::Vec3Array;
for( size_t i = 0; i < nbVerts; ++i )
{
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( vertices[i] ) ) );
}
sliceGeometry->setTexCoordArray( c, texCoords );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid(); boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid();
...@@ -610,6 +624,20 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createGeometry( int slice ) ...@@ -610,6 +624,20 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createGeometry( int slice )
sliceGeometry->setVertexArray( sliceVertices ); sliceGeometry->setVertexArray( sliceVertices );
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
boost::shared_ptr< WGridRegular3D > grid = WKernel::getRunningKernel()->getSelectionManager()->getGrid();
osg::Vec3Array* texCoords = new osg::Vec3Array;
for( size_t i = 0; i < nbVerts; ++i )
{
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( vertices[i] ) ) );
}
sliceGeometry->setTexCoordArray( c, texCoords );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid(); boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid();
...@@ -639,6 +667,20 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createGeometry( int slice ) ...@@ -639,6 +667,20 @@ osg::ref_ptr<osg::Geometry> WMNavSlices::createGeometry( int slice )
sliceGeometry->setVertexArray( sliceVertices ); sliceGeometry->setVertexArray( sliceVertices );
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
boost::shared_ptr< WGridRegular3D > grid = WKernel::getRunningKernel()->getSelectionManager()->getGrid();
osg::Vec3Array* texCoords = new osg::Vec3Array;
for( size_t i = 0; i < nbVerts; ++i )
{
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( vertices[i] ) ) );
}
sliceGeometry->setTexCoordArray( c, texCoords );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid(); boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid();
...@@ -817,6 +859,26 @@ void WMNavSlices::updateTextures() ...@@ -817,6 +859,26 @@ void WMNavSlices::updateTextures()
// for each texture -> apply // for each texture -> apply
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
osg::ref_ptr<osg::Texture3D> texture3D = WKernel::getRunningKernel()->getSelectionManager()->getTexture();
m_typeUniforms[c]->set( W_DT_UNSIGNED_CHAR );
m_thresholdUniforms[c]->set( 0.0f );
m_alphaUniforms[c]->set( WKernel::getRunningKernel()->getSelectionManager()->getTextureOpacity() );
m_cmapUniforms[c]->set( 4 );
texture3D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST );
texture3D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST );
rootState->setTextureAttributeAndModes( c, texture3D, osg::StateAttribute::ON );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
osg::ref_ptr<osg::Texture3D> texture3D = ( *iter )->getTexture(); osg::ref_ptr<osg::Texture3D> texture3D = ( *iter )->getTexture();
......
...@@ -283,6 +283,21 @@ void WMArbitraryPlane::updatePlane() ...@@ -283,6 +283,21 @@ void WMArbitraryPlane::updatePlane()
std::vector< boost::shared_ptr< WDataTexture3D > > tex = WDataHandler::getDefaultSubject()->getDataTextures( true ); std::vector< boost::shared_ptr< WDataTexture3D > > tex = WDataHandler::getDefaultSubject()->getDataTextures( true );
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
boost::shared_ptr< WGridRegular3D > grid = WKernel::getRunningKernel()->getSelectionManager()->getGrid();
osg::Vec3Array* texCoords = new osg::Vec3Array;
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( v0 ) ) );
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( v1 ) ) );
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( v2 ) ) );
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( v3 ) ) );
planeGeometry->setTexCoordArray( c, texCoords );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid(); boost::shared_ptr< WGridRegular3D > grid = ( *iter )->getGrid();
...@@ -357,6 +372,25 @@ void WMArbitraryPlane::updateTextures() ...@@ -357,6 +372,25 @@ void WMArbitraryPlane::updateTextures()
// for each texture -> apply // for each texture -> apply
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
osg::ref_ptr<osg::Texture3D> texture3D = WKernel::getRunningKernel()->getSelectionManager()->getTexture();
m_typeUniforms[c]->set( W_DT_UNSIGNED_CHAR );
m_thresholdUniforms[c]->set( 0.0f );
m_alphaUniforms[c]->set( WKernel::getRunningKernel()->getSelectionManager()->getTextureOpacity() );
m_cmapUniforms[c]->set( 4 );
texture3D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST );
texture3D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST );
rootState->setTextureAttributeAndModes( c, texture3D, osg::StateAttribute::ON );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
osg::ref_ptr<osg::Texture3D> texture3D = ( *iter )->getTexture(); osg::ref_ptr<osg::Texture3D> texture3D = ( *iter )->getTexture();
......
...@@ -586,6 +586,37 @@ void WMMarchingCubes::updateGraphics() ...@@ -586,6 +586,37 @@ void WMMarchingCubes::updateGraphics()
// for each texture -> apply // for each texture -> apply
int c = 0; int c = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////
if ( WKernel::getRunningKernel()->getSelectionManager()->getUseTexture() )
{
boost::shared_ptr< WGridRegular3D > grid = WKernel::getRunningKernel()->getSelectionManager()->getGrid();
osg::ref_ptr< osg::Geometry > surfaceGeometry = m_surfaceGeode->getDrawable( 0 )->asGeometry();
osg::Vec3Array* texCoords = new osg::Vec3Array;
for( size_t i = 0; i < m_triMesh->vertSize(); ++i )
{
osg::Vec3 vertPos = m_triMesh->getVertex( i );
texCoords->push_back( wge::wv3D2ov3( grid->worldCoordToTexCoord( wmath::WPosition( vertPos[0], vertPos[1], vertPos[2] ) ) ) );
}
surfaceGeometry->setTexCoordArray( c, texCoords );
osg::ref_ptr<osg::Texture3D> texture3D = WKernel::getRunningKernel()->getSelectionManager()->getTexture();
m_typeUniforms[c]->set( W_DT_UNSIGNED_CHAR );
m_thresholdUniforms[c]->set( 0.0f );
m_alphaUniforms[c]->set( WKernel::getRunningKernel()->getSelectionManager()->getTextureOpacity() );
m_cmapUniforms[c]->set( 4 );
texture3D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST );
texture3D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST );
rootState->setTextureAttributeAndModes( c, texture3D, osg::StateAttribute::ON );
++c;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter ) for ( std::vector< boost::shared_ptr< WDataTexture3D > >::const_iterator iter = tex.begin(); iter != tex.end(); ++iter )
{ {
if( localTextureChangedFlag ) if( localTextureChangedFlag )
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "../../kernel/WKernel.h" #include "../../kernel/WKernel.h"
#include "../../dataHandler/WDataHandler.h" #include "../../dataHandler/WDataHandler.h"
#include "../../dataHandler/WDataTexture3D.h" #include "../../dataHandler/WDataTexture3D.h"
#include "../../dataHandler/WSubject.h"
#include "../../common/WPropertyHelper.h" #include "../../common/WPropertyHelper.h"
...@@ -86,6 +87,9 @@ void WMPaintTexture::properties() ...@@ -86,6 +87,9 @@ void WMPaintTexture::properties()
{ {
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() ); m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
// use this callback for the other properties
WPropertyBase::PropertyChangeNotifierType propertyCallback = boost::bind( &WMPaintTexture::propertyChanged, this, _1 );
m_painting = m_properties->addProperty( "Paint", "If active, left click in the scene with pressed ctrl key" m_painting = m_properties->addProperty( "Paint", "If active, left click in the scene with pressed ctrl key"
" will paint something.", false, m_propCondition ); " will paint something.", false, m_propCondition );
...@@ -100,15 +104,8 @@ void WMPaintTexture::properties() ...@@ -100,15 +104,8 @@ void WMPaintTexture::properties()
m_paintIndex->setMin( 0 ); m_paintIndex->setMin( 0 );
m_paintIndex->setMax( 255 ); m_paintIndex->setMax( 255 );
// these are taken from WMData
m_interpolation = m_properties->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.",
false,
m_propCondition );
m_opacity = m_properties->addProperty( "Opacity %", "The opacity of this data in colormaps combining" m_opacity = m_properties->addProperty( "Opacity %", "The opacity of this data in colormaps combining"
" values from several data sets.", 100, m_propCondition ); " values from several data sets.", 100, propertyCallback );
m_opacity->setMax( 100 ); m_opacity->setMax( 100 );
m_opacity->setMin( 0 ); m_opacity->setMin( 0 );
...@@ -125,6 +122,18 @@ void WMPaintTexture::properties() ...@@ -125,6 +122,18 @@ void WMPaintTexture::properties()
m_queueAdded = m_properties->addProperty( "Something paint", "", false, m_propCondition ); m_queueAdded = m_properties->addProperty( "Something paint", "", false, m_propCondition );
m_queueAdded->setHidden(); m_queueAdded->setHidden();
m_buttonUpdateOutput = m_properties->addProperty( "Update output", "Updates the output connector",
WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
}
void WMPaintTexture::propertyChanged( boost::shared_ptr< WPropertyBase > property )
{
if ( property == m_opacity )
{
WKernel::getRunningKernel()->getSelectionManager()->setTextureOpacity( m_opacity->get( true ) / 100.0 );
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
}
} }
void WMPaintTexture::moduleMain() void WMPaintTexture::moduleMain()
...@@ -159,29 +168,11 @@ void WMPaintTexture::moduleMain() ...@@ -159,29 +168,11 @@ void WMPaintTexture::moduleMain()
WAssert( m_dataSet, "" ); WAssert( m_dataSet, "" );
WAssert( m_dataSet->getValueSet(), "" ); WAssert( m_dataSet->getValueSet(), "" );
if( m_outData ) createTexture();
{
WDataHandler::deregisterDataSet( m_outData );
}
m_outData = createNewOutTexture();
if( m_outData ) updateOutDataset();
{
setOutputProps();
m_outData->setFileName( std::string( "painted" ) );
WDataHandler::registerDataSet( m_outData );
}
m_output->updateData( m_outData );
}
else
{
if( m_outData )
{
setOutputProps();
}
} }
if ( m_painting->changed() ) if ( m_painting->changed() )
{ {
if ( m_painting->get( true ) ) if ( m_painting->get( true ) )
...@@ -197,99 +188,58 @@ void WMPaintTexture::moduleMain() ...@@ -197,99 +188,58 @@ void WMPaintTexture::moduleMain()
else // case !dataValid else // case !dataValid
{ {
if( m_outData ) if( m_outData )
{
WDataHandler::deregisterDataSet( m_outData );
}
m_outData = boost::shared_ptr< WDataSetScalar >(); m_outData = boost::shared_ptr< WDataSetScalar >();
m_output->updateData( m_outData ); m_output->updateData( m_outData );
} }
if ( m_queueAdded->changed() && m_queueAdded->get( true ) ) if ( m_queueAdded->changed() && m_queueAdded->get( true ) )
{ {
boost::shared_ptr< WDataSetScalar > old; doPaint();
if( m_outData ) }
{
old = m_outData;
}
m_outData = doPaint();
WDataHandler::registerDataSet( m_outData ); if ( m_buttonUpdateOutput->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
WDataHandler::deregisterDataSet( old ); {
m_output->updateData( m_outData ); updateOutDataset();
m_buttonUpdateOutput->set( WPVBaseTypes::PV_TRIGGER_READY, false );
} }
} }
debugLog() << "Shutting down..."; debugLog() << "Shutting down...";
if( m_outData ) WKernel::getRunningKernel()->getSelectionManager()->setUseTexture( false );
{ WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
WDataHandler::deregisterDataSet( m_outData );
}
debugLog() << "Finished! Good Bye!"; debugLog() << "Finished! Good Bye!";
} }
void WMPaintTexture::activate() void WMPaintTexture::activate()
{ {
if( m_outData )
{
m_outData->getTexture()->setGloballyActive( m_active->get() );
}
WModule::activate(); WModule::activate();
} }
void WMPaintTexture::setOutputProps() void WMPaintTexture::doPaint()
{
if( m_outData )
{
m_outData->getTexture()->setThreshold( 0 );
m_outData->getTexture()->setOpacity( m_opacity->get() );
m_outData->getTexture()->setInterpolation( m_interpolation->get() );
m_outData->getTexture()->setSelectedColormap( m_colorMapSelection->get( true ).getItemIndexOfSelected( 0 ) );
}
}
boost::shared_ptr< WDataSetScalar > WMPaintTexture::createNewOutTexture()
{
WAssert( m_dataSet, "" );
WAssert( m_dataSet->getValueSet(), "" );
WAssert( m_dataSet->getGrid(), "" );
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
WAssert( grid, "" );
m_values.resize( m_dataSet->getGrid()->size(), 0 );
m_values[0] = 255;
boost::shared_ptr< WValueSet< unsigned char > > vs =
boost::shared_ptr< WValueSet< unsigned char > >( new WValueSet< unsigned char >( 0, 1, m_values, W_DT_UINT8 ) );
return boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( vs, grid ) );
}
boost::shared_ptr< WDataSetScalar > WMPaintTexture::doPaint()
{ {
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_outData->getGrid() ); unsigned char* data = m_texture->getImage()->data();
while ( !m_paintQueue.empty() ) while ( !m_paintQueue.empty() )
{ {
wmath::WPosition paintPosition = m_paintQueue.front(); wmath::WPosition paintPosition = m_paintQueue.front();
m_paintQueue.pop(); m_paintQueue.pop();
int voxelNum = grid->getVoxelNum( paintPosition ); int voxelNum = m_grid->getVoxelNum( paintPosition );
if ( voxelNum != -1 ) if ( voxelNum != -1 )
{ {
switch ( m_pencilSelection->get( true ).getItemIndexOfSelected( 0 ) ) switch ( m_pencilSelection->get( true ).getItemIndexOfSelected( 0 ) )
{ {