34 #ifndef __INCLUDE_MIST_REGIONGROWING__ 
   35 #define __INCLUDE_MIST_REGIONGROWING__ 
   38 #ifndef __INCLUDE_MIST_H__ 
   42 #ifndef __INCLUDE_MIST_LIMITS__ 
   43 #include "../limits.h" 
   46 #ifndef __INCLUDE_MIST_VECTOR__ 
   47 #include "../vector.h" 
   88 namespace region_growing_utility
 
  182                 return( i * i * resoX_ * resoX_ + j * j * resoY_ * resoY_ <= radius_ * radius_ );
 
  190         circle( 
double radius, 
double resoX = 1.0, 
double resoY = 1.0, 
bool radiusInPhysicalCoords = 
false ) : radius_( radius )
 
  192             if( radiusInPhysicalCoords )
 
  199                 double max_reso = resoX > resoY ? resoX: resoY;
 
  201                 resoX_ = resoX / max_reso;
 
  202                 resoY_ = resoY / max_reso;
 
  204             width_  = 
static_cast< size_type >( std::ceil( radius_ / resoX_ ) ) * 2 + 1;
 
  205             height_ = 
static_cast< size_type >( std::ceil( radius_ / resoY_ ) ) * 2 + 1;
 
  234             return( i * i * resoX_ * resoX_ + j * j * resoY_ * resoY_+ k * k * resoZ_ * resoZ_ <= radius_ * radius_ );
 
  241         sphere( 
double radius, 
double resoX = 1.0, 
double resoY = 1.0, 
double resoZ = 1.0, 
bool radiusInPhysicalCoords = 
false ) : radius_( radius )
 
  243             if (radiusInPhysicalCoords)
 
  251                 double max_reso = resoX > resoY ? resoX: resoY;
 
  252                 max_reso = max_reso > resoZ ? max_reso : resoZ;
 
  254                 resoX_ = resoX / max_reso;
 
  255                 resoY_ = resoY / max_reso;
 
  256                 resoZ_ = resoZ / max_reso;
 
  258             width_  = 
static_cast< size_type >( std::ceil( radius_ / resoX_ ) ) * 2 + 1;
 
  259             height_ = 
static_cast< size_type >( std::ceil( radius_ / resoY_ ) ) * 2 + 1;
 
  260             depth_  = 
static_cast< size_type >( std::ceil( radius_ / resoZ_ ) ) * 2 + 1;
 
  273         typedef size_t      size_type;          
 
  274         typedef ptrdiff_t   difference_type;    
 
  275         typedef T           value_type;         
 
  282         template < 
class VerifyList >
 
  283         bool operator()( 
const VerifyList &elements, size_type num )
 const 
  285             typedef typename VerifyList::value_type verify_value_type;
 
  287             for( size_type i = 0 ; i < num ; i++ )
 
  289                 const verify_value_type &v = elements[ i ];
 
  315         typedef size_t      size_type;          
 
  316         typedef ptrdiff_t   difference_type;    
 
  317         typedef T           value_type;         
 
  324         template < 
class VerifyList >
 
  325         bool operator()( 
const VerifyList &elements, size_type num )
 const 
  327             typedef typename VerifyList::value_type verify_value_type;
 
  329             for( size_type i = 0 ; i < num ; i++ )
 
  331                 const verify_value_type &v = elements[ i ];
 
  357         typedef size_t      size_type;          
 
  358         typedef ptrdiff_t   difference_type;    
 
  359         typedef T           value_type;         
 
  366         template < 
class VerifyList >
 
  367         bool operator()( 
const VerifyList &elements, size_type num )
 const 
  369             typedef typename VerifyList::value_type verify_value_type;
 
  371             for( size_type i = 0 ; i < num ; i++ )
 
  373                 const verify_value_type &v = elements[ i ];
 
  374                 if( v < th_ || th_ < v )
 
  399         typedef size_t      size_type;          
 
  400         typedef ptrdiff_t   difference_type;    
 
  401         typedef T           value_type;         
 
  409         template < 
