OpenWalnut  1.4.0
WFiberSelector.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <iostream>
27 #include <list>
28 #include <vector>
29 
30 #include "../kernel/WKernel.h"
31 #include "WFiberSelector.h"
32 #include "WROIManager.h"
33 
34 WFiberSelector::WFiberSelector( boost::shared_ptr< const WDataSetFibers > fibers ) :
35  m_fibers( fibers ),
36  m_size( fibers->size() ),
37  m_dirty( true ),
38  m_dirtyCondition( boost::shared_ptr< WCondition >( new WCondition() ) )
39 {
40  boost::shared_ptr< std::vector< float > > verts = m_fibers->getVertices();
41  m_kdTree = boost::shared_ptr< WKdTree >( new WKdTree( verts->size() / 3, &( ( *verts )[0] ) ) );
42 
43  m_outputBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) );
44  m_outputColorMap = boost::shared_ptr< std::vector< float > >( new std::vector< float >( m_size * 4, 1.0 ) );
45 
46  std::vector< osg::ref_ptr< WROI > >rois = WKernel::getRunningKernel()->getRoiManager()->getRois();
47 
49  = boost::shared_ptr< boost::function< void() > >( new boost::function< void() >( boost::bind( &WFiberSelector::setDirty, this ) ) );
50 
52  boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
53  new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotAddRoi, this, _1 ) ) );
55 
57  boost::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
58  new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotRemoveRoi, this, _1 ) ) );
60 
62  boost::shared_ptr< boost::function< void( boost::shared_ptr< WRMBranch > ) > >(
63  new boost::function< void( boost::shared_ptr< WRMBranch > ) > (
64  boost::bind( &WFiberSelector::slotRemoveBranch, this, _1 ) ) );
65  WKernel::getRunningKernel()->getRoiManager()->addRemoveBranchNotifier( m_removeBranchSignal );
66 
67  for( size_t i = 0; i < rois.size(); ++i )
68  {
69  slotAddRoi( rois[i] );
70  ( rois[i] )->getProperties()->getProperty( "Dirty" )->toPropBool()->set( true );
71  }
72 }
73 
75 {
76  WKernel::getRunningKernel()->getRoiManager()->removeAddNotifier( m_assocRoiSignal );
77  WKernel::getRunningKernel()->getRoiManager()->removeRemoveNotifier( m_removeRoiSignal );
78  WKernel::getRunningKernel()->getRoiManager()->removeRemoveBranchNotifier( m_removeBranchSignal );
79 
80  // We need the following because not all ROIs are removed per slot below
81  {
82  for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
83  {
84  std::list< boost::shared_ptr< WSelectorRoi > > rois = ( *iter )->getROIs();
85  for( std::list< boost::shared_ptr< WSelectorRoi > >::iterator roiIter = rois.begin(); roiIter != rois.end(); ++roiIter )
86  {
87  ( *roiIter )->getRoi()->removeROIChangeNotifier( m_changeRoiSignal );
88  }
89  ( *iter )->getBranch()->removeChangeNotifier( m_changeRoiSignal );
90  }
91  }
92  m_branches.clear();
93 }
94 
95 void WFiberSelector::slotAddRoi( osg::ref_ptr< WROI > roi )
96 {
97  boost::shared_ptr< WSelectorBranch > branch;
98 
99  for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
100  {
101  if( ( *iter )->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) )
102  {
103  branch = ( *iter );
104  }
105  }
106  if( !branch )
107  {
108  branch = boost::shared_ptr<WSelectorBranch>(
109  new WSelectorBranch( m_fibers, WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) ) );
110  branch->getBranch()->addChangeNotifier( m_changeRoiSignal );
111  m_branches.push_back( branch );
112  }
113 
114  boost::shared_ptr< WSelectorRoi> sroi( new WSelectorRoi( roi, m_fibers, m_kdTree ) );
115 
116  branch->addRoi( sroi );
117  sroi->getRoi()->addROIChangeNotifier( m_changeRoiSignal );
118 
119  setDirty();
120 }
121 
122 void WFiberSelector::slotRemoveRoi( osg::ref_ptr< WROI > roi )
123 {
124  roi->removeROIChangeNotifier( m_changeRoiSignal );
125  for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
126  {
127  ( *iter )->removeRoi( roi );
128 
129  if( (*iter )->empty() )
130  {
131  ( *iter )->getBranch()->removeChangeNotifier( m_changeRoiSignal );
132  m_branches.erase( iter );
133  break;
134  }
135  }
136  setDirty();
137 }
138 
139 void WFiberSelector::slotRemoveBranch( boost::shared_ptr< WRMBranch > branch )
140 {
141  for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
142  {
143  if( branch == ( *iter )->getBranch() )
144  {
145  // remove notifier
146  branch->removeChangeNotifier( m_changeRoiSignal );
147  m_branches.erase( iter );
148  break;
149  }
150  }
151  setDirty();
152 }
153 
154 boost::shared_ptr< std::vector< bool > > WFiberSelector::getBitfield()
155 {
156  return m_outputBitfield;
157 }
158 
160 {
161  boost::shared_ptr< std::vector< bool > > m_workerBitfield( new std::vector< bool >( m_size, false ) );
162  std::vector< float > m_workerColorMap( m_size * 4, 1.0 );
163 
164  if( !m_branches.empty() )
165  {
166  for( std::list< boost::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
167  {
168  boost::shared_ptr< std::vector< bool > > bf = ( *iter )->getBitField();
169  WColor color = ( *iter )->getBranchColor();
170 
171  for( size_t i = 0; i < m_size; ++i )
172  {
173  ( *m_workerBitfield )[i] = ( *m_workerBitfield )[i] | ( *bf )[i];
174 
175  if( ( *bf )[i] )
176  {
177  // set colors, overwrite previously set colors
178  m_workerColorMap[ 4 * i + 0 ] = color.r();
179  m_workerColorMap[ 4 * i + 1 ] = color.g();
180  m_workerColorMap[ 4 * i + 2 ] = color.b();
181  m_workerColorMap[ 4 * i + 3 ] = color.a();
182  }
183  }
184  }
185  }
186 
187  for( size_t i = 0; i < m_size; ++i )
188  {
189  ( *m_outputBitfield )[i] = ( *m_workerBitfield )[i];
190  ( *m_outputColorMap )[ 4 * i + 0 ] = m_workerColorMap[ 4 * i + 0 ];
191  ( *m_outputColorMap )[ 4 * i + 1 ] = m_workerColorMap[ 4 * i + 1 ];
192  ( *m_outputColorMap )[ 4 * i + 2 ] = m_workerColorMap[ 4 * i + 2 ];
193  ( *m_outputColorMap )[ 4 * i + 3 ] = m_workerColorMap[ 4 * i + 3 ];
194  }
195  m_dirty = false;
196 }
197 
199 {
200  m_dirty = true;
201  m_dirtyCondition->notify();
202  recalculate();
203 }
204 
206 {
207  return m_dirty;
208 }
209 
211 {
212  return m_dirtyCondition;
213 }
214 
215 WColor WFiberSelector::getFiberColor( size_t fidx ) const
216 {
217  if( fidx >= m_outputBitfield->size() )
218  {
219  return WColor( 1.0, 1.0, 1.0, 1.0 );
220  }
221 
222  return WColor( ( *m_outputColorMap )[ 4 * fidx + 0 ],
223  ( *m_outputColorMap )[ 4 * fidx + 1 ],
224  ( *m_outputColorMap )[ 4 * fidx + 2 ],
225  ( *m_outputColorMap )[ 4 * fidx + 3 ] );
226 }
227 
229 {
230  return m_branches.empty();
231 }
boost::shared_ptr< boost::function< void(boost::shared_ptr< WRMBranch >) > > m_removeBranchSignal
Signal for updating the selector.
void setDirty()
setter sets the dirty flag
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
Definition: WKernel.cpp:117
implements the computation of a kd tree on a point array
Definition: WKdTree.h:105
boost::shared_ptr< std::vector< bool > > getBitfield()
getter
boost::shared_ptr< std::vector< bool > > m_outputBitfield
bit field of activated fibers
TODO(schurade): Document this!
size_t m_size
number of fibers in the dataset
boost::shared_ptr< WKdTree > m_kdTree
Stores a pointer to the kdTree used for fiber selection.
void recalculate()
update the bitfield when there was a change in the roi structure
bool m_dirty
dirty flag
bool getDirty()
Get the current dirty-state.
void slotRemoveBranch(boost::shared_ptr< WRMBranch > branch)
listener function for removing rois
WCondition::SPtr m_dirtyCondition
Condition that fires on setDirty.
boost::shared_ptr< boost::function< void(osg::ref_ptr< WROI >) > > m_assocRoiSignal
Signal that can be used to update the selector.
WCondition::SPtr getDirtyCondition()
Condition that fires upon a recalculation of the fiber selection.
boost::shared_ptr< WROIManager > getRoiManager()
get for roi manager
Definition: WKernel.cpp:209
boost::shared_ptr< boost::function< void(osg::ref_ptr< WROI >) > > m_removeRoiSignal
Signal that can be used to update the selector.
~WFiberSelector()
destructor
void slotAddRoi(osg::ref_ptr< WROI > roi)
listener function for inserting rois
boost::shared_ptr< const WDataSetFibers > m_fibers
Pointer to the fiber data set.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:39
WFiberSelector(boost::shared_ptr< const WDataSetFibers > fibers)
constructor
boost::shared_ptr< std::vector< float > > m_outputColorMap
Map each fiber to a color.
void slotRemoveRoi(osg::ref_ptr< WROI > roi)
listener function for removing rois
std::list< boost::shared_ptr< WSelectorBranch > > m_branches
list of branches int he roi structure
bool isNothingFiltered() const
Returns true if no fiber gets filtered out because there is no branch in the ROI tree.
class implements the updating of a bitfield for a roi
Definition: WSelectorRoi.h:39
boost::shared_ptr< WCondition > SPtr
Shared pointer type for WCondition.
Definition: WCondition.h:46
boost::shared_ptr< boost::function< void() > > m_changeRoiSignal
Signal that can be used to update the selector.
WColor getFiberColor(size_t fidx) const
Get color for fiber with given index.