Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes

mitk::SlicedGeometry3D Class Reference
[Geometry Classes]

Describes the geometry of a data object consisting of slices. More...

#include <mitkSlicedGeometry3D.h>

Inheritance diagram for mitk::SlicedGeometry3D:
Inheritance graph
[legend]
Collaboration diagram for mitk::SlicedGeometry3D:
Collaboration graph
[legend]

List of all members.

Public Types

typedef SlicedGeometry3D Self
typedef Geometry3D Superclass
typedef itk::SmartPointer< SelfPointer
typedef itk::SmartPointer
< const Self
ConstPointer

Public Member Functions

virtual const char * GetClassName () const
 Method for creation through the object factory.
void UpdateInformation ()
 Re-calculate the hull of the contained geometries.
virtual mitk::Geometry2DGetGeometry2D (int s) const
 Returns the Geometry2D of the slice (s).
virtual bool SetGeometry2D (mitk::Geometry2D *geometry2D, int s)
 Set Geometry2D of slice s.
virtual void SetTimeBounds (const mitk::TimeBounds &timebounds)
 Set the time bounds (in ms)
virtual const mitk::BoundingBoxGetBoundingBox () const
virtual unsigned int GetSlices () const
 Get the number of slices.
virtual bool IsValidSlice (int s=0) const
 Check whether a slice exists.
virtual void SetReferenceGeometry (Geometry3D *referenceGeometry)
virtual void SetSpacing (const mitk::Vector3D &aSpacing)
 Set the spacing (m_Spacing), in direction of the plane normal.
virtual void SetSliceNavigationController (mitk::SliceNavigationController *snc)
 Set the SliceNavigationController corresponding to this sliced geometry.
mitk::SliceNavigationControllerGetSliceNavigationController ()
virtual bool GetEvenlySpaced () const
 Set/Get whether the SlicedGeometry3D is evenly-spaced (m_EvenlySpaced)
virtual void SetEvenlySpaced (bool on=true)
virtual void SetDirectionVector (const mitk::Vector3D &directionVector)
 Set/Get the vector between slices for the evenly-spaced case (m_EvenlySpaced==true).
virtual const mitk::Vector3D & GetDirectionVector () const
virtual
AffineGeometryFrame3D::Pointer 
Clone () const
 clones the geometry
virtual void Initialize (unsigned int slices)
 Tell this instance how many Geometry2Ds it shall manage. Bounding box and the Geometry2Ds must be set additionally by calling the respective methods!
virtual void InitializeEvenlySpaced (mitk::Geometry2D *geometry2D, unsigned int slices, bool flipped=false)
 Completely initialize this instance as evenly-spaced with slices parallel to the provided Geometry2D that is used as the first slice and for spacing calculation.
virtual void InitializeEvenlySpaced (mitk::Geometry2D *geometry2D, mitk::ScalarType zSpacing, unsigned int slices, bool flipped=false)
 Completely initialize this instance as evenly-spaced with slices parallel to the provided Geometry2D that is used as the first slice and for spacing calculation (except z-spacing).
virtual void InitializePlanes (const mitk::Geometry3D *geometry3D, mitk::PlaneGeometry::PlaneOrientation planeorientation, bool top=true, bool frontside=true, bool rotated=false)
 Completely initialize this instance as evenly-spaced plane slices parallel to a side of the provided Geometry3D and using its spacing information.
virtual void SetImageGeometry (const bool isAnImageGeometry)
 Define that this Geometry3D is refering to an Image.
virtual void ExecuteOperation (Operation *operation)
 executes affine operations (translate, rotate, scale)

Static Public Member Functions

static Pointer New ()

Static Public Attributes

static const std::string SLICES
static const std::string DIRECTION_VECTOR
static const std::string EVENLY_SPACED

Protected Member Functions

 SlicedGeometry3D ()
virtual ~SlicedGeometry3D ()
virtual void ReinitializePlanes (const Point3D &center, const Point3D &referencePoint)
ScalarType GetLargestExtent (const Geometry3D *geometry)
virtual void InitializeGeometry (Self *newGeometry) const
 used in clone to initialize the newly created geometry
void PrintSelf (std::ostream &os, itk::Indent indent) const
double CalculateSpacing (const mitk::Vector3D &direction) const
mitk::Vector3D AdjustNormal (const mitk::Vector3D &normal) const

Protected Attributes

std::vector< Geometry2D::Pointerm_Geometry2Ds
bool m_EvenlySpaced
mitk::Vector3D m_DirectionVector
unsigned int m_Slices
mitk::Geometry3Dm_ReferenceGeometry
mitk::SliceNavigationControllerm_SliceNavigationController

Detailed Description

Describes the geometry of a data object consisting of slices.

A Geometry2D can be requested for each slice. In the case of evenly-spaced, plane geometries (m_EvenlySpaced==true), only the 2D-geometry of the first slice has to be set (to an instance of PlaneGeometry). The 2D geometries of the other slices are calculated by shifting the first slice in the direction m_DirectionVector by m_Spacing.z * sliceNumber. The m_Spacing member (which is only relevant in the case m_EvenlySpaced==true) descibes the size of a voxel (in mm), i.e., m_Spacing.x is the voxel width in the x-direction of the plane. It is derived from the reference geometry of this SlicedGeometry3D, which usually would be the global geometry describing how datasets are to be resliced.

By default, slices are oriented in the direction of one of the main axes (x, y, z). However, by means of rotation, it is possible to realign the slices in any possible direction. In case of an inclined plane, the spacing is derived as a product of the (regular) geometry spacing and the direction vector of the plane.