class VerifyList >
 
  410         bool operator()( 
const VerifyList &elements, size_type num )
 const 
  412             typedef typename VerifyList::value_type verify_value_type;
 
  414             for( size_type i = 0 ; i < num ; i++ )
 
  416                 const verify_value_type &v = elements[ i ];
 
  417                 if( v < min_ || max_ < v )
 
  430         range( value_type min, value_type max ) : min_( min ), max_( max ){ }
 
  436 namespace __region_growing_utility__
 
  440         typedef ptrdiff_t   difference_type;
 
  445         pointer_diff2( ptrdiff_t d1 = 0, ptrdiff_t d2 = 0 ) : diff1( d1 ), diff2( d2 ){ }
 
  448     typedef vector3< ptrdiff_t >            point_type;         
 
  449     typedef std::vector< point_type >       point_list_type;    
 
  450     typedef std::vector< pointer_diff2 >    ptrdiff_list_type;
 
  455         typedef size_t      size_type;
 
  456         typedef ptrdiff_t   difference_type;
 
  458         bool empty( )
 const { 
return( 
true ); }
 
  459         bool operator ()( difference_type , difference_type , difference_type  )
 const { 
return( 
false ); }
 
  463     template < 
class Array1, 
class Array2, 
class Component >
 
  464     ptrdiff_list_type create_component_list( 
const Array1 &in1, 
const Array2 &in2, 
const Component &components )
 
  466         typedef typename Array1::const_pointer              const_pointer1;
 
  467         typedef typename Array2::const_pointer              const_pointer2;
 
  468         typedef typename ptrdiff_list_type::size_type       size_type;
 
  469         typedef typename ptrdiff_list_type::difference_type difference_type;
 
  470         typedef typename ptrdiff_list_type::value_type      value_type;
 
  472         ptrdiff_list_type list;
 
  474         difference_type w = components.width( );
 
  475         difference_type h = components.height( );
 
  476         difference_type d = components.depth( );
 
  477         difference_type cx = w / 2;
 
  478         difference_type cy = h / 2;
 
  479         difference_type cz = d / 2;
 
  480         difference_type ox1 = in1.width( ) / 2;
 
  481         difference_type oy1 = in1.height( ) / 2;
 
  482         difference_type oz1 = in1.depth( ) / 2;
 
  483         difference_type ox2 = in2.width( ) / 2;
 
  484         difference_type oy2 = in2.height( ) / 2;
 
  485         difference_type oz2 = in2.depth( ) / 2;
 
  487         const_pointer1 p1 = &in1( ox1, oy1, oz1 );
 
  488         const_pointer2 p2 = &in2( ox2, oy2, oz2 );
 
  490         for( difference_type k = 0 ; k < d ; k++ )
 
  492             for( difference_type j = 0 ; j < h ; j++ )
 
  494                 for( difference_type i = 0 ; i < w ; i++ )
 
  496                     if( components( i - cx, j - cy, k - cz ) )
 
  498                         ptrdiff_t d1 = &in1( ox1 + i - cx, oy1 + j - cy, oz1 + k - cz ) - p1;
 
  499                         ptrdiff_t d2 = &in2( ox2 + i - cx, oy2 + j - cy, oz2 + k - cz ) - p2;
 
  500                         list.push_back( pointer_diff2( d1, d2 ) );
 
  510     template < 
