Commit 192d5803 authored by schultezub's avatar schultezub

* improved thread-safety of GeometryTransferFunctionEditor

 * stuffed a whole bunch of memory leaks

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@317 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent ddf4b0f9
......@@ -83,7 +83,20 @@ namespace TUMVis {
}
void DataContainerInspectorCanvas::deinit() {
if (_dataContainer != 0) {
_dataContainer->s_dataAdded.disconnect(this);
}
{
tbb::mutex::scoped_lock lock(_localMutex);
for (std::map<std::string, const DataHandle*>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
delete it->second;
}
}
GLJobProc.deregisterContext(this);
ShdrMgr.dispose(_paintShader);
delete _quad;
}
void DataContainerInspectorCanvas::setDataContainer(DataContainer* dataContainer) {
......
......@@ -50,6 +50,9 @@ namespace TUMVis {
}
DataContainerInspectorWidget::~DataContainerInspectorWidget() {
if (_dataContainer != 0) {
_dataContainer->s_dataAdded.disconnect(this);
}
delete _selectedDataHandle;
}
......
......@@ -56,6 +56,8 @@ namespace TUMVis {
MainWindow::~MainWindow() {
_application->s_PipelinesChanged.disconnect(this);
delete _dcInspectorCanvas;
delete _dcInspectorWidget;
}
void MainWindow::setup() {
......
......@@ -51,13 +51,13 @@ namespace TUMVis {
GeometryTransferFunctionEditor::GeometryTransferFunctionEditor(GeometryTransferFunction* tf, QWidget* parent /*= 0*/)
: AbstractTransferFunctionEditor(tf, parent)
, _selectedGeometry(0)
, _layout(0)
, _canvas(0)
, _lblIntensityLeft(0)
, _lblIntensityRight(0)
, _btnAddGeometry(0)
{
_selectedGeometry = 0;
setupGUI();
tf->s_geometryCollectionChanged.connect(this, &GeometryTransferFunctionEditor::onGeometryCollectionChanged);
updateManipulators();
......@@ -65,6 +65,17 @@ namespace TUMVis {
}
GeometryTransferFunctionEditor::~GeometryTransferFunctionEditor() {
tbb::mutex::scoped_lock lock(_localMutex);
// clear and delete former stuff
_selectedGeometry = 0;
for (std::vector<AbstractTFGeometryManipulator*>::iterator it = _manipulators.begin(); it != _manipulators.end(); ++it) {
if (WholeTFGeometryManipulator* tester = dynamic_cast<WholeTFGeometryManipulator*>(*it)) {
tester->s_selected.disconnect(this);
}
delete *it;
}
GeometryTransferFunction* gtf = static_cast<GeometryTransferFunction*>(_transferFunction);
gtf->s_geometryCollectionChanged.disconnect(this);
// TODO: this needs to be done, but we can not ensure that GLJobProc is still existant during deconstruction...
......@@ -80,6 +91,7 @@ namespace TUMVis {
void GeometryTransferFunctionEditor::paint() {
GeometryTransferFunction* gtf = static_cast<GeometryTransferFunction*>(_transferFunction);
gtf->lock();
const std::vector<TFGeometry*>& geometries = gtf->getGeometries();
const tgt::vec2& intensityDomain = gtf->getIntensityDomain();
......@@ -130,21 +142,42 @@ namespace TUMVis {
glEnd();
}
}
glPopMatrix();
glPushMatrix();
glOrtho(0, _canvas->width(), 0, _canvas->height(), -1, 1);
// render manipulators
for (std::vector<AbstractTFGeometryManipulator*>::iterator it = _manipulators.begin(); it != _manipulators.end(); ++it) {
(*it)->render();
{
tbb::mutex::scoped_lock lock(_localMutex);
// render selected geometry
if (_selectedGeometry != 0) {
const std::vector<tgt::vec2>& helperPoints = _selectedGeometry->getHelperPoints();
glColor4ub(0, 0, 0, 196);
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0xFAFA);
glBegin(GL_LINE_LOOP);
for (std::vector<tgt::vec2>::const_iterator it = helperPoints.begin(); it != helperPoints.end(); ++it)
glVertex2fv(it->elem);
glEnd();
glDisable(GL_LINE_STIPPLE);
}
glPopMatrix();
glPushMatrix();
glOrtho(0, _canvas->width(), 0, _canvas->height(), -1, 1);
// render manipulators
for (std::vector<AbstractTFGeometryManipulator*>::iterator it = _manipulators.begin(); it != _manipulators.end(); ++it) {
(*it)->render();
}
glPopMatrix();
}
glPopMatrix();
LGL_ERROR;
glPopAttrib();
gtf->unlock();
}
void GeometryTransferFunctionEditor::sizeChanged(const tgt::ivec2& size) {
tbb::mutex::scoped_lock lock(_localMutex);
for (std::vector<AbstractTFGeometryManipulator*>::iterator it = _manipulators.begin(); it != _manipulators.end(); ++it) {
(*it)->setViewportSize(size);
}
......@@ -171,6 +204,7 @@ namespace TUMVis {
}
else {
_selectedGeometry = 0;
invalidate();
e->ignore();
}
}
......@@ -220,6 +254,8 @@ namespace TUMVis {
}
void GeometryTransferFunctionEditor::updateManipulators() {
tbb::mutex::scoped_lock lock(_localMutex);
// clear and delete former stuff
_selectedGeometry = 0;
_canvas->getEventHandler()->clear();
......@@ -256,6 +292,7 @@ namespace TUMVis {
void GeometryTransferFunctionEditor::onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */) {
_selectedGeometry = wtf;
invalidate();
}
void GeometryTransferFunctionEditor::onBtnAddGeometryClicked() {
......@@ -265,18 +302,24 @@ namespace TUMVis {
void GeometryTransferFunctionEditor::onBtnRemoveGeometryClicked() {
if (_selectedGeometry != 0) {
GeometryTransferFunction* gtf = static_cast<GeometryTransferFunction*>(_transferFunction);
// to get the signal-slots disconnected in the correct order and avoid double deletion,
// this is getting a little messy and cumbersome:
GeometryTransferFunction* gtf = static_cast<GeometryTransferFunction*>(_transferFunction);
TFGeometry* geometryToRemove = _selectedGeometry->getGeometry();
for (std::vector<AbstractTFGeometryManipulator*>::iterator it = _manipulators.begin(); it != _manipulators.end(); ++it) {
if (*it == _selectedGeometry) {
_manipulators.erase(it);
break;
{
tbb::mutex::scoped_lock lock(_localMutex);
for (std::vector<AbstractTFGeometryManipulator*>::iterator it = _manipulators.begin(); it != _manipulators.end(); ++it) {
if (*it == _selectedGeometry) {
_manipulators.erase(it);
break;
}
}
delete _selectedGeometry;
_selectedGeometry = 0;
}
delete _selectedGeometry;
_selectedGeometry = 0;
gtf->removeGeometry(geometryToRemove);
}
}
......
......@@ -29,6 +29,7 @@
#ifndef GEOMETRYTRANSFERFUNCTIONEDITOR_H__
#define GEOMETRYTRANSFERFUNCTIONEDITOR_H__
#include "tbb/include/tbb/mutex.h"
#include "tgt/painter.h"
#include "tgt/event/eventlistener.h"
#include "core/classification/tfgeometry.h"
......@@ -125,7 +126,8 @@ namespace TUMVis {
void setupGUI();
std::vector<AbstractTFGeometryManipulator*> _manipulators;
WholeTFGeometryManipulator* _selectedGeometry;
tbb::atomic<WholeTFGeometryManipulator*> _selectedGeometry;
tbb::mutex _localMutex;
QGridLayout* _layout;
......
......@@ -161,6 +161,10 @@ namespace TUMVis {
return _geometry;
}
const std::vector<tgt::vec2>& WholeTFGeometryManipulator::getHelperPoints() const {
return _helperPoints;
}
void WholeTFGeometryManipulator::mousePressEvent(tgt::MouseEvent* e) {
_pressedPosition = viewportToTF(tgt::ivec2(e->coord().x, _viewportSize.y - e->coord().y));
if (insideGeometry(_pressedPosition)) {
......@@ -242,10 +246,18 @@ namespace TUMVis {
_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
......@@ -152,6 +152,12 @@ namespace TUMVis {
*/
TFGeometry* getGeometry() const;
/**
* Returns the vector caching the 2D coordinates of the TF key points.
* \return _helperPoints
*/
const std::vector<tgt::vec2>& getHelperPoints() const;
/// \see AbstractTFGeometryManipulator::render
void render();
......@@ -186,7 +192,7 @@ namespace TUMVis {
void updateHelperPoints();
TFGeometry* _geometry; ///< Parent geometry of the KeyPoint to manipulate
std::vector<tgt::vec2> _helperPoints; ///< vector chaching the 2D coordinates of the TF key points
std::vector<tgt::vec2> _helperPoints; ///< vector caching the 2D coordinates of the TF key points
// event handling stuff:
bool _mousePressed; ///< Flag whether the mouse button is currently pressed
......
......@@ -76,6 +76,8 @@ namespace TUMVis {
AbstractTransferFunction::~AbstractTransferFunction() {
if (_texture != 0)
LWARNING("Called AbstractTransferFunction dtor without proper deinitialization - you just wasted resources!");
delete _intensityHistogram;
delete _imageHandle;
}
void AbstractTransferFunction::deinit() {
......
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