diff --git a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp index ef826f915d..a76440f531 100644 --- a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp +++ b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp @@ -1,123 +1,123 @@ /*============================================================================ 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 "mitkMAPRegistrationWrapperObjectFactory.h" #include #include #include #include "mitkRegistrationWrapperMapper2D.h" #include "mitkRegistrationWrapperMapper3D.h" #include "mitkMAPRegistrationWrapper.h" typedef std::multimap MultimapType; mitk::MAPRegistrationWrapperObjectFactory::MAPRegistrationWrapperObjectFactory() : CoreObjectFactoryBase() { static bool alreadyDone = false; if (!alreadyDone) { alreadyDone = true; } } mitk::MAPRegistrationWrapperObjectFactory::~MAPRegistrationWrapperObjectFactory() { } mitk::Mapper::Pointer mitk::MAPRegistrationWrapperObjectFactory:: CreateMapper(mitk::DataNode* node, MapperSlotId slotId) { mitk::Mapper::Pointer newMapper=nullptr; if ( slotId == mitk::BaseRenderer::Standard2D ) { std::string classname("MAPRegistrationWrapper"); if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::MITKRegistrationWrapperMapper2D::New(); newMapper->SetDataNode(node); } } else if ( slotId == mitk::BaseRenderer::Standard3D ) { std::string classname("MAPRegistrationWrapper"); if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::MITKRegistrationWrapperMapper3D::New(); newMapper->SetDataNode(node); } } return newMapper; }; void mitk::MAPRegistrationWrapperObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if(node==nullptr) return; mitk::DataNode::Pointer nodePointer = node; if(node->GetData() ==nullptr) return; if( dynamic_cast(node->GetData())!=nullptr ) { mitk::MITKRegistrationWrapperMapperBase::SetDefaultProperties(node); } } const char* mitk::MAPRegistrationWrapperObjectFactory::GetFileExtensions() { std::string fileExtension; - this->CreateFileExtensions(m_FileExtensionsMap, fileExtension); + this->CreateFileExtensions({}, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::MAPRegistrationWrapperObjectFactory::GetFileExtensionsMap() { - return m_FileExtensionsMap; + return {}; } const char* mitk::MAPRegistrationWrapperObjectFactory::GetSaveFileExtensions() { std::string fileExtension; - this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); + this->CreateFileExtensions({}, fileExtension); return fileExtension.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::MAPRegistrationWrapperObjectFactory::GetSaveFileExtensionsMap() { - return m_SaveFileExtensionsMap; + return {}; } struct RegisterMAPRegistrationWrapperObjectFactoryHelper{ RegisterMAPRegistrationWrapperObjectFactoryHelper() : m_Factory( mitk::MAPRegistrationWrapperObjectFactory::New() ) { mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory( m_Factory ); } ~RegisterMAPRegistrationWrapperObjectFactoryHelper() { mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory( m_Factory ); } mitk::MAPRegistrationWrapperObjectFactory::Pointer m_Factory; }; static RegisterMAPRegistrationWrapperObjectFactoryHelper registerMITKRegistrationWrapperIOFactoryHelper; diff --git a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h index e7e2b93140..79f9a88e16 100644 --- a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h +++ b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h @@ -1,67 +1,58 @@ /*============================================================================ 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 __mitkMAPRegistrationWrapperObjectFactory_h #define __mitkMAPRegistrationWrapperObjectFactory_h #include #include "MitkMatchPointRegistrationExports.h" namespace mitk { class MAPRegistrationWrapperObjectFactory : public mitk::CoreObjectFactoryBase { public: mitkClassMacro(MAPRegistrationWrapperObjectFactory,CoreObjectFactoryBase); itkFactorylessNewMacro(Self); itkCloneMacro(Self); ~MAPRegistrationWrapperObjectFactory() override; void SetDefaultProperties(mitk::DataNode* node) override; /** * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil */ DEPRECATED(virtual const char* GetFileExtensions()); /** * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil */ DEPRECATED(virtual mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap()); /** * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil */ DEPRECATED(virtual const char* GetSaveFileExtensions()); /** * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil */ DEPRECATED(virtual mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap()); mitk::Mapper::Pointer CreateMapper(mitk::DataNode* node, MapperSlotId slotId) override; protected: MAPRegistrationWrapperObjectFactory(); - private: - void CreateFileExtensionsMap(); - std::string m_ExternalFileExtensions; - std::string m_InternalFileExtensions; - std::string m_SaveFileExtensions; - MultimapType m_FileExtensionsMap; - MultimapType m_SaveFileExtensionsMap; - - itk::ObjectFactoryBase::Pointer m_RegistrationWrapperIOFactory; }; } #endif diff --git a/Modules/Multilabel/autoload/IO/CMakeLists.txt b/Modules/Multilabel/autoload/IO/CMakeLists.txt index 9c62019a54..9a0856eff7 100644 --- a/Modules/Multilabel/autoload/IO/CMakeLists.txt +++ b/Modules/Multilabel/autoload/IO/CMakeLists.txt @@ -1,8 +1,6 @@ MITK_CREATE_MODULE( MultilabelIO - INCLUDE_DIRS - PRIVATE src/IO DEPENDS PUBLIC MitkMultilabel MitkSceneSerialization PACKAGE_DEPENDS PRIVATE ITK|ITKQuadEdgeMesh+ITKAntiAlias+ITKIONRRD AUTOLOAD_WITH MitkCore ) diff --git a/Modules/Multilabel/mitkMultilabelObjectFactory.cpp b/Modules/Multilabel/mitkMultilabelObjectFactory.cpp index e402aeff8b..6bce2dc1d8 100644 --- a/Modules/Multilabel/mitkMultilabelObjectFactory.cpp +++ b/Modules/Multilabel/mitkMultilabelObjectFactory.cpp @@ -1,124 +1,124 @@ /*============================================================================ 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 "mitkMultilabelObjectFactory.h" #include "mitkBaseRenderer.h" #include "mitkCoreObjectFactory.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include #include #include #include mitk::MultilabelObjectFactory::MultilabelObjectFactory() : CoreObjectFactoryBase() { static bool alreadyDone = false; if (!alreadyDone) { MITK_DEBUG << "MultilabelObjectFactory c'tor" << std::endl; CreateFileExtensionsMap(); alreadyDone = true; } } mitk::MultilabelObjectFactory::~MultilabelObjectFactory() { } mitk::Mapper::Pointer mitk::MultilabelObjectFactory::CreateMapper(mitk::DataNode *node, MapperSlotId id) { mitk::Mapper::Pointer newMapper = nullptr; mitk::BaseData *data = node->GetData(); if (id == mitk::BaseRenderer::Standard2D) { if ((dynamic_cast(data) != nullptr)) { newMapper = mitk::LabelSetImageVtkMapper2D::New(); newMapper->SetDataNode(node); } } return newMapper; } void mitk::MultilabelObjectFactory::SetDefaultProperties(mitk::DataNode *node) { if (node == nullptr) return; if (node->GetData() == nullptr) return; if (dynamic_cast(node->GetData()) != nullptr) { mitk::LabelSetImageVtkMapper2D::SetDefaultProperties(node); auto propertyFilters = CoreServices::GetPropertyFilters(); if (propertyFilters != nullptr) { PropertyFilter labelSetImageFilter; labelSetImageFilter.AddEntry("binaryimage.hoveringannotationcolor", PropertyFilter::Blacklist); labelSetImageFilter.AddEntry("binaryimage.hoveringcolor", PropertyFilter::Blacklist); labelSetImageFilter.AddEntry("binaryimage.selectedannotationcolor", PropertyFilter::Blacklist); labelSetImageFilter.AddEntry("binaryimage.selectedcolor", PropertyFilter::Blacklist); labelSetImageFilter.AddEntry("outline binary shadow color", PropertyFilter::Blacklist); propertyFilters->AddFilter(labelSetImageFilter, "LabelSetImage"); } } } const char *mitk::MultilabelObjectFactory::GetFileExtensions() { std::string fileExtension; - this->CreateFileExtensions(m_FileExtensionsMap, fileExtension); + this->CreateFileExtensions({}, fileExtension); return fileExtension.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::MultilabelObjectFactory::GetFileExtensionsMap() { - return m_FileExtensionsMap; + return {}; } mitk::CoreObjectFactoryBase::MultimapType mitk::MultilabelObjectFactory::GetSaveFileExtensionsMap() { - return m_SaveFileExtensionsMap; + return {}; } void mitk::MultilabelObjectFactory::CreateFileExtensionsMap() { } const char *mitk::MultilabelObjectFactory::GetSaveFileExtensions() { std::string fileExtension; - this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); + this->CreateFileExtensions({}, fileExtension); return fileExtension.c_str(); } struct RegisterMultilabelObjectFactory { RegisterMultilabelObjectFactory() : m_Factory(mitk::MultilabelObjectFactory::New()) { mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(m_Factory); } ~RegisterMultilabelObjectFactory() { mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory(m_Factory); } mitk::MultilabelObjectFactory::Pointer m_Factory; }; static RegisterMultilabelObjectFactory registerMultilabelObjectFactory; diff --git a/Modules/Multilabel/mitkMultilabelObjectFactory.h b/Modules/Multilabel/mitkMultilabelObjectFactory.h index 072f959e0e..2631cf6500 100644 --- a/Modules/Multilabel/mitkMultilabelObjectFactory.h +++ b/Modules/Multilabel/mitkMultilabelObjectFactory.h @@ -1,50 +1,42 @@ /*============================================================================ 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 MULTILABELOBJECTFACTORY_H_INCLUDED #define MULTILABELOBJECTFACTORY_H_INCLUDED #include "mitkCoreObjectFactoryBase.h" #include namespace mitk { class MultilabelObjectFactory : public CoreObjectFactoryBase { public: mitkClassMacro(MultilabelObjectFactory, CoreObjectFactoryBase); itkFactorylessNewMacro(Self); itkCloneMacro(Self) Mapper::Pointer CreateMapper(mitk::DataNode *node, MapperSlotId slotId) override; void SetDefaultProperties(mitk::DataNode *node) override; const char *GetFileExtensions() override; mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap() override; const char *GetSaveFileExtensions() override; mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap() override; protected: MultilabelObjectFactory(); ~MultilabelObjectFactory() override; void CreateFileExtensionsMap(); - MultimapType m_FileExtensionsMap; - MultimapType m_SaveFileExtensionsMap; - - private: - itk::ObjectFactoryBase::Pointer m_LabelSetImageIOFactory; - itk::ObjectFactoryBase::Pointer m_LabelSetImageWriterFactory; - - std::vector m_FileIOs; }; } #endif diff --git a/Modules/PlanarFigure/CMakeLists.txt b/Modules/PlanarFigure/CMakeLists.txt index 0933cc7d71..af4c93bb9c 100644 --- a/Modules/PlanarFigure/CMakeLists.txt +++ b/Modules/PlanarFigure/CMakeLists.txt @@ -1,7 +1,10 @@ MITK_CREATE_MODULE( - INCLUDE_DIRS PRIVATE src/Algorithms src/DataManagement src/Interactions src/IO src/Rendering - DEPENDS MitkSceneSerializationBase MitkLegacyGL MitkAnnotation + INCLUDE_DIRS PRIVATE src/Algorithms src/DataManagement src/Interactions src/Rendering + DEPENDS MitkLegacyGL MitkAnnotation ) -add_subdirectory(test) +add_subdirectory(autoload/IO) +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/Modules/PlanarFigure/autoload/IO/CMakeLists.txt b/Modules/PlanarFigure/autoload/IO/CMakeLists.txt new file mode 100644 index 0000000000..bdde2f83fc --- /dev/null +++ b/Modules/PlanarFigure/autoload/IO/CMakeLists.txt @@ -0,0 +1,4 @@ +MITK_CREATE_MODULE( PlanarFigureIO + DEPENDS MitkPlanarFigure MitkSceneSerializationBase + AUTOLOAD_WITH MitkCore +) diff --git a/Modules/PlanarFigure/autoload/IO/files.cmake b/Modules/PlanarFigure/autoload/IO/files.cmake new file mode 100644 index 0000000000..d085b5ba90 --- /dev/null +++ b/Modules/PlanarFigure/autoload/IO/files.cmake @@ -0,0 +1,12 @@ +set(H_FILES + mitkPlanarFigureIO.h + mitkPlanarFigureSerializer.h +) + +set(CPP_FILES + mitkPlanarFigureIOActivator.cpp + mitkPlanarFigureIO.cpp + mitkPlanarFigureSerializer.cpp + mitkPlanarFigureSubclassesSerializer.cpp +) + diff --git a/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIO.cpp b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIO.cpp new file mode 100644 index 0000000000..246a8c2843 --- /dev/null +++ b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIO.cpp @@ -0,0 +1,560 @@ +/*============================================================================ + +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 "mitkCustomMimeType.h" +#include "mitkIOMimeTypes.h" +#include "mitkExceptionMacro.h" + +#include "mitkPlanarAngle.h" +#include "mitkPlanarArrow.h" +#include "mitkPlanarBezierCurve.h" +#include "mitkPlanarCircle.h" +#include "mitkPlanarCross.h" +#include "mitkPlanarDoubleEllipse.h" +#include "mitkPlanarEllipse.h" +#include "mitkPlanarFourPointAngle.h" +#include "mitkPlanarLine.h" +#include "mitkPlanarPolygon.h" +#include "mitkPlanarRectangle.h" +#include "mitkPlanarSubdivisionPolygon.h" +#include "mitkPlaneGeometry.h" + +#include "mitkBasePropertySerializer.h" + +#include + +#include + +namespace mitk +{ + + PlanarFigureIO::PlanarFigureIO() + : AbstractFileIO(PlanarFigure::GetStaticNameOfClass()) + { + std::string category = "MITK PlanarFigure File"; + CustomMimeType customMimeType; + customMimeType.SetCategory(category); + customMimeType.AddExtension("pf"); + this->AbstractFileIOWriter::SetMimeType(customMimeType); + this->AbstractFileIOWriter::SetDescription(category); + + customMimeType.AddExtension("pf"); + customMimeType.AddExtension("PF"); + this->AbstractFileIOReader::SetMimeType(customMimeType); + this->AbstractFileIOReader::SetDescription(category); + + AbstractFileWriter::SetRanking(10); + AbstractFileReader::SetRanking(10); + this->RegisterService(); + } + + IFileIO::ConfidenceLevel PlanarFigureIO::GetWriterConfidenceLevel() const + { + if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) + return Unsupported; + + const auto *input = static_cast(this->GetInput()); + if (input != nullptr) + return Supported; + else + return Unsupported; + } + + void PlanarFigureIO::Write() + { + this->ValidateOutputLocation(); + + mitk::LocaleSwitch localeSwitch("C"); + + TiXmlDocument document; + auto decl = new TiXmlDeclaration("1.0", "", ""); // TODO what to write here? encoding? etc.... + document.LinkEndChild(decl); + + auto version = new TiXmlElement("Version"); + version->SetAttribute("Writer", __FILE__); + version->SetAttribute("CVSRevision", "$Revision: 17055 $"); + version->SetAttribute("FileVersion", 1); + document.LinkEndChild(version); + + auto pf = dynamic_cast(this->GetInput()); + if (pf == nullptr) + { + mitkThrow() << "Try to safe a BaseData instance as PlanarFigure. That is not a planar figure. This should not happen and is a violated precondition. Please check the program logic."; + } + + auto pfElement = new TiXmlElement("PlanarFigure"); + pfElement->SetAttribute("type", pf->GetNameOfClass()); + document.LinkEndChild(pfElement); + + // Serialize property list of PlanarFigure + mitk::PropertyList::Pointer propertyList = pf->GetPropertyList(); + mitk::PropertyList::PropertyMap::const_iterator it; + for (it = propertyList->GetMap()->begin(); it != propertyList->GetMap()->end(); ++it) + { + // Create seralizer for this property + const mitk::BaseProperty* prop = it->second; + std::string serializerName = std::string(prop->GetNameOfClass()) + "Serializer"; + std::list allSerializers = + itk::ObjectFactoryBase::CreateAllInstance(serializerName.c_str()); + + if (allSerializers.size() != 1) + { + // No or too many serializer(s) found, skip this property + continue; + } + + auto* serializer = + dynamic_cast(allSerializers.begin()->GetPointer()); + if (serializer == nullptr) + { + // Serializer not valid; skip this property + } + + auto keyElement = new TiXmlElement("property"); + keyElement->SetAttribute("key", it->first); + keyElement->SetAttribute("type", prop->GetNameOfClass()); + + serializer->SetProperty(prop); + TiXmlElement* valueElement = nullptr; + try + { + valueElement = serializer->Serialize(); + } + catch (...) + { + } + + if (valueElement == nullptr) + { + // Serialization failed; skip this property + continue; + } + + // Add value to property element + keyElement->LinkEndChild(valueElement); + + // Append serialized property to property list + pfElement->LinkEndChild(keyElement); + } + + // Serialize control points of PlanarFigure + auto controlPointsElement = new TiXmlElement("ControlPoints"); + pfElement->LinkEndChild(controlPointsElement); + for (unsigned int i = 0; i < pf->GetNumberOfControlPoints(); i++) + { + auto vElement = new TiXmlElement("Vertex"); + vElement->SetAttribute("id", i); + vElement->SetDoubleAttribute("x", pf->GetControlPoint(i)[0]); + vElement->SetDoubleAttribute("y", pf->GetControlPoint(i)[1]); + controlPointsElement->LinkEndChild(vElement); + } + auto geoElement = new TiXmlElement("Geometry"); + const auto* planeGeo = dynamic_cast(pf->GetPlaneGeometry()); + if (planeGeo != nullptr) + { + // Write parameters of IndexToWorldTransform of the PlaneGeometry + typedef mitk::Geometry3D::TransformType TransformType; + const TransformType* affineGeometry = planeGeo->GetIndexToWorldTransform(); + const TransformType::ParametersType& parameters = affineGeometry->GetParameters(); + auto vElement = new TiXmlElement("transformParam"); + for (unsigned int i = 0; i < affineGeometry->GetNumberOfParameters(); ++i) + { + std::stringstream paramName; + paramName << "param" << i; + vElement->SetDoubleAttribute(paramName.str().c_str(), parameters.GetElement(i)); + } + geoElement->LinkEndChild(vElement); + + // Write bounds of the PlaneGeometry + typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType; + const BoundsArrayType& bounds = planeGeo->GetBounds(); + vElement = new TiXmlElement("boundsParam"); + for (unsigned int i = 0; i < 6; ++i) + { + std::stringstream boundName; + boundName << "bound" << i; + vElement->SetDoubleAttribute(boundName.str().c_str(), bounds.GetElement(i)); + } + geoElement->LinkEndChild(vElement); + + // Write spacing and origin of the PlaneGeometry + Vector3D spacing = planeGeo->GetSpacing(); + Point3D origin = planeGeo->GetOrigin(); + geoElement->LinkEndChild(this->CreateXMLVectorElement("Spacing", spacing)); + geoElement->LinkEndChild(this->CreateXMLVectorElement("Origin", origin)); + + pfElement->LinkEndChild(geoElement); + } + + if (this->GetOutputStream() != nullptr) + { + *(this->GetOutputStream()) << document; + } + else + { + if (document.SaveFile(this->GetOutputLocation()) == false) + { + MITK_ERROR << "Could not write planar figures to " << this->GetOutputLocation() << "\nTinyXML reports '" << document.ErrorDesc() + << "'"; + throw std::ios_base::failure("Error during writing of planar figure xml file."); + } + } + } + + TiXmlElement* mitk::PlanarFigureIO::CreateXMLVectorElement(const char* name, itk::FixedArray v) + { + auto vElement = new TiXmlElement(name); + vElement->SetDoubleAttribute("x", v.GetElement(0)); + vElement->SetDoubleAttribute("y", v.GetElement(1)); + vElement->SetDoubleAttribute("z", v.GetElement(2)); + return vElement; + } + + IFileIO::ConfidenceLevel PlanarFigureIO::GetReaderConfidenceLevel() const + { + if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) + return Unsupported; + + return Supported; + //Remark: The original reader code assumed that al pf files can be read. + //So no content checking was done. Thus was not implemented while refactoring + //to services yet. But I think it would make sense. + } + + std::vector PlanarFigureIO::DoRead() + { + mitk::LocaleSwitch localeSwitch("C"); + + std::vector results; + + TiXmlDocument document; + + if (this->GetInputStream() != nullptr) + { + std::string s(std::istreambuf_iterator(*(this->GetInputStream())), {}); + document.Parse(s.c_str()); + //Remark: didn't use *(this->GetInputStream()) >> document; + //because our PlanarFigure files version 1 are illformed (multiple top level elements) + //and therefor tinyxml does not read them completly when streamed directly. + //only the first (version element) is read. + } + else + { + if (!document.LoadFile(this->GetInputLocation())) + { + MITK_ERROR << "Could not open/read/parse " << this->GetInputLocation() << ". TinyXML reports: '" << document.ErrorDesc() + << "'. " + << "The error occurred in row " << document.ErrorRow() << ", column " << document.ErrorCol() << "."; + return {}; + } + } + + int fileVersion = 1; + TiXmlElement* versionObject = document.FirstChildElement("Version"); + if (versionObject != nullptr) + { + if (versionObject->QueryIntAttribute("FileVersion", &fileVersion) != TIXML_SUCCESS) + { + MITK_WARN << this->GetInputLocation() << " does not contain version information! Trying version 1 format." << std::endl; + } + } + else + { + MITK_WARN << this->GetInputLocation() << " does not contain version information! Trying version 1 format." << std::endl; + } + if (fileVersion != + 1) // add file version selection and version specific file parsing here, if newer file versions are created + { + MITK_WARN << "File version > 1 is not supported by this reader."; + return {}; + } + + /* file version 1 reader code */ + for (TiXmlElement* pfElement = document.FirstChildElement("PlanarFigure"); pfElement != nullptr; + pfElement = pfElement->NextSiblingElement("PlanarFigure")) + { + std::string type = pfElement->Attribute("type"); + + mitk::PlanarFigure::Pointer planarFigure = nullptr; + if (type == "PlanarAngle") + { + planarFigure = mitk::PlanarAngle::New(); + } + else if (type == "PlanarCircle") + { + planarFigure = mitk::PlanarCircle::New(); + } + else if (type == "PlanarEllipse") + { + planarFigure = mitk::PlanarEllipse::New(); + } + else if (type == "PlanarCross") + { + planarFigure = mitk::PlanarCross::New(); + } + else if (type == "PlanarFourPointAngle") + { + planarFigure = mitk::PlanarFourPointAngle::New(); + } + else if (type == "PlanarLine") + { + planarFigure = mitk::PlanarLine::New(); + } + else if (type == "PlanarPolygon") + { + planarFigure = mitk::PlanarPolygon::New(); + } + else if (type == "PlanarSubdivisionPolygon") + { + planarFigure = mitk::PlanarSubdivisionPolygon::New(); + } + else if (type == "PlanarRectangle") + { + planarFigure = mitk::PlanarRectangle::New(); + } + else if (type == "PlanarArrow") + { + planarFigure = mitk::PlanarArrow::New(); + } + else if (type == "PlanarDoubleEllipse") + { + planarFigure = mitk::PlanarDoubleEllipse::New(); + } + else if (type == "PlanarBezierCurve") + { + planarFigure = mitk::PlanarBezierCurve::New(); + } + else + { + // unknown type + MITK_WARN << "encountered unknown planar figure type '" << type << "'. Skipping this element."; + continue; + } + + // Read properties of the planar figure + for (TiXmlElement* propertyElement = pfElement->FirstChildElement("property"); propertyElement != nullptr; + propertyElement = propertyElement->NextSiblingElement("property")) + { + const char* keya = propertyElement->Attribute("key"); + const std::string key(keya ? keya : ""); + + const char* typea = propertyElement->Attribute("type"); + const std::string type(typea ? typea : ""); + + // hand propertyElement to specific reader + std::stringstream propertyDeserializerClassName; + propertyDeserializerClassName << type << "Serializer"; + + const std::list readers = + itk::ObjectFactoryBase::CreateAllInstance(propertyDeserializerClassName.str().c_str()); + if (readers.size() < 1) + { + MITK_ERROR << "No property reader found for " << type; + } + if (readers.size() > 1) + { + MITK_WARN << "Multiple property readers found for " << type << ". Using arbitrary first one."; + } + + for (auto iter = readers.cbegin(); iter != readers.cend(); ++iter) + { + if (auto* reader = dynamic_cast(iter->GetPointer())) + { + const BaseProperty::Pointer property = reader->Deserialize(propertyElement->FirstChildElement()); + if (property.IsNotNull()) + { + planarFigure->GetPropertyList()->ReplaceProperty(key, property); + } + else + { + MITK_ERROR << "There were errors while loading property '" << key << "' of type " << type + << ". Your data may be corrupted"; + } + break; + } + } + } + + // If we load a planarFigure, it has definitely been placed correctly. + // If we do not set this property here, we cannot load old planarFigures + // without messing up the interaction (PF-Interactor needs this property. + planarFigure->GetPropertyList()->SetBoolProperty("initiallyplaced", true); + + // Which features (length or circumference etc) a figure has is decided by whether it is closed or not + // the function SetClosed has to be called in case of PlanarPolygons to ensure they hold the correct feature + auto* planarPolygon = dynamic_cast(planarFigure.GetPointer()); + if (planarPolygon != nullptr) + { + bool isClosed = false; + planarFigure->GetPropertyList()->GetBoolProperty("closed", isClosed); + planarPolygon->SetClosed(isClosed); + } + + // Read geometry of containing plane + TiXmlElement* geoElement = pfElement->FirstChildElement("Geometry"); + if (geoElement != nullptr) + { + try + { + // Create plane geometry + mitk::PlaneGeometry::Pointer planeGeo = mitk::PlaneGeometry::New(); + + // Extract and set plane transform parameters + const DoubleList transformList = + this->GetDoubleAttributeListFromXMLNode(geoElement->FirstChildElement("transformParam"), "param", 12); + + typedef mitk::BaseGeometry::TransformType TransformType; + TransformType::ParametersType parameters; + parameters.SetSize(12); + + unsigned int i; + DoubleList::const_iterator it; + for (it = transformList.cbegin(), i = 0; it != transformList.cend(); ++it, ++i) + { + parameters.SetElement(i, *it); + } + + typedef mitk::BaseGeometry::TransformType TransformType; + TransformType::Pointer affineGeometry = TransformType::New(); + affineGeometry->SetParameters(parameters); + planeGeo->SetIndexToWorldTransform(affineGeometry); + + // Extract and set plane bounds + const DoubleList boundsList = + this->GetDoubleAttributeListFromXMLNode(geoElement->FirstChildElement("boundsParam"), "bound", 6); + + typedef mitk::BaseGeometry::BoundsArrayType BoundsArrayType; + + BoundsArrayType bounds; + for (it = boundsList.cbegin(), i = 0; it != boundsList.cend(); ++it, ++i) + { + bounds[i] = *it; + } + + planeGeo->SetBounds(bounds); + + // Extract and set spacing and origin + const Vector3D spacing = this->GetVectorFromXMLNode(geoElement->FirstChildElement("Spacing")); + planeGeo->SetSpacing(spacing); + + const Point3D origin = this->GetPointFromXMLNode(geoElement->FirstChildElement("Origin")); + planeGeo->SetOrigin(origin); + planarFigure->SetPlaneGeometry(planeGeo); + } + catch (...) + { + } + } + TiXmlElement* cpElement = pfElement->FirstChildElement("ControlPoints"); + bool first = true; + if (cpElement != nullptr) + for (TiXmlElement* vertElement = cpElement->FirstChildElement("Vertex"); vertElement != nullptr; + vertElement = vertElement->NextSiblingElement("Vertex")) + { + int id = 0; + mitk::Point2D::ValueType x = 0.0; + mitk::Point2D::ValueType y = 0.0; + if (vertElement->QueryIntAttribute("id", &id) == TIXML_WRONG_TYPE) + return{}; // TODO: can we do a better error handling? + if (vertElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE) + return{}; // TODO: can we do a better error handling? + if (vertElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE) + return{}; // TODO: can we do a better error handling? + Point2D p; + p.SetElement(0, x); + p.SetElement(1, y); + if (first == true) // needed to set m_FigurePlaced to true + { + planarFigure->PlaceFigure(p); + first = false; + } + planarFigure->SetControlPoint(id, p, true); + } + + // Calculate feature quantities of this PlanarFigure + planarFigure->EvaluateFeatures(); + + // Make sure that no control point is currently selected + planarFigure->DeselectControlPoint(); + + if (planarFigure.IsNotNull()) + { + results.emplace_back(planarFigure); + } + } + + return results; + } + + mitk::PlanarFigureIO::DoubleList mitk::PlanarFigureIO::GetDoubleAttributeListFromXMLNode( + TiXmlElement* e, const char* attributeNameBase, unsigned int count) + { + DoubleList list; + + if (e == nullptr) + throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling? + + for (unsigned int i = 0; i < count; ++i) + { + mitk::ScalarType p(-1.0); + std::stringstream attributeName; + attributeName << attributeNameBase << i; + + if (e->QueryDoubleAttribute(attributeName.str().c_str(), &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + list.push_back(p); + } + + return list; + } + + mitk::Point3D mitk::PlanarFigureIO::GetPointFromXMLNode(TiXmlElement* e) + { + if (e == nullptr) + throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling? + mitk::Point3D point; + mitk::ScalarType p(-1.0); + if (e->QueryDoubleAttribute("x", &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + point.SetElement(0, p); + if (e->QueryDoubleAttribute("y", &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + point.SetElement(1, p); + if (e->QueryDoubleAttribute("z", &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + point.SetElement(2, p); + return point; + } + + mitk::Vector3D mitk::PlanarFigureIO::GetVectorFromXMLNode(TiXmlElement* e) + { + if (e == nullptr) + throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling? + mitk::Vector3D vector; + mitk::ScalarType p(-1.0); + if (e->QueryDoubleAttribute("x", &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + vector.SetElement(0, p); + if (e->QueryDoubleAttribute("y", &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + vector.SetElement(1, p); + if (e->QueryDoubleAttribute("z", &p) == TIXML_WRONG_TYPE) + throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? + vector.SetElement(2, p); + return vector; + } + + PlanarFigureIO *PlanarFigureIO::IOClone() const { return new PlanarFigureIO(*this); } + +} // namespace diff --git a/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIO.h b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIO.h new file mode 100644 index 0000000000..215ca99134 --- /dev/null +++ b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIO.h @@ -0,0 +1,92 @@ +/*============================================================================ + +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 MITK_PLANAR_FIGURE_IO_H +#define MITK_PLANAR_FIGURE_IO_H + +#include +#include + +class TiXmlElement; + +namespace mitk +{ + /** + * Reads/Writes a PlanarFigure to a file + * @ingroup Process + */ + class PlanarFigureIO : public mitk::AbstractFileIO + { + public: + typedef mitk::PlanarFigure InputType; + + PlanarFigureIO(); + + // -------------- AbstractFileReader ------------- + + using AbstractFileReader::Read; + + ConfidenceLevel GetReaderConfidenceLevel() const override; + + // -------------- AbstractFileWriter ------------- + + void Write() override; + ConfidenceLevel GetWriterConfidenceLevel() const override; + + protected: + /** + * @brief Reads a number of mitk::PlanarFigures from the file system + * @return a vector of mitk::PlanarFigures + * @throws throws an mitk::Exception if an error ocurrs during parsing the nrrd header + */ + std::vector> DoRead() override; + + using DoubleList = std::list; + /** + * \brief parses the element for the attributes name0 to nameN, where "name" and the number of attributes + * to read are passed as argument. Returns a list of double vales. + * \param[in] e the TiXmlElement that will be parsed + * \param[in] attributeNameBase the basic name of the parameters + * \param[in] count the number of parameters + * \return returns a mitk::Point3D with the values x,y,z + */ + DoubleList GetDoubleAttributeListFromXMLNode(TiXmlElement* e, const char* attributeNameBase, unsigned int count); + + /** + * \brief parses the element for the attributes x,y,z and returns a mitk::Vector3D filled with these values + * \param[in] e the TiXmlElement that will be parsed + * \return returns a mitk::Vector3D with the values x,y,z + */ + static mitk::Vector3D GetVectorFromXMLNode(TiXmlElement* e); + + /** + * \brief parses the element for the attributes x,y,z and returns a mitk::Point3D filled with these values + * \param[in] e the TiXmlElement that will be parsed + * \return returns a mitk::Point3D with the values x,y,z + */ + static mitk::Point3D GetPointFromXMLNode(TiXmlElement* e); + + /**Documentation + * \brief creates a TinyXML element that contains x, y, and z values + * + * \param[in] name the name of the XML element + * \param[in] v the vector or point that contains the x, y and z values + * \return returns a TiXmlElement named name and three attributes x, y and z. + */ + static TiXmlElement* CreateXMLVectorElement(const char* name, itk::FixedArray v); + + private: + PlanarFigureIO *IOClone() const override; + }; +} // end of namespace mitk + +#endif // MITK_PLANAR_FIGURE_IO_H diff --git a/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIOActivator.cpp b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIOActivator.cpp new file mode 100644 index 0000000000..4c509d33b9 --- /dev/null +++ b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureIOActivator.cpp @@ -0,0 +1,44 @@ +/*============================================================================ + +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 "mitkPlanarFigureIO.h" + +namespace mitk +{ + /** + \brief Registers IO services for PlanarFigure module. + */ + class PlanarFigureIOModuleActivator : public us::ModuleActivator + { + std::vector m_FileIOs; + + public: + void Load(us::ModuleContext * /*context*/) override + { + m_FileIOs.push_back(new PlanarFigureIO()); + } + void Unload(us::ModuleContext *) override + { + for (auto &elem : m_FileIOs) + { + delete elem; + } + } + }; +} + +US_EXPORT_MODULE_ACTIVATOR(mitk::PlanarFigureIOModuleActivator) diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureSerializer.cpp b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSerializer.cpp similarity index 87% rename from Modules/PlanarFigure/src/IO/mitkPlanarFigureSerializer.cpp rename to Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSerializer.cpp index 3cb1fb983b..d9e932a10e 100644 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureSerializer.cpp +++ b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSerializer.cpp @@ -1,62 +1,60 @@ /*============================================================================ 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 "mitkPlanarFigureSerializer.h" #include "mitkPlanarFigure.h" -#include "mitkPlanarFigureWriter.h" + +#include #include MITK_REGISTER_SERIALIZER(PlanarFigureSerializer) mitk::PlanarFigureSerializer::PlanarFigureSerializer() { } mitk::PlanarFigureSerializer::~PlanarFigureSerializer() { } std::string mitk::PlanarFigureSerializer::Serialize() { const auto *pf = dynamic_cast(m_Data.GetPointer()); if (pf == nullptr) { MITK_ERROR << " Object at " << (const void *)this->m_Data << " is not an mitk::PlanarFigure. Cannot serialize as PlanarFigure."; return ""; } std::string filename(this->GetUniqueFilenameInWorkingDirectory()); filename += "_"; filename += m_FilenameHint; filename += ".pf"; std::string fullname(m_WorkingDirectory); fullname += "/"; fullname += itksys::SystemTools::ConvertToOutputPath(filename.c_str()); try { - PlanarFigureWriter::Pointer writer = PlanarFigureWriter::New(); - writer->SetFileName(fullname); - writer->SetInput(const_cast(pf)); - writer->Write(); + mitk::IOUtil::Save(pf, fullname); } catch (std::exception &e) { MITK_ERROR << " Error serializing object at " << (const void *)this->m_Data << " to " << fullname << ": " << e.what(); return ""; } return filename; } diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureSerializer.h b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSerializer.h similarity index 100% rename from Modules/PlanarFigure/src/IO/mitkPlanarFigureSerializer.h rename to Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSerializer.h diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureSubclassesSerializer.cpp b/Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSubclassesSerializer.cpp similarity index 100% rename from Modules/PlanarFigure/src/IO/mitkPlanarFigureSubclassesSerializer.cpp rename to Modules/PlanarFigure/autoload/IO/mitkPlanarFigureSubclassesSerializer.cpp diff --git a/Modules/PlanarFigure/files.cmake b/Modules/PlanarFigure/files.cmake index dc4d3b3be2..321b93d75a 100644 --- a/Modules/PlanarFigure/files.cmake +++ b/Modules/PlanarFigure/files.cmake @@ -1,37 +1,31 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES Algorithms/mitkExtrudePlanarFigureFilter.cpp Algorithms/mitkImageToPlanarFigureFilter.cpp Algorithms/mitkPlanarFigureObjectFactory.cpp Algorithms/mitkPlanarFigureSource.cpp Algorithms/mitkPlanarFigureToPlanarFigureFilter.cpp DataManagement/mitkPlanarAngle.cpp DataManagement/mitkPlanarBezierCurve.cpp DataManagement/mitkPlanarCircle.cpp DataManagement/mitkPlanarDoubleEllipse.cpp DataManagement/mitkPlanarEllipse.cpp DataManagement/mitkPlanarCross.cpp DataManagement/mitkPlanarFigure.cpp DataManagement/mitkPlanarFourPointAngle.cpp DataManagement/mitkPlanarLine.cpp DataManagement/mitkPlanarArrow.cpp DataManagement/mitkPlanarPolygon.cpp DataManagement/mitkPlanarSubdivisionPolygon.cpp DataManagement/mitkPlanarRectangle.cpp DataManagement/mitkPlanarFigureControlPointStyleProperty.cpp - IO/mitkPlanarFigureIOFactory.cpp - IO/mitkPlanarFigureReader.cpp - IO/mitkPlanarFigureWriter.cpp - IO/mitkPlanarFigureWriterFactory.cpp - IO/mitkPlanarFigureSerializer.cpp - IO/mitkPlanarFigureSubclassesSerializer.cpp Interactions/mitkPlanarFigureInteractor.cpp Rendering/mitkPlanarFigureMapper2D.cpp Rendering/mitkPlanarFigureVtkMapper3D.cpp ) set(RESOURCE_FILES Interactions/PlanarFigureConfig.xml Interactions/PlanarFigureInteraction.xml ) diff --git a/Modules/PlanarFigure/include/mitkPlanarFigureObjectFactory.h b/Modules/PlanarFigure/include/mitkPlanarFigureObjectFactory.h index d524154b3f..5bfb6260bb 100644 --- a/Modules/PlanarFigure/include/mitkPlanarFigureObjectFactory.h +++ b/Modules/PlanarFigure/include/mitkPlanarFigureObjectFactory.h @@ -1,56 +1,48 @@ /*============================================================================ 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 PLANARFIGUREOBJECTFACTORY_H_INCLUDED #define PLANARFIGUREOBJECTFACTORY_H_INCLUDED #include "mitkCoreObjectFactoryBase.h" #include namespace mitk { class MITKPLANARFIGURE_EXPORT PlanarFigureObjectFactory : public CoreObjectFactoryBase { public: mitkClassMacro(PlanarFigureObjectFactory, CoreObjectFactoryBase); itkFactorylessNewMacro(Self); itkCloneMacro(Self); ~PlanarFigureObjectFactory() override; Mapper::Pointer CreateMapper(mitk::DataNode *node, MapperSlotId slotId) override; void SetDefaultProperties(mitk::DataNode *node) override; const char *GetFileExtensions() override; mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap() override; const char *GetSaveFileExtensions() override; mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap() override; - DEPRECATED(void RegisterIOFactories()); - protected: PlanarFigureObjectFactory(); void CreateFileExtensionsMap(); - MultimapType m_FileExtensionsMap; - MultimapType m_SaveFileExtensionsMap; - - private: - itk::ObjectFactoryBase::Pointer m_PlanarFigureIOFactory; - itk::ObjectFactoryBase::Pointer m_PlanarFigureWriterFactory; }; } #endif // PLANARFIGUREOBJECTFACTORY_H_INCLUDED diff --git a/Modules/PlanarFigure/include/mitkPlanarFigureReader.h b/Modules/PlanarFigure/include/mitkPlanarFigureReader.h deleted file mode 100644 index c565b99055..0000000000 --- a/Modules/PlanarFigure/include/mitkPlanarFigureReader.h +++ /dev/null @@ -1,148 +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. - -============================================================================*/ - -#ifndef _MITK_PlanarFigureReader__H_ -#define _MITK_PlanarFigureReader__H_ - -#include "mitkFileReader.h" -#include "mitkPlanarFigureSource.h" -#include - -#include - -class TiXmlElement; -namespace mitk -{ - /** - * @brief reads xml representations of mitk::PlanarFigure from a file - * - * Reader for xml files containing one or multiple xml represenations of - * mitk::PlanarFigure. If multiple mitk::PlanarFigure are stored in one file, - * these are assigned to multiple outputs of the filter. - * @ingroup MitkPlanarFigureModule - */ - class MITKPLANARFIGURE_EXPORT PlanarFigureReader : public PlanarFigureSource, public FileReader - { - public: - mitkClassMacro(PlanarFigureReader, FileReader); - - itkFactorylessNewMacro(Self); - - itkCloneMacro(Self); - - /** - * @brief Sets the filename of the file to be read - * @param _arg the filename of the point set xml-file - */ - itkSetStringMacro(FileName); - - /** - * @brief Returns the filename of the point set xml-file. - * @returns the filename of the point set xml-file. - */ - itkGetStringMacro(FileName); - - /** - * @warning multiple load not (yet) supported - */ - itkSetStringMacro(FilePrefix); - - /** - * @warning multiple load not (yet) supported - */ - itkGetStringMacro(FilePrefix); - - /** - * @warning multiple load not (yet) supported - */ - itkSetStringMacro(FilePattern); - - /** - * @warning multiple load not (yet) supported - */ - itkGetStringMacro(FilePattern); - - static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern); - - /** - * @returns whether the last read attempt was successful or not. - */ - itkGetConstMacro(Success, bool); - - protected: - typedef std::list DoubleList; - - /** - * Constructor - */ - PlanarFigureReader(); - - /** - * Virtual destructor - */ - ~PlanarFigureReader() override; - - /** - * Actually reads the point sets from the given file - */ - void GenerateData() override; - - /** - * Does nothing in the current implementation - */ - void GenerateOutputInformation() override; - - /** - * Resizes the output-objects according to the given number. - * @param num the new number of output objects. - */ - virtual void ResizeOutputs(const unsigned int &num); - - /** - * Checks if the given file has appropriate - * read access. - * @returns true if the file exists and may be read - * or false otherwise. - */ - virtual int CanReadFile(const char *name); - - /** - * \brief parses the element for the attributes x,y,z and returns a mitk::Vector3D filled with these values - * \param[in] e the TiXmlElement that will be parsed - * \return returns a mitk::Vector3D with the values x,y,z - */ - mitk::Vector3D GetVectorFromXMLNode(TiXmlElement *e); - - /** - * \brief parses the element for the attributes x,y,z and returns a mitk::Point3D filled with these values - * \param[in] e the TiXmlElement that will be parsed - * \return returns a mitk::Point3D with the values x,y,z - */ - mitk::Point3D GetPointFromXMLNode(TiXmlElement *e); - - /** - * \brief parses the element for the attributes name0 to nameN, where "name" and the number of attributes - * to read are passed as argument. Returns a list of double vales. - * \param[in] e the TiXmlElement that will be parsed - * \param[in] attributeNameBase the basic name of the parameters - * \param[in] count the number of parameters - * \return returns a mitk::Point3D with the values x,y,z - */ - DoubleList GetDoubleAttributeListFromXMLNode(TiXmlElement *e, const char *attributeNameBase, unsigned int count); - - std::string m_FileName; - std::string m_FilePrefix; - std::string m_FilePattern; - bool m_Success; - }; -} -#endif diff --git a/Modules/PlanarFigure/include/mitkPlanarFigureWriter.h b/Modules/PlanarFigure/include/mitkPlanarFigureWriter.h deleted file mode 100644 index ff4fc6476e..0000000000 --- a/Modules/PlanarFigure/include/mitkPlanarFigureWriter.h +++ /dev/null @@ -1,198 +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. - -============================================================================*/ - -#ifndef _MITK_PlanarFigure_WRITER__H_ -#define _MITK_PlanarFigure_WRITER__H_ - -#include -#include -#include -#include - -class TiXmlElement; -namespace mitk -{ - /** - * @brief XML-based writer for mitk::PlanarFigures - * - * XML-based writer for mitk::PlanarFigures. - * @ingroup MitkPlanarFigureModule - */ - class MITKPLANARFIGURE_EXPORT PlanarFigureWriter : public mitk::FileWriterWithInformation - { - public: - mitkClassMacro(PlanarFigureWriter, mitk::FileWriter); - - mitkWriterMacro; - - itkFactorylessNewMacro(Self); - - itkCloneMacro(Self); - - typedef mitk::PlanarFigure InputType; - - typedef InputType::Pointer InputTypePointer; - - /** - * Sets the filename of the file to write. - * @param FileName the name of the file to write. - */ - itkSetStringMacro(FileName); - - /** - * @returns the name of the file to be written to disk. - */ - itkGetStringMacro(FileName); - - /** - * @warning multiple write not (yet) supported - */ - itkSetStringMacro(FilePrefix); - - /** - * @warning multiple write not (yet) supported - */ - itkGetStringMacro(FilePrefix); - - /** - * @warning multiple write not (yet) supported - */ - itkSetStringMacro(FilePattern); - - /** - * @warning multiple write not (yet) supported - */ - itkGetStringMacro(FilePattern); - - using Superclass::SetInput; - - /** - * Sets the 0'th input object for the filter. - * @param input the first input for the filter. - */ - void SetInput(InputType *input); - - /** - * Sets the n'th input object for the filter. If num is - * larger than GetNumberOfInputs() the number of inputs is - * resized appropriately. - * @param input the n'th input for the filter. - */ - void SetInput(const unsigned int &num, InputType *input); - - /** - * @returns the 0'th input object of the filter. - */ - PlanarFigure *GetInput(); - - /** - * @param num the index of the desired output object. - * @returns the n'th input object of the filter. - */ - PlanarFigure *GetInput(const unsigned int &num); - - /** - * @brief Return the possible file extensions for the data type associated with the writer - */ - std::vector GetPossibleFileExtensions() override; - - /** - * @brief Return the extension to be added to the filename. - */ - std::string GetFileExtension() override; - - /** - * @brief Check if the Writer can write the Content of the - */ - bool CanWriteDataType(DataNode *) override; - - /** - * @brief Return the MimeType of the saved File. - */ - std::string GetWritenMIMEType() override; - - /** - * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. - */ - virtual void SetInput(DataNode *); - - std::string GetSupportedBaseData() const override; - - /** - * @returns whether the last write attempt was successful or not. - */ - itkGetConstMacro(Success, bool); - - const char *GetDefaultFilename() override { return "PlanarFigure.pf"; } - const char *GetFileDialogPattern() override { return "Planar Figure Files (*.pf)"; } - const char *GetDefaultExtension() override { return ".pf"; } - bool CanWriteBaseDataType(BaseData::Pointer data) override - { - return dynamic_cast(data.GetPointer()); - } - void DoWrite(BaseData::Pointer data) override - { - if (CanWriteBaseDataType(data)) - { - this->SetInput(dynamic_cast(data.GetPointer())); - this->Update(); - } - } - - /** - @brief CAUTION: It's up to the user to call this function to release the - memory buffer after use in case the file writer has written to its memory array. - See mitkFileWriter base class. */ - void ReleaseMemory() override; - - protected: - /** - * Constructor. - */ - PlanarFigureWriter(); - - /** - * Virtual destructor. - */ - ~PlanarFigureWriter() override; - - /** - * Writes the a .pf file in xml format that contains all input planar figures - */ - void GenerateData() override; - - /** - * Resizes the number of inputs of the writer. - * The inputs are initialized by empty PlanarFigures - * @param num the new number of inputs - */ - virtual void ResizeInputs(const unsigned int &num); - - /**Documentation - * \brief creates a TinyXML element that contains x, y, and z values - * - * \param[in] name the name of the XML element - * \param[in] v the vector or point that contains the x, y and z values - * \return returns a TiXmlElement named name and three attributes x, y and z. - */ - TiXmlElement *CreateXMLVectorElement(const char *name, itk::FixedArray v); - - std::string m_FileName; - std::string m_FilePrefix; - std::string m_FilePattern; - std::string m_Extension; - std::string m_MimeType; - bool m_Success; - }; -} - -#endif diff --git a/Modules/PlanarFigure/src/Algorithms/mitkPlanarFigureObjectFactory.cpp b/Modules/PlanarFigure/src/Algorithms/mitkPlanarFigureObjectFactory.cpp index ab07c731b3..6ab9c276c3 100644 --- a/Modules/PlanarFigure/src/Algorithms/mitkPlanarFigureObjectFactory.cpp +++ b/Modules/PlanarFigure/src/Algorithms/mitkPlanarFigureObjectFactory.cpp @@ -1,136 +1,117 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkPlanarFigureObjectFactory.h" -#include "mitkPlanarFigureWriter.h" #include "mitkCoreObjectFactory.h" #include "mitkPlanarFigure.h" -#include "mitkPlanarFigureIOFactory.h" #include "mitkPlanarFigureMapper2D.h" #include "mitkPlanarFigureVtkMapper3D.h" -#include "mitkPlanarFigureWriterFactory.h" #include "mitkVtkGLMapperWrapper.h" typedef std::multimap MultimapType; mitk::PlanarFigureObjectFactory::PlanarFigureObjectFactory() - : m_PlanarFigureIOFactory(PlanarFigureIOFactory::New().GetPointer()), - m_PlanarFigureWriterFactory(PlanarFigureWriterFactory::New().GetPointer()) { static bool alreadyDone = false; if (!alreadyDone) { - itk::ObjectFactoryBase::RegisterFactory(m_PlanarFigureIOFactory); - itk::ObjectFactoryBase::RegisterFactory(m_PlanarFigureWriterFactory); - - m_FileWriters.push_back(PlanarFigureWriter::New().GetPointer()); - CreateFileExtensionsMap(); alreadyDone = true; } } mitk::PlanarFigureObjectFactory::~PlanarFigureObjectFactory() { - itk::ObjectFactoryBase::UnRegisterFactory(m_PlanarFigureWriterFactory); - itk::ObjectFactoryBase::UnRegisterFactory(m_PlanarFigureIOFactory); } mitk::Mapper::Pointer mitk::PlanarFigureObjectFactory::CreateMapper(mitk::DataNode *node, MapperSlotId id) { mitk::Mapper::Pointer newMapper = nullptr; mitk::BaseData *data = node->GetData(); if (dynamic_cast(data) != nullptr) { if (id == mitk::BaseRenderer::Standard2D) { newMapper = mitk::PlanarFigureMapper2D::New(); newMapper->SetDataNode(node); } else if (id == mitk::BaseRenderer::Standard3D) { newMapper = mitk::PlanarFigureVtkMapper3D::New(); newMapper->SetDataNode(node); } } return newMapper; } void mitk::PlanarFigureObjectFactory::SetDefaultProperties(mitk::DataNode *node) { if (node == nullptr) { return; } mitk::DataNode::Pointer nodePointer = node; mitk::PlanarFigure::Pointer pf = dynamic_cast(node->GetData()); if (pf.IsNotNull()) { mitk::PlanarFigureMapper2D::SetDefaultProperties(node); mitk::PlanarFigureVtkMapper3D::SetDefaultProperties(node); node->AddProperty("color", mitk::ColorProperty::New(1.0, 1.0, 1.0), nullptr, true); node->AddProperty("opacity", mitk::FloatProperty::New(0.8), nullptr, true); } } const char *mitk::PlanarFigureObjectFactory::GetFileExtensions() { return ""; } mitk::CoreObjectFactoryBase::MultimapType mitk::PlanarFigureObjectFactory::GetFileExtensionsMap() { - return m_FileExtensionsMap; + return {}; } const char *mitk::PlanarFigureObjectFactory::GetSaveFileExtensions() { - // return ";;Planar Figures (*.pf)"; // for mitk::PlanarFigure and derived classes std::string fileExtension; - this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); + this->CreateFileExtensions({}, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::PlanarFigureObjectFactory::GetSaveFileExtensionsMap() { - return m_SaveFileExtensionsMap; + return {}; } void mitk::PlanarFigureObjectFactory::CreateFileExtensionsMap() -{ - m_FileExtensionsMap.insert(std::pair("*.pf", "Planar Figure Files")); - m_SaveFileExtensionsMap.insert(std::pair("*.pf", "Planar Figure Files")); -} - -void mitk::PlanarFigureObjectFactory::RegisterIOFactories() { } struct RegisterPlanarFigureObjectFactory { RegisterPlanarFigureObjectFactory() : m_Factory(mitk::PlanarFigureObjectFactory::New()) { mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(m_Factory); } ~RegisterPlanarFigureObjectFactory() { mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory(m_Factory); } mitk::PlanarFigureObjectFactory::Pointer m_Factory; }; static RegisterPlanarFigureObjectFactory registerPlanarFigureObjectFactory; diff --git a/Modules/PlanarFigure/src/DataManagement/mitkPlanarFigure.cpp b/Modules/PlanarFigure/src/DataManagement/mitkPlanarFigure.cpp index d135f3e58a..eb64366acd 100644 --- a/Modules/PlanarFigure/src/DataManagement/mitkPlanarFigure.cpp +++ b/Modules/PlanarFigure/src/DataManagement/mitkPlanarFigure.cpp @@ -1,781 +1,781 @@ /*============================================================================ 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 "mitkPlanarFigure.h" #include "mitkPlaneGeometry.h" #include #include #include mitk::PlanarFigure::PlanarFigure() : m_SelectedControlPoint(-1), m_PreviewControlPointVisible(false), m_FigurePlaced(false), m_PlaneGeometry(nullptr), m_PolyLineUpToDate(false), m_HelperLinesUpToDate(false), m_FeaturesUpToDate(false), m_FeaturesMTime(0) { m_HelperPolyLinesToBePainted = BoolContainerType::New(); m_DisplaySize.first = 0.0; m_DisplaySize.second = 0; this->SetProperty("closed", mitk::BoolProperty::New(false)); // Currently only single-time-step geometries are supported this->InitializeTimeGeometry(1); } mitk::PlanarFigure::PlanarFigure(const Self &other) : BaseData(other), m_ControlPoints(other.m_ControlPoints), m_NumberOfControlPoints(other.m_NumberOfControlPoints), m_SelectedControlPoint(other.m_SelectedControlPoint), m_PolyLines(other.m_PolyLines), m_HelperPolyLines(other.m_HelperPolyLines), m_PreviewControlPoint(other.m_PreviewControlPoint), m_PreviewControlPointVisible(other.m_PreviewControlPointVisible), m_FigurePlaced(other.m_FigurePlaced), - m_PlaneGeometry(other.m_PlaneGeometry), // do not clone since SetPlaneGeometry() doesn't clone either m_PolyLineUpToDate(other.m_PolyLineUpToDate), m_HelperLinesUpToDate(other.m_HelperLinesUpToDate), m_FeaturesUpToDate(other.m_FeaturesUpToDate), m_Features(other.m_Features), m_FeaturesMTime(other.m_FeaturesMTime), m_DisplaySize(other.m_DisplaySize) { m_HelperPolyLinesToBePainted = BoolContainerType::New(); for (unsigned long i = 0; i < other.m_HelperPolyLinesToBePainted->Size(); ++i) { m_HelperPolyLinesToBePainted->InsertElement(i, other.m_HelperPolyLinesToBePainted->GetElement(i)); } + m_PlaneGeometry = dynamic_cast(GetGeometry(0)); } void mitk::PlanarFigure::SetPlaneGeometry(mitk::PlaneGeometry *geometry) { this->SetGeometry(geometry); m_PlaneGeometry = dynamic_cast(GetGeometry(0)); // geometry; } const mitk::PlaneGeometry *mitk::PlanarFigure::GetPlaneGeometry() const { return m_PlaneGeometry; } bool mitk::PlanarFigure::IsClosed() const { mitk::BoolProperty *closed = dynamic_cast(this->GetProperty("closed").GetPointer()); if (closed != nullptr) { return closed->GetValue(); } return false; } void mitk::PlanarFigure::PlaceFigure(const mitk::Point2D &point) { for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i) { m_ControlPoints.push_back(this->ApplyControlPointConstraints(i, point)); } m_FigurePlaced = true; m_SelectedControlPoint = 1; } bool mitk::PlanarFigure::AddControlPoint(const mitk::Point2D &point, int position) { // if we already have the maximum number of control points, do nothing if (m_NumberOfControlPoints < this->GetMaximumNumberOfControlPoints()) { // if position has not been defined or position would be the last control point, just append the new one // we also append a new point if we click onto the line between the first two control-points if the second // control-point is selected // -> special case for PlanarCross if (position == -1 || position > (int)m_NumberOfControlPoints - 1 || (position == 1 && m_SelectedControlPoint == 2)) { if (m_ControlPoints.size() > this->GetMaximumNumberOfControlPoints() - 1) { // get rid of deprecated control points in the list. This is necessary // as ::ResetNumberOfControlPoints() only sets the member, does not resize the list! m_ControlPoints.resize(this->GetNumberOfControlPoints()); } m_ControlPoints.push_back(this->ApplyControlPointConstraints(m_NumberOfControlPoints, point)); m_SelectedControlPoint = m_NumberOfControlPoints; } else { // insert the point at the given position and set it as selected point auto iter = m_ControlPoints.begin() + position; m_ControlPoints.insert(iter, this->ApplyControlPointConstraints(position, point)); for (unsigned int i = 0; i < m_ControlPoints.size(); ++i) { if (point == m_ControlPoints.at(i)) { m_SelectedControlPoint = i; } } } // polylines & helperpolylines need to be repainted m_PolyLineUpToDate = false; m_HelperLinesUpToDate = false; m_FeaturesUpToDate = false; // one control point more ++m_NumberOfControlPoints; return true; } else { return false; } } bool mitk::PlanarFigure::SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist) { bool controlPointSetCorrectly = false; if (createIfDoesNotExist) { if (m_NumberOfControlPoints <= index) { m_ControlPoints.push_back(this->ApplyControlPointConstraints(index, point)); m_NumberOfControlPoints++; } else { m_ControlPoints.at(index) = this->ApplyControlPointConstraints(index, point); } controlPointSetCorrectly = true; } else if (index < m_NumberOfControlPoints) { m_ControlPoints.at(index) = this->ApplyControlPointConstraints(index, point); controlPointSetCorrectly = true; } else { return false; } if (controlPointSetCorrectly) { m_PolyLineUpToDate = false; m_HelperLinesUpToDate = false; m_FeaturesUpToDate = false; } return controlPointSetCorrectly; } bool mitk::PlanarFigure::SetCurrentControlPoint(const Point2D &point) { if ((m_SelectedControlPoint < 0) || (m_SelectedControlPoint >= (int)m_NumberOfControlPoints)) { return false; } return this->SetControlPoint(m_SelectedControlPoint, point, false); } unsigned int mitk::PlanarFigure::GetNumberOfControlPoints() const { return m_NumberOfControlPoints; } bool mitk::PlanarFigure::SelectControlPoint(unsigned int index) { if (index < this->GetNumberOfControlPoints()) { m_SelectedControlPoint = index; return true; } else { return false; } } bool mitk::PlanarFigure::DeselectControlPoint() { bool wasSelected = (m_SelectedControlPoint != -1); m_SelectedControlPoint = -1; return wasSelected; } void mitk::PlanarFigure::SetPreviewControlPoint(const Point2D &point) { m_PreviewControlPoint = point; m_PreviewControlPointVisible = true; } void mitk::PlanarFigure::ResetPreviewContolPoint() { m_PreviewControlPointVisible = false; } mitk::Point2D mitk::PlanarFigure::GetPreviewControlPoint() const { return m_PreviewControlPoint; } bool mitk::PlanarFigure::IsPreviewControlPointVisible() const { return m_PreviewControlPointVisible; } mitk::Point2D mitk::PlanarFigure::GetControlPoint(unsigned int index) const { if (index < m_NumberOfControlPoints) { return m_ControlPoints.at(index); } itkExceptionMacro(<< "GetControlPoint(): Invalid index!"); } mitk::Point3D mitk::PlanarFigure::GetWorldControlPoint(unsigned int index) const { Point3D point3D; if ((m_PlaneGeometry != nullptr) && (index < m_NumberOfControlPoints)) { m_PlaneGeometry->Map(m_ControlPoints.at(index), point3D); return point3D; } itkExceptionMacro(<< "GetWorldControlPoint(): Invalid index!"); } const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetPolyLine(unsigned int index) { mitk::PlanarFigure::PolyLineType polyLine; if (index > m_PolyLines.size() || !m_PolyLineUpToDate) { this->GeneratePolyLine(); m_PolyLineUpToDate = true; } return m_PolyLines.at(index); } const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetPolyLine(unsigned int index) const { return m_PolyLines.at(index); } void mitk::PlanarFigure::ClearPolyLines() { for (std::vector::size_type i = 0; i < m_PolyLines.size(); i++) { m_PolyLines.at(i).clear(); } m_PolyLineUpToDate = false; } const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetHelperPolyLine(unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight) { mitk::PlanarFigure::PolyLineType helperPolyLine; if (index < m_HelperPolyLines.size()) { // m_HelperLinesUpToDate does not cover changes in zoom-level, so we have to check previous values of the // two parameters as well if (!m_HelperLinesUpToDate || m_DisplaySize.first != mmPerDisplayUnit || m_DisplaySize.second != displayHeight) { this->GenerateHelperPolyLine(mmPerDisplayUnit, displayHeight); m_HelperLinesUpToDate = true; // store these parameters to be able to check next time if somebody zoomed in or out m_DisplaySize.first = mmPerDisplayUnit; m_DisplaySize.second = displayHeight; } helperPolyLine = m_HelperPolyLines.at(index); } return helperPolyLine; } void mitk::PlanarFigure::ClearHelperPolyLines() { for (std::vector::size_type i = 0; i < m_HelperPolyLines.size(); i++) { m_HelperPolyLines.at(i).clear(); } m_HelperLinesUpToDate = false; } /** \brief Returns the number of features available for this PlanarFigure * (such as, radius, area, ...). */ unsigned int mitk::PlanarFigure::GetNumberOfFeatures() const { return m_Features.size(); } int mitk::PlanarFigure::GetControlPointForPolylinePoint(int indexOfPolylinePoint, int /*polyLineIndex*/) const { return indexOfPolylinePoint; } const char *mitk::PlanarFigure::GetFeatureName(unsigned int index) const { if (index < m_Features.size()) { return m_Features[index].Name.c_str(); } else { return nullptr; } } const char *mitk::PlanarFigure::GetFeatureUnit(unsigned int index) const { if (index < m_Features.size()) { return m_Features[index].Unit.c_str(); } else { return nullptr; } } double mitk::PlanarFigure::GetQuantity(unsigned int index) const { if (index < m_Features.size()) { return m_Features[index].Quantity; } else { return 0.0; } } bool mitk::PlanarFigure::IsFeatureActive(unsigned int index) const { if (index < m_Features.size()) { return m_Features[index].Active; } else { return false; } } bool mitk::PlanarFigure::IsFeatureVisible(unsigned int index) const { if (index < m_Features.size()) { return m_Features[index].Visible; } else { return false; } } void mitk::PlanarFigure::SetFeatureVisible(unsigned int index, bool visible) { if (index < m_Features.size()) { m_Features[index].Visible = visible; } } void mitk::PlanarFigure::EvaluateFeatures() { if (!m_FeaturesUpToDate || !m_PolyLineUpToDate) { if (!m_PolyLineUpToDate) { this->GeneratePolyLine(); } this->EvaluateFeaturesInternal(); m_FeaturesUpToDate = true; } } void mitk::PlanarFigure::UpdateOutputInformation() { // Bounds are NOT calculated here, since the PlaneGeometry defines a fixed // frame (= bounds) for the planar figure. Superclass::UpdateOutputInformation(); this->GetTimeGeometry()->Update(); } void mitk::PlanarFigure::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::PlanarFigure::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::PlanarFigure::VerifyRequestedRegion() { return true; } void mitk::PlanarFigure::SetRequestedRegion(const itk::DataObject * /*data*/) { } void mitk::PlanarFigure::ResetNumberOfControlPoints(int numberOfControlPoints) { // DO NOT resize the list here, will cause crash!! m_NumberOfControlPoints = numberOfControlPoints; } mitk::Point2D mitk::PlanarFigure::ApplyControlPointConstraints(unsigned int /*index*/, const Point2D &point) { if (m_PlaneGeometry == nullptr) { return point; } Point2D indexPoint; m_PlaneGeometry->WorldToIndex(point, indexPoint); BoundingBox::BoundsArrayType bounds = m_PlaneGeometry->GetBounds(); if (indexPoint[0] < bounds[0]) { indexPoint[0] = bounds[0]; } if (indexPoint[0] > bounds[1]) { indexPoint[0] = bounds[1]; } if (indexPoint[1] < bounds[2]) { indexPoint[1] = bounds[2]; } if (indexPoint[1] > bounds[3]) { indexPoint[1] = bounds[3]; } Point2D constrainedPoint; m_PlaneGeometry->IndexToWorld(indexPoint, constrainedPoint); return constrainedPoint; } unsigned int mitk::PlanarFigure::AddFeature(const char *featureName, const char *unitName) { unsigned int index = m_Features.size(); Feature newFeature(featureName, unitName); m_Features.push_back(newFeature); return index; } void mitk::PlanarFigure::SetFeatureName(unsigned int index, const char *featureName) { if (index < m_Features.size()) { m_Features[index].Name = featureName; } } void mitk::PlanarFigure::SetFeatureUnit(unsigned int index, const char *unitName) { if (index < m_Features.size()) { m_Features[index].Unit = unitName; } } void mitk::PlanarFigure::SetQuantity(unsigned int index, double quantity) { if (index < m_Features.size()) { m_Features[index].Quantity = quantity; } } void mitk::PlanarFigure::ActivateFeature(unsigned int index) { if (index < m_Features.size()) { m_Features[index].Active = true; } } void mitk::PlanarFigure::DeactivateFeature(unsigned int index) { if (index < m_Features.size()) { m_Features[index].Active = false; } } void mitk::PlanarFigure::InitializeTimeGeometry(unsigned int timeSteps) { mitk::PlaneGeometry::Pointer geometry2D = mitk::PlaneGeometry::New(); geometry2D->Initialize(); // The geometry is propagated automatically to all time steps, // if EvenlyTimed is true... ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(geometry2D, timeSteps); SetTimeGeometry(timeGeometry); } void mitk::PlanarFigure::PrintSelf(std::ostream &os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << this->GetNameOfClass() << ":\n"; if (this->IsClosed()) os << indent << "This figure is closed\n"; else os << indent << "This figure is not closed\n"; os << indent << "Minimum number of control points: " << this->GetMinimumNumberOfControlPoints() << std::endl; os << indent << "Maximum number of control points: " << this->GetMaximumNumberOfControlPoints() << std::endl; os << indent << "Current number of control points: " << this->GetNumberOfControlPoints() << std::endl; os << indent << "Control points:" << std::endl; for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i) { // os << indent.GetNextIndent() << i << ": " << m_ControlPoints->ElementAt( i ) << std::endl; os << indent.GetNextIndent() << i << ": " << m_ControlPoints.at(i) << std::endl; } os << indent << "Geometry:\n"; this->GetPlaneGeometry()->Print(os, indent.GetNextIndent()); } unsigned short mitk::PlanarFigure::GetPolyLinesSize() { if (!m_PolyLineUpToDate) { this->GeneratePolyLine(); m_PolyLineUpToDate = true; } return m_PolyLines.size(); } unsigned short mitk::PlanarFigure::GetHelperPolyLinesSize() const { return m_HelperPolyLines.size(); } bool mitk::PlanarFigure::IsHelperToBePainted(unsigned int index) const { return m_HelperPolyLinesToBePainted->GetElement(index); } bool mitk::PlanarFigure::ResetOnPointSelect() { return false; } bool mitk::PlanarFigure::ResetOnPointSelectNeeded() const { return false; } void mitk::PlanarFigure::RemoveControlPoint(unsigned int index) { if (index > m_ControlPoints.size()) return; if ((m_ControlPoints.size() - 1) < this->GetMinimumNumberOfControlPoints()) return; ControlPointListType::iterator iter; iter = m_ControlPoints.begin() + index; m_ControlPoints.erase(iter); m_PolyLineUpToDate = false; m_HelperLinesUpToDate = false; m_FeaturesUpToDate = false; --m_NumberOfControlPoints; } void mitk::PlanarFigure::RemoveLastControlPoint() { RemoveControlPoint(m_ControlPoints.size() - 1); } void mitk::PlanarFigure::SetNumberOfPolyLines(unsigned int numberOfPolyLines) { m_PolyLines.resize(numberOfPolyLines); } void mitk::PlanarFigure::SetNumberOfHelperPolyLines(unsigned int numberOfHerlperPolyLines) { m_HelperPolyLines.resize(numberOfHerlperPolyLines); } void mitk::PlanarFigure::AppendPointToPolyLine(unsigned int index, PolyLineElement element) { if (index < m_PolyLines.size()) { m_PolyLines[index].push_back(element); m_PolyLineUpToDate = false; } else { MITK_ERROR << "Tried to add point to PolyLine " << index + 1 << ", although only " << m_PolyLines.size() << " exists"; } } void mitk::PlanarFigure::AppendPointToHelperPolyLine(unsigned int index, PolyLineElement element) { if (index < m_HelperPolyLines.size()) { m_HelperPolyLines[index].push_back(element); m_HelperLinesUpToDate = false; } else { MITK_ERROR << "Tried to add point to HelperPolyLine " << index + 1 << ", although only " << m_HelperPolyLines.size() << " exists"; } } bool mitk::PlanarFigure::Equals(const mitk::PlanarFigure &other) const { // check geometries if (this->GetPlaneGeometry() && other.GetPlaneGeometry()) { if (!Equal(*(this->GetPlaneGeometry()), *(other.GetPlaneGeometry()), mitk::eps, true)) { return false; } } else { MITK_ERROR << "Geometry is not equal"; return false; } // check isPlaced member if (this->m_FigurePlaced != other.m_FigurePlaced) { MITK_ERROR << "Is_Placed is not equal"; return false; } // check closed property if (this->IsClosed() != other.IsClosed()) { MITK_ERROR << "Is_closed is not equal"; return false; } // check poly lines if (this->m_PolyLines.size() != other.m_PolyLines.size()) { return false; } else { auto itThis = this->m_PolyLines.begin(); auto itEnd = this->m_PolyLines.end(); auto itOther = other.m_PolyLines.begin(); while (itThis != itEnd) { if (itThis->size() != itOther->size()) return false; else { auto itLineThis = itThis->begin(); auto itLineEnd = itThis->end(); auto itLineOther = itOther->begin(); while (itLineThis != itLineEnd) { Point2D p1 = *itLineThis; Point2D p2 = *itLineOther; ScalarType delta = fabs(p1[0] - p2[0]) + fabs(p1[1] - p2[1]); if (delta > .001) { MITK_ERROR << "Poly line is not equal"; MITK_ERROR << p1 << "/" << p2; return false; } ++itLineThis; ++itLineOther; } } ++itThis; ++itOther; } } // check features if (this->GetNumberOfFeatures() != other.GetNumberOfFeatures()) { MITK_ERROR << "Number of Features is Different"; return false; } else { auto itThis = m_Features.begin(); auto itEnd = m_Features.end(); auto itOther = other.m_Features.begin(); while (itThis != itEnd) { if ((itThis->Quantity - itOther->Quantity) > .001) { MITK_ERROR << "Quantity is Different" << itThis->Quantity << "/" << itOther->Quantity; return false; } if (itThis->Unit.compare(itOther->Unit) != 0) { MITK_ERROR << "Unit is Different" << itThis->Unit << "/" << itOther->Unit; return false; } if (itThis->Name.compare(itOther->Name) != 0) { MITK_ERROR << "Name of Measure is Different " << itThis->Name << "/ " << itOther->Name; ; return false; } ++itThis; ++itOther; } } return true; } bool mitk::Equal(const mitk::PlanarFigure &leftHandSide, const mitk::PlanarFigure &rightHandSide, ScalarType /*eps*/, bool /*verbose*/) { // FIXME: use eps and verbose return leftHandSide.Equals(rightHandSide); } diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureIOFactory.cpp b/Modules/PlanarFigure/src/IO/mitkPlanarFigureIOFactory.cpp deleted file mode 100644 index 9c6d67781c..0000000000 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureIOFactory.cpp +++ /dev/null @@ -1,37 +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 "mitkPlanarFigureIOFactory.h" -#include "mitkIOAdapter.h" -#include "mitkPlanarFigureReader.h" - -#include "itkVersion.h" - -namespace mitk -{ - PlanarFigureIOFactory::PlanarFigureIOFactory() - { - this->RegisterOverride("mitkIOAdapter", - "mitkPlanarFigureReader", - "mitk PlanarFigure IO", - true, - itk::CreateObjectFunction>::New()); - } - - PlanarFigureIOFactory::~PlanarFigureIOFactory() {} - const char *PlanarFigureIOFactory::GetITKSourceVersion() const { return ITK_SOURCE_VERSION; } - const char *PlanarFigureIOFactory::GetDescription() const - { - return "PlanarFigure IO Factory, allows the loading of .pf files"; - } - -} // end namespace mitk diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureIOFactory.h b/Modules/PlanarFigure/src/IO/mitkPlanarFigureIOFactory.h deleted file mode 100644 index f7f3b161ef..0000000000 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureIOFactory.h +++ /dev/null @@ -1,68 +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. - -============================================================================*/ -#ifndef __mitkPlanarFigureIOFactory_h -#define __mitkPlanarFigureIOFactory_h - -#ifdef _MSC_VER -#pragma warning(disable : 4786) -#endif - -#include "itkObjectFactoryBase.h" -#include "mitkBaseData.h" - -namespace mitk -{ - //##Documentation - //## @brief Create instances of PlanarFigureReader objects using an object factory. - //## - //## @ingroup MitkPlanarFigureModule - class PlanarFigureIOFactory : public itk::ObjectFactoryBase - { - public: - /** Standard class typedefs. */ - typedef PlanarFigureIOFactory Self; - typedef itk::ObjectFactoryBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Class methods used to interface with the registered factories. */ - const char *GetITKSourceVersion(void) const override; - const char *GetDescription(void) const override; - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - static PlanarFigureIOFactory *FactoryNew() { return new PlanarFigureIOFactory; } - /** Run-time type information (and related methods). */ - itkTypeMacro(PlanarFigureIOFactory, ObjectFactoryBase); - - /** - * Register one factory of this type - * \deprecatedSince{2013_09} - */ - DEPRECATED(static void RegisterOneFactory(void)) - { - PlanarFigureIOFactory::Pointer PlanarFigureIOFactory = PlanarFigureIOFactory::New(); - ObjectFactoryBase::RegisterFactory(PlanarFigureIOFactory); - } - - protected: - PlanarFigureIOFactory(); - ~PlanarFigureIOFactory() override; - - private: - PlanarFigureIOFactory(const Self &); // purposely not implemented - void operator=(const Self &); // purposely not implemented - }; - -} // end namespace mitk - -#endif diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureReader.cpp b/Modules/PlanarFigure/src/IO/mitkPlanarFigureReader.cpp deleted file mode 100644 index 5aa97568cc..0000000000 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureReader.cpp +++ /dev/null @@ -1,438 +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 "mitkPlanarFigureReader.h" - -#include "mitkPlanarAngle.h" -#include "mitkPlanarArrow.h" -#include "mitkPlanarBezierCurve.h" -#include "mitkPlanarCircle.h" -#include "mitkPlanarCross.h" -#include "mitkPlanarDoubleEllipse.h" -#include "mitkPlanarEllipse.h" -#include "mitkPlanarFourPointAngle.h" -#include "mitkPlanarLine.h" -#include "mitkPlanarPolygon.h" -#include "mitkPlanarRectangle.h" -#include "mitkPlanarSubdivisionPolygon.h" -#include "mitkPlaneGeometry.h" - -#include "mitkBasePropertySerializer.h" -#include - -#include -#include - -mitk::PlanarFigureReader::PlanarFigureReader() - : PlanarFigureSource(), FileReader(), m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false) -{ - this->SetNumberOfRequiredOutputs(1); - this->SetNumberOfIndexedOutputs(1); - this->SetNthOutput(0, this->MakeOutput(0)); - - m_CanReadFromMemory = true; - - // this->Modified(); - // this->GetOutput()->Modified(); - // this->GetOutput()->ReleaseData(); -} - -mitk::PlanarFigureReader::~PlanarFigureReader() -{ -} - -void mitk::PlanarFigureReader::GenerateData() -{ - mitk::LocaleSwitch localeSwitch("C"); - m_Success = false; - this->SetNumberOfIndexedOutputs(0); // reset all outputs, we add new ones depending on the file content - - TiXmlDocument document; - - if (m_ReadFromMemory) - { - if (m_MemoryBuffer == nullptr || m_MemorySize == 0) - { - // check - itkWarningMacro(<< "Sorry, memory buffer has not been set!"); - return; - } - if (m_MemoryBuffer[m_MemorySize - 1] == '\0') - { - document.Parse(m_MemoryBuffer); - } - else - { - auto tmpArray = new char[(int)m_MemorySize + 1]; - tmpArray[m_MemorySize] = '\0'; - memcpy(tmpArray, m_MemoryBuffer, m_MemorySize); - - document.Parse(m_MemoryBuffer); - - delete[] tmpArray; - } - } - else - { - if (m_FileName.empty()) - { - itkWarningMacro(<< "Sorry, filename has not been set!"); - return; - } - if (this->CanReadFile(m_FileName.c_str()) == false) - { - itkWarningMacro(<< "Sorry, can't read file " << m_FileName << "!"); - return; - } - if (!document.LoadFile(m_FileName)) - { - MITK_ERROR << "Could not open/read/parse " << m_FileName << ". TinyXML reports: '" << document.ErrorDesc() - << "'. " - << "The error occurred in row " << document.ErrorRow() << ", column " << document.ErrorCol() << "."; - return; - } - } - - int fileVersion = 1; - TiXmlElement *versionObject = document.FirstChildElement("Version"); - if (versionObject != nullptr) - { - if (versionObject->QueryIntAttribute("FileVersion", &fileVersion) != TIXML_SUCCESS) - { - MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl; - } - } - else - { - MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl; - } - if (fileVersion != - 1) // add file version selection and version specific file parsing here, if newer file versions are created - { - MITK_WARN << "File version > 1 is not supported by this reader."; - return; - } - - /* file version 1 reader code */ - for (TiXmlElement *pfElement = document.FirstChildElement("PlanarFigure"); pfElement != nullptr; - pfElement = pfElement->NextSiblingElement("PlanarFigure")) - { - std::string type = pfElement->Attribute("type"); - - mitk::PlanarFigure::Pointer planarFigure = nullptr; - if (type == "PlanarAngle") - { - planarFigure = mitk::PlanarAngle::New(); - } - else if (type == "PlanarCircle") - { - planarFigure = mitk::PlanarCircle::New(); - } - else if (type == "PlanarEllipse") - { - planarFigure = mitk::PlanarEllipse::New(); - } - else if (type == "PlanarCross") - { - planarFigure = mitk::PlanarCross::New(); - } - else if (type == "PlanarFourPointAngle") - { - planarFigure = mitk::PlanarFourPointAngle::New(); - } - else if (type == "PlanarLine") - { - planarFigure = mitk::PlanarLine::New(); - } - else if (type == "PlanarPolygon") - { - planarFigure = mitk::PlanarPolygon::New(); - } - else if (type == "PlanarSubdivisionPolygon") - { - planarFigure = mitk::PlanarSubdivisionPolygon::New(); - } - else if (type == "PlanarRectangle") - { - planarFigure = mitk::PlanarRectangle::New(); - } - else if (type == "PlanarArrow") - { - planarFigure = mitk::PlanarArrow::New(); - } - else if (type == "PlanarDoubleEllipse") - { - planarFigure = mitk::PlanarDoubleEllipse::New(); - } - else if (type == "PlanarBezierCurve") - { - planarFigure = mitk::PlanarBezierCurve::New(); - } - else - { - // unknown type - MITK_WARN << "encountered unknown planar figure type '" << type << "'. Skipping this element."; - continue; - } - - // Read properties of the planar figure - for (TiXmlElement *propertyElement = pfElement->FirstChildElement("property"); propertyElement != nullptr; - propertyElement = propertyElement->NextSiblingElement("property")) - { - const char *keya = propertyElement->Attribute("key"); - const std::string key(keya ? keya : ""); - - const char *typea = propertyElement->Attribute("type"); - const std::string type(typea ? typea : ""); - - // hand propertyElement to specific reader - std::stringstream propertyDeserializerClassName; - propertyDeserializerClassName << type << "Serializer"; - - const std::list readers = - itk::ObjectFactoryBase::CreateAllInstance(propertyDeserializerClassName.str().c_str()); - if (readers.size() < 1) - { - MITK_ERROR << "No property reader found for " << type; - } - if (readers.size() > 1) - { - MITK_WARN << "Multiple property readers found for " << type << ". Using arbitrary first one."; - } - - for (auto iter = readers.cbegin(); iter != readers.cend(); ++iter) - { - if (auto *reader = dynamic_cast(iter->GetPointer())) - { - const BaseProperty::Pointer property = reader->Deserialize(propertyElement->FirstChildElement()); - if (property.IsNotNull()) - { - planarFigure->GetPropertyList()->ReplaceProperty(key, property); - } - else - { - MITK_ERROR << "There were errors while loading property '" << key << "' of type " << type - << ". Your data may be corrupted"; - } - break; - } - } - } - - // If we load a planarFigure, it has definitely been placed correctly. - // If we do not set this property here, we cannot load old planarFigures - // without messing up the interaction (PF-Interactor needs this property. - planarFigure->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - - // Which features (length or circumference etc) a figure has is decided by whether it is closed or not - // the function SetClosed has to be called in case of PlanarPolygons to ensure they hold the correct feature - auto *planarPolygon = dynamic_cast(planarFigure.GetPointer()); - if (planarPolygon != nullptr) - { - bool isClosed = false; - planarFigure->GetPropertyList()->GetBoolProperty("closed", isClosed); - planarPolygon->SetClosed(isClosed); - } - - // Read geometry of containing plane - TiXmlElement *geoElement = pfElement->FirstChildElement("Geometry"); - if (geoElement != nullptr) - { - try - { - // Create plane geometry - mitk::PlaneGeometry::Pointer planeGeo = mitk::PlaneGeometry::New(); - - // Extract and set plane transform parameters - const DoubleList transformList = - this->GetDoubleAttributeListFromXMLNode(geoElement->FirstChildElement("transformParam"), "param", 12); - - typedef mitk::BaseGeometry::TransformType TransformType; - TransformType::ParametersType parameters; - parameters.SetSize(12); - - unsigned int i; - DoubleList::const_iterator it; - for (it = transformList.cbegin(), i = 0; it != transformList.cend(); ++it, ++i) - { - parameters.SetElement(i, *it); - } - - typedef mitk::BaseGeometry::TransformType TransformType; - TransformType::Pointer affineGeometry = TransformType::New(); - affineGeometry->SetParameters(parameters); - planeGeo->SetIndexToWorldTransform(affineGeometry); - - // Extract and set plane bounds - const DoubleList boundsList = - this->GetDoubleAttributeListFromXMLNode(geoElement->FirstChildElement("boundsParam"), "bound", 6); - - typedef mitk::BaseGeometry::BoundsArrayType BoundsArrayType; - - BoundsArrayType bounds; - for (it = boundsList.cbegin(), i = 0; it != boundsList.cend(); ++it, ++i) - { - bounds[i] = *it; - } - - planeGeo->SetBounds(bounds); - - // Extract and set spacing and origin - const Vector3D spacing = this->GetVectorFromXMLNode(geoElement->FirstChildElement("Spacing")); - planeGeo->SetSpacing(spacing); - - const Point3D origin = this->GetPointFromXMLNode(geoElement->FirstChildElement("Origin")); - planeGeo->SetOrigin(origin); - planarFigure->SetPlaneGeometry(planeGeo); - } - catch (...) - { - } - } - TiXmlElement *cpElement = pfElement->FirstChildElement("ControlPoints"); - bool first = true; - if (cpElement != nullptr) - for (TiXmlElement *vertElement = cpElement->FirstChildElement("Vertex"); vertElement != nullptr; - vertElement = vertElement->NextSiblingElement("Vertex")) - { - int id = 0; - mitk::Point2D::ValueType x = 0.0; - mitk::Point2D::ValueType y = 0.0; - if (vertElement->QueryIntAttribute("id", &id) == TIXML_WRONG_TYPE) - return; // TODO: can we do a better error handling? - if (vertElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE) - return; // TODO: can we do a better error handling? - if (vertElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE) - return; // TODO: can we do a better error handling? - Point2D p; - p.SetElement(0, x); - p.SetElement(1, y); - if (first == true) // needed to set m_FigurePlaced to true - { - planarFigure->PlaceFigure(p); - first = false; - } - planarFigure->SetControlPoint(id, p, true); - } - - // Calculate feature quantities of this PlanarFigure - planarFigure->EvaluateFeatures(); - - // Make sure that no control point is currently selected - planarFigure->DeselectControlPoint(); - - // \TODO: what about m_FigurePlaced and m_SelectedControlPoint ?? - this->SetNthOutput(this->GetNumberOfOutputs(), planarFigure); // add planarFigure as new output of this filter - } - - m_Success = true; -} - -mitk::Point3D mitk::PlanarFigureReader::GetPointFromXMLNode(TiXmlElement *e) -{ - if (e == nullptr) - throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling? - mitk::Point3D point; - mitk::ScalarType p(-1.0); - if (e->QueryDoubleAttribute("x", &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - point.SetElement(0, p); - if (e->QueryDoubleAttribute("y", &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - point.SetElement(1, p); - if (e->QueryDoubleAttribute("z", &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - point.SetElement(2, p); - return point; -} - -mitk::Vector3D mitk::PlanarFigureReader::GetVectorFromXMLNode(TiXmlElement *e) -{ - if (e == nullptr) - throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling? - mitk::Vector3D vector; - mitk::ScalarType p(-1.0); - if (e->QueryDoubleAttribute("x", &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - vector.SetElement(0, p); - if (e->QueryDoubleAttribute("y", &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - vector.SetElement(1, p); - if (e->QueryDoubleAttribute("z", &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - vector.SetElement(2, p); - return vector; -} - -mitk::PlanarFigureReader::DoubleList mitk::PlanarFigureReader::GetDoubleAttributeListFromXMLNode( - TiXmlElement *e, const char *attributeNameBase, unsigned int count) -{ - DoubleList list; - - if (e == nullptr) - throw std::invalid_argument("node invalid"); // TODO: can we do a better error handling? - - for (unsigned int i = 0; i < count; ++i) - { - mitk::ScalarType p(-1.0); - std::stringstream attributeName; - attributeName << attributeNameBase << i; - - if (e->QueryDoubleAttribute(attributeName.str().c_str(), &p) == TIXML_WRONG_TYPE) - throw std::invalid_argument("node malformatted"); // TODO: can we do a better error handling? - list.push_back(p); - } - - return list; -} - -void mitk::PlanarFigureReader::GenerateOutputInformation() -{ -} - -int mitk::PlanarFigureReader::CanReadFile(const char *name) -{ - if (std::string(name).empty()) - return false; - - return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(name)) == - ".pf"); // assume, we can read all .pf files - - // TiXmlDocument document(name); - // if (document.LoadFile() == false) - // return false; - // return (document.FirstChildElement("PlanarFigure") != nullptr); -} - -bool mitk::PlanarFigureReader::CanReadFile(const std::string filename, const std::string, const std::string) -{ - if (filename.empty()) - return false; - - return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(filename)) == - ".pf"); // assume, we can read all .pf files - - // TiXmlDocument document(filename); - // if (document.LoadFile() == false) - // return false; - // return (document.FirstChildElement("PlanarFigure") != nullptr); -} - -void mitk::PlanarFigureReader::ResizeOutputs(const unsigned int &num) -{ - unsigned int prevNum = this->GetNumberOfOutputs(); - this->SetNumberOfIndexedOutputs(num); - for (unsigned int i = prevNum; i < num; ++i) - { - this->SetNthOutput(i, this->MakeOutput(i).GetPointer()); - } -} diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriter.cpp b/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriter.cpp deleted file mode 100644 index ceec5adfb9..0000000000 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriter.cpp +++ /dev/null @@ -1,294 +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 "mitkPlanarFigureWriter.h" -#include "mitkBasePropertySerializer.h" -#include "mitkPlaneGeometry.h" -#include - -mitk::PlanarFigureWriter::PlanarFigureWriter() - : m_FileName(""), - m_FilePrefix(""), - m_FilePattern(""), - m_Extension(".pf"), - m_MimeType("application/MITK.PlanarFigure"), - m_Success(false) -{ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfIndexedOutputs(0); - // this->SetNthOutput( 0, mitk::PlanarFigure::New().GetPointer() ); - - m_CanWriteToMemory = true; -} - -mitk::PlanarFigureWriter::~PlanarFigureWriter() -{ -} - -void mitk::PlanarFigureWriter::GenerateData() -{ - m_Success = false; - - if (!m_WriteToMemory && m_FileName.empty()) - { - MITK_ERROR << "Could not write planar figures. File name is invalid"; - throw std::invalid_argument("file name is empty"); - } - - TiXmlDocument document; - auto decl = new TiXmlDeclaration("1.0", "", ""); // TODO what to write here? encoding? etc.... - document.LinkEndChild(decl); - - auto version = new TiXmlElement("Version"); - version->SetAttribute("Writer", __FILE__); - version->SetAttribute("CVSRevision", "$Revision: 17055 $"); - version->SetAttribute("FileVersion", 1); - document.LinkEndChild(version); - - /* create xml element for each input */ - for (unsigned int i = 0; i < this->GetNumberOfInputs(); ++i) - { - // Create root element for this PlanarFigure - InputType::Pointer pf = this->GetInput(i); - if (pf.IsNull()) - continue; - auto pfElement = new TiXmlElement("PlanarFigure"); - pfElement->SetAttribute("type", pf->GetNameOfClass()); - document.LinkEndChild(pfElement); - - if (pf->GetNumberOfControlPoints() == 0) - continue; - - // PlanarFigure::VertexContainerType* vertices = pf->GetControlPoints(); - // if (vertices == nullptr) - // continue; - - // Serialize property list of PlanarFigure - mitk::PropertyList::Pointer propertyList = pf->GetPropertyList(); - mitk::PropertyList::PropertyMap::const_iterator it; - for (it = propertyList->GetMap()->begin(); it != propertyList->GetMap()->end(); ++it) - { - // Create seralizer for this property - const mitk::BaseProperty *prop = it->second; - std::string serializerName = std::string(prop->GetNameOfClass()) + "Serializer"; - std::list allSerializers = - itk::ObjectFactoryBase::CreateAllInstance(serializerName.c_str()); - - if (allSerializers.size() != 1) - { - // No or too many serializer(s) found, skip this property - continue; - } - - auto *serializer = - dynamic_cast(allSerializers.begin()->GetPointer()); - if (serializer == nullptr) - { - // Serializer not valid; skip this property - } - - auto keyElement = new TiXmlElement("property"); - keyElement->SetAttribute("key", it->first); - keyElement->SetAttribute("type", prop->GetNameOfClass()); - - serializer->SetProperty(prop); - TiXmlElement *valueElement = nullptr; - try - { - valueElement = serializer->Serialize(); - } - catch (...) - { - } - - if (valueElement == nullptr) - { - // Serialization failed; skip this property - continue; - } - - // Add value to property element - keyElement->LinkEndChild(valueElement); - - // Append serialized property to property list - pfElement->LinkEndChild(keyElement); - } - - // Serialize control points of PlanarFigure - auto controlPointsElement = new TiXmlElement("ControlPoints"); - pfElement->LinkEndChild(controlPointsElement); - for (unsigned int i = 0; i < pf->GetNumberOfControlPoints(); i++) - { - auto vElement = new TiXmlElement("Vertex"); - vElement->SetAttribute("id", i); - vElement->SetDoubleAttribute("x", pf->GetControlPoint(i)[0]); - vElement->SetDoubleAttribute("y", pf->GetControlPoint(i)[1]); - controlPointsElement->LinkEndChild(vElement); - } - auto geoElement = new TiXmlElement("Geometry"); - const auto *planeGeo = dynamic_cast(pf->GetPlaneGeometry()); - if (planeGeo != nullptr) - { - // Write parameters of IndexToWorldTransform of the PlaneGeometry - typedef mitk::Geometry3D::TransformType TransformType; - const TransformType *affineGeometry = planeGeo->GetIndexToWorldTransform(); - const TransformType::ParametersType ¶meters = affineGeometry->GetParameters(); - auto vElement = new TiXmlElement("transformParam"); - for (unsigned int i = 0; i < affineGeometry->GetNumberOfParameters(); ++i) - { - std::stringstream paramName; - paramName << "param" << i; - vElement->SetDoubleAttribute(paramName.str().c_str(), parameters.GetElement(i)); - } - geoElement->LinkEndChild(vElement); - - // Write bounds of the PlaneGeometry - typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType; - const BoundsArrayType &bounds = planeGeo->GetBounds(); - vElement = new TiXmlElement("boundsParam"); - for (unsigned int i = 0; i < 6; ++i) - { - std::stringstream boundName; - boundName << "bound" << i; - vElement->SetDoubleAttribute(boundName.str().c_str(), bounds.GetElement(i)); - } - geoElement->LinkEndChild(vElement); - - // Write spacing and origin of the PlaneGeometry - Vector3D spacing = planeGeo->GetSpacing(); - Point3D origin = planeGeo->GetOrigin(); - geoElement->LinkEndChild(this->CreateXMLVectorElement("Spacing", spacing)); - geoElement->LinkEndChild(this->CreateXMLVectorElement("Origin", origin)); - - pfElement->LinkEndChild(geoElement); - } - } - - if (m_WriteToMemory) - { - // Declare a printer - TiXmlPrinter printer; - // attach it to the document you want to convert in to a std::string - document.Accept(&printer); - - // Create memory buffer and print tinyxmldocument there... - m_MemoryBufferSize = printer.Size() + 1; - m_MemoryBuffer = new char[m_MemoryBufferSize]; - strcpy(m_MemoryBuffer, printer.CStr()); - } - else - { - if (document.SaveFile(m_FileName) == false) - { - MITK_ERROR << "Could not write planar figures to " << m_FileName << "\nTinyXML reports '" << document.ErrorDesc() - << "'"; - throw std::ios_base::failure("Error during writing of planar figure xml file."); - } - } - m_Success = true; -} - -void mitk::PlanarFigureWriter::ReleaseMemory() -{ - if (m_MemoryBuffer != nullptr) - { - delete[] m_MemoryBuffer; - } -} - -TiXmlElement *mitk::PlanarFigureWriter::CreateXMLVectorElement(const char *name, itk::FixedArray v) -{ - auto vElement = new TiXmlElement(name); - vElement->SetDoubleAttribute("x", v.GetElement(0)); - vElement->SetDoubleAttribute("y", v.GetElement(1)); - vElement->SetDoubleAttribute("z", v.GetElement(2)); - return vElement; -} - -void mitk::PlanarFigureWriter::ResizeInputs(const unsigned int &num) -{ - // unsigned int prevNum = this->GetNumberOfInputs(); - this->SetNumberOfIndexedInputs(num); - // for ( unsigned int i = prevNum; i < num; ++i ) - //{ - // this->SetNthInput( i, mitk::PlanarFigure::New().GetPointer() ); - //} -} - -void mitk::PlanarFigureWriter::SetInput(InputType *PlanarFigure) -{ - this->ProcessObject::SetNthInput(0, PlanarFigure); -} - -void mitk::PlanarFigureWriter::SetInput(const unsigned int &id, InputType *PlanarFigure) -{ - if (id >= this->GetNumberOfInputs()) - this->ResizeInputs(id + 1); - this->ProcessObject::SetNthInput(id, PlanarFigure); -} - -mitk::PlanarFigure *mitk::PlanarFigureWriter::GetInput() -{ - if (this->GetNumberOfInputs() < 1) - return nullptr; - else - return dynamic_cast(this->GetInput(0)); -} - -mitk::PlanarFigure *mitk::PlanarFigureWriter::GetInput(const unsigned int &num) -{ - return dynamic_cast(this->ProcessObject::GetInput(num)); -} - -bool mitk::PlanarFigureWriter::CanWriteDataType(DataNode *input) -{ - if (input == nullptr) - return false; - - mitk::BaseData *data = input->GetData(); - if (data == nullptr) - return false; - - mitk::PlanarFigure::Pointer PlanarFigure = dynamic_cast(data); - if (PlanarFigure.IsNull()) - return false; - // add code for special subclasses here - return true; -} - -void mitk::PlanarFigureWriter::SetInput(DataNode *input) -{ - if (this->CanWriteDataType(input)) - this->ProcessObject::SetNthInput(0, dynamic_cast(input->GetData())); -} - -std::string mitk::PlanarFigureWriter::GetSupportedBaseData() const -{ - return PlanarFigure::GetStaticNameOfClass(); -} - -std::string mitk::PlanarFigureWriter::GetWritenMIMEType() -{ - return m_MimeType; -} - -std::vector mitk::PlanarFigureWriter::GetPossibleFileExtensions() -{ - std::vector possibleFileExtensions; - possibleFileExtensions.push_back(m_Extension); - return possibleFileExtensions; -} - -std::string mitk::PlanarFigureWriter::GetFileExtension() -{ - return m_Extension; -} diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriterFactory.cpp b/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriterFactory.cpp deleted file mode 100644 index 2b1ee14b9e..0000000000 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriterFactory.cpp +++ /dev/null @@ -1,77 +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 "mitkPlanarFigureWriterFactory.h" - -#include "itkCreateObjectFunction.h" -#include "itkVersion.h" - -#include - -namespace mitk -{ - template - class CreatePlanarFigureWriter : public itk::CreateObjectFunctionBase - { - public: - /** Standard class typedefs. */ - typedef CreatePlanarFigureWriter Self; - typedef itk::SmartPointer Pointer; - - /** Methods from itk:LightObject. */ - itkFactorylessNewMacro(Self) LightObject::Pointer CreateObject() override - { - typename T::Pointer p = T::New(); - p->Register(); - return p.GetPointer(); - } - - protected: - CreatePlanarFigureWriter() {} - ~CreatePlanarFigureWriter() override {} - private: - CreatePlanarFigureWriter(const Self &); // purposely not implemented - void operator=(const Self &); // purposely not implemented - }; - - PlanarFigureWriterFactory::PlanarFigureWriterFactory() - { - this->RegisterOverride("IOWriter", - "PlanarFigureWriter", - "PlanarFigure xml Writer", - true, - mitk::CreatePlanarFigureWriter::New()); - } - - PlanarFigureWriterFactory::~PlanarFigureWriterFactory() {} - itk::ObjectFactoryBase::Pointer PlanarFigureWriterFactory::GetInstance() - { - static itk::ObjectFactoryBase::Pointer factory(mitk::PlanarFigureWriterFactory::New().GetPointer()); - return factory; - } - - void PlanarFigureWriterFactory::RegisterOneFactory(void) - { - if (GetInstance()->GetReferenceCount() == 1) - { - ObjectFactoryBase::RegisterFactory(GetInstance().GetPointer()); - } - } - - void PlanarFigureWriterFactory::UnRegisterOneFactory(void) - { - ObjectFactoryBase::UnRegisterFactory(GetInstance().GetPointer()); - } - - const char *PlanarFigureWriterFactory::GetITKSourceVersion() const { return ITK_SOURCE_VERSION; } - const char *PlanarFigureWriterFactory::GetDescription() const { return "PlanarFigureWriterFactory"; } -} // end namespace mitk diff --git a/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriterFactory.h b/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriterFactory.h deleted file mode 100644 index b0f8d30e96..0000000000 --- a/Modules/PlanarFigure/src/IO/mitkPlanarFigureWriterFactory.h +++ /dev/null @@ -1,58 +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. - -============================================================================*/ - -#ifndef PLANARFIGURE_WRITERFACTORY_H_HEADER_INCLUDED -#define PLANARFIGURE_WRITERFACTORY_H_HEADER_INCLUDED - -#include "itkObjectFactoryBase.h" -#include "mitkBaseData.h" - -namespace mitk -{ - class PlanarFigureWriterFactory : public itk::ObjectFactoryBase - { - public: - mitkClassMacroItkParent(mitk::PlanarFigureWriterFactory, itk::ObjectFactoryBase); - - /** Class methods used to interface with the registered factories. */ - const char *GetITKSourceVersion(void) const override; - const char *GetDescription(void) const override; - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - - /** - * Register one factory of this type - * \deprecatedSince{2013_09} - */ - DEPRECATED(static void RegisterOneFactory(void)); - - /** - * UnRegister one factory of this type - * \deprecatedSince{2013_09} - */ - DEPRECATED(static void UnRegisterOneFactory(void)); - - protected: - PlanarFigureWriterFactory(); - ~PlanarFigureWriterFactory() override; - - private: - PlanarFigureWriterFactory(const Self &); // purposely not implemented - void operator=(const Self &); // purposely not implemented - - static itk::ObjectFactoryBase::Pointer GetInstance(); - }; - -} // end namespace mitk - -#endif // PLANARFIGURE_WRITERFACTORY_H_HEADER_INCLUDED diff --git a/Modules/PlanarFigure/test/mitkPlanarFigureIOTest.cpp b/Modules/PlanarFigure/test/mitkPlanarFigureIOTest.cpp index e24ed0bfef..40fd836151 100644 --- a/Modules/PlanarFigure/test/mitkPlanarFigureIOTest.cpp +++ b/Modules/PlanarFigure/test/mitkPlanarFigureIOTest.cpp @@ -1,592 +1,510 @@ /*============================================================================ 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 "mitkTestingMacros.h" #include "mitkPlanarAngle.h" #include "mitkPlanarCircle.h" #include "mitkPlanarCross.h" #include "mitkPlanarFourPointAngle.h" #include "mitkPlanarLine.h" #include "mitkPlanarPolygon.h" #include "mitkPlanarRectangle.h" #include "mitkPlanarSubdivisionPolygon.h" -#include "mitkPlanarFigureReader.h" -#include "mitkPlanarFigureWriter.h" - #include "mitkPlaneGeometry.h" -#include +#include "mitkGeometry3D.h" +#include "mitkAbstractFileIO.h" +#include "mitkFileReaderRegistry.h" +#include "mitkFileWriterRegistry.h" +#include "mitkIOUtil.h" -static mitk::PlanarFigure::Pointer Clone(mitk::PlanarFigure::Pointer original) -{ - return original->Clone(); -} +#include /** \brief Helper class for testing PlanarFigure reader and writer classes. */ class PlanarFigureIOTestClass { public: - typedef std::list PlanarFigureList; - typedef std::vector PlanarFigureToMemoryWriterList; + typedef std::map PlanarFigureMap; + typedef std::map PlanarFigureToStreamMap; - static PlanarFigureList CreatePlanarFigures() + static PlanarFigureMap CreatePlanarFigures() { - PlanarFigureList planarFigures; + PlanarFigureMap planarFigures; // Create PlaneGeometry on which to place the PlanarFigures mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New(); planeGeometry->InitializeStandardPlane(100.0, 100.0); // Create a few sample points for PlanarFigure placement mitk::Point2D p0; p0[0] = 20.0; p0[1] = 20.0; mitk::Point2D p1; p1[0] = 80.0; p1[1] = 80.0; mitk::Point2D p2; p2[0] = 90.0; p2[1] = 10.0; mitk::Point2D p3; p3[0] = 10.0; p3[1] = 90.0; // Create PlanarAngle mitk::PlanarAngle::Pointer planarAngle = mitk::PlanarAngle::New(); planarAngle->SetPlaneGeometry(planeGeometry); planarAngle->PlaceFigure(p0); planarAngle->SetCurrentControlPoint(p1); planarAngle->AddControlPoint(p2); planarAngle->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarAngle.GetPointer()); + planarFigures.emplace("planarAngle",planarAngle.GetPointer()); // Create PlanarCircle mitk::PlanarCircle::Pointer planarCircle = mitk::PlanarCircle::New(); planarCircle->SetPlaneGeometry(planeGeometry); planarCircle->PlaceFigure(p0); planarCircle->SetCurrentControlPoint(p1); planarCircle->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarCircle.GetPointer()); + planarFigures.emplace("planarCircle",planarCircle.GetPointer()); // Create PlanarCross mitk::PlanarCross::Pointer planarCross = mitk::PlanarCross::New(); planarCross->SetSingleLineMode(false); planarCross->SetPlaneGeometry(planeGeometry); planarCross->PlaceFigure(p0); planarCross->SetCurrentControlPoint(p1); planarCross->AddControlPoint(p2); planarCross->AddControlPoint(p3); planarCross->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarCross.GetPointer()); + planarFigures.emplace("planarCross",planarCross.GetPointer()); // Create PlanarFourPointAngle mitk::PlanarFourPointAngle::Pointer planarFourPointAngle = mitk::PlanarFourPointAngle::New(); planarFourPointAngle->SetPlaneGeometry(planeGeometry); planarFourPointAngle->PlaceFigure(p0); planarFourPointAngle->SetCurrentControlPoint(p1); planarFourPointAngle->AddControlPoint(p2); planarFourPointAngle->AddControlPoint(p3); planarFourPointAngle->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarFourPointAngle.GetPointer()); + planarFigures.emplace("planarFourPointAngle",planarFourPointAngle.GetPointer()); // Create PlanarLine mitk::PlanarLine::Pointer planarLine = mitk::PlanarLine::New(); planarLine->SetPlaneGeometry(planeGeometry); planarLine->PlaceFigure(p0); planarLine->SetCurrentControlPoint(p1); planarLine->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarLine.GetPointer()); + planarFigures.emplace("planarLine",planarLine.GetPointer()); // Create PlanarPolygon mitk::PlanarPolygon::Pointer planarPolygon = mitk::PlanarPolygon::New(); planarPolygon->SetClosed(false); planarPolygon->SetPlaneGeometry(planeGeometry); planarPolygon->PlaceFigure(p0); planarPolygon->SetCurrentControlPoint(p1); planarPolygon->AddControlPoint(p2); planarPolygon->AddControlPoint(p3); planarPolygon->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarPolygon.GetPointer()); + planarFigures.emplace("planarPolygon",planarPolygon.GetPointer()); // Create PlanarSubdivisionPolygon mitk::PlanarSubdivisionPolygon::Pointer planarSubdivisionPolygon = mitk::PlanarSubdivisionPolygon::New(); planarSubdivisionPolygon->SetClosed(false); planarSubdivisionPolygon->SetPlaneGeometry(planeGeometry); planarSubdivisionPolygon->PlaceFigure(p0); planarSubdivisionPolygon->SetCurrentControlPoint(p1); planarSubdivisionPolygon->AddControlPoint(p2); planarSubdivisionPolygon->AddControlPoint(p3); planarSubdivisionPolygon->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarSubdivisionPolygon.GetPointer()); + planarFigures.emplace("planarSubdivisionPolygon",planarSubdivisionPolygon.GetPointer()); // Create PlanarRectangle mitk::PlanarRectangle::Pointer planarRectangle = mitk::PlanarRectangle::New(); planarRectangle->SetPlaneGeometry(planeGeometry); planarRectangle->PlaceFigure(p0); planarRectangle->SetCurrentControlPoint(p1); planarRectangle->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarRectangle.GetPointer()); + planarFigures.emplace("planarRectangle",planarRectangle.GetPointer()); // create preciseGeometry which is using float coordinates mitk::PlaneGeometry::Pointer preciseGeometry = mitk::PlaneGeometry::New(); mitk::Vector3D right; right[0] = 0.0; right[1] = 1.23456; right[2] = 0.0; mitk::Vector3D down; down[0] = 1.23456; down[1] = 0.0; down[2] = 0.0; mitk::Vector3D spacing; spacing[0] = 0.0123456; spacing[1] = 0.0123456; spacing[2] = 1.123456; preciseGeometry->InitializeStandardPlane(right, down, &spacing); // convert points into the precise coordinates mitk::Point2D p0precise; p0precise[0] = p0[0] * spacing[0]; p0precise[1] = p0[1] * spacing[1]; mitk::Point2D p1precise; p1precise[0] = p1[0] * spacing[0]; p1precise[1] = p1[1] * spacing[1]; mitk::Point2D p2precise; p2precise[0] = p2[0] * spacing[0]; p2precise[1] = p2[1] * spacing[1]; mitk::Point2D p3precise; p3precise[0] = p3[0] * spacing[0]; p3precise[1] = p3[1] * spacing[1]; // Now all PlanarFigures are create using the precise Geometry // Create PlanarCross mitk::PlanarCross::Pointer nochncross = mitk::PlanarCross::New(); nochncross->SetSingleLineMode(false); nochncross->SetPlaneGeometry(preciseGeometry); nochncross->PlaceFigure(p0precise); nochncross->SetCurrentControlPoint(p1precise); nochncross->AddControlPoint(p2precise); nochncross->AddControlPoint(p3precise); nochncross->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(nochncross.GetPointer()); + planarFigures.emplace("nochncross", nochncross.GetPointer()); // Create PlanarAngle mitk::PlanarAngle::Pointer planarAnglePrecise = mitk::PlanarAngle::New(); planarAnglePrecise->SetPlaneGeometry(preciseGeometry); planarAnglePrecise->PlaceFigure(p0precise); planarAnglePrecise->SetCurrentControlPoint(p1precise); planarAnglePrecise->AddControlPoint(p2precise); planarAnglePrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarAnglePrecise.GetPointer()); + planarFigures.emplace("planarAnglePrecise",planarAnglePrecise.GetPointer()); // Create PlanarCircle mitk::PlanarCircle::Pointer planarCirclePrecise = mitk::PlanarCircle::New(); planarCirclePrecise->SetPlaneGeometry(preciseGeometry); planarCirclePrecise->PlaceFigure(p0precise); planarCirclePrecise->SetCurrentControlPoint(p1precise); planarCirclePrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarCirclePrecise.GetPointer()); + planarFigures.emplace("planarCirclePrecise",planarCirclePrecise.GetPointer()); // Create PlanarFourPointAngle mitk::PlanarFourPointAngle::Pointer planarFourPointAnglePrecise = mitk::PlanarFourPointAngle::New(); planarFourPointAnglePrecise->SetPlaneGeometry(preciseGeometry); planarFourPointAnglePrecise->PlaceFigure(p0precise); planarFourPointAnglePrecise->SetCurrentControlPoint(p1precise); planarFourPointAnglePrecise->AddControlPoint(p2precise); planarFourPointAnglePrecise->AddControlPoint(p3precise); planarFourPointAnglePrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarFourPointAnglePrecise.GetPointer()); + planarFigures.emplace("planarFourPointAnglePrecise",planarFourPointAnglePrecise.GetPointer()); // Create PlanarLine mitk::PlanarLine::Pointer planarLinePrecise = mitk::PlanarLine::New(); planarLinePrecise->SetPlaneGeometry(preciseGeometry); planarLinePrecise->PlaceFigure(p0precise); planarLinePrecise->SetCurrentControlPoint(p1precise); planarLinePrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarLinePrecise.GetPointer()); + planarFigures.emplace("planarLinePrecise",planarLinePrecise.GetPointer()); // Create PlanarPolygon mitk::PlanarPolygon::Pointer planarPolygonPrecise = mitk::PlanarPolygon::New(); planarPolygonPrecise->SetClosed(false); planarPolygonPrecise->SetPlaneGeometry(preciseGeometry); planarPolygonPrecise->PlaceFigure(p0precise); planarPolygonPrecise->SetCurrentControlPoint(p1precise); planarPolygonPrecise->AddControlPoint(p2precise); planarPolygonPrecise->AddControlPoint(p3precise); planarPolygonPrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarPolygonPrecise.GetPointer()); + planarFigures.emplace("planarPolygonPrecise",planarPolygonPrecise.GetPointer()); // Create PlanarSubdivisionPolygon mitk::PlanarSubdivisionPolygon::Pointer planarSubdivisionPolygonPrecise = mitk::PlanarSubdivisionPolygon::New(); planarSubdivisionPolygonPrecise->SetClosed(false); planarSubdivisionPolygonPrecise->SetPlaneGeometry(preciseGeometry); planarSubdivisionPolygonPrecise->PlaceFigure(p0precise); planarSubdivisionPolygonPrecise->SetCurrentControlPoint(p1precise); planarSubdivisionPolygonPrecise->AddControlPoint(p2precise); planarSubdivisionPolygonPrecise->AddControlPoint(p3precise); planarSubdivisionPolygonPrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarSubdivisionPolygonPrecise.GetPointer()); + planarFigures.emplace("planarSubdivisionPolygonPrecise",planarSubdivisionPolygonPrecise.GetPointer()); // Create PlanarRectangle mitk::PlanarRectangle::Pointer planarRectanglePrecise = mitk::PlanarRectangle::New(); planarRectanglePrecise->SetPlaneGeometry(preciseGeometry); planarRectanglePrecise->PlaceFigure(p0precise); planarRectanglePrecise->SetCurrentControlPoint(p1precise); planarRectanglePrecise->GetPropertyList()->SetBoolProperty("initiallyplaced", true); - planarFigures.push_back(planarRectanglePrecise.GetPointer()); + planarFigures.emplace("planarRectanglePrecise",planarRectanglePrecise.GetPointer()); return planarFigures; } - static PlanarFigureList CreateDeepCopiedPlanarFigures(PlanarFigureList original) + static PlanarFigureMap CreateClonedPlanarFigures(PlanarFigureMap original) { - PlanarFigureList copiedPlanarFigures; - - PlanarFigureList::iterator it1; + PlanarFigureMap copiedPlanarFigures; - for (it1 = original.begin(); it1 != original.end(); ++it1) + for (const auto& pf : original) { - mitk::PlanarFigure::Pointer copiedFigure = (*it1)->Clone(); + mitk::PlanarFigure::Pointer copiedFigure = pf.second->Clone(); - copiedPlanarFigures.push_back(copiedFigure); + copiedPlanarFigures[pf.first] = copiedFigure; } return copiedPlanarFigures; } - static PlanarFigureList CreateClonedPlanarFigures(PlanarFigureList original) - { - PlanarFigureList clonedPlanarFigures; - clonedPlanarFigures.resize(original.size()); - std::transform(original.begin(), original.end(), clonedPlanarFigures.begin(), Clone); - return clonedPlanarFigures; - } - - static void VerifyPlanarFigures(PlanarFigureList &planarFigures1, PlanarFigureList &planarFigures2) + static void VerifyPlanarFigures(PlanarFigureMap &referencePfs, PlanarFigureMap &testPfs) { - PlanarFigureList::iterator it1, it2; + PlanarFigureMap::iterator it1, it2; int i = 0; - for (it1 = planarFigures1.begin(); it1 != planarFigures1.end(); ++it1) + for (it1 = referencePfs.begin(); it1 != referencePfs.end(); ++it1) { bool planarFigureFound = false; int j = 0; - for (it2 = planarFigures2.begin(); it2 != planarFigures2.end(); ++it2) + for (it2 = testPfs.begin(); it2 != testPfs.end(); ++it2) { // Compare PlanarFigures (returns false if different types) - if (ComparePlanarFigures(*it1, *it2)) + if (ComparePlanarFigures(it1->second, it2->second)) { planarFigureFound = true; } ++j; } // Test if (at least) on PlanarFigure of the first type was found in the second list MITK_TEST_CONDITION_REQUIRED(planarFigureFound, - "Testing if " << (*it1)->GetNameOfClass() << " has a counterpart " << i); + "Testing if " << it1->second->GetNameOfClass() << " has a counterpart " << i); ++i; } } - static bool ComparePlanarFigures(mitk::PlanarFigure *figure1, mitk::PlanarFigure *figure2) + static bool ComparePlanarFigures(const mitk::PlanarFigure *referencePf, const mitk::PlanarFigure *testPf) { // Test if PlanarFigures are of same type; otherwise return - if (strcmp(figure1->GetNameOfClass(), figure2->GetNameOfClass()) != 0) + if (strcmp(referencePf->GetNameOfClass(), testPf->GetNameOfClass()) != 0) { return false; } - if (strcmp(figure1->GetNameOfClass(), "PlanarCross") == 0) + if (strcmp(referencePf->GetNameOfClass(), "PlanarCross") == 0) { std::cout << "Planar Cross Found" << std::endl; } // Test for equal number of control points - if (figure1->GetNumberOfControlPoints() != figure2->GetNumberOfControlPoints()) + if (referencePf->GetNumberOfControlPoints() != testPf->GetNumberOfControlPoints()) { return false; } // Test if all control points are equal - for (unsigned int i = 0; i < figure1->GetNumberOfControlPoints(); ++i) + for (unsigned int i = 0; i < referencePf->GetNumberOfControlPoints(); ++i) { - mitk::Point2D point1 = figure1->GetControlPoint(i); - mitk::Point2D point2 = figure2->GetControlPoint(i); + mitk::Point2D point1 = referencePf->GetControlPoint(i); + mitk::Point2D point2 = testPf->GetControlPoint(i); if (point1.EuclideanDistanceTo(point2) >= mitk::eps) { return false; } } // Test for equal number of properties typedef mitk::PropertyList::PropertyMap PropertyMap; - const PropertyMap *properties1 = figure1->GetPropertyList()->GetMap(); - const PropertyMap *properties2 = figure2->GetPropertyList()->GetMap(); - - if (properties1->size() != properties2->size()) - { - return false; - } + const PropertyMap *refProperties = referencePf->GetPropertyList()->GetMap(); + const PropertyMap *testProperties = testPf->GetPropertyList()->GetMap(); MITK_INFO << "List 1:"; - for (auto i1 = properties1->begin(); i1 != properties1->end(); ++i1) + for (auto i1 = refProperties->begin(); i1 != refProperties->end(); ++i1) { std::cout << i1->first << std::endl; } MITK_INFO << "List 2:"; - for (auto i2 = properties2->begin(); i2 != properties2->end(); ++i2) + for (auto i2 = testProperties->begin(); i2 != testProperties->end(); ++i2) { std::cout << i2->first << std::endl; } MITK_INFO << "-------"; - // Test if all properties are equal - if (!std::equal(properties1->begin(), properties1->end(), properties2->begin(), PropertyMapEntryCompare())) + //remark test planar figures may have additional properties + //(e.g. reader meta information), but they are not relevant + //for the test. Only check of all properties of the reference + //are present and correct. + for (const auto prop : *refProperties) { - return false; + auto finding = testProperties->find(prop.first); + if (finding == testProperties->end()) + { + return false; + } + + MITK_INFO << "Comparing " << prop.first << "(" << prop.second->GetValueAsString() << ") and " << finding->first + << "(" << finding->second->GetValueAsString() << ")"; + // Compare property objects contained in the map entries (see mitk::PropertyList) + if (!(*(prop.second) == *(finding->second))) return false; } // Test if Geometry is equal - const auto *planeGeometry1 = dynamic_cast(figure1->GetPlaneGeometry()); - const auto *planeGeometry2 = dynamic_cast(figure2->GetPlaneGeometry()); + const auto *planeGeometry1 = dynamic_cast(referencePf->GetPlaneGeometry()); + const auto *planeGeometry2 = dynamic_cast(testPf->GetPlaneGeometry()); // Test Geometry transform parameters typedef mitk::Geometry3D::TransformType TransformType; const TransformType *affineGeometry1 = planeGeometry1->GetIndexToWorldTransform(); const TransformType::ParametersType ¶meters1 = affineGeometry1->GetParameters(); const TransformType::ParametersType ¶meters2 = planeGeometry2->GetIndexToWorldTransform()->GetParameters(); for (unsigned int i = 0; i < affineGeometry1->GetNumberOfParameters(); ++i) { if (fabs(parameters1.GetElement(i) - parameters2.GetElement(i)) >= mitk::eps) { return false; } } // Test Geometry bounds typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType; const BoundsArrayType &bounds1 = planeGeometry1->GetBounds(); const BoundsArrayType &bounds2 = planeGeometry2->GetBounds(); for (unsigned int i = 0; i < 6; ++i) { if (fabs(bounds1.GetElement(i) - bounds2.GetElement(i)) >= mitk::eps) { return false; }; } // Test Geometry spacing and origin mitk::Vector3D spacing1 = planeGeometry1->GetSpacing(); mitk::Vector3D spacing2 = planeGeometry2->GetSpacing(); if ((spacing1 - spacing2).GetNorm() >= mitk::eps) { return false; } mitk::Point3D origin1 = planeGeometry1->GetOrigin(); mitk::Point3D origin2 = planeGeometry2->GetOrigin(); if (origin1.EuclideanDistanceTo(origin2) >= mitk::eps) { return false; } return true; } - static void SerializePlanarFigures(PlanarFigureList &planarFigures, std::string &fileName) + static PlanarFigureToStreamMap SerializePlanarFiguresToMemoryBuffers(PlanarFigureMap &planarFigures) { - // std::string sceneFileName = Poco::Path::temp() + /*Poco::Path::separator() +*/ "scene.zip"; - std::cout << "File name: " << fileName << std::endl; - - mitk::PlanarFigureWriter::Pointer writer = mitk::PlanarFigureWriter::New(); - writer->SetFileName(fileName.c_str()); + PlanarFigureToStreamMap pfMemoryStreams; - unsigned int i; - PlanarFigureList::iterator it; - for (it = planarFigures.begin(), i = 0; it != planarFigures.end(); ++it, ++i) + for (const auto& pf : planarFigures) { - writer->SetInput(i, *it); + mitk::FileWriterRegistry writerRegistry; + auto writers = writerRegistry.GetWriters(pf.second.GetPointer(), ""); + + std::ostringstream stream; + writers[0]->SetOutputStream("",&stream); + writers[0]->SetInput(pf.second); + writers[0]->Write(); + pfMemoryStreams.emplace(pf.first, stream.str()); } - writer->Update(); - - MITK_TEST_CONDITION_REQUIRED(writer->GetSuccess(), "Testing if writing was successful"); + return pfMemoryStreams; } - static PlanarFigureList DeserializePlanarFigures(std::string &fileName) + static PlanarFigureMap DeserializePlanarFiguresFromMemoryBuffers(PlanarFigureToStreamMap pfMemoryStreams) { - // Read in the planar figures - mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New(); - reader->SetFileName(fileName.c_str()); - reader->Update(); - - MITK_TEST_CONDITION_REQUIRED(reader->GetSuccess(), "Testing if reading was successful"); - // Store them in the list and return it - PlanarFigureList planarFigures; - for (unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i) - { - mitk::PlanarFigure *figure = reader->GetOutput(i); - planarFigures.push_back(figure); - } + PlanarFigureMap planarFigures; - return planarFigures; - } + mitk::FileReaderRegistry readerRegistry; + std::vector readers = + readerRegistry.GetReaders(mitk::FileReaderRegistry::GetMimeTypeForFile("pf")); - static PlanarFigureToMemoryWriterList SerializePlanarFiguresToMemoryBuffers(PlanarFigureList &planarFigures) - { - PlanarFigureToMemoryWriterList pfMemoryWriters; - unsigned int i; - PlanarFigureList::iterator it; - - bool success = true; - for (it = planarFigures.begin(), i = 0; it != planarFigures.end(); ++it, ++i) - { - mitk::PlanarFigureWriter::Pointer writer = mitk::PlanarFigureWriter::New(); - writer->SetWriteToMemory(true); - writer->SetInput(*it); - writer->Update(); - - pfMemoryWriters.push_back(writer); - - if (!writer->GetSuccess()) - success = false; - } - - MITK_TEST_CONDITION_REQUIRED(success, "Testing if writing to memory buffers was successful"); - - return pfMemoryWriters; - } - - static PlanarFigureList DeserializePlanarFiguresFromMemoryBuffers(PlanarFigureToMemoryWriterList pfMemoryWriters) - { - // Store them in the list and return it - PlanarFigureList planarFigures; - bool success = true; - for (unsigned int i = 0; i < pfMemoryWriters.size(); ++i) + for (const auto& pfStream : pfMemoryStreams) { - // Read in the planar figures - mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New(); - reader->SetReadFromMemory(true); - reader->SetMemoryBuffer(pfMemoryWriters[i]->GetMemoryPointer(), pfMemoryWriters[i]->GetMemorySize()); - reader->Update(); - mitk::PlanarFigure *figure = reader->GetOutput(0); - planarFigures.push_back(figure); - - if (!reader->GetSuccess()) - success = false; + std::istringstream stream; + stream.str(pfStream.second); + readers[0]->SetInput("", &stream); + auto pfRead = readers[0]->Read(); + MITK_TEST_CONDITION(pfRead.size() == 1, "One planar figure should be read from stream."); + auto pf = dynamic_cast(pfRead.front().GetPointer()); + MITK_TEST_CONDITION(pf != nullptr, "Loaded data should be a planar figure."); + planarFigures.emplace(pfStream.first, pf); } - MITK_TEST_CONDITION_REQUIRED(success, "Testing if reading was successful"); - return planarFigures; } -private: - class PropertyMapEntryCompare - { - public: - bool operator()(const mitk::PropertyList::PropertyMap::value_type &entry1, - const mitk::PropertyList::PropertyMap::value_type &entry2) - { - MITK_INFO << "Comparing " << entry1.first << "(" << entry1.second->GetValueAsString() << ") and " << entry2.first - << "(" << entry2.second->GetValueAsString() << ")"; - // Compare property objects contained in the map entries (see mitk::PropertyList) - return *(entry1.second) == *(entry2.second); - } - }; - }; // end test helper class /** \brief Test for PlanarFigure reader and writer classes. * * The test works as follows: * * First, a number of PlanarFigure objects of different types are created and placed with * various control points. These objects are the serialized to file, read again from file, and * the retrieved objects are compared with their control points, properties, and geometry * information to the original PlanarFigure objects. */ int mitkPlanarFigureIOTest(int /* argc */, char * /*argv*/ []) { MITK_TEST_BEGIN("PlanarFigureIO"); // Create a number of PlanarFigure objects - PlanarFigureIOTestClass::PlanarFigureList originalPlanarFigures = PlanarFigureIOTestClass::CreatePlanarFigures(); - - // Create a number of "deep-copied" planar figures to test the DeepCopy function (deprecated) - PlanarFigureIOTestClass::PlanarFigureList copiedPlanarFigures = - PlanarFigureIOTestClass::CreateDeepCopiedPlanarFigures(originalPlanarFigures); - - PlanarFigureIOTestClass::VerifyPlanarFigures(originalPlanarFigures, copiedPlanarFigures); + PlanarFigureIOTestClass::PlanarFigureMap originalPlanarFigures = PlanarFigureIOTestClass::CreatePlanarFigures(); // Create a number of cloned planar figures to test the Clone function - PlanarFigureIOTestClass::PlanarFigureList clonedPlanarFigures = + PlanarFigureIOTestClass::PlanarFigureMap clonedPlanarFigures = PlanarFigureIOTestClass::CreateClonedPlanarFigures(originalPlanarFigures); PlanarFigureIOTestClass::VerifyPlanarFigures(originalPlanarFigures, clonedPlanarFigures); - // Write PlanarFigure objects into temp file - // tmpname - static unsigned long count = 0; - unsigned long n = count++; - std::ostringstream name; - for (int i = 0; i < 6; ++i) + + std::map pfFileNameMap; + for (const auto& pf : originalPlanarFigures) { - name << char('a' + (n % 26)); - n /= 26; + std::string filename = mitk::IOUtil::CreateTemporaryFile(pf.first+"_XXXXXX.pf", itksys::SystemTools::GetCurrentWorkingDirectory()); + mitk::IOUtil::Save(pf.second, filename); + pfFileNameMap.emplace(pf.first, filename); } - std::string myname; - myname.append(name.str()); - - std::string fileName = itksys::SystemTools::GetCurrentWorkingDirectory() + myname + ".pf"; - - PlanarFigureIOTestClass::SerializePlanarFigures(originalPlanarFigures, fileName); // Write PlanarFigure objects to memory buffers - PlanarFigureIOTestClass::PlanarFigureToMemoryWriterList writersWithMemoryBuffers = + PlanarFigureIOTestClass::PlanarFigureToStreamMap writersStreams = PlanarFigureIOTestClass::SerializePlanarFiguresToMemoryBuffers(originalPlanarFigures); // Read PlanarFigure objects from temp file - PlanarFigureIOTestClass::PlanarFigureList retrievedPlanarFigures = - PlanarFigureIOTestClass::DeserializePlanarFigures(fileName); - - // Read PlanarFigure objects from memory buffers - PlanarFigureIOTestClass::PlanarFigureList retrievedPlanarFiguresFromMemory = - PlanarFigureIOTestClass::DeserializePlanarFiguresFromMemoryBuffers(writersWithMemoryBuffers); - - auto it = writersWithMemoryBuffers.begin(); - while (it != writersWithMemoryBuffers.end()) + PlanarFigureIOTestClass::PlanarFigureMap retrievedPlanarFigures; + for (const auto& files : pfFileNameMap) { - (*it)->ReleaseMemory(); - ++it; + auto pf = mitk::IOUtil::Load(files.second); + retrievedPlanarFigures.emplace(files.first, pf); } + // Read PlanarFigure objects from memory buffers + PlanarFigureIOTestClass::PlanarFigureMap retrievedPlanarFiguresFromMemory = + PlanarFigureIOTestClass::DeserializePlanarFiguresFromMemoryBuffers(writersStreams); + // Test if original and retrieved PlanarFigure objects are the same PlanarFigureIOTestClass::VerifyPlanarFigures(originalPlanarFigures, retrievedPlanarFigures); // Test if original and memory retrieved PlanarFigure objects are the same PlanarFigureIOTestClass::VerifyPlanarFigures(originalPlanarFigures, retrievedPlanarFiguresFromMemory); // empty the originalPlanarFigures originalPlanarFigures.clear(); - // Test if deep-copied and retrieved PlanarFigure objects are the same - PlanarFigureIOTestClass::VerifyPlanarFigures(copiedPlanarFigures, retrievedPlanarFigures); + // Test if cloned and retrieved PlanarFigure objects are the same + PlanarFigureIOTestClass::VerifyPlanarFigures(clonedPlanarFigures, retrievedPlanarFigures); MITK_TEST_END() } diff --git a/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp b/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp index ed99c4df76..66852cd761 100644 --- a/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp +++ b/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp @@ -1,202 +1,197 @@ /*============================================================================ 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 "mitkTestingMacros.h" #include #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(Angle2InteractionCreate); MITK_TEST(BezierCurveInteractionCreate); MITK_TEST(CircleInteractionCreate); MITK_TEST(DoubleEllipseInteractionCreate); MITK_TEST(PlanarFourPointAngleInteractionCreate); MITK_TEST(PlanarLineInteractionCreate); MITK_TEST(PlanarPolygonInteractionCreate); MITK_TEST(NonClosedPlanarPolygonInteractionCreate); MITK_TEST(RectangleInteractionCreate); // BUG 19304 // 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::Load(GetTestDataFilePath("Pic3D.nrrd")); figure->SetGeometry(testImage->GetGeometry()); 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); + auto reference = mitk::IOUtil::Load(GetTestDataFilePath(referenceFigurePath)); // 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/Angle1.xml", "InteractionTestData/ReferenceData/Angle1.pf"); } void Angle2InteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarAngle::New(); RunTest(figure, "InteractionTestData/Interactions/Angle2.xml", "InteractionTestData/ReferenceData/Angle2.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/SubdivisionPolygon.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"); } // this is only for the OpenGL check mitkPlanarFigureInteractionTestSuite() : m_RenderingTestHelper(300, 300) {} private: mitk::RenderingTestHelper m_RenderingTestHelper; }; MITK_TEST_SUITE_REGISTRATION(mitkPlanarFigureInteraction) diff --git a/Modules/QtWidgetsExt/CMakeLists.txt b/Modules/QtWidgetsExt/CMakeLists.txt index 5fc72f81b0..c2e295c41b 100644 --- a/Modules/QtWidgetsExt/CMakeLists.txt +++ b/Modules/QtWidgetsExt/CMakeLists.txt @@ -1,6 +1,6 @@ MITK_CREATE_MODULE( - DEPENDS MitkAlgorithmsExt MitkQtWidgets + DEPENDS MitkAlgorithmsExt MitkQtWidgets PRIVATE MitkSceneSerializationBase PACKAGE_DEPENDS PUBLIC Qwt CTK|CTKWidgets PRIVATE Qt5|Concurrent+Svg+Xml ) diff --git a/Modules/US/CMakeLists.txt b/Modules/US/CMakeLists.txt index 5add219afe..d45cfcac5f 100644 --- a/Modules/US/CMakeLists.txt +++ b/Modules/US/CMakeLists.txt @@ -1,16 +1,16 @@ MITK_CREATE_MODULE( SUBPROJECTS INCLUDE_DIRS USControlInterfaces USFilters USModel INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} - PACKAGE_DEPENDS Poco + PACKAGE_DEPENDS Poco PRIVATE tinyxml DEPENDS MitkOpenCVVideoSupport MitkQtWidgetsExt MitkIGTBase MitkOpenIGTLink ) ## create US config #CONFIGURE_FILE(mitkUSConfig.h.in ${PROJECT_BINARY_DIR}/mitkUSConfig.h @ONLY) ADD_SUBDIRECTORY(USHardwareTelemed) ADD_SUBDIRECTORY(USHardwareDiPhAS) ADD_SUBDIRECTORY(USNavigation) ADD_SUBDIRECTORY(Testing)