class Array1, 
class Array2, 
class Component >
 
  511     ptrdiff_list_type create_update_list( 
const Array1 &in1, 
const Array2 &in2, 
const Component &components )
 
  513         typedef typename Array1::const_pointer              const_pointer1;
 
  514         typedef typename Array2::const_pointer              const_pointer2;
 
  515         typedef typename ptrdiff_list_type::size_type       size_type;
 
  516         typedef typename ptrdiff_list_type::difference_type difference_type;
 
  517         typedef typename ptrdiff_list_type::value_type      value_type;
 
  519         ptrdiff_list_type list;
 
  521         difference_type ox1 = in1.width( ) / 2;
 
  522         difference_type oy1 = in1.height( ) / 2;
 
  523         difference_type oz1 = in1.depth( ) / 2;
 
  524         difference_type ox2 = in2.width( ) / 2;
 
  525         difference_type oy2 = in2.height( ) / 2;
 
  526         difference_type oz2 = in2.depth( ) / 2;
 
  528         const_pointer1 p1 = &in1( ox1, oy1, oz1 );
 
  529         const_pointer2 p2 = &in2( ox2, oy2, oz2 );
 
  531         switch( components.expand_mode( ) )
 
  534             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1, oz1 ) - p1, &in2( ox2 - 1, oy2, oz2 ) - p2 ) );
 
  535             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1, oz1 ) - p1, &in2( ox2 + 1, oy2, oz2 ) - p2 ) );
 
  536             list.push_back( pointer_diff2( &in1( ox1, oy1 - 1, oz1 ) - p1, &in2( ox2, oy2 - 1, oz2 ) - p2 ) );
 
  537             list.push_back( pointer_diff2( &in1( ox1, oy1 + 1, oz1 ) - p1, &in2( ox2, oy2 + 1, oz2 ) - p2 ) );
 
  541             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 ) - p2 ) );
 
  542             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1 ) - p1, &in2( ox2    , oy2 - 1, oz2 ) - p2 ) );
 
  543             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 ) - p2 ) );
 
  544             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1 ) - p1, &in2( ox2 - 1, oy2    , oz2 ) - p2 ) );
 
  545             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1 ) - p1, &in2( ox2 + 1, oy2    , oz2 ) - p2 ) );
 
  546             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 ) - p2 ) );
 
  547             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1 ) - p1, &in2( ox2    , oy2 + 1, oz2 ) - p2 ) );
 
  548             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 ) - p2 ) );
 
  552             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1, oz1 ) - p1, &in2( ox2 - 1, oy2, oz2 ) - p2 ) );
 
  553             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1, oz1 ) - p1, &in2( ox2 + 1, oy2, oz2 ) - p2 ) );
 
  554             list.push_back( pointer_diff2( &in1( ox1, oy1 - 1, oz1 ) - p1, &in2( ox2, oy2 - 1, oz2 ) - p2 ) );
 
  555             list.push_back( pointer_diff2( &in1( ox1, oy1 + 1, oz1 ) - p1, &in2( ox2, oy2 + 1, oz2 ) - p2 ) );
 
  556             list.push_back( pointer_diff2( &in1( ox1, oy1, oz1 - 1 ) - p1, &in2( ox2, oy2, oz2 - 1 ) - p2 ) );
 
  557             list.push_back( pointer_diff2( &in1( ox1, oy1, oz1 + 1 ) - p1, &in2( ox2, oy2, oz2 + 1 ) - p2 ) );
 
  561             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1 - 1 ) - p1, &in2( ox2    , oy2 - 1, oz2 - 1 ) - p2 ) );
 
  562             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1 - 1 ) - p1, &in2( ox2 - 1, oy2    , oz2 - 1 ) - p2 ) );
 
  563             list.push_back( pointer_diff2( &in1( ox1    , oy1    , oz1 - 1 ) - p1, &in2( ox2    , oy2    , oz2 - 1 ) - p2 ) );
 
  564             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1 - 1 ) - p1, &in2( ox2 + 1, oy2    , oz2 - 1 ) - p2 ) );
 
  565             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1 - 1 ) - p1, &in2( ox2    , oy2 + 1, oz2 - 1 ) - p2 ) );
 
  566             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1     ) - p1, &in2( ox2 - 1, oy2 - 1, oz2     ) - p2 ) );
 
  567             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1     ) - p1, &in2( ox2    , oy2 - 1, oz2     ) - p2 ) );
 
  568             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1     ) - p1, &in2( ox2 + 1, oy2 - 1, oz2     ) - p2 ) );
 
  569             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1     ) - p1, &in2( ox2 - 1, oy2    , oz2     ) - p2 ) );
 
  570             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1     ) - p1, &in2( ox2 + 1, oy2    , oz2     ) - p2 ) );
 
  571             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1     ) - p1, &in2( ox2 - 1, oy2 + 1, oz2     ) - p2 ) );
 
  572             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1     ) - p1, &in2( ox2    , oy2 + 1, oz2     ) - p2 ) );
 
  573             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1     ) - p1, &in2( ox2 + 1, oy2 + 1, oz2     ) - p2 ) );
 
  574             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1 + 1 ) - p1, &in2( ox2    , oy2 - 1, oz2 + 1 ) - p2 ) );
 
  575             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1 + 1 ) - p1, &in2( ox2 - 1, oy2    , oz2 + 1 ) - p2 ) );
 
  576             list.push_back( pointer_diff2( &in1( ox1    , oy1    , oz1 + 1 ) - p1, &in2( ox2    , oy2    , oz2 + 1 ) - p2 ) );
 
  577             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1 + 1 ) - p1, &in2( ox2 + 1, oy2    , oz2 + 1 ) - p2 ) );
 
  578             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1 + 1 ) - p1, &in2( ox2    , oy2 + 1, oz2 + 1 ) - p2 ) );
 
  582             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 - 1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 - 1 ) - p2 ) );
 
  583             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1 - 1 ) - p1, &in2( ox2    , oy2 - 1, oz2 - 1 ) - p2 ) );
 
  584             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 - 1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 - 1 ) - p2 ) );
 
  585             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1 - 1 ) - p1, &in2( ox2 - 1, oy2    , oz2 - 1 ) - p2 ) );
 
  586             list.push_back( pointer_diff2( &in1( ox1    , oy1    , oz1 - 1 ) - p1, &in2( ox2    , oy2    , oz2 - 1 ) - p2 ) );
 
  587             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1 - 1 ) - p1, &in2( ox2 + 1, oy2    , oz2 - 1 ) - p2 ) );
 
  588             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 - 1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 - 1 ) - p2 ) );
 
  589             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1 - 1 ) - p1, &in2( ox2    , oy2 + 1, oz2 - 1 ) - p2 ) );
 
  590             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 - 1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 - 1 ) - p2 ) );
 
  591             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1     ) - p1, &in2( ox2 - 1, oy2 - 1, oz2     ) - p2 ) );
 
  592             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1     ) - p1, &in2( ox2    , oy2 - 1, oz2     ) - p2 ) );
 
  593             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1     ) - p1, &in2( ox2 + 1, oy2 - 1, oz2     ) - p2 ) );
 
  594             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1     ) - p1, &in2( ox2 - 1, oy2    , oz2     ) - p2 ) );
 
  595             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1     ) - p1, &in2( ox2 + 1, oy2    , oz2     ) - p2 ) );
 
  596             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1     ) - p1, &in2( ox2 - 1, oy2 + 1, oz2     ) - p2 ) );
 
  597             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1     ) - p1, &in2( ox2    , oy2 + 1, oz2     ) - p2 ) );
 
  598             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1     ) - p1, &in2( ox2 + 1, oy2 + 1, oz2     ) - p2 ) );
 
  599             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 + 1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 + 1 ) - p2 ) );
 
  600             list.push_back( pointer_diff2( &in1( ox1    , oy1 - 1, oz1 + 1 ) - p1, &in2( ox2    , oy2 - 1, oz2 + 1 ) - p2 ) );
 
  601             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 + 1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 + 1 ) - p2 ) );
 
  602             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1    , oz1 + 1 ) - p1, &in2( ox2 - 1, oy2    , oz2 + 1 ) - p2 ) );
 
  603             list.push_back( pointer_diff2( &in1( ox1    , oy1    , oz1 + 1 ) - p1, &in2( ox2    , oy2    , oz2 + 1 ) - p2 ) );
 
  604             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1    , oz1 + 1 ) - p1, &in2( ox2 + 1, oy2    , oz2 + 1 ) - p2 ) );
 
  605             list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 + 1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 + 1 ) - p2 ) );
 
  606             list.push_back( pointer_diff2( &in1( ox1    , oy1 + 1, oz1 + 1 ) - p1, &in2( ox2    , oy2 + 1, oz2 + 1 ) - p2 ) );
 
  607             list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 + 1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 + 1 ) - p2 ) );
 
  612             list = create_component_list( in1, in2, components );
 
  620     template < 
