OpenWalnut
1.4.0
|
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 m_dirtyCondition( boost::shared_ptr< WCondition >( new WCondition() ) ) 00039 { 00040 boost::shared_ptr< std::vector< float > > verts = m_fibers->getVertices(); 00041 m_kdTree = boost::shared_ptr< WKdTree >( new WKdTree( verts->size() / 3, &( ( *verts )[0] ) ) ); 00042 00043 m_outputBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) ); 00044 m_outputColorMap = boost::shared_ptr< std::vector< float > >( new std::vector< float >( m_size * 4, 1.0 ) ); 00045 00046 std::vector< osg::ref_ptr< WROI > >rois = WKernel::getRunningKernel()->getRoiManager()->getRois(); 00047 00048 m_changeRoiSignal 00049 = boost::shared_ptr< boost::function< void() > >( new boost::function< void() >( boost::bind( &WFiberSelector::setDirty, this ) ) ); 00050 00051 m_assocRoiSignal = 00052 boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >( 00053 new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotAddRoi, this, _1 ) ) ); 00054 WKernel::getRunningKernel()->getRoiManager()->addAddNotifier( m_assocRoiSignal ); 00055 00056 m_removeRoiSignal = 00057 boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >( 00058 new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotRemoveRoi, this, _1 ) ) ); 00059 WKernel::getRunningKernel()->getRoiManager()->addRemoveNotifier( m_removeRoiSignal ); 00060 00061 m_removeBranchSignal = 00062 boost::shared_ptr< boost::function< void( boost::shared_ptr< WRMBranch > ) > >( 00063 new boost::function< void( boost::shared_ptr< WRMBranch > ) > ( 00064 boost::bind( &WFiberSelector::slotRemoveBranch, this, _1 ) ) ); 00065 WKernel::getRunningKernel()->getRoiManager()->addRemoveBranchNotifier( m_removeBranchSignal ); 00066 00067 for( size_t i = 0; i < rois.size(); ++i ) 00068 { 00069 slotAddRoi( rois[i] ); 00070 ( rois[i] )->getProperties()->getProperty( "Dirty" )->toPropBool()->set( true ); 00071 } 00072 } 00073 00074 WFiberSelector::~WFiberSelector() 00075 { 00076 WKernel::getRunningKernel()->getRoiManager()->removeAddNotifier( m_assocRoiSignal ); 00077 WKernel::getRunningKernel()->getRoiManager()->removeRemoveNotifier( m_removeRoiSignal ); 00078 WKernel::getRunningKernel()->getRoiManager()->removeRemoveBranchNotifier( m_removeBranchSignal ); 00079 00080 // We need the following because not all ROIs are removed per slot below 00081 { 00082 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter ) 00083 { 00084 std::list< boost::shared_ptr< WSelectorRoi > > rois = ( *iter )->getROIs(); 00085 for( std::list< boost::shared_ptr< WSelectorRoi > >::iterator roiIter = rois.begin(); roiIter != rois.end(); ++roiIter ) 00086 { 00087 ( *roiIter )->getRoi()->removeROIChangeNotifier( m_changeRoiSignal ); 00088 } 00089 ( *iter )->getBranch()->removeChangeNotifier( m_changeRoiSignal ); 00090 } 00091 } 00092 m_branches.clear(); 00093 } 00094 00095 void WFiberSelector::slotAddRoi( osg::ref_ptr< WROI > roi ) 00096 { 00097 boost::shared_ptr< WSelectorBranch > branch; 00098 00099 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter ) 00100 { 00101 if( ( *iter )->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) ) 00102 { 00103 branch = ( *iter ); 00104 } 00105 } 00106 if( !branch ) 00107 { 00108 branch = boost::shared_ptr<WSelectorBranch>( 00109 new WSelectorBranch( m_fibers, WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) ) ); 00110 branch->getBranch()->addChangeNotifier( m_changeRoiSignal ); 00111 m_branches.push_back( branch ); 00112 } 00113 00114 boost::shared_ptr< WSelectorRoi> sroi( new WSelectorRoi( roi, m_fibers, m_kdTree ) ); 00115 00116 branch->addRoi( sroi ); 00117 sroi->getRoi()->addROIChangeNotifier( m_changeRoiSignal ); 00118 00119 setDirty(); 00120 } 00121 00122 void WFiberSelector::slotRemoveRoi( osg::ref_ptr< WROI > roi ) 00123 { 00124 roi->removeROIChangeNotifier( m_changeRoiSignal ); 00125 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter ) 00126 { 00127 ( *iter )->removeRoi( roi ); 00128 00129 if( (*iter )->empty() ) 00130 { 00131 ( *iter )->getBranch()->removeChangeNotifier( m_changeRoiSignal ); 00132 m_branches.erase( iter ); 00133 break; 00134 } 00135 } 00136 setDirty(); 00137 } 00138 00139 void WFiberSelector::slotRemoveBranch( boost::shared_ptr< WRMBranch > branch ) 00140 { 00141 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter ) 00142 { 00143 if( branch == ( *iter )->getBranch() ) 00144 { 00145 // remove notifier 00146 branch->removeChangeNotifier( m_changeRoiSignal ); 00147 m_branches.erase( iter ); 00148 break; 00149 } 00150 } 00151 setDirty(); 00152 } 00153 00154 boost::shared_ptr< std::vector< bool > > WFiberSelector::getBitfield() 00155 { 00156 return m_outputBitfield; 00157 } 00158 00159 void WFiberSelector::recalculate() 00160 { 00161 boost::shared_ptr< std::vector< bool > > m_workerBitfield( new std::vector< bool >( m_size, false ) ); 00162 std::vector< float > m_workerColorMap( m_size * 4, 1.0 ); 00163 00164 if( !m_branches.empty() ) 00165 { 00166 for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter ) 00167 { 00168 boost::shared_ptr< std::vector< bool > > bf = ( *iter )->getBitField(); 00169 WColor color = ( *iter )->getBranchColor(); 00170 00171 for( size_t i = 0; i < m_size; ++i ) 00172 { 00173 ( *m_workerBitfield )[i] = ( *m_workerBitfield )[i] | ( *bf )[i]; 00174 00175 if( ( *bf )[i] ) 00176 { 00177 // set colors, overwrite previously set colors 00178 m_workerColorMap[ 4 * i + 0 ] = color.r(); 00179 m_workerColorMap[ 4 * i + 1 ] = color.g(); 00180 m_workerColorMap[ 4 * i + 2 ] = color.b(); 00181 m_workerColorMap[ 4 * i + 3 ] = color.a(); 00182 } 00183 } 00184 } 00185 } 00186 00187 for( size_t i = 0; i < m_size; ++i ) 00188 { 00189 ( *m_outputBitfield )[i] = ( *m_workerBitfield )[i]; 00190 ( *m_outputColorMap )[ 4 * i + 0 ] = m_workerColorMap[ 4 * i + 0 ]; 00191 ( *m_outputColorMap )[ 4 * i + 1 ] = m_workerColorMap[ 4 * i + 1 ]; 00192 ( *m_outputColorMap )[ 4 * i + 2 ] = m_workerColorMap[ 4 * i + 2 ]; 00193 ( *m_outputColorMap )[ 4 * i + 3 ] = m_workerColorMap[ 4 * i + 3 ]; 00194 } 00195 m_dirty = false; 00196 } 00197 00198 void WFiberSelector::setDirty() 00199 { 00200 m_dirty = true; 00201 m_dirtyCondition->notify(); 00202 recalculate(); 00203 } 00204 00205 bool WFiberSelector::getDirty() 00206 { 00207 return m_dirty; 00208 } 00209 00210 WCondition::SPtr WFiberSelector::getDirtyCondition() 00211 { 00212 return m_dirtyCondition; 00213 } 00214 00215 WColor WFiberSelector::getFiberColor( size_t fidx ) const 00216 { 00217 if( fidx >= m_outputBitfield->size() ) 00218 { 00219 return WColor( 1.0, 1.0, 1.0, 1.0 ); 00220 } 00221 00222 return WColor( ( *m_outputColorMap )[ 4 * fidx + 0 ], 00223 ( *m_outputColorMap )[ 4 * fidx + 1 ], 00224 ( *m_outputColorMap )[ 4 * fidx + 2 ], 00225 ( *m_outputColorMap )[ 4 * fidx + 3 ] ); 00226 } 00227 00228 bool WFiberSelector::isNothingFiltered() const 00229 { 00230 return m_branches.empty(); 00231 }