diff --git a/Modules/TubeGraph/include/mitkTubeGraphDataInteractor.h b/Modules/TubeGraph/include/mitkTubeGraphDataInteractor.h index faaacb4202..29c30145b4 100644 --- a/Modules/TubeGraph/include/mitkTubeGraphDataInteractor.h +++ b/Modules/TubeGraph/include/mitkTubeGraphDataInteractor.h @@ -1,126 +1,126 @@ /*=================================================================== 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 mitkTubeGraphDataInteractor3D_h_ #define mitkTubeGraphDataInteractor3D_h_ #include #include #include #include "mitkTubeGraph.h" #include "mitkTubeGraphProperty.h" namespace mitk { // Define events for TubeGraph interaction notifications itkEventMacro(SelectionChangedTubeGraphEvent, itk::AnyEvent); /** * \brief * * \ingroup Interaction */ // Inherit from DataInteratcor, this provides functionality of a state machine and configurable inputs. class MITKTUBEGRAPH_EXPORT TubeGraphDataInteractor : public DataInteractor { public: mitkClassMacro(TubeGraphDataInteractor, DataInteractor); itkNewMacro(Self); /** * Describes, which activation modes are available based on the * currently picked tube: * * \li None means "no tube is active" * \li Single means "only the picked tube is active" * \li ToRoot means "all tubes from the picked on down to the root of the tube graph are active" * \li ToPeriphery means "all tubes included in the subgraph of the currently picked vessel are active" * \li Points means "shortes path between two picked tubes are active" * \li Multiple means "all picked tubes are active" */ enum ActivationMode { None = 0, Single, ToRoot, ToPeriphery, Points, Multiple }; enum ActionMode { AttributationMode = 0, AnnotationMode, EditMode, RootMode, InformationMode }; void SetActivationMode(const ActivationMode &activationMode); ActivationMode GetActivationMode(); void SetActionMode(const ActionMode &actionMode); ActionMode GetActionMode(); void ResetPickedTubes(); mitk::Point3D GetLastPickedPosition(); protected: TubeGraphDataInteractor(); ~TubeGraphDataInteractor() override; /** * Here actions strings from the loaded state machine pattern are mapped to functions of * the DataInteractor. These functions are called when an action from the state machine pattern is executed. */ void ConnectActionsAndFunctions() override; /** * This function is called when a DataNode has been set/changed. */ void DataNodeChanged() override; /** * Initializes the movement, stores starting position. */ virtual bool CheckOverTube(const InteractionEvent *); virtual void SelectTube(StateMachineAction *, InteractionEvent *); virtual void DeselectTube(StateMachineAction *, InteractionEvent *); void SelectTubesByActivationModus(); void UpdateActivation(); private: std::vector GetTubesToRoot(); std::vector GetTubesBetweenPoints(); std::vector GetPathToPeriphery(); std::vector GetPathBetweenTubes(const TubeGraph::TubeDescriptorType &start, const TubeGraph::TubeDescriptorType &end); TubeGraph::Pointer m_TubeGraph; TubeGraphProperty::Pointer m_TubeGraphProperty; TubeGraph::TubeDescriptorType m_LastPickedTube; TubeGraph::TubeDescriptorType m_SecondLastPickedTube; ActivationMode m_ActivationMode; ActionMode m_ActionMode; - mitk::TubeElement* m_LastPickedElement; + mitk::TubeElement *m_LastPickedElement = 0; }; } #endif diff --git a/Modules/TubeGraph/src/Interactions/mitkTubeGraphDataInteractor.cpp b/Modules/TubeGraph/src/Interactions/mitkTubeGraphDataInteractor.cpp index 422a4d04e4..d1011562f2 100644 --- a/Modules/TubeGraph/src/Interactions/mitkTubeGraphDataInteractor.cpp +++ b/Modules/TubeGraph/src/Interactions/mitkTubeGraphDataInteractor.cpp @@ -1,286 +1,289 @@ /*=================================================================== 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 "mitkTubeGraphDataInteractor.h" #include #include #include #include "mitkTubeGraphPicker.h" #include #include #include #include #include mitk::TubeGraphDataInteractor::TubeGraphDataInteractor() : m_LastPickedTube(TubeGraph::ErrorId), m_SecondLastPickedTube(TubeGraph::ErrorId), m_ActivationMode(None), m_ActionMode(AttributationMode) { } mitk::TubeGraphDataInteractor::~TubeGraphDataInteractor() {} void mitk::TubeGraphDataInteractor::ConnectActionsAndFunctions() { // **Conditions** that can be used in the state machine, to ensure that certain conditions are met, before actually // executing an action CONNECT_CONDITION("isOverTube", CheckOverTube); // **Function** in the statmachine patterns also referred to as **Actions** CONNECT_FUNCTION("selectTube", SelectTube); CONNECT_FUNCTION("deselectTube", DeselectTube); } void mitk::TubeGraphDataInteractor::DataNodeChanged() { if (GetDataNode() != nullptr) { if (GetDataNode()->GetData() != nullptr) { m_TubeGraph = dynamic_cast(GetDataNode()->GetData()); m_TubeGraphProperty = dynamic_cast( m_TubeGraph->GetProperty("Tube Graph.Visualization Information").GetPointer()); if (m_TubeGraphProperty.IsNull()) MITK_ERROR << "Something went wrong! No tube graph property!"; } else m_TubeGraph = nullptr; } else m_TubeGraph = nullptr; } bool mitk::TubeGraphDataInteractor::CheckOverTube(const InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast(interactionEvent); if (positionEvent == nullptr) return false; auto *picker = new mitk::TubeGraphPicker(); picker->SetTubeGraph(m_TubeGraph); auto pickedTube = picker->GetPickedTube(positionEvent->GetPositionInWorld()); TubeGraph::TubeDescriptorType tubeDescriptor = pickedTube.first; if (tubeDescriptor != TubeGraph::ErrorId) { m_LastPickedElement = pickedTube.second; m_SecondLastPickedTube = m_LastPickedTube; m_LastPickedTube = tubeDescriptor; return true; } else // nothing picked return false; } void mitk::TubeGraphDataInteractor::SelectTube(StateMachineAction *, InteractionEvent *interactionEvent) { if (m_TubeGraph.IsNull()) return; this->SelectTubesByActivationModus(); interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll(); if (m_ActivationMode != None) { // show tube id on status bar std::stringstream displayText; displayText << "Picked tube: ID [" << m_LastPickedTube.first << "," << m_LastPickedTube.second << "]"; StatusBar::GetInstance()->DisplayText(displayText.str().c_str()); // TODO!!! this->InvokeEvent(SelectionChangedTubeGraphEvent()); } } void mitk::TubeGraphDataInteractor::DeselectTube(StateMachineAction *, InteractionEvent *interactionEvent) { if (m_TubeGraph.IsNull()) return; if ((m_ActivationMode != Multiple) && (m_ActivationMode != Points)) { m_TubeGraphProperty->DeactivateAllTubes(); interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll(); // TODO!!!this->InvokeEvent(SelectionChangedTubeGraphEvent()); } // show info on status bar StatusBar::GetInstance()->DisplayText("No tube hit!"); } void mitk::TubeGraphDataInteractor::SetActivationMode(const ActivationMode &activationMode) { m_ActivationMode = activationMode; if (m_TubeGraph.IsNotNull()) if (m_LastPickedTube != mitk::TubeGraph::ErrorId) this->UpdateActivation(); } mitk::TubeGraphDataInteractor::ActivationMode mitk::TubeGraphDataInteractor::GetActivationMode() { return m_ActivationMode; } void mitk::TubeGraphDataInteractor::SetActionMode(const ActionMode &actionMode) { m_ActionMode = actionMode; } mitk::TubeGraphDataInteractor::ActionMode mitk::TubeGraphDataInteractor::GetActionMode() { return m_ActionMode; } void mitk::TubeGraphDataInteractor::SelectTubesByActivationModus() { if (m_LastPickedTube != mitk::TubeGraph::ErrorId) { this->UpdateActivation(); } } void mitk::TubeGraphDataInteractor::UpdateActivation() { if (m_ActionMode == RootMode) { m_TubeGraphProperty->DeactivateAllTubes(); m_TubeGraphProperty->SetTubeActive(m_LastPickedTube, true); // QmitkTubeGraphSelectRootDialog* dialog = new QmitkTubeGraphSelectRootDialog(m_Parent); // int dialogReturnValue = dialog->exec(); // delete dialog; // if ( dialogReturnValue != QDialog::Rejected ) // user doesn't clicked cancel or pressed Esc or something similar //{ m_TubeGraph->SetRootTube(m_LastPickedTube); //} m_TubeGraphProperty->DeactivateAllTubes(); RenderingManager::GetInstance()->RequestUpdateAll(); } else { switch (m_ActivationMode) { case None: { m_TubeGraphProperty->DeactivateAllTubes(); } break; case Single: { m_TubeGraphProperty->DeactivateAllTubes(); m_TubeGraphProperty->SetTubeActive(m_LastPickedTube, true); } break; case Multiple: { // special deactivation for multiple modus // if activated--> deactivate; if not activated--> activate if (m_TubeGraphProperty->IsTubeActive(m_LastPickedTube)) m_TubeGraphProperty->SetTubeActive(m_LastPickedTube, false); else m_TubeGraphProperty->SetTubeActive(m_LastPickedTube, true); } break; case ToRoot: { m_TubeGraphProperty->DeactivateAllTubes(); std::vector activeTubes = this->GetTubesToRoot(); m_TubeGraphProperty->SetTubesActive(activeTubes); } break; case ToPeriphery: { m_TubeGraphProperty->DeactivateAllTubes(); std::vector activeTubes = this->GetPathToPeriphery(); m_TubeGraphProperty->SetTubesActive(activeTubes); } break; case Points: { m_TubeGraphProperty->DeactivateAllTubes(); std::vector activeTubes = this->GetTubesBetweenPoints(); m_TubeGraphProperty->SetTubesActive(activeTubes); } break; default: MITK_WARN << "Unknown tube graph interaction mode!"; break; } } } std::vector mitk::TubeGraphDataInteractor::GetTubesToRoot() { TubeGraph::TubeDescriptorType root = m_TubeGraph->GetRootTube(); if (root == TubeGraph::ErrorId) { root = m_TubeGraph->GetThickestTube(); m_TubeGraph->SetRootTube(root); } return this->GetPathBetweenTubes(m_LastPickedTube, root); } std::vector mitk::TubeGraphDataInteractor::GetTubesBetweenPoints() { return this->GetPathBetweenTubes(m_LastPickedTube, m_SecondLastPickedTube); } std::vector mitk::TubeGraphDataInteractor::GetPathBetweenTubes( const mitk::TubeGraph::TubeDescriptorType &start, const mitk::TubeGraph::TubeDescriptorType &end) { std::vector solutionPath; if ((start != TubeGraph::ErrorId) && (end != TubeGraph::ErrorId)) { if (start != end) solutionPath = m_TubeGraph->SearchAllPathBetweenVertices(start, end); else solutionPath.push_back(start); } return solutionPath; } std::vector mitk::TubeGraphDataInteractor::GetPathToPeriphery() { std::vector solutionPath; if (m_LastPickedTube != TubeGraph::ErrorId) solutionPath = m_TubeGraph->SearchPathToPeriphery(m_LastPickedTube); return solutionPath; } void mitk::TubeGraphDataInteractor::ResetPickedTubes() { m_LastPickedTube = TubeGraph::ErrorId; m_SecondLastPickedTube = TubeGraph::ErrorId; } mitk::Point3D mitk::TubeGraphDataInteractor::GetLastPickedPosition() { - return m_LastPickedElement->GetCoordinates(); + if (m_LastPickedElement) + return m_LastPickedElement->GetCoordinates(); + else + return mitk::Point3D(); }