1 #ifndef __FPA__BASE__ALGORITHM__HXX__
2 #define __FPA__BASE__ALGORITHM__HXX__
6 // -------------------------------------------------------------------------
7 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
8 const _TVertexCompare fpa::Base::
9 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
10 TNode::VertexCompare = _TVertexCompare( );
12 // -------------------------------------------------------------------------
13 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
15 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
16 InvokeEvent( const itk::EventObject& e )
18 if( this->m_ThrowEvents )
19 this->Superclass::InvokeEvent( e );
22 // -------------------------------------------------------------------------
23 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
25 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
26 InvokeEvent( const itk::EventObject& e ) const
28 if( this->m_ThrowEvents )
29 this->Superclass::InvokeEvent( e );
32 // -------------------------------------------------------------------------
33 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
34 unsigned long fpa::Base::
35 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
36 GetNumberOfSeeds( ) const
38 return( this->m_Seeds.size( ) );
41 // -------------------------------------------------------------------------
42 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
44 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
45 AddSeed( const TVertex& s, const TScalar& v )
51 n.Label = Self::FrontLabel;
55 // -------------------------------------------------------------------------
56 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
58 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
59 AddSeed( const TNode& n )
61 this->m_Seeds.insert( n );
65 // -------------------------------------------------------------------------
66 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
68 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
69 RemoveSeed( const TVertex& s )
73 typename TNodes::iterator i = this->m_Seeds.find( n );
74 if( i != this->m_Seeds.end( ) )
76 this->m_Seeds.erase( i );
82 // -------------------------------------------------------------------------
83 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
85 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
88 this->m_Seeds.clear( );
92 // -------------------------------------------------------------------------
93 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
95 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
98 m_StopAtOneFront( false ),
99 m_ThrowEvents( false )
104 // -------------------------------------------------------------------------
105 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
107 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
112 // -------------------------------------------------------------------------
113 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
115 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
118 this->InvokeEvent( TStartEvent( ) );
119 this->_BeforeGenerateData( );
121 unsigned int N = this->m_Seeds.size( );
125 typename TNodes::iterator nIt = this->m_Seeds.begin( );
126 for( unsigned long i = 1; nIt != this->m_Seeds.end( ); ++nIt, ++i )
129 // Prepare collisions
130 TCollision coll( TVertex( ), false );
131 TCollisionsRow row( N, coll );
132 this->m_Collisions.clear( );
133 this->m_Collisions.resize( N, row );
135 // Put seeds on queue
136 this->_QueueClear( );
137 for( nIt = this->m_Seeds.begin( ); nIt != this->m_Seeds.end( ); ++nIt )
138 this->_QueuePush( *nIt );
140 // Init marks and results
142 this->_InitResults( );
145 this->_BeforeLoop( );
149 // Deallocate any memory
150 this->_DeallocateAuxiliary( );
154 this->_AfterGenerateData( );
155 this->InvokeEvent( TEndEvent( ) );
158 // -------------------------------------------------------------------------
159 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
161 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
164 this->InvokeEvent( TStartLoopEvent( ) );
165 this->_BeforeLoop( );
167 while( !( this->_IsQueueEmpty( ) ) )
169 // Extract next candidate
170 TNode node = this->_QueuePop( );
172 // Check if it has been visited
173 if( this->_GetMark( node ) > 0 )
176 // Mark it as visited
177 this->_Visit( node );
178 this->InvokeEvent( TAliveEvent( node.Vertex, node.FrontId ) );
180 // Check if there is an external stop condition
181 if( this->_NeedToStop( ) )
183 this->_QueueClear( );
189 TVertices neighborhood = this->_GetNeighborhood( node );
191 // Update neighborhood
192 auto neighIt = neighborhood.begin( );
194 for( ; neighIt != neighborhood.end( ); ++neighIt )
196 if( this->_GetMark( *neighIt ) == 0 )
199 neigh.Vertex = *neighIt;
200 neigh.Parent = node.Vertex;
201 neigh.FrontId = node.FrontId;
202 if( this->_Result( neigh, node ) )
204 this->_QueuePush( neigh );
205 this->InvokeEvent( TFrontEvent( *neighIt, node.FrontId ) );
210 stop |= this->_UpdateCollisions( node.Vertex, *neighIt );
215 this->_QueueClear( );
220 this->InvokeEvent( TEndLoopEvent( ) );
223 // -------------------------------------------------------------------------
224 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
226 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
227 _BeforeGenerateData( )
231 // -------------------------------------------------------------------------
232 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
234 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
235 _AfterGenerateData( )
239 // -------------------------------------------------------------------------
240 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
242 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
247 // -------------------------------------------------------------------------
248 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
250 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
255 // -------------------------------------------------------------------------
256 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
258 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
260 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
261 _GetMark( const TNode& v )
263 return( this->_GetMark( v.Vertex ) );
266 // -------------------------------------------------------------------------
267 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
269 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
275 // -------------------------------------------------------------------------
276 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
278 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
279 TVertices fpa::Base::
280 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
281 _GetNeighborhood( const TNode& n ) const
283 return( this->_GetNeighborhood( n.Vertex ) );
286 // -------------------------------------------------------------------------
287 template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
289 Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
290 _UpdateCollisions( const TVertex& a, const TVertex& b )
292 auto ma = this->_GetMark( a );
293 auto mb = this->_GetMark( b );
294 if( ma == mb || ma == 0 || mb == 0 )
299 // Mark collision, if it is new
301 bool exists = this->m_Collisions[ ma ][ mb ].second;
302 exists &= this->m_Collisions[ mb ][ ma ].second;
305 this->m_Collisions[ ma ][ mb ].first = a;
306 this->m_Collisions[ ma ][ mb ].second = true;
307 this->m_Collisions[ mb ][ ma ].first = b;
308 this->m_Collisions[ mb ][ ma ].second = true;
310 // Stop if one front is desired
311 if( this->m_StopAtOneFront )
313 // Perform a depth-first iteration on front graph
314 unsigned long N = this->GetNumberOfSeeds( );
315 unsigned long count = 0;
316 std::vector< bool > m( N, false );
317 std::queue< unsigned long > q;
321 unsigned long f = q.front( );
329 for( unsigned int n = 0; n < N; ++n )
330 if( this->m_Collisions[ f ][ n ].second && !m[ n ] )
334 ret = ( count == N );
335 this->InvokeEvent( TCollisionEvent( a, ma + 1 ) );
336 this->InvokeEvent( TCollisionEvent( b, mb + 1 ) );
344 #endif // __FPA__BASE__ALGORITHM__HXX__