class T, 
class Allocator, 
class Array, 
class Po
intType >
 
  621     bool check_component_list( 
const array2< T, Allocator > &in1, 
const Array &in2, 
const PointType &pt, pointer_diff2 &ptr )
 
  623         typedef typename array2< T, Allocator >::const_pointer  const_pointer1;
 
  624         typedef typename Array::const_pointer                   const_pointer2;
 
  625         typedef typename ptrdiff_list_type::difference_type     difference_type;
 
  627         difference_type x = 
static_cast< difference_type 
>( pt.x );
 
  628         difference_type y = 
static_cast< difference_type 
>( pt.y );
 
  629         difference_type w = in1.width( );
 
  630         difference_type h = in1.height( );
 
  632         if( x < 0 || x >= w || y < 0 || y >= h )
 
  636         else if( in2( x, y ) != 0 )
 
  642             ptr.diff1 = &in1( x, y) - &in1[ 0 ];
 
  643             ptr.diff2 = &in2( x, y ) - &in2[ 0 ];
 
  649     template < 
class T, 
class Allocator, 
class Array, 
class Po
intType >
 
  650     bool check_component_list( 
const array3< T, Allocator > &in1, 
const Array &in2, 
const PointType &pt, pointer_diff2 &ptr )
 
  652         typedef typename array3< T, Allocator >::const_pointer  const_pointer1;
 
  653         typedef typename Array::const_pointer                   const_pointer2;
 
  654         typedef typename ptrdiff_list_type::difference_type     difference_type;
 
  656         difference_type x = 
