From 995ead176a9b8b2c6f0097b77a325e7c9d612b2f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 13 Sep 2008 09:09:51 +0000 Subject: [PATCH] Introduced TransferFunction1D::assign(ValueMap&). --- include/osg/TransferFunction | 21 +++++++ src/osg/TransferFunction.cpp | 78 ++++++++++++++++++++++++ src/osgWrappers/osg/TransferFunction.cpp | 14 +++++ 3 files changed, 113 insertions(+) diff --git a/include/osg/TransferFunction b/include/osg/TransferFunction index 09ec18594..9d76c46f6 100644 --- a/include/osg/TransferFunction +++ b/include/osg/TransferFunction @@ -17,6 +17,8 @@ #include #include +#include + namespace osg { @@ -77,6 +79,25 @@ class OSG_EXPORT TransferFunction1D : public osg::TransferFunction void setValue(unsigned int i, const osg::Vec4& color) { _colors[i] = color; if (_image.valid()) _image->dirty(); } const osg::Vec4& getValue(unsigned int i) const { return _colors[i]; } + osg::Vec4 getInterpolatedValue(float v) const + { + float iPos = (v-_minimum)*float(_colors.size()-1)/(_maximum-_minimum); + if (iPos<0.0) return _colors[0]; + if (iPos>float(_colors.size()-1)) return _colors[_colors.size()-1]; + + unsigned int iLower = (unsigned int)(iPos); + unsigned int iUpper = iLower+1; + if (iUpper>=_colors.size()) return _colors[iLower]; + + float r = iPos-floorf(iLower); + const osg::Vec4& cLower = _colors[iLower]; + const osg::Vec4& cUpper = _colors[iUpper]; + return cLower + (cUpper-cLower)*r; + } + + typedef std::map ValueMap; + void assign(const ValueMap& vcm, bool updateMinMaxRange); + protected: float _minimum; diff --git a/src/osg/TransferFunction.cpp b/src/osg/TransferFunction.cpp index a68655f80..9d71b883c 100644 --- a/src/osg/TransferFunction.cpp +++ b/src/osg/TransferFunction.cpp @@ -13,6 +13,10 @@ #include +#include +#include + + using namespace osg; /////////////////////////////////////////////////////////////////////// @@ -59,3 +63,77 @@ void TransferFunction1D::clear(const osg::Vec4& color) *itr = color; } } + + +void TransferFunction1D::assign(const ValueMap& vcm, bool updateMinMaxRange) +{ + if (vcm.empty()) return; + + if (updateMinMaxRange) + { + _minimum = vcm.begin()->first; + _maximum = vcm.rbegin()->first; + } + + if (_colors.empty()) allocate(1024); + + + float multiplier = float(_colors.size()-1)/(_maximum - _minimum); + + if (vcm.size()==1) + { + osg::Vec4 color = vcm.begin()->second; + if (_minimum == _maximum) + { + clear(color); + } + else + { + float iPos = (vcm.begin()->first - _minimum)*multiplier; + if (iPos>=0.0f || iPosfirst; + const osg::Vec4& lower_c = lower_itr->second; + float upper_v = upper_itr->first; + const osg::Vec4& upper_c = upper_itr->second; + + float lower_iPos = (lower_v - _minimum)*multiplier; + float upper_iPos = (upper_v - _minimum)*multiplier; + + float start_iPos = ceilf(lower_iPos); + if (start_iPos<0.0f) start_iPos=0.0f; + if (start_iPos>float(_colors.size()-1)) break; + + float end_iPos = floorf(upper_iPos); + if (end_iPos<0.0f) continue; + if (end_iPos>float(_colors.size()-1)) end_iPos=_colors.size()-1; + + Vec4 delta_c = (upper_c-lower_c)/(upper_iPos-lower_iPos); + unsigned int i=static_cast(start_iPos); + for(float iPos=start_iPos; + iPos<=end_iPos; + ++iPos, ++i) + { + _colors[i] = lower_c + delta_c*(iPos-lower_v); + } + + lower_itr = upper_itr; + } +} + diff --git a/src/osgWrappers/osg/TransferFunction.cpp b/src/osgWrappers/osg/TransferFunction.cpp index c5a7a30e2..9c1736f97 100644 --- a/src/osgWrappers/osg/TransferFunction.cpp +++ b/src/osgWrappers/osg/TransferFunction.cpp @@ -71,6 +71,8 @@ BEGIN_OBJECT_REFLECTOR(osg::TransferFunction) 0); END_REFLECTOR +TYPE_NAME_ALIAS(std::map< float COMMA osg::Vec4 >, osg::TransferFunction1D::ValueMap) + BEGIN_OBJECT_REFLECTOR(osg::TransferFunction1D) I_DeclaringFile("osg/TransferFunction"); I_BaseType(osg::TransferFunction); @@ -127,6 +129,16 @@ BEGIN_OBJECT_REFLECTOR(osg::TransferFunction1D) __C5_osg_Vec4_R1__getValue__unsigned_int, "", ""); + I_Method1(osg::Vec4, getInterpolatedValue, IN, float, v, + Properties::NON_VIRTUAL, + __osg_Vec4__getInterpolatedValue__float, + "", + ""); + I_Method2(void, assign, IN, const osg::TransferFunction1D::ValueMap &, vcm, IN, bool, updateMinMaxRange, + Properties::NON_VIRTUAL, + __void__assign__C5_ValueMap_R1__bool, + "", + ""); I_SimpleProperty(float, Maximum, __float__getMaximum, __void__setMaximum__float); @@ -142,3 +154,5 @@ BEGIN_OBJECT_REFLECTOR(osg::TransferFunction1D) 0); END_REFLECTOR +STD_MAP_REFLECTOR(std::map< float COMMA osg::Vec4 >) +