Renamed the osgVolume::Layer/ImageDetails parameters RescaleIntercept and RescaleSlope to more general TexelOffset and TexelScale, and changed type to Vec4.

Refactored the transfer function set up in RayTracedTechnique to prepare for new scale and offset uniforms.

Updated wrappers
This commit is contained in:
Robert Osfield 2009-09-03 13:40:50 +00:00
parent 43e3089417
commit fa84f280f6
6 changed files with 205 additions and 74 deletions

View File

@ -1353,8 +1353,8 @@ int main( int argc, char **argv )
if (details)
{
layer->setRescaleIntercept(details->getRescaleIntercept());
layer->setRescaleSlope(details->getRescaleSlope());
layer->setTexelOffset(details->getTexelOffset());
layer->setTexelScale(details->getTexelScale());
}
switch(rescaleOperation)

View File

@ -34,11 +34,11 @@ class OSGVOLUME_EXPORT ImageDetails : public osg::Object
META_Object(osgVolume, ImageDetails);
void setRescaleIntercept(double intercept) { _rescaleIntercept = intercept; }
double getRescaleIntercept() const { return _rescaleIntercept; }
void setTexelOffset(const osg::Vec4& offset) { _texelOffset = offset; }
const osg::Vec4& getTexelOffset() const { return _texelOffset; }
void setRescaleSlope(double slope) { _rescaleSlope = slope; }
double getRescaleSlope() const { return _rescaleSlope; }
void setTexelScale(const osg::Vec4& scale) { _texelScale = scale; }
const osg::Vec4& getTexelScale() const { return _texelScale; }
void setMatrix(osg::RefMatrix* matrix) { _matrix = matrix; }
osg::RefMatrix* getMatrix() { return _matrix.get(); }
@ -46,8 +46,8 @@ class OSGVOLUME_EXPORT ImageDetails : public osg::Object
protected:
double _rescaleIntercept;
double _rescaleSlope;
osg::Vec4 _texelOffset;
osg::Vec4 _texelScale;
osg::ref_ptr<osg::RefMatrix> _matrix;
};
@ -163,11 +163,11 @@ class OSGVOLUME_EXPORT ImageLayer : public Layer
virtual const osg::Image* getImage() const { return _image.get(); }
void setRescaleIntercept(double intercept) { _rescaleIntercept = intercept; }
double getRescaleIntercept() const { return _rescaleIntercept; }
void setTexelOffset(const osg::Vec4& offset) { _texelOffset = offset; }
const osg::Vec4& getTexelOffset() const { return _texelOffset; }
void setRescaleSlope(double slope) { _rescaleSlope = slope; }
double setRescaleSlope() const { return _rescaleSlope; }
void setTexelScale(const osg::Vec4& scale) { _texelScale = scale; }
const osg::Vec4& getTexelScale() const { return _texelScale; }
/** Compute the min and max pixel colors.*/
@ -194,8 +194,8 @@ class OSGVOLUME_EXPORT ImageLayer : public Layer
virtual ~ImageLayer() {}
double _rescaleIntercept;
double _rescaleSlope;
osg::Vec4 _texelOffset;
osg::Vec4 _texelScale;
osg::ref_ptr<osg::Image> _image;
};

View File

