00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkSliceNavigationController.h"
00019 #include "mitkPlaneGeometry.h"
00020 #include "mitkSlicedGeometry3D.h"
00021 #include "mitkTimeSlicedGeometry.h"
00022
00023 #include <vnl/vnl_quaternion.h>
00024 #include <vnl/vnl_quaternion.txx>
00025
00026 #include <fstream>
00027
00028 bool operator==(const mitk::Geometry3D & left, const mitk::Geometry3D & right)
00029 {
00030 mitk::BoundingBox::BoundsArrayType leftbounds, rightbounds;
00031 leftbounds =left.GetBounds();
00032 rightbounds=right.GetBounds();
00033
00034 unsigned int i;
00035 for(i=0;i<6;++i)
00036 if(mitk::Equal(leftbounds[i],rightbounds[i])==false) return false;
00037
00038 const mitk::Geometry3D::TransformType::MatrixType & leftmatrix = left.GetIndexToWorldTransform()->GetMatrix();
00039 const mitk::Geometry3D::TransformType::MatrixType & rightmatrix = right.GetIndexToWorldTransform()->GetMatrix();
00040
00041 unsigned int j;
00042 for(i=0;i<3;++i)
00043 {
00044 const mitk::Geometry3D::TransformType::MatrixType::ValueType* leftvector = leftmatrix[i];
00045 const mitk::Geometry3D::TransformType::MatrixType::ValueType* rightvector = rightmatrix[i];
00046 for(j=0;j<3;++j)
00047 if(mitk::Equal(leftvector[i],rightvector[i])==false) return false;
00048 }
00049
00050 const mitk::Geometry3D::TransformType::OffsetType & leftoffset = left.GetIndexToWorldTransform()->GetOffset();
00051 const mitk::Geometry3D::TransformType::OffsetType & rightoffset = right.GetIndexToWorldTransform()->GetOffset();
00052 for(i=0;i<3;++i)
00053 if(mitk::Equal(leftoffset[i],rightoffset[i])==false) return false;
00054
00055 return true;
00056 }
00057
00058 int compareGeometry(const mitk::Geometry3D & geometry,
00059 const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& numSlices,
00060 const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::ScalarType& thicknessInMM,
00061 const mitk::Point3D& cornerpoint0, const mitk::Vector3D& right, const mitk::Vector3D& bottom, const mitk::Vector3D& normal)
00062 {
00063 std::cout << "Testing width, height and thickness (in units): ";
00064 if((mitk::Equal(geometry.GetExtent(0),width)==false) ||
00065 (mitk::Equal(geometry.GetExtent(1),height)==false) ||
00066 (mitk::Equal(geometry.GetExtent(2),numSlices)==false)
00067 )
00068 {
00069 std::cout<<"[FAILED]"<<std::endl;
00070 return EXIT_FAILURE;
00071 }
00072 std::cout<<"[PASSED]"<<std::endl;
00073
00074 std::cout << "Testing width, height and thickness (in mm): ";
00075 if((mitk::Equal(geometry.GetExtentInMM(0),widthInMM)==false) ||
00076 (mitk::Equal(geometry.GetExtentInMM(1),heightInMM)==false) ||
00077 (mitk::Equal(geometry.GetExtentInMM(2),thicknessInMM)==false)
00078 )
00079 {
00080 std::cout<<"[FAILED]"<<std::endl;
00081 return EXIT_FAILURE;
00082 }
00083 std::cout<<"[PASSED]"<<std::endl;
00084
00085 std::cout << "Testing GetAxisVector(): ";
00086 std::cout << "dir=0 ";
00087 mitk::Vector3D dv;
00088 dv=right; dv.Normalize(); dv*=widthInMM;
00089 if((mitk::Equal(geometry.GetAxisVector(0), dv)==false))
00090 {
00091 std::cout<<"[FAILED]"<<std::endl;
00092 return EXIT_FAILURE;
00093 }
00094 std::cout<<"[PASSED]";
00095 std::cout << ", dir=1 ";
00096 dv=bottom; dv.Normalize(); dv*=heightInMM;
00097 if((mitk::Equal(geometry.GetAxisVector(1), dv)==false))
00098 {
00099 std::cout<<"[FAILED]"<<std::endl;
00100 return EXIT_FAILURE;
00101 }
00102 std::cout<<"[PASSED]";
00103 std::cout << ", dir=2 ";
00104 dv=normal; dv.Normalize(); dv*=thicknessInMM;
00105 if((mitk::Equal(geometry.GetAxisVector(2), dv)==false))
00106 {
00107 std::cout<<"[FAILED]"<<std::endl;
00108 return EXIT_FAILURE;
00109 }
00110 std::cout<<"[PASSED]"<<std::endl;
00111
00112 std::cout << "Testing offset: ";
00113 if((mitk::Equal(geometry.GetCornerPoint(0),cornerpoint0)==false))
00114 {
00115 std::cout<<"[FAILED]"<<std::endl;
00116 return EXIT_FAILURE;
00117 }
00118 std::cout<<"[PASSED]"<<std::endl;
00119 return EXIT_SUCCESS;
00120 }
00121
00122 int testGeometry(const mitk::Geometry3D * geometry,
00123 const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& numSlices,
00124 const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::ScalarType& thicknessInMM,
00125 const mitk::Point3D& cornerpoint0, const mitk::Vector3D& right, const mitk::Vector3D& bottom, const mitk::Vector3D& normal)
00126 {
00127 int result=EXIT_FAILURE;
00128
00129 std::cout << "Comparing GetCornerPoint(0) of Geometry3D with provided cornerpoint0: ";
00130 if(mitk::Equal(geometry->GetCornerPoint(0), cornerpoint0)==false)
00131 {
00132 std::cout<<"[FAILED]"<<std::endl;
00133 return EXIT_FAILURE;
00134 }
00135 std::cout<<"[PASSED]"<<std::endl;
00136
00137 std::cout << "Creating and initializing a SliceNavigationController with the Geometry3D: ";
00138 mitk::SliceNavigationController::Pointer sliceCtrl = mitk::SliceNavigationController::New();
00139 sliceCtrl->SetInputWorldGeometry(geometry);
00140 std::cout<<"[PASSED]"<<std::endl;
00141
00142 std::cout << "Testing SetViewDirection(mitk::SliceNavigationController::Transversal): ";
00143 sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Transversal);
00144 std::cout<<"[PASSED]"<<std::endl;
00145
00146 std::cout << "Testing Update(): ";
00147 sliceCtrl->Update();
00148 std::cout<<"[PASSED]"<<std::endl;
00149
00150 std::cout << "Testing result of CreatedWorldGeometry(): ";
00151 mitk::Point3D transversalcornerpoint0;
00152 transversalcornerpoint0 = cornerpoint0+bottom+normal*(numSlices-1+0.5);
00153 result = compareGeometry(*sliceCtrl->GetCreatedWorldGeometry(), width, height, numSlices, widthInMM, heightInMM, thicknessInMM*numSlices, transversalcornerpoint0, right, bottom*(-1.0), normal*(-1.0));
00154 if(result!=EXIT_SUCCESS)
00155 {
00156 std::cout<<"[FAILED]"<<std::endl;
00157 return result;
00158 }
00159 std::cout<<"[PASSED]"<<std::endl;
00160
00161
00162
00163 std::cout << "Testing SetViewDirection(mitk::SliceNavigationController::Frontal): ";
00164 sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Frontal);
00165 std::cout<<"[PASSED]"<<std::endl;
00166
00167 std::cout << "Testing Update(): ";
00168 sliceCtrl->Update();
00169 std::cout<<"[PASSED]"<<std::endl;
00170
00171 std::cout << "Testing result of CreatedWorldGeometry(): ";
00172 mitk::Point3D frontalcornerpoint0;
00173 frontalcornerpoint0 = cornerpoint0+geometry->GetAxisVector(1)*(+0.5/geometry->GetExtent(1));
00174 result = compareGeometry(*sliceCtrl->GetCreatedWorldGeometry(), width, numSlices, height, widthInMM, thicknessInMM*numSlices, heightInMM, frontalcornerpoint0, right, normal, bottom);
00175 if(result!=EXIT_SUCCESS)
00176 {
00177 std::cout<<"[FAILED]"<<std::endl;
00178 return result;
00179 }
00180 std::cout<<"[PASSED]"<<std::endl;
00181
00182
00183
00184 std::cout << "Testing SetViewDirection(mitk::SliceNavigationController::Sagittal): ";
00185 sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Sagittal);
00186 std::cout<<"[PASSED]"<<std::endl;
00187
00188 std::cout << "Testing Update(): "<<std::endl;
00189 sliceCtrl->Update();
00190 std::cout<<"[PASSED]"<<std::endl;
00191
00192 std::cout << "Testing result of CreatedWorldGeometry(): ";
00193 mitk::Point3D sagittalcornerpoint0;
00194 sagittalcornerpoint0 = cornerpoint0+geometry->GetAxisVector(0)*(+0.5/geometry->GetExtent(0));
00195 result = compareGeometry(*sliceCtrl->GetCreatedWorldGeometry(), height, numSlices, width, heightInMM, thicknessInMM*numSlices, widthInMM, sagittalcornerpoint0, bottom, normal, right);
00196 if(result!=EXIT_SUCCESS)
00197 {
00198 std::cout<<"[FAILED]"<<std::endl;
00199 return result;
00200 }
00201 std::cout<<"[PASSED]"<<std::endl;
00202
00203 return EXIT_SUCCESS;
00204 }
00205
00206 int mitkSliceNavigationControllerTest(int , char* [])
00207 {
00208 int result=EXIT_FAILURE;
00209
00210 std::cout << "Creating and initializing a PlaneGeometry: ";
00211 mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
00212
00213 mitk::Point3D origin;
00214 mitk::Vector3D right, bottom, normal;
00215 mitk::ScalarType width, height;
00216 mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
00217
00218 width = 100; widthInMM = width;
00219 height = 200; heightInMM = height;
00220 thicknessInMM = 1.5;
00221
00222 mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
00223 mitk::FillVector3D(right, widthInMM, 0, 0);
00224 mitk::FillVector3D(bottom, 0, heightInMM, 0);
00225 mitk::FillVector3D(normal, 0, 0, thicknessInMM);
00226
00227 mitk::Vector3D spacing;
00228 normal.Normalize(); normal *= thicknessInMM;
00229 mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
00230 planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector(), &spacing);
00231 planegeometry->SetOrigin(origin);
00232 std::cout<<"[PASSED]"<<std::endl;
00233
00234 std::cout << "Creating and initializing a SlicedGeometry3D with the PlaneGeometry: ";
00235 mitk::SlicedGeometry3D::Pointer slicedgeometry = mitk::SlicedGeometry3D::New();
00236 unsigned int numSlices = 5;
00237 slicedgeometry->InitializeEvenlySpaced(planegeometry, thicknessInMM, numSlices, false);
00238 std::cout<<"[PASSED]"<<std::endl;
00239
00240 std::cout << "Creating a Geometry3D with the same extent as the SlicedGeometry3D: ";
00241 mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New();
00242 geometry->SetBounds(slicedgeometry->GetBounds());
00243 geometry->SetIndexToWorldTransform(slicedgeometry->GetIndexToWorldTransform());
00244 std::cout<<"[PASSED]"<<std::endl;
00245
00246 mitk::Point3D cornerpoint0;
00247 cornerpoint0 = geometry->GetCornerPoint(0);
00248
00249
00250 result=testGeometry(geometry, width, height, numSlices, widthInMM, heightInMM, thicknessInMM, cornerpoint0, right, bottom, normal);
00251 if(result!=EXIT_SUCCESS)
00252 return result;
00253
00254
00255
00256 mitk::BoundingBox::BoundsArrayType bounds = geometry->GetBounds();
00257 mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New();
00258 transform->SetMatrix(geometry->GetIndexToWorldTransform()->GetMatrix());
00259 mitk::BoundingBox::Pointer boundingbox = geometry->CalculateBoundingBoxRelativeToTransform(transform);
00260 geometry->SetBounds(boundingbox->GetBounds());
00261 cornerpoint0 = geometry->GetCornerPoint(0);
00262
00263 result=testGeometry(geometry, width, height, numSlices, widthInMM, heightInMM, thicknessInMM, cornerpoint0, right, bottom, normal);
00264 if(result!=EXIT_SUCCESS)
00265 return result;
00266
00267
00268
00269 std::cout << "Changing the IndexToWorldTransform of the geometry to a rotated version by SetIndexToWorldTransform() (keep cornerpoint0): ";
00270 transform = mitk::AffineTransform3D::New();
00271 mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
00272 vnlmatrix = planegeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
00273 mitk::VnlVector axis(3);
00274 mitk::FillVector3D(axis, 1.0, 1.0, 1.0); axis.normalize();
00275 vnl_quaternion<mitk::ScalarType> rotation(axis, 0.223);
00276 vnlmatrix = rotation.rotation_matrix_transpose()*vnlmatrix;
00277 mitk::Matrix3D matrix;
00278 matrix = vnlmatrix;
00279 transform->SetMatrix(matrix);
00280 transform->SetOffset(cornerpoint0.GetVectorFromOrigin());
00281
00282 right.Set_vnl_vector( rotation.rotation_matrix_transpose()*right.Get_vnl_vector() );
00283 bottom.Set_vnl_vector(rotation.rotation_matrix_transpose()*bottom.Get_vnl_vector());
00284 normal.Set_vnl_vector(rotation.rotation_matrix_transpose()*normal.Get_vnl_vector());
00285 geometry->SetIndexToWorldTransform(transform);
00286 std::cout<<"[PASSED]"<<std::endl;
00287
00288 cornerpoint0 = geometry->GetCornerPoint(0);
00289
00290 result = testGeometry(geometry, width, height, numSlices, widthInMM, heightInMM, thicknessInMM, cornerpoint0, right, bottom, normal);
00291 if(result!=EXIT_SUCCESS)
00292 return result;
00293
00294
00295
00296
00297
00298 std::cout<<"[TEST DONE]"<<std::endl;
00299 return EXIT_SUCCESS;
00300 }