SlicedGeometry3D and the associated Geometry2Ds have to be initialized in the method GenerateOutputInformation() of BaseProcess (or CopyInformation / UpdateOutputInformation of BaseData, if possible, e.g., by analyzing pic tags in Image) subclasses. See also

See also:
itk::ProcessObject::GenerateOutputInformation(),
itk::DataObject::CopyInformation() and itk::DataObject::UpdateOutputInformation().

Rule: everything is in mm (or ms for temporal information) if not stated otherwise.

Warning:
The hull (i.e., transform, bounding-box and time-bounds) is only guaranteed to be up-to-date after calling UpdateInformation().

Definition at line 68 of file mitkSlicedGeometry3D.h.


Member Typedef Documentation

typedef itk::SmartPointer<const Self> mitk::SlicedGeometry3D::ConstPointer

Reimplemented from mitk::Geometry3D.

Definition at line 71 of file mitkSlicedGeometry3D.h.

typedef itk::SmartPointer<Self> mitk::SlicedGeometry3D::Pointer

Reimplemented from mitk::Geometry3D.

Definition at line 71 of file mitkSlicedGeometry3D.h.

Reimplemented from mitk::Geometry3D.

Definition at line 71 of file mitkSlicedGeometry3D.h.

Reimplemented from mitk::Geometry3D.

Definition at line 71 of file mitkSlicedGeometry3D.h.


Constructor & Destructor Documentation

mitk::SlicedGeometry3D::SlicedGeometry3D (  ) [protected]

Definition at line 26 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::Initialize(), and m_Slices.

mitk::SlicedGeometry3D::~SlicedGeometry3D (  ) [protected, virtual]

Definition at line 36 of file mitkSlicedGeometry3D.cpp.

{
}

Member Function Documentation

mitk::Vector3D mitk::SlicedGeometry3D::AdjustNormal ( const mitk::Vector3D &  normal ) const [protected]

The extent of the slice stack, i.e. the number of slices, depends on the plane normal. For rotated geometries, the geometry's transform needs to be accounted in this calculation.

Definition at line 432 of file mitkSlicedGeometry3D.cpp.

References inverse, and mitk::Geometry3D::New().

{
  Geometry3D::TransformType::Pointer inverse = Geometry3D::TransformType::New();
  m_ReferenceGeometry->GetIndexToWorldTransform()->GetInverse( inverse );
  
  Vector3D transformedNormal = inverse->TransformVector( normal );

  transformedNormal.Normalize();
  return transformedNormal;
}
double mitk::SlicedGeometry3D::CalculateSpacing ( const mitk::Vector3D &  direction ) const [protected]

Calculate "directed spacing", i.e. the spacing in directions non-orthogonal to the coordinate axes. This is done via the ellipsoid equation.

Definition at line 405 of file mitkSlicedGeometry3D.cpp.

References QuadProgPP::sqrt().

{
  // Need the spacing of the underlying dataset / geometry
  if ( !m_ReferenceGeometry )
  {
    return 1.0;
  }

  // The following can be derived from the ellipsoid equation
  //
  //   1 = x^2/a^2 + y^2/b^2 + z^2/c^2
  //
  // where (a,b,c) = spacing of original volume (ellipsoid radii)
  // and   (x,y,z) = scaled coordinates of vector d (according to ellipsoid)
  //
  const mitk::Vector3D &spacing = m_ReferenceGeometry->GetSpacing();

  double scaling = d[0]*d[0] / (spacing[0] * spacing[0])
    + d[1]*d[1] / (spacing[1] * spacing[1])
    + d[2]*d[2] / (spacing[2] * spacing[2]);

  scaling = sqrt( scaling );

  return ( sqrt( d[0]*d[0] + d[1]*d[1] + d[2]*d[2] ) / scaling );
}
mitk::AffineGeometryFrame3D::Pointer mitk::SlicedGeometry3D::Clone (  ) const [virtual]

clones the geometry

Overwrite in all sub-classes. Normally looks like:

  //##  Self::Pointer newGeometry = Self::New();
  //##  newGeometry->Initialize();
  //##  InitializeGeometry(newGeometry);
  //##  return newGeometry.GetPointer();
  //## 
See also:
InitializeGeometry

Reimplemented from mitk::Geometry3D.

Definition at line 614 of file mitkSlicedGeometry3D.cpp.

{
  Self::Pointer newGeometry = Self::New();
  newGeometry->Initialize(m_Slices);
  InitializeGeometry(newGeometry);
  return newGeometry.GetPointer();
}
void mitk::SlicedGeometry3D::ExecuteOperation ( Operation operation ) [virtual]

executes affine operations (translate, rotate, scale)

Reimplemented from mitk::Geometry3D.

Definition at line 687 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::ExecuteOperation(), mitk::RotationOperation::GetAngleOfRotation(), mitk::RotationOperation::GetCenterOfRotation(), mitk::PlaneOperation::GetNormal(), mitk::PlaneGeometry::GetNormal(), mitk::Operation::GetOperationType(), mitk::PointOperation::GetPoint(), mitk::RotationOperation::GetVectorOfRotation(), mitk::OpNOTHING, mitk::OpORIENT, and mitk::OpROTATE.

