38 #ifndef __INCLUDE_MIST_VOLUMERENDER__
39 #define __INCLUDE_MIST_VOLUMERENDER__
42 #ifndef __INCLUDE_MIST_CONF_H__
46 #ifndef __INCLUDE_MIST_H__
51 #ifndef __INCLUDE_MIST_COLOR_H__
55 #ifndef __INCLUDE_MIST_VECTOR__
59 #ifndef __INCLUDE_MIST_LIMITS__
64 #ifndef __INCLUDE_MIST_THREAD__
68 #ifndef __INCLUDE_MIST_DISTANCE_TRANSFORM__
96 namespace volumerender
101 typedef T value_type;
107 attribute( ) : pixel( ), alpha( 0 ), has_alpha( false ){ }
112 attribute(
const attribute &a ) : pixel( a.pixel ), alpha( a.alpha ), has_alpha( a.has_alpha ){ }
114 attribute(
const value_type &pix,
double a ) : pixel( pix ), alpha( a ), has_alpha( a > 0.0 ){ }
119 struct attribute_element
121 typedef T value_type;
122 typedef ptrdiff_t difference_type;
125 difference_type value_lower;
126 difference_type value_upper;
130 attribute_element( ) : pixel( ), value_lower( 0 ), value_upper( 0 ), alpha_lower( 0 ), alpha_upper( 0 ){ }
131 attribute_element(
const value_type &pixel, difference_type vs, difference_type ve,
double as,
double ae )
132 : pixel( pixel ), value_lower( vs ), value_upper( ve ), alpha_lower( as ), alpha_upper( ae ){ }
134 attribute_element(
const attribute_element &a ) : pixel( a.pixel ), value_lower( a.value_lower ), value_upper( a.value_upper ), alpha_lower( a.alpha_lower ), alpha_upper( a.alpha_upper ){ }
139 class attribute_table :
protected std::vector< attribute< T > >
142 typedef std::vector< attribute< T > > base;
143 typedef attribute< T > attribute_type;
144 typedef attribute_element< T > attribute_element_type;
145 typedef typename base::allocator_type allocator_type;
146 typedef typename base::reference reference;
147 typedef typename base::const_reference const_reference;
148 typedef typename base::value_type value_type;
149 typedef typename base::size_type size_type;
150 typedef typename base::difference_type difference_type;
151 typedef typename base::pointer pointer;
152 typedef typename base::const_pointer const_pointer;
154 typedef T pixel_type;
155 typedef std::vector< attribute_element_type > attribute_element_list;
158 difference_type sindex_;
159 difference_type eindex_;
160 difference_type zero_index_;
162 attribute_element_list attribute_element_table;
165 void append(
const pixel_type &pixel, difference_type vs, difference_type ve,
double as,
double ae )
173 difference_type tmp = vs;
177 vs = vs < sindex_ ? sindex_: vs;
178 vs = vs > eindex_ ? eindex_: vs;
179 ve = ve < sindex_ ? sindex_: ve;
180 ve = ve > eindex_ ? eindex_: ve;
189 attribute_element_table.push_back( attribute_element_type( pixel, vs, ve, as, ae ) );
191 double step = ( ae - as ) / static_cast< double >( ve - vs + 1 );
192 for( difference_type i = vs ; i <= ve ; i++ )
194 value_type &p = at( i );
196 p.alpha = as +
static_cast< double >( i - vs ) * step;
197 p.has_alpha = p.alpha > 0.0;
202 const difference_type minimum( )
const
207 const difference_type maximum( )
const
212 const bool empty( )
const
214 return( eindex_ < sindex_ );
217 value_type &operator []( difference_type index )
219 return( base::operator []( zero_index_ + index ) );
222 value_type &at( difference_type index )
224 return( base::at( zero_index_ + index ) );
227 const value_type &operator []( difference_type index )
const
229 return( base::operator []( zero_index_ + index ) );
232 const value_type &at( difference_type index )
const
234 return( base::at( zero_index_ + index ) );
237 bool has_alpha( difference_type index )
const
239 return(
operator []( index ).has_alpha );
242 const attribute_table &operator =(
const attribute_table &a )
246 base::operator =( a );
249 zero_index_ = a.zero_index_;
250 attribute_element_table = a.attribute_element_table;
255 const attribute_element_list &attribute_elements( )
const {
return( attribute_element_table ); }
259 void create( difference_type si, difference_type ei )
264 base::resize( ei - si + 1 );
268 attribute_element_table.clear( );
277 attribute_element_table.clear( );
282 for( size_type i = 0 ; i < base::size( ) ; i++ )
284 base::operator []( i ) = attribute_type( );
286 attribute_element_table.clear( );
289 attribute_table( ) : sindex_( 0 ), eindex_( -1 ), zero_index_( 0 ){ }
291 attribute_table( difference_type si, difference_type ei ) : base( ei - si + 1 ), sindex_( si ), eindex_( ei ), zero_index_( 0 )
296 attribute_table(
const attribute_table &a ) : base( a ), sindex_( a.sindex_ ), eindex_( a.eindex_ ), zero_index_( a.zero_index_ ), attribute_element_table( a.attribute_element_table )
317 boundingbox( ) : a( 0 ), b( 0 ), c( 0 ), d( 0 ){ }
318 boundingbox(
double aa,
double bb,
double cc,
double dd ) : a( aa ), b( bb ), c( cc ), d( dd ){ }
323 inline bool check_intersection( vector3< T > &p1, vector3< T > &p2,
const boundingbox &box )
325 typedef vector3< T > vector_type;
326 typedef typename vector3< T >::value_type value_type;
328 vector_type n( box.a, box.b, box.c );
330 value_type d1 = p1.inner( n );
331 value_type d2 = p2.inner( n );
332 bool c1 = box.d + d1 >= 0;
333 bool c2 = box.d + d2 >= 0;
339 else if( !c1 && !c2 )
347 p1 = v2 + ( v1 - v2 ) * ( ( box.d + d2 ) / ( d2 - d1 ) );
351 p2 = v1 + ( v2 - v1 ) * ( ( box.d + d1 ) / ( d1 - d2 ) );
357 inline bool check_intersection( vector3< T > &p1, vector3< T > &p2,
const boundingbox &box, vector3< T > &normal )
359 typedef vector3< T > vector_type;
360 typedef typename vector3< T >::value_type value_type;
362 vector_type n( box.a, box.b, box.c );
364 value_type d1 = p1.inner( n );
365 value_type d2 = p2.inner( n );
366 bool c1 = box.d + d1 >= 0;
367 bool c2 = box.d + d2 >= 0;
373 else if( !c1 && !c2 )
381 p1 = v2 + ( v1 - v2 ) * ( ( box.d + d2 ) / ( d2 - d1 ) );
386 p2 = v1 + ( v2 - v1 ) * ( ( box.d + d1 ) / ( d1 - d2 ) );
393 typedef vector3< double > vector_type;
399 bool perspective_view;
401 bool value_interpolation;
403 double ambient_ratio;
404 double diffuse_ratio;
405 double light_attenuation;
406 double sampling_step;
414 boundingbox box[ 6 ];
416 parameter( ) : perspective_view( true ), mirror_view( false ), value_interpolation( true ), fovy( 80.0 ), ambient_ratio( 0.4 ), diffuse_ratio( 0.6 ),
417 light_attenuation( 0.0 ), sampling_step( 1.0 ), termination( 0.01 ), specular( 1.0 ), background_R( 0.0 ), background_G( 0.0 ), background_B( 0.0 )
422 inline std::ostream &
operator <<( std::ostream &out,
const parameter &p )
424 out <<
"Pos = ( " << p.pos <<
" )" << std::endl;
425 out <<
"Dir = ( " << p.dir <<
" )" << std::endl;
426 out <<
"Up = ( " << p.up <<
" )" << std::endl;
428 out <<
"BOX Center = ( " << p.offset <<
" )" << std::endl;
430 out <<
"Perspective = " << p.perspective_view << std::endl;
431 out <<
"Mirror View = " << p.mirror_view << std::endl;
432 out <<
"ValueInterpolation = " << p.value_interpolation << std::endl;
433 out <<
"Fovy = " << p.fovy << std::endl;
434 out <<
"Ambient = " << p.ambient_ratio << std::endl;
435 out <<
"Diffuse = " << p.diffuse_ratio << std::endl;
436 out <<
"Specular = " << p.specular << std::endl;
437 out <<
"LightAtten = " << p.light_attenuation << std::endl;
438 out <<
"SamplingStep = " << p.sampling_step << std::endl;
439 out <<
"Termination = " << p.termination << std::endl;
446 typedef ptrdiff_t difference_type;
447 double operator()( difference_type i, difference_type j, difference_type k )
const
453 template <
class DepthMap >
456 typedef DepthMap depth_map_type;
457 typedef typename depth_map_type::difference_type difference_type;
459 const depth_map_type &depth_map_;
461 depth_map(
const depth_map_type &dmap ) : depth_map_( dmap )
465 double operator()( difference_type i, difference_type j, difference_type k )
const
467 double l = depth_map_( i >> 2, j >> 2, k >> 2 );
468 return( l < 1.0 ? 2.0 : l * 4.0 - 2.0 );
476 inline long to_integer(
double val )
478 return( static_cast< long >( val ) );
484 inline void normalize_vector( vector3< T > &v )
486 double len = std::sqrt( v.x * v.x + v.y * v.y + v.z * v.z ) + 1.0e-10;
492 inline double _3(
double v )
496 return( - std::pow( -v, 1.0 / 3.0 ) );
500 return( std::pow( v, 1.0 / 3.0 ) );
508 inline double __maximum__(
double v1,
double v2 )
510 return( v1 > v2 ? v1 : v2 );
513 inline double __maximum__(
double v1,
double v2,
double v3 )
536 inline double __minimum__(
double v1,
double v2 )
538 return( v1 < v2 ? v1 : v2 );
541 inline double __minimum__(
double v1,
double v2,
double v3 )
564 inline size_t solve_equation(
double p,
double q,
double &v1,
double &v2,
double &v3 )
566 const double pai = 3.1415926535897932384626433832795;
567 double p_3 = p / 3.0;
568 double q_2 = q / 2.0;
569 double D = - ( q_2 * q_2 + p_3 * p_3 * p_3 );
573 double r = std::sqrt( - 4.0 * p / 3.0 );
574 double t1 = 1.0 / ( 3.0 * std::cos( 3.0 * q / ( p * r ) ) );
575 double t2 = 2.0 * pai / 3.0 + t1;
576 double t3 = 2.0 * pai / 3.0 - t1;
577 v1 = r * std::cos( t1 );
578 v2 = r * std::cos( t2 );
579 v3 = r * std::cos( t3 );
591 double r = std::sqrt( - 4.0 * p / 3.0 );
593 v2 = r * std::cos( 2.0 * pai / 3.0 );
607 double _D = std::sqrt( -D );
608 v1 = _3( - q / 2.0 + _D ) + _3( - q / 2.0 - _D );
614 inline size_t solve_equation(
double a,
double b,
double c,
double d,
double &v1,
double &v2,
double &v3 )
622 return( solve_equation( ( - b * b / ( 3.0 * a ) + c ) / a, ( 2.0 * b * b * b / ( 27.0 * a * a ) - b * c / ( 3.0 * a ) + d ) / a, v1, v2, v3 ) );
634 namespace rendering_helper
636 template <
class Array,
class T >
637 class value_interpolation
640 typedef typename volumerender::parameter::vector_type vector_type;
641 typedef typename Array::size_type size_type;
642 typedef typename Array::const_pointer const_pointer;
643 typedef typename Array::difference_type difference_type;
644 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
648 const volumerender::parameter &p;
649 const volumerender::attribute_table< T > &table;
650 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
652 value_interpolation(
const Array &image,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &tbl ) : in( image ), p( param ), table( tbl )
654 difference_type cx = in.width( ) / 2;
655 difference_type cy = in.height( ) / 2;
656 difference_type cz = in.depth( ) / 2;
657 const_pointer ppp = &in( cx, cy, cz );
659 d1 = &in( cx , cy + 1, cz ) - ppp;
660 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
661 d3 = &in( cx + 1, cy , cz ) - ppp;
662 d4 = &in( cx , cy , cz + 1 ) - ppp;
663 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
664 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
665 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
666 _1 = &in( cx + 1, cy , cz ) - ppp;
667 _2 = &in( cx , cy + 1, cz ) - ppp;
668 _3 = &in( cx , cy , cz + 1 ) - ppp;
671 bool check( difference_type i, difference_type j, difference_type k )
const
673 const_pointer p = &in( i, j, k );
676 return( table.has_alpha( p[ d0 ] ) || table.has_alpha( p[ d1 ] ) ||
677 table.has_alpha( p[ d2 ] ) || table.has_alpha( p[ d3 ] ) ||
678 table.has_alpha( p[ d4 ] ) || table.has_alpha( p[ d5 ] ) ||
679 table.has_alpha( p[ d6 ] ) || table.has_alpha( p[ d7 ] ) );
682 bool render( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz, attribute_type &oc )
const
684 const_pointer p = &in( i, j, k );
687 double ct = ( p[ d0 ] + ( p[ d3 ] - p[ d0 ] ) * xx ) + ( p[ d1 ] - p[ d0 ] + ( p[ d0 ] - p[ d1 ] + p[ d2 ] - p[ d3 ] ) * xx ) * yy;
688 ct += ( ( p[ d4 ] + ( p[ d7 ] - p[ d4 ] ) * xx ) + ( p[ d5 ] - p[ d4 ] + ( p[ d4 ] - p[ d5 ] + p[ d6 ] - p[ d7 ] ) * xx ) * yy - ct ) * zz;
690 oc = table[ volumerender::to_integer( ct ) ];
692 return( oc.has_alpha );
695 vector_type normal( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz )
const
697 const_pointer p0 = &in( i, j, k );
698 const_pointer p1 = p0 + d1;
699 const_pointer p2 = p0 + d2;
700 const_pointer p3 = p0 + d3;
701 const_pointer p4 = p0 + d4;
702 const_pointer p5 = p0 + d5;
703 const_pointer p6 = p0 + d6;
704 const_pointer p7 = p0 + d7;
706 double n0x = p3[ 0 ] - p0[ -_1 ];
707 double n0y = p1[ 0 ] - p0[ -_2 ];
708 double n0z = p4[ 0 ] - p0[ -_3 ];
709 double n1x = p2[ 0 ] - p1[ -_1 ];
710 double n1y = p1[ _2 ] - p0[ 0 ];
711 double n1z = p5[ 0 ] - p1[ -_3 ];
712 double n2x = p2[ _1 ] - p1[ 0 ];
713 double n2y = p2[ _2 ] - p3[ 0 ];
714 double n2z = p6[ 0 ] - p2[ -_3 ];
715 double n3x = p3[ _1 ] - p0[ 0 ];
716 double n3y = p2[ 0 ] - p3[ -_2 ];
717 double n3z = p7[ 0 ] - p3[ -_3 ];
718 double n4x = p7[ 0 ] - p4[ -_1 ];
719 double n4y = p5[ 0 ] - p4[ -_2 ];
720 double n4z = p4[ _3 ] - p0[ 0 ];
721 double n5x = p6[ 0 ] - p5[ -_1 ];
722 double n5y = p5[ _2 ] - p4[ 0 ];
723 double n5z = p5[ _3 ] - p1[ 0 ];
724 double n6x = p6[ _1 ] - p5[ 0 ];
725 double n6y = p6[ _2 ] - p7[ 0 ];
726 double n6z = p6[ _3 ] - p2[ 0 ];
727 double n7x = p7[ _1 ] - p4[ 0 ];
728 double n7y = p6[ 0 ] - p7[ -_2 ];
729 double n7z = p7[ _3 ] - p3[ 0 ];
731 double nx = ( n0x + ( n3x - n0x ) * xx ) + ( n1x - n0x + ( n0x - n1x + n2x - n3x ) * xx ) * yy;
732 nx += ( ( n4x + ( n7x - n4x ) * xx ) + ( n5x - n4x + ( n4x - n5x + n6x - n7x ) * xx ) * yy - nx ) * zz;
733 double ny = ( n0y + ( n3y - n0y ) * xx ) + ( n1y - n0y + ( n0y - n1y + n2y - n3y ) * xx ) * yy;
734 ny += ( ( n4y + ( n7y - n4y ) * xx ) + ( n5y - n4y + ( n4y - n5y + n6y - n7y ) * xx ) * yy - ny ) * zz;
735 double nz = ( n0z + ( n3z - n0z ) * xx ) + ( n1z - n0z + ( n0z - n1z + n2z - n3z ) * xx ) * yy;
736 nz += ( ( n4z + ( n7z - n4z ) * xx ) + ( n5z - n4z + ( n4z - n5z + n6z - n7z ) * xx ) * yy - nz ) * zz;
741 double len = std::sqrt( nx * nx + ny * ny + nz * nz ) + type_limits< double >::tiny( );
746 return( vector_type( nx, ny, nz ) );
751 template <
class Array,
class T >
752 class color_interpolation
755 typedef typename volumerender::parameter::vector_type vector_type;
756 typedef typename Array::size_type size_type;
757 typedef typename Array::const_pointer const_pointer;
758 typedef typename Array::difference_type difference_type;
759 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
763 const volumerender::parameter &p;
764 const volumerender::attribute_table< T > &table;
765 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
767 color_interpolation(
const Array &image,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &tbl ) : in( image ), p( param ), table( tbl )
769 difference_type cx = in.width( ) / 2;
770 difference_type cy = in.height( ) / 2;
771 difference_type cz = in.depth( ) / 2;
772 const_pointer ppp = &in( cx, cy, cz );
774 d1 = &in( cx , cy + 1, cz ) - ppp;
775 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
776 d3 = &in( cx + 1, cy , cz ) - ppp;
777 d4 = &in( cx , cy , cz + 1 ) - ppp;
778 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
779 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
780 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
781 _1 = &in( cx + 1, cy , cz ) - ppp;
782 _2 = &in( cx , cy + 1, cz ) - ppp;
783 _3 = &in( cx , cy , cz + 1 ) - ppp;
786 bool check( difference_type i, difference_type j, difference_type k )
const
788 const_pointer p = &in( i, j, k );
791 return( table.has_alpha( p[ d0 ] ) || table.has_alpha( p[ d1 ] ) ||
792 table.has_alpha( p[ d2 ] ) || table.has_alpha( p[ d3 ] ) ||
793 table.has_alpha( p[ d4 ] ) || table.has_alpha( p[ d5 ] ) ||
794 table.has_alpha( p[ d6 ] ) || table.has_alpha( p[ d7 ] ) );
797 bool render( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz, attribute_type &oc )
const
799 const_pointer p = &in( i, j, k );
802 attribute_type oc0 = table[ volumerender::to_integer( p[ d0 ] ) ];
803 attribute_type oc1 = table[ volumerender::to_integer( p[ d1 ] ) ];
804 attribute_type oc2 = table[ volumerender::to_integer( p[ d2 ] ) ];
805 attribute_type oc3 = table[ volumerender::to_integer( p[ d3 ] ) ];
806 attribute_type oc4 = table[ volumerender::to_integer( p[ d4 ] ) ];
807 attribute_type oc5 = table[ volumerender::to_integer( p[ d5 ] ) ];
808 attribute_type oc6 = table[ volumerender::to_integer( p[ d6 ] ) ];
809 attribute_type oc7 = table[ volumerender::to_integer( p[ d7 ] ) ];
811 int number_of_visible_voxels = oc0.has_alpha;
812 number_of_visible_voxels += oc1.has_alpha;
813 number_of_visible_voxels += oc2.has_alpha;
814 number_of_visible_voxels += oc3.has_alpha;
815 number_of_visible_voxels += oc4.has_alpha;
816 number_of_visible_voxels += oc5.has_alpha;
817 number_of_visible_voxels += oc6.has_alpha;
818 number_of_visible_voxels += oc7.has_alpha;
820 if( number_of_visible_voxels == 0 )
827 oc.pixel = ( oc0.pixel * oc0.has_alpha + oc1.pixel * oc1.has_alpha
828 + oc2.pixel * oc2.has_alpha + oc3.pixel * oc3.has_alpha
829 + oc4.pixel * oc4.has_alpha + oc5.pixel * oc5.has_alpha
830 + oc6.pixel * oc6.has_alpha + oc7.pixel * oc7.has_alpha ) / static_cast< double >( number_of_visible_voxels );
833 if( !oc0.has_alpha ){ oc0.pixel = oc.pixel; }
834 if( !oc1.has_alpha ){ oc1.pixel = oc.pixel; }
835 if( !oc2.has_alpha ){ oc2.pixel = oc.pixel; }
836 if( !oc3.has_alpha ){ oc3.pixel = oc.pixel; }
837 if( !oc4.has_alpha ){ oc4.pixel = oc.pixel; }
838 if( !oc5.has_alpha ){ oc5.pixel = oc.pixel; }
839 if( !oc6.has_alpha ){ oc6.pixel = oc.pixel; }
840 if( !oc7.has_alpha ){ oc7.pixel = oc.pixel; }
842 oc.pixel = ( oc0.pixel + ( oc3.pixel - oc0.pixel ) * xx ) + ( oc1.pixel - oc0.pixel + ( oc0.pixel - oc1.pixel + oc2.pixel - oc3.pixel ) * xx ) * yy;
843 oc.pixel = oc.pixel + ( ( oc4.pixel + ( oc7.pixel - oc4.pixel ) * xx ) + ( oc5.pixel - oc4.pixel + ( oc4.pixel - oc5.pixel + oc6.pixel - oc7.pixel ) * xx ) * yy - oc.pixel ) * zz;
844 oc.alpha = ( oc0.alpha + ( oc3.alpha - oc0.alpha ) * xx ) + ( oc1.alpha - oc0.alpha + ( oc0.alpha - oc1.alpha + oc2.alpha - oc3.alpha ) * xx ) * yy;
845 oc.alpha = oc.alpha + ( ( oc4.alpha + ( oc7.alpha - oc4.alpha ) * xx ) + ( oc5.alpha - oc4.alpha + ( oc4.alpha - oc5.alpha + oc6.alpha - oc7.alpha ) * xx ) * yy - oc.alpha ) * zz;
851 vector_type normal( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz )
const
853 const_pointer p0 = &in( i, j, k );
854 const_pointer p1 = p0 + d1;
855 const_pointer p2 = p0 + d2;
856 const_pointer p3 = p0 + d3;
857 const_pointer p4 = p0 + d4;
858 const_pointer p5 = p0 + d5;
859 const_pointer p6 = p0 + d6;
860 const_pointer p7 = p0 + d7;
862 double n0x = p3[ 0 ] - p0[ -_1 ];
863 double n0y = p1[ 0 ] - p0[ -_2 ];
864 double n0z = p4[ 0 ] - p0[ -_3 ];
865 double n1x = p2[ 0 ] - p1[ -_1 ];
866 double n1y = p1[ _2 ] - p0[ 0 ];
867 double n1z = p5[ 0 ] - p1[ -_3 ];
868 double n2x = p2[ _1 ] - p1[ 0 ];
869 double n2y = p2[ _2 ] - p3[ 0 ];
870 double n2z = p6[ 0 ] - p2[ -_3 ];
871 double n3x = p3[ _1 ] - p0[ 0 ];
872 double n3y = p2[ 0 ] - p3[ -_2 ];
873 double n3z = p7[ 0 ] - p3[ -_3 ];
874 double n4x = p7[ 0 ] - p4[ -_1 ];
875 double n4y = p5[ 0 ] - p4[ -_2 ];
876 double n4z = p4[ _3 ] - p0[ 0 ];
877 double n5x = p6[ 0 ] - p5[ -_1 ];
878 double n5y = p5[ _2 ] - p4[ 0 ];
879 double n5z = p5[ _3 ] - p1[ 0 ];
880 double n6x = p6[ _1 ] - p5[ 0 ];
881 double n6y = p6[ _2 ] - p7[ 0 ];
882 double n6z = p6[ _3 ] - p2[ 0 ];
883 double n7x = p7[ _1 ] - p4[ 0 ];
884 double n7y = p6[ 0 ] - p7[ -_2 ];
885 double n7z = p7[ _3 ] - p3[ 0 ];
887 double nx = ( n0x + ( n3x - n0x ) * xx ) + ( n1x - n0x + ( n0x - n1x + n2x - n3x ) * xx ) * yy;
888 nx += ( ( n4x + ( n7x - n4x ) * xx ) + ( n5x - n4x + ( n4x - n5x + n6x - n7x ) * xx ) * yy - nx ) * zz;
889 double ny = ( n0y + ( n3y - n0y ) * xx ) + ( n1y - n0y + ( n0y - n1y + n2y - n3y ) * xx ) * yy;
890 ny += ( ( n4y + ( n7y - n4y ) * xx ) + ( n5y - n4y + ( n4y - n5y + n6y - n7y ) * xx ) * yy - ny ) * zz;
891 double nz = ( n0z + ( n3z - n0z ) * xx ) + ( n1z - n0z + ( n0z - n1z + n2z - n3z ) * xx ) * yy;
892 nz += ( ( n4z + ( n7z - n4z ) * xx ) + ( n5z - n4z + ( n4z - n5z + n6z - n7z ) * xx ) * yy - nz ) * zz;
897 double len = std::sqrt( nx * nx + ny * ny + nz * nz ) + type_limits< double >::tiny( );
902 return( vector_type( nx, ny, nz ) );
907 template <
class Array1,
class Array2,
class T >
908 class value_interpolation_with_mark
911 typedef typename volumerender::parameter::vector_type vector_type;
912 typedef typename Array1::size_type size_type;
913 typedef typename Array1::const_pointer const_pointer;
914 typedef typename Array2::const_pointer const_mk_pointer;
915 typedef typename Array1::difference_type difference_type;
916 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
921 const volumerender::parameter &p;
922 const volumerender::attribute_table< T > &table;
923 const volumerender::attribute_table< T > &mktable;
924 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
926 value_interpolation_with_mark(
const Array1 &image,
const Array2 &mark,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &tbl,
const volumerender::attribute_table< T > &mktbl )
927 : in( image ), mk( mark ), p( param ), table( tbl ), mktable( mktbl )
929 difference_type cx = in.width( ) / 2;
930 difference_type cy = in.height( ) / 2;
931 difference_type cz = in.depth( ) / 2;
932 const_pointer ppp = &in( cx, cy, cz );
934 d1 = &in( cx , cy + 1, cz ) - ppp;
935 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
936 d3 = &in( cx + 1, cy , cz ) - ppp;
937 d4 = &in( cx , cy , cz + 1 ) - ppp;
938 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
939 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
940 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
941 _1 = &in( cx + 1, cy , cz ) - ppp;
942 _2 = &in( cx , cy + 1, cz ) - ppp;
943 _3 = &in( cx , cy , cz + 1 ) - ppp;
946 bool check( difference_type i, difference_type j, difference_type k )
const
948 const_pointer p = &in( i, j, k );
951 return( table.has_alpha( p[ d0 ] ) || table.has_alpha( p[ d1 ] ) ||
952 table.has_alpha( p[ d2 ] ) || table.has_alpha( p[ d3 ] ) ||
953 table.has_alpha( p[ d4 ] ) || table.has_alpha( p[ d5 ] ) ||
954 table.has_alpha( p[ d6 ] ) || table.has_alpha( p[ d7 ] ) );
957 bool render( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz, attribute_type &oc )
const
959 const_pointer p = &in( i, j, k );
962 double ct = ( p[ d0 ] + ( p[ d3 ] - p[ d0 ] ) * xx ) + ( p[ d1 ] - p[ d0 ] + ( p[ d0 ] - p[ d1 ] + p[ d2 ] - p[ d3 ] ) * xx ) * yy;
963 ct += ( ( p[ d4 ] + ( p[ d7 ] - p[ d4 ] ) * xx ) + ( p[ d5 ] - p[ d4 ] + ( p[ d4 ] - p[ d5 ] + p[ d6 ] - p[ d7 ] ) * xx ) * yy - ct ) * zz;
965 oc = table[ volumerender::to_integer( ct ) ];
974 const_mk_pointer pm = &mk( i, j, k );
977 attribute_type mc0 = mktable[ volumerender::to_integer( pm[ d0 ] ) ];
978 attribute_type mc1 = mktable[ volumerender::to_integer( pm[ d1 ] ) ];
979 attribute_type mc2 = mktable[ volumerender::to_integer( pm[ d2 ] ) ];
980 attribute_type mc3 = mktable[ volumerender::to_integer( pm[ d3 ] ) ];
981 attribute_type mc4 = mktable[ volumerender::to_integer( pm[ d4 ] ) ];
982 attribute_type mc5 = mktable[ volumerender::to_integer( pm[ d5 ] ) ];
983 attribute_type mc6 = mktable[ volumerender::to_integer( pm[ d6 ] ) ];
984 attribute_type mc7 = mktable[ volumerender::to_integer( pm[ d7 ] ) ];
986 int number_of_visible_voxels = mc0.has_alpha;
987 number_of_visible_voxels += mc1.has_alpha;
988 number_of_visible_voxels += mc2.has_alpha;
989 number_of_visible_voxels += mc3.has_alpha;
990 number_of_visible_voxels += mc4.has_alpha;
991 number_of_visible_voxels += mc5.has_alpha;
992 number_of_visible_voxels += mc6.has_alpha;
993 number_of_visible_voxels += mc7.has_alpha;
995 if( number_of_visible_voxels > 0 )
999 mc.pixel = ( mc0.pixel * mc0.has_alpha + mc1.pixel * mc1.has_alpha
1000 + mc2.pixel * mc2.has_alpha + mc3.pixel * mc3.has_alpha
1001 + mc4.pixel * mc4.has_alpha + mc5.pixel * mc5.has_alpha
1002 + mc6.pixel * mc6.has_alpha + mc7.pixel * mc7.has_alpha ) / static_cast< double >( number_of_visible_voxels );
1005 if( !mc0.has_alpha ){ mc0.pixel = mc.pixel; }
1006 if( !mc1.has_alpha ){ mc1.pixel = mc.pixel; }
1007 if( !mc2.has_alpha ){ mc2.pixel = mc.pixel; }
1008 if( !mc3.has_alpha ){ mc3.pixel = mc.pixel; }
1009 if( !mc4.has_alpha ){ mc4.pixel = mc.pixel; }
1010 if( !mc5.has_alpha ){ mc5.pixel = mc.pixel; }
1011 if( !mc6.has_alpha ){ mc6.pixel = mc.pixel; }
1012 if( !mc7.has_alpha ){ mc7.pixel = mc.pixel; }
1014 mc.pixel = ( mc0.pixel + ( mc3.pixel - mc0.pixel ) * xx ) + ( mc1.pixel - mc0.pixel + ( mc0.pixel - mc1.pixel + mc2.pixel - mc3.pixel ) * xx ) * yy;
1015 mc.pixel = mc.pixel + ( ( mc4.pixel + ( mc7.pixel - mc4.pixel ) * xx ) + ( mc5.pixel - mc4.pixel + ( mc4.pixel - mc5.pixel + mc6.pixel - mc7.pixel ) * xx ) * yy - mc.pixel ) * zz;
1016 mc.alpha = ( mc0.alpha + ( mc3.alpha - mc0.alpha ) * xx ) + ( mc1.alpha - mc0.alpha + ( mc0.alpha - mc1.alpha + mc2.alpha - mc3.alpha ) * xx ) * yy;
1017 mc.alpha = mc.alpha + ( ( mc4.alpha + ( mc7.alpha - mc4.alpha ) * xx ) + ( mc5.alpha - mc4.alpha + ( mc4.alpha - mc5.alpha + mc6.alpha - mc7.alpha ) * xx ) * yy - mc.alpha ) * zz;
1020 oc.pixel = oc.pixel * ( 1.0 - mc.alpha ) + mc.pixel * mc.alpha;
1027 vector_type normal( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz )
const
1029 const_pointer p0 = &in( i, j, k );
1030 const_pointer p1 = p0 + d1;
1031 const_pointer p2 = p0 + d2;
1032 const_pointer p3 = p0 + d3;
1033 const_pointer p4 = p0 + d4;
1034 const_pointer p5 = p0 + d5;
1035 const_pointer p6 = p0 + d6;
1036 const_pointer p7 = p0 + d7;
1038 double n0x = p3[ 0 ] - p0[ -_1 ];
1039 double n0y = p1[ 0 ] - p0[ -_2 ];
1040 double n0z = p4[ 0 ] - p0[ -_3 ];
1041 double n1x = p2[ 0 ] - p1[ -_1 ];
1042 double n1y = p1[ _2 ] - p0[ 0 ];
1043 double n1z = p5[ 0 ] - p1[ -_3 ];
1044 double n2x = p2[ _1 ] - p1[ 0 ];
1045 double n2y = p2[ _2 ] - p3[ 0 ];
1046 double n2z = p6[ 0 ] - p2[ -_3 ];
1047 double n3x = p3[ _1 ] - p0[ 0 ];
1048 double n3y = p2[ 0 ] - p3[ -_2 ];
1049 double n3z = p7[ 0 ] - p3[ -_3 ];
1050 double n4x = p7[ 0 ] - p4[ -_1 ];
1051 double n4y = p5[ 0 ] - p4[ -_2 ];
1052 double n4z = p4[ _3 ] - p0[ 0 ];
1053 double n5x = p6[ 0 ] - p5[ -_1 ];
1054 double n5y = p5[ _2 ] - p4[ 0 ];
1055 double n5z = p5[ _3 ] - p1[ 0 ];
1056 double n6x = p6[ _1 ] - p5[ 0 ];
1057 double n6y = p6[ _2 ] - p7[ 0 ];
1058 double n6z = p6[ _3 ] - p2[ 0 ];
1059 double n7x = p7[ _1 ] - p4[ 0 ];
1060 double n7y = p6[ 0 ] - p7[ -_2 ];
1061 double n7z = p7[ _3 ] - p3[ 0 ];
1063 double nx = ( n0x + ( n3x - n0x ) * xx ) + ( n1x - n0x + ( n0x - n1x + n2x - n3x ) * xx ) * yy;
1064 nx += ( ( n4x + ( n7x - n4x ) * xx ) + ( n5x - n4x + ( n4x - n5x + n6x - n7x ) * xx ) * yy - nx ) * zz;
1065 double ny = ( n0y + ( n3y - n0y ) * xx ) + ( n1y - n0y + ( n0y - n1y + n2y - n3y ) * xx ) * yy;
1066 ny += ( ( n4y + ( n7y - n4y ) * xx ) + ( n5y - n4y + ( n4y - n5y + n6y - n7y ) * xx ) * yy - ny ) * zz;
1067 double nz = ( n0z + ( n3z - n0z ) * xx ) + ( n1z - n0z + ( n0z - n1z + n2z - n3z ) * xx ) * yy;
1068 nz += ( ( n4z + ( n7z - n4z ) * xx ) + ( n5z - n4z + ( n4z - n5z + n6z - n7z ) * xx ) * yy - nz ) * zz;
1073 double len = std::sqrt( nx * nx + ny * ny + nz * nz ) + type_limits< double >::tiny( );
1078 return( vector_type( nx, ny, nz ) );
1083 template <
class Array1,
class Array2,
class T >
1084 class value_interpolation_and_mark
1087 typedef typename volumerender::parameter::vector_type vector_type;
1088 typedef typename Array1::size_type size_type;
1089 typedef typename Array1::const_pointer const_pointer;
1090 typedef typename Array2::const_pointer const_mk_pointer;
1091 typedef typename Array1::difference_type difference_type;
1092 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
1097 const volumerender::parameter &p;
1098 const volumerender::attribute_table< T > &table;
1099 const volumerender::attribute_table< T > &mktable;
1100 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
1102 value_interpolation_and_mark(
const Array1 &image,
const Array2 &mark,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &tbl,
const volumerender::attribute_table< T > &mktbl )
1103 : in( image ), mk( mark ), p( param ), table( tbl ), mktable( mktbl )
1105 difference_type cx = in.width( ) / 2;
1106 difference_type cy = in.height( ) / 2;
1107 difference_type cz = in.depth( ) / 2;
1108 const_pointer ppp = &in( cx, cy, cz );
1110 d1 = &in( cx , cy + 1, cz ) - ppp;
1111 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
1112 d3 = &in( cx + 1, cy , cz ) - ppp;
1113 d4 = &in( cx , cy , cz + 1 ) - ppp;
1114 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
1115 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
1116 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
1117 _1 = &in( cx + 1, cy , cz ) - ppp;
1118 _2 = &in( cx , cy + 1, cz ) - ppp;
1119 _3 = &in( cx , cy , cz + 1 ) - ppp;
1122 bool check( difference_type i, difference_type j, difference_type k )
const
1124 const_pointer p = &in( i, j, k );
1125 const_mk_pointer pm = &mk( i, j, k );
1128 return( ( table.has_alpha( p[ d0 ] ) || table.has_alpha( p[ d1 ] ) || table.has_alpha( p[ d2 ] ) ||
1129 table.has_alpha( p[ d3 ] ) || table.has_alpha( p[ d4 ] ) || table.has_alpha( p[ d5 ] ) ||
1130 table.has_alpha( p[ d6 ] ) || table.has_alpha( p[ d7 ] ) ) &&
1131 ( mktable.has_alpha( pm[ d0 ] ) || mktable.has_alpha( pm[ d1 ] ) || mktable.has_alpha( pm[ d2 ] ) ||
1132 mktable.has_alpha( pm[ d3 ] ) || mktable.has_alpha( pm[ d4 ] ) || mktable.has_alpha( pm[ d5 ] ) ||
1133 mktable.has_alpha( pm[ d6 ] ) || mktable.has_alpha( pm[ d7 ] ) ) );
1136 bool render( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz, attribute_type &oc )
const
1139 const_mk_pointer pm = &mk( i, j, k );
1142 const attribute_type &mc0 = mktable[ volumerender::to_integer( pm[ d0 ] ) ];
1143 const attribute_type &mc1 = mktable[ volumerender::to_integer( pm[ d1 ] ) ];
1144 const attribute_type &mc2 = mktable[ volumerender::to_integer( pm[ d2 ] ) ];
1145 const attribute_type &mc3 = mktable[ volumerender::to_integer( pm[ d3 ] ) ];
1146 const attribute_type &mc4 = mktable[ volumerender::to_integer( pm[ d4 ] ) ];
1147 const attribute_type &mc5 = mktable[ volumerender::to_integer( pm[ d5 ] ) ];
1148 const attribute_type &mc6 = mktable[ volumerender::to_integer( pm[ d6 ] ) ];
1149 const attribute_type &mc7 = mktable[ volumerender::to_integer( pm[ d7 ] ) ];
1151 int number_of_visible_voxels = mc0.has_alpha;
1152 number_of_visible_voxels += mc1.has_alpha;
1153 number_of_visible_voxels += mc2.has_alpha;
1154 number_of_visible_voxels += mc3.has_alpha;
1155 number_of_visible_voxels += mc4.has_alpha;
1156 number_of_visible_voxels += mc5.has_alpha;
1157 number_of_visible_voxels += mc6.has_alpha;
1158 number_of_visible_voxels += mc7.has_alpha;
1160 if( number_of_visible_voxels > 0 )
1162 const_pointer p = &in( i, j, k );
1165 double ct = ( p[ d0 ] + ( p[ d3 ] - p[ d0 ] ) * xx ) + ( p[ d1 ] - p[ d0 ] + ( p[ d0 ] - p[ d1 ] + p[ d2 ] - p[ d3 ] ) * xx ) * yy;
1166 ct += ( ( p[ d4 ] + ( p[ d7 ] - p[ d4 ] ) * xx ) + ( p[ d5 ] - p[ d4 ] + ( p[ d4 ] - p[ d5 ] + p[ d6 ] - p[ d7 ] ) * xx ) * yy - ct ) * zz;
1168 oc = table[ volumerender::to_integer( ct ) ];
1171 double alpha = ( mc0.alpha + ( mc3.alpha - mc0.alpha ) * xx ) + ( mc1.alpha - mc0.alpha + ( mc0.alpha - mc1.alpha + mc2.alpha - mc3.alpha ) * xx ) * yy;
1172 alpha = alpha + ( ( mc4.alpha + ( mc7.alpha - mc4.alpha ) * xx ) + ( mc5.alpha - mc4.alpha + ( mc4.alpha - mc5.alpha + mc6.alpha - mc7.alpha ) * xx ) * yy - alpha ) * zz;
1185 vector_type normal( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz )
const
1187 const_pointer p0 = &in( i, j, k );
1188 const_pointer p1 = p0 + d1;
1189 const_pointer p2 = p0 + d2;
1190 const_pointer p3 = p0 + d3;
1191 const_pointer p4 = p0 + d4;
1192 const_pointer p5 = p0 + d5;
1193 const_pointer p6 = p0 + d6;
1194 const_pointer p7 = p0 + d7;
1196 double n0x = p3[ 0 ] - p0[ -_1 ];
1197 double n0y = p1[ 0 ] - p0[ -_2 ];
1198 double n0z = p4[ 0 ] - p0[ -_3 ];
1199 double n1x = p2[ 0 ] - p1[ -_1 ];
1200 double n1y = p1[ _2 ] - p0[ 0 ];
1201 double n1z = p5[ 0 ] - p1[ -_3 ];
1202 double n2x = p2[ _1 ] - p1[ 0 ];
1203 double n2y = p2[ _2 ] - p3[ 0 ];
1204 double n2z = p6[ 0 ] - p2[ -_3 ];
1205 double n3x = p3[ _1 ] - p0[ 0 ];
1206 double n3y = p2[ 0 ] - p3[ -_2 ];
1207 double n3z = p7[ 0 ] - p3[ -_3 ];
1208 double n4x = p7[ 0 ] - p4[ -_1 ];
1209 double n4y = p5[ 0 ] - p4[ -_2 ];
1210 double n4z = p4[ _3 ] - p0[ 0 ];
1211 double n5x = p6[ 0 ] - p5[ -_1 ];
1212 double n5y = p5[ _2 ] - p4[ 0 ];
1213 double n5z = p5[ _3 ] - p1[ 0 ];
1214 double n6x = p6[ _1 ] - p5[ 0 ];
1215 double n6y = p6[ _2 ] - p7[ 0 ];
1216 double n6z = p6[ _3 ] - p2[ 0 ];
1217 double n7x = p7[ _1 ] - p4[ 0 ];
1218 double n7y = p6[ 0 ] - p7[ -_2 ];
1219 double n7z = p7[ _3 ] - p3[ 0 ];
1221 double nx = ( n0x + ( n3x - n0x ) * xx ) + ( n1x - n0x + ( n0x - n1x + n2x - n3x ) * xx ) * yy;
1222 nx += ( ( n4x + ( n7x - n4x ) * xx ) + ( n5x - n4x + ( n4x - n5x + n6x - n7x ) * xx ) * yy - nx ) * zz;
1223 double ny = ( n0y + ( n3y - n0y ) * xx ) + ( n1y - n0y + ( n0y - n1y + n2y - n3y ) * xx ) * yy;
1224 ny += ( ( n4y + ( n7y - n4y ) * xx ) + ( n5y - n4y + ( n4y - n5y + n6y - n7y ) * xx ) * yy - ny ) * zz;
1225 double nz = ( n0z + ( n3z - n0z ) * xx ) + ( n1z - n0z + ( n0z - n1z + n2z - n3z ) * xx ) * yy;
1226 nz += ( ( n4z + ( n7z - n4z ) * xx ) + ( n5z - n4z + ( n4z - n5z + n6z - n7z ) * xx ) * yy - nz ) * zz;
1231 double len = std::sqrt( nx * nx + ny * ny + nz * nz ) + type_limits< double >::tiny( );
1236 return( vector_type( nx, ny, nz ) );
1241 template <
class Array1,
class Array2,
class T >
1242 class value_interpolation_or_mark
1245 typedef typename volumerender::parameter::vector_type vector_type;
1246 typedef typename Array1::size_type size_type;
1247 typedef typename Array1::const_pointer const_pointer;
1248 typedef typename Array2::const_pointer const_mk_pointer;
1249 typedef typename Array1::difference_type difference_type;
1250 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
1255 const volumerender::parameter &p;
1256 const volumerender::attribute_table< T > &table;
1257 const volumerender::attribute_table< T > &mktable;
1258 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
1260 value_interpolation_or_mark(
const Array1 &image,
const Array2 &mark,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &tbl,
const volumerender::attribute_table< T > &mktbl )
1261 : in( image ), mk( mark ), p( param ), table( tbl ), mktable( mktbl )
1263 difference_type cx = in.width( ) / 2;
1264 difference_type cy = in.height( ) / 2;
1265 difference_type cz = in.depth( ) / 2;
1266 const_pointer ppp = &in( cx, cy, cz );
1268 d1 = &in( cx , cy + 1, cz ) - ppp;
1269 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
1270 d3 = &in( cx + 1, cy , cz ) - ppp;
1271 d4 = &in( cx , cy , cz + 1 ) - ppp;
1272 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
1273 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
1274 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
1275 _1 = &in( cx + 1, cy , cz ) - ppp;
1276 _2 = &in( cx , cy + 1, cz ) - ppp;
1277 _3 = &in( cx , cy , cz + 1 ) - ppp;
1280 bool check( difference_type i, difference_type j, difference_type k )
const
1282 const_pointer p = &in( i, j, k );
1283 const_mk_pointer pm = &mk( i, j, k );
1286 return( table.has_alpha( p[ d0 ] ) || table.has_alpha( p[ d1 ] ) ||
1287 table.has_alpha( p[ d2 ] ) || table.has_alpha( p[ d3 ] ) ||
1288 table.has_alpha( p[ d4 ] ) || table.has_alpha( p[ d5 ] ) ||
1289 table.has_alpha( p[ d6 ] ) || table.has_alpha( p[ d7 ] ) ||
1290 mktable.has_alpha( pm[ d0 ] ) || mktable.has_alpha( pm[ d1 ] ) ||
1291 mktable.has_alpha( pm[ d2 ] ) || mktable.has_alpha( pm[ d3 ] ) ||
1292 mktable.has_alpha( pm[ d4 ] ) || mktable.has_alpha( pm[ d5 ] ) ||
1293 mktable.has_alpha( pm[ d6 ] ) || mktable.has_alpha( pm[ d7 ] ) );
1296 bool render( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz, attribute_type &oc )
const
1298 const_pointer p = &in( i, j, k );
1301 double ct = ( p[ d0 ] + ( p[ d3 ] - p[ d0 ] ) * xx ) + ( p[ d1 ] - p[ d0 ] + ( p[ d0 ] - p[ d1 ] + p[ d2 ] - p[ d3 ] ) * xx ) * yy;
1302 ct += ( ( p[ d4 ] + ( p[ d7 ] - p[ d4 ] ) * xx ) + ( p[ d5 ] - p[ d4 ] + ( p[ d4 ] - p[ d5 ] + p[ d6 ] - p[ d7 ] ) * xx ) * yy - ct ) * zz;
1304 oc = table[ volumerender::to_integer( ct ) ];
1307 const_mk_pointer pm = &mk( i, j, k );
1310 attribute_type mc0 = mktable[ volumerender::to_integer( pm[ d0 ] ) ];
1311 attribute_type mc1 = mktable[ volumerender::to_integer( pm[ d1 ] ) ];
1312 attribute_type mc2 = mktable[ volumerender::to_integer( pm[ d2 ] ) ];
1313 attribute_type mc3 = mktable[ volumerender::to_integer( pm[ d3 ] ) ];
1314 attribute_type mc4 = mktable[ volumerender::to_integer( pm[ d4 ] ) ];
1315 attribute_type mc5 = mktable[ volumerender::to_integer( pm[ d5 ] ) ];
1316 attribute_type mc6 = mktable[ volumerender::to_integer( pm[ d6 ] ) ];
1317 attribute_type mc7 = mktable[ volumerender::to_integer( pm[ d7 ] ) ];
1319 int number_of_visible_voxels = mc0.has_alpha;
1320 number_of_visible_voxels += mc1.has_alpha;
1321 number_of_visible_voxels += mc2.has_alpha;
1322 number_of_visible_voxels += mc3.has_alpha;
1323 number_of_visible_voxels += mc4.has_alpha;
1324 number_of_visible_voxels += mc5.has_alpha;
1325 number_of_visible_voxels += mc6.has_alpha;
1326 number_of_visible_voxels += mc7.has_alpha;
1328 if( number_of_visible_voxels > 0 )
1333 mc.pixel = ( mc0.pixel * mc0.has_alpha + mc1.pixel * mc1.has_alpha
1334 + mc2.pixel * mc2.has_alpha + mc3.pixel * mc3.has_alpha
1335 + mc4.pixel * mc4.has_alpha + mc5.pixel * mc5.has_alpha
1336 + mc6.pixel * mc6.has_alpha + mc7.pixel * mc7.has_alpha ) / static_cast< double >( number_of_visible_voxels );
1339 if( !mc0.has_alpha ){ mc0.pixel = mc.pixel; }
1340 if( !mc1.has_alpha ){ mc1.pixel = mc.pixel; }
1341 if( !mc2.has_alpha ){ mc2.pixel = mc.pixel; }
1342 if( !mc3.has_alpha ){ mc3.pixel = mc.pixel; }
1343 if( !mc4.has_alpha ){ mc4.pixel = mc.pixel; }
1344 if( !mc5.has_alpha ){ mc5.pixel = mc.pixel; }
1345 if( !mc6.has_alpha ){ mc6.pixel = mc.pixel; }
1346 if( !mc7.has_alpha ){ mc7.pixel = mc.pixel; }
1348 mc.pixel = ( mc0.pixel + ( mc3.pixel - mc0.pixel ) * xx ) + ( mc1.pixel - mc0.pixel + ( mc0.pixel - mc1.pixel + mc2.pixel - mc3.pixel ) * xx ) * yy;
1349 mc.pixel = mc.pixel + ( ( mc4.pixel + ( mc7.pixel - mc4.pixel ) * xx ) + ( mc5.pixel - mc4.pixel + ( mc4.pixel - mc5.pixel + mc6.pixel - mc7.pixel ) * xx ) * yy - mc.pixel ) * zz;
1350 mc.alpha = ( mc0.alpha + ( mc3.alpha - mc0.alpha ) * xx ) + ( mc1.alpha - mc0.alpha + ( mc0.alpha - mc1.alpha + mc2.alpha - mc3.alpha ) * xx ) * yy;
1351 mc.alpha = mc.alpha + ( ( mc4.alpha + ( mc7.alpha - mc4.alpha ) * xx ) + ( mc5.alpha - mc4.alpha + ( mc4.alpha - mc5.alpha + mc6.alpha - mc7.alpha ) * xx ) * yy - mc.alpha ) * zz;
1354 oc.pixel = oc.pixel * ( 1.0 - mc.alpha ) + mc.pixel * mc.alpha;
1355 oc.alpha = ( oc.alpha + mc.alpha ) / 2.0;
1361 return( oc.has_alpha );
1365 template <
class Po
inter >
1366 vector_type normal( Pointer p,
double xx,
double yy,
double zz )
const
1368 const_pointer p0 = p;
1369 const_pointer p1 = p0 + d1;
1370 const_pointer p2 = p0 + d2;
1371 const_pointer p3 = p0 + d3;
1372 const_pointer p4 = p0 + d4;
1373 const_pointer p5 = p0 + d5;
1374 const_pointer p6 = p0 + d6;
1375 const_pointer p7 = p0 + d7;
1377 double n0x = p3[ 0 ] - p0[ -_1 ];
1378 double n0y = p1[ 0 ] - p0[ -_2 ];
1379 double n0z = p4[ 0 ] - p0[ -_3 ];
1380 double n1x = p2[ 0 ] - p1[ -_1 ];
1381 double n1y = p1[ _2 ] - p0[ 0 ];
1382 double n1z = p5[ 0 ] - p1[ -_3 ];
1383 double n2x = p2[ _1 ] - p1[ 0 ];
1384 double n2y = p2[ _2 ] - p3[ 0 ];
1385 double n2z = p6[ 0 ] - p2[ -_3 ];
1386 double n3x = p3[ _1 ] - p0[ 0 ];
1387 double n3y = p2[ 0 ] - p3[ -_2 ];
1388 double n3z = p7[ 0 ] - p3[ -_3 ];
1389 double n4x = p7[ 0 ] - p4[ -_1 ];
1390 double n4y = p5[ 0 ] - p4[ -_2 ];
1391 double n4z = p4[ _3 ] - p0[ 0 ];
1392 double n5x = p6[ 0 ] - p5[ -_1 ];
1393 double n5y = p5[ _2 ] - p4[ 0 ];
1394 double n5z = p5[ _3 ] - p1[ 0 ];
1395 double n6x = p6[ _1 ] - p5[ 0 ];
1396 double n6y = p6[ _2 ] - p7[ 0 ];
1397 double n6z = p6[ _3 ] - p2[ 0 ];
1398 double n7x = p7[ _1 ] - p4[ 0 ];
1399 double n7y = p6[ 0 ] - p7[ -_2 ];
1400 double n7z = p7[ _3 ] - p3[ 0 ];
1402 double nx = ( n0x + ( n3x - n0x ) * xx ) + ( n1x - n0x + ( n0x - n1x + n2x - n3x ) * xx ) * yy;
1403 nx += ( ( n4x + ( n7x - n4x ) * xx ) + ( n5x - n4x + ( n4x - n5x + n6x - n7x ) * xx ) * yy - nx ) * zz;
1404 double ny = ( n0y + ( n3y - n0y ) * xx ) + ( n1y - n0y + ( n0y - n1y + n2y - n3y ) * xx ) * yy;
1405 ny += ( ( n4y + ( n7y - n4y ) * xx ) + ( n5y - n4y + ( n4y - n5y + n6y - n7y ) * xx ) * yy - ny ) * zz;
1406 double nz = ( n0z + ( n3z - n0z ) * xx ) + ( n1z - n0z + ( n0z - n1z + n2z - n3z ) * xx ) * yy;
1407 nz += ( ( n4z + ( n7z - n4z ) * xx ) + ( n5z - n4z + ( n4z - n5z + n6z - n7z ) * xx ) * yy - nz ) * zz;
1412 double len = std::sqrt( nx * nx + ny * ny + nz * nz ) + type_limits< double >::tiny( );
1417 return( vector_type( nx, ny, nz ) );
1421 vector_type normal( difference_type i, difference_type j, difference_type k,
double xx,
double yy,
double zz )
const
1423 const_pointer p = &in( i, j, k );
1424 const_mk_pointer pm = &mk( i, j, k );
1427 const attribute_type &oc0 = table[ volumerender::to_integer( p[ d0 ] ) ];
1428 const attribute_type &oc1 = table[ volumerender::to_integer( p[ d1 ] ) ];
1429 const attribute_type &oc2 = table[ volumerender::to_integer( p[ d2 ] ) ];
1430 const attribute_type &oc3 = table[ volumerender::to_integer( p[ d3 ] ) ];
1431 const attribute_type &oc4 = table[ volumerender::to_integer( p[ d4 ] ) ];
1432 const attribute_type &oc5 = table[ volumerender::to_integer( p[ d5 ] ) ];
1433 const attribute_type &oc6 = table[ volumerender::to_integer( p[ d6 ] ) ];
1434 const attribute_type &oc7 = table[ volumerender::to_integer( p[ d7 ] ) ];
1436 const attribute_type &mc0 = mktable[ volumerender::to_integer( pm[ d0 ] ) ];
1437 const attribute_type &mc1 = mktable[ volumerender::to_integer( pm[ d1 ] ) ];
1438 const attribute_type &mc2 = mktable[ volumerender::to_integer( pm[ d2 ] ) ];
1439 const attribute_type &mc3 = mktable[ volumerender::to_integer( pm[ d3 ] ) ];
1440 const attribute_type &mc4 = mktable[ volumerender::to_integer( pm[ d4 ] ) ];
1441 const attribute_type &mc5 = mktable[ volumerender::to_integer( pm[ d5 ] ) ];
1442 const attribute_type &mc6 = mktable[ volumerender::to_integer( pm[ d6 ] ) ];
1443 const attribute_type &mc7 = mktable[ volumerender::to_integer( pm[ d7 ] ) ];
1445 double oc_alpha = oc0.alpha + oc1.alpha + oc2.alpha + oc3.alpha + oc4.alpha + oc5.alpha + oc6.alpha + oc7.alpha;
1446 double mc_alpha = mc0.alpha + mc1.alpha + mc2.alpha + mc3.alpha + mc4.alpha + mc5.alpha + mc6.alpha + mc7.alpha;
1447 if( oc_alpha > mc_alpha )
1449 return( normal( p, xx, yy, zz ) );
1453 return( normal( pm, xx, yy, zz ) );
1461 namespace __volumerendering_specialized__
1464 template <
class Array1,
class Array2,
class DepthMap,
class T >
1465 bool volumerendering(
const Array1 &in, Array2 &out,
const DepthMap &depth_map,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &volrtable,
typename Array1::size_type thread_id,
typename Array1::size_type thread_num )
1467 typedef typename volumerender::parameter::vector_type vector_type;
1468 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
1469 typedef typename volumerender::attribute_table< T >::pixel_type pixel_type;
1470 typedef typename Array1::size_type size_type;
1471 typedef typename Array1::difference_type difference_type;
1472 typedef typename Array1::value_type value_type;
1473 typedef typename Array1::const_pointer const_pointer;
1474 typedef typename Array2::value_type out_value_type;
1476 vector_type offset = param.offset;
1477 vector_type pos = param.pos - offset;
1478 const volumerender::boundingbox *box = param.box;
1479 double fovy = param.fovy;
1480 double ambient_ratio = param.ambient_ratio;
1481 double diffuse_ratio = param.diffuse_ratio;
1482 double specular = param.specular;
1483 bool bSpecular = specular > 0.0;
1484 double lightAtten = param.light_attenuation;
1485 bool bLightAtten = lightAtten > 0.0;
1486 double sampling_step = param.sampling_step;
1487 double termination = param.termination;
1488 bool bperspective = param.perspective_view;
1490 const size_type w = in.width( );
1491 const size_type h = in.height( );
1492 const size_type d = in.depth( );
1494 const size_type image_width = out.width( );
1495 const size_type image_height = out.height( );
1497 const attribute_type *table = &volrtable[ 0 ];
1499 const pixel_type background = _pixel_converter_< pixel_type >::convert_to( param.background_R, param.background_G, param.background_B );
1502 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
1504 difference_type cx = in.width( ) / 2;
1505 difference_type cy = in.height( ) / 2;
1506 difference_type cz = in.depth( ) / 2;
1507 const_pointer ppp = &in( cx, cy, cz );
1509 d1 = &in( cx , cy + 1, cz ) - ppp;
1510 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
1511 d3 = &in( cx + 1, cy , cz ) - ppp;
1512 d4 = &in( cx , cy , cz + 1 ) - ppp;
1513 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
1514 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
1515 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
1516 _1 = &in( cx + 1, cy , cz ) - ppp;
1517 _2 = &in( cx , cy + 1, cz ) - ppp;
1518 _3 = &in( cx , cy , cz + 1 ) - ppp;
1522 vector_type casting_start, casting_end;
1524 const double pai = 3.1415926535897932384626433832795;
1525 double focal = (
static_cast< double >( image_height ) / 2.0 ) / std::tan( fovy * pai / 180.0 / 2.0 );
1527 double cx =
static_cast< double >( image_width ) / 2.0;
1528 double cy =
static_cast< double >( image_height ) / 2.0;
1529 double ax = in.reso1( );
1530 double ay = in.reso2( );
1531 double az = in.reso3( );
1532 double _1_ax = 1.0 / ax;
1533 double _1_ay = 1.0 / ay;
1534 double _1_az = 1.0 / az;
1536 double masp = ax < ay ? ax : ay;
1537 masp = masp < az ? masp : az;
1539 vector_type eZ = -param.dir.unit( );
1540 vector_type eY = param.up.unit( );
1541 vector_type eX = ( eY * eZ ).unit( );
1543 if( param.mirror_view )
1550 if( out.reso1( ) < out.reso2( ) )
1552 eX *= out.reso1( ) / out.reso2( );
1556 eY *= out.reso2( ) / out.reso1( );
1557 focal *= out.reso2( ) / out.reso1( );
1560 double max_distance = pos.length( ) + std::sqrt( static_cast< double >( w * w + h * h + d * d ) );
1562 for( size_type j = thread_id ; j < image_height ; j += thread_num )
1564 for( size_type i = 0 ; i < image_width ; i++ )
1567 vector_type Pos( static_cast< double >( i ) - cx, cy - static_cast< double >( j ), -focal );
1573 light = ( eX * Pos.x + eY * Pos.y + eZ * Pos.z ).unit( );
1577 pos = param.pos - offset + eX * Pos.x + eY * Pos.y;
1581 pixel_type add_intensity( 0 );
1582 double add_opacity = 1;
1584 casting_start = pos;
1585 casting_end = pos + light * max_distance;
1589 if( volumerender::check_intersection( casting_start, casting_end, box[ 0 ], normal )
1590 && volumerender::check_intersection( casting_start, casting_end, box[ 1 ], normal )
1591 && volumerender::check_intersection( casting_start, casting_end, box[ 2 ], normal )
1592 && volumerender::check_intersection( casting_start, casting_end, box[ 3 ], normal )
1593 && volumerender::check_intersection( casting_start, casting_end, box[ 4 ], normal )
1594 && volumerender::check_intersection( casting_start, casting_end, box[ 5 ], normal ) )
1597 Pos.x = ( pos.x + offset.x ) * _1_ax;
1598 Pos.y = ( pos.y + offset.y ) * _1_ay;
1599 Pos.z = ( pos.z + offset.z ) * _1_az;
1603 casting_start.x = ( casting_start.x + offset.x ) * _1_ax;
1604 casting_start.y = ( casting_start.y + offset.y ) * _1_ay;
1605 casting_start.z = ( casting_start.z + offset.z ) * _1_az;
1606 casting_end.x = ( casting_end.x + offset.x ) * _1_ax;
1607 casting_end.y = ( casting_end.y + offset.y ) * _1_ay;
1608 casting_end.z = ( casting_end.z + offset.z ) * _1_az;
1610 vector_type spos = casting_start;
1611 vector_type ray = ( casting_end - casting_start ).unit( );
1614 double dlen = vector_type( ray.x * ax, ray.y * ay, ray.z * az ).length( );
1617 double ray_sampling_step = sampling_step * masp / dlen;
1619 vector_type ray_step = ray * ray_sampling_step;
1621 double n = ( casting_end - casting_start ).length( );
1622 double l = 0, of = ( Pos - casting_start ).length( );
1626 difference_type si = volumerender::to_integer( spos.x );
1627 difference_type sj = volumerender::to_integer( spos.y );
1628 difference_type sk = volumerender::to_integer( spos.z );
1631 const_pointer p = &in( si, sj, sk );
1634 if( table[ p[ d0 ] ].has_alpha || table[ p[ d1 ] ].has_alpha ||
1635 table[ p[ d2 ] ].has_alpha || table[ p[ d3 ] ].has_alpha ||
1636 table[ p[ d4 ] ].has_alpha || table[ p[ d5 ] ].has_alpha ||
1637 table[ p[ d6 ] ].has_alpha || table[ p[ d7 ] ].has_alpha )
1649 double current_step = depth_map( si, sj, sk );
1651 spos.x += ray.x * current_step;
1652 spos.y += ray.y * current_step;
1653 spos.z += ray.z * current_step;
1657 si = volumerender::to_integer( spos.x );
1658 sj = volumerender::to_integer( spos.y );
1659 sk = volumerender::to_integer( spos.z );
1661 current_step = depth_map( si, sj, sk );
1663 if( current_step <= 2.0 )
1669 spos.x += ray.x * current_step;
1670 spos.y += ray.y * current_step;
1671 spos.z += ray.z * current_step;
1682 double nct[ 8 ] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1683 double ndx[ 8 ] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1684 double ndy[ 8 ] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1685 double ndz[ 8 ] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1686 const_pointer op = NULL;
1690 difference_type si = volumerender::to_integer( spos.x );
1691 difference_type sj = volumerender::to_integer( spos.y );
1692 difference_type sk = volumerender::to_integer( spos.z );
1694 double xx = spos.x - si;
1695 double yy = spos.y - sj;
1696 double zz = spos.z - sk;
1698 const_pointer p = &in( si, sj, sk );
1701 nct[ 1 ] = p[ d3 ] - p[ d0 ];
1702 nct[ 2 ] = p[ d1 ] - p[ d0 ];
1703 nct[ 3 ] = p[ d2 ] - p[ d3 ] - nct[ 2 ];
1705 nct[ 5 ] = p[ d7 ] - p[ d4 ];
1706 nct[ 6 ] = p[ d5 ] - p[ d4 ];
1707 nct[ 7 ] = p[ d6 ] - p[ d7 ] - nct[ 6 ];
1710 double ct = ( nct[ 0 ] + nct[ 1 ] * xx ) + ( nct[ 2 ] + nct[ 3 ] * xx ) * yy;
1711 ct += ( ( nct[ 4 ] + nct[ 5 ] * xx ) + ( nct[ 6 ] + nct[ 7 ] * xx ) * yy - ct ) * zz;
1713 const attribute_type &oc = table[ volumerender::to_integer( ct ) ];
1717 const_pointer p0 = p;
1718 const_pointer p1 = p0 + d1;
1719 const_pointer p2 = p0 + d2;
1720 const_pointer p3 = p0 + d3;
1721 const_pointer p4 = p0 + d4;
1722 const_pointer p5 = p0 + d5;
1723 const_pointer p6 = p0 + d6;
1724 const_pointer p7 = p0 + d7;
1726 double n0x = p3[ 0 ] - p0[ -_1 ];
1727 double n0y = p1[ 0 ] - p0[ -_2 ];
1728 double n0z = p4[ 0 ] - p0[ -_3 ];
1729 double n1x = p2[ 0 ] - p1[ -_1 ];
1730 double n1y = p1[ _2 ] - p0[ 0 ];
1731 double n1z = p5[ 0 ] - p1[ -_3 ];
1732 double n2x = p2[ _1 ] - p1[ 0 ];
1733 double n2y = p2[ _2 ] - p3[ 0 ];
1734 double n2z = p6[ 0 ] - p2[ -_3 ];
1735 double n3x = p3[ _1 ] - p0[ 0 ];
1736 double n3y = p2[ 0 ] - p3[ -_2 ];
1737 double n3z = p7[ 0 ] - p3[ -_3 ];
1738 double n4x = p7[ 0 ] - p4[ -_1 ];
1739 double n4y = p5[ 0 ] - p4[ -_2 ];
1740 double n4z = p4[ _3 ] - p0[ 0 ];
1741 double n5x = p6[ 0 ] - p5[ -_1 ];
1742 double n5y = p5[ _2 ] - p4[ 0 ];
1743 double n5z = p5[ _3 ] - p1[ 0 ];
1744 double n6x = p6[ _1 ] - p5[ 0 ];
1745 double n6y = p6[ _2 ] - p7[ 0 ];
1746 double n6z = p6[ _3 ] - p2[ 0 ];
1747 double n7x = p7[ _1 ] - p4[ 0 ];
1748 double n7y = p6[ 0 ] - p7[ -_2 ];
1749 double n7z = p7[ _3 ] - p3[ 0 ];
1752 ndx[ 1 ] = n3x - n0x;
1753 ndx[ 2 ] = n1x - n0x;
1754 ndx[ 3 ] = n2x - n3x - ndx[ 2 ];
1756 ndx[ 5 ] = n7x - n4x;
1757 ndx[ 6 ] = n5x - n4x;
1758 ndx[ 7 ] = n6x - n7x - ndx[ 6 ];
1761 ndy[ 1 ] = n3y - n0y;
1762 ndy[ 2 ] = n1y - n0y;
1763 ndy[ 3 ] = n2y - n3y - ndy[ 2 ];
1765 ndy[ 5 ] = n7y - n4y;
1766 ndy[ 6 ] = n5y - n4y;
1767 ndy[ 7 ] = n6y - n7y - ndy[ 6 ];
1770 ndz[ 1 ] = n3z - n0z;
1771 ndz[ 2 ] = n1z - n0z;
1772 ndz[ 3 ] = n2z - n3z - ndz[ 2 ];
1774 ndz[ 5 ] = n7z - n4z;
1775 ndz[ 6 ] = n5z - n4z;
1776 ndz[ 7 ] = n6z - n7z - ndz[ 6 ];
1780 double nx = ( ndx[ 0 ] + ndx[ 1 ] * xx ) + ( ndx[ 2 ] + ndx[ 3 ] * xx ) * yy;
1781 nx += ( ( ndx[ 4 ] + ndx[ 5 ] * xx ) + ( ndx[ 6 ] + ndx[ 7 ] * xx ) * yy - nx ) * zz;
1782 double ny = ( ndy[ 0 ] + ndy[ 1 ] * xx ) + ( ndy[ 2 ] + ndy[ 3 ] * xx ) * yy;
1783 ny += ( ( ndy[ 4 ] + ndy[ 5 ] * xx ) + ( ndy[ 6 ] + ndy[ 7 ] * xx ) * yy - ny ) * zz;
1784 double nz = ( ndz[ 0 ] + ndz[ 1 ] * xx ) + ( ndz[ 2 ] + ndz[ 3 ] * xx ) * yy;
1785 nz += ( ( ndz[ 4 ] + ndz[ 5 ] * xx ) + ( ndz[ 6 ] + ndz[ 7 ] * xx ) * yy - nz ) * zz;
1788 double _1_len = 0.5 / ( std::sqrt( nx * nx + ny * ny + nz * nz ) + type_limits< double >::tiny( ) );
1789 nx = ( nx * _1_len + normal.x ) * _1_ax;
1790 ny = ( ny * _1_len + normal.y ) * _1_ay;
1791 nz = ( nz * _1_len + normal.z ) * _1_az;
1794 double c = light.x * nx + light.y * ny + light.z * nz;
1795 c = std::sqrt( ( c * c ) / ( nx * nx + ny * ny + nz * nz + type_limits< double >::tiny( ) ) );
1800 spec = 2.0 * c * c - 1.0;
1815 spec *= specular * 255.0;
1819 double lAtten = 1.0;
1822 double len = ( l + of ) * dlen;
1823 lAtten /= 1.0 + lightAtten * ( len * len );
1826 double alpha = oc.alpha * sampling_step;
1827 add_intensity += alpha * add_opacity * ( oc.pixel * ( c * diffuse_ratio + ambient_ratio ) + spec ) * lAtten;
1828 add_opacity *= ( 1.0 - alpha );
1831 if( add_opacity < termination )
1833 out( i, j ) =
static_cast< out_value_type
>(
mist::limits_0_255( add_intensity * ( 1.0 - add_opacity ) + background * add_opacity ) );
1837 spos.x += ray_step.x;
1838 spos.y += ray_step.y;
1839 spos.z += ray_step.z;
1840 l += ray_sampling_step;
1846 l += ray_sampling_step;
1851 difference_type si = volumerender::to_integer( spos.x );
1852 difference_type sj = volumerender::to_integer( spos.y );
1853 difference_type sk = volumerender::to_integer( spos.z );
1855 const_pointer p = &in( si, sj, sk );
1858 if( table[ p[ d0 ] ].has_alpha || table[ p[ d1 ] ].has_alpha ||
1859 table[ p[ d2 ] ].has_alpha || table[ p[ d3 ] ].has_alpha ||
1860 table[ p[ d4 ] ].has_alpha || table[ p[ d5 ] ].has_alpha ||
1861 table[ p[ d6 ] ].has_alpha || table[ p[ d7 ] ].has_alpha )
1873 double current_step = depth_map( si, sj, sk );
1875 spos.x += ray.x * current_step;
1876 spos.y += ray.y * current_step;
1877 spos.z += ray.z * current_step;
1881 si = volumerender::to_integer( spos.x );
1882 sj = volumerender::to_integer( spos.y );
1883 sk = volumerender::to_integer( spos.z );
1885 current_step = depth_map( si, sj, sk );
1887 if( current_step <= 2.0 )
1893 spos.x += ray.x * current_step;
1894 spos.y += ray.y * current_step;
1895 spos.z += ray.z * current_step;
1903 difference_type si = volumerender::to_integer( spos.x );
1904 difference_type sj = volumerender::to_integer( spos.y );
1905 difference_type sk = volumerender::to_integer( spos.z );
1907 double xx = spos.x - si;
1908 double yy = spos.y - sj;
1909 double zz = spos.z - sk;
1911 const_pointer p = &in( si, sj, sk );
1913 bool need_update = p != op;
1918 nct[ 1 ] = p[ d3 ] - p[ d0 ];
1919 nct[ 2 ] = p[ d1 ] - p[ d0 ];
1920 nct[ 3 ] = p[ d2 ] - p[ d3 ] - nct[ 2 ];
1922 nct[ 5 ] = p[ d7 ] - p[ d4 ];
1923 nct[ 6 ] = p[ d5 ] - p[ d4 ];
1924 nct[ 7 ] = p[ d6 ] - p[ d7 ] - nct[ 6 ];
1928 double ct = ( nct[ 0 ] + nct[ 1 ] * xx ) + ( nct[ 2 ] + nct[ 3 ] * xx ) * yy;
1929 ct += ( ( nct[ 4 ] + nct[ 5 ] * xx ) + ( nct[ 6 ] + nct[ 7 ] * xx ) * yy - ct ) * zz;
1931 const attribute_type &oc = table[ volumerender::to_integer( ct ) ];
1937 const_pointer p0 = p;
1938 const_pointer p1 = p0 + d1;
1939 const_pointer p2 = p0 + d2;
1940 const_pointer p3 = p0 + d3;
1941 const_pointer p4 = p0 + d4;
1942 const_pointer p5 = p0 + d5;
1943 const_pointer p6 = p0 + d6;
1944 const_pointer p7 = p0 + d7;
1946 double n0x = p3[ 0 ] - p0[ -_1 ];
1947 double n0y = p1[ 0 ] - p0[ -_2 ];
1948 double n0z = p4[ 0 ] - p0[ -_3 ];
1949 double n1x = p2[ 0 ] - p1[ -_1 ];
1950 double n1y = p1[ _2 ] - p0[ 0 ];
1951 double n1z = p5[ 0 ] - p1[ -_3 ];
1952 double n2x = p2[ _1 ] - p1[ 0 ];
1953 double n2y = p2[ _2 ] - p3[ 0 ];
1954 double n2z = p6[ 0 ] - p2[ -_3 ];
1955 double n3x = p3[ _1 ] - p0[ 0 ];
1956 double n3y = p2[ 0 ] - p3[ -_2 ];
1957 double n3z = p7[ 0 ] - p3[ -_3 ];
1958 double n4x = p7[ 0 ] - p4[ -_1 ];
1959 double n4y = p5[ 0 ] - p4[ -_2 ];
1960 double n4z = p4[ _3 ] - p0[ 0 ];
1961 double n5x = p6[ 0 ] - p5[ -_1 ];
1962 double n5y = p5[ _2 ] - p4[ 0 ];
1963 double n5z = p5[ _3 ] - p1[ 0 ];
1964 double n6x = p6[ _1 ] - p5[ 0 ];
1965 double n6y = p6[ _2 ] - p7[ 0 ];
1966 double n6z = p6[ _3 ] - p2[ 0 ];
1967 double n7x = p7[ _1 ] - p4[ 0 ];
1968 double n7y = p6[ 0 ] - p7[ -_2 ];
1969 double n7z = p7[ _3 ] - p3[ 0 ];
1972 ndx[ 1 ] = n3x - n0x;
1973 ndx[ 2 ] = n1x - n0x;
1974 ndx[ 3 ] = n2x - n3x - ndx[ 2 ];
1976 ndx[ 5 ] = n7x - n4x;
1977 ndx[ 6 ] = n5x - n4x;
1978 ndx[ 7 ] = n6x - n7x - ndx[ 6 ];
1981 ndy[ 1 ] = n3y - n0y;
1982 ndy[ 2 ] = n1y - n0y;
1983 ndy[ 3 ] = n2y - n3y - ndy[ 2 ];
1985 ndy[ 5 ] = n7y - n4y;
1986 ndy[ 6 ] = n5y - n4y;
1987 ndy[ 7 ] = n6y - n7y - ndy[ 6 ];
1990 ndz[ 1 ] = n3z - n0z;
1991 ndz[ 2 ] = n1z - n0z;
1992 ndz[ 3 ] = n2z - n3z - ndz[ 2 ];
1994 ndz[ 5 ] = n7z - n4z;
1995 ndz[ 6 ] = n5z - n4z;
1996 ndz[ 7 ] = n6z - n7z - ndz[ 6 ];
2001 double nx = ( ndx[ 0 ] + ndx[ 1 ] * xx ) + ( ndx[ 2 ] + ndx[ 3 ] * xx ) * yy;
2002 nx = ( nx + ( ( ndx[ 4 ] + ndx[ 5 ] * xx ) + ( ndx[ 6 ] + ndx[ 7 ] * xx ) * yy - nx ) * zz ) * _1_ax;
2003 double ny = ( ndy[ 0 ] + ndy[ 1 ] * xx ) + ( ndy[ 2 ] + ndy[ 3 ] * xx ) * yy;
2004 ny = ( ny + ( ( ndy[ 4 ] + ndy[ 5 ] * xx ) + ( ndy[ 6 ] + ndy[ 7 ] * xx ) * yy - ny ) * zz ) * _1_ay;
2005 double nz = ( ndz[ 0 ] + ndz[ 1 ] * xx ) + ( ndz[ 2 ] + ndz[ 3 ] * xx ) * yy;
2006 nz = ( nz + ( ( ndz[ 4 ] + ndz[ 5 ] * xx ) + ( ndz[ 6 ] + ndz[ 7 ] * xx ) * yy - nz ) * zz ) * _1_az;
2009 double c = light.x * nx + light.y * ny + light.z * nz;
2010 c = std::sqrt( ( c * c ) / ( nx * nx + ny * ny + nz * nz + type_limits< double >::tiny( ) ) );
2015 spec = 2.0 * c * c - 1.0;
2030 spec *= specular * 255.0;
2034 double lAtten = 1.0;
2037 double len = ( l + of ) * dlen;
2038 lAtten /= 1.0 + lightAtten * ( len * len );
2041 double alpha = oc.alpha * sampling_step;
2042 add_intensity += alpha * add_opacity * ( oc.pixel * ( c * diffuse_ratio + ambient_ratio ) + spec ) * lAtten;
2043 add_opacity *= ( 1.0 - alpha );
2046 if( add_opacity < termination )
2051 spos.x += ray_step.x;
2052 spos.y += ray_step.y;
2053 spos.z += ray_step.z;
2054 l += ray_sampling_step;
2060 l += ray_sampling_step;
2065 difference_type si = volumerender::to_integer( spos.x );
2066 difference_type sj = volumerender::to_integer( spos.y );
2067 difference_type sk = volumerender::to_integer( spos.z );
2069 const_pointer p = &in( si, sj, sk );
2072 if( table[ p[ d0 ] ].has_alpha || table[ p[ d1 ] ].has_alpha ||
2073 table[ p[ d2 ] ].has_alpha || table[ p[ d3 ] ].has_alpha ||
2074 table[ p[ d4 ] ].has_alpha || table[ p[ d5 ] ].has_alpha ||
2075 table[ p[ d6 ] ].has_alpha || table[ p[ d7 ] ].has_alpha )
2087 double current_step = depth_map( si, sj, sk );
2089 spos.x += ray.x * current_step;
2090 spos.y += ray.y * current_step;
2091 spos.z += ray.z * current_step;
2095 si = volumerender::to_integer( spos.x );
2096 sj = volumerender::to_integer( spos.y );
2097 sk = volumerender::to_integer( spos.z );
2099 current_step = depth_map( si, sj, sk );
2101 if( current_step <= 2.0 )
2107 spos.x += ray.x * current_step;
2108 spos.y += ray.y * current_step;
2109 spos.z += ray.z * current_step;
2115 out( i, j ) =
static_cast< out_value_type
>(
mist::limits_0_255( add_intensity * ( 1.0 - add_opacity ) + background * add_opacity ) );
2126 template <
class Array1,
class Array2,
class DepthMap,
class T >
2127 class volumerendering_thread :
public mist::thread< volumerendering_thread< Array1, Array2, DepthMap, T > >
2131 typedef typename base::thread_exit_type thread_exit_type;
2132 typedef typename Array1::size_type size_type;
2133 typedef typename Array1::value_type value_type;
2142 const DepthMap *depth_map_;
2143 const volumerender::parameter *param_;
2144 const volumerender::attribute_table< T > *table_;
2147 void setup_parameters(
const Array1 &in, Array2 &out,
const DepthMap &depth_map,
const volumerender::parameter &p,
const volumerender::attribute_table< T > &t, size_type thread_id, size_type thread_num )
2151 depth_map_ = &depth_map;
2154 thread_id_ = thread_id;
2155 thread_num_ = thread_num;
2158 volumerendering_thread( size_type
id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ),
2159 in_( NULL ), out_( NULL ), depth_map_( NULL ), param_( NULL ), table_( NULL )
2162 volumerendering_thread(
const volumerendering_thread &p ) : base( p ), thread_id_( p.thread_id_ ), thread_num_( p.thread_num_ ),
2163 in_( p.in_ ), out_( p.out_ ), depth_map_( p.depth_map_ ),
2164 param_( p.param_ ), table_( p.table_ )
2170 virtual thread_exit_type thread_function( )
2172 volumerendering( *in_, *out_, *depth_map_, *param_, *table_, thread_id_, thread_num_ );
2180 namespace __volumerendering_controller__
2183 template <
class Array1,
class Array2,
class DepthMap,
class Renderer,
class T >
2184 bool volumerendering(
const Array1 &in, Array2 &out,
const DepthMap &depth_map,
const Renderer &renderer,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array1::size_type thread_id,
typename Array1::size_type thread_num )
2186 typedef typename volumerender::parameter::vector_type vector_type;
2187 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
2188 typedef typename volumerender::attribute_table< T >::pixel_type pixel_type;
2189 typedef typename Array1::size_type size_type;
2190 typedef typename Array1::difference_type difference_type;
2191 typedef typename Array1::value_type value_type;
2192 typedef typename Array1::const_pointer const_pointer;
2193 typedef typename Array2::value_type out_value_type;
2195 vector_type offset = param.offset;
2196 vector_type pos = param.pos - offset;
2197 const volumerender::boundingbox *box = param.box;
2198 double fovy = param.fovy;
2199 double ambient_ratio = param.ambient_ratio;
2200 double diffuse_ratio = param.diffuse_ratio;
2201 double specular = param.specular;
2202 bool bSpecular = specular > 0.0;
2203 double lightAtten = param.light_attenuation;
2204 double sampling_step = param.sampling_step;
2205 double termination = param.termination;
2206 bool bperspective = param.perspective_view;
2208 const size_type w = in.width( );
2209 const size_type h = in.height( );
2210 const size_type d = in.depth( );
2212 const size_type image_width = out.width( );
2213 const size_type image_height = out.height( );
2215 const pixel_type background = _pixel_converter_< pixel_type >::convert_to( param.background_R, param.background_G, param.background_B );
2218 vector_type casting_start, casting_end;
2220 const double pai = 3.1415926535897932384626433832795;
2221 double focal = (
static_cast< double >( image_height ) / 2.0 ) / std::tan( fovy * pai / 180.0 / 2.0 );
2223 double cx =
static_cast< double >( image_width ) / 2.0;
2224 double cy =
static_cast< double >( image_height ) / 2.0;
2225 double ax = in.reso1( );
2226 double ay = in.reso2( );
2227 double az = in.reso3( );
2228 double _1_ax = 1.0 / ax;
2229 double _1_ay = 1.0 / ay;
2230 double _1_az = 1.0 / az;
2232 double masp = ax < ay ? ax : ay;
2233 masp = masp < az ? masp : az;
2235 vector_type eZ = -param.dir.unit( );
2236 vector_type eY = param.up.unit( );
2237 vector_type eX = ( eY * eZ ).unit( );
2239 if( param.mirror_view )
2246 if( out.reso1( ) < out.reso2( ) )
2248 eX *= out.reso1( ) / out.reso2( );
2252 eY *= out.reso2( ) / out.reso1( );
2253 focal *= out.reso2( ) / out.reso1( );
2256 double max_distance = pos.length( ) + std::sqrt( static_cast< double >( w * w + h * h + d * d ) );
2258 for( size_type j = thread_id ; j < image_height ; j += thread_num )
2260 for( size_type i = 0 ; i < image_width ; i++ )
2263 vector_type Pos( static_cast< double >( i ) - cx, cy - static_cast< double >( j ), -focal );
2269 light = ( eX * Pos.x + eY * Pos.y + eZ * Pos.z ).unit( );
2273 pos = param.pos - offset + eX * Pos.x + eY * Pos.y;
2277 pixel_type add_intensity( 0 );
2278 double add_opacity = 1;
2280 casting_start = pos;
2281 casting_end = pos + light * max_distance;
2285 if( volumerender::check_intersection( casting_start, casting_end, box[ 0 ], normal )
2286 && volumerender::check_intersection( casting_start, casting_end, box[ 1 ], normal )
2287 && volumerender::check_intersection( casting_start, casting_end, box[ 2 ], normal )
2288 && volumerender::check_intersection( casting_start, casting_end, box[ 3 ], normal )
2289 && volumerender::check_intersection( casting_start, casting_end, box[ 4 ], normal )
2290 && volumerender::check_intersection( casting_start, casting_end, box[ 5 ], normal ) )
2293 Pos.x = ( pos.x + offset.x ) * _1_ax;
2294 Pos.y = ( pos.y + offset.y ) * _1_ay;
2295 Pos.z = ( pos.z + offset.z ) * _1_az;
2299 casting_start.x = ( casting_start.x + offset.x ) * _1_ax;
2300 casting_start.y = ( casting_start.y + offset.y ) * _1_ay;
2301 casting_start.z = ( casting_start.z + offset.z ) * _1_az;
2302 casting_end.x = ( casting_end.x + offset.x ) * _1_ax;
2303 casting_end.y = ( casting_end.y + offset.y ) * _1_ay;
2304 casting_end.z = ( casting_end.z + offset.z ) * _1_az;
2306 vector_type spos = casting_start;
2307 vector_type ray = ( casting_end - casting_start ).unit( );
2310 double dlen = vector_type( ray.x * ax, ray.y * ay, ray.z * az ).length( );
2313 double ray_sampling_step = sampling_step * masp / dlen;
2315 vector_type ray_step = ray * ray_sampling_step;
2317 double n = ( casting_end - casting_start ).length( );
2318 double l = 0, of = ( Pos - casting_start ).length( );
2322 difference_type si = volumerender::to_integer( spos.x );
2323 difference_type sj = volumerender::to_integer( spos.y );
2324 difference_type sk = volumerender::to_integer( spos.z );
2327 if( renderer.check( si, sj, sk ) )
2339 double current_step = depth_map( si, sj, sk );
2341 spos.x += ray.x * current_step;
2342 spos.y += ray.y * current_step;
2343 spos.z += ray.z * current_step;
2355 difference_type si = volumerender::to_integer( spos.x );
2356 difference_type sj = volumerender::to_integer( spos.y );
2357 difference_type sk = volumerender::to_integer( spos.z );
2359 double xx = spos.x - si;
2360 double yy = spos.y - sj;
2361 double zz = spos.z - sk;
2365 if( renderer.render( si, sj, sk, xx, yy, zz, oc ) )
2367 double lAtten = 1.0;
2368 if( lightAtten > 0.0 )
2370 double len = ( l + of ) * dlen;
2371 lAtten /= 1.0 + lightAtten * ( len * len );
2374 double c = light.inner( renderer.normal( si, sj, sk, xx, yy, zz ) );
2375 c = c < 0.0 ? -c : c;
2380 spec = 2.0 * c * c - 1.0;
2395 spec *= specular * 255.0;
2399 c = c * diffuse_ratio + ambient_ratio;
2401 double alpha = oc.alpha * sampling_step;
2402 add_intensity += alpha * add_opacity * ( oc.pixel * c + spec ) * lAtten;
2403 add_opacity *= ( 1.0 - alpha );
2406 if( add_opacity < termination )
2411 spos.x += ray_step.x;
2412 spos.y += ray_step.y;
2413 spos.z += ray_step.z;
2414 l += ray_sampling_step;
2420 l += ray_sampling_step;
2425 difference_type si = volumerender::to_integer( spos.x );
2426 difference_type sj = volumerender::to_integer( spos.y );
2427 difference_type sk = volumerender::to_integer( spos.z );
2430 if( renderer.check( si, sj, sk ) )
2442 double current_step = depth_map( si, sj, sk );
2444 spos.x += ray.x * current_step;
2445 spos.y += ray.y * current_step;
2446 spos.z += ray.z * current_step;
2451 out( i, j ) =
static_cast< out_value_type
>(
mist::limits_0_255( add_intensity * ( 1.0 - add_opacity ) + background * add_opacity ) );
2464 template <
class Array,
class DepthMap,
class Renderer,
class T >
2465 typename volumerender::parameter::vector_type collision_detection(
const Array &in,
typename Array::size_type image_width,
typename Array::size_type image_height,
double resoX,
double resoY,
2466 const DepthMap &depth_map,
const Renderer &renderer,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array::size_type i,
typename Array::size_type j )
2468 typedef typename volumerender::parameter::vector_type vector_type;
2469 typedef typename volumerender::attribute_table< T >::attribute_type attribute_type;
2470 typedef typename volumerender::attribute_table< T >::pixel_type pixel_type;
2471 typedef typename Array::size_type size_type;
2472 typedef typename Array::difference_type difference_type;
2473 typedef typename Array::value_type value_type;
2474 typedef typename Array::const_pointer const_pointer;
2476 vector_type offset = param.offset;
2477 vector_type pos = param.pos - offset;
2478 double fovy = param.fovy;
2479 double ambient_ratio = param.ambient_ratio;
2480 double diffuse_ratio = param.diffuse_ratio;
2481 double specular = param.specular;
2482 bool bSpecular = specular > 0.0;
2483 const volumerender::boundingbox *box = param.box;
2484 double lightAtten = param.light_attenuation;
2485 double sampling_step = param.sampling_step;
2486 double termination = param.termination;
2487 bool bperspective = param.perspective_view;
2489 const size_type w = in.width( );
2490 const size_type h = in.height( );
2491 const size_type d = in.depth( );
2494 vector_type casting_start, casting_end;
2496 const double pai = 3.1415926535897932384626433832795;
2497 double focal = (
static_cast< double >( image_height ) / 2.0 ) / std::tan( fovy * pai / 180.0 / 2.0 );
2499 double cx =
static_cast< double >( image_width ) / 2.0;
2500 double cy =
static_cast< double >( image_height ) / 2.0;
2501 double ax = in.reso1( );
2502 double ay = in.reso2( );
2503 double az = in.reso3( );
2504 double _1_ax = 1.0 / ax;
2505 double _1_ay = 1.0 / ay;
2506 double _1_az = 1.0 / az;
2508 double asp = resoY / resoX;
2510 double masp = ax < ay ? ax : ay;
2511 masp = masp < az ? masp : az;
2513 vector_type eZ = -param.dir.unit( );
2514 vector_type eY = param.up.unit( );
2515 vector_type eX = ( eY * eZ ).unit( );
2517 if( param.mirror_view )
2526 eX *= resoX / resoY;
2530 eY *= resoY / resoX;
2531 focal *= resoY / resoX;
2534 double max_distance = pos.length( ) + std::sqrt( static_cast< double >( w * w + h * h + d * d ) );
2538 vector_type Pos( static_cast< double >( i ) - cx, cy - static_cast< double >( j ), -focal );
2544 light = ( eX * Pos.x + eY * Pos.y + eZ * Pos.z ).unit( );
2548 pos = param.pos - offset + eX * Pos.x + eY * Pos.y;
2552 double add_opacity = 1;
2553 double old_add_opacity = 0.0;
2555 casting_start = pos;
2556 casting_end = pos + light * max_distance;
2559 if( volumerender::check_intersection( casting_start, casting_end, box[ 0 ] )
2560 && volumerender::check_intersection( casting_start, casting_end, box[ 1 ] )
2561 && volumerender::check_intersection( casting_start, casting_end, box[ 2 ] )
2562 && volumerender::check_intersection( casting_start, casting_end, box[ 3 ] )
2563 && volumerender::check_intersection( casting_start, casting_end, box[ 4 ] )
2564 && volumerender::check_intersection( casting_start, casting_end, box[ 5 ] ) )
2568 casting_start.x = ( casting_start.x + offset.x ) * _1_ax;
2569 casting_start.y = ( casting_start.y + offset.y ) * _1_ay;
2570 casting_start.z = ( casting_start.z + offset.z ) * _1_az;
2571 casting_end.x = ( casting_end.x + offset.x ) * _1_ax;
2572 casting_end.y = ( casting_end.y + offset.y ) * _1_ay;
2573 casting_end.z = ( casting_end.z + offset.z ) * _1_az;
2575 vector_type opos = casting_start;
2576 vector_type spos = casting_start;
2577 vector_type ray = ( casting_end - casting_start ).unit( );
2580 double dlen = vector_type( ray.x * ax, ray.y * ay, ray.z * az ).length( );
2583 double ray_sampling_step = sampling_step * masp / dlen;
2585 vector_type ray_step = ray * ray_sampling_step;
2587 double n = ( casting_end - casting_start ).length( );
2588 double l = 0, of = ( Pos - casting_start ).length( );
2592 difference_type si = volumerender::to_integer( spos.x );
2593 difference_type sj = volumerender::to_integer( spos.y );
2594 difference_type sk = volumerender::to_integer( spos.z );
2597 if( renderer.check( si, sj, sk ) )
2609 double current_step = depth_map( si, sj, sk );
2611 spos.x += ray.x * current_step;
2612 spos.y += ray.y * current_step;
2613 spos.z += ray.z * current_step;
2618 difference_type si = volumerender::to_integer( spos.x );
2619 difference_type sj = volumerender::to_integer( spos.y );
2620 difference_type sk = volumerender::to_integer( spos.z );
2622 double xx = spos.x - si;
2623 double yy = spos.y - sj;
2624 double zz = spos.z - sk;
2628 if( renderer.render( si, sj, sk, xx, yy, zz, oc ) )
2630 double alpha = oc.alpha * sampling_step;
2631 double aopacity = alpha * add_opacity;
2634 if( old_add_opacity < aopacity )
2637 old_add_opacity = aopacity;
2640 add_opacity = add_opacity * ( 1.0 - alpha );
2643 if( add_opacity < termination )
2648 spos.x += ray_step.x;
2649 spos.y += ray_step.y;
2650 spos.z += ray_step.z;
2651 l += ray_sampling_step;
2657 l += ray_sampling_step;
2662 difference_type si = volumerender::to_integer( spos.x );
2663 difference_type sj = volumerender::to_integer( spos.y );
2664 difference_type sk = volumerender::to_integer( spos.z );
2667 if( renderer.check( si, sj, sk ) )
2679 double current_step = depth_map( si, sj, sk );
2681 spos.x += ray.x * current_step;
2682 spos.y += ray.y * current_step;
2683 spos.z += ray.z * current_step;
2695 double infinity = type_limits< double >::maximum( );
2696 return( vector_type( infinity, infinity, infinity ) );
2703 template <
class Array1,
class Array2,
class DepthMap,
class Renderer,
class T >
2704 class volumerendering_thread :
public mist::thread< volumerendering_thread< Array1, Array2, DepthMap, Renderer, T > >
2708 typedef typename base::thread_exit_type thread_exit_type;
2709 typedef typename Array1::size_type size_type;
2710 typedef typename Array1::value_type value_type;
2719 const DepthMap *depth_map_;
2720 const Renderer *renderer_;
2721 const volumerender::parameter *param_;
2722 const volumerender::attribute_table< T > *table_;
2725 void setup_parameters(
const Array1 &in, Array2 &out,
const DepthMap &depth_map,
const Renderer &renderer,
const volumerender::parameter &p,
const volumerender::attribute_table< T > &t, size_type thread_id, size_type thread_num )
2729 depth_map_ = &depth_map;
2730 renderer_ = &renderer;
2733 thread_id_ = thread_id;
2734 thread_num_ = thread_num;
2737 volumerendering_thread( size_type
id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ),
2738 in_( NULL ), out_( NULL ), depth_map_( NULL ), renderer_( NULL ), param_( NULL ), table_( NULL )
2744 virtual thread_exit_type thread_function( )
2746 volumerendering( *in_, *out_, *depth_map_, *renderer_, *param_, *table_, thread_id_, thread_num_ );
2753 namespace __mip_controller__
2755 template <
class Array1,
class Array2 >
2756 bool mip(
const Array1 &in, Array2 &out,
const volumerender::parameter ¶m,
typename Array1::size_type thread_id,
typename Array1::size_type thread_num )
2758 typedef typename volumerender::parameter::vector_type vector_type;
2759 typedef typename Array1::size_type size_type;
2760 typedef typename Array1::difference_type difference_type;
2761 typedef typename Array1::value_type value_type;
2762 typedef typename Array1::const_pointer const_pointer;
2763 typedef typename Array2::value_type out_value_type;
2765 vector_type offset = param.offset;
2766 vector_type pos = param.pos - offset;
2767 const volumerender::boundingbox *box = param.box;
2768 const double sampling_step = param.sampling_step;
2770 const size_type w = in.width( );
2771 const size_type h = in.height( );
2772 const size_type d = in.depth( );
2774 const size_type image_width = out.width( );
2775 const size_type image_height = out.height( );
2778 difference_type d0, d1, d2, d3, d4, d5, d6, d7, _1, _2, _3;
2780 difference_type cx = in.width( ) / 2;
2781 difference_type cy = in.height( ) / 2;
2782 difference_type cz = in.depth( ) / 2;
2783 const_pointer ppp = &in( cx, cy, cz );
2785 d1 = &in( cx , cy + 1, cz ) - ppp;
2786 d2 = &in( cx + 1, cy + 1, cz ) - ppp;
2787 d3 = &in( cx + 1, cy , cz ) - ppp;
2788 d4 = &in( cx , cy , cz + 1 ) - ppp;
2789 d5 = &in( cx , cy + 1, cz + 1 ) - ppp;
2790 d6 = &in( cx + 1, cy + 1, cz + 1 ) - ppp;
2791 d7 = &in( cx + 1, cy , cz + 1 ) - ppp;
2792 _1 = &in( cx + 1, cy , cz ) - ppp;
2793 _2 = &in( cx , cy + 1, cz ) - ppp;
2794 _3 = &in( cx , cy , cz + 1 ) - ppp;
2798 vector_type casting_start, casting_end;
2801 double cx =
static_cast< double >( image_width ) / 2.0;
2802 double cy =
static_cast< double >( image_height ) / 2.0;
2803 double ax = in.reso1( );
2804 double ay = in.reso2( );
2805 double az = in.reso3( );
2806 double _1_ax = 1.0 / ax;
2807 double _1_ay = 1.0 / ay;
2808 double _1_az = 1.0 / az;
2810 double masp = ax < ay ? ax : ay;
2811 masp = masp < az ? masp : az;
2813 vector_type eZ = -param.dir.unit( );
2814 vector_type eY = param.up.unit( );
2815 vector_type eX = ( eY * eZ ).unit( );
2817 if( param.mirror_view )
2824 if( out.reso1( ) < out.reso2( ) )
2826 eX *= out.reso1( ) / out.reso2( );
2830 eY *= out.reso2( ) / out.reso1( );
2833 if( out.reso1( ) * image_width >= out.reso2( ) * image_height )
2835 iasp = out.reso1( );
2839 iasp = out.reso2( );
2842 double max_distance = pos.length( ) + std::sqrt( static_cast< double >( w * w + h * h + d * d ) );
2844 for( size_type j = thread_id ; j < image_height ; j += thread_num )
2846 for( size_type i = 0 ; i < image_width ; i++ )
2848 casting_start = pos + eZ * max_distance + (
static_cast< double >( i ) - cx ) * iasp * eX + ( cy -
static_cast< double >( j ) ) * iasp * eY;
2849 casting_end = casting_start - eZ * max_distance * 2.0;
2852 if( volumerender::check_intersection( casting_start, casting_end, box[ 0 ] )
2853 && volumerender::check_intersection( casting_start, casting_end, box[ 1 ] )
2854 && volumerender::check_intersection( casting_start, casting_end, box[ 2 ] )
2855 && volumerender::check_intersection( casting_start, casting_end, box[ 3 ] )
2856 && volumerender::check_intersection( casting_start, casting_end, box[ 4 ] )
2857 && volumerender::check_intersection( casting_start, casting_end, box[ 5 ] ) )
2861 casting_start.x = ( casting_start.x + offset.x ) * _1_ax;
2862 casting_start.y = ( casting_start.y + offset.y ) * _1_ay;
2863 casting_start.z = ( casting_start.z + offset.z ) * _1_az;
2864 casting_end.x = ( casting_end.x + offset.x ) * _1_ax;
2865 casting_end.y = ( casting_end.y + offset.y ) * _1_ay;
2866 casting_end.z = ( casting_end.z + offset.z ) * _1_az;
2868 vector_type spos = casting_start;
2869 vector_type ray = ( casting_end - casting_start ).unit( );
2871 vector_type ray_step = ray * sampling_step;
2873 double n = ( casting_end - casting_start ).length( );
2878 difference_type si = volumerender::to_integer( spos.x );
2879 difference_type sj = volumerender::to_integer( spos.y );
2880 difference_type sk = volumerender::to_integer( spos.z );
2882 double xx = spos.x - si;
2883 double yy = spos.y - sj;
2884 double zz = spos.z - sk;
2886 const_pointer p = &in( si, sj, sk );
2888 double nct0 = p[ d0 ];
2889 double nct1 = p[ d3 ] - p[ d0 ];
2890 double nct2 = p[ d1 ] - p[ d0 ];
2891 double nct3 = p[ d2 ] - p[ d3 ] - nct2;
2892 double nct4 = p[ d4 ];
2893 double nct5 = p[ d7 ] - p[ d4 ];
2894 double nct6 = p[ d5 ] - p[ d4 ];
2895 double nct7 = p[ d6 ] - p[ d7 ] - nct6;
2898 double ct = ( nct0 + nct1 * xx ) + ( nct2 + nct3 * xx ) * yy;
2899 ct += ( ( nct4 + nct5 * xx ) + ( nct6 + nct7 * xx ) * yy - ct ) * zz;
2906 spos.x += ray_step.x;
2907 spos.y += ray_step.y;
2908 spos.z += ray_step.z;
2912 out( i, j ) =
static_cast< out_value_type
>( maxct );
2925 template <
class Array1,
class Array2 >
2926 class mip_thread :
public mist::thread< mip_thread< Array1, Array2 > >
2930 typedef typename base::thread_exit_type thread_exit_type;
2931 typedef typename Array1::size_type size_type;
2932 typedef typename Array1::value_type value_type;
2941 const volumerender::parameter *param_;
2944 void setup_parameters(
const Array1 &in, Array2 &out,
const volumerender::parameter &p, size_type thread_id, size_type thread_num )
2949 thread_id_ = thread_id;
2950 thread_num_ = thread_num;
2953 mip_thread( size_type
id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ), in_( NULL ), out_( NULL ), param_( NULL )
2959 virtual thread_exit_type thread_function( )
2961 mip( *in_, *out_, *param_, thread_id_, thread_num_ );
2995 template <
class Array1,
class Array2,
class DepthMap,
class Renderer,
class ATTRIBUTETYPE >
2996 bool volumerendering(
const Array1 &in, Array2 &out,
const DepthMap &dmap,
const Renderer &renderer,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
typename Array1::size_type thread_num = 0 )
3003 typedef typename Array1::size_type size_type;
3004 typedef __volumerendering_controller__::volumerendering_thread< Array1, Array2, DepthMap, Renderer, ATTRIBUTETYPE > volumerendering_thread;
3006 if( thread_num == 0 )
3008 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
3011 volumerendering_thread *
thread =
new volumerendering_thread[ thread_num ];
3014 for( i = 0 ; i < thread_num ; i++ )
3016 thread[ i ].setup_parameters( in, out, dmap, renderer, param, table, i, thread_num );
3043 template <
class Array1,
class Array2,
class DepthMap,
class ATTRIBUTETYPE >
3044 bool volumerendering(
const Array1 &in, Array2 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
3045 const volumerender::attribute_table< ATTRIBUTETYPE > &table,
typename Array1::size_type thread_num = 0 )
3047 if( param.value_interpolation )
3049 typedef rendering_helper::value_interpolation< Array1, ATTRIBUTETYPE > Renderer;
3050 return( volumerendering( in, out, dmap, Renderer( in, param, table ), param, table, thread_num ) );
3054 typedef rendering_helper::color_interpolation< Array1, ATTRIBUTETYPE > Renderer;
3055 return( volumerendering( in, out, dmap, Renderer( in, param, table ), param, table, thread_num ) );
3076 template <
class Array1,
class Array2,
class ATTRIBUTETYPE >
3077 bool volumerendering(
const Array1 &in, Array2 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
typename Array1::size_type thread_num = 0 )
3079 return( volumerendering( in, out, volumerender::no_depth_map( ), param, table, thread_num ) );
3101 template <
class Array1,
class Array2,
class Array3,
class DepthMap,
class ATTRIBUTETYPE >
3102 bool volumerendering(
const Array1 &in,
const Array2 &mk, Array3 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
const volumerender::attribute_table< ATTRIBUTETYPE > &mktable,
typename Array1::size_type thread_num = 0 )
3104 if( in.width( ) != mk.width( ) || in.height( ) != mk.height( ) || in.depth( ) != mk.depth( ) )
3109 typedef rendering_helper::value_interpolation_with_mark< Array1, Array2, ATTRIBUTETYPE > Renderer;
3110 return( volumerendering( in, out, dmap, Renderer( in, mk, param, table, mktable ), param, table, thread_num ) );
3133 template <
class Array1,
class Array2,
class Array3,
class DepthMap,
class ATTRIBUTETYPE >
3134 bool volumerendering(
const Array1 &in,
const Array2 &mk, Array3 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
const volumerender::attribute_table< ATTRIBUTETYPE > &mktable,
bool apply_and_operation,
typename Array1::size_type thread_num = 0 )
3136 if( in.width( ) != mk.width( ) || in.height( ) != mk.height( ) || in.depth( ) != mk.depth( ) )
3141 if( apply_and_operation )
3143 typedef rendering_helper::value_interpolation_and_mark< Array1, Array2, ATTRIBUTETYPE > Renderer;
3144 return( volumerendering( in, out, dmap, Renderer( in, mk, param, table, mktable ), param, table, thread_num ) );
3148 typedef rendering_helper::value_interpolation_or_mark< Array1, Array2, ATTRIBUTETYPE > Renderer;
3149 return( volumerendering( in, out, dmap, Renderer( in, mk, param, table, mktable ), param, table, thread_num ) );
3170 template <
class Array1,
class Array2,
class Array3,
class ATTRIBUTETYPE >
3171 bool volumerendering(
const Array1 &in,
const Array2 &mk, Array3 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
const volumerender::attribute_table< ATTRIBUTETYPE > &mktable,
typename Array1::size_type thread_num = 0 )
3173 return( volumerendering( in, mk, out, volumerender::no_depth_map( ), param, table, mktable, thread_num ) );
3194 template <
class Array1,
class Array2,
class Array3,
class ATTRIBUTETYPE >
3195 bool volumerendering(
const Array1 &in,
const Array2 &mk, Array3 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
const volumerender::attribute_table< ATTRIBUTETYPE > &mktable,
bool apply_and_operation,
typename Array1::size_type thread_num = 0 )
3197 return( volumerendering( in, mk, out, volumerender::no_depth_map( ), param, table, mktable, apply_and_operation, thread_num ) );
3201 namespace specialized
3218 template <
class Array1,
class Array2,
class DepthMap,
class ATTRIBUTETYPE >
3219 bool volumerendering(
const Array1 &in, Array2 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
typename Array1::size_type thread_num = 0 )
3226 typedef typename Array1::size_type size_type;
3227 typedef __volumerendering_specialized__::volumerendering_thread< Array1, Array2, DepthMap, ATTRIBUTETYPE > volumerendering_thread;
3229 if( thread_num == 0 )
3231 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
3234 volumerendering_thread *thread =
new volumerendering_thread[ thread_num ];
3237 for( i = 0 ; i < thread_num ; i++ )
3239 thread[ i ].setup_parameters( in, out, dmap, param, table, i, thread_num );
3265 template <
class Array1,
class Array2,
class ATTRIBUTETYPE >
3266 bool volumerendering(
const Array1 &in, Array2 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
typename Array1::size_type thread_num = 0 )
3268 return( specialized::volumerendering( in, out, volumerender::no_depth_map( ), param, table, thread_num ) );
3286 template <
class Array1,
class Array2 >
3287 bool mip(
const Array1 &in, Array2 &out,
const volumerender::parameter &p,
typename Array1::size_type thread_num = 0 )
3294 typedef typename Array1::size_type size_type;
3295 typedef __mip_controller__::mip_thread< Array1, Array2 > mip_thread;
3297 if( thread_num == 0 )
3299 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
3302 mip_thread *thread =
new mip_thread[ thread_num ];
3305 for( i = 0 ; i < thread_num ; i++ )
3307 thread[ i ].setup_parameters( in, out, p, i, thread_num );
3337 template <
class Array,
class DepthMap,
class Renderer,
class T >
3339 const DepthMap &dmap,
const Renderer &renderer,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array::size_type i,
typename Array::size_type j )
3341 return( __volumerendering_controller__::collision_detection( in, image_width, image_height, resoX, resoY, dmap, renderer, param, table, i, j ) );
3360 template <
class Array1,
class Array2,
class DepthMap,
class Renderer,
class T >
3361 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &out,
const DepthMap &dmap,
const Renderer &renderer,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array1::size_type i,
typename Array1::size_type j )
3363 return( __volumerendering_controller__::collision_detection( in, out.width( ), out.height( ), out.reso1( ), out.reso2( ), dmap, renderer, param, table, i, j ) );
3385 template <
class Array,
class DepthMap,
class T >
3386 volumerender::parameter::vector_type collision_detection(
const Array &in,
typename Array::size_type image_width,
typename Array::size_type image_height,
double resoX,
double resoY,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array::size_type i,
typename Array::size_type j )
3388 if( param.value_interpolation )
3390 typedef rendering_helper::value_interpolation< Array, T > Renderer;
3391 return( collision_detection( in, image_width, image_height, resoX, resoY, dmap, Renderer( in, param, table ), param, table, i, j ) );
3395 typedef rendering_helper::color_interpolation< Array, T > Renderer;
3396 return( collision_detection( in, image_width, image_height, resoX, resoY, dmap, Renderer( in, param, table ), param, table, i, j ) );
3416 template <
class Array1,
class Array2,
class DepthMap,
class T >
3417 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array1::size_type i,
typename Array1::size_type j )
3419 if( param.value_interpolation )
3421 typedef rendering_helper::value_interpolation< Array1, T > Renderer;
3422 return( collision_detection( in, out, dmap, Renderer( in, param, table ), param, table, i, j ) );
3426 typedef rendering_helper::color_interpolation< Array1, T > Renderer;
3427 return( collision_detection( in, out, dmap, Renderer( in, param, table ), param, table, i, j ) );
3449 template <
class Array,
class T >
3450 volumerender::parameter::vector_type collision_detection(
const Array &in,
typename Array::size_type image_width,
typename Array::size_type image_height,
double resoX,
double resoY,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array::size_type i,
typename Array::size_type j )
3452 return( collision_detection( in, image_width, image_height, resoX, resoY, volumerender::no_depth_map( ), param, table, i, j ) );
3470 template <
class Array1,
class Array2,
class T >
3471 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
typename Array1::size_type i,
typename Array1::size_type j )
3473 return( collision_detection( in, out, volumerender::no_depth_map( ), param, table, i, j ) );
3497 template <
class Array1,
class Array2,
class DepthMap,
class T >
3498 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
typename Array1::size_type image_width,
typename Array1::size_type image_height,
double resoX,
double resoY,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
typename Array1::size_type i,
typename Array1::size_type j )
3500 typedef rendering_helper::value_interpolation_with_mark< Array1, Array2, T > Renderer;
3501 return( collision_detection( in, image_width, image_height, resoX, resoY, dmap, Renderer( in, mk, param, table, mktable ), param, table, i, j ) );
3522 template <
class Array1,
class Array2,
class Array3,
class DepthMap,
class T >
3523 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
const Array3 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
typename Array1::size_type i,
typename Array1::size_type j )
3525 typedef rendering_helper::value_interpolation_with_mark< Array1, Array2, T > Renderer;
3526 return( collision_detection( in, out, dmap, Renderer( in, mk, param, table, mktable ), param, table, i, j ) );
3551 template <
class Array1,
class Array2,
class DepthMap,
class T >
3552 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
typename Array1::size_type image_width,
typename Array1::size_type image_height,
double resoX,
double resoY,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
bool apply_and_operation,
typename Array1::size_type i,
typename Array1::size_type j )
3554 if( apply_and_operation )
3556 typedef rendering_helper::value_interpolation_and_mark< Array1, Array2, T > Renderer;
3557 return( collision_detection( in, image_width, image_height, resoX, resoY, dmap, Renderer( in, mk, param, table, mktable ), param, table, i, j ) );
3561 typedef rendering_helper::value_interpolation_or_mark< Array1, Array2, T > Renderer;
3562 return( collision_detection( in, image_width, image_height, resoX, resoY, dmap, Renderer( in, mk, param, table, mktable ), param, table, i, j ) );
3585 template <
class Array1,
class Array2,
class Array3,
class DepthMap,
class T >
3586 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
const Array3 &out,
const DepthMap &dmap,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
bool apply_and_operation,
typename Array1::size_type i,
typename Array1::size_type j )
3588 if( apply_and_operation )
3590 typedef rendering_helper::value_interpolation_and_mark< Array1, Array2, T > Renderer;
3591 return( collision_detection( in, out, dmap, Renderer( in, mk, param, table, mktable ), param, table, i, j ) );
3595 typedef rendering_helper::value_interpolation_or_mark< Array1, Array2, T > Renderer;
3596 return( collision_detection( in, out, dmap, Renderer( in, mk, param, table, mktable ), param, table, i, j ) );
3620 template <
class Array1,
class Array2,
class T >
3621 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
typename Array1::size_type image_width,
typename Array1::size_type image_height,
double resoX,
double resoY,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
typename Array1::size_type i,
typename Array1::size_type j )
3623 return( collision_detection( in, mk, image_width, image_height, resoX, resoY, volumerender::no_depth_map( ), param, table, mktable, i, j ) );
3643 template <
class Array1,
class Array2,
class Array3,
class T >
3644 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
const Array3 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
typename Array1::size_type i,
typename Array1::size_type j )
3646 return( collision_detection( in, mk, out, volumerender::no_depth_map( ), param, table, mktable, i, j ) );
3670 template <
class Array1,
class Array2,
class T >
3671 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
typename Array1::size_type image_width,
typename Array1::size_type image_height,
double resoX,
double resoY,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
bool apply_and_operation,
typename Array1::size_type i,
typename Array1::size_type j )
3673 return( collision_detection( in, mk, image_width, image_height, resoX, resoY, volumerender::no_depth_map( ), param, table, mktable, apply_and_operation, i, j ) );
3694 template <
class Array1,
class Array2,
class Array3,
class T >
3695 volumerender::parameter::vector_type collision_detection(
const Array1 &in,
const Array2 &mk,
const Array3 &out,
const volumerender::parameter ¶m,
const volumerender::attribute_table< T > &table,
const volumerender::attribute_table< T > &mktable,
bool apply_and_operation,
typename Array1::size_type i,
typename Array1::size_type j )
3697 return( collision_detection( in, mk, out, volumerender::no_depth_map( ), param, table, mktable, apply_and_operation, i, j ) );
3715 template <
class Array,
class DepthMap,
class ATTRIBUTETYPE >
3716 bool generate_depth_map(
const Array &in, DepthMap &dmap,
const volumerender::attribute_table< ATTRIBUTETYPE > &table,
typename Array::size_type thread_num = 0 )
3718 if(
is_same_object( in, dmap ) || in.empty( ) || in.depth( ) < 2 )
3723 typedef typename DepthMap::value_type value_type;
3724 typedef typename Array::size_type size_type;
3725 typedef typename Array::difference_type difference_type;
3726 typedef typename Array::const_pointer const_pointer;
3729 size_type w = in.width( ) / num;
3730 size_type h = in.height( ) / num;
3731 size_type d = in.depth( ) / num;
3732 size_type rw = in.width( ) > w * num ? 1 : 0;
3733 size_type rh = in.height( ) > h * num ? 1 : 0;
3734 size_type rd = in.depth( ) > d * num ? 1 : 0;
3736 dmap.resize( w + rw + 1, h + rh + 1, d + rd + 1 );
3737 dmap.reso( 1.0, 1.0, 1.0 );
3740 for( size_type k = 0 ; k < in.depth( ) ; k++ )
3742 size_type _3 = k / num;
3743 for( size_type j = 0 ; j < in.height( ) ; j++ )
3745 size_type _2 = j / num;
3746 for( size_type i = 0 ; i < in.width( ) ; i++ )
3748 size_type _1 = i / num;
3750 if( table.has_alpha( in( i, j, k ) ) )
3752 dmap( _1, _2, _3 ) = 0;
3760 for( size_type i = 0 ; i < dmap.size( ) ; i++ )
3762 dmap[ i ] =
static_cast< value_type
>( std::sqrt( static_cast< double >( dmap[ i ] ) ) );
3780 #endif // __INCLUDE_MIST_VOLUMERENDER__