16 #include <vtkMatrix4x4.h> 17 #include <vtkMatrixToLinearTransform.h> 34 m_FrameOfReferenceID(0),
35 m_IndexToWorldTransformLastModified(0),
36 m_ImageGeometry(false),
37 m_ModifiedLockFlag(false),
38 m_ModifiedCalledFlag(false)
47 m_FrameOfReferenceID(other.m_FrameOfReferenceID),
48 m_IndexToWorldTransformLastModified(other.m_IndexToWorldTransformLastModified),
49 m_ImageGeometry(other.m_ImageGeometry),
50 m_ModifiedLockFlag(false),
51 m_ModifiedCalledFlag(false)
59 delete m_GeometryTransform;
90 float b[6] = {0, 1, 0, 1, 0, 1};
95 m_FrameOfReferenceID = 0;
97 m_ImageGeometry =
false;
103 const float *input = bounds;
105 for (mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6; ++i)
113 const double *input = bounds;
115 for (mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6; ++i)
123 newGeometry->
SetBounds(m_BoundingBox->GetBounds());
127 newGeometry->InitializeGeometryTransformHolder(
this);
129 newGeometry->m_ImageGeometry = m_ImageGeometry;
132 void mitk::BaseGeometry::InitializeGeometryTransformHolder(
const BaseGeometry *otherGeometry)
144 m_BoundingBox = BoundingBoxType::New();
146 BoundingBoxType::PointsContainer::Pointer pointscontainer = BoundingBoxType::PointsContainer::New();
147 BoundingBoxType::PointType p;
148 BoundingBoxType::PointIdentifier pointid;
150 for (pointid = 0; pointid < 2; ++pointid)
153 for (i = 0; i < m_NDimensions; ++i)
155 p[i] = bounds[2 * i + pointid];
157 pointscontainer->InsertElement(pointid, p);
160 m_BoundingBox->SetPoints(pointscontainer);
161 m_BoundingBox->ComputeBoundingBox();
190 MITK_WARN <<
"Spacing has changed in a method, where the spacing must not change.";
197 assert(m_BoundingBox.IsNotNull());
198 return m_BoundingBox->GetBounds();
214 m_GeometryTransform->
SetSpacing(aSpacing, enforceSetSpacing);
227 assert(m_BoundingBox.IsNotNull());
228 if (direction >= m_NDimensions)
229 mitkThrow() <<
"Direction is too big. This geometry is for 3D Data";
231 return bounds[direction * 2 + 1] - bounds[direction * 2];
236 bool isConvertableWithoutLoss =
true;
241 isConvertableWithoutLoss =
false;
246 isConvertableWithoutLoss =
false;
254 if ((col0[2] != 0) || (col1[2] != 0) || (col2[0] != 0) || (col2[1] != 0) || (col2[2] != 1))
256 isConvertableWithoutLoss =
false;
261 return isConvertableWithoutLoss;
266 assert(m_BoundingBox.IsNotNull());
267 Point3D c = m_BoundingBox->GetCenter();
283 return diagonalvector.GetSquaredNorm();
302 FillVector3D(cornerpoint, bounds[0], bounds[2], bounds[4]);
305 FillVector3D(cornerpoint, bounds[0], bounds[2], bounds[5]);
308 FillVector3D(cornerpoint, bounds[0], bounds[3], bounds[4]);
311 FillVector3D(cornerpoint, bounds[0], bounds[3], bounds[5]);
314 FillVector3D(cornerpoint, bounds[1], bounds[2], bounds[4]);
317 FillVector3D(cornerpoint, bounds[1], bounds[2], bounds[5]);
320 FillVector3D(cornerpoint, bounds[1], bounds[3], bounds[4]);
323 FillVector3D(cornerpoint, bounds[1], bounds[3], bounds[5]);
327 itkExceptionMacro(<<
"A cube only has 8 corners. These are labeled 0-7.");
334 FillVector3D(cornerpoint, cornerpoint[0] - 0.5, cornerpoint[1] - 0.5, cornerpoint[2] - 0.5);
345 cornerpoint[0] = (xFront ? bounds[0] : bounds[1]);
346 cornerpoint[1] = (yFront ? bounds[2] : bounds[3]);
347 cornerpoint[2] = (zFront ? bounds[4] : bounds[5]);
352 FillVector3D(cornerpoint, cornerpoint[0] - 0.5, cornerpoint[1] - 0.5, cornerpoint[2] - 0.5);
371 AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
373 if (len > extentInMM)
374 vnlmatrix.set_column(direction, vnlmatrix.get_column(direction) / len * extentInMM);
376 vnlmatrix.set_column(direction, vnlmatrix.get_column(direction) * extentInMM / len);
400 discretIndex[0] = itk::Math::RoundHalfIntegerUp<mitk::ScalarType>(index[0]);
401 discretIndex[1] = itk::Math::RoundHalfIntegerUp<mitk::ScalarType>(index[1]);
402 discretIndex[2] = itk::Math::RoundHalfIntegerUp<mitk::ScalarType>(index[2]);
410 if ((discretIndex[0] == bounds[1]) || (discretIndex[1] == bounds[3]) || (discretIndex[2] == bounds[5]))
424 tempIn = pt_mm.GetVectorFromOrigin() -
offset;
436 if (!m_InvertedTransform)
438 m_InvertedTransform = TransformType::New();
442 itkExceptionMacro(
"Internal ITK matrix inversion error, cannot proceed.");
448 const TransformType::MatrixType &inverse = m_InvertedTransform->GetMatrix();
449 if (inverse.GetVnlMatrix().has_nans())
451 itkExceptionMacro(
"Internal ITK matrix inversion error, cannot proceed. Matrix was: " 454 <<
"Suggested inverted matrix is:" 459 vec_units = inverse * vec_mm;
466 MITK_WARN <<
"Warning! Call of the deprecated function BaseGeometry::WorldToIndex(point, vec, vec). Use " 467 "BaseGeometry::WorldToIndex(vec, vec) instead!";
492 m_GeometryTransform->
Compose(other, pre);
498 mitk::BaseGeometry::TransformType::Pointer itkTransform = mitk::BaseGeometry::TransformType::New();
505 if ((vector[0] != 0) || (vector[1] != 0) || (vector[2] != 0))
525 vtkTransform *vtktransform = vtkTransform::New();
534 if (pointOp ==
nullptr)
536 MITK_ERROR <<
"Point move operation is null!";
541 vtktransform->GetPosition(data);
542 vtktransform->PostMultiply();
543 vtktransform->Translate(newPos[0], newPos[1], newPos[2]);
544 vtktransform->PreMultiply();
550 if (scaleOp ==
nullptr)
564 vtktransform->PostMultiply();
565 vtktransform->Translate(-anchor[0], -anchor[1], -anchor[2]);
566 vtktransform->Scale(scalefactor[0], scalefactor[1], scalefactor[2]);
567 vtktransform->Translate(anchor[0], anchor[1], anchor[2]);
573 if (rotateOp ==
nullptr)
578 Vector3D rotationVector = rotateOp->GetVectorOfRotation();
579 Point3D center = rotateOp->GetCenterOfRotation();
580 ScalarType angle = rotateOp->GetAngleOfRotation();
581 vtktransform->PostMultiply();
582 vtktransform->Translate(-center[0], -center[1], -center[2]);
583 vtktransform->RotateWXYZ(angle, rotationVector[0], rotationVector[1], rotationVector[2]);
584 vtktransform->Translate(center[0], center[1], center[2]);
585 vtktransform->PreMultiply();
591 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
593 dynamic_cast<mitk::RestorePlanePositionOperation *>(operation)->GetTransform().GetPointer(), matrix);
594 vtktransform->SetMatrix(matrix);
601 vtktransform->SetMatrix(applyMatrixOp->GetMatrix());
605 vtktransform->Delete();
610 vtktransform->Delete();
621 mitk::BoundingBox::PointsContainer::Pointer pointscontainer = mitk::BoundingBox::PointsContainer::New();
623 mitk::BoundingBox::PointIdentifier pointid = 0;
626 if (transform !=
nullptr)
628 mitk::AffineTransform3D::Pointer inverse = mitk::AffineTransform3D::New();
629 transform->GetInverse(inverse);
630 for (i = 0; i < 8; ++i)
631 pointscontainer->InsertElement(pointid++, inverse->TransformPoint(
GetCornerPoint(i)));
635 for (i = 0; i < 8; ++i)
639 mitk::BoundingBox::Pointer result = mitk::BoundingBox::New();
640 result->SetPoints(pointscontainer);
641 result->ComputeBoundingBox();
648 std::ostringstream out;
652 for (
int i = 0; i < 3; ++i)
655 for (
int j = 0; j < 3; ++j)
656 out << transformType->GetMatrix().GetVnlMatrix().get(i, j) <<
' ';
662 for (
int i = 0; i < 3; ++i)
663 out << transformType->GetOffset()[i] <<
' ';
684 MITK_WARN <<
"Warning! Call of the deprecated function BaseGeometry::IndexToWorld(point, vec, vec). Use " 685 "BaseGeometry::IndexToWorld(vec, vec) instead!";
697 return m_BoundingBox.IsNull();
712 if (m_ImageGeometry == isAnImageGeometry)
718 FillVector3D(originIndex, boundsarray[0], boundsarray[2], boundsarray[4]);
720 if (isAnImageGeometry ==
true)
721 FillVector3D(originIndex, originIndex[0] + 0.5, originIndex[1] + 0.5, originIndex[2] + 0.5);
723 FillVector3D(originIndex, originIndex[0] - 0.5, originIndex[1] - 0.5, originIndex[2] - 0.5);
737 os << indent <<
" IndexToWorldTransform: ";
739 os <<
"nullptr" << std::endl;
745 os << indent <<
"Matrix: " << std::endl;
746 for (i = 0; i < 3; i++)
748 os << indent.GetNextIndent();
749 for (j = 0; j < 3; j++)
760 os << indent <<
"Inverse: " << std::endl;
761 for (i = 0; i < 3; i++)
763 os << indent.GetNextIndent();
764 for (j = 0; j < 3; j++)
772 os << indent <<
"Scale : ";
773 for (i = 0; i < 3; i++)
780 os << indent <<
" BoundingBox: ";
782 os <<
"nullptr" << std::endl;
785 os << indent <<
"( ";
786 for (
unsigned int i = 0; i < 3; i++)
790 os <<
" )" << std::endl;
793 os << indent <<
" Origin: " << this->
GetOrigin() << std::endl;
794 os << indent <<
" ImageGeometry: " << this->
GetImageGeometry() << std::endl;
795 os << indent <<
" Spacing: " << this->
GetSpacing() << std::endl;
800 if (!m_ModifiedLockFlag)
801 Superclass::Modified();
803 m_ModifiedCalledFlag =
true;
818 return m_GeometryTransform;
826 if ((leftHandSide ==
nullptr) || (rightHandSide ==
nullptr))
828 MITK_ERROR <<
"mitk::Equal( const mitk::Geometry3D::BoundingBoxType *leftHandSide, const " 829 "mitk::Geometry3D::BoundingBoxType *rightHandSide, ScalarType eps, bool verbose ) does not with nullptr " 833 return Equal(*leftHandSide, *rightHandSide, eps, verbose);
845 BaseGeometry::BoundsArrayType::Iterator itLeft = leftBounds.Begin();
846 for (BaseGeometry::BoundsArrayType::Iterator itRight = rightBounds.Begin(); itRight != rightBounds.End(); ++itRight)
852 MITK_INFO <<
"[( Geometry3D::BoundingBoxType )] bounds are not equal.";
853 MITK_INFO <<
"rightHandSide is " << setprecision(12) << *itRight <<
" : leftHandSide is " << *itLeft
854 <<
" and tolerance is " <<
eps;
868 if ((leftHandSide ==
nullptr) || (rightHandSide ==
nullptr))
870 MITK_ERROR <<
"mitk::Equal(const mitk::Geometry3D *leftHandSide, const mitk::Geometry3D *rightHandSide, ScalarType " 871 "eps, bool verbose) does not with nullptr pointer input.";
874 return Equal(*leftHandSide, *rightHandSide, eps, verbose);
889 MITK_INFO <<
"[( Geometry3D )] Spacing differs.";
890 MITK_INFO <<
"rightHandSide is " << setprecision(12) << rightHandSide.
GetSpacing() <<
" : leftHandSide is " 901 MITK_INFO <<
"[( Geometry3D )] Origin differs.";
902 MITK_INFO <<
"rightHandSide is " << setprecision(12) << rightHandSide.
GetOrigin() <<
" : leftHandSide is " 903 << leftHandSide.
GetOrigin() <<
" and tolerance is " <<
eps;
909 for (
unsigned int i = 0; i < 3; ++i)
915 MITK_INFO <<
"[( Geometry3D )] AxisVector #" << i <<
" differ";
916 MITK_INFO <<
"rightHandSide is " << setprecision(12) << rightHandSide.
GetAxisVector(i) <<
" : leftHandSide is " 926 MITK_INFO <<
"[( Geometry3D )] Extent #" << i <<
" differ";
927 MITK_INFO <<
"rightHandSide is " << setprecision(12) << rightHandSide.
GetExtent(i) <<
" : leftHandSide is " 928 << leftHandSide.
GetExtent(i) <<
" and tolerance is " <<
eps;
939 MITK_INFO <<
"[( Geometry3D )] GetImageGeometry is different.";
951 MITK_INFO <<
"[( Geometry3D )] GetFrameOfReferenceID is different.";
977 if ((leftHandSide ==
nullptr) || (rightHandSide ==
nullptr))
979 MITK_ERROR <<
"mitk::Equal(const Geometry3D::TransformType *leftHandSide, const Geometry3D::TransformType " 980 "*rightHandSide, ScalarType eps, bool verbose ) does not with nullptr pointer input.";
983 return Equal(*leftHandSide, *rightHandSide, eps, verbose);
996 MITK_INFO <<
"[( Geometry3D::TransformType )] Index to World Transformation matrix differs.";
997 MITK_INFO <<
"rightHandSide is " << setprecision(12) << rightHandSide.GetMatrix() <<
" : leftHandSide is " 998 << leftHandSide.GetMatrix() <<
" and tolerance is " <<
eps;
void TransferVtkMatrixToItkTransform(const vtkMatrix4x4 *vtkmatrix, TTransformType *itkTransform)
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBoxType
void IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
Convert (continuous or discrete) index coordinates of a vector vec_units to world coordinates (in mm)...
virtual bool GetImageGeometry() const
Is this an ImageGeometry?
vtkMatrix4x4 * GetVtkMatrix()
void SetSpacing(const mitk::Vector3D &aSpacing, bool enforceSetSpacing=false)
Set the spacing (m_Spacing).
void SetIndexToWorldTransformWithoutChangingSpacing(mitk::AffineTransform3D *transform)
void SetIndexToWorldTransform(mitk::AffineTransform3D *transform)
bool MatrixEqualElementWise(const vnl_matrix_fixed< TCoordRep, NRows, NCols > &matrix1, const vnl_matrix_fixed< TCoordRep, NRows, NCols > &matrix2, mitk::ScalarType epsilon=mitk::eps)
Check for element-wise matrix equality with a user defined accuracy.
bool IsBoundingBoxNull() const
BoundingBoxType::BoundsArrayType BoundsArrayType
Vector3D GetAxisVector(unsigned int direction) const
Get vector along bounding-box in the specified direction in mm.
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Base class of all Operation-classes.
vnl_vector< ScalarType > VnlVector
bool IsIndexInside(const mitk::Point3D &index) const
Test whether the point p ((continous!)index coordinates in units) is inside the bounding box...
void SetIdentity()
Set the transform to identity, the spacing to 1 and origin to 0.
vtkLinearTransform * GetVtkTransform() const
Get the m_IndexToWorldTransform as a vtkLinearTransform.
bool IsInside(const mitk::Point3D &p) const
Test whether the point p (world coordinates in mm) is inside the bounding box.
void _SetSpacing(const mitk::Vector3D &aSpacing, bool enforceSetSpacing=false)
double GetDiagonalLength2() const
Get the squared length of the diagonal of the bounding-box in mm.
GeometryTransformHolder::TransformType TransformType
ModifiedLock manages the calls of Modified() functions.
ScalarType GetExtent(unsigned int direction) const
Set the time bounds (in ms)
DataCollection - Class to facilitate loading/accessing structured data.
Point3D GetCornerPoint(int id) const
Get the position of the corner number id (in world coordinates)
void TransferItkTransformToVtkMatrix(const TTransformType *itkTransform, vtkMatrix4x4 *vtkmatrix)
void Initialize()
Initialize the BaseGeometry.
Constants for most interaction classes, due to the generic StateMachines.
Point3D GetCenter() const
Get the center of the bounding-box in mm.
void Translate(const Vector3D &vector)
Translate the origin by a vector.
virtual void CheckIndexToWorldTransform(mitk::AffineTransform3D *)
CheckIndexToWorldTransform.
abstract class, that can be used by Undo to undo an operation.
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
ScalarType GetExtentInMM(int direction) const
Get the extent of the bounding-box in the specified direction in mm.
const GeometryTransformHolder * GetGeometryTransformHolder() const
void Compose(const TransformType *other, bool pre=false)
Compose new IndexToWorldTransform with a given transform.
virtual void CheckBounds(const BoundsArrayType &)
CheckBounds.
void InitializeGeometry(Self *newGeometry) const
virtual void PreSetSpacing(const mitk::Vector3D &)
PreSetSpacing.
static const std::string GetTransformAsString(TransformType *transformType)
void SetVtkMatrixDeepCopy(vtkTransform *vtktransform)
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
void Modified() const override
Overload of function Modified() to prohibit several calls of Modified() using the ModifiedLock class...
Operation that handles all actions on one Point.
bool IsIndexToWorldTransformNull() const
itk::AffineGeometryFrame< ScalarType, 3 >::TransformType AffineTransform3D
virtual unsigned int GetFrameOfReferenceID() const
Get the DICOM FrameOfReferenceID referring to the used world coordinate system.
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
virtual bool IsValid() const
Is this BaseGeometry in a state that is valid?
virtual void ChangeImageGeometryConsideringOriginOffset(const bool isAnImageGeometry)
When switching from an Image Geometry to a normal Geometry (and the other way around), you have to.
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
void SetBounds(const BoundsArrayType &bounds)
Set the bounding box (in index/unit coordinates)
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
The ScaleOperation is an operation to scale any mitk::BaseGeometry.
void SetExtentInMM(int direction, ScalarType extentInMM)
Set the extent of the bounding-box in the specified direction in mm.
double GetDiagonalLength() const
Get the length of the diagonal of the bounding-box in mm.
void SetIndexToWorldTransformByVtkMatrix(vtkMatrix4x4 *vtkmatrix)
Convenience method for setting the ITK transform (m_IndexToWorldTransform) via an vtkMatrix4x4...
VnlVector GetOriginVnl() const
Get the origin as VnlVector.
virtual void SetFrameOfReferenceID(unsigned int _arg)
Set the DICOM FrameOfReferenceID referring to the used world coordinate system.
mitk::BoundingBox::Pointer CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D *transform) const
Calculates a bounding-box around the geometry relative to a coordinate system defined by a transform...
MITKCORE_EXPORT const ScalarType eps
void SetIndexToWorldTransformByVtkMatrixWithoutChangingSpacing(vtkMatrix4x4 *vtkmatrix)
Convenience method for setting the ITK transform (m_IndexToWorldTransform) via an vtkMatrix4x4...
OperationType GetOperationType()
virtual bool Is2DConvertable()
Checks, if the given geometry can be converted to 2D without information loss e.g. when a 2D image is saved, the matrix is usually cropped to 2x2, and when you load it back to MITK it will be filled with standard values. This function checks, if information would be lost during this procedure.
Operation, that holds everything necessary for an rotation operation on mitk::BaseData.
const BoundsArrayType GetBounds() const
virtual void SetImageGeometry(bool _arg)
Define that this BaseGeometry is refering to an Image.
BaseGeometry Describes the geometry of a data object.
void ExecuteOperation(Operation *operation) override
executes affine operations (translate, rotate, scale)
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.
VnlVector GetMatrixColumn(unsigned int direction) const
Get a VnlVector along bounding-box in the specified direction, length is spacing. ...
BoundingBoxType::BoundsArrayType BoundsArrayType
void SetFloatBounds(const float bounds[6])
Set the bounding box (in index/unit coordinates) via a float array.
virtual const BoundingBoxType * GetBoundingBox()