{
  switch ( operation->GetOperationType() )
  {
  case OpNOTHING:
    break;
  
  case OpROTATE:
    if ( m_EvenlySpaced )
    {
      // Need a reference frame to align the rotation
      if ( m_ReferenceGeometry )
      {
        // Clear all generated geometries and then rotate only the first slice.
        // The other slices will be re-generated on demand
        
        // Save first slice
        Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];

        RotationOperation *rotOp = dynamic_cast< RotationOperation * >( operation );

        // Generate a RotationOperation using the dataset center instead of
        // the supplied rotation center. This is necessary so that the rotated 
        // zero-plane does not shift away. The supplied center is instead used
        // to adjust the slice stack afterwards.
        Point3D center = m_ReferenceGeometry->GetCenter();

        RotationOperation centeredRotation(
          rotOp->GetOperationType(),
          center,
          rotOp->GetVectorOfRotation(),
          rotOp->GetAngleOfRotation()
        );

        // Rotate first slice
        geometry2D->ExecuteOperation( &centeredRotation );

        // Clear the slice stack and adjust it according to the center of
        // the dataset and the supplied rotation center (see documentation of 
        // ReinitializePlanes)
        this->ReinitializePlanes( center, rotOp->GetCenterOfRotation() );

        if ( m_SliceNavigationController )
        {
          m_SliceNavigationController->SelectSliceByPoint(
            rotOp->GetCenterOfRotation() );
          m_SliceNavigationController->AdjustSliceStepperRange();
        }

        Geometry3D::ExecuteOperation( &centeredRotation );
      }
    }
    else
    {
      // Reach through to all slices
      for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
          iter != m_Geometry2Ds.end();
          ++iter)
      {
        (*iter)->ExecuteOperation(operation);
      }
    }
    break;

  case OpORIENT:
    if ( m_EvenlySpaced )
    {
      // Save first slice
      Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];

      PlaneGeometry *planeGeometry = dynamic_cast< PlaneGeometry * >( 
        geometry2D.GetPointer() );

      PlaneOperation *planeOp = dynamic_cast< PlaneOperation * >( operation );

      // Need a PlaneGeometry, a PlaneOperation and a reference frame to
      // carry out the re-orientation
      if ( m_ReferenceGeometry && planeGeometry && planeOp )
      {
        // Clear all generated geometries and then rotate only the first slice.
        // The other slices will be re-generated on demand

        // Generate a RotationOperation by calculating the angle between
        // the current and the requested slice orientation
        Point3D center = m_ReferenceGeometry->GetCenter();

        const mitk::Vector3D &currentNormal = planeGeometry->GetNormal();
        const mitk::Vector3D &newNormal = planeOp->GetNormal();

        Vector3D rotationAxis = itk::CrossProduct( newNormal, currentNormal );

        vtkFloatingPointType rotationAngle = - atan2( 
          (double) rotationAxis.GetNorm(),
          (double) (newNormal * currentNormal) );

        rotationAngle *= 180.0 / vnl_math::pi;

        RotationOperation centeredRotation(
          mitk::OpROTATE,
          center,
          rotationAxis,
          rotationAngle
        );

        // Rotate first slice
        geometry2D->ExecuteOperation( &centeredRotation );

        // Clear the slice stack and adjust it according to the center of
        // rotation and plane position (see documentation of ReinitializePlanes)
        this->ReinitializePlanes( center, planeOp->GetPoint() );

        if ( m_SliceNavigationController )
        {
          m_SliceNavigationController->SelectSliceByPoint( planeOp->GetPoint() );
          m_SliceNavigationController->AdjustSliceStepperRange();
        }

        Geometry3D::ExecuteOperation( &centeredRotation );
      }
    }
    else
    {
      // Reach through to all slices
      for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
          iter != m_Geometry2Ds.end();
          ++iter)
      {
        (*iter)->ExecuteOperation(operation);
      }
    }
    break;
  }

  this->Modified();
}
const mitk::BoundingBox * mitk::SlicedGeometry3D::GetBoundingBox (  ) const [virtual]

Definition at line 93 of file mitkSlicedGeometry3D.cpp.

{
  assert(m_BoundingBox.IsNotNull());
  return m_BoundingBox.GetPointer();
}
virtual const char* mitk::SlicedGeometry3D::GetClassName (  ) const [virtual]

Method for creation through the object factory.

Reimplemented from mitk::Geometry3D.

virtual const mitk::Vector3D& mitk::SlicedGeometry3D::GetDirectionVector (  ) const [virtual]
virtual bool mitk::SlicedGeometry3D::GetEvenlySpaced (  ) const [virtual]

Set/Get whether the SlicedGeometry3D is evenly-spaced (m_EvenlySpaced)

If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored for the requested slice, and (c) the first slice (s=0) is a PlaneGeometry instance, then we calculate the geometry of the requested as the plane of the first slice shifted by m_Spacing.z * s in the direction of m_DirectionVector.

See also:
GetGeometry2D
mitk::Geometry2D * mitk::SlicedGeometry3D::GetGeometry2D ( int  s ) const [virtual]

Returns the Geometry2D of the slice (s).

If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored for the requested slice, and (c) the first slice (s=0) is a PlaneGeometry instance, then we calculate the geometry of the requested as the plane of the first slice shifted by m_Spacing[3]*s in the direction of m_DirectionVector.

Warning:
The Geometry2Ds are not necessarily up-to-date and not even initialized.

The Geometry2Ds have to be initialized in the method GenerateOutputInformation() of BaseProcess (or CopyInformation / UpdateOutputInformation of BaseData, if possible, e.g., by analyzing pic tags in Image) subclasses. See also

See also:
itk::ProcessObject::GenerateOutputInformation(),
itk::DataObject::CopyInformation() and
itk::DataObject::UpdateOutputInformation().

Definition at line 42 of file mitkSlicedGeometry3D.cpp.

References mitk::PlaneGeometry::Clone(), mitk::PlaneGeometry::GetNormal(), and mitk::Geometry3D::SetOrigin().

