OpenWalnut 1.3.1
WFiberSelector.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <algorithm>
00026 #include <iostream>
00027 #include <list>
00028 #include <vector>
00029 
00030 #include "../kernel/WKernel.h"
00031 #include "WFiberSelector.h"
00032 #include "WROIManager.h"
00033 
00034 WFiberSelector::WFiberSelector( boost::shared_ptr< const WDataSetFibers > fibers ) :
00035     m_fibers( fibers ),
00036     m_size( fibers->size() ),
00037     m_dirty( true )
00038 {
00039     boost::shared_ptr< std::vector< float > > verts = m_fibers->getVertices();
00040     m_kdTree = boost::shared_ptr< WKdTree >( new WKdTree( verts->size() / 3, &( ( *verts )[0] ) ) );
00041 
00042     m_outputBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) );
00043 
00044     std::vector< osg::ref_ptr< WROI > >rois = WKernel::getRunningKernel()->getRoiManager()->getRois();
00045 
00046     m_changeRoiSignal
00047         = boost::shared_ptr< boost::function< void() > >( new boost::function< void() >( boost::bind( &WFiberSelector::setDirty, this ) ) );
00048 
00049     m_assocRoiSignal =
00050         boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
00051             new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotAddRoi, this, _1 ) ) );
00052     WKernel::getRunningKernel()->getRoiManager()->addAddNotifier( m_assocRoiSignal );
00053 
00054     m_removeRoiSignal =
00055              boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
00056                  new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotRemoveRoi, this, _1 ) ) );
00057     WKernel::getRunningKernel()->getRoiManager()->addRemoveNotifier( m_removeRoiSignal );
00058 
00059     m_removeBranchSignal =
00060              boost::shared_ptr< boost::function< void( boost::shared_ptr< WRMBranch >  ) > >(
00061                  new boost::function< void( boost::shared_ptr< WRMBranch > ) > (
00062                      boost::bind( &WFiberSelector::slotRemoveBranch, this, _1 ) ) );
00063     WKernel::getRunningKernel()->getRoiManager()->addRemoveBranchNotifier( m_removeBranchSignal );
00064 
00065     for( size_t i = 0; i < rois.size(); ++i )
00066     {
00067         slotAddRoi( rois[i] );
00068         ( rois[i] )->getProperties()->getProperty( "Dirty" )->toPropBool()->set( true );
00069     }
00070 }
00071 
00072 WFiberSelector::~WFiberSelector()
00073 {
00074     WKernel::getRunningKernel()->getRoiManager()->removeAddNotifier( m_assocRoiSignal );
00075     WKernel::getRunningKernel()->getRoiManager()->removeRemoveNotifier( m_removeRoiSignal );
00076     WKernel::getRunningKernel()->getRoiManager()->removeRemoveBranchNotifier( m_removeBranchSignal );
00077 
00078     // We need the following because not all ROIs are removed per slot below
00079     {
00080         for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00081         {
00082             std::list< boost::shared_ptr< WSelectorRoi > > rois = ( *iter )->getROIs();
00083             for( std::list< boost::shared_ptr< WSelectorRoi > >::iterator roiIter = rois.begin(); roiIter != rois.end(); ++roiIter )
00084             {
00085                 ( *roiIter )->getRoi()->removeROIChangeNotifier( m_changeRoiSignal );
00086             }
00087         }
00088     }
00089     m_branches.clear();
00090 }
00091 
00092 void WFiberSelector::slotAddRoi( osg::ref_ptr< WROI > roi )
00093 {
00094     boost::shared_ptr< WSelectorBranch > branch;
00095 
00096     for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00097     {
00098         if( ( *iter )->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) )
00099         {
00100             branch = ( *iter );
00101         }
00102     }
00103     if( !branch )
00104     {
00105         branch = boost::shared_ptr<WSelectorBranch>(
00106                 new WSelectorBranch( m_fibers, WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) ) );
00107         m_branches.push_back( branch );
00108     }
00109 
00110     boost::shared_ptr< WSelectorRoi> sroi = boost::shared_ptr< WSelectorRoi>( new WSelectorRoi( roi, m_fibers, m_kdTree ) );
00111 
00112     branch->addRoi( sroi );
00113     sroi->getRoi()->addROIChangeNotifier( m_changeRoiSignal );
00114 
00115     setDirty();
00116 }
00117 
00118 void WFiberSelector::slotRemoveRoi( osg::ref_ptr< WROI > roi )
00119 {
00120     roi->removeROIChangeNotifier( m_changeRoiSignal );
00121     for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00122     {
00123         ( *iter )->removeRoi( roi );
00124 
00125         if( (*iter )->empty() )
00126         {
00127             m_branches.erase( iter );
00128             break;
00129         }
00130     }
00131     setDirty();
00132 }
00133 
00134 void WFiberSelector::slotRemoveBranch( boost::shared_ptr< WRMBranch > branch )
00135 {
00136     for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00137     {
00138         if( branch == ( *iter )->getBranch() )
00139         {
00140             m_branches.erase( iter );
00141             break;
00142         }
00143     }
00144     setDirty();
00145 }
00146 
00147 boost::shared_ptr< std::vector< bool > > WFiberSelector::getBitfield()
00148 {
00149     for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00150     {
00151         m_dirty = std::max( m_dirty, ( *iter )->dirty() );
00152     }
00153 
00154     if( m_dirty )
00155     {
00156         recalculate();
00157     }
00158     return m_outputBitfield;
00159 }
00160 
00161 void WFiberSelector::recalculate()
00162 {
00163     if( m_branches.empty() )
00164     {
00165         m_workerBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) );
00166     }
00167     else
00168     {
00169         m_workerBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, false ) );
00170 
00171         for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
00172         {
00173             boost::shared_ptr< std::vector< bool > > bf = ( *iter )->getBitField();
00174 
00175             for( size_t i = 0; i < m_size; ++i )
00176             {
00177                 ( *m_workerBitfield )[i] = ( *m_workerBitfield )[i] | ( *bf )[i];
00178             }
00179         }
00180     }
00181 
00182     for( size_t i = 0; i < m_size; ++i )
00183     {
00184       ( *m_outputBitfield )[i] = ( *m_workerBitfield )[i];
00185     }
00186     m_dirty = false;
00187     //m_outputBitfield = m_workerBitfield;
00188 }
00189 
00190 void WFiberSelector::setDirty()
00191 {
00192     recalculate();
00193     m_dirty = true;
00194 }