Commit e3c0e9fe authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] - adopted voxelizer to new dataset types

- added property for parameterization algorithm selection
- modules now use std::vector for connector management -> adding-order used for compatibility test
parent 63c4f789
......@@ -42,16 +42,39 @@ boost::shared_ptr< WPrototyped > WFiberCluster::m_prototype = boost::shared_ptr<
// \endcond
WFiberCluster::WFiberCluster()
: WTransferable()
: WTransferable(),
m_centerLineCreationLock( new boost::shared_mutex() ),
m_longestLineCreationLock( new boost::shared_mutex() )
{
}
WFiberCluster::WFiberCluster( size_t index )
: WTransferable()
: WTransferable(),
m_centerLineCreationLock( new boost::shared_mutex() ),
m_longestLineCreationLock( new boost::shared_mutex() )
{
m_memberIndices.push_back( index );
}
WFiberCluster::WFiberCluster( const WFiberCluster& other )
: WTransferable( other ),
m_memberIndices( other.m_memberIndices ),
m_fibs( other.m_fibs ),
m_color( other.m_color ),
m_centerLineCreationLock( new boost::shared_mutex() ), // do not copy the mutex as both instances of WFiberCluster can be modifed at the
// same time
m_longestLineCreationLock( new boost::shared_mutex() ),
m_centerLine( boost::shared_ptr< wmath::WFiber >( new wmath::WFiber( *other.m_centerLine.get() ) ) ),
m_longestLine( boost::shared_ptr< wmath::WFiber >( new wmath::WFiber( *other.m_longestLine.get() ) ) )
{
}
WFiberCluster::~WFiberCluster()
{
delete m_centerLineCreationLock;
delete m_longestLineCreationLock;
}
void WFiberCluster::merge( WFiberCluster& other ) // NOLINT
{
std::list< size_t >::const_iterator cit = other.m_memberIndices.begin();
......@@ -89,8 +112,17 @@ boost::shared_ptr< WPrototyped > WFiberCluster::getPrototype()
}
// \endcond
void WFiberCluster::generateCenterLine()
void WFiberCluster::generateCenterLine() const
{
// ensure nobody changes the mutable m_centerline
boost::unique_lock< boost::shared_mutex > lock = boost::unique_lock< boost::shared_mutex >( *m_centerLineCreationLock );
// has the line been calculated while we waited?
if ( m_centerLine )
{
lock.unlock();
return;
}
// make copies of the fibers
boost::shared_ptr< WDataSetFiberVector > fibs( new WDataSetFiberVector() );
size_t avgFiberSize = 0;
......@@ -120,6 +152,46 @@ void WFiberCluster::generateCenterLine()
avgPosition /= fibs->size();
m_centerLine->push_back( avgPosition );
}
lock.unlock();
}
void WFiberCluster::generateLongestLine() const
{
// ensure nobody changes the mutable m_longestline
boost::unique_lock< boost::shared_mutex > lock = boost::unique_lock< boost::shared_mutex >( *m_longestLineCreationLock );
// has the line been calculated while we waited?
if ( m_longestLine )
{
lock.unlock();
return;
}
m_longestLine = boost::shared_ptr< wmath::WFiber >( new wmath::WFiber() );
// empty datasets can be ignored
if ( m_fibs->size() == 0 )
{
return;
}
size_t longest = 0;
size_t longestID = 0;
for( size_t cit = 0; cit < m_fibs->size(); ++cit )
{
if ( m_fibs->at( cit ).size() > longest )
{
longest = m_fibs->at( cit ).size();
longestID = cit;
}
}
for ( wmath::WFiber::const_iterator cit = m_fibs->at( longestID ).begin(); cit != m_fibs->at( longestID ).end(); ++cit )
{
m_longestLine->push_back( *cit );
}
lock.unlock();
}
void WFiberCluster::unifyDirection( boost::shared_ptr< WDataSetFiberVector > fibs ) const
......@@ -160,5 +232,19 @@ void WFiberCluster::unifyDirection( boost::shared_ptr< WDataSetFiberVector > fib
boost::shared_ptr< wmath::WFiber > WFiberCluster::getCenterLine() const
{
if ( !m_centerLine )
{
generateCenterLine();
}
return m_centerLine;
}
boost::shared_ptr< wmath::WFiber > WFiberCluster::getLongestLine() const
{
if ( !m_longestLine )
{
generateLongestLine();
}
return m_longestLine;
}
......@@ -30,6 +30,7 @@
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include "../../common/WColor.h"
#include "../../common/WTransferable.h"
......@@ -50,11 +51,23 @@ public:
*/
explicit WFiberCluster( size_t index );
/**
* Copies the specified \ref WFiberCluster Instance. The copy does not contain a valid centerline or longest line.
*
* \param other the other instance to clone.
*/
WFiberCluster( const WFiberCluster& other );
/**
* Constructs an empty cluster.
*/
WFiberCluster();
/**
* Destructs. Frees used locks/mutex.
*/
virtual ~WFiberCluster();
/**
* Returns true if there are no fibers in that cluster, false otherwise.
*/
......@@ -152,16 +165,28 @@ public:
// \endcond
/**
* Returns the center line of this cluster
* Returns the center line of this cluster. The centerline gets calculated during the first call of this method.
*
* \return Reference to the center line
*/
boost::shared_ptr< wmath::WFiber > getCenterLine() const;
/**
* Returns the center line of this cluster. The longest line gets calculated during the first call if this method.
*
* \return Reference to the longest line
*/
boost::shared_ptr< wmath::WFiber > getLongestLine() const;
/**
* Makes the hard work to compute the center line.
*/
void generateCenterLine();
void generateCenterLine() const;
/**
* Makes the hard work to find the longest line.
*/
void generateLongestLine() const;
protected:
// TODO(math): The only reason why we store here a Reference to the fiber
......@@ -200,7 +225,29 @@ private:
*/
WColor m_color;
boost::shared_ptr< wmath::WFiber > m_centerLine; //!< Average fiber for this cluster representing the main direction and curvatur of this cluster
/**
* Lock the modification in the m_centerLine mutable. The lock is stored as pointer to avoid copy construction problems.
*/
boost::shared_mutex* m_centerLineCreationLock;
/**
* Lock the modification in the m_longestLine mutable. The lock is stored as pointer to avoid copy construction problems.
*/
boost::shared_mutex* m_longestLineCreationLock;
/**
* Average fiber for this cluster representing the main direction and curvature of this cluster.
*
* \note This member is mutable as it needs to be modified during a const getter.
*/
mutable boost::shared_ptr< wmath::WFiber > m_centerLine;
/**
* The longest fiber in the dataset.
*
* \note This member is mutable as it needs to be modified during a const getter.
*/
mutable boost::shared_ptr< wmath::WFiber > m_longestLine;
};
inline bool WFiberCluster::empty() const
......
......@@ -93,18 +93,18 @@ void WQtTreeItem::updateTooltip( std::string progress )
// also list the connectors
std::string conList = "";
std::set< boost::shared_ptr< WModuleInputConnector > > cons = m_module->getInputConnectors();
std::set< boost::shared_ptr< WModuleOutputConnector > > consOut = m_module->getOutputConnectors();
WModule::InputConnectorList cons = m_module->getInputConnectors();
WModule::OutputConnectorList consOut = m_module->getOutputConnectors();
conList += "<table><tr><th>Name</th><th>Description</th><th>Connected</th></tr>";
int conCount = 0;
for ( std::set< boost::shared_ptr< WModuleInputConnector > >::const_iterator it = cons.begin(); it != cons.end(); ++it )
for ( WModule::InputConnectorList::const_iterator it = cons.begin(); it != cons.end(); ++it )
{
++conCount;
conList += "<tr><td><b>" + ( *it )->getName() + "&nbsp;</b></td><td>&nbsp;" + ( *it )->getDescription() + "&nbsp;</td>";
conList += ( *it )->isConnected() ? "<td>&nbsp;yes&nbsp;</td>" : "<td>&nbsp;no&nbsp;</td>";
conList += "</tr>";
}
for ( std::set< boost::shared_ptr< WModuleOutputConnector > >::const_iterator it = consOut.begin(); it != consOut.end(); ++it )
for ( WModule::OutputConnectorList::const_iterator it = consOut.begin(); it != consOut.end(); ++it )
{
++conCount;
conList += "<tr><td><b>" + ( *it )->getName() + "&nbsp;</b></td><td>&nbsp;" + ( *it )->getDescription() + "&nbsp;</td>";
......
......@@ -26,6 +26,7 @@
#include <sys/prctl.h>
#endif
#include <algorithm>
#include <set>
#include <string>
#include <sstream>
......@@ -95,23 +96,29 @@ WModule::~WModule()
void WModule::addConnector( boost::shared_ptr< WModuleInputConnector > con )
{
m_inputConnectors.insert( con );
if ( std::count( m_inputConnectors.begin(), m_inputConnectors.end(), con ) == 0 )
{
m_inputConnectors.push_back( con );
}
}
void WModule::addConnector( boost::shared_ptr< WModuleOutputConnector > con )
{
m_outputConnectors.insert( con );
if ( std::count( m_outputConnectors.begin(), m_outputConnectors.end(), con ) == 0 )
{
m_outputConnectors.push_back( con );
}
}
void WModule::disconnect()
{
// remove connections and their signals
for( std::set<boost::shared_ptr< WModuleInputConnector > >::iterator listIter = m_inputConnectors.begin();
for( InputConnectorList::iterator listIter = m_inputConnectors.begin();
listIter != m_inputConnectors.end(); ++listIter )
{
( *listIter )->disconnectAll();
}
for( std::set<boost::shared_ptr< WModuleOutputConnector > >::iterator listIter = m_outputConnectors.begin();
for( OutputConnectorList::iterator listIter = m_outputConnectors.begin();
listIter != m_outputConnectors.end(); ++listIter )
{
( *listIter )->disconnectAll();
......@@ -184,12 +191,12 @@ MODULE_TYPE WModule::getType() const
return MODULE_ARBITRARY;
}
const std::set<boost::shared_ptr< WModuleInputConnector > >& WModule::getInputConnectors() const
const WModule::InputConnectorList& WModule::getInputConnectors() const
{
return m_inputConnectors;
}
const std::set<boost::shared_ptr< WModuleOutputConnector > >& WModule::getOutputConnectors() const
const WModule::OutputConnectorList& WModule::getOutputConnectors() const
{
return m_outputConnectors;
}
......@@ -197,7 +204,7 @@ const std::set<boost::shared_ptr< WModuleOutputConnector > >& WModule::getOutput
boost::shared_ptr< WModuleInputConnector > WModule::getInputConnector( std::string name )
{
// simply search
for( std::set<boost::shared_ptr< WModuleInputConnector > >::const_iterator listIter = m_inputConnectors.begin();
for( InputConnectorList::const_iterator listIter = m_inputConnectors.begin();
listIter != m_inputConnectors.end(); ++listIter )
{
// try the canonical name
......@@ -213,7 +220,7 @@ boost::shared_ptr< WModuleInputConnector > WModule::getInputConnector( std::stri
boost::shared_ptr< WModuleOutputConnector > WModule::getOutputConnector( std::string name )
{
// simply search
for( std::set<boost::shared_ptr< WModuleOutputConnector > >::const_iterator listIter = m_outputConnectors.begin();
for( OutputConnectorList::const_iterator listIter = m_outputConnectors.begin();
listIter != m_outputConnectors.end(); ++listIter )
{
// try the canonical name
......
......@@ -82,12 +82,22 @@ public:
*/
virtual ~WModule();
/**
* The type for the list of input connectors.
*/
typedef std::vector< boost::shared_ptr< WModuleInputConnector > > InputConnectorList;
/**
* The type for the list of output connectors.
*/
typedef std::vector< boost::shared_ptr< WModuleOutputConnector > > OutputConnectorList;
/**
* Gives back input connectors.
*
* \return the input connectors.
*/
const std::set< boost::shared_ptr< WModuleInputConnector > >& getInputConnectors() const;
const InputConnectorList& getInputConnectors() const;
/**
* Finds the named connector for the module.
......@@ -104,7 +114,7 @@ public:
*
* \return the output connectors.
*/
const std::set< boost::shared_ptr< WModuleOutputConnector > >& getOutputConnectors() const;
const OutputConnectorList& getOutputConnectors() const;
/**
* Finds the named connector for the module.
......@@ -470,14 +480,13 @@ protected:
/**
* Set of input connectors associated with this module.
* NOTE: we need a thread safe list implementation!
*/
std::set<boost::shared_ptr< WModuleInputConnector > > m_inputConnectors;
InputConnectorList m_inputConnectors;
/**
* Set of output connectors associated with this module.
*/
std::set<boost::shared_ptr< WModuleOutputConnector > > m_outputConnectors;
OutputConnectorList m_outputConnectors;
/**
* True whenever the module should be active
......
......@@ -367,9 +367,9 @@ boost::shared_ptr< WModule > WModuleContainer::applyModule( boost::shared_ptr< W
// crashed module has set some data on its output and some other module needs it. -> so we ignore the case of crashed modules here.
// get offered outputs
std::set<boost::shared_ptr<WModuleInputConnector> > ins = m->getInputConnectors();
WModule::InputConnectorList ins = m->getInputConnectors();
// get offered inputs
std::set<boost::shared_ptr<WModuleOutputConnector> > outs = applyOn->getOutputConnectors();
WModule::OutputConnectorList outs = applyOn->getOutputConnectors();
// TODO(ebaum): search best matching instead of simply connecting both
if ( !ins.empty() && !outs.empty() )
......
......@@ -259,7 +259,7 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
++listIter )
{
// get connectors of this prototype
std::set<boost::shared_ptr<WModuleInputConnector> > pcons = ( *listIter )->getInputConnectors();
WModule::InputConnectorList pcons = ( *listIter )->getInputConnectors();
if( pcons.size() == 0 )
{
// NOTE: it is OK here to use the variable module even if it is NULL as the combiner in this case only adds the specified module
......@@ -274,7 +274,7 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
}
// get offered outputs
std::set<boost::shared_ptr<WModuleOutputConnector> > cons = module->getOutputConnectors();
WModule::OutputConnectorList cons = module->getOutputConnectors();
// return early if we have no output connector, because the modules with no input connector
// are already added at this point.
......@@ -296,7 +296,7 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
++listIter )
{
// get connectors of this prototype
std::set<boost::shared_ptr<WModuleInputConnector> > pcons = ( *listIter )->getInputConnectors();
WModule::InputConnectorList pcons = ( *listIter )->getInputConnectors();
// ensure we have 1 connector
if( pcons.size() == 0 )
......
......@@ -403,8 +403,8 @@ void WModuleProjectFileCombiner::save( std::ostream& output ) // NOLINT
for ( WModuleContainer::ModuleConstIterator iter = container->get().begin(); iter != container->get().end(); ++iter )
{
// iterate over all outputs
const std::set< boost::shared_ptr< WModuleOutputConnector > >& outs = ( *iter )->getOutputConnectors();
for ( std::set< boost::shared_ptr< WModuleOutputConnector > >::const_iterator citer = outs.begin(); citer != outs.end(); ++citer )
const WModule::OutputConnectorList& outs = ( *iter )->getOutputConnectors();
for ( WModule::OutputConnectorList::const_iterator citer = outs.begin(); citer != outs.end(); ++citer )
{
// iterate over all connections:
// TODO(ebaum): iterating over a protected member variable? Thats ugly. This should be adopted to WSharedAccess
......
......@@ -44,10 +44,10 @@ WCenterlineParameterization::~WCenterlineParameterization()
// cleanup
}
boost::shared_ptr< WDataSetSingle > WCenterlineParameterization::getDataSet()
boost::shared_ptr< WDataSetScalar > WCenterlineParameterization::getDataSet()
{
boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 0, 1, m_paramFinalValues, W_DT_DOUBLE ) );
return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( valueSet, m_grid ) );
return boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( valueSet, m_grid ) );
}
namespace
......
......@@ -70,7 +70,7 @@ public:
*
* \return the dataset.
*/
virtual boost::shared_ptr< WDataSetSingle > getDataSet();
virtual boost::shared_ptr< WDataSetScalar > getDataSet();
/**
* Gets called for each new line getting rasterized. Here, it is used to reset the internal length integrator
......
//---------------------------------------------------------------------------
//
// 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 "WDirectionParameterization.h"
WDirectionParameterization::WDirectionParameterization( boost::shared_ptr< WGridRegular3D > grid ):
WRasterParameterization( grid ),
m_dirValues( 3 * grid->size(), 0.0 )
{
// initialize members
}
WDirectionParameterization::~WDirectionParameterization()
{
// cleanup
}
boost::shared_ptr< WDataSetSingle > WDirectionParameterization::getDataSet()
{
boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, m_dirValues, W_DT_DOUBLE ) );
return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( valueSet, m_grid ) );
}
void WDirectionParameterization::parameterizeVoxel( const wmath::WValue< int >& /*voxel*/, size_t voxelId, const int /*axis*/,
const double /*value*/,
const wmath::WPosition& start,
const wmath::WPosition& end )
{
// segment end and start point define its direction
wmath::WPosition vec = end - start;
m_dirValues[ ( 3 * voxelId ) ] = vec[0];
m_dirValues[ ( 3 * voxelId ) + 1 ] = vec[1];
m_dirValues[ ( 3 * voxelId ) + 2 ] = vec[2];
}
//---------------------------------------------------------------------------
//
// 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 WDIRECTIONPARAMETERIZATION_H
#define WDIRECTIONPARAMETERIZATION_H
#include <vector>
#include "WRasterParameterization.h"
/**
* Stores the direction if a line in a separate dataset for each voxel.
*/
class WDirectionParameterization: public WRasterParameterization
{
public:
/**
* Default constructor.
*
* \param grid the grid used for the new dataset.
*/
explicit WDirectionParameterization( boost::shared_ptr< WGridRegular3D > grid );
/**
* Destructor.
*/
virtual ~WDirectionParameterization();
/**
* This method allows this parameterization to update. It gets called for every voxel which is rasterized by the WRasterAlgorithm.
*
* \param voxel the voxel to parameterize
* \param voxelIdx the voxel index in the common grid calculated using "voxel" (this is for convenience)
* \param axis Along which axis the traversal takes place. Since when walking in e.g. X-direction there are not supporting voxels in the
* \param value the new voxel value
* \param start Start point of the line segement (used to computed the distance)
* \param end End point of the line segement (used to computed the distance)
*/
virtual void parameterizeVoxel( const wmath::WValue< int >& voxel, size_t voxelIdx, const int axis, const double value,
const wmath::WPosition& start,
const wmath::WPosition& end );
/**
* Gets the dataset representing the parameterization.
*
* \return the dataset.
*/
virtual boost::shared_ptr< WDataSetSingle > getDataSet();
protected:
/**
* Stores the direction of the fiber at each voxel.
*/
std::vector< double > m_dirValues;
private:
};
#endif // WDIRECTIONPARAMETERIZATION_H
......@@ -37,10 +37,10 @@ WIntegrationParameterization::~WIntegrationParameterization()
// cleanup
}
boost::shared_ptr< WDataSetSingle > WIntegrationParameterization::getDataSet()
boost::shared_ptr< WDataSetScalar > WIntegrationParameterization::getDataSet()
{
boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 0, 1, m_lengthValues, W_DT_DOUBLE ) );
return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( valueSet, m_grid ) );
return boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( valueSet, m_grid ) );
}