static_cast< difference_type 
>( pt.x );
 
  657         difference_type y = 
static_cast< difference_type 
>( pt.y );
 
  658         difference_type z = 
static_cast< difference_type 
>( pt.z );
 
  659         difference_type w = in1.width( );
 
  660         difference_type h = in1.height( );
 
  661         difference_type d = in1.depth( );
 
  663         if( x < 0 || x >= w || y < 0 || y >= h || z < 0 || z >= d )
 
  667         else if( in2( x, y, z ) != 0 )
 
  673             ptr.diff1 = &in1( x, y, z ) - &in1[ 0 ];
 
  674             ptr.diff2 = &in2( x, y, z ) - &in2[ 0 ];
 
  680     template < 
class Po
intType >
 
  681     struct point_list_converter
 
  683         typedef std::vector< PointType > point_list_type;
 
  685         static point_list_type create_point_list( 
const PointType &pt )
 
  687             point_list_type list( 1 );
 
  694     template < 
class Po
intType >
 
  695     struct point_list_converter< std::vector< PointType > >
 
  697         typedef std::vector< PointType > point_list_type;
 
  699         static point_list_type create_point_list( 
const point_list_type &list )
 
  705     template < 
class Po
intType >
 
  706     struct point_list_converter< std::deque< PointType > >
 
  708         typedef std::deque< PointType > point_list_type;
 
  710         static point_list_type create_point_list( 
const point_list_type &list )
 
  718     inline const T maximum( 
const T &v0, 
const typename type_trait< T >::value_type &v1 )
 
  720         return( v0 > v1 ? v0 : v1 );
 
  724     inline const T maximum( 
const T &v0, 
const typename type_trait< T >::value_type &v1, 
const typename type_trait< T >::value_type &v2 )
 
  726         return( v0 > v1 ? ( v0 > v2 ? v0 : v2 ) : ( v1 > v2 ? v1 : v2 ) );
 
  730     inline const T maximum( 
const T &v0, 
const typename type_trait< T >::value_type &v1, 
const typename type_trait< T >::value_type &v2, 
const typename type_trait< T >::value_type &v3 )
 
  732         return( maximum( maximum( v0, v1 ), maximum( v2, v3 ) ) );
 
  752 template < 
class Array1, 
class Array2, 
class MaskType, 
class Po
intList, 
class Component, 
class Condition >
 
  753 typename Array1::difference_type 
