Commit 894aa901 authored by schultezub's avatar schultezub

moved numChannels field from ImageRepresentationXYZ to ImageData

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@405 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 18997156
......@@ -158,7 +158,11 @@ namespace campvis {
return _imageHandle;
}
void AbstractTransferFunction::setImageHandle(const DataHandle& imageHandle) {
void AbstractTransferFunction::setImageHandle(DataHandle imageHandle) {
tgtAssert(
imageHandle.getData() == 0 || dynamic_cast<const ImageData*>(imageHandle.getData()) != 0,
"The data in the image handle must either be 0 or point to a valid ImageData object!");
_imageHandle = imageHandle;
_dirtyHistogram = true;
s_imageHandleChanged();
......
......@@ -125,17 +125,19 @@ namespace campvis {
const tgt::Texture* getTexture();
/**
* Returns a DataHandle to the image for this transfer function, may be 0.
* \return _imageHandle, may be 0!
* Returns a DataHandle to the image for this transfer function, its pointer may be 0.
* \note If the data in \a imageHandle is not 0, it points to a valid ImageData object.
* \return _imageHandle, its pointer may be 0.
*/
DataHandle getImageHandle() const;
/**
* Sets the DataHandle for this transfer function, may be 0.
* \note This method makes a copy of \a imageHandle, hence does not take ownership.
* \param imageHandle The new DataHandle for this transfer function
* Sets the DataHandle for this transfer function, its pointer may be 0.
* \note If the data in \a imageHandle is not 0, it must point to a valid ImageData object.
* \param imageHandle The new DataHandle for this transfer function, if its pointer is
* not 0 it must point to a valid ImageData object.
*/
void setImageHandle(const DataHandle& imageHandle);
void setImageHandle(DataHandle imageHandle);
/**
* Returns the intensity histogram
......
......@@ -173,9 +173,10 @@ namespace campvis {
template<typename BASETYPE, size_t NUMCHANNELS>
campvis::GenericImageRepresentationLocal<BASETYPE, NUMCHANNELS>::GenericImageRepresentationLocal(const ImageData* parent, ElementType* data)
: ImageRepresentationLocal(parent, TypeTraits<BASETYPE, NUMCHANNELS>::weaklyTypedPointerBaseType, NUMCHANNELS)
: ImageRepresentationLocal(parent, TypeTraits<BASETYPE, NUMCHANNELS>::weaklyTypedPointerBaseType)
, _data(data)
{
tgtAssert(_parent->getNumChannels() == NUMCHANNELS, "Number of channels must match parent image's number of channels!");
if (_data == 0) {
size_t numElements = getNumElements();
_data = new ElementType[numElements];
......
......@@ -32,13 +32,15 @@
namespace campvis {
const std::string ImageData::loggerCat_ = "CAMPVis.core.datastructures.ImageData";
ImageData::ImageData(size_t dimensionality, const tgt::svec3& size)
ImageData::ImageData(size_t dimensionality, const tgt::svec3& size, size_t numChannels)
: AbstractData()
, _dimensionality(dimensionality)
, _size(size)
, _numChannels(numChannels)
, _numElements(tgt::hmul(size))
, _mappingInformation(size, tgt::vec3(0.f), tgt::vec3(1.f)) // TODO: get offset/voxel size as parameter or put default values into ImageMappingInformation ctor.
{
tgtAssert(numChannels > 0, "Number of channels must be greater than 0!");
}
ImageData::~ImageData() {
......@@ -46,7 +48,7 @@ namespace campvis {
}
ImageData* ImageData::clone() const {
ImageData* toReturn = new ImageData(_dimensionality, _size);
ImageData* toReturn = new ImageData(_dimensionality, _size, _numChannels);
toReturn->_mappingInformation = _mappingInformation;
toReturn->_representations.assign(_representations.begin(), _representations.end());
return toReturn;
......@@ -76,6 +78,10 @@ namespace campvis {
return _size;
}
size_t ImageData::getNumChannels() const {
return _numChannels;
}
const ImageMappingInformation& ImageData::getMappingInformation() const {
return _mappingInformation;
}
......@@ -111,7 +117,7 @@ namespace campvis {
newDimensionality = 3;
// create new ImageData object and assign mapping information
ImageData* toReturn = new ImageData(newDimensionality, newSize);
ImageData* toReturn = new ImageData(newDimensionality, newSize, _numChannels);
toReturn->_mappingInformation = ImageMappingInformation(newSize, _mappingInformation.getOffset(), _mappingInformation.getVoxelSize(), _mappingInformation.getRealWorldMapping());
// create sub-image of every image representation
......
......@@ -50,8 +50,15 @@ namespace campvis {
*/
class ImageData : public AbstractData {
public:
ImageData(size_t dimensionality, const tgt::svec3& size);
/**
* Creates a new ImageData instance with the given parameters.
* \param dimensionality Dimensionality of this image
* \param size Size of this image (number of elements per dimension)
* \param numChannels Number of channels per element
*/
ImageData(size_t dimensionality, const tgt::svec3& size, size_t numChannels);
/// Destructor
virtual ~ImageData();
/**
......@@ -85,6 +92,12 @@ namespace campvis {
*/
const tgt::svec3& getSize() const;
/**
* Returns the number of channels per element.
* \return _numChannels
*/
size_t getNumChannels() const;
/**
* Returns the number of elements (= tgt::hmul(getSize())).
* \return _numElements
......@@ -181,6 +194,7 @@ namespace campvis {
size_t _dimensionality; ///< Dimensionality of this image
tgt::svec3 _size; ///< Size of this image (number of elements per dimension)
size_t _numChannels; ///< Number of channels per element
size_t _numElements; ///< number of elements (= tgt::hmul(size))
ImageMappingInformation _mappingInformation; ///< Mapping information of this image
......
......@@ -35,12 +35,11 @@
namespace campvis {
const std::string ImageRepresentationDisk::loggerCat_ = "CAMPVis.core.datastructures.ImageRepresentationDisk";
ImageRepresentationDisk::ImageRepresentationDisk(const ImageData* parent, const std::string& url, WeaklyTypedPointer::BaseType type, size_t numChannels, size_t offset /*= 0*/, EndianHelper::Endianness endianness /*= EndianHelper::LITTLE_ENDIAN*/, const tgt::svec3& stride /*= tgt::svec2::zero */)
ImageRepresentationDisk::ImageRepresentationDisk(const ImageData* parent, const std::string& url, WeaklyTypedPointer::BaseType type, size_t offset /*= 0*/, EndianHelper::Endianness endianness /*= EndianHelper::LITTLE_ENDIAN*/, const tgt::svec3& stride /*= tgt::svec2::zero */)
: GenericAbstractImageRepresentation<ImageRepresentationDisk>(parent)
, _url(url)
, _offset(offset)
, _type(type)
, _numChannels(numChannels)
, _endianess(endianness)
, _stride(stride)
{
......@@ -59,16 +58,16 @@ namespace campvis {
return clone();
}
size_t newOffset = _offset + WeaklyTypedPointer::numBytes(_type, _numChannels) * (llf.x + llf.y * size.y + llf.z * size.x * size.y);
size_t newOffset = _offset + WeaklyTypedPointer::numBytes(_type, _parent->getNumChannels()) * (llf.x + llf.y * size.y + llf.z * size.x * size.y);
// the stride doesn't change!
tgt::svec3 newStride = (_stride == tgt::svec3::zero) ? getCanonicStride(getSize()) : _stride;
return new ImageRepresentationDisk(parent, _url, _type, _numChannels, newOffset, _endianess, newStride);
return new ImageRepresentationDisk(parent, _url, _type, newOffset, _endianess, newStride);
}
campvis::WeaklyTypedPointer ImageRepresentationDisk::getImageData() const {
const tgt::svec3& size = getSize();
size_t numElements = tgt::hmul(size);
size_t numBytesPerElement = WeaklyTypedPointer::numBytes(_type, _numChannels);
size_t numBytesPerElement = WeaklyTypedPointer::numBytes(_type, _parent->getNumChannels());
size_t numBytes = numElements * numBytesPerElement;
// open file and prepare for read
......@@ -77,7 +76,7 @@ namespace campvis {
size_t fileSize = static_cast<size_t>(file.tellg());
if (fileSize < numBytes) {
LERROR("File is smaller than expected.");
return WeaklyTypedPointer(_type, _numChannels, 0);
return WeaklyTypedPointer(_type, _parent->getNumChannels(), 0);
}
file.seekg(_offset, std::ios::beg);
......@@ -182,11 +181,11 @@ namespace campvis {
}
return WeaklyTypedPointer(_type, _numChannels, static_cast<void*>(data));
return WeaklyTypedPointer(_type, _parent->getNumChannels(), static_cast<void*>(data));
}
else {
LERROR("Could not open file " << _url << " for reading.");
return WeaklyTypedPointer(_type, _numChannels, 0);
return WeaklyTypedPointer(_type, _parent->getNumChannels(), 0);
}
}
......@@ -196,7 +195,7 @@ namespace campvis {
}
ImageRepresentationDisk* ImageRepresentationDisk::clone() const {
return new ImageRepresentationDisk(_parent, _url, _type, _numChannels, _offset, _endianess, _stride);
return new ImageRepresentationDisk(_parent, _url, _type, _offset, _endianess, _stride);
}
size_t ImageRepresentationDisk::getLocalMemoryFootprint() const {
......@@ -211,10 +210,6 @@ namespace campvis {
return _type;
}
size_t ImageRepresentationDisk::getNumChannels() const {
return _numChannels;
}
ImageRepresentationDisk* ImageRepresentationDisk::tryConvertFrom(const AbstractImageRepresentation* source) {
// no conversion availible for now
return 0;
......
......@@ -50,7 +50,6 @@ namespace campvis {
* \param parent Image this representation represents, must not be 0.
* \param url Path to file with raw data
* \param type Base type of data
* \param numChannels Number of channels per element
* \param offset Offset of first data element in file (in bytes)
* \param endianness Endianess of data
* \param stride Number of _elemments_ _between_ adjacent elements for each dimension (\see ImageRepresentationDisk::_stride).
......@@ -59,7 +58,6 @@ namespace campvis {
const ImageData* parent,
const std::string& url,
WeaklyTypedPointer::BaseType type,
size_t numChannels,
size_t offset = 0,
EndianHelper::Endianness endianness = EndianHelper::LITTLE_ENDIAN,
const tgt::svec3& stride = tgt::svec3::zero
......@@ -106,12 +104,6 @@ namespace campvis {
*/
WeaklyTypedPointer::BaseType getBaseType() const;
/**
* Returns the number of channels per element
* \return _numChannels
*/
size_t getNumChannels() const;
private:
/**
* Calculates the canonical stride for the given image size.
......@@ -123,7 +115,6 @@ namespace campvis {
std::string _url; ///< path to file with raw data
size_t _offset; ///< offset of first data element in file (in bytes)
WeaklyTypedPointer::BaseType _type; ///< base type of data
size_t _numChannels; ///< number of channels per element
EndianHelper::Endianness _endianess; ///< endianess of data
/**
......
......@@ -88,7 +88,7 @@ namespace campvis {
ImageRepresentationGL* ImageRepresentationGL::getSubImage(const ImageData* parent, const tgt::svec3& llf, const tgt::svec3& urb) const {
// TODO: implement
tgtAssert(false, "not yet implemented...");
//LWARNING("ImageRepresentationGL::getSubImage() not implemented!");
return 0;
}
......@@ -177,12 +177,14 @@ namespace campvis {
shader->setUniform(texUniform + "._texture", texUnit.getUnitNumber());
shader->setUniform(texUniform + "._size", tgt::vec2(getSize().xy()));
shader->setUniform(texUniform + "._sizeRCP", tgt::vec2(1.f) / tgt::vec2(getSize().xy()));
shader->setUniform(texUniform + "._numChannels", static_cast<int>(_parent->getNumChannels()));
break;
case 3:
shader->setUniform(texUniform + "._texture", texUnit.getUnitNumber());
shader->setUniform(texUniform + "._size", tgt::vec3(getSize()));
shader->setUniform(texUniform + "._sizeRCP", tgt::vec3(1.f) / tgt::vec3(getSize()));
shader->setUniform(texUniform + "._numChannels", static_cast<int>(_parent->getNumChannels()));
shader->setUniform(texUniform + "._voxelSize", _parent->getMappingInformation().getVoxelSize());
shader->setUniform(texUniform + "._voxelSizeRCP", tgt::vec3(1.f) / _parent->getMappingInformation().getVoxelSize());
shader->setUniform(texUniform + "._textureToWorldMatrix", _parent->getMappingInformation().getTextureToWorldMatrix());
......
......@@ -96,10 +96,9 @@ namespace campvis {
const std::string ImageRepresentationLocal::loggerCat_ = "CAMPVis.core.datastructures.ImageRepresentationLocal";
ImageRepresentationLocal::ImageRepresentationLocal(const ImageData* parent, WeaklyTypedPointer::BaseType baseType, size_t numChannels)
ImageRepresentationLocal::ImageRepresentationLocal(const ImageData* parent, WeaklyTypedPointer::BaseType baseType)
: GenericAbstractImageRepresentation<ImageRepresentationLocal>(parent)
, _baseType(baseType)
, _numChannels(numChannels)
, _intensityHistogram(0)
{
_intensityRangeDirty = true;
......@@ -160,7 +159,7 @@ namespace campvis {
reinterpret_cast< TypeTraits<baseType, numChannels>::ElementType*>(wtp._pointer));
#define DISPATCH_CONVERSION(numChannels) \
if (source->getNumChannels() == (numChannels)) { \
if (source->getParent()->getNumChannels() == (numChannels)) { \
switch (source->getBaseType()) { \
case WeaklyTypedPointer::UINT8: \
CONVERT_TO_GENERIC_LOCAL(uint8_t, (numChannels)) \
......
......@@ -55,9 +55,8 @@ namespace campvis {
* \param dimensionality Dimensionality of data
* \param size Size of this image (number of elements per dimension)
* \param baseType Base type of the image data.
* \param numChannels Number of channels per image element.
*/
ImageRepresentationLocal(const ImageData* parent, WeaklyTypedPointer::BaseType baseType, size_t numChannels);
ImageRepresentationLocal(const ImageData* parent, WeaklyTypedPointer::BaseType baseType);
/**
* Destructor
......@@ -202,7 +201,6 @@ namespace campvis {
void computeIntensityHistogram() const;
WeaklyTypedPointer::BaseType _baseType; ///< Base type of the image data
size_t _numChannels; ///< Number of channels per image element.
mutable tbb::atomic<bool> _intensityRangeDirty; ///< Flag whether _normalizedIntensityRange is dirty and has to be recomputed
mutable Interval<float> _normalizedIntensityRange; ///< Range of the normalized intensities, mutable to allow lazy instantiation
......
......@@ -43,7 +43,7 @@ namespace campvis {
const std::string ImageRepresentationRenderTarget::loggerCat_ = "CAMPVis.core.datastructures.ImageRepresentationRenderTarget";
std::pair<ImageData*, ImageRepresentationRenderTarget*> ImageRepresentationRenderTarget::createWithImageData(const tgt::svec2& size, GLint internalFormatColor /*= GL_RGBA8*/, GLint internalFormatDepth /*= GL_DEPTH_COMPONENT24*/) {
ImageData* id = new ImageData(2, tgt::svec3(size, 1));
ImageData* id = new ImageData(2, tgt::svec3(size, 1), 4);
ImageRepresentationRenderTarget* toReturn = new ImageRepresentationRenderTarget(id, internalFormatColor, internalFormatDepth);
id->setInitialRepresentation(toReturn);
return std::make_pair(id, toReturn);
......
......@@ -33,6 +33,7 @@ struct Texture2D {
sampler2D _texture;
vec2 _size;
vec2 _sizeRCP;
int _numChannels;
};
/**
......
......@@ -37,6 +37,9 @@ struct Texture3D {
vec3 _size;
vec3 _sizeRCP;
// Number of channels
int _numChannels;
// Voxel spacing
vec3 _voxelSize;
vec3 _voxelSizeRCP;
......
......@@ -79,7 +79,7 @@ namespace campvis {
void DevilImageReader::process(DataContainer& data) {
tgt::Texture* tex = _devilTextureReader->loadTexture(p_url.getValue(), tgt::Texture::LINEAR, false, true, true, false);
if (tex != 0) {
ImageData id (2, tex->getDimensions());
ImageData id (2, tex->getDimensions(), tex->getNumChannels());
ImageRepresentationGL image(&id, tex);
std::pair<ImageData*, ImageRepresentationRenderTarget*> rt = ImageRepresentationRenderTarget::createWithImageData(_renderTargetSize.getValue());
......
......@@ -169,8 +169,8 @@ namespace campvis {
// all parsing done - lets create the image:
ImageData* image = new ImageData(dimensionality, size);
image->setInitialRepresentation(new ImageRepresentationDisk(image, url, pt, 1, offset, e));
ImageData* image = new ImageData(dimensionality, size, 1);
image->setInitialRepresentation(new ImageRepresentationDisk(image, url, pt, offset, e));
image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize + p_voxelSize.getValue()));
data.addData(p_targetImageID.getValue(), image);
p_targetImageID.issueWrite();
......
......@@ -113,7 +113,7 @@ namespace campvis {
float* asFloats = new float[numElements];
for (size_t i = 0; i < numElements; ++i)
asFloats[i] = img->getElementNormalized(i, 0);
ImageData* id = new ImageData(img->getDimensionality(), img->getSize());
ImageData* id = new ImageData(img->getDimensionality(), img->getSize(), img->getParent()->getNumChannels());
GenericImageRepresentationLocal<float, 1>* imageWithFloats = new GenericImageRepresentationLocal<float, 1>(id, asFloats);
id->setInitialRepresentation(imageWithFloats);
......
......@@ -88,11 +88,11 @@ namespace campvis {
GradientVolumeGenerator::GradientVolumeGenerator()
: AbstractProcessor()
, p_inputVolume("InputVolume", "Input Volume ID", "volume", DataNameProperty::READ)
, p_outputGradients("OutputGradients", "Output Gradient Volume ID", "gradients", DataNameProperty::WRITE)
, p_sourceImageID("InputVolume", "Input Volume ID", "volume", DataNameProperty::READ)
, p_targetImageID("OutputGradients", "Output Gradient Volume ID", "gradients", DataNameProperty::WRITE)
{
addProperty(&p_inputVolume);
addProperty(&p_outputGradients);
addProperty(&p_sourceImageID);
addProperty(&p_targetImageID);
}
GradientVolumeGenerator::~GradientVolumeGenerator() {
......@@ -100,16 +100,16 @@ namespace campvis {
}
void GradientVolumeGenerator::process(DataContainer& data) {
ImageRepresentationLocal::ScopedRepresentation input(data, p_inputVolume.getValue());
ImageRepresentationLocal::ScopedRepresentation input(data, p_sourceImageID.getValue());
if (input != 0) {
ImageData* id = new ImageData(input->getDimensionality(), input->getSize());
ImageData* id = new ImageData(input->getDimensionality(), input->getSize(), 4);
GenericImageRepresentationLocal<float, 4>* output = new GenericImageRepresentationLocal<float, 4>(id, 0);
tbb::parallel_for(tbb::blocked_range<size_t>(0, input->getNumElements()), ApplyCentralDifferences(input, output));
id->setInitialRepresentation(output);
data.addData(p_outputGradients.getValue(), id);
p_outputGradients.issueWrite();
data.addData(p_targetImageID.getValue(), id);
p_targetImageID.issueWrite();
}
else {
LDEBUG("No suitable input image found.");
......
......@@ -62,8 +62,8 @@ namespace campvis {
virtual void process(DataContainer& data);
DataNameProperty p_inputVolume; ///< ID for input volume
DataNameProperty p_outputGradients; //< ID for output gradient volume
DataNameProperty p_sourceImageID; ///< ID for input volume
DataNameProperty p_targetImageID; ///< ID for output gradient volume
protected:
......
......@@ -61,7 +61,7 @@ namespace campvis {
_imageReader.p_url.setValue("D:\\Medical Data\\Dentalscan\\dental.mhd");
_imageReader.p_targetImageID.setValue("reader.output");
_imageReader.p_targetImageID.connect(&_gvg.p_inputVolume);
_imageReader.p_targetImageID.connect(&_gvg.p_sourceImageID);
_imageReader.p_targetImageID.connect(&_lhh.p_inputVolume);
_imageReader.p_targetImageID.connect(&_sliceExtractor.p_sourceImageID);
......
......@@ -77,7 +77,12 @@ namespace campvis {
if (img != 0) {
if (img->getDimensionality() == 3) {
updateProperties(img);
if (img.getDataHandle().getTimestamp() != _sourceImageTimestamp) {
// source DataHandle has changed
updateProperties(img.getDataHandle());
_sourceImageTimestamp = img.getDataHandle().getTimestamp();
}
const tgt::svec3& imgSize = img->getSize();
ImageData* slice = img->getSubImage(tgt::svec3(0, 0, p_sliceNumber.getValue()), tgt::svec3(imgSize.x, imgSize.y, p_sliceNumber.getValue()+1));
......@@ -114,8 +119,9 @@ namespace campvis {
_invalidationLevel.setValid();
}
void SliceExtractor::updateProperties(const ImageData* img) {
const tgt::svec3& imgSize = img->getSize();
void SliceExtractor::updateProperties(DataHandle img) {
p_transferFunction.getTF()->setImageHandle(img);
const tgt::svec3& imgSize = static_cast<const ImageData*>(img.getData())->getSize();
if (p_sliceNumber.getMaxValue() != imgSize.z - 1){
p_sliceNumber.setMaxValue(imgSize.z - 1);
}
......
......@@ -82,11 +82,14 @@ namespace campvis {
protected:
/// adapts the range of the p_sliceNumber property to the image
void updateProperties(const ImageData* img);
void updateProperties(DataHandle img);
tgt::Shader* _shader; ///< Shader for slice rendering
static const std::string loggerCat_;
private:
clock_t _sourceImageTimestamp;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment