Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing 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 099ffa57 authored by schultezub's avatar schultezub
Browse files

started implementing more sophisticated transfer functions

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@303 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 2944a868
// ================================================================================================
//
// 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 "geometrytransferfunction.h"
#include "tgt/assert.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/texture.h"
#include "tgt/textureunit.h"
#include "core/classification/tfgeometry.h"
namespace TUMVis {
const std::string GeometryTransferFunction::loggerCat_ = "TUMVis.core.classification.GeometryTransferFunction";
GeometryTransferFunction::GeometryTransferFunction(size_t size, const tgt::vec2& intensityDomain /*= tgt::vec2(0.f, 1.f)*/)
: AbstractTransferFunction(tgt::svec3(size, 1, 1), intensityDomain)
{
}
GeometryTransferFunction::~GeometryTransferFunction() {
}
size_t GeometryTransferFunction::getDimensionality() const {
return 1;
}
void GeometryTransferFunction::createTexture() {
delete _texture;
GLenum dataType = GL_UNSIGNED_BYTE;
_texture = new tgt::Texture(_size, GL_RGBA, dataType, tgt::Texture::LINEAR);
_texture->setWrapping(tgt::Texture::CLAMP);
GLubyte* ptr = _texture->getPixelData();
memset(ptr, 0, _texture->getArraySize());
for (std::vector<TFGeometry*>::const_iterator it = _geometries.begin(); it != _geometries.end(); ++it) {
(*it)->rasterize(*_texture);
}
_texture->uploadTexture();
_dirty = false;
}
const std::vector<TFGeometry*>& GeometryTransferFunction::getGeometries() const {
return _geometries;
}
void GeometryTransferFunction::addGeometry(TFGeometry* geometry) {
{
tbb::mutex::scoped_lock lock(_localMutex);
_geometries.push_back(geometry);
}
_dirty = true;
s_changed();
}
}
\ No newline at end of file
// ================================================================================================
//
// 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 GEOMETRYTRANSFERFUNCTION_H__
#define GEOMETRYTRANSFERFUNCTION_H__
#include "core/classification/abstracttransferfunction.h"
#include <vector>
namespace TUMVis {
class TFGeometry;
/**
* A 1D transfer function built from multiple geometries.
*/
class GeometryTransferFunction : public AbstractTransferFunction {
public:
/**
* Creates a new GeometryTransferFunction.
* \param size Size of the transfer function texture
* \param intensityDomain Intensity Domain where the transfer function is mapped to during classification
*/
GeometryTransferFunction(size_t size, const tgt::vec2& intensityDomain = tgt::vec2(0.f, 1.f));
/**
* Destructor, make sure to delete the OpenGL texture beforehand by calling deinit() with a valid OpenGL context!
*/
virtual ~GeometryTransferFunction();
/**
* Returns the dimensionality of the transfer function.
* \return The dimensionality of the transfer function.
*/
virtual size_t getDimensionality() const;
/**
* Gets the list of transfer function geometries.
* \return _geometries
*/
const std::vector<TFGeometry*>& getGeometries() const;
/**
* Adds the given TF geometry to this transfer function.
* \param geometry TF geometry to add
*/
void addGeometry(TFGeometry* geometry);
protected:
/**
* Creates the texture and uploads it to OpenGL.
* Gets called by bind() with the local mutex already acquired.
*/
virtual void createTexture();
std::vector<TFGeometry*> _geometries; ///< The list of transfer function geometries.
static const std::string loggerCat_;
};
}
#endif // GEOMETRYTRANSFERFUNCTION_H__
// ================================================================================================
//
// 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.
//
// ================================================================================================
#include "tfgeometry.h"
#include "tgt/assert.h"
#include "tgt/texture.h"
#include "tgt/tgt_math.h"
#include <algorithm>
namespace {
tgt::col4 toCol(const tgt::vec4& c) {
return tgt::col4(
static_cast<uint8_t>(255 * c.r),
static_cast<uint8_t>(255 * c.g),
static_cast<uint8_t>(255 * c.b),
static_cast<uint8_t>(255 * c.a));
}
tgt::vec4 toVec(const tgt::col4& c) {
return tgt::vec4(
static_cast<float>(c.r) / 255.f,
static_cast<float>(c.g) / 255.f,
static_cast<float>(c.b) / 255.f,
static_cast<float>(c.a) / 255.f);
}
}
namespace TUMVis {
bool operator< (const TFGeometry::KeyPoint& left, const TFGeometry::KeyPoint& right) {
return left._position < right._position;
}
TFGeometry::TFGeometry(const std::vector<KeyPoint>& keyPoints)
: _keyPoints(keyPoints)
{
std::sort(_keyPoints.begin(), _keyPoints.end());
}
TFGeometry::~TFGeometry() {
}
void TFGeometry::rasterize(tgt::Texture& texture) const {
if (_keyPoints.size() < 2)
return;
int width = texture.getWidth();
float rcpWidth = 1.f / static_cast<float>(width);
// _keyPoints has at least 2 items
std::vector<KeyPoint>::const_iterator start = _keyPoints.begin();
std::vector<KeyPoint>::const_iterator end = _keyPoints.begin()+1;
for (/* already inited */; end != _keyPoints.end(); ++start, ++end) {
size_t startIndex = static_cast<size_t>(tgt::round(start->_position * width));
size_t endIndex = static_cast<size_t>(tgt::round(end->_position * width));
float dist = end->_position - start->_position;
tgt::vec4 startColor = toVec(start->_color);
tgt::vec4 endColor = toVec(end->_color);
for (size_t i = startIndex; i < endIndex; ++i) {
tgt::vec4 result = toVec(texture.texel<tgt::col4>(i));
tgt::vec4 color = tgt::mix(startColor, endColor, tgt::clamp((static_cast<float>(i) * rcpWidth - start->_position) / dist, 0.f, 1.f));
result = tgt::vec4(tgt::mix(color.xyz(), result.xyz(), result.a), result.a + (1.f - result.a) * color.a);
texture.texel<tgt::col4>(i) = toCol(result);
}
}
}
TFGeometry* TFGeometry::createQuad(const tgt::vec2& interval, const tgt::col4& leftColor, const tgt::vec4 rightColor) {
tgtAssert(interval.x >= 0.f && interval.y <= 1.f, "Interval out of bounds");
std::vector<KeyPoint> keyPoints;
keyPoints.push_back(KeyPoint(interval.x, leftColor));
keyPoints.push_back(KeyPoint(interval.y, rightColor));
return new TFGeometry(keyPoints);
}
}
\ No newline at end of file
// ================================================================================================
//
// 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 TFGEOMETRY_H__
#define TFGEOMETRY_H__
#include "tgt/vector.h"
#include <vector>
namespace tgt {
class Texture;
}
namespace TUMVis {
/**
* Defines a single shape for the GeometryTransferFunction class.
* TFGeometry is defined by a sorted list of KeyPoints, each having a position and a color.
*/
class TFGeometry {
public:
struct KeyPoint {
KeyPoint(float position, const tgt::col4& color)
: _position(position)
, _color(color)
{};
float _position;
tgt::col4 _color;
};
/**
* Creates a new TFGeometry
* \param Bounds Bounds of the position of the geometry in texture coordinates.
*/
TFGeometry(const std::vector<KeyPoint>& keyPoints);
/**
* Virtual destructor
*/
virtual ~TFGeometry();
/**
* Rasterizes this transfer function geometry into the given texture
* \param texture Texture to rasterize this geometry into.
*/
void rasterize(tgt::Texture& texture) const;
/**
* Creates a simple quad geometry for the given interval.
* A quad geometry consists of two KeyPoints.
* \param interval Interval the geometry resides in
* \param leftColor Color for left KeyPoint
* \param rightColor Color for right KeyPoint
* \return A TFGeometry modelling a quad with two KeyPoints.
*/
static TFGeometry* createQuad(const tgt::vec2& interval, const tgt::col4& leftColor, const tgt::vec4 rightColor);
protected:
std::vector<KeyPoint> _keyPoints; ///< vector of KeyPoints, KeyPoints are sorted by x-coordinate of the position
};
// ================================================================================================
/**
* Less operator for sorting KeyPoints by their position.
* \param left Left KeyPoint to compare
* \param right RightKeyPoint to compare
* \return left._position < right._position
*/
bool operator< (const TFGeometry::KeyPoint& left, const TFGeometry::KeyPoint& right);
}
#endif // TFGEOMETRY_H__
...@@ -57,4 +57,12 @@ namespace TUMVis { ...@@ -57,4 +57,12 @@ namespace TUMVis {
_transferFunction->deinit(); _transferFunction->deinit();
} }
void TransferFunctionProperty::replaceTF(AbstractTransferFunction* tf) {
tgtAssert(tf != 0, "Transfer function must not be 0.");
s_BeforeTFReplace(_transferFunction);
delete _transferFunction;
_transferFunction = tf;
s_AfterTFReplace(_transferFunction);
}
} }
...@@ -64,12 +64,23 @@ namespace TUMVis { ...@@ -64,12 +64,23 @@ namespace TUMVis {
*/ */
AbstractTransferFunction* getTF(); AbstractTransferFunction* getTF();
/**
* Replaces the transfer function with \a tf.
* \note First triggers s_BeforeTFReplace, then deletes the current TF, replaces it with
* \a tf and finally triffers s_AfterTFReplace.
* \param tf The new transfer function for this property.
*/
void replaceTF(AbstractTransferFunction* tf);
/** /**
* Slot being called when \a _transferFunction has changed. * Slot being called when \a _transferFunction has changed.
*/ */
void onTFChanged(); void onTFChanged();
sigslot::signal1<AbstractTransferFunction*> s_BeforeTFReplace;
sigslot::signal1<AbstractTransferFunction*> s_AfterTFReplace;
protected: protected:
AbstractTransferFunction* _transferFunction; ///< Transfer function of this property AbstractTransferFunction* _transferFunction; ///< Transfer function of this property
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "tgt/glcontext.h" #include "tgt/glcontext.h"
#include "tgt/qt/qtcontextmanager.h" #include "tgt/qt/qtcontextmanager.h"
#include "core/datastructures/imagedataconverter.h" #include "core/datastructures/imagedataconverter.h"
#include "core/classification/geometrytransferfunction.h"
#include "core/classification/tfgeometry.h"
namespace TUMVis { namespace TUMVis {
...@@ -87,6 +89,11 @@ namespace TUMVis { ...@@ -87,6 +89,11 @@ namespace TUMVis {
_dvrNormal._targetImageID.setValue("drr.output"); _dvrNormal._targetImageID.setValue("drr.output");
_dvrNormal._sourceImageID.setValue("eep.input"); _dvrNormal._sourceImageID.setValue("eep.input");
GeometryTransferFunction* dvrTF = new GeometryTransferFunction(128, tgt::vec2(0.f, .05f));
dvrTF->addGeometry(TFGeometry::createQuad(tgt::vec2(.4f, .42f), tgt::col4(255, 0, 0, 255), tgt::col4(255, 0, 0, 255)));
dvrTF->addGeometry(TFGeometry::createQuad(tgt::vec2(.45f, .5f), tgt::col4(0, 255, 0, 255), tgt::col4(0, 255, 0, 255)));
_dvrNormal._transferFunction.replaceTF(dvrTF);
_dvrVM._targetImageID.setValue("dvr.output"); _dvrVM._targetImageID.setValue("dvr.output");
_dvrVM._sourceImageID.setValue("eep.input"); _dvrVM._sourceImageID.setValue("eep.input");
......
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