1 #ifndef __FPA__BASE__ALGORITHM__HXX__
2 #define __FPA__BASE__ALGORITHM__HXX__
8 // -------------------------------------------------------------------------
9 template< class T, class B >
10 void fpa::Base::Algorithm< T, B >::
11 InvokeEvent( const itk::EventObject& e )
13 if( this->m_ThrowEvents )
14 this->Superclass::InvokeEvent( e );
17 // -------------------------------------------------------------------------
18 template< class T, class B >
19 void fpa::Base::Algorithm< T, B >::
20 InvokeEvent( const itk::EventObject& e ) const
22 if( this->m_ThrowEvents )
23 this->Superclass::InvokeEvent( e );
26 // -------------------------------------------------------------------------
27 template< class T, class B >
28 void fpa::Base::Algorithm< T, B >::
29 AddSeed( const TVertex& s, const TResult& v )
31 this->m_Seeds.push_back( _TNode( s, v, this->m_Seeds.size( ) ) );
35 // -------------------------------------------------------------------------
36 template< class T, class B >
37 const typename fpa::Base::Algorithm< T, B >::
38 TVertex& fpa::Base::Algorithm< T, B >::
39 GetSeed( const unsigned long& i ) const
41 return( this->m_Seeds[ i ].Vertex );
44 // -------------------------------------------------------------------------
45 template< class T, class B >
46 void fpa::Base::Algorithm< T, B >::
49 this->m_Seeds.clear( );
53 // -------------------------------------------------------------------------
54 template< class T, class B >
55 unsigned long fpa::Base::Algorithm< T, B >::
56 GetNumberOfSeeds( ) const
58 return( this->m_Seeds.size( ) );
61 // -------------------------------------------------------------------------
62 template< class T, class B >
63 fpa::Base::Algorithm< T, B >::
66 m_StopAtOneFront( false ),
67 m_ThrowEvents( false )
71 // -------------------------------------------------------------------------
72 template< class T, class B >
73 fpa::Base::Algorithm< T, B >::
78 // -------------------------------------------------------------------------
79 template< class T, class B >
80 void fpa::Base::Algorithm< T, B >::
83 this->AllocateOutputs( );
85 unsigned long N = this->m_Seeds.size( );
88 this->m_CollisionSites.clear( );
89 this->m_CollisionSites.
90 resize( N, _TCollisionSitesRow( N, _TCollision( TVertex( ), false ) ) );
96 // -------------------------------------------------------------------------
97 template< class T, class B >
98 void fpa::Base::Algorithm< T, B >::
103 // -------------------------------------------------------------------------
104 template< class T, class B >
105 void fpa::Base::Algorithm< T, B >::
110 // -------------------------------------------------------------------------
111 template< class T, class B >
112 void fpa::Base::Algorithm< T, B >::
115 this->_InitializeMarks( );
116 this->_InitializeResults( );
117 this->_InitializeQueue( );
118 while( !( this->_IsQueueEmpty( ) ) )
120 _TNode n = this->_QueuePop( );
121 if( this->_IsMarked( n.Vertex ) )
125 this->InvokeEvent( TMarkEvent( n ) );
126 if( this->_UpdateResult( n ) )
128 if( !( this->_CheckStopCondition( ) ) )
131 this->_Neighs( n, N );
132 typename _TNodes::iterator nnIt = N.begin( );
133 while( nnIt != N.end( ) )
135 if( this->_IsMarked( nnIt->Vertex ) )
137 // Update real front identifier
138 nnIt->FrontId = this->_FrontId( nnIt->Vertex );
141 if( this->_CheckCollisions( n, *nnIt ) )
143 if( this->m_StopAtOneFront )
145 this->_QueueClear( );
154 if( this->_UpdateNeigh( *nnIt, n ) )
156 nnIt->Parent = n.Vertex;
157 this->_QueuePush( *nnIt );
158 this->InvokeEvent( TFrontEvent( *nnIt ) );
163 if( nnIt != N.end( ) )
169 this->_QueueClear( );
174 this->InvokeEvent( TEndEvent( ) );
177 // -------------------------------------------------------------------------
178 template< class T, class B >
179 bool fpa::Base::Algorithm< T, B >::
180 _CheckCollisions( const _TNode& a, const _TNode& b )
183 if( a.FrontId != b.FrontId )
185 // Mark collision, if it is new
186 bool exists = this->m_CollisionSites[ a.FrontId ][ b.FrontId ].second;
187 exists &= this->m_CollisionSites[ b.FrontId ][ a.FrontId ].second;
190 this->m_CollisionSites[ a.FrontId ][ b.FrontId ].first = a.Vertex;
191 this->m_CollisionSites[ a.FrontId ][ b.FrontId ].second = true;
192 this->m_CollisionSites[ b.FrontId ][ a.FrontId ].first = b.Vertex;
193 this->m_CollisionSites[ b.FrontId ][ a.FrontId ].second = true;
195 // Stop if one front is desired
196 if( this->m_StopAtOneFront )
198 // Perform a depth-first iteration on front graph
199 unsigned long N = this->GetNumberOfSeeds( );
201 std::vector< bool > m( N, false );
202 std::queue< unsigned long > q;
206 unsigned long f = q.front( );
214 for( unsigned int n = 0; n < N; ++n )
215 if( this->m_CollisionSites[ f ][ n ].second && !m[ n ] )
229 // -------------------------------------------------------------------------
230 template< class T, class B >
231 bool fpa::Base::Algorithm< T, B >::
232 _CheckStopCondition( )
237 // -------------------------------------------------------------------------
238 template< class T, class B >
239 bool fpa::Base::Algorithm< T, B >::
240 _UpdateResult( _TNode& n )
245 // -------------------------------------------------------------------------
246 template< class T, class B >
247 void fpa::Base::Algorithm< T, B >::
250 this->m_Marks.clear( );
253 // -------------------------------------------------------------------------
254 template< class T, class B >
255 bool fpa::Base::Algorithm< T, B >::
256 _IsMarked( const TVertex& v ) const
258 return( this->m_Marks.find( v ) != this->m_Marks.end( ) );
261 // -------------------------------------------------------------------------
262 template< class T, class B >
263 typename fpa::Base::Algorithm< T, B >::
264 _TFrontId fpa::Base::Algorithm< T, B >::
265 _FrontId( const TVertex& v ) const
267 typename _TMarks::const_iterator mIt = this->m_Marks.find( v );
268 if( mIt != this->m_Marks.end( ) )
269 return( mIt->second.FrontId );
271 return( std::numeric_limits< _TFrontId >::max( ) );
274 // -------------------------------------------------------------------------
275 template< class T, class B >
276 typename fpa::Base::Algorithm< T, B >::
277 TVertex fpa::Base::Algorithm< T, B >::
278 _Parent( const TVertex& v ) const
280 typename _TMarks::const_iterator mIt = this->m_Marks.find( v );
281 if( mIt == this->m_Marks.end( ) )
287 return( mIt->second.Parent );
290 // -------------------------------------------------------------------------
291 template< class T, class B >
292 void fpa::Base::Algorithm< T, B >::
293 _Mark( const _TNode& n )
295 this->m_Marks[ n.Vertex ] = n;
298 #endif // __FPA__BASE__ALGORITHM__HXX__