31 #include "WTransferFunction.h"
40 std::vector< double >::const_iterator ait1 =
m_histogram.begin();
41 std::vector< double >::const_iterator ait2 = rhs.
m_histogram.begin();
64 std::vector< ColorEntry >::const_iterator it1 =
m_colors.begin();
65 std::vector< ColorEntry >::const_iterator it2 = rhs.
m_colors.begin();
70 if( !( *it1 == *it2 ) )
76 std::vector< AlphaEntry >::const_iterator ait1 =
m_alphas.begin();
77 std::vector< AlphaEntry >::const_iterator ait2 = rhs.
m_alphas.begin();
82 if( !( *ait1 == *ait2 ) )
93 return !( ( *this ) == rhs );
99 WColor blend(
const WColor&a,
double ta,
const WColor &b,
double tb )
104 ta*a[ 2 ]+tb*b[ 2 ], 1. );
108 double ablend(
const double a,
const double ta,
const double b,
const double tb )
120 std::vector< ColorEntry >::const_iterator c1 =
m_colors.begin();
121 std::vector< ColorEntry >::const_iterator c2 = c1+1;
123 std::vector< AlphaEntry >::const_iterator a1 =
m_alphas.begin();
124 std::vector< AlphaEntry >::const_iterator a2 = a1+1;
126 for(
int i = 0; i < width; ++i )
129 double iso = ( double )i/(
double )width * ( max-min ) + min;
134 color[ 3 ] =
m_alphas.begin()->alpha;
143 while( c2 !=
m_colors.end() && iso > c2->iso )
145 WAssert( c2 !=
m_colors.end(),
"Corruption of internal data structure." );
148 WAssert( c1 !=
m_colors.end(),
"Corruption of internal data structure." );
151 while( a2 !=
m_alphas.end() && iso > a2->iso )
153 WAssert( a2 !=
m_alphas.end(),
"Corruption of internal data structure." );
156 WAssert( a1 !=
m_alphas.end(),
"Corruption of internal data structure." );
165 double colorParameter = ( iso - c1->iso )/( c2->iso - c1->iso );
166 color = blend( c1->color, 1.-colorParameter, c2->color, colorParameter );
170 color[ 3 ] = a1->alpha;
174 double alphaParameter = ( iso - a1->iso )/( a2->iso - a1->iso );
175 color[ 3 ] = ablend( a1->alpha, 1.-alphaParameter, a2->alpha, alphaParameter );
178 for(
int j = 0; j < 4; ++j )
180 array[ 4*i + j ] = color[ j ]*255.;
242 const double MIN_ERROR_THRESHOLD = 5.0;
244 std::vector < float > values( size );
247 for(
size_t i = 0; i < size; ++i )
249 values[ i ] =
static_cast<double>( rgba[ i*4+3 ] );
253 rgbatf.
addAlpha( 0.0, values[ 0 ]/255. );
254 rgbatf.
addAlpha( 1.0, values[ size-1 ]/255. );
256 std::vector < float > errors( size );
259 while( seed < size-1 )
266 double incline = ( values[ to ] - values[ seed ] )/( to-seed );
267 for(
size_t j = seed+1; j < to; ++j )
269 error += std::sqrt( std::pow( values[ j ] - values[ seed ] - incline * ( j-seed ), 2 ) );
271 errors[ to ] = error/( to-seed );
274 size_t minElement = size-1;
275 double minerror = errors[ minElement ];
276 for( to = size-1; to > seed; --to )
278 if( errors[ to ] < minerror )
281 minerror = errors[ to ];
282 if( minerror < MIN_ERROR_THRESHOLD )
288 if( minElement < size-1 )
290 rgbatf.
addAlpha( (
double )minElement/(
double )( size-1 ), values[ minElement ]/255. );
298 rgbatf.
addColor( 0.0, WColor( rgba[ 0*4+0 ]/255.f, rgba[ 0*4+1 ]/255.f, rgba[ 0*4+2 ]/255.f, 0.f ) );
299 rgbatf.
addColor( 1.0, WColor( rgba[ ( size-1 )*4+0 ]/255.f, rgba[ ( size-1 )*4+1 ]/255.f, rgba[ ( size-1 )*4+2 ]/255.f, 0.f ) );
304 while( seed < size-1 )
311 double inclineR = ( rgba[ to*4+0 ] - rgba[ seed*4+0 ] )/( to-seed );
312 double inclineG = ( rgba[ to*4+1 ] - rgba[ seed*4+1 ] )/( to-seed );
313 double inclineB = ( rgba[ to*4+2 ] - rgba[ seed*4+2 ] )/( to-seed );
315 for(
size_t j = seed; j < to; ++j )
318 std::pow( rgba[ 4*j+0 ] - rgba[ 4*seed+0 ] - inclineR * ( j-seed ), 2 ) +
319 std::pow( rgba[ 4*j+1 ] - rgba[ 4*seed+1 ] - inclineG * ( j-seed ), 2 ) +
320 std::pow( rgba[ 4*j+2 ] - rgba[ 4*seed+2 ] - inclineB * ( j-seed ), 2 )
323 errors[ to ] = error/( to-seed );
327 size_t minElement = size-1;
328 double minerror = errors[ size-1 ];
330 for( to = size-2; to > seed; --to )
332 if( errors[ to ] < minerror )
335 minerror = errors[ to ];
337 if( minerror < MIN_ERROR_THRESHOLD*2.0 )
342 if( minElement < size-1 )
344 rgbatf.
addColor( (
double )minElement/(
double )( size-1 ),
345 WColor( rgba[ minElement*4+0 ]/255.f, rgba[ minElement*4+1 ]/255.f, rgba[ minElement*4+2 ]/255.f, 0.f ) );
350 std::cout <<
"New Transfer Function: " << rgbatf <<
"." << std::endl;
357 for(
size_t i = 0; i < numColors; ++i )
361 out <<
"c:" << iso <<
":" << c[ 0 ] <<
":" << c[ 1 ] <<
":" << c[ 2 ] <<
";";
364 for(
size_t i = 0; i < numAlphas; ++i )
368 out <<
"a:" << iso <<
":" << alpha;
369 if( i != numAlphas-1 )
A class that stores a 1D transfer function which consists of a linear interpolation of alpha and colo...
std::vector< ColorEntry > m_colors
Sorted list of colors.
void sample1DTransferFunction(unsigned char *array, int width, double min, double max) const
sample/render the transfer function linearly between min and max in an RGBA texture.
Color entries are linearly interpolated colors along isovalues.
bool operator==(const WTransferFunction &rhs) const
Check equivalence of two transfer functions.
size_t numColors() const
Get the number of colors.
double m_isomin
The smallest used iso value.
double getColorIsovalue(size_t i) const
The isovalue of the color at a given index.
Alpha entries represent linearly interpolated transparency values along the isovalue scale...
static WTransferFunction createFromRGBA(unsigned char const *const rgba, size_t size)
Try to estimate a transfer function from an RGBA image.
std::vector< AlphaEntry > m_alphas
Sorted list of alpha values.
Templatized comparison predicate for internal searching.
double m_isomax
The largest used iso value.
std::vector< double > m_histogram
Sores a histogram.
void addAlpha(double iso, double alpha)
Insert a new alpha point.
void addColor(double iso, const WColor &color)
Insert a new color point.
bool operator!=(const WTransferFunction &rhs) const
Check equivalence of two transfer functions.
size_t numAlphas() const
Get the number of alphas.
double getAlphaIsovalue(size_t i) const
Get the isovalue at a given index in the alpha values.
const WColor & getColor(size_t i) const
Get color at given index.
double getAlpha(size_t i) const
Get alpha at given index.