region_growing( 
const Array1 &in, Array2 &out, 
const MaskType &mask, 
const PointList &start_points, 
typename Array2::value_type output_value,
 
  754                                                         const Component &components, 
const Condition &condition, 
typename Array1::size_type max_paint )
 
  761     typedef typename Array1::template rebind< unsigned char >::other mask_type;
 
  762     typedef __region_growing_utility__::pointer_diff2 pointer_diff_type;
 
  764     typedef typename Array1::size_type          size_type;
 
  765     typedef typename Array1::value_type         value_type;
 
  766     typedef typename Array1::difference_type    difference_type;
 
  767     typedef typename Array2::value_type         out_value_type;
 
  769     typedef typename Array1::const_pointer      const_pointer;
 
  770     typedef typename mask_type::pointer         work_pointer;
 
  771     typedef typename Array2::pointer            output_pointer;
 
  773     size_type rx = components.width( ) / 2;
 
  774     size_type ry = components.height( ) / 2;
 
  775     size_type rz = components.depth( ) / 2;
 
  781     __region_growing_utility__::ptrdiff_list_type clist = __region_growing_utility__::create_component_list( in, work, components );    
 
  782     __region_growing_utility__::ptrdiff_list_type ulist = __region_growing_utility__::create_update_list( in, work, components );       
 
  784     std::deque< pointer_diff_type > que;                                    
 
  785     std::vector< value_type > element( clist.size( ) );                     
 
  786     __region_growing_utility__::ptrdiff_list_type elist( clist.size( ) );   
 
  795         for( size_type k = 0 ; k < in.depth( ) ; k++ )
 
  797             for( size_type j = 0 ; j < in.height( ) ; j++ )
 
  799                 for( size_type i = 0 ; i < in.width( ) ; i++ )
 
  801                     if( mask( i, j, k ) )
 
  803                         work( i, j, k ) = 255;
 
  810     typedef __region_growing_utility__::point_list_converter< PointList > start_point_list_converter;
 
  811     typedef typename start_point_list_converter::point_list_type start_point_list_type;
 
  812     start_point_list_type sps = start_point_list_converter::create_point_list( start_points );
 
  815     for( 
typename start_point_list_type::const_iterator ite = sps.begin( ) ; ite != sps.end( ) ; ++ite )
 
  817         __region_growing_utility__::pointer_diff2 ptr;
 
  818         if( __region_growing_utility__::check_component_list( in, work, *ite, ptr ) )
 
  820             que.push_back( ptr );
 
  825     if( in.size( ) != out.size( ) )
 
  827         out.resize( in.width( ), in.height( ), in.depth( ) );
 
  828         out.reso1( in.reso1( ) );
 
  829         out.reso2( in.reso2( ) );
 
  830         out.reso3( in.reso3( ) );
 
  834     size_type num_painted = 0;  
 
  839     if( condition.require_all_elements( ) )
 
  842         while( !que.empty( ) )
 
  844             if( num_painted >= max_paint )
 
  846                 return( num_painted );
 
  850             pointer_diff_type cur = que.front( );
 
  853             const_pointer  pi = &in[ 0 ] + cur.diff1;
 
  854             work_pointer   pw = &work[ 0 ] + cur.diff2;
 
  855             output_pointer po = &out[ 0 ] + cur.diff1;
 
  863             for( size_type i = 0 ; i < clist.size( ) ; i++ )
 
  865                 const pointer_diff_type &d = clist[ i ];
 
  866                 if( ( pw[ d.diff2 ] & 0x0f ) == 0 )
 
  868                     element[ num ] = pi[ d.diff1 ];
 
  875             if( num != 0 && condition( element, num ) )
 
  878                 for( size_type i = 0 ; i < num ; i++ )
 
  880                     const pointer_diff_type &d = elist[ i ];
 
  881                     num_painted += po[ d.diff1 ] != output_value ? 1 : 0;
 
  882                     po[ d.diff1 ] = output_value;
 
  886                 for( size_type i = 0 ; i < ulist.size( ) ; i++ )
 
  888                     const pointer_diff_type &d = ulist[ i ];
 
  889                     if( ( pw[ d.diff2 ] & 0xf0 ) == 0 )
 
  891                         pw[ d.diff2 ] |= 0xf0;
 
  892                         que.push_back( pointer_diff_type( cur.diff1 + d.diff1, cur.diff2 + d.diff2 ) );
 
  901         while( !que.empty( ) )
 
  903             if( num_painted >= max_paint )
 
  905                 return( num_painted );
 
  909             pointer_diff_type cur = que.front( );
 
  912             const_pointer  pi = &in[ 0 ] + cur.diff1;
 
  913             work_pointer   pw = &work[ 0 ] + cur.diff2;
 
  914             output_pointer po = &out[ 0 ] + cur.diff1;
 
  924             for( size_type i = 0 ; i < clist.size( ) ; i++ )
 
  926                 const pointer_diff_type &d = clist[ i ];
 
  927                 if( ( pw[ d.diff2 ] & 0x0f ) == 0 )
 
  929                     element[ num ] = pi[ d.diff1 ];
 
  936             if( condition( element, num ) )
 
  939                 for( size_type i = 0 ; i < num ; i++ )
 
  941                     const pointer_diff_type &d = elist[ i ];
 
  942                     num_painted += po[ d.diff1 ] != output_value ? 1 : 0;
 
  944                     po[ d.diff1 ] = output_value;
 
  948                 for( size_type i = 0 ; i < ulist.size( ) ; i++ )
 
  950                     const pointer_diff_type &d = ulist[ i ];
 
  951                     if( ( pw[ d.diff2 ] & 0xf0 ) == 0 )
 
  953                         pw[ d.diff2 ] |= 0xf0;
 
  954                         que.push_back( pointer_diff_type( cur.diff1 + d.diff1, cur.diff2 + d.diff2 ) );
 
  961     return( num_painted );
 
  982 template < 
class Array1, 
class Array2, 
class Po
intList, 
class Component, 
class Condition >
 
  983 typename Array1::difference_type 
region_growing( 
const Array1 &in, Array2 &out, 
const PointList &start_points, 
typename Array2::value_type output_value,
 
  986     return( 
region_growing( in, out, __region_growing_utility__::no_mask( ), start_points, output_value, components, condition, max_paint ) );
 
  998 #endif // __INCLUDE_MIST_REGIONGROWING__