From Hatwig Wiesmann, "osg::TransferFunction1D::assignToImage may assign NaN values to the image in case an underflow inside the method occurs. This underflow can be reproduced by the following call sequence:
osg::TransferFunction1D* tf(new osg::TransferFunction1D()); tf->allocate(18); tf->setColor(-10000,osg::Vec4( 1.0, 1.0, 1.0,1.0)); tf->setColor(-1e-6,osg::Vec4( 1.0, 1.0, 1.0,1.0)); tf->setColor( 0,osg::Vec4( 0.0, 0.0, 1.0,1.0)); Remark: The value -1e-6 may be added (falsely) because of a rounding error. The attached fix prevents assigning NaN values to the image. "
This commit is contained in:
parent
75fc7b6598
commit
64acd4df54
@ -69,32 +69,35 @@ void TransferFunction1D::clear(const osg::Vec4& color)
|
|||||||
|
|
||||||
void TransferFunction1D::assignToImage(float lower_v, const osg::Vec4& lower_c, float upper_v, const osg::Vec4& upper_c)
|
void TransferFunction1D::assignToImage(float lower_v, const osg::Vec4& lower_c, float upper_v, const osg::Vec4& upper_c)
|
||||||
{
|
{
|
||||||
|
int endPos = getNumberImageCells()-1;
|
||||||
float minimum = _colorMap.begin()->first;
|
float minimum = _colorMap.begin()->first;
|
||||||
float maximum = _colorMap.rbegin()->first;
|
float maximum = _colorMap.rbegin()->first;
|
||||||
float endPos = float(getNumberImageCells()-1);
|
float multiplier = float(endPos)/(maximum - minimum);
|
||||||
float multiplier = endPos/(maximum - minimum);
|
|
||||||
osg::Vec4* imageData = reinterpret_cast<osg::Vec4*>(_image->data());
|
osg::Vec4* imageData = reinterpret_cast<osg::Vec4*>(_image->data());
|
||||||
|
|
||||||
float lower_iPos = (lower_v - minimum)*multiplier;
|
float lower_iPos = (lower_v - minimum)*multiplier;
|
||||||
float upper_iPos = (upper_v - minimum)*multiplier;
|
float upper_iPos = (upper_v - minimum)*multiplier;
|
||||||
|
|
||||||
float start_iPos = ceilf(lower_iPos);
|
int start_iPos = static_cast<int>(ceilf(lower_iPos));
|
||||||
if (start_iPos<0.0f) start_iPos=0.0f;
|
if (start_iPos < 0) start_iPos = 0;
|
||||||
if (start_iPos>endPos) return;
|
if (start_iPos > endPos) return;
|
||||||
|
|
||||||
float end_iPos = floorf(upper_iPos);
|
int end_iPos = static_cast<int>(floorf(upper_iPos));
|
||||||
if (end_iPos<0.0f) return;
|
if (end_iPos < 0) return;
|
||||||
if (end_iPos>endPos) end_iPos=endPos;
|
if (end_iPos > endPos) end_iPos = endPos;
|
||||||
|
|
||||||
//osg::notify(osg::NOTICE)<<"TransferFunction1D::assignToImage[lower_v="<<lower_v<<", lower_c="<<lower_c<<", upper_v="<<upper_v<<" upper_c="<<upper_c<<std::endl;
|
//osg::notify(osg::NOTICE)<<"TransferFunction1D::assignToImage[lower_v="<<lower_v<<", lower_c="<<lower_c<<", upper_v="<<upper_v<<" upper_c="<<upper_c<<std::endl;
|
||||||
//osg::notify(osg::NOTICE)<<" lower_iPos="<<lower_iPos<<" start_iPpos="<<start_iPos<<std::endl;
|
//osg::notify(osg::NOTICE)<<" lower_iPos="<<lower_iPos<<" start_iPpos="<<start_iPos<<std::endl;
|
||||||
//osg::notify(osg::NOTICE)<<" upper_iPos="<<upper_iPos<<" end_iPpos="<<end_iPos<<std::endl;
|
//osg::notify(osg::NOTICE)<<" upper_iPos="<<upper_iPos<<" end_iPpos="<<end_iPos<<std::endl;
|
||||||
|
|
||||||
Vec4 delta_c = (upper_c-lower_c)/(upper_iPos-lower_iPos);
|
// upper_iPos can be identical to lower_iPos in case an underflow occurred while calculation the values;
|
||||||
unsigned int i=static_cast<unsigned int>(start_iPos);
|
// if both values are identical delta_c is identical to the null vector otherwise it is calculated like follows:
|
||||||
for(float iPos=start_iPos;
|
Vec4 delta_c;
|
||||||
iPos<=end_iPos;
|
if (upper_iPos != lower_iPos)
|
||||||
++iPos, ++i)
|
delta_c = (upper_c-lower_c)/(upper_iPos-lower_iPos);
|
||||||
|
|
||||||
|
float iPos = static_cast<float>(start_iPos);
|
||||||
|
for(int i=start_iPos; i<=end_iPos; ++i, ++iPos)
|
||||||
{
|
{
|
||||||
imageData[i] = lower_c + delta_c*(iPos-lower_iPos);
|
imageData[i] = lower_c + delta_c*(iPos-lower_iPos);
|
||||||
//osg::notify(osg::NOTICE)<<" imageData["<<i<<"] = "<<imageData[i]<<std::endl;
|
//osg::notify(osg::NOTICE)<<" imageData["<<i<<"] = "<<imageData[i]<<std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user