diff --git a/Modules/Core/CMakeLists.txt b/Modules/Core/CMakeLists.txt
index 0d72d5511a..7ffa8c7796 100644
--- a/Modules/Core/CMakeLists.txt
+++ b/Modules/Core/CMakeLists.txt
@@ -1,78 +1,87 @@
set(TOOL_CPPS "")
# temporary suppress warnings in the following files until image accessors are fully integrated.
set_source_files_properties( src/DataManagement/mitkImage.cpp COMPILE_FLAGS -DMITK_NO_DEPRECATED_WARNINGS )
set_source_files_properties( src/Controllers/mitkSliceNavigationController.cpp COMPILE_FLAGS -DMITK_NO_DEPRECATED_WARNINGS )
#if(MSVC)
# set(optional_private_package_depends psapi)
#endif()
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
+ set(optional_public_target_depends stdc++fs)
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
+ set(optional_public_target_depends c++fs)
+endif()
+
mitk_create_module(
INCLUDE_DIRS
PUBLIC
${MITK_BINARY_DIR}
PRIVATE
src/Algorithms
src/Controllers
src/DataManagement
src/Interactions
src/IO
src/Rendering
DEPENDS
PUBLIC
mbilog
CppMicroServices
PACKAGE_DEPENDS
PUBLIC
Boost
ITK|IOImageBase+SpatialObjects+Statistics
#ITK|Statistics+Transform
VTK|FiltersTexture+FiltersParallel+ImagingStencil+ImagingMath+InteractionStyle+RenderingOpenGL2+RenderingVolumeOpenGL2+RenderingFreeType+RenderingLabel+InteractionWidgets+IOGeometry+IOXML
PRIVATE
ITK|IOBioRad+IOBMP+IOBruker+IOCSV+IOGDCM+IOGE+IOGIPL+IOHDF5+IOIPL+IOJPEG+IOJPEG2000+IOLSM+IOMesh+IOMeta+IOMINC+IOMRC+IONIFTI+IONRRD+IOPNG+IOSiemens+IOSpatialObjects+IOStimulate+IOTIFF+IOTransformBase+IOTransformHDF5+IOTransformInsightLegacy+IOTransformMatlab+IOVTK+IOXML
nlohmann_json
tinyxml2
${optional_private_package_depends}
+ TARGET_DEPENDS
+ PUBLIC
+ ${optional_public_target_depends}
# Do not automatically create CppMicroServices initialization code.
# Because the VTK "auto-init" functionality injects file-local static
# initialization code in every cpp file which includes a VTK header,
# static initialization order becomes an issue again. For the Mitk
# core library, we need to ensure that the VTK static initialization stuff
# happens before the CppMicroServices initialization, since the latter
# might already use VTK code which needs to access VTK object factories.
# Hence, CppMicroServices initialization code is placed manually within
# the mitkCoreActivator.cpp file.
NO_INIT
)
if(NOT TARGET ${MODULE_TARGET})
message(SEND_ERROR "Core target ${MODULE_TARGET} does not exist")
endif()
function(_itk_create_factory_register_manager)
# In MITK_ITK_Config.cmake, we do *not* include ITK_USE_FILE, which
# prevents multiple registrations/unregistrations of ITK IO factories
# during library loading/unloading (of MITK libraries). However, we need
# "one" place where the IO factories are registered at
# least once. This could be the application executable, but every executable would
# need to take care of that itself. Instead, we allow the auto registration in the
# Mitk Core library.
set(NO_DIRECTORY_SCOPED_ITK_COMPILE_DEFINITION 1)
find_package(ITK)
include(${ITK_USE_FILE})
if(NOT ITK_NO_IO_FACTORY_REGISTER_MANAGER)
# We manually add the define which will be of target scope. MITK
# patches ITK_USE_FILE to remove the directory scoped compile
# definition since it would be propagated to other targets in the
# same directory scope but these targets might want to *not*
# use the ITK factory manager stuff.
target_compile_definitions(${MODULE_TARGET} PRIVATE ITK_IO_FACTORY_REGISTER_MANAGER)
endif()
endfunction()
_itk_create_factory_register_manager()
if(BUILD_TESTING)
add_subdirectory(TestingHelper)
add_subdirectory(test)
endif()
diff --git a/Modules/Core/include/mitkFileSystem.h b/Modules/Core/include/mitkFileSystem.h
new file mode 100644
index 0000000000..b23d69df0a
--- /dev/null
+++ b/Modules/Core/include/mitkFileSystem.h
@@ -0,0 +1,24 @@
+/*============================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center (DKFZ)
+All rights reserved.
+
+Use of this source code is governed by a 3-clause BSD license that can be
+found in the LICENSE file.
+
+============================================================================*/
+
+#ifndef mitkFileSystem_h
+#define mitkFileSystem_h
+
+#if __has_include()
+ #include
+ namespace fs = std::filesystem;
+#elif __has_include()
+ #include
+ namespace fs = std::experimental::filesystem;
+#endif
+
+#endif
diff --git a/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp b/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp
index 231f8d4aed..ce8653ac5d 100644
--- a/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp
+++ b/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp
@@ -1,75 +1,75 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#include "mitkMultilabelIOMimeTypes.h"
#include
-#include
+#include
#include
#include
mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType::MitkSegmentationTaskListMimeType()
: CustomMimeType(SEGMENTATIONTASKLIST_MIMETYPE_NAME())
{
this->AddExtension("json");
this->SetCategory("MITK Segmentation Task List");
this->SetComment("MITK Segmentation Task List");
}
bool mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType::AppliesTo(const std::string& path) const
{
bool result = CustomMimeType::AppliesTo(path);
- if (!std::filesystem::exists(path)) // T18572
+ if (!fs::exists(path)) // T18572
return result;
std::ifstream file(path);
if (!file.is_open())
return false;
auto json = nlohmann::json::parse(file, nullptr, false);
if (json.is_discarded() || !json.is_object())
return false;
if ("MITK Segmentation Task List" != json.value("FileFormat", ""))
return false;
if (1 != json.value("Version", 0))
return false;
return true;
}
mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType* mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType::Clone() const
{
return new MitkSegmentationTaskListMimeType(*this);
}
mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType mitk::MitkMultilabelIOMimeTypes::SEGMENTATIONTASKLIST_MIMETYPE()
{
return MitkSegmentationTaskListMimeType();
}
std::string mitk::MitkMultilabelIOMimeTypes::SEGMENTATIONTASKLIST_MIMETYPE_NAME()
{
return IOMimeTypes::DEFAULT_BASE_NAME() + ".segmentationtasklist";
}
std::vector mitk::MitkMultilabelIOMimeTypes::Get()
{
std::vector mimeTypes;
mimeTypes.push_back(SEGMENTATIONTASKLIST_MIMETYPE().Clone());
return mimeTypes;
}
diff --git a/Modules/Multilabel/autoload/IO/mitkSegmentationTaskListIO.cpp b/Modules/Multilabel/autoload/IO/mitkSegmentationTaskListIO.cpp
index 6afa7c5a81..e883c20426 100644
--- a/Modules/Multilabel/autoload/IO/mitkSegmentationTaskListIO.cpp
+++ b/Modules/Multilabel/autoload/IO/mitkSegmentationTaskListIO.cpp
@@ -1,267 +1,267 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#include "mitkSegmentationTaskListIO.h"
#include "mitkMultilabelIOMimeTypes.h"
#include
#include
-#include
+#include
#include
namespace mitk
{
void to_json(nlohmann::json& json, const SegmentationTaskList::Task& task)
{
if (task.HasName())
json["Name"] = task.GetName();
if (task.HasDescription())
json["Description"] = task.GetDescription();
if (task.HasImage())
json["Image"] = task.GetImage().string();
if (task.HasSegmentation())
json["Segmentation"] = task.GetSegmentation().string();
if (task.HasLabelName())
json["LabelName"] = task.GetLabelName();
if (task.HasLabelNameSuggestions())
json["LabelNameSuggestions"] = task.GetLabelNameSuggestions().string();
if (task.HasPreset())
json["Preset"] = task.GetPreset().string();
if (task.HasResult())
json["Result"] = task.GetResult().string();
if (task.HasDynamic())
json["Dynamic"] = task.GetDynamic();
}
void from_json(const nlohmann::json& json, SegmentationTaskList::Task& task)
{
auto iter = json.find("Name");
if (iter != json.end())
task.SetName(json["Name"].get());
iter = json.find("Description");
if (iter != json.end())
task.SetDescription(json["Description"].get());
iter = json.find("Image");
if (iter != json.end())
task.SetImage(json["Image"].get());
iter = json.find("Segmentation");
if (iter != json.end())
task.SetSegmentation(json["Segmentation"].get());
iter = json.find("LabelName");
if (iter != json.end())
task.SetLabelName(json["LabelName"].get());
iter = json.find("LabelNameSuggestions");
if (iter != json.end())
task.SetLabelNameSuggestions(json["LabelNameSuggestions"].get());
iter = json.find("Preset");
if (iter != json.end())
task.SetPreset(json["Preset"].get());
iter = json.find("Result");
if (iter != json.end())
task.SetResult(json["Result"].get());
iter = json.find("Dynamic");
if (iter != json.end())
task.SetDynamic(json["Dynamic"].get());
}
}
mitk::SegmentationTaskListIO::SegmentationTaskListIO()
: AbstractFileIO(SegmentationTaskList::GetStaticNameOfClass(), MitkMultilabelIOMimeTypes::SEGMENTATIONTASKLIST_MIMETYPE(), "MITK Segmentation Task List")
{
this->RegisterService();
}
std::vector mitk::SegmentationTaskListIO::DoRead()
{
auto* stream = this->GetInputStream();
std::ifstream fileStream;
if (nullptr == stream)
{
auto filename = this->GetInputLocation();
- if (filename.empty() || !std::filesystem::exists(filename))
+ if (filename.empty() || !fs::exists(filename))
mitkThrow() << "Invalid or nonexistent filename: \"" << filename << "\"!";
fileStream.open(filename);
if (!fileStream.is_open())
mitkThrow() << "Could not open file \"" << filename << "\" for reading!";
stream = &fileStream;
}
nlohmann::json json;
try
{
json = nlohmann::json::parse(*stream);
}
catch (const nlohmann::json::exception& e)
{
mitkThrow() << e.what();
}
if (!json.is_object())
mitkThrow() << "Unknown file format (expected JSON object as root)!";
if ("MITK Segmentation Task List" != json.value("FileFormat", ""))
mitkThrow() << "Unknown file format (expected \"MITK Segmentation Task List\")!";
if (1 != json.value("Version", 0))
mitkThrow() << "Unknown file format version (expected \"1\")!";
if (!json.contains("Tasks") || !json["Tasks"].is_array())
mitkThrow() << "Tasks array not found!";
auto segmentationTaskList = SegmentationTaskList::New();
if (json.contains("Name"))
segmentationTaskList->SetProperty("name", StringProperty::New(json["Name"].get()));
try
{
if (json.contains("Defaults"))
{
segmentationTaskList->SetDefaults(json["Defaults"].get());
if (segmentationTaskList->GetDefaults().HasResult())
mitkThrow() << "Defaults must not contain \"Result\"!";
}
for (const auto& task : json["Tasks"])
{
auto i = segmentationTaskList->AddTask(task.get());
if (!segmentationTaskList->HasImage(i))
mitkThrow() << "Task " << i << " must contain \"Image\"!";
- std::filesystem::path imagePath(segmentationTaskList->GetImage(i));
+ fs::path imagePath(segmentationTaskList->GetImage(i));
if (imagePath.is_relative())
{
auto inputLocation = this->GetInputLocation();
/* If we have access to properties, we are reading from an MITK scene
* file. In this case, paths are still relative to the original input
* location, which is preserved in the properties.
*/
const auto* properties = this->GetProperties();
if (properties != nullptr)
properties->GetStringProperty("MITK.IO.reader.inputlocation", inputLocation);
- imagePath = std::filesystem::path(inputLocation).remove_filename() / imagePath;
+ imagePath = fs::path(inputLocation).remove_filename() / imagePath;
}
- if (!std::filesystem::exists(imagePath))
+ if (!fs::exists(imagePath))
mitkThrow() << "Referenced image \"" << imagePath << "\" in task " << i << " does not exist!";
if (!segmentationTaskList->HasResult(i))
mitkThrow() << "Task " << i << " must contain \"Result\"!";
}
}
catch (const nlohmann::json::type_error& e)
{
mitkThrow() << e.what();
}
std::vector result;
result.push_back(segmentationTaskList.GetPointer());
return result;
}
void mitk::SegmentationTaskListIO::Write()
{
auto segmentationTaskList = dynamic_cast(this->GetInput());
if (nullptr == segmentationTaskList)
mitkThrow() << "Invalid input for writing!";
if (segmentationTaskList->GetNumberOfTasks() == 0)
mitkThrow() << "No tasks found!";
auto* stream = this->GetOutputStream();
std::ofstream fileStream;
if (nullptr == stream)
{
auto filename = this->GetOutputLocation();
if (filename.empty())
mitkThrow() << "Neither an output stream nor an output filename was specified!";
fileStream.open(filename);
if (!fileStream.is_open())
mitkThrow() << "Could not open file \"" << filename << "\" for writing!";
stream = &fileStream;
}
if (!stream->good())
mitkThrow() << "Stream for writing is not good!";
nlohmann::ordered_json json = {
{ "FileFormat", "MITK Segmentation Task List" },
{ "Version", 1 },
{ "Name", segmentationTaskList->GetProperty("name")->GetValueAsString() }
};
nlohmann::json defaults = segmentationTaskList->GetDefaults();
if (!defaults.is_null())
json["Defaults"] = defaults;
nlohmann::json tasks;
for (const auto& task : *segmentationTaskList)
tasks.push_back(task);
json["Tasks"] = tasks;
*stream << std::setw(2) << json << std::endl;
}
mitk::SegmentationTaskListIO* mitk::SegmentationTaskListIO::IOClone() const
{
return new SegmentationTaskListIO(*this);
}
diff --git a/Modules/Multilabel/mitkSegmentationTaskList.cpp b/Modules/Multilabel/mitkSegmentationTaskList.cpp
index a1a844bc8a..71e17397f8 100644
--- a/Modules/Multilabel/mitkSegmentationTaskList.cpp
+++ b/Modules/Multilabel/mitkSegmentationTaskList.cpp
@@ -1,174 +1,174 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#include "mitkSegmentationTaskList.h"
#include
#include
mitk::SegmentationTaskList::Task::Task()
: m_Defaults(nullptr)
{
}
mitk::SegmentationTaskList::Task::~Task()
{
}
void mitk::SegmentationTaskList::Task::SetDefaults(const Task* defaults)
{
m_Defaults = defaults;
}
mitk::SegmentationTaskList::SegmentationTaskList()
{
// A base data cannot be serialized if empty. To be not considered empty its
// geometry must consist of at least one time step. However, a segmentation
// task would then appear as invisible spacial object in a scene. This can
// be prevented by excluding it from the scene's bounding box calculations.
this->GetTimeGeometry()->Expand(1);
this->SetProperty("includeInBoundingBox", BoolProperty::New(false));
}
mitk::SegmentationTaskList::SegmentationTaskList(const Self& other)
: BaseData(other)
{
}
mitk::SegmentationTaskList::~SegmentationTaskList()
{
}
size_t mitk::SegmentationTaskList::GetNumberOfTasks() const
{
return m_Tasks.size();
}
size_t mitk::SegmentationTaskList::AddTask(const Task& subtask)
{
m_Tasks.push_back(subtask);
m_Tasks.back().SetDefaults(&m_Defaults);
return m_Tasks.size() - 1;
}
const mitk::SegmentationTaskList::Task* mitk::SegmentationTaskList::GetTask(size_t index) const
{
return &m_Tasks.at(index);
}
mitk::SegmentationTaskList::Task* mitk::SegmentationTaskList::GetTask(size_t index)
{
return &m_Tasks.at(index);
}
const mitk::SegmentationTaskList::Task& mitk::SegmentationTaskList::GetDefaults() const
{
return m_Defaults;
}
void mitk::SegmentationTaskList::SetDefaults(const Task& defaults)
{
m_Defaults = defaults;
for (auto& subtask : m_Tasks)
subtask.SetDefaults(&m_Defaults);
}
bool mitk::SegmentationTaskList::IsDone() const
{
for (size_t i = 0; i < m_Tasks.size(); ++i)
{
if (!this->IsDone(i))
return false;
}
return true;
}
bool mitk::SegmentationTaskList::IsDone(size_t index) const
{
- return std::filesystem::exists(this->GetAbsolutePath(m_Tasks.at(index).GetResult()));
+ return fs::exists(this->GetAbsolutePath(m_Tasks.at(index).GetResult()));
}
-std::filesystem::path mitk::SegmentationTaskList::GetInputLocation() const
+fs::path mitk::SegmentationTaskList::GetInputLocation() const
{
std::string inputLocation;
this->GetPropertyList()->GetStringProperty("MITK.IO.reader.inputlocation", inputLocation);
return !inputLocation.empty()
- ? std::filesystem::path(inputLocation).lexically_normal()
- : std::filesystem::path();
+ ? fs::path(inputLocation)/*.lexically_normal()*/ // See T29246
+ : fs::path();
}
-std::filesystem::path mitk::SegmentationTaskList::GetBasePath() const
+fs::path mitk::SegmentationTaskList::GetBasePath() const
{
return this->GetInputLocation().remove_filename();
}
-std::filesystem::path mitk::SegmentationTaskList::GetAbsolutePath(const std::filesystem::path& path) const
+fs::path mitk::SegmentationTaskList::GetAbsolutePath(const fs::path& path) const
{
if (path.empty())
return path;
- auto normalizedPath = path.lexically_normal();
+ auto normalizedPath = path/*.lexically_normal()*/; // See T29246
return !normalizedPath.is_absolute()
? this->GetBasePath() / normalizedPath
: normalizedPath;
}
void mitk::SegmentationTaskList::SaveTask(size_t index, const BaseData* segmentation)
{
if (segmentation == nullptr)
return;
auto path = this->GetAbsolutePath(this->GetResult(index));
IOUtil::Save(segmentation, path.string());
}
std::vector::const_iterator mitk::SegmentationTaskList::begin() const
{
return m_Tasks.begin();
}
std::vector::const_iterator mitk::SegmentationTaskList::end() const
{
return m_Tasks.end();
}
std::vector::iterator mitk::SegmentationTaskList::begin()
{
return m_Tasks.begin();
}
std::vector::iterator mitk::SegmentationTaskList::end()
{
return m_Tasks.end();
}
void mitk::SegmentationTaskList::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::SegmentationTaskList::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::SegmentationTaskList::VerifyRequestedRegion()
{
return true;
}
void mitk::SegmentationTaskList::SetRequestedRegion(const itk::DataObject*)
{
}
diff --git a/Modules/Multilabel/mitkSegmentationTaskList.h b/Modules/Multilabel/mitkSegmentationTaskList.h
index dae82b718e..bc72f6e72c 100644
--- a/Modules/Multilabel/mitkSegmentationTaskList.h
+++ b/Modules/Multilabel/mitkSegmentationTaskList.h
@@ -1,110 +1,110 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#ifndef mitkSegmentationTaskList_h
#define mitkSegmentationTaskList_h
#include
#include
#include
-#include
+#include
#include
namespace mitk
{
/** \brief A list of segmentation tasks.
*
* See \ref MITKSegmentationTaskListsPage for more information.
*/
class MITKMULTILABEL_EXPORT SegmentationTaskList : public BaseData
{
public:
class MITKMULTILABEL_EXPORT Task
{
public:
Task();
~Task();
void SetDefaults(const Task* defaults);
mitkSegmentationTaskValueMacro(std::string, Name)
mitkSegmentationTaskValueMacro(std::string, Description)
- mitkSegmentationTaskValueMacro(std::filesystem::path, Image)
- mitkSegmentationTaskValueMacro(std::filesystem::path, Segmentation)
+ mitkSegmentationTaskValueMacro(fs::path, Image)
+ mitkSegmentationTaskValueMacro(fs::path, Segmentation)
mitkSegmentationTaskValueMacro(std::string, LabelName)
- mitkSegmentationTaskValueMacro(std::filesystem::path, LabelNameSuggestions)
- mitkSegmentationTaskValueMacro(std::filesystem::path, Preset)
- mitkSegmentationTaskValueMacro(std::filesystem::path, Result)
+ mitkSegmentationTaskValueMacro(fs::path, LabelNameSuggestions)
+ mitkSegmentationTaskValueMacro(fs::path, Preset)
+ mitkSegmentationTaskValueMacro(fs::path, Result)
mitkSegmentationTaskValueMacro(bool, Dynamic)
private:
const Task* m_Defaults;
};
mitkClassMacro(SegmentationTaskList, BaseData)
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
mitkSegmentationTaskListValueMacro(std::string, Name)
mitkSegmentationTaskListValueMacro(std::string, Description)
- mitkSegmentationTaskListValueMacro(std::filesystem::path, Image)
- mitkSegmentationTaskListValueMacro(std::filesystem::path, Segmentation)
+ mitkSegmentationTaskListValueMacro(fs::path, Image)
+ mitkSegmentationTaskListValueMacro(fs::path, Segmentation)
mitkSegmentationTaskListValueMacro(std::string, LabelName)
- mitkSegmentationTaskListValueMacro(std::filesystem::path, LabelNameSuggestions)
- mitkSegmentationTaskListValueMacro(std::filesystem::path, Preset)
- mitkSegmentationTaskListValueMacro(std::filesystem::path, Result)
+ mitkSegmentationTaskListValueMacro(fs::path, LabelNameSuggestions)
+ mitkSegmentationTaskListValueMacro(fs::path, Preset)
+ mitkSegmentationTaskListValueMacro(fs::path, Result)
mitkSegmentationTaskListValueMacro(bool, Dynamic)
size_t GetNumberOfTasks() const;
size_t AddTask(const Task& subtask);
const Task* GetTask(size_t index) const;
Task* GetTask(size_t index);
const Task& GetDefaults() const;
void SetDefaults(const Task& defaults);
bool IsDone() const;
bool IsDone(size_t index) const;
- std::filesystem::path GetInputLocation() const;
- std::filesystem::path GetBasePath() const;
- std::filesystem::path GetAbsolutePath(const std::filesystem::path& path) const;
+ fs::path GetInputLocation() const;
+ fs::path GetBasePath() const;
+ fs::path GetAbsolutePath(const fs::path& path) const;
void SaveTask(size_t index, const BaseData* segmentation);
std::vector::const_iterator begin() const;
std::vector::const_iterator end() const;
std::vector::iterator begin();
std::vector::iterator end();
void SetRequestedRegionToLargestPossibleRegion() override;
bool RequestedRegionIsOutsideOfTheBufferedRegion() override;
bool VerifyRequestedRegion() override;
void SetRequestedRegion(const itk::DataObject*) override;
protected:
mitkCloneMacro(Self)
SegmentationTaskList();
SegmentationTaskList(const Self& other);
~SegmentationTaskList() override;
private:
Task m_Defaults;
std::vector m_Tasks;
};
}
#endif
diff --git a/Modules/Remeshing/CMakeLists.txt b/Modules/Remeshing/CMakeLists.txt
index 4e658c5ebe..499635ca66 100644
--- a/Modules/Remeshing/CMakeLists.txt
+++ b/Modules/Remeshing/CMakeLists.txt
@@ -1,7 +1,5 @@
mitk_create_module(
DEPENDS PUBLIC MitkCore
- PACKAGE_DEPENDS ACVD|Surface+VolumeProcessing
+ PACKAGE_DEPENDS ACVD|Surface
WARNINGS_NO_ERRORS # ACVD's header files trigger some unused parameter errors
)
-
-add_subdirectory(Testing)
diff --git a/Modules/Remeshing/Testing/CMakeLists.txt b/Modules/Remeshing/Testing/CMakeLists.txt
deleted file mode 100644
index 7a1edabe1d..0000000000
--- a/Modules/Remeshing/Testing/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-if(MITK_USE_ACVD)
- MITK_CREATE_MODULE_TESTS()
-
- mitkAddCustomModuleTest(mitkRemeshingTest mitkRemeshingTest ${MITK_DATA_DIR}/binary.stl 0 1228 1.0 10 0.0 1 0 0)
-endif()
diff --git a/Modules/Remeshing/Testing/files.cmake b/Modules/Remeshing/Testing/files.cmake
deleted file mode 100644
index b41ec2ca0c..0000000000
--- a/Modules/Remeshing/Testing/files.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-set(MODULE_TESTS
-)
-
-set(MODULE_CUSTOM_TESTS
- mitkRemeshingTest.cpp
-)
diff --git a/Modules/Remeshing/Testing/mitkRemeshingTest.cpp b/Modules/Remeshing/Testing/mitkRemeshingTest.cpp
deleted file mode 100644
index a4fa0343fd..0000000000
--- a/Modules/Remeshing/Testing/mitkRemeshingTest.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*============================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center (DKFZ)
-All rights reserved.
-
-Use of this source code is governed by a 3-clause BSD license that can be
-found in the LICENSE file.
-
-============================================================================*/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define _MITK_TEST_FOR_EXCEPTION(STATEMENT, EXCEPTION, MESSAGE) \
- MITK_TEST_OUTPUT_NO_ENDL(<< MESSAGE) \
- try \
- { \
- STATEMENT; \
- MITK_TEST_OUTPUT(<< " [FAILED]") \
- mitk::TestManager::GetInstance()->TestFailed(); \
- } \
- catch (const EXCEPTION &e) \
- { \
- MITK_TEST_OUTPUT(<< "\n " << e.GetDescription() << " [PASSED]") \
- mitk::TestManager::GetInstance()->TestPassed(); \
- }
-
-template
-static T lexical_cast(const std::string &string)
-{
- std::istringstream sstream(string);
- T value;
-
- sstream >> value;
-
- if (sstream.fail())
- {
- MITK_ERROR << "Lexical cast failed for '" << string << "'!";
- exit(EXIT_FAILURE);
- }
-
- return value;
-}
-
-static void Remesh_SurfaceIsNull_ThrowsException()
-{
- mitk::Surface::ConstPointer surface;
- _MITK_TEST_FOR_EXCEPTION(
- mitk::Remesh(surface, 0, 100, 0.0), mitk::Exception, "Remesh_SurfaceIsNull_ThrowsException")
-}
-
-static void Remesh_PolyDataIsNull_ThrowsException()
-{
- mitk::Surface::ConstPointer surface = mitk::Surface::New().GetPointer();
- _MITK_TEST_FOR_EXCEPTION(
- mitk::Remesh(surface, 0, 100, 0.0), mitk::Exception, "Remesh_PolyDataIsNull_ThrowsException")
-}
-
-static void Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException()
-{
- mitk::Surface::ConstPointer surface = mitk::Surface::New().GetPointer();
- _MITK_TEST_FOR_EXCEPTION(mitk::Remesh(surface, 1, 100, 0.0),
- mitk::Exception,
- "Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException")
-}
-
-static void Remesh_SurfaceHasNoPolygons_ThrowsException()
-{
- mitk::Surface::Pointer surface = mitk::Surface::New();
- vtkSmartPointer polyData = vtkSmartPointer::New();
- surface->SetVtkPolyData(polyData);
- _MITK_TEST_FOR_EXCEPTION(mitk::Remesh(surface.GetPointer(), 0, 100, 0.0),
- mitk::Exception,
- "Remesh_SurfaceHasNoPolygons_ThrowsException")
-}
-
-static void Remesh_SurfaceIsValid_ReturnsRemeshedSurface(const std::string &filename,
- unsigned int t,
- int numVertices,
- double gradation,
- int subsampling,
- double edgeSplitting,
- int optimizationLevel,
- bool forceManifold,
- bool boundaryFixing)
-{
- auto surface = mitk::IOUtil::Load(filename);
- mitk::Surface::Pointer remeshedSurface = mitk::Remesh(
- surface.GetPointer(), t, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing);
- MITK_TEST_CONDITION(remeshedSurface.IsNotNull() && remeshedSurface->GetVtkPolyData() != nullptr &&
- remeshedSurface->GetVtkPolyData()->GetNumberOfPolys() != 0,
- "Remesh_SurfaceIsValid_ReturnsRemeshedSurface")
-}
-
-int mitkRemeshingTest(int argc, char *argv[])
-{
- if (argc != 10)
- {
- MITK_ERROR << "Invalid argument count!\n"
- << "Usage: mitkRemeshingTest \n"
- << " \n"
- << " \n"
- << " See MITK API documentation of mitk::Remesh() for details.";
-
- return EXIT_FAILURE;
- }
-
- const std::string filename = argv[1];
- const unsigned int t = lexical_cast(argv[2]);
- const int numVertices = lexical_cast(argv[3]);
- const double gradation = lexical_cast(argv[4]);
- const int subsampling = lexical_cast(argv[5]);
- const double edgeSplitting = lexical_cast(argv[6]);
- const int optimizationLevel = lexical_cast(argv[7]);
- const bool forceManifold = lexical_cast(argv[8]);
- const bool boundaryFixing = lexical_cast(argv[9]);
-
- MITK_TEST_BEGIN("mitkRemeshingTest")
-
- vtkDebugLeaks::SetExitError(0);
-
- Remesh_SurfaceIsNull_ThrowsException();
- Remesh_PolyDataIsNull_ThrowsException();
- Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException();
- Remesh_SurfaceHasNoPolygons_ThrowsException();
-
- Remesh_SurfaceIsValid_ReturnsRemeshedSurface(
- filename, t, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing);
-
- MITK_TEST_END()
-}
diff --git a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp
index c28b3e54ce..6144ccae55 100644
--- a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp
+++ b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp
@@ -1,463 +1,463 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#include "mitkSceneReaderV1.h"
#include "Poco/Path.h"
#include "mitkBaseRenderer.h"
#include "mitkIOUtil.h"
#include "mitkProgressBar.h"
#include "mitkPropertyListDeserializer.h"
#include "mitkSerializerMacros.h"
#include
#include
#include
-#include
+#include
#include
").arg(isDone
? ColorString("Done", Qt::white, QColor(Qt::green).darker())
: ColorString("Not done", Qt::white, QColor(Qt::red).darker()));
}
if (m_TaskList->HasDescription(current))
details += QString("Description: %1
").arg(QString::fromStdString(m_TaskList->GetDescription(current)));
QStringList stringList;
if (m_TaskList->HasImage(current))
stringList << QString::fromStdString("Image: " + m_TaskList->GetImage(current).string());
if (m_TaskList->HasSegmentation(current))
stringList << QString::fromStdString("Segmentation: " + m_TaskList->GetSegmentation(current).string());
if (m_TaskList->HasLabelName(current))
stringList << QString::fromStdString("Label name: " + m_TaskList->GetLabelName(current));
if (m_TaskList->HasLabelNameSuggestions(current))
stringList << QString::fromStdString("Label name suggestions: " + m_TaskList->GetLabelNameSuggestions(current).string());
if (m_TaskList->HasPreset(current))
stringList << QString::fromStdString("Label set preset: " + m_TaskList->GetPreset(current).string());
if (m_TaskList->HasDynamic(current))
stringList << QString("Segmentation type: %1").arg(m_TaskList->GetDynamic(current) ? "Dynamic" : "Static");
if (!stringList.empty())
details += QString("%1
").arg(stringList.join(QStringLiteral("
")));
m_Ui->detailsLabel->setText(details);
}
/* Load/activate the currently displayed task. Unload all data nodes from
* previously active tasks first, but spare and reuse the image if possible.
*/
void QmitkSegmentationTaskListWidget::OnLoadButtonClicked()
{
if (!this->HandleUnsavedChanges() || m_UnsavedChanges)
return;
m_Ui->loadButton->setEnabled(false);
QApplication::setOverrideCursor(Qt::BusyCursor);
this->LoadTask(this->GetImageDataNode(m_CurrentTaskIndex.value()));
QApplication::restoreOverrideCursor();
}
/* If present, return the image data node for the task with the specified
* index. Otherwise, return nullptr.
*/
mitk::DataNode* QmitkSegmentationTaskListWidget::GetImageDataNode(size_t index) const
{
const auto imagePath = m_TaskList->GetAbsolutePath(m_TaskList->GetImage(index));
auto imageNodes = GetDataStorage()->GetDerivations(m_TaskListNode, mitk::NodePredicateFunction::New([imagePath](const mitk::DataNode* node) {
return imagePath == GetInputLocation(node->GetData());
}));
return !imageNodes->empty()
? imageNodes->front()
: nullptr;
}
/* If present, return the segmentation data node for the task with the
* specified index. Otherwise, return nullptr.
*/
mitk::DataNode* QmitkSegmentationTaskListWidget::GetSegmentationDataNode(size_t index) const
{
const auto* imageNode = this->GetImageDataNode(index);
if (imageNode != nullptr)
{
auto segmentations = GetDataStorage()->GetDerivations(imageNode, mitk::TNodePredicateDataType::New());
if (!segmentations->empty())
return segmentations->front();
}
return nullptr;
}
/* Unload all task data nodes but spare the passed image data node.
*/
void QmitkSegmentationTaskListWidget::UnloadTasks(const mitk::DataNode* skip)
{
this->UnsubscribeFromActiveSegmentation();
if (m_TaskListNode.IsNotNull())
{
mitk::DataStorage::Pointer dataStorage = GetDataStorage();
auto imageNodes = dataStorage->GetDerivations(m_TaskListNode, mitk::TNodePredicateDataType::New());
for (auto imageNode : *imageNodes)
{
dataStorage->Remove(dataStorage->GetDerivations(imageNode, nullptr, false));
if (imageNode != skip)
dataStorage->Remove(imageNode);
}
}
this->SetActiveTaskIndex(std::nullopt);
}
/* Load/activate the currently displayed task. The task must specify
* an image. The segmentation is either created from scratch with an optional
* name for the first label, possibly based on a label set preset specified by
* the task, or loaded as specified by the task. If a result file does
* exist, it is chosen as segmentation instead.
*/
void QmitkSegmentationTaskListWidget::LoadTask(mitk::DataNode::Pointer imageNode)
{
this->UnloadTasks(imageNode);
const auto current = m_CurrentTaskIndex.value();
mitk::Image::Pointer image;
mitk::LabelSetImage::Pointer segmentation;
try
{
if (imageNode.IsNull())
{
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetImage(current));
image = mitk::IOUtil::Load(path.string());
}
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetResult(current));
- if (std::filesystem::exists(path))
+ if (fs::exists(path))
{
segmentation = mitk::IOUtil::Load(path.string());
}
else if (m_TaskList->HasSegmentation(current))
{
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetSegmentation(current));
segmentation = mitk::IOUtil::Load(path.string());
}
}
catch (const mitk::Exception&)
{
return;
}
auto dataStorage = GetDataStorage();
if (imageNode.IsNull())
{
imageNode = mitk::DataNode::New();
imageNode->SetData(image);
dataStorage->Add(imageNode, m_TaskListNode);
mitk::RenderingManager::GetInstance()->InitializeViews(image->GetTimeGeometry());
}
else
{
image = static_cast(imageNode->GetData());
}
auto name = "Task " + std::to_string(current + 1);
imageNode->SetName(name);
if (segmentation.IsNull())
{
mitk::Image::ConstPointer templateImage = image;
if (templateImage->GetDimension() > 3)
{
if (m_TaskList->HasDynamic(current))
{
if (!m_TaskList->GetDynamic(current))
templateImage = mitk::SegmentationHelper::GetStaticSegmentationTemplate(image);
}
else
{
QmitkStaticDynamicSegmentationDialog dialog(this);
dialog.SetReferenceImage(templateImage);
dialog.exec();
templateImage = dialog.GetSegmentationTemplate();
}
}
auto segmentationNode = mitk::LabelSetImageHelper::CreateNewSegmentationNode(imageNode, templateImage, name);
segmentation = static_cast(segmentationNode->GetData());
if (m_TaskList->HasPreset(current))
{
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetPreset(current));
mitk::LabelSetIOHelper::LoadLabelSetImagePreset(path.string(), segmentation);
}
else
{
auto label = mitk::LabelSetImageHelper::CreateNewLabel(segmentation);
if (m_TaskList->HasLabelName(current))
label->SetName(m_TaskList->GetLabelName(current));
segmentation->GetActiveLabelSet()->AddLabel(label);
}
dataStorage->Add(segmentationNode, imageNode);
}
else
{
auto segmentationNode = mitk::DataNode::New();
segmentationNode->SetName(name);
segmentationNode->SetData(segmentation);
dataStorage->Add(segmentationNode, imageNode);
}
auto prefs = GetSegmentationPreferences();
if (prefs.IsNotNull())
{
if (m_TaskList->HasLabelNameSuggestions(current))
{
auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetLabelNameSuggestions(current));
prefs->PutBool("default label naming", false);
prefs->Put("label suggestions", QString::fromStdString(path.string()));
prefs->PutBool("replace standard suggestions", true);
prefs->PutBool("suggest once", true);
}
else
{
prefs->PutBool("default label naming", true);
prefs->Put("label suggestions", "");
}
}
m_UnsavedChanges = false;
this->SetActiveTaskIndex(current);
this->SubscribeToActiveSegmentation();
this->OnCurrentTaskChanged();
}
void QmitkSegmentationTaskListWidget::SubscribeToActiveSegmentation()
{
if (m_ActiveTaskIndex.has_value())
{
auto segmentationNode = this->GetSegmentationDataNode(m_ActiveTaskIndex.value());
if (segmentationNode != nullptr)
{
auto segmentation = static_cast(segmentationNode->GetData());
auto command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationTaskListWidget::OnSegmentationModified);
m_SegmentationModifiedObserverTag = segmentation->AddObserver(itk::ModifiedEvent(), command);
}
}
}
void QmitkSegmentationTaskListWidget::UnsubscribeFromActiveSegmentation()
{
if (m_ActiveTaskIndex.has_value() && m_SegmentationModifiedObserverTag.has_value())
{
auto segmentationNode = this->GetSegmentationDataNode(m_ActiveTaskIndex.value());
if (segmentationNode != nullptr)
{
auto segmentation = static_cast(segmentationNode->GetData());
segmentation->RemoveObserver(m_SegmentationModifiedObserverTag.value());
}
m_SegmentationModifiedObserverTag.reset();
}
}
void QmitkSegmentationTaskListWidget::OnSegmentationModified()
{
if (!m_UnsavedChanges)
{
m_UnsavedChanges = true;
if (m_ActiveTaskIndex.value() == m_CurrentTaskIndex)
this->UpdateDetailsLabel();
}
}
void QmitkSegmentationTaskListWidget::SetActiveTaskIndex(const std::optional& index)
{
if (m_ActiveTaskIndex != index)
{
m_ActiveTaskIndex = index;
emit ActiveTaskChanged(m_ActiveTaskIndex);
}
}
void QmitkSegmentationTaskListWidget::SetCurrentTaskIndex(const std::optional& index)
{
if (m_CurrentTaskIndex != index)
{
m_CurrentTaskIndex = index;
this->OnCurrentTaskChanged();
emit CurrentTaskChanged(m_CurrentTaskIndex);
}
}
bool QmitkSegmentationTaskListWidget::ActiveTaskIsShown() const
{
return m_ActiveTaskIndex.has_value() && m_CurrentTaskIndex.has_value() && m_ActiveTaskIndex == m_CurrentTaskIndex;
}
bool QmitkSegmentationTaskListWidget::HandleUnsavedChanges()
{
if (m_UnsavedChanges)
{
const auto active = m_ActiveTaskIndex.value();
const auto current = m_CurrentTaskIndex.value();
auto title = QString("Load task %1").arg(current + 1);
if (m_TaskList->HasName(current))
title += ": " + QString::fromStdString(m_TaskList->GetName(current));
auto text = QString("The currently active task %1 ").arg(active + 1);
if (m_TaskList->HasName(active))
text += "(" + QString::fromStdString(m_TaskList->GetName(active)) + ") ";
text += "has unsaved changes.";
auto reply = QMessageBox::question(this, title, text, QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel);
switch (reply)
{
case QMessageBox::Save:
this->SaveActiveTask();
break;
case QMessageBox::Discard:
m_UnsavedChanges = false;
break;
default:
return false;
}
}
return true;
}
void QmitkSegmentationTaskListWidget::SaveActiveTask()
{
if (!m_ActiveTaskIndex.has_value())
return;
QApplication::setOverrideCursor(Qt::BusyCursor);
try
{
const auto active = m_ActiveTaskIndex.value();
m_TaskList->SaveTask(active, this->GetSegmentationDataNode(active)->GetData());
this->OnUnsavedChangesSaved();
}
catch (const mitk::Exception& e)
{
MITK_ERROR << e;
}
QApplication::restoreOverrideCursor();
}