Commit 8402ca8e authored by schurade's avatar schurade
Browse files

[ADD] rois extrated from underlying datasets

parent 65df0569
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <osg/LineWidth>
#include <osg/LightModel>
#include "../common/WProgressCombiner.h"
#include "../modules/marchingCubes/WMarchingCubesAlgorithm.h"
#include "WROIArbitrary.h"
#include "WGraphicsEngine.h"
#include "WGEUtils.h"
WROIArbitrary::WROIArbitrary( boost::shared_ptr< const WDataSetScalar > dataSet, boost::shared_ptr< WTriangleMesh2 > triMesh, float threshold ) :
WROI(),
m_dataSet( dataSet ),
m_triMesh( triMesh ),
m_threshold( threshold )
{
updateGFX();
m_isModified = true;
WGraphicsEngine::getGraphicsEngine()->getScene()->addChild( this );
setUserData( this );
setUpdateCallback( osg::ref_ptr<ROIArbNodeCallback>( new ROIArbNodeCallback ) );
}
WROIArbitrary::~WROIArbitrary()
{
// std::cout << "destructor called" << std::endl;
// std::cout << "ref count geode: " << m_geode->referenceCount() << std::endl;
//
// WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_geode );
}
void WROIArbitrary::setThreshold( double threshold )
{
m_threshold = threshold;
m_isModified = true;
}
double WROIArbitrary::getThreshold()
{
return m_threshold;
}
double WROIArbitrary::getMaxThreshold()
{
return m_dataSet->getMax();
}
boost::shared_ptr< const WDataSetScalar > WROIArbitrary::getDataSet()
{
return m_dataSet;
}
void WROIArbitrary::updateGFX()
{
if ( m_isModified )
{
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( ( *m_dataSet ).getGrid() );
boost::shared_ptr< WValueSet< float > > vals = boost::shared_dynamic_cast< WValueSet< float > >( ( *m_dataSet ).getValueSet() );
boost::shared_ptr< WProgressCombiner > progress = boost::shared_ptr< WProgressCombiner >( new WProgressCombiner() );
WMarchingCubesAlgorithm mcAlgo;
m_triMesh = mcAlgo.generateSurface( grid, vals, m_threshold, progress );
osg::Geometry* surfaceGeometry = new osg::Geometry();
setName( "roi" );
surfaceGeometry->setVertexArray( m_triMesh->getVertexArray() );
// ------------------------------------------------
// normals
surfaceGeometry->setNormalArray( m_triMesh->getVertexNormalArray() );
surfaceGeometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
// ------------------------------------------------
// colors
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4( 1.0f, .2f, 0.2f, 1.0f ) );
surfaceGeometry->setColorArray( colors );
surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
osg::DrawElementsUInt* surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
std::vector< size_t >tris = m_triMesh->getTriangles();
surfaceElement->reserve( tris.size() );
for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
{
surfaceElement->push_back( tris[vertId] );
}
surfaceGeometry->addPrimitiveSet( surfaceElement );
removeDrawables( 0 );
addDrawable( surfaceGeometry );
osg::StateSet* state = getOrCreateStateSet();
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
lightModel->setTwoSided( true );
state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
state->setMode( GL_BLEND, osg::StateAttribute::ON );
// {
// osg::ref_ptr< osg::Material > material = new osg::Material();
// material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
// material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
// material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
// material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
// material->setShininess( osg::Material::FRONT, 25.0 );
// state->setAttribute( material );
// }
m_isModified = false;
}
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WROIARBITRARY_H
#define WROIARBITRARY_H
#include <string>
#include <utility>
#include <boost/thread.hpp>
#include "../common/math/WPosition.h"
#include "WPickHandler.h"
#include "WGEViewer.h"
#include "../dataHandler/WDataSetScalar.h"
#include "WTriangleMesh2.h"
#include "WROI.h"
/**
* A box representing a region of interest.
*/
class WROIArbitrary : public WROI
{
public:
/**
* constructor
* \param dataSet
* \param triMesh
* \param threshold
*/
WROIArbitrary( boost::shared_ptr< const WDataSetScalar > dataSet, boost::shared_ptr< WTriangleMesh2 > triMesh, float threshold );
/**
* destructor
*/
virtual ~WROIArbitrary();
/**
* setter
* \param threshold
*/
void setThreshold( double threshold );
/**
* getter
*/
double getThreshold();
/**
* getter
*/
double getMaxThreshold();
/**
* getter
*/
boost::shared_ptr< const WDataSetScalar > getDataSet();
/**
* updates the graphics
*/
virtual void updateGFX();
protected:
private:
boost::shared_ptr< const WDataSetScalar > m_dataSet; //!< pointer to dataSet to be able to access it throughout the whole module.
boost::shared_ptr< WTriangleMesh2 > m_triMesh; //!< This triangle mesh is provided as output through the connector.
double m_threshold; //!< the threshold
/**
* Node callback to handle updates properly
*/
class ROIArbNodeCallback : public osg::NodeCallback
{
public: // NOLINT
/**
* operator ()
*
* \param node the osg node
* \param nv the node visitor
*/
virtual void operator()( osg::Node* node, osg::NodeVisitor* nv )
{
osg::ref_ptr< WROIArbitrary > module = static_cast< WROIArbitrary* > ( node->getUserData() );
if ( module )
{
module->updateGFX();
}
traverse( node, nv );
}
};
};
#endif // WROIARBITRARY_H
......@@ -114,7 +114,9 @@ WROIBox::WROIBox( wmath::WPosition minPos, wmath::WPosition maxPos ) :
WROI(),
boxId( maxBoxId++ ),
m_pickNormal( wmath::WVector3D() ),
m_oldPixelPosition( std::make_pair( 0, 0 ) )
m_oldPixelPosition( std::make_pair( 0, 0 ) ),
m_color( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) ),
m_notColor( osg::Vec4( 1.0f, 0.0f, 0.0f, 0.4f ) )
{
m_minPos = minPos;
m_maxPos = maxPos;
......@@ -276,11 +278,11 @@ void WROIBox::updateGFX()
osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
if ( m_isNot )
{
colors->push_back( osg::Vec4( 1.0f, 0.0f, 0.0f, 0.4f ) );
colors->push_back( m_notColor );
}
else
{
colors->push_back( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) );
colors->push_back( m_color );
}
m_surfaceGeometry->setColorArray( colors );
}
......@@ -304,11 +306,11 @@ void WROIBox::updateGFX()
osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
if ( m_isNot )
{
colors->push_back( osg::Vec4( 1.0f, 0.f, 0.f, 0.4f ) );
colors->push_back( m_notColor );
}
else
{
colors->push_back( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) );
colors->push_back( m_color );
}
m_surfaceGeometry->setColorArray( colors );
m_pickNormal = wmath::WVector3D();
......@@ -320,14 +322,24 @@ void WROIBox::updateGFX()
osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
if ( m_isNot )
{
colors->push_back( osg::Vec4( 1.0f, 0.f, 0.f, 0.4f ) );
colors->push_back( m_notColor );
}
else
{
colors->push_back( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) );
colors->push_back( m_color );
}
m_surfaceGeometry->setColorArray( colors );
}
lock.unlock();
}
void WROIBox::setColor( osg::Vec4 color )
{
m_color = color;
}
void WROIBox::setNotColor( osg::Vec4 color )
{
m_notColor = color;
}
......@@ -61,6 +61,17 @@ public:
*/
wmath::WPosition getMaxPos() const;
/**
* setter
* \param color
*/
void setColor( osg::Vec4 color );
/**
* setter
* \param color
*/
void setNotColor( osg::Vec4 color );
protected:
private:
......@@ -80,6 +91,10 @@ private:
boost::shared_ptr< WGEViewer > m_viewer; //!< makes viewer available all over this class.
osg::Vec4 m_color; //!< the color of the box
osg::Vec4 m_notColor; //!< the color of the box when negated
/**
* note that there was a pick
* \param pickInfo info from pick
......
......@@ -417,6 +417,7 @@ void WQtDatasetBrowser::selectRoiTreeItem()
break;
}
}
WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getFirstRoiInSelectedBranch() );
buildPropTab( props );
}
......@@ -610,7 +611,6 @@ boost::shared_ptr< WRMROIRepresentation > WQtDatasetBrowser::getFirstRoiInSelect
void WQtDatasetBrowser::deleteTreeItem()
{
boost::shared_ptr< WRMROIRepresentation >roi;
if ( m_roiTreeWidget->selectedItems().count() > 0 )
{
if ( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
......@@ -633,4 +633,5 @@ void WQtDatasetBrowser::deleteTreeItem()
}
}
}
WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getFirstRoiInSelectedBranch() );
}
......@@ -57,7 +57,7 @@
#include "../modules/writeNIfTI/WMWriteNIfTI.h"
#include "../modules/vectorPlot/WMVectorPlot.h"
#include "../modules/geometryGlyphs/WMGeometryGlyphs.h"
#include "../modules/meshReader/WMMeshReader.h"
#include "../modules/arbitraryRois/WMArbitraryRois.h"
#include "WModuleFactory.h"
#include "exceptions/WPrototypeNotUnique.h"
#include "exceptions/WPrototypeUnknown.h"
......@@ -113,7 +113,7 @@ void WModuleFactory::load()
m_prototypes.insert( boost::shared_ptr< WModule >( new WMClusterSlicer() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMVectorPlot() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMGeometryGlyphs() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMMeshReader() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMArbitraryRois() ) );
lock.unlock();
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <string>
#include <vector>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/StateSet>
#include <osg/StateAttribute>
#include <osg/PolygonMode>
#include <osg/LightModel>
#include "../../kernel/WKernel.h"
#include "../../common/WAssert.h"
#include "../../graphicsEngine/WROIArbitrary.h"
#include "../marchingCubes/WMarchingCubesAlgorithm.h"
#include "WMArbitraryRois.h"
WMArbitraryRois::WMArbitraryRois():
WModule(),
m_textureChanged( true ),
m_recompute( boost::shared_ptr< WCondition >( new WCondition() ) ),
m_dataSet(),
m_moduleNode( new WGEGroupNode() ),
m_showSelector( true )
{
}
WMArbitraryRois::~WMArbitraryRois()
{
// Cleanup!
}
boost::shared_ptr< WModule > WMArbitraryRois::factory() const
{
// See "src/modules/template/" for an extensively documented example.
return boost::shared_ptr< WModule >( new WMArbitraryRois() );
}
const std::string WMArbitraryRois::getName() const
{
// Specify your module name here. This name must be UNIQUE!
return "Arbitrary Rois";
}
const std::string WMArbitraryRois::getDescription() const
{
// Specify your module description here. Be detailed. This text is read by the user.
// See "src/modules/template/" for an extensively documented example.
return "Someone should add some documentation here. ";
}
void WMArbitraryRois::connectors()
{
// initialize connectors
m_input = boost::shared_ptr< WModuleInputData < WDataSetScalar > >(
new WModuleInputData< WDataSetScalar >( shared_from_this(), "in", "Dataset to cut roi from." ) );
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
addConnector( m_input );
// call WModules initialization
WModule::connectors();
}
void WMArbitraryRois::properties()
{
m_aTrigger = m_properties->addProperty( "Create", "Create a roi", WPVBaseTypes::PV_TRIGGER_READY );
m_bTrigger = m_properties->addProperty( "Finalize", "finalize and add to roi manager", WPVBaseTypes::PV_TRIGGER_READY );
m_threshold = m_properties->addProperty( "threshold", "Threshold", 0. );
m_surfaceColor = m_properties->addProperty( "Surface Color", "Description.", WColor( 1.0, 0.3, 0.3, 1.0 ) );
}
void WMArbitraryRois::moduleMain()
{
// use the m_input "data changed" flag
m_moduleState.setResetable( true, true );
m_moduleState.add( m_input->getDataChangedCondition() );
m_moduleState.add( m_recompute );
// signal ready state
ready();
// loop until the module container requests the module to quit
while ( !m_shutdownFlag() )
{
if( m_dataSet != m_input->getData() )
{
// acquire data from the input connector
m_dataSet = m_input->getData();
m_threshold->setMin( m_dataSet->getMin() );
m_threshold->setMax( m_dataSet->getMax() );
m_threshold->set( 0. );
initSelectionRoi();
}
// this waits for m_moduleState to fire. By default, this is only the m_shutdownFlag condition.
// NOTE: you can add your own conditions to m_moduleState using m_moduleState.add( ... )
if ( m_aTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
{
debugLog() << "Creating cut dataset.";
m_showSelector = true;
createCutDataset();
renderMesh();
m_aTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, false );
}
if ( m_bTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
{
debugLog() << "Creating cut dataset.";
m_showSelector = false;
createCutDataset();
renderMesh();
finalizeRoi();
m_bTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, false );
}
//m_moduleState.wait();
}
}
void WMArbitraryRois::initSelectionRoi()
{
wmath::WPosition crossHairPos = WKernel::getRunningKernel()->getSelectionManager()->getCrosshair()->getPosition();
wmath::WPosition minROIPos = crossHairPos - wmath::WPosition( 10., 10., 10. );
wmath::WPosition maxROIPos = crossHairPos + wmath::WPosition( 10., 10., 10. );
m_selectionRoi = osg::ref_ptr< WROIBox >( new WROIBox( minROIPos, maxROIPos ) );
m_selectionRoi->setColor( osg::Vec4( 0., 0., 1.0, 0.4 ) );
createCutDataset();
}
void WMArbitraryRois::createCutDataset()
{
boost::shared_ptr< WValueSetBase > newValueSet;
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
size_t order = ( *m_dataSet ).getValueSet()->order();
size_t vDim = ( *m_dataSet ).getValueSet()->dimension();
float threshold = m_threshold->get();
std::vector< float > data;
switch( ( *m_dataSet ).getValueSet()->getDataType() )
{
case W_DT_UNSIGNED_CHAR:
{
boost::shared_ptr< WValueSet< unsigned char > > vals;
vals = boost::shared_dynamic_cast< WValueSet< unsigned char > >( ( *m_dataSet ).getValueSet() );
WAssert( vals, "Data type and data type indicator must fit." );
data = cutArea( ( *m_dataSet ).getGrid(), vals );
break;
}
case W_DT_INT16:
{
boost::shared_ptr< WValueSet< int16_t > > vals;
vals = boost::shared_dynamic_cast< WValueSet< int16_t > >( ( *m_dataSet ).getValueSet() );
WAssert( vals, "Data type and data type indicator must fit." );
data = cutArea( ( *m_dataSet ).getGrid(), vals );
break;
}
case W_DT_SIGNED_INT:
{
boost::shared_ptr< WValueSet< int32_t > > vals;
vals = boost::shared_dynamic_cast< WValueSet< int32_t > >( ( *m_dataSet ).getValueSet() );
WAssert( vals, "Data type and data type indicator must fit." );
cutArea( ( *m_dataSet ).getGrid(), vals );
data = cutArea( ( *m_dataSet ).getGrid(), vals );
break;
}
case W_DT_FLOAT:
{
boost::shared_ptr< WValueSet< float > > vals;
vals = boost::shared_dynamic_cast< WValueSet< float > >( ( *m_dataSet ).getValueSet() );
WAssert( vals, "Data type and data type indicator must fit." );
data = cutArea( ( *m_dataSet ).getGrid(), vals );
break;
}
case W_DT_DOUBLE:
{
boost::shared_ptr< WValueSet< double > > vals;
vals = boost::shared_dynamic_cast< WValueSet< double > >( ( *m_dataSet ).getValueSet() );