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 }