36 #ifndef __INCLUDE_MIST_MODE__
37 #define __INCLUDE_MIST_MODE__
40 #ifndef __INCLUDE_MIST_H__
44 #ifndef __INCLUDE_MIST_LIMITS__
45 #include "../limits.h"
49 #ifndef __INCLUDE_MIST_THREAD__
50 #include "../thread.h"
129 double max_reso = resoX > resoY ? resoX: resoY;
131 double ax = resoX / max_reso;
132 double ay = resoY / max_reso;
133 double xx, yy, rr = radius * radius;
134 difference_type rx =
static_cast< size_type
>( ceil( radius / ax ) );
135 difference_type ry =
static_cast< size_type
>( ceil( radius / ay ) );
136 difference_type x, y;
138 size_type ox = rx + 1;
139 size_type oy = ry + 1;
141 size_type w = 2 * ox + 1;
142 size_type h = 2 * oy + 1;
148 for( y = -ry ; y <= ry ; y++ )
150 yy = y * y * ay * ay;
151 for( x = -rx ; x <= rx ; x++ )
153 xx = x * x * ax * ax;
156 m( x + ox, y + oy ) =
true;
162 for( y = -ry ; y <= ry ; y++ )
164 for( x = -rx ; x <= rx ; x++ )
166 if( m( x + ox, y + oy ) )
169 if( !m( x + ox + 1, y + oy ) )
173 if( !m( x + ox - 1, y + oy ) )
206 double max_reso = resoX > resoY ? resoX: resoY;
207 max_reso = max_reso > resoZ ? max_reso : resoZ;
209 double ax = resoX / max_reso;
210 double ay = resoY / max_reso;
211 double az = resoZ / max_reso;
212 double xx, yy, zz, rr = radius * radius;
213 difference_type rx =
static_cast< size_type
>( ceil( radius / ax ) );
214 difference_type ry =
static_cast< size_type
>( ceil( radius / ay ) );
215 difference_type rz =
static_cast< size_type
>( ceil( radius / az ) );
216 difference_type x, y, z;
218 size_type ox = rx + 1;
219 size_type oy = ry + 1;
220 size_type oz = rz + 1;
222 size_type w = 2 * ox + 1;
223 size_type h = 2 * oy + 1;
224 size_type d = 2 * oz + 1;
230 for( z = -rz ; z <= rz ; z++ )
232 zz = z * z * az * az;
233 for( y = -ry ; y <= ry ; y++ )
235 yy = y * y * ay * ay;
236 for( x = -rx ; x <= rx ; x++ )
238 xx = x * x * ax * ax;
239 if( xx + yy + zz <= rr )
241 m( x + ox, y + oy, z + oz ) =
true;
248 for( z = -rz ; z <= rz ; z++ )
250 for( y = -ry ; y <= ry ; y++ )
252 for( x = -rx ; x <= rx ; x++ )
254 if( m( x + ox, y + oy, z + oz ) )
257 if( !m( x + ox + 1, y + oy, z + oz ) )
261 if( !m( x + ox - 1, y + oy, z + oz ) )
295 double max_reso = resoX > resoY ? resoX: resoY;
297 double ax = resoX / max_reso;
298 double ay = resoY / max_reso;
300 difference_type rx =
static_cast< size_type
>( ceil( radius / ax ) );
301 difference_type ry =
static_cast< size_type
>( ceil( radius / ay ) );
302 difference_type x, y;
304 size_type ox = rx + 1;
305 size_type oy = ry + 1;
307 size_type w = 2 * ox + 1;
308 size_type h = 2 * oy + 1;
314 for( y = -ry ; y <= ry ; y++ )
317 for( x = -rx ; x <= rx ; x++ )
320 if( std::abs( xx ) <= radius && std::abs( yy ) <= radius )
322 m( x + ox, y + oy ) =
true;
328 for( y = -ry ; y <= ry ; y++ )
330 for( x = -rx ; x <= rx ; x++ )
332 if( m( x + ox, y + oy ) )
334 s.object.push_back(
point( x, y, 0 ) );
335 if( !m( x + ox + 1, y + oy ) )
337 s.update_in.push_back(
point( x, y, 0 ) );
339 if( !m( x + ox - 1, y + oy ) )
341 s.update_out.push_back(
point( x - 1, y, 0 ) );
372 double max_reso = resoX > resoY ? resoX: resoY;
373 max_reso = max_reso > resoZ ? max_reso : resoZ;
375 double ax = resoX / max_reso;
376 double ay = resoY / max_reso;
377 double az = resoZ / max_reso;
379 difference_type rx =
static_cast< size_type
>( ceil( radius / ax ) );
380 difference_type ry =
static_cast< size_type
>( ceil( radius / ay ) );
381 difference_type rz =
static_cast< size_type
>( ceil( radius / az ) );
382 difference_type x, y, z;
384 size_type ox = rx + 1;
385 size_type oy = ry + 1;
386 size_type oz = rz + 1;
388 size_type w = 2 * ox + 1;
389 size_type h = 2 * oy + 1;
390 size_type d = 2 * oz + 1;
396 for( z = -rz ; z <= rz ; z++ )
399 for( y = -ry ; y <= ry ; y++ )
402 for( x = -rx ; x <= rx ; x++ )
405 if( std::abs( xx ) <= radius && std::abs( yy ) <= radius && std::abs( zz ) <= radius )
407 m( x + ox, y + oy, z + oz ) =
true;
414 for( z = -rz ; z <= rz ; z++ )
416 for( y = -ry ; y <= ry ; y++ )
418 for( x = -rx ; x <= rx ; x++ )
420 if( m( x + ox, y + oy, z + oz ) )
422 s.object.push_back(
point( x, y, z ) );
423 if( !m( x + ox + 1, y + oy, z + oz ) )
425 s.update_in.push_back(
point( x, y, z ) );
427 if( !m( x + ox - 1, y + oy, z + oz ) )
429 s.update_out.push_back(
point( x - 1, y, z ) );
456 template <
class Array >
460 typedef typename Array::size_type size_type;
461 typedef typename Array::difference_type difference_type;
462 difference_type x, y, z;
464 difference_type w = in.width( );
465 difference_type h = in.height( );
466 difference_type d = in.depth( );
472 for( z = 0 ; z < d ; z++ )
474 for( y = 0 ; y < h ; y++ )
476 for( x = 0 ; x < w ; x++ )
478 m( x, y, z ) = in( x, y, z ) == 0 ?
false :
true;
484 for( z = 0 ; z < d ; z++ )
486 for( y = 0 ; y < h ; y++ )
489 for( x = 0 ; x < w ; x++ )
493 s.object.push_back(
point( x - cx, y - cy, z - cz ) );
494 if( !m( x + 1, y, z ) )
496 s.update_in.push_back(
point( x - cx, y - cy, z - cz ) );
498 if( !m( x - 1, y, z ) )
500 s.update_out.push_back(
point( x - cx - 1, y - cy, z - cz ) );
507 s.margin_x = cx > w - cx - 1 ? cx : w - cx;
508 s.margin_y = cy > h - cy - 1 ? cy : h - cy;
509 s.margin_z = cz > d - cz - 1 ? cz : d - cz;
524 template <
class Array >
527 typedef typename Array::size_type size_type;
528 typedef typename Array::const_pointer const_pointer;
529 size_type cx = in.width( ) / 2;
530 size_type cy = in.height( ) / 2;
531 size_type cz = in.depth( ) / 2;
532 const_pointer p = &( in( cx, cy, cz ) );
534 std::vector< ptrdiff_t > out;
536 for( size_type i = 0 ; i < list.size( ) ; i++ )
538 const point &pt = list[ i ];
539 const_pointer pp = &in( cx + pt.
x, cy + pt.
y, cz + pt.
z );
540 out.push_back( pp - p );
554 template <
class Array1,
class Array2,
class Functor >
555 void mode(
const Array1 &in, Array2 &out,
556 const std::vector< ptrdiff_t > &
object,
const std::vector< ptrdiff_t > &update_in,
const std::vector< ptrdiff_t > &update_out,
557 typename Array1::size_type thread_idy,
typename Array1::size_type thread_numy,
558 typename Array1::size_type thread_idz,
typename Array1::size_type thread_numz, Functor f )
560 typedef typename Array1::size_type size_type;
561 typedef typename Array1::value_type value_type;
562 typedef typename Array1::const_pointer const_pointer;
563 typedef typename Array1::difference_type difference_type;
564 typedef typename Array2::value_type out_value_type;
565 typedef typename Array2::value_type out_value_type;
566 typedef std::vector< ptrdiff_t > list_type;
567 typedef list_type::const_iterator const_iterator;
569 size_type w = in.width( );
570 size_type h = in.height( );
571 size_type d = in.depth( );
573 const bool bprogress1 = thread_idy == 0 && d == 1;
574 const bool bprogress2 = thread_idz == 0 && d > 1;
576 for( size_type k = thread_idz ; k < d ; k += thread_numz )
578 for( size_type j = thread_idy ; j < h ; j += thread_numy )
580 const_pointer p = &in( 0, j, k );
581 difference_type count[ 2 ] = { 0, 0 };
582 for( const_iterator ite =
object.begin( ) ; ite !=
object.end( ) ; ++ite )
584 count[ p[ *ite ] > 0 ]++;
587 out( 0, j, k ) =
static_cast< out_value_type
>( count[ 0 ] > count[ 1 ] ? 0 : 1 );
589 for( size_type i = 1 ; i < w ; i++ )
594 for( const_iterator ite = update_out.begin( ) ; ite != update_out.end( ) ; ++ite )
596 count[ p[ *ite ] > 0 ]--;
600 for( const_iterator ite = update_in.begin( ) ; ite != update_in.end( ) ; ++ite )
602 count[ p[ *ite ] > 0 ]++;
605 out( i, j, k ) =
static_cast< out_value_type
>( count[ 0 ] > count[ 1 ] ? 0 : 1 );
610 f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
616 f( static_cast< double >( k + 1 ) / static_cast< double >( d ) * 100.0 );
626 namespace __mode_controller__
629 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
630 void mode(
const marray< array< T1, Allocator1 > > &in, array< T2, Allocator2 > &out,
631 const std::vector< ptrdiff_t > &
object,
const std::vector< ptrdiff_t > &update_in,
const std::vector< ptrdiff_t > &update_out,
632 typename array< T1, Allocator1 >::size_type thread_id,
typename array< T1, Allocator1 >::size_type thread_num, Functor f )
634 __mode__::mode( in, out,
object, update_in, update_out, 0, 1, thread_id, thread_num, f );
637 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
638 void mode(
const marray< array1< T1, Allocator1 > > &in, array1< T2, Allocator2 > &out,
639 const std::vector< ptrdiff_t > &
object,
const std::vector< ptrdiff_t > &update_in,
const std::vector< ptrdiff_t > &update_out,
640 typename array1< T1, Allocator1 >::size_type thread_id,
typename array1< T1, Allocator1 >::size_type thread_num, Functor f )
642 __mode__::mode( in, out,
object, update_in, update_out, 0, 1, thread_id, thread_num, f );
645 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
646 void mode(
const marray< array2< T1, Allocator1 > > &in, array2< T2, Allocator2 > &out,
647 const std::vector< ptrdiff_t > &
object,
const std::vector< ptrdiff_t > &update_in,
const std::vector< ptrdiff_t > &update_out,
648 typename array2< T1, Allocator1 >::size_type thread_id,
typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
650 __mode__::mode( in, out,
object, update_in, update_out, thread_id, thread_num, 0, 1, f );
653 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
654 void mode(
const marray< array3< T1, Allocator1 > > &in, array3< T2, Allocator2 > &out,
655 const std::vector< ptrdiff_t > &
object,
const std::vector< ptrdiff_t > &update_in,
const std::vector< ptrdiff_t > &update_out,
656 typename array3< T1, Allocator1 >::size_type thread_id,
typename array3< T1, Allocator1 >::size_type thread_num, Functor f )
658 __mode__::mode( in, out,
object, update_in, update_out, 0, 1, thread_id, thread_num, f );
662 template <
class T1,
class T2,
class Functor >
663 class mode_thread :
public mist::thread< mode_thread< T1, T2, Functor > >
667 typedef typename base::thread_exit_type thread_exit_type;
668 typedef typename T1::size_type size_type;
669 typedef typename T1::value_type value_type;
670 typedef typename T1::difference_type difference_type;
671 typedef std::vector< difference_type > list_type;
681 list_type *update_in_;
682 list_type *update_out_;
687 void setup_parameters(
const T1 &in, T2 &out, list_type &
object, list_type &update_in, list_type &update_out, size_type thread_id, size_type thread_num, Functor f )
692 update_in_ = &update_in;
693 update_out_ = &update_out;
694 thread_id_ = thread_id;
695 thread_num_ = thread_num;
699 const mode_thread& operator =(
const mode_thread &p )
703 base::operator =( p );
704 thread_id_ = p.thread_id_;
705 thread_num_ = p.thread_num_;
709 update_in_ = p.update_in_;
710 update_out_ = p.update_out_;
716 mode_thread( size_type
id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ),
717 in_( NULL ), out_( NULL ), object_( NULL ), update_in_( NULL ), update_out_( NULL )
720 mode_thread(
const mode_thread &p ) : base( p ), thread_id_( p.thread_id_ ), thread_num_( p.thread_num_ ),
721 in_( p.in_ ), out_( p.out_ ), object_( p.object_ ), update_in_( p.update_in_ ), update_out_( p.update_out_ )
727 virtual thread_exit_type thread_function( )
729 mode( *in_, *out_, *object_, *update_in_, *update_out_, thread_id_, thread_num_, f_ );
753 template <
class T,
class Allocator,
class Functor >
764 typedef __mode_controller__::mode_thread< marray< array2< T, Allocator > >,
array2< T, Allocator >, Functor > mode_thread;
765 typedef std::vector< difference_type > list_type;
767 if( thread_num == 0 )
769 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
778 mode_thread *
thread =
new mode_thread[ thread_num ];
780 for( size_type i = 0 ; i < thread_num ; i++ )
782 thread[ i ].setup_parameters( out, in,
object, update_in, update_out, i, thread_num, f );
810 template <
class T,
class Allocator >
831 template <
class T,
class Allocator,
class Functor >
850 template <
class T,
class Allocator >
875 template <
class T,
class Allocator,
class Functor >
886 typedef __mode_controller__::mode_thread< marray< array3< T, Allocator > >,
array3< T, Allocator >, Functor > mode_thread;
887 typedef std::vector< difference_type > list_type;
889 if( thread_num == 0 )
891 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
900 mode_thread *
thread =
new mode_thread[ thread_num ];
902 for( size_type i = 0 ; i < thread_num ; i++ )
904 thread[ i ].setup_parameters( out, in,
object, update_in, update_out, i, thread_num, f );
932 template <
class T,
class Allocator >
954 template <
class T,
class Allocator,
class Functor >
975 template <
class T,
class Allocator >
991 #endif // __INCLUDE_MIST_MODE__