00001 /*========================================================================= 00002 00003 Program: Medical Imaging & Interaction Toolkit 00004 Language: C++ 00005 Date: $Date$ 00006 Version: $Revision$ 00007 00008 Copyright (c) German Cancer Research Center, Division of Medical and 00009 Biological Informatics. All rights reserved. 00010 See MITKCopyright.txt or https://www.mitk.org/copyright.html for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 00018 00019 #ifndef GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD 00020 #define GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD 00021 00022 #include "mitkCommon.h" 00023 #include "mitkVector.h" 00024 #include "mitkOperationActor.h" 00025 00026 #include <itkIndex.h> 00027 #include <itkBoundingBox.h> 00028 #include <itkQuaternionRigidTransform.h> 00029 #include <itkAffineGeometryFrame.h> 00030 00031 class vtkLinearTransform; 00032 class vtkMatrixToLinearTransform; 00033 class vtkMatrix4x4; 00034 00035 namespace mitk { 00036 00037 //##Documentation 00038 //## @brief Standard 3D-BoundingBox typedef 00039 //## 00040 //## Standard 3D-BoundingBox typedef to get rid of template arguments (3D, type). 00041 typedef itk::BoundingBox<unsigned long, 3, ScalarType> BoundingBox; 00042 00043 //##Documentation 00044 //## @brief Standard typedef for time-bounds 00045 typedef itk::FixedArray<ScalarType,2> TimeBounds; 00046 typedef itk::FixedArray<ScalarType, 3> FixedArrayType; 00047 00048 typedef itk::AffineGeometryFrame<ScalarType, 3> AffineGeometryFrame3D; 00049 00050 //##Documentation 00051 //## @brief Describes the geometry of a data object 00052 //## 00053 //## At least, it can return the bounding box of the data object. 00054 //## 00055 //## The class holds 00056 //## \li a bounding box which is axes-parallel in intrinsic coordinates 00057 //## (often integer indices of pixels), to be accessed by 00058 //## GetBoundingBox() 00059 //## \li a transform to convert intrinsic coordinates into a 00060 //## world-coordinate system with coordinates in millimeters 00061 //## and milliseconds (all are floating point values), to 00062 //## be accessed by GetIndexToWorldTransform() 00063 //## \li a life span, i.e. a bounding box in time in ms (with 00064 //## start and end time), to be accessed by GetTimeBounds(). 00065 //## The default is minus infinity to plus infinity. 00066 //## 00067 //## Geometry3D and its sub-classes allow converting between 00068 //## intrinsic coordinates (called index or unit coordinates) 00069 //## and world-coordinates (called world or mm coordinates), 00070 //## e.g. WorldToIndex. 00071 //## In case you need integer index coordinates, provide an 00072 //## mitk::Index3D (or itk::Index) as target variable to 00073 //## WorldToIndex, otherwise you will get a continuous index 00074 //## (floating point values). 00075 //## 00076 //## An important sub-class is SlicedGeometry3D, which descibes 00077 //## data objects consisting of slices, e.g., objects of type Image. 00078 //## Conversions between world coordinates (in mm) and unit coordinates 00079 //## (e.g., pixels in the case of an Image) can be performed. 00080 //## 00081 //## For more information on related classes, see \ref Geometry. 00082 //## 00083 //## Geometry3D instances referring to an Image need a slightly 00084 //## different definition of corners, see SetImageGeometry. This 00085 //## is usualy automatically called by Image. 00086 //## 00087 //## Geometry3D have to be initialized in the method GenerateOutputInformation() 00088 //## of BaseProcess (or CopyInformation/ UpdateOutputInformation of BaseData, 00089 //## if possible, e.g., by analyzing pic tags in Image) subclasses. See also 00090 //## itk::ProcessObject::GenerateOutputInformation(), 00091 //## itk::DataObject::CopyInformation() and 00092 //## itk::DataObject::UpdateOutputInformation(). 00093 //## 00094 //## Rule: everything is in mm (ms) if not stated otherwise. 00095 //## @ingroup Geometry 00096 class MITK_CORE_EXPORT Geometry3D : public AffineGeometryFrame3D, public OperationActor 00097 { 00098 public: 00099 mitkClassMacro(Geometry3D, AffineGeometryFrame3D); 00100 00101 typedef itk::QuaternionRigidTransform< ScalarType > QuaternionTransformType; 00102 typedef QuaternionTransformType::VnlQuaternionType VnlQuaternionType; 00103 00105 itkNewMacro(Self); 00106 00107 // a bit of a misuse, but we want only doxygen to see the following: 00108 #ifdef DOXYGEN_SKIP 00109 //##Documentation 00110 //## @brief Get the transformation used to convert from index 00111 //## to world coordinates 00112 itkGetObjectMacro(IndexToWorldTransform, AffineTransform3D); 00113 #endif 00114 //## @brief Set the transformation used to convert from index 00115 //## to world coordinates 00116 virtual void SetIndexToWorldTransform(mitk::AffineTransform3D* transform); 00117 //##Documentation 00118 //## @brief Convenience method for setting the ITK transform 00119 //## (m_IndexToWorldTransform) via an vtkMatrix4x4 00120 //## \sa SetIndexToWorldTransform 00121 virtual void SetIndexToWorldTransformByVtkMatrix(vtkMatrix4x4* vtkmatrix); 00122 00123 #ifdef DOXYGEN_SKIP 00124 //##Documentation 00125 //## @brief Get bounding box (in index/unit coordinates) 00126 itkGetConstObjectMacro(BoundingBox, BoundingBoxType); 00127 //##Documentation 00128 //## @brief Get bounding box (in index/unit coordinates) as a BoundsArrayType 00129 const BoundsArrayType GetBounds() const 00130 { 00131 assert(m_BoundingBox.IsNotNull()); 00132 return m_BoundingBox->GetBounds(); 00133 } 00134 //##Documentation 00135 //## \brief Set the bounding box (in index/unit coordinates) 00136 //## 00137 //## Only possible via the BoundsArray to make clear that a 00138 //## copy of the bounding-box is stored, not a reference to it. 00139 virtual void SetBounds(const BoundsArrayType& bounds); 00140 #endif 00141 //##Documentation 00142 //## @brief Set the bounding box (in index/unit coordinates) via a float array 00143 virtual void SetFloatBounds(const float bounds[6]); 00144 //##Documentation 00145 //## @brief Set the bounding box (in index/unit coordinates) via a double array 00146 virtual void SetFloatBounds(const double bounds[6]); 00147 00148 //##Documentation 00149 //## @brief Get the time bounds (in ms) 00150 itkGetConstReferenceMacro(TimeBounds, TimeBounds); 00151 //##Documentation 00152 //## @brief Set the time bounds (in ms) 00153 virtual void SetTimeBounds(const TimeBounds& timebounds); 00154 00155 //##Documentation 00156 //## @brief Get the position of the corner number \a id (in world coordinates) 00157 //## 00158 //## See SetImageGeometry for how a corner is defined on images. 00159 Point3D GetCornerPoint(int id) const; 00160 00161 //##Documentation 00162 //## @brief Get the position of a corner (in world coordinates) 00163 //## 00164 //## See SetImageGeometry for how a corner is defined on images. 00165 Point3D GetCornerPoint(bool xFront=true, bool yFront=true, bool zFront=true) const; 00166 00167 //##Documentation 00168 //## @brief Get vector along bounding-box in the specified @a direction in mm 00169 //## 00170 //## The length of the vector is the size of the bounding-box in the 00171 //## specified @a direction in mm 00172 //## \sa GetMatrixColumn 00173 Vector3D GetAxisVector(unsigned int direction) const 00174 { 00175 Vector3D frontToBack; 00176 frontToBack.Set_vnl_vector(m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction)); 00177 frontToBack *= GetExtent(direction); 00178 return frontToBack; 00179 } 00180 00181 //##Documentation 00182 //## @brief Get the center of the bounding-box in mm 00183 //## 00184 Point3D GetCenter() const 00185 { 00186 assert(m_BoundingBox.IsNotNull()); 00187 return m_IndexToWorldTransform->TransformPoint(m_BoundingBox->GetCenter()); 00188 } 00189 00190 //##Documentation 00191 //## @brief Get the squared length of the diagonal of the bounding-box in mm 00192 //## 00193 double GetDiagonalLength2() const 00194 { 00195 Vector3D diagonalvector = GetCornerPoint()-GetCornerPoint(false, false, false); 00196 return diagonalvector.GetSquaredNorm(); 00197 } 00198 00199 //##Documentation 00200 //## @brief Get the length of the diagonal of the bounding-box in mm 00201 //## 00202 double GetDiagonalLength() const 00203 { 00204 return sqrt(GetDiagonalLength2()); 00205 } 00206 00207 //##Documentation 00208 //## @brief Get a VnlVector along bounding-box in the specified 00209 //## @a direction, length is spacing 00210 //## 00211 //## \sa GetAxisVector 00212 VnlVector GetMatrixColumn(unsigned int direction) const 00213 { 00214 return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction); 00215 } 00216 00217 #ifdef DOXYGEN_SKIP 00218 //##Documentation 00219 //## @brief Get the extent of the bounding box (in index/unit coordinates) 00220 //## 00221 //## To access the extent in mm use GetExtentInMM 00222 ScalarType GetExtent(unsigned int direction) const; 00223 #endif 00224 00225 //##Documentation 00226 //## @brief Get the extent of the bounding-box in the specified @a direction in mm 00227 //## 00228 //## Equals length of GetAxisVector(direction). 00229 ScalarType GetExtentInMM(int direction) const 00230 { 00231 return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction).magnitude()*GetExtent(direction); 00232 } 00233 00234 //##Documentation 00235 //## @brief Set the extent of the bounding-box in the specified @a direction in mm 00236 //## 00237 //## @note This changes the matrix in the transform, @a not the bounds, which are given in units! 00238 virtual void SetExtentInMM(int direction, ScalarType extentInMM); 00239 00240 //##Documentation 00241 //## @brief Get the m_IndexToWorldTransform as a vtkLinearTransform 00242 vtkLinearTransform* GetVtkTransform() const 00243 { 00244 return (vtkLinearTransform*)m_VtkIndexToWorldTransform; 00245 } 00246 00247 //##Documentation 00248 //## @brief Set the origin, i.e. the upper-left corner of the plane 00249 //## 00250 virtual void SetOrigin(const Point3D& origin); 00251 00252 //##Documentation 00253 //## @brief Translate the origin by a vector 00254 //## 00255 virtual void Translate(const Vector3D& vector); 00256 00257 //##Documentation 00258 //## @brief Set the transform to identity 00259 //## 00260 virtual void SetIdentity(); 00261 00262 //##Documentation 00263 //## @brief Compose new IndexToWorldTransform with a given transform. 00264 //## 00265 //## This method composes m_IndexToWorldTransform with another transform, 00266 //## modifying self to be the composition of self and other. 00267 //## If the argument pre is true, then other is precomposed with self; 00268 //## that is, the resulting transformation consists of first applying 00269 //## other to the source, followed by self. If pre is false or omitted, 00270 //## then other is post-composed with self; that is the resulting 00271 //## transformation consists of first applying self to the source, 00272 //## followed by other. 00273 virtual void Compose( const AffineGeometryFrame3D::TransformType * other, bool pre = 0 ); 00274 00275 //##Documentation 00276 //## @brief Compose new IndexToWorldTransform with a given vtkMatrix4x4. 00277 //## 00278 //## Converts the vtkMatrix4x4 into a itk-transform and calls the previous method. 00279 virtual void Compose( const vtkMatrix4x4 * vtkmatrix, bool pre = 0 ); 00280 00281 //##Documentation 00282 //## @brief Get the origin, i.e. the upper-left corner of the plane 00283 const Point3D& GetOrigin() const 00284 { 00285 return m_Origin; 00286 } 00287 00288 //##Documentation 00289 //## @brief Get the origin as VnlVector 00290 //## 00291 //## \sa GetOrigin 00292 VnlVector GetOriginVnl() const 00293 { 00294 return const_cast<Self*>(this)->m_Origin.Get_vnl_vector(); 00295 } 00296 00297 //##Documentation 00298 //## @brief Convert world coordinates (in mm) of a \em point to (continuous!) index coordinates (in units) 00299 //## \warning If you need integer index coordinates (e.g., for accessing a pixel in an image), 00300 //## use WorldToIndex(const mitk::Point3D& pt_mm, itk::Index<VIndexDimension> &index). 00301 void WorldToIndex(const mitk::Point3D& pt_mm, mitk::Point3D& pt_units) const; 00302 00303 //##Documentation 00304 //## @brief Convert index coordinates (in units) of a \em point to world coordinates (in mm) 00305 void IndexToWorld(const mitk::Point3D& pt_units, mitk::Point3D& pt_mm) const; 00306 00307 //##Documentation 00308 //## @brief Convert world coordinates (in mm) of a \em vector 00309 //## \a vec_mm (at the point \a atPt3d_mm) to (continuous!) index coordinates (in units) 00310 //## \warning If you need integer index coordinates (e.g., for accessing a pixel in an image), 00311 //## use WorldToIndex(const mitk::Point3D& pt_mm, itk::Index<VIndexDimension> &index). 00312 void WorldToIndex(const mitk::Point3D& atPt3d_mm, const mitk::Vector3D& vec_mm, mitk::Vector3D& vec_units) const; 00313 00314 //##Documentation 00315 //## @brief Convert index coordinates (in units) of a \em vector 00316 //## \a vec_units (at the point \a atPt3d_units) to world coordinates (in mm) 00317 void IndexToWorld(const mitk::Point3D& atPt3d_units, const mitk::Vector3D& vec_units, mitk::Vector3D& vec_mm) const; 00318 00319 //##Documentation 00320 //## @brief Convert world coordinates (in mm) of a \em point to index coordinates (in units). 00321 //## This method rounds to integer indices! 00322 template <unsigned int VIndexDimension> 00323 void WorldToIndex(const mitk::Point3D& pt_mm, itk::Index<VIndexDimension> &index) const 00324 { 00325 typedef itk::Index<VIndexDimension> IndexType; 00326 mitk::Point3D pt_units; 00327 this->WorldToIndex(pt_mm, pt_units); 00328 int i, dim=index.GetIndexDimension(); 00329 if(dim>3) 00330 { 00331 index.Fill(0); 00332 dim=3; 00333 } 00334 for(i=0;i<dim;++i){ 00335 //index[i]=itk::Math::RoundHalfIntegerUp<typename IndexType::IndexValueType >( pt_units[i] ); 00336 index[i]=itk::Math::RoundHalfIntegerUp( pt_units[i] ); 00337 } 00338 } 00339 00340 //##Documentation 00341 //## @brief Deprecated for use with ITK version 3.10 or newer. 00342 //## Convert world coordinates (in mm) of a \em point to 00343 //## ITK physical coordinates (in mm, but without a possible rotation) 00344 //## 00345 //## This method is useful if you have want to access an mitk::Image 00346 //## via an itk::Image. ITK v3.8 and older did not support rotated (tilted) 00347 //## images, i.e., ITK images are always parallel to the coordinate axes. 00348 //## When accessing a (possibly rotated) mitk::Image via an itk::Image 00349 //## the rotational part of the transformation in the Geometry3D is 00350 //## simply discarded; in other word: only the origin and spacing is 00351 //## used by ITK, not the complete matrix available in MITK. 00352 //## With WorldToItkPhysicalPoint you can convert an MITK world 00353 //## coordinate (including the rotation) into a coordinate that 00354 //## can be used with the ITK image as a ITK physical coordinate 00355 //## (excluding the rotation). 00356 template<class TCoordRep> 00357 void WorldToItkPhysicalPoint(const mitk::Point3D& pt_mm, 00358 itk::Point<TCoordRep, 3>& itkPhysicalPoint) const 00359 { 00360 #if ((ITK_VERSION_MAJOR > 3) || (ITK_VERSION_MAJOR == 3 && ITK_VERSION_MINOR > 8)) 00361 mitk::vtk2itk(pt_mm, itkPhysicalPoint); 00362 #else 00363 mitk::Point3D index; 00364 WorldToIndex(pt_mm, index); 00365 for (unsigned int i = 0 ; i < 3 ; i++) 00366 { 00367 itkPhysicalPoint[i] = static_cast<TCoordRep>( this->m_Spacing[i] * index[i] + this->m_Origin[i] ); 00368 } 00369 #endif 00370 } 00371 00372 //##Documentation 00373 //## @brief Deprecated for use with ITK version 3.10 or newer. 00374 //## Convert ITK physical coordinates of a \em point (in mm, 00375 //## but without a rotation) into MITK world coordinates (in mm) 00376 //## 00377 //## For more information, see WorldToItkPhysicalPoint. 00378 template<class TCoordRep> 00379 void ItkPhysicalPointToWorld(const itk::Point<TCoordRep, 3>& itkPhysicalPoint, 00380 mitk::Point3D& pt_mm) const 00381 { 00382 #if ((ITK_VERSION_MAJOR > 3) || (ITK_VERSION_MAJOR == 3 && ITK_VERSION_MINOR > 8)) 00383 mitk::vtk2itk(itkPhysicalPoint, pt_mm); 00384 #else 00385 mitk::Point3D index; 00386 for (unsigned int i = 0 ; i < 3 ; i++) 00387 { 00388 index[i] = static_cast<ScalarType>( (itkPhysicalPoint[i]- this->m_Origin[i]) / this->m_Spacing[i] ); 00389 } 00390 IndexToWorld(index, pt_mm); 00391 #endif 00392 } 00393 00394 //##Documentation 00395 //## @brief Initialize the Geometry3D 00396 virtual void Initialize(); 00397 00398 //##Documentation 00399 //## @brief Is this an ImageGeometry? 00400 //## 00401 //## For more information, see SetImageGeometry 00402 itkGetConstMacro(ImageGeometry, bool); 00403 //##Documentation 00404 //## @brief Define that this Geometry3D is refering to an Image 00405 //## 00406 //## A geometry referring to an Image needs a slightly different 00407 //## definition of the position of the corners (see GetCornerPoint). 00408 //## The position of a voxel is defined by the position of its center. 00409 //## If we would use the origin (position of the (center of) the first 00410 //## voxel) as a corner and display this point, it would seem to be 00411 //## \em not at the corner but a bit within the image. Even worse for 00412 //## the opposite corner of the image: here the corner would appear 00413 //## outside the image (by half of the voxel diameter). Thus, we have 00414 //## to correct for this and to be able to do that, we need to know 00415 //## that the Geometry3D is referring to an Image. 00416 itkSetMacro(ImageGeometry, bool); 00417 itkBooleanMacro(ImageGeometry); 00418 00419 //##Documentation 00420 //## @brief Is this Geometry3D in a state that is valid? 00421 virtual bool IsValid() const 00422 { 00423 return m_Valid; 00424 } 00425 00426 //##Documentation 00427 //## @brief Test whether the point \a p (world coordinates in mm) is 00428 //## inside the bounding box 00429 bool IsInside(const mitk::Point3D& p) const 00430 { 00431 mitk::Point3D index; 00432 WorldToIndex(p, index); 00433 return IsIndexInside(index); 00434 } 00435 00436 //##Documentation 00437 //## @brief Test whether the point \a p ((continous!)index coordinates in units) is 00438 //## inside the bounding box 00439 bool IsIndexInside(const mitk::Point3D& index) const 00440 { 00441 bool inside = false; 00442 //if it is an image geometry, we need to convert the index to discrete values 00443 //this is done by applying the rounding function also used in WorldToIndex (see line 323) 00444 if (m_ImageGeometry) 00445 { 00446 mitk::Point3D discretIndex; 00447 discretIndex[0]=itk::Math::RoundHalfIntegerUp( index[0] ); 00448 discretIndex[1]=itk::Math::RoundHalfIntegerUp( index[1] ); 00449 discretIndex[2]=itk::Math::RoundHalfIntegerUp( index[2] ); 00450 00451 inside = m_BoundingBox->IsInside(discretIndex); 00452 //we have to check if the index is at the upper border of each dimension, 00453 // because the boundingbox is not centerbased 00454 if (inside) 00455 { 00456 const BoundingBox::BoundsArrayType& bounds = m_BoundingBox->GetBounds(); 00457 if((discretIndex[0] == bounds[1]) || 00458 (discretIndex[1] == bounds[3]) || 00459 (discretIndex[2] == bounds[5])) 00460 inside = false; 00461 } 00462 } 00463 else 00464 inside = m_BoundingBox->IsInside(index); 00465 00466 return inside; 00467 } 00468 00469 //##Documentation 00470 //## @brief Convenience method for working with ITK indices 00471 template <unsigned int VIndexDimension> 00472 bool IsIndexInside(const itk::Index<VIndexDimension> &index) const 00473 { 00474 int i, dim=index.GetIndexDimension(); 00475 Point3D pt_index; 00476 pt_index.Fill(0); 00477 for ( i = 0; i < dim; ++i ) 00478 { 00479 pt_index[i] = index[i]; 00480 } 00481 return IsIndexInside(pt_index); 00482 } 00483 00484 00485 //##Documentation 00486 //## @brief Get the spacing (size of a pixel). 00487 //## 00488 itkGetConstReferenceMacro(Spacing, mitk::Vector3D); 00489 00490 //##Documentation 00491 //## @brief Get the spacing as a float[3] array. 00492 const float* GetFloatSpacing() const; 00493 00494 //##Documentation 00495 //## @brief Set the spacing (m_Spacing) 00496 virtual void SetSpacing(const mitk::Vector3D& aSpacing); 00497 //##Documentation 00498 //## @brief Set the spacing (m_Spacing) via a float array 00499 virtual void SetSpacing(const float aSpacing[3]); 00500 00501 //##Documentation 00502 //## @brief Get the DICOM FrameOfReferenceID referring to the 00503 //## used world coordinate system 00504 itkGetConstMacro(FrameOfReferenceID, unsigned int); 00505 //##Documentation 00506 //## @brief Set the DICOM FrameOfReferenceID referring to the 00507 //## used world coordinate system 00508 itkSetMacro(FrameOfReferenceID, unsigned int); 00509 00510 //##Documentation 00511 //## @brief Copy the ITK transform 00512 //## (m_IndexToWorldTransform) to the VTK transform 00513 //## \sa SetIndexToWorldTransform 00514 void TransferItkToVtkTransform(); 00515 00516 //##Documentation 00517 //## @brief Copy the VTK transform 00518 //## to the ITK transform (m_IndexToWorldTransform) 00519 //## \sa SetIndexToWorldTransform 00520 void TransferVtkToItkTransform(); 00521 00522 //##Documentation 00523 //## @brief Get the parametric bounding-box 00524 //## 00525 //## See AbstractTransformGeometry for an example usage of this. 00526 itkGetConstObjectMacro(ParametricBoundingBox, BoundingBox); 00527 //##Documentation 00528 //## @brief Get the parametric bounds 00529 //## 00530 //## See AbstractTransformGeometry for an example usage of this. 00531 const BoundingBox::BoundsArrayType& GetParametricBounds() const 00532 { 00533 assert(m_ParametricBoundingBox.IsNotNull()); 00534 return m_ParametricBoundingBox->GetBounds(); 00535 } 00536 00537 //##Documentation 00538 //## @brief Get the parametric extent 00539 //## 00540 //## See AbstractTransformGeometry for an example usage of this. 00541 mitk::ScalarType GetParametricExtent(int direction) const 00542 { 00543 assert(direction>=0 && direction<3); 00544 assert(m_ParametricBoundingBox.IsNotNull()); 00545 00546 BoundingBoxType::BoundsArrayType bounds = m_ParametricBoundingBox->GetBounds(); 00547 return bounds[direction*2+1]-bounds[direction*2]; 00548 } 00549 00550 //##Documentation 00551 //## @brief Get the parametric extent in mm 00552 //## 00553 //## See AbstractTransformGeometry for an example usage of this. 00554 virtual mitk::ScalarType GetParametricExtentInMM(int direction) const 00555 { 00556 return GetExtentInMM(direction); 00557 } 00558 00559 //##Documentation 00560 //## @brief Get the parametric transform 00561 //## 00562 //## See AbstractTransformGeometry for an example usage of this. 00563 virtual const Transform3D* GetParametricTransform() const 00564 { 00565 return m_IndexToWorldTransform; 00566 } 00567 00568 //##Documentation 00569 //## @brief Calculates a bounding-box around the geometry relative 00570 //## to a coordinate system defined by a transform 00571 //## 00572 mitk::BoundingBox::Pointer CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D* transform) const; 00573 00574 //##Documentation 00575 //## @brief clones the geometry 00576 //## 00577 //## Overwrite in all sub-classes. 00578 //## Normally looks like: 00579 //## \code 00580 //## Self::Pointer newGeometry = Self::New(); 00581 //## newGeometry->Initialize(); 00582 //## InitializeGeometry(newGeometry); 00583 //## return newGeometry.GetPointer(); 00584 //## \endcode 00585 //## \sa InitializeGeometry 00586 virtual AffineGeometryFrame3D::Pointer Clone() const; 00587 00588 //##Documentation 00589 //##@brief executes affine operations (translate, rotate, scale) 00590 virtual void ExecuteOperation(Operation* operation); 00591 00592 protected: 00593 Geometry3D(); 00594 static const char* GetTransformAsString( TransformType* transformType ); 00595 00596 virtual ~Geometry3D(); 00597 00598 //##Documentation 00599 //## @brief used in clone to initialize the newly created geometry 00600 //## 00601 //## Has to be overwritten in sub-classes, if they add members. 00602 //## Do the following: 00603 //## \li call Superclass::InitializeGeometry(newGeometry) 00604 //## \li transfer all additional members of Self compared to Superclass 00605 virtual void InitializeGeometry(Self * newGeometry) const; 00606 00607 virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; 00608 00609 virtual void BackTransform(const mitk::Point3D& in, mitk::Point3D& out) const; 00610 virtual void BackTransform(const mitk::Point3D& at, const mitk::Vector3D& in, mitk::Vector3D& out) const; 00611 00612 //##Documentation 00613 //## @brief Set the parametric bounds 00614 //## 00615 //## Protected in this class, made public in some sub-classes, e.g., 00616 //## ExternAbstractTransformGeometry. 00617 virtual void SetParametricBounds(const BoundingBox::BoundsArrayType& bounds); 00618 00622 virtual void ResetSubTransforms(); 00623 00624 mutable mitk::BoundingBox::Pointer m_ParametricBoundingBox; 00625 00626 mutable mitk::TimeBounds m_TimeBounds; 00627 00628 vtkMatrix4x4* m_VtkMatrix; 00629 00630 bool m_ImageGeometry; 00631 00632 //##Documentation 00633 //## @brief Spacing of the data. Only significant if the geometry describes 00634 //## an Image (m_ImageGeometry==true). 00635 mitk::Vector3D m_Spacing; 00636 00637 bool m_Valid; 00638 00639 unsigned int m_FrameOfReferenceID; 00640 00641 static const std::string INDEX_TO_OBJECT_TRANSFORM; 00642 static const std::string OBJECT_TO_NODE_TRANSFORM; 00643 static const std::string INDEX_TO_NODE_TRANSFORM; 00644 static const std::string INDEX_TO_WORLD_TRANSFORM; 00645 00646 private: 00647 mutable TransformType::Pointer m_InvertedTransform; 00648 mutable unsigned long m_IndexToWorldTransformLastModified; 00649 QuaternionTransformType::Pointer m_IndexToWorldRotationTransform; 00650 00651 VnlQuaternionType m_RotationQuaternion; 00652 00653 00654 float m_FloatSpacing[3]; 00655 vtkMatrixToLinearTransform* m_VtkIndexToWorldTransform; 00656 00657 //##Documentation 00658 //## @brief Origin, i.e. upper-left corner of the plane 00659 //## 00660 Point3D m_Origin; 00661 }; 00662 00663 } // namespace mitk 00664 00665 #endif /* GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD */