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 192d5803 authored by schultezub's avatar schultezub
Browse files

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