diff --git a/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h b/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h index f45de16ade..95007119b3 100644 --- a/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h +++ b/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h @@ -1,84 +1,86 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKRENDERWINDOWVIEWDIRECTIONCONTROLLER_H #define MITKRENDERWINDOWVIEWDIRECTIONCONTROLLER_H // render window manager module #include "MitkRenderWindowManagerExports.h" #include "mitkRenderWindowLayerUtilities.h" // mitk core #include #include namespace mitk { /** * The RenderWindowViewDirectionController is used to manipulate the 'sliceNavigationController' of a given base renderer. * The 'sliceNavigationController' is used to set the view direction / camera perspective of a base renderer. * The view direction can changed to 'mitk::SliceNavigationController::Axial', 'mitk::SliceNavigationController::Frontal' * or 'mitk::SliceNavigationController::Sagittal'. * * Functions with 'mitk::BaseRenderer* renderer' have 'nullptr' as their default argument. Using the nullptr * these functions operate on all base renderer. Giving a specific base renderer will modify the node only for the given renderer. */ class MITKRENDERWINDOWMANAGER_EXPORT RenderWindowViewDirectionController { public: using ViewDirection = mitk::SliceNavigationController::ViewDirection; RenderWindowViewDirectionController(); /** * @brief Set the data storage on which to work. */ void SetDataStorage(DataStorage::Pointer dataStorage); /** * @brief Set the controlled base renderer. */ void SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer); // wrapper functions to modify the view direction /** * @brief Set the view direction for the given renderer (nullptr = all renderer) * @param viewDirection The view direction that should be used for this renderer as a string. * Currently "axial", "coronal" and "sagittal" is supported. * @param renderer Pointer to the renderer instance for which the view direction should be changed. - * If it is a nullptr (default) nothing happens. The view direction can not be changed - * for all controlled renderer at the moment. + * If it is a nullptr (default) nothing happens. */ void SetViewDirectionOfRenderer(const std::string &viewDirection, BaseRenderer* renderer = nullptr); /** * @brief Set the view direction for the given renderer (nullptr = all renderer) * @param viewDirection The view direction that should be used for this renderer. * @param renderer Pointer to the renderer instance for which the view direction should be changed. - * If it is a nullptr (default) nothing happens. The view direction can not be changed - * for all controlled renderer at the moment. + * If it is a nullptr (default) nothing happens. */ void SetViewDirectionOfRenderer(ViewDirection viewDirection, BaseRenderer* renderer = nullptr); + /** + * @brief Reinitialize the given renderer with the currently visible nodes. + * @param renderer Pointer to the renderer instance for which the view direction should be changed. + * If it is a nullptr (default) nothing happens. + */ + void InitializeViewByBoundingObjects(const BaseRenderer* renderer); private: - void InitializeViewByBoundingObjects(const BaseRenderer* renderer); - DataStorage::Pointer m_DataStorage; RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; }; } // namespace mitk #endif // MITKRENDERWINDOWVIEWDIRECTIONCONTROLLER_H diff --git a/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp b/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp index 929cc73d00..81f23c81d7 100644 --- a/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp +++ b/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp @@ -1,132 +1,132 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkRenderWindowViewDirectionController.h" // mitk #include #include #include mitk::RenderWindowViewDirectionController::RenderWindowViewDirectionController() : m_DataStorage(nullptr) { // nothing here } void mitk::RenderWindowViewDirectionController::SetDataStorage(DataStorage::Pointer dataStorage) { if (m_DataStorage != dataStorage) { // set the new data storage m_DataStorage = dataStorage; } } void mitk::RenderWindowViewDirectionController::SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer) { if (m_ControlledRenderer != controlledRenderer) { // set the new set of controlled renderer m_ControlledRenderer = controlledRenderer; } } -void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(const std::string &viewDirection, BaseRenderer* renderer /*=nullptr*/) +void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(const std::string &viewDirection, BaseRenderer* renderer/* =nullptr*/) { if (nullptr == renderer) { // set visibility of data node in all controlled renderer for (auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { SetViewDirectionOfRenderer(viewDirection, renderer); } } } else { mitk::SliceNavigationController* sliceNavigationController = renderer->GetSliceNavigationController(); if ("axial" == viewDirection) { sliceNavigationController->SetDefaultViewDirection(ViewDirection::Axial); } else if ("coronal" == viewDirection) { sliceNavigationController->SetDefaultViewDirection(ViewDirection::Frontal); } else if ("sagittal" == viewDirection) { sliceNavigationController->SetDefaultViewDirection(ViewDirection::Sagittal); } // initialize the views to the bounding geometry InitializeViewByBoundingObjects(renderer); } } -void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(ViewDirection viewDirection , BaseRenderer* renderer /*=nullptr*/) +void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(ViewDirection viewDirection , BaseRenderer* renderer/* =nullptr*/) { if (nullptr == renderer) { // set visibility of data node in all controlled renderer for (auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { SetViewDirectionOfRenderer(viewDirection, renderer); } } } else { mitk::SliceNavigationController* sliceNavigationController = renderer->GetSliceNavigationController(); sliceNavigationController->SetDefaultViewDirection(viewDirection); // initialize the views to the bounding geometry InitializeViewByBoundingObjects(renderer); } } void mitk::RenderWindowViewDirectionController::InitializeViewByBoundingObjects(const BaseRenderer* renderer) { if (nullptr == m_DataStorage || nullptr == renderer) { return; } // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateProperty::Pointer includeInBoundingBox = mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false)); mitk::NodePredicateNot::Pointer notIncludeInBoundingBox = mitk::NodePredicateNot::New(includeInBoundingBox); // get all non-helper objects mitk::NodePredicateProperty::Pointer helperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer notAHelperObject = mitk::NodePredicateNot::New(helperObject); // get all nodes that have a fixed layer for the given renderer mitk::NodePredicateProperty::Pointer fixedLayer = mitk::NodePredicateProperty::New("fixedLayer", mitk::BoolProperty::New(true), renderer); // combine node predicates mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(notIncludeInBoundingBox, notAHelperObject, fixedLayer); mitk::DataStorage::SetOfObjects::ConstPointer filteredDataNodes = m_DataStorage->GetSubset(combinedNodePredicate); // calculate bounding geometry of these nodes mitk::TimeGeometry::Pointer bounds = m_DataStorage->ComputeBoundingGeometry3D(filteredDataNodes, "visible", renderer); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeView(renderer->GetRenderWindow(), bounds); } \ No newline at end of file diff --git a/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h b/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h index e08edafbce..5b8c411351 100644 --- a/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h +++ b/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h @@ -1,108 +1,109 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITKRENDERWINDOWMANIPULATORWIDGET_H #define QMITKRENDERWINDOWMANIPULATORWIDGET_H // render window manager UI module #include "MitkRenderWindowManagerUIExports.h" #include "ui_QmitkRenderWindowManipulatorWidget.h" // render window manager module #include #include #include // qt #include /** * The QmitkRenderWindowManipulatorWidget offers a GUI to manipulate the base renderer / render windows of the MITK workbench. * The widgets supports adding a layer to an active render window, moving layers up and down, removing layers, * resetting layers (hiding them) or removing all layers at once. * * In order to use this widget, a (e.g.) plugin has to set the controlled renderer, which will be forwarded to * a render window layer controller and a render window view direction controller. * The plugin also has to provide a Q_SLOT that is connected to the 'AddLayerButtonClicked'-Q_SIGNAL of this widget. * This allows for a customized add-layer functionality. */ class MITKRENDERWINDOWMANAGERUI_EXPORT QmitkRenderWindowManipulatorWidget : public QWidget { Q_OBJECT public: QmitkRenderWindowManipulatorWidget(mitk::DataStorage::Pointer dataStorage, QWidget* parent = nullptr); /** * @brief Set the controlled base renderer. */ void SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer); /** * @brief Set the currently selected render window * * @param renderWindowId the text inside the combo box */ void SetActiveRenderWindow(const QString &renderWindowId); /** * @brief Use the RenderWindowLayerController to insert the given data node into the currently active render window. * The new node is placed on top of all existing layer nodes in that render window. * * @param dataNode The data node that should be inserted. */ void AddLayer(mitk::DataNode* dataNode); /** * @brief Use the RenderWindowLayerController to insert the given data node into all controlled render windows. * The new node is placed on top of all existing layer nodes in the render window. * * @param dataNode The data node that should be inserted. */ void AddLayerToAllRenderer(mitk::DataNode* dataNode); /** * @brief Use the RenderWindowLayerController to hide the given data node in the currently active render window. * * @param dataNode The data node that should be hid. */ void HideDataNodeInAllRenderer(const mitk::DataNode* dataNode); Q_SIGNALS: void AddLayerButtonClicked(); private Q_SLOTS: void RemoveLayer(); void SetAsBaseLayer(); void MoveLayer(const QString &direction); void ResetRenderer(); void ClearRenderer(); + void ReinitRenderer(); void ChangeViewDirection(const QString &viewDirection); private: void Init(); void SetUpConnections(); Ui::QmitkRenderWindowManipulatorWidget m_Controls; mitk::DataStorage::Pointer m_DataStorage; std::unique_ptr m_RenderWindowDataModel; std::unique_ptr m_RenderWindowLayerController; std::unique_ptr m_RenderWindowViewDirectionController; }; #endif // QMITKRENDERWINDOWMANIPULATORWIDGET_H diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp index c8ecd4bee7..c9676b2ba3 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp +++ b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp @@ -1,216 +1,222 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // render window manager UI module #include "QmitkRenderWindowManipulatorWidget.h" #include "QmitkCustomVariants.h" // mitk core #include // qt #include QmitkRenderWindowManipulatorWidget::QmitkRenderWindowManipulatorWidget(mitk::DataStorage::Pointer dataStorage, QWidget* parent /*=nullptr*/) : QWidget(parent) , m_DataStorage(dataStorage) { Init(); } void QmitkRenderWindowManipulatorWidget::Init() { // create GUI from the Qt Designer's .ui file m_Controls.setupUi(this); // initialize the render window layer controller and the render window view direction controller // and set the controller renderer (in constructor) and the data storage m_RenderWindowLayerController = std::make_unique(); m_RenderWindowViewDirectionController = std::make_unique(); m_RenderWindowLayerController->SetDataStorage(m_DataStorage); m_RenderWindowViewDirectionController->SetDataStorage(m_DataStorage); // create a new model m_RenderWindowDataModel = std::make_unique(this); m_RenderWindowDataModel->SetDataStorage(m_DataStorage); m_Controls.renderWindowTableView->setModel(m_RenderWindowDataModel.get()); m_Controls.renderWindowTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_Controls.renderWindowTableView->horizontalHeader()->setStretchLastSection(true); m_Controls.renderWindowTableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.renderWindowTableView->setSelectionMode(QAbstractItemView::SingleSelection); SetUpConnections(); } void QmitkRenderWindowManipulatorWidget::SetUpConnections() { // signal to signal connection connect(m_Controls.pushButtonAddLayer, SIGNAL(clicked()), this, SIGNAL(AddLayerButtonClicked())); connect(m_Controls.pushButtonRemoveLayer, SIGNAL(clicked()), this, SLOT(RemoveLayer())); connect(m_Controls.pushButtonSetAsBaseLayer, SIGNAL(clicked()), this, SLOT(SetAsBaseLayer())); QSignalMapper* udSignalMapper = new QSignalMapper(this); udSignalMapper->setMapping(m_Controls.pushButtonMoveUp, QString("up")); udSignalMapper->setMapping(m_Controls.pushButtonMoveDown, QString("down")); connect(udSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(MoveLayer(const QString&))); connect(m_Controls.pushButtonMoveUp, SIGNAL(clicked()), udSignalMapper, SLOT(map())); connect(m_Controls.pushButtonMoveDown, SIGNAL(clicked()), udSignalMapper, SLOT(map())); connect(m_Controls.pushButtonResetRenderer, SIGNAL(clicked()), this, SLOT(ResetRenderer())); connect(m_Controls.pushButtonClearRenderer, SIGNAL(clicked()), this, SLOT(ClearRenderer())); + connect(m_Controls.pushButtonReinitRenderer, SIGNAL(clicked()), this, SLOT(ReinitRenderer())); QSignalMapper* changeViewDirectionSignalMapper = new QSignalMapper(this); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonAxial, QString("axial")); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonCoronal, QString("coronal")); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonSagittal, QString("sagittal")); connect(changeViewDirectionSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(ChangeViewDirection(const QString&))); connect(m_Controls.radioButtonAxial, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); connect(m_Controls.radioButtonCoronal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); connect(m_Controls.radioButtonSagittal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); } void QmitkRenderWindowManipulatorWidget::SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer) { m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer); m_RenderWindowViewDirectionController->SetControlledRenderer(controlledRenderer); } void QmitkRenderWindowManipulatorWidget::SetActiveRenderWindow(const QString &renderWindowId) { std::string currentRendererName = renderWindowId.toStdString(); m_RenderWindowDataModel->SetCurrentRenderer(currentRendererName); mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(currentRendererName); if (nullptr == selectedRenderer) { return; } mitk::SliceNavigationController::ViewDirection viewDirection = selectedRenderer->GetSliceNavigationController()->GetDefaultViewDirection(); switch (viewDirection) { case mitk::SliceNavigationController::Axial: m_Controls.radioButtonAxial->setChecked(true); break; case mitk::SliceNavigationController::Frontal: m_Controls.radioButtonCoronal->setChecked(true); break; case mitk::SliceNavigationController::Sagittal: m_Controls.radioButtonSagittal->setChecked(true); break; default: break; } } void QmitkRenderWindowManipulatorWidget::AddLayer(mitk::DataNode* dataNode) { m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, m_RenderWindowDataModel->GetCurrentRenderer()); } void QmitkRenderWindowManipulatorWidget::AddLayerToAllRenderer(mitk::DataNode* dataNode) { m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, nullptr); } void QmitkRenderWindowManipulatorWidget::HideDataNodeInAllRenderer(const mitk::DataNode* dataNode) { m_RenderWindowLayerController->HideDataNodeInAllRenderer(dataNode); } void QmitkRenderWindowManipulatorWidget::RemoveLayer() { QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); if (selectedIndex.isValid()) { QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); m_RenderWindowLayerController->RemoveLayerNode(dataNode, m_RenderWindowDataModel->GetCurrentRenderer()); m_Controls.renderWindowTableView->clearSelection(); } } } void QmitkRenderWindowManipulatorWidget::SetAsBaseLayer() { QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); if (selectedIndex.isValid()) { QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); m_RenderWindowLayerController->SetBaseDataNode(dataNode, m_RenderWindowDataModel->GetCurrentRenderer()); m_Controls.renderWindowTableView->clearSelection(); } } } void QmitkRenderWindowManipulatorWidget::MoveLayer(const QString &direction) { QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); if (selectedIndex.isValid()) { QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); const mitk::BaseRenderer* selectedRenderer = m_RenderWindowDataModel->GetCurrentRenderer(); bool success = false; if ("up" == direction) { success = m_RenderWindowLayerController->MoveNodeUp(dataNode, selectedRenderer); if (success) { // node has been successfully moved up m_Controls.renderWindowTableView->selectRow(selectedIndex.row() - 1); } } else { success = m_RenderWindowLayerController->MoveNodeDown(dataNode, selectedRenderer); if (success) { // node has been successfully moved down m_Controls.renderWindowTableView->selectRow(selectedIndex.row() + 1); } } } } } void QmitkRenderWindowManipulatorWidget::ResetRenderer() { m_RenderWindowLayerController->ResetRenderer(true, m_RenderWindowDataModel->GetCurrentRenderer()); m_Controls.renderWindowTableView->clearSelection(); } void QmitkRenderWindowManipulatorWidget::ClearRenderer() { m_RenderWindowLayerController->ResetRenderer(false, m_RenderWindowDataModel->GetCurrentRenderer()); m_Controls.renderWindowTableView->clearSelection(); } +void QmitkRenderWindowManipulatorWidget::ReinitRenderer() +{ + m_RenderWindowViewDirectionController->InitializeViewByBoundingObjects(m_RenderWindowDataModel->GetCurrentRenderer()); +} + void QmitkRenderWindowManipulatorWidget::ChangeViewDirection(const QString &viewDirection) { m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), m_RenderWindowDataModel->GetCurrentRenderer()); } diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui index 01e6a1b05f..c200ea241d 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui +++ b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui @@ -1,120 +1,127 @@ QmitkRenderWindowManipulatorWidget 0 0 308 246 0 0 0 0 Render window manager Render window overview Add Layer Remove layer Set as base layer - + Move up Move down Reset render window Clear render window + + + + + Reinit render window + + Axial true Coronal Sagittal