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 {
}
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