Commit 080bd7be authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[MERGE]

parents 1d7cc055 ba8bd4f0
## This is a sample configuration file for OpenWalnut.
## Uncomment the options you are interested in.
[general]
allowOnlyOneFiberDataSet = yes # This will prevent you from accidently loading multiple fiber data sets.
[modules]
## use this to specify the default module to add during load.
## It is a comma seperated list. If this is not specified the
......
......@@ -70,8 +70,7 @@
WMainWindow::WMainWindow() :
QMainWindow(),
m_currentCompatiblesToolbar( NULL ),
m_iconManager(),
m_fibLoaded( false )
m_iconManager()
{
}
......@@ -712,33 +711,7 @@ void WMainWindow::openLoadDialog()
stdFileNames.push_back( ( *constIterator ).toLocal8Bit().constData() );
}
//
// WE KNOW THAT THIS IS KIND OF A HACK. It is only provided to prevent naive users from having trouble.
//
bool allowOnlyOneFiberDataSet = false;
bool doubleFibersFound = false; // have we detected the multiple loading of fibers?
if( WPreferences::getPreference( "general.allowOnlyOneFiberDataSet", &allowOnlyOneFiberDataSet ) && allowOnlyOneFiberDataSet )
{
for( std::vector< std::string >::iterator it = stdFileNames.begin(); it != stdFileNames.end(); ++it )
{
using wiotools::getSuffix;
std::string suffix = getSuffix( *it );
bool isFib = ( suffix == ".fib" );
if( m_fibLoaded && isFib )
{
QCoreApplication::postEvent( this, new WModuleCrashEvent(
WModuleFactory::getModuleFactory()->getPrototypeByName( "Data Module" ),
std::string( "Tried to load two fiber data sets. This is not allowed by your preferences." ) ) );
doubleFibersFound = true;
}
m_fibLoaded |= isFib;
}
}
if( !doubleFibersFound )
{
m_loaderSignal( stdFileNames );
}
m_loaderSignal( stdFileNames );
// walkaround that a button keeps his down state after invoking a dialog
m_loadButton->setDown( false );
......@@ -991,11 +964,6 @@ void WMainWindow::newRoi()
}
}
void WMainWindow::setFibersLoaded( bool flag )
{
m_fibLoaded = flag;
}
void WMainWindow::openConfigDialog()
{
if( m_configWidget.get() )
......
......@@ -280,12 +280,6 @@ public slots:
*/
void projectSaveModuleOnly();
/**
* Sets that a fiber data set has already been loaded. Thi shelps to prevent multiple fiber data sets to be loaded.
* \param flag Indicates how to set the internal state.
*/
void setFibersLoaded( bool flag );
/**
* Gets called when menu option or toolbar button load is activated
*/
......@@ -323,12 +317,6 @@ private:
*/
boost::shared_ptr< WQtConfigWidget > m_configWidget;
/**
* Used to ensure that only one fiber dataset can be loaded since the
* ROIManager is not known to work with more than one fiber dataset
*/
bool m_fibLoaded; // TODO(all): remove this when its possible to display more than one fiber dataset
/**
* All registered WQtCustomDockWidgets.
*/
......
......@@ -206,40 +206,7 @@ int WQt4Gui::run()
// check if we want to load data due to command line and call the respective function
if( m_optionsMap.count("input") )
{
//
// WE KNOW THAT THIS IS KIND OF A HACK. Iis is only provided to prevent naive users from having trouble.
//
bool allowOnlyOneFiberDataSet = false;
bool doubleFibersFound = false; // have we detected the multiple loading of fibers?
if( WPreferences::getPreference( "general.allowOnlyOneFiberDataSet", &allowOnlyOneFiberDataSet ) && allowOnlyOneFiberDataSet )
{
bool fibFound = false;
std::vector< std::string > tmpFiles = m_optionsMap["input"].as< std::vector< std::string > >();
for( std::vector< std::string >::iterator it = tmpFiles.begin(); it != tmpFiles.end(); ++it )
{
std::string suffix = wiotools::getSuffix( *it );
bool isFib = ( suffix == ".fib" );
if( fibFound && isFib )
{
QCoreApplication::postEvent( m_mainWindow, new WModuleCrashEvent(
WModuleFactory::getModuleFactory()->getPrototypeByName( "Data Module" ),
std::string( "Tried to load two fiber data sets. This is not allowed by your preferences." ) ) );
doubleFibersFound = true;
}
fibFound |= isFib;
}
if( fibFound && !doubleFibersFound )
{
// Found exactly one fiber data set. So signal this to main window.
// If more than one are found we do not load them anyways. Thus we can allow to load a new one.
m_mainWindow->setFibersLoaded( true );
}
}
if( !doubleFibersFound )
{
m_kernel->loadDataSets( m_optionsMap["input"].as< std::vector< std::string > >() );
}
m_kernel->loadDataSets( m_optionsMap["input"].as< std::vector< std::string > >() );
}
// Load project file
......@@ -314,11 +281,6 @@ void WQt4Gui::slotRemoveDatasetOrModuleInTree( boost::shared_ptr< WModule > modu
{
boost::shared_ptr< WMData > dataModule = boost::shared_dynamic_cast< WMData >( module );
WAssert( dataModule, "Internal failure." );
std::string suffix = wiotools::getSuffix( dataModule->getFilename().file_string() );
if( suffix == ".fib" )
{
m_mainWindow->setFibersLoaded( false );
}
}
QCoreApplication::postEvent( m_mainWindow->getControlPanel(), new WModuleRemovedEvent( module ) );
}
......
......@@ -262,7 +262,6 @@ void WQtConfigWidget::registerComponents()
m_defaultProperties->addProperty( "qt4gui.useAutoDisplay", "use Auto Display", true, m_propCondition );
m_defaultProperties->addProperty( "qt4gui.useToolBarBreak", "use ToolBarBreak", true, m_propCondition );
m_defaultProperties->addProperty( "general.allowOnlyOneFiberDataSet", "allow only one FiberDataSet", false, m_propCondition );
WPropInt tbs = m_defaultProperties->addProperty( "qt4gui.toolBarStyle", "The style of all toolbars in OpenWalnut", 0, m_propCondition );
WPropInt ctbs = m_defaultProperties->addProperty( "qt4gui.compatiblesToolBarStyle", "The style of all compatibles toolbar in OpenWalnut", 0,
m_propCondition );
......
FILE( GLOB_RECURSE MODULES_SRC "*.cpp" "*.h" )
# Grab module name and setup target directories
GET_FILENAME_COMPONENT( MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME )
SET( MODULE_TARGET_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/modules/${MODULE_NAME} )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MODULE_TARGET_DIR} )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MODULE_TARGET_DIR} )
SET( MODULE_DIRNAME ${MODULE_NAME} )
SET( MODULE_NAME "OWmodule_${MODULE_NAME}" ) # prefix all module names with "OWmodule_" to separate them from other libs
# Build module lib
ADD_LIBRARY( ${MODULE_NAME} SHARED ${MODULES_SRC} )
TARGET_LINK_LIBRARIES( ${MODULE_NAME} OWkernel ${Teem_LIBRARIES} )
# Copy local shaders to module target directory
IF( OW_COPY_SHADERS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/shaders ) # copy shaders only if the user wants it
ADD_CUSTOM_TARGET( ${MODULE_NAME}_CopyShaders
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/shaders ${MODULE_TARGET_DIR}/shaders/
COMMENT "Copy shaders of ${MODULE_NAME}"
)
ADD_DEPENDENCIES( ${MODULE_NAME} ${MODULE_NAME}_CopyShaders )
ENDIF()
# Build unit tests
IF( OW_COMPILE_TESTS )
# This ensures that the test is copied to the module directory
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MODULE_TARGET_DIR} )
CXXTEST_ADD_TESTS_FROM_LIST( "${MODULES_SRC}"
"OWkernel;${MODULE_NAME}"
)
# Copy fixtures if they exist
IF( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/fixtures )
ADD_CUSTOM_TARGET( ${MODULE_NAME}_CopyFixtures
# as the "test" target runs in CMakes temporary build dir, the fixtures need to be placed there too.
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/test/fixtures ${CMAKE_BINARY_DIR}/modules/${MODULE_DIRNAME}/fixtures/
COMMENT "Copy fixtures of ${MODULE_NAME}"
)
ADD_DEPENDENCIES( ${MODULE_NAME} ${MODULE_NAME}_CopyFixtures )
ENDIF( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/fixtures )
ENDIF( OW_COMPILE_TESTS )
//---------------------------------------------------------------------------
//
// 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 "../../dataHandler/WDataHandler.h"
#include "../../dataHandler/WDataSetFibers.h"
#include "../../dataHandler/WSubject.h"
#include "../../dataHandler/exceptions/WDHNoSuchSubject.h"
#include "../../graphicsEngine/WGEUtils.h"
#include "../../kernel/WKernel.h"
#include "WMSliceContext.h"
#include "WTransparentLinesDrawable.h"
#include "slicecontext.xpm"
// This line is needed by the module loader to actually find your module.
W_LOADABLE_MODULE( WMSliceContext )
WMSliceContext::WMSliceContext():
WModule()
{
}
WMSliceContext::~WMSliceContext()
{
// Cleanup!
}
boost::shared_ptr< WModule > WMSliceContext::factory() const
{
// See "src/modules/template/" for an extensively documented example.
return boost::shared_ptr< WModule >( new WMSliceContext() );
}
const char** WMSliceContext::getXPMIcon() const
{
return slicecontext_xpm;
}
const std::string WMSliceContext::getName() const
{
// Specify your module name here. This name must be UNIQUE!
return "Slice Context";
}
const std::string WMSliceContext::getDescription() const
{
return "Show the spatial context of the slices.";
}
void WMSliceContext::connectors()
{
// The input fiber dataset
m_fiberInput = boost::shared_ptr< WModuleInputData < const WDataSetFibers > >(
new WModuleInputData< const WDataSetFibers >( shared_from_this(), "fibers", "The fiber dataset to use as context." )
);
// As properties, every connector needs to be added to the list of connectors.
addConnector( m_fiberInput );
// call WModules initialization
WModule::connectors();
}
void WMSliceContext::properties()
{
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
wmath::WPosition ch = WKernel::getRunningKernel()->getSelectionManager()->getCrosshair()->getPosition();
m_crosshairProp = m_infoProperties->addProperty( "Slice Position", "Position where the three navigation slices intersect.", ch, m_propCondition );
m_insideCountProp =
m_properties
->addProperty( "Inside count",
"The number of positions of a fiber that have to be inside the context for the fiber to be considered.",
1,
m_propCondition );
m_contextWidthProp = m_properties->addProperty( "Context width",
"The width of the area around the slice that is considere as context.",
1.0,
m_propCondition );
}
void WMSliceContext::moduleMain()
{
m_moduleState.setResetable( true, true );
m_moduleState.add( m_fiberInput->getDataChangedCondition() );
m_moduleState.add( m_propCondition );
ready();
m_rootNode = new osg::Group();
m_shaderFibers = osg::ref_ptr< WShader > ( new WShader( "WMSliceContext", m_localPath ) );
// main loop
while ( !m_shutdownFlag() )
{
debugLog() << "Waiting ...";
m_moduleState.wait();
// woke up since the module is requested to finish?
if ( m_shutdownFlag() )
{
break;
}
// To query whether an input was updated, simply ask the input:
bool dataUpdated = m_fiberInput->updated();
boost::shared_ptr< const WDataSetFibers > fibers( m_fiberInput->getData() );
bool dataValid = fibers;
if ( !( dataValid && dataUpdated ) )
{
continue;
}
// findFirstFiberDataSet();
m_tracts = fibers;
WAssert( m_tracts, "No fiber data set found." );
boost::shared_ptr< WProgress > progress = boost::shared_ptr< WProgress >( new WProgress( "Slice Context", 1 ) );
m_progress->addSubProgress( progress );
m_rootNode->addUpdateCallback( new WMSliceContext::SliceContextUpdateCallback( this ) );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_rootNode );
progress->finish();
}
// Since the modules run in a separate thread: wait
waitForStop();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_rootNode );
}
void WMSliceContext::SliceContextUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
{
m_module->update();
traverse( node, nv );
}
osg::ref_ptr< WGEManagedGroupNode > WMSliceContext::paintTracts( const std::vector< size_t >& selectedTracts ) const
{
osg::ref_ptr< WGEManagedGroupNode > result = osg::ref_ptr< WGEManagedGroupNode >( new WGEManagedGroupNode( m_active ) );
result->insert( genTractGeode( selectedTracts ).get() );
return result;
}
osg::ref_ptr< osg::Geode > WMSliceContext::genTractGeode( const std::vector< size_t >& selectedTracts ) const
{
using osg::ref_ptr;
ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
ref_ptr< WTransparentLinesDrawable > geometry = ref_ptr< WTransparentLinesDrawable >( new WTransparentLinesDrawable );
geometry->setDataVariance( osg::Object::DYNAMIC );
boost::shared_ptr< std::vector < size_t > > lineLengths = m_tracts->getLineLengths();
size_t insideCountLocal = m_insideCountProp->get();
// for( size_t fiberId = 0; fiberId < selectedTracts.size(); ++fiberId )
// {
// if( selectedTracts[fiberId] >= insideCountLocal )
// {
// size_t fiberLength = ( *lineLengths )[fiberId];
// for( size_t posId = 0; posId < fiberLength; ++posId )
// {
// wmath::WPosition pos;
// vertices->push_back( m_tracts->getPosition( fiberId, posId ) );
// }
// geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, vertices->size() - fiberLength, fiberLength ) );
// }
// }
for( size_t fiberId = 0; fiberId < selectedTracts.size(); ++fiberId )
{
if( selectedTracts[fiberId] >= insideCountLocal )
{
size_t fiberLength = ( *lineLengths )[fiberId];
for( size_t posId = 0; posId < fiberLength - 1 ; ++posId )
{
wmath::WPosition pos;
vertices->push_back( m_tracts->getPosition( fiberId, posId ) );
vertices->push_back( m_tracts->getPosition( fiberId, posId + 1 ) );
}
}
}
geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, 0, vertices->size() ) );
geometry->setUseDisplayList( false );
geometry->setUseVertexBufferObjects( false );
geometry->setVertexArray( vertices );
ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
colors->push_back( wge::osgColor( WColor( 1.0, 0.0, 1.0 ) ) );
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
geode->addDrawable( geometry.get() );
osg::Vec3Array* texCoords = new osg::Vec3Array;
texCoords->clear();
for( size_t i = 0; i < vertices->size(); ++i )
{
double distance = fabs( m_crosshairProp->get()[0] - ( *vertices )[i][0] );
texCoords->push_back( wmath::WPosition( distance, m_contextWidthProp->get(), 0.0 ) );
}
geometry->setTexCoordArray( 0, texCoords );
osg::StateSet* state = geode->getOrCreateStateSet();
state->setMode( GL_BLEND, osg::StateAttribute::ON );
m_shaderFibers->apply( geode );
geode->setDataVariance( osg::Object::DYNAMIC );
return geode;
}
void WMSliceContext::checkContainment( std::vector< size_t >* selected, bool counting, double distance ) const
{
boost::shared_ptr< std::vector < size_t > > lineLengths = m_tracts->getLineLengths();
for( size_t fiberId = 0; fiberId < lineLengths->size(); ++fiberId )
{
for( size_t posId = 0; posId < ( *lineLengths )[fiberId]; ++posId )
{
wmath::WPosition pos = m_tracts->getPosition( fiberId, posId );
if( fabs( m_crosshairProp->get()[0] - pos[0] ) < distance )
{
++( ( *selected )[fiberId] );
if( !counting )
{
break;
}
}
}
}
}
void WMSliceContext::update()
{
m_crosshairProp->set( WKernel::getRunningKernel()->getSelectionManager()->getCrosshair()->getPosition() );
// TODO(wiebel): change to complete set of slices
if( m_current[0] == m_crosshairProp->get()[0] && !m_insideCountProp->changed() && !m_contextWidthProp->changed() )
{
// nothing changed --> nothing to do
return;
}
std::vector< size_t > selected( m_tracts->size(), 0 );
const bool counting = ( m_insideCountProp->get( true ) > 1 );
checkContainment( &selected, counting, m_contextWidthProp->get( true ) );
m_rootNode->removeChild( m_osgNode );
m_osgNode = paintTracts( selected );
m_rootNode->addChild( m_osgNode );
m_current = WKernel::getRunningKernel()->getSelectionManager()->getCrosshair()->getPosition();
}
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------
#ifndef WMSLICECONTEXT_H
#define WMSLICECONTEXT_H
#include <string>
#include <vector>
#include <osg/Geode>
#include "../../graphicsEngine/WGEManagedGroupNode.h"
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleInputData.h"
#include "../../kernel/WModuleOutputData.h"
/**
* Someone should add some documentation here.
* Probably the best person would be the module's
* creator, i.e. "wiebel".
*
* This is only an empty template for a new module. For
* an example module containing many interesting concepts
* and extensive documentation have a look at "src/modules/template"
*
* \ingroup modules
*/
class WMSliceContext: public WModule
{
public:
/**
*
*/
WMSliceContext();
/**
*
*/
virtual ~WMSliceContext();
/**
* Gives back the name of this module.
* \return the module's name.
*/
virtual const std::string getName() const;
/**
* Gives back a description of this module.
* \return description to module.
*/
virtual const std::string getDescription() const;
/**
* 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;
/**
* Get the icon for this module in XPM format.
*/
virtual const char** getXPMIcon() const;
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();
private:
/**
* Updates the visualization produced by this module.
*/
virtual void update();
/**
* Generates an osg geode for the given tract selection with the given color
*
* \param selectedTracts This vector specifies which tracts should be used to generate the node.
* \return geode containing the graphical representation of the tracts
*/
osg::ref_ptr< osg::Geode > genTractGeode( const std::vector< size_t >& selectedTracts ) const;
/**
* Choose colors and build new OSG node for chosen tracts.
*