Commit 39eb232a authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge remote-tracking branch 'remotes/origin/DataInspector' into development

Conflicts:
	application/gui/datacontainerinspectorcanvas.cpp

+ some minor beautifications/fixes
parents 94e178dc e841360b
...@@ -26,3 +26,6 @@ moc_*.cxx_parameters ...@@ -26,3 +26,6 @@ moc_*.cxx_parameters
# Documentation generated by Doxygen # Documentation generated by Doxygen
/doc/html/ /doc/html/
/doc/Doxyfile /doc/Doxyfile
# TBB library in ext/
ext/tbb
...@@ -44,6 +44,10 @@ ...@@ -44,6 +44,10 @@
#include "core/properties/numericproperty.h" #include "core/properties/numericproperty.h"
#include "core/properties/transferfunctionproperty.h" #include "core/properties/transferfunctionproperty.h"
#include "core/tools/opengljobprocessor.h" #include "core/tools/opengljobprocessor.h"
#include "modules/vis/processors/geometryrenderer.h"
#include "core/eventhandlers/trackballnavigationeventlistener.h"
#include "core/datastructures/meshgeometry.h"
namespace tgt { namespace tgt {
class Shader; class Shader;
...@@ -57,6 +61,27 @@ namespace campvis { ...@@ -57,6 +61,27 @@ namespace campvis {
class DataContainerTreeWidget; class DataContainerTreeWidget;
class DataHandle; class DataHandle;
class FaceGeometry; class FaceGeometry;
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 { class DataContainerInspectorCanvas : public tgt::QtThreadedCanvas, tgt::Painter, public tgt::EventListener, public HasPropertyCollection {
Q_OBJECT; Q_OBJECT;
...@@ -77,7 +102,7 @@ namespace campvis { ...@@ -77,7 +102,7 @@ namespace campvis {
* Initializes the OpenGL stuff (e.g. shaders). * Initializes the OpenGL stuff (e.g. shaders).
* Must be called with a valid and locked OpenGL context. * Must be called with a valid and locked OpenGL context.
*/ */
virtual void init(); virtual void init(DataContainerInspectorWidget* _pWidget);
/** /**
* Deinitializes the OpenGL stuff (e.g. shaders). * Deinitializes the OpenGL stuff (e.g. shaders).
...@@ -85,7 +110,23 @@ namespace campvis { ...@@ -85,7 +110,23 @@ namespace campvis {
*/ */
void deinit(); 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); 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 * Size hint for the default window size
...@@ -108,11 +149,29 @@ namespace campvis { ...@@ -108,11 +149,29 @@ namespace campvis {
virtual void mouseDoubleClickEvent(tgt::MouseEvent* e); virtual void mouseDoubleClickEvent(tgt::MouseEvent* e);
/** /**
* Called on mouse wheel even on this canvas. * Called on mouse move event on this canvas
* \param e Mouse event arguments
*/
virtual void mouseMoveEvent(tgt::MouseEvent* e);
/**
* Called on mouse wheel event on this canvas.
* \param e Mouse event arguments * \param e Mouse event arguments
*/ */
virtual void wheelEvent(tgt::MouseEvent* e); 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. * Slot getting called when one of the observed properties changed and notifies its observers.
* \param prop Property that emitted the signal * \param prop Property that emitted the signal
...@@ -120,6 +179,7 @@ namespace campvis { ...@@ -120,6 +179,7 @@ namespace campvis {
virtual void onPropertyChanged(const AbstractProperty* prop); virtual void onPropertyChanged(const AbstractProperty* prop);
IntProperty p_currentSlice; IntProperty p_currentSlice;
IVec4Property p_meshSolidColor; ///< Color used to render the mesh object
TransferFunctionProperty p_transferFunction; ///< Transfer function TransferFunctionProperty p_transferFunction; ///< Transfer function
private slots: private slots:
...@@ -136,6 +196,11 @@ namespace campvis { ...@@ -136,6 +196,11 @@ namespace campvis {
*/ */
virtual void paint(); 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. * 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. * If \a name equals the name of the renderTarget, the s_renderTargetChanged signal will be emitted.
...@@ -150,41 +215,77 @@ namespace campvis { ...@@ -150,41 +215,77 @@ namespace campvis {
*/ */
void updateTextures(); void updateTextures();
/**
* Updates the textures vector elements that belongs to mesh geomteries.
* \note Only call with acquired lock and valid OpenGL context!!
*/
void updateMeshGeomRenderedTextures();
/** /**
* To be called when the canvas is invalidated, issues new paint job. * To be called when the canvas is invalidated, issues new paint job.
*/ */
void invalidate(); 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. * Renders the given 2D texture.
* Binds the texture to the shader, sets the uniforms and renders the quad. * 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.
* \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); 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.
*/
void drawGeomteryData(const campvis::GeometryData* meshgeometry, tgt::Texture* colorBuffer, const int& trackballIndx);
/** /**
* Creates the quad used for rendering the textures. * Creates the quad used for rendering the textures.
*/ */
void createQuad(); void createQuad();
std::map<QString, QtDataHandle> _handles; std::map<QString, QtDataHandle> _handles;
std::vector<const tgt::Texture*> _textures; std::vector<const tgt::Texture*> _textures; ///< vector of textures
bool _texturesDirty; 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
tgt::Shader* _paintShader; ///< GLSL shader for rendering the textures
FaceGeometry* _quad; ///< Quad used for rendering
DataContainer* _dataContainer; ///< The DataContainer this widget is inspecting tgt::Color _color; ///< Color under the mouse cursor
tbb::mutex _localMutex; ///< Mutex protecting the local members float _depth; ///< Depth under the mouse cursor
DataContainerInspectorWidget* _widget; ///< Pointer to the widget which has access to this canvas
tgt::Shader* _paintShader; ///< GLSL shader for rendering the textures tgt::ivec2 _numTiles; ///< number of tiles on texture overview
FaceGeometry* _quad; ///< Quad used for rendering 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
tgt::ivec2 _numTiles; ///< number of tiles on texture overview int _currentSlice; ///< current slice if rendering a 3D image fullscreen, render MIP if negative
tgt::ivec2 _quadSize; ///< size in pixels for each tile in overview
size_t _selectedTexture; ///< index of selected texture for fullscreen view
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
}; };
} }
#endif // DATACONTAINERINSPECTORCANVAS_H__ #endif // DATACONTAINERINSPECTORCANVAS_H__
\ No newline at end of file
...@@ -141,6 +141,27 @@ namespace campvis { ...@@ -141,6 +141,27 @@ namespace campvis {
_lblSize = new QLabel(tr("Size: "), _infoWidget); _lblSize = new QLabel(tr("Size: "), _infoWidget);
_infoWidgetLayout->addWidget(_lblSize); _infoWidgetLayout->addWidget(_lblSize);
_colorWidget = new QWidget(this);
_lblColorVal = new QLabel(tr("Color: n/a"), _colorWidget);
_colorValWidget = new QWidget(_colorWidget);
_colorValWidget->setAutoFillBackground(true);
_colorValWidget->setFixedSize(16, 16);
_ColorValWidgetPalette = new QPalette(palette());
_ColorValWidgetPalette->setColor(QPalette::ColorRole::Background, Qt::gray);
_colorValWidget->setPalette(*(_ColorValWidgetPalette));
_colorWidgetLayout = new QHBoxLayout();
_colorWidgetLayout->setSpacing(0);
_colorWidgetLayout->setMargin(0);
_colorWidget->setLayout(_colorWidgetLayout);
_colorWidgetLayout->addWidget(_lblColorVal);
_colorWidgetLayout->addWidget(_colorValWidget);
_infoWidgetLayout->addWidget(_colorWidget);
_lblBounds = new QLabel(tr("World Bounds:"), _infoWidget); _lblBounds = new QLabel(tr("World Bounds:"), _infoWidget);
_infoWidgetLayout->addWidget(_lblBounds); _infoWidgetLayout->addWidget(_lblBounds);
...@@ -172,6 +193,26 @@ namespace campvis { ...@@ -172,6 +193,26 @@ namespace campvis {
this, SLOT(onBtnSaveToFileClicked())); this, SLOT(onBtnSaveToFileClicked()));
} }
void DataContainerInspectorWidget::updateColor(){
const tgt::Color color = _canvas->getCapturedColor();
_lblColorVal->setText(QString("Color: R = %1 G = %2 B = %3").arg(QString::number(static_cast<int>(color.r * 255)), QString::number(static_cast<int>(color.g * 255)), QString::number(static_cast<int>(color.b * 255))));
_ColorValWidgetPalette->setColor(QPalette::ColorRole::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::ColorRole::Background, QColor(static_cast<int>(depth * 255), static_cast<int>(depth * 255), static_cast<int>(depth * 255)));
_colorValWidget->setPalette(*_ColorValWidgetPalette);
}
void DataContainerInspectorWidget::updateInfoWidget() { void DataContainerInspectorWidget::updateInfoWidget() {
if (!_inited) if (!_inited)
return; return;
...@@ -186,7 +227,6 @@ namespace campvis { ...@@ -186,7 +227,6 @@ namespace campvis {
for (QModelIndexList::const_iterator index = indices.begin(); index != indices.end(); ++index) { for (QModelIndexList::const_iterator index = indices.begin(); index != indices.end(); ++index) {
if (! index->isValid()) if (! index->isValid())
continue; continue;
// get DataHandle and Handle name // get DataHandle and Handle name
QVariant item = index->data(Qt::UserRole); QVariant item = index->data(Qt::UserRole);
QtDataHandle handle = item.value<QtDataHandle>(); QtDataHandle handle = item.value<QtDataHandle>();
...@@ -215,13 +255,14 @@ namespace campvis { ...@@ -215,13 +255,14 @@ namespace campvis {
ss.str(""); ss.str("");
ss << tester->getWorldBounds(); ss << tester->getWorldBounds();
_lblBounds->setText(tr("World Bounds: ") + QString::fromStdString(ss.str())); _lblBounds->setText(tr("World Bounds: ") + QString::fromStdString(ss.str()));
} }
else if (const GeometryData* tester = dynamic_cast<const GeometryData*>(handles.front().second.getData())) { else if (const GeometryData* tester = dynamic_cast<const GeometryData*>(handles.front().second.getData())) {
_lblSize->setText(tr("Size: n/a")); _lblSize->setText(tr("Size: n/a"));
std::ostringstream ss; std::ostringstream ss;
ss << tester->getWorldBounds(); ss << tester->getWorldBounds();
_lblBounds->setText(tr("World Bounds: ") + QString::fromStdString(ss.str())); _lblBounds->setText(tr("World Bounds: ") + QString::fromStdString(ss.str()));
} }
else if (const RenderData* tester = dynamic_cast<const RenderData*>(handles.front().second.getData())) { else if (const RenderData* tester = dynamic_cast<const RenderData*>(handles.front().second.getData())) {
const ImageData* id = tester->getNumColorTextures() > 0 ? tester->getColorTexture() : tester->getDepthTexture(); const ImageData* id = tester->getNumColorTextures() > 0 ? tester->getColorTexture() : tester->getDepthTexture();
...@@ -251,6 +292,7 @@ namespace campvis { ...@@ -251,6 +292,7 @@ namespace campvis {
} }
#endif #endif
else { else {
_lblSize->setText(tr("Size: n/a")); _lblSize->setText(tr("Size: n/a"));
_lblBounds->setText(tr("World Bounds: n/a")); _lblBounds->setText(tr("World Bounds: n/a"));
} }
...@@ -287,7 +329,7 @@ namespace campvis { ...@@ -287,7 +329,7 @@ namespace campvis {
void DataContainerInspectorWidget::init() { void DataContainerInspectorWidget::init() {
if (_canvas != 0) if (_canvas != 0)
_canvas->init(); _canvas->init(this);
_inited = true; _inited = true;
} }
......
...@@ -89,6 +89,10 @@ namespace campvis { ...@@ -89,6 +89,10 @@ namespace campvis {
*/ */
void onDataContainerDataAdded(const std::string&, const DataHandle&); void onDataContainerDataAdded(const std::string&, const DataHandle&);
void mousePressEvent(QMouseEvent*) {
updateInfoWidget();
}
/** /**
* Size hint for the default window size * Size hint for the default window size
* \return QSize(640, 480) * \return QSize(640, 480)
...@@ -107,6 +111,16 @@ namespace campvis { ...@@ -107,6 +111,16 @@ namespace campvis {
*/ */
void deinit(); void deinit();
/**
* Updates color of the info widget
*/
void updateColor();
/**
* Updates depth of the info widget
*/
void updateDepth();
signals: signals:
void dataContainerChanged(const QString&, QtDataHandle); void dataContainerChanged(const QString&, QtDataHandle);
...@@ -130,17 +144,15 @@ namespace campvis { ...@@ -130,17 +144,15 @@ namespace campvis {
*/ */
void setupGUI(); void setupGUI();
/**
* Updates _infoWidget
*/
void updateInfoWidget();
/** /**
* Saves the Image in \a handle to the file \a filename. * Saves the Image in \a handle to the file \a filename.
* \note This method must be called with a valid OpenGL context! * \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 handle DataHandle containing the image to save. Must contain ImageData or RenderData!
* \param filename Filename for the file to save. * \param filename Filename for the file to save.
*/ */
protected:
static void saveToFile(DataHandle handle, std::string filename); static void saveToFile(DataHandle handle, std::string filename);
/** /**
...@@ -150,24 +162,34 @@ namespace campvis { ...@@ -150,24 +162,34 @@ namespace campvis {
*/ */
QString humanizeBytes(size_t numBytes) const; QString humanizeBytes(size_t numBytes) const;
/**
* Updates _infoWidget
*/
void updateInfoWidget();
bool _inited; bool _inited;
DataContainer* _dataContainer; ///< The DataContainer this widget is inspecting DataContainer* _dataContainer; ///< The DataContainer this widget is inspecting
DataContainerTreeWidget* _dctWidget; ///< The TreeWidget showing the DataHandles in _dataContainer DataContainerTreeWidget* _dctWidget; ///< The TreeWidget showing the DataHandles in _dataContainer
DataContainerInspectorCanvas* _canvas; ///< The OpenGL canvas for rendering the DataContainer's contents DataContainerInspectorCanvas* _canvas; ///< The OpenGL canvas for rendering the DataContainer's contents
PropertyCollectionWidget* _pcWidget; PropertyCollectionWidget* _pcWidget;
QHBoxLayout* _mainLayout; ///< Layout for this widget QHBoxLayout* _mainLayout; ///< Layout for this widget
QWidget* _infoWidget; ///< Widget showing the information about the selected QtDataHandle QWidget* _infoWidget; ///< Widget showing the information about the selected QtDataHandle
QVBoxLayout* _infoWidgetLayout; ///< Layout for the _infoWidget QVBoxLayout* _infoWidgetLayout; ///< Layout for the _infoWidget
QLabel* _lblName; QLabel* _lblName;
QLabel* _lblLocalMemoryFootprint; QLabel* _lblLocalMemoryFootprint;
QLabel* _lblVideoMemoryFootprint; QLabel* _lblVideoMemoryFootprint;
QLabel* _lblTimestamp; QLabel* _lblTimestamp;
QLabel* _lblSize; QLabel* _lblSize;
QLabel* _lblBounds; QLabel* _lblBounds;
QWidget* _colorWidget; ///< The widget use to show the color value and the color in a single window
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
QPushButton* _btnSaveToFile; QPushButton* _btnSaveToFile;
static const std::string loggerCat_; static const std::string loggerCat_;
......
...@@ -260,7 +260,12 @@ namespace campvis { ...@@ -260,7 +260,12 @@ namespace campvis {
LGL_ERROR; LGL_ERROR;
} }
void ImageRepresentationGL::downloadTexture() const {
_texture->downloadTexture();
}
const tgt::Texture* ImageRepresentationGL::getTexture() const { const tgt::Texture* ImageRepresentationGL::getTexture() const {
return _texture; return _texture;
} }
......
...@@ -118,6 +118,12 @@ namespace campvis { ...@@ -118,6 +118,12 @@ namespace campvis {
const std::string& texUniform = "_texture", const std::string& texUniform = "_texture",
const std::string& texParamsUniform = "_textureParams") const; const std::string& texParamsUniform = "_textureParams") const;
/**
* Download the OpenGL texture from the GPU memory to the texture cpu buffer.
* \return _texture
*/
void downloadTexture() const;
/** /**
* Gets the OpenGL texture. * Gets the OpenGL texture.
* \return _texture * \return _texture
......
...@@ -124,7 +124,7 @@ namespace campvis { ...@@ -124,7 +124,7 @@ namespace campvis {
reinitializeCamera(pos, worldBounds.center(), _cameraProperty->getValue().getUpVector()); reinitializeCamera(pos, worldBounds.center(), _cameraProperty->getValue().getUpVector());
} }
} }
void TrackballNavigationEventListener::setCenter(const tgt::vec3& center) { void TrackballNavigationEventListener::setCenter(const tgt::vec3& center) {
_trackball->setCenter(center); _trackball->setCenter(center);
} }
...@@ -137,6 +137,10 @@ namespace campvis { ...@@ -137,6 +137,10 @@ namespace campvis {
return _trackball->getSceneBounds(); return _trackball->getSceneBounds();
} }
tgt::Trackball* TrackballNavigationEventListener::getTrackball() {
return _trackball;
}
void TrackballNavigationEventListener::addLqModeProcessor(VisualizationProcessor* vp) { void TrackballNavigationEventListener::addLqModeProcessor(VisualizationProcessor* vp) {
tgtAssert(vp != 0, "Pointer to processor must not be 0."); tgtAssert(vp != 0, "Pointer to processor must not be 0.");
tgtAssert(std::find(_lqModeProcessors.begin(), _lqModeProcessors.end(), vp) == _lqModeProcessors.end(), "Processor already in list of LQ mode processors."); tgtAssert(std::find(_lqModeProcessors.begin(), _lqModeProcessors.end(), vp) == _lqModeProcessors.end(), "Processor already in list of LQ mode processors.");
......
...@@ -149,6 +149,11 @@ namespace campvis { ...@@ -149,6 +149,11 @@ namespace campvis {
*/ */
const tgt::Bounds& getSceneBounds() const; const tgt::Bounds& getSceneBounds() const;