Referenced by mitk::SlicesRotator::ExecuteAction(), QmitkSlicesInterpolator::GetSliceForWindowsID(), mitk::Image::Initialize(), mitkPicFileReaderTest(), mitk::BaseRenderer::SetSlice(), mitk::BaseRenderer::SetTimeStep(), mitk::BaseRenderer::SetWorldGeometry(), QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(), and mitk::BaseRenderer::UpdateGeometry().

{
  mitk::Geometry2D::Pointer geometry2D = NULL;
  
  if ( this->IsValidSlice(s) )
  {
    geometry2D = m_Geometry2Ds[s];

    // If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored
    // for the requested slice, and (c) the first slice (s=0) 
    // is a PlaneGeometry instance, then we calculate the geometry of the
    // requested as the plane of the first slice shifted by m_Spacing[2]*s
    // in the direction of m_DirectionVector.
    if ( (m_EvenlySpaced) && (geometry2D.IsNull()) )
    {
      PlaneGeometry *firstSlice = dynamic_cast< PlaneGeometry * > (
        m_Geometry2Ds[0].GetPointer() );

      if ( firstSlice != NULL )
      {
        if ( (m_DirectionVector[0] == 0.0)
          && (m_DirectionVector[1] == 0.0)
          && (m_DirectionVector[2] == 0.0) )
        {
          m_DirectionVector = firstSlice->GetNormal();
          m_DirectionVector.Normalize();
        }

        Vector3D direction;
        direction = m_DirectionVector * m_Spacing[2];

        mitk::PlaneGeometry::Pointer requestedslice;
        requestedslice = static_cast< mitk::PlaneGeometry * >(
          firstSlice->Clone().GetPointer() );

        requestedslice->SetOrigin(
          requestedslice->GetOrigin() + direction * s );

        geometry2D = requestedslice;
        m_Geometry2Ds[s] = geometry2D;
      }
    }
    return geometry2D;
  }
  else
  {
    return NULL;
  }
}
ScalarType mitk::SlicedGeometry3D::GetLargestExtent ( const Geometry3D geometry ) [protected]
mitk::SliceNavigationController * mitk::SlicedGeometry3D::GetSliceNavigationController (  )

Definition at line 564 of file mitkSlicedGeometry3D.cpp.

virtual unsigned int mitk::SlicedGeometry3D::GetSlices (  ) const [virtual]
void mitk::SlicedGeometry3D::Initialize ( unsigned int  slices ) [virtual]

Tell this instance how many Geometry2Ds it shall manage. Bounding box and the Geometry2Ds must be set additionally by calling the respective methods!

Warning:
Bounding box and the 2D-geometries must be set additionally: use SetBounds(), SetGeometry().

Definition at line 114 of file mitkSlicedGeometry3D.cpp.

{
  Superclass::Initialize();
  m_Slices = slices;

  Geometry2D::Pointer gnull = NULL;
  m_Geometry2Ds.assign( m_Slices, gnull );
 
  Vector3D spacing;
  spacing.Fill( 1.0 );
  this->SetSpacing( spacing );

  m_DirectionVector.Fill( 0 );
}
void mitk::SlicedGeometry3D::InitializeEvenlySpaced ( mitk::Geometry2D geometry2D,
unsigned int  slices,
bool  flipped = false 
) [virtual]

Completely initialize this instance as evenly-spaced with slices parallel to the provided Geometry2D that is used as the first slice and for spacing calculation.

Initializes the bounding box according to the width/height of the Geometry2D and slices. The spacing is calculated from the Geometry2D.

Definition at line 131 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::GetExtent(), and mitk::Geometry3D::GetExtentInMM().

Referenced by mitk::ItkImageFileReader::GenerateData(), mitk::Image::InitializeByItk(), and mitk::PicHelper::InitializeEvenlySpaced().

{
  assert( geometry2D != NULL );
  this->InitializeEvenlySpaced(
    geometry2D, geometry2D->GetExtentInMM(2)/geometry2D->GetExtent(2),
    slices, flipped );
}
void mitk::SlicedGeometry3D::InitializeEvenlySpaced ( mitk::Geometry2D geometry2D,
mitk::ScalarType  zSpacing,
unsigned int  slices,
bool  flipped = false 
) [virtual]

Completely initialize this instance as evenly-spaced with slices parallel to the provided Geometry2D that is used as the first slice and for spacing calculation (except z-spacing).

Initializes the bounding box according to the width/height of the Geometry2D and slices. The x-/y-spacing is calculated from the Geometry2D.

Definition at line 142 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::GetAxisVector(), mitk::Geometry3D::GetBounds(), mitk::Geometry3D::GetExtent(), mitk::Geometry3D::GetExtentInMM(), mitk::Geometry3D::GetFrameOfReferenceID(), mitk::Geometry3D::GetImageGeometry(), mitk::Geometry3D::GetIndexToWorldTransform(), and mitk::Geometry3D::GetTimeBounds().

{
  assert( geometry2D != NULL );
  assert( geometry2D->GetExtent(0) > 0 );
  assert( geometry2D->GetExtent(1) > 0 );

  geometry2D->Register();

  Superclass::Initialize();
  m_Slices = slices;

  BoundingBox::BoundsArrayType bounds = geometry2D->GetBounds();
  bounds[4] = 0;
  bounds[5] = slices;

  // clear and reserve
  Geometry2D::Pointer gnull = NULL;
  m_Geometry2Ds.assign( m_Slices, gnull );

  Vector3D directionVector = geometry2D->GetAxisVector(2);
  directionVector.Normalize();
  directionVector *= zSpacing;

  if ( flipped == false )
  {
    // Normally we should use the following four lines to create a copy of
    // the transform contrained in geometry2D, because it may not be changed
    // by us. But we know that SetSpacing creates a new transform without
    // changing the old (coming from geometry2D), so we can use the fifth
    // line instead. We check this at (**).
    //
    // AffineTransform3D::Pointer transform = AffineTransform3D::New();
    // transform->SetMatrix(geometry2D->GetIndexToWorldTransform()->GetMatrix());
    // transform->SetOffset(geometry2D->GetIndexToWorldTransform()->GetOffset());
    // SetIndexToWorldTransform(transform);

    m_IndexToWorldTransform = const_cast< AffineTransform3D * >(
      geometry2D->GetIndexToWorldTransform() );
  }
  else
  {
    directionVector *= -1.0;
    m_IndexToWorldTransform = AffineTransform3D::New();
    m_IndexToWorldTransform->SetMatrix(
      geometry2D->GetIndexToWorldTransform()->GetMatrix() );

    AffineTransform3D::OutputVectorType scaleVector;
    FillVector3D(scaleVector, 1.0, 1.0, -1.0);
    m_IndexToWorldTransform->Scale(scaleVector, true);
    m_IndexToWorldTransform->SetOffset(
      geometry2D->GetIndexToWorldTransform()->GetOffset() );
  }

  mitk::Vector3D spacing;
  FillVector3D( spacing,
    geometry2D->GetExtentInMM(0) / bounds[1],
    geometry2D->GetExtentInMM(1) / bounds[3],
    zSpacing );

  // Ensure that spacing differs from m_Spacing to make SetSpacing change the
  // matrix.
  m_Spacing[2] = zSpacing - 1;

  this->SetDirectionVector( directionVector );
  this->SetBounds( bounds );
  this->SetGeometry2D( geometry2D, 0 );
  this->SetSpacing( spacing );
  this->SetEvenlySpaced();
  this->SetTimeBounds( geometry2D->GetTimeBounds() );

  assert(m_IndexToWorldTransform.GetPointer()
         != geometry2D->GetIndexToWorldTransform()); // (**) see above.

  this->SetFrameOfReferenceID( geometry2D->GetFrameOfReferenceID() );
  this->SetImageGeometry( geometry2D->GetImageGeometry() );

  geometry2D->UnRegister();
}
void mitk::SlicedGeometry3D::InitializeGeometry ( Self newGeometry ) const [protected, virtual]

used in clone to initialize the newly created geometry

Has to be overwritten in sub-classes, if they add members. Do the following:

  • call Superclass::InitializeGeometry(newGeometry)
  • transfer all additional members of Self compared to Superclass

Reimplemented from mitk::Geometry3D.

Definition at line 624 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::Clone(), and mitk::Geometry3D::SetSpacing().

{
  Superclass::InitializeGeometry( newGeometry );

  newGeometry->SetEvenlySpaced( m_EvenlySpaced );
  newGeometry->SetSpacing( this->GetSpacing() );
  newGeometry->SetDirectionVector( this->GetDirectionVector() );

  newGeometry->SetSliceNavigationController( m_SliceNavigationController );
  newGeometry->m_ReferenceGeometry = m_ReferenceGeometry;

  if ( m_EvenlySpaced )
  {
    AffineGeometryFrame3D::Pointer geometry = m_Geometry2Ds[0]->Clone();
    Geometry2D* geometry2D = dynamic_cast<Geometry2D*>(geometry.GetPointer());
    assert(geometry2D!=NULL);
    newGeometry->SetGeometry2D(geometry2D, 0);
  }
  else
  {
    unsigned int s;
    for ( s = 0; s < m_Slices; ++s )
    {
      if ( m_Geometry2Ds[s].IsNull() )
      {
        assert(m_EvenlySpaced);
      }
      else
      {
        AffineGeometryFrame3D::Pointer geometry = m_Geometry2Ds[s]->Clone();
        Geometry2D* geometry2D = dynamic_cast<Geometry2D*>(geometry.GetPointer());
        assert(geometry2D!=NULL);
        newGeometry->SetGeometry2D(geometry2D, s);
      }
    }
  }
}
void mitk::SlicedGeometry3D::InitializePlanes ( const mitk::Geometry3D geometry3D,
mitk::PlaneGeometry::PlaneOrientation  planeorientation,
bool  top = true,
bool  frontside = true,
bool  rotated = false 
) [virtual]

Completely initialize this instance as evenly-spaced plane slices parallel to a side of the provided Geometry3D and using its spacing information.

Initializes the bounding box according to the width/height of the Geometry3D and the number of slices according to Geometry3D::GetExtent(2).

Parameters:
planeorientationside parallel to which the slices will be oriented
topif true, create plane at top, otherwise at bottom (for PlaneOrientation Transversal, for other plane locations respectively)
frontsidedefines the side of the plane (the definition of front/back is somewhat arbitrary)
rotaterotates the plane by 180 degree around its normal (the definition of rotated vs not rotated is somewhat arbitrary)

Definition at line 225 of file mitkSlicedGeometry3D.cpp.

References mitk::PlaneGeometry::Frontal, mitk::Geometry3D::GetExtent(), mitk::Geometry3D::GetSpacing(), int(), mitk::PlaneGeometry::New(), mitk::PlaneGeometry::Sagittal, and mitk::PlaneGeometry::Transversal.

