]> Creatis software - FrontAlgorithms.git/blobdiff - lib/fpa/Base/Algorithm.hxx
...
[FrontAlgorithms.git] / lib / fpa / Base / Algorithm.hxx
index 21670ef7396522c40c2a918432182d7d96037b34..35307874ab8a43c732169bb008612b13994ff10e 100644 (file)
@@ -2,10 +2,11 @@
 #define __FPA__BASE__ALGORITHM__HXX__
 
 #include <queue>
+#include <itkProcessObject.h>
 
 // -------------------------------------------------------------------------
-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
 }