Commit 8345ab92 authored by schultezub's avatar schultezub
Browse files

* added ImageDataLocal::getElementNormalizedLinear()

 * added ImageData::indexToPosition()
 * fixed glsl/tools/transferfunction.frag
 * fixed TextFileParser
 * added GradientVolumeGenerator and LHHistogram processors

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@305 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent ae6e0d00
......@@ -78,6 +78,9 @@ namespace TUMVis {
/// \see ImageDataLocal::getElementNormalized
virtual float getElementNormalized(const tgt::svec3& position, size_t channel) const;
/// \see ImageDataLocal::getElementNormalizedLinear
virtual float getElementNormalizedLinear(const tgt::vec3& position, size_t channel) const;
/// \see ImageDataLocal::setElementNormalized
virtual void setElementNormalized(const tgt::svec3& position, size_t channel, float value);
......@@ -157,7 +160,11 @@ namespace TUMVis {
: ImageDataLocal(dimensionality, size, TypeTraits<BASETYPE, NUMCHANNELS>::weaklyTypedPointerBaseType, NUMCHANNELS)
, _data(data)
{
tgtAssert(data != 0, "Pointer to image data must not be 0!");
if (_data == 0) {
size_t numElements = tgt::hmul(_size);
_data = new ElementType[numElements];
memset(_data, 0, numElements * TypeTraits<BASETYPE, NUMCHANNELS>::elementSize);
}
}
template<typename BASETYPE, size_t NUMCHANNELS>
......@@ -276,6 +283,30 @@ namespace TUMVis {
tgtAssert(false, "Yet to be implemented!");
return ElementType(0);
}
template<typename BASETYPE, size_t NUMCHANNELS>
float TUMVis::GenericImageDataLocal<BASETYPE, NUMCHANNELS>::getElementNormalizedLinear(const tgt::vec3& position, size_t channel) const {
tgt::vec3 posAbs = tgt::max(position - 0.5f, tgt::vec3::zero);
tgt::vec3 p = posAbs - floor(posAbs); // get decimal part
tgt::svec3 llb = tgt::svec3(posAbs);
tgt::svec3 urf = tgt::svec3(ceil(posAbs));
urf = min(urf, _size - tgt::svec3(1)); // clamp so the lookups do not exceed the dimensions
llb = min(llb, _size - tgt::svec3(1)); // dito
/*
interpolate linearly
*/
return getElementNormalized(tgt::svec3(llb.x, llb.y, llb.z), channel) * (1.f-p.x)*(1.f-p.y)*(1.f-p.z) // llB
+ getElementNormalized(tgt::svec3(urf.x, llb.y, llb.z), channel) * ( p.x)*(1.f-p.y)*(1.f-p.z) // lrB
+ getElementNormalized(tgt::svec3(urf.x, urf.y, llb.z), channel) * ( p.x)*( p.y)*(1.f-p.z) // urB
+ getElementNormalized(tgt::svec3(llb.x, urf.y, llb.z), channel) * (1.f-p.x)*( p.y)*(1.f-p.z) // ulB
+ getElementNormalized(tgt::svec3(llb.x, llb.y, urf.z), channel) * (1.f-p.x)*(1.f-p.y)*( p.z) // llF
+ getElementNormalized(tgt::svec3(urf.x, llb.y, urf.z), channel) * ( p.x)*(1.f-p.y)*( p.z) // lrF
+ getElementNormalized(tgt::svec3(urf.x, urf.y, urf.z), channel) * ( p.x)*( p.y)*( p.z) // urF
+ getElementNormalized(tgt::svec3(llb.x, urf.y, urf.z), channel) * (1.f-p.x)*( p.y)*( p.z);// ulF
}
}
#endif // GENERICIMAGEDATALOCAL_H__
......@@ -72,4 +72,12 @@ namespace TUMVis {
size_t ImageData::positionToIndex(const tgt::svec3& position) const {
return position.x + (position.y * _size.x) + (position.z * _size.x * _size.y);
}
tgt::svec3 ImageData::indexToPosition(size_t index) const {
size_t z = index / (_size.x * _size.y);
size_t y = (index % (_size.x * _size.y)) / _size.x;
size_t x = index % _size.x;
return tgt::svec3(x, y, z);
}
}
\ No newline at end of file
......@@ -97,7 +97,6 @@ namespace TUMVis {
*/
virtual ImageData* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const = 0;
protected:
/**
* Transforms a vector based position to the corresponding array index.
* \note Caution, this method might return wrong results for non-continuous storage.
......@@ -107,6 +106,16 @@ namespace TUMVis {
*/
size_t positionToIndex(const tgt::svec3& position) const;
/**
* Transforms an array index to the corresponding vector based position.
* \note Caution, this method might return wrong results for non-continuous storage.
* In this case you should provide an appropriate overload.
* \param index Array index when image is stored continuously.
* \return Vector based image coordinates.
*/
tgt::svec3 indexToPosition(size_t index) const;
protected:
size_t _dimensionality; ///< Dimensionality of this image
tgt::svec3 _size; ///< Size of this image (number of elements per dimension)
size_t _numElements; ///< number of elements (= tgt::hmul(size))
......
......@@ -93,6 +93,23 @@ namespace TUMVis {
*/
virtual float getElementNormalized(const tgt::svec3& position, size_t channel) const = 0;
/**
* Returns the normalized value of the element at the given position and channel using linear interpolation.
* - for \em unsigned integer types, the value range is mapped linearly to [0.0;1.0]
* - for \em signed integer types, the value range is mapped linearly to [-1.0;1.0]
* - floating point types are not mapped
*
* Simple algorithms on images might not always want to test for the actual base data type.
* For them access to the normalized element values provided here might be enough.
*
* \note This method is virtual => know the costs!
* \sa ImageDataLocal::getElementNormalized
* \param position Element position within the image
* \param channel Image channel
* \return A normalized float representation of the element at the given position and channel.
*/
virtual float getElementNormalizedLinear(const tgt::vec3& position, size_t channel) const = 0;
/**
* Sets the element at the given position and channel denormalized from the given value \a value.
* - for \em unsigned integer types, the value range is mapped linearly to [0.0;1.0]
......
......@@ -38,9 +38,9 @@ struct TFParameters {
*/
float mapIntensityToTFDomain(in TFParameters p, in float intensity) {
if(intensity <= p._intensityDomain.x)
return 0.0;
return -1.0;
else if(intensity >= p._intensityDomain.y)
return 1.0;
return -1.0;
else
return (intensity - p._intensityDomain.x) / (p._intensityDomain.y - p._intensityDomain.x);
}
......@@ -55,7 +55,7 @@ float mapIntensityToTFDomain(in TFParameters p, in float intensity) {
*/
vec4 lookupTF(in TFParameters p, in sampler1D tex, in float intensity) {
intensity = mapIntensityToTFDomain(p, intensity);
return texture(tex, intensity);
return (intensity >= 0.0 ? texture(tex, intensity) : vec4(0.0, 0.0, 0.0, 0.0));
}
/**
......@@ -69,5 +69,5 @@ vec4 lookupTF(in TFParameters p, in sampler1D tex, in float intensity) {
*/
vec4 lookupTF(in TFParameters p, in sampler2D tex, in float intensity, in float y) {
intensity = mapIntensityToTFDomain(p, intensity);
return texture(tex, vec2(intensity, y));
return (intensity >= 0.0 ? texture(tex, vec2(intensity, y)) : vec4(0.0, 0.0, 0.0, 0.0));
}
......@@ -30,6 +30,8 @@
#include "tgt/exception.h"
#include "core/pipeline/abstractprocessor.h"
#include <ctime>
namespace TUMVis {
const std::string AbstractPipeline::loggerCat_ = "TUMVis.core.datastructures.AbstractPipeline";
......@@ -76,7 +78,7 @@ namespace TUMVis {
s_PipelineInvalidated();
}
void AbstractPipeline::onProcessorInvalidated(const AbstractProcessor* processor) {
void AbstractPipeline::onProcessorInvalidated(AbstractProcessor* processor) {
_invalidationLevel.setLevel(InvalidationLevel::INVALID_RESULT);
s_PipelineInvalidated();
}
......@@ -94,8 +96,18 @@ namespace TUMVis {
if (processor->getEnabled() && !processor->getInvalidationLevel().isValid()) {
processor->lockProperties();
#ifdef TUMVIS_DEBUG
clock_t startTime = clock();
#endif
processor->process(_data);
#ifdef TUMVIS_DEBUG
clock_t endTime = clock();
#endif
processor->unlockProperties();
#ifdef TUMVIS_DEBUG
LDEBUG("Executed processor " << processor->getName() << " duration: " << (endTime - startTime));
#endif
}
}
......
......@@ -139,7 +139,7 @@ namespace TUMVis {
* The default behaviour is just to set the invalidation level to invalid.
* \param processor The processor that emitted the signal
*/
virtual void onProcessorInvalidated(const AbstractProcessor* processor);
virtual void onProcessorInvalidated(AbstractProcessor* processor);
/**
* Executes the processor \a processor on the pipeline's data and locks its properties meanwhile.
......
......@@ -150,7 +150,7 @@ namespace TUMVis {
/// Signal emitted when the processor has been invalidated.
sigslot::signal1<const AbstractProcessor*> s_invalidated;
sigslot::signal1<AbstractProcessor*> s_invalidated;
/**
* Slot getting called when one of the observed properties changed and notifies its observers.
......
......@@ -125,7 +125,7 @@ namespace TUMVis {
fatherNode->second->addDependency(childNode->second);
}
void DigraphVisualizationPipeline::onProcessorInvalidated(const AbstractProcessor* processor) {
void DigraphVisualizationPipeline::onProcessorInvalidated(AbstractProcessor* processor) {
// TODO: implement
}
......
......@@ -117,7 +117,7 @@ namespace TUMVis {
* The default behaviour is just to set the invalidation level to invalid.
* \param processor The processor that emitted the signal
*/
virtual void onProcessorInvalidated(const AbstractProcessor* processor);
virtual void onProcessorInvalidated(AbstractProcessor* processor);
static const std::string loggerCat_;
......
......@@ -49,7 +49,7 @@ namespace TUMVis {
, _exitImageID("exitImageID", "Input Exit Points Image", "", DataNameProperty::READ)
, _camera("camera", "Camera")
, _transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
, _samplingStepSize("samplingStepSize", "Sampling Step Size", .02f, 0.001f, 1.f)
, _samplingStepSize("samplingStepSize", "Sampling Step Size", .05f, 0.001f, 1.f)
, _jitterEntryPoints("jitterEntryPoints", "Jitter Entry Points", true)
, _jitterStepSizeMultiplier("jitterStepSizeMultiplier", "Jitter Step Size Multiplier", .5f, .1f, 1.f)
, _fragmentShaderFilename(fragmentShaderFileName)
......@@ -104,7 +104,7 @@ namespace TUMVis {
_shader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(_renderTargetSize.getValue()));
_shader->setUniform("_jitterEntryPoints", _jitterEntryPoints.getValue());
_shader->setUniform("_jitterStepSizeMultiplier", _jitterStepSizeMultiplier.getValue());
_shader->setUniform("_samplingStepSize", _samplingStepSize.getValue());
_shader->setUniform("_samplingStepSize", _samplingStepSize.getValue() * .1f);
const tgt::Camera& cam = _camera.getValue();
float n = cam.getNearDist();
......
......@@ -67,7 +67,7 @@ namespace TUMVis {
* \param delimiters Set of delimiters for separating key-value pair
* \param whitespace Set of characters identifying whitespace
*/
TextFileParser(const std::string& url, bool caseSensitiveKeys, const std::string& delimiters, const std::string& whitespace = " \t");
TextFileParser(const std::string& url, bool caseSensitiveKeys, const std::string& delimiters, const std::string& whitespace = " \t\n\r");
/**
......
......@@ -5,14 +5,18 @@ INCLUDE(../cmake/commonconf.cmake)
MESSAGE(STATUS "Configuring TUMVis Modules")
FILE(GLOB TUMVIS_MODULES_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
classification/*.cpp
io/*.cpp
pipelines/*.cpp
preprocessing/*.cpp
vis/*.cpp
)
FILE(GLOB TUMVIS_MODULES_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
classification/*.h
io/*.h
pipelines/*.h
preprocessing/*.h
vis/*.h
vis/*.frag
vis/*.cl
......
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb@in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "lhhistogram.h"
#include "tgt/glmath.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "tbb/include/tbb/tbb.h"
#include "core/datastructures/genericimagedatalocal.h"
namespace TUMVis {
class LHGenerator {
public:
LHGenerator(const ImageDataLocal* intensities, const GenericImageDataLocal<float, 4>* gradients, ImageDataLocal* fh, ImageDataLocal* fl, float epsilon)
: _intensities(intensities)
, _gradients(gradients)
, _fh(fh)
, _fl(fl)
, _epsilon(epsilon)
{
tgtAssert(_intensities->getDimensionality() == _gradients->getDimensionality(), "Dimensionality of intensities volumes must match!");
tgtAssert(_intensities->getSize() == _gradients->getSize(), "Size of intensities volumes must match!");
}
tgt::vec4 getGradientLinear(const tgt::vec3& position) const {
tgt::vec4 result;
result.x = _gradients->getElementNormalizedLinear(position, 0);
result.y = _gradients->getElementNormalizedLinear(position, 1);
result.z = _gradients->getElementNormalizedLinear(position, 2);
result.w = _gradients->getElementNormalizedLinear(position, 3);
return result;
}
float integrateHeun(tgt::vec3 position, const tgt::vec4& direction) const {
tgt::vec4 gradient1 = direction;
tgt::vec3 stepSize(1.f);
tgt::vec3 size(_intensities->getSize());
while (gradient1.w > _epsilon) {
tgt::vec4 gradient2 = getGradientLinear(position + tgt::normalize(gradient1.xyz()) * stepSize);
position += tgt::normalize((gradient1 + gradient2).xyz()) * stepSize;
gradient1 = getGradientLinear(position);
if (tgt::hor(tgt::lessThan(position, tgt::vec3::zero)) || tgt::hor(tgt::greaterThan(position, size)))
break;
}
return _intensities->getElementNormalizedLinear(position, 0);;
}
void operator() (const tbb::blocked_range<size_t>& range) const {
for (size_t i = range.begin(); i != range.end(); ++i) {
tgt::svec3 pos = _intensities->indexToPosition(i);
const tgt::svec3& size = _intensities->getSize();
const tgt::vec4& gradient = _gradients->getElement(i);
float fl = _intensities->getElementNormalized(pos, 0);
float fh = fl;
float forwardIntensity = integrateHeun(tgt::vec3(static_cast<float>(pos.x), static_cast<float>(pos.y), static_cast<float>(pos.z)), gradient);
float backwardIntensity = integrateHeun(tgt::vec3(static_cast<float>(pos.x), static_cast<float>(pos.y), static_cast<float>(pos.z)), gradient * -1.f);
fh = std::max(forwardIntensity, backwardIntensity);
fl = std::min(forwardIntensity, backwardIntensity);
_fl->setElementNormalized(pos, 0, fl);
_fh->setElementNormalized(pos, 0, fh);
}
}
protected:
const ImageDataLocal* _intensities;
const GenericImageDataLocal<float, 4>* _gradients;
ImageDataLocal* _fh;
ImageDataLocal* _fl;
float _epsilon;
};
// ================================================================================================
const std::string LHHistogram::loggerCat_ = "TUMVis.modules.classification.LHHistogram";
LHHistogram::LHHistogram()
: AbstractProcessor()
, _inputVolume("InputVolume", "Input Volume ID", "volume", DataNameProperty::READ)
, _inputGradients("InputGradients", "Input Gradient Volume ID", "gradients", DataNameProperty::READ)
, _outputFH("OutputFH", "FH Output Volume", "fh", DataNameProperty::WRITE)
, _outputFL("OutputFL", "FL Output Volume", "fl", DataNameProperty::WRITE)
{
addProperty(&_inputVolume);
addProperty(&_inputGradients);
addProperty(&_outputFH);
addProperty(&_outputFL);
}
LHHistogram::~LHHistogram() {
}
void LHHistogram::process(DataContainer& data) {
DataContainer::ScopedTypedData<ImageDataLocal> intensities(data, _inputVolume.getValue());
DataContainer::ScopedTypedData< GenericImageDataLocal<float, 4> > gradients(data, _inputGradients.getValue());
if (intensities != 0 && gradients != 0) {
ImageDataLocal* fh = intensities->clone();
ImageDataLocal* fl = intensities->clone();
tbb::parallel_for(tbb::blocked_range<size_t>(0, intensities->getNumElements()), LHGenerator(intensities, gradients, fh, fl, .01f));
data.addData(_outputFH.getValue(), fh);
data.addData(_outputFL.getValue(), fl);
_outputFH.issueWrite();
_outputFL.issueWrite();
}
else {
LDEBUG("No suitable intensities image found.");
}
_invalidationLevel.setValid();
}
}
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb@in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef LHHISTOGRAM_H__
#define LHHISTOGRAM_H__
#include <string>
#include "core/classification/abstracttransferfunction.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/genericproperty.h"
#include "core/properties/numericproperty.h"
#include "core/properties/cameraproperty.h"
namespace TUMVis {
/**
* Creates Lookup volumes vor generation LH-Histograms of volumes as well as the LH histogram.
*/
class LHHistogram : public AbstractProcessor {
public:
/**
* Constructs a new LHHistogram Processor
**/
LHHistogram();
/**
* Destructor
**/
virtual ~LHHistogram();
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "LHHistogram"; };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Creates Lookup volumes vor generation LH-Histograms of volumes as well as the LH histogram."; };
virtual void process(DataContainer& data);
DataNameProperty _inputVolume; ///< ID for input volume
DataNameProperty _inputGradients; ///< ID for input gradient volume
DataNameProperty _outputFH; ///< ID for output FH volume
DataNameProperty _outputFL; ///< ID for output FL volume
protected:
static const std::string loggerCat_;
};
}
#endif // LHHISTOGRAM_H__
......@@ -45,7 +45,7 @@ namespace TUMVis {
MhdImageReader::MhdImageReader()
: AbstractProcessor()
, _url("url", "Image URL", "")
, _targetImageID("targetImageName", "Target Image ID", "MhdImageReader.output")
, _targetImageID("targetImageName", "Target Image ID", "MhdImageReader.output", DataNameProperty::WRITE)
{
addProperty(&_url);
addProperty(&_targetImageID);
......
......@@ -32,6 +32,7 @@
#include <string>
#include "core/pipeline/abstractprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/genericproperty.h"
namespace TUMVis {
......@@ -65,7 +66,7 @@ namespace TUMVis {
virtual const std::string getDescription() const { return "Reads an MHD image into the pipeline."; };
GenericProperty<std::string> _url; ///< URL for file to read
GenericProperty<std::string> _targetImageID; ///< image ID for read image
DataNameProperty _targetImageID; ///< image ID for read image
protected:
......
......@@ -36,10 +36,14 @@ namespace TUMVis {
SliceVis::SliceVis()
: VisualizationPipeline()
, _imageReader()
, _gvg()
, _lhh()
, _sliceExtractor(_renderTargetSize)
, _wheelHandler(&_sliceExtractor._sliceNumber)
{
_processors.push_back(&_imageReader);
_processors.push_back(&_gvg);
_processors.push_back(&_lhh);
_processors.push_back(&_sliceExtractor);
_eventHandlers.push_back(&_wheelHandler);
}
......@@ -53,6 +57,11 @@ namespace TUMVis {
_imageReader._url.setValue("D:\\Medical Data\\smallHeart.mhd");
_imageReader._targetImageID.setValue("reader.output");
_gvg._inputVolume.setValue("se.input");
_lhh._inputVolume.setValue("se.input");
_gvg._outputGradients.connect(&_lhh._inputGradients);
_sliceExtractor._sourceImageID.setValue("se.input");
_sliceExtractor._sliceNumber.setValue(0);
// TODO: replace this hardcoded domain by automatically determined from image min/max values
......@@ -62,6 +71,7 @@ namespace TUMVis {
_renderTargetID.addSharedProperty(&(_sliceExtractor._targetImageID));
_imageReader.s_invalidated.connect<SliceVis>(this, &SliceVis::onProcessorInvalidated);
_gvg.s_invalidated.connect<SliceVis>(this, &SliceVis::onProcessorInvalidated);
_sliceExtractor.s_invalidated.connect<SliceVis>(this, &SliceVis::onProcessorInvalidated);
}
......@@ -81,6 +91,12 @@ namespace TUMVis {
_data.addData("se.input", local);
}
}
if (! _gvg.getInvalidationLevel().isValid()) {
executeProcessor(&_gvg);
}
if (! _lhh.getInvalidationLevel().isValid()) {
executeProcessor(&_lhh);
}
if (! _sliceExtractor.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_sliceExtractor);
}
......
......@@ -34,6 +34,8 @@
#include "core/pipeline/visualizationpipeline.h"
#include "modules/io/mhdimagereader.h"
#include "modules/vis/sliceextractor.h"
#include "modules/preprocessing/gradientvolumegenerator.h"
#include "modules/classification/lhhistogram.h"
namespace TUMVis {