diff --git a/CMake/MITKDashboardSetup.cmake b/CMake/MITKDashboardSetup.cmake index 5d90a834a7..12d5c7128f 100644 --- a/CMake/MITKDashboardSetup.cmake +++ b/CMake/MITKDashboardSetup.cmake @@ -1,198 +1,202 @@ # This file is intended to be included at the end of a custom MITKDashboardScript.TEMPLATE.cmake file list(APPEND CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") # # Automatically determined properties # set(MY_OPERATING_SYSTEM ) if(UNIX) # Download a utility script set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/mitkDetectOS.sh;hb=${hb}") set(dest "${CTEST_SCRIPT_DIRECTORY}/mitkDetectOS.sh") downloadFile("${url}" "${dest}") execute_process(COMMAND sh "${dest}" RESULT_VARIABLE _result OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT _result) set(MY_OPERATING_SYSTEM "${_out}") endif() endif() if(NOT MY_OPERATING_SYSTEM) set(MY_OPERATING_SYSTEM "${CMAKE_HOST_SYSTEM}") # Windows 7, Linux-2.6.32, Darwin... endif() site_name(CTEST_SITE) if(NOT DEFINED MITK_USE_QT) set(MITK_USE_QT 1) endif() if(MITK_USE_QT) if(NOT QT_QMAKE_EXECUTABLE) find_program(QT_QMAKE_EXECUTABLE NAMES qmake qmake-qt4 HINTS ${QT_BINARY_DIR}) endif() execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} --version OUTPUT_VARIABLE MY_QT_VERSION RESULT_VARIABLE qmake_error) if(qmake_error) message(FATAL_ERROR "Error when executing ${QT_QMAKE_EXECUTABLE} --version\n${qmake_error}") endif() string(REGEX REPLACE ".*Qt version ([0-9.]+) .*" "\\1" MY_QT_VERSION ${MY_QT_VERSION}) endif() # # Project specific properties # if(NOT CTEST_BUILD_NAME) if(MITK_USE_QT) set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} Qt${MY_QT_VERSION} ${CTEST_BUILD_CONFIGURATION}") else() set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} ${CTEST_BUILD_CONFIGURATION}") endif() endif() set(PROJECT_BUILD_DIR "MITK-build") set(CTEST_PATH "$ENV{PATH}") if(WIN32) set(ANN_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ANN-build/${CTEST_BUILD_CONFIGURATION}") set(CPPUNIT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/CppUnit-build/${CTEST_BUILD_CONFIGURATION}") set(GLUT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLUT-build/${CTEST_BUILD_CONFIGURATION}") set(GLEW_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLEW-build/${CTEST_BUILD_CONFIGURATION}") set(TINYXML_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/tinyxml-build/${CTEST_BUILD_CONFIGURATION}") set(QWT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qwt-build/${CTEST_BUILD_CONFIGURATION}") set(QXT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qxt-build/${CTEST_BUILD_CONFIGURATION}") set(VTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/VTK-build/bin/${CTEST_BUILD_CONFIGURATION}") set(ACVD_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ACVD-build/bin/${CTEST_BUILD_CONFIGURATION}") set(ITK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ITK-build/bin/${CTEST_BUILD_CONFIGURATION}") set(BOOST_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Boost-install/lib") set(GDCM_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GDCM-build/bin/${CTEST_BUILD_CONFIGURATION}") set(OPENCV_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/OpenCV-build/bin/${CTEST_BUILD_CONFIGURATION}") set(POCO_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Poco-install/lib") set(SOFA_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/SOFA-build/bin/${CTEST_BUILD_CONFIGURATION}") set(BLUEBERRY_OSGI_DIR "${CTEST_BINARY_DIRECTORY}/MITK-build/bin/BlueBerry/org.blueberry.osgi/bin/${CTEST_BUILD_CONFIGURATION}") set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${QXT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}") endif() set(ENV{PATH} "${CTEST_PATH}") set(SUPERBUILD_TARGETS "") # If the dashscript doesn't define a GIT_REPOSITORY variable, let's define it here. if(NOT DEFINED GIT_REPOSITORY OR GIT_REPOSITORY STREQUAL "") set(GIT_REPOSITORY "http://git.mitk.org/MITK.git") endif() # # Display build info # message("Site name: ${CTEST_SITE}") message("Build name: ${CTEST_BUILD_NAME}") message("Script Mode: ${SCRIPT_MODE}") message("Coverage: ${WITH_COVERAGE}, MemCheck: ${WITH_MEMCHECK}") # # Set initial cache options # if(${CMAKE_VERSION} VERSION_GREATER "2.8.9") set(CTEST_USE_LAUNCHERS 1) set(ENV{CTEST_USE_LAUNCHERS_DEFAULT} 1) endif() # Remove this if block after all dartclients work if(DEFINED ADDITIONNAL_CMAKECACHE_OPTION) message(WARNING "Rename ADDITIONNAL to ADDITIONAL in your dartlclient script: ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") set(ADDITIONAL_CMAKECACHE_OPTION ${ADDITIONNAL_CMAKECACHE_OPTION}) endif() if(NOT DEFINED MITK_USE_ACVD) set(MITK_USE_ACVD 1) endif() if(NOT DEFINED MITK_USE_Boost) set(MITK_USE_Boost 1) endif() if(NOT DEFINED MITK_USE_OpenCV) set(MITK_USE_OpenCV 1) endif() if(NOT DEFINED MITK_USE_Poco) set(MITK_USE_Poco 1) endif() +if(NOT DEFINED MITK_USE_Python) + set(MITK_USE_Python TRUE) +endif() + if(NOT DEFINED MITK_USE_SOFA) set(MITK_USE_SOFA 1) endif() +if(NOT DEFINED MITK_VTK_DEBUG_LEAKS) + set(MITK_VTK_DEBUG_LEAKS 1) +endif() if(NOT DEFINED MITK_BUILD_ALL_APPS) set(MITK_BUILD_ALL_APPS TRUE) endif() if(NOT DEFINED BLUEBERRY_BUILD_ALL_PLUGINS) set(BLUEBERRY_BUILD_ALL_PLUGINS TRUE) endif() if(NOT DEFINED MITK_BUILD_ALL_PLUGINS) set(MITK_BUILD_ALL_PLUGINS TRUE) endif() if(NOT DEFINED MITK_BUILD_EXAMPLES) set(MITK_BUILD_EXAMPLES TRUE) endif() -if(NOT DEFINED MITK_USE_Python) - set(MITK_USE_Python TRUE) -endif() - if(NOT BUILD_DiffusionMiniApps) set(BUILD_DiffusionMiniApps TRUE) endif() set(INITIAL_CMAKECACHE_OPTIONS " BLUEBERRY_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS} MITK_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS} MITK_BUILD_ALL_APPS:BOOL=${MITK_BUILD_ALL_APPS} MITK_BUILD_EXAMPLES:BOOL=${MITK_BUILD_EXAMPLES} SUPERBUILD_EXCLUDE_MITKBUILD_TARGET:BOOL=TRUE MITK_USE_ACVD:BOOL=${MITK_USE_ACVD} MITK_USE_Boost:BOOL=${MITK_USE_Boost} MITK_USE_OpenCV:BOOL=${MITK_USE_OpenCV} MITK_USE_Poco:BOOL=${MITK_USE_Poco} +MITK_USE_Python:BOOL=${MITK_USE_Python} MITK_USE_SOFA:BOOL=${MITK_USE_SOFA} MITK_USE_QT:BOOL=${MITK_USE_QT} -MITK_USE_Python:BOOL=${MITK_USE_Python} +MITK_VTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS} ${ADDITIONAL_CMAKECACHE_OPTION} ") if(MITK_USE_QT) set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS} QT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}") endif() # Write a cache file for populating the MITK initial cache (not the superbuild cache). # This can be used to provide variables which are not passed through the # superbuild process to the MITK configure step) if(MITK_INITIAL_CACHE) set(mitk_cache_file "${CTEST_SCRIPT_DIRECTORY}/mitk_initial_cache.txt") file(WRITE "${mitk_cache_file}" "${MITK_INITIAL_CACHE}") set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS} MITK_INITIAL_CACHE_FILE:INTERNAL=${mitk_cache_file} ") endif() # # Download and include dashboard driver script # set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/MITKDashboardDriverScript.cmake;hb=${hb}") set(dest ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}.driver) downloadFile("${url}" "${dest}") include(${dest}) diff --git a/CMakeExternals/VTK.cmake b/CMakeExternals/VTK.cmake index 495f9a4e28..3d72218929 100644 --- a/CMakeExternals/VTK.cmake +++ b/CMakeExternals/VTK.cmake @@ -1,95 +1,103 @@ #----------------------------------------------------------------------------- # VTK #----------------------------------------------------------------------------- if(WIN32) option(VTK_USE_SYSTEM_FREETYPE OFF) else(WIN32) option(VTK_USE_SYSTEM_FREETYPE ON) endif(WIN32) # Sanity checks if(DEFINED VTK_DIR AND NOT EXISTS ${VTK_DIR}) message(FATAL_ERROR "VTK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj VTK) set(proj_DEPENDENCIES ) set(VTK_DEPENDS ${proj}) if(NOT DEFINED VTK_DIR) set(additional_cmake_args ) if(MINGW) set(additional_cmake_args -DCMAKE_USE_WIN32_THREADS:BOOL=ON -DCMAKE_USE_PTHREADS:BOOL=OFF -DVTK_USE_VIDEO4WINDOWS:BOOL=OFF # no header files provided by MinGW ) endif() + # Optionally enable memory leak checks for any objects derived from vtkObject. This + # will force unit tests to fail if they have any of these memory leaks. + option(MITK_VTK_DEBUG_LEAKS OFF) + mark_as_advanced(MITK_VTK_DEBUG_LEAKS) + set(additional_cmake_args + -DVTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS} + ) + if(MITK_USE_Python) if(NOT MITK_USE_SYSTEM_PYTHON) list(APPEND proj_DEPENDENCIES Python) endif() list(APPEND additional_cmake_args -DVTK_WRAP_PYTHON:BOOL=ON -DVTK_USE_TK:BOOL=OFF -DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} ) else() list(APPEND additional_cmake_args -DVTK_WRAP_PYTHON:BOOL=OFF -DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF ) endif() if(MITK_USE_QT) list(APPEND additional_cmake_args -DVTK_QT_VERSION:STRING=${DESIRED_QT_VERSION} -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DModule_vtkGUISupportQt:BOOL=ON -DModule_vtkGUISupportQtWebkit:BOOL=ON -DModule_vtkGUISupportQtSQL:BOOL=ON -DModule_vtkRenderingQt:BOOL=ON -DVTK_Group_Qt:BOOL=ON ) endif() set(VTK_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/VTK-6.1.0.tar.gz) set(VTK_URL_MD5 25e4dfb3bad778722dcaec80cd5dab7d) ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake URL ${VTK_URL} URL_MD5 ${VTK_URL_MD5} INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} -DVTK_WRAP_TCL:BOOL=OFF -DVTK_WRAP_PYTHON:BOOL=OFF -DVTK_WRAP_JAVA:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=ON -DVTK_USE_SYSTEM_FREETYPE:BOOL=${VTK_USE_SYSTEM_FREETYPE} -DVTK_LEGACY_REMOVE:BOOL=ON -DModule_vtkTestingRendering:BOOL=ON -DVTK_MAKE_INSTANTIATORS:BOOL=ON ${additional_cmake_args} DEPENDS ${proj_DEPENDENCIES} ) set(VTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() diff --git a/Core/Code/Testing/files.cmake b/Core/Code/Testing/files.cmake index 249f1f2017..0ecd2a832c 100644 --- a/Core/Code/Testing/files.cmake +++ b/Core/Code/Testing/files.cmake @@ -1,203 +1,205 @@ # tests with no extra command line parameter set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## DISABLED TESTS ################################################# #mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesnt exist any more #mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529 #mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more #mitkSegmentationInterpolationTest.cpp #file doesn't exist! #mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist! #mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK #mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more #mitkTestUtilSharedLibrary.cpp #Linker problem with this test... #mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details. ################# RUNNING TESTS ################################################### mitkAccessByItkTest.cpp mitkCoreObjectFactoryTest.cpp mitkDataNodeTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkDispatcherTest.cpp mitkEnumerationPropertyTest.cpp mitkEventTest.cpp mitkFocusManagerTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometry3DEqualTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkGlobalInteractionTest.cpp mitkImageCastTest.cpp mitkImageEqualTest.cpp mitkImageDataItemTest.cpp mitkImageGeneratorTest.cpp mitkIOUtilTest.cpp mitkBaseDataTest.cpp mitkImportItkImageTest.cpp mitkGrabItkImageMemoryTest.cpp mitkInstantiateAccessFunctionTest.cpp mitkInteractorTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetTest.cpp mitkPointSetEqualTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetOnEmptyTest.cpp mitkPointSetWriterTest.cpp mitkPointSetReaderTest.cpp mitkPointSetInteractorTest.cpp mitkPointSetPointOperationsTest.cpp + mitkProgressBarTest.cpp mitkPropertyTest.cpp mitkPropertyListTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkStateMachineTest.cpp mitkStateTest.cpp mitkSurfaceTest.cpp mitkSurfaceEqualTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeGeometryTest.cpp + mitkProportionalTimeGeometryTest.cpp mitkTransitionTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp mitkStepperTest.cpp mitkRenderingManagerTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp mitkVectorTest.cpp mitkClippedSurfaceBoundsCalculatorTest.cpp mitkExceptionTest.cpp mitkExtractSliceFilterTest.cpp mitkLogTest.cpp mitkImageDimensionConverterTest.cpp mitkLoggingAdapterTest.cpp mitkUIDGeneratorTest.cpp mitkShaderRepositoryTest.cpp mitkPlanePositionManagerTest.cpp mitkAffineTransformBaseTest.cpp mitkPropertyAliasesTest.cpp mitkPropertyDescriptionsTest.cpp mitkPropertyExtensionsTest.cpp mitkPropertyFiltersTest.cpp mitkTinyXMLTest.cpp mitkRawImageFileReaderTest.cpp mitkInteractionEventTest.cpp mitkLookupTableTest.cpp mitkSTLFileReaderTest.cpp mitkPointTypeConversionTest.cpp mitkVectorTypeConversionTest.cpp mitkMatrixTypeConversionTest.cpp mitkArrayTypeConversionTest.cpp mitkSurfaceToImageFilterTest.cpp mitkBaseGeometryTest.cpp mitkImageToSurfaceFilterTest.cpp mitkEqualTest.cpp mitkLineTest.cpp ) if(MITK_ENABLE_RENDERING_TESTING) #since mitkInteractionTestHelper is currently creating a vtkRenderWindow set(MODULE_TESTS ${MODULE_TESTS} mitkPointSetDataInteractorTest.cpp ) endif() # test with image filename as an extra command line parameter set(MODULE_IMAGE_TESTS mitkImageTimeSelectorTest.cpp #only runs on images mitkImageAccessorTest.cpp #only runs on images mitkDataNodeFactoryTest.cpp #runs on all types of data ) set(MODULE_SURFACE_TESTS mitkSurfaceVtkWriterTest.cpp #only runs on surfaces mitkDataNodeFactoryTest.cpp #runs on all types of data ) # list of images for which the tests are run set(MODULE_TESTIMAGES US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd Png2D-bw.png ) set(MODULE_TESTSURFACES binary.stl ball.stl ) set(MODULE_CUSTOM_TESTS mitkDataStorageTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkEventMapperTest.cpp mitkEventConfigTest.cpp mitkNodeDependentPointSetInteractorTest.cpp mitkStateMachineFactoryTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp mitkImageWriterTest.cpp mitkImageVtkMapper2DTest.cpp mitkImageVtkMapper2DLevelWindowTest.cpp mitkImageVtkMapper2DOpacityTest.cpp mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp mitkImageVtkMapper2DColorTest.cpp mitkImageVtkMapper2DSwivelTest.cpp mitkImageVtkMapper2DTransferFunctionTest.cpp mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp mitkImageVtkMapper2DLookupTableTest.cpp mitkSurfaceVtkMapper3DTest mitkSurfaceVtkMapper3DTexturedSphereTest.cpp mitkSurfaceGLMapper2DColorTest.cpp mitkSurfaceGLMapper2DOpacityTest.cpp mitkVolumeCalculatorTest.cpp mitkLevelWindowManagerTest.cpp mitkPointSetVtkMapper2DTest.cpp mitkPointSetVtkMapper2DImageTest.cpp mitkPointSetVtkMapper2DGlyphTypeTest.cpp mitkPointSetVtkMapper2DTransformedPointsTest.cpp mitkVTKRenderWindowSizeTest.cpp mitkMultiComponentImageDataComparisonFilterTest.cpp mitkImageToItkTest.cpp mitkImageSliceSelectorTest.cpp mitkSurfaceDepthPeelingTest.cpp mitkSurfaceDepthSortingTest.cpp ) set(MODULE_RESOURCE_FILES Interactions/AddAndRemovePoints.xml Interactions/globalConfig.xml Interactions/StatemachineTest.xml Interactions/StatemachineConfigTest.xml ) # Create an artificial module initializing class for # the usServiceListenerTest.cpp usFunctionGenerateExecutableInit(testdriver_init_file IDENTIFIER ${MODULE_NAME}TestDriver ) # Embed the resources set(testdriver_resources ) usFunctionEmbedResources(testdriver_resources EXECUTABLE_NAME ${MODULE_NAME}TestDriver ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Resources FILES ${MODULE_RESOURCE_FILES} ) set(TEST_CPP_FILES ${testdriver_init_file} ${testdriver_resources}) diff --git a/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp b/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp index d6ce1efc2a..92abdea764 100644 --- a/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp +++ b/Core/Code/Testing/mitkPointSetDataInteractorTest.cpp @@ -1,178 +1,179 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include class mitkPointSetDataInteractorTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPointSetDataInteractorTestSuite); MITK_TEST(AddPointInteraction); MITK_TEST(DeletePointInteraction); CPPUNIT_TEST_SUITE_END(); private: mitk::DataNode::Pointer m_TestPointSetNode; mitk::PointSetDataInteractor::Pointer m_DataInteractor; mitk::PointSet::Pointer m_TestPointSet; public: void setUp() { //Create DataNode as a container for our PointSet to be tested m_TestPointSetNode = mitk::DataNode::New(); // Create PointSetData Interactor m_DataInteractor = mitk::PointSetDataInteractor::New(); // Load the according state machine for regular point set interaction m_DataInteractor->LoadStateMachine("PointSet.xml"); // Set the configuration file that defines the triggers for the transitions m_DataInteractor->SetEventConfig("PointSetConfig.xml"); //Create new PointSet which will receive the interaction input m_TestPointSet = mitk::PointSet::New(); m_TestPointSetNode->SetData(m_TestPointSet); // set the DataNode (which already is added to the DataStorage) m_DataInteractor->SetDataNode(m_TestPointSetNode); } void tearDown() { //destroy all objects + m_TestPointSetNode->SetDataInteractor(NULL); m_TestPointSetNode = NULL; m_TestPointSet = NULL; m_DataInteractor = NULL; } void AddPointInteraction() { //Path to the reference PointSet std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/PointSetDataInteractor_add_points_in_2D_ref.mps"); //Path to the interaction xml file std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PointSetDataInteractor_add_points_in_2D.xml"); //Create test helper to initialize all necessary objects for interaction mitk::InteractionTestHelper interactionTestHelper(interactionXmlPath); //Add our test node to the DataStorage of our test helper interactionTestHelper.AddNodeToStorage(m_TestPointSetNode); //Start Interaction interactionTestHelper.PlaybackInteraction(); //Load the reference PointSet mitk::PointSet::Pointer referencePointSet = mitk::IOUtil::LoadPointSet(referencePointSetPath); //Compare reference with the result of the interaction MITK_ASSERT_EQUAL(m_TestPointSet, referencePointSet, ""); } void PlayInteraction( std::string &xmlFile, mitk::DataNode* node ) { mitk::InteractionTestHelper interactionTestHelper( xmlFile ); interactionTestHelper.AddNodeToStorage( node ); interactionTestHelper.PlaybackInteraction(); } void EvaluateState( std::string &refPsFile, mitk::PointSet::Pointer ps, int selected ) { mitk::PointSet::Pointer refPs = mitk::IOUtil::LoadPointSet( refPsFile ); refPs->UpdateOutputInformation(); ps->UpdateOutputInformation(); MITK_ASSERT_EQUAL(ps, refPs, ""); MITK_TEST_CONDITION_REQUIRED(true, "Test against reference point set." ); MITK_TEST_CONDITION_REQUIRED(ps->GetNumberOfSelected() == 1, "One selected point." ); MITK_TEST_CONDITION_REQUIRED(ps->GetSelectInfo( selected ) , "Testing if proper point is selected." ); } void SetupInteractor( mitk::PointSetDataInteractor* dataInteractor, mitk::DataNode* node ) { dataInteractor->LoadStateMachine("PointSet.xml"); dataInteractor->SetEventConfig("PointSetConfig.xml"); dataInteractor->SetDataNode( node ); } void DeletePointInteraction() { mitk::PointSetDataInteractor::Pointer dataInteractor = mitk::PointSetDataInteractor::New(); mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); //Path to the reference PointSet std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/InputData/InitPointSet.mps"); mitk::PointSet::Pointer ps = mitk::IOUtil::LoadPointSet( referencePointSetPath ); pointSetNode->SetData( ps ); this->SetupInteractor( dataInteractor, pointSetNode ); std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-0_1.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-0.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 1 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-1_3.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-1.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 1 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-2_4.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-2.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 1 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-3_8.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-3.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 1 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-4_2.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-4.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 4 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-5_6.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-5.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 4 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-6_7.xml"); referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/DataInteractionDel-refPS-6.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); EvaluateState( referencePointSetPath, ps, 4 ); interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PSDataInteractionDel-7_5.xml"); //referencePointSetPath = GetTestDataFilePath("InteractionTestData/PointSet1.mps"); PlayInteraction( interactionXmlPath, pointSetNode ); MITK_TEST_CONDITION_REQUIRED(ps->GetPointSet()->GetNumberOfPoints() == 0, "Empty point set check."); MITK_TEST_CONDITION_REQUIRED(ps->GetNumberOfSelected() == 0, "No selected points." ); } }; MITK_TEST_SUITE_REGISTRATION(mitkPointSetDataInteractor) diff --git a/Core/Code/Testing/mitkProgressBarTest.cpp b/Core/Code/Testing/mitkProgressBarTest.cpp new file mode 100644 index 0000000000..5cec7687c0 --- /dev/null +++ b/Core/Code/Testing/mitkProgressBarTest.cpp @@ -0,0 +1,37 @@ +/*=================================================================== + +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 + +class mitkProgressBarTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkProgressBarTestSuite); + MITK_TEST(TestInstantiation); + CPPUNIT_TEST_SUITE_END(); + +public: + + void TestInstantiation() + { + mitk::ProgressBar::Pointer pb = mitk::ProgressBar::GetInstance(); + CPPUNIT_ASSERT_MESSAGE("Single instance can be created on demand", pb.IsNotNull()); + } +}; + +MITK_TEST_SUITE_REGISTRATION(mitkProgressBar) diff --git a/Core/Code/Testing/mitkProportionalTimeGeometryTest.cpp b/Core/Code/Testing/mitkProportionalTimeGeometryTest.cpp new file mode 100644 index 0000000000..97a2805040 --- /dev/null +++ b/Core/Code/Testing/mitkProportionalTimeGeometryTest.cpp @@ -0,0 +1,112 @@ +/*=================================================================== + +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 "mitkProportionalTimeGeometry.h" +#include "mitkGeometry3D.h" +#include "mitkThinPlateSplineCurvedGeometry.h" +#include "mitkSlicedGeometry3D.h" + +#include +#include + + +class mitkProportionalTimeGeometryTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkProportionalTimeGeometryTestSuite); + MITK_TEST(TestInheritance); + MITK_TEST(TestProportionalTimeGeometryCloning); + CPPUNIT_TEST_SUITE_END(); + +public: + + void setUp() + { + } + + void tearDown() + { + } + + // This test is supposed to verify inheritance behaviour, this test will fail if the behaviour changes in the future + void TestInheritance() + { + mitk::ProportionalTimeGeometry::Pointer ptGeom = mitk::ProportionalTimeGeometry::New(); + mitk::Geometry3D::Pointer g3d = dynamic_cast < mitk::Geometry3D* > ( ptGeom.GetPointer() ); + CPPUNIT_ASSERT_MESSAGE("ProportionalTimeGeometry should not be castable to Geometry3D", g3d.IsNull()); + + mitk::TimeGeometry::Pointer base = dynamic_cast < mitk::TimeGeometry* > ( ptGeom.GetPointer() ); + CPPUNIT_ASSERT_MESSAGE("ProportionalTimeGeometry should be castable to TimeGeometry", base.IsNotNull()); + } + + + void TestProportionalTimeGeometryCloning() + { + mitk::ProportionalTimeGeometry::Pointer geom = CreateProportionalTimeGeometry(); + + mitk::ProportionalTimeGeometry::Pointer clone = geom->Clone(); + CPPUNIT_ASSERT_MESSAGE("First time point of clone matches original", + clone->GetFirstTimePoint() == 1.1); + CPPUNIT_ASSERT_MESSAGE("Step duration of clone matches original", + clone->GetStepDuration() == 2.2); + + mitk::PlaneGeometry *planeGeom = dynamic_cast(clone->GetGeometryForTimeStep(0).GetPointer()); + itk::Matrix matrix = planeGeom->GetIndexToWorldTransform()->GetMatrix(); + CPPUNIT_ASSERT_MESSAGE("Matrix element [0][0] of clone matches original", matrix[0][0] == 31); + + double origin = planeGeom->GetOrigin()[0]; + CPPUNIT_ASSERT_MESSAGE("First Point of origin of clone matches original", mitk::Equal(origin, 8)); + + double spacing = planeGeom->GetSpacing()[0]; + CPPUNIT_ASSERT_MESSAGE("First Point of spacing of clone matches original", mitk::Equal(spacing, 31)); + } + +private: + // helper Methods for the Tests + + mitk::ProportionalTimeGeometry::Pointer CreateProportionalTimeGeometry() + { + mitk::Vector3D mySpacing; + mySpacing[0] = 31; + mySpacing[1] = 0.1; + mySpacing[2] = 5.4; + mitk::Point3D myOrigin; + myOrigin[0] = 8; + myOrigin[1] = 9; + myOrigin[2] = 10; + mitk::AffineTransform3D::Pointer myTransform = mitk::AffineTransform3D::New(); + itk::Matrix transMatrix; + transMatrix.Fill(0); + transMatrix[0][0] = 1; + transMatrix[1][1] = 2; + transMatrix[2][2] = 4; + + myTransform->SetMatrix(transMatrix); + + mitk::PlaneGeometry::Pointer geom2D = mitk::PlaneGeometry::New(); + geom2D->SetIndexToWorldTransform(myTransform); + geom2D->SetSpacing(mySpacing); + geom2D->SetOrigin(myOrigin); + + mitk::ProportionalTimeGeometry::Pointer geom = mitk::ProportionalTimeGeometry::New(); + geom->SetFirstTimePoint(1.1); + geom->SetStepDuration(2.2); + geom->SetTimeStepGeometry(geom2D, 0); + + return geom; + } + +}; +MITK_TEST_SUITE_REGISTRATION(mitkProportionalTimeGeometry) diff --git a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp index 550ecdd3c7..58bc9b97f5 100644 --- a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp +++ b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkCreationTest.cpp @@ -1,112 +1,119 @@ /*=================================================================== 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. ===================================================================*/ // Testing #include "mitkTestingMacros.h" #include "mitkTestFixture.h" // std includes #include // MITK includes #include #include "mitkConnectomicsNetworkCreator.h" #include +// VTK includes +#include + class mitkConnectomicsNetworkCreationTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkConnectomicsNetworkCreationTestSuite); + + /// \todo Fix VTK memory leaks. Bug 18097. + vtkDebugLeaks::SetExitError(0); + MITK_TEST(CreateNetworkFromFibersAndParcellation); CPPUNIT_TEST_SUITE_END(); private: std::string m_ParcellationPath; std::string m_FiberPath; std::string m_ReferenceNetworkPath; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() { m_ReferenceNetworkPath = GetTestDataFilePath("DiffusionImaging/Connectomics/reference.cnf"); m_ParcellationPath = GetTestDataFilePath("DiffusionImaging/Connectomics/parcellation.nrrd"); m_FiberPath = GetTestDataFilePath("DiffusionImaging/Connectomics/fiberBundle.fib"); } void tearDown() { m_ReferenceNetworkPath = ""; m_ParcellationPath = ""; m_FiberPath = ""; } void CreateNetworkFromFibersAndParcellation() { const std::string s1="", s2=""; // load fiber image std::vector fiberInfile = mitk::BaseDataIO::LoadBaseDataFromFile( m_FiberPath, s1, s2, false ); if( fiberInfile.empty() ) { std::string errorMessage = "Fiber Image at " + m_FiberPath + " could not be read. Aborting."; CPPUNIT_ASSERT_MESSAGE( errorMessage, false ); } mitk::BaseData* fiberBaseData = fiberInfile.at(0); mitk::FiberBundleX* fiberBundle = dynamic_cast( fiberBaseData ); // load parcellation std::vector parcellationInFile = mitk::BaseDataIO::LoadBaseDataFromFile( m_ParcellationPath, s1, s2, false ); if( parcellationInFile.empty() ) { std::string errorMessage = "Parcellation at " + m_ParcellationPath + " could not be read. Aborting."; CPPUNIT_ASSERT_MESSAGE( errorMessage, false ); } mitk::BaseData* parcellationBaseData = parcellationInFile.at(0); mitk::Image* parcellationImage = dynamic_cast( parcellationBaseData ); // do creation mitk::ConnectomicsNetworkCreator::Pointer connectomicsNetworkCreator = mitk::ConnectomicsNetworkCreator::New(); connectomicsNetworkCreator->SetSegmentation( parcellationImage ); connectomicsNetworkCreator->SetFiberBundle( fiberBundle ); connectomicsNetworkCreator->CalculateCenterOfMass(); connectomicsNetworkCreator->SetEndPointSearchRadius( 15 ); connectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation(); // load network std::vector referenceFile = mitk::BaseDataIO::LoadBaseDataFromFile( m_ReferenceNetworkPath, s1, s2, false ); if( referenceFile.empty() ) { std::string errorMessage = "Reference Network at " + m_ReferenceNetworkPath + " could not be read. Aborting."; CPPUNIT_ASSERT_MESSAGE( errorMessage, false ); } mitk::BaseData* referenceBaseData = referenceFile.at(0); mitk::ConnectomicsNetwork* referenceNetwork = dynamic_cast( referenceBaseData ); mitk::ConnectomicsNetwork::Pointer network = connectomicsNetworkCreator->GetNetwork(); CPPUNIT_ASSERT_MESSAGE( "Comparing created and reference network.", mitk::Equal( network.GetPointer(), referenceNetwork, mitk::eps, true) ); } }; MITK_TEST_SUITE_REGISTRATION(mitkConnectomicsNetworkCreation) diff --git a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp index 1c66f05ea5..9d6b132968 100644 --- a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp +++ b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsNetworkTest.cpp @@ -1,525 +1,531 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkConnectomicsNetwork.h" #include "mitkConnectomicsSyntheticNetworkGenerator.h" #include "mitkConnectomicsSimulatedAnnealingManager.h" #include "mitkConnectomicsSimulatedAnnealingPermutationModularity.h" #include "mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h" + +#include + #include #include #include /**Documentation * Test for synthetic connectomics generation and connectomics network functionality */ int mitkConnectomicsNetworkTest(int argc, char* argv[]) { // Test begins MITK_TEST_BEGIN("mitkConnectomicsNetworkTest"); + /// \todo Fix VTK memory leaks. Bug 18097. + vtkDebugLeaks::SetExitError(0); + // Typedefs typedef mitk::ConnectomicsNetwork::VertexDescriptorType VertexType; typedef mitk::ConnectomicsNetwork::EdgeDescriptorType EdgeType; typedef mitk::ConnectomicsNetwork::NetworkNode NodeType; // The test network std::vector< NodeType > inNodes; NodeType node; node.id = 0; node.label = "1-1"; node.coordinates.clear(); node.coordinates.push_back( 0 ); node.coordinates.push_back( 0 ); node.coordinates.push_back( 0 ); inNodes.push_back(node); node.id = 1; node.label = "2-1"; node.coordinates.clear(); node.coordinates.push_back( 10 ); node.coordinates.push_back( 0 ); node.coordinates.push_back( 0 ); inNodes.push_back(node); node.id = 2; node.label = "3-1"; node.coordinates.clear(); node.coordinates.push_back( 20 ); node.coordinates.push_back( 10 ); node.coordinates.push_back( 0 ); inNodes.push_back(node); node.id = 3; node.label = "4-1"; node.coordinates.clear(); node.coordinates.push_back( 30 ); node.coordinates.push_back( 20 ); node.coordinates.push_back( 0 ); inNodes.push_back(node); node.id = 4; node.label = "5-1"; node.coordinates.clear(); node.coordinates.push_back( 40 ); node.coordinates.push_back( 50 ); node.coordinates.push_back( 0 ); inNodes.push_back(node); node.id = 5; node.label = "6-2"; node.coordinates.clear(); node.coordinates.push_back( 0 ); node.coordinates.push_back( 0 ); node.coordinates.push_back( 10 ); inNodes.push_back(node); node.id = 6; node.label = "7-2"; node.coordinates.clear(); node.coordinates.push_back( 0 ); node.coordinates.push_back( 10 ); node.coordinates.push_back( 20 ); inNodes.push_back(node); node.id = 7; node.label = "8-2"; node.coordinates.clear(); node.coordinates.push_back( 0 ); node.coordinates.push_back( 20 ); node.coordinates.push_back( 30 ); inNodes.push_back(node); node.id = 8; node.label = "9-2"; node.coordinates.clear(); node.coordinates.push_back( 0 ); node.coordinates.push_back( 30 ); node.coordinates.push_back( 40 ); inNodes.push_back(node); node.id = 9; node.label = "10-3"; node.coordinates.clear(); node.coordinates.push_back( 20 ); node.coordinates.push_back( 0 ); node.coordinates.push_back( 10 ); inNodes.push_back(node); node.id = 10; node.label = "11-3"; node.coordinates.clear(); node.coordinates.push_back( 30 ); node.coordinates.push_back( 0 ); node.coordinates.push_back( 20 ); inNodes.push_back(node); node.id = 11; node.label = "12-3"; node.coordinates.clear(); node.coordinates.push_back( 40 ); node.coordinates.push_back( 0 ); node.coordinates.push_back( 30 ); inNodes.push_back(node); std::vector< mitk::ConnectomicsNetwork::NetworkEdge > inEdges; mitk::ConnectomicsNetwork::NetworkEdge edge; edge.sourceId = 0; edge.targetId = 1; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 0; edge.targetId = 2; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 0; edge.targetId = 4; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 1; edge.targetId = 4; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 1; edge.targetId = 3; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 2; edge.targetId = 3; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 3; edge.targetId = 4; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 4; edge.targetId = 5; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 5; edge.targetId = 6; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 5; edge.targetId = 7; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 5; edge.targetId = 8; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 7; edge.targetId = 8; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 6; edge.targetId = 8; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 6; edge.targetId = 9; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 3; edge.targetId = 10; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 9; edge.targetId = 10; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 10; edge.targetId = 11; edge.weight = 2; inEdges.push_back( edge ); edge.sourceId = 9; edge.targetId = 11; edge.weight = 2; inEdges.push_back( edge ); // further variables double eps(0.001); try { // Testing synthetic network generation mitk::ConnectomicsSyntheticNetworkGenerator::Pointer generator = mitk::ConnectomicsSyntheticNetworkGenerator::New(); MITK_TEST_CONDITION_REQUIRED(generator.IsNotNull(),"Synthetic network generator has been instantiated") // first and second parameter std::vector< std::pair > parameterVector; // name and isRandom std::vector< std::pair > messageVector; // order of results is # vertices, # edges, # self loops, average degree, connection density // global clustering coefficient std::vector< std::vector< double > > resultVector; int numberOfOptions = 3; parameterVector.resize(numberOfOptions); messageVector.resize(numberOfOptions); resultVector.resize(numberOfOptions); // Create regular lattice network in the form of a cube with sidelength 5 and distance 10 between nodes parameterVector[0] = std::pair< int, double>(5, 10); messageVector[0] = std::pair("Regular Lattice Network", false); resultVector[0].push_back( 5 * 5 * 5 ); resultVector[0].push_back( 300 ); resultVector[0].push_back( 0 ); resultVector[0].push_back( 4.8 ); resultVector[0].push_back(0.0387); resultVector[0].push_back(0); // Create a heterogeneous sphere network with 1 central node and 49 nodes on the surface and radius 10 parameterVector[1] = std::pair< int, double>(50, 10); messageVector[1] = std::pair("Heterogeneous Sphere Network", false); resultVector[1].push_back( 50 ); resultVector[1].push_back( 49 ); resultVector[1].push_back( 0 ); resultVector[1].push_back( 1.96 ); resultVector[1].push_back(0.0400); resultVector[1].push_back(0); // Create random network with 50 nodes and edges between them generated with a 0.1 likelihood parameterVector[2] = std::pair< int, double>(50, 0.1); messageVector[2] = std::pair("Random Network", true); resultVector[2].push_back( 50 ); for(int loop(0); loop < numberOfOptions; loop++) { mitk::ConnectomicsNetwork::Pointer network = generator->CreateSyntheticNetwork(loop, parameterVector[loop].first, parameterVector[loop].second); bool generationWorked = generator->WasGenerationSuccessfull() && network.IsNotNull(); std::string message = messageVector[loop].first + " has been instantiated"; MITK_TEST_CONDITION_REQUIRED(generationWorked,message) bool verticesCloseEnough( std::abs(resultVector[loop][0] - network->GetNumberOfVertices()) < eps); MITK_TEST_CONDITION_REQUIRED( verticesCloseEnough, "Expected number of vertices") if(!messageVector[loop].second) { bool edgesCloseEnough( std::abs(resultVector[loop][1] - network->GetNumberOfEdges()) < eps); MITK_TEST_CONDITION_REQUIRED( edgesCloseEnough, "Expected number of edges") bool selfLoopsCloseEnough( std::abs(resultVector[loop][2] - network->GetNumberOfSelfLoops()) < eps); MITK_TEST_CONDITION_REQUIRED( selfLoopsCloseEnough, "Expected number of self loops") bool avDegCloseEnough( std::abs(resultVector[loop][3] - network->GetAverageDegree()) < eps); MITK_TEST_CONDITION_REQUIRED( avDegCloseEnough, "Expected average degree") bool conDensCloseEnough( std::abs(resultVector[loop][4] - network->GetConnectionDensity()) < eps); MITK_TEST_CONDITION_REQUIRED( conDensCloseEnough, "Expected connection density") bool clustCoeffCloseEnough( std::abs(resultVector[loop][5] - network->GetGlobalClusteringCoefficient()) < eps); MITK_TEST_CONDITION_REQUIRED( clustCoeffCloseEnough, "Expected global clustering coefficient") } } } catch (...) { MITK_ERROR << "Unhandled exception caught while testing synthetic network generation [FAILED]" ; return EXIT_FAILURE; } try { // Testing network interface // Create network mitk::ConnectomicsNetwork::Pointer network = mitk::ConnectomicsNetwork::New(); std::vector< VertexType > vertexVector; vertexVector.resize( inNodes.size() ); for(unsigned int loop(0); loop < inNodes.size(); loop++) { VertexType newVertex = network->AddVertex( inNodes[loop].id ); vertexVector[ inNodes[loop].id ] = newVertex; network->SetLabel( newVertex, inNodes[loop].label ); network->SetCoordinates( newVertex, inNodes[loop].coordinates ); } for(unsigned int loop(0); loop < inEdges.size(); loop++) { int sourceId = inEdges[loop].sourceId; int targetId = inEdges[loop].targetId; VertexType sourceVertex = vertexVector[ sourceId ]; VertexType targetVertex = vertexVector[ targetId ]; // there are two methods to add nodes if( loop % 2 == 0 ) { network->AddEdge(sourceVertex, targetVertex); for( int remaining( inEdges[loop].weight ); remaining > 1; remaining-- ) { network->IncreaseEdgeWeight( sourceVertex, targetVertex ); } } else { network->AddEdge(sourceVertex, targetVertex, sourceId, targetId, inEdges[loop].weight ); } } // Test whether network parameters are as expected MITK_TEST_CONDITION_REQUIRED( inNodes.size() == (unsigned int)network->GetNumberOfVertices(), "Expected number of vertices") MITK_TEST_CONDITION_REQUIRED( inEdges.size() == (unsigned int)network->GetNumberOfEdges(), "Expected number of edges") MITK_TEST_CONDITION_REQUIRED( 0 == network->GetNumberOfSelfLoops(), "Expected number of self loops") bool avDegCloseEnough( std::abs(3 - network->GetAverageDegree()) < eps); MITK_TEST_CONDITION_REQUIRED( avDegCloseEnough, "Expected average degree") bool conDensCloseEnough( std::abs(0.2727 - network->GetConnectionDensity()) < eps); MITK_TEST_CONDITION_REQUIRED( conDensCloseEnough, "Expected connection density") bool clustCoeffCloseEnough( std::abs(0.4583 - network->GetGlobalClusteringCoefficient()) < eps); MITK_TEST_CONDITION_REQUIRED( clustCoeffCloseEnough, "Expected global clustering coefficient") MITK_TEST_CONDITION_REQUIRED( network->GetMaximumWeight() == 2, "Expected maximum weight") MITK_TEST_CONDITION_REQUIRED( network->GetVectorOfAllVertexDescriptors().size() == vertexVector.size(), "Expected number of vertex descriptors") } catch (...) { MITK_ERROR << "Unhandled exception caught while testing network interface [FAILED]" ; return EXIT_FAILURE; } try { // Testing modularity calculation typedef std::map< VertexType, int > ToModuleMapType; // Create network mitk::ConnectomicsNetwork::Pointer network = mitk::ConnectomicsNetwork::New(); std::vector< VertexType > vertexVector; vertexVector.resize( inNodes.size() ); for(unsigned int loop(0); loop < inNodes.size(); loop++) { VertexType newVertex = network->AddVertex( inNodes[loop].id ); vertexVector[ inNodes[loop].id ] = newVertex; network->SetLabel( newVertex, inNodes[loop].label ); network->SetCoordinates( newVertex, inNodes[loop].coordinates ); } for(unsigned int loop(0); loop < inEdges.size(); loop++) { int sourceId = inEdges[loop].sourceId; int targetId = inEdges[loop].targetId; VertexType sourceVertex = vertexVector[ sourceId ]; VertexType targetVertex = vertexVector[ targetId ]; // there are two methods to add nodes if( loop % 2 == 0 ) { network->AddEdge(sourceVertex, targetVertex); for( int remaining( inEdges[loop].weight ); remaining > 1; remaining-- ) { network->IncreaseEdgeWeight( sourceVertex, targetVertex ); } } else { network->AddEdge(sourceVertex, targetVertex, sourceId, targetId, inEdges[loop].weight ); } } // Simulated annealing classes mitk::ConnectomicsSimulatedAnnealingManager::Pointer manager = mitk::ConnectomicsSimulatedAnnealingManager::New(); mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Pointer permutation = mitk::ConnectomicsSimulatedAnnealingPermutationModularity::New(); mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::Pointer costFunction = mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::New(); // Test whether modularity calculation behaves as expected ToModuleMapType threeModuleSolution; std::vector< VertexType > vertexInVector = network->GetVectorOfAllVertexDescriptors(); threeModuleSolution.insert( std::pair( vertexInVector[ 0 ], 0 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 1 ], 0 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 2 ], 0 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 3 ], 0 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 4 ], 0 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 5 ], 1 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 6 ], 1 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 7 ], 1 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 8 ], 1 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 9 ], 2 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 10 ], 2 ) ); threeModuleSolution.insert( std::pair( vertexInVector[ 11 ], 2 ) ); bool threeModuleModularity( std::abs(0.4753 - costFunction->CalculateModularity( network, &threeModuleSolution )) < eps); MITK_TEST_CONDITION_REQUIRED( threeModuleModularity, "Expected three module modularity") bool correctNumberOfModules( permutation->getNumberOfModules( &threeModuleSolution ) == 3 ); MITK_TEST_CONDITION_REQUIRED( correctNumberOfModules, "Expected number of modules") bool correctNumberOfVertices( permutation->getNumberOfVerticesInModule( &threeModuleSolution, 0 ) == 5 && permutation->getNumberOfVerticesInModule( &threeModuleSolution, 1 ) == 4 && permutation->getNumberOfVerticesInModule( &threeModuleSolution, 2 ) == 3 ); MITK_TEST_CONDITION_REQUIRED( correctNumberOfVertices, "Expected number of vertices per module") ToModuleMapType oneModuleSolution; oneModuleSolution.insert( std::pair( vertexInVector[ 0 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 1 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 2 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 3 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 4 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 5 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 6 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 7 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 8 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 9 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 10 ], 0 ) ); oneModuleSolution.insert( std::pair( vertexInVector[ 11 ], 0 ) ); bool oneModuleModularity( std::abs(0.0 - costFunction->CalculateModularity( network, &oneModuleSolution )) < eps); MITK_TEST_CONDITION_REQUIRED( oneModuleModularity, "Expected one module modularity") ToModuleMapType badTwoModuleSolution; badTwoModuleSolution.insert( std::pair( vertexInVector[ 0 ], 0 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 1 ], 0 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 2 ], 0 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 3 ], 0 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 4 ], 0 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 5 ], 1 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 6 ], 1 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 7 ], 1 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 8 ], 0 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 9 ], 1 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 10 ], 1 ) ); badTwoModuleSolution.insert( std::pair( vertexInVector[ 11 ], 0 ) ); bool badTwoModuleModularity( std::abs(0.097222 - costFunction->CalculateModularity( network, &badTwoModuleSolution )) < eps); MITK_TEST_CONDITION_REQUIRED( badTwoModuleModularity, "Expected bad two module modularity") ToModuleMapType noInternalLinksThreeModuleSolution; noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 0 ], 0 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 1 ], 2 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 2 ], 1 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 3 ], 0 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 4 ], 1 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 5 ], 2 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 6 ], 0 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 7 ], 0 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 8 ], 1 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 9 ], 2 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 10 ], 1 ) ); noInternalLinksThreeModuleSolution.insert( std::pair( vertexInVector[ 11 ], 0 ) ); bool noInternalThreeModuleModularity( std::abs(-0.3395 - costFunction->CalculateModularity( network, &noInternalLinksThreeModuleSolution )) < eps); MITK_TEST_CONDITION_REQUIRED( noInternalThreeModuleModularity, "Expected three module modularity containing no internal links") } catch (...) { MITK_ERROR << "Unhandled exception caught while testing modularity calculation [FAILED]" ; return EXIT_FAILURE; } // Test ends MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp index 37186f892c..102c26eeb1 100644 --- a/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp +++ b/Modules/DiffusionImaging/Connectomics/Testing/mitkConnectomicsStatisticsCalculatorTest.cpp @@ -1,137 +1,143 @@ /*=================================================================== 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. ===================================================================*/ // Testing #include "mitkTestingMacros.h" #include "mitkTestFixture.h" // std includes #include #include // MITK includes #include #include +// VTK includes +#include class mitkConnectomicsStatisticsCalculatorTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkConnectomicsStatisticsCalculatorTestSuite); + + /// \todo Fix VTK memory leaks. Bug 18097. + vtkDebugLeaks::SetExitError(0); + MITK_TEST(StatisticsCalculatorUpdate); CPPUNIT_TEST_SUITE_END(); private: mitk::ConnectomicsNetwork::Pointer m_Network; std::string m_NetworkPath; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() { //load network m_NetworkPath = GetTestDataFilePath("DiffusionImaging/Connectomics/reference.cnf"); const std::string s1="", s2=""; std::vector networkFile = mitk::BaseDataIO::LoadBaseDataFromFile( m_NetworkPath, s1, s2, false ); if( networkFile.empty() ) { std::string errorMessage = "File at " + m_NetworkPath + " could not be read. Aborting."; CPPUNIT_ASSERT_MESSAGE( errorMessage, !networkFile.empty() ); return; } mitk::BaseData* networkBaseData = networkFile.at(0); mitk::ConnectomicsNetwork* network = dynamic_cast( networkBaseData ); if( !network ) { std::string errorMessage = "Read file at " + m_NetworkPath + " could not be recognized as network. Aborting."; CPPUNIT_ASSERT_MESSAGE( errorMessage, network); return; } m_Network = network; } void tearDown() { m_Network = NULL; m_NetworkPath = ""; } void StatisticsCalculatorUpdate() { mitk::ConnectomicsStatisticsCalculator::Pointer statisticsCalculator = mitk::ConnectomicsStatisticsCalculator::New(); statisticsCalculator->SetNetwork( m_Network ); statisticsCalculator->Update(); double eps( 0.0001 ); CPPUNIT_ASSERT_MESSAGE( "GetNumberOfVertices", mitk::Equal( statisticsCalculator->GetNumberOfVertices( ), 4 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetNumberOfEdges" , mitk::Equal( statisticsCalculator->GetNumberOfEdges( ), 5 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageDegree", mitk::Equal( statisticsCalculator->GetAverageDegree( ), 2.5 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetConnectionDensity", mitk::Equal( statisticsCalculator->GetConnectionDensity( ), 0.833333 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetNumberOfConnectedComponents", mitk::Equal( statisticsCalculator->GetNumberOfConnectedComponents( ), 1 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageComponentSize", mitk::Equal( statisticsCalculator->GetAverageComponentSize( ), 4 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetLargestComponentSize", mitk::Equal( statisticsCalculator->GetLargestComponentSize( ), 4 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetRatioOfNodesInLargestComponent", mitk::Equal( statisticsCalculator->GetRatioOfNodesInLargestComponent( ), 1 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetHopPlotExponent", mitk::Equal( statisticsCalculator->GetHopPlotExponent( ), 0.192645 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetEffectiveHopDiameter", mitk::Equal( statisticsCalculator->GetEffectiveHopDiameter( ), 1 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageClusteringCoefficientsC", mitk::Equal( statisticsCalculator->GetAverageClusteringCoefficientsC( ), 0.833333 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageClusteringCoefficientsD", mitk::Equal( statisticsCalculator->GetAverageClusteringCoefficientsD( ), 0.916667 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageClusteringCoefficientsE", mitk::Equal( statisticsCalculator->GetAverageClusteringCoefficientsE( ), 0.833333 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageVertexBetweennessCentrality", mitk::Equal( statisticsCalculator->GetAverageVertexBetweennessCentrality( ), 0.25 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageEdgeBetweennessCentrality", mitk::Equal( statisticsCalculator->GetAverageEdgeBetweennessCentrality( ), 1.4 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetNumberOfIsolatedPoints" , mitk::Equal( statisticsCalculator->GetNumberOfIsolatedPoints( ), 0 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetRatioOfIsolatedPoints", mitk::Equal( statisticsCalculator->GetRatioOfIsolatedPoints( ), 0 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetNumberOfEndPoints", mitk::Equal( statisticsCalculator->GetNumberOfEndPoints( ), 0 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetRatioOfEndPoints", mitk::Equal( statisticsCalculator->GetRatioOfEndPoints( ), 0 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetDiameter", mitk::Equal( statisticsCalculator->GetDiameter( ), 2 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetDiameter90", mitk::Equal( statisticsCalculator->GetDiameter90( ), 2 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetRadius" , mitk::Equal( statisticsCalculator->GetRadius( ), 1 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetRadius90", mitk::Equal( statisticsCalculator->GetRadius90( ), 1 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageEccentricity", mitk::Equal( statisticsCalculator->GetAverageEccentricity( ), 1.5 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAverageEccentricity90", mitk::Equal( statisticsCalculator->GetAverageEccentricity90( ), 1.5 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetAveragePathLength" , mitk::Equal( statisticsCalculator->GetAveragePathLength( ), 1.16667 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetNumberOfCentralPoints" , mitk::Equal( statisticsCalculator->GetNumberOfCentralPoints( ), 2 , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetRatioOfCentralPoints", mitk::Equal( statisticsCalculator->GetRatioOfCentralPoints( ), 0.5 , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetSpectralRadius( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetSecondLargestEigenValue( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetAdjacencyTrace( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetAdjacencyEnergy( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetLaplacianTrace( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetLaplacianEnergy( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetLaplacianSpectralGap( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianTrace( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianEnergy( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianNumberOf2s( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianNumberOf1s( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianNumberOf0s( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianLowerSlope( ), , eps, true ) ); // CPPUNIT_ASSERT_MESSAGE( " ", mitk::Equal( statisticsCalculator->GetNormalizedLaplacianUpperSlope( ), , eps, true ) ); CPPUNIT_ASSERT_MESSAGE( "GetSmallWorldness", mitk::Equal( statisticsCalculator->GetSmallWorldness( ), 1.72908 , eps, true ) ); } }; MITK_TEST_SUITE_REGISTRATION(mitkConnectomicsStatisticsCalculator) diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp index 59554ecd46..e8aaee34b0 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp @@ -1,101 +1,106 @@ /*=================================================================== 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 #include #include +#include + /**Documentation * Test if fiber transfortaiom methods work correctly */ int mitkFiberExtractionTest(int argc, char* argv[]) { MITK_TEST_BEGIN("mitkFiberExtractionTest"); + /// \todo Fix VTK memory leaks. Bug 18097. + vtkDebugLeaks::SetExitError(0); + MITK_INFO << "argc: " << argc; MITK_TEST_CONDITION_REQUIRED(argc==13,"check for input data") try{ mitk::FiberBundleX::Pointer groundTruthFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[1])->GetData()); mitk::FiberBundleX::Pointer testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[2])->GetData()); // test planar figure based extraction mitk::PlanarFigure::Pointer pf1 = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[3])->GetData()); mitk::PlanarFigure::Pointer pf2 = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[4])->GetData()); mitk::PlanarFigure::Pointer pf3 = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[5])->GetData()); MITK_INFO << "TEST1"; mitk::PlanarFigureComposite::Pointer pfc1 = mitk::PlanarFigureComposite::New(); pfc1->setOperationType(mitk::PFCOMPOSITION_AND_OPERATION); pfc1->addPlanarFigure(dynamic_cast(pf2.GetPointer())); pfc1->addPlanarFigure(dynamic_cast(pf3.GetPointer())); MITK_INFO << "TEST2"; mitk::PlanarFigureComposite::Pointer pfc2 = mitk::PlanarFigureComposite::New(); pfc2->setOperationType(mitk::PFCOMPOSITION_OR_OPERATION); pfc2->addPlanarFigure(dynamic_cast(pf1.GetPointer())); pfc2->addPlanarFigure(pfc1.GetPointer()); MITK_INFO << "TEST3"; mitk::FiberBundleX::Pointer extractedFibs = groundTruthFibs->ExtractFiberSubset(pfc2); MITK_INFO << "TEST4"; MITK_TEST_CONDITION_REQUIRED(extractedFibs->Equals(testFibs),"check planar figure extraction") MITK_INFO << "TEST5"; // test subtraction and addition mitk::FiberBundleX::Pointer notExtractedFibs = groundTruthFibs->SubtractBundle(extractedFibs); MITK_INFO << argv[11]; testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[11])->GetData()); MITK_TEST_CONDITION_REQUIRED(notExtractedFibs->Equals(testFibs),"check bundle subtraction") mitk::FiberBundleX::Pointer joinded = extractedFibs->AddBundle(notExtractedFibs); testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[12])->GetData()); MITK_TEST_CONDITION_REQUIRED(joinded->Equals(testFibs),"check bundle addition") // test binary image based extraction mitk::Image::Pointer mitkRoiImage = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[6])->GetData()); typedef itk::Image< unsigned char, 3 > itkUCharImageType; itkUCharImageType::Pointer itkRoiImage = itkUCharImageType::New(); mitk::CastToItkImage(mitkRoiImage, itkRoiImage); mitk::FiberBundleX::Pointer inside = groundTruthFibs->RemoveFibersOutside(itkRoiImage, false); mitk::FiberBundleX::Pointer outside = groundTruthFibs->RemoveFibersOutside(itkRoiImage, true); mitk::FiberBundleX::Pointer passing = groundTruthFibs->ExtractFiberSubset(itkRoiImage, true); mitk::FiberBundleX::Pointer ending = groundTruthFibs->ExtractFiberSubset(itkRoiImage, false); testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[7])->GetData()); MITK_TEST_CONDITION_REQUIRED(inside->Equals(testFibs),"check inside mask extraction") testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[8])->GetData()); MITK_TEST_CONDITION_REQUIRED(outside->Equals(testFibs),"check outside mask extraction") testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[9])->GetData()); MITK_TEST_CONDITION_REQUIRED(passing->Equals(testFibs),"check passing mask extraction") testFibs = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[10])->GetData()); MITK_TEST_CONDITION_REQUIRED(ending->Equals(testFibs),"check ending in mask extraction") } catch(...) { return EXIT_FAILURE; } // always end with this! MITK_TEST_END(); } diff --git a/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp b/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp index 8812bbddbf..91a0276601 100644 --- a/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp +++ b/Modules/PlanarFigure/Testing/mitkPlanarFigureInteractionTest.cpp @@ -1,189 +1,193 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include + #include "usModuleRegistry.h" class mitkPlanarFigureInteractionTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPlanarFigureInteractionTestSuite); MITK_TEST(AngleInteractionCreate); MITK_TEST(BezierCurveInteractionCreate); MITK_TEST(CircleInteractionCreate); MITK_TEST(DoubleEllipseInteractionCreate); MITK_TEST(PlanarFourPointAngleInteractionCreate); MITK_TEST(PlanarLineInteractionCreate); MITK_TEST(PlanarPolygonInteractionCreate); MITK_TEST(NonClosedPlanarPolygonInteractionCreate); MITK_TEST(RectangleInteractionCreate); MITK_TEST(PlanarSubdivisionInteractionCreate); CPPUNIT_TEST_SUITE_END(); public: void setUp() { + /// \todo Fix leaks of vtkObjects. Bug 18095. + vtkDebugLeaks::SetExitError(0); } void tearDown() { } void RunTest(mitk::PlanarFigure::Pointer figure, std::string interactionXmlPath, std::string referenceFigurePath) { mitk::DataNode::Pointer node; mitk::PlanarFigureInteractor::Pointer figureInteractor; //Create DataNode as a container for our PlanarFigure node = mitk::DataNode::New(); node->SetData(figure); mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionXmlPath)); //Load a bounding image mitk::Image::Pointer testImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("InteractionTestData/InputData/scaledSingleSlice.nrrd")); mitk::DataNode::Pointer dn = mitk::DataNode::New(); dn->SetData(testImage); interactionTestHelper.AddNodeToStorage(dn); interactionTestHelper.GetDataStorage()->Add(node, dn); node->SetName("PLANAR FIGURE"); // set as selected node->SetSelected(true); node->AddProperty("selected", mitk::BoolProperty::New(true)); //Load state machine figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule("MitkPlanarFigure"); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( node ); //Start Interaction interactionTestHelper.PlaybackInteraction(); //Load reference PlanarFigure mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New(); reader->SetFileName(GetTestDataFilePath(referenceFigurePath)); reader->Update(); mitk::PlanarFigure::Pointer reference = reader->GetOutput(0); //Compare figures MITK_ASSERT_EQUAL(figure, reference, "Compare figure with reference"); } void AngleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarAngle::New(); RunTest(figure, "InteractionTestData/Interactions/Angle.xml", "InteractionTestData/ReferenceData/Angle.pf"); } void BezierCurveInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarBezierCurve::New(); RunTest(figure, "InteractionTestData/Interactions/Bezier.xml", "InteractionTestData/ReferenceData/Bezier.pf"); } void CircleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarCircle::New(); RunTest(figure, "InteractionTestData/Interactions/Circle.xml", "InteractionTestData/ReferenceData/Circle.pf"); } void DoubleEllipseInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarDoubleEllipse::New(); RunTest(figure, "InteractionTestData/Interactions/DoubleEllipse.xml", "InteractionTestData/ReferenceData/DoubleEllipse.pf"); } void PlanarSubdivisionInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarSubdivisionPolygon::New(); RunTest(figure, "InteractionTestData/Interactions/SubDivision.xml", "InteractionTestData/ReferenceData/SubDivision.pf"); } void PlanarFourPointAngleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarFourPointAngle::New(); RunTest(figure, "InteractionTestData/Interactions/Planar4PointAngle.xml", "InteractionTestData/ReferenceData/Planar4PointAngle.pf"); } void PlanarLineInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarLine::New(); RunTest(figure, "InteractionTestData/Interactions/Line.xml", "InteractionTestData/ReferenceData/Line.pf"); } void PlanarPolygonInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarPolygon::New(); RunTest(figure, "InteractionTestData/Interactions/Polygon.xml", "InteractionTestData/ReferenceData/Polygon.pf"); } void NonClosedPlanarPolygonInteractionCreate() { mitk::PlanarPolygon::Pointer figure; figure = mitk::PlanarPolygon::New(); figure->ClosedOff(); RunTest(figure.GetPointer(), "InteractionTestData/Interactions/Path.xml", "InteractionTestData/ReferenceData/Path.pf"); } void RectangleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarRectangle::New(); RunTest(figure, "InteractionTestData/Interactions/Rectangle.xml", "InteractionTestData/ReferenceData/Rectangle.pf"); } }; MITK_TEST_SUITE_REGISTRATION(mitkPlanarFigureInteraction) diff --git a/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp b/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp index de74b4938b..cabc312a40 100644 --- a/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp +++ b/Modules/PlanarFigure/Testing/mitkViewportRenderingTest.cpp @@ -1,153 +1,157 @@ /*=================================================================== 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. ===================================================================*/ // MITK #include "mitkTestingMacros.h" #include "mitkRenderingTestHelper.h" #include "mitkNodePredicateDataType.h" #include "mitkLevelWindowProperty.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkPlanarFigure.h" #include "mitkSurface.h" #include "mitkImage.h" // ITK #include // VTK #include +#include // stdlib #include int mitkViewportRenderingTest(int argc, char* argv[]) { // load all arguments into a datastorage, take last argument as reference rendering // setup a renderwindow of fixed size X*Y // render the datastorage // compare rendering to reference image MITK_TEST_BEGIN("mitkViewportRenderingTest") + /// \todo Fix leaks of vtkObjects. Bug 18095. + vtkDebugLeaks::SetExitError(0); + // enough parameters? if ( argc < 2 ) { MITK_TEST_OUTPUT( << "Usage: " << std::string(*argv) << " [file1 file2 ...] outputfile" ) MITK_TEST_OUTPUT( << "Will render a central axial slice of all given files into outputfile" ) exit( EXIT_FAILURE ); } double renderWindowWidth = atof(argv[1]); double renderWindowHeight = atof(argv[2]); double left = atof(argv[3]); double bottom = atof(argv[4]); double right = atof(argv[5]); double top = atof(argv[6]); std::string referenceFilename = argv[8+6]; argv += 6; // DO NOT attempt to read these as files, this just makes no sense argc -= 6; // DO NOT attempt to read these as files, this just makes no sense MITK_INFO << "Testing viewport "<GetSubset( mitk::TNodePredicateDataType::New()); for (ObjectsSet::const_iterator iterFigures = figures->begin(); iterFigures != figures->end(); ++iterFigures) { (*iterFigures)->SetProperty("planarfigure.default.line.color", mitk::ColorProperty::New( 1.0, 0.0, 0.0 ) ); // red (*iterFigures)->SetProperty("planarfigure.drawcontrolpoints", mitk::BoolProperty::New( false ) ); (*iterFigures)->SetProperty("planarfigure.drawname", mitk::BoolProperty::New( false ) ); (*iterFigures)->SetProperty("planarfigure.drawquantities", mitk::BoolProperty::New( true ) ); } ObjectsSet::ConstPointer surfaces = renderingHelper.GetDataStorage()->GetSubset( mitk::TNodePredicateDataType::New()); for (ObjectsSet::const_iterator iterSurfaces = surfaces->begin(); iterSurfaces != surfaces->end(); ++iterSurfaces) { (*iterSurfaces)->SetProperty("color", mitk::ColorProperty::New( 0.0, 1.0, 0.0 ) ); // green } ObjectsSet::ConstPointer images = renderingHelper.GetDataStorage()->GetSubset( mitk::TNodePredicateDataType::New()); for (ObjectsSet::const_iterator iterImages = images->begin(); iterImages != images->end(); ++iterImages) { (*iterImages)->SetProperty("levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(128.0, 256.0) ) ); // green int imageWidth = dynamic_cast((*iterImages)->GetData())->GetDimension(0); int imageHeight = dynamic_cast((*iterImages)->GetData())->GetDimension(1); MITK_INFO << "Image dimension "<InitializeViews( renderingHelper.GetDataStorage()->ComputeBoundingGeometry3D( images ) ); double vLeft = left / renderWindowWidth; double vBottom = bottom / renderWindowHeight; double vRight = right / renderWindowWidth; double vTop = top / renderWindowHeight; // THIS HERE IS THE ACTUAL TEST PART, all the rest is setup and decoration renderingHelper.GetVtkRenderer()->SetViewport( vLeft, vBottom, vRight, vTop ); renderingHelper.SetAutomaticallyCloseRenderWindow(true); // set to false for testing the test itself renderingHelper.Render(); //use this to generate a reference screenshot or save the file: bool generateReferenceScreenshot = false; if(generateReferenceScreenshot) { std::string tmpFilename = referenceFilename; std::string::size_type slashpos = referenceFilename.find_last_of('/'); tmpFilename = referenceFilename.substr(slashpos+1); tmpFilename = std::string("/tmp/") + tmpFilename; renderingHelper.SaveAsPNG( tmpFilename ); MITK_INFO << "*********************************"; MITK_INFO << "SAVE TO " << tmpFilename; MITK_INFO << "*********************************"; } //### Usage of vtkRegressionTestImage: //vtkRegressionTestImage( vtkRenderWindow ) //Set a vtkRenderWindow containing the desired scene. //vtkRegressionTestImage automatically searches in argc and argv[] //for a path a valid image with -V. If the test failed with the //first image (foo.png) check if there are images of the form //foo_N.png (where N=1,2,3...) and compare against them. int retVal = vtkRegressionTestImage( renderingHelper.GetVtkRenderWindow() ); //retVal meanings: (see VTK/Rendering/vtkTesting.h) //0 = test failed //1 = test passed //2 = test not run //3 = something with vtkInteraction MITK_TEST_CONDITION( retVal == 1, "VTK rendering result matches expectation" ); MITK_TEST_END(); } diff --git a/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp b/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp index 60ed8ea022..a658d39a3d 100644 --- a/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp +++ b/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp @@ -1,213 +1,218 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include +#include class mitkToolInteractionTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToolInteractionTestSuite); + + /// \todo Fix VTK memory leaks. Bug 18098. + vtkDebugLeaks::SetExitError(0); + /* ####### example ###### MITK_TEST(AddToolInteraction_4D_Test); #########################*/ MITK_TEST(AddToolInteractionTest); MITK_TEST(SubtractToolInteractionTest); MITK_TEST(PaintToolInteractionTest); MITK_TEST(WipeToolInteractionTest); MITK_TEST(RegionGrowingToolInteractionTest); MITK_TEST(CorrectionToolInteractionTest); MITK_TEST(EraseToolInteractionTest); MITK_TEST(FillToolInteractionTest); CPPUNIT_TEST_SUITE_END(); private: mitk::DataStorage::Pointer m_DataStorage; mitk::ToolManager::Pointer m_ToolManager; public: int GetToolIdByToolName (const std::string& toolName) { //find tool from toolname int numberOfTools = m_ToolManager->GetTools().size(); int toolId = 0; for(; toolId < numberOfTools; ++toolId) { mitk::Tool* currentTool = m_ToolManager->GetToolById(toolId); if(toolName.compare( currentTool->GetNameOfClass() ) == 0) { return toolId; } } return -1; } void RunTestWithParameters(const std::string& patientImagePath, const std::string& referenceSegmentationImage, const std::string& toolName, const std::string& interactionPattern, unsigned int timestep=0, const std::string& preSegmentationImagePath = std::string()) { //Create test helper to initialize all necessary objects for interaction mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionPattern)); //Use data storage of test helper m_DataStorage = interactionTestHelper.GetDataStorage().GetPointer(); //create ToolManager m_ToolManager = mitk::ToolManager::New(m_DataStorage); m_ToolManager->InitializeTools(); m_ToolManager->RegisterClient();//This is needed because there must be at least one registered. Otherwise tools can't be activated. //Load patient image mitk::Image::Pointer patientImage = mitk::IOUtil::LoadImage(GetTestDataFilePath(patientImagePath)); CPPUNIT_ASSERT(patientImage.IsNotNull()); mitk::DataNode::Pointer patientImageNode = mitk::DataNode::New(); patientImageNode->SetData(patientImage); //Activate tool to work with int toolID = GetToolIdByToolName(toolName); mitk::Tool* tool = m_ToolManager->GetToolById(toolID); CPPUNIT_ASSERT(tool != NULL); //Create empty segmentation working image mitk::DataNode::Pointer workingImageNode = mitk::DataNode::New(); const std::string organName = "test"; mitk::Color color;//actually it dosn't matter which color we are using color.SetRed(1); //but CreateEmptySegmentationNode expects a color parameter color.SetGreen(0); color.SetBlue(0); if(preSegmentationImagePath.empty()) { workingImageNode = tool->CreateEmptySegmentationNode(patientImage, organName, color); } else { mitk::Image::Pointer preSegmentation = mitk::IOUtil::LoadImage(GetTestDataFilePath(preSegmentationImagePath)); workingImageNode = tool->CreateSegmentationNode(preSegmentation, organName, color); } CPPUNIT_ASSERT(workingImageNode.IsNotNull()); CPPUNIT_ASSERT(workingImageNode->GetData() != NULL); //add images to datastorage interactionTestHelper.AddNodeToStorage(patientImageNode); interactionTestHelper.AddNodeToStorage(workingImageNode); //set reference and working image m_ToolManager->SetWorkingData(workingImageNode); m_ToolManager->SetReferenceData(patientImageNode); //set time step interactionTestHelper.SetTimeStep(timestep); //load interaction events m_ToolManager->ActivateTool(toolID); CPPUNIT_ASSERT(m_ToolManager->GetActiveTool() != NULL); //Start Interaction interactionTestHelper.PlaybackInteraction(); //load reference segmentation image mitk::Image::Pointer segmentationReferenceImage = mitk::IOUtil::LoadImage(GetTestDataFilePath(referenceSegmentationImage)); mitk::Image::Pointer currentSegmentationImage = mitk::Image::New(); currentSegmentationImage = dynamic_cast(workingImageNode->GetData()); //compare reference with interaction result MITK_ASSERT_EQUAL(segmentationReferenceImage, currentSegmentationImage, "Reference equals interaction result." ); } void setUp() { } void tearDown() { m_ToolManager->ActivateTool(-1); m_ToolManager = NULL; } void AddToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_AddTool.nrrd", "AddContourTool", "InteractionTestData/Interactions/SegmentationInteractor_AddTool.xml"); } void SubtractToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_SubtractTool.nrrd", "SubtractContourTool", "InteractionTestData/Interactions/SegmentationInteractor_SubtractTool.xml"); } void PaintToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_PaintTool.nrrd", "DrawPaintbrushTool", "InteractionTestData/Interactions/SegmentationInteractor_PaintTool.xml"); } void WipeToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_WipeTool.nrrd", "ErasePaintbrushTool", "InteractionTestData/Interactions/SegmentationInteractor_WipeTool.xml"); } void RegionGrowingToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_RegionGrowingTool.nrrd", "RegionGrowingTool", "InteractionTestData/Interactions/SegmentationInteractor_RegionGrowingTool.xml"); } void CorrectionToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_CorrectionTool.nrrd", "CorrectorTool2D", "InteractionTestData/Interactions/SegmentationInteractor_CorrectionTool.xml"); } void EraseToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_EraseTool.nrrd", "EraseRegionTool", "InteractionTestData/Interactions/SegmentationInteractor_EraseTool.xml", 0, "InteractionTestData/ReferenceData/SegmentationInteractor_AddTool.nrrd"); } void FillToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_FillTool.nrrd", "FillRegionTool", "InteractionTestData/Interactions/SegmentationInteractor_FillTool.xml", 0, "InteractionTestData/InputData/SegmentationInteractor_FillTool_input.nrrd"); } /*############ example ################### void AddToolInteraction_4D_Test() { RunTestWithParameters("US4DCyl.nrrd", "Segmentation/ReferenceSegmentations/AddTool_4D.nrrd", "AddContourTool", "Segmentation/InteractionPatterns/AddTool_4D.xml", 1); } #########################################*/ }; MITK_TEST_SUITE_REGISTRATION(mitkToolInteraction) diff --git a/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp index 280234f504..3f8fccd63a 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp @@ -1,88 +1,94 @@ /*=================================================================== 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 #include #include #include +#include + class mitkComputeContourSetNormalsFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkComputeContourSetNormalsFilterTestSuite); + + /// \todo Fix leaks of vtkObjects. Bug 18096. + vtkDebugLeaks::SetExitError(0); + MITK_TEST(TestComputeNormals); MITK_TEST(TestComputeNormalsWithHole); CPPUNIT_TEST_SUITE_END(); private: mitk::ComputeContourSetNormalsFilter::Pointer m_ContourNormalsFilter; public: void setUp() { m_ContourNormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ReduceContourSetFilter", m_ContourNormalsFilter.IsNotNull()); } // Compute the normals for a regular contour void TestComputeNormals() { mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); m_ContourNormalsFilter->SetInput(contour); m_ContourNormalsFilter->Update(); // Get the computed normals (basically lines) mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface(); // Get the actual surface object which has the contours stored as normals internally mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput(); mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithNormals.vtk")); mitk::Surface::Pointer referenceNormals = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourNormals.vtk")); CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(*(contourWithNormals->GetVtkPolyData()), *(referenceContour->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(*(normals->GetVtkPolyData()), *(referenceNormals->GetVtkPolyData()), 0.000001, true)); } // Reduce contours with Douglas Peucker void TestComputeNormalsWithHole() { mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd")); mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/ComputeNormals/ContourWithHoles.vtk")); m_ContourNormalsFilter->SetInput(contour); m_ContourNormalsFilter->SetSegmentationBinaryImage(segmentationImage); m_ContourNormalsFilter->Update(); mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput(); mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface(); mitk::Surface::Pointer contourReference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithHolesWithNormals.vtk")); mitk::Surface::Pointer normalsReference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/NormalsWithHoles.vtk")); CPPUNIT_ASSERT_MESSAGE("Error computing normals", mitk::Equal(*(normals->GetVtkPolyData()), *(normalsReference->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Error computing normals", contourWithNormals->GetVtkPolyData()->GetCellData()->GetNormals()->GetNumberOfTuples() == contourReference->GetVtkPolyData()->GetNumberOfPoints()); } }; MITK_TEST_SUITE_REGISTRATION(mitkComputeContourSetNormalsFilter) diff --git a/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp index fd7bef3d2c..45a2b0a1b6 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp @@ -1,134 +1,137 @@ /*=================================================================== 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 #include +#include + class mitkCreateDistanceImageFromSurfaceFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkCreateDistanceImageFromSurfaceFilterTestSuite); + vtkDebugLeaks::SetExitError(0); MITK_TEST(TestCreateDistanceImageForLiver); MITK_TEST(TestCreateDistanceImageForTube); CPPUNIT_TEST_SUITE_END(); private: std::vector contourList; public: void setUp() { } template void GetImageBase(itk::Image* input, itk::ImageBase<3>::Pointer& result) { result->Graft(input); } // Interpolate the shape of a liver void TestCreateDistanceImageForLiver() { // That's the number of available liver contours in MITK-Data unsigned int NUMBER_OF_LIVER_CONTOURS = 18; for (unsigned int i = 0; i <= NUMBER_OF_LIVER_CONTOURS; ++i) { std::stringstream s; s << "SurfaceInterpolation/InterpolateLiver/LiverContourWithNormals_"; s << i; s << ".vtk"; mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath(s.str())); contourList.push_back(contour); } mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd")); mitk::ComputeContourSetNormalsFilter::Pointer m_NormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); mitk::CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter = mitk::CreateDistanceImageFromSurfaceFilter::New(); itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New(); AccessFixedDimensionByItk_1( segmentationImage, GetImageBase, 3, itkImage ); m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() ); for (unsigned int j = 0; j < contourList.size(); j++) { m_NormalsFilter->SetInput(j, contourList.at(j)); m_InterpolateSurfaceFilter->SetInput(j, m_NormalsFilter->GetOutput(j)); } m_InterpolateSurfaceFilter->Update(); mitk::Image::Pointer liverDistanceImage = m_InterpolateSurfaceFilter->GetOutput(); CPPUNIT_ASSERT(liverDistanceImage.IsNotNull()); mitk::Image::Pointer liverDistanceImageReference = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverDistanceImage.nrrd")); CPPUNIT_ASSERT_MESSAGE("LiverDistanceImages are not equal!", mitk::Equal(*(liverDistanceImageReference), *(liverDistanceImage), 0.0001, true)); } void TestCreateDistanceImageForTube() { // That's the number of available contours with holes in MITK-Data unsigned int NUMBER_OF_TUBE_CONTOURS = 5; for (unsigned int i = 0; i < NUMBER_OF_TUBE_CONTOURS; ++i) { std::stringstream s; s << "SurfaceInterpolation/InterpolateWithHoles/ContourWithHoles_"; s << i; s << ".vtk"; mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath(s.str())); contourList.push_back(contour); } mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/SegmentationWithHoles.nrrd")); mitk::ComputeContourSetNormalsFilter::Pointer m_NormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); mitk::CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter = mitk::CreateDistanceImageFromSurfaceFilter::New(); m_NormalsFilter->SetSegmentationBinaryImage(segmentationImage); itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New(); AccessFixedDimensionByItk_1( segmentationImage, GetImageBase, 3, itkImage ); m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() ); for (unsigned int j = 0; j < contourList.size(); j++) { m_NormalsFilter->SetInput(j, contourList.at(j)); m_InterpolateSurfaceFilter->SetInput(j, m_NormalsFilter->GetOutput(j)); } m_InterpolateSurfaceFilter->Update(); mitk::Image::Pointer holeDistanceImage = m_InterpolateSurfaceFilter->GetOutput(); CPPUNIT_ASSERT(holeDistanceImage.IsNotNull()); mitk::Image::Pointer holesDistanceImageReference = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/Reference/HolesDistanceImage.nrrd")); CPPUNIT_ASSERT_MESSAGE("HolesDistanceImages are not equal!", mitk::Equal(*(holesDistanceImageReference), *(holeDistanceImage), 0.0001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkCreateDistanceImageFromSurfaceFilter) diff --git a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp index 2c1e6d4f6e..0fed5cca44 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp @@ -1,335 +1,344 @@ /*=================================================================== 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 class mitkSurfaceInterpolationControllerTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSurfaceInterpolationControllerTestSuite); MITK_TEST(TestSingleton); MITK_TEST(TestSetCurrentInterpolationSession); MITK_TEST(TestRemoveAllInterpolationSessions); MITK_TEST(TestRemoveInterpolationSession); MITK_TEST(TestOnSegmentationDeleted); + + /// \todo Workaround for memory leak in TestAddNewContour. Bug 18096. + vtkDebugLeaks::SetExitError(0); + MITK_TEST(TestAddNewContour); CPPUNIT_TEST_SUITE_END(); private: mitk::SurfaceInterpolationController::Pointer m_Controller; public: mitk::Image::Pointer createImage(unsigned int *dimensions) { mitk::Image::Pointer newImage = mitk::Image::New(); mitk::PixelType p_type = mitk::MakeScalarPixelType(); newImage->Initialize(p_type, 3, dimensions); return newImage; } mitk::PlaneGeometry::Pointer createPlaneForContour(mitk::BaseGeometry* geo, vtkPolyData* contour, mitk::PlaneGeometry::PlaneOrientation orientation) { mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); mitk::Point3D p = contour->GetPoint(0); geo->WorldToIndex(p,p); unsigned int sliceIndex; if (orientation == mitk::PlaneGeometry::Axial) { sliceIndex = p[2]; } else if (orientation == mitk::PlaneGeometry::Sagittal) { sliceIndex = p[0]; } else { sliceIndex = p[1]; } plane->InitializeStandardPlane(geo, orientation, sliceIndex, true, false); mitk::Point3D origin = plane->GetOrigin(); mitk::Vector3D normal; normal = plane->GetNormal(); normal.Normalize(); origin += normal * 0.5; plane->SetOrigin(origin); return plane; } void setUp() { m_Controller = mitk::SurfaceInterpolationController::GetInstance(); vtkSmartPointer polygonSource = vtkSmartPointer::New(); polygonSource->SetRadius(100); polygonSource->SetNumberOfSides(7); polygonSource->Update(); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(polygonSource->GetOutput()); } void TestSingleton() { mitk::SurfaceInterpolationController::Pointer controller2 = mitk::SurfaceInterpolationController::GetInstance(); CPPUNIT_ASSERT_MESSAGE("SurfaceInterpolationController pointers are not equal!", m_Controller.GetPointer() == controller2.GetPointer()); } void TestSetCurrentInterpolationSession() { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); unsigned int dimensions2[] = {20, 10, 30}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); // Test 1 m_Controller->SetCurrentInterpolationSession(segmentation_1); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); // Test 2 m_Controller->SetCurrentInterpolationSession(segmentation_2); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_2->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test 3 m_Controller->SetCurrentInterpolationSession(segmentation_1); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test 4 m_Controller->SetCurrentInterpolationSession(segmentation_1); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test 5 m_Controller->SetCurrentInterpolationSession(0); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().IsNull()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); } void TestRemoveAllInterpolationSessions() { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); unsigned int dimensions2[] = {20, 10, 30}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); // Test 1 m_Controller->SetCurrentInterpolationSession(segmentation_1); m_Controller->SetCurrentInterpolationSession(segmentation_2); m_Controller->RemoveAllInterpolationSessions(); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0); } void TestRemoveInterpolationSession() { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); unsigned int dimensions2[] = {20, 10, 30}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); // Test 1 m_Controller->SetCurrentInterpolationSession(segmentation_1); m_Controller->SetCurrentInterpolationSession(segmentation_2); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test current segmentation should not be null if another one was removed m_Controller->RemoveInterpolationSession(segmentation_1); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Current segmentation is null after another one was removed", m_Controller->GetCurrentSegmentation().IsNotNull()); m_Controller->SetCurrentInterpolationSession(segmentation_1); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test current segmentation should not be null if another one was removed m_Controller->RemoveInterpolationSession(segmentation_1); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); CPPUNIT_ASSERT_MESSAGE("Current segmentation is not null after session was removed", m_Controller->GetCurrentSegmentation().IsNull()); } void TestOnSegmentationDeleted() { { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); m_Controller->SetCurrentInterpolationSession(segmentation_1); } CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0); } void TestAddNewContour() { // Create segmentation image unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); mitk::BaseGeometry* geo_1 = segmentation_1->GetGeometry(); m_Controller->SetCurrentInterpolationSession(segmentation_1); // Create some contours vtkSmartPointer p_source = vtkSmartPointer::New(); p_source->SetNumberOfSides(20); p_source->SetCenter(4.0,4.0,4.0); p_source->SetRadius(4); p_source->SetNormal(0,1,0); p_source->Update(); vtkPolyData* poly_1 = p_source->GetOutput(); mitk::Surface::Pointer surf_1 = mitk::Surface::New(); surf_1->SetVtkPolyData(poly_1); vtkSmartPointer p_source_2 = vtkSmartPointer::New(); p_source_2->SetNumberOfSides(80); p_source_2->SetCenter(4.0,4.0,4.0); p_source_2->SetRadius(4); p_source_2->SetNormal(1, 0, 0); p_source_2->Update(); vtkPolyData* poly_2 = p_source_2->GetOutput(); mitk::Surface::Pointer surf_2 = mitk::Surface::New(); surf_2->SetVtkPolyData(poly_2); vtkSmartPointer p_source_3 = vtkSmartPointer::New(); p_source_3->SetNumberOfSides(10); p_source_3->SetCenter(4.0,4.0,3.0); p_source_3->SetRadius(4); p_source_3->SetNormal(0,0,1); p_source_3->Update(); vtkPolyData* poly_3 = p_source_3->GetOutput(); mitk::Surface::Pointer surf_3 = mitk::Surface::New(); surf_3->SetVtkPolyData(poly_3); // Create planes for contours mitk::PlaneGeometry::Pointer plane_1 = createPlaneForContour(geo_1, poly_1, mitk::PlaneGeometry::Frontal); mitk::PlaneGeometry::Pointer plane_2 = createPlaneForContour(geo_1, poly_2, mitk::PlaneGeometry::Sagittal); mitk::PlaneGeometry::Pointer plane_3 = createPlaneForContour(geo_1, poly_3, mitk::PlaneGeometry::Axial); // Add contours m_Controller->AddNewContour(surf_1, plane_1); m_Controller->AddNewContour(surf_2, plane_2); m_Controller->AddNewContour(surf_3, plane_3); // Check if all contours are there mitk::PlaneGeometry::Pointer plane_1_clone = plane_1->Clone(); mitk::PlaneGeometry::Pointer plane_2_clone = plane_2->Clone(); mitk::PlaneGeometry::Pointer plane_3_clone = plane_3->Clone(); mitk::Surface* contour_1 = const_cast(m_Controller->GetContour(plane_1_clone)); mitk::Surface* contour_2 = const_cast(m_Controller->GetContour(plane_2_clone)); mitk::Surface* contour_3 = const_cast(m_Controller->GetContour(plane_3_clone)); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_1->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_2->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_3->GetVtkPolyData()), 0.000001, true)); // Create another segmentation image unsigned int dimensions2[] = {20, 20, 20}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); mitk::BaseGeometry* geo_2 = segmentation_2->GetGeometry(); m_Controller->SetCurrentInterpolationSession(segmentation_2); // Create some contours - p_source->SetNumberOfSides(8); - p_source->SetCenter(10.0,10.0,10.0); - p_source->SetRadius(5); - p_source->SetNormal(0,1,0); - p_source->Update(); - vtkPolyData* poly_4 = p_source->GetOutput(); + vtkSmartPointer p_source_4 = vtkSmartPointer::New(); + p_source_4->SetNumberOfSides(8); + p_source_4->SetCenter(10.0,10.0,10.0); + p_source_4->SetRadius(5); + p_source_4->SetNormal(0,1,0); + p_source_4->Update(); + vtkPolyData* poly_4 = p_source_4->GetOutput(); mitk::Surface::Pointer surf_4 = mitk::Surface::New(); surf_4->SetVtkPolyData(poly_4); - p_source_2->SetNumberOfSides(16); - p_source_2->SetCenter(3.0,10.0,10.0); - p_source_2->SetRadius(8); - p_source_2->SetNormal(1, 0, 0); - p_source_2->Update(); - vtkPolyData* poly_5 = p_source_2->GetOutput(); + vtkSmartPointer p_source_5 = vtkSmartPointer::New(); + p_source_5->SetNumberOfSides(16); + p_source_5->SetCenter(3.0,10.0,10.0); + p_source_5->SetRadius(8); + p_source_5->SetNormal(1, 0, 0); + p_source_5->Update(); + vtkPolyData* poly_5 = p_source_5->GetOutput(); mitk::Surface::Pointer surf_5 = mitk::Surface::New(); surf_5->SetVtkPolyData(poly_5); - p_source_3->SetNumberOfSides(100); - p_source_3->SetCenter(10.0,10.0,3.0); - p_source_3->SetRadius(5); - p_source_3->SetNormal(0,0,1); - p_source_3->Update(); - vtkPolyData* poly_6 = p_source_3->GetOutput(); + vtkSmartPointer p_source_6 = vtkSmartPointer::New(); + p_source_6->SetNumberOfSides(100); + p_source_6->SetCenter(10.0,10.0,3.0); + p_source_6->SetRadius(5); + p_source_6->SetNormal(0,0,1); + p_source_6->Update(); + vtkPolyData* poly_6 = p_source_6->GetOutput(); mitk::Surface::Pointer surf_6 = mitk::Surface::New(); surf_6->SetVtkPolyData(poly_6); // Create planes for contours mitk::PlaneGeometry::Pointer plane_4 = createPlaneForContour(geo_2, poly_4, mitk::PlaneGeometry::Frontal); mitk::PlaneGeometry::Pointer plane_5 = createPlaneForContour(geo_2, poly_5, mitk::PlaneGeometry::Sagittal); mitk::PlaneGeometry::Pointer plane_6 = createPlaneForContour(geo_2, poly_6, mitk::PlaneGeometry::Axial); // Add contours m_Controller->AddNewContour(surf_4, plane_4); m_Controller->AddNewContour(surf_5, plane_5); m_Controller->AddNewContour(surf_6, plane_6); // Check if all contours are there mitk::PlaneGeometry::Pointer plane_4_clone = plane_4->Clone(); mitk::PlaneGeometry::Pointer plane_5_clone = plane_5->Clone(); mitk::PlaneGeometry::Pointer plane_6_clone = plane_6->Clone(); mitk::Surface* contour_4 = const_cast(m_Controller->GetContour(plane_4_clone)); mitk::Surface* contour_5 = const_cast(m_Controller->GetContour(plane_5_clone)); mitk::Surface* contour_6 = const_cast(m_Controller->GetContour(plane_6_clone)); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_4->GetVtkPolyData()), *(contour_4->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_5->GetVtkPolyData()), *(contour_5->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_6->GetVtkPolyData()), *(contour_6->GetVtkPolyData()), 0.000001, true)); // Modify some contours - p_source_2->SetNumberOfSides(200); - p_source_2->SetCenter(3.0,10.0,10.0); - p_source_2->SetRadius(5); - p_source_2->SetNormal(1, 0, 0); - p_source_2->Update(); - vtkPolyData* poly_7 = p_source_2->GetOutput(); + vtkSmartPointer p_source_7 = vtkSmartPointer::New(); + p_source_7->SetNumberOfSides(200); + p_source_7->SetCenter(3.0,10.0,10.0); + p_source_7->SetRadius(5); + p_source_7->SetNormal(1, 0, 0); + p_source_7->Update(); + vtkPolyData* poly_7 = p_source_7->GetOutput(); mitk::Surface::Pointer surf_7 = mitk::Surface::New(); surf_7->SetVtkPolyData(poly_7); m_Controller->AddNewContour(surf_7, plane_5); mitk::Surface* contour_7 = const_cast(m_Controller->GetContour(plane_5_clone)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_7->GetVtkPolyData()), *(contour_7->GetVtkPolyData()), 0.000001, true)); // Change session and test if all contours are available m_Controller->SetCurrentInterpolationSession(segmentation_1); mitk::Surface* contour_8 = const_cast(m_Controller->GetContour(plane_1_clone)); mitk::Surface* contour_9 = const_cast(m_Controller->GetContour(plane_2_clone)); mitk::Surface* contour_10 = const_cast(m_Controller->GetContour(plane_3_clone)); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_8->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_9->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_10->GetVtkPolyData()), 0.000001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkSurfaceInterpolationController) diff --git a/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp b/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp index 487bbf7af5..162bca4c8b 100644 --- a/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp +++ b/Modules/SurfaceInterpolation/mitkReduceContourSetFilter.cpp @@ -1,502 +1,502 @@ /*=================================================================== 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 "mitkReduceContourSetFilter.h" mitk::ReduceContourSetFilter::ReduceContourSetFilter() { m_MaxSegmentLenght = 0; m_StepSize = 10; m_Tolerance = -1; m_ReductionType = DOUGLAS_PEUCKER; m_MaxSpacing = -1; m_MinSpacing = -1; this->m_UseProgressBar = false; this->m_ProgressStepSize = 1; m_NumberOfPointsAfterReduction = 0; mitk::Surface::Pointer output = mitk::Surface::New(); this->SetNthOutput(0, output.GetPointer()); } mitk::ReduceContourSetFilter::~ReduceContourSetFilter() { } void mitk::ReduceContourSetFilter::GenerateData() { unsigned int numberOfInputs = this->GetNumberOfIndexedInputs(); unsigned int numberOfOutputs (0); vtkSmartPointer newPolyData; vtkSmartPointer newPolygons; vtkSmartPointer newPoints; //For the purpose of evaluation // unsigned int numberOfPointsBefore (0); m_NumberOfPointsAfterReduction=0; for(unsigned int i = 0; i < numberOfInputs; i++) { mitk::Surface* currentSurface = const_cast( this->GetInput(i) ); vtkSmartPointer polyData = currentSurface->GetVtkPolyData(); - newPolyData = vtkPolyData::New(); - newPolygons = vtkCellArray::New(); - newPoints = vtkPoints::New(); + newPolyData = vtkSmartPointer::New(); + newPolygons = vtkSmartPointer::New(); + newPoints = vtkSmartPointer::New(); vtkSmartPointer existingPolys = polyData->GetPolys(); vtkSmartPointer existingPoints = polyData->GetPoints(); existingPolys->InitTraversal(); vtkIdType* cell (NULL); vtkIdType cellSize (0); for( existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);) { bool incorporatePolygon = this->CheckForIntersection(cell,cellSize,existingPoints, /*numberOfIntersections, intersectionPoints, */i); if ( !incorporatePolygon ) continue; vtkSmartPointer newPolygon = vtkSmartPointer::New(); if(m_ReductionType == NTH_POINT) { this->ReduceNumberOfPointsByNthPoint(cellSize, cell, existingPoints, newPolygon, newPoints); if (newPolygon->GetPointIds()->GetNumberOfIds() != 0) { newPolygons->InsertNextCell(newPolygon); } } else if (m_ReductionType == DOUGLAS_PEUCKER) { this->ReduceNumberOfPointsByDouglasPeucker(cellSize, cell, existingPoints, newPolygon, newPoints); if (newPolygon->GetPointIds()->GetNumberOfIds() > 3) { newPolygons->InsertNextCell(newPolygon); } } //Again for evaluation // numberOfPointsBefore += cellSize; m_NumberOfPointsAfterReduction += newPolygon->GetPointIds()->GetNumberOfIds(); } if (newPolygons->GetNumberOfCells() != 0) { newPolyData->SetPolys(newPolygons); newPolyData->SetPoints(newPoints); newPolyData->BuildLinks(); this->SetNumberOfIndexedOutputs(numberOfOutputs + 1); mitk::Surface::Pointer surface = mitk::Surface::New(); this->SetNthOutput(numberOfOutputs, surface.GetPointer()); surface->SetVtkPolyData(newPolyData); numberOfOutputs++; } } // MITK_INFO<<"Points before: "<SetNumberOfIndexedOutputs(numberOfOutputs); //Setting progressbar if (this->m_UseProgressBar) mitk::ProgressBar::GetInstance()->Progress(this->m_ProgressStepSize); } void mitk::ReduceContourSetFilter::ReduceNumberOfPointsByNthPoint (vtkIdType cellSize, vtkIdType* cell, vtkPoints* points, vtkPolygon* reducedPolygon, vtkPoints* reducedPoints) { unsigned int newNumberOfPoints (0); unsigned int mod = cellSize%m_StepSize; if(mod == 0) { newNumberOfPoints = cellSize/m_StepSize; } else { newNumberOfPoints = ( (cellSize-mod)/m_StepSize )+1; } if (newNumberOfPoints <= 3) { return; } reducedPolygon->GetPointIds()->SetNumberOfIds(newNumberOfPoints); reducedPolygon->GetPoints()->SetNumberOfPoints(newNumberOfPoints); for (vtkIdType i = 0; i < cellSize; i++) { if (i%m_StepSize == 0) { double point[3]; points->GetPoint(cell[i], point); vtkIdType id = reducedPoints->InsertNextPoint(point); reducedPolygon->GetPointIds()->SetId(i/m_StepSize, id); } } vtkIdType id = cell[0]; double point[3]; points->GetPoint(id, point); id = reducedPoints->InsertNextPoint(point); reducedPolygon->GetPointIds()->SetId(newNumberOfPoints-1, id); } void mitk::ReduceContourSetFilter::ReduceNumberOfPointsByDouglasPeucker(vtkIdType cellSize, vtkIdType* cell, vtkPoints* points, vtkPolygon* reducedPolygon, vtkPoints* reducedPoints) { //If the cell is too small to obtain a reduced polygon with the given stepsize return if (cellSize <= static_cast(m_StepSize*3))return; /* What we do now is (see the Douglas Peucker Algorithm): 1. Divide the current contour in two line segments (start - middle; middle - end), put them into the stack 2. Fetch first line segment and create the following vectors: - v1 = (start;end) - v2 = (start;currentPoint) -> for each point of the current line segment! 3. Calculate the distance from the currentPoint to v1: a. Determine the length of the orthogonal projection of v2 to v1 by: l = v2 * (normalized v1) b. There a three possibilities for the distance then: d = sqrt(lenght(v2)^2 - l^2) if l > 0 and l < length(v1) d = lenght(v2-v1) if l > 0 and l > lenght(v1) d = length(v2) if l < 0 because v2 is then pointing in a different direction than v1 4. Memorize the point with the biggest distance and create two new line segments with it at the end of the iteration and put it into the stack 5. If the distance value D <= m_Tolerance, then add the start and end index and the corresponding points to the reduced ones */ //First of all set tolerance if none is specified if(m_Tolerance < 0) { if(m_MaxSpacing > 0) { m_Tolerance = m_MinSpacing; } else { m_Tolerance = 1.5; } } std::stack lineSegments; //1. Divide in line segments LineSegment ls2; ls2.StartIndex = cell[cellSize/2]; ls2.EndIndex = cell[cellSize-1]; lineSegments.push(ls2); LineSegment ls1; ls1.StartIndex = cell[0]; ls1.EndIndex = cell[cellSize/2]; lineSegments.push(ls1); LineSegment currentSegment; double v1[3]; double v2[3]; double tempV[3]; double lenghtV1; double currentMaxDistance (0); vtkIdType currentMaxDistanceIndex (0); double l; double d; vtkIdType pointId (0); //Add the start index to the reduced points. From now on just the end indices will be added pointId = reducedPoints->InsertNextPoint(points->GetPoint(cell[0])); reducedPolygon->GetPointIds()->InsertNextId(pointId); while (!lineSegments.empty()) { currentSegment = lineSegments.top(); lineSegments.pop(); //2. Create vectors points->GetPoint(currentSegment.EndIndex, tempV); points->GetPoint(currentSegment.StartIndex, v1); v1[0] = tempV[0]-v1[0]; v1[1] = tempV[1]-v1[1]; v1[2] = tempV[2]-v1[2]; lenghtV1 = vtkMath::Norm(v1); vtkMath::Normalize(v1); int range = currentSegment.EndIndex - currentSegment.StartIndex; for (int i = 1; i < abs(range); ++i) { points->GetPoint(currentSegment.StartIndex+i, tempV); points->GetPoint(currentSegment.StartIndex, v2); v2[0] = tempV[0]-v2[0]; v2[1] = tempV[1]-v2[1]; v2[2] = tempV[2]-v2[2]; //3. Calculate the distance l = vtkMath::Dot(v2, v1); d = vtkMath::Norm(v2); if (l > 0 && l < lenghtV1) { d = sqrt((d*d-l*l)); } else if (l > 0 && l > lenghtV1) { tempV[0] = lenghtV1*v1[0] - v2[0]; tempV[1] = lenghtV1*v1[1] - v2[1]; tempV[2] = lenghtV1*v1[2] - v2[2]; d = vtkMath::Norm(tempV); } //4. Memorize maximum distance if (d > currentMaxDistance) { currentMaxDistance = d; currentMaxDistanceIndex = currentSegment.StartIndex+i; } } //4. & 5. if (currentMaxDistance <= m_Tolerance) { //double temp[3]; int segmentLenght = currentSegment.EndIndex - currentSegment.StartIndex; if (segmentLenght > (int)m_MaxSegmentLenght) { m_MaxSegmentLenght = (unsigned int)segmentLenght; } // MITK_INFO<<"Lenght: "< 25) { unsigned int newLenght(segmentLenght); while (newLenght > 25) { newLenght = newLenght*0.5; } unsigned int divisions = abs(segmentLenght)/newLenght; // MITK_INFO<<"Divisions: "<InsertNextPoint(points->GetPoint(currentSegment.StartIndex + newLenght*i)); reducedPolygon->GetPointIds()->InsertNextId(pointId); } } // MITK_INFO<<"Inserting END: "<InsertNextPoint(points->GetPoint(currentSegment.EndIndex)); reducedPolygon->GetPointIds()->InsertNextId(pointId); } else { ls2.StartIndex = currentMaxDistanceIndex; ls2.EndIndex = currentSegment.EndIndex; lineSegments.push(ls2); ls1.StartIndex = currentSegment.StartIndex; ls1.EndIndex = currentMaxDistanceIndex; lineSegments.push(ls1); } currentMaxDistance = 0; } } bool mitk::ReduceContourSetFilter::CheckForIntersection (vtkIdType* currentCell, vtkIdType currentCellSize, vtkPoints* currentPoints,/* vtkIdType numberOfIntersections, vtkIdType* intersectionPoints,*/ unsigned int currentInputIndex) { /* If we check the current cell for intersections then we have to consider three possibilies: 1. There is another cell among all the other input surfaces which intersects the current polygon: - That means we have to save the intersection points because these points should not be eliminated 2. There current polygon exists just because of an intersection of another polygon with the current plane defined by the current polygon - That means the current polygon should not be incorporated and all of its points should be eliminated 3. There is no intersection - That mean we can just reduce the current polygons points without considering any intersections */ for (unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++) { //Don't check for intersection with the polygon itself if (i == currentInputIndex) continue; //Get the next polydata to check for intersection vtkSmartPointer poly = const_cast( this->GetInput(i) )->GetVtkPolyData(); vtkSmartPointer polygonArray = poly->GetPolys(); polygonArray->InitTraversal(); vtkIdType anotherInputPolygonSize (0); vtkIdType* anotherInputPolygonIDs(NULL); /* The procedure is: - Create the equation of the plane, defined by the points of next input - Calculate the distance of each point of the current polygon to the plane - If the maximum distance is not bigger than 1.5 of the maximum spacing AND the minimal distance is not bigger than 0.5 of the minimum spacing then the current contour is an intersection contour */ for( polygonArray->InitTraversal(); polygonArray->GetNextCell(anotherInputPolygonSize, anotherInputPolygonIDs);) { //Choosing three plane points to calculate the plane vectors double p1[3]; double p2[3]; double p3[3]; //The plane vectors double v1[3]; double v2[3] = { 0 }; //The plane normal double normal[3]; //Create first Vector poly->GetPoint(anotherInputPolygonIDs[0], p1); poly->GetPoint(anotherInputPolygonIDs[1], p2); v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; //Find 3rd point for 2nd vector (The angle between the two plane vectors should be bigger than 30 degrees) double maxDistance (0); double minDistance (10000); for (vtkIdType j = 2; j < anotherInputPolygonSize; j++) { poly->GetPoint(anotherInputPolygonIDs[j], p3); v2[0] = p3[0]-p1[0]; v2[1] = p3[1]-p1[1]; v2[2] = p3[2]-p1[2]; //Calculate the angle between the two vector for the current point double dotV1V2 = vtkMath::Dot(v1,v2); double absV1 = sqrt(vtkMath::Dot(v1,v1)); double absV2 = sqrt(vtkMath::Dot(v2,v2)); double cosV1V2 = dotV1V2/(absV1*absV2); double arccos = acos(cosV1V2); double degree = vtkMath::DegreesFromRadians(arccos); //If angle is bigger than 30 degrees break if (degree > 30) break; }//for (to find 3rd point) //Calculate normal of the plane by taking the cross product of the two vectors vtkMath::Cross(v1,v2,normal); vtkMath::Normalize(normal); //Determine position of the plane double lambda = vtkMath::Dot(normal, p1); /* Calculate the distance to the plane for each point of the current polygon If the distance is zero then save the currentPoint as intersection point */ for (vtkIdType k = 0; k < currentCellSize; k++) { double currentPoint[3]; currentPoints->GetPoint(currentCell[k], currentPoint); double tempPoint[3]; tempPoint[0] = normal[0]*currentPoint[0]; tempPoint[1] = normal[1]*currentPoint[1]; tempPoint[2] = normal[2]*currentPoint[2]; double temp = tempPoint[0]+tempPoint[1]+tempPoint[2]-lambda; double distance = fabs(temp); if (distance > maxDistance) { maxDistance = distance; } if (distance < minDistance) { minDistance = distance; } }//for (to calculate distance and intersections with currentPolygon) if (maxDistance < 1.5*m_MaxSpacing && minDistance < 0.5*m_MinSpacing) { return false; } //Because we are considering the plane defined by the acual input polygon only one iteration is sufficient //We do not need to consider each cell of the plane break; }//for (to traverse through all cells of actualInputPolyData) }//for (to iterate through all inputs) return true; } void mitk::ReduceContourSetFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); } void mitk::ReduceContourSetFilter::Reset() { for (unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++) { this->PopBackInput(); } this->SetNumberOfIndexedInputs(0); this->SetNumberOfIndexedOutputs(0); mitk::Surface::Pointer output = mitk::Surface::New(); this->SetNthOutput(0, output.GetPointer()); m_NumberOfPointsAfterReduction = 0; } void mitk::ReduceContourSetFilter::SetUseProgressBar(bool status) { this->m_UseProgressBar = status; } void mitk::ReduceContourSetFilter::SetProgressStepSize(unsigned int stepSize) { this->m_ProgressStepSize = stepSize; } diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp index 420dff55aa..a6e05165b8 100644 --- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp +++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp @@ -1,366 +1,367 @@ /*=================================================================== 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 "mitkSurfaceInterpolationController.h" #include "mitkMemoryUtilities.h" #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include "mitkImageToSurfaceFilter.h" mitk::SurfaceInterpolationController::SurfaceInterpolationController() :m_SelectedSegmentation(0) { m_ReduceFilter = ReduceContourSetFilter::New(); m_NormalsFilter = ComputeContourSetNormalsFilter::New(); m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New(); m_ReduceFilter->SetUseProgressBar(false); m_NormalsFilter->SetUseProgressBar(false); m_InterpolateSurfaceFilter->SetUseProgressBar(false); m_Contours = Surface::New(); m_PolyData = vtkSmartPointer::New(); - m_PolyData->SetPoints(vtkPoints::New()); + vtkSmartPointer points = vtkSmartPointer::New(); + m_PolyData->SetPoints(points); m_InterpolationResult = 0; m_CurrentNumberOfReducedContours = 0; } mitk::SurfaceInterpolationController::~SurfaceInterpolationController() { //Removing all observers std::map::iterator dataIter = m_SegmentationObserverTags.begin(); for (; dataIter != m_SegmentationObserverTags.end(); ++dataIter ) { (*dataIter).first->RemoveObserver( (*dataIter).second ); } m_SegmentationObserverTags.clear(); } mitk::SurfaceInterpolationController* mitk::SurfaceInterpolationController::GetInstance() { - static mitk::SurfaceInterpolationController* m_Instance; + static mitk::SurfaceInterpolationController::Pointer m_Instance; - if ( m_Instance == 0) + if ( m_Instance.IsNull() ) { - m_Instance = new SurfaceInterpolationController(); + m_Instance = SurfaceInterpolationController::New(); } return m_Instance; } void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour, PlaneGeometry::Pointer plane) { ContourPositionPair pair; pair.contour = newContour; pair.plane = plane; this->AddToInterpolationPipeline(pair); this->Modified(); } void mitk::SurfaceInterpolationController::AddNewContours(ContourPositionPairList newContours) { for (unsigned int i = 0; i < newContours.size(); ++i) { this->AddToInterpolationPipeline(newContours.at(i)); } this->Modified(); } void mitk::SurfaceInterpolationController::AddToInterpolationPipeline(ContourPositionPair pair) { int pos (-1); ContourPositionPairList currentContourList = m_ListOfInterpolationSessions[m_SelectedSegmentation]; mitk::PlaneGeometry* plane = pair.plane; mitk::Surface* newContour = pair.contour; for (unsigned int i = 0; i < currentContourList.size(); i++) { mitk::PlaneGeometry::Pointer planeFromList = currentContourList.at(i).plane; if ( mitk::Equal(*plane, *planeFromList, mitk::eps, false) ) { pos = i; break; } } //Don't save a new empty contour if (pos == -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0) { m_ReduceFilter->SetInput(m_ListOfInterpolationSessions[m_SelectedSegmentation].size(), newContour); m_ListOfInterpolationSessions[m_SelectedSegmentation].push_back(pair); } else if (pos != -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0) { m_ListOfInterpolationSessions[m_SelectedSegmentation].at(pos) = pair; m_ReduceFilter->SetInput(pos, newContour); } m_ReduceFilter->Update(); m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs(); for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++) { m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i)); m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i)); } } const mitk::Surface* mitk::SurfaceInterpolationController::GetContour(mitk::PlaneGeometry::Pointer plane) { ContourPositionPairList contourList = m_ListOfInterpolationSessions[m_SelectedSegmentation]; for (unsigned int i = 0; i < contourList.size(); ++i) { ContourPositionPair pair = contourList.at(i); if (mitk::Equal(*plane, *pair.plane, mitk::eps, false)) return pair.contour; } return 0; } unsigned int mitk::SurfaceInterpolationController::GetNumberOfContours() { return m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); } void mitk::SurfaceInterpolationController::Interpolate() { if (m_CurrentNumberOfReducedContours< 2) { //If no interpolation is possible reset the interpolation result m_InterpolationResult = 0; return; } //Setting up progress bar /* * Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation */ //mitk::ProgressBar::GetInstance()->AddStepsToDo(8); // update the filter and get teh resulting distance-image m_InterpolateSurfaceFilter->Update(); Image::Pointer distanceImage = m_InterpolateSurfaceFilter->GetOutput(); // create a surface from the distance-image mitk::ImageToSurfaceFilter::Pointer imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New(); imageToSurfaceFilter->SetInput( distanceImage ); imageToSurfaceFilter->SetThreshold( 0 ); imageToSurfaceFilter->SetSmooth(true); imageToSurfaceFilter->SetSmoothIteration(20); imageToSurfaceFilter->Update(); m_InterpolationResult = imageToSurfaceFilter->GetOutput(); vtkSmartPointer polyDataAppender = vtkSmartPointer::New(); for (unsigned int i = 0; i < m_ReduceFilter->GetNumberOfOutputs(); i++) { polyDataAppender->AddInputData(m_ReduceFilter->GetOutput(i)->GetVtkPolyData()); } polyDataAppender->Update(); m_Contours->SetVtkPolyData(polyDataAppender->GetOutput()); //Last progress step /* * Removed due to bug 12441. ProgressBar messes around with Qt event queue which is fatal for segmentation */ //mitk::ProgressBar::GetInstance()->Progress(8); m_InterpolationResult->DisconnectPipeline(); } mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult() { return m_InterpolationResult; } mitk::Surface* mitk::SurfaceInterpolationController::GetContoursAsSurface() { return m_Contours; } void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage::Pointer ds) { m_DataStorage = ds; } void mitk::SurfaceInterpolationController::SetMinSpacing(double minSpacing) { m_ReduceFilter->SetMinSpacing(minSpacing); } void mitk::SurfaceInterpolationController::SetMaxSpacing(double maxSpacing) { m_ReduceFilter->SetMaxSpacing(maxSpacing); m_NormalsFilter->SetMaxSpacing(maxSpacing); } void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume) { m_InterpolateSurfaceFilter->SetDistanceImageVolume(distImgVolume); } void mitk::SurfaceInterpolationController::SetSegmentationImage(Image* /*workingImage*/) { // m_NormalsFilter->SetSegmentationBinaryImage(workingImage); } mitk::Image::Pointer mitk::SurfaceInterpolationController::GetCurrentSegmentation() { return m_SelectedSegmentation; } mitk::Image* mitk::SurfaceInterpolationController::GetImage() { return m_InterpolateSurfaceFilter->GetOutput(); } double mitk::SurfaceInterpolationController::EstimatePortionOfNeededMemory() { double numberOfPointsAfterReduction = m_ReduceFilter->GetNumberOfPointsAfterReduction()*3; double sizeOfPoints = pow(numberOfPointsAfterReduction,2)*sizeof(double); double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); double percentage = sizeOfPoints/totalMem; return percentage; } unsigned int mitk::SurfaceInterpolationController::GetNumberOfInterpolationSessions() { return m_ListOfInterpolationSessions.size(); } template void mitk::SurfaceInterpolationController::GetImageBase(itk::Image* input, itk::ImageBase<3>::Pointer& result) { result->Graft(input); } void mitk::SurfaceInterpolationController::SetCurrentSegmentationInterpolationList(mitk::Image::Pointer segmentation) { this->SetCurrentInterpolationSession(segmentation); } void mitk::SurfaceInterpolationController::SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage) { if (currentSegmentationImage.GetPointer() == m_SelectedSegmentation) return; m_ReduceFilter->Reset(); m_NormalsFilter->Reset(); m_InterpolateSurfaceFilter->Reset(); if (currentSegmentationImage.IsNull()) { m_SelectedSegmentation = 0; return; } ContourListMap::iterator it = m_ListOfInterpolationSessions.find(currentSegmentationImage.GetPointer()); m_SelectedSegmentation = currentSegmentationImage.GetPointer(); itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New(); AccessFixedDimensionByItk_1( m_SelectedSegmentation, GetImageBase, 3, itkImage ); m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() ); if (it == m_ListOfInterpolationSessions.end()) { ContourPositionPairList newList; m_ListOfInterpolationSessions.insert(std::pair(m_SelectedSegmentation, newList)); m_InterpolationResult = 0; m_CurrentNumberOfReducedContours = 0; itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted); m_SegmentationObserverTags.insert( std::pair( m_SelectedSegmentation, m_SelectedSegmentation->AddObserver( itk::DeleteEvent(), command ) ) ); } else { for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++) { m_ReduceFilter->SetInput(i, m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour); } m_ReduceFilter->Update(); m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs(); for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++) { m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i)); m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i)); } } Modified(); } void mitk::SurfaceInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation) { this->RemoveInterpolationSession(segmentation); } void mitk::SurfaceInterpolationController::RemoveInterpolationSession(mitk::Image::Pointer segmentationImage) { if (segmentationImage) { if (m_SelectedSegmentation == segmentationImage) { SetSegmentationImage(NULL); m_SelectedSegmentation = 0; } m_ListOfInterpolationSessions.erase(segmentationImage); // Remove observer std::map::iterator pos = m_SegmentationObserverTags.find(segmentationImage); if (pos != m_SegmentationObserverTags.end()) { segmentationImage->RemoveObserver((*pos).second); m_SegmentationObserverTags.erase(pos); } } } void mitk::SurfaceInterpolationController::RemoveAllInterpolationSessions() { //Removing all observers std::map::iterator dataIter = m_SegmentationObserverTags.begin(); while (dataIter != m_SegmentationObserverTags.end()) { mitk::Image* image = (*dataIter).first; image->RemoveObserver((*dataIter).second); ++dataIter; } m_SegmentationObserverTags.clear(); m_SelectedSegmentation = 0; m_ListOfInterpolationSessions.clear(); } void mitk::SurfaceInterpolationController::OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &/*event*/) { mitk::Image* tempImage = dynamic_cast(const_cast(caller)); if (tempImage) { if (m_SelectedSegmentation == tempImage) { SetSegmentationImage(NULL); m_SelectedSegmentation = 0; } m_SegmentationObserverTags.erase(tempImage); m_ListOfInterpolationSessions.erase(tempImage); } }