The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 60e29112 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge branch 'refactor_tf_property' of /mnt/bigone/git/repositories/berge/campvis into development

parents b77f179e f211c483
......@@ -241,7 +241,7 @@ namespace campvis {
_lblTimestamp->setText("Timestamp: " + QString::number(handles.front().second.getTimestamp()));
if (const ImageData* tester = dynamic_cast<const ImageData*>(handles.front().second.getData())) {
_canvas->p_transferFunction.getTF()->setImageHandle(handles.front().second);
_canvas->p_transferFunction.setImageHandle(handles.front().second);
std::ostringstream ss;
ss << tester->getSize();
......@@ -296,7 +296,7 @@ namespace campvis {
_lblName->setText(QString::number(handles.size()) + " DataHandles selected");
_lblTimestamp->setText("Timestamp: n/a");
_canvas->p_transferFunction.getTF()->setImageHandle(DataHandle(0));
_canvas->p_transferFunction.setImageHandle(DataHandle(0));
}
_lblLocalMemoryFootprint->setText("Local Memory Footprint: " + humanizeBytes(_localFootprint));
_lblVideoMemoryFootprint->setText("Video Memory Footprint: " + humanizeBytes(_videoFootprint));
......
......@@ -24,11 +24,13 @@
#include "abstracttransferfunctioneditor.h"
#include "core/classification/abstracttransferfunction.h"
#include "core/properties/transferfunctionproperty.h"
namespace campvis {
AbstractTransferFunctionEditor::AbstractTransferFunctionEditor(AbstractTransferFunction* tf, QWidget* parent /*= 0*/)
AbstractTransferFunctionEditor::AbstractTransferFunctionEditor(TransferFunctionProperty* prop, AbstractTransferFunction* tf, QWidget* parent /*= 0*/)
: QWidget(parent)
, _tfProperty(prop)
, _transferFunction(tf)
{
_ignorePropertyUpdates = 0;
......@@ -43,4 +45,9 @@ namespace campvis {
if (_ignorePropertyUpdates == 0)
updateWidgetFromProperty();
}
const TransferFunctionProperty::IntensityHistogramType* AbstractTransferFunctionEditor::getIntensityHistogram() const {
return _tfProperty->getIntensityHistogram();
}
}
\ No newline at end of file
......@@ -26,6 +26,9 @@
#define ABSTRACTTRANSFERFUNCTIONEDITOR_H__
#include "sigslot/sigslot.h"
#include "core/properties/transferfunctionproperty.h"
#include <QBoxLayout>
#include <QLabel>
#include <QWidget>
......@@ -43,10 +46,11 @@ namespace campvis {
public:
/**
* Creates a new editor widget for the for the AbstractTransferFunction \a tf.
* \param prop TransferFunctionProperty to generate the editor for.
* \param tf The transfer function the editor shall handle.
* \param parent Parent Qt widget
*/
AbstractTransferFunctionEditor(AbstractTransferFunction* tf, QWidget* parent = 0);
AbstractTransferFunctionEditor(TransferFunctionProperty* prop, AbstractTransferFunction* tf, QWidget* parent = 0);
/**
* Destructor
......@@ -59,6 +63,13 @@ namespace campvis {
*/
virtual void updateWidgetFromProperty() = 0;
/**
* Tries to get the intensity histogram of the image stored in the Tf's property. May return 0.
* \return The intensity histogram of the image stored in the TF's property's data handle.
*/
const TransferFunctionProperty::IntensityHistogramType* getIntensityHistogram() const;
TransferFunctionProperty* _tfProperty; ///< The parent TransferFunctionProperty of this editor
AbstractTransferFunction* _transferFunction; ///< The transfer function this widget handles
/// Semaphore acts as flag whether the widget shall ignore incoming signals from properties being updated.
......
......@@ -46,8 +46,8 @@
namespace campvis {
Geometry1DTransferFunctionEditor::Geometry1DTransferFunctionEditor(Geometry1DTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(tf, parent)
Geometry1DTransferFunctionEditor::Geometry1DTransferFunctionEditor(TransferFunctionProperty* prop, Geometry1DTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(prop, tf, parent)
, _logScale(true)
, _layout(0)
, _canvas(0)
......@@ -111,7 +111,7 @@ namespace campvis {
LGL_ERROR;
// render histogram if existent
const AbstractTransferFunction::IntensityHistogramType* ih = gtf->getIntensityHistogram();
const TransferFunctionProperty::IntensityHistogramType* ih = getIntensityHistogram();
if (ih != 0) {
size_t numBuckets = ih->getNumBuckets(0);
if (numBuckets > 0) {
......
......@@ -56,10 +56,11 @@ namespace campvis {
public:
/**
* Creates a new editor widget for the for the TransferFunctionProperty \a property.
* \param prop TransferFunctionProperty to generate the editor for.
* \param tf The transfer function the editor shall handle.
* \param parent Parent Qt widget
*/
Geometry1DTransferFunctionEditor(Geometry1DTransferFunction* tf, QWidget* parent = 0);
Geometry1DTransferFunctionEditor(TransferFunctionProperty* prop, Geometry1DTransferFunction* tf, QWidget* parent = 0);
/**
* Destructor
......
......@@ -45,8 +45,8 @@
namespace campvis {
Geometry2DTransferFunctionEditor::Geometry2DTransferFunctionEditor(Geometry2DTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(tf, parent)
Geometry2DTransferFunctionEditor::Geometry2DTransferFunctionEditor(TransferFunctionProperty* prop, Geometry2DTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(prop, tf, parent)
, _layout(0)
, _canvas(0)
, _lblIntensityLeft(0)
......@@ -115,7 +115,7 @@ namespace campvis {
}
// render histogram if existent
const AbstractTransferFunction::IntensityHistogramType* ih = gtf->getIntensityHistogram();
const TransferFunctionProperty::IntensityHistogramType* ih = getIntensityHistogram();
if (ih != 0) {
size_t numBuckets = ih->getNumBuckets(0);
if (numBuckets > 0) {
......
......@@ -55,10 +55,11 @@ namespace campvis {
public:
/**
* Creates a new editor widget for the for the TransferFunctionProperty \a property.
* \param prop TransferFunctionProperty to generate the editor for.
* \param tf The transfer function the editor shall handle.
* \param parent Parent Qt widget
*/
Geometry2DTransferFunctionEditor(Geometry2DTransferFunction* tf, QWidget* parent = 0);
Geometry2DTransferFunctionEditor(TransferFunctionProperty* prop, Geometry2DTransferFunction* tf, QWidget* parent = 0);
/**
* Destructor
......
......@@ -33,8 +33,8 @@
namespace campvis {
SimpleTransferFunctionEditor::SimpleTransferFunctionEditor(SimpleTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(tf, parent)
SimpleTransferFunctionEditor::SimpleTransferFunctionEditor(TransferFunctionProperty* prop, SimpleTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(prop, tf, parent)
, _layout(0)
, _lblColorLeft(0)
, _lblColorRight(0)
......
......@@ -44,10 +44,11 @@ namespace campvis {
public:
/**
* Creates a new editor widget for the for the TransferFunctionProperty \a property.
* \param prop TransferFunctionProperty to generate the editor for.
* \param tf The transfer function the editor shall handle.
* \param parent Parent Qt widget
*/
SimpleTransferFunctionEditor(SimpleTransferFunction* tf, QWidget* parent = 0);
SimpleTransferFunctionEditor(TransferFunctionProperty* prop, SimpleTransferFunction* tf, QWidget* parent = 0);
/**
* Destructor
......
......@@ -34,21 +34,26 @@
#include "core/classification/geometry2dtransferfunction.h"
#include "core/classification/simpletransferfunction.h"
#include "core/properties/transferfunctionproperty.h"
namespace campvis {
AbstractTransferFunctionEditor* TransferFunctionEditorFactory::createEditor(AbstractTransferFunction* tf) {
AbstractTransferFunctionEditor* TransferFunctionEditorFactory::createEditor(TransferFunctionProperty* prop) {
tgtAssert(prop != 0, "Property must not be 0.");
AbstractTransferFunction* tf = prop->getTF();
tgtAssert(tf != 0, "Transfer function must not be 0.");
if (SimpleTransferFunction* tester = dynamic_cast<SimpleTransferFunction*>(tf)) {
return new SimpleTransferFunctionEditor(tester);
return new SimpleTransferFunctionEditor(prop, tester);
}
if (Geometry1DTransferFunction* tester = dynamic_cast<Geometry1DTransferFunction*>(tf)) {
return new Geometry1DTransferFunctionEditor(tester);
return new Geometry1DTransferFunctionEditor(prop, tester);
}
if (Geometry2DTransferFunction* tester = dynamic_cast<Geometry2DTransferFunction*>(tf)) {
return new Geometry2DTransferFunctionEditor(tester);
return new Geometry2DTransferFunctionEditor(prop, tester);
}
return 0;
......
......@@ -28,6 +28,7 @@
namespace campvis {
class AbstractTransferFunction;
class AbstractTransferFunctionEditor;
class TransferFunctionProperty;
/**
* Factory class offering the static method createEditor to create transfer function editors
......@@ -38,10 +39,10 @@ namespace campvis {
/**
* Creates the corresponding TransferFunctionEditor for the given transfer function \a tf.
* \note The callee has to take the ownership of the returned pointer.
* \param tf Transfer function to generate the editor for.
* \param prop TransferFunctionProperty to generate the editor for.
* \return A new transfer function editor for the given transfer function (depending on its type).
*/
static AbstractTransferFunctionEditor* createEditor(AbstractTransferFunction* tf);
static AbstractTransferFunctionEditor* createEditor(TransferFunctionProperty* prop);
private:
/// Shall not instantiate
......
......@@ -34,6 +34,7 @@
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
namespace campvis {
TransferFunctionPropertyWidget::TransferFunctionPropertyWidget(TransferFunctionProperty* property, QWidget* parent /*= 0*/)
......@@ -43,6 +44,8 @@ namespace campvis {
, _lblDomain(0)
, _spinDomainLeft(0)
, _spinDomainRight(0)
, _cbAutoFitDomainToImage(0)
, _btnFitDomainToImage(0)
, _btnEditTF(0)
, _dockWidget(0)
, _editor(0)
......@@ -51,7 +54,7 @@ namespace campvis {
_gridLayout = new QGridLayout(_widget);
_widget->setLayout(_gridLayout);
_lblDomain = new QLabel("Intensity Domain: ", _widget);
_lblDomain = new QLabel("Window:", _widget);
_gridLayout->addWidget(_lblDomain, 0, 0);
......@@ -70,38 +73,30 @@ namespace campvis {
_btnFitDomainToImage = new QPushButton("Fit", _widget);
_gridLayout->addWidget(_btnFitDomainToImage, 0, 3);
_cbAutoFitDomainToImage = new QCheckBox("Auto", _widget);
_gridLayout->addWidget(_cbAutoFitDomainToImage, 0, 4);
_btnEditTF = new QPushButton("Edit Transfer Function", _widget);
_gridLayout->addWidget(_btnEditTF, 1, 1, 1, 3);
_gridLayout->addWidget(_btnEditTF, 1, 1, 1, 4);
addWidget(_widget);
onTransferFunctionImageHandleChanged();
updateWidgetFromProperty();
property->getTF()->s_imageHandleChanged.connect(this, &TransferFunctionPropertyWidget::onTransferFunctionImageHandleChanged);
connect(_spinDomainLeft, SIGNAL(valueChanged(double)), this, SLOT(onDomainChanged(double)));
connect(_spinDomainRight, SIGNAL(valueChanged(double)), this, SLOT(onDomainChanged(double)));
connect(_btnEditTF, SIGNAL(clicked(bool)), this, SLOT(onEditClicked(bool)));
connect(_btnFitDomainToImage, SIGNAL(clicked(bool)), this, SLOT(onFitClicked(bool)));
connect(_cbAutoFitDomainToImage, SIGNAL(stateChanged(int)), this, SLOT(onAutoFitDomainToImageChanged(int)));
property->s_autoFitWindowToDataChanged.connect(this, &TransferFunctionPropertyWidget::onTransferFunctionAutoFitWindowToDataChanged);
}
TransferFunctionPropertyWidget::~TransferFunctionPropertyWidget() {
static_cast<TransferFunctionProperty*>(_property)->getTF()->s_imageHandleChanged.disconnect(this);
static_cast<TransferFunctionProperty*>(_property)->s_autoFitWindowToDataChanged.disconnect(this);
delete _dockWidget;
}
void TransferFunctionPropertyWidget::onTransferFunctionImageHandleChanged() {
DataHandle dh = static_cast<TransferFunctionProperty*>(_property)->getTF()->getImageHandle();
if (dh.getData() != 0) {
const ImageRepresentationLocal* idl = dynamic_cast<const ImageRepresentationLocal*>(dh.getData());
if (idl != 0) {
Interval<float> intensityInterval = idl->getNormalizedIntensityRange();
// _spinDomainLeft->setMinimum(intensityInterval.getLeft());
// _spinDomainRight->setMaximum(intensityInterval.getRight());
}
}
}
void TransferFunctionPropertyWidget::updateWidgetFromProperty() {
TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
AbstractTransferFunction* tf = prop->getTF();
......@@ -116,6 +111,10 @@ namespace campvis {
_spinDomainRight->setMinimum(domain.x);
_spinDomainRight->setValue(domain.y);
_spinDomainRight->blockSignals(false);
_cbAutoFitDomainToImage->blockSignals(true);
_cbAutoFitDomainToImage->setChecked(prop->getAutoFitWindowToData());
_cbAutoFitDomainToImage->blockSignals(false);
}
void TransferFunctionPropertyWidget::onDomainChanged(double value) {
......@@ -131,7 +130,7 @@ namespace campvis {
void TransferFunctionPropertyWidget::onEditClicked(bool checked) {
if (_editor == 0) {
TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
_editor = TransferFunctionEditorFactory::createEditor(prop->getTF());
_editor = TransferFunctionEditorFactory::createEditor(prop);
_dockWidget = new QDockWidget("Transfer Function Editor");
_dockWidget->setWidget(_editor);
......@@ -146,7 +145,7 @@ namespace campvis {
TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
AbstractTransferFunction* tf = prop->getTF();
DataHandle dh = tf->getImageHandle();
DataHandle dh = prop->getImageHandle();
if (dh.getData() != 0) {
const ImageRepresentationLocal* idl = static_cast<const ImageData*>(dh.getData())->getRepresentation<ImageRepresentationLocal>();
if (idl != 0) {
......@@ -156,5 +155,14 @@ namespace campvis {
}
}
void TransferFunctionPropertyWidget::onAutoFitDomainToImageChanged(int state) {
TransferFunctionProperty* prop = static_cast<TransferFunctionProperty*>(_property);
prop->setAutoFitWindowToData(state != Qt::Unchecked);
}
void TransferFunctionPropertyWidget::onTransferFunctionAutoFitWindowToDataChanged() {
emit s_propertyChanged(_property);
}
}
\ No newline at end of file
......@@ -33,6 +33,7 @@ class QDoubleSpinBox;
class QGridLayout;
class QLabel;
class QPushButton;
class QCheckBox;
namespace campvis {
class AbstractTransferFunctionEditor;
......@@ -56,17 +57,17 @@ namespace campvis {
*/
virtual ~TransferFunctionPropertyWidget();
/**
* Slot to be called when the propertie's TF changed its image DataHandle.
* Resets the intensity domain borders.
*/
void onTransferFunctionImageHandleChanged();
protected:
/**
* Gets called when the property has changed, so that widget can update its state.
*/
virtual void updateWidgetFromProperty();
/**
* Slot to be called from property when the property's flag whether to auto fit the TF window has changed.
*/
void onTransferFunctionAutoFitWindowToDataChanged();
private slots:
/// slot called when one of the intensity domain spin edits has changed
......@@ -75,6 +76,8 @@ namespace campvis {
void onEditClicked(bool checked);
/// slot called when _btnFitDomainToImage clicked
void onFitClicked(bool checked);
/// slot called when _cbAutoFitDomainToImage changed
void onAutoFitDomainToImageChanged(int state);
private:
QWidget* _widget; ///< Widget grouping the widgets together
......@@ -83,6 +86,7 @@ namespace campvis {
QLabel* _lblDomain; ///< intensity domain label
QDoubleSpinBox* _spinDomainLeft; ///< spin edit for intensity domain lower bound
QDoubleSpinBox* _spinDomainRight; ///< spin edit for intensity domain upper bound
QCheckBox* _cbAutoFitDomainToImage; ///< Checkbox for the flag whether to automatically fit the TF domain to new image data
QPushButton* _btnFitDomainToImage; ///< button for fitting the intensity domain to the image
QPushButton* _btnEditTF; ///< button for showing the TF editor widget
......
......@@ -41,30 +41,24 @@ namespace campvis {
: _size(size)
, _intensityDomain(intensityDomain)
, _texture(0)
, _imageHandle(0)
, _intensityHistogram(0)
{
_dirtyTexture = false;
_dirtyHistogram = false;
}
AbstractTransferFunction::~AbstractTransferFunction() {
if (_texture != 0)
LWARNING("Called AbstractTransferFunction dtor without proper deinitialization - you just wasted resources!");
delete _intensityHistogram;
}
void AbstractTransferFunction::deinit() {
delete _texture;
_texture = 0;
_imageHandle = DataHandle(0);
}
void AbstractTransferFunction::bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& transFuncUniform /*= "_transferFunction"*/, const std::string& transFuncParamsUniform /*= "_transferFunctionParameters"*/) {
tgtAssert(shader != 0, "Shader must not be 0.");
{
// TODO: lock here or in createTexture?
tbb::mutex::scoped_lock lock(_localMutex);
if (_texture == 0 || _dirtyTexture) {
shader->deactivate();
......@@ -93,23 +87,14 @@ namespace campvis {
shader->setIgnoreUniformLocationError(tmp);
}
void AbstractTransferFunction::uploadTexture() {
{
tbb::mutex::scoped_lock lock(_localMutex);
if (_texture == 0 || _dirtyTexture) {
createTexture();
}
}
}
void AbstractTransferFunction::setIntensityDomain(const tgt::vec2& newDomain) {
tgtAssert(newDomain.x <= newDomain.y, "Intensity domain is not a valid interval.");
{
tbb::mutex::scoped_lock lock(_localMutex);
_intensityDomain = newDomain;
}
_dirtyHistogram = true;
s_intensityDomainChanged();
s_changed();
}
......@@ -118,7 +103,6 @@ namespace campvis {
}
const tgt::Texture* AbstractTransferFunction::getTexture() {
// TODO: lock here or in createTexture?
{
tbb::mutex::scoped_lock lock(_localMutex);
if (_texture == 0 || _dirtyTexture) {
......@@ -127,49 +111,5 @@ namespace campvis {
}
return _texture;
}
DataHandle AbstractTransferFunction::getImageHandle() const {
return _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();
}
void AbstractTransferFunction::computeIntensityHistogram() const {
delete _intensityHistogram;
_intensityHistogram = 0;
ImageRepresentationLocal::ScopedRepresentation repLocal(_imageHandle);
if (repLocal != 0) {
float mins = _intensityDomain.x;
float maxs = _intensityDomain.y;
size_t numBuckets = std::min(WeaklyTypedPointer::numBytes(repLocal->getWeaklyTypedPointer()._baseType) << 8, static_cast<size_t>(512));
_intensityHistogram = new IntensityHistogramType(&mins, &maxs, &numBuckets);
tbb::parallel_for(tbb::blocked_range<size_t>(0, repLocal->getNumElements()), [&] (const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i != range.end(); ++i) {
float value = repLocal->getElementNormalized(i, 0);
_intensityHistogram->addSample(&value);
}
});
}
_dirtyHistogram = false;
}
const AbstractTransferFunction::IntensityHistogramType* AbstractTransferFunction::getIntensityHistogram() const {
if (_dirtyHistogram) {
computeIntensityHistogram();
}
return _intensityHistogram;
}
}
\ No newline at end of file
......@@ -55,8 +55,6 @@ namespace campvis {
* b) All OpenGL-related methods must be called by a thread with a valid and locked OpenGL
* context. Even though other internals might be changed meanwhile, this ensures that
* the OpenGL stuff (e.g. the texture) stays valid for this time.
*
* \todo Check thread-safety, the private local lock is probably not the best design.
*/
class AbstractTransferFunction {
public:
......@@ -101,12 +99,6 @@ namespace campvis {
*/
void bind(tgt::Shader* shader, const tgt::TextureUnit& texUnit, const std::string& transFuncUniform = "_transferFunction", const std::string& transFuncParamsUniform = "_transferFunctionParams");
/**
* Creates the OpenGL texture.
* \note Calling thread must have a valid OpenGL context.
*/
void uploadTexture();
/**
* Sets the intensity domain where the transfer function is mapped to during classification.
* \param newDomain new intensity domain
......@@ -125,34 +117,11 @@ namespace campvis {
* \return _texture
*/
const tgt::Texture* getTexture();
/**
* 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, 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(DataHandle imageHandle);
/**
* Returns the intensity histogram
* \todo This is NOT thread-safe!
* \return _intensityHistogram
*/
const IntensityHistogramType* getIntensityHistogram() const;
/// Signal emitted when transfer function has changed.
sigslot::signal0<> s_changed;
/// Signal emitted when the image DataHandle for this TF has changed.
sigslot::signal0<> s_imageHandleChanged;
/// Signal emitted when the intensity domain has changed
sigslot::signal0<> s_intensityDomainChanged;
protected:
/**
......@@ -171,11 +140,7 @@ namespace campvis {
tgt::Texture* _texture; ///< OpenGL lookup texture storing the TF
tbb::atomic<bool> _dirtyTexture; ///< Flag whether the OpenGL texture has to be updated
DataHandle _imageHandle; ///< DataHandle to the image for this transfer function. May be 0.
mutable IntensityHistogramType* _intensityHistogram; ///< Intensity histogram of the intensity in _imageHandle for the current _intensityDomain
mutable tbb::atomic<bool> _dirtyHistogram; ///< Flag whether the intensity histogram has to be updated.
mutable tbb::mutex _localMutex; ///< mutex protecting the local members
mutable tbb::mutex _localMutex; ///< mutex protecting the local members
static const std::string loggerCat_;
......
......@@ -46,13 +46,12 @@ namespace campvis {
ImageRepresentationLocal::ImageRepresentationLocal(ImageData* parent, WeaklyTypedPointer::BaseType baseType)
: GenericAbstractImageRepresentation<ImageRepresentationLocal>(parent)
, _baseType(baseType)
, _intensityHistogram(0)
{
_intensityRangeDirty = true;
}
ImageRepresentationLocal::~ImageRepresentationLocal() {
delete _intensityHistogram;
}
ImageRepresentationLocal* ImageRepresentationLocal::tryConvertFrom(const AbstractImageRepresentation* source) {
......@@ -145,13 +144,6 @@ namespace campvis {