OpenWalnut  1.5.0dev
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 <memory>
29 #include <vector>
30 
31 #include "../kernel/WKernel.h"
32 #include "WFiberSelector.h"
33 #include "WROIManager.h"
34 
35 WFiberSelector::WFiberSelector( std::shared_ptr< const WDataSetFibers > fibers ) :
36  m_fibers( fibers ),
37  m_size( fibers->size() ),
38  m_dirty( true ),
39  m_dirtyCondition( std::shared_ptr< WCondition >( new WCondition() ) )
40 {
41  std::shared_ptr< std::vector< float > > verts = m_fibers->getVertices();
42  m_kdTree = std::shared_ptr< WKdTree >( new WKdTree( verts->size() / 3, &( ( *verts )[0] ) ) );
43 
44  m_outputBitfield = std::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, true ) );
45  m_outputColorMap = std::shared_ptr< std::vector< float > >( new std::vector< float >( m_size * 4, 1.0 ) );
46 
47  std::vector< osg::ref_ptr< WROI > >rois = WKernel::getRunningKernel()->getRoiManager()->getRois();
48 
50  = std::shared_ptr< boost::function< void() > >( new boost::function< void() >( boost::bind( &WFiberSelector::setDirty, this ) ) );
51 
53  std::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
54  new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotAddRoi, this, boost::placeholders::_1 ) ) );
56 
58  std::shared_ptr< boost::function< void( osg::ref_ptr< WROI > ) > >(
59  new boost::function< void( osg::ref_ptr< WROI > ) > ( boost::bind( &WFiberSelector::slotRemoveRoi,
60  this,
61  boost::placeholders::_1 ) ) );
63 
65  std::shared_ptr< boost::function< void( std::shared_ptr< WRMBranch > ) > >(
66  new boost::function< void( std::shared_ptr< WRMBranch > ) > (
67  boost::bind( &WFiberSelector::slotRemoveBranch, this, boost::placeholders::_1 ) ) );
68  WKernel::getRunningKernel()->getRoiManager()->addRemoveBranchNotifier( m_removeBranchSignal );
69 
70  for( size_t i = 0; i < rois.size(); ++i )
71  {
72  slotAddRoi( rois[i] );
73  ( rois[i] )->getProperties()->getProperty( "Dirty" )->toPropBool()->set( true );
74  }
75 }
76 
78 {
79  WKernel::getRunningKernel()->getRoiManager()->removeAddNotifier( m_assocRoiSignal );
80  WKernel::getRunningKernel()->getRoiManager()->removeRemoveNotifier( m_removeRoiSignal );
81  WKernel::getRunningKernel()->getRoiManager()->removeRemoveBranchNotifier( m_removeBranchSignal );
82 
83  // We need the following because not all ROIs are removed per slot below
84  {
85  for( std::list< std::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
86  {
87  std::list< std::shared_ptr< WSelectorRoi > > rois = ( *iter )->getROIs();
88  for( std::list< std::shared_ptr< WSelectorRoi > >::iterator roiIter = rois.begin(); roiIter != rois.end(); ++roiIter )
89  {
90  ( *roiIter )->getRoi()->removeROIChangeNotifier( m_changeRoiSignal );
91  }
92  ( *iter )->getBranch()->removeChangeNotifier( m_changeRoiSignal );
93  }
94  }
95  m_branches.clear();
96 }
97 
98 void WFiberSelector::slotAddRoi( osg::ref_ptr< WROI > roi )
99 {
100  std::shared_ptr< WSelectorBranch > branch;
101 
102  for( std::list< std::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
103  {
104  if( ( *iter )->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) )
105  {
106  branch = ( *iter );
107  }
108  }
109  if( !branch )
110  {
111  branch = std::shared_ptr<WSelectorBranch>(
112  new WSelectorBranch( m_fibers, WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) ) );
113  branch->getBranch()->addChangeNotifier( m_changeRoiSignal );
114  m_branches.push_back( branch );
115  }
116 
117  std::shared_ptr< WSelectorRoi> sroi( new WSelectorRoi( roi, m_fibers, m_kdTree ) );
118 
119  branch->addRoi( sroi );
120  sroi->getRoi()->addROIChangeNotifier( m_changeRoiSignal );
121 
122  setDirty();
123 }
124 
125 void WFiberSelector::slotRemoveRoi( osg::ref_ptr< WROI > roi )
126 {
127  roi->removeROIChangeNotifier( m_changeRoiSignal );
128  for( std::list< std::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
129  {
130  ( *iter )->removeRoi( roi );
131 
132  if( ( *iter )->empty() )
133  {
134  ( *iter )->getBranch()->removeChangeNotifier( m_changeRoiSignal );
135  m_branches.erase( iter );
136  break;
137  }
138  }
139  setDirty();
140 }
141 
142 void WFiberSelector::slotRemoveBranch( std::shared_ptr< WRMBranch > branch )
143 {
144  for( std::list< std::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
145  {
146  if( branch == ( *iter )->getBranch() )
147  {
148  // remove notifier
149  branch->removeChangeNotifier( m_changeRoiSignal );
150  m_branches.erase( iter );
151  break;
152  }
153  }
154  setDirty();
155 }
156 
157 std::shared_ptr< std::vector< bool > > WFiberSelector::getBitfield()
158 {
159  return m_outputBitfield;
160 }
161 
163 {
164  std::shared_ptr< std::vector< bool > > m_workerBitfield( new std::vector< bool >( m_size, false ) );
165  std::vector< float > m_workerColorMap( m_size * 4, 1.0 );
166 
167  if( !m_branches.empty() )
168  {
169  for( std::list< std::shared_ptr< WSelectorBranch > >::iterator iter = m_branches.begin(); iter != m_branches.end(); ++iter )
170  {
171  std::shared_ptr< std::vector< bool > > bf = ( *iter )->getBitField();
172  WColor color = ( *iter )->getBranchColor();
173 
174  for( size_t i = 0; i < m_size; ++i )
175  {
176  ( *m_workerBitfield )[i] = ( *m_workerBitfield )[i] | ( *bf )[i];
177 
178  if( ( *bf )[i] )
179  {
180  // set colors, overwrite previously set colors
181  m_workerColorMap[ 4 * i + 0 ] = color.r();
182  m_workerColorMap[ 4 * i + 1 ] = color.g();
183  m_workerColorMap[ 4 * i + 2 ] = color.b();
184  m_workerColorMap[ 4 * i + 3 ] = color.a();
185  }
186  }
187  }
188  }
189 
190  for( size_t i = 0; i < m_size; ++i )
191  {
192  ( *m_outputBitfield )[i] = ( *m_workerBitfield )[i];
193  ( *m_outputColorMap )[ 4 * i + 0 ] = m_workerColorMap[ 4 * i + 0 ];
194  ( *m_outputColorMap )[ 4 * i + 1 ] = m_workerColorMap[ 4 * i + 1 ];
195  ( *m_outputColorMap )[ 4 * i + 2 ] = m_workerColorMap[ 4 * i + 2 ];
196  ( *m_outputColorMap )[ 4 * i + 3 ] = m_workerColorMap[ 4 * i + 3 ];
197  }
198  m_dirty = false;
199 }
200 
202 {
203  m_dirty = true;
204  m_dirtyCondition->notify();
205  recalculate();
206 }
207 
209 {
210  return m_dirty;
211 }
212 
214 {
215  return m_dirtyCondition;
216 }
217 
218 WColor WFiberSelector::getFiberColor( size_t fidx ) const
219 {
220  if( fidx >= m_outputBitfield->size() )
221  {
222  return WColor( 1.0, 1.0, 1.0, 1.0 );
223  }
224 
225  return WColor( ( *m_outputColorMap )[ 4 * fidx + 0 ],
226  ( *m_outputColorMap )[ 4 * fidx + 1 ],
227  ( *m_outputColorMap )[ 4 * fidx + 2 ],
228  ( *m_outputColorMap )[ 4 * fidx + 3 ] );
229 }
230 
232 {
233  return m_branches.empty();
234 }
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
std::shared_ptr< WCondition > SPtr
Shared pointer type for WCondition.
Definition: WCondition.h:48
std::shared_ptr< boost::function< void(osg::ref_ptr< WROI >) > > m_assocRoiSignal
Signal that can be used to update the selector.
std::shared_ptr< std::vector< bool > > m_outputBitfield
bit field of activated fibers
WColor getFiberColor(size_t fidx) const
Get color for fiber with given index.
bool m_dirty
dirty flag
void slotRemoveBranch(std::shared_ptr< WRMBranch > branch)
listener function for removing rois
std::shared_ptr< boost::function< void() > > m_changeRoiSignal
Signal that can be used to update the selector.
std::list< std::shared_ptr< WSelectorBranch > > m_branches
list of branches int he roi structure
void slotAddRoi(osg::ref_ptr< WROI > roi)
listener function for inserting rois
WFiberSelector(std::shared_ptr< const WDataSetFibers > fibers)
constructor
void setDirty()
setter sets the dirty flag
std::shared_ptr< std::vector< bool > > getBitfield()
getter
WCondition::SPtr getDirtyCondition()
Condition that fires upon a recalculation of the fiber selection.
size_t m_size
number of fibers in the dataset
void recalculate()
update the bitfield when there was a change in the roi structure
std::shared_ptr< const WDataSetFibers > m_fibers
Pointer to the fiber data set.
std::shared_ptr< boost::function< void(std::shared_ptr< WRMBranch >) > > m_removeBranchSignal
Signal for updating the selector.
std::shared_ptr< WKdTree > m_kdTree
Stores a pointer to the kdTree used for fiber selection.
bool getDirty()
Get the current dirty-state.
WCondition::SPtr m_dirtyCondition
Condition that fires on setDirty.
~WFiberSelector()
destructor
std::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::shared_ptr< boost::function< void(osg::ref_ptr< WROI >) > > m_removeRoiSignal
Signal that can be used to update the selector.
bool isNothingFiltered() const
Returns true if no fiber gets filtered out because there is no branch in the ROI tree.
implements the computation of a kd tree on a point array
Definition: WKdTree.h:106
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
Definition: WKernel.cpp:117
std::shared_ptr< WROIManager > getRoiManager()
get for roi manager
Definition: WKernel.cpp:209
TODO(schurade): Document this!
class implements the updating of a bitfield for a roi
Definition: WSelectorRoi.h:40