diff --git a/Core/Code/DataManagement/mitkVector.h b/Core/Code/DataManagement/mitkVector.h index d4279acabc..e63760cffd 100644 --- a/Core/Code/DataManagement/mitkVector.h +++ b/Core/Code/DataManagement/mitkVector.h @@ -1,96 +1,111 @@ /*=================================================================== 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 MITKVECTOR_H_ #define MITKVECTOR_H_ #include #include #include #include "mitkTypeBasics.h" #include "mitkLogMacros.h" namespace mitk { template class Vector : public itk::Vector { public: /** Default constructor has nothing to do. */ - Vector() {} + Vector() + : itk::Vector() {} - /** Pass-through constructors for the Array base class. */ - Vector(const Vector& r) - : itk::Vector(r) {} + /** + * Constructor to convert from mitk::Vector to mitk::Vector. + * Can convert nonidentical types. + * E.g. use this to convert from mitk::Vector to mitk::Vector + */ + template + Vector(const Vector& r) + : itk::Vector(r) {} + + /** + * Constructor to convert from itk::Vector to mitk::Vector. + * Can convert nonidentical types. + * E.g. use this to convert from itk::Vector to mitk::Vector + */ + template + Vector(const itk::Vector& r) + : itk::Vector(r) {} Vector(const TCoordRep r[NVectorDimension]) - : itk::Vector(r) {} + : itk::Vector(r) {} + /** + * Constructor to initialize entire vector to one value. + */ Vector(const TCoordRep & v):itk::Vector(v) - {} - - Vector(const itk::Vector r) - : itk::Vector(r) {} + {} /** * Attention: vnlVector should have same size as NVectorDimension, otherwise * 1. elements will be lost in case vnlVector is bigger. * 2. elements will be set to 0 in case this is bigger. * In both cases, MITK_WARN warnings will be issued. */ Vector(const vnl_vector& vnlVector) : itk::Vector() { this->Fill(0); if (vnlVector.size() < NVectorDimension) MITK_WARN << "Attention: conversion of vnl_vector to mitk::Vector:" << "the mitk::Vector has more elements than the vnl_vector. Remaining elements will be set to 0."; if (NVectorDimension < vnlVector.size()) MITK_WARN << "Attention: conversion of vnl_vector to mitk::Vector:" << "the vnl_vector has more elements than the mitk::Vector. vnlVector[NVectorDimension .. vnlVector.size()] will be lost."; for (int var = 0; (var < NVectorDimension) && (var < vnlVector.size()); ++var) { this->SetElement(var, vnlVector.get(var)); } }; Vector(const vnl_vector_fixed vnlVectorFixed) : itk::Vector(vnlVectorFixed.data_block()){}; /** * Warning: Array must have same dimension as Vector */ void CopyToArray(ScalarType array_p[NVectorDimension]) const { for (int i = 0; i < this->GetVectorDimension(); i++) { array_p[i] = this->GetElement(i); } } }; typedef Vector Vector2D; typedef Vector Vector3D; typedef Vector Vector4D; } #endif /* MITKVECTOR_H_ */ diff --git a/Core/Code/Testing/mitkTypeVectorConversionTest.cpp b/Core/Code/Testing/mitkTypeVectorConversionTest.cpp index 2f78733248..72f2901827 100644 --- a/Core/Code/Testing/mitkTypeVectorConversionTest.cpp +++ b/Core/Code/Testing/mitkTypeVectorConversionTest.cpp @@ -1,147 +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 "mitkTestingMacros.h" -#include "mitkTypeBasics.h" -#include "mitkVector.h" -#include "mitkTypes.h" // for Equals +#include + #include "itkVector.h" + #include #include +#include "vnl/vnl_math.h" -#include +#include "mitkTestingMacros.h" +#include "mitkTypeBasics.h" +#include "mitkVector.h" +#include "mitkTypes.h" // for Equals using namespace mitk; +/** + * these private variables are used in the test functions + * + * The variable which should be copied into is set to its original value. + * The value which should be copied is set to valuesToCopy. + * + * Then the copying takes place. The test is successful, if the variable which + * should be copied into holds the valuesToCopy afterwards and is equal to the + * vector which should be copied. + */ +static const ScalarType originalValues[] = {1.123456789987, 2.789456321456, 3.123654789987456}; +static const float originalValuesFloat[] = {1.123456789987, 2.789456321456, 3.123654789987456}; -static const ScalarType originalValues[] = {1.0, 2.0, 3.0}; -static const ScalarType valuesToCopy[] = {4.0, 5.0, 6.0}; +static const ScalarType valuesToCopy[] = {4.654789123321, 5.987456789321, 6.321654987789546}; +static const float valuesToCopyFloat[] = {4.654789123321, 5.987456789321, 6.321654987789546}; + + + +static void Test_mitk2Mitk_DifferntTypeCompatibility(void) +{ + mitk::Vector floatVector3D = originalValuesFloat; + mitk::Vector doubleVector3D = valuesToCopy; + floatVector3D = doubleVector3D; + + MITK_TEST_CONDITION(floatVector3D == doubleVector3D, "mitk double vector assigned to mitk float vector") + + // test for correct values needs a little more love than in other cases + // since Equal cannot compare arrays/vectors of different type + bool correctValuesAssigned = true; + for (int var = 0; var < 3; ++var) { + correctValuesAssigned = correctValuesAssigned + && Equal(floatVector3D[var], valuesToCopy[var], vnl_math::float_eps * 10.0); + } + MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned within float accuracy") +} static void Test_itk2Mitk_Compatibility(void) { Vector3D vector3D = originalValues; itk::Vector itkVector = valuesToCopy; vector3D = itkVector; MITK_TEST_CONDITION(vector3D == itkVector, "itk vector assigned to mitk vector") MITK_TEST_CONDITION(vector3D == valuesToCopy, "correct values were assigned") } +static void Test_itk2Mitk_floatCompatibility(void) +{ + Vector3D vector3D = originalValues; + itk::Vector itkVector = valuesToCopyFloat; + + vector3D = itkVector; + + MITK_TEST_CONDITION(vector3D == itkVector, "itk float vector assigned to mitk vector") + + // test for correct values needs a little more love than in other cases + // since Equal cannot compare arrays/vectors of different type + bool correctValuesAssigned = true; + for (int var = 0; var < 3; ++var) { + correctValuesAssigned = correctValuesAssigned + && Equal(vector3D[var], valuesToCopyFloat[var]); + } + MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned") +} + static void Test_Mitk2itk_Compatibility(void) { Vector3D vector3D = valuesToCopy; itk::Vector itkVector = originalValues; itkVector = vector3D; MITK_TEST_CONDITION(vector3D == itkVector, "mitk vector assigned to itk vector") MITK_TEST_CONDITION(itkVector == valuesToCopy, "correct values were assigned") } static void Test_Vnl2Mitk_VectorFixedCompatibility() { mitk::Vector3D vector3D = originalValues; vnl_vector_fixed vnlVectorFixed(valuesToCopy); vector3D = vnlVectorFixed; MITK_TEST_CONDITION( vector3D.GetVnlVector() == vnlVectorFixed, "vnl_vector_fixed assigned to mitk vector") MITK_TEST_CONDITION( vector3D == valuesToCopy, "correct values were assigned" ) - MITK_TEST_CONDITION( Equal(vnlVectorFixed, vnlVectorFixed), "vnl_vector_fixed holds its original values" ) } static void Test_Vnl2Mitk_VectorCompatibility() { mitk::Vector3D vector3D = originalValues; vnl_vector vnlVector(3); vnlVector.set(valuesToCopy); vector3D = vnlVector; MITK_TEST_CONDITION( vector3D.GetVnlVector() == vnlVector, "vnl_vector assigned to mitk vector") MITK_TEST_CONDITION( vector3D == valuesToCopy, "correct values were assigned" ) } /** * tests if constructing a mitk::Vector using a shorter in size vnl_vector is handled properly */ static void Test_Vnl2Mitk_ShortVectorCompatibility() { ScalarType shorterValuesToCopy[] = {4.12345678910, 5.10987654321}; mitk::Vector3D vector3D = originalValues; vnl_vector vnlVector(2); vnlVector.set(shorterValuesToCopy); vector3D = vnlVector; bool correctValuesInVector3D = true; for (int var = 0; var < 2; ++var) { correctValuesInVector3D = correctValuesInVector3D && (vector3D[var] && shorterValuesToCopy[var]); } correctValuesInVector3D = correctValuesInVector3D && (vector3D[2] == 0.0); MITK_TEST_CONDITION(correctValuesInVector3D, "shorter vnl vector correctly assigned to mitk vector" ) } /** * tests if constructing a mitk::Vector using a large in size vnl_vector is handled properly */ static void Test_Vnl2Mitk_LargeVectorCompatibility() { ScalarType largerValuesToCopy[] = {4.12345678910, 5.10987654321, 6.123456789132456, 7.123456987789456}; mitk::Vector3D vector3D = originalValues; vnl_vector vnlVector(4); vnlVector.set(largerValuesToCopy); vector3D = vnlVector; bool correctValuesInVector3D = true; for (int var = 0; var < 3; ++var) { correctValuesInVector3D = correctValuesInVector3D && (vector3D[var] && largerValuesToCopy[var]); } MITK_TEST_CONDITION(correctValuesInVector3D, "larger vnl vector correctly assigned to mitk vector" ) } /** * Test the conversions from and to the mitk vector type */ int mitkTypeVectorConversionTest(int /*argc*/ , char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("VectorConversionTest") + Test_mitk2Mitk_DifferntTypeCompatibility(); + Test_itk2Mitk_Compatibility(); + Test_itk2Mitk_floatCompatibility(); + Test_Mitk2itk_Compatibility(); Test_Vnl2Mitk_VectorFixedCompatibility(); Test_Vnl2Mitk_VectorCompatibility(); Test_Vnl2Mitk_ShortVectorCompatibility(); Test_Vnl2Mitk_LargeVectorCompatibility(); MITK_TEST_END() }