{
  m_ReferenceGeometry = const_cast< Geometry3D * >( geometry3D );
  
  PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
  planeGeometry->InitializeStandardPlane(
    geometry3D, top, planeorientation, frontside, rotated );

  ScalarType viewSpacing = 1;
  unsigned int slices = 1;

  switch ( planeorientation )
  {
    case PlaneGeometry::Transversal:
      viewSpacing = geometry3D->GetSpacing()[2];
      slices = (unsigned int) geometry3D->GetExtent( 2 );
      break;

    case PlaneGeometry::Frontal:
      viewSpacing = geometry3D->GetSpacing()[1];
      slices = (unsigned int) geometry3D->GetExtent( 1 );
      break;

    case PlaneGeometry::Sagittal:
      viewSpacing = geometry3D->GetSpacing()[0];
      slices = (unsigned int) geometry3D->GetExtent( 0 );
      break;

    default:
      itkExceptionMacro("unknown PlaneOrientation");
  }

  mitk::Vector3D normal = this->AdjustNormal( planeGeometry->GetNormal() );


  ScalarType directedExtent =
      fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
    + fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
    + fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );

  if ( directedExtent >= viewSpacing )
  {
    slices = static_cast< int >(directedExtent / viewSpacing + 0.5);
  }
  else
  {
    slices = 1;
  }

  bool flipped = (top == false);
  
  if ( frontside == false )
  {
    flipped = !flipped;
  }
  if ( planeorientation == PlaneGeometry::Frontal )
  {
    flipped = !flipped;
  }

  this->InitializeEvenlySpaced( planeGeometry, viewSpacing, slices, flipped );
}
bool mitk::SlicedGeometry3D::IsValidSlice ( int  s = 0 ) const [virtual]

Check whether a slice exists.

Definition at line 463 of file mitkSlicedGeometry3D.cpp.

Referenced by mitk::PicHelper::SetGeometry2D().

{
  return ((s >= 0) && (s < (int)m_Slices));
}
static Pointer mitk::SlicedGeometry3D::New (  ) [static]

Method for creation through the object factory.

Reimplemented from mitk::Geometry3D.

Referenced by mitk::Image::Initialize(), mitkSlicedGeometry3DTest(), mitkSliceNavigationControllerTest(), and mitk::SlicedData::SetGeometry().

void mitk::SlicedGeometry3D::PrintSelf ( std::ostream &  os,
itk::Indent  indent 
) const [protected, virtual]

Reimplemented from mitk::Geometry3D.

Definition at line 664 of file mitkSlicedGeometry3D.cpp.

{
  Superclass::PrintSelf(os,indent);
  os << indent << " EvenlySpaced: " << m_EvenlySpaced << std::endl;
  if ( m_EvenlySpaced )
  {
    os << indent << " DirectionVector: " << m_DirectionVector << std::endl;
  }
  os << indent << " Slices: " << m_Slices << std::endl;

  os << std::endl;
  os << indent << " GetGeometry2D(0): ";
  if ( this->GetGeometry2D(0) == NULL )
  {
    os << "NULL" << std::endl;
  }
  else
  {
    this->GetGeometry2D(0)->Print(os, indent);
  }
}
void mitk::SlicedGeometry3D::ReinitializePlanes ( const Point3D &  center,
const Point3D &  referencePoint 
) [protected, virtual]

Reinitialize plane stack after rotation. More precisely, the first plane of the stack needs to spatially aligned, in two respects:

1. Re-alignment with respect to the dataset center; this is necessary since the distance from the first palne to the center could otherwise continuously decrease or increase. 2. Re-alignment with respect to a given reference point; the reference point is a location which the user wants to be exactly touched by one plane of the plane stack. The first plane is minimally shifted to ensure this touching. Usually, the reference point would be the point around which the geometry is rotated.

Definition at line 294 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::GetAxisVector(), mitk::PlaneGeometry::GetNormal(), mitk::Geometry3D::GetOrigin(), mitk::Geometry3D::SetOrigin(), and mitk::PlaneGeometry::SignedDistanceFromPlane().

{
  // Need a reference frame to align the rotated planes
  if ( !m_ReferenceGeometry )
  {
    return;
  }

  // Get first plane of plane stack
  PlaneGeometry *firstPlane = 
    dynamic_cast< PlaneGeometry * >( m_Geometry2Ds[0].GetPointer() );

  // If plane stack is empty, exit
  if ( firstPlane == NULL )
  {
    return;
  }

  // Calculate the "directed" spacing when taking the plane (defined by its axes
  // vectors and normal) as the reference coordinate frame.
  //
  // This is done by calculating the radius of the ellipsoid defined by the
  // original volume spacing axes, in the direction of the respective axis of the
  // reference frame.
  mitk::Vector3D axis0 = firstPlane->GetAxisVector(0);
  mitk::Vector3D axis1 = firstPlane->GetAxisVector(1);
  mitk::Vector3D normal = firstPlane->GetNormal();
  normal.Normalize();

  Vector3D spacing;
  spacing[0] = this->CalculateSpacing( axis0 );
  spacing[1] = this->CalculateSpacing( axis1 );
  spacing[2] = this->CalculateSpacing( normal );

  Superclass::SetSpacing( spacing );

  
  // Now we need to calculate the number of slices in the plane's normal
  // direction, so that the entire volume is covered. This is done by first
  // calculating the dot product between the volume diagonal (the maximum
  // distance inside the volume) and the normal, and dividing this value by
  // the directed spacing calculated above.
  ScalarType directedExtent =
      fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
    + fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
    + fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );

  if ( directedExtent >= spacing[2] )
  {
    m_Slices = static_cast< unsigned int >(directedExtent / spacing[2] + 0.5);
  }
  else
  {
    m_Slices = 1;
  }

  // The origin of our "first plane" needs to be adapted to this new extent.
  // To achieve this, we first calculate the current distance to the volume's
  // center, and then shift the origin in the direction of the normal by the
  // difference between this distance and half of the new extent.
  double centerOfRotationDistance =
    firstPlane->SignedDistanceFromPlane( center );
    
  if ( centerOfRotationDistance > 0 )
  {
    firstPlane->SetOrigin( firstPlane->GetOrigin()
      + normal * (centerOfRotationDistance - directedExtent / 2.0)
    );
    m_DirectionVector = normal;
  }
  else
  {
    firstPlane->SetOrigin( firstPlane->GetOrigin()
      + normal * (directedExtent / 2.0 + centerOfRotationDistance)
    );
    m_DirectionVector = -normal;
  }

  // Now we adjust this distance according with respect to the given reference
  // point: we need to make sure that the point is touched by one slice of the
  // new slice stack.
  double referencePointDistance =
    firstPlane->SignedDistanceFromPlane( referencePoint );

  int referencePointSlice = static_cast< int >(
    referencePointDistance / spacing[2]);

  double alignmentValue =
    referencePointDistance / spacing[2] - referencePointSlice;

  firstPlane->SetOrigin(
    firstPlane->GetOrigin() + normal * alignmentValue * spacing[2] );

  
  // Finally, we can clear the previous geometry stack and initialize it with
  // our re-initialized "first plane".
  m_Geometry2Ds.assign( m_Slices, Geometry2D::Pointer( NULL ) );

  if ( m_Slices > 0 )
  {
    m_Geometry2Ds[0] = firstPlane;
  }

  // Reinitialize SNC with new number of slices
  m_SliceNavigationController->GetSlice()->SetSteps( m_Slices );

  this->Modified();
}
void mitk::SlicedGeometry3D::SetDirectionVector ( const mitk::Vector3D &  directionVector ) [virtual]

