diff --git a/Core/Code/DataManagement/mitkBaseGeometry.cpp b/Core/Code/DataManagement/mitkBaseGeometry.cpp index fb51ca75e3..13164835ed 100644 --- a/Core/Code/DataManagement/mitkBaseGeometry.cpp +++ b/Core/Code/DataManagement/mitkBaseGeometry.cpp @@ -1,1086 +1,1088 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include "mitkBaseGeometry.h" #include "mitkVector.h" #include "mitkMatrixConvert.h" #include #include #include "mitkRotationOperation.h" #include "mitkRestorePlanePositionOperation.h" #include "mitkApplyTransformMatrixOperation.h" #include "mitkPointOperation.h" #include "mitkInteractionConst.h" #include "mitkModifiedLock.h" mitk::BaseGeometry::BaseGeometry(): Superclass(), mitk::OperationActor(), m_FrameOfReferenceID(0), m_IndexToWorldTransformLastModified(0), m_ImageGeometry(false), m_ModifiedLockFlag(false), m_ModifiedCalledFlag(false) { m_VtkMatrix = vtkMatrix4x4::New(); m_VtkIndexToWorldTransform = vtkMatrixToLinearTransform::New(); m_VtkIndexToWorldTransform->SetInput(m_VtkMatrix); Initialize(); } mitk::BaseGeometry::BaseGeometry(const BaseGeometry& other): Superclass(), mitk::OperationActor(), //m_TimeBounds(other.m_TimeBounds), m_FrameOfReferenceID(other.m_FrameOfReferenceID), m_IndexToWorldTransformLastModified(other.m_IndexToWorldTransformLastModified), m_Origin(other.m_Origin), m_ImageGeometry(other.m_ImageGeometry), m_ModifiedLockFlag(false), m_ModifiedCalledFlag(false) { m_VtkMatrix = vtkMatrix4x4::New(); m_VtkIndexToWorldTransform = vtkMatrixToLinearTransform::New(); m_VtkIndexToWorldTransform->SetInput(m_VtkMatrix); other.InitializeGeometry(this); } mitk::BaseGeometry::~BaseGeometry() { m_VtkMatrix->Delete(); m_VtkIndexToWorldTransform->Delete(); } const mitk::Point3D& mitk::BaseGeometry::GetOrigin() const { return m_Origin; } void mitk::BaseGeometry::SetOrigin(const Point3D & origin) { mitk::ModifiedLock lock(this); if(origin!=GetOrigin()) { m_Origin = origin; m_IndexToWorldTransform->SetOffset(m_Origin.GetVectorFromOrigin()); Modified(); TransferItkToVtkTransform(); } } void mitk::BaseGeometry::TransferItkToVtkTransform() { mitk::ModifiedLock lock(this); // copy m_IndexToWorldTransform into m_VtkIndexToWorldTransform TransferItkTransformToVtkMatrix(m_IndexToWorldTransform.GetPointer(), m_VtkMatrix); m_VtkIndexToWorldTransform->Modified(); } static void CopySpacingFromTransform(mitk::AffineTransform3D* transform, mitk::Vector3D& spacing) { mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix; vnlmatrix = transform->GetMatrix().GetVnlMatrix(); spacing[0]=vnlmatrix.get_column(0).magnitude(); spacing[1]=vnlmatrix.get_column(1).magnitude(); spacing[2]=vnlmatrix.get_column(2).magnitude(); } void mitk::BaseGeometry::Initialize() { float b[6] = {0,1,0,1,0,1}; SetFloatBounds(b); if(m_IndexToWorldTransform.IsNull()) m_IndexToWorldTransform = TransformType::New(); else m_IndexToWorldTransform->SetIdentity(); CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin); m_VtkMatrix->Identity(); //m_TimeBounds[0]=ScalarTypeNumericTraits::NonpositiveMin(); m_TimeBounds[1]=ScalarTypeNumericTraits::max(); m_FrameOfReferenceID = 0; m_ImageGeometry = false; this->PostInitialize(); } void mitk::BaseGeometry::PostInitializeGeometry(BaseGeometry * newGeometry) const { newGeometry->m_ImageGeometry = m_ImageGeometry; } void mitk::BaseGeometry::SetFloatBounds(const float bounds[6]) { mitk::BoundingBox::BoundsArrayType b; const float *input = bounds; int i=0; for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6 ;++i) *it++ = (mitk::ScalarType)*input++; SetBounds(b); } void mitk::BaseGeometry::SetFloatBounds(const double bounds[6]) { mitk::BoundingBox::BoundsArrayType b; const double *input = bounds; int i=0; for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6 ;++i) *it++ = (mitk::ScalarType)*input++; SetBounds(b); } /** Initialize the geometry */ void mitk::BaseGeometry::InitializeGeometry(BaseGeometry* newGeometry) const { newGeometry->SetBounds(m_BoundingBox->GetBounds()); // we have to create a new transform!! //newGeometry->SetTimeBounds(m_TimeBounds); newGeometry->SetFrameOfReferenceID(GetFrameOfReferenceID()); if(m_IndexToWorldTransform) { TransformType::Pointer indexToWorldTransform = m_IndexToWorldTransform->Clone(); newGeometry->SetIndexToWorldTransform(indexToWorldTransform); } this->PostInitializeGeometry(newGeometry); } void mitk::BaseGeometry::PostInitialize() { } /** Set the bounds */ void mitk::BaseGeometry::SetBounds(const BoundsArrayType& bounds) { mitk::ModifiedLock lock(this); PreSetBounds(bounds); m_BoundingBox = BoundingBoxType::New(); BoundingBoxType::PointsContainer::Pointer pointscontainer = BoundingBoxType::PointsContainer::New(); BoundingBoxType::PointType p; BoundingBoxType::PointIdentifier pointid; for(pointid=0; pointid<2;++pointid) { unsigned int i; for(i=0; iInsertElement(pointid, p); } m_BoundingBox->SetPoints(pointscontainer); m_BoundingBox->ComputeBoundingBox(); this->Modified(); } void mitk::BaseGeometry::PreSetBounds(const BoundsArrayType& /*bounds*/){}; void mitk::BaseGeometry::SetIndexToWorldTransform(mitk::AffineTransform3D* transform) { mitk::ModifiedLock lock(this); PreSetIndexToWorldTransform(transform); - if(m_IndexToWorldTransform.GetPointer() != transform) - { - m_IndexToWorldTransform = transform; - CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); - vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin); - TransferItkToVtkTransform(); - Modified(); - } + + m_IndexToWorldTransform = transform; + CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); + vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin); + TransferItkToVtkTransform(); + Modified(); + PostSetIndexToWorldTransform(transform); + } void mitk::BaseGeometry::PreSetIndexToWorldTransform(mitk::AffineTransform3D* /*transform*/) {} void mitk::BaseGeometry::PostSetIndexToWorldTransform(mitk::AffineTransform3D* /*transform*/) {} const mitk::BaseGeometry::BoundsArrayType mitk::BaseGeometry::GetBounds() const { assert(m_BoundingBox.IsNotNull()); return m_BoundingBox->GetBounds(); } bool mitk::BaseGeometry::IsValid() const { return true; } void mitk::BaseGeometry::SetSpacing(const mitk::Vector3D& aSpacing, bool enforceSetSpacing ) { PreSetSpacing(aSpacing); _SetSpacing(aSpacing, enforceSetSpacing); } void mitk::BaseGeometry::PreSetSpacing(const mitk::Vector3D& /*aSpacing*/) {} void mitk::BaseGeometry::_SetSpacing(const mitk::Vector3D& aSpacing, bool enforceSetSpacing){ if(mitk::Equal(m_Spacing, aSpacing) == false || enforceSetSpacing) { assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0); m_Spacing = aSpacing; AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix; vnlmatrix = m_IndexToWorldTransform->GetMatrix().GetVnlMatrix(); mitk::VnlVector col; col = vnlmatrix.get_column(0); col.normalize(); col*=aSpacing[0]; vnlmatrix.set_column(0, col); col = vnlmatrix.get_column(1); col.normalize(); col*=aSpacing[1]; vnlmatrix.set_column(1, col); col = vnlmatrix.get_column(2); col.normalize(); col*=aSpacing[2]; vnlmatrix.set_column(2, col); Matrix3D matrix; matrix = vnlmatrix; AffineTransform3D::Pointer transform = AffineTransform3D::New(); transform->SetMatrix(matrix); transform->SetOffset(m_IndexToWorldTransform->GetOffset()); SetIndexToWorldTransform(transform.GetPointer()); } } mitk::Vector3D mitk::BaseGeometry::GetAxisVector(unsigned int direction) const { Vector3D frontToBack; frontToBack.SetVnlVector(m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction)); frontToBack *= GetExtent(direction); return frontToBack; } mitk::ScalarType mitk::BaseGeometry::GetExtent(unsigned int direction) const { assert(m_BoundingBox.IsNotNull()); if (direction>=m_NDimensions) mitkThrow() << "Direction is too big. This geometry is for 3D Data"; BoundsArrayType bounds = m_BoundingBox->GetBounds(); return bounds[direction*2+1]-bounds[direction*2]; } bool mitk::BaseGeometry::Is2DConvertable() { bool isConvertableWithoutLoss = true; do { if (this->GetSpacing()[2] != 1) { isConvertableWithoutLoss = false; break; } if (this->GetOrigin()[2] != 0) { isConvertableWithoutLoss = false; break; } mitk::Vector3D col0, col1, col2; col0.SetVnlVector(this->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); col1.SetVnlVector(this->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); col2.SetVnlVector(this->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); if ((col0[2] != 0) || (col1[2] != 0) || (col2[0] != 0) || (col2[1] != 0) || (col2[2] != 1)) { isConvertableWithoutLoss = false; break; } } while (0); return isConvertableWithoutLoss; } mitk::Point3D mitk::BaseGeometry::GetCenter() const { assert(m_BoundingBox.IsNotNull()); return m_IndexToWorldTransform->TransformPoint(m_BoundingBox->GetCenter()); } double mitk::BaseGeometry::GetDiagonalLength2() const { Vector3D diagonalvector = GetCornerPoint()-GetCornerPoint(false, false, false); return diagonalvector.GetSquaredNorm(); } //##Documentation //## @brief Get the length of the diagonal of the bounding-box in mm //## double mitk::BaseGeometry::GetDiagonalLength() const { return sqrt(GetDiagonalLength2()); } mitk::Point3D mitk::BaseGeometry::GetCornerPoint(int id) const { assert(id >= 0); assert(this->IsBoundingBoxNull()==false); BoundingBox::BoundsArrayType bounds = this->GetBoundingBox()->GetBounds(); Point3D cornerpoint; switch(id) { case 0: FillVector3D(cornerpoint, bounds[0],bounds[2],bounds[4]); break; case 1: FillVector3D(cornerpoint, bounds[0],bounds[2],bounds[5]); break; case 2: FillVector3D(cornerpoint, bounds[0],bounds[3],bounds[4]); break; case 3: FillVector3D(cornerpoint, bounds[0],bounds[3],bounds[5]); break; case 4: FillVector3D(cornerpoint, bounds[1],bounds[2],bounds[4]); break; case 5: FillVector3D(cornerpoint, bounds[1],bounds[2],bounds[5]); break; case 6: FillVector3D(cornerpoint, bounds[1],bounds[3],bounds[4]); break; case 7: FillVector3D(cornerpoint, bounds[1],bounds[3],bounds[5]); break; default: { itkExceptionMacro(<<"A cube only has 8 corners. These are labeled 0-7."); } } if(m_ImageGeometry) { // Here i have to adjust the 0.5 offset manually, because the cornerpoint is the corner of the // bounding box. The bounding box itself is no image, so it is corner-based FillVector3D(cornerpoint, cornerpoint[0]-0.5, cornerpoint[1]-0.5, cornerpoint[2]-0.5); } return this->GetIndexToWorldTransform()->TransformPoint(cornerpoint); } mitk::Point3D mitk::BaseGeometry::GetCornerPoint(bool xFront, bool yFront, bool zFront) const { assert(this->IsBoundingBoxNull()==false); BoundingBox::BoundsArrayType bounds = this->GetBoundingBox()->GetBounds(); Point3D cornerpoint; cornerpoint[0] = (xFront ? bounds[0] : bounds[1]); cornerpoint[1] = (yFront ? bounds[2] : bounds[3]); cornerpoint[2] = (zFront ? bounds[4] : bounds[5]); if(m_ImageGeometry) { // Here i have to adjust the 0.5 offset manually, because the cornerpoint is the corner of the // bounding box. The bounding box itself is no image, so it is corner-based FillVector3D(cornerpoint, cornerpoint[0]-0.5, cornerpoint[1]-0.5, cornerpoint[2]-0.5); } return this->GetIndexToWorldTransform()->TransformPoint(cornerpoint); } mitk::ScalarType mitk::BaseGeometry::GetExtentInMM(int direction) const { return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction).magnitude()*GetExtent(direction); } void mitk::BaseGeometry::SetExtentInMM(int direction, ScalarType extentInMM) { mitk::ModifiedLock lock(this); ScalarType len = GetExtentInMM(direction); if(fabs(len - extentInMM)>=mitk::eps) { AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix; vnlmatrix = m_IndexToWorldTransform->GetMatrix().GetVnlMatrix(); if(len>extentInMM) vnlmatrix.set_column(direction, vnlmatrix.get_column(direction)/len*extentInMM); else vnlmatrix.set_column(direction, vnlmatrix.get_column(direction)*extentInMM/len); Matrix3D matrix; matrix = vnlmatrix; m_IndexToWorldTransform->SetMatrix(matrix); + TransferItkToVtkTransform(); Modified(); } PostSetExtentInMM(direction,extentInMM); } void mitk::BaseGeometry::PostSetExtentInMM(int /*direction*/, ScalarType /*extentInMM*/){}; bool mitk::BaseGeometry::IsInside(const mitk::Point3D& p) const { mitk::Point3D index; WorldToIndex(p, index); return IsIndexInside(index); } bool mitk::BaseGeometry::IsIndexInside(const mitk::Point3D& index) const { bool inside = false; //if it is an image geometry, we need to convert the index to discrete values //this is done by applying the rounding function also used in WorldToIndex (see line 323) if (m_ImageGeometry) { mitk::Point3D discretIndex; discretIndex[0]=itk::Math::RoundHalfIntegerUp( index[0] ); discretIndex[1]=itk::Math::RoundHalfIntegerUp( index[1] ); discretIndex[2]=itk::Math::RoundHalfIntegerUp( index[2] ); inside = this->GetBoundingBox()->IsInside(discretIndex); //we have to check if the index is at the upper border of each dimension, // because the boundingbox is not centerbased if (inside) { const BoundingBox::BoundsArrayType& bounds = this->GetBoundingBox()->GetBounds(); if((discretIndex[0] == bounds[1]) || (discretIndex[1] == bounds[3]) || (discretIndex[2] == bounds[5])) inside = false; } } else inside = this->GetBoundingBox()->IsInside(index); return inside; } void mitk::BaseGeometry::WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const { BackTransform(pt_mm, pt_units); } void mitk::BaseGeometry::WorldToIndex( const mitk::Vector3D &vec_mm, mitk::Vector3D &vec_units) const { BackTransform( vec_mm, vec_units); } void mitk::BaseGeometry::BackTransform(const mitk::Vector3D& in, mitk::Vector3D& out) const { // Get WorldToIndex transform if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime()) { m_InvertedTransform = TransformType::New(); if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() )) { itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." ); } m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime(); } // Check for valid matrix inversion const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix(); if(inverse.GetVnlMatrix().has_nans()) { itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl << m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl << inverse ); } // Transform vector for (unsigned int i = 0; i < 3; i++) { out[i] = 0.0; for (unsigned int j = 0; j < 3; j++) { out[i] += inverse[i][j]*in[j]; } } } void mitk::BaseGeometry::BackTransform(const mitk::Point3D &in, mitk::Point3D& out) const { ScalarType temp[3]; unsigned int i, j; const TransformType::OffsetType& offset = m_IndexToWorldTransform->GetOffset(); // Remove offset for (j = 0; j < 3; j++) { temp[j] = in[j] - offset[j]; } // Get WorldToIndex transform if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime()) { m_InvertedTransform = TransformType::New(); if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() )) { itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." ); } m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime(); } // Check for valid matrix inversion const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix(); if(inverse.GetVnlMatrix().has_nans()) { itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl << m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl << inverse ); } // Transform point for (i = 0; i < 3; i++) { out[i] = 0.0; for (j = 0; j < 3; j++) { out[i] += inverse[i][j]*temp[j]; } } } mitk::VnlVector mitk::BaseGeometry::GetOriginVnl() const { return const_cast(this)->m_Origin.GetVnlVector(); } vtkLinearTransform* mitk::BaseGeometry::GetVtkTransform() const { return (vtkLinearTransform*)m_VtkIndexToWorldTransform; } void mitk::BaseGeometry::SetIdentity() { mitk::ModifiedLock lock(this); m_IndexToWorldTransform->SetIdentity(); m_Origin.Fill(0); CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); Modified(); TransferItkToVtkTransform(); } void mitk::BaseGeometry::TransferVtkToItkTransform() { TransferVtkMatrixToItkTransform(m_VtkMatrix, m_IndexToWorldTransform.GetPointer()); CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin); + TransferItkToVtkTransform(); } void mitk::BaseGeometry::Compose( const mitk::BaseGeometry::TransformType * other, bool pre ) { mitk::ModifiedLock lock(this); m_IndexToWorldTransform->Compose(other, pre); CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing); vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin); Modified(); TransferItkToVtkTransform(); } void mitk::BaseGeometry::Compose( const vtkMatrix4x4 * vtkmatrix, bool pre ) { mitk::BaseGeometry::TransformType::Pointer itkTransform = mitk::BaseGeometry::TransformType::New(); TransferVtkMatrixToItkTransform(vtkmatrix, itkTransform.GetPointer()); Compose(itkTransform, pre); } void mitk::BaseGeometry::Translate(const Vector3D & vector) { if((vector[0] != 0) || (vector[1] != 0) || (vector[2] != 0)) { this->SetOrigin(m_Origin + vector); } } void mitk::BaseGeometry::IndexToWorld(const mitk::Point3D &pt_units, mitk::Point3D &pt_mm) const { pt_mm = m_IndexToWorldTransform->TransformPoint(pt_units); } void mitk::BaseGeometry::IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const { vec_mm = m_IndexToWorldTransform->TransformVector(vec_units); } #include void mitk::BaseGeometry::ExecuteOperation(Operation* operation) { mitk::ModifiedLock lock(this); vtkTransform *vtktransform = vtkTransform::New(); vtktransform->SetMatrix(m_VtkMatrix); switch (operation->GetOperationType()) { case OpNOTHING: break; case OpMOVE: { mitk::PointOperation *pointOp = dynamic_cast(operation); if (pointOp == NULL) { //mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000); return; } mitk::Point3D newPos = pointOp->GetPoint(); ScalarType data[3]; vtktransform->GetPosition(data); vtktransform->PostMultiply(); vtktransform->Translate(newPos[0], newPos[1], newPos[2]); vtktransform->PreMultiply(); break; } case OpSCALE: { mitk::PointOperation *pointOp = dynamic_cast(operation); if (pointOp == NULL) { //mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000); return; } mitk::Point3D newScale = pointOp->GetPoint(); ScalarType data[3]; /* calculate new scale: newscale = oldscale * (oldscale + scaletoadd)/oldscale */ data[0] = 1 + (newScale[0] / GetMatrixColumn(0).magnitude()); data[1] = 1 + (newScale[1] / GetMatrixColumn(1).magnitude()); data[2] = 1 + (newScale[2] / GetMatrixColumn(2).magnitude()); mitk::Point3D center = const_cast(m_BoundingBox.GetPointer())->GetCenter(); ScalarType pos[3]; vtktransform->GetPosition(pos); vtktransform->PostMultiply(); vtktransform->Translate(-pos[0], -pos[1], -pos[2]); vtktransform->Translate(-center[0], -center[1], -center[2]); vtktransform->PreMultiply(); vtktransform->Scale(data[0], data[1], data[2]); vtktransform->PostMultiply(); vtktransform->Translate(+center[0], +center[1], +center[2]); vtktransform->Translate(pos[0], pos[1], pos[2]); vtktransform->PreMultiply(); break; } case OpROTATE: { mitk::RotationOperation *rotateOp = dynamic_cast(operation); if (rotateOp == NULL) { //mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000); return; } Vector3D rotationVector = rotateOp->GetVectorOfRotation(); Point3D center = rotateOp->GetCenterOfRotation(); ScalarType angle = rotateOp->GetAngleOfRotation(); vtktransform->PostMultiply(); vtktransform->Translate(-center[0], -center[1], -center[2]); vtktransform->RotateWXYZ(angle, rotationVector[0], rotationVector[1], rotationVector[2]); vtktransform->Translate(center[0], center[1], center[2]); vtktransform->PreMultiply(); break; } case OpRESTOREPLANEPOSITION: { //Copy necessary to avoid vtk warning vtkMatrix4x4* matrix = vtkMatrix4x4::New(); TransferItkTransformToVtkMatrix(dynamic_cast(operation)->GetTransform().GetPointer(), matrix); vtktransform->SetMatrix(matrix); break; } case OpAPPLYTRANSFORMMATRIX: { ApplyTransformMatrixOperation *applyMatrixOp = dynamic_cast< ApplyTransformMatrixOperation* >( operation ); vtktransform->SetMatrix(applyMatrixOp->GetMatrix()); break; } default: vtktransform->Delete(); return; } m_VtkMatrix->DeepCopy(vtktransform->GetMatrix()); TransferVtkToItkTransform(); Modified(); vtktransform->Delete(); } mitk::VnlVector mitk::BaseGeometry::GetMatrixColumn(unsigned int direction) const { return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction); } mitk::BoundingBox::Pointer mitk::BaseGeometry::CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D* transform) const { mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New(); mitk::BoundingBox::PointIdentifier pointid=0; unsigned char i; if(transform!=NULL) { mitk::AffineTransform3D::Pointer inverse = mitk::AffineTransform3D::New(); transform->GetInverse(inverse); for(i=0; i<8; ++i) pointscontainer->InsertElement( pointid++, inverse->TransformPoint( GetCornerPoint(i) )); } else { for(i=0; i<8; ++i) pointscontainer->InsertElement( pointid++, GetCornerPoint(i) ); } mitk::BoundingBox::Pointer result = mitk::BoundingBox::New(); result->SetPoints(pointscontainer); result->ComputeBoundingBox(); return result; } //void mitk::BaseGeometry::SetTimeBounds(const TimeBounds& timebounds) //{ // mitk::ModifiedLock lock(this); // // if(m_TimeBounds != timebounds) // { // m_TimeBounds = timebounds; // Modified(); // } // PostSetTimeBounds(timebounds); //} // //void mitk::BaseGeometry::PostSetTimeBounds(const TimeBounds& timebounds) //{} const std::string mitk::BaseGeometry::GetTransformAsString( TransformType* transformType ) { std::ostringstream out; out << '['; for( int i=0; i<3; ++i ) { out << '['; for( int j=0; j<3; ++j ) out << transformType->GetMatrix().GetVnlMatrix().get(i, j) << ' '; out << ']'; } out << "]["; for( int i=0; i<3; ++i ) out << transformType->GetOffset()[i] << ' '; out << "]\0"; return out.str(); } void mitk::BaseGeometry::SetIndexToWorldTransformByVtkMatrix(vtkMatrix4x4* vtkmatrix) { m_VtkMatrix->DeepCopy(vtkmatrix); TransferVtkToItkTransform(); } void mitk::BaseGeometry::WorldToIndex(const mitk::Point3D & /*atPt3d_mm*/, const mitk::Vector3D &vec_mm, mitk::Vector3D &vec_units) const { MITK_WARN<<"Warning! Call of the deprecated function BaseGeometry::WorldToIndex(point, vec, vec). Use BaseGeometry::WorldToIndex(vec, vec) instead!"; //BackTransform(atPt3d_mm, vec_mm, vec_units); this->WorldToIndex(vec_mm, vec_units); } void mitk::BaseGeometry::IndexToWorld(const mitk::Point3D &/*atPt3d_units*/, const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const { MITK_WARN<<"Warning! Call of the deprecated function BaseGeometry::IndexToWorld(point, vec, vec). Use BaseGeometry::IndexToWorld(vec, vec) instead!"; //vec_mm = m_IndexToWorldTransform->TransformVector(vec_units); this->IndexToWorld(vec_units, vec_mm); } void mitk::BaseGeometry::BackTransform(const mitk::Point3D &/*at*/, const mitk::Vector3D &in, mitk::Vector3D& out) const { MITK_INFO<<"Warning! Call of the deprecated function BaseGeometry::BackTransform(point, vec, vec). Use BaseGeometry::BackTransform(vec, vec) instead!"; //// Get WorldToIndex transform //if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime()) //{ // m_InvertedTransform = TransformType::New(); // if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() )) // { // itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." ); // } // m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime(); //} //// Check for valid matrix inversion //const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix(); //if(inverse.GetVnlMatrix().has_nans()) //{ // itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl // << m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl // << inverse ); //} //// Transform vector //for (unsigned int i = 0; i < 3; i++) //{ // out[i] = 0.0; // for (unsigned int j = 0; j < 3; j++) // { // out[i] += inverse[i][j]*in[j]; // } //} this->BackTransform(in, out); } vtkMatrix4x4* mitk::BaseGeometry::GetVtkMatrix(){ return m_VtkMatrix; } bool mitk::BaseGeometry::IsBoundingBoxNull() const{ return m_BoundingBox.IsNull(); } bool mitk::BaseGeometry::IsIndexToWorldTransformNull() const{ return m_IndexToWorldTransform.IsNull(); } void mitk::BaseGeometry::ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry ) { // If Geometry is switched to ImageGeometry, you have to put an offset to the origin, because // imageGeometries origins are pixel-center-based // ... and remove the offset, if you switch an imageGeometry back to a normal geometry // For more information please see the Geometry documentation page if(m_ImageGeometry == isAnImageGeometry) return; const BoundingBox::BoundsArrayType& boundsarray = this->GetBoundingBox()->GetBounds(); Point3D originIndex; FillVector3D(originIndex, boundsarray[0], boundsarray[2], boundsarray[4]); if(isAnImageGeometry == true) FillVector3D( originIndex, originIndex[0] + 0.5, originIndex[1] + 0.5, originIndex[2] + 0.5 ); else FillVector3D( originIndex, originIndex[0] - 0.5, originIndex[1] - 0.5, originIndex[2] - 0.5 ); Point3D originWorld; originWorld = GetIndexToWorldTransform() ->TransformPoint( originIndex ); // instead could as well call IndexToWorld(originIndex,originWorld); SetOrigin(originWorld); this->SetImageGeometry(isAnImageGeometry); } //itk::LightObject::Pointer mitk::BaseGeometry::InternalClone() const //{ // Self::Pointer newGeometry = new Self(*this); // newGeometry->UnRegister(); // return newGeometry.GetPointer(); //} void mitk::BaseGeometry::PrintSelf(std::ostream& os, itk::Indent indent) const { os << indent << " IndexToWorldTransform: "; if(this->IsIndexToWorldTransformNull()) os << "NULL" << std::endl; else { // from itk::MatrixOffsetTransformBase unsigned int i, j; os << std::endl; os << indent << "Matrix: " << std::endl; for (i = 0; i < 3; i++) { os << indent.GetNextIndent(); for (j = 0; j < 3; j++) { os << this->GetIndexToWorldTransform()->GetMatrix()[i][j] << " "; } os << std::endl; } os << indent << "Offset: " << this->GetIndexToWorldTransform()->GetOffset() << std::endl; os << indent << "Center: " << this->GetIndexToWorldTransform()->GetCenter() << std::endl; os << indent << "Translation: " << this->GetIndexToWorldTransform()->GetTranslation() << std::endl; os << indent << "Inverse: " << std::endl; for (i = 0; i < 3; i++) { os << indent.GetNextIndent(); for (j = 0; j < 3; j++) { os << this->GetIndexToWorldTransform()->GetInverseMatrix()[i][j] << " "; } os << std::endl; } // from itk::ScalableAffineTransform os << indent << "Scale : "; for (i = 0; i < 3; i++) { os << this->GetIndexToWorldTransform()->GetScale()[i] << " "; } os << std::endl; } os << indent << " BoundingBox: "; if(this->IsBoundingBoxNull()) os << "NULL" << std::endl; else { os << indent << "( "; for (unsigned int i=0; i<3; i++) { os << this->GetBoundingBox()->GetBounds()[2*i] << "," << this->GetBoundingBox()->GetBounds()[2*i+1] << " "; } os << " )" << std::endl; } os << indent << " Origin: " << this->GetOrigin() << std::endl; os << indent << " ImageGeometry: " << this->GetImageGeometry() << std::endl; os << indent << " Spacing: " << this->GetSpacing() << std::endl; //os << indent << " TimeBounds: " << this->GetTimeBounds() << std::endl; } void mitk::BaseGeometry::Modified() const{ if(!m_ModifiedLockFlag) Superclass::Modified(); else m_ModifiedCalledFlag = true; } bool mitk::Equal( const mitk::BaseGeometry::BoundingBoxType *leftHandSide, const mitk::BaseGeometry::BoundingBoxType *rightHandSide, ScalarType eps, bool verbose ) { if(( leftHandSide == NULL) || ( rightHandSide == NULL )) { MITK_ERROR << "mitk::Equal( const mitk::Geometry3D::BoundingBoxType *leftHandSide, const mitk::Geometry3D::BoundingBoxType *rightHandSide, ScalarType eps, bool verbose ) does not with NULL pointer input."; return false; } return Equal( *leftHandSide, *rightHandSide, eps, verbose); } bool mitk::Equal( const mitk::BaseGeometry::BoundingBoxType& leftHandSide, const mitk::BaseGeometry::BoundingBoxType& rightHandSide, ScalarType eps, bool verbose ) { bool result = true; BaseGeometry::BoundsArrayType rightBounds = rightHandSide.GetBounds(); BaseGeometry::BoundsArrayType leftBounds = leftHandSide.GetBounds(); BaseGeometry::BoundsArrayType::Iterator itLeft = leftBounds.Begin(); for( BaseGeometry::BoundsArrayType::Iterator itRight = rightBounds.Begin(); itRight != rightBounds.End(); ++itRight) { if(( !mitk::Equal( *itLeft, *itRight, eps )) ) { if(verbose) { MITK_INFO << "[( Geometry3D::BoundingBoxType )] bounds are not equal."; MITK_INFO << "rightHandSide is " << setprecision(12) << *itRight << " : leftHandSide is " << *itLeft << " and tolerance is " << eps; } result = false; } itLeft++; } return result; } bool mitk::Equal(const mitk::BaseGeometry *leftHandSide, const mitk::BaseGeometry *rightHandSide, ScalarType eps, bool verbose) { if(( leftHandSide == NULL) || ( rightHandSide == NULL )) { MITK_ERROR << "mitk::Equal(const mitk::Geometry3D *leftHandSide, const mitk::Geometry3D *rightHandSide, ScalarType eps, bool verbose) does not with NULL pointer input."; return false; } return Equal( *leftHandSide, *rightHandSide, eps, verbose); } bool mitk::Equal(const mitk::BaseGeometry& leftHandSide, const mitk::BaseGeometry& rightHandSide, ScalarType eps, bool verbose) { bool result = true; //Compare spacings if( !mitk::Equal( leftHandSide.GetSpacing(), rightHandSide.GetSpacing(), eps ) ) { if(verbose) { MITK_INFO << "[( Geometry3D )] Spacing differs."; MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetSpacing() << " : leftHandSide is " << leftHandSide.GetSpacing() << " and tolerance is " << eps; } result = false; } //Compare Origins if( !mitk::Equal( leftHandSide.GetOrigin(), rightHandSide.GetOrigin(), eps ) ) { if(verbose) { MITK_INFO << "[( Geometry3D )] Origin differs."; MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetOrigin() << " : leftHandSide is " << leftHandSide.GetOrigin() << " and tolerance is " << eps; } result = false; } //Compare Axis and Extents for( unsigned int i=0; i<3; ++i) { if( !mitk::Equal( leftHandSide.GetAxisVector(i), rightHandSide.GetAxisVector(i), eps)) { if(verbose) { MITK_INFO << "[( Geometry3D )] AxisVector #" << i << " differ"; MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetAxisVector(i) << " : leftHandSide is " << leftHandSide.GetAxisVector(i) << " and tolerance is " << eps; } result = false; } if( !mitk::Equal( leftHandSide.GetExtent(i), rightHandSide.GetExtent(i), eps) ) { if(verbose) { MITK_INFO << "[( Geometry3D )] Extent #" << i << " differ"; MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetExtent(i) << " : leftHandSide is " << leftHandSide.GetExtent(i) << " and tolerance is " << eps; } result = false; } } //Compare ImageGeometry Flag if( rightHandSide.GetImageGeometry() != leftHandSide.GetImageGeometry() ) { if(verbose) { MITK_INFO << "[( Geometry3D )] GetImageGeometry is different."; MITK_INFO << "rightHandSide is " << rightHandSide.GetImageGeometry() << " : leftHandSide is " << leftHandSide.GetImageGeometry(); } result = false; } //Compare BoundingBoxes if( !mitk::Equal( *leftHandSide.GetBoundingBox(), *rightHandSide.GetBoundingBox(), eps, verbose) ) { result = false; } //Compare IndexToWorldTransform Matrix if( !mitk::Equal( *leftHandSide.GetIndexToWorldTransform(), *rightHandSide.GetIndexToWorldTransform(), eps, verbose) ) { result = false; } return result; } bool mitk::Equal(const BaseGeometry::TransformType *leftHandSide, const BaseGeometry::TransformType *rightHandSide, ScalarType eps, bool verbose ) { if(( leftHandSide == NULL) || ( rightHandSide == NULL )) { MITK_ERROR << "mitk::Equal(const Geometry3D::TransformType *leftHandSide, const Geometry3D::TransformType *rightHandSide, ScalarType eps, bool verbose ) does not with NULL pointer input."; return false; } return Equal( *leftHandSide, *rightHandSide, eps, verbose); } bool mitk::Equal(const BaseGeometry::TransformType& leftHandSide, const BaseGeometry::TransformType& rightHandSide, ScalarType eps, bool verbose ) { //Compare IndexToWorldTransform Matrix if( !mitk::MatrixEqualElementWise( leftHandSide.GetMatrix(), rightHandSide.GetMatrix() ) ) { if(verbose) { MITK_INFO << "[( Geometry3D::TransformType )] Index to World Transformation matrix differs."; MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetMatrix() << " : leftHandSide is " << leftHandSide.GetMatrix() << " and tolerance is " << eps; } return false; } return true; } diff --git a/Core/Code/Testing/mitkBaseGeometryTest.cpp b/Core/Code/Testing/mitkBaseGeometryTest.cpp index e65cc9054c..cd7e9b205e 100644 --- a/Core/Code/Testing/mitkBaseGeometryTest.cpp +++ b/Core/Code/Testing/mitkBaseGeometryTest.cpp @@ -1,1230 +1,1250 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingMacros.h" #include #include #include #include #include #include "mitkOperationActor.h" #include #include "mitkVector.h" #include #include #include "itkScalableAffineTransform.h" #include #include #include #include "mitkRotationOperation.h" #include "mitkInteractionConst.h" #include #include class vtkMatrix4x4; class vtkMatrixToLinearTransform; class vtkLinearTransform; typedef itk::BoundingBox BoundingBox; typedef itk::BoundingBox BoundingBoxType; typedef BoundingBoxType::BoundsArrayType BoundsArrayType; typedef BoundingBoxType::Pointer BoundingBoxPointer; // Dummy instance of abstract base class class DummyTestClass : public mitk::BaseGeometry { public: DummyTestClass(){}; DummyTestClass(const DummyTestClass& other) : BaseGeometry(other){}; ~DummyTestClass(){}; mitkClassMacro(DummyTestClass, mitk::BaseGeometry); itkNewMacro(Self); mitkNewMacro1Param(Self, const Self&); itk::LightObject::Pointer InternalClone() const { Self::Pointer newGeometry = new Self(*this); newGeometry->UnRegister(); return newGeometry.GetPointer(); } virtual void PrintSelf(std::ostream& os, itk::Indent indent) const{}; }; class mitkBaseGeometryTestSuite : public mitk::TestFixture { // List of Tests CPPUNIT_TEST_SUITE(mitkBaseGeometryTestSuite); //Constructor MITK_TEST(TestConstructors); MITK_TEST(TestInitialize); //Set MITK_TEST(TestSetOrigin); MITK_TEST(TestSetBounds); MITK_TEST(TestSetFloatBounds); MITK_TEST(TestSetFloatBoundsDouble); MITK_TEST(TestSetFrameOfReferenceID); MITK_TEST(TestSetIndexToWorldTransform); + MITK_TEST(TestSetIndexToWorldTransform_WithPointerToSameTransform); MITK_TEST(TestSetSpacing); MITK_TEST(TestTransferItkToVtkTransform); MITK_TEST(TestSetIndexToWorldTransformByVtkMatrix); MITK_TEST(TestSetIdentity); MITK_TEST(TestSetImageGeometry); //Equal MITK_TEST(Equal_CloneAndOriginal_ReturnsTrue); MITK_TEST(Equal_DifferentOrigin_ReturnsFalse); MITK_TEST(Equal_DifferentIndexToWorldTransform_ReturnsFalse); MITK_TEST(Equal_DifferentSpacing_ReturnsFalse); MITK_TEST(Equal_InputIsNull_ReturnsFalse); MITK_TEST(Equal_DifferentBoundingBox_ReturnsFalse); //other Functions MITK_TEST(TestComposeTransform); MITK_TEST(TestComposeVtkMatrix); MITK_TEST(TestTranslate); MITK_TEST(TestIndexToWorld); MITK_TEST(TestExecuteOperation); MITK_TEST(TestCalculateBoundingBoxRelToTransform); //MITK_TEST(TestSetTimeBounds); MITK_TEST(TestIs2DConvertable); MITK_TEST(TestGetCornerPoint); MITK_TEST(TestExtentInMM); MITK_TEST(TestGetAxisVector); MITK_TEST(TestGetCenter); MITK_TEST(TestGetDiagonalLength); MITK_TEST(TestGetExtent); MITK_TEST(TestIsInside); MITK_TEST(TestGetMatrixColumn); CPPUNIT_TEST_SUITE_END(); // Used Variables private: mitk::Point3D aPoint; float aFloatSpacing[3]; mitk::Vector3D aSpacing; mitk::AffineTransform3D::Pointer aTransform; BoundingBoxPointer aBoundingBox; mitk::AffineTransform3D::MatrixType aMatrix; mitk::Point3D anotherPoint; mitk::Vector3D anotherSpacing; BoundingBoxPointer anotherBoundingBox; BoundingBoxPointer aThirdBoundingBox; mitk::AffineTransform3D::Pointer anotherTransform; mitk::AffineTransform3D::Pointer aThirdTransform; mitk::AffineTransform3D::MatrixType anotherMatrix; mitk::AffineTransform3D::MatrixType aThirdMatrix; DummyTestClass::Pointer aDummyGeometry; DummyTestClass::Pointer anotherDummyGeometry; public: // Set up for variables void setUp() { mitk::FillVector3D(aFloatSpacing, 1,1,1); mitk::FillVector3D(aSpacing, 1,1,1); mitk::FillVector3D(aPoint, 0,0,0); //Transform aTransform = mitk::AffineTransform3D::New(); aTransform->SetIdentity(); aMatrix.SetIdentity(); anotherTransform = mitk::AffineTransform3D::New(); anotherMatrix.SetIdentity(); anotherMatrix(1,1) = 2; anotherTransform->SetMatrix( anotherMatrix ); aThirdTransform = mitk::AffineTransform3D::New(); aThirdMatrix.SetIdentity(); aThirdMatrix(1,1) = 7; aThirdTransform->SetMatrix( aThirdMatrix ); //Bounding Box float bounds[6] = {0,1,0,1,0,1}; mitk::BoundingBox::BoundsArrayType b; const float *input = bounds; int j=0; for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); j < 6 ;++j) *it++ = (mitk::ScalarType)*input++; aBoundingBox = BoundingBoxType::New(); BoundingBoxType::PointsContainer::Pointer pointscontainer = BoundingBoxType::PointsContainer::New(); BoundingBoxType::PointType p; BoundingBoxType::PointIdentifier pointid; for(pointid=0; pointid<2;++pointid) { unsigned int i; for(i=0; i<3; ++i) { p[i] = bounds[2*i+pointid]; } pointscontainer->InsertElement(pointid, p); } aBoundingBox->SetPoints(pointscontainer); aBoundingBox->ComputeBoundingBox(); anotherBoundingBox = BoundingBoxType::New(); p[0]=11; p[1]=12; p[2]=13; pointscontainer->InsertElement(1, p); anotherBoundingBox->SetPoints(pointscontainer); anotherBoundingBox->ComputeBoundingBox(); aThirdBoundingBox = BoundingBoxType::New(); p[0]=22; p[1]=23; p[2]=24; pointscontainer->InsertElement(1, p); aThirdBoundingBox->SetPoints(pointscontainer); aThirdBoundingBox->ComputeBoundingBox(); mitk::FillVector3D(anotherPoint, 2,3,4); mitk::FillVector3D(anotherSpacing, 5,6.5,7); aDummyGeometry = DummyTestClass::New(); aDummyGeometry->Initialize(); anotherDummyGeometry = aDummyGeometry->Clone(); } void tearDown() { aDummyGeometry = NULL; anotherDummyGeometry = NULL; } // Test functions void TestSetOrigin() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetOrigin(anotherPoint); - CPPUNIT_ASSERT(anotherPoint==dummy->GetOrigin()); + CPPUNIT_ASSERT(mitk::Equal(anotherPoint,dummy->GetOrigin())); //undo changes, new and changed object need to be the same! dummy->SetOrigin(aPoint); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetImageGeometry() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetImageGeometry(true); CPPUNIT_ASSERT(dummy->GetImageGeometry()); //undo changes, new and changed object need to be the same! dummy->SetImageGeometry(false); CPPUNIT_ASSERT(dummy->GetImageGeometry()==false); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetFloatBounds(){ float bounds[6] = {0,11,0,12,0,13}; DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, true)); //Wrong bounds, test needs to fail bounds[1]=7; dummy->SetFloatBounds(bounds); CPPUNIT_ASSERT((mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, false))==false); //undo changes, new and changed object need to be the same! float originalBounds[6] = {0,1,0,1,0,1}; dummy->SetFloatBounds(originalBounds); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetBounds(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetBounds(anotherBoundingBox->GetBounds()); CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, true)); //Test needs to fail now dummy->SetBounds(aThirdBoundingBox->GetBounds()); CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, false)==false); //undo changes, new and changed object need to be the same! dummy->SetBounds(aBoundingBox->GetBounds()); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetFloatBoundsDouble(){ double bounds[6] = {0,11,0,12,0,13}; DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, true)); //Test needs to fail now bounds[3]=7; dummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal( dummy->GetBoundingBox(), anotherBoundingBox, mitk::eps, false)==false); //undo changes, new and changed object need to be the same! double originalBounds[6] = {0,1,0,1,0,1}; dummy->SetFloatBounds(originalBounds); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetFrameOfReferenceID() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetFrameOfReferenceID(5); CPPUNIT_ASSERT(dummy->GetFrameOfReferenceID()==5); //undo changes, new and changed object need to be the same! dummy->SetFrameOfReferenceID(0); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetIndexToWorldTransform() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(anotherTransform); CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,true)); //Test needs to fail now dummy->SetIndexToWorldTransform(aThirdTransform); CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,false)==false); //undo changes, new and changed object need to be the same! dummy->SetIndexToWorldTransform(aTransform); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } + void TestSetIndexToWorldTransform_WithPointerToSameTransform() + { + DummyTestClass::Pointer dummy = DummyTestClass::New(); + + dummy->SetOrigin(anotherPoint); + dummy->SetIndexToWorldTransform(anotherTransform); + dummy->SetSpacing(anotherSpacing); + + mitk::AffineTransform3D::Pointer testTransfrom = dummy->GetIndexToWorldTransform(); + + mitk::Vector3D modifiedPoint = anotherPoint.GetVectorFromOrigin() *2.; + + testTransfrom->SetOffset(modifiedPoint); + + dummy->SetIndexToWorldTransform(testTransfrom); + + CPPUNIT_ASSERT(mitk::Equal(modifiedPoint, dummy->GetOrigin().GetVectorFromOrigin())); + } + void TestSetIndexToWorldTransformByVtkMatrix() { vtkMatrix4x4* vtkmatrix; vtkmatrix = vtkMatrix4x4::New(); vtkmatrix->Identity(); vtkmatrix->SetElement(1,1,2); DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransformByVtkMatrix(vtkmatrix); CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,true)); //test needs to fail now vtkmatrix->SetElement(1,1,7); dummy->SetIndexToWorldTransformByVtkMatrix(vtkmatrix); CPPUNIT_ASSERT(mitk::Equal(anotherTransform,dummy->GetIndexToWorldTransform(),mitk::eps,false)==false); //undo changes, new and changed object need to be the same! vtkmatrix->SetElement(1,1,1); dummy->SetIndexToWorldTransformByVtkMatrix(vtkmatrix); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetIdentity() { DummyTestClass::Pointer dummy = DummyTestClass::New(); //Change IndextoWorldTransform and Origin dummy->SetIndexToWorldTransform(anotherTransform); dummy->SetOrigin(anotherPoint); //Set Identity should reset ITWT and Origin dummy->SetIdentity(); CPPUNIT_ASSERT(mitk::Equal(aTransform,dummy->GetIndexToWorldTransform(),mitk::eps,true)); - CPPUNIT_ASSERT(aPoint==dummy->GetOrigin()); - CPPUNIT_ASSERT(aSpacing==dummy->GetSpacing()); + CPPUNIT_ASSERT(mitk::Equal(aPoint,dummy->GetOrigin())); + CPPUNIT_ASSERT(mitk::Equal(aSpacing,dummy->GetSpacing())); //new and changed object need to be the same! DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestSetSpacing() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetSpacing(anotherSpacing); - CPPUNIT_ASSERT(anotherSpacing==dummy->GetSpacing()); + CPPUNIT_ASSERT(mitk::Equal(anotherSpacing,dummy->GetSpacing())); //undo changes, new and changed object need to be the same! dummy->SetSpacing(aSpacing); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestTransferItkToVtkTransform() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(anotherTransform); //calls TransferItkToVtkTransform mitk::AffineTransform3D::Pointer dummyTransform = dummy->GetIndexToWorldTransform(); CPPUNIT_ASSERT(mitk::MatrixEqualElementWise( anotherMatrix, dummyTransform->GetMatrix() )); } void TestConstructors() { //test standard constructor DummyTestClass::Pointer dummy1 = DummyTestClass::New(); bool test = dummy1->IsValid(); CPPUNIT_ASSERT(test == true); CPPUNIT_ASSERT(dummy1->GetFrameOfReferenceID() == 0); CPPUNIT_ASSERT(dummy1->GetIndexToWorldTransformLastModified() == 0); - CPPUNIT_ASSERT(dummy1->GetSpacing() == aSpacing); - CPPUNIT_ASSERT(dummy1->GetOrigin()==aPoint); + CPPUNIT_ASSERT(mitk::Equal(dummy1->GetSpacing(), aSpacing)); + CPPUNIT_ASSERT(mitk::Equal(dummy1->GetOrigin(), aPoint)); CPPUNIT_ASSERT(dummy1->GetImageGeometry()==false); CPPUNIT_ASSERT(mitk::Equal( dummy1->GetIndexToWorldTransform(), aTransform, mitk::eps, true)); CPPUNIT_ASSERT(mitk::Equal( dummy1->GetBoundingBox(), aBoundingBox, mitk::eps, true)); DummyTestClass::Pointer dummy2 = DummyTestClass::New(); dummy2->SetOrigin(anotherPoint); float bounds[6] = {0,11,0,12,0,13}; dummy2->SetFloatBounds(bounds); dummy2->SetIndexToWorldTransform(anotherTransform); dummy2->SetSpacing(anotherSpacing); DummyTestClass::Pointer dummy3 = DummyTestClass::New(*dummy2); CPPUNIT_ASSERT(mitk::Equal(dummy3,dummy2,mitk::eps,true)); } //Equal Tests void Equal_CloneAndOriginal_ReturnsTrue() { CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,true)); } void Equal_DifferentOrigin_ReturnsFalse() { anotherDummyGeometry->SetOrigin(anotherPoint); CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false); } void Equal_DifferentIndexToWorldTransform_ReturnsFalse() { anotherDummyGeometry->SetIndexToWorldTransform(anotherTransform); CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false); } void Equal_DifferentSpacing_ReturnsFalse() { anotherDummyGeometry->SetSpacing(anotherSpacing); CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false); } void Equal_InputIsNull_ReturnsFalse() { DummyTestClass::Pointer geometryNull = NULL; MITK_INFO<<"Test, if a Null pointer throws an error. The next line needs to display an error."; CPPUNIT_ASSERT( mitk::Equal(geometryNull, anotherDummyGeometry, mitk::eps,false)==false); } void Equal_DifferentBoundingBox_ReturnsFalse() { //create different bounds to make the comparison false mitk::ScalarType bounds[ ] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; anotherDummyGeometry->SetBounds(bounds); CPPUNIT_ASSERT( mitk::Equal(aDummyGeometry, anotherDummyGeometry, mitk::eps,false)==false); } void TestComposeTransform(){ //Create Transformations to set and compare mitk::AffineTransform3D::Pointer transform1; transform1 = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix1; matrix1.SetIdentity(); matrix1(1,1) = 2; transform1->SetMatrix( matrix1 ); //Spacing = 2 mitk::AffineTransform3D::Pointer transform2; transform2 = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix2; matrix2.SetIdentity(); matrix2(1,1) = 2; transform2->SetMatrix( matrix2 ); //Spacing = 2 mitk::AffineTransform3D::Pointer transform3; transform3 = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix3; matrix3.SetIdentity(); matrix3(1,1) = 4; transform3->SetMatrix( matrix3 ); //Spacing = 4 mitk::AffineTransform3D::Pointer transform4; transform4 = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix4; matrix4.SetIdentity(); matrix4(1,1) = 0.25; transform4->SetMatrix( matrix4 ); //Spacing = 0.25 //Vector to compare spacing mitk::Vector3D expectedSpacing; expectedSpacing.Fill(1.0); expectedSpacing[1] = 4; DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(transform1); //Spacing = 2 dummy->Compose(transform2); //Spacing = 4 CPPUNIT_ASSERT(mitk::Equal(dummy->GetSpacing(), expectedSpacing)); CPPUNIT_ASSERT(mitk::Equal(transform3,dummy->GetIndexToWorldTransform(),mitk::eps,true)); // 4=4 //undo changes, new and changed object need to be the same! dummy->Compose(transform4); //Spacing = 1 DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); // 1=1 } void TestComposeVtkMatrix(){ //Create Transformations to set and compare mitk::AffineTransform3D::Pointer transform1; transform1 = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix1; matrix1.SetIdentity(); matrix1(1,1) = 2; transform1->SetMatrix( matrix1 ); //Spacing = 2 vtkMatrix4x4* vtkmatrix2; vtkmatrix2 = vtkMatrix4x4::New(); vtkmatrix2->Identity(); vtkmatrix2->SetElement(1,1,2); //Spacing = 2 mitk::AffineTransform3D::Pointer transform3; transform3 = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix3; matrix3.SetIdentity(); matrix3(1,1) = 4; transform3->SetMatrix( matrix3 ); //Spacing = 4 vtkMatrix4x4* vtkmatrix4; vtkmatrix4 = vtkMatrix4x4::New(); vtkmatrix4->Identity(); vtkmatrix4->SetElement(1,1,0.25); //Spacing = 0.25 //Vector to compare spacing mitk::Vector3D expectedSpacing; expectedSpacing.Fill(1.0); expectedSpacing[1] = 4; DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(transform1); //Spacing = 2 dummy->Compose(vtkmatrix2); //Spacing = 4 CPPUNIT_ASSERT(mitk::Equal(transform3,dummy->GetIndexToWorldTransform(),mitk::eps,true)); // 4=4 CPPUNIT_ASSERT(mitk::Equal(dummy->GetSpacing(), expectedSpacing)); //undo changes, new and changed object need to be the same! dummy->Compose(vtkmatrix4); //Spacing = 1 DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); // 1=1 } void TestTranslate(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetOrigin(anotherPoint); - CPPUNIT_ASSERT(anotherPoint==dummy->GetOrigin()); + CPPUNIT_ASSERT(mitk::Equal(anotherPoint,dummy->GetOrigin())); //use some random values for translation mitk::Vector3D translationVector; translationVector.SetElement(0, 17.5f); translationVector.SetElement(1, -32.3f); translationVector.SetElement(2, 4.0f); //compute ground truth mitk::Point3D tmpResult = anotherPoint + translationVector; dummy->Translate(translationVector); CPPUNIT_ASSERT( mitk::Equal( dummy->GetOrigin(), tmpResult )); //undo changes translationVector*=-1; dummy->Translate(translationVector); CPPUNIT_ASSERT( mitk::Equal( dummy->GetOrigin(), anotherPoint )); //undo changes, new and changed object need to be the same! translationVector.SetElement(0, -1 * anotherPoint[0]); translationVector.SetElement(1, -1 * anotherPoint[1]); translationVector.SetElement(2, -1 * anotherPoint[2]); dummy->Translate(translationVector); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } // a part of the test requires axis-parallel coordinates int testIndexAndWorldConsistency(DummyTestClass::Pointer dummyGeometry) { //Testing consistency of index and world coordinate systems mitk::Point3D origin = dummyGeometry->GetOrigin(); mitk::Point3D dummyPoint; //Testing index->world->index conversion consistency dummyGeometry->WorldToIndex(origin, dummyPoint); dummyGeometry->IndexToWorld(dummyPoint, dummyPoint); CPPUNIT_ASSERT(mitk::EqualArray(dummyPoint, origin, 3, mitk::eps, true)); //Testing WorldToIndex(origin, mitk::Point3D)==(0,0,0) mitk::Point3D globalOrigin; mitk::FillVector3D(globalOrigin, 0,0,0); mitk::Point3D originContinuousIndex; dummyGeometry->WorldToIndex(origin, originContinuousIndex); CPPUNIT_ASSERT(mitk::EqualArray(originContinuousIndex, globalOrigin, 3, mitk::eps, true)); //Testing WorldToIndex(origin, itk::Index)==(0,0,0) itk::Index<3> itkindex; dummyGeometry->WorldToIndex(origin, itkindex); itk::Index<3> globalOriginIndex; mitk::vtk2itk(globalOrigin, globalOriginIndex); CPPUNIT_ASSERT(mitk::EqualArray(itkindex, globalOriginIndex, 3, mitk::eps, true)); //Testing WorldToIndex(origin-0.5*spacing, itk::Index)==(0,0,0) mitk::Vector3D halfSpacingStep = dummyGeometry->GetSpacing()*0.5; mitk::Matrix3D rotation; mitk::Point3D originOffCenter = origin-halfSpacingStep; dummyGeometry->WorldToIndex(originOffCenter, itkindex); CPPUNIT_ASSERT(mitk::EqualArray(itkindex, globalOriginIndex, 3, mitk::eps, true)); //Testing WorldToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0) originOffCenter = origin+halfSpacingStep; originOffCenter -= 0.0001; dummyGeometry->WorldToIndex( originOffCenter, itkindex); CPPUNIT_ASSERT(mitk::EqualArray(itkindex, globalOriginIndex, 3, mitk::eps, true)); //Testing WorldToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)"); originOffCenter = origin+halfSpacingStep; itk::Index<3> global111; mitk::FillVector3D(global111, 1,1,1); dummyGeometry->WorldToIndex( originOffCenter, itkindex); CPPUNIT_ASSERT(mitk::EqualArray(itkindex, global111, 3, mitk::eps, true)); //Testing WorldToIndex(GetCenter())==BoundingBox.GetCenter mitk::Point3D center = dummyGeometry->GetCenter(); mitk::Point3D centerContIndex; dummyGeometry->WorldToIndex(center, centerContIndex); mitk::BoundingBox::ConstPointer boundingBox = dummyGeometry->GetBoundingBox(); mitk::BoundingBox::PointType centerBounds = boundingBox->GetCenter(); CPPUNIT_ASSERT(mitk::Equal(centerContIndex,centerBounds)); //Testing GetCenter()==IndexToWorld(BoundingBox.GetCenter) center = dummyGeometry->GetCenter(); mitk::Point3D centerBoundsInWorldCoords; dummyGeometry->IndexToWorld(centerBounds, centerBoundsInWorldCoords); CPPUNIT_ASSERT(mitk::Equal(center,centerBoundsInWorldCoords)); //Test using random point, //Testing consistency of index and world coordinate systems mitk::Point3D point; mitk::FillVector3D(point,3.5,-2,4.6); //Testing index->world->index conversion consistency dummyGeometry->WorldToIndex(point, dummyPoint); dummyGeometry->IndexToWorld(dummyPoint, dummyPoint); CPPUNIT_ASSERT(mitk::EqualArray(dummyPoint, point, 3, mitk::eps, true)); return EXIT_SUCCESS; } int testIndexAndWorldConsistencyForVectors(DummyTestClass::Pointer dummyGeometry) { //Testing consistency of index and world coordinate systems for vectors mitk::Vector3D xAxisMM = dummyGeometry->GetAxisVector(0); mitk::Vector3D xAxisContinuousIndex; mitk::Point3D p, pIndex, origin; origin = dummyGeometry->GetOrigin(); p[0] = xAxisMM[0]+origin[0]; p[1] = xAxisMM[1]+origin[1]; p[2] = xAxisMM[2]+origin[2]; dummyGeometry->WorldToIndex(p,pIndex); dummyGeometry->WorldToIndex(xAxisMM,xAxisContinuousIndex); - CPPUNIT_ASSERT(xAxisContinuousIndex[0] == pIndex[0]); - CPPUNIT_ASSERT(xAxisContinuousIndex[1] == pIndex[1]); - CPPUNIT_ASSERT(xAxisContinuousIndex[2] == pIndex[2]); + CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[0], pIndex[0])); + CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[1], pIndex[1])); + CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[2], pIndex[2])); dummyGeometry->IndexToWorld(xAxisContinuousIndex,xAxisContinuousIndex); dummyGeometry->IndexToWorld(pIndex,p); CPPUNIT_ASSERT(xAxisContinuousIndex == xAxisMM); - CPPUNIT_ASSERT(xAxisContinuousIndex[0] == p[0]-origin[0]); - CPPUNIT_ASSERT(xAxisContinuousIndex[1] == p[1]-origin[1]); - CPPUNIT_ASSERT(xAxisContinuousIndex[2] == p[2]-origin[2]); + CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[0], p[0]-origin[0])); + CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[1], p[1]-origin[1])); + CPPUNIT_ASSERT(mitk::Equal(xAxisContinuousIndex[2], p[2]-origin[2])); //Test consictency for random vector mitk::Vector3D vector; mitk::FillVector3D(vector, 2.5,-3.2,8.1); mitk::Vector3D vectorContinuousIndex; p[0] = vector[0]+origin[0]; p[1] = vector[1]+origin[1]; p[2] = vector[2]+origin[2]; dummyGeometry->WorldToIndex(p,pIndex); dummyGeometry->WorldToIndex(vector,vectorContinuousIndex); - CPPUNIT_ASSERT(vectorContinuousIndex[0] == pIndex[0]); - CPPUNIT_ASSERT(vectorContinuousIndex[1] == pIndex[1]); - CPPUNIT_ASSERT(vectorContinuousIndex[2] == pIndex[2]); + CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[0], pIndex[0])); + CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[1], pIndex[1])); + CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[2], pIndex[2])); dummyGeometry->IndexToWorld(vectorContinuousIndex,vectorContinuousIndex); dummyGeometry->IndexToWorld(pIndex,p); CPPUNIT_ASSERT(vectorContinuousIndex == vector); - CPPUNIT_ASSERT(vectorContinuousIndex[0] == p[0]-origin[0]); - CPPUNIT_ASSERT(vectorContinuousIndex[1] == p[1]-origin[1]); - CPPUNIT_ASSERT(vectorContinuousIndex[2] == p[2]-origin[2]); + CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[0], p[0]-origin[0])); + CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[1], p[1]-origin[1])); + CPPUNIT_ASSERT(mitk::Equal(vectorContinuousIndex[2], p[2]-origin[2])); return EXIT_SUCCESS; } int testIndexAndWorldConsistencyForIndex(DummyTestClass::Pointer dummyGeometry) { //Testing consistency of index and world coordinate systems // creating testing data itk::Index<4> itkIndex4, itkIndex4b; itk::Index<3> itkIndex3, itkIndex3b; itk::Index<2> itkIndex2, itkIndex2b; itk::Index<3> mitkIndex, mitkIndexb; itkIndex4[0] = itkIndex4[1] = itkIndex4[2] = itkIndex4[3] = 4; itkIndex3[0] = itkIndex3[1] = itkIndex3[2] = 6; itkIndex2[0] = itkIndex2[1] = 2; mitkIndex[0] = mitkIndex[1] = mitkIndex[2] = 13; // check for constistency mitk::Point3D point; dummyGeometry->IndexToWorld(itkIndex2,point); dummyGeometry->WorldToIndex(point,itkIndex2b); CPPUNIT_ASSERT( ((itkIndex2b[0] == itkIndex2[0]) && (itkIndex2b[1] == itkIndex2[1]))); //Testing itk::index<2> for IndexToWorld/WorldToIndex consistency dummyGeometry->IndexToWorld(itkIndex3,point); dummyGeometry->WorldToIndex(point,itkIndex3b); CPPUNIT_ASSERT( ((itkIndex3b[0] == itkIndex3[0]) && (itkIndex3b[1] == itkIndex3[1]) && (itkIndex3b[2] == itkIndex3[2]))); //Testing itk::index<3> for IndexToWorld/WorldToIndex consistency dummyGeometry->IndexToWorld(itkIndex4,point); dummyGeometry->WorldToIndex(point,itkIndex4b); CPPUNIT_ASSERT( ((itkIndex4b[0] == itkIndex4[0]) && (itkIndex4b[1] == itkIndex4[1]) && (itkIndex4b[2] == itkIndex4[2]) && (itkIndex4b[3] == 0))); //Testing itk::index<3> for IndexToWorld/WorldToIndex consistency dummyGeometry->IndexToWorld(mitkIndex,point); dummyGeometry->WorldToIndex(point,mitkIndexb); CPPUNIT_ASSERT( ((mitkIndexb[0] == mitkIndex[0]) && (mitkIndexb[1] == mitkIndex[1]) && (mitkIndexb[2] == mitkIndex[2]))); //Testing mitk::Index for IndexToWorld/WorldToIndex consistency return EXIT_SUCCESS; } void TestIndexToWorld(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); testIndexAndWorldConsistency(dummy); testIndexAndWorldConsistencyForVectors(dummy); testIndexAndWorldConsistencyForIndex(dummy); //Geometry must not have changed DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); //Test with other geometries dummy->SetOrigin(anotherPoint); testIndexAndWorldConsistency(dummy); testIndexAndWorldConsistencyForVectors(dummy); testIndexAndWorldConsistencyForIndex(dummy); dummy->SetIndexToWorldTransform(anotherTransform); testIndexAndWorldConsistency(dummy); testIndexAndWorldConsistencyForVectors(dummy); testIndexAndWorldConsistencyForIndex(dummy); dummy->SetOrigin(anotherPoint); testIndexAndWorldConsistency(dummy); testIndexAndWorldConsistencyForVectors(dummy); testIndexAndWorldConsistencyForIndex(dummy); dummy->SetSpacing(anotherSpacing); testIndexAndWorldConsistency(dummy); testIndexAndWorldConsistencyForVectors(dummy); testIndexAndWorldConsistencyForIndex(dummy); } void TestExecuteOperation(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); //Do same Operations with new Dummy and compare DummyTestClass::Pointer newDummy = DummyTestClass::New(); //Test operation Nothing mitk::Operation* opN = new mitk::Operation(mitk::OpNOTHING); dummy->ExecuteOperation(opN); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); //Test operation Move mitk::PointOperation* opP = new mitk::PointOperation(mitk::OpMOVE,anotherPoint); dummy->ExecuteOperation(opP); - CPPUNIT_ASSERT(anotherPoint==dummy->GetOrigin()); + CPPUNIT_ASSERT(mitk::Equal(anotherPoint,dummy->GetOrigin())); newDummy->SetOrigin(anotherPoint); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); //Test operation Scale, Scale sets spacing to scale+1 mitk::Point3D spacing; spacing[0]=anotherSpacing[0]-1.; spacing[1]=anotherSpacing[1]-1.; spacing[2]=anotherSpacing[2]-1.; mitk::PointOperation* opS = new mitk::PointOperation(mitk::OpSCALE,spacing); dummy->ExecuteOperation(opS); - CPPUNIT_ASSERT(anotherSpacing==dummy->GetSpacing()); + CPPUNIT_ASSERT(mitk::Equal(anotherSpacing,dummy->GetSpacing())); newDummy->SetSpacing(anotherSpacing); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); //change Geometry to test more cases dummy->SetIndexToWorldTransform(anotherTransform); dummy->SetSpacing(anotherSpacing); //Testing a rotation of the geometry double angle = 35.0; mitk::Vector3D rotationVector; mitk::FillVector3D( rotationVector, 1, 0, 0 ); mitk::Point3D center = dummy->GetCenter(); mitk::RotationOperation* opR = new mitk::RotationOperation( mitk::OpROTATE, center, rotationVector, angle ); dummy->ExecuteOperation(opR); mitk::Matrix3D rotation; mitk::GetRotation(dummy, rotation); mitk::Vector3D voxelStep=rotation*anotherSpacing; mitk::Vector3D voxelStepIndex; dummy->WorldToIndex(voxelStep, voxelStepIndex); mitk::Vector3D expectedVoxelStepIndex; expectedVoxelStepIndex.Fill(1); CPPUNIT_ASSERT(mitk::Equal(voxelStepIndex,expectedVoxelStepIndex)); delete opR; delete opN; delete opS; delete opP; } void TestCalculateBoundingBoxRelToTransform(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetExtentInMM(0,15); dummy->SetExtentInMM(1,20); dummy->SetExtentInMM(2,8); mitk::BoundingBox::Pointer dummyBoundingBox = dummy->CalculateBoundingBoxRelativeToTransform(anotherTransform); mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New(); mitk::BoundingBox::PointIdentifier pointid=0; unsigned char i; mitk::AffineTransform3D::Pointer inverse = mitk::AffineTransform3D::New(); anotherTransform->GetInverse(inverse); for(i=0; i<8; ++i) pointscontainer->InsertElement( pointid++, inverse->TransformPoint( dummy->GetCornerPoint(i) )); mitk::BoundingBox::Pointer result = mitk::BoundingBox::New(); result->SetPoints(pointscontainer); result->ComputeBoundingBox(); CPPUNIT_ASSERT(mitk::Equal(result,dummyBoundingBox,mitk::eps,true)); //dummy still needs to be unchanged, except for extend DummyTestClass::Pointer newDummy = DummyTestClass::New(); newDummy->SetExtentInMM(0,15); newDummy->SetExtentInMM(1,20); newDummy->SetExtentInMM(2,8); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } //void TestSetTimeBounds(){ // mitk::TimeBounds timeBounds; // timeBounds[0] = 1; // timeBounds[1] = 9; // DummyTestClass::Pointer dummy = DummyTestClass::New(); // dummy->SetTimeBounds(timeBounds); // mitk::TimeBounds timeBounds2 = dummy->GetTimeBounds(); // CPPUNIT_ASSERT(timeBounds[0]==timeBounds2[0]); // CPPUNIT_ASSERT(timeBounds[1]==timeBounds2[1]); // //undo changes, new and changed object need to be the same! // timeBounds[0]=mitk::ScalarTypeNumericTraits::NonpositiveMin(); // timeBounds[1]=mitk::ScalarTypeNumericTraits::max(); // DummyTestClass::Pointer newDummy = DummyTestClass::New(); // CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); //} void TestIs2DConvertable(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); //new initialized geometry is 2D convertable CPPUNIT_ASSERT(dummy->Is2DConvertable()); //Wrong Spacing needs to fail dummy->SetSpacing(anotherSpacing); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); //undo dummy->SetSpacing(aSpacing); CPPUNIT_ASSERT(dummy->Is2DConvertable()); //Wrong Origin needs to fail dummy->SetOrigin(anotherPoint); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); //undo dummy->SetOrigin(aPoint); CPPUNIT_ASSERT(dummy->Is2DConvertable()); //third dimension must not be transformed mitk::AffineTransform3D::Pointer dummyTransform = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType dummyMatrix; dummyMatrix.SetIdentity(); dummyTransform->SetMatrix( dummyMatrix ); dummy->SetIndexToWorldTransform(dummyTransform); //identity matrix is 2DConvertable CPPUNIT_ASSERT(dummy->Is2DConvertable()); dummyMatrix(0,2) = 3; dummyTransform->SetMatrix( dummyMatrix ); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); dummyMatrix.SetIdentity(); dummyMatrix(1,2) = 0.4; dummyTransform->SetMatrix( dummyMatrix ); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); dummyMatrix.SetIdentity(); dummyMatrix(2,2) = 3; dummyTransform->SetMatrix( dummyMatrix ); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); dummyMatrix.SetIdentity(); dummyMatrix(2,1) = 3; dummyTransform->SetMatrix( dummyMatrix ); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); dummyMatrix.SetIdentity(); dummyMatrix(2,0) = 3; dummyTransform->SetMatrix( dummyMatrix ); CPPUNIT_ASSERT(dummy->Is2DConvertable()==false); //undo changes, new and changed object need to be the same! dummyMatrix.SetIdentity(); dummyTransform->SetMatrix( dummyMatrix ); DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestGetCornerPoint(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(anotherTransform); double bounds[6] = {0,11,0,12,0,13}; dummy->SetFloatBounds(bounds); mitk::Point3D corner, refCorner; //Corner 0 mitk::FillVector3D(refCorner,bounds[0],bounds[2],bounds[4]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(0); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(true,true,true); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 1 mitk::FillVector3D(refCorner,bounds[0],bounds[2],bounds[5]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(1); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(true,true,false); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 2 mitk::FillVector3D(refCorner,bounds[0],bounds[3],bounds[4]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(2); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(true,false,true); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 3 mitk::FillVector3D(refCorner,bounds[0],bounds[3],bounds[5]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(3); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(true,false,false); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 4 mitk::FillVector3D(refCorner,bounds[1],bounds[2],bounds[4]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(4); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(false,true,true); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 5 mitk::FillVector3D(refCorner,bounds[1],bounds[2],bounds[5]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(5); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(false,true,false); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 6 mitk::FillVector3D(refCorner,bounds[1],bounds[3],bounds[4]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(6); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(false,false,true); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Corner 7 mitk::FillVector3D(refCorner,bounds[1],bounds[3],bounds[5]); refCorner = anotherTransform->TransformPoint(refCorner); corner=dummy->GetCornerPoint(7); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); corner=dummy->GetCornerPoint(false,false,false); - CPPUNIT_ASSERT(refCorner==corner); + CPPUNIT_ASSERT(mitk::Equal(refCorner,corner)); //Wrong Corner needs to fail CPPUNIT_ASSERT_THROW(dummy->GetCornerPoint(20),itk::ExceptionObject); //dummy geometry must not have changed! DummyTestClass::Pointer newDummy = DummyTestClass::New(); newDummy->SetIndexToWorldTransform(anotherTransform); newDummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestExtentInMM() { DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetExtentInMM(0,50); - CPPUNIT_ASSERT(50==dummy->GetExtentInMM(0)); + CPPUNIT_ASSERT(mitk::Equal(50.,dummy->GetExtentInMM(0))); //Vnl Matrix has changed. The next line only works because the spacing is 1! - CPPUNIT_ASSERT(50==dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).magnitude()); + CPPUNIT_ASSERT(mitk::Equal(50.,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).magnitude())); //Smaller extent than original dummy->SetExtentInMM(0,5); - CPPUNIT_ASSERT(5==dummy->GetExtentInMM(0)); - CPPUNIT_ASSERT(5==dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).magnitude()); + CPPUNIT_ASSERT(mitk::Equal(5.,dummy->GetExtentInMM(0))); + CPPUNIT_ASSERT(mitk::Equal(5.,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).magnitude())); dummy->SetExtentInMM(1,4); - CPPUNIT_ASSERT(4==dummy->GetExtentInMM(1)); - CPPUNIT_ASSERT(4==dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1).magnitude()); + CPPUNIT_ASSERT(mitk::Equal(4.,dummy->GetExtentInMM(1))); + CPPUNIT_ASSERT(mitk::Equal(4.,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1).magnitude())); dummy->SetExtentInMM(2,2.5); - CPPUNIT_ASSERT(2.5==dummy->GetExtentInMM(2)); - CPPUNIT_ASSERT(2.5==dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2).magnitude()); + CPPUNIT_ASSERT(mitk::Equal(2.5,dummy->GetExtentInMM(2))); + CPPUNIT_ASSERT(mitk::Equal(2.5,dummy->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2).magnitude())); } void TestGetAxisVector(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(anotherTransform); double bounds[6] = {0,11,0,12,0,13}; dummy->SetFloatBounds(bounds); mitk::Vector3D vector; mitk::FillVector3D(vector,bounds[1],0,0); dummy->IndexToWorld(vector,vector); - CPPUNIT_ASSERT(dummy->GetAxisVector(0)==vector); + CPPUNIT_ASSERT(mitk::Equal(dummy->GetAxisVector(0),vector)); mitk::FillVector3D(vector,0,bounds[3],0); dummy->IndexToWorld(vector,vector); - CPPUNIT_ASSERT(dummy->GetAxisVector(1)==vector); + CPPUNIT_ASSERT(mitk::Equal(dummy->GetAxisVector(1),vector)); mitk::FillVector3D(vector,0,0,bounds[5]); dummy->IndexToWorld(vector,vector); - CPPUNIT_ASSERT(dummy->GetAxisVector(2)==vector); + CPPUNIT_ASSERT(mitk::Equal(dummy->GetAxisVector(2),vector)); } void TestGetCenter(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(anotherTransform); double bounds[6] = {0,11,2,12,1,13}; dummy->SetFloatBounds(bounds); mitk::Point3D refCenter; for( int i=0;i<3;i++) refCenter.SetElement(i,( bounds[2 * i] + bounds[2 * i + 1] ) / 2.0); dummy->IndexToWorld(refCenter,refCenter); - CPPUNIT_ASSERT(dummy->GetCenter()==refCenter); + CPPUNIT_ASSERT(mitk::Equal(dummy->GetCenter(),refCenter)); } void TestGetDiagonalLength(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); double bounds[6] = {1,3,5,8,7.5,11.5}; dummy->SetFloatBounds(bounds); //3-1=2, 8-5=3, 11.5-7.5=4; 2^2+3^2+4^2 = 29 double expectedLength = sqrt(29.); CPPUNIT_ASSERT(mitk::Equal(expectedLength, dummy->GetDiagonalLength(), mitk::eps, true)); CPPUNIT_ASSERT(mitk::Equal(29., dummy->GetDiagonalLength2(), mitk::eps, true)); //dummy must not have changed DummyTestClass::Pointer newDummy = DummyTestClass::New(); newDummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestGetExtent(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); double bounds[6] = {1,3,5,8,7.5,11.5}; dummy->SetFloatBounds(bounds); - CPPUNIT_ASSERT(2==dummy->GetExtent(0)); - CPPUNIT_ASSERT(3==dummy->GetExtent(1)); - CPPUNIT_ASSERT(4==dummy->GetExtent(2)); + CPPUNIT_ASSERT(mitk::Equal(2.,dummy->GetExtent(0))); + CPPUNIT_ASSERT(mitk::Equal(3.,dummy->GetExtent(1))); + CPPUNIT_ASSERT(mitk::Equal(4.,dummy->GetExtent(2))); //dummy must not have changed DummyTestClass::Pointer newDummy = DummyTestClass::New(); newDummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestIsInside(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); double bounds[6] = {1,3,5,8,7.5,11.5}; dummy->SetFloatBounds(bounds); mitk::Point3D insidePoint; mitk::Point3D outsidePoint; mitk::FillVector3D(insidePoint,2,6,7.6); mitk::FillVector3D(outsidePoint,0,9,8.2); CPPUNIT_ASSERT(dummy->IsIndexInside(insidePoint)); CPPUNIT_ASSERT(false==dummy->IsIndexInside(outsidePoint)); dummy->IndexToWorld(insidePoint,insidePoint); dummy->IndexToWorld(outsidePoint,outsidePoint); CPPUNIT_ASSERT(dummy->IsInside(insidePoint)); CPPUNIT_ASSERT(false==dummy->IsInside(outsidePoint)); //dummy must not have changed DummyTestClass::Pointer newDummy = DummyTestClass::New(); newDummy->SetFloatBounds(bounds); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } void TestInitialize() { //test standard constructor DummyTestClass::Pointer dummy1 = DummyTestClass::New(); DummyTestClass::Pointer dummy2 = DummyTestClass::New(); dummy2->SetOrigin(anotherPoint); dummy2->SetBounds(anotherBoundingBox->GetBounds()); //mitk::TimeBounds timeBounds; //timeBounds[0] = 1; //timeBounds[1] = 9; //dummy2->SetTimeBounds(timeBounds); dummy2->SetIndexToWorldTransform(anotherTransform); dummy2->SetSpacing(anotherSpacing); dummy1->InitializeGeometry(dummy2); CPPUNIT_ASSERT(mitk::Equal(dummy1,dummy2,mitk::eps,true)); dummy1->Initialize(); DummyTestClass::Pointer dummy3 = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy3,dummy1,mitk::eps,true)); } void TestGetMatrixColumn(){ DummyTestClass::Pointer dummy = DummyTestClass::New(); dummy->SetIndexToWorldTransform(anotherTransform); mitk::Vector3D testVector,refVector; testVector.SetVnlVector(dummy->GetMatrixColumn(0)); mitk::FillVector3D(refVector,1,0,0); CPPUNIT_ASSERT(testVector==refVector); testVector.SetVnlVector(dummy->GetMatrixColumn(1)); mitk::FillVector3D(refVector,0,2,0); CPPUNIT_ASSERT(testVector==refVector); testVector.SetVnlVector(dummy->GetMatrixColumn(2)); mitk::FillVector3D(refVector,0,0,1); CPPUNIT_ASSERT(testVector==refVector); //dummy must not have changed DummyTestClass::Pointer newDummy = DummyTestClass::New(); newDummy->SetIndexToWorldTransform(anotherTransform); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } /* void (){ DummyTestClass::Pointer dummy = DummyTestClass::New(); CPPUNIT_ASSERT(); //undo changes, new and changed object need to be the same! DummyTestClass::Pointer newDummy = DummyTestClass::New(); CPPUNIT_ASSERT(mitk::Equal(dummy,newDummy,mitk::eps,true)); } */ };//end class mitkBaseGeometryTestSuite MITK_TEST_SUITE_REGISTRATION(mitkBaseGeometry) diff --git a/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp b/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp index 67d257c8d3..91992670d5 100644 --- a/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp @@ -1,315 +1,437 @@ /*=================================================================== 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 "mitkNavigationDataObjectVisualizationFilter.h" #include "mitkNavigationData.h" #include "mitkTestingMacros.h" +#include +#include #include #include #include "mitkSurface.h" - /**Documentation - * test for the class "NavigationDataObjectVisualizationFilter". - */ -int mitkNavigationDataObjectVisualizationFilterTest(int /* argc */, char* /*argv*/[]) +* test for the class "NavigationDataObjectVisualizationFilter". +*/ +class mitkNavigationDataObjectVisualizationFilterTestSuite : public mitk::TestFixture { - MITK_TEST_BEGIN("NavigationDataObjectVisualizationFilter") - - // let's create an object of our class - mitk::NavigationDataObjectVisualizationFilter::Pointer myFilter = mitk::NavigationDataObjectVisualizationFilter::New(); - - // first test: did this work? - // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since - // it makes no sense to continue without an object. - MITK_TEST_CONDITION_REQUIRED(myFilter.IsNotNull(),"Testing instantiation"); - - /* create helper objects: navigation data with position as origin, zero quaternion, zero error and data valid */ + // List of Tests + CPPUNIT_TEST_SUITE(mitkNavigationDataObjectVisualizationFilterTestSuite); + + //Constructor + MITK_TEST(TestInitialize); + MITK_TEST(TestInput); + MITK_TEST(TestOutput); + MITK_TEST(TestRepresentationObjects); + MITK_TEST(TestTransforms); + MITK_TEST(TestMessWithRepresentationObjects); + MITK_TEST(TestThirdInput); + MITK_TEST(TestSetTransformPosition); + MITK_TEST(TestSetTransformOrientation); + MITK_TEST(TestConvenienceSetTransformOrientation); + MITK_TEST(TestUpdateOrientation); + + CPPUNIT_TEST_SUITE_END(); + + // Used Variables +private: + mitk::NavigationDataObjectVisualizationFilter::Pointer myFilter; mitk::NavigationData::PositionType initialPos1, initialPos2; - mitk::FillVector3D(initialPos1, 1.1, 2.2, 3.3); - mitk::FillVector3D(initialPos2, 5.0, 6.0, 7.0); - mitk::NavigationData::OrientationType initialOri1(0.1, 0.2, 0.3, 0.4); - mitk::NavigationData::OrientationType initialOri2(0.5, 0.6, 0.7, 0.8); - mitk::ScalarType initialError1(0.0); - mitk::ScalarType initialError2(5.0); - bool initialValid1(true); - bool initialValid2(true); - - mitk::NavigationData::Pointer nd1 = mitk::NavigationData::New(); - nd1->SetPosition(initialPos1); - nd1->SetOrientation(initialOri1); - nd1->SetPositionAccuracy(initialError1); - nd1->SetDataValid(initialValid1); - - mitk::NavigationData::Pointer nd2 = mitk::NavigationData::New(); - nd2->SetPosition(initialPos2); - nd2->SetOrientation(initialOri2); - nd2->SetPositionAccuracy(initialError2); - nd2->SetDataValid(initialValid2); - - myFilter->SetInput(nd1); - myFilter->SetInput(1, nd2); - - //testing the input - MITK_TEST_CONDITION(myFilter->GetInput() == nd1, "Testing Set-/GetInput() input 1 without index"); - MITK_TEST_CONDITION(myFilter->GetInput(0) == nd1, "Testing Set-/GetInput() input 1"); - MITK_TEST_CONDITION(myFilter->GetInput(1) == nd2, "Testing Set-/GetInput() input 2"); - MITK_TEST_CONDITION(myFilter->GetNumberOfToolRepresentations() == 0, "Testing GetNumberOfToolRepresentations()"); - - //testing getting the output - mitk::NavigationData* output = myFilter->GetOutput(); - MITK_TEST_CONDITION_REQUIRED(output != NULL, "Testing GetOutput()"); - MITK_TEST_CONDITION_REQUIRED(output == myFilter->GetOutput(), "Testing GetOutput() == GetOutput()"); - MITK_TEST_CONDITION_REQUIRED(output != myFilter->GetOutput(1), "Testing GetOutput() != GetOutput(1)"); + mitk::NavigationData::OrientationType initialOri1; + mitk::NavigationData::OrientationType initialOri2; + mitk::ScalarType initialError1; + mitk::ScalarType initialError2; + bool initialValid1; + bool initialValid2; + mitk::NavigationData::Pointer nd1; + mitk::NavigationData::Pointer nd2; // Test setting BaseData - mitk::Surface::Pointer mitkToolData1 = mitk::Surface::New(); + mitk::Surface::Pointer mitkToolData1 ; - mitk::Surface::Pointer mitkToolData2 = mitk::Surface::New(); + mitk::Surface::Pointer mitkToolData2 ; //dummy for test; will not be set but used to test find - mitk::Surface::Pointer mitkToolDataDummy = mitk::Surface::New(); + mitk::Surface::Pointer mitkToolDataDummy ; //and the Dummy NavigationData for this + mitk::NavigationData::OrientationType initialOriDummy; mitk::NavigationData::PositionType initialPosDummy; - mitk::FillVector3D(initialPosDummy, 8.8, 9.9, 10.10); - mitk::NavigationData::OrientationType initialOriDummy(1.1, 2.2, 3.3, 4.4); - mitk::ScalarType initialErrorDummy(10.0); - bool initialValidDummy(true); - mitk::NavigationData::Pointer ndDummy = mitk::NavigationData::New(); - ndDummy->SetPosition(initialPosDummy); - ndDummy->SetOrientation(initialOriDummy); - ndDummy->SetPositionAccuracy(initialErrorDummy); - ndDummy->SetDataValid(initialValidDummy); - //now we have ndDummy and mitkToolDataDummy to test with - - //setting nodes - myFilter->SetRepresentationObject(0, mitkToolData1); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) == mitkToolData1, "Testing SetRepresentationObject()/GetRepresentationObject() node 1"); - MITK_TEST_CONDITION(myFilter->GetNumberOfToolRepresentations() == 1, "Testing GetNumberOfToolRepresentations() after adding first tool"); - myFilter->SetRepresentationObject(1, mitkToolData2); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(1) == mitkToolData2, "Testing SetRepresentationObject() node 2"); - MITK_TEST_CONDITION(myFilter->GetNumberOfToolRepresentations() == 2, "Testing GetNumberOfToolRepresentations() after adding second tool"); - //getting nodes - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) == mitkToolData1, "Testing GetRepresentationObject() node 1"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) != mitkToolDataDummy, "Testing GetRepresentationObject() != Dummy node"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(1) == mitkToolData2, "Testing GetRepresentationObject() node 2"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(1) != mitkToolDataDummy, "Testing GetRepresentationObject() != Dummy node"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(111) == NULL, "Testing GetRepresentationObject() with out of range parameter"); - - //Process - myFilter->Update(); - - //now check it there are data connected to the nodes with the according orientation and offsets - mitk::AffineTransform3D::Pointer affineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); - mitk::AffineTransform3D::OutputVectorType offset1 = affineTransform1->GetOffset(); - MITK_TEST_CONDITION(offset1.GetVnlVector()==initialPos1.GetVnlVector(), "Testing Offset position 1"); - - mitk::AffineTransform3D::Pointer affineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); - mitk::AffineTransform3D::OutputVectorType offset2 = affineTransform2->GetOffset(); - MITK_TEST_CONDITION(offset2.GetVnlVector()==initialPos2.GetVnlVector(), "Testing Offset position 2"); - - mitk::AffineTransform3D::MatrixType::InternalMatrixType m1 = affineTransform1->GetMatrix().GetVnlMatrix(); - MITK_TEST_OUTPUT( << "\n initOrient1="<GetVnlMatrix():\n "<< m1); - - mitk::AffineTransform3D::MatrixType::InternalMatrixType m2 = affineTransform2->GetMatrix().GetVnlMatrix(); - MITK_TEST_OUTPUT( << "\n initOrient2=" << initialOri2 << " affineTransform2->GetVnlMatrix():\n " << m2); - - -//messing with SetRepresentationObject -//setting nodes - myFilter->SetRepresentationObject(0, mitkToolData2); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) == mitkToolData2, "Twisting mitkToolData by using SetRepresentationObject() NavigationData 1 with ToolData 2"); - MITK_TEST_CONDITION(myFilter->GetNumberOfToolRepresentations() == 2, "Testing GetNumberOfToolRepresentations() == 1"); - myFilter->SetRepresentationObject(1, mitkToolData1); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(1) == mitkToolData1, "Twisting mitkToolData by using SetRepresentationObject() NavigationData 2 with ToolData 1"); - MITK_TEST_CONDITION(myFilter->GetNumberOfToolRepresentations() == 2, "Testing GetNumberOfToolRepresentations() == 2"); - //getting nodes - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) == mitkToolData2, "Testing switched BaseData of NavigationData 1 "); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) != mitkToolDataDummy, "Testing GetRepresentationObject() != Dummy node"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(1) == mitkToolData1, "Testing switched BaseData NavigationData 2"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(1) != mitkToolDataDummy, "Testing GetRepresentationObject() != Dummy node"); - - //processing update through pipeline - myFilter->Update(); - - //now check it there are data connected to the nodes with the according orientation and offsets - mitk::AffineTransform3D::Pointer affineTransform1Second = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); - MITK_TEST_CONDITION(affineTransform1 == affineTransform1Second, "Testing affineTransform1 after second update"); - mitk::AffineTransform3D::OutputVectorType offset1Second = affineTransform1->GetOffset(); - MITK_TEST_CONDITION(offset1 == offset1Second, "Testing offset1 after second update"); - MITK_TEST_CONDITION(offset1Second.GetVnlVector()==offset1.GetVnlVector(), "Testing offset1 equals first update"); - - mitk::AffineTransform3D::Pointer affineTransform2Second = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); - MITK_TEST_CONDITION(affineTransform2 == affineTransform2Second, "Testing affineTransform2 after second update"); - mitk::AffineTransform3D::OutputVectorType offset2Second = affineTransform2->GetOffset(); - MITK_TEST_CONDITION(offset2 == offset2Second, "Testing offset2 after second update"); - MITK_TEST_CONDITION(offset2Second.GetVnlVector()==offset2.GetVnlVector(), "Testing offset2 equals first update"); - - mitk::AffineTransform3D::MatrixType::InternalMatrixType m1Second= affineTransform1Second->GetMatrix().GetVnlMatrix(); - MITK_TEST_OUTPUT( <<"\n after second update initOrient1="<GetVnlMatrix():\n "<< m1Second); - - mitk::AffineTransform3D::MatrixType::InternalMatrixType m2Second= affineTransform2Second->GetMatrix().GetVnlMatrix(); - MITK_TEST_OUTPUT( << "\n after second update initOrient2="<GetVnlMatrix():\n "<< m2Second); - - //testing adding a third input - myFilter->SetInput(2,ndDummy); - MITK_TEST_CONDITION(myFilter->GetNumberOfInputs() == 3, "Adding new input and testing GetNumberOfInputs == 3"); - MITK_TEST_CONDITION(myFilter->GetNumberOfOutputs() == 3, "testing GetNumberOfOutputs == 3"); - MITK_TEST_CONDITION(myFilter->GetInput(2) == ndDummy, "Testing Input == newly added input"); - MITK_TEST_CONDITION_REQUIRED(myFilter->GetOutput(2) != NULL, "Testing GetOutput(2) != NULL"); - MITK_TEST_CONDITION_REQUIRED(myFilter->GetOutput(2) != myFilter->GetOutput(1), "Testing GetOutput(2) != GetOutput(1)"); - myFilter->SetRepresentationObject(2, mitkToolDataDummy); - MITK_TEST_CONDITION(myFilter->GetNumberOfToolRepresentations() == 3, "Testing GetNumberOfToolRepresentations() after adding latest tool"); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(2) == mitkToolDataDummy, "Testing Set-/GetRepresentationObject() equals was set"); - - //last time processing update through pipeline - myFilter->Update(); - - //now check for the new values - mitk::AffineTransform3D::Pointer affineTransformDummy = mitkToolDataDummy->GetGeometry()->GetIndexToWorldTransform(); - mitk::AffineTransform3D::OutputVectorType offsetDummy = affineTransformDummy->GetOffset(); - MITK_TEST_CONDITION(offsetDummy.GetVnlVector()==initialPosDummy.GetVnlVector(), "Testing Offset latest added tool"); - - mitk::AffineTransform3D::MatrixType::InternalMatrixType m1Latest= affineTransformDummy->GetMatrix().GetVnlMatrix(); - MITK_TEST_OUTPUT( << "\n latest initOrient="<GetVnlMatrix():\n "<< m1Latest); - - mitk::Surface::Pointer anotherSurface = mitk::Surface::New(); - myFilter->SetRepresentationObject(0, anotherSurface); - MITK_TEST_CONDITION(myFilter->GetRepresentationObject(0) == anotherSurface, "Overwriting BaseData index 0"); - - // test Set/GetTransformPosition() - myFilter->SetTransformPosition(0,true); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(0)==true,"test Set/GetTransformPosition(0,true)"); - myFilter->SetTransformPosition(1,true); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(1)==true,"test Set/GetTransformPosition(1,true)"); - myFilter->SetTransformPosition(2,true); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(2)==true,"test Set/GetTransformPosition(2,true)"); - myFilter->SetTransformPosition(3,true); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(3)==true,"test Set/GetTransformPosition(3,true)"); - - myFilter->SetTransformPosition(0,false); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(0)==false,"test Set/GetTransformPosition(0,false)"); - myFilter->SetTransformPosition(1,false); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(1)==false,"test Set/GetTransformPosition(1,false)"); - myFilter->SetTransformPosition(2,false); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(2)==false,"test Set/GetTransformPosition(2,false)"); - myFilter->SetTransformPosition(3,false); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(3)==false,"test Set/GetTransformPosition(3,false)"); - - // test Set/GetTransformOrientation() - myFilter->SetTransformOrientation(0,true); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(0)==true,"test Set/GetTransformOrientation(0,true)"); - myFilter->SetTransformOrientation(1,true); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(1)==true,"test Set/GetTransformOrientation(1,true)"); - myFilter->SetTransformOrientation(2,true); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(2)==true,"test Set/GetTransformOrientation(2,true)"); - myFilter->SetTransformOrientation(3,true); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(3)==true,"test Set/GetTransformOrientation(3,true)"); - - myFilter->SetTransformOrientation(0,false); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(0)==false,"test Set/GetTransformOrientation(0,false)"); - myFilter->SetTransformOrientation(1,false); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(1)==false,"test Set/GetTransformOrientation(1,false)"); - myFilter->SetTransformOrientation(2,false); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(2)==false,"test Set/GetTransformOrientation(2,false)"); - myFilter->SetTransformOrientation(3,false); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(3)==false,"test Set/GetTransformOrientation(3,false)"); - - // test the convenience methods to set/getTransformOrientation/Position - myFilter->TransformOrientationOn(0); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(0)==true,"test TransformOrientationOn()"); - myFilter->TransformOrientationOff(0); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(0)==false,"test TransformOrientationOff()"); - myFilter->TransformOrientationOff(1); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(1)==false,"test TransformOrientationOff()"); - myFilter->TransformOrientationOn(1); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(1)==true,"test TransformOrientationOn()"); - myFilter->TransformOrientationOn(2); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(2)==true,"test TransformOrientationOn()"); - myFilter->TransformOrientationOff(2); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(2)==false,"test TransformOrientationOff()"); - myFilter->TransformOrientationOn(3); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(3)==true,"test TransformOrientationOn()"); - myFilter->TransformOrientationOff(3); - MITK_TEST_CONDITION(myFilter->GetTransformOrientation(3)==false,"test TransformOrientationOff()"); - - myFilter->TransformPositionOn(0); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(0)==true,"test TransformPositionOn()"); - myFilter->TransformPositionOff(0); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(0)==false,"test TransformPositionOff()"); - myFilter->TransformPositionOff(1); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(1)==false,"test TransformPositionOff()"); - myFilter->TransformPositionOn(1); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(1)==true,"test TransformPositionOn()"); - myFilter->TransformPositionOn(2); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(2)==true,"test TransformPositionOn()"); - myFilter->TransformPositionOff(2); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(2)==false,"test TransformPositionOff()"); - myFilter->TransformPositionOn(3); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(3)==true,"test TransformPositionOn()"); - myFilter->TransformPositionOff(3); - MITK_TEST_CONDITION(myFilter->GetTransformPosition(3)==false,"test TransformPositionOff()"); - // update position and orientation - mitk::NavigationData::PositionType updatedPos1, updatedPos2, zero; - mitk::FillVector3D(updatedPos1, 3.2, 1.5, 2.8); - mitk::FillVector3D(updatedPos2, 4.3, 5.2, 6.0); - mitk::FillVector3D(zero, 0.0, 0.0, 0.0); - mitk::NavigationData::OrientationType updatedOri1(0.7, 0.5, 0.1, 0.4); - mitk::NavigationData::OrientationType updatedOri2(0.2, 0.7, 0.6, 0.1); - nd1->SetPosition(updatedPos1); - nd1->SetOrientation(updatedOri1); - nd2->SetPosition(updatedPos2); - nd2->SetOrientation(updatedOri2); - myFilter->SetRepresentationObject(0,mitkToolData1); - myFilter->SetRepresentationObject(1,mitkToolData2); - myFilter->TransformPositionOn(0); - myFilter->TransformOrientationOff(0); - myFilter->TransformPositionOff(1); - myFilter->TransformOrientationOn(1); - myFilter->Update(); - - // test positions and orientations - mitk::AffineTransform3D::Pointer updatedAffineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); - mitk::AffineTransform3D::OutputVectorType updatedOffset1 = updatedAffineTransform1->GetOffset(); - MITK_TEST_CONDITION(mitk::Equal(updatedOffset1.GetVnlVector(),updatedPos1.GetVnlVector()), "Testing updated position 1"); - mitk::AffineTransform3D::Pointer updatedAffineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); - mitk::AffineTransform3D::OutputVectorType updatedOffset2 = updatedAffineTransform2->GetOffset(); - MITK_TEST_CONDITION(mitk::Equal(updatedOffset2.GetVnlVector(),zero.GetVnlVector()), "Testing updated position 2"); - - mitk::AffineTransform3D::Pointer identityTransform = mitk::AffineTransform3D::New(); - identityTransform->SetIdentity(); - mitk::AffineTransform3D::MatrixType identityMatrix = identityTransform->GetMatrix(); - mitk::AffineTransform3D::MatrixType uM1 = updatedAffineTransform1->GetMatrix(); - MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(uM1,identityMatrix), "Testing updated orientation 1"); - mitk::AffineTransform3D::MatrixType::InternalMatrixType uM2 = updatedAffineTransform2->GetMatrix().GetVnlMatrix(); - MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(uM2,updatedOri2.rotation_matrix_transpose().transpose()), "Testing updated orientation 2"); - - // Test that the second RepresentationObject is updated properly even when - // the first RepresentationObject is invalid - nd2->Modified(); - myFilter->SetRepresentationObject(0, NULL); - mitkToolData2->GetGeometry()->SetIdentity(); - myFilter->Update(); - MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(mitkToolData2->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix(), - updatedOri2.rotation_matrix_transpose().transpose()), - "Test that the second repr object is updated correctly when the first repr object is invalid"); - - // always end with this! - MITK_TEST_END(); -} + mitk::ScalarType initialErrorDummy; + bool initialValidDummy; + mitk::NavigationData::Pointer ndDummy ; + + mitk::NavigationData* output; + + mitk::AffineTransform3D::Pointer affineTransform1; + mitk::AffineTransform3D::OutputVectorType offset1; + + mitk::AffineTransform3D::Pointer affineTransform2; + mitk::AffineTransform3D::OutputVectorType offset2; + mitk::AffineTransform3D::MatrixType::InternalMatrixType m1; + mitk::AffineTransform3D::MatrixType::InternalMatrixType m2; + +public: + + // Set up for variables + void setUp() + { + // -------------- Setup for Filter --------------------------- + + /* create helper objects: navigation data with position as origin, zero quaternion, zero error and data valid */ + myFilter = mitk::NavigationDataObjectVisualizationFilter::New(); + mitk::FillVector3D(initialPos1, 1.1, 2.2, 3.3); + mitk::FillVector3D(initialPos2, 5.0, 6.0, 7.0); + mitk::FillVector4D(initialOri1, 0.1, 0.2, 0.3, 0.4); + mitk::FillVector4D(initialOri2,0.5, 0.6, 0.7, 0.8); + initialError1=0.0; + initialError2=5.0; + initialValid1 = true; + initialValid2 = true; + + //Set Navigation Data + nd1 = mitk::NavigationData::New(); + nd1->SetPosition(initialPos1); + nd1->SetOrientation(initialOri1); + nd1->SetPositionAccuracy(initialError1); + nd1->SetDataValid(initialValid1); + + nd2 = mitk::NavigationData::New(); + nd2->SetPosition(initialPos2); + nd2->SetOrientation(initialOri2); + nd2->SetPositionAccuracy(initialError2); + nd2->SetDataValid(initialValid2); + + //Set Input + myFilter->SetInput(nd1); + myFilter->SetInput(1, nd2); + output = myFilter->GetOutput(); + + // -------------------------- Setup for TestData ---------------------- + + // Test setting BaseData + mitkToolData1 = mitk::Surface::New(); + mitkToolData2 = mitk::Surface::New(); + + //dummy for test; will not be set but used to test find + mitkToolDataDummy = mitk::Surface::New(); + //and the Dummy NavigationData for this + mitk::FillVector3D(initialPosDummy, 8.8, 9.9, 10.10); + mitk::FillVector4D(initialOriDummy,1.1, 2.2, 3.3, 4.4); + initialErrorDummy=10.0; + initialValidDummy=true; + ndDummy = mitk::NavigationData::New(); + ndDummy->SetPosition(initialPosDummy); + ndDummy->SetOrientation(initialOriDummy); + ndDummy->SetPositionAccuracy(initialErrorDummy); + ndDummy->SetDataValid(initialValidDummy); + //now we have ndDummy and mitkToolDataDummy to test with + } + + void tearDown() + { + } + + // Test functions + + void TestInitialize(){ + // first test: did this work? + CPPUNIT_ASSERT_MESSAGE("Testing instantiation", myFilter.IsNotNull()); + } + + void TestInput(){ + //testing the input + CPPUNIT_ASSERT_MESSAGE("Testing Set-/GetInput() input 1 without index",myFilter->GetInput() == nd1); + CPPUNIT_ASSERT_MESSAGE("Testing Set-/GetInput() input 1", myFilter->GetInput(0) == nd1); + CPPUNIT_ASSERT_MESSAGE( "Testing Set-/GetInput() input 2", myFilter->GetInput(1) == nd2); + CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations()", myFilter->GetNumberOfToolRepresentations() == 0); + } + + void TestOutput(){ + //testing getting the output + CPPUNIT_ASSERT_MESSAGE("Testing GetOutput()", output != NULL); + CPPUNIT_ASSERT_MESSAGE("Testing GetOutput() == GetOutput()", output == myFilter->GetOutput()); + CPPUNIT_ASSERT_MESSAGE("Testing GetOutput() != GetOutput(1)", output != myFilter->GetOutput(1)); + } + + void TestRepresentationObjects(){ + //setting nodes + myFilter->SetRepresentationObject(0, mitkToolData1); + CPPUNIT_ASSERT_MESSAGE( "Testing SetRepresentationObject()/GetRepresentationObject() node 1", myFilter->GetRepresentationObject(0) == mitkToolData1); + CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations() after adding first tool", myFilter->GetNumberOfToolRepresentations() == 1); + + myFilter->SetRepresentationObject(1, mitkToolData2); + CPPUNIT_ASSERT_MESSAGE( "Testing SetRepresentationObject() node 2", myFilter->GetRepresentationObject(1) == mitkToolData2); + CPPUNIT_ASSERT_MESSAGE( "Testing GetNumberOfToolRepresentations() after adding second tool", myFilter->GetNumberOfToolRepresentations() == 2); + //getting nodes + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() node 1", myFilter->GetRepresentationObject(0) == mitkToolData1); + CPPUNIT_ASSERT_MESSAGE( "Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(0) != mitkToolDataDummy); + CPPUNIT_ASSERT_MESSAGE( "Testing GetRepresentationObject() node 2", myFilter->GetRepresentationObject(1) == mitkToolData2); + CPPUNIT_ASSERT_MESSAGE( "Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(1) != mitkToolDataDummy); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() with out of range parameter", myFilter->GetRepresentationObject(111) == NULL); + } + + void TestTransforms(){ + myFilter->SetRepresentationObject(0, mitkToolData1); + myFilter->SetRepresentationObject(1, mitkToolData2); + //Process + myFilter->Update(); + + affineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); + offset1 = affineTransform1->GetOffset(); + affineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); + offset2 = affineTransform2->GetOffset(); + + m1 = affineTransform1->GetMatrix().GetVnlMatrix(); + m2 = affineTransform2->GetMatrix().GetVnlMatrix(); + + //now check it there are data connected to the nodes with the according orientation and offsets + CPPUNIT_ASSERT_MESSAGE("Testing Offset position 1", offset1.GetVnlVector()==initialPos1.GetVnlVector()); + CPPUNIT_ASSERT_MESSAGE("Testing Offset position 2", offset2.GetVnlVector()==initialPos2.GetVnlVector()); + + MITK_TEST_OUTPUT( << "\n initOrient1="<GetVnlMatrix():\n "<< m1); + MITK_TEST_OUTPUT( << "\n initOrient2=" << initialOri2 << " affineTransform2->GetVnlMatrix():\n " << m2); + } + + void TestMessWithRepresentationObjects(){ + myFilter->SetRepresentationObject(0, mitkToolData1); + myFilter->SetRepresentationObject(1, mitkToolData2); + //Process + myFilter->Update(); + + affineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); + offset1 = affineTransform1->GetOffset(); + affineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); + offset2 = affineTransform2->GetOffset(); + + m1 = affineTransform1->GetMatrix().GetVnlMatrix(); + m2 = affineTransform2->GetMatrix().GetVnlMatrix(); + + //messing with SetRepresentationObject + //setting nodes + myFilter->SetRepresentationObject(0, mitkToolData2); + CPPUNIT_ASSERT_MESSAGE("Twisting mitkToolData by using SetRepresentationObject() NavigationData 1 with ToolData 2", myFilter->GetRepresentationObject(0) == mitkToolData2); + CPPUNIT_ASSERT_MESSAGE( "Testing GetNumberOfToolRepresentations() == 1", myFilter->GetNumberOfToolRepresentations() == 2); + + myFilter->SetRepresentationObject(1, mitkToolData1); + CPPUNIT_ASSERT_MESSAGE("Twisting mitkToolData by using SetRepresentationObject() NavigationData 2 with ToolData 1", myFilter->GetRepresentationObject(1) == mitkToolData1); + CPPUNIT_ASSERT_MESSAGE( "Testing GetNumberOfToolRepresentations() == 2", myFilter->GetNumberOfToolRepresentations() == 2); + + //getting nodes + CPPUNIT_ASSERT_MESSAGE("Testing switched BaseData of NavigationData 1 ", myFilter->GetRepresentationObject(0) == mitkToolData2); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(0) != mitkToolDataDummy); + CPPUNIT_ASSERT_MESSAGE("Testing switched BaseData NavigationData 2", myFilter->GetRepresentationObject(1) == mitkToolData1); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(1) != mitkToolDataDummy); + + //processing update through pipeline + myFilter->Update(); + + //now check it there are data connected to the nodes with the according orientation and offsets + mitk::AffineTransform3D::Pointer affineTransform1Second = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); + CPPUNIT_ASSERT_MESSAGE( "Testing affineTransform1 after second update", affineTransform1 == affineTransform1Second); + mitk::AffineTransform3D::OutputVectorType offset1Second = affineTransform1->GetOffset(); + CPPUNIT_ASSERT_MESSAGE( "Testing offset1 after second update", offset1 == offset1Second); + CPPUNIT_ASSERT_MESSAGE("Testing offset1 equals first update", offset1Second.GetVnlVector()==offset1.GetVnlVector()); + + mitk::AffineTransform3D::Pointer affineTransform2Second = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); + CPPUNIT_ASSERT_MESSAGE("Testing affineTransform2 after second update", affineTransform2 == affineTransform2Second); + mitk::AffineTransform3D::OutputVectorType offset2Second = affineTransform2->GetOffset(); + CPPUNIT_ASSERT_MESSAGE("Testing offset2 after second update", offset2 == offset2Second); + CPPUNIT_ASSERT_MESSAGE("Testing offset2 equals first update", offset2Second.GetVnlVector()==offset2.GetVnlVector()); + + mitk::AffineTransform3D::MatrixType::InternalMatrixType m1Second= affineTransform1Second->GetMatrix().GetVnlMatrix(); + MITK_TEST_OUTPUT( <<"\n after second update initOrient1="<GetVnlMatrix():\n "<< m1Second); + + mitk::AffineTransform3D::MatrixType::InternalMatrixType m2Second= affineTransform2Second->GetMatrix().GetVnlMatrix(); + MITK_TEST_OUTPUT( << "\n after second update initOrient2="<GetVnlMatrix():\n "<< m2Second); + } + + void TestThirdInput(){ + myFilter->SetRepresentationObject(0, mitkToolData1); + myFilter->SetRepresentationObject(1, mitkToolData2); + //Process + myFilter->Update(); + + //testing adding a third input + myFilter->SetInput(2,ndDummy); + CPPUNIT_ASSERT_MESSAGE("Adding new input and testing GetNumberOfInputs == 3", myFilter->GetNumberOfInputs() == 3); + CPPUNIT_ASSERT_MESSAGE("testing GetNumberOfOutputs == 3", myFilter->GetNumberOfOutputs() == 3); + CPPUNIT_ASSERT_MESSAGE("Testing Input == newly added input", myFilter->GetInput(2) == ndDummy); + CPPUNIT_ASSERT_MESSAGE("Testing GetOutput(2) != NULL", myFilter->GetOutput(2) != NULL); + CPPUNIT_ASSERT_MESSAGE( "Testing GetOutput(2) != GetOutput(1)", myFilter->GetOutput(2) != myFilter->GetOutput(1)); + myFilter->SetRepresentationObject(2, mitkToolDataDummy); + CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations() after adding latest tool", myFilter->GetNumberOfToolRepresentations() == 3); + CPPUNIT_ASSERT_MESSAGE("Testing Set-/GetRepresentationObject() equals was set", myFilter->GetRepresentationObject(2) == mitkToolDataDummy); + + //last time processing update through pipeline + myFilter->Update(); + + //now check for the new values + mitk::AffineTransform3D::Pointer affineTransformDummy = mitkToolDataDummy->GetGeometry()->GetIndexToWorldTransform(); + mitk::AffineTransform3D::OutputVectorType offsetDummy = affineTransformDummy->GetOffset(); + CPPUNIT_ASSERT_MESSAGE("Testing Offset latest added tool", offsetDummy.GetVnlVector()==initialPosDummy.GetVnlVector()); + + mitk::AffineTransform3D::MatrixType::InternalMatrixType m1Latest= affineTransformDummy->GetMatrix().GetVnlMatrix(); + MITK_TEST_OUTPUT( << "\n latest initOrient="<GetVnlMatrix():\n "<< m1Latest); + + mitk::Surface::Pointer anotherSurface = mitk::Surface::New(); + myFilter->SetRepresentationObject(0, anotherSurface); + CPPUNIT_ASSERT_MESSAGE("Overwriting BaseData index 0", myFilter->GetRepresentationObject(0) == anotherSurface); + } + + void TestSetTransformPosition(){ + // test Set/GetTransformPosition() + myFilter->SetTransformPosition(0,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(0,true)", myFilter->GetTransformPosition(0)==true); + myFilter->SetTransformPosition(1,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(1,true)", myFilter->GetTransformPosition(1)==true); + myFilter->SetTransformPosition(2,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(2,true)", myFilter->GetTransformPosition(2)==true); + myFilter->SetTransformPosition(3,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(3,true)", myFilter->GetTransformPosition(3)==true); + + myFilter->SetTransformPosition(0,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(0,false)", myFilter->GetTransformPosition(0)==false); + myFilter->SetTransformPosition(1,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(1,false)", myFilter->GetTransformPosition(1)==false); + myFilter->SetTransformPosition(2,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(2,false)", myFilter->GetTransformPosition(2)==false); + myFilter->SetTransformPosition(3,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(3,false)", myFilter->GetTransformPosition(3)==false); + } + + void TestSetTransformOrientation(){ + // test Set/GetTransformOrientation() + myFilter->SetTransformOrientation(0,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(0,true)", myFilter->GetTransformOrientation(0)==true); + myFilter->SetTransformOrientation(1,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(1,true)", myFilter->GetTransformOrientation(1)==true); + myFilter->SetTransformOrientation(2,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(2,true)", myFilter->GetTransformOrientation(2)==true); + myFilter->SetTransformOrientation(3,true); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(3,true)", myFilter->GetTransformOrientation(3)==true); + + myFilter->SetTransformOrientation(0,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(0,false)", myFilter->GetTransformOrientation(0)==false); + myFilter->SetTransformOrientation(1,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(1,false)", myFilter->GetTransformOrientation(1)==false); + myFilter->SetTransformOrientation(2,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(2,false)", myFilter->GetTransformOrientation(2)==false); + myFilter->SetTransformOrientation(3,false); + CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(3,false)", myFilter->GetTransformOrientation(3)==false); + } + + void TestConvenienceSetTransformOrientation(){ + // test the convenience methods to set/getTransformOrientation/Position + myFilter->TransformOrientationOn(0); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(0)==true); + myFilter->TransformOrientationOff(0); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(0)==false); + myFilter->TransformOrientationOff(1); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(1)==false); + myFilter->TransformOrientationOn(1); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(1)==true); + myFilter->TransformOrientationOn(2); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(2)==true); + myFilter->TransformOrientationOff(2); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(2)==false); + myFilter->TransformOrientationOn(3); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(3)==true); + myFilter->TransformOrientationOff(3); + CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(3)==false); + + myFilter->TransformPositionOn(0); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(0)==true); + myFilter->TransformPositionOff(0); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(0)==false); + myFilter->TransformPositionOff(1); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(1)==false); + myFilter->TransformPositionOn(1); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(1)==true); + myFilter->TransformPositionOn(2); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(2)==true); + myFilter->TransformPositionOff(2); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(2)==false); + myFilter->TransformPositionOn(3); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(3)==true); + myFilter->TransformPositionOff(3); + CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(3)==false); + } + + void TestUpdateOrientation(){ + // update position and orientation + mitk::NavigationData::PositionType updatedPos1, updatedPos2, zero; + mitk::FillVector3D(updatedPos1, 3.2, 1.5, 2.8); + mitk::FillVector3D(updatedPos2, 4.3, 5.2, 6.0); + mitk::FillVector3D(zero, 0.0, 0.0, 0.0); + mitk::NavigationData::OrientationType updatedOri1(0.7, 0.5, 0.1, 0.4); + mitk::NavigationData::OrientationType updatedOri2(0.2, 0.7, 0.6, 0.1); + + updatedOri1.normalize(); + updatedOri2.normalize(); + + nd1->SetPosition(updatedPos1); + nd1->SetOrientation(updatedOri1); + + nd2->SetPosition(updatedPos2); + nd2->SetOrientation(updatedOri2); + + myFilter->SetRepresentationObject(0,mitkToolData1); + myFilter->SetRepresentationObject(1,mitkToolData2); + + myFilter->TransformPositionOn(0); + myFilter->TransformOrientationOff(0); + myFilter->TransformPositionOff(1); + myFilter->TransformOrientationOn(1); + + myFilter->Update(); + + // test positions and orientations + mitk::AffineTransform3D::Pointer updatedAffineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); + mitk::AffineTransform3D::OutputVectorType updatedOffset1 = updatedAffineTransform1->GetOffset(); + CPPUNIT_ASSERT_MESSAGE("Testing updated position 1", mitk::Equal(updatedOffset1.GetVnlVector(),updatedPos1.GetVnlVector())); + + mitk::AffineTransform3D::Pointer updatedAffineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); + mitk::AffineTransform3D::OutputVectorType updatedOffset2 = updatedAffineTransform2->GetOffset(); + CPPUNIT_ASSERT_MESSAGE( "Testing updated position 2", mitk::Equal(updatedOffset2.GetVnlVector(),zero.GetVnlVector())); + + mitk::AffineTransform3D::Pointer identityTransform = mitk::AffineTransform3D::New(); + identityTransform->SetIdentity(); + mitk::AffineTransform3D::MatrixType identityMatrix = identityTransform->GetMatrix(); + mitk::AffineTransform3D::MatrixType uM1 = updatedAffineTransform1->GetMatrix(); + + CPPUNIT_ASSERT_MESSAGE( "Testing updated orientation 1", mitk::MatrixEqualElementWise(uM1, identityMatrix)); + + mitk::AffineTransform3D::MatrixType::InternalMatrixType uM2 = updatedAffineTransform2->GetMatrix().GetVnlMatrix(); + mitk::AffineTransform3D::MatrixType::InternalMatrixType updatedOriTransform2 = updatedOri2.rotation_matrix_transpose().transpose(); + + CPPUNIT_ASSERT_MESSAGE("Testing updated orientation 2", mitk::MatrixEqualElementWise(uM2,updatedOriTransform2)); + + // Test that the second RepresentationObject is updated properly even when + // the first RepresentationObject is invalid + nd2->Modified(); + myFilter->SetRepresentationObject(0, NULL); + mitkToolData2->GetGeometry()->SetIdentity(); + myFilter->Update(); + CPPUNIT_ASSERT_MESSAGE( "Test that the second repr object is updated correctly when the first repr object is invalid", + mitk::MatrixEqualElementWise(mitkToolData2->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix(), + updatedOri2.rotation_matrix_transpose().transpose())); + } +};//end class mitkNavigationDataObjectVisualizationFilterTestSuite + +MITK_TEST_SUITE_REGISTRATION(mitkNavigationDataObjectVisualizationFilter)