Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

Commit 4229330a authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Large refactorings in DataContainerInspectorWidget and DataContainerInspectorCanvas:

* DataContainerInspectorCanvas uses the GeometryRenderer processor to render geometry
* DataContainerInspectorCanvas::_textures now uses DataHandle to improve thread safety avoid segfaults
* replaced some function calls with Qt signals to loose coupling
* removed obsolete fields and methods

refs #546
parent bf30ff15
......@@ -35,14 +35,16 @@
#include "application/gui/qtdatahandle.h"
#include "core/properties/propertycollection.h"
#include "core/properties/metaproperty.h"
#include "core/properties/numericproperty.h"
#include "core/properties/propertycollection.h"
#include "core/properties/transferfunctionproperty.h"
#include "core/tools/opengljobprocessor.h"
#include "core/eventhandlers/trackballnavigationeventlistener.h"
#include "modules/base/processors/lightsourceprovider.h"
#include "modules/vis/processors/geometryrenderer.h"
#include "core/eventhandlers/trackballnavigationeventlistener.h"
#include "core/datastructures/meshgeometry.h"
namespace tgt {
class Shader;
......@@ -56,28 +58,9 @@ namespace campvis {
class DataContainerTreeWidget;
class DataHandle;
class FaceGeometry;
class GeometryData;
class DataContainerInspectorWidget;
/**
* Stores information about the textures which store the rendered geomtery.
* Note: The object's destroy() function should be called before deleting or releasing the object's memory.
*/
struct GeometryTextureInfo {
campvis::QtDataHandle _geomData;
tgt::Texture* _texture;
int _trackballIndx;
GeometryTextureInfo(): _geomData(0), _texture(0) {
}
void destroy() {
delete _texture;
}
~GeometryTextureInfo() {
}
};
class DataContainerInspectorCanvas : public tgt::QtThreadedCanvas, tgt::Painter, public tgt::EventListener, public HasPropertyCollection {
Q_OBJECT;
......@@ -97,7 +80,7 @@ namespace campvis {
* Initializes the OpenGL stuff (e.g. shaders).
* Must be called with a valid and locked OpenGL context.
*/
virtual void init(DataContainerInspectorWidget* _pWidget);
virtual void init();
/**
* Deinitializes the OpenGL stuff (e.g. shaders).
......@@ -105,23 +88,7 @@ namespace campvis {
*/
void deinit();
/**
* Reset the content of the canvas.
* It will clear the array of textures, rendered geomteries, color buffers, depth buffers and its content.
*/
void resetContent();
void setDataHandles(const std::vector< std::pair<QString, QtDataHandle> >& handles);
/**
* returns the color value which is captured with the mouse.
*/
const tgt::Color& getCapturedColor();
/**
* returns the depth value which is captured with the mouse.
*/
const float& getCapturedDepth();
/**
* Size hint for the default window size
......@@ -129,6 +96,8 @@ namespace campvis {
*/
QSize sizeHint() const;
QSize minimumSizeHint() const { return QSize(320, 320); }
/**
* Schedule a repaint job for the inspector's render target
*/
......@@ -155,26 +124,7 @@ namespace campvis {
*/
virtual void wheelEvent(tgt::MouseEvent* e);
/**
* Called on mouse press button event on this canvas.
* \param e Mouse event arguments
*/
virtual void mousePressEvent(tgt::MouseEvent* e);
/**
* Called on mouse release button event on this canvas.
* \param e Mouse event arguments
*/
virtual void mouseReleaseEvent(tgt::MouseEvent* e);
/**
* Slot getting called when one of the observed properties changed and notifies its observers.
* \param prop Property that emitted the signal
*/
virtual void onPropertyChanged(const AbstractProperty* prop);
IntProperty p_currentSlice;
Vec4Property p_meshSolidColor; ///< Color used to render the mesh object
TransferFunctionProperty p_transferFunction; ///< Transfer function
BoolProperty p_renderRChannel; /// Flag whether to render Red channel
......@@ -182,6 +132,12 @@ namespace campvis {
BoolProperty p_renderBChannel; /// Flag whether to render Blue channel
BoolProperty p_renderAChannel; /// Flag whether to render Alpha channel
MetaProperty p_geometryRendererProperties;
signals:
void s_colorChanged(const tgt::vec4&);
void s_depthChanged(float depth);
private slots:
/**
* Slot being called when a QtDataHandle has been added to the DataContainer.
......@@ -196,11 +152,6 @@ namespace campvis {
*/
virtual void paint();
/**
* Performs the painting.
*/
virtual void paintMeshGeomTextures();
/**
* Gets called when the data collection of this pipeline has changed and thus has notified its observers.
* If \a name equals the name of the renderTarget, the s_renderTargetChanged signal will be emitted.
......@@ -208,47 +159,40 @@ namespace campvis {
* \param dh DataHandle to the newly added data.
*/
void onDataContainerDataAdded(const std::string& name, const DataHandle& dh);
/**
* Updates the textures vector.
* \note Only call with acquired lock and valid OpenGL context!!
* Slot getting called when one of the observed properties changed and notifies its observers.
* \param prop Property that emitted the signal
*/
void updateTextures();
virtual void onPropertyChanged(const AbstractProperty* prop);
virtual void onGeometryRendererPropertyChanged(const AbstractProperty* prop);
/**
* Updates the textures vector elements that belongs to mesh geomteries.
* Updates the textures vector.
* \note Only call with acquired lock and valid OpenGL context!!
*/
void updateMeshGeomRenderedTextures();
void updateTextures();
/**
* To be called when the canvas is invalidated, issues new paint job.
*/
void invalidate();
/**
* To be called when the mesh geometry parts of the scene is invalidated, issues new paint job only for textures that belong to mesh geomteries.
*/
void invalidateMeshGeomTextures();
/**
* Renders the given 2D texture.
* Binds the texture to the shader, sets the uniforms and renders the quad.
* \param texture The texture to render.
* \param texture The texture to render. Must not be 0.
* \param uint2d The texture unit that will be attached to rendering pipeline (2D for 2D textures).
* \param uint2d The texture unit that will be attached to rendering pipeline (3D for 3D textures).
*/
void paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d);
/**
* Renders the Meshgeometry into the geometry renderer color buffer and depth buffer.
* Binds the texture to the shader, sets the uniforms and renders the mesh geometry.
* \param meshgeometry The mesh to be rendered.
* \param colorBuffer The color buffer that the object will be rendered to.
* \param depthBuffer The depth buffer that the object will be rendered to.
* \param meshIndex The index of the rendered mesh in the texture array.
* Renders \a geometry into a texture.
*
* \param name
* \param geometry
*/
void drawGeomteryData(const campvis::GeometryData* meshgeometry, tgt::Texture* colorBuffer, const int& trackballIndx);
void renderGeometryIntoTexture(const std::string& name, const GeometryData* geometry);
/**
* Creates the quad used for rendering the textures.
......@@ -256,9 +200,12 @@ namespace campvis {
void createQuad();
std::map<QString, QtDataHandle> _handles;
std::vector<const tgt::Texture*> _textures; ///< vector of textures
/// Vector of textures to render. Each DataHandle contains an ImageData that has an OpenGL representation.
/// This ensures thread safety.
std::vector<QtDataHandle> _textures;
bool _texturesDirty; ///< Flag that shows that the textures need update or not.
bool _meshGeomTexturesDirty; ///< Flag that shows that the mesh geometry textures need updare or not.
DataContainer* _dataContainer; ///< The DataContainer this widget is inspecting
tbb::mutex _localMutex; ///< Mutex protecting the local members
......@@ -266,25 +213,18 @@ namespace campvis {
tgt::Shader* _paintShader; ///< GLSL shader for rendering the textures
FaceGeometry* _quad; ///< Quad used for rendering
tgt::Color _color; ///< Color under the mouse cursor
float _depth; ///< Depth under the mouse cursor
DataContainerInspectorWidget* _widget; ///< Pointer to the widget which has access to this canvas
tgt::ivec2 _numTiles; ///< number of tiles on texture overview
tgt::ivec2 _quadSize; ///< size in pixels for each tile in overview
size_t _selectedTexture; ///< index of selected texture by mouse
int _selectedTrackball; ///< index of selected trackball which will be updated currently
bool _renderFullscreen; ///< flag whether to render in full screen
int _currentSlice; ///< current slice if rendering a 3D image fullscreen, render MIP if negative
tgt::Shader* _geometryRenderingShader; ///< GLSL shader for rendering the mesh geomteries
tgt::FramebufferObject* _frameBuffer;
tgt::Texture* _depthBuffer;
std::vector<campvis::CameraProperty*> _trackballCameraProperties; ///< The property of the trackball camera. Used to pass the trackball camera to the shader.
std::vector<TrackballNavigationEventListener*> _trackballEHs; ///< TrackBall Event Handler for the camera rotating around the object in the canvas
std::vector<GeometryTextureInfo> _geomTextureInfos; ///< Array of data regarding the rendered geomteries
DataContainer _localDataContainer; ///< Local DataContainer the GeometryRenderer works on
IVec2Property p_viewportSize;
CameraProperty p_camera;
GeometryRenderer _geometryRenderer; ///< GeometryRenderer used to render geometries
TrackballNavigationEventListener* _trackballEH;
};
}
......
......@@ -55,6 +55,7 @@
#include "modules/io/processors/genericimagereader.h"
#include <QFileDialog>
#include <QScrollArea>
namespace campvis {
......@@ -81,7 +82,6 @@ namespace campvis {
, _colorWidgetLayout(0)
, _lblColorVal(0)
, _colorValWidget(0)
, _ColorValWidgetPalette(0)
, _btnLoadFile(0)
, _btnSaveToFile(0)
, _propEditorWid(0)
......@@ -183,9 +183,9 @@ namespace campvis {
_colorValWidget->setAutoFillBackground(true);
_colorValWidget->setFixedSize(16, 16);
_ColorValWidgetPalette = new QPalette(palette());
_ColorValWidgetPalette->setColor(QPalette::Background, Qt::gray);
_colorValWidget->setPalette(*(_ColorValWidgetPalette));
_colorValWidgetPalette = QPalette(palette());
_colorValWidgetPalette.setColor(QPalette::Background, Qt::gray);
_colorValWidget->setPalette(_colorValWidgetPalette);
_colorWidgetLayout = new QHBoxLayout();
_colorWidgetLayout->setSpacing(0);
......@@ -201,19 +201,33 @@ namespace campvis {
_canvas->setMinimumSize(QSize(100, 100));
_infoWidgetLayout->addWidget(_canvas, 5, 0, 1, 2);
_pcWidget = new PropertyCollectionWidget(_infoWidget);
QScrollArea* _pipelinePropertiesScrollArea = new QScrollArea(_infoWidget);
_pipelinePropertiesScrollArea->setWidgetResizable(true);
_pipelinePropertiesScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
_pipelinePropertiesScrollArea->setFrameStyle(QScrollArea::NoFrame);
_pcWidget = new PropertyCollectionWidget(_pipelinePropertiesScrollArea);
_pcWidget->updatePropCollection(_canvas, _dataContainer);
_infoWidgetLayout->addWidget(_pcWidget, 6, 0, 1, 2);
_pipelinePropertiesScrollArea->setWidget(_pcWidget);
_infoWidgetLayout->addWidget(_pipelinePropertiesScrollArea, 6, 0, 1, 2);
_mainLayout->addWidget(_infoWidget, 0, 1, 3, 1);
qRegisterMetaType<QtDataHandle>("QtDataHandle");
qRegisterMetaType<tgt::vec4>("tgt_vec4");
connect(
_dctWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
this, SLOT(onDCTWidgetSelectionModelSelectionChanged(const QItemSelection&, const QItemSelection&)));
connect(
this, SIGNAL(dataContainerChanged(const QString&, QtDataHandle)),
_canvas, SLOT(onDataContainerChanged(const QString&, QtDataHandle)));
connect(
_canvas, SIGNAL(s_colorChanged(const tgt::vec4&)),
this, SLOT(onColorChanged(const tgt::vec4&)));
connect(
_canvas, SIGNAL(s_depthChanged(float)),
this, SLOT(onDepthChanged(float)));
connect(
this, SIGNAL(dataContainerChanged(const QString&, QtDataHandle)),
_dctWidget->getTreeModel(), SLOT(onDataContainerChanged(const QString&, QtDataHandle)));
......@@ -222,26 +236,6 @@ namespace campvis {
this, SLOT(onBtnLoadFileClicked()));
}
void DataContainerInspectorWidget::updateColor(){
const tgt::Color& color = _canvas->getCapturedColor();
_lblColorVal->setText(QString("Color: [%1, %2, %3, %4]").arg(QString::number(color.r), QString::number(color.g), QString::number(color.b), QString::number(color.a)));
_ColorValWidgetPalette->setColor(QPalette::Background, QColor(static_cast<int>(color.r * 255), static_cast<int>(color.g * 255), static_cast<int>(color.b * 255)));
_colorValWidget->setPalette(*_ColorValWidgetPalette);
}
void DataContainerInspectorWidget::updateDepth(){
float depth = _canvas->getCapturedDepth();
_lblColorVal->setText(QString("Depth: %1").arg(QString::number(depth)));
_ColorValWidgetPalette->setColor(QPalette::Background, QColor(static_cast<int>(depth * 255), static_cast<int>(depth * 255), static_cast<int>(depth * 255)));
_colorValWidget->setPalette(*_ColorValWidgetPalette);
}
void DataContainerInspectorWidget::updateInfoWidget() {
if (!_inited)
return;
......@@ -290,11 +284,11 @@ namespace campvis {
_canvas->p_currentSlice.setVisible(tester->getDimensionality() == 3);
_canvas->p_transferFunction.setVisible(true);
_canvas->p_meshSolidColor.setVisible(false);
_canvas->p_renderRChannel.setVisible(true);
_canvas->p_renderGChannel.setVisible(true);
_canvas->p_renderBChannel.setVisible(true);
_canvas->p_renderAChannel.setVisible(true);
_canvas->p_geometryRendererProperties.setVisible(false);
}
else if (const GeometryData* tester = dynamic_cast<const GeometryData*>(handles.front().second.getData())) {
_lblSize->setText(tr("Size: n/a"));
......@@ -306,11 +300,11 @@ namespace campvis {
_canvas->p_currentSlice.setVisible(false);
_canvas->p_transferFunction.setVisible(false);
_canvas->p_meshSolidColor.setVisible(true);
_canvas->p_renderRChannel.setVisible(false);
_canvas->p_renderGChannel.setVisible(false);
_canvas->p_renderBChannel.setVisible(false);
_canvas->p_renderAChannel.setVisible(false);
_canvas->p_geometryRendererProperties.setVisible(true);
}
else if (const RenderData* tester = dynamic_cast<const RenderData*>(handles.front().second.getData())) {
const ImageData* id = tester->getNumColorTextures() > 0 ? tester->getColorTexture() : tester->getDepthTexture();
......@@ -333,11 +327,11 @@ namespace campvis {
_canvas->p_currentSlice.setVisible(false);
_canvas->p_transferFunction.setVisible(true);
_canvas->p_meshSolidColor.setVisible(false);
_canvas->p_renderRChannel.setVisible(true);
_canvas->p_renderGChannel.setVisible(true);
_canvas->p_renderBChannel.setVisible(true);
_canvas->p_renderAChannel.setVisible(true);
_canvas->p_geometryRendererProperties.setVisible(false);
}
#ifdef CAMPVIS_HAS_MODULE_COLUMBIA
else if (const FiberData* tester = dynamic_cast<const FiberData*>(handles.front().second.getData())) {
......@@ -389,7 +383,7 @@ namespace campvis {
void DataContainerInspectorWidget::init() {
if (_canvas != 0)
_canvas->init(this);
_canvas->init();
_inited = true;
}
......@@ -533,4 +527,20 @@ namespace campvis {
}
void DataContainerInspectorWidget::onColorChanged(const tgt::vec4& color) {
_lblColorVal->setText(QString("Color: [%1, %2, %3, %4]").arg(QString::number(color.r), QString::number(color.g), QString::number(color.b), QString::number(color.a)));
tgt::ivec4 clamped(tgt::clamp(color * 255.f, 0.f, 255.f));
_colorValWidgetPalette.setColor(QPalette::Background, QColor(clamped.r, clamped.g, clamped.b, clamped.a));
_colorValWidget->setPalette(_colorValWidgetPalette);
}
void DataContainerInspectorWidget::onDepthChanged(float depth) {
_lblColorVal->setText(QString("Depth: %1").arg(QString::number(depth)));
tgt::ivec4 clamped(tgt::clamp(depth * 255.f, 0.f, 255.f));
_colorValWidgetPalette.setColor(QPalette::Background, QColor(clamped.r, clamped.g, clamped.b, clamped.a));
_colorValWidget->setPalette(_colorValWidgetPalette);
}
}
\ No newline at end of file
......@@ -89,10 +89,6 @@ namespace campvis {
*/
void onDataContainerDataAdded(const std::string&, const DataHandle&);
void mousePressEvent(QMouseEvent*) {
updateInfoWidget();
}
/**
* Size hint for the default window size
* \return QSize(640, 480)
......@@ -111,16 +107,6 @@ namespace campvis {
*/
void deinit();
/**
* Updates color of the info widget
*/
void updateColor();
/**
* Updates depth of the info widget
*/
void updateDepth();
signals:
void dataContainerChanged(const QString&, QtDataHandle);
......@@ -138,26 +124,22 @@ namespace campvis {
*/
void onBtnSaveToFileClicked();
/**
* Slot being called when the user clicks on the "Load File" button.
*/
void onBtnLoadFileClicked();
/// Slot being called when the color under the mouse has changed
void onColorChanged(const tgt::vec4& color);
/// Slot being called when the depth under the mouse has changed
void onDepthChanged(float depth);
protected:
/**
* Setup the GUI stuff
*/
void setupGUI();
/**
* Saves the Image in \a handle to the file \a filename.
* \note This method must be called with a valid OpenGL context!
* \param handle DataHandle containing the image to save. Must contain ImageData or RenderData!
* \param filename Filename for the file to save.
*/
protected:
static void saveToFile(DataHandle handle, std::string filename);
......@@ -196,7 +178,7 @@ namespace campvis {
QHBoxLayout* _colorWidgetLayout; ///< Layout for the following widget
QLabel* _lblColorVal; ///< Color Label Value in text
QWidget* _colorValWidget; ///< Widget that shows the color value in color
QPalette* _ColorValWidgetPalette; ///< Palette which will be used to colorize the color widget
QPalette _colorValWidgetPalette; ///< Palette which will be used to colorize the color widget
// Added by Hossain Mahmud <mahmud@in.tum.de>
// Date: January 02, 2014
......
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