Set/Get the vector between slices for the evenly-spaced case (m_EvenlySpaced==true).

If the direction-vector is (0,0,0) (the default) and the first 2D geometry is a PlaneGeometry, then the direction-vector will be calculated from the plane normal.

See also:
m_DirectionVector

Definition at line 582 of file mitkSlicedGeometry3D.cpp.

{
  Vector3D diff = m_DirectionVector - directionVector;

  if ( (m_DirectionVector.GetSquaredNorm() == 0.0)
    || (diff.GetNorm() >= vnl_math::float_eps) )
  {
    m_DirectionVector = directionVector;
    m_DirectionVector.Normalize();
    this->Modified();
  }
}
void mitk::SlicedGeometry3D::SetEvenlySpaced ( bool  on = true ) [virtual]

Definition at line 570 of file mitkSlicedGeometry3D.cpp.

{
  if(m_EvenlySpaced!=on)
  {
    m_EvenlySpaced=on;
    this->Modified();
  }
}
bool mitk::SlicedGeometry3D::SetGeometry2D ( mitk::Geometry2D geometry2D,
int  s 
) [virtual]

Set Geometry2D of slice s.

Definition at line 101 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry2D::SetReferenceGeometry().

Referenced by mitk::PicHelper::SetGeometry2D().

{
  if ( this->IsValidSlice(s) )
  {
    m_Geometry2Ds[s] = geometry2D;
    m_Geometry2Ds[s]->SetReferenceGeometry( m_ReferenceGeometry );
    return true;
  }
  return false;
}
void mitk::SlicedGeometry3D::SetImageGeometry ( const bool  _arg ) [virtual]

Define that this Geometry3D is refering to an Image.

A geometry referring to an Image needs a slightly different definition of the position of the corners (see GetCornerPoint). The position of a voxel is defined by the position of its center. If we would use the origin (position of the (center of) the first voxel) as a corner and display this point, it would seem to be not at the corner but a bit within the image. Even worse for the opposite corner of the image: here the corner would appear outside the image (by half of the voxel diameter). Thus, we have to correct for this and to be able to do that, we need to know that the Geometry3D is referring to an Image.

Reimplemented from mitk::Geometry3D.

Definition at line 445 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::SetImageGeometry().

{
  Superclass::SetImageGeometry( isAnImageGeometry );

  mitk::Geometry3D* geometry;
  
  unsigned int s;
  for ( s = 0; s < m_Slices; ++s )
  {
    geometry = m_Geometry2Ds[s];
    if ( geometry!=NULL )
    {
      geometry->SetImageGeometry( isAnImageGeometry );
    }
  }
}
void mitk::SlicedGeometry3D::SetReferenceGeometry ( Geometry3D referenceGeometry ) [virtual]

Definition at line 469 of file mitkSlicedGeometry3D.cpp.

{
  m_ReferenceGeometry = referenceGeometry;

  std::vector<Geometry2D::Pointer>::iterator it;

  for ( it = m_Geometry2Ds.begin(); it != m_Geometry2Ds.end(); ++it )
  {
    (*it)->SetReferenceGeometry( referenceGeometry );
  }
}
void mitk::SlicedGeometry3D::SetSliceNavigationController ( mitk::SliceNavigationController snc ) [virtual]

Set the SliceNavigationController corresponding to this sliced geometry.

The SNC needs to be informed when the number of slices in the geometry changes, which can occur whenthe slices are re-oriented by rotation.

Definition at line 557 of file mitkSlicedGeometry3D.cpp.

void mitk::SlicedGeometry3D::SetSpacing ( const mitk::Vector3D &  aSpacing ) [virtual]

Set the spacing (m_Spacing), in direction of the plane normal.

INTERNAL METHOD.

Reimplemented from mitk::Geometry3D.

Definition at line 482 of file mitkSlicedGeometry3D.cpp.

