Commit aee478c6 authored by schultezub's avatar schultezub
Browse files

* introducing AlgorithmicGeometry utility class

 * implemented WholeTFGeometryManipulator interaction metaphors

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@314 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 75cd24be
......@@ -35,6 +35,7 @@
#include "application/gui/qtcolortools.h"
#include "core/classification/geometrytransferfunction.h"
#include "core/classification/tfgeometry.h"
#include "core/tools/algorithmicgeometry.h"
#include <QColorDialog>
......@@ -91,25 +92,28 @@ namespace TUMVis {
_mousePressed = true;
e->accept();
}
else {
e->ignore();
}
}
void KeyPointManipulator::mouseReleaseEvent(tgt::MouseEvent* e) {
_mousePressed = false;
// no accept here, because other listeners probably need this signal as well
// ignore here, because other listeners probably need this signal as well
e->ignore();
}
void KeyPointManipulator::mouseMoveEvent(tgt::MouseEvent* e) {
if (_mousePressed) {
tgt::ivec2 currentPosition = tgt::clamp(tgt::ivec2(e->coord().x, _viewportSize.y - e->coord().y), tgt::ivec2(0, 0), _viewportSize);
//tgt::vec2 displacement = viewportToTF(currentPosition - _pressedPosition);
tgt::vec2 tfCoords = viewportToTF(currentPosition);
_keyPoint->_position = tfCoords.x;
_keyPoint->_color.a = static_cast<uint8_t>(tfCoords.y * 255.f);
_geometry->s_changed();
// no accept here, because other listeners probably need this signal as well
}
// ignore here, because other listeners probably need this signal as well
e->ignore();
}
void KeyPointManipulator::mouseDoubleClickEvent(tgt::MouseEvent* e) {
......@@ -124,6 +128,9 @@ namespace TUMVis {
}
e->accept();
}
else {
e->ignore();
}
}
......@@ -136,10 +143,104 @@ namespace TUMVis {
, _geometry(geometry)
{
tgtAssert(geometry != 0, "Geometry must not be 0.");
_geometry->s_changed.connect(this, &WholeTFGeometryManipulator::onGeometryChanged);
updateHelperPoints();
}
WholeTFGeometryManipulator::~WholeTFGeometryManipulator() {
_geometry->s_changed.disconnect(this);
}
void WholeTFGeometryManipulator::render() {
}
void WholeTFGeometryManipulator::mousePressEvent(tgt::MouseEvent* e) {
_pressedPosition = viewportToTF(tgt::ivec2(e->coord().x, _viewportSize.y - e->coord().y));
if (insideGeometry(_pressedPosition)) {
_mousePressed = true;
_valuesWhenPressed = _geometry->getKeyPoints();
e->accept();
}
else {
e->ignore();
}
}
void WholeTFGeometryManipulator::mouseReleaseEvent(tgt::MouseEvent* e) {
_mousePressed = false;
// ignore here, because other listeners probably need this signal as well
e->ignore();
}
void WholeTFGeometryManipulator::mouseMoveEvent(tgt::MouseEvent* e) {
if (_mousePressed) {
tgt::vec2 currentPosition = viewportToTF(tgt::clamp(tgt::ivec2(e->coord().x, _viewportSize.y - e->coord().y), tgt::ivec2(0, 0), _viewportSize));
tgt::vec2 displacement = currentPosition - _pressedPosition;
for (size_t i = 0; i < _valuesWhenPressed.size(); ++i) {
_geometry->getKeyPoints()[i]._position = _valuesWhenPressed[i]._position + displacement.x;
}
_geometry->s_changed();
}
// ignore here, because other listeners probably need this signal as well
e->ignore();
}
void WholeTFGeometryManipulator::mouseDoubleClickEvent(tgt::MouseEvent* e) {
tgt::vec2 pos = viewportToTF(tgt::ivec2(e->coord().x, _viewportSize.y - e->coord().y));
if (insideGeometry(pos)) {
// launch a color picker dialog and set new color on success
QColor newColor = QColorDialog::getColor(QtColorTools::toQColor(_geometry->getKeyPoints().front()._color), 0, "Select New Color");
if(newColor.isValid()) {
tgt::col4 tmp = QtColorTools::toTgtColor(newColor);
for (std::vector<TFGeometry::KeyPoint>::iterator it = _geometry->getKeyPoints().begin(); it != _geometry->getKeyPoints().end(); ++it) {
it->_color = tgt::col4(tmp.xyz(), it->_color.a);
}
_geometry->s_changed();
}
e->accept();
}
else {
e->ignore();
}
}
void WholeTFGeometryManipulator::onGeometryChanged() {
updateHelperPoints();
}
bool WholeTFGeometryManipulator::insideGeometry(const tgt::vec2& position) const {
if (_helperPoints.size() < 3)
return false;
// simple approach: check for left turn for every triple of points
for (std::vector<tgt::vec2>::const_iterator it = _helperPoints.begin()+1; it != _helperPoints.end(); ++it) {
if (! AlgorithmicGeometry::rightTurn2D(*(it-1), *it, position))
return false;
}
return true;
}
void WholeTFGeometryManipulator::updateHelperPoints() {
_helperPoints.clear();
const std::vector<TFGeometry::KeyPoint>& keyPoints = _geometry->getKeyPoints();
if (keyPoints.front()._color.w > 0) {
_helperPoints.push_back(tgt::vec2(keyPoints.front()._position, 0.f));
}
for (std::vector<TFGeometry::KeyPoint>::const_iterator it = keyPoints.begin(); it != keyPoints.end(); ++it) {
float y = static_cast<float>(it->_color.a) / 255.f;
_helperPoints.push_back(tgt::vec2(it->_position, y));
}
if (keyPoints.back()._color.w > 0) {
_helperPoints.push_back(tgt::vec2(keyPoints.back()._position, 0.f));
}
}
}
\ No newline at end of file
......@@ -108,11 +108,11 @@ namespace TUMVis {
void render();
/// \see tgt::EventListener::mousePressEvent
virtual void mousePressEvent(tgt::MouseEvent* e);
virtual void mousePressEvent(tgt::MouseEvent* e);
/// \see tgt::EventListener::mouseReleaseEvent
virtual void mouseReleaseEvent(tgt::MouseEvent* e);
virtual void mouseReleaseEvent(tgt::MouseEvent* e);
/// \see tgt::EventListener::mouseMoveEvent
virtual void mouseMoveEvent(tgt::MouseEvent* e);
virtual void mouseMoveEvent(tgt::MouseEvent* e);
/// \see tgt::EventListener::mouseDoubleClickEvent
virtual void mouseDoubleClickEvent(tgt::MouseEvent* e);
......@@ -131,7 +131,7 @@ namespace TUMVis {
/**
* Class for manipulating the whole TFGeometry at once.
*/
class WholeTFGeometryManipulator : public AbstractTFGeometryManipulator {
class WholeTFGeometryManipulator : public AbstractTFGeometryManipulator, public sigslot::has_slots<> {
public:
/**
* Creates a new KeyPointManipulator
......@@ -141,11 +141,48 @@ namespace TUMVis {
*/
WholeTFGeometryManipulator(const tgt::ivec2& viewportSize, GeometryTransferFunction* tf, TFGeometry* geometry);
/**
* Destructor
*/
virtual ~WholeTFGeometryManipulator();
/// \see AbstractTFGeometryManipulator::render
void render();
/// \see tgt::EventListener::mousePressEvent
virtual void mousePressEvent(tgt::MouseEvent* e);
/// \see tgt::EventListener::mouseReleaseEvent
virtual void mouseReleaseEvent(tgt::MouseEvent* e);
/// \see tgt::EventListener::mouseMoveEvent
virtual void mouseMoveEvent(tgt::MouseEvent* e);
/// \see tgt::EventListener::mouseDoubleClickEvent
virtual void mouseDoubleClickEvent(tgt::MouseEvent* e);
/**
* Slot to be called when the geometry has changed.
*/
void onGeometryChanged();
protected:
/**
* Checks whether \a position is within the geometry.
* \param position Position to check in TF coordinate system
* \return true if \a position is within the bounds of this geometry.
*/
bool insideGeometry(const tgt::vec2& position) const;
/**
* Updates the helper points.
*/
void updateHelperPoints();
TFGeometry* _geometry; ///< Parent geometry of the KeyPoint to manipulate
std::vector<tgt::vec2> _helperPoints;
// event handling stuff:
bool _mousePressed; ///< Flag whether the mouse button is currently pressed
tgt::vec2 _pressedPosition; ///< Position where mousedown occured, in TF coordinates
std::vector<TFGeometry::KeyPoint> _valuesWhenPressed; ///< KeyPoints when pressed
};
}
......
// ================================================================================================
//
// 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 "algorithmicgeometry.h"
namespace TUMVis {
}
// ================================================================================================
//
// 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 GEOMETRYTOOLS_H__
#define GEOMETRYTOOLS_H__
#include "tgt/vector.h"
namespace TUMVis {
/**
* Implements various algorithms from algorithmic geometry
*/
struct AlgorithmicGeometry {
public:
/**
* Computes the orientation2D of the three points a, b, c in 2D.
* \param a First vertex
* \param b Second vertex
* \param c Third vertex
* \return Left turn: &lt; 0, collinear: = 0, right turn: &gt; 0
*/
template<typename T>
static T orientation2D(const tgt::Vector2<T>& a, const tgt::Vector2<T>& b, const tgt::Vector2<T>& c) {
return a.x * b.y + a.y * c.x + b.x * c.y - c.x * b.y - c.y * a.x - b.x * a.y;
};
/**
* Checks whether the three points are collinear.
* \param a First vertex
* \param b Second vertex
* \param c Third vertex
* \return True, when a, b, c are collinear.
*/
template<typename T>
static bool collinear2D(const tgt::Vector2<T>& a, const tgt::Vector2<T>& b, const tgt::Vector2<T>& c) {
return (orientation2D(a, b, c) == 0);
};
/**
* Checks whether the three points build a left turn.
* \param a First vertex
* \param b Second vertex
* \param c Third vertex
* \return True, when a, b, c build a left turn.
*/
template<typename T>
static bool leftTurn2D(const tgt::Vector2<T>& a, const tgt::Vector2<T>& b, const tgt::Vector2<T>& c) {
return (orientation2D(a, b, c) > 0);
};
/**
* Checks whether the three points build a right turn.
* \param a First vertex
* \param b Second vertex
* \param c Third vertex
* \return True, when a, b, c build a right turn.
*/
template<typename T>
static bool rightTurn2D(const tgt::Vector2<T>& a, const tgt::Vector2<T>& b, const tgt::Vector2<T>& c) {
return (orientation2D(a, b, c) < 0);
};
};
}
#endif // GEOMETRYTOOLS_H__
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