@ -212,8 +212,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
if (details)
{
layer->setRescaleIntercept(details->getRescaleIntercept());
layer->setRescaleSlope(details->getRescaleSlope());
layer->setTexelOffset(details->getTexelOffset());
layer->setTexelScale(details->getTexelScale());
}
if (matrix)
@ -593,10 +593,10 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
const char *classUID = NULL;
if (fileformat.getDataset()->findAndGetString(DCM_SOPClassUID, classUID).good())
{
osg::notify(osg::NOTICE)<<" classUID = "<<classUID<<std::endl;
info()<<" classUID = "<<classUID<<std::endl;
if (0 == strcmp(classUID, UID_CTImageStorage))
{
osg::notify(osg::NOTICE)<<" is a UID_CTImageStorage "<<std::endl;
info()<<" is a UID_CTImageStorage "<<std::endl;
}
}
@ -607,8 +607,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
{
fileInfo.rescaleIntercept = rescaleIntercept;
fileInfo.rescaleSlope = rescaleSlope;
osg::notify(osg::NOTICE)<<" rescaleIntercept = "<<rescaleIntercept<<std::endl;
osg::notify(osg::NOTICE)<<" rescaleSlope = "<<rescaleSlope<<std::endl;
info()<<" rescaleIntercept = "<<rescaleIntercept<<std::endl;
info()<<" rescaleSlope = "<<rescaleSlope<<std::endl;
}
@ -829,8 +829,22 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
(*matrix)(1,2) = fileInfo.matrix(1,2) * averageThickness;
(*matrix)(2,2) = fileInfo.matrix(2,2) * averageThickness;
details->setRescaleIntercept(fileInfo.rescaleIntercept);
details->setRescaleSlope(fileInfo.rescaleSlope);
// note from Robert Osfield, testing various dicom files I have found that the rescaleIntercept
// for CT data doesn't look to be applicable as an straight value offset, so we'll ignore for now.
// details->setTexelOffset(fileInfo.rescaleIntercept);
double s = fileInfo.rescaleSlope;
switch(dataType)
{
case(GL_BYTE): s *= 128.0; break;
case(GL_UNSIGNED_BYTE): s *= 255.0; break;
case(GL_SHORT): s *= 32768.0; break;
case(GL_UNSIGNED_SHORT): s *= 65535.0; break;
case(GL_INT): s *= 2147483648.0; break;
case(GL_UNSIGNED_INT): s *= 4294967295.0; break;
default: break;
}
details->setTexelScale(osg::Vec4(s,s,s,s));
image = new osg::Image;
image->setUserData(details.get());

View File

