diff --git a/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt index a4b3d17818..12c8c7349f 100644 --- a/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt @@ -1,7 +1,11 @@ project(org_mitk_gui_qt_simulation) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE SIMULATION_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgets MitkSimulation ) + +if(MSVC) + set_property(TARGET ${PLUGIN_TARGET} APPEND_STRING PROPERTY COMPILE_FLAGS " /wd4250 /wd4251 /wd4267 /wd4275") +endif() \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.simulation/files.cmake b/Plugins/org.mitk.gui.qt.simulation/files.cmake index b9f3403b63..73c35280fd 100644 --- a/Plugins/org.mitk.gui.qt.simulation/files.cmake +++ b/Plugins/org.mitk.gui.qt.simulation/files.cmake @@ -1,39 +1,41 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_simulation_Activator.cpp QmitkSimulationPreferencePage.cpp + QmitkSimulationSceneTreeWidget.cpp QmitkSimulationView.cpp ) set(UI_FILES src/internal/QmitkSimulationPreferencePageControls.ui src/internal/QmitkSimulationViewControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_simulation_Activator.h src/internal/QmitkSimulationPreferencePage.h + src/internal/QmitkSimulationSceneTreeWidget.h src/internal/QmitkSimulationView.h ) set(CACHED_RESOURCE_FILES resources/SOFAIcon.png plugin.xml ) set(QRC_FILES resources/Simulation.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach() foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach() diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png new file mode 100644 index 0000000000..558445718c Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png differ diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png new file mode 100644 index 0000000000..4832b76336 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png differ diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc b/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc index 8af9ac81f8..2684648ed4 100644 --- a/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc +++ b/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc @@ -1,5 +1,8 @@ + Node_16x16.png + Object_16x16.png + Slave_16x16.png SOFAIcon.png diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png new file mode 100644 index 0000000000..9281fff450 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png differ diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.cpp new file mode 100644 index 0000000000..ea3f61ed25 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.cpp @@ -0,0 +1,381 @@ +/*=================================================================== + +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 "QmitkSimulationSceneTreeWidget.h" +#include +#include +#include +#include + +template +static inline T* as(QmitkSimulationSceneTreeWidget::Base* base) +{ + return dynamic_cast(base); +} + +template +static inline bool is(QmitkSimulationSceneTreeWidget::Base* base) +{ + return dynamic_cast(base) != NULL; +} + +template +static inline bool is(QmitkSimulationSceneTreeWidget::Base* base) +{ + return is(base) || is(base); +} + +template +static inline bool is(QmitkSimulationSceneTreeWidget::Base* base) +{ + return is(base) || is(base) || is(base); +} + +static inline bool isBaseInteractionForceField(QmitkSimulationSceneTreeWidget::Base* base) +{ + sofa::core::behavior::BaseInteractionForceField* iff = dynamic_cast(base); + return iff != NULL && iff->getMechModel1() != iff->getMechModel2(); +} + +static inline bool isMechanicalMapping(QmitkSimulationSceneTreeWidget::Base* base) +{ + sofa::core::BaseMapping* mm = dynamic_cast(base); + return mm != NULL && mm->isMechanical(); +} + +static QRgb GetColor(QmitkSimulationSceneTreeWidget::Base* base) +{ + using namespace sofa::core; + using namespace sofa::core::behavior; + using namespace sofa::core::collision; + using namespace sofa::core::loader; + using namespace sofa::core::objectmodel; + using namespace sofa::core::topology; + using namespace sofa::core::visual; + using namespace sofa::simulation::Colors; + + QString hexColor; + + if (is(base)) + { + hexColor = COLOR[NODE]; + } + else if (is(base)) + { + if (is(base)) + hexColor = COLOR[sofa::simulation::Colors::CONTEXT]; + else if (is(base)) + hexColor = COLOR[BMODEL]; + else if (is(base)) + hexColor = COLOR[CMODEL]; + else if (is(base)) + hexColor = COLOR[MMODEL]; + else if (is(base)) + hexColor = COLOR[PROJECTIVECONSTRAINTSET]; + else if (is(base)) + hexColor = COLOR[CONSTRAINTSET]; + else if (is(base)) + hexColor = COLOR[MASS]; + else if (isBaseInteractionForceField(base)) + hexColor = COLOR[IFFIELD]; + else if (is(base)) + hexColor = COLOR[FFIELD]; + else if (is(base)) + hexColor = COLOR[SOLVER]; + else if (is(base)) + hexColor = COLOR[COLLISION]; + else if (isMechanicalMapping(base)) + hexColor = COLOR[MMAPPING]; + else if (is(base)) + hexColor = COLOR[MAPPING]; + else if (is(base)) + hexColor = COLOR[TOPOLOGY]; + else if (is(base)) + hexColor = COLOR[LOADER]; + else if (is(base)) + hexColor = COLOR[CONFIGURATIONSETTING]; + else if (is(base)) + hexColor = COLOR[VMODEL]; + else + hexColor = COLOR[OBJECT]; + } + else + { + hexColor = "#000"; + } + + QColor color; + color.setNamedColor(hexColor); + + return color.rgb(); +} + +static QPixmap ReplaceColor(const QPixmap& pixmap, QRgb from, QRgb to) +{ + QImage image = pixmap.toImage(); + + const int width = image.width(); + const int height = image.height(); + int x, y; + + for (y = 0; y < height; ++y) + { + for (x = 0; x < width; ++x) + { + if (image.pixel(x, y) == from) + image.setPixel(x, y, to); + } + } + + return QPixmap::fromImage(image); +} + +static inline QIcon CreateObjectIcon(QmitkSimulationSceneTreeWidget::Base* base) +{ + return QIcon(ReplaceColor(QPixmap(":/Simulation/Object"), 0xff00ff00, GetColor(base))); +} + +static inline QIcon CreateNodeIcon(QmitkSimulationSceneTreeWidget::BaseNode* node) +{ + return QIcon(ReplaceColor(QPixmap(":/Simulation/Node"), 0xff00ff00, GetColor(node))); +} + +static inline QIcon CreateSlaveIcon(QmitkSimulationSceneTreeWidget::Base* base) +{ + return QIcon(ReplaceColor(QPixmap(":/Simulation/Slave"), 0xff00ff00, GetColor(base))); +} + +static inline QString GetName(QmitkSimulationSceneTreeWidget::Base* base) +{ + return QString::fromStdString(base->getName()); +} + +static inline QString GetClassName(QmitkSimulationSceneTreeWidget::Base* base) +{ + return QString::fromStdString(base->getClassName()); +} + +QmitkSimulationSceneTreeWidget::QmitkSimulationSceneTreeWidget(QWidget* parent) + : QTreeWidget(parent) +{ +} + +QmitkSimulationSceneTreeWidget::~QmitkSimulationSceneTreeWidget() +{ +} + +void QmitkSimulationSceneTreeWidget::clear() +{ + QTreeWidgetItem* rootItem = this->topLevelItem(0); + + if (rootItem != NULL) + this->removeChild(NULL, as(m_ItemBaseMap[rootItem])); + + this->ClearMaps(); + + QTreeWidget::clear(); +} + +void QmitkSimulationSceneTreeWidget::addChild(Node* parent, Node* child) +{ + assert(child != NULL && "Child node is NULL!"); + assert(!m_BaseItemMap.contains(child) && "TODO: Support nodes with multiple parents!"); + + QTreeWidgetItem* item; + + if (parent == NULL) + { + item = new QTreeWidgetItem(QStringList() << GetName(child)); + this->addTopLevelItem(item); + } + else + { + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(child)); + } + + item->setIcon(0, CreateNodeIcon(child)); + this->InsertIntoMaps(child, item); + + MutationListener::addChild(parent, child); +} + +void QmitkSimulationSceneTreeWidget::removeChild(Node* parent, Node* child) +{ + assert(child != NULL && "Child node is NULL!"); + assert(m_BaseItemMap.contains(child) && "Child node has already been removed!"); + + MutationListener::removeChild(parent, child); + + if (parent == NULL) + { + delete m_BaseItemMap[child]; + } + else + { + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + m_BaseItemMap[parent]->removeChild(m_BaseItemMap[child]); + } + + this->RemoveFromMaps(child); +} + +void QmitkSimulationSceneTreeWidget::moveChild(Node* previous, Node* parent, Node* child) +{ + if (previous == NULL) + { + this->addChild(parent, child); + } + else if (parent == NULL) + { + this->removeChild(previous, child); + } + else + { + assert(child != NULL && "Child node is NULL!"); + assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(m_BaseItemMap.contains(child) && "Unknown child node!"); + + QTreeWidgetItem* previousItem = m_BaseItemMap[previous]; + m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[child]))); + } +} + +void QmitkSimulationSceneTreeWidget::addObject(Node* parent, BaseObject* object) +{ + assert(parent != NULL && "Parent node is NULL!"); + assert(object != NULL && "Object is NULL!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(!m_BaseItemMap.contains(object) && "Object has already been added!"); + + QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(object)); + item->setToolTip(0, GetClassName(object)); + item->setIcon(0, CreateObjectIcon(object)); + this->InsertIntoMaps(object, item); + + MutationListener::addObject(parent, object); +} + +void QmitkSimulationSceneTreeWidget::removeObject(Node* parent, BaseObject* object) +{ + assert(parent != NULL && "Parent node is NULL!"); + assert(object != NULL && "Object is NULL!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(m_BaseItemMap.contains(object) && "Object has already been removed!"); + + MutationListener::removeObject(parent, object); + + m_BaseItemMap[parent]->removeChild(m_BaseItemMap[object]); + this->RemoveFromMaps(object); +} + +void QmitkSimulationSceneTreeWidget::moveObject(Node* previous, Node* parent, BaseObject* object) +{ + if (previous == NULL) + { + this->addObject(parent, object); + } + else if (parent == NULL) + { + this->removeObject(previous, object); + } + else + { + assert(object != NULL && "Object is NULL!"); + assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(m_BaseItemMap.contains(object) && "Unknown object!"); + + QTreeWidgetItem* previousItem = m_BaseItemMap[previous]; + m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[object]))); + } +} + +void QmitkSimulationSceneTreeWidget::addSlave(BaseObject* master, BaseObject* slave) +{ + assert(master != NULL && "Master object is NULL!"); + assert(slave != NULL && "Slave object is NULL!"); + assert(m_BaseItemMap.contains(master) && "Unknown master object!"); + assert(!m_BaseItemMap.contains(slave) && "Slave object has already been added!"); + + QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[master], QStringList() << GetName(slave)); + item->setToolTip(0, GetClassName(slave)); + item->setIcon(0, CreateSlaveIcon(slave)); + this->InsertIntoMaps(slave, item); + + MutationListener::addSlave(master, slave); +} + +void QmitkSimulationSceneTreeWidget::removeSlave(BaseObject* master, BaseObject* slave) +{ + assert(master != NULL && "Master object is NULL!"); + assert(slave != NULL && "Slave object is NULL!"); + assert(m_BaseItemMap.contains(master) && "Unknown master object!"); + assert(m_BaseItemMap.contains(slave) && "Slave object has already been removed!"); + + MutationListener::removeSlave(master, slave); + + m_BaseItemMap[master]->removeChild(m_BaseItemMap[slave]); + this->RemoveFromMaps(slave); +} + +void QmitkSimulationSceneTreeWidget::moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave) +{ + if (previousMaster == NULL) + { + this->addSlave(master, slave); + } + else if (master == NULL) + { + this->removeSlave(previousMaster, slave); + } + else + { + assert(slave != NULL && "Slave object is NULL!"); + assert(m_BaseItemMap.contains(previousMaster) && "Unknown previous master object!"); + assert(m_BaseItemMap.contains(master) && "Unknown master object!"); + assert(m_BaseItemMap.contains(slave) && "Unknown slave object!"); + + QTreeWidgetItem* previousMasterItem = m_BaseItemMap[previousMaster]; + m_BaseItemMap[master]->addChild(previousMasterItem->takeChild(previousMasterItem->indexOfChild(m_BaseItemMap[slave]))); + } +} + +QmitkSimulationSceneTreeWidget::Base* QmitkSimulationSceneTreeWidget::GetBaseFromItem(QTreeWidgetItem* item) const +{ + return m_ItemBaseMap.contains(item) + ? m_ItemBaseMap[item] + : NULL; +} + +void QmitkSimulationSceneTreeWidget::ClearMaps() +{ + m_BaseItemMap.clear(); + m_ItemBaseMap.clear(); +} + +void QmitkSimulationSceneTreeWidget::InsertIntoMaps(Base* base, QTreeWidgetItem* item) +{ + m_BaseItemMap.insert(base, item); + m_ItemBaseMap.insert(item, base); +} + +void QmitkSimulationSceneTreeWidget::RemoveFromMaps(Base* base) +{ + m_ItemBaseMap.remove(m_BaseItemMap[base]); + m_BaseItemMap.remove(base); +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.h new file mode 100644 index 0000000000..f870f2f4d2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationSceneTreeWidget.h @@ -0,0 +1,82 @@ +/*=================================================================== + +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 QmitkSimulationSceneTreeWidget_h +#define QmitkSimulationSceneTreeWidget_h + +#include +#include +#include + +namespace sofa +{ + namespace core + { + namespace objectmodel + { + class Base; + class BaseNode; + class BaseObject; + } + } + + namespace simulation + { + class Node; + } +} + +class QmitkSimulationSceneTreeWidget : public QTreeWidget, public sofa::simulation::MutationListener +{ + Q_OBJECT + +public: + typedef sofa::core::objectmodel::Base Base; + typedef sofa::core::objectmodel::BaseNode BaseNode; + typedef sofa::core::objectmodel::BaseObject BaseObject; + typedef sofa::simulation::Node Node; + + explicit QmitkSimulationSceneTreeWidget(QWidget* parent = NULL); + ~QmitkSimulationSceneTreeWidget(); + + Base* GetBaseFromItem(QTreeWidgetItem* item) const; + + // QTreeWidget, QTreeView, and QAbstractItemView Interfaces ////////////////////// + void clear(); + ////////////////////////////////////////////////////////////////////////////////// + + // MutationListener Interface //////////////////////////////////////////////////// + void addChild(Node* parent, Node* child); + void removeChild(Node* parent, Node* child); + void moveChild(Node* previous, Node* parent, Node* child); + void addObject(Node* parent, BaseObject* object); + void removeObject(Node* parent, BaseObject* object); + void moveObject(Node* previous, Node* parent, BaseObject* object); + void addSlave(BaseObject* master, BaseObject* slave); + void removeSlave(BaseObject* master, BaseObject* slave); + void moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave); + ////////////////////////////////////////////////////////////////////////////////// + +private: + void ClearMaps(); + void InsertIntoMaps(Base* base, QTreeWidgetItem* item); + void RemoveFromMaps(Base* base); + + QMap m_BaseItemMap; + QMap m_ItemBaseMap; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp index 1e0e3973b8..d4a0ce1761 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp @@ -1,195 +1,240 @@ /*=================================================================== 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 "org_mitk_gui_qt_simulation_Activator.h" #include "QmitkSimulationView.h" #include #include #include #include template static T* GetService() { ctkPluginContext* context = mitk::org_mitk_gui_qt_simulation_Activator::GetContext(); if (context == NULL) return NULL; ctkServiceReference serviceReference = context->getServiceReference(); return serviceReference ? context->getService(serviceReference) : NULL; } QmitkSimulationView::QmitkSimulationView() : m_SimulationService(GetService()), m_Timer(this) { this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); } QmitkSimulationView::~QmitkSimulationView() { this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); } void QmitkSimulationView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Controls.simulationComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.simulationComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); connect(m_Controls.simulationComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSimulationChanged(const mitk::DataNode*))); connect(m_Controls.animateButton, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool))); connect(m_Controls.stepButton, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked())); connect(m_Controls.resetButton, SIGNAL(clicked()), this, SLOT(OnResetButtonClicked())); connect(m_Controls.dtSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDtChanged(double))); if (m_Controls.simulationComboBox->GetSelectedNode().IsNotNull()) + { this->OnSelectedSimulationChanged(m_Controls.simulationComboBox->GetSelectedNode()); + } + else + { + this->SetSimulationControlsEnabled(false); + } } void QmitkSimulationView::OnAnimateButtonToggled(bool toggled) { - mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); if (toggled) { + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + simulation->SetAnimationFlag(true); scheduler->AddProcess(simulation); m_Controls.stepButton->setEnabled(false); } - else + else if (m_Selection.IsNotNull()) { + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + scheduler->RemoveProcess(simulation); simulation->SetAnimationFlag(false); m_Controls.stepButton->setEnabled(true); } if (!scheduler->IsEmpty()) { if (!m_Timer.isActive()) m_Timer.start(0); } else { m_Timer.stop(); } } void QmitkSimulationView::OnDtChanged(double dt) { + if (m_Selection.IsNull()) + return; + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); simulation->SetDt(std::max(0.0, dt)); } void QmitkSimulationView::OnNodeRemovedFromDataStorage(const mitk::DataNode* node) { mitk::Simulation::Pointer simulation = dynamic_cast(node->GetData()); - mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); if (simulation.IsNotNull()) { + mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); + scheduler->RemoveProcess(simulation); if (scheduler->IsEmpty() && m_Timer.isActive()) m_Timer.stop(); + + if (m_SimulationService->GetActiveSimulation() == simulation) + m_SimulationService->SetActiveSimulation(NULL); } } void QmitkSimulationView::OnResetButtonClicked() { mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); m_SimulationService->SetActiveSimulation(simulation); m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); simulation->Reset(); this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnSelectedSimulationChanged(const mitk::DataNode* node) { if (node != NULL) { m_Selection = m_Controls.simulationComboBox->GetSelectedNode(); mitk::Simulation* simulation = static_cast(m_Selection->GetData()); m_Controls.animateButton->setChecked(simulation->GetAnimationFlag()); m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); - m_Controls.simulationGroupBox->setEnabled(true); + this->SetSimulationControlsEnabled(true); } else { - m_Controls.simulationGroupBox->setEnabled(false); + m_Selection = NULL; + + this->SetSimulationControlsEnabled(false); m_Controls.animateButton->setChecked(false); m_Controls.dtSpinBox->setValue(0.0); } + + this->ResetSimulationSceneTreeWidget(); } void QmitkSimulationView::OnStep(bool renderWindowUpdate) { mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); mitk::Simulation::Pointer simulation = dynamic_cast(scheduler->GetNextProcess()); m_SimulationService->SetActiveSimulation(simulation); if (simulation.IsNotNull()) simulation->Animate(); if (renderWindowUpdate) this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnStepButtonClicked() { + if (m_Selection.IsNull()) + return; + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); m_SimulationService->SetActiveSimulation(simulation); simulation->Animate(); this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnTimeout() { QTime currentTime = QTime::currentTime(); if (currentTime.msecsTo(m_NextRenderWindowUpdate) > 0) { this->OnStep(false); } else { m_NextRenderWindowUpdate = currentTime.addMSecs(MSecsPerFrame); this->OnStep(true); } } +void QmitkSimulationView::ResetSimulationSceneTreeWidget() +{ + m_Controls.simulationSceneTreeWidget->clear(); + + if (m_Selection.IsNull()) + return; + + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + + m_Controls.simulationSceneTreeWidget->addChild(NULL, simulation->GetRootNode().get()); + m_Controls.simulationSceneTreeWidget->expandItem(m_Controls.simulationSceneTreeWidget->topLevelItem(0)); +} + +void QmitkSimulationView::SetSimulationControlsEnabled(bool enabled) +{ + m_Controls.animateButton->setEnabled(enabled); + m_Controls.stepButton->setEnabled(enabled); + m_Controls.resetButton->setEnabled(enabled); + m_Controls.dtLabel->setEnabled(enabled); + m_Controls.dtSpinBox->setEnabled(enabled); +} + void QmitkSimulationView::SetFocus() { m_Controls.animateButton->setFocus(); } diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h index 0de564fc8a..f96483c7c2 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h @@ -1,62 +1,64 @@ /*=================================================================== 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 QmitkSimulationView_h #define QmitkSimulationView_h #include #include #include #include namespace mitk { class ISimulationService; } class QmitkSimulationView : public QmitkAbstractView { Q_OBJECT public: QmitkSimulationView(); ~QmitkSimulationView(); void CreateQtPartControl(QWidget* parent); void SetFocus(); private slots: void OnAnimateButtonToggled(bool toggled); void OnDtChanged(double dt); void OnResetButtonClicked(); void OnSelectedSimulationChanged(const mitk::DataNode* node); void OnStep(bool renderWindowUpdate); void OnStepButtonClicked(); void OnTimeout(); private: void OnNodeRemovedFromDataStorage(const mitk::DataNode* node); + void ResetSimulationSceneTreeWidget(); + void SetSimulationControlsEnabled(bool enabled); static const int MSecsPerFrame = 17; Ui::QmitkSimulationViewControls m_Controls; mitk::ISimulationService* m_SimulationService; mitk::DataNode::Pointer m_Selection; QTimer m_Timer; QTime m_NextRenderWindowUpdate; }; #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui index 491677b328..f17287a356 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui @@ -1,143 +1,151 @@ QmitkSimulationViewControls true 0 0 - 301 - 548 + 274 + 751 Simulation - - - false - - - Simulation - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Animate - - - true - - - false - - - - - - - - 0 - 0 - - - - Step - - - - - - - - 0 - 0 - - - - Reset - - - - - - - - 0 - 0 - - - - dt - - - - - - - - 0 - 0 - - - - s - - - 3 - - - 0.010000000000000 - - - - - + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Animate + + + true + + + false + + + + + + + + 0 + 0 + + + + Step + + + + + + + + 0 + 0 + + + + Reset + + + + + + + + 0 + 0 + + + + dt + + + + + + + + 0 + 0 + + + + s + + + 3 + + + 0.010000000000000 + + + + - - - Qt::Vertical + + + QAbstractItemView::NoEditTriggers + + + true - - - 20 - 421 - + + false - + + 1 + + + false + + + + Name + + + QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
+ + QmitkSimulationSceneTreeWidget + QTreeWidget +
QmitkSimulationSceneTreeWidget.h
+