diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index 2efe3c5dc2..0a3ef325a0 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,325 +1,326 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkCoreActivator.cpp mitkCoreObjectFactoryBase.cpp mitkCoreObjectFactory.cpp mitkCoreServices.cpp mitkException.cpp Algorithms/mitkBaseDataSource.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGeometryTransformHolder.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkIPersistenceService.cpp DataManagement/mitkIPropertyAliases.cpp DataManagement/mitkIPropertyDescriptions.cpp DataManagement/mitkIPropertyExtensions.cpp DataManagement/mitkIPropertyFilters.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLine.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMaterial.cpp DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEvent.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkInteractionEventObserver.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkState.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkTransition.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkWheelEvent.cpp Interactions/mitkXML2EventParser.cpp IO/mitkAbstractFileIO.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkCustomMimeType.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSeriesReaderService.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileReaderWriterBase.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp + IO/mitkGeometry3DToXML.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkImageGenerator.cpp IO/mitkImageVtkLegacyIO.cpp IO/mitkImageVtkXmlIO.cpp IO/mitkIMimeTypeProvider.cpp IO/mitkIOConstants.cpp IO/mitkIOMimeTypes.cpp IO/mitkIOUtil.cpp IO/mitkItkImageIO.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkLegacyFileReaderService.cpp IO/mitkLegacyFileWriterService.cpp IO/mitkLog.cpp IO/mitkMimeType.cpp IO/mitkMimeTypeProvider.cpp IO/mitkOperation.cpp IO/mitkPixelType.cpp IO/mitkPointSetReaderService.cpp IO/mitkPointSetWriterService.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSurfaceStlIO.cpp IO/mitkSurfaceVtkIO.cpp IO/mitkSurfaceVtkLegacyIO.cpp IO/mitkSurfaceVtkXmlIO.cpp IO/mitkVtkLoggingAdapter.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkBaseRenderer.cpp #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module Rendering/mitkGradientBackground.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/mitkIShaderRepository.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkOverlay.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowFrame.cpp #Rendering/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/Core/src/IO/mitkGeometry3DToXML.cpp b/Modules/Core/src/IO/mitkGeometry3DToXML.cpp new file mode 100644 index 0000000000..2855711f6f --- /dev/null +++ b/Modules/Core/src/IO/mitkGeometry3DToXML.cpp @@ -0,0 +1,193 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkGeometry3DToXML.h" + +#include + +TiXmlElement* mitk::Geometry3DToXML::ToXML(const Geometry3D* geom3D) +{ + assert(geom3D); + + // really serialize + const AffineTransform3D* transform = geom3D->GetIndexToWorldTransform(); + + // get transform parameters that would need to be serialized + AffineTransform3D::MatrixType matrix = transform->GetMatrix(); + AffineTransform3D::OffsetType offset = transform->GetOffset(); + + bool isImageGeometry = geom3D->GetImageGeometry(); + BaseGeometry::BoundsArrayType bounds = geom3D->GetBounds(); + + // create XML file + // construct XML tree describing the geometry + TiXmlElement* geomElem = new TiXmlElement("Geometry3D"); + geomElem->SetAttribute("ImageGeometry", isImageGeometry ? "true" : "false" ); + geomElem->SetAttribute("FrameOfReferenceID", geom3D->GetFrameOfReferenceID()); + + // coefficients are matrix[row][column]! + TiXmlElement* matrixElem = new TiXmlElement("IndexToWorld"); + matrixElem->SetAttribute("type", "Matrix3x3"); + matrixElem->SetDoubleAttribute("m_0_0", matrix[0][0]); + matrixElem->SetDoubleAttribute("m_0_1", matrix[0][1]); + matrixElem->SetDoubleAttribute("m_0_2", matrix[0][2]); + matrixElem->SetDoubleAttribute("m_1_0", matrix[1][0]); + matrixElem->SetDoubleAttribute("m_1_1", matrix[1][1]); + matrixElem->SetDoubleAttribute("m_1_2", matrix[1][2]); + matrixElem->SetDoubleAttribute("m_2_0", matrix[2][0]); + matrixElem->SetDoubleAttribute("m_2_1", matrix[2][1]); + matrixElem->SetDoubleAttribute("m_2_2", matrix[2][2]); + geomElem->LinkEndChild(matrixElem); + + TiXmlElement* offsetElem = new TiXmlElement("Offset"); + offsetElem->SetAttribute("type", "Vector3D"); + offsetElem->SetDoubleAttribute("x", offset[0]); + offsetElem->SetDoubleAttribute("y", offset[1]); + offsetElem->SetDoubleAttribute("z", offset[2]); + geomElem->LinkEndChild(offsetElem); + + TiXmlElement* boundsElem = new TiXmlElement("Bounds"); + TiXmlElement* boundsMinElem = new TiXmlElement("Min"); + boundsMinElem->SetAttribute("type", "Vector3D"); + boundsMinElem->SetDoubleAttribute("x", bounds[0]); + boundsMinElem->SetDoubleAttribute("y", bounds[2]); + boundsMinElem->SetDoubleAttribute("z", bounds[4]); + boundsElem->LinkEndChild(boundsMinElem); + TiXmlElement* boundsMaxElem = new TiXmlElement("Max"); + boundsMaxElem->SetAttribute("type", "Vector3D"); + boundsMaxElem->SetDoubleAttribute("x", bounds[1]); + boundsMaxElem->SetDoubleAttribute("y", bounds[3]); + boundsMaxElem->SetDoubleAttribute("z", bounds[5]); + boundsElem->LinkEndChild(boundsMaxElem); + geomElem->LinkEndChild(boundsElem); + + return geomElem; +} + +mitk::Geometry3D::Pointer mitk::Geometry3DToXML::FromXML( TiXmlElement* geometryElement ) +{ + if (!geometryElement) + { + MITK_ERROR << "Cannot deserialize Geometry3D from nullptr."; + return nullptr; + } + + AffineTransform3D::MatrixType matrix; + AffineTransform3D::OffsetType offset; + bool isImageGeometry(false); + unsigned int frameOfReferenceID(0); + BaseGeometry::BoundsArrayType bounds; + + if ( TIXML_SUCCESS != geometryElement->QueryUnsignedAttribute("FrameOfReferenceID", &frameOfReferenceID) ) + { + MITK_WARN << "Missing FrameOfReference for Geometry3D."; + } + + if ( TIXML_SUCCESS != geometryElement->QueryBoolAttribute("ImageGeometry", &isImageGeometry) ) + { + MITK_WARN << "Missing bool ImageGeometry for Geometry3D."; + } + + // matrix + if ( TiXmlElement* matrixElem = geometryElement->FirstChildElement("IndexToWorld")->ToElement() ) + { + bool matrixComplete = true; + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_0_0", &matrix[0][0]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_0_1", &matrix[0][1]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_0_2", &matrix[0][2]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_1_0", &matrix[1][0]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_1_1", &matrix[1][1]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_1_2", &matrix[1][2]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_2_0", &matrix[2][0]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_2_1", &matrix[2][1]); + matrixComplete &= TIXML_SUCCESS == matrixElem->QueryDoubleAttribute("m_2_2", &matrix[2][2]); + + if ( !matrixComplete ) + { + MITK_ERROR << "Could not parse all Geometry3D matrix coefficients!"; + return nullptr; + } + } else + { + MITK_ERROR << "Parse error: expected Matrix3x3 child below Geometry3D node"; + return nullptr; + } + + // offset + if ( TiXmlElement* offsetElem = geometryElement->FirstChildElement("Offset")->ToElement() ) + { + bool vectorComplete = true; + vectorComplete &= TIXML_SUCCESS == offsetElem->QueryDoubleAttribute("x", &offset[0]); + vectorComplete &= TIXML_SUCCESS == offsetElem->QueryDoubleAttribute("y", &offset[1]); + vectorComplete &= TIXML_SUCCESS == offsetElem->QueryDoubleAttribute("z", &offset[2]); + + if ( !vectorComplete ) + { + MITK_ERROR << "Could not parse complete Geometry3D offset!"; + return nullptr; + } + } else + { + MITK_ERROR << "Parse error: expected Offset3D child below Geometry3D node"; + return nullptr; + } + + // bounds + if ( TiXmlElement* boundsElem = geometryElement->FirstChildElement("Bounds")->ToElement() ) + { + bool vectorsComplete(true); + if ( TiXmlElement* minElem = boundsElem->FirstChildElement("Min")->ToElement() ) + { + vectorsComplete &= TIXML_SUCCESS == minElem->QueryDoubleAttribute("x", &bounds[0]); + vectorsComplete &= TIXML_SUCCESS == minElem->QueryDoubleAttribute("y", &bounds[2]); + vectorsComplete &= TIXML_SUCCESS == minElem->QueryDoubleAttribute("z", &bounds[4]); + } else + { + vectorsComplete = false; + } + + if ( TiXmlElement* maxElem = boundsElem->FirstChildElement("Max")->ToElement() ) + { + vectorsComplete &= TIXML_SUCCESS == maxElem->QueryDoubleAttribute("x", &bounds[1]); + vectorsComplete &= TIXML_SUCCESS == maxElem->QueryDoubleAttribute("y", &bounds[3]); + vectorsComplete &= TIXML_SUCCESS == maxElem->QueryDoubleAttribute("z", &bounds[5]); + } else + { + vectorsComplete = false; + } + + if ( !vectorsComplete ) + { + MITK_ERROR << "Could not parse complete Geometry3D bounds!"; + return nullptr; + } + } + + // build GeometryData from matrix/offset + AffineTransform3D::Pointer newTransform = AffineTransform3D::New(); + newTransform->SetMatrix(matrix); + newTransform->SetOffset(offset); + + Geometry3D::Pointer newGeometry = Geometry3D::New(); + newGeometry->SetFrameOfReferenceID(frameOfReferenceID); + newGeometry->SetImageGeometry(isImageGeometry); + + newGeometry->SetIndexToWorldTransform(newTransform); + + newGeometry->SetBounds(bounds); + + return newGeometry; +} diff --git a/Modules/Core/src/IO/mitkGeometry3DToXML.h b/Modules/Core/src/IO/mitkGeometry3DToXML.h new file mode 100644 index 0000000000..865cbe78ff --- /dev/null +++ b/Modules/Core/src/IO/mitkGeometry3DToXML.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkPointSetToXML_h +#define mitkPointSetToXML_h + +// MITK +#include "mitkGeometry3D.h" + +class TiXmlElement; + +namespace mitk +{ + +/** + * @internal + * + * @brief Helper for Geometry3D related I/O classes. + * + * Creates TinyXML elements (blocks) that describe a Geometry3D. + * Also offers a method to read such blocks and create a corresponding Geometry3D. + * + * @sa PointSetWriterService, PointSetReaderService + * + * @ingroup IO + */ +class Geometry3DToXML +{ +public: + + /** + * @brief Serialize given geometry to XML. + */ + static TiXmlElement* ToXML( const Geometry3D* geometry); + + /** + * @brief Create a Geometry3D from XML. + * Interprets only the format created by ToXML(). + */ + static Geometry3D::Pointer FromXML( TiXmlElement* node ); +}; + +} + +#endif diff --git a/Modules/Core/src/IO/mitkPointSetReaderService.cpp b/Modules/Core/src/IO/mitkPointSetReaderService.cpp index 955d587de2..ea0f130916 100644 --- a/Modules/Core/src/IO/mitkPointSetReaderService.cpp +++ b/Modules/Core/src/IO/mitkPointSetReaderService.cpp @@ -1,130 +1,273 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // MITK #include "mitkPointSetReaderService.h" +#include "mitkGeometry3DToXML.h" +#include "mitkProportionalTimeGeometry.h" #include "mitkIOMimeTypes.h" // STL #include #include #include #include mitk::PointSetReaderService::PointSetReaderService() : AbstractFileReader(CustomMimeType(IOMimeTypes::POINTSET_MIMETYPE()), "MITK Point Set Reader") { RegisterService(); } mitk::PointSetReaderService::~PointSetReaderService() {} std::vector< itk::SmartPointer > mitk::PointSetReaderService::Read() { // Switch the current locale to "C" LocaleSwitch localeSwitch("C"); std::vector< itk::SmartPointer > result; InputStream stream(this); TiXmlDocument doc; stream >> doc; if (!doc.Error()) { TiXmlHandle docHandle( &doc ); //unsigned int pointSetCounter(0); for( TiXmlElement* currentPointSetElement = docHandle.FirstChildElement("point_set_file").FirstChildElement("point_set").ToElement(); currentPointSetElement != NULL; currentPointSetElement = currentPointSetElement->NextSiblingElement()) { mitk::PointSet::Pointer newPointSet = mitk::PointSet::New(); + + // time geometry assembled for addition after all points + // else the SetPoint method would already transform the points that we provide it + mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New(); + if(currentPointSetElement->FirstChildElement("time_series") != NULL) { for( TiXmlElement* currentTimeSeries = currentPointSetElement->FirstChildElement("time_series")->ToElement(); currentTimeSeries != NULL; currentTimeSeries = currentTimeSeries->NextSiblingElement()) { unsigned int currentTimeStep(0); TiXmlElement* currentTimeSeriesID = currentTimeSeries->FirstChildElement("time_series_id"); currentTimeStep = atoi(currentTimeSeriesID->GetText()); - newPointSet = this->ReadPoint(newPointSet, currentTimeSeries, currentTimeStep); + timeGeometry->Expand( currentTimeStep + 1 ); // expand (default to identity) in any case + TiXmlElement* geometryElem = currentTimeSeries->FirstChildElement("Geometry3D"); + if ( geometryElem ) + { + Geometry3D::Pointer geometry = Geometry3DToXML::FromXML(geometryElem); + if (geometry.IsNotNull()) + { + timeGeometry->SetTimeStepGeometry(geometry,currentTimeStep); + } + else + { + MITK_ERROR << "Could not deserialize Geometry3D element."; + } + } + else + { + MITK_WARN << "Fallback to legacy behavior: defining PointSet geometry as identity"; + } + + newPointSet = this->ReadPoints(newPointSet, currentTimeSeries, currentTimeStep); } } else { - newPointSet = this->ReadPoint(newPointSet, currentPointSetElement, 0); + newPointSet = this->ReadPoints(newPointSet, currentPointSetElement, 0); } + + newPointSet->SetTimeGeometry(timeGeometry); + result.push_back( newPointSet.GetPointer() ); } } else { mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc(); } return result; } -mitk::PointSet::Pointer mitk::PointSetReaderService::ReadPoint(mitk::PointSet::Pointer newPointSet, +mitk::BaseGeometry::Pointer mitk::PointSetReaderService::ReadGeometry(TiXmlElement* parentElement) +{ + TiXmlElement* geometryElem = parentElement->FirstChildElement("geometry3d"); + if (!geometryElem) return nullptr; + + // data to generate + AffineTransform3D::MatrixType matrix; + AffineTransform3D::OffsetType offset; + bool isImageGeometry(false); + unsigned int frameOfReferenceID(0); + BaseGeometry::BoundsArrayType bounds; + + bool somethingMissing(false); + + // find data in xml structure + TiXmlElement* imageGeometryElem = geometryElem->FirstChildElement("image_geometry"); + if (imageGeometryElem) + { + std::string igs = imageGeometryElem->GetText(); + isImageGeometry = igs == "true" || igs == "TRUE" || igs =="1"; + } + else + somethingMissing = true; + + TiXmlElement* frameOfReferenceElem = geometryElem->FirstChildElement("frame_of_reference_id"); + if (frameOfReferenceElem) + { + frameOfReferenceID = atoi(frameOfReferenceElem->GetText()); + } + else + somethingMissing = true; + + TiXmlElement* indexToWorldElem = geometryElem->FirstChildElement("index_to_world"); + if (indexToWorldElem) + { + TiXmlElement* matrixElem = indexToWorldElem->FirstChildElement("matrix3x3"); + TiXmlElement* offsetElem = indexToWorldElem->FirstChildElement("offset"); + if (indexToWorldElem && offsetElem) + { + TiXmlElement* col0 = matrixElem->FirstChildElement("column_0"); + TiXmlElement* col1 = matrixElem->FirstChildElement("column_1"); + TiXmlElement* col2 = matrixElem->FirstChildElement("column_2"); + + if (col0 && col1 && col2) + { + somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("x", &matrix[0][0]); + somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("y", &matrix[1][0]); + somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("z", &matrix[2][0]); + + somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("x", &matrix[0][1]); + somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("y", &matrix[1][1]); + somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("z", &matrix[2][1]); + + somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("x", &matrix[0][2]); + somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("y", &matrix[1][2]); + somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("z", &matrix[2][2]); + } + else + somethingMissing = true; + + somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("x", &offset[0]); + somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("y", &offset[1]); + somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("z", &offset[2]); + } + else + somethingMissing = true; + + TiXmlElement* boundsElem = geometryElem->FirstChildElement("bounds"); + if (boundsElem) + { + TiXmlElement* minBoundsElem = boundsElem->FirstChildElement("min"); + TiXmlElement* maxBoundsElem = boundsElem->FirstChildElement("max"); + + if (minBoundsElem && maxBoundsElem) + { + somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("x", &bounds[0]); + somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("y", &bounds[2]); + somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("z", &bounds[4]); + + somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("x", &bounds[1]); + somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("y", &bounds[3]); + somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("z", &bounds[5]); + } + else + somethingMissing = true; + } + else + somethingMissing = true; + } + else + somethingMissing = true; + + if (somethingMissing) + { + MITK_ERROR << "XML structure of geometry inside a PointSet file broken. Refusing to build Geometry3D"; + return nullptr; + } + else + { + Geometry3D::Pointer g = Geometry3D::New(); + g->SetImageGeometry( isImageGeometry ); + g->SetFrameOfReferenceID( frameOfReferenceID ); + g->SetBounds(bounds); + + AffineTransform3D::Pointer transform = AffineTransform3D::New(); + transform->SetMatrix(matrix); + transform->SetOffset(offset); + + g->SetIndexToWorldTransform( transform ); + + return g.GetPointer(); + } +} + +mitk::PointSet::Pointer mitk::PointSetReaderService::ReadPoints(mitk::PointSet::Pointer newPointSet, TiXmlElement* currentTimeSeries, unsigned int currentTimeStep) { if(currentTimeSeries->FirstChildElement("point") != NULL) { for( TiXmlElement* currentPoint = currentTimeSeries->FirstChildElement("point")->ToElement(); currentPoint != NULL; currentPoint = currentPoint->NextSiblingElement()) { unsigned int id(0); mitk::PointSpecificationType spec((mitk::PointSpecificationType) 0); double x(0.0); double y(0.0); double z(0.0); id = atoi(currentPoint->FirstChildElement("id")->GetText()); if(currentPoint->FirstChildElement("specification") != NULL) { spec = (mitk::PointSpecificationType) atoi(currentPoint->FirstChildElement("specification")->GetText()); } x = atof(currentPoint->FirstChildElement("x")->GetText()); y = atof(currentPoint->FirstChildElement("y")->GetText()); z = atof(currentPoint->FirstChildElement("z")->GetText()); mitk::Point3D point; mitk::FillVector3D(point, x, y, z); newPointSet->SetPoint(id, point, spec, currentTimeStep); } } else { if(currentTimeStep != newPointSet->GetTimeSteps()+1) { newPointSet->Expand(currentTimeStep+1); // expand time step series with empty time step } } return newPointSet; } mitk::PointSetReaderService::PointSetReaderService(const mitk::PointSetReaderService& other) : mitk::AbstractFileReader(other) { } mitk::PointSetReaderService* mitk::PointSetReaderService::Clone() const { return new mitk::PointSetReaderService(*this); } diff --git a/Modules/Core/src/IO/mitkPointSetReaderService.h b/Modules/Core/src/IO/mitkPointSetReaderService.h index df87265a71..786288ad49 100644 --- a/Modules/Core/src/IO/mitkPointSetReaderService.h +++ b/Modules/Core/src/IO/mitkPointSetReaderService.h @@ -1,64 +1,66 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITK_POINT_SET_READER_SERVICE__H_ #define _MITK_POINT_SET_READER_SERVICE__H_ // MITK #include #include class TiXmlElement; namespace mitk { /** * @internal * * @brief reads xml representations of mitk::PointSets from a file * * Reader for xml files containing one or multiple xml represenations of * mitk::PointSet. If multiple mitk::PointSet objects are stored in one file, * these are assigned to multiple BaseData objects. * * The reader is able to read the old 3D Pointsets without the "specification" and "timeseries" tags and the new 4D Pointsets. * * @ingroup IO */ class PointSetReaderService: public AbstractFileReader { public: PointSetReaderService(); virtual ~PointSetReaderService(); using AbstractFileReader::Read; virtual std::vector< itk::SmartPointer > Read() override; private: PointSetReaderService(const PointSetReaderService& other); - mitk::PointSet::Pointer ReadPoint(mitk::PointSet::Pointer newPointSet, + mitk::BaseGeometry::Pointer ReadGeometry(TiXmlElement* parentElement); + + mitk::PointSet::Pointer ReadPoints(mitk::PointSet::Pointer newPointSet, TiXmlElement* currentTimeSeries, unsigned int currentTimeStep); virtual PointSetReaderService* Clone() const override; }; } #endif diff --git a/Modules/Core/src/IO/mitkPointSetWriterService.cpp b/Modules/Core/src/IO/mitkPointSetWriterService.cpp index f70c461c16..b153a6798f 100644 --- a/Modules/Core/src/IO/mitkPointSetWriterService.cpp +++ b/Modules/Core/src/IO/mitkPointSetWriterService.cpp @@ -1,194 +1,189 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPointSetWriterService.h" +#include "mitkGeometry3DToXML.h" #include "mitkIOMimeTypes.h" +#include "mitkLocaleSwitch.h" + +#include "mitkGeometry3D.h" + +#include #include #include #include // // Initialization of the xml tags. // const std::string mitk::PointSetWriterService::XML_POINT_SET_FILE = "point_set_file" ; const std::string mitk::PointSetWriterService::XML_FILE_VERSION = "file_version" ; const std::string mitk::PointSetWriterService::XML_POINT_SET = "point_set" ; const std::string mitk::PointSetWriterService::XML_TIME_SERIES = "time_series"; const std::string mitk::PointSetWriterService::XML_TIME_SERIES_ID = "time_series_id"; const std::string mitk::PointSetWriterService::XML_POINT = "point" ; const std::string mitk::PointSetWriterService::XML_ID = "id" ; const std::string mitk::PointSetWriterService::XML_SPEC = "specification" ; const std::string mitk::PointSetWriterService::XML_X = "x" ; const std::string mitk::PointSetWriterService::XML_Y = "y" ; const std::string mitk::PointSetWriterService::XML_Z = "z" ; const std::string mitk::PointSetWriterService::VERSION_STRING = "0.1" ; mitk::PointSetWriterService::PointSetWriterService() : AbstractFileWriter(PointSet::GetStaticNameOfClass(), CustomMimeType(IOMimeTypes::POINTSET_MIMETYPE()), "MITK Point Set Writer") - , m_IndentDepth(0) - , m_Indent(2) { RegisterService(); } mitk::PointSetWriterService::PointSetWriterService(const mitk::PointSetWriterService& other) : AbstractFileWriter(other) - , m_IndentDepth(other.m_IndentDepth) - , m_Indent(other.m_Indent) { } mitk::PointSetWriterService::~PointSetWriterService() -{} +{ + +} void mitk::PointSetWriterService::Write() { - OutputStream out(this); + mitk::LocaleSwitch localeC("C"); - if ( !out.good() ) - { - mitkThrow() << "Stream not good."; - } + TiXmlDocument doc; - std::locale previousLocale(out.getloc()); - std::locale I("C"); - out.imbue(I); + TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere... + doc.LinkEndChild(decl); + + TiXmlElement* rootNode = new TiXmlElement(XML_POINT_SET_FILE); + doc.LinkEndChild(rootNode); - // - // Here the actual xml writing begins - // - WriteXMLHeader( out ); - WriteStartElement( XML_POINT_SET_FILE, out ); - WriteStartElement( XML_FILE_VERSION, out ); - out << VERSION_STRING; - WriteEndElement( XML_FILE_VERSION, out, false ); + TiXmlElement* versionNode = new TiXmlElement(XML_FILE_VERSION); + TiXmlText* versionText = new TiXmlText(VERSION_STRING ); + versionNode->LinkEndChild(versionText); + rootNode->LinkEndChild( versionNode ); - WriteXML( static_cast(this->GetInput()), out ); + TiXmlElement* pointSetNode = ToXML( static_cast(this->GetInput()) ); + if (!pointSetNode) + { + mitkThrow() << "Serialization error during PointSet writing."; + } + rootNode->LinkEndChild(pointSetNode); - WriteEndElement( XML_POINT_SET_FILE, out ); + //out << doc; // streaming of TinyXML write no new-lines, + // rendering XML files unreadable (for humans) - out.imbue(previousLocale); - if ( !out.good() ) // some error during output + LocalFile f(this); + if ( !doc.SaveFile( f.GetFileName() ) ) { mitkThrow() << "Some error during point set writing."; } } mitk::PointSetWriterService*mitk::PointSetWriterService::Clone() const { return new PointSetWriterService(*this); } -void mitk::PointSetWriterService::WriteXML( const mitk::PointSet* pointSet, std::ostream& out ) +TiXmlElement* mitk::PointSetWriterService::ToXML( const mitk::PointSet* pointSet ) { - WriteStartElement( XML_POINT_SET, out ); + // the following is rather bloated and could be expressed in more compact XML + // (e.g. using attributes instead of tags for x/y/z). The current format is + // kept to be compatible with the previous writer. + TiXmlElement* pointSetElement = new TiXmlElement( XML_POINT_SET ); unsigned int timecount = pointSet->GetTimeSteps(); for(unsigned int i=0; i< timecount; i++) { - WriteStartElement( XML_TIME_SERIES, out ); + TiXmlElement* timeSeriesElement = new TiXmlElement( XML_TIME_SERIES ); + pointSetElement->LinkEndChild(timeSeriesElement); - WriteStartElement( XML_TIME_SERIES_ID, out ); - out << ConvertToString( i ); - WriteEndElement( XML_TIME_SERIES_ID, out, false ); + TiXmlElement* timeSeriesIDElement = new TiXmlElement( XML_TIME_SERIES_ID ); + timeSeriesElement->LinkEndChild(timeSeriesIDElement); + TiXmlText* timeSeriesIDText = new TiXmlText(ConvertToString(i)); + timeSeriesIDElement->LinkEndChild(timeSeriesIDText); - mitk::PointSet::PointsContainer* pointsContainer = pointSet->GetPointSet(i)->GetPoints(); - mitk::PointSet::PointsContainer::Iterator it; + PointSet::PointsContainer* pointsContainer = pointSet->GetPointSet(i)->GetPoints(); + PointSet::PointsContainer::Iterator it; + + Geometry3D* geometry = dynamic_cast( pointSet->GetGeometry(i) ); + if (geometry == nullptr) + { + MITK_WARN << "Writing a PointSet with something other that a Geometry3D. This is not foreseen and not handled."; + // we'll continue anyway, this imitates previous behavior + } + else + { + TiXmlElement* geometryElement = Geometry3DToXML::ToXML( geometry ); + timeSeriesElement->LinkEndChild(geometryElement); + } for ( it = pointsContainer->Begin(); it != pointsContainer->End(); ++it ) { - WriteStartElement( XML_POINT, out ); + TiXmlElement* pointElement = new TiXmlElement(XML_POINT); + timeSeriesElement->LinkEndChild(pointElement); - WriteStartElement( XML_ID, out ); - out << ConvertToString( it->Index() ); - WriteEndElement( XML_ID, out, false ); + TiXmlElement* pointIDElement = new TiXmlElement(XML_ID); + TiXmlText* pointIDText = new TiXmlText( ConvertToString( it->Index() ) ); + pointIDElement->LinkEndChild(pointIDText); + pointElement->LinkEndChild(pointIDElement); mitk::PointSet::PointType point = it->Value(); - WriteStartElement( XML_SPEC, out ); - out << ConvertToString( pointSet->GetSpecificationTypeInfo(it->Index(), i) ); - WriteEndElement( XML_SPEC, out, false ); - - WriteStartElement( XML_X, out ); - out << ConvertToString( point[ 0 ] ); - WriteEndElement( XML_X, out, false ); - - WriteStartElement( XML_Y, out ); - out << ConvertToString( point[ 1 ] ); - WriteEndElement( XML_Y, out, false ); - - WriteStartElement( XML_Z, out ); - out << ConvertToString( point[ 2 ] ); - WriteEndElement( XML_Z, out, false ); - - WriteEndElement( XML_POINT, out ); + TiXmlElement* pointSpecElement = new TiXmlElement(XML_SPEC); + TiXmlText* pointSpecText = new TiXmlText( ConvertToString( pointSet->GetSpecificationTypeInfo(it->Index(), i) ) ); + pointSpecElement->LinkEndChild(pointSpecText); + pointElement->LinkEndChild(pointSpecElement); + + TiXmlElement* pointXElement = new TiXmlElement(XML_X); + TiXmlText* pointXText = new TiXmlText( ConvertToString( point[0] ) ); + pointXElement->LinkEndChild(pointXText); + pointElement->LinkEndChild(pointXElement); + + TiXmlElement* pointYElement = new TiXmlElement(XML_Y); + TiXmlText* pointYText = new TiXmlText( ConvertToString( point[1] ) ); + pointYElement->LinkEndChild(pointYText); + pointElement->LinkEndChild(pointYElement); + + TiXmlElement* pointZElement = new TiXmlElement(XML_Z); + TiXmlText* pointZText = new TiXmlText( ConvertToString( point[2] ) ); + pointZElement->LinkEndChild(pointZText); + pointElement->LinkEndChild(pointZElement); } - WriteEndElement( XML_TIME_SERIES, out ); } - WriteEndElement( XML_POINT_SET, out ); + return pointSetElement; } template < typename T> std::string mitk::PointSetWriterService::ConvertToString( T value ) { std::ostringstream o; std::locale I("C"); o.imbue(I); - if ( o << value ) + if ( o << std::setprecision(12) << value ) { return o.str(); } else { return "conversion error"; } -} - -void mitk::PointSetWriterService::WriteXMLHeader( std::ostream &file ) -{ - file << ""; -} - -void mitk::PointSetWriterService::WriteStartElement( const std::string& tag, std::ostream &file ) -{ - file << std::endl; - WriteIndent( file ); - file << '<' << tag << '>'; - m_IndentDepth++; -} - -void mitk::PointSetWriterService::WriteEndElement( const std::string& tag, std::ostream &file, const bool& indent ) -{ - m_IndentDepth--; - if ( indent ) - { - file << std::endl; - WriteIndent( file ); - } - file << '<' << '/' << tag << '>'; -} - -void mitk::PointSetWriterService::WriteIndent( std::ostream& file ) -{ - std::string spaces( m_IndentDepth * m_Indent, ' ' ); - file << spaces; -} +} \ No newline at end of file diff --git a/Modules/Core/src/IO/mitkPointSetWriterService.h b/Modules/Core/src/IO/mitkPointSetWriterService.h index 9ad8a5a58b..98cd5aa8a6 100644 --- a/Modules/Core/src/IO/mitkPointSetWriterService.h +++ b/Modules/Core/src/IO/mitkPointSetWriterService.h @@ -1,112 +1,81 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITK_POINT_SET_WRITER_SERVICE__H_ #define _MITK_POINT_SET_WRITER_SERVICE__H_ #include #include +class TiXmlElement; + namespace mitk { +class Geometry3D; + /** * @internal * * @brief XML-based writer for mitk::PointSets * * XML-based writer for mitk::PointSet. Multiple PointSets can be written in * a single XML file by simply setting multiple inputs to the filter. * + * @todo This class would merit a XML library for maintainability or a denser format for performance. + * * @ingroup IO */ class PointSetWriterService : public AbstractFileWriter { public: PointSetWriterService(); virtual ~PointSetWriterService(); using AbstractFileWriter::Write; virtual void Write() override; private: PointSetWriterService(const PointSetWriterService& other); virtual mitk::PointSetWriterService* Clone() const override; - /** - * Converts an arbitrary type to a string. The type has to - * support the << operator. This works fine at least for integral - * data types as float, int, long etc. - * @param value the value to convert - * @returns the string representation of value - */ template < typename T> std::string ConvertToString( T value ); - /** - * Writes an XML representation of the given point set to - * an outstream. The XML-Header an root node is not included! - * @param pointSet the point set to be converted to xml - * @param out the stream to write to. - */ - void WriteXML( const mitk::PointSet* pointSet, std::ostream& out ); - - /** - * Writes an standard xml header to the given stream. - * @param file the stream in which the header is written. - */ - void WriteXMLHeader( std::ostream &file ); - - /** - * Write an end element tag - * End-Elements following character data should pass indent = false. - */ - void WriteEndElement( const std::string& tag, std::ostream &file, const bool& indent = true ); - - /** Write a start element tag */ - void WriteStartElement( const std::string &tag, std::ostream &file ); - - /** Write character data inside a tag. */ - void WriteCharacterData( const std::string &data, std::ostream &file ); - - /** Writes empty spaces to the stream according to m_IndentDepth and m_Indent */ - void WriteIndent( std::ostream& file ); - - unsigned int m_IndentDepth; - const unsigned int m_Indent; + TiXmlElement* ToXML( const mitk::PointSet* pointSet ); static const std::string XML_POINT_SET; static const std::string XML_TIME_SERIES; static const std::string XML_TIME_SERIES_ID; static const std::string XML_POINT_SET_FILE; static const std::string XML_FILE_VERSION; static const std::string XML_POINT; static const std::string XML_SPEC; static const std::string XML_ID; static const std::string XML_X; static const std::string XML_Y; static const std::string XML_Z; static const std::string VERSION_STRING; }; } #endif diff --git a/Modules/Core/test/CMakeLists.txt b/Modules/Core/test/CMakeLists.txt index 8676f4097f..742b45f2a1 100644 --- a/Modules/Core/test/CMakeLists.txt +++ b/Modules/Core/test/CMakeLists.txt @@ -1,226 +1,223 @@ # The core tests need relaxed compiler flags... # TODO fix core tests to compile without these additional no-error flags if(MSVC_VERSION) # disable deprecated warnings (they would lead to errors) mitkFunctionCheckCAndCXXCompilerFlags("/wd4996" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated-declarations" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() MITK_CREATE_MODULE_TESTS() if(TARGET ${TESTDRIVER}) mitk_use_modules(TARGET ${TESTDRIVER} PACKAGES ITK|ITKThresholding+ITKTestKernel VTK|vtkTestingRendering tinyxml) mitkAddCustomModuleTest(mitkVolumeCalculatorTest_Png2D-bw mitkVolumeCalculatorTest ${MITK_DATA_DIR}/Png2D-bw.png ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkEventMapperTest_Test1And2 mitkEventMapperTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml ) mitkAddCustomModuleTest(mitkEventConfigTest_CreateObjectInDifferentWays mitkEventConfigTest ${MITK_SOURCE_DIR}/Modules/Core/test/resource/Interactions/StatemachineConfigTest.xml ) mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/BallBinary30x30x30.nrrd ) mitkAddCustomModuleTest(mitkDataStorageTest_US4DCyl mitkDataStorageTest ${MITK_DATA_DIR}/US4DCyl.nrrd ) mitkAddCustomModuleTest(mitkStateMachineFactoryTest_TestStateMachine1_2 mitkStateMachineFactoryTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml ) mitkAddCustomModuleTest(mitkDicomSeriesReaderTest_CTImage mitkDicomSeriesReaderTest ${MITK_DATA_DIR}/TinyCTAbdomen ${MITK_DATA_DIR}/DICOMReader/Broken-Series ) mitkAddCustomModuleTest(mitkPointSetReaderTest mitkPointSetReaderTest ${MITK_DATA_DIR}/PointSetReaderTestData.mps ) mitkAddCustomModuleTest(mitkImageTest_4DImageData mitkImageTest ${MITK_DATA_DIR}/US4DCyl.nrrd ) mitkAddCustomModuleTest(mitkImageTest_2D+tImageData mitkImageTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkImageEqualTest mitkImageEqualTest) mitkAddCustomModuleTest(mitkImageTest_brainImage mitkImageTest ${MITK_DATA_DIR}/brain.mhd ) mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageGeneratorTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkLevelWindowManagerTest mitkLevelWindowManagerTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkMultiComponentImageDataComparisonFilterTest mitkMultiComponentImageDataComparisonFilterTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg ) mitkAddCustomModuleTest(mitkImageToItkTest mitkImageToItkTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkImageSliceSelectorTest mitkImageSliceSelectorTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkRotatedSlice4DTest mitkRotatedSlice4DTest ${MITK_DATA_DIR}/UltrasoundImages/4D_TEE_Data_MV.dcm ) if(MITK_ENABLE_RENDERING_TESTING) ### since the rendering test's do not run in ubuntu, yet, we build them only for other systems or if the user explicitly sets the variable MITK_ENABLE_RENDERING_TESTING mitkAddCustomModuleTest(mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/rgbaImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3d640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2DColorTest #test for color property (=blue) Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dColorBlue640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2DLevelWindowTest #test for levelwindow property (=blood) #Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dLevelWindowBlood640x480REF.png #corresponding reference #screenshot ) #mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dOpacity640x480 mitkImageVtkMapper2DOpacityTest #test for opacity (=0.5) Pic3D coronal slice # ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dOpacity640x480REF.png corresponding reference screenshot #) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DSwivelTest #test for a randomly chosen Pic3D swivelled slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dSwivel640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAlone640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2DImageTest ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/PointSetForPic3D.mps #input point set and image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Pic3DPointSetForPic3D640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2DGlyphTypeTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneGlyphType640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 mitkPointSetVtkMapper2DTransformedPointsTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneTransformedPoints640x480REF.png #corresponding reference screenshot ) # Currently not working on windows because of a rendering timing issue # see bug 18083 for details if(NOT WIN32) mitkAddCustomModuleTest(mitkSurfaceDepthSortingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthSortingTest ${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthSorting640x480REF.png ) endif() if(NOT APPLE) mitkAddCustomModuleTest(mitkSurfaceDepthPeelingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthPeelingTest ${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthPeeling640x480REF.png #corresponding reference screenshot ) endif() #Test reslice interpolation #note: nearest mode is already tested by swivel test mitkAddCustomModuleTest(ResliceInterpolationIsLinear mitkImageVtkMapper2DResliceInterpolationPropertyTest 1 #linear ${MITK_DATA_DIR}/Pic3D.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefLinear.png #corresponding reference screenshot LINEAR ) mitkAddCustomModuleTest(ResliceInterpolationIsCubic mitkImageVtkMapper2DResliceInterpolationPropertyTest 3 #cubic ${MITK_DATA_DIR}/Pic3D.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefCubic.png #corresponding reference screenshot CUBIC ) #End test reslice interpolation # Testing of the rendering of binary images #mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImage640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice # ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImage640x480REF.png #corresponding reference screenshot #) #mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImageWithRef640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice # ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImageWithRef640x480REF.png #corresponding reference screenshot #) # End of binary image tests mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTest_TextureProperty mitkSurfaceVtkMapper3DTest ${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom.vtp ${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom_RGBImage.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedLiver640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-TransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2DOpacityTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DOpacityTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-OpacityTransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) ############################## DISABLED TESTS #Removed due to high rendering error. #mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTexturedSphereTest_Football mitkSurfaceVtkMapper3DTexturedSphereTest # ${MITK_DATA_DIR}/RenderingTestData/texture.jpg #input texture # -V # ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedSphere640x480REF.png corresponding reference screenshot #) mitkAddCustomModuleTest(mitkImageVtkMapper2DLookupTableTest_Png2D-bw mitkImageVtkMapper2DLookupTableTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-LookupTableRGBImage640x480REF.png #corresponding reference screenshot ) #mitkAddCustomModuleTest(mitkImageTest_color2DImage mitkImageTest # ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg #) #mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest # ${MITK_DATA_DIR}/Pic3D.pic.gz ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz #) SET_PROPERTY(TEST mitkRotatedSlice4DTest mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw # mitkImageVtkMapper2D_pic3dOpacity640x480 mitkSurfaceVtkMapper2DTest mitkSurfaceVtkMapper3DTest_TextureProperty mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 #mitkSurfaceVtkMapper3DTexturedSphereTest_Football PROPERTY RUN_SERIAL TRUE) endif() - add_test(mitkPointSetLocaleTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkPointSetLocaleTest ${MITK_DATA_DIR}/pointSet.mps) - set_property(TEST mitkPointSetLocaleTest PROPERTY LABELS MITK-Core) - endif() # TARGET ${TESTDRIVER} diff --git a/Modules/Core/test/files.cmake b/Modules/Core/test/files.cmake index 0a398c0f8b..1e7773a72e 100644 --- a/Modules/Core/test/files.cmake +++ b/Modules/Core/test/files.cmake @@ -1,195 +1,196 @@ # tests with no extra command line parameter set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## DISABLED TESTS ################################################# #mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesnt exist any more #mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529 #mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more #mitkSegmentationInterpolationTest.cpp #file doesn't exist! #mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist! #mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK #mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more #mitkTestUtilSharedLibrary.cpp #Linker problem with this test... #mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details. ################# RUNNING TESTS ################################################### mitkAccessByItkTest.cpp mitkCoreObjectFactoryTest.cpp mitkDataNodeTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkDispatcherTest.cpp mitkEnumerationPropertyTest.cpp mitkEventTest.cpp mitkFileReaderRegistryTest.cpp #mitkFileWriterRegistryTest.cpp mitkFocusManagerTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometry3DEqualTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkGlobalInteractionTest.cpp mitkImageCastTest.cpp mitkImageEqualTest.cpp mitkImageDataItemTest.cpp mitkImageGeneratorTest.cpp mitkIOUtilTest.cpp mitkBaseDataTest.cpp mitkImportItkImageTest.cpp mitkGrabItkImageMemoryTest.cpp mitkInstantiateAccessFunctionTest.cpp mitkInteractorTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetTest.cpp mitkPointSetEqualTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetOnEmptyTest.cpp + mitkPointSetLocaleTest.cpp mitkPointSetWriterTest.cpp mitkPointSetReaderTest.cpp mitkPointSetInteractorTest.cpp mitkPointSetPointOperationsTest.cpp mitkProgressBarTest.cpp mitkPropertyTest.cpp mitkPropertyListTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkStateMachineTest.cpp mitkStateTest.cpp mitkSurfaceTest.cpp mitkSurfaceEqualTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeGeometryTest.cpp mitkProportionalTimeGeometryTest.cpp mitkTransitionTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp mitkStepperTest.cpp mitkRenderingManagerTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp mitkVectorTest.cpp mitkClippedSurfaceBoundsCalculatorTest.cpp mitkExceptionTest.cpp mitkExtractSliceFilterTest.cpp mitkLogTest.cpp mitkImageDimensionConverterTest.cpp mitkLoggingAdapterTest.cpp mitkUIDGeneratorTest.cpp mitkShaderRepositoryTest.cpp mitkPlanePositionManagerTest.cpp mitkAffineTransformBaseTest.cpp mitkPropertyAliasesTest.cpp mitkPropertyDescriptionsTest.cpp mitkPropertyExtensionsTest.cpp mitkPropertyFiltersTest.cpp mitkTinyXMLTest.cpp mitkRawImageFileReaderTest.cpp mitkInteractionEventTest.cpp mitkLookupTableTest.cpp mitkSTLFileReaderTest.cpp mitkPointTypeConversionTest.cpp mitkVectorTypeConversionTest.cpp mitkMatrixTypeConversionTest.cpp mitkArrayTypeConversionTest.cpp mitkSurfaceToImageFilterTest.cpp mitkBaseGeometryTest.cpp mitkImageToSurfaceFilterTest.cpp mitkEqualTest.cpp mitkLineTest.cpp mitkItkImageIOTest.cpp mitkRotatedSlice4DTest.cpp ) if(MITK_ENABLE_RENDERING_TESTING) set(MODULE_TESTS ${MODULE_TESTS} mitkPointSetDataInteractorTest.cpp #since mitkInteractionTestHelper is currently creating a vtkRenderWindow mitkSurfaceVtkMapper2DTest.cpp #new rendering test in CppUnit style ) endif() # test with image filename as an extra command line parameter set(MODULE_IMAGE_TESTS mitkImageTimeSelectorTest.cpp #only runs on images mitkImageAccessorTest.cpp #only runs on images ) set(MODULE_SURFACE_TESTS mitkSurfaceVtkWriterTest.cpp #only runs on surfaces ) # list of images for which the tests are run set(MODULE_TESTIMAGES US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd Png2D-bw.png ) set(MODULE_TESTSURFACES binary.stl ball.stl ) set(MODULE_CUSTOM_TESTS mitkDataStorageTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkDataNodeTest.cpp mitkEventMapperTest.cpp mitkEventConfigTest.cpp mitkNodeDependentPointSetInteractorTest.cpp mitkStateMachineFactoryTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp mitkImageVtkMapper2DTest.cpp mitkImageVtkMapper2DLevelWindowTest.cpp mitkImageVtkMapper2DOpacityTest.cpp mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp mitkImageVtkMapper2DColorTest.cpp mitkImageVtkMapper2DSwivelTest.cpp mitkImageVtkMapper2DTransferFunctionTest.cpp mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp mitkImageVtkMapper2DLookupTableTest.cpp mitkSurfaceVtkMapper3DTest mitkSurfaceVtkMapper3DTexturedSphereTest.cpp mitkVolumeCalculatorTest.cpp mitkLevelWindowManagerTest.cpp mitkPointSetVtkMapper2DTest.cpp mitkPointSetVtkMapper2DImageTest.cpp mitkPointSetVtkMapper2DGlyphTypeTest.cpp mitkPointSetVtkMapper2DTransformedPointsTest.cpp mitkVTKRenderWindowSizeTest.cpp mitkMultiComponentImageDataComparisonFilterTest.cpp mitkImageToItkTest.cpp mitkImageSliceSelectorTest.cpp mitkSurfaceDepthPeelingTest.cpp ) # Currently not working on windows because of a rendering timing issue # see bug 18083 for details if(NOT WIN32) set(MODULE_CUSTOM_TESTS ${MODULE_CUSTOM_TESTS} mitkSurfaceDepthSortingTest.cpp) endif() set(RESOURCE_FILES Interactions/AddAndRemovePoints.xml Interactions/globalConfig.xml Interactions/StatemachineTest.xml Interactions/StatemachineConfigTest.xml ) diff --git a/Modules/Core/test/mitkPointSetFileIOTest.cpp b/Modules/Core/test/mitkPointSetFileIOTest.cpp index a925e6a772..dfc1aac847 100644 --- a/Modules/Core/test/mitkPointSetFileIOTest.cpp +++ b/Modules/Core/test/mitkPointSetFileIOTest.cpp @@ -1,156 +1,204 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPointSet.h" #include "mitkTestingMacros.h" #include "mitkFileWriterRegistry.h" #include "mitkIOUtil.h" +#include "mitkProportionalTimeGeometry.h" #include #include #include +#include //unsigned int numberOfTestPointSets = 1; unsigned int numberOfTimeSeries = 5; // create one test PointSet class mitkPointSetFileIOTestClass { public: mitk::PointSet::Pointer m_SavedPointSet; std::string m_FilePath; mitkPointSetFileIOTestClass() { } ~mitkPointSetFileIOTestClass() { if (!m_FilePath.empty()) { std::remove(m_FilePath.c_str()); } } - mitk::PointSet::Pointer CreateTestPointSet() + mitk::PointSet::Pointer CreateTestPointSet(mitk::BaseGeometry* geometry = nullptr) { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); + std::uniform_real_distribution<> r(0, 1); + std::mt19937 gen; for (unsigned int t = 0; t < numberOfTimeSeries; t++) { - unsigned int position(0); - mitk::Point3D point; - mitk::FillVector3D(point, (rand()%1000) /1000.0 , (rand()%1000) /1000.0, (rand()%1000)/1000.0); - pointSet->SetPoint(position, point, t); - - mitk::FillVector3D(point, (rand()%1000) /1000.0 , (rand()%1000) /1000.0, (rand()%1000)/1000.0); - ++position; - pointSet->SetPoint(position, point, t); - - mitk::FillVector3D(point, (rand()%1000) /1000.0 , (rand()%1000) /1000.0, (rand()%1000)/1000.0); - ++position; - pointSet->SetPoint(position, point, t); + for (unsigned int position = 0; position < 3; ++position) + { + mitk::Point3D point; + mitk::FillVector3D(point, r(gen), r(gen), r(gen)); + pointSet->SetPoint(position, point, t); + } } m_SavedPointSet = pointSet; - return pointSet; + // we set the geometry AFTER adding points. Else all points added via SetPoint would already bee transformed + if (geometry != nullptr) + { + mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New(); + timeGeometry->Initialize( geometry, numberOfTimeSeries ); + pointSet->SetTimeGeometry( timeGeometry ); + } + return pointSet; } void PointSetCompare(mitk::PointSet::Pointer pointSet2, mitk::PointSet::Pointer pointSet1, bool& /*identical*/) { - MITK_TEST_CONDITION(pointSet1->GetSize() == pointSet2->GetSize(), "Testing if PointSet size is correct" ); for (unsigned int t = 0; t < numberOfTimeSeries; t++) { for (unsigned int i = 0; i < (unsigned int) pointSet1->GetSize(t); ++i) { mitk::Point3D p1 = pointSet1->GetPoint(i); mitk::Point3D p2 = pointSet2->GetPoint(i); //test std::cout << "r point: " << p2 << std::endl; std::cout << "w point: " << p1 << std::endl; //test end MITK_TEST_CONDITION((p1[0] - p2[0]) <= 0.0001, "Testing if X coordinates of the Point are at the same Position" ); MITK_TEST_CONDITION((p1[1] - p2[1]) <= 0.0001, "Testing if Y coordinates of the Point are at the same Position" ); MITK_TEST_CONDITION((p1[2] - p2[2]) <= 0.0001, "Testing if Z coordinates of the Point are at the same Position" ); } } + // testing geometry + MITK_TEST_CONDITION( mitk::Equal( *(pointSet1->GetGeometry()), *(pointSet2->GetGeometry()), 0.000001, true), + "Restored geometry must equal original one."); } - bool PointSetWrite() + bool PointSetWrite(mitk::BaseGeometry* geometry = nullptr) { try { m_SavedPointSet = NULL; std::ofstream tmpStream; - m_FilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream); - mitk::IOUtil::Save(CreateTestPointSet(), m_FilePath); + m_FilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream) + ".mps"; + MITK_INFO << "PointSet test file at " << m_FilePath; + mitk::IOUtil::Save(CreateTestPointSet(geometry), m_FilePath); } - catch (std::exception& /*e*/) + catch (std::exception& e) { + MITK_ERROR << "Error during pointset creation: " << e.what(); return false; } return true; } void PointSetLoadAndCompareTest() { try { mitk::PointSet::Pointer pointSet = mitk::IOUtil::LoadPointSet(m_FilePath); MITK_TEST_CONDITION(pointSet.IsNotNull(), "Testing if the loaded Data are NULL" ); bool identical(true); PointSetCompare(pointSet.GetPointer(), m_SavedPointSet.GetPointer(), identical); - } catch (std::exception& /*e*/) + } catch (std::exception& e) { + MITK_ERROR << "Error during pointset creation: " << e.what(); } } }; //mitkPointSetFileIOTestClass int mitkPointSetFileIOTest(int, char*[]) { MITK_TEST_BEGIN("PointSet"); - mitkPointSetFileIOTestClass* test = new mitkPointSetFileIOTestClass(); - - // write - MITK_TEST_CONDITION(test->PointSetWrite(), "Testing if the PointSetWriter writes Data" ); + // minimum test w/ identity geometry + { + mitkPointSetFileIOTestClass test; + MITK_TEST_CONDITION(test.PointSetWrite(), "Testing if the PointSetWriter writes Data" ); + test.PointSetLoadAndCompareTest(); // load - compare + } - // load - compare - test->PointSetLoadAndCompareTest(); + // case with a more complex geometry + { + mitkPointSetFileIOTestClass test; + + mitk::Geometry3D::Pointer g = mitk::Geometry3D::New(); + + // define arbitrary transformation matrix + // the number don't have much meaning - we just want them reproduced + // by the writer/reader cycle + mitk::BaseGeometry::BoundsArrayType bounds; + bounds[0] = -918273645.18293746; + bounds[1] = -52.723; + bounds[2] = -1.002; + bounds[3] = 918273645.18293746; + bounds[4] = +1.002; + bounds[5] = +52.723; + g->SetBounds(bounds); + + mitk::ScalarType matrixCoeffs[9] = { + 0.0, 1.1, 2.2, + 3.3, 4.4, 5.5, + 6.6, 7.7, 8.8 + }; + + mitk::AffineTransform3D::MatrixType matrix; + matrix.GetVnlMatrix().set(matrixCoeffs); + + mitk::AffineTransform3D::OffsetType offset; + offset[0] = -43.1829374; + offset[1] = 0.0; + offset[2] = +43.1829374; + + mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New(); + transform->SetMatrix(matrix); + transform->SetOffset(offset); + g->SetIndexToWorldTransform(transform); + + MITK_TEST_CONDITION( test.PointSetWrite(g), "Testing if the PointSetWriter writes Data _with_ geometry" ); + test.PointSetLoadAndCompareTest(); // load - compare + } - //Delete correctly - delete test; MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkPointSetLocaleTest.cpp b/Modules/Core/test/mitkPointSetLocaleTest.cpp index 1e4af92832..9c41c4c9d9 100644 --- a/Modules/Core/test/mitkPointSetLocaleTest.cpp +++ b/Modules/Core/test/mitkPointSetLocaleTest.cpp @@ -1,170 +1,170 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPointSet.h" #include "mitkStandardFileLocations.h" #include "mitkIOUtil.h" #include "mitkTestingMacros.h" #include #include #include #include bool ChangeLocale(const std::string& locale) { try { MITK_TEST_OUTPUT(<< "\n** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'"); setlocale(LC_ALL, locale.c_str()); std::locale l( locale.c_str() ); std::cin.imbue(l); std::cout.imbue(l); return true; } catch(...) { - MITK_TEST_OUTPUT(<< "Could not activate locale" << locale << "\n"); + MITK_TEST_OUTPUT(<< "Could not activate locale " << locale << "\n"); return false; } } void ReaderLocaleTest(mitk::Point3D & refPoint, std::string filename) { MITK_TEST_OUTPUT(<< "---- Reader Test ---- "); mitk::PointSet::Pointer pointSet = mitk::IOUtil::LoadPointSet(filename); mitk::Point3D point; if (pointSet->GetPointIfExists(0, &point)) { MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[0] - point[0]) < 0.00001, "read x correct"); MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[1] - point[1]) < 0.00001, "read y correct"); MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[2] - point[2]) < 0.00001, "read z correct"); }else { MITK_TEST_FAILED_MSG(<< "File "<< filename << " can not be read - test will not applied." ); return; } } void WriterLocaleTest(mitk::Point3D & refPoint, std::string filename) { MITK_TEST_OUTPUT(<< "---- Writer Test---- "); //create pointset mitk::PointSet::Pointer refPointSet = mitk::PointSet::New(); refPointSet->InsertPoint(0,refPoint); //SetPoint(0, refPoint); - std::ofstream tmpStream; - std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream); + std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile("testPointSet_XXXXXX.mps"); // write point set mitk::IOUtil::Save(refPointSet, tmpFilePath); - tmpStream.close(); std::ifstream stream(tmpFilePath.c_str()); //compare two .mps files std::ifstream refStream (filename.c_str()); MITK_TEST_CONDITION_REQUIRED(refStream,"Read reference point set"); MITK_TEST_CONDITION_REQUIRED(stream,"Read point set"); bool differ = false; if (stream.is_open() && refStream.is_open()) { std::string streamLine; std::string refStreamLine; while(!stream.eof() && ! refStream.eof()) { getline(stream, streamLine); getline(refStream, refStreamLine); if(streamLine.compare(refStreamLine) != 0) { differ = true; break; } } stream.close(); refStream.close(); } MITK_TEST_CONDITION_REQUIRED(!differ, "Write point set correct"); } -int mitkPointSetLocaleTest(int argc, char* argv[]) +int mitkPointSetLocaleTest(int, char*[]) { MITK_TEST_BEGIN("PointSetLocaleTest"); - if (argc<2) {MITK_TEST_FAILED_MSG(<<"Error: test file name is needed as second argument.");} - - - std::string filename = argv[1]; - - MITK_INFO << filename; - //create reference point set mitk::PointSet::Pointer refPointSet = mitk::PointSet::New(); mitk::Point3D refPoint; refPoint[0] = 32.2946; refPoint[1] = -17.7359; refPoint[2] = 29.6502; refPointSet->SetPoint(0, refPoint); //create locale list std::ofstream stream; std::locale previousLocale(stream.getloc()); typedef std::list StringList; StringList alllocales; alllocales.push_back("de_DE"); alllocales.push_back("de_DE.utf8"); alllocales.push_back("de_DE.UTF-8"); alllocales.push_back("de_DE@euro"); alllocales.push_back("German_Germany"); // QuickFix for MAC OS X // See for more the Bug #3894 comments #if defined (__APPLE__) || defined(MACOSX) alllocales.push_back("C"); #endif + // write a reference file using the "C" locale once + ChangeLocale("C"); + std::string referenceFilePath = mitk::IOUtil::CreateTemporaryFile("refPointSet_XXXXXX.mps"); + MITK_INFO << "Reference PointSet in " << referenceFilePath; + + // write point set + mitk::IOUtil::Save(refPointSet, referenceFilePath); + + unsigned int numberOfTestedGermanLocales(0); for (StringList::iterator iter = alllocales.begin(); iter != alllocales.end(); ++iter) { if ( ChangeLocale(*iter) ) { ++numberOfTestedGermanLocales; - WriterLocaleTest(refPoint,filename); - ReaderLocaleTest(refPoint,filename); + WriterLocaleTest(refPoint, referenceFilePath); + ReaderLocaleTest(refPoint, referenceFilePath); } } if(numberOfTestedGermanLocales == 0) { MITK_TEST_OUTPUT(<< "Warning: No German locale was found on the system."); } //MITK_TEST_CONDITION_REQUIRED( numberOfTestedGermanLocales > 0, "Verify that at least one German locale has been tested."); MITK_TEST_END(); }