@ -22,14 +22,14 @@
using namespace osgVolume;
ImageDetails::ImageDetails():
_rescaleIntercept(0.0),
_rescaleSlope(1.0)
_texelOffset(0.0,0.0,0.0,0.0),
_texelScale(1.0,1.0,1.0,1.0)
{
}
ImageDetails::ImageDetails(const ImageDetails& rhs,const osg::CopyOp& copyop):
_rescaleIntercept(rhs._rescaleIntercept),
_rescaleSlope(rhs._rescaleSlope),
_texelOffset(rhs._texelOffset),
_texelScale(rhs._texelScale),
_matrix(rhs._matrix)
{
}
@ -95,16 +95,16 @@ void Layer::addProperty(Property* property)
// ImageLayer
//
ImageLayer::ImageLayer(osg::Image* image):
_rescaleIntercept(0.0),
_rescaleSlope(1.0),
_texelOffset(0.0,0.0,0.0,0.0),
_texelScale(1.0,1.0,1.0,1.0),
_image(image)
{
}
ImageLayer::ImageLayer(const ImageLayer& imageLayer,const osg::CopyOp& copyop):
Layer(imageLayer, copyop),
_rescaleIntercept(imageLayer._rescaleIntercept),
_rescaleSlope(imageLayer._rescaleSlope),
_texelOffset(imageLayer._texelOffset),
_texelScale(imageLayer._texelScale),
_image(imageLayer._image)
{
}
@ -141,14 +141,48 @@ void ImageLayer::offsetAndScaleImage(const osg::Vec4& offset, const osg::Vec4& s
{
if (!_image) return;
#if 0
osg::Vec4 minValue, maxValue;
if (computeMinMax(minValue, maxValue))
{
osg::notify(osg::NOTICE)<<"ImageLayer::offsetAndScaleImage("<<offset<<" and "<<scale<<")"<<std::endl;
osg::notify(osg::NOTICE)<<" before _texelOffset "<<_texelOffset<<std::endl;
osg::notify(osg::NOTICE)<<" before _texelScale "<<_texelScale<<std::endl;
osg::notify(osg::NOTICE)<<" before minValue "<<minValue<<std::endl;
osg::notify(osg::NOTICE)<<" before maxValue "<<maxValue<<std::endl;
osg::notify(osg::NOTICE)<<" before minValue transformed "<<minValue[0]*_texelScale[0]+_texelOffset[0]<<std::endl;
osg::notify(osg::NOTICE)<<" before maxValue transformed "<<maxValue[0]*_texelScale[0]+_texelOffset[0]<<std::endl;
}
#endif
osg::offsetAndScaleImage(_image.get(), offset, scale);
_texelScale[0] /= scale[0];
_texelScale[1] /= scale[1];
_texelScale[2] /= scale[2];
_texelScale[3] /= scale[3];
_texelOffset[0] -= offset[0]*_texelScale[0];
_texelOffset[1] -= offset[1]*_texelScale[1];
_texelOffset[2] -= offset[2]*_texelScale[2];
_texelOffset[3] -= offset[3]*_texelScale[3];
#if 0
if (computeMinMax(minValue, maxValue))
{
osg::notify(osg::NOTICE)<<" after _texelOffset "<<_texelOffset<<std::endl;
osg::notify(osg::NOTICE)<<" after _texelScale "<<_texelScale<<std::endl;
osg::notify(osg::NOTICE)<<" after minValue "<<minValue<<std::endl;
osg::notify(osg::NOTICE)<<" after maxValue "<<maxValue<<std::endl;
osg::notify(osg::NOTICE)<<" after minValue transformed "<<minValue[0]*_texelScale[0]+_texelOffset[0]<<std::endl;
osg::notify(osg::NOTICE)<<" after maxValue transformed "<<maxValue[0]*_texelScale[0]+_texelOffset[0]<<std::endl;
}
#endif
}
void ImageLayer::rescaleToZeroToOneRange()
{
osg::notify(osg::NOTICE)<<"ImageLayer::rescaleToZeroToOneRange()"<<std::endl;
osg::notify(osg::NOTICE)<<" _rescaleIntercept "<<_rescaleIntercept<<std::endl;
osg::notify(osg::NOTICE)<<" _rescaleSlope "<<_rescaleSlope<<std::endl;
osg::Vec4 minValue, maxValue;
if (computeMinMax(minValue, maxValue))

View File

@ -249,16 +249,28 @@ void RayTracedTechnique::init()
bool enableBlending = false;
if (tf)
{
osg::ref_ptr<osg::Texture1D> tf_texture = new osg::Texture1D;
tf_texture->setImage(tf->getImage());
tf_texture->setResizeNonPowerOfTwoHint(false);
tf_texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
tf_texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
tf_texture->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
osg::ref_ptr<osg::Uniform> tf_sampler = new osg::Uniform("tfTexture",1);
stateset->setTextureAttributeAndModes(1, tf_texture.get(), osg::StateAttribute::ON);
stateset->addUniform(tf_sampler.get());
}
if (shadingModel==MaximumIntensityProjection)
{
enableBlending = true;
if (tf)
{
osg::Texture1D* texture1D = new osg::Texture1D;
texture1D->setImage(tf->getImage());
stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON);
osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/volume_tf_mip.frag");
if (fragmentShader)
{
@ -295,17 +307,6 @@ void RayTracedTechnique::init()
if (tf)
{
osg::Texture1D* texture1D = new osg::Texture1D;
texture1D->setImage(tf->getImage());
texture1D->setResizeNonPowerOfTwoHint(false);
texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON);
osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1);
stateset->addUniform(tfTextureSampler);
osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/volume_tf_iso.frag");
if (fragmentShader)
{
@ -341,17 +342,6 @@ void RayTracedTechnique::init()
if (tf)
{
osg::Texture1D* texture1D = new osg::Texture1D;
texture1D->setImage(tf->getImage());
texture1D->setResizeNonPowerOfTwoHint(false);
texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON);
osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1);
stateset->addUniform(tfTextureSampler);
osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/volume_lit_tf.frag");
if (fragmentShader)
{
@ -366,7 +356,6 @@ void RayTracedTechnique::init()
}
else
{
osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/volume_lit.frag");
if (fragmentShader)
{
@ -385,19 +374,6 @@ void RayTracedTechnique::init()
if (tf)
{
osg::notify(osg::INFO)<<"Setting up TF path"<<std::endl;
osg::Texture1D* texture1D = new osg::Texture1D;
texture1D->setImage(tf->getImage());
texture1D->setResizeNonPowerOfTwoHint(false);
texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON);
osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1);
stateset->addUniform(tfTextureSampler);
osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/volume_tf.frag");
if (fragmentShader)
{
@ -412,7 +388,6 @@ void RayTracedTechnique::init()
}
else
{
osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/volume.frag");
if (fragmentShader)
{
@ -425,7 +400,7 @@ void RayTracedTechnique::init()
}
}
}
if (cpv._sampleDensityProperty.valid())
stateset->addUniform(cpv._sampleDensityProperty->getUniform());
else

View File

@ -13,6 +13,7 @@
#include <osg/BoundingSphere>
#include <osg/CopyOp>
#include <osg/Image>
#include <osg/Matrix>
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/Texture>
@ -132,6 +133,87 @@ BEGIN_OBJECT_REFLECTOR(osgVolume::CompositeLayer)
__void__removeLayer__unsigned_int);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgVolume::ImageDetails)
I_DeclaringFile("osgVolume/Layer");
I_BaseType(osg::Object);
I_Constructor0(____ImageDetails,
"",
"");
I_ConstructorWithDefaults2(IN, const osgVolume::ImageDetails &, x, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
____ImageDetails__C5_ImageDetails_R1__C5_osg_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 &, x,
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_Method1(void, setTexelOffset, IN, const osg::Vec4 &, offset,
Properties::NON_VIRTUAL,
__void__setTexelOffset__C5_osg_Vec4_R1,
"",
"");
I_Method0(const osg::Vec4 &, getTexelOffset,
Properties::NON_VIRTUAL,
__C5_osg_Vec4_R1__getTexelOffset,
"",
"");
I_Method1(void, setTexelScale, IN, const osg::Vec4 &, scale,
Properties::NON_VIRTUAL,
__void__setTexelScale__C5_osg_Vec4_R1,
"",
"");
I_Method0(const osg::Vec4 &, getTexelScale,
Properties::NON_VIRTUAL,
__C5_osg_Vec4_R1__getTexelScale,
"",
"");
I_Method1(void, setMatrix, IN, osg::RefMatrix *, matrix,
Properties::NON_VIRTUAL,
__void__setMatrix__osg_RefMatrix_P1,
"",
"");
I_Method0(osg::RefMatrix *, getMatrix,
Properties::NON_VIRTUAL,
__osg_RefMatrix_P1__getMatrix,
"",
"");
I_Method0(const osg::RefMatrix *, getMatrix,
Properties::NON_VIRTUAL,
__C5_osg_RefMatrix_P1__getMatrix,
"",
"");
I_SimpleProperty(osg::RefMatrix *, Matrix,
__osg_RefMatrix_P1__getMatrix,
__void__setMatrix__osg_RefMatrix_P1);
I_SimpleProperty(const osg::Vec4 &, TexelOffset,
__C5_osg_Vec4_R1__getTexelOffset,
__void__setTexelOffset__C5_osg_Vec4_R1);
I_SimpleProperty(const osg::Vec4 &, TexelScale,
__C5_osg_Vec4_R1__getTexelScale,
__void__setTexelScale__C5_osg_Vec4_R1);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgVolume::ImageLayer)
I_DeclaringFile("osgVolume/Layer");
I_BaseType(osgVolume::Layer);
@ -194,6 +276,26 @@ BEGIN_OBJECT_REFLECTOR(osgVolume::ImageLayer)
__C5_osg_Image_P1__getImage,
"Return const image associated with layer. ",
"");
I_Method1(void, setTexelOffset, IN, const osg::Vec4 &, offset,
Properties::NON_VIRTUAL,
__void__setTexelOffset__C5_osg_Vec4_R1,
"",
"");
I_Method0(const osg::Vec4 &, getTexelOffset,
Properties::NON_VIRTUAL,
__C5_osg_Vec4_R1__getTexelOffset,
"",
"");
I_Method1(void, setTexelScale, IN, const osg::Vec4 &, scale,
Properties::NON_VIRTUAL,
__void__setTexelScale__C5_osg_Vec4_R1,
"",
"");
I_Method0(const osg::Vec4 &, getTexelScale,
Properties::NON_VIRTUAL,
__C5_osg_Vec4_R1__getTexelScale,
"",
"");
I_Method2(bool, computeMinMax, IN, osg::Vec4 &, min, IN, osg::Vec4 &, max,
Properties::NON_VIRTUAL,
__bool__computeMinMax__osg_Vec4_R1__osg_Vec4_R1,
@ -248,6 +350,12 @@ BEGIN_OBJECT_REFLECTOR(osgVolume::ImageLayer)
I_SimpleProperty(unsigned int, ModifiedCount,
__unsigned_int__getModifiedCount,
__void__setModifiedCount__unsigned_int);
I_SimpleProperty(const osg::Vec4 &, TexelOffset,
__C5_osg_Vec4_R1__getTexelOffset,
__void__setTexelOffset__C5_osg_Vec4_R1);
I_SimpleProperty(const osg::Vec4 &, TexelScale,
__C5_osg_Vec4_R1__getTexelScale,
__void__setTexelScale__C5_osg_Vec4_R1);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgVolume::Layer)