diff --git a/Modules/QtWidgets/include/QmitkRenderWindowContextDataStorageInspector.h b/Modules/QtWidgets/include/QmitkRenderWindowContextDataStorageInspector.h index 5f07548423..00a5e77477 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindowContextDataStorageInspector.h +++ b/Modules/QtWidgets/include/QmitkRenderWindowContextDataStorageInspector.h @@ -1,91 +1,90 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKRENDERWINDOWCONTEXTDATASTORAGEINSPECTOR_H #define QMITKRENDERWINDOWCONTEXTDATASTORAGEINSPECTOR_H // qt widgets module #include "MitkQtWidgetsExports.h" #include "ui_QmitkRenderWindowContextDataStorageInspector.h" // render window manager module #include #include // qt widgets module #include // mitk core #include /** * The 'QmitkRenderWindowContextDataStorageInspector' offers a GUI to manipulate the base renderer / render windows of the MITK workbench. * * In order to use this widget, a (e.g.) plugin has to set the controlled renderer, which will be forwarded to * a render window view direction controller. */ class MITKQTWIDGETS_EXPORT QmitkRenderWindowContextDataStorageInspector : public QmitkAbstractDataStorageInspector { Q_OBJECT public: QmitkRenderWindowContextDataStorageInspector(QWidget* parent = nullptr, mitk::BaseRenderer* renderer = nullptr); // override from 'QmitkAbstractDataStorageInspector' /** * @brief See 'QmitkAbstractDataStorageInspector' */ QAbstractItemView* GetView() override; /** * @brief See 'QmitkAbstractDataStorageInspector' */ const QAbstractItemView* GetView() const override; /** * @brief See 'QmitkAbstractDataStorageInspector' */ void SetSelectionMode(SelectionMode mode) override; /** * @brief See 'QmitkAbstractDataStorageInspector' */ SelectionMode GetSelectionMode() const override; QItemSelectionModel* GetDataNodeSelectionModel() const; Q_SIGNALS: void ReinitAction(QList selectedNodes); void ResetAction(QList selectedNodes); private Q_SLOTS: void ModelRowsInserted(const QModelIndex& parent, int start, int end); void ResetRenderer(); void OnContextMenuRequested(const QPoint& pos); void OnReinit(); void OnReset(); private: void Initialize() override; void SetUpConnections(); - QList GetSelectedNodes(); Ui::QmitkRenderWindowContextDataStorageInspector m_Controls; std::unique_ptr m_StorageModel; std::unique_ptr m_RenderWindowLayerController; }; #endif // QMITKRENDERWINDOWCONTEXTDATASTORAGEINSPECTOR_H diff --git a/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h b/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h index 914c9007a5..637300f3aa 100644 --- a/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h +++ b/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h @@ -1,75 +1,77 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKRENDERWINDOWLAYERUTILITIES_H #define MITKRENDERWINDOWLAYERUTILITIES_H // qt widgets module #include "MitkQtWidgetsExports.h" // mitk core #include #include #include -#include +#include /** * @brief Render window layer helper functions to retrieve the currently valid layer stack */ namespace mitk { namespace RenderWindowLayerUtilities { typedef std::vector RendererVector; typedef std::map> LayerStack; /** * The base data node of a renderer is supposed to be on layer 0 (zero), which should be the lowest layer in a render window. */ const int BASE_LAYER_INDEX = 0; /** * The top layer index, denoting that no valid (positive) layer index is given and therefore the index should be resolved into the topmost layer index. */ const int TOP_LAYER_INDEX = -1; /** * @brief Return the stack of layers of the given renderer as std::map, which guarantees ordering of the layers. * Stacked layers are only included if they have their "fixedLayer" property set to true and their "layer" property set. * * If "renderer" = nullptr: a layer stack won't be created and an empty "LayerStack" will be returned. * If "withBaseNode" = true: include the base node in the layer stack, if existing. * If "withBaseNode" = false: exclude the base node from the layer stack. * * @param dataStorage Pointer to a data storage instance whose data nodes should be checked and possibly be included. * @param renderer Pointer to the renderer instance for which the layer stack should be generated. * @param withBaseNode Boolean to decide whether the base node should be included in or excluded from the layer stack. */ MITKQTWIDGETS_EXPORT LayerStack GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer, bool withBaseNode); /** * @brief Helper function to get a node predicate that can be used to filter render window specific data nodes. + * The data nodes must have set a 'fixed layer' property for the given renderer. * - * The data nodes must not be 'helper objects'. The must have set a 'fixed layer' property for the given renderer. + * @param renderer Pointer to the renderer instance for which the 'fixed layer' should be true. + * @return The node predicate to filter 'fixed layer' data nodes. */ - MITKQTWIDGETS_EXPORT NodePredicateAnd::Pointer GetRenderWindowPredicate(const BaseRenderer* renderer); + MITKQTWIDGETS_EXPORT NodePredicateBase::Pointer GetRenderWindowPredicate(const BaseRenderer* renderer); /** * @brief Set renderer-specific properties to mark a data node as 'managed by the specific renderer'. * In order for a renderer to manage a data node, the 'fixedLayer' property has to be set for the given renderer. * Additionally, the 'visible' and the 'layer' property are set and allow to individually render a set of nodes * with a specific renderer. * The last two mentioned properties are set so that they initially have the same value as the corresponding * global property. */ MITKQTWIDGETS_EXPORT void SetRenderWindowProperties(mitk::DataNode* dataNode, const BaseRenderer* renderer); } // namespace RenderWindowLayerUtilities } // namespace mitk #endif // MITKRENDERWINDOWLAYERUTILITIES_H diff --git a/Modules/QtWidgets/src/QmitkRenderWindowContextDataStorageInspector.cpp b/Modules/QtWidgets/src/QmitkRenderWindowContextDataStorageInspector.cpp index 3758aaaa10..7cfa9f9099 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindowContextDataStorageInspector.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindowContextDataStorageInspector.cpp @@ -1,157 +1,146 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager UI module #include "QmitkRenderWindowContextDataStorageInspector.h" #include #include +#include +#include +#include + // qt #include #include QmitkRenderWindowContextDataStorageInspector::QmitkRenderWindowContextDataStorageInspector( QWidget* parent /* =nullptr */, mitk::BaseRenderer* renderer /* = nullptr */) : QmitkAbstractDataStorageInspector(parent) { m_Controls.setupUi(this); mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer{ renderer }; // initialize the render window layer controller and the render window view direction controller m_RenderWindowLayerController = std::make_unique(); m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer); m_StorageModel = std::make_unique(this); m_StorageModel->SetControlledRenderer(controlledRenderer); m_Controls.renderWindowTreeView->setModel(m_StorageModel.get()); m_Controls.renderWindowTreeView->setHeaderHidden(true); m_Controls.renderWindowTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_Controls.renderWindowTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.renderWindowTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.renderWindowTreeView->setAlternatingRowColors(true); m_Controls.renderWindowTreeView->setDragEnabled(true); m_Controls.renderWindowTreeView->setDropIndicatorShown(true); m_Controls.renderWindowTreeView->setAcceptDrops(true); m_Controls.renderWindowTreeView->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_Controls.renderWindowTreeView, &QTreeView::customContextMenuRequested, this, &QmitkRenderWindowContextDataStorageInspector::OnContextMenuRequested); SetUpConnections(); if (nullptr == renderer) { return; } m_StorageModel->SetCurrentRenderer(renderer); } QAbstractItemView* QmitkRenderWindowContextDataStorageInspector::GetView() { return m_Controls.renderWindowTreeView; } const QAbstractItemView* QmitkRenderWindowContextDataStorageInspector::GetView() const { return m_Controls.renderWindowTreeView; } void QmitkRenderWindowContextDataStorageInspector::SetSelectionMode(SelectionMode mode) { m_Controls.renderWindowTreeView->setSelectionMode(mode); } QmitkRenderWindowContextDataStorageInspector::SelectionMode QmitkRenderWindowContextDataStorageInspector::GetSelectionMode() const { return m_Controls.renderWindowTreeView->selectionMode(); } QItemSelectionModel* QmitkRenderWindowContextDataStorageInspector::GetDataNodeSelectionModel() const { return m_Controls.renderWindowTreeView->selectionModel(); } void QmitkRenderWindowContextDataStorageInspector::Initialize() { auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNull()) return; m_StorageModel->SetDataStorage(dataStorage); - m_StorageModel->SetNodePredicate(m_NodePredicate); + + mitk::NodePredicateAnd::Pointer noHelperObjects = mitk::NodePredicateAnd::New(); + noHelperObjects->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); + noHelperObjects->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); + m_StorageModel->SetNodePredicate(noHelperObjects); m_RenderWindowLayerController->SetDataStorage(dataStorage); m_Connector->SetView(m_Controls.renderWindowTreeView); } void QmitkRenderWindowContextDataStorageInspector::SetUpConnections() { connect(m_StorageModel.get(), &QAbstractItemModel::rowsInserted, this, &QmitkRenderWindowContextDataStorageInspector::ModelRowsInserted); } void QmitkRenderWindowContextDataStorageInspector::ModelRowsInserted(const QModelIndex& parent, int /*start*/, int /*end*/) { m_Controls.renderWindowTreeView->setExpanded(parent, true); } void QmitkRenderWindowContextDataStorageInspector::ResetRenderer() { m_RenderWindowLayerController->ResetRenderer(true, m_StorageModel->GetCurrentRenderer()); m_Controls.renderWindowTreeView->clearSelection(); } void QmitkRenderWindowContextDataStorageInspector::OnContextMenuRequested(const QPoint& pos) { QMenu contextMenu; contextMenu.addAction(tr("Reinit with node"), this, &QmitkRenderWindowContextDataStorageInspector::OnReinit); contextMenu.addAction(tr("Reset to node geometry"), this, &QmitkRenderWindowContextDataStorageInspector::OnReset); contextMenu.exec(this->mapToGlobal(pos)); } void QmitkRenderWindowContextDataStorageInspector::OnReinit() { auto nodes = this->GetSelectedNodes(); emit ReinitAction(nodes); } void QmitkRenderWindowContextDataStorageInspector::OnReset() { auto nodes = this->GetSelectedNodes(); emit ResetAction(nodes); } - -QList QmitkRenderWindowContextDataStorageInspector::GetSelectedNodes() -{ - auto baseRenderer = m_StorageModel->GetCurrentRenderer(); - - QList nodes; - QModelIndexList selectedIndexes = this->GetDataNodeSelectionModel()->selectedIndexes(); - for (const auto& index : qAsConst(selectedIndexes)) - { - QVariant qvariantDataNode = m_StorageModel->data(index, QmitkDataNodeRole); - if (qvariantDataNode.canConvert()) - { - mitk::DataNode* dataNode = qvariantDataNode.value(); - nodes.insert(nodes.size(), dataNode); - } - } - - return nodes; -} diff --git a/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp b/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp index a97f95f694..3d761af13c 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp @@ -1,607 +1,628 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager UI module #include "QmitkRenderWindowDataStorageTreeModel.h" -// mitk core #include +// mitk core +#include + // qt widgets module #include "QmitkCustomVariants.h" #include "QmitkEnums.h" #include "QmitkMimeTypes.h" #include "QmitkNodeDescriptorManager.h" QmitkRenderWindowDataStorageTreeModel::QmitkRenderWindowDataStorageTreeModel(QObject* parent /*= nullptr*/) : QmitkAbstractDataStorageModel(parent) , m_Root(nullptr) { m_RenderWindowLayerController = std::make_unique(); ResetTree(); } void QmitkRenderWindowDataStorageTreeModel::DataStorageChanged() { m_RenderWindowLayerController->SetDataStorage(m_DataStorage.Lock()); ResetTree(); UpdateModelData(); } void QmitkRenderWindowDataStorageTreeModel::NodePredicateChanged() { ResetTree(); UpdateModelData(); } void QmitkRenderWindowDataStorageTreeModel::NodeAdded(const mitk::DataNode* node) { for (const auto renderer : m_ControlledRenderer) { // add the node to each render window mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(const_cast(node), renderer); } auto baseRenderer = m_BaseRenderer.Lock(); - if (baseRenderer.IsNotNull()) + if (baseRenderer.IsNull()) + { + return; + } + + mitk::NodePredicateBase::Pointer renderWindowPredicate = mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(baseRenderer); + mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(); + combinedNodePredicate->AddPredicate(renderWindowPredicate); + if (m_NodePredicate.IsNotNull()) + { + combinedNodePredicate->AddPredicate(m_NodePredicate); + } + if (combinedNodePredicate->CheckNode(node)) { AddNodeInternal(node, baseRenderer); } } void QmitkRenderWindowDataStorageTreeModel::NodeChanged(const mitk::DataNode* node) { auto item = m_Root->Find(node); if (nullptr != item) { auto parentItem = item->GetParent(); // as the root node should not be removed one should always have a parent item if (nullptr == parentItem) { return; } auto index = createIndex(item->GetIndex(), 0, item); emit dataChanged(index, index); } } void QmitkRenderWindowDataStorageTreeModel::NodeRemoved(const mitk::DataNode* node) { RemoveNodeInternal(node); } QModelIndex QmitkRenderWindowDataStorageTreeModel::index(int row, int column, const QModelIndex& parent) const { auto item = GetItemByIndex(parent); if (nullptr != item) { item = item->GetChild(row); } if (nullptr == item) { return QModelIndex(); } return createIndex(row, column, item); } QModelIndex QmitkRenderWindowDataStorageTreeModel::parent(const QModelIndex& parent) const { auto item = GetItemByIndex(parent); if (nullptr != item) { item = item->GetParent(); } if(nullptr == item) { return QModelIndex(); } if (item == m_Root) { return QModelIndex(); } return createIndex(item->GetIndex(), 0, item); } int QmitkRenderWindowDataStorageTreeModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const { auto item = GetItemByIndex(parent); if (nullptr == item) { return 0; } return item->GetChildCount(); } int QmitkRenderWindowDataStorageTreeModel::columnCount(const QModelIndex&/* parent = QModelIndex()*/) const { if (0 == m_Root->GetChildCount()) { // no items stored, no need to display columns return 0; } return 1; } QVariant QmitkRenderWindowDataStorageTreeModel::data(const QModelIndex& index, int role) const { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return QVariant(); } if (!index.isValid() || this != index.model()) { return QVariant(); } auto item = GetItemByIndex(index); if (nullptr == item) { return QVariant(); } auto dataNode = item->GetDataNode(); if (nullptr == dataNode) { return QVariant(); } if (Qt::CheckStateRole == role) { bool visibility = false; dataNode->GetVisibility(visibility, baseRenderer); if (visibility) { return Qt::Checked; } else { return Qt::Unchecked; } } else if (Qt::DisplayRole == role) { return QVariant(QString::fromStdString(dataNode->GetName())); } else if (Qt::ToolTipRole == role) { return QVariant("Name of the data node."); } else if (Qt::DecorationRole == role) { QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(dataNode); } else if (Qt::UserRole == role || QmitkDataNodeRawPointerRole == role) { // user role always returns a reference to the data node, // which can be used to modify the data node in the data storage return QVariant::fromValue(dataNode); } else if (QmitkDataNodeRole == role) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } return QVariant(); } bool QmitkRenderWindowDataStorageTreeModel::setData(const QModelIndex& index, const QVariant& value, int role /*= Qt::EditRole*/) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return false; } if (!index.isValid() || this != index.model()) { return false; } auto item = GetItemByIndex(index); if (nullptr == item) { return false; } auto dataNode = item->GetDataNode(); if (nullptr == dataNode) { return false; } if (Qt::EditRole == role && !value.toString().isEmpty()) { dataNode->SetName(value.toString().toStdString().c_str()); emit dataChanged(index, index); return true; } if (Qt::CheckStateRole == role) { Qt::CheckState newCheckState = static_cast(value.toInt()); bool isVisible = newCheckState; dataNode->SetVisibility(isVisible, baseRenderer); emit dataChanged(index, index); mitk::RenderingManager::GetInstance()->RequestUpdate(baseRenderer->GetRenderWindow()); return true; } return false; } Qt::ItemFlags QmitkRenderWindowDataStorageTreeModel::flags(const QModelIndex& index) const { if (this != index.model()) { return Qt::NoItemFlags; } if (!index.isValid()) { return Qt::ItemIsDropEnabled; } auto item = GetItemByIndex(index); if (nullptr == item) { return Qt::NoItemFlags; } const auto dataNode = item->GetDataNode(); if (m_NodePredicate.IsNull() || m_NodePredicate->CheckNode(dataNode)) { return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } return Qt::NoItemFlags; } Qt::DropActions QmitkRenderWindowDataStorageTreeModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions QmitkRenderWindowDataStorageTreeModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } QStringList QmitkRenderWindowDataStorageTreeModel::mimeTypes() const { QStringList types = QAbstractItemModel::mimeTypes(); types << QmitkMimeTypes::DataNodePtrs; return types; } QMimeData* QmitkRenderWindowDataStorageTreeModel::mimeData(const QModelIndexList& indexes) const { QMimeData* mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); for (const auto& index : indexes) { if (index.isValid()) { auto dataNode = data(index, QmitkDataNodeRawPointerRole).value(); stream << reinterpret_cast(dataNode); } } mimeData->setData(QmitkMimeTypes::DataNodePtrs, encodedData); return mimeData; } bool QmitkRenderWindowDataStorageTreeModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex& parent) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return false; } if (action == Qt::IgnoreAction) { return true; } if (!data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { return false; } if (!parent.isValid()) { return false; } int layer = -1; auto dataNode = this->data(parent, QmitkDataNodeRawPointerRole).value(); if (nullptr != dataNode) { dataNode->GetIntProperty("layer", layer, baseRenderer); } auto dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); for (const auto& dataNode : qAsConst(dataNodeList)) { m_RenderWindowLayerController->MoveNodeToPosition(dataNode, layer, baseRenderer); } ResetTree(); UpdateModelData(); AdjustLayerProperty(); return true; } void QmitkRenderWindowDataStorageTreeModel::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer) { m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer); m_ControlledRenderer = controlledRenderer; ResetTree(); auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNull()) { return; } for (const auto& renderer : controlledRenderer) { if (nullptr == renderer) { continue; } auto allDataNodes = dataStorage->GetAll(); for (const auto& dataNode : *allDataNodes) { // add the node to each render window mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(dataNode, renderer); } } } void QmitkRenderWindowDataStorageTreeModel::SetCurrentRenderer(mitk::BaseRenderer* baseRenderer) { if (m_BaseRenderer == baseRenderer) { return; } // base renderer changed // reset tree to build a new renderer-specific item hierarchy m_BaseRenderer = baseRenderer; ResetTree(); UpdateModelData(); } mitk::BaseRenderer::Pointer QmitkRenderWindowDataStorageTreeModel::GetCurrentRenderer() const { return m_BaseRenderer.Lock(); } void QmitkRenderWindowDataStorageTreeModel::ResetTree() { beginResetModel(); if (nullptr != m_Root) { m_Root->Delete(); } mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New(); rootDataNode->SetName("Data Storage"); m_Root = new QmitkDataStorageTreeModelInternalItem(rootDataNode); endResetModel(); } void QmitkRenderWindowDataStorageTreeModel::UpdateModelData() { auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNotNull()) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNotNull()) { auto allDataNodes = dataStorage->GetAll(); for (const auto& dataNode : *allDataNodes) { // add the node to each render window mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(dataNode, baseRenderer); } - mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(baseRenderer); + mitk::NodePredicateBase::Pointer renderWindowPredicate = mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(baseRenderer); + mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(); + combinedNodePredicate->AddPredicate(renderWindowPredicate); + if (m_NodePredicate.IsNotNull()) + { + combinedNodePredicate->AddPredicate(m_NodePredicate); + } + auto filteredDataNodes = dataStorage->GetSubset(combinedNodePredicate); for (const auto& dataNode : *filteredDataNodes) { AddNodeInternal(dataNode, baseRenderer); } } } } void QmitkRenderWindowDataStorageTreeModel::AdjustLayerProperty() { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return; } std::vector treeAsVector; TreeToVector(m_Root, treeAsVector); int i = treeAsVector.size() - 1; for (auto it = treeAsVector.begin(); it != treeAsVector.end(); ++it) { auto dataNode = (*it)->GetDataNode(); dataNode->SetIntProperty("layer", i, baseRenderer); --i; } } void QmitkRenderWindowDataStorageTreeModel::TreeToVector(QmitkDataStorageTreeModelInternalItem* parent, std::vector& treeAsVector) const { QmitkDataStorageTreeModelInternalItem* item; for (int i = 0; i < parent->GetChildCount(); ++i) { item = parent->GetChild(i); TreeToVector(item, treeAsVector); treeAsVector.push_back(item); } } void QmitkRenderWindowDataStorageTreeModel::AddNodeInternal(const mitk::DataNode* dataNode, const mitk::BaseRenderer* renderer) { if (nullptr == dataNode || m_DataStorage.IsExpired() || nullptr != m_Root->Find(dataNode)) { return; } // find out if we have a root node auto parentItem = m_Root; QModelIndex index; auto parentDataNode = GetParentNode(dataNode); if (nullptr != parentDataNode) // no top level data node { parentItem = m_Root->Find(parentDataNode); if (nullptr == parentItem) { // parent node not contained in the tree; add it NodeAdded(parentDataNode); parentItem = m_Root->Find(parentDataNode); if (nullptr == parentItem) { // could not find and add the parent tree; abort return; } } // get the index of this parent with the help of the grand parent index = createIndex(parentItem->GetIndex(), 0, parentItem); } int firstRowWithASiblingBelow = 0; int nodeLayer = -1; dataNode->GetIntProperty("layer", nodeLayer, renderer); for (const auto& siblingItem : parentItem->GetChildren()) { int siblingLayer = -1; auto siblingNode = siblingItem->GetDataNode(); if (nullptr != siblingNode) { siblingNode->GetIntProperty("layer", siblingLayer, renderer); } if (nodeLayer > siblingLayer) { break; } ++firstRowWithASiblingBelow; } beginInsertRows(index, firstRowWithASiblingBelow, firstRowWithASiblingBelow); auto newNode = new QmitkDataStorageTreeModelInternalItem(const_cast(dataNode)); parentItem->InsertChild(newNode, firstRowWithASiblingBelow); endInsertRows(); } void QmitkRenderWindowDataStorageTreeModel::RemoveNodeInternal(const mitk::DataNode* dataNode) { if (nullptr == dataNode || nullptr == m_Root) { return; } auto item = m_Root->Find(dataNode); if (nullptr == item) { return; } auto parentItem = item->GetParent(); auto parentIndex = GetIndexByItem(parentItem); auto children = item->GetChildren(); beginRemoveRows(parentIndex, item->GetIndex(), item->GetIndex()); parentItem->RemoveChild(item); delete item; endRemoveRows(); if (!children.empty()) { // rebuild tree because children could not be at the top level ResetTree(); UpdateModelData(); } } mitk::DataNode* QmitkRenderWindowDataStorageTreeModel::GetParentNode(const mitk::DataNode* node) const { mitk::DataNode* dataNode = nullptr; auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNull()) { return dataNode; } auto sources = dataStorage->GetSources(node); if (sources->empty()) { return dataNode; } return sources->front(); } QmitkDataStorageTreeModelInternalItem* QmitkRenderWindowDataStorageTreeModel::GetItemByIndex(const QModelIndex& index) const { if (index.isValid()) { return static_cast(index.internalPointer()); } return m_Root; } QModelIndex QmitkRenderWindowDataStorageTreeModel::GetIndexByItem(QmitkDataStorageTreeModelInternalItem* item) const { if (item == m_Root) { return QModelIndex(); } return createIndex(item->GetIndex(), 0, item); } diff --git a/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp b/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp index b387f8265e..e2e8c375ba 100644 --- a/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp +++ b/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp @@ -1,88 +1,82 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager module #include "mitkRenderWindowLayerUtilities.h" // mitk core -#include #include mitk::RenderWindowLayerUtilities::LayerStack mitk::RenderWindowLayerUtilities::GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer, bool withBaseNode) { LayerStack stackedLayers; if (nullptr == dataStorage || nullptr == renderer) { // no nodes to stack or no renderer selected return stackedLayers; } int layer = -1; - NodePredicateAnd::Pointer combinedNodePredicate = GetRenderWindowPredicate(renderer); - DataStorage::SetOfObjects::ConstPointer filteredDataNodes = dataStorage->GetSubset(combinedNodePredicate); + NodePredicateBase::Pointer fixedLayerPredicate = GetRenderWindowPredicate(renderer); + DataStorage::SetOfObjects::ConstPointer filteredDataNodes = dataStorage->GetSubset(fixedLayerPredicate); for (DataStorage::SetOfObjects::ConstIterator it = filteredDataNodes->Begin(); it != filteredDataNodes->End(); ++it) { DataNode::Pointer dataNode = it->Value(); if (dataNode.IsNull()) { continue; } bool layerFound = dataNode->GetIntProperty("layer", layer, renderer); if (layerFound) { if (BASE_LAYER_INDEX != layer|| withBaseNode) { // data node is not on the base layer or the base layer should be included anyway stackedLayers.insert(std::make_pair(layer, dataNode)); } } } return stackedLayers; } -mitk::NodePredicateAnd::Pointer mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(const BaseRenderer* renderer) +mitk::NodePredicateBase::Pointer mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(const BaseRenderer* renderer) { - NodePredicateAnd::Pointer renderWindowPredicate = NodePredicateAnd::New(); + NodePredicateBase::Pointer fixedLayerPredicate = + NodePredicateProperty::New("fixedLayer", BoolProperty::New(true), renderer); - NodePredicateProperty::Pointer helperObject = NodePredicateProperty::New("helper object", BoolProperty::New(true)); - NodePredicateProperty::Pointer fixedLayer = NodePredicateProperty::New("fixedLayer", BoolProperty::New(true), renderer); - - renderWindowPredicate->AddPredicate(NodePredicateNot::New(helperObject)); - renderWindowPredicate->AddPredicate(fixedLayer); - - return renderWindowPredicate; + return fixedLayerPredicate; } void mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(mitk::DataNode* dataNode, const BaseRenderer* renderer) { dataNode->SetBoolProperty("fixedLayer", true, renderer); // use visibility of existing renderer or common renderer // common renderer is used if renderer-specific property does not exist bool visible = false; bool visibilityProperty = dataNode->GetVisibility(visible, renderer); if (true == visibilityProperty) { // found a visibility property dataNode->SetVisibility(visible, renderer); } // use layer of existing renderer or common renderer // common renderer is used if renderer-specific property does not exist int layer = -1; bool layerProperty = dataNode->GetIntProperty("layer", layer, renderer); if (true == layerProperty) { // found a layer property dataNode->SetIntProperty("layer", layer, renderer); } }