diff --git a/Examples/Tutorial/Step2/Step2.cpp b/Examples/Tutorial/Step2/Step2.cpp index e40fbd0610..2dac5068de 100644 --- a/Examples/Tutorial/Step2/Step2.cpp +++ b/Examples/Tutorial/Step2/Step2.cpp @@ -1,102 +1,102 @@ /*=================================================================== 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 "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include #include #include #include //##Documentation //## @brief Load one or more data sets (many image, surface //## and other formats) and display it in a 2D view int main(int argc, char *argv[]) { QApplication qtapplication(argc, argv); if (argc < 2) { fprintf( stderr, "Usage: %s [filename1] [filename2] ...\n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str()); return 1; } // Register Qmitk-dependent global instances QmitkRegisterClasses(); //************************************************************************* // Part I: Basic initialization //************************************************************************* // Create a data storage object. We will use it as a singleton mitk::StandaloneDataStorage::Pointer storage = mitk::StandaloneDataStorage::New(); //************************************************************************* // Part II: Create some data by reading files //************************************************************************* int i; for (i = 1; i < argc; ++i) { // For testing if (strcmp(argv[i], "-testing") == 0) continue; //********************************************************************* // Part III: Put the data into the datastorage //********************************************************************* // Add the node to the DataStorage mitk::IOUtil::Load(argv[i], *storage); } //************************************************************************* // Part IV: Create window and pass the datastorage to it //************************************************************************* // Create a RenderWindow QmitkRenderWindow renderWindow; // Tell the RenderWindow which (part of) the datastorage to render renderWindow.GetRenderer()->SetDataStorage(storage); // Initialize the RenderWindow mitk::TimeGeometry::Pointer geo = storage->ComputeBoundingGeometry3D(storage->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); // Select a slice mitk::SliceNavigationController::Pointer sliceNaviController = renderWindow.GetSliceNavigationController(); if (sliceNaviController) sliceNaviController->GetSlice()->SetPos(2); //************************************************************************* // Part V: Qt-specific initialization //************************************************************************* renderWindow.show(); renderWindow.resize(256, 256); -// for testing + // for testing #include "QtTesting.h" if (strcmp(argv[argc - 1], "-testing") != 0) return qtapplication.exec(); else return QtTesting(); } /** \example Step2.cpp -*/ +*/ \ No newline at end of file diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 0efaed9db9..fa15ad05f9 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,80 +1,82 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(mitk_modules Core CommandLine AppUtil DCMTesting RDF LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel ImageStatistics ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QtWidgets QtWidgetsExt C3js QmlItems SegmentationUI Classification DiffusionImaging GPGPU OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI VtkShaders DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware TumorInvasionAnalysis MatchPointRegistration MatchPointRegistrationUI BoundingShape RenderWindowManager RenderWindowManagerUI CEST DICOMQI + MyAwesomeLib + SurfaceRegistration ) if(MITK_ENABLE_PIC_READER) list(APPEND mitk_modules IpPicSupportIO) endif() diff --git a/Modules/MyAwesomeLib/CMakeLists.txt b/Modules/MyAwesomeLib/CMakeLists.txt new file mode 100644 index 0000000000..0198c5b80c --- /dev/null +++ b/Modules/MyAwesomeLib/CMakeLists.txt @@ -0,0 +1,3 @@ +mitk_create_module( MyAwesomeLib + DEPENDS PUBLIC MitkCore +) diff --git a/Modules/MyAwesomeLib/files.cmake b/Modules/MyAwesomeLib/files.cmake new file mode 100644 index 0000000000..a578fb19e3 --- /dev/null +++ b/Modules/MyAwesomeLib/files.cmake @@ -0,0 +1,9 @@ +set(CPP_FILES + AwesomeImageFilter.cpp + AwesomeImageInteractor.cpp +) + +set(RESOURCE_FILES + Interactions/Paint.xml + Interactions/PaintConfig.xml +) diff --git a/Modules/MyAwesomeLib/include/AwesomeImageFilter.h b/Modules/MyAwesomeLib/include/AwesomeImageFilter.h new file mode 100644 index 0000000000..f821bf1a82 --- /dev/null +++ b/Modules/MyAwesomeLib/include/AwesomeImageFilter.h @@ -0,0 +1,52 @@ +/*=================================================================== + +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 AwesomeImageFilter_h +#define AwesomeImageFilter_h + +#include + +// The following header file is generated by CMake and thus it's located in +// the build directory. It provides an export macro for classes and functions +// that you want to be part of the public interface of your module. +#include + +// While you are free to derive directly from ITK filter base classes, +// MITK filter base classes provide typed accessor methods for the inputs +// and outputs, which will save you and your clients lots of manual casting. +class MITKMYAWESOMELIB_EXPORT AwesomeImageFilter final : public mitk::ImageToImageFilter +{ +public: + // All classes that derive from an ITK-based MITK class need at least the + // following two macros. Make sure you don't declare the constructor public + // to force clients of your class to follow the ITK convention for + // instantiating classes via the static New() method. + mitkClassMacro(AwesomeImageFilter, mitk::ImageToImageFilter) + itkFactorylessNewMacro(Self) + + itkSetMacro(Offset, int) + itkGetMacro(Offset, int) + +private: + AwesomeImageFilter(); + ~AwesomeImageFilter(); + + void GenerateData() override; + + int m_Offset; +}; + +#endif diff --git a/Modules/MyAwesomeLib/include/AwesomeImageInteractor.h b/Modules/MyAwesomeLib/include/AwesomeImageInteractor.h new file mode 100644 index 0000000000..c922f33e0f --- /dev/null +++ b/Modules/MyAwesomeLib/include/AwesomeImageInteractor.h @@ -0,0 +1,50 @@ +/*=================================================================== + +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 AwesomeImageInteractor_h +#define AwesomeImageInteractor_h + +#include +#include + +#include +//namespace mitk +//{ +// + // See AwesomeImageFilter.h for details on typical class declarations + // in MITK. The actual functionality of this class is commented in its + // implementation file. + + class MITKMYAWESOMELIB_EXPORT AwesomeImageInteractor final : public mitk::DataInteractor + { + public: + mitkClassMacro(AwesomeImageInteractor, DataInteractor) + itkFactorylessNewMacro(Self) + + private: + AwesomeImageInteractor(); + ~AwesomeImageInteractor(); + + void ConnectActionsAndFunctions() override; + void DataNodeChanged() override; + + void Paint(mitk::StateMachineAction* action, mitk::InteractionEvent* event); + + itk::Index<3> m_LastPixelIndex; + }; + +#endif +//} \ No newline at end of file diff --git a/Modules/MyAwesomeLib/resource/Interactions/Paint.xml b/Modules/MyAwesomeLib/resource/Interactions/Paint.xml new file mode 100644 index 0000000000..c63efb3683 --- /dev/null +++ b/Modules/MyAwesomeLib/resource/Interactions/Paint.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/Modules/MyAwesomeLib/resource/Interactions/PaintConfig.xml b/Modules/MyAwesomeLib/resource/Interactions/PaintConfig.xml new file mode 100644 index 0000000000..e141844565 --- /dev/null +++ b/Modules/MyAwesomeLib/resource/Interactions/PaintConfig.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Modules/MyAwesomeLib/src/AwesomeImageFilter.cpp b/Modules/MyAwesomeLib/src/AwesomeImageFilter.cpp new file mode 100644 index 0000000000..2f91a99430 --- /dev/null +++ b/Modules/MyAwesomeLib/src/AwesomeImageFilter.cpp @@ -0,0 +1,100 @@ +/*=================================================================== + +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 +#include + +#include + +// See definition of AwesomeImageFilter::GenerateData() further below for +// a rationale behind this function template. +template +static void AddOffset(const itk::Image* inputImage, int offset, mitk::Image::Pointer outputImage) +{ + typedef itk::Image ImageType; + typedef itk::ShiftScaleImageFilter FilterType; + + auto filter = FilterType::New(); + filter->SetInput(inputImage); + filter->SetShift(offset); + + filter->Update(); + + // This is the tricky part that is done wrong very often. As the image data + // of ITK images and MITK images are binary compatible, we don't need to + // cast or copy the ITK output image. Instead, we just want to reference + // the image data and tell ITK that we took the ownership. + mitk::GrabItkImageMemory(filter->GetOutput(), outputImage); +} + +AwesomeImageFilter::AwesomeImageFilter() + : m_Offset(0) +{ + this->SetNumberOfRequiredInputs(1); + this->SetNumberOfRequiredOutputs(1); +} + +AwesomeImageFilter::~AwesomeImageFilter() +{ +} + +void AwesomeImageFilter::GenerateData() +{ + mitk::Image::Pointer inputImage = this->GetInput(0); + + if (m_Offset == 0) + { + // Nothing to calculate in this case, just copy the input image. + this->SetPrimaryOutput(inputImage->Clone().GetPointer()); + } + else + { + mitk::Image::Pointer outputImage = this->GetOutput(); + + try + { + // We want to apply an ITK filter to the MITK input image. While MITK + // images are not templated, ITK images are templated by both pixel type + // and image dimension. The actual image data is binary compatible, though. + // MITK provides ITK access macros that enable you to directly operate + // on MITK images without any superfluous copying. + // To allow ITK filters to work with different image types at runtime you + // would be required to instantiate your function templates for each and + // every expected combination of pixel type and image dimension. Luckily, + // MITK provides a whole bunch of multiplexer macros to save you doing this + // manually (see mitkImageAccessByItk.h). + // These macros range from being completely generic to partly constrained + // variants. For example, you may want to constrain the image dimension or + // the pixel type. As your function template is compiled for each allowed + // combination, compile time and code size may increase dramatically. + // As a rule of thumb, use a suitable multiplexer macro that is as + // constrained as possible and yet as generic as necessary. + // To prevent a combinatorial explosion, image dimension is restricted to + // 2 and 3 even for the dimension-variable multiplexer macros. + // Thus, the following multiplexer macro allows for 2-dimensional and + // 3-dimensional images with an integer pixel type, for example, + // (un)signed char, short, and int, resulting in a total of 12 distinct + // combinations. + AccessIntegralPixelTypeByItk_n(inputImage, AddOffset, (m_Offset, outputImage)); + } + catch (const mitk::AccessByItkException& e) + { + MITK_ERROR << "Unsupported pixel type or image dimension: " << e.what(); + } + } +} diff --git a/Modules/MyAwesomeLib/src/AwesomeImageInteractor.cpp b/Modules/MyAwesomeLib/src/AwesomeImageInteractor.cpp new file mode 100644 index 0000000000..2cfdcfd46c --- /dev/null +++ b/Modules/MyAwesomeLib/src/AwesomeImageInteractor.cpp @@ -0,0 +1,185 @@ +/*=================================================================== + +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 +#include +#include + +#include + + + + // Helper function to get an image from a data node. + static mitk::Image::Pointer GetImage(mitk::DataNode::Pointer dataNode) + { + if (dataNode.IsNull()) + mitkThrow(); + + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + + if (image.IsNull()) + mitkThrow(); + + return image; + } + + // Helper function to get a geometry of an image for a specific time step. + static mitk::BaseGeometry::Pointer GetGeometry(mitk::Image::Pointer image, unsigned int timeStep) + { + mitk::TimeGeometry::Pointer timeGeometry = image->GetTimeGeometry(); + + if (timeGeometry.IsNull()) + mitkThrow(); + + auto geometry = timeGeometry->GetGeometryForTimeStep(timeStep); + + if (geometry.IsNull()) + mitkThrow(); + + return geometry; + } + + // The actual painting happens here. We're using a write accessor to gain safe + // write access to our image. The whole image volume for a given time step is + // locked. However, it's also possible - and preferable - to lock the slice of + // interest only. + template + static void Paint(mitk::Image::Pointer image, itk::Index<3> index, unsigned int timeStep) + { + // As soon as the ImagePixelWriteAccessor object goes out of scope at the + // end of this function, the image will be unlocked again (RAII). + mitk::ImagePixelWriteAccessor writeAccessor(image, image->GetVolumeData(timeStep)); + writeAccessor.SetPixelByIndex(index, std::numeric_limits::min()); + + // Don't forget to update the modified time stamp of the image. Otherwise, + // everything downstream wouldn't recognize that the image changed, + // including the rendering system. + image->Modified(); + } + + // Helper function to multiplex the actual Paint function call for different + // pixel types. As it's cumbersome and ugly, you may want to avoid such + // functions by using ITK for the actual painting and use the ITK access + // macros like we did for the AwesomeImageFilter. + static void Paint(mitk::Image::Pointer image, itk::Index<3> index, unsigned int timeStep) + { + switch (image->GetPixelType().GetComponentType()) + { + case itk::ImageIOBase::CHAR: + Paint(image, index, timeStep); + break; + + case itk::ImageIOBase::UCHAR: + Paint(image, index, timeStep); + break; + + case itk::ImageIOBase::SHORT: + Paint(image, index, timeStep); + break; + + case itk::ImageIOBase::USHORT: + Paint(image, index, timeStep); + break; + + case itk::ImageIOBase::INT: + Paint(image, index, timeStep); + break; + + case itk::ImageIOBase::UINT: + Paint(image, index, timeStep); + break; + + default: + mitkThrow(); + } + } + + AwesomeImageInteractor::AwesomeImageInteractor() + { + } + +AwesomeImageInteractor::~AwesomeImageInteractor() + { + } + + void AwesomeImageInteractor::ConnectActionsAndFunctions() + { + // Wire up this interactor with the state machine that is described by + // resource/Interactions/Paint.xml. + CONNECT_FUNCTION("paint", Paint) + } + + void AwesomeImageInteractor::DataNodeChanged() + { + // You almost always want to reset the state machine when the interactor + // has been attached to another data node. + this->ResetToStartState(); + } + + // The state machine is wired up with this Paint method. We wrote a few helper + // functions at the top of this files to keep this method clear and easy to + // read. + void AwesomeImageInteractor::Paint(mitk::StateMachineAction* action, mitk::InteractionEvent* event) + { + try + { + auto renderer = event->GetSender(); + + auto image = GetImage(this->GetDataNode()); + auto timeStep = renderer->GetTimeStep(); + auto geometry = GetGeometry(image, timeStep); + + // This method is wired up to mouse events. Thus, we can safely assume + // that the following cast will succeed and we have access to the mouse + // position and the first intersection point of a ray originating at the + // mouse position and shot into the scene. Convenient, isn't it? :-) + auto positionEvent = dynamic_cast(event); + auto position = positionEvent->GetPositionInWorld(); + + if (!geometry->IsInside(position)) + return; // Nothing to paint, as we're not inside the image bounds. + + // Okay, we're safe. Convert the mouse position to the index of the pixel + // we're pointing at. + itk::Index<3> index; + geometry->WorldToIndex<3>(position, index); + + // We don't need to paint over and over again while moving the mouse + // pointer inside the same pixel. That's especially relevant when operating + // on zoomed images. + if (index != m_LastPixelIndex) + { + // And finally... + ::Paint(image, index, timeStep); + + // Nearly done. We request the renderer to update the render window in + // order to see the result immediately. Actually, we should update all + // of the render windows by caling RequestUpdateAll() instead, as the + // painted pixels are possibly visible in other render windows, too. + // However, we decided to prefer performance here. + mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); + MITK_INFO << index[0] << " " << index[1] << " " << index[2]; + + m_LastPixelIndex = index; + } + } + catch (...) + { + return; + } + } diff --git a/Modules/SurfaceRegistration/CMakeLists.txt b/Modules/SurfaceRegistration/CMakeLists.txt new file mode 100644 index 0000000000..ae81db85cd --- /dev/null +++ b/Modules/SurfaceRegistration/CMakeLists.txt @@ -0,0 +1,4 @@ +mitk_create_module( SurfaceRegistration + INCLUDE_DIRS PRIVATE src/DataManagement src/Interactions src/IO src/Rendering + DEPENDS PUBLIC MitkCore + ) diff --git a/Modules/SurfaceRegistration/files.cmake b/Modules/SurfaceRegistration/files.cmake new file mode 100644 index 0000000000..8c760ea658 --- /dev/null +++ b/Modules/SurfaceRegistration/files.cmake @@ -0,0 +1,13 @@ +file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") + +set(CPP_FILES + mitkShapeComparisonManager.cpp + DataManagement/mitkShortestDistanceCalculator.cpp + DataManagement/mitkSurfaceRegistrationICP.cpp +) + +set(RESOURCE_FILES + Interactions/Paint.xml + Interactions/PaintConfig.xml +) + diff --git a/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h b/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h new file mode 100644 index 0000000000..846cdc70d9 --- /dev/null +++ b/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h @@ -0,0 +1,50 @@ +/*=================================================================== + +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 MitkShapeComparisonManager_h +#define MitkShapeComparisonManager_h + +#include "mitkSurface.h" +#include +#include "mitkDataNode.h" + +//#include "mitkSurfaceRegistrationICP.h" + +#include + +namespace mitk +{ + class MITKSURFACEREGISTRATION_EXPORT ShapeComparisonManager + { + public: + + ShapeComparisonManager(); + ~ShapeComparisonManager(); + + void setMovingSurface(mitk::Surface::Pointer moving); + void setTargetSurface(mitk::Surface::Pointer target); + + mitk::DataNode::Pointer manageICPCalculation(); + void manageCalculateDistances(); + + private: + + mitk::Surface::Pointer m_MovingSurface; + mitk::Surface::Pointer m_TargetSurface; + }; +} + +#endif diff --git a/Modules/SurfaceRegistration/include/mitkShortestDistanceCalculator.h b/Modules/SurfaceRegistration/include/mitkShortestDistanceCalculator.h new file mode 100644 index 0000000000..10935e4433 --- /dev/null +++ b/Modules/SurfaceRegistration/include/mitkShortestDistanceCalculator.h @@ -0,0 +1,36 @@ +/*=================================================================== + +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 mitkShortestDistanceCalculator_h +#define mitkShortestDistanceCalculator_h + +#include +#include + +namespace mitk{ + class ShortestDistanceCalculator + { + public: + ShortestDistanceCalculator(); + ~ShortestDistanceCalculator(); + + void calculateShortestDistance(vtkSmartPointer moving, vtkSmartPointer target); + + private: + + }; +}; +#endif \ No newline at end of file diff --git a/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h b/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h new file mode 100644 index 0000000000..dd228e7325 --- /dev/null +++ b/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h @@ -0,0 +1,34 @@ +/*=================================================================== + +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 +#include + +namespace mitk{ +#ifndef mitkSurfaceRegistrationICP_h +#define mitkSurfaceRegistrationICP_h + class SurfaceRegistrationICP + { + public: + SurfaceRegistrationICP(); + ~SurfaceRegistrationICP(); + + mitk::Surface::Pointer CalculateICP(mitk::Surface::Pointer movingSurface, mitk::Surface::Pointer targetSurface); + private: + }; + +#endif +}; \ No newline at end of file diff --git a/Modules/SurfaceRegistration/resource/Interactions/Paint.xml b/Modules/SurfaceRegistration/resource/Interactions/Paint.xml new file mode 100644 index 0000000000..c63efb3683 --- /dev/null +++ b/Modules/SurfaceRegistration/resource/Interactions/Paint.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/Modules/SurfaceRegistration/resource/Interactions/PaintConfig.xml b/Modules/SurfaceRegistration/resource/Interactions/PaintConfig.xml new file mode 100644 index 0000000000..e141844565 --- /dev/null +++ b/Modules/SurfaceRegistration/resource/Interactions/PaintConfig.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.cpp b/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.cpp new file mode 100644 index 0000000000..deee49f439 --- /dev/null +++ b/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.cpp @@ -0,0 +1,51 @@ +/*=================================================================== + +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 "mitkShortestDistanceCalculator.h" + +#include "vtkCellLocator.h" +#include "vtkPointData.h" +#include "vtkImplicitPolyDataDistance.h" +#include "vtkFloatArray.h" + + +mitk::ShortestDistanceCalculator::ShortestDistanceCalculator() +{ + +} + +mitk::ShortestDistanceCalculator::~ShortestDistanceCalculator() +{ + +} + +void mitk::ShortestDistanceCalculator::calculateShortestDistance(vtkSmartPointer moving, vtkSmartPointer target) +{ + // was passiert wenn der andere pointset groesser ist + MITK_INFO << "calculate shortest distance ..."; + std::vector *distances = new std::vector(); + double fromPoint[3] = { 0, 0, 0 }; + int pointNumber = moving->GetPoints()->GetNumberOfPoints(); + vtkSmartPointer implicitPolyDataDistance = + vtkSmartPointer::New(); + implicitPolyDataDistance->SetInput(moving); + // + for (int i = 0; i < pointNumber; ++i) + { + moving->GetPoints()->GetPoint(i, fromPoint); + double distance = implicitPolyDataDistance->FunctionValue(fromPoint[0], fromPoint[1], fromPoint[2]); + distances->push_back(distance); + } +} \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp b/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp new file mode 100644 index 0000000000..8ab7ab204a --- /dev/null +++ b/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp @@ -0,0 +1,56 @@ +#include "mitkSurfaceRegistrationICP.h" + +#include +#include +#include +#include +#include +#include +#include + +mitk::SurfaceRegistrationICP::SurfaceRegistrationICP() +{ +} + +mitk::SurfaceRegistrationICP::~SurfaceRegistrationICP() +{ +} + +mitk::Surface::Pointer mitk::SurfaceRegistrationICP::CalculateICP(mitk::Surface::Pointer movingSurface, mitk::Surface::Pointer targetSurface) +{ + vtkSmartPointer icp = vtkSmartPointer::New(); + icp->SetCheckMeanDistance(1); + mitk::Surface::Pointer movedData = mitk::Surface::New(); + + icp->SetSource(movingSurface->GetVtkPolyData()); + icp->SetTarget(targetSurface->GetVtkPolyData()); + icp->SetMaximumNumberOfIterations(1000); + icp->SetMaximumMeanDistance(0.01); + icp->SetMeanDistanceModeToRMS(); + icp->StartByMatchingCentroidsOn(); + icp->SetMaximumNumberOfLandmarks(100000); + icp->Modified(); + vtkSmartPointer transform = vtkSmartPointer::New(); + transform = icp->GetLandmarkTransform(); + + vtkSmartPointer icpTransformFilter = + vtkSmartPointer::New(); + icpTransformFilter->SetInputData(movingSurface->GetVtkPolyData()); + icpTransformFilter->SetTransform(icp); + icpTransformFilter->Update(); + + vtkSmartPointer m = icp->GetMatrix(); + MITK_INFO << "The resulting matrix is: " << *m; + MITK_INFO << "The mean distance is: " << icp->GetMeanDistance(); + + movedData->SetVtkPolyData(icpTransformFilter->GetOutput()); + movedData->Modified(); + //clean up + icpTransformFilter->Delete(); + transform->Delete(); + icp->Delete(); + + MITK_INFO << "registration done"; + + return movedData; +} \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp b/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp new file mode 100644 index 0000000000..c32e3ccb22 --- /dev/null +++ b/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp @@ -0,0 +1,58 @@ +/*=================================================================== + +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 +#include + +mitk::ShapeComparisonManager::ShapeComparisonManager() +{ +} + +mitk::ShapeComparisonManager::~ShapeComparisonManager() +{ + m_MovingSurface->Delete(); + m_TargetSurface->Delete(); +} + +void mitk::ShapeComparisonManager::setMovingSurface(mitk::Surface::Pointer moving) +{ + this->m_MovingSurface = moving; +} + +void mitk::ShapeComparisonManager::setTargetSurface(mitk::Surface::Pointer target) +{ + this->m_TargetSurface = target; +} + +mitk::DataNode::Pointer mitk::ShapeComparisonManager::manageICPCalculation() +{ + mitk::Surface::Pointer moveCopy = mitk::Surface::New(); + //moveCopy->SetVtkPolyData(m_MovingSurface->GetVtkPolyData()); + mitk::DataNode::Pointer registeredNode = mitk::DataNode::New(); + mitk::SurfaceRegistrationICP *registrationHelper = new SurfaceRegistrationICP(); + moveCopy = registrationHelper->CalculateICP(m_MovingSurface, m_TargetSurface); + registeredNode->SetData(moveCopy); + manageCalculateDistances(); + + return registeredNode; +} +void mitk::ShapeComparisonManager::manageCalculateDistances() +{ + //mitk::ShortestDistanceCalculator *distanceCalculator = new ShortestDistanceCalculator(); + //distanceCalculator->calculateShortestDistance(m_MovingSurface->GetVtkPolyData(), m_TargetSurface->GetVtkPolyData()); + +} \ No newline at end of file diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 9193ed80c3..08f8ffbc82 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,98 +1,100 @@ # Plug-ins must be ordered according to their dependencies set(MITK_PLUGINS org.blueberry.core.runtime:ON org.blueberry.core.expressions:OFF org.blueberry.core.commands:OFF org.blueberry.core.jobs:OFF org.blueberry.ui.qt:OFF org.blueberry.ui.qt.help:ON org.blueberry.ui.qt.log:ON org.blueberry.ui.qt.objectinspector:OFF #org.blueberry.test:ON #org.blueberry.uitest:ON #Testing/org.blueberry.core.runtime.tests:ON #Testing/org.blueberry.osgi.tests:ON org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.simulation:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.dicominspector:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.diffusionimaging.connectomics:OFF org.mitk.gui.qt.diffusionimaging.denoising:OFF org.mitk.gui.qt.diffusionimaging.fiberfox:OFF org.mitk.gui.qt.diffusionimaging.fiberprocessing:OFF org.mitk.gui.qt.diffusionimaging.ivim:OFF org.mitk.gui.qt.diffusionimaging.odfpeaks:OFF org.mitk.gui.qt.diffusionimaging.partialvolume:OFF org.mitk.gui.qt.diffusionimaging.preprocessing:OFF org.mitk.gui.qt.diffusionimaging.reconstruction:OFF org.mitk.gui.qt.diffusionimaging.registration:OFF org.mitk.gui.qt.diffusionimaging.tbss:OFF org.mitk.gui.qt.diffusionimaging.tractography:OFF org.mitk.gui.qt.dosevisualization:OFF org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.openigtlink:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.pointsetinteractionmultispectrum:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.simulation:OFF org.mitk.gui.qt.aicpregistration:OFF org.mitk.gui.qt.renderwindowmanager:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.tubegraph:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF org.mitk.gui.qt.igt.app.echotrack:OFF org.mitk.gui.qt.spectrocamrecorder:OFF org.mitk.gui.qt.classificationsegmentation:OFF org.mitk.gui.qt.overlaymanager:OFF org.mitk.gui.qt.igt.app.hummelprotocolmeasurements:OFF org.mitk.gui.qt.multilabelsegmentation:OFF org.mitk.matchpoint.core.helper:OFF org.mitk.gui.qt.matchpoint.algorithm.browser:OFF org.mitk.gui.qt.matchpoint.algorithm.control:OFF org.mitk.gui.qt.matchpoint.algorithm.batch:OFF org.mitk.gui.qt.matchpoint.mapper:OFF org.mitk.gui.qt.matchpoint.framereg:OFF org.mitk.gui.qt.matchpoint.visualizer:OFF org.mitk.gui.qt.matchpoint.evaluator:OFF org.mitk.gui.qt.matchpoint.manipulator:OFF org.mitk.gui.qt.cest:OFF + org.mitk.gui.qt.exampleplugin:OFF + org.mitk.gui.qt.surfaceregistration:OFF ) diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/CMakeLists.txt b/Plugins/org.mitk.gui.qt.exampleplugin/CMakeLists.txt new file mode 100644 index 0000000000..aed63c1627 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_gui_qt_exampleplugin) + +mitk_create_plugin( + EXPORT_DIRECTIVE AWESOME_EXPORTS + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS PRIVATE MitkQtWidgetsExt MitkMyAwesomeLib +) diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.exampleplugin/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..74e21d8648 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/documentation/UserManual/Manual.dox @@ -0,0 +1,20 @@ +/** +\page my_awesomeproject_exampleplugin The Awesome Example Plugin + +\imageMacro{icon.xpm,"Icon of Awesome Example Plugin",2.00} + +\tableofcontents + +\section my_awesomeproject_examplepluginOverview Overview + +Describe the features of your awesome plugin here + +
    +
  • Increases productivity
  • +
  • Creates beautiful images
  • +
  • Generates PhD thesis
  • +
  • Brings world peace
  • +
+ +*/ + diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/documentation/UserManual/icon.xpm b/Plugins/org.mitk.gui.qt.exampleplugin/documentation/UserManual/icon.xpm new file mode 100644 index 0000000000..83e48be4d8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/documentation/UserManual/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.exampleplugin/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..0a267aec8e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup my_awesomeproject_exampleplugin my.awesomeproject.exampleplugin Plugin + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup my_awesomeproject_exampleplugin_internal Internal + \ingroup my_awesomeproject_exampleplugin + + \brief This subcategory includes the internal classes of the my.awesomeproject.exampleplugin plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/files.cmake b/Plugins/org.mitk.gui.qt.exampleplugin/files.cmake new file mode 100644 index 0000000000..cadf2b0605 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/files.cmake @@ -0,0 +1,24 @@ +set(CPP_FILES + src/internal/AwesomePluginActivator.cpp + src/internal/AwesomeView.cpp +) + +set(UI_FILES + src/internal/AwesomeViewControls.ui +) + +set(MOC_H_FILES + src/internal/AwesomePluginActivator.h + src/internal/AwesomeView.h +) + +# List of resource files that can be used by the plugin system without loading +# the actual plugin. For example, the icon that is typically displayed in the +# plugin view menu at the top of the application window. +set(CACHED_RESOURCE_FILES + resources/AwesomeIcon.png + plugin.xml +) + +set(QRC_FILES +) diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.exampleplugin/manifest_headers.cmake new file mode 100644 index 0000000000..fc9b0eb826 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Awesome Example Plugin") +set(Plugin-Version "0.1") +set(Plugin-Vendor "Awesome Company") +set(Plugin-ContactAddress "http://www.awesomeproject.my") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/plugin.xml b/Plugins/org.mitk.gui.qt.exampleplugin/plugin.xml new file mode 100644 index 0000000000..7b868c6b46 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/plugin.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/resources/AwesomeIcon.png b/Plugins/org.mitk.gui.qt.exampleplugin/resources/AwesomeIcon.png new file mode 100644 index 0000000000..a858653b2a Binary files /dev/null and b/Plugins/org.mitk.gui.qt.exampleplugin/resources/AwesomeIcon.png differ diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomePluginActivator.cpp b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomePluginActivator.cpp new file mode 100644 index 0000000000..ceb9979915 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomePluginActivator.cpp @@ -0,0 +1,27 @@ +/*=================================================================== + +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 "AwesomePluginActivator.h" +#include "AwesomeView.h" + +void my_awesomeproject_exampleplugin_PluginActivator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(AwesomeView, context) +} + +void my_awesomeproject_exampleplugin_PluginActivator::stop(ctkPluginContext*) +{ +} diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomePluginActivator.h b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomePluginActivator.h new file mode 100644 index 0000000000..2471f4d1d8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomePluginActivator.h @@ -0,0 +1,35 @@ +/*=================================================================== + +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 my_awesomeproject_exampleplugin_PluginActivator_h +#define my_awesomeproject_exampleplugin_PluginActivator_h + +#include + +class my_awesomeproject_exampleplugin_PluginActivator + : public QObject, + public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.mitk.gui.qt.exampleplugin") + Q_INTERFACES(ctkPluginActivator) + +public: + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeView.cpp b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeView.cpp new file mode 100644 index 0000000000..7b5466846e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeView.cpp @@ -0,0 +1,178 @@ +/*=================================================================== + +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 "AwesomeView.h" + +#include +#include + +#include + +#include + +#include + +#include +#include + + + + //Helper function to create a fully set up instance of our + //AwesomeImageInteractor, based on the state machine specified in Paint.xml + //as well as its configuration in PaintConfig.xml. Both files are compiled + //into our MyAwesomeLib module as resources. + static AwesomeImageInteractor::Pointer CreateAwesomeImageInteractor() + { + auto myAwesomeLib = us::ModuleRegistry::GetModule("MitkMyAwesomeLib");//wichtig ist hier das Mitk noch dran zu schreiben + + auto interactor = AwesomeImageInteractor::New(); + interactor->LoadStateMachine("Paint.xml", myAwesomeLib); + interactor->SetEventConfig("PaintConfig.xml", myAwesomeLib); + + return interactor; + } + + // Don't forget to initialize the VIEW_ID. + const std::string AwesomeView::VIEW_ID = "my.awesomeproject.views.awesomeview"; + + void AwesomeView::CreateQtPartControl(QWidget* parent) + { + // Setting up the UI is a true pleasure when using .ui files, isn't it? + m_Controls.setupUi(parent); + + // Wire up the UI widgets with our functionality. + connect(m_Controls.processImageButton, SIGNAL(clicked()), this, SLOT(ProcessSelectedImage())); + } + + void AwesomeView::SetFocus() + { + m_Controls.processImageButton->setFocus(); + } + + void AwesomeView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& dataNodes) + { + for (const auto& dataNode : dataNodes) + { + // Write robust code. Always check pointers before using them. If the + // data node pointer is null, the second half of our condition isn't + // even evaluated and we're safe (C++ short-circuit evaluation). + if (dataNode.IsNotNull() && dynamic_cast(dataNode->GetData()) != nullptr) + { + m_Controls.selectImageLabel->setVisible(false); + return; + } + } + + // Nothing is selected or the selection doesn't contain an image. + m_Controls.selectImageLabel->setVisible(true); + } + + void AwesomeView::ProcessSelectedImage() + { + MITK_INFO << "Process start"; + // Before we even think about processing something, we need to make sure + // that we have valid input. Don't be sloppy, this is a main reason + // for application crashes if neglected. + + auto selectedDataNodes = this->GetDataManagerSelection(); + + if (selectedDataNodes.empty()) + return; + + auto firstSelectedDataNode = selectedDataNodes.front(); + + if (firstSelectedDataNode.IsNull()) + { + QMessageBox::information(nullptr, "Awesome View", "Please load and select an image before starting image processing."); + return; + } + MITK_INFO << "Process data"; + auto data = firstSelectedDataNode->GetData(); + + // Something is selected, but does it contain data? + if (data != nullptr) + { + // We don't use the auto keyword here, which would evaluate to a native + // image pointer. Instead, we want a smart pointer in order to ensure that + // the image isn't deleted somewhere else while we're using it. + mitk::Image::Pointer image = dynamic_cast(data); + + // Something is selected and it contains data, but is it an image? + if (image.IsNotNull()) + { + auto imageName = firstSelectedDataNode->GetName(); + auto offset = m_Controls.offsetSpinBox->value(); + + MITK_INFO << "Process image \"" << imageName << "\" ..."; + + // We're finally using the AwesomeImageFilter from our AwesomeLib module. + auto filter = AwesomeImageFilter::New(); + filter->SetInput(image); + filter->SetOffset(offset); + + filter->Update(); + + mitk::Image::Pointer processedImage = filter->GetOutput(); + + if (processedImage.IsNull() || !processedImage->IsInitialized()) + return; + + MITK_INFO << " done"; + + //// Stuff the resulting image into a data node, set some properties, + //// and add it to the data storage, which will eventually display the + //// image in the application. + auto processedImageDataNode = mitk::DataNode::New(); + processedImageDataNode->SetData(processedImage); + + QString name = QString("%1 (Offset: %2)").arg(imageName.c_str()).arg(offset); + processedImageDataNode->SetName(name.toStdString()); + + //// We don't really need to copy the level window, but if we wouldn't + //// do it, the new level window would be initialized to display the image + //// with optimal contrast in order to capture the whole range of pixel + //// values. This is also true for the input image as long as one didn't + //// modify its level window manually. Thus, the images would appear + //// identical unless you compare the level window widget for both images. + mitk::LevelWindow levelWindow; + + if (firstSelectedDataNode->GetLevelWindow(levelWindow)) + processedImageDataNode->SetLevelWindow(levelWindow); + + // We also attach our AwesomeImageInteractor, which allows us to paint + // on the resulting images by using the mouse as long as the CTRL key + // is pressed. + auto interactor = CreateAwesomeImageInteractor(); + + if (interactor.IsNotNull()) + interactor->SetDataNode(processedImageDataNode); + + this->GetDataStorage()->Add(processedImageDataNode); + } + } + + // Now it's your turn. This class/method has lots of room for improvements, + // for example: + // + // - What happens when multiple items are selected but the first one isn't + // an image? - There isn't any feedback for the user at all. + // - What's the front item of a selection? Does it depend on the order + // of selection or the position in the Data Manager? - Isn't it + // better to process all selected images? Don't forget to adjust the + // titles of the UI widgets. + // - In addition to the the displayed label, it's probably a good idea to + // enable or disable the button depending on the selection. + } diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeView.h b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeView.h new file mode 100644 index 0000000000..2a545080b5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeView.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 AwesomeView_h +#define AwesomeView_h + +#include +#include + +// There's an item "AwesomeViewControls.ui" in the UI_FILES list in +// files.cmake. The Qt UI Compiler will parse this file and generate a +// header file prefixed with "ui_", which is located in the build directory. +// Use Qt Creator to view and edit .ui files. The generated header file +// provides a class that contains all of the UI widgets. +#include + +// All views in MITK derive from QmitkAbstractView. You have to override +// at least the two methods CreateQtPartControl() and SetFocus(). +class AwesomeView : public QmitkAbstractView +{ + // As QmitkAbstractView derives from QObject and we want to use the Qt + // signal and slot mechanism, we must not forget the Q_OBJECT macro. + // This header file also has to be listed in MOC_H_FILES in files.cmake, + // in order that the Qt Meta-Object Compiler can find and process this + // class declaration. + Q_OBJECT + +public: + // This is a tricky one and will give you some headache later on in + // your debug sessions if it has been forgotten. Also, don't forget + // to initialize it in the implementation file. + static const std::string VIEW_ID; + + // In this method we initialize the GUI components and connect the + // associated signals and slots. + void CreateQtPartControl(QWidget* parent) override; + +private slots: + void ProcessSelectedImage(); + +private: + // Typically a one-liner. Set the focus to the default widget. + void SetFocus() override; + + // This method is conveniently called whenever the selection of Data Manager + // items changes. + void OnSelectionChanged( + berry::IWorkbenchPart::Pointer source, + const QList& dataNodes) override; + + // Generated from the associated UI file, it encapsulates all the widgets + // of our view. + Ui::AwesomeViewControls m_Controls; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeViewControls.ui b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeViewControls.ui new file mode 100644 index 0000000000..600c1d46a7 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.exampleplugin/src/internal/AwesomeViewControls.ui @@ -0,0 +1,96 @@ + + + AwesomeViewControls + + + + 0 + 0 + 398 + 636 + + + + Awesome View + + + + + + QLabel { color: rgb(255, 0, 0) } + + + Please select image. + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Offset + + + + + + + + 0 + 0 + + + + 9999 + + + + + + + + + + Process selected image + + + add Offset + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/CMakeLists.txt b/Plugins/org.mitk.gui.qt.surfaceregistration/CMakeLists.txt new file mode 100644 index 0000000000..79422fc910 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_surfaceregistration) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_QT_SURFACEREGISTRATION + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkSurfaceRegistration +) + diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/Advanced_ImageCropperView.png b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/Advanced_ImageCropperView.png new file mode 100644 index 0000000000..cd9fa4e650 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/Advanced_ImageCropperView.png differ diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/Basic_ImageCropperView.png b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/Basic_ImageCropperView.png new file mode 100644 index 0000000000..85b78cbb87 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/Basic_ImageCropperView.png differ diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/BoundingBox_ImageCropperView.png b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/BoundingBox_ImageCropperView.png new file mode 100644 index 0000000000..b2b870f138 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/BoundingBox_ImageCropperView.png differ diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/QmitkImageCropper.dox b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/QmitkImageCropper.dox new file mode 100644 index 0000000000..584790fbde --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/QmitkImageCropper.dox @@ -0,0 +1,40 @@ +/** +\page org_mitk_gui_qt_imagecropper Image Cropper Plugin + +\imageMacro{QmitkImageCropper_Icon.png,"Icon of the Image Cropper Plugin.",20} + +\tableofcontents + +\section org_mitk_gui_qt_imagecropperUsage Usage + +The Image Cropper Plugin allows you to crop subvolumes out of your orginial image volume by defining a cubic bounding box. + +This box can be placed at an arbitrary position in the volume and can be easily adjusted by using the handles on each of the faces. +Touching the handles changes the size of the box whereas touching the box itself changes its position. + +As soon as the bounding box is placed at the desired position, pressing the button 'Crop' creates a new image assigned to the orginal image +as child node containing only the selected subvolume. The size of the subvolume equals the size of the bounding box. +Pressing the "Mask" button keeps the original image size but masks out the area not contained within the bounding box bounds. +In case of 3D+t images the whole timeseries is cropped by default. + +\imageMacro{BoundingBox_ImageCropperView.png,"Bounding Box.",12.00} +\imageMacro{Basic_ImageCropperView.png,"Basic Settings.",7.09} + +\section org_mitk_gui_qt_imagecropperAdvanced Advanced settings +In the advanced settings view you find additional features to manipulate the bounding box. +\imageMacro{Advanced_ImageCropperView.png,"Advanced Settings.",7.09} + +\subsection org_mitk_gui_qt_imagecropperAdvancedColor Bounding Shape Color +By pressing the two color buttons you may change the color for the selected and unselected state of the box. +\subsection org_mitk_gui_qt_imagecropperAdvancedOverwrite Overwrite original image +By enabling this checkbox the image is replaced by the cropped subvolume. Be careful to use this option since there is now Redo action available. +\subsection org_mitk_gui_qt_imagecropperAdvancedTimestep Crop current timestep only +If this checkbox is enabled the xD + t image is reduced to a xD image (3D+t --> 3D) with the timestep visible in the widget. This is useful if you want to extract a single image or its corresponding +subvolume of the timeseries. The whole timeseries is cropped by default using the timeGeometry of the timestep visible in the widget. + +\section org_mitk_gui_qt_imagecropperIssues Current issues +Due to the latest changes in MITK slicegeometry is it currently not supported to crop 2D images unless the are 3D +images containing only a single slice. The user will be notified by a warning and and the input is handled as a single lable image. + +Right now changing the shape or rotation of the bounding box is not supported but might be integrated in the future. +*/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/QmitkImageCropper_Icon.png b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/QmitkImageCropper_Icon.png new file mode 100644 index 0000000000..10649b8e8f Binary files /dev/null and b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/UserManual/QmitkImageCropper_Icon.png differ diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..89ff4bc555 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_surfaceregistration org.mitk.gui.qt.surfaceregistration + \ingroup MITKPlugins + + \brief TODO + +*/ + +/** + \defgroup org_mitk_gui_qt_surfaceregistration_internal Internal + \ingroup org_mitk_gui_qt_surfaceregistration + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.surfaceregistration plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/files.cmake b/Plugins/org.mitk.gui.qt.surfaceregistration/files.cmake new file mode 100644 index 0000000000..9be9068c28 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/files.cmake @@ -0,0 +1,36 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_surfaceregistration_Activator.cpp + QmitkSurfaceRegistration.cpp +) + +set(UI_FILES + src/internal/SurfaceRegistrationControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_surfaceregistration_Activator.h + src/internal/QmitkSurfaceRegistration.h +) + +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +set(QRC_FILES + #resources/imagecropper.qrc +) + +set(CPP_FILES) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.surfaceregistration/manifest_headers.cmake new file mode 100644 index 0000000000..38e2a4bf86 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MITK Surface Registration") +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) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/plugin.xml b/Plugins/org.mitk.gui.qt.surfaceregistration/plugin.xml new file mode 100644 index 0000000000..cf5f59fa59 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/plugin.xml @@ -0,0 +1,30 @@ + + + + + + + + + Please describe + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/resources/icon.png b/Plugins/org.mitk.gui.qt.surfaceregistration/resources/icon.png new file mode 100644 index 0000000000..88300643d6 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.surfaceregistration/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/AwesomeView.cpp b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/AwesomeView.cpp new file mode 100644 index 0000000000..ef2ca51cec --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/AwesomeView.cpp @@ -0,0 +1,178 @@ +/*=================================================================== + +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 "AwesomeView.h" + +#include +#include + +#include + +#include + +#include + +#include +#include + + + + //Helper function to create a fully set up instance of our + //AwesomeImageInteractor, based on the state machine specified in Paint.xml + //as well as its configuration in PaintConfig.xml. Both files are compiled + //into our MyAwesomeLib module as resources. + static mitk::AwesomeImageInteractor::Pointer CreateAwesomeImageInteractor() + { + auto myAwesomeLib = us::ModuleRegistry::GetModule("MitkMyAwesomeLib");//wichtig ist hier das Mitk noch dran zu schreiben + + auto interactor = mitk::AwesomeImageInteractor::New(); + interactor->LoadStateMachine("Paint.xml", myAwesomeLib); + interactor->SetEventConfig("PaintConfig.xml", myAwesomeLib); + + return interactor; + } + + // Don't forget to initialize the VIEW_ID. + const std::string AwesomeView::VIEW_ID = "my.awesomeproject.views.awesomeview"; + + void AwesomeView::CreateQtPartControl(QWidget* parent) + { + // Setting up the UI is a true pleasure when using .ui files, isn't it? + m_Controls.setupUi(parent); + + // Wire up the UI widgets with our functionality. + connect(m_Controls.processImageButton, SIGNAL(clicked()), this, SLOT(ProcessSelectedImage())); + } + + void AwesomeView::SetFocus() + { + m_Controls.processImageButton->setFocus(); + } + + void AwesomeView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& dataNodes) + { + for (const auto& dataNode : dataNodes) + { + // Write robust code. Always check pointers before using them. If the + // data node pointer is null, the second half of our condition isn't + // even evaluated and we're safe (C++ short-circuit evaluation). + if (dataNode.IsNotNull() && dynamic_cast(dataNode->GetData()) != nullptr) + { + m_Controls.selectImageLabel->setVisible(false); + return; + } + } + + // Nothing is selected or the selection doesn't contain an image. + m_Controls.selectImageLabel->setVisible(true); + } + + void AwesomeView::ProcessSelectedImage() + { + MITK_INFO << "Process start"; + // Before we even think about processing something, we need to make sure + // that we have valid input. Don't be sloppy, this is a main reason + // for application crashes if neglected. + + auto selectedDataNodes = this->GetDataManagerSelection(); + + if (selectedDataNodes.empty()) + return; + + auto firstSelectedDataNode = selectedDataNodes.front(); + + if (firstSelectedDataNode.IsNull()) + { + QMessageBox::information(nullptr, "Awesome View", "Please load and select an image before starting image processing."); + return; + } + MITK_INFO << "Process data"; + auto data = firstSelectedDataNode->GetData(); + + // Something is selected, but does it contain data? + if (data != nullptr) + { + // We don't use the auto keyword here, which would evaluate to a native + // image pointer. Instead, we want a smart pointer in order to ensure that + // the image isn't deleted somewhere else while we're using it. + mitk::Image::Pointer image = dynamic_cast(data); + + // Something is selected and it contains data, but is it an image? + if (image.IsNotNull()) + { + auto imageName = firstSelectedDataNode->GetName(); + auto offset = m_Controls.offsetSpinBox->value(); + + MITK_INFO << "Process image \"" << imageName << "\" ..."; + + // We're finally using the AwesomeImageFilter from our AwesomeLib module. + auto filter = AwesomeImageFilter::New(); + filter->SetInput(image); + filter->SetOffset(offset); + + filter->Update(); + + mitk::Image::Pointer processedImage = filter->GetOutput(); + + if (processedImage.IsNull() || !processedImage->IsInitialized()) + return; + + MITK_INFO << " done"; + + //// Stuff the resulting image into a data node, set some properties, + //// and add it to the data storage, which will eventually display the + //// image in the application. + auto processedImageDataNode = mitk::DataNode::New(); + processedImageDataNode->SetData(processedImage); + + QString name = QString("%1 (Offset: %2)").arg(imageName.c_str()).arg(offset); + processedImageDataNode->SetName(name.toStdString()); + + //// We don't really need to copy the level window, but if we wouldn't + //// do it, the new level window would be initialized to display the image + //// with optimal contrast in order to capture the whole range of pixel + //// values. This is also true for the input image as long as one didn't + //// modify its level window manually. Thus, the images would appear + //// identical unless you compare the level window widget for both images. + mitk::LevelWindow levelWindow; + + if (firstSelectedDataNode->GetLevelWindow(levelWindow)) + processedImageDataNode->SetLevelWindow(levelWindow); + + // We also attach our AwesomeImageInteractor, which allows us to paint + // on the resulting images by using the mouse as long as the CTRL key + // is pressed. + auto interactor = CreateAwesomeImageInteractor(); + + if (interactor.IsNotNull()) + interactor->SetDataNode(processedImageDataNode); + + this->GetDataStorage()->Add(processedImageDataNode); + } + } + + // Now it's your turn. This class/method has lots of room for improvements, + // for example: + // + // - What happens when multiple items are selected but the first one isn't + // an image? - There isn't any feedback for the user at all. + // - What's the front item of a selection? Does it depend on the order + // of selection or the position in the Data Manager? - Isn't it + // better to process all selected images? Don't forget to adjust the + // titles of the UI widgets. + // - In addition to the the displayed label, it's probably a good idea to + // enable or disable the button depending on the selection. + } diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/AwesomeView.h b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/AwesomeView.h new file mode 100644 index 0000000000..2a545080b5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/AwesomeView.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 AwesomeView_h +#define AwesomeView_h + +#include +#include + +// There's an item "AwesomeViewControls.ui" in the UI_FILES list in +// files.cmake. The Qt UI Compiler will parse this file and generate a +// header file prefixed with "ui_", which is located in the build directory. +// Use Qt Creator to view and edit .ui files. The generated header file +// provides a class that contains all of the UI widgets. +#include + +// All views in MITK derive from QmitkAbstractView. You have to override +// at least the two methods CreateQtPartControl() and SetFocus(). +class AwesomeView : public QmitkAbstractView +{ + // As QmitkAbstractView derives from QObject and we want to use the Qt + // signal and slot mechanism, we must not forget the Q_OBJECT macro. + // This header file also has to be listed in MOC_H_FILES in files.cmake, + // in order that the Qt Meta-Object Compiler can find and process this + // class declaration. + Q_OBJECT + +public: + // This is a tricky one and will give you some headache later on in + // your debug sessions if it has been forgotten. Also, don't forget + // to initialize it in the implementation file. + static const std::string VIEW_ID; + + // In this method we initialize the GUI components and connect the + // associated signals and slots. + void CreateQtPartControl(QWidget* parent) override; + +private slots: + void ProcessSelectedImage(); + +private: + // Typically a one-liner. Set the focus to the default widget. + void SetFocus() override; + + // This method is conveniently called whenever the selection of Data Manager + // items changes. + void OnSelectionChanged( + berry::IWorkbenchPart::Pointer source, + const QList& dataNodes) override; + + // Generated from the associated UI file, it encapsulates all the widgets + // of our view. + Ui::AwesomeViewControls m_Controls; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp new file mode 100644 index 0000000000..fd3a6a8fbf --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp @@ -0,0 +1,210 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "QmitkSurfaceRegistration.h" + +#include +#include + +#include +#include +#include +#include +#include // Includes for image casting between ITK and MITK: added after using Plugin Generator +#include // added for surface dynamic cast +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +const std::string QmitkSurfaceRegistration::VIEW_ID = "org.mitk.views.qmitksurfaceregistration"; + +QmitkSurfaceRegistration::QmitkSurfaceRegistration(QObject *parent) + : m_ParentWidget(0), m_movingSurfaceNode(nullptr), m_targetSurfaceNode(nullptr) +{ +} + +QmitkSurfaceRegistration::~QmitkSurfaceRegistration() +{ + // delete pointer objects + m_movingSurfaceNode = nullptr; + m_targetSurfaceNode = nullptr; +} +// + +void QmitkSurfaceRegistration::SetFocus(){ + m_Controls.groupBoxMoving->setFocus(); +} + +void QmitkSurfaceRegistration::CreateQtPartControl(QWidget *parent) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + connect(m_Controls.pushButtonExecute, SIGNAL(clicked()), this, SLOT(doExecute())); + + mitk::RenderingManager::GetInstance()->SetDataStorage(this->GetDataStorageReference()->GetDataStorage()); + mitk::RenderingManager::GetInstance()->InitializeViews(); + + m_ParentWidget = parent; +} + +void QmitkSurfaceRegistration::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, + const QList &nodes) +{ + MITK_INFO << "On Selection Changed"; + bool rotationEnabled = false; + + if (nodes.empty()) + { + MITK_INFO << "Nothing selected yet"; + m_Controls.labelSelectMovingSurface->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); + m_Controls.labelSelectTargetSurface->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); + m_Controls.labelMovingSurfaceName->setText(QString::fromStdString("No moving surface selected")); + m_Controls.labelTargetSurfaceName->setText(QString::fromStdString("No target surface selected")); + m_Controls.groupBoxMoving->setEnabled(true); + m_Controls.groupBoxMappedData->setEnabled(false); + if (m_useTestConfig) + { + m_Controls.pushButtonExecute->setEnabled(true); + } + else{ + m_Controls.pushButtonExecute->setEnabled(false); + } + m_Controls.radioButtonMirroring->setEnabled(false); + return; + } + else + { + if (nodes.size() == 1) + { + if (nodes[0].IsNotNull() && dynamic_cast(nodes[0]->GetData())) + { + MITK_INFO << "There is exactly one image selected"; + m_movingSurfaceNode = nodes[0]; + m_Controls.labelSelectMovingSurface->setText("Selected moving surface:"); + m_Controls.labelSelectMovingSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); + m_Controls.labelMovingSurfaceName->setText( + QString::fromStdString("File name: " + m_movingSurfaceNode->GetName())); + m_Controls.radioButtonMirroring->setEnabled(true); + m_Controls.groupBoxTarget->setEnabled(true); + m_Controls.groupBoxMappedData->setEnabled(true); + m_Controls.groupBoxTarget->setEnabled(true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + else + { + QMessageBox::information(nullptr, "Warning", "Are you sure? - I dont think this is a Surface! Try again!"); + } + } + else if (nodes.size() == 2) + { + if (nodes[1].IsNotNull() && dynamic_cast(nodes[1]->GetData())) + { + MITK_INFO << "There are two images selected"; + m_targetSurfaceNode = nodes[1]; + m_Controls.labelSelectTargetSurface->setText("Selected target surface:"); + m_Controls.labelSelectTargetSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); + m_Controls.labelTargetSurfaceName->setText( + QString::fromStdString("File name: " + m_targetSurfaceNode->GetName())); + m_Controls.textMappedDataName->setEnabled(true); + m_Controls.pushButtonExecute->setEnabled(true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + m_useTestConfig = false; + } + else + { + QMessageBox::information(nullptr, "Warning", "Are you sure? - I dont think this is a Surface!"); + } + } + else + { + QMessageBox::information(nullptr, "Warning", "You do know that it only works with two surfaces, right? If you continue to click execute, this might crash one day!"); + //wie kann ich die Auswahl zurueck setzen? + } + } +} +void QmitkSurfaceRegistration::doExecute() +{ + if (m_useTestConfig) + { + setUpTestConfig(); + } + MITK_INFO << "pushButtonExecute clicked"; + performICPRegistration(); +} + +void QmitkSurfaceRegistration::setUpTestConfig() +{ + mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); + mitk::IOUtil::Load("//ad/fs/E130-Projekte/BGLU/Fibula/Python/DataGAN/Registered/Surface/Tibia/tibia01_q0.stl", *ds); + mitk::IOUtil::Load("//ad/fs/E130-Projekte/BGLU/Fibula/Python/DataGAN/Registered/Surface/Tibia/tibia02_q0.stl", *ds); + + m_movingSurfaceNode = ds->GetAll()->at(0); + m_targetSurfaceNode = ds->GetAll()->at(1); + this->GetDataStorageReference()->GetDataStorage()->Add(mitk::DataNode::Pointer(ds->GetAll()->at(0))); + this->GetDataStorageReference()->GetDataStorage()->Add(mitk::DataNode::Pointer(ds->GetAll()->at(1))); + this->GetDataStorageReference()->GetDataStorage()->Modified(); + + mitk::RenderingManager::GetInstance()->SetDataStorage(this->GetDataStorageReference()->GetDataStorage()); + mitk::RenderingManager::GetInstance()->InitializeViews(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + m_Controls.pushButtonExecute->setEnabled(true); + m_Controls.labelMovingSurfaceName->setText("tibia01_q0"); + m_Controls.labelTargetSurfaceName->setText("tibia02_q0"); + m_Controls.labelSelectMovingSurface->setText("Selected moving surface:"); + m_Controls.labelSelectMovingSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); + m_Controls.labelSelectTargetSurface->setText("Selected target surface:"); + m_Controls.labelSelectTargetSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); + + this->GetDataStorageReference()->GetDataStorage()->Modified(); + mitk::RenderingManager::GetInstance()->InitializeViews(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkSurfaceRegistration::performICPRegistration() +{ + mitk::Surface::Pointer movingSurface = dynamic_cast (m_movingSurfaceNode->GetData()); + mitk::Surface::Pointer targetSurface = dynamic_cast (m_targetSurfaceNode->GetData()); + + mitk::DataNode::Pointer registeredNode = mitk::DataNode::New(); + + mitk::ShapeComparisonManager *manager = new mitk::ShapeComparisonManager(); + manager->setMovingSurface(movingSurface); + manager->setTargetSurface(targetSurface); + registeredNode = manager->manageICPCalculation(); + this->GetDataStorageReference()->GetDataStorage()->Add(registeredNode, m_movingSurfaceNode); + + manager->~ShapeComparisonManager(); + + registeredNode->SetName("Moving"); + this->GetDataStorageReference()->GetDataStorage()->Modified(); + mitk::RenderingManager::GetInstance()->InitializeViews(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + MITK_INFO << "registration done"; +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h new file mode 100644 index 0000000000..3b0cb1b242 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h @@ -0,0 +1,105 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef QmitkSurfaceRegistration_h +#define QmitkSurfaceRegistration_h + +#include + +#ifdef WIN32 +#pragma warning( disable : 4250 ) +#endif + +#include "QVTKWidget.h" +#include "QmitkRegisterClasses.h" + +#include + +#include "ui_SurfaceRegistrationControls.h" +#include "usServiceRegistration.h" + +/*! +@brief QmitkSurfaceRegistrationView +\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + +\sa QmitkFunctionality +\ingroup ${plugin_target}_internal +*/ +class QmitkSurfaceRegistration : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) +private: + + Q_OBJECT + +public: + /*! + @brief Constructor. Called by SampleApp (or other apps that use functionalities) + */ + QmitkSurfaceRegistration(QObject *parent = 0); + + virtual ~QmitkSurfaceRegistration(); + + static const std::string VIEW_ID; + + virtual void CreateQtPartControl(QWidget *parent); + + virtual void SetFocus() override; + + ///*! + //@brief Creates the Qt connections needed + //*/ + QWidget* GetControls(); + + /// @brief Called when the user clicks the GUI button + protected slots: + + void doExecute(); + +protected: + + // /*! + //@brief called by QmitkFunctionality when DataManager's selection has changed + // */ + void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; + +private: + /*! + * The parent QWidget + */ + QWidget* m_ParentWidget; + + /*! + * @brief A pointer to the node of the moving surface. + */ + mitk::DataNode::Pointer m_movingSurfaceNode; + /*! + * @brief A pointer to the node of the target surface. + */ + mitk::DataNode::Pointer m_targetSurfaceNode; + + Ui::SurfaceRegistrationControls m_Controls; + + bool m_useTestConfig = true; + + void performICPRegistration(); + + void setUpTestConfig(); +}; + +#endif // QmitkSurfaceRegistration_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/SurfaceRegistrationControls.ui b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/SurfaceRegistrationControls.ui new file mode 100644 index 0000000000..588e537e2e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/SurfaceRegistrationControls.ui @@ -0,0 +1,456 @@ + + + SurfaceRegistrationControls + + + Qt::WindowModal + + + true + + + + 0 + 0 + 271 + 863 + + + + + 0 + 0 + + + + + 100 + 100 + + + + + 16777215 + 16777215 + + + + QmitkTemplate + + + + + + true + + + + 0 + 0 + + + + + 0 + 95 + + + + Moving + + + false + + + + + 10 + 20 + 347 + 13 + + + + + 0 + 0 + + + + QLabel { color: rgb(255, 0, 0) } + + + Select moving surface + + + + + + 10 + 40 + 171 + 20 + + + + + 0 + 0 + + + + + 50 + 20 + + + + + 16777215 + 16777215 + + + + QFrame::Box + + + No moving surface selected + + + + + false + + + + 10 + 70 + 82 + 17 + + + + Mirroring + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 75 + + + + Target + + + false + + + + + 10 + 20 + 331 + 16 + + + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + + QLabel { color: rgb(255, 0, 0) } + + + Select target surface + + + + + + 10 + 40 + 171 + 20 + + + + + 0 + 0 + + + + + 50 + 20 + + + + + 16777215 + 16777215 + + + + QFrame::Box + + + No target surface selected + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 75 + + + + + 0 + 75 + + + + Mapped Data + + + + + 10 + 20 + 331 + 16 + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + + Type mapped data name: + + + + + + 10 + 40 + 171 + 20 + + + + + 0 + 0 + + + + + 50 + 20 + + + + true + + + false + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustIgnored + + + true + + + defaultMappedDataName + + + Qt::TextEditable + + + + + + + + true + + + Execute + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/org_mitk_gui_qt_surfaceregistration_Activator.cpp b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/org_mitk_gui_qt_surfaceregistration_Activator.cpp new file mode 100644 index 0000000000..3165cf1ca7 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/org_mitk_gui_qt_surfaceregistration_Activator.cpp @@ -0,0 +1,41 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "org_mitk_gui_qt_surfaceregistration_Activator.h" +#include "QmitkSurfaceRegistration.h" +#include + +#include +#include + +US_INITIALIZE_MODULE + +namespace mitk { + void org_mitk_gui_qt_surfaceregistration_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(QmitkSurfaceRegistration, context) + } + + void org_mitk_gui_qt_surfaceregistration_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context) + } +} + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +Q_EXPORT_PLUGIN2(org_mitk_gui_qt_surfaceregistration, mitk::PluginActivator) +#endif \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/org_mitk_gui_qt_surfaceregistration_Activator.h b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/org_mitk_gui_qt_surfaceregistration_Activator.h new file mode 100644 index 0000000000..01756f3873 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/org_mitk_gui_qt_surfaceregistration_Activator.h @@ -0,0 +1,42 @@ +/*=================================================================== + +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 org_mitk_gui_qt_surfaceregistration_Activator_h +#define org_mitk_gui_qt_surfaceregistration_Activator_h + +#include + +namespace mitk { + + class org_mitk_gui_qt_surfaceregistration_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_surfaceregistration") +#endif + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context) override; + void stop(ctkPluginContext* context) override; + +}; // PluginActivator + +} + +#endif // org_mitk_gui_qt_surfaceregistration_Activator_h