diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index c0ba552d3..ad8ae8733 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -831,15 +831,17 @@ int main(int argc, char** argv) osg::ref_ptr tf = new osg::TransferFunction1D; - tf->setInputRange(minValue, maxValue); + unsigned int numCells = 6; + float delta = (maxValue-minValue)/float(numCells-1); + float v = minValue; tf->allocate(6); - tf->setValue(0, osg::Vec4(1.0,1.0,1.0,1.0)); - tf->setValue(1, osg::Vec4(1.0,0.0,1.0,1.0)); - tf->setValue(2, osg::Vec4(1.0,0.0,0.0,1.0)); - tf->setValue(3, osg::Vec4(1.0,1.0,0.0,1.0)); - tf->setValue(4, osg::Vec4(0.0,1.0,1.0,1.0)); - tf->setValue(5, osg::Vec4(0.0,1.0,0.0,1.0)); + tf->setColor(v, osg::Vec4(1.0,1.0,1.0,1.0)); v += delta; + tf->setColor(v, osg::Vec4(1.0,0.0,1.0,1.0)); v += delta; + tf->setColor(v, osg::Vec4(1.0,0.0,0.0,1.0)); v += delta; + tf->setColor(v, osg::Vec4(1.0,1.0,0.0,1.0)); v += delta; + tf->setColor(v, osg::Vec4(0.0,1.0,1.0,1.0)); v += delta; + tf->setColor(v, osg::Vec4(0.0,1.0,0.0,1.0)); osg::notify(osg::NOTICE)<<"--tf "<assign(valueMap, true); + tf->assign(colorMap); return tf; } @@ -851,6 +851,23 @@ int main( int argc, char **argv ) { transferFunction = readTransferFunctionFile(tranferFunctionFile); } + + while(arguments.read("--test")) + { + transferFunction = new osg::TransferFunction1D; + transferFunction->setColor(0.0, osg::Vec4(1.0,0.0,0.0,0.0)); + transferFunction->setColor(0.5, osg::Vec4(1.0,1.0,0.0,0.5)); + transferFunction->setColor(1.0, osg::Vec4(0.0,0.0,1.0,1.0)); + } + + while(arguments.read("--test2")) + { + transferFunction = new osg::TransferFunction1D; + transferFunction->setColor(0.0, osg::Vec4(1.0,0.0,0.0,0.0)); + transferFunction->setColor(0.5, osg::Vec4(1.0,1.0,0.0,0.5)); + transferFunction->setColor(1.0, osg::Vec4(0.0,0.0,1.0,1.0)); + transferFunction->assign(transferFunction->getColorMap()); + } unsigned int numSlices=500; while (arguments.read("-s",numSlices)) {} @@ -975,7 +992,7 @@ int main( int argc, char **argv ) osgDB::ifstream fin(transfer_filename.c_str()); if (fin) { - osg::TransferFunction1D::ValueMap valueMap; + osg::TransferFunction1D::ColorMap colorMap; float value = 0.0; while(fin && value<=1.0) { @@ -983,21 +1000,21 @@ int main( int argc, char **argv ) fin >> red >> green >> blue >> alpha; if (fin) { - valueMap[value] = osg::Vec4(red/255.0f,green/255.0f,blue/255.0f,alpha/255.0f); + colorMap[value] = osg::Vec4(red/255.0f,green/255.0f,blue/255.0f,alpha/255.0f); std::cout<<"value = "<assign(valueMap, true); + transferFunction->assign(colorMap); } } diff --git a/include/osg/TransferFunction b/include/osg/TransferFunction index ce4e0b39d..e887a93f0 100644 --- a/include/osg/TransferFunction +++ b/include/osg/TransferFunction @@ -38,16 +38,16 @@ class OSG_EXPORT TransferFunction : public osg::Object META_Object(osg, TransferFunction) + /** Get the image that is used for passing the transfer function data to the GPU.*/ osg::Image* getImage() { return _image.get(); } + + /** Get the const image that is used for passing the transfer function data to the GPU.*/ const osg::Image* getImage() const { return _image.get(); } protected: virtual ~TransferFunction(); - typedef std::vector Colors; - - Colors _colors; osg::ref_ptr _image; }; @@ -62,48 +62,65 @@ class OSG_EXPORT TransferFunction1D : public osg::TransferFunction TransferFunction1D(const TransferFunction1D& tf, const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_Object(osg, TransferFunction1D) - - void setInputRange(float minimum, float maximum); - void setMinimum(float value) { _minimum = value; } - float getMinimum() const { return _minimum; } + /** Get the mnimum transfer function value.*/ + float getMinimum() const { return _colorMap.empty() ? 0.0f : _colorMap.begin()->first; } - void setMaximum(float value) { _maximum = value; } - float getMaximum() const { return _maximum; } + /** Get the maximum transfer function value.*/ + float getMaximum() const { return _colorMap.empty() ? 0.0f : _colorMap.rbegin()->first; } - void allocate(unsigned int numX); + /** allocate the osg::Image with specified dimension. The Image tracks the color map, and is used to represent the + * transfer function when download to GPU.*/ + void allocate(unsigned int numImageCells); + /** Clear the whole range to just represet a single color.*/ void clear(const osg::Vec4& color = osg::Vec4(1.0f,1.0f,1.0f,1.0f)); - unsigned int getNumberCellsX() const { return _colors.size(); } - - 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 + /** Get pixel value from the image. */ + osg::Vec4 getPixelValue(unsigned int i) 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; + if (_image.valid() && i(_image->s())) + { + return *reinterpret_cast(_image->data(i)); + } + else + { + return osg::Vec4(1.0f,1.0f,1.0f,1.0f); + } } + + /** Get the number of image cells that are assigned to the represent the transfer function when download to the GPU.*/ + unsigned int getNumberImageCells() const { return _image.valid() ? _image->s() : 0; } + + /** Set the color for a specified transfer function value. + * updateImage defaults to true, and tells the setColor function to update the associate osg::Image that + * tracks the color map. Pass in false as the updateImage parameter if you are setting up many values + * at once to avoid recomputating og the image data, then once all setColor calls are made explictly call + * updateImage() to bring the osg::Image back into sync with the color map. */ + void setColor(float v, const osg::Vec4& color, bool updateImage=true); - typedef std::map ValueMap; - void assign(const ValueMap& vcm, bool updateMinMaxRange); + /** Get the color for a specified transfer function value, interpolating the value if no exact match is found.*/ + osg::Vec4 getColor(float v) const; + + typedef std::map ColorMap; + + /** Get the color map that stores the mapping between the the tranfser function value and the colour it maps to.*/ + ColorMap& getColorMap() { return _colorMap; } + + /** Get the const color map that stores the mapping between the the tranfser function value and the colour it maps to.*/ + const ColorMap& getColorMap() const { return _colorMap; } + + /** Assign a color map and automatically update the image to make sure they are in sync.*/ + void assign(const ColorMap& vcm); + + /** Manually update the associate osg::Image to represent the colors assigned in the color map.*/ + void updateImage(); protected: - float _minimum; - float _maximum; - + ColorMap _colorMap; + + void assignToImage(float lower_v, const osg::Vec4& lower_c, float upper_v, const osg::Vec4& upper_c); }; } diff --git a/include/osgTerrain/Layer b/include/osgTerrain/Layer index 9004278be..f8058dfa1 100644 --- a/include/osgTerrain/Layer +++ b/include/osgTerrain/Layer @@ -285,7 +285,7 @@ class OSGTERRAIN_EXPORT ContourLayer : public Layer virtual const osg::Image* getImage() const { return _tf.valid() ? _tf->getImage() : 0; } - virtual unsigned int getNumColumns() const { return _tf.valid() ? _tf->getNumberCellsX() : 0; } + virtual unsigned int getNumColumns() const { return _tf.valid() ? _tf->getNumberImageCells() : 0; } virtual unsigned int getNumRows() const { return _tf.valid() ? 1 : 0; } virtual bool getValue(unsigned int i, unsigned int j, float& value) const; diff --git a/src/osg/TransferFunction.cpp b/src/osg/TransferFunction.cpp index 7ecdbad45..0f069210f 100644 --- a/src/osg/TransferFunction.cpp +++ b/src/osg/TransferFunction.cpp @@ -42,118 +42,175 @@ TransferFunction::~TransferFunction() // TransferFunction1D::TransferFunction1D() { - _minimum = 0.0; - _maximum = 1.0; } TransferFunction1D::TransferFunction1D(const TransferFunction1D& tf, const CopyOp& copyop): - TransferFunction(tf,copyop), - _minimum(tf._minimum), - _maximum(tf._maximum) + TransferFunction(tf,copyop) { - allocate(tf._colors.size()); - for(unsigned int i=0; i<_colors.size(); ++i) - { - _colors[i] = tf._colors[i]; - } -} - -void TransferFunction1D::setInputRange(float minimum, float maximum) -{ - _minimum = minimum; - _maximum = maximum; + allocate(tf.getNumberImageCells()); + assign(_colorMap); } void TransferFunction1D::allocate(unsigned int numX) { - _colors.resize(numX); _image = new osg::Image; - _image->setImage(numX,1,1,GL_RGBA, GL_RGBA, GL_FLOAT, (unsigned char*)&_colors[0], osg::Image::NO_DELETE); + _image->allocateImage(numX,1,1,GL_RGBA, GL_FLOAT); + if (!_colorMap.empty()) assign(_colorMap); } void TransferFunction1D::clear(const osg::Vec4& color) { - for(Colors::iterator itr = _colors.begin(); - itr != _colors.end(); - ++itr) + ColorMap newColours; + newColours[getMinimum()] = color; + newColours[getMaximum()] = color; + + assign(newColours); +} + +void TransferFunction1D::assignToImage(float lower_v, const osg::Vec4& lower_c, float upper_v, const osg::Vec4& upper_c) +{ + float minimum = _colorMap.begin()->first; + float maximum = _colorMap.rbegin()->first; + float endPos = float(getNumberImageCells()-1); + float multiplier = endPos/(maximum - minimum); + osg::Vec4* imageData = reinterpret_cast(_image->data()); + + 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>endPos) return; + + float end_iPos = floorf(upper_iPos); + if (end_iPos<0.0f) return; + if (end_iPos>endPos) end_iPos=endPos; + + 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) { - *itr = color; + imageData[i] = lower_c + delta_c*(iPos-lower_v); } + + _image->dirty(); } -void TransferFunction1D::assign(const ValueMap& vcm, bool updateMinMaxRange) +void TransferFunction1D::setColor(float v, const osg::Vec4& color, bool updateImage) { - if (vcm.empty()) return; - - if (updateMinMaxRange) + if (!updateImage) { - _minimum = vcm.begin()->first; - _maximum = vcm.rbegin()->first; + _colorMap[v] = color; + return; } + + if (!_image) allocate(1024); - if (_colors.empty()) allocate(1024); - - - float multiplier = float(_colors.size()-1)/(_maximum - _minimum); - - if (vcm.size()==1) + if (_colorMap.empty() || vgetMaximum()) { - osg::Vec4 color = vcm.begin()->second; - if (_minimum == _maximum) + _colorMap[v] = color; + + assign(_colorMap); + return; + } + + _colorMap[v] = color; + + ColorMap::iterator itr = _colorMap.find(v); + + if (itr != _colorMap.begin()) + { + ColorMap::iterator previous_itr = itr; + --previous_itr; + + assignToImage(previous_itr->first, previous_itr->second, v, color); + } + + ColorMap::iterator next_itr = itr; + ++next_itr; + + if (next_itr != _colorMap.end()) + { + assignToImage(v, color, next_itr->first, next_itr->second); + } +} + +osg::Vec4 TransferFunction1D::getColor(float v) const +{ + if (_colorMap.empty()) return osg::Vec4(1.0f,1.0f,1.0f,1.0f); + if (_colorMap.size()==1) return _colorMap.begin()->second; + + if (v <= _colorMap.begin()->first) return _colorMap.begin()->second; + if (v >= _colorMap.rbegin()->first) return _colorMap.rbegin()->second; + + // need to implement + std::pair range = _colorMap.equal_range(v); + + // we have an identical match + if (v == range.first->first) return range.first->second; + + // range.first will be at the next element after v, so move it before. + --range.first; + + float vBefore = range.first->first; + const osg::Vec4& cBefore = range.first->second; + + float vAfter = range.second->first; + const osg::Vec4& cAfter = range.second->second; + + float r = (v-vBefore)/(vAfter-vBefore); + + return cBefore*(1.0f-r) + cAfter*r; +} + + +void TransferFunction1D::assign(const ColorMap& newColours) +{ + _colorMap = newColours; + + updateImage(); +} + +void TransferFunction1D::updateImage() +{ + if (_colorMap.empty()) return; + + if (!_image || _image->data()==0) allocate(1024); + + osg::Vec4* imageData = reinterpret_cast(_image->data()); + + if (_colorMap.size()==1) + { + osg::Vec4 color = _colorMap.begin()->second; + + for(int i=0; i<_image->s(); ++i) { - clear(color); - } - else - { - float iPos = (vcm.begin()->first - _minimum)*multiplier; - if (iPos>=0.0f || iPosdirty(); return; } - ValueMap::const_iterator lower_itr = vcm.begin(); - ValueMap::const_iterator upper_itr = lower_itr; + ColorMap::const_iterator lower_itr = _colorMap.begin(); + ColorMap::const_iterator upper_itr = lower_itr; ++upper_itr; for(; - upper_itr != vcm.end(); + upper_itr != _colorMap.end(); ++upper_itr) { float lower_v = lower_itr->first; 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); - } + assignToImage(lower_v, lower_c, upper_v, upper_c); lower_itr = upper_itr; } _image->dirty(); } - diff --git a/src/osgPlugins/osg/TransferFunction.cpp b/src/osgPlugins/osg/TransferFunction.cpp index f5d3f6c29..43726f802 100644 --- a/src/osgPlugins/osg/TransferFunction.cpp +++ b/src/osgPlugins/osg/TransferFunction.cpp @@ -31,22 +31,60 @@ bool TransferFunction1D_readLocalData(osg::Object& obj, osgDB::Input &fr) osg::TransferFunction1D& tf = static_cast(obj); bool itrAdvanced = false; + + unsigned int numCells; + if (fr.read("NumberImageCells ",numCells)) + { + tf.allocate(numCells); + itrAdvanced = true; + } + + if (fr.matchSequence("Colours {")) + { + int entry = fr[0].getNoNestedBrackets(); + + fr += 2; + + float v; + osg::Vec4 color; + osg::TransferFunction1D::ColorMap colorMap; + + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + if (fr.read(v, color.r(), color.g(), color.b(), color.a())) + { + colorMap[v] = color; + } + else + { + ++fr; + } + } + + tf.assign(colorMap); + + itrAdvanced = true; + } + + return itrAdvanced; } bool TransferFunction1D_writeLocalData(const osg::Object& obj, osgDB::Output& fw) { const osg::TransferFunction1D& tf = static_cast(obj); - - fw.indent()<<"Minimum "<second; + fw.indent()<first<<" "< tf = new osg::TransferFunction1D; - - int entry = fr[0].getNoNestedBrackets(); - - fr += 2; - - std::vector colours; - - while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) - { - bool itrAdvanced = false; - if (fr.matchSequence("range %f %f")) - { - float minValue,maxValue; - fr[1].getFloat(minValue); - fr[2].getFloat(maxValue); - - tf->setInputRange(minValue,maxValue); - - fr += 3; - itrAdvanced = true; - } - - if (fr.matchSequence("color %f %f %f %f")) - { - float r,g,b,a; - fr[1].getFloat(r); - fr[2].getFloat(g); - fr[3].getFloat(b); - fr[4].getFloat(a); - - colours.push_back(osg::Vec4(r,g,b,a)); - - fr += 5; - itrAdvanced = true; - } - - if (fr.matchSequence("color %f %f %f")) - { - float r,g,b; - fr[1].getFloat(r); - fr[2].getFloat(g); - fr[3].getFloat(b); - - colours.push_back(osg::Vec4(r,g,b,1.0f)); - - fr += 5; - itrAdvanced = true; - } - - if (!itrAdvanced) - { - if (fr[0].getStr()) osg::notify(osg::NOTICE)<<"TransferFunction - unreconised token : "<allocate(colours.size()); - for(unsigned int i=0; isetValue(i, colours[i]); - } - } - - if (tf->getNumberCellsX()==0) - { - tf->allocate(6); - tf->setValue(0, osg::Vec4(1.0,1.0,1.0,1.0)); - tf->setValue(1, osg::Vec4(1.0,0.0,1.0,1.0)); - tf->setValue(2, osg::Vec4(1.0,0.0,0.0,1.0)); - tf->setValue(3, osg::Vec4(1.0,1.0,0.0,1.0)); - tf->setValue(4, osg::Vec4(0.0,1.0,1.0,1.0)); - tf->setValue(5, osg::Vec4(0.0,1.0,0.0,1.0)); - } - - return tf.release(); -} - - bool TerrainTile_readLocalData(osg::Object& obj, osgDB::Input &fr) { osgTerrain::TerrainTile& terrainTile = static_cast(obj); diff --git a/src/osgPlugins/osgVolume/VolumeTile.cpp b/src/osgPlugins/osgVolume/VolumeTile.cpp index 18a4fdf7b..ab5ac17ae 100644 --- a/src/osgPlugins/osgVolume/VolumeTile.cpp +++ b/src/osgPlugins/osgVolume/VolumeTile.cpp @@ -25,93 +25,6 @@ osgDB::RegisterDotOsgWrapperProxy VolumeTile_Proxy VolumeTile_writeLocalData ); -osg::TransferFunction* readTransferFunction(osgDB::Input& fr) -{ - osg::ref_ptr tf = new osg::TransferFunction1D; - - int entry = fr[0].getNoNestedBrackets(); - - fr += 2; - - std::vector colours; - - while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) - { - bool itrAdvanced = false; - if (fr.matchSequence("range %f %f")) - { - float minValue,maxValue; - fr[1].getFloat(minValue); - fr[2].getFloat(maxValue); - - tf->setInputRange(minValue,maxValue); - - fr += 3; - itrAdvanced = true; - } - - if (fr.matchSequence("color %f %f %f %f")) - { - float r,g,b,a; - fr[1].getFloat(r); - fr[2].getFloat(g); - fr[3].getFloat(b); - fr[4].getFloat(a); - - colours.push_back(osg::Vec4(r,g,b,a)); - - fr += 5; - itrAdvanced = true; - } - - if (fr.matchSequence("color %f %f %f")) - { - float r,g,b; - fr[1].getFloat(r); - fr[2].getFloat(g); - fr[3].getFloat(b); - - colours.push_back(osg::Vec4(r,g,b,1.0f)); - - fr += 5; - itrAdvanced = true; - } - - if (!itrAdvanced) - { - if (fr[0].getStr()) osg::notify(osg::NOTICE)<<"TransferFunction - unreconised token : "<allocate(colours.size()); - for(unsigned int i=0; isetValue(i, colours[i]); - } - } - - if (tf->getNumberCellsX()==0) - { - tf->allocate(6); - tf->setValue(0, osg::Vec4(1.0,1.0,1.0,1.0)); - tf->setValue(1, osg::Vec4(1.0,0.0,1.0,1.0)); - tf->setValue(2, osg::Vec4(1.0,0.0,0.0,1.0)); - tf->setValue(3, osg::Vec4(1.0,1.0,0.0,1.0)); - tf->setValue(4, osg::Vec4(0.0,1.0,1.0,1.0)); - tf->setValue(5, osg::Vec4(0.0,1.0,0.0,1.0)); - } - - return tf.release(); -} - - bool VolumeTile_readLocalData(osg::Object& obj, osgDB::Input &fr) { osgVolume::VolumeTile& volumeTile = static_cast(obj); diff --git a/src/osgTerrain/Layer.cpp b/src/osgTerrain/Layer.cpp index 5e7d1d15b..c96260bd8 100644 --- a/src/osgTerrain/Layer.cpp +++ b/src/osgTerrain/Layer.cpp @@ -328,16 +328,20 @@ bool ContourLayer::transform(float offset, float scale) osg::notify(osg::NOTICE)<<"ContourLayer::transform("<getNumberCellsX(); ++i) + osg::TransferFunction1D::ColorMap newColorMap = _tf->getColorMap(); + for(osg::TransferFunction1D::ColorMap::iterator itr = newColorMap.begin(); + itr != newColorMap.end(); + ++itr) { - osg::Vec4 value = _tf->getValue(i); + osg::Vec4& value = itr->second; value.r() = offset + value.r()* scale; value.g() = offset + value.g()* scale; value.b() = offset + value.b()* scale; value.a() = offset + value.a()* scale; - _tf->setValue(i, value); } + _tf->assign(newColorMap); + dirty(); return true; @@ -347,7 +351,7 @@ bool ContourLayer::getValue(unsigned int i, unsigned int j, float& value) const { if (!_tf) return false; - const osg::Vec4& v = _tf->getValue(i); + const osg::Vec4& v = _tf->getPixelValue(i); value = v[0]; return true; @@ -357,7 +361,7 @@ bool ContourLayer::getValue(unsigned int i, unsigned int j, osg::Vec2& value) co { if (!_tf) return false; - const osg::Vec4& v = _tf->getValue(i); + const osg::Vec4& v = _tf->getPixelValue(i); value.x() = v.x(); value.y() = v.y(); @@ -368,7 +372,7 @@ bool ContourLayer::getValue(unsigned int i, unsigned int j, osg::Vec3& value) co { if (!_tf) return false; - const osg::Vec4& v = _tf->getValue(i); + const osg::Vec4& v = _tf->getPixelValue(i); value.x() = v.x(); value.y() = v.y(); value.z() = v.z(); @@ -380,7 +384,7 @@ bool ContourLayer::getValue(unsigned int i, unsigned int j, osg::Vec4& value) co { if (!_tf) return false; - value = _tf->getValue(i); + value = _tf->getPixelValue(i); return true; } diff --git a/src/osgViewer/CMakeLists.txt b/src/osgViewer/CMakeLists.txt index 0b2bcfe70..6347eb79a 100644 --- a/src/osgViewer/CMakeLists.txt +++ b/src/osgViewer/CMakeLists.txt @@ -117,7 +117,8 @@ ELSE(WIN32) IF(OSGVIEWER_USE_XRANDR) ADD_DEFINITIONS(-DOSGVIEWER_USE_XRANDR) SET(LIB_PRIVATE_HEADERS ${LIB_PRIVATE_HEADERS} ${XRANDR_INCLUDE_DIRS} ) - SET(LIB_EXTRA_LIBS ${X11_Xrandr_LIB} ${LIB_EXTRA_LIBS}) +# SET(LIB_EXTRA_LIBS ${X11_Xrandr_LIB} ${LIB_EXTRA_LIBS}) + SET(LIB_EXTRA_LIBS ${XRANDR_LIBRARIES} ${LIB_EXTRA_LIBS}) ENDIF(OSGVIEWER_USE_XRANDR) # X11 on Apple requires X11 library plus OpenGL linking hack on Leopard diff --git a/src/osgVolume/Layer.cpp b/src/osgVolume/Layer.cpp index 87b7958e8..6f4946be0 100644 --- a/src/osgVolume/Layer.cpp +++ b/src/osgVolume/Layer.cpp @@ -398,7 +398,7 @@ struct ApplyTransferFunctionOperator inline void luminance(float l) const { - osg::Vec4 c = _tf->getInterpolatedValue(l); + osg::Vec4 c = _tf->getColor(l); //std::cout<<"l = "<, osg::TransferFunction1D::ValueMap) +TYPE_NAME_ALIAS(std::map< float COMMA osg::Vec4 >, osg::TransferFunction1D::ColorMap) BEGIN_OBJECT_REFLECTOR(osg::TransferFunction1D) I_DeclaringFile("osg/TransferFunction"); @@ -51,79 +82,113 @@ BEGIN_OBJECT_REFLECTOR(osg::TransferFunction1D) I_Constructor0(____TransferFunction1D, "", ""); - I_Method2(void, setInputRange, IN, float, minimum, IN, float, maximum, - Properties::NON_VIRTUAL, - __void__setInputRange__float__float, - "", - ""); - I_Method1(void, setMinimum, IN, float, value, - Properties::NON_VIRTUAL, - __void__setMinimum__float, + I_ConstructorWithDefaults2(IN, const osg::TransferFunction1D &, tf, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY, + ____TransferFunction1D__C5_TransferFunction1D_R1__C5_CopyOp_R1, + "Copy constructor using CopyOp to manage deep vs shallow copy. ", + ""); + I_Method0(osg::Object *, cloneType, + Properties::VIRTUAL, + __osg_Object_P1__cloneType, + "Clone the type of an object, with Object* return type. ", + "Must be defined by derived classes. "); + I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop, + Properties::VIRTUAL, + __osg_Object_P1__clone__C5_osg_CopyOp_R1, + "Clone an object, with Object* return type. ", + "Must be defined by derived classes. "); + I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj, + Properties::VIRTUAL, + __bool__isSameKindAs__C5_osg_Object_P1, "", ""); + I_Method0(const char *, libraryName, + Properties::VIRTUAL, + __C5_char_P1__libraryName, + "return the name of the object's library. ", + "Must be defined by derived classes. The OpenSceneGraph convention is that the namespace of a library is the same as the library name. "); + I_Method0(const char *, className, + Properties::VIRTUAL, + __C5_char_P1__className, + "return the name of the object's class type. ", + "Must be defined by derived classes. "); I_Method0(float, getMinimum, Properties::NON_VIRTUAL, __float__getMinimum, - "", - ""); - I_Method1(void, setMaximum, IN, float, value, - Properties::NON_VIRTUAL, - __void__setMaximum__float, - "", + "Get the mnimum transfer function value. ", ""); I_Method0(float, getMaximum, Properties::NON_VIRTUAL, __float__getMaximum, - "", + "Get the maximum transfer function value. ", ""); - I_Method1(void, allocate, IN, unsigned int, numX, + I_Method1(void, allocate, IN, unsigned int, numImageCells, Properties::NON_VIRTUAL, __void__allocate__unsigned_int, - "", - ""); + "allocate the osg::Image with specified dimension. ", + "The Image tracks the color map, and is used to represent the transfer function when download to the graphics card. "); I_MethodWithDefaults1(void, clear, IN, const osg::Vec4 &, color, osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f), Properties::NON_VIRTUAL, __void__clear__C5_osg_Vec4_R1, - "", + "Clear the whole range to just represet a single color. ", ""); - I_Method0(unsigned int, getNumberCellsX, + I_Method1(osg::Vec4, getPixelValue, IN, unsigned int, i, Properties::NON_VIRTUAL, - __unsigned_int__getNumberCellsX, - "", + __osg_Vec4__getPixelValue__unsigned_int, + "Get pixel value from the image. ", ""); - I_Method2(void, setValue, IN, unsigned int, i, IN, const osg::Vec4 &, color, + I_Method0(unsigned int, getNumberImageCells, Properties::NON_VIRTUAL, - __void__setValue__unsigned_int__C5_osg_Vec4_R1, - "", + __unsigned_int__getNumberImageCells, + "Get the number of image cells that are assigned to the represent the transfer function when download to the graphics card. ", ""); - I_Method1(const osg::Vec4 &, getValue, IN, unsigned int, i, + I_MethodWithDefaults3(void, setColor, IN, float, v, , IN, const osg::Vec4 &, color, , IN, bool, updateImage, true, + Properties::NON_VIRTUAL, + __void__setColor__float__C5_osg_Vec4_R1__bool, + "Set the color for a specified transfer function value. ", + "updateImage defaults to true, and tells the setColor function to update the associate osg::Image that tracks the color map. Pass in false as the updateImage parameter if you are setting up many values at once to avoid recomputating og the image data, then once all setColor calls are made explictly call updateImage() to bring the osg::Image back into sync with the color map. "); + I_Method1(osg::Vec4, getColor, IN, float, v, Properties::NON_VIRTUAL, - __C5_osg_Vec4_R1__getValue__unsigned_int, - "", + __osg_Vec4__getColor__float, + "Get the color for a specified transfer function value, interpolating the value if no exact match is found. ", ""); - I_Method1(osg::Vec4, getInterpolatedValue, IN, float, v, + I_Method0(osg::TransferFunction1D::ColorMap &, getColorMap, Properties::NON_VIRTUAL, - __osg_Vec4__getInterpolatedValue__float, - "", + __ColorMap_R1__getColorMap, + "Get the color map that stores the mapping between the the tranfser function value and the colour it maps to. ", ""); - I_Method2(void, assign, IN, const osg::TransferFunction1D::ValueMap &, vcm, IN, bool, updateMinMaxRange, + I_Method0(const osg::TransferFunction1D::ColorMap &, getColorMap, Properties::NON_VIRTUAL, - __void__assign__C5_ValueMap_R1__bool, - "", + __C5_ColorMap_R1__getColorMap, + "Get the const color map that stores the mapping between the the tranfser function value and the colour it maps to. ", ""); + I_Method1(void, assign, IN, const osg::TransferFunction1D::ColorMap &, vcm, + Properties::NON_VIRTUAL, + __void__assign__C5_ColorMap_R1, + "Assign a color map and automatically update the image to make sure they are in sync. ", + ""); + I_Method0(void, updateImage, + Properties::NON_VIRTUAL, + __void__updateImage, + "Manually update the associate osg::Image to represent the colors assigned in the color map. ", + ""); + I_ProtectedMethod4(void, assignToImage, IN, float, lower_v, IN, const osg::Vec4 &, lower_c, IN, float, upper_v, IN, const osg::Vec4 &, upper_c, + Properties::NON_VIRTUAL, + Properties::NON_CONST, + __void__assignToImage__float__C5_osg_Vec4_R1__float__C5_osg_Vec4_R1, + "", + ""); + I_SimpleProperty(osg::TransferFunction1D::ColorMap &, ColorMap, + __ColorMap_R1__getColorMap, + 0); I_SimpleProperty(float, Maximum, __float__getMaximum, - __void__setMaximum__float); + 0); I_SimpleProperty(float, Minimum, __float__getMinimum, - __void__setMinimum__float); - I_SimpleProperty(unsigned int, NumberCellsX, - __unsigned_int__getNumberCellsX, 0); - I_IndexedProperty(const osg::Vec4 &, Value, - __C5_osg_Vec4_R1__getValue__unsigned_int, - __void__setValue__unsigned_int__C5_osg_Vec4_R1, - 0); + I_SimpleProperty(unsigned int, NumberImageCells, + __unsigned_int__getNumberImageCells, + 0); END_REFLECTOR STD_MAP_REFLECTOR(std::map< float COMMA osg::Vec4 >)