X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2Ffpa%2FBase%2FAlgorithm.hxx;h=35307874ab8a43c732169bb008612b13994ff10e;hb=aaeabf9e79b8db1b97bc3381e95e46c77da4d891;hp=21670ef7396522c40c2a918432182d7d96037b34;hpb=b70a564ee2d7bc180b77a05c37ab431ab9c393e7;p=FrontAlgorithms.git diff --git a/lib/fpa/Base/Algorithm.hxx b/lib/fpa/Base/Algorithm.hxx index 21670ef..3530787 100644 --- a/lib/fpa/Base/Algorithm.hxx +++ b/lib/fpa/Base/Algorithm.hxx @@ -2,10 +2,11 @@ #define __FPA__BASE__ALGORITHM__HXX__ #include +#include // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -fpa::Base::Algorithm< V, C, R, B >::_TNode:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >::_TNode:: _TNode( ) : Result( TResult( 0 ) ), FrontId( -1 ), @@ -14,15 +15,15 @@ _TNode( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -fpa::Base::Algorithm< V, C, R, B >::_TNode:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >::_TNode:: ~_TNode( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: InvokeEvent( const itk::EventObject& e ) { if( this->m_ThrowEvents ) @@ -30,8 +31,8 @@ InvokeEvent( const itk::EventObject& e ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: InvokeEvent( const itk::EventObject& e ) const { if( this->m_ThrowEvents ) @@ -39,49 +40,50 @@ InvokeEvent( const itk::EventObject& e ) const } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: AddSeed( const TVertex& s, const TResult& r ) { _TNode ns; - ns.Vertex = s; ns.Parent = s; ns.Result = r; - ns.FrontId = this->m_Seeds.size( ); + ns.FrontId = this->m_SeedVertices.size( ); ns.Label = Self::FrontLabel; - this->m_Seeds.push_back( ns ); + this->m_Seeds[ s ] = ns; + this->m_SeedVertices.push_back( s ); this->Modified( ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -const typename fpa::Base::Algorithm< V, C, R, B >:: -TVertex& fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +const typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +TVertex& fpa::Base::Algorithm< V, C, R, S, VC, B >:: GetSeed( const unsigned int& id ) const { - return( this->m_Seeds[ id ].Vertex ); + return( this->m_SeedVertices[ id ] ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: ClearSeeds( ) { this->m_Seeds.clear( ); + this->m_SeedVertices.clear( ); this->Modified( ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -unsigned long fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +unsigned long fpa::Base::Algorithm< V, C, R, S, VC, B >:: GetNumberOfSeeds( ) const { return( this->m_Seeds.size( ) ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >:: Algorithm( ) : Superclass( ), m_ThrowEvents( false ), @@ -90,15 +92,15 @@ Algorithm( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +fpa::Base::Algorithm< V, C, R, S, VC, B >:: ~Algorithm( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: GenerateData( ) { unsigned long N = this->m_Seeds.size( ); @@ -120,8 +122,8 @@ GenerateData( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _Loop( ) { this->InvokeEvent( TStartLoopEvent( ) ); @@ -129,61 +131,60 @@ _Loop( ) while( !( this->_IsQueueEmpty( ) ) ) { // Get next candidate - _TNode candidate = this->_QueuePop( ); - if( this->_Node( candidate.Vertex ).Label == Self::AliveLabel ) + TVertex vertex; + _TNode node; + this->_QueuePop( vertex, node ); + if( this->_Node( vertex ).Label == Self::AliveLabel ) continue; // Mark it as "Alive" and update final result - candidate.Label = Self::AliveLabel; - this->_Mark( candidate ); - this->_SetResult( candidate.Vertex, candidate.Result ); - this->InvokeEvent( TAliveEvent( candidate.Vertex, candidate.FrontId ) ); + node.Label = Self::AliveLabel; + this->_Mark( vertex, node ); + this->_SetResult( vertex, node ); + this->InvokeEvent( TAliveEvent( vertex, node.FrontId ) ); // Check if a forced stop condition arises if( !( this->_NeedToStop( ) ) ) { // Compute neighborhood _TVertices neighborhood; - this->_Neighborhood( neighborhood, candidate.Vertex ); + this->_Neighborhood( neighborhood, vertex ); // Iterate over neighbors typename _TVertices::iterator nIt = neighborhood.begin( ); - for( ; nIt != neighborhood.end( ); ++nIt ) + while( nIt != neighborhood.end( ) ) { _TNode neighbor = this->_Node( *nIt ); - neighbor.Vertex = *nIt; if( neighbor.Label == Self::AliveLabel ) { // Update collisions - if( this->_UpdateCollisions( candidate.Vertex, *nIt ) ) + if( this->_UpdateCollisions( vertex, *nIt ) ) { this->_QueueClear( ); nIt = neighborhood.end( ); + continue; } // fi } else { // Add new candidate to queue - if( - this->_ComputeNeighborResult( - neighbor.Result, *nIt, candidate.Vertex - ) - ) + if( this->_ComputeNeighborResult( neighbor.Result, *nIt, vertex ) ) { - neighbor.FrontId = candidate.FrontId; - neighbor.Parent = candidate.Vertex; + neighbor.FrontId = node.FrontId; + neighbor.Parent = vertex; neighbor.Label = Self::FrontLabel; - this->_QueuePush( neighbor ); - this->_Mark( neighbor ); - this->InvokeEvent( TFrontEvent( *nIt, candidate.FrontId ) ); + this->_QueuePush( *nIt, neighbor ); + this->_Mark( *nIt, neighbor ); + this->InvokeEvent( TFrontEvent( *nIt, node.FrontId ) ); } else - this->InvokeEvent( TFreezeEvent( *nIt, candidate.FrontId ) ); + this->InvokeEvent( TFreezeEvent( *nIt, node.FrontId ) ); } // fi + ++nIt; - } // rof + } // elihw } else this->_QueueClear( ); @@ -194,54 +195,55 @@ _Loop( ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _BeforeGenerateData( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _AfterGenerateData( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _BeforeLoop( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _AfterLoop( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -bool fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::Algorithm< V, C, R, S, VC, B >:: _UpdateCollisions( const TVertex& a, const TVertex& b ) { bool ret = false; _TNode na = this->_Node( a ); _TNode nb = this->_Node( b ); long fa = na.FrontId; - long fb = na.FrontId; + long fb = nb.FrontId; if( fa != fb ) { // Mark collision, if it is new bool exists = this->m_Collisions[ fa ][ fb ].second; exists &= this->m_Collisions[ fb ][ fa ].second; + if( !exists ) { - this->m_Collisions[ fa ][ fb ].first = na.Vertex; + this->m_Collisions[ fa ][ fb ].first = a; this->m_Collisions[ fa ][ fb ].second = true; - this->m_Collisions[ fb ][ fa ].first = nb.Vertex; + this->m_Collisions[ fb ][ fa ].first = b; this->m_Collisions[ fb ][ fa ].second = true; // Stop if one front is desired @@ -279,16 +281,71 @@ _UpdateCollisions( const TVertex& a, const TVertex& b ) } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -bool fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +bool fpa::Base::Algorithm< V, C, R, S, VC, B >:: _NeedToStop( ) const { return( false ); } // ------------------------------------------------------------------------- -template< class V, class C, class R, class B > -void fpa::Base::Algorithm< V, C, R, B >:: +template< class V, class C, class R, class S, class VC, class B > +typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_TNode& fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_Node( const TVertex& v ) +{ + typename _TNodes::iterator vIt = this->m_Marks.find( v ); + if( vIt == this->m_Marks.end( ) ) + { + _TNode new_node; + new_node.Parent = v; + new_node.Result = TResult( 0 ); + new_node.FrontId = -1; + new_node.Label = Self::FarLabel; + this->m_Marks[ v ] = new_node; + vIt = this->m_Marks.find( v ); + + } // fi + return( vIt->second ); +} + +// ------------------------------------------------------------------------- +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_SetResult( const TVertex& v, const _TNode& n ) +{ + // Do nothing at this hierarchy level +} + +// ------------------------------------------------------------------------- +template< class V, class C, class R, class S, class VC, class B > +const typename fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_TNode& fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_Node( const TVertex& v ) const +{ + typename _TNodes::const_iterator vIt = this->m_Marks.find( v ); + return( vIt->second ); +} + +// ------------------------------------------------------------------------- +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_InitMarks( ) +{ + this->m_Marks.clear( ); +} + +// ------------------------------------------------------------------------- +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: +_Mark( const TVertex& v, const _TNode& node ) +{ + this->m_Marks[ v ] = node; +} + +// ------------------------------------------------------------------------- +template< class V, class C, class R, class S, class VC, class B > +void fpa::Base::Algorithm< V, C, R, S, VC, B >:: _InitQueue( ) { this->_QueueClear( ); @@ -298,8 +355,8 @@ _InitQueue( ) sIt++ ) { - this->_QueuePush( *sIt ); - this->_Mark( *sIt ); + this->_QueuePush( sIt->first, sIt->second ); + this->_Mark( sIt->first, sIt->second ); } // rof }