Commit 8e8225c6 authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[CHANGE #155, #196]

 * switchted to the brand new now available module connection thing to get Datasets (so nasty while loop are gone for freedom :)
 * OSG group nodes should be destroyed in all Modules. BTW: the Clustering module want to use later the display module too
parent b0d555b4
......@@ -54,11 +54,11 @@
WMFiberClustering::WMFiberClustering()
: WModule(),
m_maxDistance_t( 0.0 ),
m_maxDistance_t( 6.5 ),
m_dLtTableExists( false ),
m_minClusterSize( 10 ),
m_separatePrimitives( true ),
m_proximity_t( 0.0 ),
m_proximity_t( 1.0 ),
m_lastFibsSize( 0 )
{
}
......@@ -74,26 +74,31 @@ boost::shared_ptr< WModule > WMFiberClustering::factory() const
void WMFiberClustering::moduleMain()
{
// signal ready state
// additional fire-condition: "data changed" flag
m_moduleState.add( m_fiberInput->getDataChangedCondition() );
ready();
boost::shared_ptr< WDataHandler > dataHandler;
// TODO(math): fix this hack when possible by using an input connector.
while( !WKernel::getRunningKernel() )
{
sleep( 1 );
}
while( !( dataHandler = WKernel::getRunningKernel()->getDataHandler() ) )
{
sleep( 1 );
}
while( !dataHandler->getNumberOfSubjects() )
while ( !m_shutdownFlag() ) // loop until the module container requests the module to quit
{
sleep( 1 );
}
m_fibs = m_fiberInput->getData();
if ( !m_fibs.get() ) // ok, the output has not yet sent data
{
m_moduleState.wait();
continue;
}
assert( m_fibs = boost::shared_dynamic_cast< WDataSetFibers >( dataHandler->getSubject( 0 )->getDataSet( 0 ) ) );
update();
m_moduleState.wait(); // waits for firing of m_moduleState ( dataChanged, shutdown, etc. )
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->removeChild( m_osgNode.get() );
}
}
void WMFiberClustering::update()
{
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->removeChild( m_osgNode.get() );
checkDLtLookUpTable();
if( !m_dLtTableExists )
......@@ -101,20 +106,11 @@ void WMFiberClustering::moduleMain()
m_dLtTable.reset( new WDXtLookUpTable( m_fibs->size() ) );
}
m_proximity_t = 1.0;
infoLog() << "Proximity threshold: " << m_proximity_t;
m_maxDistance_t = 6.5;
infoLog() << "Maximum inter cluster distance threshold: " << m_maxDistance_t;
cluster();
paint();
// Since the modules run in a separate thread: such loops are possible
while ( !m_FinishRequested )
{
// do fancy stuff
sleep( 1 );
}
}
void WMFiberClustering::checkDLtLookUpTable()
......@@ -267,15 +263,15 @@ void WMFiberClustering::paint()
WColor color;
infoLog() << "cluster: " << m_clusters.size();
osg::ref_ptr< osg::Group > group = osg::ref_ptr< osg::Group >( new osg::Group );
m_osgNode = osg::ref_ptr< osg::Group >( new osg::Group );
for( size_t i = 0; i < m_clusters.size(); ++i, hue += hue_increment )
{
color.setHSV( hue, 1.0, 0.75 );
m_clusters[i].setColor( color );
group->addChild( genFiberGeode( m_clusters[i] ).get() );
m_osgNode->addChild( genFiberGeode( m_clusters[i] ).get() );
}
group->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->addChild( group.get() );
m_osgNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->addChild( m_osgNode.get() );
}
void WMFiberClustering::meld( size_t qClusterID, size_t rClusterID )
......@@ -304,3 +300,48 @@ void WMFiberClustering::meld( size_t qClusterID, size_t rClusterID )
assert( rCluster.empty() );
}
void WMFiberClustering::connectors()
{
using boost::shared_ptr;
typedef WModuleInputData< WDataSetFibers > FiberInputData; // just an alias
m_fiberInput = shared_ptr< FiberInputData >( new FiberInputData( shared_from_this(), "fiberInput", "A loaded fiber dataset." ) );
addConnector( m_fiberInput );
WModule::connectors(); // call WModules initialization
}
void WMFiberClustering::properties()
{
m_properties->addString( "Fibers Display Module", "Display fibers" );
// this bool is hidden
m_properties->addBool( "active", true, true )->connect( boost::bind( &WMFiberClustering::slotPropertyChanged, this, _1 ) );
m_properties->addDouble( "Threshold", 6.5 )->connect( boost::bind( &WMFiberClustering::slotPropertyChanged, this, _1 ) );
}
void WMFiberClustering::slotPropertyChanged( std::string propertyName )
{
if( propertyName == "active" )
{
if ( m_properties->getValue< bool >( propertyName ) )
{
m_osgNode->setNodeMask( 0xFFFFFFFF );
}
else
{
m_osgNode->setNodeMask( 0x0 );
}
}
else if( propertyName == "Threshold" )
{
m_maxDistance_t = m_properties->getValue< double >( propertyName );
update();
}
else
{
// instead of WLogger we must use std::cerr since WLogger needs to much time!
std::cerr << propertyName << std::endl;
assert( 0 && "This property name is not supported by this function yet." );
}
}
......@@ -36,6 +36,7 @@
#include "../../common/datastructures/WFiberCluster.h"
#include "../../dataHandler/WDataSetFibers.h"
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleInputData.h"
#include "../../math/WFiber.h"
/**
......@@ -77,12 +78,33 @@ public:
*/
virtual boost::shared_ptr< WModule > factory() const;
/**
* Determine what to do if a property was changed.
* \param propertyName Name of the property.
*/
void slotPropertyChanged( std::string propertyName );
protected:
/**
* Entry point after loading the module. Runs in separate thread.
*/
virtual void moduleMain();
/**
* Initialize the connectors this module is using.
*/
virtual void connectors();
/**
* Initialize the properties for this module.
*/
virtual void properties();
/**
* Reclusters the scene.
*/
void update();
private:
/**
* Group fibers into WFiberCluster.
......@@ -143,6 +165,17 @@ private:
double m_proximity_t;
size_t m_lastFibsSize; //!< Last known number of fibers
/**
* Input connector for a fiber dataset.
*/
boost::shared_ptr< WModuleInputData< WDataSetFibers > > m_fiberInput;
/**
* OSG node for this module. All other OSG nodes of this module should be
* placed as child to this node.
*/
osg::ref_ptr< osg::Group > m_osgNode;
};
inline const std::string WMFiberClustering::getName() const
......
......@@ -30,23 +30,23 @@
#include <osg/Geode>
#include <osg/Geometry>
#include "WMFiberCulling.h"
#include "../../math/WFiber.h"
#include "../../math/fiberSimilarity/WDSTMetric.h"
#include "../../common/WColor.h"
#include "../../common/WLogger.h"
#include "../../common/WStatusReport.h"
#include "../../dataHandler/WDataHandler.h"
#include "../../dataHandler/WSubject.h"
#include "../../dataHandler/WDataSetFibers.h"
#include "../../dataHandler/WSubject.h"
#include "../../dataHandler/io/WWriterFiberVTK.h"
#include "../../kernel/WKernel.h"
#include "../../math/WFiber.h"
#include "../../math/fiberSimilarity/WDSTMetric.h"
#include "../../utils/WColorUtils.h"
#include "WMFiberCulling.h"
WMFiberCulling::WMFiberCulling()
: WModule(),
m_proximity_t( 0.0 ),
m_dSt_culling_t( 0.0 ),
m_proximity_t( 1.0 ),
m_dSt_culling_t( 6.5 ),
m_saveCulledCurves( false )
{
}
......@@ -62,51 +62,58 @@ boost::shared_ptr< WModule > WMFiberCulling::factory() const
void WMFiberCulling::moduleMain()
{
// signal ready state
// additional fire-condition: "data changed" flag
m_moduleState.add( m_fiberInput->getDataChangedCondition() );
ready();
boost::shared_ptr< WDataHandler > dataHandler;
// TODO(math): fix this hack when possible by using an input connector.
while( !WKernel::getRunningKernel() )
{
sleep( 1 );
}
while( !( dataHandler = WKernel::getRunningKernel()->getDataHandler() ) )
while ( !m_shutdownFlag() ) // loop until the module container requests the module to quit
{
sleep( 1 );
}
while( !dataHandler->getNumberOfSubjects() )
{
sleep( 1 );
}
m_dataset = m_fiberInput->getData();
if ( !m_dataset.get() ) // ok, the output has not yet sent data
{
m_moduleState.wait();
continue;
}
boost::shared_ptr< WDataSetFibers > fiberDS;
assert( fiberDS = boost::shared_dynamic_cast< WDataSetFibers >( dataHandler->getSubject( 0 )->getDataSet( 0 ) ) );
update();
m_moduleState.wait(); // waits for firing of m_moduleState ( dataChanged, shutdown, etc. )
}
}
// TODO(math): default parameters via property object
m_proximity_t = 1.0;
void WMFiberCulling::update()
{
infoLog() << "Proximity threshold: " << m_proximity_t;
m_dSt_culling_t = 6.5;
infoLog() << "Culling threshold: " << m_dSt_culling_t;
cullOutFibers( fiberDS );
cullOutFibers();
infoLog() << "done.";
infoLog() << "Clulling done.";
}
// Since the modules run in a separate thread: such loops are possible
while ( !m_FinishRequested )
{
// do fancy stuff
sleep( 1 );
}
void WMFiberCulling::connectors()
{
using boost::shared_ptr;
typedef WModuleInputData< WDataSetFibers > FiberInputData; // just an alias
m_fiberInput = shared_ptr< FiberInputData >( new FiberInputData( shared_from_this(), "fiberInput", "A loaded fiber dataset." ) );
addConnector( m_fiberInput );
WModule::connectors(); // call WModules initialization
}
void WMFiberCulling::properties()
{
m_properties->addString( "Fibers Display Module", "Display fibers" );
}
void WMFiberCulling::cullOutFibers( boost::shared_ptr< WDataSetFibers > fibers )
void WMFiberCulling::cullOutFibers()
{
size_t numFibers = fibers->size();
size_t numFibers = m_dataset->size();
infoLog() << "Recoginzed " << numFibers << " fibers";
fibers->sortDescLength(); // biggest first, this is for speed up
m_dataset->sortDescLength(); // biggest first, this is for speed up
infoLog() << "Sorted fibers done.";
std::vector< bool > unusedFibers( numFibers, false );
......@@ -126,10 +133,10 @@ void WMFiberCulling::cullOutFibers( boost::shared_ptr< WDataSetFibers > fibers )
{
continue;
}
double dst = dSt.dist( (*fibers)[q], (*fibers)[r] );
double dst = dSt.dist( (*m_dataset)[q], (*m_dataset)[r] );
if( dst < m_dSt_culling_t ) // cullout small fibs nearby long fibs
{
if( (*fibers)[q].size() < (*fibers)[r].size() )
if( (*m_dataset)[q].size() < (*m_dataset)[r].size() )
{
unusedFibers[q] = true;
break;
......@@ -146,12 +153,12 @@ void WMFiberCulling::cullOutFibers( boost::shared_ptr< WDataSetFibers > fibers )
}
std::cout << std::endl;
fibers->erase( unusedFibers );
m_dataset->erase( unusedFibers );
infoLog() << "Erasing done.";
infoLog() << "Culled out " << numFibers - fibers->size() << " fibers";
infoLog() << "There are " << fibers->size() << " fibers left.";
infoLog() << "Culled out " << numFibers - m_dataset->size() << " fibers";
infoLog() << "There are " << m_dataset->size() << " fibers left.";
// TODO(math): make saving parameter dependent, and apply the desired path for saving
WWriterFiberVTK w( "/tmp/pansen.fib", true );
w.writeFibs( fibers );
w.writeFibs( m_dataset );
}
......@@ -33,6 +33,7 @@
#include "../../dataHandler/WDataSetFibers.h"
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleInputData.h"
#include "../../math/WFiber.h"
/**
......@@ -67,11 +68,28 @@ public:
/**
* Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
* should never be initialized or modified in some other way. A simple new instance is required.
*
*
* \return the prototype used to create every module in OpenWalnut.
*/
virtual boost::shared_ptr< WModule > factory() const;
/**
* Initialize the connectors this module is using.
*/
virtual void connectors();
/**
* Initialize the properties for this module.
*/
virtual void properties();
/**
* ReCulls the scene.
*
* \problem This might take a while with e.g. 70,000 fibers approx 2h
*/
void update();
protected:
/**
* Entry point after loading the module. Runs in separate thread.
......@@ -82,10 +100,8 @@ protected:
* Detect and removes fibers that have a short distance in terms of the
* dSt metric and are below the threshold given via the member
* m_dSt_culling_t.
*
* \param fibers Fiber dataset, which should be processed.
*/
virtual void cullOutFibers( boost::shared_ptr< WDataSetFibers > fibers );
virtual void cullOutFibers();
/**
* Proximity threshold, which defines the minimum distance which should be
......@@ -99,6 +115,16 @@ protected:
std::string m_savePath; //!< Path where remaining fibers should be stored
/**
* Input connector for a fiber dataset.
*/
boost::shared_ptr< WModuleInputData< WDataSetFibers > > m_fiberInput;
/**
* Pointer to the fiber data set
*/
boost::shared_ptr< WDataSetFibers > m_dataset;
private:
};
......
......@@ -102,8 +102,6 @@ void WMFiberDisplay::moduleMain()
ready();
boost::shared_ptr< const WDataSetFibers > fiberDS;
while ( !m_shutdownFlag() ) // loop until the module container requests the module to quit
{
m_dataset = m_fiberInput->getData();
......@@ -113,15 +111,11 @@ void WMFiberDisplay::moduleMain()
continue;
}
m_osgNode = osg::ref_ptr< osg::Group >( new osg::Group );
m_osgNode->addChild( genFiberGeode( m_dataset, m_globalColoring ).get() );
m_osgNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->addChild( m_osgNode.get() );
update();
m_moduleState.wait(); // waits for firing of m_moduleState ( dataChanged, shutdown, etc. )
// May be called twice
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->removeChild( m_osgNode.get() );
}
}
......@@ -180,7 +174,8 @@ void WMFiberDisplay::slotPropertyChanged( std::string propertyName )
}
else
{
debugLog() << propertyName << std::endl;
// instead of WLogger we must use std::cerr since WLogger needs to much time!
std::cerr << propertyName << std::endl;
assert( 0 && "This property name is not supported by this function yet." );
}
}
......@@ -110,7 +110,7 @@ protected:
/**
* Redraws the scene.
*
* \problem This might take a while with e.g. 70,000 fibers \approx 4 sec
* \problem This might take a while with e.g. 70,000 fibers approx 4 sec
*/
void update();
......
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