diff --git a/Modules/Segmentation/Interactions/mitkContourModelInteractor.cpp b/Modules/Segmentation/Interactions/mitkContourModelInteractor.cpp index 18fd453d22..e7b2be3442 100644 --- a/Modules/Segmentation/Interactions/mitkContourModelInteractor.cpp +++ b/Modules/Segmentation/Interactions/mitkContourModelInteractor.cpp @@ -1,201 +1,201 @@ /*============================================================================ 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. ============================================================================*/ #include "mitkContourModelInteractor.h" #include "mitkToolManager.h" #include "mitkBaseRenderer.h" #include "mitkRenderingManager.h" #include #include mitk::ContourModelInteractor::ContourModelInteractor() { } void mitk::ContourModelInteractor::ConnectActionsAndFunctions() { CONNECT_CONDITION("checkisOverPoint", OnCheckPointClick); CONNECT_CONDITION("mouseMove", IsHovering); CONNECT_FUNCTION("movePoint", OnMovePoint); CONNECT_FUNCTION("deletePoint", OnDeletePoint); CONNECT_FUNCTION("finish", OnFinishEditing); } mitk::ContourModelInteractor::~ContourModelInteractor() { } void mitk::ContourModelInteractor::SetRestrictedAreas(std::vector restrictedAreas) { m_RestrictedAreas = restrictedAreas; } bool mitk::ContourModelInteractor::OnCheckPointClick(const InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast(interactionEvent); if (!positionEvent) return false; const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *contour = dynamic_cast(this->GetDataNode()->GetData()); contour->Deselect(); mitk::Point3D click = positionEvent->GetPositionInWorld(); bool isVertexSelected = contour->SelectVertexAt(click, 1.5, timeStep); if (!isVertexSelected) { bool isHover = false; if (this->GetDataNode()->GetBoolProperty("contour.hovering", isHover, positionEvent->GetSender()) == false) { MITK_WARN << "Unknown property contour.hovering"; } if (isHover) { auto lastVertex = *(contour->GetVertexList(timeStep).end() - 1); - mitk::ContourElement::VertexType *previousVertex = - &mitk::ContourElement::VertexType(lastVertex->Coordinates, lastVertex->IsControlPoint); - contour->GetLineSegmentForPoint(click, mitk::ContourModelInteractor::eps, timeStep, previousVertex); + mitk::ContourElement::VertexType previousVertex = + mitk::ContourElement::VertexType(lastVertex->Coordinates, lastVertex->IsControlPoint); + contour->GetLineSegmentForPoint(click, mitk::ContourModelInteractor::eps, timeStep, &previousVertex); auto previousVertexInList = - contour->GetVertexAt(previousVertex->Coordinates, mitk::ContourModelInteractor::eps, timeStep); + contour->GetVertexAt(previousVertex.Coordinates, mitk::ContourModelInteractor::eps, timeStep); auto index = contour->GetIndex(previousVertexInList, timeStep); contour->InsertVertexAtIndex(click, index + 1, true, timeStep); isVertexSelected = contour->SelectVertexAt(click, mitk::ContourModelInteractor::eps, timeStep); } } if (isVertexSelected) { auto foundVertex = contour->GetSelectedVertex(); for (auto restrictedArea : m_RestrictedAreas) { if (restrictedArea->SelectVertexAt(foundVertex->Coordinates, mitk::ContourModelInteractor::eps, timeStep)) { isVertexSelected = false; } } } if (isVertexSelected) { contour->SetSelectedVertexAsControlPoint(); mitk::RenderingManager::GetInstance()->RequestUpdate(interactionEvent->GetSender()->GetRenderWindow()); m_lastMousePosition = click; auto *contourGeometry = dynamic_cast(contour->GetGeometry(timeStep)); if (contourGeometry->IsInside(click)) { m_lastMousePosition = click; return true; } else return false; } else { return false; } return true; } void mitk::ContourModelInteractor::OnDeletePoint(StateMachineAction *, InteractionEvent *) { auto *contour = dynamic_cast(this->GetDataNode()->GetData()); contour->RemoveVertex(contour->GetSelectedVertex()); } bool mitk::ContourModelInteractor::IsHovering(const InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast(interactionEvent); if (!positionEvent) return false; const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *contour = dynamic_cast(this->GetDataNode()->GetData()); mitk::Point3D currentPosition = positionEvent->GetPositionInWorld(); bool isHover = false; this->GetDataNode()->GetBoolProperty("contour.hovering", isHover, positionEvent->GetSender()); if (contour->IsNearContour(currentPosition, 1.5, timeStep)) { if (isHover == false) { this->GetDataNode()->SetBoolProperty("contour.hovering", true); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } } else { if (isHover == true) { this->GetDataNode()->SetBoolProperty("contour.hovering", false); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } } return false; } void mitk::ContourModelInteractor::OnMovePoint(StateMachineAction *, InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast(interactionEvent); if (!positionEvent) return; auto *contour = dynamic_cast(this->GetDataNode()->GetData()); mitk::Vector3D translation; mitk::Point3D currentPosition = positionEvent->GetPositionInWorld(); translation[0] = currentPosition[0] - this->m_lastMousePosition[0]; translation[1] = currentPosition[1] - this->m_lastMousePosition[1]; translation[2] = currentPosition[2] - this->m_lastMousePosition[2]; contour->ShiftSelectedVertex(translation); this->m_lastMousePosition = positionEvent->GetPositionInWorld(); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } void mitk::ContourModelInteractor::OnMoveContour(StateMachineAction *, InteractionEvent *interactionEvent) { const auto *positionEvent = dynamic_cast(interactionEvent); if (!positionEvent) return; const auto timeStep = interactionEvent->GetSender()->GetTimeStep(GetDataNode()->GetData()); auto *contour = dynamic_cast(this->GetDataNode()->GetData()); mitk::Vector3D translation; mitk::Point3D currentPosition = positionEvent->GetPositionInWorld(); translation[0] = currentPosition[0] - this->m_lastMousePosition[0]; translation[1] = currentPosition[1] - this->m_lastMousePosition[1]; translation[2] = currentPosition[2] - this->m_lastMousePosition[2]; contour->ShiftContour(translation, timeStep); this->m_lastMousePosition = positionEvent->GetPositionInWorld(); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); } -void mitk::ContourModelInteractor::OnFinishEditing(StateMachineAction *, InteractionEvent *interactionEvent) +void mitk::ContourModelInteractor::OnFinishEditing(StateMachineAction *, InteractionEvent *) { } diff --git a/Modules/Segmentation/Interactions/mitkEditableContourTool.cpp b/Modules/Segmentation/Interactions/mitkEditableContourTool.cpp index 2ae3dbb8dd..c40e3ba602 100644 --- a/Modules/Segmentation/Interactions/mitkEditableContourTool.cpp +++ b/Modules/Segmentation/Interactions/mitkEditableContourTool.cpp @@ -1,328 +1,322 @@ /*============================================================================ 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. ============================================================================*/ #include "mitkEditableContourTool.h" #include mitk::EditableContourTool::EditableContourTool() : FeedbackContourTool("EditableContourTool") {} mitk::EditableContourTool::~EditableContourTool() { } void mitk::EditableContourTool::ConnectActionsAndFunctions() { CONNECT_FUNCTION("InitObject", OnInitContour); CONNECT_FUNCTION("AddPoint", OnAddPoint); CONNECT_FUNCTION("CtrlAddPoint", OnAddPoint); CONNECT_FUNCTION("Drawing", OnDrawing); CONNECT_FUNCTION("EndDrawing", OnEndDrawing); CONNECT_FUNCTION("FinishContour", OnFinish); CONNECT_FUNCTION("CtrlMovePoint", OnMouseMoved); } void mitk::EditableContourTool::Activated() { Superclass::Activated(); this->ResetToStartState(); this->EnableContourInteraction(true); } void mitk::EditableContourTool::Deactivated() { this->ConfirmSegmentation(); Superclass::Deactivated(); } void mitk::EditableContourTool::ConfirmSegmentation() { auto referenceImage = this->GetReferenceData(); auto workingImage = this->GetWorkingData(); if (nullptr != referenceImage && nullptr != workingImage) { std::vector sliceInfos; sliceInfos.reserve(m_WorkingContours.size()); const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); TimeStepType workingImageTimeStep = workingImage->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint); for (const auto &workingContour : m_WorkingContours) { auto contour = dynamic_cast(workingContour.first->GetData()); if (nullptr == contour || contour->IsEmpty()) continue; auto sameSlicePredicate = [&workingContour, workingImageTimeStep](const SliceInformation &si) { return workingContour.second->IsOnPlane(si.plane) && workingImageTimeStep == si.timestep; }; auto finding = std::find_if(sliceInfos.begin(), sliceInfos.end(), sameSlicePredicate); if (finding == sliceInfos.end()) { auto workingSlice = this->GetAffectedImageSliceAs2DImage(workingContour.second, workingImage, workingImageTimeStep)->Clone(); sliceInfos.emplace_back(workingSlice, workingContour.second, workingImageTimeStep); finding = std::prev(sliceInfos.end()); } // cast const away is OK in this case, because these are all slices created and manipulated // localy in this function call. And we want to keep the high constness of SliceInformation for // public interfaces. auto workingSlice = const_cast(finding->slice.GetPointer()); auto projectedContour = ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contour); int activePixelValue = ContourModelUtils::GetActivePixelValue(workingImage); ContourModelUtils::FillContourInSlice(projectedContour, workingSlice, workingImage, activePixelValue); } this->WriteBackSegmentationResults(sliceInfos); } this->ClearSegmentation(); } void mitk::EditableContourTool::ClearSegmentation() { this->ReleaseHelperObjects(); this->ReleaseInteractors(); this->ResetToStartState(); } bool mitk::EditableContourTool::IsPositionEventInsideImageRegion(mitk::InteractionPositionEvent *positionEvent, mitk::BaseData *data) { bool isPositionEventInsideImageRegion = nullptr != data && data->GetGeometry()->IsInside(positionEvent->GetPositionInWorld()); if (!isPositionEventInsideImageRegion) MITK_WARN("EditableContourTool") << "PositionEvent is outside ImageRegion!"; return isPositionEventInsideImageRegion; } void mitk::EditableContourTool::OnInitContour(StateMachineAction *, InteractionEvent *interactionEvent) { auto positionEvent = dynamic_cast(interactionEvent); if (nullptr == positionEvent) return; auto workingDataNode = this->GetWorkingDataNode(); if (!IsPositionEventInsideImageRegion(positionEvent, workingDataNode->GetData())) { this->ResetToStartState(); return; } m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); m_Contour = this->CreateNewContour(); m_ContourNode = mitk::DataNode::New(); m_ContourNode->SetData(m_Contour); m_ContourNode->SetName("working contour node"); m_ContourNode->SetProperty("layer", IntProperty::New(100)); m_ContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_ContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_ContourNode->AddProperty("contour.color", ColorProperty::New(1.0f, 1.0f, 0.0f), nullptr, true); m_ContourNode->AddProperty("contour.points.color", ColorProperty::New(1.0f, 0.0f, 0.1f), nullptr, true); m_ContourNode->AddProperty("contour.controlpoints.show", BoolProperty::New(true), nullptr, true); m_PreviewContour = this->CreateNewContour(); m_PreviewContourNode = mitk::DataNode::New(); m_PreviewContourNode->SetData(m_PreviewContour); m_PreviewContourNode->SetName("active preview node"); m_PreviewContourNode->SetProperty("layer", IntProperty::New(101)); m_PreviewContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_PreviewContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_PreviewContourNode->AddProperty("contour.color", ColorProperty::New(0.1f, 1.0f, 0.1f), nullptr, true); m_PreviewContourNode->AddProperty("contour.width", mitk::FloatProperty::New(4.0f), nullptr, true); m_ClosureContour = this->CreateNewContour(); m_ClosureContourNode = mitk::DataNode::New(); m_ClosureContourNode->SetData(m_ClosureContour); m_ClosureContourNode->SetName("active closure node"); m_ClosureContourNode->SetProperty("layer", IntProperty::New(101)); m_ClosureContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_ClosureContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_ClosureContourNode->AddProperty("contour.color", ColorProperty::New(0.0f, 1.0f, 0.1f), nullptr, true); m_ClosureContourNode->AddProperty("contour.width", mitk::FloatProperty::New(2.0f), nullptr, true); m_EditingContour = this->CreateNewContour(); m_EditingContourNode = mitk::DataNode::New(); m_EditingContourNode->SetData(m_EditingContour); m_EditingContourNode->SetName("editing node"); m_EditingContourNode->SetProperty("layer", IntProperty::New(102)); m_EditingContourNode->AddProperty("fixedLayer", BoolProperty::New(true)); m_EditingContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_EditingContourNode->AddProperty("contour.color", ColorProperty::New(0.1f, 1.0f, 0.1f), nullptr, true); m_EditingContourNode->AddProperty("contour.points.color", ColorProperty::New(0.0f, 0.0f, 1.0f), nullptr, true); m_EditingContourNode->AddProperty("contour.width", mitk::FloatProperty::New(4.0f), nullptr, true); m_CurrentRestrictedArea = this->CreateNewContour(); auto dataStorage = this->GetToolManager()->GetDataStorage(); dataStorage->Add(m_ContourNode, workingDataNode); dataStorage->Add(m_PreviewContourNode, workingDataNode); dataStorage->Add(m_ClosureContourNode, workingDataNode); dataStorage->Add(m_EditingContourNode, workingDataNode); m_ReferenceDataSlice = this->GetAffectedReferenceSlice(positionEvent); auto origin = m_ReferenceDataSlice->GetSlicedGeometry()->GetOrigin(); m_ReferenceDataSlice->GetSlicedGeometry()->WorldToIndex(origin, origin); m_ReferenceDataSlice->GetSlicedGeometry()->IndexToWorld(origin, origin); m_ReferenceDataSlice->GetSlicedGeometry()->SetOrigin(origin); // Remember PlaneGeometry to determine if events were triggered in the same plane m_PlaneGeometry = interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry(); } - -bool mitk::EditableContourTool::OnCheckPoint(const InteractionEvent *interactionEvent) -{ - return false; -} - void mitk::EditableContourTool::OnFinish(StateMachineAction *, InteractionEvent *interactionEvent) { auto positionEvent = dynamic_cast(interactionEvent); if (nullptr == positionEvent) return; if (m_PlaneGeometry.IsNotNull()) { // Check if the point is in the correct slice if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::sqrteps) return; } // remove green connection between mouse position and start point m_ClosureContour->Clear(); // Save contour and corresponding plane geometry to list this->m_WorkingContours.emplace_back(std::make_pair(m_ContourNode, positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone())); this->m_EditingContours.emplace_back(std::make_pair(m_EditingContourNode, positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone())); } void mitk::EditableContourTool::FinishTool() { auto numberOfTimesteps = static_cast(m_Contour->GetTimeSteps()); for (int i = 0; i <= numberOfTimesteps; ++i) m_Contour->Close(i); this->GetToolManager()->GetDataStorage()->Remove(m_PreviewContourNode); m_PreviewContourNode = nullptr; m_PreviewContour = nullptr; } void mitk::EditableContourTool::ReleaseHelperObjects() { this->RemoveHelperObjects(); m_EditingContours.clear(); m_WorkingContours.clear(); m_RestrictedAreas.clear(); m_EditingContourNode = nullptr; m_EditingContour = nullptr; m_PreviewContourNode = nullptr; m_PreviewContour = nullptr; m_ClosureContourNode = nullptr; m_ClosureContour = nullptr; m_ContourNode = nullptr; m_Contour = nullptr; m_CurrentRestrictedArea = nullptr; } void mitk::EditableContourTool::RemoveHelperObjects() { auto dataStorage = this->GetToolManager()->GetDataStorage(); if (nullptr == dataStorage) return; for (const auto &editingContour : m_EditingContours) dataStorage->Remove(editingContour.first); for (const auto &workingContour : m_WorkingContours) dataStorage->Remove(workingContour.first); if (m_EditingContourNode.IsNotNull()) dataStorage->Remove(m_EditingContourNode); if (m_PreviewContourNode.IsNotNull()) dataStorage->Remove(m_PreviewContourNode); if (m_ClosureContourNode.IsNotNull()) dataStorage->Remove(m_ClosureContourNode); if (m_ContourNode.IsNotNull()) dataStorage->Remove(m_ContourNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } mitk::ContourModel::Pointer mitk::EditableContourTool::CreateNewContour() const { auto workingData = this->GetWorkingData(); if (nullptr == workingData) { this->InteractiveSegmentationBugMessage( "Cannot create new contour. No valid working data is set. Application is in invalid state."); mitkThrow() << "Cannot create new contour. No valid working data is set. Application is in invalid state."; } auto contour = ContourModel::New(); // generate a time geometry that is always visible as the working contour should always be. auto contourTimeGeometry = ProportionalTimeGeometry::New(); contourTimeGeometry->SetStepDuration(std::numeric_limits::max()); contourTimeGeometry->SetTimeStepGeometry(contour->GetTimeGeometry()->GetGeometryForTimeStep(0)->Clone(), 0); contour->SetTimeGeometry(contourTimeGeometry); return contour; } void mitk::EditableContourTool::UpdateClosureContour(mitk::Point3D endpoint) { if (m_ClosureContour->GetNumberOfVertices() > 2) { m_ClosureContour = this->CreateNewContour(); } if (m_ClosureContour->GetNumberOfVertices() == 0) { m_ClosureContour->AddVertex(m_Contour->GetVertexAt(0)->Coordinates); m_ClosureContour->Update(); } if (m_ClosureContour->GetNumberOfVertices() == 2) { m_ClosureContour->RemoveVertexAt(0); } m_ClosureContour->AddVertexAtFront(endpoint); } diff --git a/Modules/Segmentation/Interactions/mitkEditableContourTool.h b/Modules/Segmentation/Interactions/mitkEditableContourTool.h index bbc2d47c22..bc55161e76 100644 --- a/Modules/Segmentation/Interactions/mitkEditableContourTool.h +++ b/Modules/Segmentation/Interactions/mitkEditableContourTool.h @@ -1,104 +1,101 @@ /*============================================================================ 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 mitkEditbaleContourTool_h_Included #define mitkEditbaleContourTool_h_Included #include namespace mitk { class MITKSEGMENTATION_EXPORT EditableContourTool : public FeedbackContourTool { public: mitkClassMacro(EditableContourTool, FeedbackContourTool); /// \brief Convert all current contours to binary segmentations. virtual void ConfirmSegmentation(); /// \brief Delete all current contours. virtual void ClearSegmentation(); protected: EditableContourTool(); ~EditableContourTool() override; void ConnectActionsAndFunctions() override; void Activated() override; void Deactivated() override; /// \brief Initialize tool. virtual void OnInitContour(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Add a control point and finish current segment. virtual void OnAddPoint(StateMachineAction *, InteractionEvent *interactionEvent) = 0; /// \brief Draw a contour according to the mouse movement when mouse button is pressed and mouse is moved. virtual void OnDrawing(StateMachineAction *, InteractionEvent *interactionEvent) = 0; virtual void OnEndDrawing(StateMachineAction *, InteractionEvent *interactionEvent) = 0; /// \brief Computation of the preview contour. virtual void OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent) = 0; - /// \brief Check double click on first control point to finish the EditableContour tool. - virtual bool OnCheckPoint(const InteractionEvent *interactionEvent); - /// \brief Finish EditableContour tool. virtual void OnFinish(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Finish contour interaction. virtual void FinishTool(); virtual void EnableContourInteraction(bool on) = 0; virtual void ReleaseInteractors() = 0; virtual void ReleaseHelperObjects(); virtual void RemoveHelperObjects(); ContourModel::Pointer CreateNewContour() const; virtual void UpdateClosureContour(mitk::Point3D endpoint); bool IsPositionEventInsideImageRegion(InteractionPositionEvent *positionEvent, BaseData *data); mitk::ContourModel::Pointer m_Contour; mitk::DataNode::Pointer m_ContourNode; mitk::ContourModel::Pointer m_PreviewContour; mitk::DataNode::Pointer m_PreviewContourNode; mitk::ContourModel::Pointer m_ClosureContour; mitk::DataNode::Pointer m_ClosureContourNode; mitk::ContourModel::Pointer m_EditingContour; mitk::DataNode::Pointer m_EditingContourNode; mitk::ContourModel::Pointer m_CurrentRestrictedArea; std::vector m_RestrictedAreas; /** Slice of the reference data the tool is currently actively working on to define contours.*/ mitk::Image::Pointer m_ReferenceDataSlice; std::vector> m_WorkingContours; std::vector> m_EditingContours; PlaneGeometry::ConstPointer m_PlaneGeometry; }; } #endif diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h index 41b8556574..8638f02a19 100644 --- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h +++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.h @@ -1,117 +1,117 @@ /*============================================================================ 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 mitkLiveWireTool2D_h #define mitkLiveWireTool2D_h #include #include namespace mitk { /** \brief A 2D segmentation tool based on a LiveWire approach. The contour between the last point and the current mouse position is computed by searching the shortest path according to specific features of the image. The contour thus tends to snap to the boundary of objects. The tool always assumes that unconfirmed contours are always defined for the current time point. So the time step in which the contours will be stored as segmentations will be determined when the contours got confirmed. Then they will be transfered to the slices of the currently selected time step. Changing the time point/time step while tool is active will updated the working slice the live wire filter. So the behavior of the active live wire contour is always WYSIWYG (What you see is what you get). \sa SegTool2D \sa ImageLiveWireContourModelFilter \ingroup Interaction \ingroup ToolManagerEtAl \warning Only to be instantiated by mitk::ToolManager. */ class MITKSEGMENTATION_EXPORT LiveWireTool2D : public EditableContourTool { public: mitkClassMacro(LiveWireTool2D, SegTool2D); itkFactorylessNewMacro(Self); us::ModuleResource GetCursorIconResource() const override; us::ModuleResource GetIconResource() const override; const char *GetName() const override; const char **GetXPM() const override; void SetSnapClosureContour(bool snap); protected: LiveWireTool2D(); ~LiveWireTool2D() override; void ConnectActionsAndFunctions() override; void UpdateLiveWireContour(); void OnTimePointChanged() override; private: /// \brief Initialize tool. void OnInitContour(StateMachineAction *, InteractionEvent *interactionEvent) override; /// \brief Add a control point and finish current segment. void OnAddPoint(StateMachineAction *, InteractionEvent *interactionEvent) override; /// \brief Draw a contour according to the mouse movement when mouse button is pressed and mouse is moved. void OnDrawing(StateMachineAction *, InteractionEvent *interactionEvent) override; void OnEndDrawing(StateMachineAction *, InteractionEvent *interactionEvent) override; /// \brief Actual LiveWire computation. void OnMouseMoved(StateMachineAction *, InteractionEvent *interactionEvent) override; /// \brief Check double click on first control point to finish the LiveWire tool. - bool OnCheckPoint(const InteractionEvent *interactionEvent) override; + bool OnCheckPoint(const InteractionEvent *interactionEvent); /// \brief Finish LiveWire tool. void OnFinish(StateMachineAction *, InteractionEvent *interactionEvent) override; /// \brief Don't use dynamic cost map for LiveWire calculation. void OnMouseMoveNoDynamicCosts(StateMachineAction *, InteractionEvent *interactionEvent); /// \brief Finish contour interaction. void FinishTool() override; void EnableContourInteraction(bool on) override; void ReleaseInteractors() override; template void FindHighestGradientMagnitudeByITK(itk::Image *inputImage, itk::Index<3> &index, itk::Index<3> &returnIndex); void UpdateClosureContour(mitk::Point3D endpoint) override; bool m_SnapClosureContour; mitk::ContourModelLiveWireInteractor::Pointer m_ContourInteractor; mitk::ImageLiveWireContourModelFilter::Pointer m_LiveWireFilter; mitk::ImageLiveWireContourModelFilter::Pointer m_LiveWireFilterClosure; bool m_CreateAndUseDynamicCosts; std::vector m_LiveWireInteractors; }; } #endif