Commit caa7620d authored by schultezub's avatar schultezub

=== ATTENTION: CAMPVis does compile, but image representation conversion not...

=== ATTENTION: CAMPVis does compile, but image representation conversion not yet functional again! ===

Revising ImageData concept step 2:
 * Removed all ImageDataXYZ classes
 * Introducing GenericAbstractImageRepresentation<T> and its GenericAbstractImageRepresentation<T>::ScopedRepresentation
 * Updated all processors and pipelines to use ImageRepresentationXYZ instead of ImageDataXYZ and the implicit conversion feature

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@401 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 670e632c
......@@ -28,6 +28,7 @@
// ================================================================================================
#include "application/campvisapplication.h"
#include "modules/vis/pipelines/advancedusvis.h"
#include "modules/vis/pipelines/ixpvdemo.h"
#include "modules/vis/pipelines/dvrvis.h"
#include "modules/vis/pipelines/slicevis.h"
......@@ -44,7 +45,8 @@ using namespace campvis;
**/
int main(int argc, char** argv) {
CampVisApplication app(argc, argv);
app.addVisualizationPipeline("IXPV", new IxpvDemo());
app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis());
//app.addVisualizationPipeline("IXPV", new IxpvDemo());
//app.addVisualizationPipeline("SliceVis", new SliceVis());
//app.addVisualizationPipeline("DVRVis", new DVRVis());
//app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline());
......
......@@ -37,7 +37,8 @@
#include "tgt/quadric.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/pipeline/visualizationpipeline.h"
#include "core/tools/job.h"
#include "core/tools/opengljobprocessor.h"
......@@ -94,7 +95,7 @@ namespace campvis {
glViewport(0, 0, size.x, size.y);
// try get Data
DataContainer::ScopedTypedData<ImageDataRenderTarget> image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
ImageRepresentationRenderTarget::ScopedRepresentation image(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (image != 0) {
// activate shader
......
......@@ -35,8 +35,8 @@
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/datahandle.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedatagl.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/facegeometry.h"
#include "core/tools/job.h"
......@@ -140,10 +140,10 @@ namespace campvis {
std::vector<const tgt::Texture*> textures;
for (std::map<std::string, DataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
if (const ImageDataGL* imgGL = dynamic_cast<const ImageDataGL*>(it->second.getData())) {
if (const ImageRepresentationGL* imgGL = dynamic_cast<const ImageRepresentationGL*>(it->second.getData())) {
textures.push_back(imgGL->getTexture());
}
else if (const ImageDataRenderTarget* imgRT = dynamic_cast<const ImageDataRenderTarget*>(it->second.getData())) {
else if (const ImageRepresentationRenderTarget* imgRT = dynamic_cast<const ImageRepresentationRenderTarget*>(it->second.getData())) {
if (imgRT->getDimensionality() == 2) {
for (size_t i = 0; i < imgRT->getNumColorTextures(); ++i)
textures.push_back(imgRT->getColorTexture(i));
......
......@@ -36,10 +36,10 @@
#include "application/gui/qtdatahandle.h"
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/abstractdata.h"
#include "core/datastructures/imagedatadisk.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedatagl.h"
#include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#include "core/datastructures/imagerepresentationgl.h"
#include <QHeaderView>
#include <QStringList>
......@@ -91,16 +91,16 @@ namespace campvis {
else if (column == COLUMN_TYPE) {
const AbstractData* data = _dataHandle.getData();
tgtAssert(data != 0, "WTF - QtDataHandle with empty data?");
if (const ImageDataDisk* tester = dynamic_cast<const ImageDataDisk*>(data)) {
if (const ImageRepresentationDisk* tester = dynamic_cast<const ImageRepresentationDisk*>(data)) {
return QVariant(QString("ImageData on disk"));
}
else if (const ImageDataLocal* tester = dynamic_cast<const ImageDataLocal*>(data)) {
else if (const ImageRepresentationLocal* tester = dynamic_cast<const ImageRepresentationLocal*>(data)) {
return QVariant(QString("ImageData in local memory"));
}
else if (const ImageDataGL* tester = dynamic_cast<const ImageDataGL*>(data)) {
else if (const ImageRepresentationGL* tester = dynamic_cast<const ImageRepresentationGL*>(data)) {
return QVariant(QString("ImageData in OpenGL texture."));
}
else if (const ImageDataRenderTarget* tester = dynamic_cast<const ImageDataRenderTarget*>(data)) {
else if (const ImageRepresentationRenderTarget* tester = dynamic_cast<const ImageRepresentationRenderTarget*>(data)) {
return QVariant(QString("RenderTarget"));
}
}
......
......@@ -39,7 +39,7 @@
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/properties/transferfunctionproperty.h"
#include "core/tools/opengljobprocessor.h"
......
......@@ -39,7 +39,7 @@
#include "core/classification/geometry2dtransferfunction.h"
#include "core/classification/TFGeometry2D.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/properties/transferfunctionproperty.h"
#include "core/tools/opengljobprocessor.h"
......
......@@ -31,7 +31,7 @@
#include "application/gui/properties/abstracttransferfunctioneditor.h"
#include "application/gui/properties/transferfunctioneditorfactory.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include <QDockWidget>
#include <QDoubleSpinBox>
......@@ -97,7 +97,7 @@ namespace campvis {
void TransferFunctionPropertyWidget::onTransferFunctionImageHandleChanged() {
DataHandle dh = static_cast<TransferFunctionProperty*>(_property)->getTF()->getImageHandle();
if (dh.getData() != 0) {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(dh.getData());
const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(dh.getData());
if (idl != 0) {
Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
// _spinDomainLeft->setMinimum(intensityInterval.getLeft());
......@@ -150,7 +150,7 @@ namespace campvis {
DataHandle dh = tf->getImageHandle();
if (dh.getData() != 0) {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(dh.getData());
const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(dh.getData());
if (idl != 0) {
Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
tf->setIntensityDomain(tgt::vec2(intensityInterval.getLeft(), intensityInterval.getRight()));
......
......@@ -36,13 +36,13 @@
#include "tgt/texture.h"
#include "tgt/textureunit.h"
#include "core/datastructures/imagedatalocal.h"
#include "core/datastructures/imagerepresentationlocal.h"
namespace campvis {
class IntensityHistogramGenerator {
public:
IntensityHistogramGenerator(const ImageDataLocal* intensityData, AbstractTransferFunction::IntensityHistogramType* histogram)
IntensityHistogramGenerator(const ImageRepresentationLocal* intensityData, AbstractTransferFunction::IntensityHistogramType* histogram)
: _intensityData(intensityData)
, _histogram(histogram)
{}
......@@ -55,7 +55,7 @@ namespace campvis {
}
protected:
const ImageDataLocal* _intensityData;
const ImageRepresentationLocal* _intensityData;
AbstractTransferFunction::IntensityHistogramType* _histogram;
};
......@@ -169,7 +169,7 @@ namespace campvis {
_intensityHistogram = 0;
if (_imageHandle.getData() != 0) {
const ImageDataLocal* idl = dynamic_cast<const ImageDataLocal*>(_imageHandle.getData());
const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(_imageHandle.getData());
if (idl != 0) {
float mins = _intensityDomain.x;
float maxs = _intensityDomain.y;
......
......@@ -106,7 +106,7 @@ namespace campvis {
* \param urb Upper-Right-Back coordinates of subimage
* \return An image representation containing the subimage of this with the given coordinates.
*/
virtual AbstractImageRepresentation* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
virtual AbstractImageRepresentation* getSubImage(const ImageData* parent, const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
protected:
......@@ -114,7 +114,6 @@ namespace campvis {
static const std::string loggerCat_;
};
}
#endif // ABSTRACTIMAGEREPRESENTATION_H__
......@@ -58,7 +58,7 @@ namespace campvis {
public:
/**
* Proxy class for scoped strongly-typed access to the data of a DataContainer.
* From the outside ScopedTypedData<T> behaves exactly like a const T*, but internally it preserves the
* From the outside DataContainer::ScopedTypedData<T> behaves exactly like a const T*, but internally it preserves the
* reference counting of a DataHandle. Use this class when you want temporary access to a strongly-typed
* data item in a DataContainer but don't want to to the dynamic_cast yourself.
*
......
......@@ -27,118 +27,107 @@
//
// ================================================================================================
#ifndef IMAGEDATADISK_H__
#define IMAGEDATADISK_H__
#ifndef GENERICABSTRACTIMAGEREPRESENTATION_H__
#define GENERICABSTRACTIMAGEREPRESENTATION_H__
#include "tgt/vector.h"
#include "core/datastructures/abstractimagerepresentation.h"
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/imagedata.h"
#include "core/tools/endianhelper.h"
#include "core/tools/typetraits.h"
#include "core/tools/weaklytypedpointer.h"
#include <fstream>
#include <string>
namespace campvis {
/**
* Subclass of ImageData offering access to image data stored in binary form on the local harddisk.
*
* \todo Number of channels
* Generic wrapper around an AbstractImageRepresentation that provides a ScopedRepresentation proxy.
* The concept is very similar to the DataContainer::ScopedData proxy.
* From the outside ScopedRepresentation behaves exactly like a const T*, but internally it preserves the
* reference counting of a DataHandle. Use this class when you want temporary access to a specific
* representation of an ImageData item in a DataContainer but don't want to do the dynamic_cast and
* the getRepresentation<T> yourself.
*
* \tparam T Base class of the ImageRepresentation to get.
*/
class ImageDataDisk : public ImageData {
template<typename T>
class GenericAbstractImageRepresentation : public AbstractImageRepresentation {
public:
/**
* Creates a new ImageData disk representation.
*
* \param url Path to file with raw data
* \param dimensionality Dimensionality of data
* \param size Size of this image (number of elements per dimension)
* \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 ImageDataDisk::_stride).
*/
ImageDataDisk(
const std::string& url,
size_t dimensionality,
const tgt::svec3& size,
WeaklyTypedPointer::BaseType type,
size_t numChannels,
size_t offset = 0,
EndianHelper::Endianness endianness = EndianHelper::LITTLE_ENDIAN,
const tgt::svec3& stride = tgt::svec3::zero
);
/**
* Destructor
*/
virtual ~ImageDataDisk();
/**
* \see AbstractData::clone()
**/
virtual ImageDataDisk* clone() const;
/// \see AbstractData::getLocalMemoryFootprint()
virtual size_t getLocalMemoryFootprint() const;
/// \see AbstractData::getVideoMemoryFootprint()
virtual size_t getVideoMemoryFootprint() const;
struct ScopedRepresentation {
/**
* Creates a new DataHandle to the data item with the key \a name in \a dc, that behaves like a T*.
* \param dc DataContainer to grab data from
* \param name Key of the DataHandle to search for
*/
ScopedRepresentation(const DataContainer& dc, const std::string& name)
: dh(dc.getData(name))
, data(0)
, representation(0)
{
if (dh.getData() != 0) {
data = dynamic_cast<const ImageData*>(dh.getData());
if (data != 0) {
representation = data->getRepresentation<T>();
}
}
};
/**
* Implicit conversion operator to const T*.
* \return The image representation of the image in the DataHandle, may be 0 when no DataHandle was found,
* the data is of the wrong type, or no suitable representation was found.
*/
operator const T*() {
return representation;
}
/**
* Implicit arrow operator to const T*.
* \return The image representation of the image in the DataHandle, may be 0 when no DataHandle was found,
* the data is of the wrong type, or no suitable representation was found.
*/
const T* operator->() const {
return representation;
}
/**
* Gets the DataHandle.
* \return dh
*/
DataHandle getDataHandle() const {
return dh;
}
/**
* Returns the parent ImageData of this image representation.
* \return data
*/
const ImageData* getImageData() const {
return data;
}
private:
/// Not copy-constructable
ScopedRepresentation(const ScopedRepresentation& rhs);
/// Not assignable
ScopedRepresentation& operator=(const ScopedRepresentation& rhs);
DataHandle dh; ///< DataHandle
const ImageData* data; ///< strongly-typed pointer to data, may be 0
const T* representation; ///< strongly-typed pointer to the image representation, may be 0
};
/**
* \see ImageData::getSubImage
* Creates a new abstract representation for the image \a parent.
* \param parent Image this representation represents, must not be 0.
*/
virtual ImageDataDisk* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
GenericAbstractImageRepresentation(const ImageData* parent)
: AbstractImageRepresentation(parent)
{
}
/**
* Downloads the whole image data to local memory.
* \note The caller has to take ownership of the returned pointer.
* \return Pointer to the image data in the local memory, to be owned by caller.
* Virtual Destructor.
*/
WeaklyTypedPointer getImageData() const;
/**
* Returns the base type of the data
* \return _type
*/
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.
* \param size Image size (number of elements per dimension).
* \return (0, size.x, size.x * size.y)
*/
tgt::svec3 getCanonicStride(const tgt::svec3& size) const;
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
/**
* Number of _elemments_ _between_ adjacent elements for each dimension.
* If the stride is 0 for a dimension, the elements are assumed to be tightly packed, hence for
* the x-dimension 0, for the y-dimension _size.x and for the z-dimension (_size.x * _size.y).
**/
tgt::svec3 _stride;
virtual ~GenericAbstractImageRepresentation() {};
static const std::string loggerCat_;
};
}
#endif // IMAGEDATADISK_H__
#endif // GENERICABSTRACTIMAGEREPRESENTATION_H__
This diff is collapsed.
......@@ -38,7 +38,7 @@
namespace campvis {
/**
* Templated version of ImageDataLocal, storing image data in the local memory.
* Templated version of ImageRepresentationLocal, storing image data in the local memory.
*
* \sa TypeTraits
* \tparam BASETYPE Base type of the image data (type of a single channel of an image element)
......@@ -76,28 +76,28 @@ namespace campvis {
virtual size_t getVideoMemoryFootprint() const;
/// \see AbstractImageRepresentation::getSubImage
virtual ThisType* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
virtual ThisType* getSubImage(const ImageData* parent, const tgt::svec3& llf, const tgt::svec3& urb) const;
/**
* Returns a WeaklyTypedPointer to the image data.
* \note The pointer is still owned by this ImageDataLocal. If you want a copy, use clone().
* \note The pointer is still owned by this ImageRepresentationLocal. If you want a copy, use clone().
* \return A WeaklyTypedPointer to the image data.
*/
virtual const WeaklyTypedPointer getWeaklyTypedPointer() const;
/// \see ImageDataLocal::getElementNormalized
/// \see ImageRepresentationLocal::getElementNormalized
virtual float getElementNormalized(size_t index, size_t channel) const;
/// \see ImageDataLocal::getElementNormalized
/// \see ImageRepresentationLocal::getElementNormalized
virtual float getElementNormalized(const tgt::svec3& position, size_t channel) const;
/// \see ImageDataLocal::getElementNormalizedLinear
/// \see ImageRepresentationLocal::getElementNormalizedLinear
virtual float getElementNormalizedLinear(const tgt::vec3& position, size_t channel) const;
/// \see ImageDataLocal::setElementNormalized
/// \see ImageRepresentationLocal::setElementNormalized
virtual void setElementNormalized(size_t index, size_t channel, float value);
/// \see ImageDataLocal::setElementNormalized
/// \see ImageRepresentationLocal::setElementNormalized
virtual void setElementNormalized(const tgt::svec3& position, size_t channel, float value);
......@@ -208,11 +208,11 @@ namespace campvis {
}
template<typename BASETYPE, size_t NUMCHANNELS>
GenericImageRepresentationLocal<BASETYPE, NUMCHANNELS>* campvis::GenericImageRepresentationLocal<BASETYPE, NUMCHANNELS>::getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const {
tgtAssert(tgt::hor(tgt::lessThan(llf, urb)), "Coordinates in LLF must be component-wise smaller than the ones in URB!");
GenericImageRepresentationLocal<BASETYPE, NUMCHANNELS>* campvis::GenericImageRepresentationLocal<BASETYPE, NUMCHANNELS>::getSubImage(const ImageData* parent, const tgt::svec3& llf, const tgt::svec3& urb) const {
tgtAssert(tgt::hand(tgt::lessThan(llf, urb)), "Coordinates in LLF must be component-wise smaller than the ones in URB!");
const tgt::svec3& size = getSize();
tgt::svec3 newSize = urb - llf + tgt::svec3(1);
tgt::svec3 newSize = urb - llf;
if (newSize == size) {
// nothing has changed, just provide a copy:
return clone();
......@@ -231,15 +231,15 @@ namespace campvis {
// slice image data into new array
size_t index = 0;
for (size_t z = llf.z; z <= urb.z; ++z) {
for (size_t y = llf.y; y <= urb.y; ++y) {
for (size_t z = llf.z; z < urb.z; ++z) {
for (size_t y = llf.y; y < urb.y; ++y) {
size_t offset = llf.x + (y * size.x) + (z * size.y * size.x);
memcpy(newData + index, _data + offset, newSize.x * numBytesPerElement);
index += newSize.x;
}
}
return new ThisType(_parent, newData);
return new ThisType(parent, newData);
}
template<typename BASETYPE, size_t NUMCHANNELS>
......
......@@ -42,6 +42,30 @@ namespace campvis {
}
ImageData::~ImageData() {
clearRepresentations();
}
ImageData* ImageData::clone() const {
ImageData* toReturn = new ImageData(_dimensionality, _size);
toReturn->_mappingInformation = _mappingInformation;
toReturn->_representations.assign(_representations.begin(), _representations.end());
return toReturn;
}
size_t ImageData::getLocalMemoryFootprint() const {
size_t toReturn = sizeof(*this) + _representations.size() * sizeof(AbstractImageRepresentation*);
for (std::vector<const AbstractImageRepresentation*>::iterator it = _representations.begin(); it != _representations.end(); ++it)
toReturn += (*it)->getLocalMemoryFootprint();
return toReturn;
}
size_t ImageData::getVideoMemoryFootprint() const {
size_t toReturn = 0;
for (std::vector<const AbstractImageRepresentation*>::iterator it = _representations.begin(); it != _representations.end(); ++it)
toReturn += (*it)->getVideoMemoryFootprint();
return toReturn;
}
size_t ImageData::getDimensionality() const {
......@@ -70,6 +94,36 @@ namespace campvis {
_mappingInformation.getOffset() + (tgt::vec3(urb) * _mappingInformation.getVoxelSize()));
}
ImageData* ImageData::getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const {
tgtAssert(tgt::hand(tgt::lessThan(llf, urb)), "Coordinates in LLF must be component-wise smaller than the ones in URB!");
tgt::svec3 newSize = urb - llf;
if (newSize == getSize()) {
// nothing has changed, just provide a copy:
return clone();
}
// compute new dimensionality
size_t newDimensionality = 1;
if (newSize.y > 1)
newDimensionality = 2;
if (newSize.z > 1)
newDimensionality = 3;
// create new ImageData object and assign mapping information
ImageData* toReturn = new ImageData(newDimensionality, newSize);
toReturn->_mappingInformation = ImageMappingInformation(newSize, _mappingInformation.getOffset(), _mappingInformation.getVoxelSize(), _mappingInformation.getRealWorldMapping());
// create sub-image of every image representation
for (std::vector<const AbstractImageRepresentation*>::iterator it = _representations.begin(); it != _representations.end(); ++it) {
AbstractImageRepresentation* si = (*it)->getSubImage(toReturn, llf, urb);
if (si != 0)
toReturn->_representations.push_back(si);
}
return toReturn;
}
size_t ImageData::getNumElements() const {
return _numElements;
}
......@@ -85,4 +139,11 @@ namespace campvis {
return tgt::svec3(x, y, z);
}
void ImageData::clearRepresentations() {
for (std::vector<const AbstractImageRepresentation*>::iterator it = _representations.begin(); it != _representations.end(); ++it)
delete *it;
_representations.clear();
}
}
\ No newline at end of file
......@@ -31,9 +31,14 @@
#define IMAGEDATA_H__
#include "tgt/bounds.h"
#include "tgt/logmanager.h"
#include "tgt/vector.h"
#include "core/datastructures/abstractdata.h"
#include "core/datastructures/abstractimagerepresentation.h"
#include "core/datastructures/imagemappinginformation.h"
//#include "core/datastructures/imagerepresentationconverter.h"
#include <vector>
namespace campvis {
......@@ -50,6 +55,25 @@ namespace campvis {
virtual ~ImageData();
/**
* Prototype - clone method, some people call this virtual constructor...
* \note Deep-copies all contained representations!
* \return A copy of this object.
*/
virtual ImageData* clone() const;
/**
* Returns the local memory footprint of the data in bytes.
* \return Number of bytes occupied in local memory by the data.
*/
virtual size_t getLocalMemoryFootprint() const;
/**