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