diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_Technical.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_Technical.dox
index 0881222a0e..83a22733cd 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_Technical.dox
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_Technical.dox
@@ -1,101 +1,101 @@
/**
\page QmitkSegmentationTechnicalPage Technical design of QmitkSegmentation
\li \ref QmitkSegmentationTechnicalPage2
\li \ref QmitkSegmentationTechnicalPage3
\li \ref QmitkSegmentationTechnicalPage4
\section QmitkSegmentationTechnicalPage2 Introduction
QmitkSegmentation was designed for the liver resection planning
project "ReLiver".
The goal was a stable, well-documented, extensible, and testable
re-implementation of a functionality called "ERIS", which was used for manual
segmentation in 2D slices of 3D or 3D+t images.
Re-implementation was chosen because it seemed to be easier to write
documentation and tests for newly developed code. In addition, the old code had
some design weaknesses (e.g. a monolithic class), which would be hard to
maintain in the future.
By now Segmentation is a well tested and easily extensible vehicle for all kinds of interactive
segmentation applications. A separate page describes how you can extend Segmentation with new
tools in a shared object (DLL): \ref toolextensions.
\section QmitkSegmentationTechnicalPage3 Overview of tasks
We identified the following major tasks:
- Management of images: what is the original patient image, what
images are the active segmentations?
- Management of drawing tools: there is a set of drawing tools, one at
a time is active, that is, someone has to decide which tool will receive mouse
(and other) events.
- Drawing tools: each tool can modify a segmentation in reaction to
user interaction. To do so, the tools have to know about the relevant images.
- Slice manipulation: drawing tools need to have means to extract a
single slice from an image volume and to write a single slice back into an image
volume.
- Interpolation of unsegmented slices: some class has to keep track of
all the segmentations in a volume and generate suggestions for missing slices.
This should be possible in all three orthogonal slice direction.
- Undo: Slice manipulations should be undoable, no matter whether a
tool or the interpolation mechanism changed something.
- GUI: Integration of everything.
\section QmitkSegmentationTechnicalPage4 Classes involved
The above blocks correspond to a number of classes. Here is an overview of all
related classes with their responsibilities and relations:
\imageMacro{QmitkSegmentation_InteractiveSegmentationClasses.png,"",16.00}
- Management of images: mitk::ToolManager has a set of reference
data (original images) and a second set of working data (segmentations).
mitk::Tool objects know a ToolManager and can ask the manager for the currently
relevant images. There are two GUI elements that enable
the user to modify the set of reference and working images (QmitkToolReferenceDataSelectionBox and QmitkToolWorkingDataSelectionBox). GUI and non-GUI
classes are coupled by itk::Events (non-GUI to GUI) and direct method calls (GUI
to non-GUI).
- Management of drawing tools: As a second task, ToolManager manages all available tools and makes sure that one at a time is able to receive MITK events.
The GUI for selecting tools is implemented in QmitkToolSelectionBox.
- Drawing tools: Drawing tools all inherit from mitk::Tool, which is a
mitk::StateMachine. There is a number of derivations from Tool, each offering
some helper methods for specific sub-classes, like manipulation of 2D slices.
Tools are instantiated through the itk::ObjectFactory, which means that there is
also one factory for each tool (e.g. mitk::AddContourToolFactory). For the GUI representation, each tool has an
identification, consisting of a name and an icon (XPM). The actual drawing
methods are mainly implemented in mitk::SegTool2D (helper methods) and its
sub-classes for region growing, freehand drawing, etc.
- Slice manipulation: There are two filters for manipulation of slices
inside a 3D image volume. mitk::ExtractImageFilter retrieves a single 2D slice
from a 3D volume. mitk::OverwriteSliceImageFilter replaces a slice inside a 3D
volume with a second slice which is a parameter to the filter. These classes are
used extensively by most of the tools to fulfill their task.
mitk::OverwriteSliceImageFilter cooperates with the interpolation classes to
inform them of single slice modifications.
- Interpolation of unsegmented slices: There are two classes involved
in interpolation: mitk::SegmentationInterpolationController knows a mitk::Image (the
segmentation) and scans its contents for slices with non-zero pixels. It keeps
track of changes in the image and is always able to tell, which neighbors of a
slice (in the three orthogonal slice directions) contain segmentations. The
class also performs this interpolation for single slices on demand.
Again, we have a second class responsible for the GUI:
QmitkSlicesInterpolator enables/disables interpolation and offers to
accept interpolations for one or all slices.
- Undo: Undo functionality is implemented in mitk::OverwriteSliceImageFilter,
since this is the central place where all image modifications are made. The filter stores a binary difference image
to the undo stack as a mitk::ApplyDiffImageOperation. When the user requests undo, this ApplyDiffImageOperation
will be executed by a singleton class DiffImageApplier. The operation itself observes the image, which it refers to,
for itk::DeleteEvent, so no undo operation will be executed on/for images that have already been destroyed.
-
- GUI: The top-level GUI is the functionality
+
- GUI: The top-level GUI is the view
QmitkSegmentation, which is very thin in comparison to ERIS. There are
separate widgets for image and tool selection, for interpolation. Additionaly,
there are some methods to create, delete, crop, load and save segmentations.
**/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolExtensionsGeneralOverview.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolExtensionsGeneralOverview.dox
index 75fe65f746..47b868ad49 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolExtensionsGeneralOverview.dox
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolExtensionsGeneralOverview.dox
@@ -1,182 +1,182 @@
/**
\page toolextensions How to extend the Segmentation view with external tools
\warning This documentation is outdated (see bug 19726).
- \ref ToolExtensionsGeneralOverview2
- \ref ToolExtensionsGeneralOverview3
- \ref ToolExtensionsGeneralOverview31
- \ref ToolExtensionsGeneralOverview32
- \ref ToolExtensionsGeneralOverview33
- \ref ToolExtensionsGeneralOverview4
- \ref ToolExtensionsGeneralOverview5
- \ref ToolExtensionsGeneralOverview6
\section ToolExtensionsGeneralOverview2 Introduction
The application for manual segmentation in MITK (Segmentation view) comes
with a tool class framework that is extensible with new tools (description at
\ref QmitkSegmentationTechnicalPage). The usual way
to create new tools (since it is mostly used inside DKFZ) is to just add new
files to the MITK source code tree. However, this requires to be familiar with
the MITK build system and turnaround time during development might be long
(recompiling parts of MITK again and again).
For external users who just want to use
MITK as a library and application, there is a way to create new segmentation
tools in an MITK external project, which will compile the new tools into a
shared object (DLL). Such shared objects can be loaded via the ITK object factory
and its autoload feature on application startup. This document describes
how to build such external extensions.
Example files can be found in the MITK source code in the directory
${MITK_SOURCE_DIR}/QApplications/ToolExtensionsExample/.
\section ToolExtensionsGeneralOverview3 What might be part of an extension
The extension concept assumes that you want to create one or several new
interactive segmentation tools for Segmentation or another MITK
-functionality that uses the tools infrastructure. In the result you
+view that uses the tools infrastructure. In the result you
will create a shared object (DLL), which contains several tools and their GUI
counterparts, plus optional code that your extension requires. The following
sections shortly describe each of these parts.
\subsection ToolExtensionsGeneralOverview31 Tool classes
A tool is basically any subclass of mitk::Tool. Tools are created at runtime
through the ITK object factory (so they inherit from itk::Object). Tools
should handle the interaction part of a segmentation method, i.e. create
seed points, draw contours, etc., in order to parameterize segmentation algorithms.
Simple algorithms can even be part of a tool. A tools is identified by icon (XPM format),
name (short string) and optionally a group name (e.g. the group name for Segmentation
is "default").
There is a naming convention: you should put a tool called \c mitk::ExternalTool into
files called \c mitkExternalTool.h and \c mitkExternalTool.cpp. This is \e required if
you use the convenience macros described below, because there need to be ITK factories,
which names are directly derived from the file names of the tools. For the example of mitk::ExternalTool
there would be a factory called \c mitk::ExternalToolFactory in a file named \c mitkExternalToolFactory.cpp.
\subsection ToolExtensionsGeneralOverview32 GUI classes for tools
Tools are non-graphical classes that only implement interactions in renderwindows. However,
some tools will need a means to allow the user to set some parameters -- a graphical user interface, GUI.
In the Qt3 case, tool GUIs inherit from QmitkToolGUI, which is a mixture of QWidget and itk::Object.
Tool GUIs are also created through the ITK object factory.
Tools inform their GUIs about state changes by messages. Tool GUIs communicate with their associated tools
via direct method calls (they know their tools). See mitk::BinaryThresholdTool for examples.
Again a naming convention: if the convenience macros for tool extension shared objects are used,
you have to put a tool GUI called \c QmitkExternalToolGUI into a files named \c QmitkExternalToolGUI.cpp
and \c QmitkExternalToolGUI.h. The convenience macro will create a factory called \c QmitkExternalToolGUIFactory
into a file named \c QmitkExternalToolGUIFactory.cpp.
\subsection ToolExtensionsGeneralOverview33 Additional files
If you are writing tools MITK externally, these tools might depend on additional files, e.g.
segmentation algorithms. These can also be compiled into a tool extension shared object.
\section ToolExtensionsGeneralOverview4 Writing a CMake file for a tool extension
Summing up the last section, an example tool extension could comprise the following files:
\verbatim
mitkExternalTool.h \
mitkExternalTool.png >--- implementing mitk::ExternalTool (header, icon, implementation)
mitkExternalTool.cpp /
QmitkExternalToolGUI.h ,-- implementing a GUI for mitk::ExternalTool
QmitkExternalToolGUI.cpp /
externalalgorithm.h \
externalalgorithm.cpp \
externalalgorithmsolver.h >-- a couple of files (not related to MITK tools)
externalalgorithmsolver.cpp /
\endverbatim
This should all be compiled into one shared object. Just like ITK, VTK and MITK we
will use CMake for this purpose (I assume you either know or are willing to learn about
www.cmake.org)
A CMake file for the above example would look like this:
\code
project( ExternalTool )
find_package(ITK)
find_package(MITK)
find_package(Qt3)
add_definitions(${QT_DEFINITIONS})
set( TOOL_QT3GUI_FILES
QmitkExternalToolGUI.cpp
)
set( TOOL_FILES
mitkExternalTool.cpp
)
set( TOOL_ADDITIONAL_CPPS
externalalgorithm.cpp
externalalgorithmsolver.cpp
)
set( TOOL_ADDITIONAL_MOC_H
)
MITK_GENERATE_TOOLS_LIBRARY(mitkExternalTools)
\endcode
Basically, you only have to change the definitions of \c TOOL_FILES and, optionally,
\c TOOL_QT3GUI_FILES, \c TOOL_ADDITIONAL_CPPS and \c TOOL_ADDITIONAL_MOC_H.
For all .cpp files in \c TOOL_FILES and \c TOOL_QT3GUI_FILES there will be factories
created assuming the naming conventions described in the sections above.
Files listed in \c TOOL_ADDITIONAL_CPPS will just be compiled. Files listed in
\c TOOL_ADDITIONAL_MOC_H will be run through Qts meta object compiler \c moc --
this is neccessary for all objects that have the Q_OBJECT macro in their declaration.
\c moc will create new files that will also be compiled into the library.
\section ToolExtensionsGeneralOverview5 Compiling the extension
For compiling a tool extension, you will need a compiled version of MITK. We will
assume MITK was compiled into /home/user/mitk/debug. You need to build MITK with
BUILD_SHARED_CORE turned on!
You build the tool extension just like any other CMake based project:
\li know where your source code is (e.g. /home/user/mitk/tool-extension-src)
\li change into the directory, where you want to compile the shared object (e.g. /home/user/mitk/tool-extension-debug)
\li invoke cmake: ccmake /home/user/mitk/tool-extension-src
\li configure (press c or the "configure" button)
\li set the ITK_DIR variable to the directory, where you compiled ITK
\li set the MITK_DIR variable to the directory, where you compiled MITK: /home/user/mitk/debug
\li configure (press "c" or the "configure" button)
\li generate (press "g" or the "generate" button)
This should do it and leave you with a or project file or Makefile that you can compile (using make or VisualStudio).
\section ToolExtensionsGeneralOverview6 Configuring ITK autoload
If the compile succeeds, you will get a library mitkExternalTools.dll or libmitkExternalTools.so.
This library exports a symbol \c itkLoad which is expected by the ITK object factory.
On application startup the ITK object factory will search a list of directories from
the environment variable \c ITK_AUTOLOAD_PATH. Set this environment variable to your binary directory (/home/user/mitk/tool-extension-debug).
The ITK object factory will load all shared objects that it finds in the specified directories
and will test if they contain a symbol (function pointer) \c itkLoad, which is expected
to return a pointer to a itk::ObjectFactoryBase instance. If such a symbol is found, the
returned factory will be registered with the ITK object factory.
If you successfully followed all the steps above, MITK will find your mitk::ExternalTool on
application startup, when the ITK object factory is asked to create all known instances of
mitk::Tool. Furthermore, if your mitk::ExternalTool claims to be part of the "default" group,
there will be a new icon in Segmentation, which activates your tool.
Have fun! (And Windows users: welcome to the world of DLLs)
**/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.segmentation/manifest_headers.cmake
index 6d9c997827..f7cd162d1a 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/manifest_headers.cmake
+++ b/Plugins/org.mitk.gui.qt.segmentation/manifest_headers.cmake
@@ -1,5 +1,5 @@
set(Plugin-Name "MITK Segmentation")
set(Plugin-Version "1.0.0")
set(Plugin-Vendor "DKFZ, Medical and Biological Informatics")
set(Plugin-ContactAddress "http://www.mitk.org")
-set(Require-Plugin org.mitk.gui.qt.common.legacy org.mitk.gui.qt.datamanager)
+set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager)
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.cpp
index 8d8c6aead3..a02a27ed04 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.cpp
@@ -1,198 +1,198 @@
/*===================================================================
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 "QmitkAutocropAction.h"
#include "mitkAutoCropImageFilter.h"
#include "mitkImageCast.h"
#include "mitkImageWriteAccessor.h"
#include "mitkRenderingManager.h"
#include "mitkProgressBar.h"
#include
//needed for qApp
#include
QmitkAutocropAction::QmitkAutocropAction()
{
}
QmitkAutocropAction::~QmitkAutocropAction()
{
}
void QmitkAutocropAction::Run( const QList &selectedNodes )
{
foreach ( mitk::DataNode::Pointer node, selectedNodes )
{
if (node)
{
mitk::Image::Pointer image = dynamic_cast( node->GetData() );
if (image.IsNull()) return;
mitk::ProgressBar::GetInstance()->AddStepsToDo(10);
mitk::ProgressBar::GetInstance()->Progress(2);
qApp->processEvents();
mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New();
cropFilter->SetInput( image );
cropFilter->SetBackgroundValue( 0 );
try
{
cropFilter->Update();
image = cropFilter->GetOutput();
if (image.IsNotNull())
{
if (image->GetDimension() == 4)
{
MITK_INFO << "4D AUTOCROP DOES NOT WORK AT THE MOMENT";
throw "4D AUTOCROP DOES NOT WORK AT THE MOMENT";
unsigned int timesteps = image->GetDimension(3);
for (unsigned int i = 0; i < timesteps; i++)
{
mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
imageTimeSelector->SetInput(image);
imageTimeSelector->SetTimeNr(i);
imageTimeSelector->UpdateLargestPossibleRegion();
// We split a long nested code line into separate calls for debugging:
mitk::ImageSource::OutputImageType *_3dSlice = imageTimeSelector->GetOutput();
mitk::Image::Pointer _cropped3dSlice = this->IncreaseCroppedImageSize(_3dSlice);
// +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++ BUG +++
mitk::ImageWriteAccessor imAccess(_cropped3dSlice);
void *_data = imAccess.GetData();
//
// We write some stripes into the image
if ((i & 1) == 0)
{
int depth = _cropped3dSlice->GetDimension(2);
int height = _cropped3dSlice->GetDimension(1);
int width = _cropped3dSlice->GetDimension(0);
for (int z = 0; z < depth; ++z)
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
reinterpret_cast(_data)[(width * height * z) + (width * y) + x] = x & 1;
//
}
image->SetVolume(_data, i);
}
node->SetData( image ); // bug fix 3145
}
else
{
node->SetData( this->IncreaseCroppedImageSize(image) ); // bug fix 3145
}
// Reinit node
mitk::RenderingManager::GetInstance()->InitializeViews(
node->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
catch(...)
{
MITK_ERROR << "Cropping image failed...";
}
mitk::ProgressBar::GetInstance()->Progress(8);
}
else
{
MITK_INFO << " a NULL node selected";
}
}
}
mitk::Image::Pointer QmitkAutocropAction::IncreaseCroppedImageSize( mitk::Image::Pointer image )
{
typedef itk::Image< short, 3 > ImageType;
typedef itk::Image< unsigned char, 3 > PADOutputImageType;
ImageType::Pointer itkTransformImage = ImageType::New();
mitk::CastToItkImage( image, itkTransformImage );
typedef itk::ConstantPadImageFilter< ImageType, PADOutputImageType > PadFilterType;
PadFilterType::Pointer padFilter = PadFilterType::New();
unsigned long upperPad[3];
unsigned long lowerPad[3];
int borderLiner = 3;
mitk::Point3D mitkOriginPoint;
double origin[3];
origin[0]=0;
origin[1]=0;
origin[2]=0;
itkTransformImage->SetOrigin(origin);
lowerPad[0]=borderLiner;
lowerPad[1]=borderLiner;
lowerPad[2]=borderLiner;
upperPad[0]=borderLiner;
upperPad[1]=borderLiner;
upperPad[2]=borderLiner;
padFilter->SetInput(itkTransformImage);
padFilter->SetConstant(0);
padFilter->SetPadUpperBound(upperPad);
padFilter->SetPadLowerBound(lowerPad);
padFilter->UpdateLargestPossibleRegion();
mitk::Image::Pointer paddedImage = mitk::Image::New();
paddedImage->InitializeByItk(padFilter->GetOutput());
mitk::CastToMitkImage(padFilter->GetOutput(), paddedImage);
//calculate translation according to padding to get the new origin
mitk::Point3D paddedOrigin = image->GetGeometry()->GetOrigin();
mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
paddedOrigin[0] -= (borderLiner)*spacing[0];
paddedOrigin[1] -= (borderLiner)*spacing[1];
paddedOrigin[2] -= (borderLiner)*spacing[2];
paddedImage->GetGeometry()->SetOrigin( paddedOrigin );
return paddedImage;
}
void QmitkAutocropAction::SetSmoothed(bool /*smoothed*/)
{
//not needed
}
void QmitkAutocropAction::SetDecimated(bool /*decimated*/)
{
//not needed
}
void QmitkAutocropAction::SetDataStorage(mitk::DataStorage* /*dataStorage*/)
{
//not needed
}
-void QmitkAutocropAction::SetFunctionality(berry::QtViewPart* /*functionality*/)
+void QmitkAutocropAction::SetFunctionality(berry::QtViewPart* /*view*/)
{
//not needed
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.h
index ab2cf06897..7077a51602 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkAutocropAction.h
@@ -1,56 +1,54 @@
/*===================================================================
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 QMITK_AUTOCROPACTION_H
#define QMITK_AUTOCROPACTION_H
#include "mitkIContextMenuAction.h"
#include "org_mitk_gui_qt_segmentation_Export.h"
#include "vector"
#include "mitkDataNode.h"
#include "mitkImage.h"
-class QmitkStdMultiWidget;
-
class MITK_QT_SEGMENTATION QmitkAutocropAction : public QObject, public mitk::IContextMenuAction
{
Q_OBJECT
Q_INTERFACES(mitk::IContextMenuAction)
public:
QmitkAutocropAction();
virtual ~QmitkAutocropAction();
//interface methods
void Run( const QList& selectedNodes ) override;
void SetDataStorage(mitk::DataStorage* dataStorage) override;
void SetSmoothed(bool smoothed) override;
void SetDecimated(bool decimated) override;
- void SetFunctionality(berry::QtViewPart* functionality) override;
+ void SetFunctionality(berry::QtViewPart* view) override;
protected:
mitk::Image::Pointer IncreaseCroppedImageSize( mitk::Image::Pointer image );
private:
typedef QList NodeList;
};
#endif // QMITK_AUTOCROPACTION_H
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.cpp
index 3b651a16f6..1e3b1a4f83 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.cpp
@@ -1,140 +1,139 @@
/*===================================================================
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 "QmitkCreatePolygonModelAction.h"
// MITK
#include
#include
#include
#include
-#include
#include
#include
// Blueberry
#include
#include
#include
#include
using namespace berry;
using namespace mitk;
using namespace std;
QmitkCreatePolygonModelAction::QmitkCreatePolygonModelAction()
{
}
QmitkCreatePolygonModelAction::~QmitkCreatePolygonModelAction()
{
}
void QmitkCreatePolygonModelAction::Run(const QList &selectedNodes)
{
DataNode::Pointer selectedNode = selectedNodes[0];
Image::Pointer image = dynamic_cast(selectedNode->GetData());
if (image.IsNull())
{
return;
}
try
{
// Get preference properties for smoothing and decimation
IPreferencesService* prefService = Platform::GetPreferencesService();
IPreferences::Pointer segPref = prefService->GetSystemPreferences()->Node("/org.mitk.views.segmentation");
bool smoothingHint = segPref->GetBool("smoothing hint", true);
ScalarType smoothing = segPref->GetDouble("smoothing value", 1.0);
ScalarType decimation = segPref->GetDouble("decimation rate", 0.5);
if (smoothingHint)
{
smoothing = 0.0;
Vector3D spacing = image->GetGeometry()->GetSpacing();
for (Vector3D::Iterator iter = spacing.Begin(); iter != spacing.End(); ++iter)
smoothing = max(smoothing, *iter);
}
ShowSegmentationAsSurface::Pointer surfaceFilter = ShowSegmentationAsSurface::New();
// Activate callback functions
itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New();
successCommand->SetCallbackFunction(this, &QmitkCreatePolygonModelAction::OnSurfaceCalculationDone);
surfaceFilter->AddObserver(ResultAvailable(), successCommand);
itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New();
errorCommand->SetCallbackFunction(this, &QmitkCreatePolygonModelAction::OnSurfaceCalculationDone);
surfaceFilter->AddObserver(ProcessingError(), errorCommand);
// set filter parameter
surfaceFilter->SetDataStorage(*m_DataStorage);
surfaceFilter->SetPointerParameter("Input", image);
surfaceFilter->SetPointerParameter("Group node", selectedNode);
surfaceFilter->SetParameter("Show result", true);
surfaceFilter->SetParameter("Sync visibility", false);
surfaceFilter->SetParameter("Median kernel size", 3u);
surfaceFilter->SetParameter("Decimate mesh", m_IsDecimated);
surfaceFilter->SetParameter("Decimation rate", (float) decimation);
if (m_IsSmoothed)
{
surfaceFilter->SetParameter("Apply median", true);
surfaceFilter->SetParameter("Smooth", true);
surfaceFilter->SetParameter("Gaussian SD", sqrtf(smoothing)); // use sqrt to account for setting of variance in preferences
StatusBar::GetInstance()->DisplayText("Smoothed surface creation started in background...");
}
else
{
surfaceFilter->SetParameter("Apply median", false);
surfaceFilter->SetParameter("Smooth", false);
StatusBar::GetInstance()->DisplayText("Surface creation started in background...");
}
surfaceFilter->StartAlgorithm();
}
catch(...)
{
MITK_ERROR << "Surface creation failed!";
}
}
void QmitkCreatePolygonModelAction::OnSurfaceCalculationDone()
{
StatusBar::GetInstance()->Clear();
}
void QmitkCreatePolygonModelAction::SetDataStorage(DataStorage *dataStorage)
{
m_DataStorage = dataStorage;
}
void QmitkCreatePolygonModelAction::SetSmoothed(bool smoothed)
{
m_IsSmoothed = smoothed;
}
void QmitkCreatePolygonModelAction::SetDecimated(bool decimated)
{
m_IsDecimated = decimated;
}
void QmitkCreatePolygonModelAction::SetFunctionality(QtViewPart *)
{
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.h
index d0276e9260..0711757314 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkCreatePolygonModelAction.h
@@ -1,57 +1,55 @@
/*===================================================================
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 QMITKCREATEPOLYGONMODELACTION_H
#define QMITKCREATEPOLYGONMODELACTION_H
#include
// Parent classes
#include
#include
// Data members
#include
-class QmitkStdMultiWidget;
-
class MITK_QT_SEGMENTATION QmitkCreatePolygonModelAction : public QObject, public mitk::IContextMenuAction
{
Q_OBJECT
Q_INTERFACES(mitk::IContextMenuAction)
public:
QmitkCreatePolygonModelAction();
~QmitkCreatePolygonModelAction();
// IContextMenuAction
void Run(const QList &selectedNodes) override;
void SetDataStorage(mitk::DataStorage *dataStorage) override;
void SetSmoothed(bool smoothed) override;
void SetDecimated(bool decimated) override;
- void SetFunctionality(berry::QtViewPart *functionality) override;
+ void SetFunctionality(berry::QtViewPart* view) override;
void OnSurfaceCalculationDone();
private:
QmitkCreatePolygonModelAction(const QmitkCreatePolygonModelAction &);
QmitkCreatePolygonModelAction & operator=(const QmitkCreatePolygonModelAction &);
mitk::DataStorage::Pointer m_DataStorage;
bool m_IsSmoothed;
bool m_IsDecimated;
};
#endif
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.cpp
index 312901db9c..942b1c216f 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.cpp
@@ -1,636 +1,633 @@
/*===================================================================
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 "QmitkDeformableClippingPlaneView.h"
#include "mitkClippingPlaneInteractor3D.h"
#include "mitkHeightFieldSurfaceClipImageFilter.h"
+#include
#include "mitkImageToSurfaceFilter.h"
#include "mitkInteractionConst.h"
#include "mitkLabeledImageLookupTable.h"
#include "mitkLabeledImageVolumeCalculator.h"
#include "mitkLevelWindowProperty.h"
#include "mitkLookupTableProperty.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkRenderingModeProperty.h"
#include "mitkRotationOperation.h"
#include "mitkSurfaceDeformationDataInteractor3D.h"
#include "mitkSurfaceVtkMapper3D.h"
#include "mitkVtkRepresentationProperty.h"
#include "usModuleRegistry.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkProperty.h"
#include
const std::string QmitkDeformableClippingPlaneView::VIEW_ID = "org.mitk.views.deformableclippingplane";
QmitkDeformableClippingPlaneView::QmitkDeformableClippingPlaneView()
- : QmitkFunctionality()
- , m_MultiWidget(NULL)
+ : QmitkAbstractView()
, m_ReferenceNode(NULL)
, m_WorkingNode(NULL)
{
}
QmitkDeformableClippingPlaneView::~QmitkDeformableClippingPlaneView()
{
}
void QmitkDeformableClippingPlaneView::CreateQtPartControl(QWidget *parent)
{
// create GUI widgets
m_Controls.setupUi(parent);
this->CreateConnections();
}
-void QmitkDeformableClippingPlaneView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
+void QmitkDeformableClippingPlaneView::SetFocus()
{
- m_MultiWidget = &stdMultiWidget;
-}
-
-void QmitkDeformableClippingPlaneView::StdMultiWidgetNotAvailable()
-{
- m_MultiWidget = NULL;
+ m_Controls.createNewPlanePushButton->setFocus();
}
void QmitkDeformableClippingPlaneView::CreateConnections()
{
mitk::NodePredicateProperty::Pointer clipPredicate = mitk::NodePredicateProperty::New("clippingPlane",mitk::BoolProperty::New(true));
//set only clipping planes in the list of the selector
- m_Controls.clippingPlaneSelector->SetDataStorage(this->GetDefaultDataStorage());
+ m_Controls.clippingPlaneSelector->SetDataStorage(this->GetDataStorage());
m_Controls.clippingPlaneSelector->SetPredicate(clipPredicate);
//No working data set, yet
m_Controls.volumeGroupBox->setEnabled(false);
m_Controls.interactionSelectionBox->setEnabled(false);
m_Controls.noSelectedImageLabel->show();
m_Controls.planesWarningLabel->hide();
connect (m_Controls.translationPushButton, SIGNAL(toggled(bool)), this, SLOT(OnTranslationMode(bool)));
connect (m_Controls.rotationPushButton, SIGNAL(toggled(bool)), this, SLOT(OnRotationMode(bool)));
connect (m_Controls.deformationPushButton, SIGNAL(toggled(bool)), this, SLOT(OnDeformationMode(bool)));
connect (m_Controls.createNewPlanePushButton, SIGNAL(clicked()), this, SLOT(OnCreateNewClippingPlane()));
connect (m_Controls.updateVolumePushButton, SIGNAL(clicked()), this, SLOT(OnCalculateClippingVolume()));
connect (m_Controls.clippingPlaneSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),
this, SLOT(OnComboBoxSelectionChanged(const mitk::DataNode*)));
}
void QmitkDeformableClippingPlaneView::Activated()
{
- QmitkFunctionality::Activated();
//If a tube graph already exist in the data storage, set the working node correctly
m_WorkingNode = m_Controls.clippingPlaneSelector->GetSelectedNode();
this->UpdateView();
}
void QmitkDeformableClippingPlaneView::Deactivated()
{
if(m_WorkingNode.IsNotNull())
{
if(m_WorkingNode->GetDataInteractor().IsNotNull())
m_WorkingNode->SetDataInteractor(NULL);
}
- QmitkFunctionality::Deactivated();
+}
+
+void QmitkDeformableClippingPlaneView::Visible()
+{
+}
+
+void QmitkDeformableClippingPlaneView::Hidden()
+{
}
void QmitkDeformableClippingPlaneView::OnComboBoxSelectionChanged( const mitk::DataNode* node )
{
this->DeactivateInteractionButtons();
mitk::DataNode* selectedNode = const_cast(node);
if( selectedNode != NULL )
{
if(m_WorkingNode.IsNotNull())
selectedNode->SetDataInteractor(m_WorkingNode->GetDataInteractor());
m_WorkingNode = selectedNode;
}
this->UpdateView();
}
void QmitkDeformableClippingPlaneView::OnSelectionChanged(mitk::DataNode* node)
{
- std::vector nodes;
+ berry::IWorkbenchPart::Pointer nullPart;
+ QList nodes;
nodes.push_back(node);
- this->OnSelectionChanged(nodes);
+ this->OnSelectionChanged(nullPart, nodes);
}
-void QmitkDeformableClippingPlaneView::OnSelectionChanged(std::vector nodes)
+void QmitkDeformableClippingPlaneView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes)
{
bool isClippingPlane(false);
- for(unsigned int i = 0; i < nodes.size(); ++i)
+ for (mitk::DataNode::Pointer node: nodes)
{
- if(nodes.at(i)->GetBoolProperty("clippingPlane", isClippingPlane))
- m_Controls.clippingPlaneSelector->setCurrentIndex( m_Controls.clippingPlaneSelector->Find(nodes.at(i)) );
+ if(node->GetBoolProperty("clippingPlane", isClippingPlane))
+ m_Controls.clippingPlaneSelector->setCurrentIndex( m_Controls.clippingPlaneSelector->Find(node) );
else
{
- if(dynamic_cast (nodes.at(i)->GetData())&& nodes.at(i))
+ if(dynamic_cast (node->GetData())&& node)
{
- if(m_ReferenceNode.IsNotNull() && nodes.at(i)->GetData() == m_ReferenceNode->GetData())
+ if(m_ReferenceNode.IsNotNull() && node->GetData() == m_ReferenceNode->GetData())
return;
- m_ReferenceNode =nodes.at(i);
+ m_ReferenceNode =node;
}
}
}
this->UpdateView();
}
void::QmitkDeformableClippingPlaneView::NodeChanged(const mitk::DataNode* /*node*/)
{
this->UpdateView();
}
void QmitkDeformableClippingPlaneView::NodeRemoved(const mitk::DataNode* node)
{
bool isClippingPlane(false);
if (node->GetBoolProperty("clippingPlane", isClippingPlane))
{
if(this->GetAllClippingPlanes()->Size()<=1)
{
m_WorkingNode = NULL;
this->UpdateView();
}
else
{
if (GetAllClippingPlanes()->front()!= node)
this->OnSelectionChanged(GetAllClippingPlanes()->front());
else
this->OnSelectionChanged(GetAllClippingPlanes()->ElementAt(1));
}
}
else
{
if(m_ReferenceNode.IsNotNull())
{
if(node->GetData() == m_ReferenceNode->GetData())
{
m_ReferenceNode = NULL;
m_Controls.volumeList->clear();
}
this->UpdateView();
}
}
}
void QmitkDeformableClippingPlaneView::UpdateView()
{
if (m_ReferenceNode.IsNotNull())
{
m_Controls.noSelectedImageLabel->hide();
m_Controls.selectedImageLabel->setText(QString::fromUtf8(m_ReferenceNode->GetName().c_str()));
if (m_WorkingNode.IsNotNull())
{
bool isSegmentation(false);
m_ReferenceNode->GetBoolProperty("binary", isSegmentation);
m_Controls.interactionSelectionBox->setEnabled(true);
m_Controls.volumeGroupBox->setEnabled(isSegmentation);
//clear list --> than search for all shown clipping plans (max 7 planes)
m_Controls.selectedVolumePlanesLabel->setText("");
m_Controls.planesWarningLabel->hide();
int volumePlanes=0;
mitk::DataStorage::SetOfObjects::ConstPointer allClippingPlanes = this->GetAllClippingPlanes();
for (mitk::DataStorage::SetOfObjects::ConstIterator itPlanes = allClippingPlanes->Begin(); itPlanes != allClippingPlanes->End(); itPlanes++)
{
bool isVisible(false);
itPlanes.Value()->GetBoolProperty("visible",isVisible);
if (isVisible)
{
if (volumePlanes<7)
{
volumePlanes ++;
m_Controls.selectedVolumePlanesLabel->setText(m_Controls.selectedVolumePlanesLabel->text().append(QString::fromStdString(itPlanes.Value()->GetName()+"\n")));
}
else
{
m_Controls.planesWarningLabel->show();
return;
}
}
}
}
else
{
m_Controls.volumeGroupBox->setEnabled(false);
m_Controls.interactionSelectionBox->setEnabled(false);
m_Controls.selectedVolumePlanesLabel->setText("");
m_Controls.volumeList->clear();
}
}
else
{
m_Controls.volumeGroupBox->setEnabled(false);
m_Controls.noSelectedImageLabel->show();
m_Controls.selectedImageLabel->setText("");
m_Controls.selectedVolumePlanesLabel->setText("");
m_Controls.planesWarningLabel->hide();
if(m_WorkingNode.IsNull())
m_Controls.interactionSelectionBox->setEnabled(false);
else
m_Controls.interactionSelectionBox->setEnabled(true);
}
}
void QmitkDeformableClippingPlaneView::OnCreateNewClippingPlane()
{
this->DeactivateInteractionButtons();
//the new clipping plane
mitk::Surface::Pointer plane = mitk::Surface::New();
mitk::Image::Pointer referenceImage = mitk::Image::New();
vtkSmartPointer planeSource = vtkSmartPointer::New();
// default initialization of the clipping plane
planeSource->SetOrigin( -32.0, -32.0, 0.0 );
planeSource->SetPoint1( 32.0, -32.0, 0.0 );
planeSource->SetPoint2( -32.0, 32.0, 0.0 );
planeSource->SetResolution( 128, 128 );
planeSource->Update();
plane->SetVtkPolyData(planeSource->GetOutput());
double imageDiagonal = 200;
if (m_ReferenceNode.IsNotNull())
{
referenceImage = dynamic_cast (m_ReferenceNode->GetData());
if (referenceImage.IsNotNull())
{
// check if user wants a surface model
if(m_Controls.surfaceModelCheckBox->isChecked())
{
//Check if there is a surface node from the image. If not, create one
bool createSurfaceFromImage(true);
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isSurface = mitk::NodePredicateDataType::New("Surface");
mitk::DataStorage::SetOfObjects::ConstPointer childNodes = GetDataStorage()->GetDerivations(m_ReferenceNode,isSurface, true);
for (mitk::DataStorage::SetOfObjects::ConstIterator itChildNodes = childNodes->Begin();
itChildNodes != childNodes->End(); itChildNodes++)
{
if (itChildNodes.Value().IsNotNull() && itChildNodes->Value()->GetName().compare(m_ReferenceNode->GetName()) == 0)
{
createSurfaceFromImage = false;
itChildNodes.Value()->SetVisibility(true);
}
}
if(createSurfaceFromImage)
{
//Lsg 2: Surface for the 3D-perspective
mitk::ImageToSurfaceFilter::Pointer surfaceFilter = mitk::ImageToSurfaceFilter::New();
surfaceFilter->SetInput(referenceImage);
surfaceFilter->SetThreshold(1);
surfaceFilter->SetSmooth(true);
//Downsampling
surfaceFilter->SetDecimate(mitk::ImageToSurfaceFilter::DecimatePro);
mitk::DataNode::Pointer surfaceNode = mitk::DataNode::New();
surfaceNode->SetData(surfaceFilter->GetOutput());
surfaceNode->SetProperty("color", m_ReferenceNode->GetProperty("color"));
surfaceNode->SetOpacity(0.5);
surfaceNode->SetName(m_ReferenceNode->GetName());
GetDataStorage()->Add(surfaceNode, m_ReferenceNode);
}
}
//If an image is selected trim the plane to this.
imageDiagonal = referenceImage->GetGeometry()->GetDiagonalLength();
plane->SetOrigin( referenceImage->GetGeometry()->GetCenter());
// Rotate plane
mitk::Vector3D rotationAxis;
mitk::FillVector3D(rotationAxis, 0.0, 1.0, 0.0);
mitk::RotationOperation op(mitk::OpROTATE, referenceImage->GetGeometry()->GetCenter(), rotationAxis, 90.0);
plane->GetGeometry()->ExecuteOperation(&op);
}
}
//set some properties for the clipping plane
// plane->SetExtent(imageDiagonal * 0.9, imageDiagonal * 0.9);
// plane->SetResolution(64, 64);
// eequivalent to the extent and resolution function of the clipping plane
const double x = imageDiagonal * 0.9;
planeSource->SetOrigin( -x / 2.0, -x / 2.0, 0.0 );
planeSource->SetPoint1( x / 2.0, -x / 2.0, 0.0 );
planeSource->SetPoint2( -x / 2.0, x / 2.0, 0.0 );
planeSource->SetResolution( 64, 64 );
planeSource->Update();
plane->SetVtkPolyData(planeSource->GetOutput());
// Set scalars (for colorization of plane)
vtkFloatArray *scalars = vtkFloatArray::New();
scalars->SetName("Distance");
scalars->SetNumberOfComponents(1);
for ( unsigned int i = 0; i < plane->GetVtkPolyData(0)->GetNumberOfPoints(); ++i)
{
scalars->InsertNextValue(-1.0);
}
plane->GetVtkPolyData(0)->GetPointData()->SetScalars(scalars);
plane->GetVtkPolyData(0)->GetPointData()->Update();
mitk::DataNode::Pointer planeNode = mitk::DataNode::New();
planeNode->SetData(plane);
std::stringstream planeName;
planeName << "ClippingPlane ";
planeName << this->GetAllClippingPlanes()->Size() + 1;
planeNode->SetName(planeName.str());
planeNode->AddProperty("clippingPlane",mitk::BoolProperty::New(true));
// Make plane pickable
planeNode->SetBoolProperty("pickable", true);
mitk::SurfaceVtkMapper3D::SetDefaultProperties(planeNode);
// Don't include plane in bounding box!
planeNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
// Set lookup table for plane surface visualization
vtkSmartPointer lookupTable = vtkSmartPointer::New();
lookupTable->SetHueRange(0.6, 0.0);
lookupTable->SetSaturationRange(1.0, 1.0);
lookupTable->SetValueRange(1.0, 1.0);
lookupTable->SetTableRange(-1.0, 1.0);
lookupTable->Build();
mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
lut->SetVtkLookupTable(lookupTable);
mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(lut);
planeNode->SetProperty("LookupTable", prop);
planeNode->SetBoolProperty("scalar visibility", true);
planeNode->SetBoolProperty("color mode", true);
planeNode->SetFloatProperty("ScalarsRangeMinimum", -1.0);
planeNode->SetFloatProperty("ScalarsRangeMaximum", 1.0);
// Configure material so that only scalar colors are shown
planeNode->SetColor(0.0f,0.0f,0.0f);
planeNode->SetOpacity(1.0f);
planeNode->SetFloatProperty("material.wireframeLineWidth",2.0f);
//Set view of plane to wireframe
planeNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME));
//Set the plane as working data for the tools and selected it
this->OnSelectionChanged (planeNode);
//Add the plane to data storage
this->GetDataStorage()->Add(planeNode);
//Change the index of the selector to the new generated node
m_Controls.clippingPlaneSelector->setCurrentIndex( m_Controls.clippingPlaneSelector->Find(planeNode) );
m_Controls.interactionSelectionBox->setEnabled(true);
- // set crosshair invisible
- mitk::DataNode* dataNode;
-
- dataNode = this->m_MultiWidget->GetWidgetPlane1();
- if(dataNode) dataNode->SetVisibility(false);
- dataNode = this->m_MultiWidget->GetWidgetPlane2();
- if(dataNode) dataNode->SetVisibility(false);
- dataNode = this->m_MultiWidget->GetWidgetPlane3();
- if(dataNode) dataNode->SetVisibility(false);
+ if (auto renderWindowPart = dynamic_cast(this->GetRenderWindowPart()))
+ {
+ renderWindowPart->EnableSlicingPlanes(false);
+ }
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDeformableClippingPlaneView::OnCalculateClippingVolume()
{
bool isSegmentation(false);
m_ReferenceNode->GetBoolProperty("binary", isSegmentation);
if(m_ReferenceNode.IsNull() || !isSegmentation)
{
MITK_ERROR << "No segmentation selected! Can't calculate volume";
return;
}
std::vector clippingPlanes;
mitk::DataStorage::SetOfObjects::ConstPointer allClippingPlanes = this->GetAllClippingPlanes();
for (mitk::DataStorage::SetOfObjects::ConstIterator itPlanes = allClippingPlanes->Begin(); itPlanes != allClippingPlanes->End(); itPlanes++)
{
bool isVisible(false);
itPlanes.Value()->GetBoolProperty("visible",isVisible);
mitk::Surface* plane = dynamic_cast(itPlanes.Value()->GetData());
if (isVisible && plane)
clippingPlanes.push_back(plane);
}
if (clippingPlanes.empty())
{
MITK_ERROR << "No clipping plane selected! Can't calculate volume";
return;
}
// deactivate Tools
this->DeactivateInteractionButtons();
//Clear the list of volumes, before calculating the new values
m_Controls.volumeList->clear();
m_ReferenceNode->SetBoolProperty("visible", false);
//set some properties for clipping the image-->Output: labled Image
mitk::HeightFieldSurfaceClipImageFilter::Pointer surfaceClipFilter = mitk::HeightFieldSurfaceClipImageFilter::New();
surfaceClipFilter->SetInput(dynamic_cast (m_ReferenceNode->GetData()));
surfaceClipFilter->SetClippingModeToMultiPlaneValue();
surfaceClipFilter->SetClippingSurfaces(clippingPlanes);
surfaceClipFilter->Update();
//delete the old clipped image node
mitk::DataStorage::SetOfObjects::ConstPointer oldClippedNode = this->GetDataStorage()->GetSubset(mitk::NodePredicateProperty::New("name", mitk::StringProperty::New("Clipped Image")));
if (oldClippedNode.IsNotNull())
this->GetDataStorage()->Remove(oldClippedNode);
//add the new clipped image node
mitk::DataNode::Pointer clippedNode = mitk::DataNode::New();
mitk::Image::Pointer clippedImage = surfaceClipFilter->GetOutput();
clippedImage->DisconnectPipeline();
clippedNode->SetData(clippedImage);
//clippedNode->SetProperty("helper object", mitk::BoolProperty::New(true));
clippedNode->SetName("Clipped Image");
clippedNode->SetColor(1.0,1.0,1.0); // color property will not be used, labeled image lookuptable will be used instead
clippedNode->SetProperty ("use color", mitk::BoolProperty::New(false));
clippedNode->SetOpacity(0.4);
this->GetDataStorage()->Add(clippedNode);
mitk::LabeledImageVolumeCalculator::Pointer volumeCalculator = mitk::LabeledImageVolumeCalculator::New();
volumeCalculator->SetImage(clippedImage);
volumeCalculator->Calculate();
std::vector volumes = volumeCalculator->GetVolumes();
mitk::LabeledImageLookupTable::Pointer lut = mitk::LabeledImageLookupTable::New();
int lablesWithVolume=0;
for(unsigned int i = 1; i < volumes.size(); ++i)
{
if(volumes.at(i)!=0)
{
lablesWithVolume++;
mitk::Color color (GetLabelColor(lablesWithVolume));
lut->SetColorForLabel(i,color.GetRed(), color.GetGreen(), color.GetBlue(), 1.0);
QColor qcolor;
qcolor.setRgbF(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.7);
//output volume as string "x.xx ml"
std::stringstream stream;
stream<< std::fixed << std::setprecision(2)<setText(QString::fromStdString(stream.str()));
item->setBackgroundColor(qcolor);
m_Controls.volumeList->addItem(item);
}
}
//set the rendering mode to use the lookup table and level window
clippedNode->SetProperty("Image Rendering.Mode", mitk::RenderingModeProperty::New(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR));
mitk::LookupTableProperty::Pointer lutProp = mitk::LookupTableProperty::New(lut.GetPointer());
clippedNode->SetProperty("LookupTable", lutProp);
// it is absolutely important, to use the LevelWindow settings provided by
// the LUT generator, otherwise, it is not guaranteed, that colors show
// up correctly.
clippedNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(lut->GetLevelWindow()));
}
mitk::DataStorage::SetOfObjects::ConstPointer QmitkDeformableClippingPlaneView::GetAllClippingPlanes()
{
mitk::NodePredicateProperty::Pointer clipPredicate= mitk::NodePredicateProperty::New("clippingPlane",mitk::BoolProperty::New(true));
mitk::DataStorage::SetOfObjects::ConstPointer allPlanes = GetDataStorage()->GetSubset(clipPredicate);
return allPlanes;
}
mitk::Color QmitkDeformableClippingPlaneView::GetLabelColor(int label)
{
float red, green, blue;
switch ( label % 6 )
{
case 0:
{red = 1.0; green = 0.0; blue = 0.0; break;}
case 1:
{red = 0.0; green = 1.0; blue = 0.0; break;}
case 2:
{red = 0.0; green = 0.0; blue = 1.0;break;}
case 3:
{red = 1.0; green = 1.0; blue = 0.0;break;}
case 4:
{red = 1.0; green = 0.0; blue = 1.0;break;}
case 5:
{red = 0.0; green = 1.0; blue = 1.0;break;}
default:
{red = 0.0; green = 0.0; blue = 0.0;}
}
float tmp[3] = { red, green, blue };
double factor;
int outerCycleNr = label / 6;
int cycleSize = pow(2.0,(int)(log((double)(outerCycleNr))/log( 2.0 )));
if (cycleSize==0)
cycleSize = 1;
int insideCycleCounter = outerCycleNr % cycleSize;
if ( outerCycleNr == 0)
factor = 255;
else
factor = ( 256 / ( 2 * cycleSize ) ) + ( insideCycleCounter * ( 256 / cycleSize ) );
tmp[0]= tmp[0]/256*factor;
tmp[1]= tmp[1]/256*factor;
tmp[2]= tmp[2]/256*factor;
return mitk::Color(tmp);
}
void QmitkDeformableClippingPlaneView::OnTranslationMode(bool check)
{
if(check)
{ //uncheck all other buttons
m_Controls.rotationPushButton->setChecked(false);
m_Controls.deformationPushButton->setChecked(false);
mitk::ClippingPlaneInteractor3D::Pointer affineDataInteractor = mitk::ClippingPlaneInteractor3D::New();
affineDataInteractor->LoadStateMachine("ClippingPlaneInteraction3D.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt"));
affineDataInteractor->SetEventConfig("ClippingPlaneTranslationConfig.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt"));
affineDataInteractor->SetDataNode(m_WorkingNode);
}
else
m_WorkingNode->SetDataInteractor(NULL);
}
void QmitkDeformableClippingPlaneView::OnRotationMode(bool check)
{
if(check)
{ //uncheck all other buttons
m_Controls.translationPushButton->setChecked(false);
m_Controls.deformationPushButton->setChecked(false);
mitk::ClippingPlaneInteractor3D::Pointer affineDataInteractor = mitk::ClippingPlaneInteractor3D::New();
affineDataInteractor->LoadStateMachine("ClippingPlaneInteraction3D.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt"));
affineDataInteractor->SetEventConfig("ClippingPlaneRotationConfig.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt"));
affineDataInteractor->SetDataNode(m_WorkingNode);
}
else
m_WorkingNode->SetDataInteractor(NULL);
}
void QmitkDeformableClippingPlaneView::OnDeformationMode(bool check)
{
if(check)
{ //uncheck all other buttons
m_Controls.translationPushButton->setChecked(false);
m_Controls.rotationPushButton->setChecked(false);
mitk::SurfaceDeformationDataInteractor3D::Pointer surfaceDataInteractor = mitk::SurfaceDeformationDataInteractor3D::New();
surfaceDataInteractor->LoadStateMachine("ClippingPlaneInteraction3D.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt"));
surfaceDataInteractor->SetEventConfig("ClippingPlaneDeformationConfig.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt"));
surfaceDataInteractor->SetDataNode(m_WorkingNode);
}
else
m_WorkingNode->SetDataInteractor(NULL);
}
void QmitkDeformableClippingPlaneView::DeactivateInteractionButtons()
{
m_Controls.translationPushButton->setChecked(false);
m_Controls.rotationPushButton->setChecked(false);
m_Controls.deformationPushButton->setChecked(false);
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.h
index 4ca1432d85..ba0383a9b6 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkDeformableClippingPlaneView.h
@@ -1,99 +1,105 @@
/*===================================================================
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 _QMITKDEFORMABLECLIPPINGPLANEVIEW_H_INCLUDED
#define _QMITKDEFORMABLECLIPPINGPLANEVIEW_H_INCLUDED
#include "ui_QmitkDeformableClippingPlaneViewControls.h"
#include "mitkImage.h"
-#include
+#include
+#include
typedef itk::RGBPixel< float > Color;
/*!
* \ingroup org_mitk_gui_qt_deformableSurface
*
* \brief QmitkDeformableClippingPlaneView
*
* Document your class here.
-*
-* \sa QmitkFunctionality
*/
-class QmitkDeformableClippingPlaneView : public QmitkFunctionality
+class QmitkDeformableClippingPlaneView : public QmitkAbstractView, public mitk::ILifecycleAwarePart
{
// this is needed for all Qt objects that should have a MOC object (everything that derives from QObject)
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkDeformableClippingPlaneView();
virtual ~QmitkDeformableClippingPlaneView();
virtual void CreateQtPartControl(QWidget *parent) override;
/// \brief Creation of the connections of main and control widget
virtual void CreateConnections();
- /// \brief Called when the functionality is activated
+ ///
+ /// Sets the focus to an internal widget.
+ ///
+ virtual void SetFocus() override;
+
+ /// \brief Called when the view gets activated
virtual void Activated() override;
- /// \brief Called when the functionality is deactivated
+ /// \brief Called when the view gets deactivated
virtual void Deactivated() override;
- virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) override;
- virtual void StdMultiWidgetNotAvailable() override;
+ /// \brief Called when the view becomes visible
+ virtual void Visible() override;
+
+ /// \brief Called when the view becomes hidden
+ virtual void Hidden() override;
protected slots:
/// \brief Called when the user clicks the GUI button/makes a selection
void OnComboBoxSelectionChanged(const mitk::DataNode* node);
void OnCreateNewClippingPlane();
void OnCalculateClippingVolume();
void OnTranslationMode(bool check);
void OnRotationMode(bool check);
void OnDeformationMode(bool check);
protected:
/*!
\brief Invoked when the DataManager selection changed
*/
virtual void OnSelectionChanged(mitk::DataNode* node);
- virtual void OnSelectionChanged(std::vector nodes) override;
+ virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override;
virtual void NodeRemoved(const mitk::DataNode* node) override;
virtual void NodeChanged(const mitk::DataNode* node) override;
void UpdateView();
- QmitkStdMultiWidget* m_MultiWidget;
Ui::QmitkDeformableClippingPlaneViewControls m_Controls;
private:
mitk::DataStorage::SetOfObjects::ConstPointer GetAllClippingPlanes();
mitk::Color GetLabelColor(int label);
void DeactivateInteractionButtons();
mitk::DataNode::Pointer m_ReferenceNode;
mitk::DataNode::Pointer m_WorkingNode;
};
#endif // _QMITKDEFORMABLECLIPPINGPLANEVIEW_H_INCLUDED
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.cpp
index 3842d283c4..2f7f181c5c 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.cpp
@@ -1,197 +1,197 @@
/*===================================================================
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 "QmitkOtsuAction.h"
// MITK
#include
#include
#include
#include
#include
#include
#include
#include
#include
// ITK
#include
// Qt
#include
#include
#include
#include
#include
#include
using namespace berry;
using namespace mitk;
using namespace std;
QmitkOtsuAction::QmitkOtsuAction()
: m_OtsuSegmentationDialog(NULL)
{
}
QmitkOtsuAction::~QmitkOtsuAction()
{
}
void QmitkOtsuAction::Run(const QList &selectedNodes)
{
this->m_DataNode = selectedNodes[0];
//this->m_selectedNodes = selectedNodes;
m_OtsuSegmentationDialog = new QDialog(QApplication::activeWindow(),Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
QHBoxLayout* spinBoxLayout = new QHBoxLayout;
QHBoxLayout* buttonLayout = new QHBoxLayout;
m_OtsuSpinBox = new QSpinBox;
m_OtsuSpinBox->setRange(2, 32);
m_OtsuSpinBox->setValue(2);
m_OtsuPushButton = new QPushButton("OK");
QPushButton* CancelButton = new QPushButton("Cancel");
connect(m_OtsuPushButton, SIGNAL(clicked()), this, SLOT(OtsuSegmentationDone()));
connect(CancelButton, SIGNAL(clicked()), m_OtsuSegmentationDialog, SLOT(reject()));
QLabel* numberOfThresholdsLabel = new QLabel("Select number of Regions of Interest:");
numberOfThresholdsLabel->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
layout->addWidget(numberOfThresholdsLabel);
layout->addLayout(spinBoxLayout);
spinBoxLayout->addSpacing(50);
spinBoxLayout->addWidget(m_OtsuSpinBox);
spinBoxLayout->addSpacing(50);
layout->addLayout(buttonLayout);
buttonLayout->addWidget(m_OtsuPushButton);
buttonLayout->addWidget(CancelButton);
m_OtsuSegmentationDialog->setLayout(layout);
m_OtsuSegmentationDialog->setFixedSize(300, 80);
m_OtsuSegmentationDialog->open();
}
void QmitkOtsuAction::OtsuSegmentationDone()
{
this->PerformOtsuSegmentation();
m_OtsuSegmentationDialog->deleteLater();
m_OtsuSegmentationDialog = NULL;
RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkOtsuAction::SetDataStorage(DataStorage *dataStorage)
{
m_DataStorage = dataStorage;
}
-void QmitkOtsuAction::SetFunctionality(QtViewPart* /*functionality*/)
+void QmitkOtsuAction::SetFunctionality(QtViewPart* /*view*/)
{
}
void QmitkOtsuAction::PerformOtsuSegmentation()
{
this->m_OtsuSegmentationDialog->setCursor(Qt::WaitCursor);
int numberOfThresholds = this->m_OtsuSpinBox->value() - 1;
int proceed;
QMessageBox* messageBox = new QMessageBox(QMessageBox::Question, NULL, "The otsu segmentation computation may take several minutes depending on the number of Regions you selected. Proceed anyway?", QMessageBox::Ok | QMessageBox::Cancel);
if (numberOfThresholds >= 5)
{
proceed = messageBox->exec();
if (proceed != QMessageBox::Ok) return;
}
mitk::Image::Pointer mitkImage = 0;
mitkImage = dynamic_cast( this->m_DataNode->GetData() );
try
{
// get selected mitk image
const unsigned short dim = 3;
typedef short InputPixelType;
typedef unsigned char OutputPixelType;
typedef itk::Image< InputPixelType, dim > InputImageType;
typedef itk::Image< OutputPixelType, dim > OutputImageType;
typedef itk::OtsuMultipleThresholdsImageFilter< InputImageType, OutputImageType > FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetNumberOfThresholds(numberOfThresholds);
InputImageType::Pointer itkImage;
mitk::CastToItkImage(mitkImage, itkImage);
filter->SetInput( itkImage );
filter->Update();
mitk::DataNode::Pointer resultNode = mitk::DataNode::New();
std::string nameOfResultImage = this->m_DataNode->GetName();
nameOfResultImage.append("Otsu");
resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) );
resultNode->SetProperty("binary", mitk::BoolProperty::New(false) );
mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New();
renderingMode->SetValue( mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR );
resultNode->SetProperty("Image Rendering.Mode", renderingMode);
mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(lut);
vtkLookupTable *lookupTable = vtkLookupTable::New();
lookupTable->SetHueRange(1.0, 0.0);
lookupTable->SetSaturationRange(1.0, 1.0);
lookupTable->SetValueRange(1.0, 1.0);
lookupTable->SetTableRange(-1.0, 1.0);
lookupTable->Build();
lut->SetVtkLookupTable(lookupTable);
prop->SetLookupTable(lut);
resultNode->SetProperty("LookupTable",prop);
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
mitk::LevelWindow levelwindow;
levelwindow.SetRangeMinMax(0, numberOfThresholds+1);
levWinProp->SetLevelWindow( levelwindow );
resultNode->SetProperty( "levelwindow", levWinProp );
resultNode->SetData( mitk::GrabItkImageMemory( filter->GetOutput() ) );
this->m_DataStorage->Add(resultNode, this->m_DataNode);
this->m_OtsuSegmentationDialog->setCursor(Qt::ArrowCursor);
}
catch( std::exception& err )
{
MITK_ERROR(this->GetClassName()) << err.what();
}
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.h
index e09d58259c..125d74d3a4 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkOtsuAction.h
@@ -1,71 +1,70 @@
/*===================================================================
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 QMITKOTSUACTION_H
#define QMITKOTSUACTION_H
#include
// Parent classes
#include
#include
// Data members
#include
#include
#include
// Mitk classes
#include
class QDialog;
-class QmitkStdMultiWidget;
/** \deprecatedSince{2013_09} The interaction for the Otsu image filter was revised and moved to the segmentation plugin view. */
class DEPRECATED() MITK_QT_SEGMENTATION QmitkOtsuAction : public QObject, public mitk::IContextMenuAction
{
Q_OBJECT
Q_INTERFACES(mitk::IContextMenuAction)
public:
QmitkOtsuAction();
~QmitkOtsuAction();
// IContextMenuAction
void Run(const QList &selectedNodes);
void SetDataStorage(mitk::DataStorage *dataStorage);
- void SetFunctionality(berry::QtViewPart *functionality);
+ void SetFunctionality(berry::QtViewPart* view);
void SetSmoothed(bool smoothed){}
void SetDecimated(bool decimated){}
private slots:
void OtsuSegmentationDone();
private:
QmitkOtsuAction(const QmitkOtsuAction &);
QmitkOtsuAction & operator=(const QmitkOtsuAction &);
void PerformOtsuSegmentation();
mitk::DataStorage::Pointer m_DataStorage;
QDialog *m_OtsuSegmentationDialog;
QSpinBox* m_OtsuSpinBox;
QPushButton* m_OtsuPushButton;
mitk::DataNode::Pointer m_DataNode;
};
#endif
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
index f9b18c6cb4..9ed8c246c8 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
@@ -1,1295 +1,1313 @@
/*===================================================================
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
#include "mitkProperties.h"
#include "mitkSegTool2D.h"
#include "mitkStatusBar.h"
-#include "QmitkStdMultiWidget.h"
#include "QmitkNewSegmentationDialog.h"
#include
#include
#include
#include "QmitkSegmentationView.h"
#include
#include "mitkVtkResliceInterpolationProperty.h"
#include "mitkApplicationCursor.h"
#include "mitkSegmentationObjectFactory.h"
#include "mitkPluginActivator.h"
#include "mitkCameraController.h"
#include "mitkLabelSetImage.h"
+#include
+
#include "usModuleResource.h"
#include "usModuleResourceStream.h"
//micro service to get the ToolManager instance
#include "mitkToolManagerProvider.h"
const std::string QmitkSegmentationView::VIEW_ID =
"org.mitk.views.segmentation";
// public methods
QmitkSegmentationView::QmitkSegmentationView()
:m_MouseCursorSet(false)
,m_Parent(NULL)
,m_Controls(NULL)
- ,m_MultiWidget(NULL)
,m_DataSelectionChanged(false)
+ ,m_Activated(false)
{
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti);
isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi);
m_IsOfTypeImagePredicate = mitk::NodePredicateOr::New(isDiffusionImage, mitk::TNodePredicateDataType::New());
m_IsBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
m_IsNotBinaryPredicate = mitk::NodePredicateNot::New( m_IsBinaryPredicate );
m_IsNotABinaryImagePredicate = mitk::NodePredicateAnd::New( m_IsOfTypeImagePredicate, m_IsNotBinaryPredicate );
m_IsABinaryImagePredicate = mitk::NodePredicateAnd::New( m_IsOfTypeImagePredicate, m_IsBinaryPredicate);
m_IsASegmentationImagePredicate = mitk::NodePredicateOr::New(m_IsABinaryImagePredicate, mitk::TNodePredicateDataType::New());
m_IsAPatientImagePredicate = mitk::NodePredicateAnd::New(m_IsNotABinaryImagePredicate, mitk::NodePredicateNot::New(mitk::TNodePredicateDataType::New()));
}
QmitkSegmentationView::~QmitkSegmentationView()
{
delete m_Controls;
}
void QmitkSegmentationView::NewNodesGenerated()
{
MITK_WARN<<"Use of deprecated function: NewNodesGenerated!! This function is empty and will be removed in the next time!";
}
void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes)
{
if (!nodes) return;
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
if (!toolManager) return;
for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
{
this->FireNodeSelected( *iter );
// only last iteration meaningful, multiple generated objects are not taken into account here
}
}
void QmitkSegmentationView::Visible()
{
if (m_DataSelectionChanged)
{
- this->OnSelectionChanged(this->GetDataManagerSelection());
+ berry::IWorkbenchPart::Pointer nullPart;
+ this->OnSelectionChanged(nullPart, this->GetDataManagerSelection());
}
}
+void QmitkSegmentationView::Hidden()
+{
+}
+
void QmitkSegmentationView::Activated()
{
+ m_Activated = true;
+
// should be moved to ::BecomesVisible() or similar
if( m_Controls )
{
m_Controls->m_ManualToolSelectionBox2D->setEnabled( true );
m_Controls->m_ManualToolSelectionBox3D->setEnabled( true );
// m_Controls->m_OrganToolSelectionBox->setEnabled( true );
// m_Controls->m_LesionToolSelectionBox->setEnabled( true );
// m_Controls->m_SlicesInterpolator->Enable3DInterpolation( m_Controls->widgetStack->currentWidget() == m_Controls->pageManual );
- mitk::DataStorage::SetOfObjects::ConstPointer segmentations = this->GetDefaultDataStorage()->GetSubset( m_IsABinaryImagePredicate );
+ mitk::DataStorage::SetOfObjects::ConstPointer segmentations = this->GetDataStorage()->GetSubset( m_IsABinaryImagePredicate );
- mitk::DataStorage::SetOfObjects::ConstPointer image = this->GetDefaultDataStorage()->GetSubset(m_IsAPatientImagePredicate);
+ mitk::DataStorage::SetOfObjects::ConstPointer image = this->GetDataStorage()->GetSubset(m_IsAPatientImagePredicate);
if (!image->empty()) {
OnSelectionChanged(*image->begin());
}
for ( mitk::DataStorage::SetOfObjects::const_iterator iter = segmentations->begin();
iter != segmentations->end();
++iter)
{
mitk::DataNode* node = *iter;
itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged);
m_WorkingDataObserverTags.insert( std::pair( node, node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) );
itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New();
command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged);
m_BinaryPropertyObserverTags.insert( std::pair( node, node->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) );
}
}
itk::SimpleMemberCommand::Pointer command3 = itk::SimpleMemberCommand::New();
command3->SetCallbackFunction( this, &QmitkSegmentationView::RenderingManagerReinitialized );
m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver( mitk::RenderingManagerViewsInitializedEvent(), command3 );
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode());
}
void QmitkSegmentationView::Deactivated()
{
if( m_Controls )
{
this->SetToolSelectionBoxesEnabled( false );
//deactivate all tools
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
//Removing all observers
for ( NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter )
{
(*dataIter).first->GetProperty("visible")->RemoveObserver( (*dataIter).second );
}
m_WorkingDataObserverTags.clear();
for ( NodeTagMapType::iterator dataIter = m_BinaryPropertyObserverTags.begin(); dataIter != m_BinaryPropertyObserverTags.end(); ++dataIter )
{
(*dataIter).first->GetProperty("binary")->RemoveObserver( (*dataIter).second );
}
m_BinaryPropertyObserverTags.clear();
mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag);
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService* service = context->getService(ppmRef);
service->RemoveAllPlanePositions();
context->ungetService(ppmRef);
this->SetToolManagerSelection(0,0);
}
-}
-void QmitkSegmentationView::StdMultiWidgetAvailable( QmitkStdMultiWidget& stdMultiWidget )
-{
- SetMultiWidget(&stdMultiWidget);
-}
-
-void QmitkSegmentationView::StdMultiWidgetNotAvailable()
-{
- SetMultiWidget(NULL);
+ m_Activated = false;
}
-void QmitkSegmentationView::StdMultiWidgetClosed( QmitkStdMultiWidget& /*stdMultiWidget*/ )
+bool QmitkSegmentationView::IsActivated() const
{
- SetMultiWidget(NULL);
+ return m_Activated;
}
-void QmitkSegmentationView::SetMultiWidget(QmitkStdMultiWidget* multiWidget)
+void QmitkSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
- // save the current multiwidget as the working widget
- m_MultiWidget = multiWidget;
-
if (m_Parent)
{
- m_Parent->setEnabled(m_MultiWidget);
+ m_Parent->setEnabled(true);
}
- // tell the interpolation about toolmanager and multiwidget (and data storage)
- if (m_Controls && m_MultiWidget)
+ // tell the interpolation about toolmanager and render window part (and data storage)
+ if (m_Controls)
{
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
- m_Controls->m_SlicesInterpolator->SetDataStorage( this->GetDefaultDataStorage());
+ m_Controls->m_SlicesInterpolator->SetDataStorage( this->GetDataStorage());
QList controllers;
- controllers.push_back(m_MultiWidget->GetRenderWindow1()->GetSliceNavigationController());
- controllers.push_back(m_MultiWidget->GetRenderWindow2()->GetSliceNavigationController());
- controllers.push_back(m_MultiWidget->GetRenderWindow3()->GetSliceNavigationController());
+ controllers.push_back(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController());
+ controllers.push_back(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController());
+ controllers.push_back(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController());
m_Controls->m_SlicesInterpolator->Initialize( toolManager, controllers );
}
}
+void QmitkSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/)
+{
+ if (m_Parent)
+ {
+ m_Parent->setEnabled(false);
+ }
+}
+
void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if (m_Controls != NULL)
{
bool slimView = prefs->GetBool("slim view", false);
m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView);
m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView);
}
m_AutoSelectionEnabled = prefs->GetBool("auto selection", false);
this->ForceDisplayPreferencesUponAllImages();
}
void QmitkSegmentationView::CreateNewSegmentation()
{
mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
if (node.IsNotNull())
{
mitk::Image::Pointer image = dynamic_cast( node->GetData() );
if (image.IsNotNull())
{
if (image->GetDimension()>1)
{
// ask about the name and organ type of the new segmentation
QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog( m_Parent ); // needs a QWidget as parent, "this" is not QWidget
QString storedList = this->GetPreferences()->Get("Organ-Color-List","");
QStringList organColors;
if (storedList.isEmpty())
{
organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString();
}
else
{
/*
a couple of examples of how organ names are stored:
a simple item is built up like 'name#AABBCC' where #AABBCC is the hexadecimal notation of a color as known from HTML
items are stored separated by ';'
this makes it necessary to escape occurrences of ';' in name.
otherwise the string "hugo;ypsilon#AABBCC;eugen#AABBCC" could not be parsed as two organs
but we would get "hugo" and "ypsilon#AABBCC" and "eugen#AABBCC"
so the organ name "hugo;ypsilon" is stored as "hugo\;ypsilon"
and must be unescaped after loading
the following lines could be one split with Perl's negative lookbehind
*/
// recover string list from BlueBerry view's preferences
QString storedString = this->GetPreferences()->Get("Organ-Color-List","");
MITK_DEBUG << "storedString: " << storedString.toStdString();
// match a string consisting of any number of repetitions of either "anything but ;" or "\;". This matches everything until the next unescaped ';'
QRegExp onePart("(?:[^;]|\\\\;)*");
MITK_DEBUG << "matching " << onePart.pattern().toStdString();
int count = 0;
int pos = 0;
while( (pos = onePart.indexIn( storedString, pos )) != -1 )
{
++count;
int length = onePart.matchedLength();
if (length == 0) break;
QString matchedString = storedString.mid(pos, length);
MITK_DEBUG << " Captured length " << length << ": " << matchedString.toStdString();
pos += length + 1; // skip separating ';'
// unescape possible occurrences of '\;' in the string
matchedString.replace("\\;", ";");
// add matched string part to output list
organColors << matchedString;
}
MITK_DEBUG << "Captured " << count << " organ name/colors";
}
dialog->SetSuggestionList( organColors );
int dialogReturnValue = dialog->exec();
if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar
// ask the user about an organ type and name, add this information to the image's (!) propertylist
// create a new image of the same dimensions and smallest possible pixel type
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
mitk::Tool* firstTool = toolManager->GetToolById(0);
if (firstTool)
{
try
{
std::string newNodeName = dialog->GetSegmentationName().toStdString();
if(newNodeName.empty())
newNodeName = "no_name";
mitk::DataNode::Pointer emptySegmentation =
firstTool->CreateEmptySegmentationNode( image, newNodeName, dialog->GetColor() );
// initialize showVolume to false to prevent recalculating the volume while working on the segmentation
emptySegmentation->SetProperty( "showVolume", mitk::BoolProperty::New( false ) );
if (!emptySegmentation) return; // could be aborted by user
mitk::OrganNamesHandling::UpdateOrganList(organColors, dialog->GetSegmentationName(), dialog->GetColor());
/*
escape ';' here (replace by '\;'), see longer comment above
*/
QString stringForStorage = organColors.replaceInStrings(";","\\;").join(";");
MITK_DEBUG << "Will store: " << stringForStorage;
this->GetPreferences()->Put("Organ-Color-List", stringForStorage);
this->GetPreferences()->Flush();
if(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0))
{
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false);
}
emptySegmentation->SetSelected(true);
- this->GetDefaultDataStorage()->Add( emptySegmentation, node ); // add as a child, because the segmentation "derives" from the original
+ this->GetDataStorage()->Add( emptySegmentation, node ); // add as a child, because the segmentation "derives" from the original
this->ApplyDisplayOptions( emptySegmentation );
this->FireNodeSelected( emptySegmentation );
this->OnSelectionChanged( emptySegmentation );
m_Controls->segImageSelector->SetSelectedNode(emptySegmentation);
mitk::RenderingManager::GetInstance()->InitializeViews(emptySegmentation->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
}
catch (std::bad_alloc)
{
QMessageBox::warning(NULL,tr("Create new segmentation"),tr("Could not allocate memory for new segmentation"));
}
}
}
else
{
QMessageBox::information(NULL,tr("Segmentation"),tr("Segmentation is currently not supported for 2D images"));
}
}
}
else
{
MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected...";
}
}
void QmitkSegmentationView::OnWorkingNodeVisibilityChanged()
{
mitk::DataNode* selectedNode = m_Controls->segImageSelector->GetSelectedNode();
if ( !selectedNode )
{
this->SetToolSelectionBoxesEnabled(false);
return;
}
- bool selectedNodeIsVisible = selectedNode->IsVisible(mitk::BaseRenderer::GetInstance(
- mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")));
+ mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
+ bool selectedNodeIsVisible = renderWindowPart
+ && selectedNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer());
if (!selectedNodeIsVisible)
{
this->SetToolSelectionBoxesEnabled(false);
this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!"));
}
else
{
this->SetToolSelectionBoxesEnabled(true);
this->UpdateWarningLabel("");
}
}
void QmitkSegmentationView::OnBinaryPropertyChanged()
{
mitk::DataStorage::SetOfObjects::ConstPointer patImages = m_Controls->patImageSelector->GetNodes();
bool isBinary(false);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = patImages->Begin(); it != patImages->End(); ++it)
{
const mitk::DataNode* node = it->Value();
node->GetBoolProperty("binary", isBinary);
mitk::LabelSetImage::Pointer labelSetImage = dynamic_cast(node->GetData());
isBinary = isBinary || labelSetImage.IsNotNull();
if(isBinary)
{
m_Controls->patImageSelector->RemoveNode(node);
m_Controls->segImageSelector->AddNode(node);
this->SetToolManagerSelection(NULL,NULL);
return;
}
}
mitk::DataStorage::SetOfObjects::ConstPointer segImages = m_Controls->segImageSelector->GetNodes();
isBinary = true;
for (mitk::DataStorage::SetOfObjects::ConstIterator it = segImages->Begin(); it != segImages->End(); ++it)
{
const mitk::DataNode* node = it->Value();
node->GetBoolProperty("binary", isBinary);
mitk::LabelSetImage::Pointer labelSetImage = dynamic_cast(node->GetData());
isBinary = isBinary || labelSetImage.IsNotNull();
if(!isBinary)
{
m_Controls->segImageSelector->RemoveNode(node);
m_Controls->patImageSelector->AddNode(node);
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node)
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->SetWorkingData(NULL);
return;
}
}
}
void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node)
{
bool isBinary (false);
bool isHelperObject (false);
bool isImage (false);
node->GetBoolProperty("binary", isBinary);
mitk::LabelSetImage::Pointer labelSetImage = dynamic_cast(node->GetData());
isBinary = isBinary || labelSetImage.IsNotNull();
node->GetBoolProperty("helper object", isHelperObject);
if( dynamic_cast(node->GetData()) )
{
isImage = true;
}
if (m_AutoSelectionEnabled)
{
if (!isBinary && isImage)
{
FireNodeSelected(const_cast(node));
}
}
if (isImage && !isHelperObject)
{
itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged);
m_WorkingDataObserverTags.insert( std::pair( const_cast(node), node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) );
itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New();
command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged);
m_BinaryPropertyObserverTags.insert( std::pair( const_cast(node), node->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) );
this->ApplyDisplayOptions( const_cast(node) );
m_Controls->segImageSelector->setCurrentIndex( m_Controls->segImageSelector->Find(node) );
}
}
void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node)
{
bool isSeg(false);
bool isHelperObject(false);
node->GetBoolProperty("helper object", isHelperObject);
node->GetBoolProperty("binary", isSeg);
mitk::LabelSetImage::Pointer labelSetImage = dynamic_cast(node->GetData());
isSeg = isSeg || labelSetImage.IsNotNull();
mitk::Image* image = dynamic_cast(node->GetData());
if(isSeg && !isHelperObject && image)
{
//First of all remove all possible contour markers of the segmentation
mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker"
, mitk::BoolProperty::New(true)));
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService* service = context->getService(ppmRef);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t+1).c_str())-1;
service->RemovePlanePosition(id);
this->GetDataStorage()->Remove(it->Value());
}
context->ungetService(ppmRef);
service = NULL;
if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull())
{
this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), NULL);
this->UpdateWarningLabel(tr("Select or create a segmentation"));
}
mitk::SurfaceInterpolationController::GetInstance()->RemoveInterpolationSession(image);
}
mitk::DataNode* tempNode = const_cast(node);
//Since the binary property could be changed during runtime by the user
if (image && !isHelperObject)
{
node->GetProperty("visible")->RemoveObserver( m_WorkingDataObserverTags[tempNode] );
m_WorkingDataObserverTags.erase(tempNode);
node->GetProperty("binary")->RemoveObserver( m_BinaryPropertyObserverTags[tempNode] );
m_BinaryPropertyObserverTags.erase(tempNode);
}
if((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) == node))
{
//as we don't know which node was actually removed e.g. our reference node, disable 'New Segmentation' button.
//consider the case that there is no more image in the datastorage
this->SetToolManagerSelection(NULL, NULL);
this->SetToolSelectionBoxesEnabled( false );
}
}
//void QmitkSegmentationView::CreateSegmentationFromSurface()
//{
// mitk::DataNode::Pointer surfaceNode =
// m_Controls->MaskSurfaces->GetSelectedNode();
// mitk::Surface::Pointer surface(0);
// if(surfaceNode.IsNotNull())
// surface = dynamic_cast ( surfaceNode->GetData() );
// if(surface.IsNull())
// {
// this->HandleException( "No surface selected.", m_Parent, true);
// return;
// }
// mitk::DataNode::Pointer imageNode
// = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
// mitk::Image::Pointer image(0);
// if (imageNode.IsNotNull())
// image = dynamic_cast( imageNode->GetData() );
// if(image.IsNull())
// {
// this->HandleException( "No image selected.", m_Parent, true);
// return;
// }
// mitk::SurfaceToImageFilter::Pointer s2iFilter
// = mitk::SurfaceToImageFilter::New();
// s2iFilter->MakeOutputBinaryOn();
// s2iFilter->SetInput(surface);
// s2iFilter->SetImage(image);
// s2iFilter->Update();
// mitk::DataNode::Pointer resultNode = mitk::DataNode::New();
// std::string nameOfResultImage = imageNode->GetName();
// nameOfResultImage.append(surfaceNode->GetName());
// resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) );
// resultNode->SetProperty("binary", mitk::BoolProperty::New(true) );
// resultNode->SetData( s2iFilter->GetOutput() );
// this->GetDataStorage()->Add(resultNode, imageNode);
//}
//void QmitkSegmentationView::ToolboxStackPageChanged(int id)
//{
// // interpolation only with manual tools visible
// m_Controls->m_SlicesInterpolator->EnableInterpolation( id == 0 );
// if( id == 0 )
// {
// mitk::DataNode::Pointer workingData = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0);
// if( workingData.IsNotNull() )
// {
// m_Controls->segImageSelector->setCurrentIndex( m_Controls->segImageSelector->Find(workingData) );
// }
// }
// // this is just a workaround, should be removed when all tools support 3D+t
// if (id==2) // lesions
// {
// mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
// if (node.IsNotNull())
// {
// mitk::Image::Pointer image = dynamic_cast( node->GetData() );
// if (image.IsNotNull())
// {
// if (image->GetDimension()>3)
// {
// m_Controls->widgetStack->setCurrentIndex(0);
// QMessageBox::information(NULL,"Segmentation","Lesion segmentation is currently not supported for 4D images");
// }
// }
// }
// }
//}
// protected
void QmitkSegmentationView::OnPatientComboBoxSelectionChanged( const mitk::DataNode* node )
{
//mitk::DataNode* selectedNode = const_cast(node);
if( node != NULL )
{
this->UpdateWarningLabel("");
mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode();
if (segNode)
{
- mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources(segNode, m_IsAPatientImagePredicate);
+ mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDataStorage()->GetSources(segNode, m_IsAPatientImagePredicate);
bool isSourceNode(false);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = possibleParents->Begin(); it != possibleParents->End(); it++)
{
if (it.Value() == node)
isSourceNode = true;
}
if ( !isSourceNode && (!this->CheckForSameGeometry(segNode, node) || possibleParents->Size() > 0 ))
{
this->SetToolManagerSelection(node, NULL);
this->SetToolSelectionBoxesEnabled( false );
this->UpdateWarningLabel(tr("The selected patient image does not match with the selected segmentation!"));
}
else if ((!isSourceNode && this->CheckForSameGeometry(segNode, node)) || isSourceNode )
{
this->SetToolManagerSelection(node, segNode);
//Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are
//loaded separately
int layer(10);
node->GetIntProperty("layer", layer);
layer++;
segNode->SetProperty("layer", mitk::IntProperty::New(layer));
//this->UpdateWarningLabel("");
RenderingManagerReinitialized();
}
}
else
{
this->SetToolManagerSelection(node, NULL);
this->SetToolSelectionBoxesEnabled( false );
this->UpdateWarningLabel(tr("Select or create a segmentation"));
}
}
else
{
this->UpdateWarningLabel(tr("Please load an image!"));
this->SetToolSelectionBoxesEnabled( false );
}
}
void QmitkSegmentationView::OnSegmentationComboBoxSelectionChanged(const mitk::DataNode *node)
{
if (node == NULL)
{
this->UpdateWarningLabel(tr("Select or create a segmentation"));
this->SetToolSelectionBoxesEnabled( false );
return;
}
mitk::DataNode* refNode = m_Controls->patImageSelector->GetSelectedNode();
RenderingManagerReinitialized();
if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further
return;
if (m_AutoSelectionEnabled)
{
this->OnSelectionChanged(const_cast(node));
}
else
{
- mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources(node, m_IsAPatientImagePredicate);
+ mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDataStorage()->GetSources(node, m_IsAPatientImagePredicate);
if ( possibleParents->Size() == 1 )
{
mitk::DataNode* parentNode = possibleParents->ElementAt(0);
if (parentNode != refNode)
{
this->UpdateWarningLabel(tr("The selected segmentation does not match with the selected patient image!"));
this->SetToolSelectionBoxesEnabled( false );
this->SetToolManagerSelection(NULL, node);
}
else
{
this->UpdateWarningLabel("");
this->SetToolManagerSelection(refNode, node);
}
}
else if (refNode && this->CheckForSameGeometry(node, refNode))
{
this->UpdateWarningLabel("");
this->SetToolManagerSelection(refNode, node);
}
else if (!refNode || !this->CheckForSameGeometry(node, refNode))
{
this->UpdateWarningLabel(tr("Please select or load the according patient image!"));
}
}
- if (!node->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))))
+
+ mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
+ if (!renderWindowPart || !node->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()))
{
this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!"));
this->SetToolSelectionBoxesEnabled( false );
}
}
void QmitkSegmentationView::OnShowMarkerNodes (bool state)
{
mitk::SegTool2D::Pointer manualSegmentationTool;
unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size();
for(unsigned int i = 0; i < numberOfExistingTools; i++)
{
manualSegmentationTool = dynamic_cast(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i));
if (manualSegmentationTool)
{
if(state == true)
{
manualSegmentationTool->SetShowMarkerNodes( true );
}
else
{
manualSegmentationTool->SetShowMarkerNodes( false );
}
}
}
}
void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node)
{
- std::vector nodes;
- nodes.push_back( node );
- this->OnSelectionChanged( nodes );
+ berry::IWorkbenchPart::Pointer nullPart;
+ QList nodes;
+ nodes.push_back(node);
+ this->OnSelectionChanged(nullPart, nodes);
}
-void QmitkSegmentationView::OnSelectionChanged(std::vector nodes)
+void QmitkSegmentationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes)
{
if (nodes.size() != 0)
{
std::string markerName = "Position";
unsigned int numberOfNodes = nodes.size();
std::string nodeName = nodes.at( 0 )->GetName();
if ( ( numberOfNodes == 1 ) && ( nodeName.find( markerName ) == 0) )
{
this->OnContourMarkerSelected( nodes.at( 0 ) );
return;
}
}
if (m_AutoSelectionEnabled && this->IsActivated())
{
if (nodes.size() == 0 && m_Controls->patImageSelector->GetSelectedNode().IsNull())
{
SetToolManagerSelection(NULL,NULL);
}
else if (nodes.size() == 1)
{
mitk::DataNode::Pointer selectedNode = nodes.at(0);
if(selectedNode.IsNull())
{
return;
}
mitk::Image::Pointer selectedImage = dynamic_cast(selectedNode->GetData());
if (selectedImage.IsNull())
{
SetToolManagerSelection(NULL,NULL);
return;
}
else
{
bool isASegmentation(false);
selectedNode->GetBoolProperty("binary", isASegmentation);
mitk::LabelSetImage::Pointer labelSetImage = dynamic_cast(selectedNode->GetData());
isASegmentation = isASegmentation || labelSetImage.IsNotNull();
if (isASegmentation)
{
//If a segmentation is selected find a possible reference image:
mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(selectedNode, m_IsAPatientImagePredicate);
mitk::DataNode::Pointer refNode;
if (sources->Size() != 0)
{
refNode = sources->ElementAt(0);
refNode->SetVisibility(true);
selectedNode->SetVisibility(true);
SetToolManagerSelection(refNode,selectedNode);
mitk::DataStorage::SetOfObjects::ConstPointer otherSegmentations = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherSegmentations->begin(); iter != otherSegmentations->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast(node->GetData()) != selectedImage.GetPointer())
node->SetVisibility(false);
}
mitk::DataStorage::SetOfObjects::ConstPointer otherPatientImages = this->GetDataStorage()->GetSubset(m_IsAPatientImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherPatientImages->begin(); iter != otherPatientImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast(node->GetData()) != dynamic_cast(refNode->GetData()))
node->SetVisibility(false);
}
}
else
{
mitk::DataStorage::SetOfObjects::ConstPointer possiblePatientImages = this->GetDataStorage()->GetSubset(m_IsAPatientImagePredicate);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = possiblePatientImages->Begin(); it != possiblePatientImages->End(); it++)
{
refNode = it->Value();
if (this->CheckForSameGeometry(selectedNode, it->Value()))
{
refNode->SetVisibility(true);
selectedNode->SetVisibility(true);
mitk::DataStorage::SetOfObjects::ConstPointer otherSegmentations = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherSegmentations->begin(); iter != otherSegmentations->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast(node->GetData()) != selectedImage.GetPointer())
node->SetVisibility(false);
}
mitk::DataStorage::SetOfObjects::ConstPointer otherPatientImages = this->GetDataStorage()->GetSubset(m_IsAPatientImagePredicate);
for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherPatientImages->begin(); iter != otherPatientImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
if (dynamic_cast(node->GetData()) != dynamic_cast(refNode->GetData()))
node->SetVisibility(false);
}
this->SetToolManagerSelection(refNode, selectedNode);
//Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are at the
//same level in the datamanager
int layer(10);
refNode->GetIntProperty("layer", layer);
layer++;
selectedNode->SetProperty("layer", mitk::IntProperty::New(layer));
return;
}
}
this->SetToolManagerSelection(NULL, selectedNode);
}
mitk::RenderingManager::GetInstance()->InitializeViews(selectedNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
}
else
{
if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) != selectedNode)
{
SetToolManagerSelection(selectedNode, NULL);
//May be a bug in the selection services. A node which is deselected will be passed as selected node to the OnSelectionChanged function
- if (!selectedNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))))
+ mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
+ if (renderWindowPart && !selectedNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()))
selectedNode->SetVisibility(true);
this->UpdateWarningLabel(tr("The selected patient image does not\nmatchwith the selected segmentation!"));
this->SetToolSelectionBoxesEnabled( false );
}
}
}
}
if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further
return;
RenderingManagerReinitialized();
}
}
void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node)
{
QmitkRenderWindow* selectedRenderWindow = 0;
- QmitkRenderWindow* RenderWindow1 =
- this->GetActiveStdMultiWidget()->GetRenderWindow1();
- QmitkRenderWindow* RenderWindow2 =
- this->GetActiveStdMultiWidget()->GetRenderWindow2();
- QmitkRenderWindow* RenderWindow3 =
- this->GetActiveStdMultiWidget()->GetRenderWindow3();
- QmitkRenderWindow* RenderWindow4 =
- this->GetActiveStdMultiWidget()->GetRenderWindow4();
+ QmitkRenderWindow* axialRenderWindow =
+ this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("axial");
+ QmitkRenderWindow* sagittalRenderWindow =
+ this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("sagittal");
+ QmitkRenderWindow* coronalRenderWindow =
+ this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("coronal");
+ QmitkRenderWindow* _3DRenderWindow =
+ this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("3d");
bool PlanarFigureInitializedWindow = false;
// find initialized renderwindow
if (node->GetBoolProperty("PlanarFigureInitializedWindow",
- PlanarFigureInitializedWindow, RenderWindow1->GetRenderer()))
+ PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer()))
{
- selectedRenderWindow = RenderWindow1;
+ selectedRenderWindow = axialRenderWindow;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
- RenderWindow2->GetRenderer()))
+ sagittalRenderWindow->GetRenderer()))
{
- selectedRenderWindow = RenderWindow2;
+ selectedRenderWindow = sagittalRenderWindow;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
- RenderWindow3->GetRenderer()))
+ coronalRenderWindow->GetRenderer()))
{
- selectedRenderWindow = RenderWindow3;
+ selectedRenderWindow = coronalRenderWindow;
}
if (!selectedRenderWindow && node->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
- RenderWindow4->GetRenderer()))
+ _3DRenderWindow->GetRenderer()))
{
- selectedRenderWindow = RenderWindow4;
+ selectedRenderWindow = _3DRenderWindow;
}
// make node visible
if (selectedRenderWindow)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t+1).c_str())-1;
{
ctkPluginContext* context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService* service = context->getService(ppmRef);
selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id));
context->ungetService(ppmRef);
}
selectedRenderWindow->GetRenderer()->GetCameraController()->Fit();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkSegmentationView::OnTabWidgetChanged(int id)
{
//always disable tools on tab changed
mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
//2D Tab ID = 0
//3D Tab ID = 1
if (id == 0)
{
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox3D->hide();
m_Controls->m_ManualToolSelectionBox2D->show();
//Deactivate possible active tool
//TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator
}
else
{
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox2D->hide();
m_Controls->m_ManualToolSelectionBox3D->show();
//Deactivate possible active tool
}
}
void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData)
{
// called as a result of new BlueBerry selections
// tells the ToolManager for manual segmentation about new selections
// updates GUI information about what the user should select
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
toolManager->SetReferenceData(const_cast(referenceData));
toolManager->SetWorkingData( const_cast(workingData));
// check original image
m_Controls->btnNewSegmentation->setEnabled(referenceData != NULL);
if (referenceData)
{
this->UpdateWarningLabel("");
disconnect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) );
m_Controls->patImageSelector->setCurrentIndex( m_Controls->patImageSelector->Find(referenceData) );
connect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) );
}
// check segmentation
if (referenceData)
{
if (workingData)
{
this->FireNodeSelected(const_cast(workingData));
// if( m_Controls->widgetStack->currentIndex() == 0 )
// {
disconnect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnSegmentationComboBoxSelectionChanged( const mitk::DataNode* ) ) );
m_Controls->segImageSelector->setCurrentIndex(m_Controls->segImageSelector->Find(workingData));
connect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*)) );
// }
}
}
}
void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages()
{
if (!m_Parent)
{
return;
}
// check all images and segmentations in DataStorage:
// (items in brackets are implicitly done by previous steps)
// 1.
// if a reference image is selected,
// show the reference image
// and hide all other images (orignal and segmentation),
// (and hide all segmentations of the other original images)
// and show all the reference's segmentations
// if no reference image is selected, do do nothing
//
// 2.
// if a segmentation is selected,
// show it
// (and hide all all its siblings (childs of the same parent, incl, NULL parent))
// if no segmentation is selected, do nothing
if (!m_Controls)
{
return; // might happen on initialization (preferences loaded)
}
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
mitk::DataNode::Pointer referenceData = toolManager->GetReferenceData(0);
mitk::DataNode::Pointer workingData = toolManager->GetWorkingData(0);
// 1.
if (referenceData.IsNotNull())
{
// iterate all images
- mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDefaultDataStorage()->GetSubset(m_IsASegmentationImagePredicate);
+ mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate);
for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
{
mitk::DataNode* node = *iter;
// apply display preferences
ApplyDisplayOptions(node);
// set visibility
node->SetVisibility(node == referenceData);
}
}
// 2.
if (workingData.IsNotNull())
workingData->SetVisibility(true);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node)
{
if (!node)
{
return;
}
mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true));
mitk::BoolProperty::Pointer volumeRendering = mitk::BoolProperty::New(GetPreferences()->GetBool("volume rendering", false));
mitk::LabelSetImage* labelSetImage = dynamic_cast(node->GetData());
if (nullptr != labelSetImage)
{
// node is actually a multi label segmentation,
// but its outline property can be set in the 'single label' segmentation preference page as well
node->SetProperty("labelset.contour.active", drawOutline);
node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
node->SetProperty("volumerendering", volumeRendering);
// force render window update to show outline
node->GetData()->Modified();
}
else
{
// node is a 'single label' segmentation
bool isBinary = false;
node->GetBoolProperty("binary", isBinary);
if (isBinary)
{
node->SetProperty("outline binary", drawOutline);
node->SetProperty("outline width", mitk::FloatProperty::New(2.0));
node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
node->SetProperty("volumerendering", volumeRendering);
// force render window update to show outline
node->GetData()->Modified();
}
}
}
void QmitkSegmentationView::RenderingManagerReinitialized()
{
- if ( ! m_MultiWidget ) { return; }
+ if (!this->GetRenderWindowPart())
+ {
+ return;
+ }
/*
* Here we check whether the geometry of the selected segmentation image if aligned with the worldgeometry
* At the moment it is not supported to use a geometry different from the selected image for reslicing.
* For further information see Bug 16063
*/
mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode();
- const mitk::BaseGeometry* worldGeo = m_MultiWidget->GetRenderWindow4()->GetSliceNavigationController()->GetCurrentGeometry3D();
+ const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D();
if (workingNode && worldGeo)
{
const mitk::BaseGeometry* workingNodeGeo = workingNode->GetData()->GetGeometry();
- const mitk::BaseGeometry* worldGeo = m_MultiWidget->GetRenderWindow4()->GetSliceNavigationController()->GetCurrentGeometry3D();
+ const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D();
if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true))
{
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), workingNode);
this->SetToolSelectionBoxesEnabled(true);
this->UpdateWarningLabel("");
}
else
{
this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), NULL);
this->SetToolSelectionBoxesEnabled(false);
this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!"));
}
}
}
bool QmitkSegmentationView::CheckForSameGeometry(const mitk::DataNode *node1, const mitk::DataNode *node2) const
{
bool isSameGeometry(true);
mitk::Image* image1 = dynamic_cast(node1->GetData());
mitk::Image* image2 = dynamic_cast(node2->GetData());
if (image1 && image2)
{
mitk::BaseGeometry* geo1 = image1->GetGeometry();
mitk::BaseGeometry* geo2 = image2->GetGeometry();
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetOrigin(), geo2->GetOrigin());
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(0), geo2->GetExtent(0));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(1), geo2->GetExtent(1));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(2), geo2->GetExtent(2));
isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetSpacing(), geo2->GetSpacing());
isSameGeometry = isSameGeometry && mitk::MatrixEqualElementWise(geo1->GetIndexToWorldTransform()->GetMatrix(), geo2->GetIndexToWorldTransform()->GetMatrix());
return isSameGeometry;
}
else
{
return false;
}
}
void QmitkSegmentationView::UpdateWarningLabel(QString text)
{
if (text.size() == 0)
m_Controls->lblSegmentationWarnings->hide();
else
m_Controls->lblSegmentationWarnings->show();
m_Controls->lblSegmentationWarnings->setText(text);
}
void QmitkSegmentationView::CreateQtPartControl(QWidget* parent)
{
// setup the basic GUI of this view
m_Parent = parent;
m_Controls = new Ui::QmitkSegmentationControls;
m_Controls->setupUi(parent);
- m_Controls->patImageSelector->SetDataStorage(this->GetDefaultDataStorage());
+ m_Controls->patImageSelector->SetDataStorage(this->GetDataStorage());
m_Controls->patImageSelector->SetPredicate(mitk::NodePredicateAnd::New(m_IsAPatientImagePredicate, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer());
this->UpdateWarningLabel(tr("Please load an image"));
if( m_Controls->patImageSelector->GetSelectedNode().IsNotNull() )
this->UpdateWarningLabel(tr("Select or create a new segmentation"));
- m_Controls->segImageSelector->SetDataStorage(this->GetDefaultDataStorage());
+ m_Controls->segImageSelector->SetDataStorage(this->GetDataStorage());
m_Controls->segImageSelector->SetPredicate(mitk::NodePredicateAnd::New(m_IsASegmentationImagePredicate, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer());
if( m_Controls->segImageSelector->GetSelectedNode().IsNotNull() )
this->UpdateWarningLabel("");
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
assert ( toolManager );
- toolManager->SetDataStorage( *(this->GetDefaultDataStorage()) );
+ toolManager->SetDataStorage( *(this->GetDataStorage()) );
toolManager->InitializeTools();
// all part of open source MITK
m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true);
m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer2D );
m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups(tr("Add Subtract Correction Paint Wipe 'Region Growing' Fill Erase 'Live Wire' '2D Fast Marching'").toStdString());
m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3);
m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible );
connect( m_Controls->m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int)) );
//setup 3D Tools
m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true);
m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer3D );
//specify tools to be added to 3D Tool area
m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups(tr("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking").toStdString());
m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3);
m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible );
//Hide 3D selection box, show 2D selection box
m_Controls->m_ManualToolSelectionBox3D->hide();
m_Controls->m_ManualToolSelectionBox2D->show();
toolManager->NewNodesGenerated +=
mitk::MessageDelegate( this, &QmitkSegmentationView::NewNodesGenerated ); // update the list of segmentations
toolManager->NewNodeObjectsGenerated +=
mitk::MessageDelegate1( this, &QmitkSegmentationView::NewNodeObjectsGenerated ); // update the list of segmentations
// create signal/slot connections
connect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) );
connect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
this, SLOT( OnSegmentationComboBoxSelectionChanged( const mitk::DataNode* ) ) );
connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) );
// connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) );
// connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) );
connect( m_Controls->tabWidgetSegmentationTools, SIGNAL(currentChanged(int)), this, SLOT(OnTabWidgetChanged(int)));
// connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
// this, SLOT( OnSurfaceSelectionChanged( ) ) );
connect(m_Controls->m_SlicesInterpolator, SIGNAL(SignalShowMarkerNodes(bool)), this, SLOT(OnShowMarkerNodes(bool)));
- // m_Controls->MaskSurfaces->SetDataStorage(this->GetDefaultDataStorage());
+ // m_Controls->MaskSurfaces->SetDataStorage(this->GetDataStorage());
// m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface"));
}
+void QmitkSegmentationView::SetFocus()
+{
+ m_Controls->btnNewSegmentation->setFocus();
+}
+
void QmitkSegmentationView::OnManualTool2DSelected(int id)
{
if (id >= 0)
{
std::string text = "Active Tool: \"";
mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
text += toolManager->GetToolById(id)->GetName();
text += "\"";
mitk::StatusBar::GetInstance()->DisplayText(text.c_str());
us::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource();
this->SetMouseCursor(resource, 0, 0);
}
else
{
this->ResetMouseCursor();
mitk::StatusBar::GetInstance()->DisplayText("");
}
}
void QmitkSegmentationView::ResetMouseCursor()
{
if ( m_MouseCursorSet )
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
m_MouseCursorSet = false;
}
}
void QmitkSegmentationView::SetMouseCursor( const us::ModuleResource& resource, int hotspotX, int hotspotY )
{
if (!resource) return;
// Remove previously set mouse cursor
if ( m_MouseCursorSet )
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
}
us::ModuleResourceStream cursor(resource, std::ios::binary);
mitk::ApplicationCursor::GetInstance()->PushCursor( cursor, hotspotX, hotspotY );
m_MouseCursorSet = true;
}
void QmitkSegmentationView::SetToolSelectionBoxesEnabled(bool status)
{
if (status)
{
m_Controls->m_ManualToolSelectionBox2D->RecreateButtons();
m_Controls->m_ManualToolSelectionBox3D->RecreateButtons();
}
m_Controls->m_ManualToolSelectionBox2D->setEnabled(status);
m_Controls->m_ManualToolSelectionBox3D->setEnabled(status);
m_Controls->m_SlicesInterpolator->setEnabled(status);
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h
index fbc87b517e..8be9da5b55 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.h
@@ -1,176 +1,180 @@
/*===================================================================
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 QmitkSegmentationView_h
#define QmitkSegmentationView_h
-#include "QmitkFunctionality.h"
+#include
+#include
+#include
#include
#include "ui_QmitkSegmentationControls.h"
class QmitkRenderWindow;
/**
* \ingroup ToolManagerEtAl
* \ingroup org_mitk_gui_qt_segmentation_internal
* \warning Implementation of this class is split up into two .cpp files to make things more compact. Check both this file and QmitkSegmentationOrganNamesHandling.cpp
*/
-class QmitkSegmentationView : public QmitkFunctionality
+class QmitkSegmentationView : public QmitkAbstractView, public mitk::ILifecycleAwarePart, public mitk::IRenderWindowPartListener
{
Q_OBJECT
public:
QmitkSegmentationView();
virtual ~QmitkSegmentationView();
typedef std::map NodeTagMapType;
/*!
\brief Invoked when the DataManager selection changed
*/
virtual void OnSelectionChanged(mitk::DataNode* node);
- virtual void OnSelectionChanged(std::vector nodes) override;
+ virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override;
// reaction to new segmentations being created by segmentation tools
void NewNodesGenerated();
void NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType*);
- // QmitkFunctionality's activate/deactivate
virtual void Activated() override;
virtual void Deactivated() override;
+ bool IsActivated() const;
virtual void Visible() override;
+ virtual void Hidden() override;
- // QmitkFunctionality's changes regarding THE QmitkStdMultiWidget
- virtual void StdMultiWidgetAvailable(QmitkStdMultiWidget& stdMultiWidget) override;
- virtual void StdMultiWidgetNotAvailable() override;
- virtual void StdMultiWidgetClosed(QmitkStdMultiWidget& stdMultiWidget) override;
+ ///
+ /// Sets the focus to an internal widget.
+ ///
+ virtual void SetFocus() override;
+
+ virtual void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override;
+
+ virtual void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override;
// BlueBerry's notification about preference changes (e.g. from a dialog)
virtual void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override;
// observer to mitk::RenderingManager's RenderingManagerViewsInitializedEvent event
void RenderingManagerReinitialized();
// observer to mitk::SliceController's SliceRotation event
void SliceRotation(const itk::EventObject&);
static const std::string VIEW_ID;
protected slots:
void OnPatientComboBoxSelectionChanged(const mitk::DataNode* node);
void OnSegmentationComboBoxSelectionChanged(const mitk::DataNode* node);
// reaction to the button "New segmentation"
void CreateNewSegmentation();
void OnManualTool2DSelected(int id);
void OnWorkingNodeVisibilityChanged();
// called if a node's binary property has changed
void OnBinaryPropertyChanged();
void OnShowMarkerNodes(bool);
void OnTabWidgetChanged(int);
protected:
// a type for handling lists of DataNodes
typedef std::vector NodeList;
- // set available multiwidget
- void SetMultiWidget(QmitkStdMultiWidget* multiWidget);
-
// actively query the current selection of data manager
//void PullCurrentDataManagerSelection();
// reactions to selection events from data manager (and potential other senders)
//void BlueBerrySelectionChanged(berry::IWorkbenchPart::Pointer sourcepart, berry::ISelection::ConstPointer selection);
mitk::DataNode::Pointer FindFirstRegularImage( std::vector nodes );
mitk::DataNode::Pointer FindFirstSegmentation( std::vector nodes );
// propagate BlueBerry selection to ToolManager for manual segmentation
void SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData);
// checks if given render window aligns with the slices of given image
bool IsRenderWindowAligned(QmitkRenderWindow* renderWindow, mitk::Image* image);
// make sure all images/segmentations look as selected by the users in this view's preferences
void ForceDisplayPreferencesUponAllImages();
// decorates a DataNode according to the user preference settings
void ApplyDisplayOptions(mitk::DataNode* node);
// GUI setup
void CreateQtPartControl(QWidget* parent) override;
void ResetMouseCursor( );
void SetMouseCursor(const us::ModuleResource&, int hotspotX, int hotspotY );
void SetToolSelectionBoxesEnabled(bool);
bool m_MouseCursorSet;
// If a contourmarker is selected, the plane in the related widget will be reoriented according to the marker`s geometry
void OnContourMarkerSelected (const mitk::DataNode* node);
void NodeRemoved(const mitk::DataNode* node) override;
void NodeAdded(const mitk::DataNode *node) override;
bool CheckForSameGeometry(const mitk::DataNode*, const mitk::DataNode*) const;
void UpdateWarningLabel(QString text/*, bool overwriteExistingText = true*/);
// the Qt parent of our GUI (NOT of this object)
QWidget* m_Parent;
// our GUI
Ui::QmitkSegmentationControls * m_Controls;
- // THE currently existing QmitkStdMultiWidget
- QmitkStdMultiWidget * m_MultiWidget;
-
unsigned long m_VisibilityChangedObserverTag;
bool m_DataSelectionChanged;
NodeTagMapType m_WorkingDataObserverTags;
NodeTagMapType m_BinaryPropertyObserverTags;
unsigned int m_RenderingManagerObserverTag;
bool m_AutoSelectionEnabled;
mitk::NodePredicateOr::Pointer m_IsOfTypeImagePredicate;
mitk::NodePredicateProperty::Pointer m_IsBinaryPredicate;
mitk::NodePredicateNot::Pointer m_IsNotBinaryPredicate;
mitk::NodePredicateAnd::Pointer m_IsNotABinaryImagePredicate;
mitk::NodePredicateAnd::Pointer m_IsABinaryImagePredicate;
mitk::NodePredicateOr::Pointer m_IsASegmentationImagePredicate;
mitk::NodePredicateAnd::Pointer m_IsAPatientImagePredicate;
+
+ bool m_Activated;
+
};
#endif /*QMITKsegmentationVIEW_H_*/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.cpp
index 7b0547a5e1..7233b9a5eb 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.cpp
@@ -1,117 +1,117 @@
/*===================================================================
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 "QmitkThresholdAction.h"
// MITK
#include
#include
#include
// Qt
#include
#include
#include
#include
using namespace berry;
using namespace mitk;
using namespace std;
QmitkThresholdAction::QmitkThresholdAction()
{
}
QmitkThresholdAction::~QmitkThresholdAction()
{
}
void QmitkThresholdAction::Run(const QList &selectedNodes)
{
m_ThresholdingToolManager = ToolManager::New(m_DataStorage);
m_ThresholdingToolManager->RegisterClient();
Tool *binaryThresholdTool = m_ThresholdingToolManager->GetToolById(m_ThresholdingToolManager->GetToolIdByToolType());
if (binaryThresholdTool != NULL)
{
QmitkBinaryThresholdToolGUI *gui = dynamic_cast(binaryThresholdTool->GetGUI("Qmitk", "GUI").GetPointer());
if (gui != NULL)
{
QDialog thresholdingDialog(QApplication::activeWindow(), Qt::Window | Qt::WindowStaysOnTopHint);
thresholdingDialog.setWindowFlags(thresholdingDialog.windowFlags() & ~Qt::WindowMinimizeButtonHint);
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(rejected()), &thresholdingDialog, SLOT(reject()));
connect(gui, SIGNAL(thresholdAccepted()), &thresholdingDialog, SLOT(reject()));
QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins(3, 3, 3, 3);
gui->SetTool(binaryThresholdTool);
gui->setParent(&thresholdingDialog);
layout->addWidget(gui);
layout->addWidget(buttonBox);
thresholdingDialog.setLayout(layout);
thresholdingDialog.setMinimumWidth(350);
m_SelectedNode = selectedNodes[0];
m_ThresholdingToolManager->SetReferenceData(selectedNodes[0]);
m_ThresholdingToolManager->ActivateTool(m_ThresholdingToolManager->GetToolIdByToolType());
m_ThresholdingToolManager->ActiveToolChanged += mitk::MessageDelegate(this, &QmitkThresholdAction::OnThresholdingToolManagerToolModified);
thresholdingDialog.exec();
m_ThresholdingToolManager->ActiveToolChanged -= mitk::MessageDelegate(this, &QmitkThresholdAction::OnThresholdingToolManagerToolModified);
m_ThresholdingToolManager->SetReferenceData(NULL);
m_ThresholdingToolManager->ActivateTool(-1);
m_SelectedNode = 0;
}
}
m_ThresholdingToolManager->UnregisterClient();
}
void QmitkThresholdAction::OnThresholdingToolManagerToolModified()
{
if (m_ThresholdingToolManager.IsNotNull())
{
if (m_ThresholdingToolManager->GetActiveToolID() < 0)
{
m_ThresholdingToolManager->SetReferenceData(m_SelectedNode);
m_ThresholdingToolManager->ActivateTool(m_ThresholdingToolManager->GetToolIdByToolType());
}
}
}
void QmitkThresholdAction::SetDataStorage(DataStorage *dataStorage)
{
m_DataStorage = dataStorage;
}
void QmitkThresholdAction::SetSmoothed(bool)
{
}
void QmitkThresholdAction::SetDecimated(bool)
{
}
-void QmitkThresholdAction::SetFunctionality(QtViewPart* /*functionality*/)
+void QmitkThresholdAction::SetFunctionality(QtViewPart* /*view*/)
{
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.h
index 139ba20fa9..30ee4f4c04 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkThresholdAction.h
@@ -1,57 +1,57 @@
/*===================================================================
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 QMITKTHRESHOLDACTION_H
#define QMITKTHRESHOLDACTION_H
#include
// Parent classes
#include
#include
// Data members
#include
#include
class MITK_QT_SEGMENTATION QmitkThresholdAction : public QObject, public mitk::IContextMenuAction
{
Q_OBJECT
Q_INTERFACES(mitk::IContextMenuAction)
public:
QmitkThresholdAction();
~QmitkThresholdAction();
// IContextMenuAction
void Run(const QList &selectedNodes) override;
void SetDataStorage(mitk::DataStorage *dataStorage) override;
void SetSmoothed(bool smoothed) override;
void SetDecimated(bool decimated) override;
- void SetFunctionality(berry::QtViewPart *functionality) override;
+ void SetFunctionality(berry::QtViewPart* view) override;
void OnThresholdingToolManagerToolModified();
private:
QmitkThresholdAction(const QmitkThresholdAction &);
QmitkThresholdAction & operator=(const QmitkThresholdAction &);
mitk::DataNode::Pointer m_SelectedNode;
mitk::DataStorage::Pointer m_DataStorage;
mitk::ToolManager::Pointer m_ThresholdingToolManager;
};
#endif
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp
index 6f9634a0f2..68da1f47d0 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp
@@ -1,230 +1,230 @@
/*===================================================================
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 "QmitkContourModelToImageWidget.h"
#include "mitkImage.h"
#include "../../Common/QmitkDataSelectionWidget.h"
#include
#include
#include
#include
#include
#include
#include
static const char* const HelpText = "Select a image and a contour(set)";
class QmitkContourModelToImageWidgetPrivate
{
public:
QmitkContourModelToImageWidgetPrivate();
~QmitkContourModelToImageWidgetPrivate();
/** @brief Check if selections is valid. */
void SelectionControl( unsigned int index, const mitk::DataNode* selection);
/** @brief Enable buttons if data selction is valid. */
void EnableButtons(bool enable = true);
/** @brief Does the actual contour filling */
mitk::Image::Pointer FillContourModelSetIntoImage(mitk::Image *image, mitk::ContourModelSet *contourSet, unsigned int timeStep);
Ui::QmitkContourModelToImageWidgetControls m_Controls;
QFutureWatcher m_Watcher;
};
QmitkContourModelToImageWidgetPrivate::QmitkContourModelToImageWidgetPrivate()
{
}
QmitkContourModelToImageWidgetPrivate::~QmitkContourModelToImageWidgetPrivate()
{
}
void QmitkContourModelToImageWidgetPrivate::EnableButtons(bool enable)
{
m_Controls.btnProcess->setEnabled(enable);
}
void QmitkContourModelToImageWidgetPrivate::SelectionControl(unsigned int index, const mitk::DataNode* /*selection*/)
{
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(index);
dataSelectionWidget->SetHelpText("");
this->EnableButtons();
}
mitk::Image::Pointer QmitkContourModelToImageWidgetPrivate::FillContourModelSetIntoImage(mitk::Image* image, mitk::ContourModelSet* contourSet, unsigned int timeStep)
{
// Use mitk::ContourModelSetToImageFilter to fill the ContourModelSet into the image
mitk::ContourModelSetToImageFilter::Pointer contourFiller = mitk::ContourModelSetToImageFilter::New();
contourFiller->SetTimeStep(timeStep);
contourFiller->SetImage(image);
contourFiller->SetInput(contourSet);
contourFiller->MakeOutputBinaryOn();
contourFiller->Update();
mitk::Image::Pointer result = contourFiller->GetOutput();
if (result.IsNull())
{
MITK_ERROR<<"Could not write the selected contours into the image!";
}
result->DisconnectPipeline();
return result;
}
void QmitkContourModelToImageWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection)
{
Q_D(QmitkContourModelToImageWidget);
QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer node0 = dataSelectionWidget->GetSelection(0);
mitk::DataNode::Pointer node1 = dataSelectionWidget->GetSelection(1);
if (node0.IsNull() || node1.IsNull() )
{
d->EnableButtons(false);
dataSelectionWidget->SetHelpText(HelpText);
}
else
{
d->SelectionControl(index, selection);
}
}
void QmitkContourModelToImageWidget::OnProcessingFinished()
{
// Called when processing finished
// Adding the result to the data storage
Q_D(QmitkContourModelToImageWidget);
// Adding the result to the data storage
mitk::Image::Pointer result = d->m_Watcher.result();
if (result.IsNotNull())
{
QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0);
mitk::DataNode::Pointer contourNode = dataSelectionWidget->GetSelection(1);
mitk::DataNode::Pointer filled = mitk::DataNode::New();
std::stringstream stream;
stream << imageNode->GetName();
stream << "_";
stream << contourNode->GetName();
filled->SetName(stream.str());
filled->SetData(result);
dataSelectionWidget->GetDataStorage()->Add(filled, imageNode);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else
{
MITK_ERROR<<"Error filling contours into an image!";
}
d->EnableButtons();
}
void QmitkContourModelToImageWidget::OnProcessPressed()
{
Q_D(QmitkContourModelToImageWidget);
QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0);
mitk::DataNode::Pointer contourNode = dataSelectionWidget->GetSelection(1);
// Check if data nodes are valid
if(imageNode.IsNull() || contourNode.IsNull() )
{
MITK_ERROR << "Selection does not contain valid data";
QMessageBox::information( this, "Contour To Image",
"Selection does not contain valid data, please select a binary image and a contour(set)",
QMessageBox::Ok );
d->m_Controls.btnProcess->setEnabled(false);
return;
}
mitk::Image::Pointer image = static_cast(imageNode->GetData());
// Check if the image is valid
if (image.IsNull())
{
MITK_ERROR<<"Error writing contours into image! Invalid image data selected!";
return;
}
unsigned int timeStep = this->GetTimeNavigationController()->GetTime()->GetPos();
// Check if the selected contours are valid
mitk::ContourModelSet::Pointer contourSet;
mitk::ContourModel::Pointer contour = dynamic_cast(contourNode->GetData());
if (contour.IsNotNull())
{
contourSet = mitk::ContourModelSet::New();
contourSet->AddContourModel(contour);
}
else
{
contourSet = static_cast(contourNode->GetData());
if (contourSet.IsNull())
{
MITK_ERROR<<"Error writing contours into binary image! Invalid contour data selected!";
return;
}
}
//Disable Buttons during calculation and initialize Progressbar
d->EnableButtons(false);
// Start the computation in a background thread
QFuture< mitk::Image::Pointer > future = QtConcurrent::run(d, &QmitkContourModelToImageWidgetPrivate::FillContourModelSetIntoImage, image, contourSet, timeStep);
d->m_Watcher.setFuture(future);
}
QmitkContourModelToImageWidget::QmitkContourModelToImageWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent)
: QmitkSegmentationUtilityWidget(timeNavigationController, parent),
d_ptr(new QmitkContourModelToImageWidgetPrivate())
{
Q_D(QmitkContourModelToImageWidget);
// Set up UI
d->m_Controls.setupUi(this);
d->m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::ImageAndSegmentationPredicate);
d->m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::ContourModelPredicate);
d->m_Controls.dataSelectionWidget->SetHelpText(HelpText);
d->EnableButtons(false);
// Create connections
connect (d->m_Controls.btnProcess, SIGNAL(pressed()), this, SLOT(OnProcessPressed()));
connect(d->m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)),
this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*)));
connect(&d->m_Watcher, SIGNAL(finished()), this, SLOT(OnProcessingFinished()));
if( d->m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() &&
d->m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() )
{
- OnSelectionChanged( 0, d->m_Controls.dataSelectionWidget->GetSelection(0));
+ OnSelectionChanged(0, d->m_Controls.dataSelectionWidget->GetSelection(0));
}
}
QmitkContourModelToImageWidget::~QmitkContourModelToImageWidget()
{
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp
index f2ca4eb75d..d707feba0b 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp
@@ -1,302 +1,302 @@
/*===================================================================
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 "QmitkImageMaskingWidget.h"
#include "mitkImage.h"
#include "../../Common/QmitkDataSelectionWidget.h"
#include
#include
#include
#include
#include
#include
#include
#include
static const char* const HelpText = "Select a regular image and a binary image";
QmitkImageMaskingWidget::QmitkImageMaskingWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent)
: QmitkSegmentationUtilityWidget(timeNavigationController, parent)
{
m_Controls.setupUi(this);
m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::ImagePredicate);
m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::SegmentationPredicate);
m_Controls.dataSelectionWidget->SetHelpText(HelpText);
this->EnableButtons(false);
connect (m_Controls.rbMaskImage, SIGNAL(toggled(bool)), this, SLOT(OnImageMaskingToggled(bool)));
connect (m_Controls.rbMaskSurface, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceMaskingToggled(bool)));
connect (m_Controls.btnMaskImage, SIGNAL(clicked()), this, SLOT(OnMaskImagePressed()));
connect(m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)),
this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*)));
if( m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() &&
m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() )
{
- this->OnSelectionChanged( 0, m_Controls.dataSelectionWidget->GetSelection(0));
+ this->OnSelectionChanged(0, m_Controls.dataSelectionWidget->GetSelection(0));
}
}
QmitkImageMaskingWidget::~QmitkImageMaskingWidget()
{
}
void QmitkImageMaskingWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection)
{
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer node0 = dataSelectionWidget->GetSelection(0);
mitk::DataNode::Pointer node1 = dataSelectionWidget->GetSelection(1);
if (node0.IsNull() || node1.IsNull() )
{
if( m_Controls.rbMaskImage->isChecked() )
{
dataSelectionWidget->SetHelpText(HelpText);
}
else
{
dataSelectionWidget->SetHelpText("Select a regular image and a surface");
}
this->EnableButtons(false);
}
else
{
this->SelectionControl(index, selection);
}
}
void QmitkImageMaskingWidget::SelectionControl(unsigned int index, const mitk::DataNode* selection)
{
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(index);
//if Image-Masking is enabled, check if image-dimension of reference and binary image is identical
if( m_Controls.rbMaskImage->isChecked() )
{
if( dataSelectionWidget->GetSelection(0) == dataSelectionWidget->GetSelection(1) )
{
dataSelectionWidget->SetHelpText("Select two different images above");
this->EnableButtons(false);
return;
}
else if( node.IsNotNull() && selection )
{
mitk::Image::Pointer referenceImage = dynamic_cast ( dataSelectionWidget->GetSelection(0)->GetData() );
mitk::Image::Pointer maskImage = dynamic_cast ( dataSelectionWidget->GetSelection(1)->GetData() );
if( maskImage.IsNull() || referenceImage->GetLargestPossibleRegion().GetSize() != maskImage->GetLargestPossibleRegion().GetSize() )
{
dataSelectionWidget->SetHelpText("Different image sizes cannot be masked");
this->EnableButtons(false);
return;
}
}
else
{
dataSelectionWidget->SetHelpText(HelpText);
return;
}
}
dataSelectionWidget->SetHelpText("");
this->EnableButtons();
}
void QmitkImageMaskingWidget::EnableButtons(bool enable)
{
m_Controls.btnMaskImage->setEnabled(enable);
}
void QmitkImageMaskingWidget::OnImageMaskingToggled(bool status)
{
if (status)
{
m_Controls.dataSelectionWidget->SetHelpText("Select a regular image and a binary image");
m_Controls.dataSelectionWidget->SetPredicate(1, QmitkDataSelectionWidget::SegmentationPredicate);
}
}
void QmitkImageMaskingWidget::OnSurfaceMaskingToggled(bool status)
{
if (status)
{
m_Controls.dataSelectionWidget->SetHelpText("Select a regular image and a surface");
m_Controls.dataSelectionWidget->SetPredicate(1, QmitkDataSelectionWidget::SurfacePredicate);
}
}
void QmitkImageMaskingWidget::OnMaskImagePressed()
{
//Disable Buttons during calculation and initialize Progressbar
this->EnableButtons(false);
mitk::ProgressBar::GetInstance()->AddStepsToDo(4);
mitk::ProgressBar::GetInstance()->Progress();
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
//create result image, get mask node and reference image
mitk::Image::Pointer resultImage(nullptr);
mitk::DataNode::Pointer maskingNode = dataSelectionWidget->GetSelection(1);
mitk::Image::Pointer referenceImage = static_cast(dataSelectionWidget->GetSelection(0)->GetData());
if(referenceImage.IsNull() || maskingNode.IsNull() )
{
MITK_ERROR << "Selection does not contain an image";
QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain an image", QMessageBox::Ok );
m_Controls.btnMaskImage->setEnabled(true);
return;
}
//Do Image-Masking
if (m_Controls.rbMaskImage->isChecked())
{
mitk::ProgressBar::GetInstance()->Progress();
mitk::Image::Pointer maskImage = dynamic_cast ( maskingNode->GetData() );
if(maskImage.IsNull() )
{
MITK_ERROR << "Selection does not contain a binary image";
QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain a binary image", QMessageBox::Ok );
this->EnableButtons();
return;
}
if( referenceImage->GetLargestPossibleRegion().GetSize() == maskImage->GetLargestPossibleRegion().GetSize() )
{
resultImage = this->MaskImage( referenceImage, maskImage );
}
}
//Do Surface-Masking
else
{
mitk::ProgressBar::GetInstance()->Progress();
//1. convert surface to image
mitk::Surface::Pointer surface = dynamic_cast ( maskingNode->GetData() );
//TODO Get 3D Surface of current time step
if(surface.IsNull())
{
MITK_ERROR << "Selection does not contain a surface";
QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain a surface", QMessageBox::Ok );
this->EnableButtons();
return;
}
mitk::Image::Pointer maskImage = this->ConvertSurfaceToImage( referenceImage, surface );
//2. mask reference image with mask image
if(maskImage.IsNotNull() &&
referenceImage->GetLargestPossibleRegion().GetSize() == maskImage->GetLargestPossibleRegion().GetSize() )
{
resultImage = this->MaskImage( referenceImage, maskImage );
}
}
mitk::ProgressBar::GetInstance()->Progress();
if( resultImage.IsNull() )
{
MITK_ERROR << "Masking failed";
QMessageBox::information( this, "Image and Surface Masking", "Masking failed. For more information please see logging window.", QMessageBox::Ok );
this->EnableButtons();
mitk::ProgressBar::GetInstance()->Progress(4);
return;
}
//Add result to data storage
this->AddToDataStorage(
dataSelectionWidget->GetDataStorage(),
resultImage,
dataSelectionWidget->GetSelection(0)->GetName() + "_" + dataSelectionWidget->GetSelection(1)->GetName(),
dataSelectionWidget->GetSelection(0));
this->EnableButtons();
mitk::ProgressBar::GetInstance()->Progress();
}
mitk::Image::Pointer QmitkImageMaskingWidget::MaskImage(mitk::Image::Pointer referenceImage, mitk::Image::Pointer maskImage )
{
mitk::Image::Pointer resultImage(nullptr);
mitk::MaskImageFilter::Pointer maskFilter = mitk::MaskImageFilter::New();
maskFilter->SetInput( referenceImage );
maskFilter->SetMask( maskImage );
maskFilter->OverrideOutsideValueOn();
maskFilter->SetOutsideValue( referenceImage->GetStatistics()->GetScalarValueMin() );
try
{
maskFilter->Update();
}
catch(itk::ExceptionObject& excpt)
{
MITK_ERROR << excpt.GetDescription();
return nullptr;
}
resultImage = maskFilter->GetOutput();
return resultImage;
}
mitk::Image::Pointer QmitkImageMaskingWidget::ConvertSurfaceToImage( mitk::Image::Pointer image, mitk::Surface::Pointer surface )
{
mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
mitk::ProgressBar::GetInstance()->Progress();
mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
surfaceToImageFilter->MakeOutputBinaryOn();
surfaceToImageFilter->SetInput(surface);
surfaceToImageFilter->SetImage(image);
try
{
surfaceToImageFilter->Update();
}
catch(itk::ExceptionObject& excpt)
{
MITK_ERROR << excpt.GetDescription();
return nullptr;
}
mitk::ProgressBar::GetInstance()->Progress();
mitk::Image::Pointer resultImage = mitk::Image::New();
resultImage = surfaceToImageFilter->GetOutput();
return resultImage;
}
void QmitkImageMaskingWidget::AddToDataStorage(mitk::DataStorage::Pointer dataStorage, mitk::Image::Pointer segmentation, const std::string& name, mitk::DataNode::Pointer parent )
{
mitk::DataNode::Pointer dataNode = mitk::DataNode::New();
dataNode->SetName(name);
dataNode->SetData(segmentation);
dataStorage->Add(dataNode, parent);
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidget.cpp
index 91aa429b58..693c70910d 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidget.cpp
@@ -1,161 +1,161 @@
/*===================================================================
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 "QmitkSurfaceToImageWidget.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const char* const HelpText = "Select an image and a surface above";
QmitkSurfaceToImageWidget::QmitkSurfaceToImageWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent)
: QmitkSegmentationUtilityWidget(timeNavigationController, parent)
{
m_Controls.setupUi(this);
m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::ImageAndSegmentationPredicate);
m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::SurfacePredicate);
m_Controls.dataSelectionWidget->SetHelpText(HelpText);
this->EnableButtons(false);
connect (m_Controls.btnSurface2Image, SIGNAL(pressed()), this, SLOT(OnSurface2ImagePressed()));
connect(m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)),
this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*)));
if( m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() &&
m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() )
{
- this->OnSelectionChanged( 0, m_Controls.dataSelectionWidget->GetSelection(0));
+ this->OnSelectionChanged(0, m_Controls.dataSelectionWidget->GetSelection(0));
}
}
QmitkSurfaceToImageWidget::~QmitkSurfaceToImageWidget()
{
}
void QmitkSurfaceToImageWidget::EnableButtons(bool enable)
{
m_Controls.btnSurface2Image->setEnabled(enable);
}
void QmitkSurfaceToImageWidget::OnSelectionChanged(unsigned int, const mitk::DataNode*)
{
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0);
mitk::DataNode::Pointer surfaceNode = dataSelectionWidget->GetSelection(1);
if (imageNode.IsNull() || surfaceNode.IsNull() )
{
dataSelectionWidget->SetHelpText(HelpText);
this->EnableButtons(false);
}
else
{
mitk::Image::Pointer image = dynamic_cast( dataSelectionWidget->GetSelection(0)->GetData() );
mitk::Surface::Pointer surface = dynamic_cast( dataSelectionWidget->GetSelection(1)->GetData() );
if( image->GetTimeSteps() != surface->GetTimeSteps() )
{
dataSelectionWidget->SetHelpText("Image and surface are of different size");
this->EnableButtons(false);
}
else
{
dataSelectionWidget->SetHelpText("");
this->EnableButtons();
}
}
}
void QmitkSurfaceToImageWidget::OnSurface2ImagePressed()
{
this->EnableButtons(false);
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::Image::Pointer image = dynamic_cast( dataSelectionWidget->GetSelection(0)->GetData() );
mitk::Surface::Pointer surface = dynamic_cast( dataSelectionWidget->GetSelection(1)->GetData() );
if( image.IsNull() || surface.IsNull())
{
MITK_ERROR << "Selection does not contain an image and/or a surface";
QMessageBox::information( this, "Surface To Image", "Selection does not contain an image and/or a surface", QMessageBox::Ok );
this->EnableButtons();
return;
}
mitk::Image::Pointer resultImage(nullptr);
resultImage = this->ConvertSurfaceToImage( image, surface );
if( resultImage.IsNull() )
{
MITK_ERROR << "Convert Surface to binary image failed";
QMessageBox::information( this, "Surface To Image", "Convert Surface to binary image failed", QMessageBox::Ok );
this->EnableButtons();
return;
}
//create name for result node
std::string nameOfResultImage = dataSelectionWidget->GetSelection(0)->GetName();
nameOfResultImage.append("_");
nameOfResultImage.append(dataSelectionWidget->GetSelection(1)->GetName());
//create data node and add to data storage
mitk::DataNode::Pointer resultNode = mitk::DataNode::New();
resultNode->SetData( resultImage );
resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) );
// resultNode->SetProperty("binary", mitk::BoolProperty::New(true) );
dataSelectionWidget->GetDataStorage()->Add(resultNode, dataSelectionWidget->GetSelection(0));
this->EnableButtons();
}
mitk::LabelSetImage::Pointer QmitkSurfaceToImageWidget::ConvertSurfaceToImage( mitk::Image::Pointer image, mitk::Surface::Pointer surface )
{
mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
mitk::ProgressBar::GetInstance()->Progress();
mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
surfaceToImageFilter->MakeOutputBinaryOn();
surfaceToImageFilter->SetInput(surface);
surfaceToImageFilter->SetImage(image);
try
{
surfaceToImageFilter->Update();
}
catch(itk::ExceptionObject& excpt)
{
MITK_ERROR << excpt.GetDescription();
return nullptr;
}
mitk::ProgressBar::GetInstance()->Progress();
mitk::Image::Pointer resultImage = surfaceToImageFilter->GetOutput();
mitk::LabelSetImage::Pointer multilabelImage = mitk::LabelSetImage::New();
multilabelImage->InitializeByLabeledImage(resultImage);
return multilabelImage;
}