00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <iostream>
00026
00027 #include "../kernel/WKernel.h"
00028 #include "WFiberSelector.h"
00029 #include "WROIManager.h"
00030
00031 WFiberSelector::WFiberSelector( boost::shared_ptr< const WDataSetFibers > fibers ) :
00032 m_fibers( fibers ),
00033 m_size( fibers->size() ),
00034 m_dirty( true )
00035 {
00036 boost::shared_ptr< std::vector< float > > verts = m_fibers->getVertices();
00037 m_kdTree = boost::shared_ptr< WKdTree >( new WKdTree( verts->size() / 3, &( ( *verts )[0] ) ) );
00038
00039 m_outputBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) );
00040
00041 std::vector< osg::ref_ptr< WROI > >rois = WKernel::getRunningKernel()->getRoiManager()->getRois();
00042
00043 m_changeRoiSignal
00044 = boost::shared_ptr< boost::function< void() > >( new boost::function< void() >( boost::bind( &WFiberSelector::setDirty, this ) ) );
00045
00046 m_assocRoiSignal =
00047 boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
00048 new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotAddRoi, this, _1 ) ) );
00049 WKernel::getRunningKernel()->getRoiManager()->addAddNotifier( m_assocRoiSignal );
00050
00051 m_removeRoiSignal =
00052 boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
00053 new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotRemoveRoi, this, _1 ) ) );
00054 WKernel::getRunningKernel()->getRoiManager()->addRemoveNotifier( m_removeRoiSignal );
00055
00056 m_removeBranchSignal =
00057 boost::shared_ptr< boost::function< void( boost::shared_ptr< WRMBranch > ) > >(
00058 new boost::function< void( boost::shared_ptr< WRMBranch > ) > (
00059 boost::bind( &WFiberSelector::slotRemoveBranch, this, _1 ) ) );
00060 WKernel::getRunningKernel()->getRoiManager()->addRemoveBranchNotifier( m_removeBranchSignal );
00061
00062 for( size_t i = 0; i < rois.size(); ++i )
00063 {
00064 slotAddRoi( rois[i] );
00065 ( rois[i] )->getProperties()->getProperty( "Dirty" )->toPropBool()->set( true );
00066 }
00067 }
00068
00069 WFiberSelector::~WFiberSelector()
00070 {
00071 WKernel::getRunningKernel()->getRoiManager()->removeAddNotifier( m_assocRoiSignal );
00072 WKernel::getRunningKernel()->getRoiManager()->removeRemoveNotifier( m_removeRoiSignal );
00073 WKernel::getRunningKernel()->getRoiManager()->removeRemoveBranchNotifier( m_removeBranchSignal );
00074
00075
00076 {
00077 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00078 {
00079 std::list< boost::shared_ptr< WSelectorRoi > > rois = ( *iter )->getROIs();
00080 for( std::list< boost::shared_ptr< WSelectorRoi > >::iterator roiIter = rois.begin(); roiIter != rois.end(); ++roiIter )
00081 {
00082 ( *roiIter )->getRoi()->removeROIChangeNotifier( m_changeRoiSignal );
00083 }
00084 }
00085 }
00086 m_branches.clear();
00087 }
00088
00089 void WFiberSelector::slotAddRoi( osg::ref_ptr< WROI > roi )
00090 {
00091 boost::shared_ptr< WSelectorBranch > branch;
00092
00093 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00094 {
00095 if( ( *iter )->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) )
00096 {
00097 branch = ( *iter );
00098 }
00099 }
00100 if( !branch )
00101 {
00102 branch = boost::shared_ptr<WSelectorBranch>(
00103 new WSelectorBranch( m_fibers, WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) ) );
00104 m_branches.push_back( branch );
00105 }
00106
00107 boost::shared_ptr< WSelectorRoi> sroi = boost::shared_ptr< WSelectorRoi>( new WSelectorRoi( roi, m_fibers, m_kdTree ) );
00108
00109 branch->addRoi( sroi );
00110 sroi->getRoi()->addROIChangeNotifier( m_changeRoiSignal );
00111
00112 setDirty();
00113 }
00114
00115 void WFiberSelector::slotRemoveRoi( osg::ref_ptr< WROI > roi )
00116 {
00117 roi->removeROIChangeNotifier( m_changeRoiSignal );
00118 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00119 {
00120 ( *iter )->removeRoi( roi );
00121
00122 if( (*iter )->empty() )
00123 {
00124 m_branches.erase( iter );
00125 break;
00126 }
00127 }
00128 setDirty();
00129 }
00130
00131 void WFiberSelector::slotRemoveBranch( boost::shared_ptr< WRMBranch > branch )
00132 {
00133 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00134 {
00135 if( branch == ( *iter )->getBranch() )
00136 {
00137 m_branches.erase( iter );
00138 break;
00139 }
00140 }
00141 setDirty();
00142 }
00143
00144 boost::shared_ptr< std::vector< bool > > WFiberSelector::getBitfield()
00145 {
00146 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00147 {
00148 m_dirty = std::max( m_dirty, ( *iter )->dirty() );
00149 }
00150
00151 if( m_dirty )
00152 {
00153 recalculate();
00154 }
00155 return m_outputBitfield;
00156 }
00157
00158 void WFiberSelector::recalculate()
00159 {
00160 if( m_branches.empty() )
00161 {
00162 m_workerBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) );
00163 }
00164 else
00165 {
00166 m_workerBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, false ) );
00167
00168 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00169 {
00170 boost::shared_ptr< std::vector< bool > > bf = ( *iter )->getBitField();
00171
00172 for( size_t i = 0; i < m_size; ++i )
00173 {
00174 ( *m_workerBitfield )[i] = ( *m_workerBitfield )[i] | ( *bf )[i];
00175 }
00176 }
00177 }
00178
00179 for( size_t i = 0; i < m_size; ++i )
00180 {
00181 ( *m_outputBitfield )[i] = ( *m_workerBitfield )[i];
00182 }
00183 m_dirty = false;
00184
00185 }
00186
00187 void WFiberSelector::setDirty()
00188 {
00189 recalculate();
00190 m_dirty = true;
00191 }