References mitk::Geometry3D::GetAxisVector(), mitk::Geometry3D::GetBounds(), mitk::Geometry3D::GetOrigin(), and mitk::PlaneGeometry::New().

Referenced by mitk::ItkImageFileReader::GenerateData(), mitk::Image::Initialize(), mitk::Image::InitializeByItk(), mitk::SlicedData::SetSpacing(), and mitk::PicHelper::SetSpacing().

{
  bool hasEvenlySpacedPlaneGeometry = false;
  mitk::Point3D origin;
  mitk::Vector3D rightDV, bottomDV;
  BoundingBox::BoundsArrayType bounds;

  assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0);

  // In case of evenly-spaced data: re-initialize instances of Geometry2D,
  // since the spacing influences them
  if ((m_EvenlySpaced) && (m_Geometry2Ds.size() > 0))
  {
    mitk::Geometry2D::ConstPointer firstGeometry =
      m_Geometry2Ds[0].GetPointer();

    const PlaneGeometry *planeGeometry =
      dynamic_cast< const PlaneGeometry * >( firstGeometry.GetPointer() );

    if (planeGeometry != NULL )
    {
      this->WorldToIndex( planeGeometry->GetOrigin(), origin );
      this->WorldToIndex( planeGeometry->GetOrigin(),
        planeGeometry->GetAxisVector(0), rightDV );
      this->WorldToIndex( planeGeometry->GetOrigin(),
        planeGeometry->GetAxisVector(1), bottomDV );

      bounds = planeGeometry->GetBounds();
      hasEvenlySpacedPlaneGeometry = true;
    }
  }

  Superclass::SetSpacing(aSpacing);

  mitk::Geometry2D::Pointer firstGeometry;

  // In case of evenly-spaced data: re-initialize instances of Geometry2D,
  // since the spacing influences them
  if ( hasEvenlySpacedPlaneGeometry )
  {
    //create planeGeometry according to new spacing
    this->IndexToWorld( origin, origin );
    this->IndexToWorld( origin, rightDV, rightDV );
    this->IndexToWorld( origin, bottomDV, bottomDV );

    mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();

    planeGeometry->SetReferenceGeometry( m_ReferenceGeometry );
    planeGeometry->InitializeStandardPlane(
      rightDV.Get_vnl_vector(), bottomDV.Get_vnl_vector(), &m_Spacing );
    planeGeometry->SetOrigin(origin);
    planeGeometry->SetBounds(bounds);

    firstGeometry = planeGeometry;
  }
  else if ( (m_EvenlySpaced) && (m_Geometry2Ds.size() > 0) )
  {
    firstGeometry = m_Geometry2Ds[0].GetPointer();
  }

  //clear and reserve
  Geometry2D::Pointer gnull=NULL;
  m_Geometry2Ds.assign(m_Slices, gnull);

  if ( m_Slices > 0 )
  {
    m_Geometry2Ds[0] = firstGeometry;
  }

  this->Modified();
}
void mitk::SlicedGeometry3D::SetTimeBounds ( const mitk::TimeBounds timebounds ) [virtual]

Set the time bounds (in ms)

Reimplemented from mitk::Geometry3D.

Definition at line 597 of file mitkSlicedGeometry3D.cpp.

Referenced by mitk::PicHelper::InitializeEvenlySpaced().

{
  Superclass::SetTimeBounds( timebounds );

  unsigned int s;
  for ( s = 0; s < m_Slices; ++s )
  {
    if(m_Geometry2Ds[s].IsNotNull())
    {
      m_Geometry2Ds[s]->SetTimeBounds( timebounds );
    }
  }
  m_TimeBounds = timebounds;
}
void mitk::SlicedGeometry3D::UpdateInformation (  )

Re-calculate the hull of the contained geometries.

The transforms, bounding-box and time-bounds of this geometry (stored in members of the super-class Geometry3D) are re-calculated from the contained geometries.


Member Data Documentation

const std::string mitk::SlicedGeometry3D::DIRECTION_VECTOR [static]

Definition at line 183 of file mitkSlicedGeometry3D.h.

const std::string mitk::SlicedGeometry3D::EVENLY_SPACED [static]

Definition at line 184 of file mitkSlicedGeometry3D.h.

mitk::Vector3D mitk::SlicedGeometry3D::m_DirectionVector [mutable, protected]

Vector between slices for the evenly-spaced case (m_EvenlySpaced==true). If the direction-vector is (0,0,0) (the default) and the first 2D geometry is a PlaneGeometry, then the direction-vector will be calculated from the plane normal.

Definition at line 314 of file mitkSlicedGeometry3D.h.

If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored for the requested slice, and (c) the first slice (s=0) is a PlaneGeometry instance, then we calculate the geometry of the requested as the plane of the first slice shifted by m_Spacing.z*s in the direction of m_DirectionVector.

See also:
GetGeometry2D

Definition at line 306 of file mitkSlicedGeometry3D.h.

Container for the 2D-geometries contained within this SliceGeometry3D.

Definition at line 294 of file mitkSlicedGeometry3D.h.

Underlying Geometry3D for this SlicedGeometry

Definition at line 320 of file mitkSlicedGeometry3D.h.

SNC correcsponding to this geometry; used to reflect changes in the number of slices due to rotation.

Definition at line 325 of file mitkSlicedGeometry3D.h.

unsigned int mitk::SlicedGeometry3D::m_Slices [protected]

Number of slices this SliceGeometry3D is descibing.

Definition at line 317 of file mitkSlicedGeometry3D.h.

Referenced by SlicedGeometry3D().

const std::string mitk::SlicedGeometry3D::SLICES [static]

Definition at line 182 of file mitkSlicedGeometry3D.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines