Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkTimeGeometry.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 #include <mitkTimeGeometry.h>
17 
18 #include <mitkExceptionMacro.h>
19 #include <mitkGeometry3D.h>
20 
22 {
23  typedef BoundingBox::PointsContainer ContainerType;
25  m_BoundingBox->SetPoints(points.GetPointer());
26 }
27 
29 {
30 }
31 
33 {
34 }
35 
36 /* \brief short description
37  * parameters
38  *
39  */
41 {
42  assert(id >= 0);
43  assert(m_BoundingBox.IsNotNull());
44 
45  BoundingBox::BoundsArrayType bounds = m_BoundingBox->GetBounds();
46 
47  Point3D cornerpoint;
48  switch (id)
49  {
50  case 0:
51  FillVector3D(cornerpoint, bounds[0], bounds[2], bounds[4]);
52  break;
53  case 1:
54  FillVector3D(cornerpoint, bounds[0], bounds[2], bounds[5]);
55  break;
56  case 2:
57  FillVector3D(cornerpoint, bounds[0], bounds[3], bounds[4]);
58  break;
59  case 3:
60  FillVector3D(cornerpoint, bounds[0], bounds[3], bounds[5]);
61  break;
62  case 4:
63  FillVector3D(cornerpoint, bounds[1], bounds[2], bounds[4]);
64  break;
65  case 5:
66  FillVector3D(cornerpoint, bounds[1], bounds[2], bounds[5]);
67  break;
68  case 6:
69  FillVector3D(cornerpoint, bounds[1], bounds[3], bounds[4]);
70  break;
71  case 7:
72  FillVector3D(cornerpoint, bounds[1], bounds[3], bounds[5]);
73  break;
74  default:
75  {
76  itkExceptionMacro(<< "A cube only has 8 corners. These are labeled 0-7.");
77  return Point3D();
78  }
79  }
80 
81  // TimeGeometry has no Transformation. Therefore the bounding box
82  // contains all data in world coordinates
83  return cornerpoint;
84 }
85 
86 mitk::Point3D mitk::TimeGeometry::GetCornerPointInWorld(bool xFront, bool yFront, bool zFront) const
87 {
88  assert(m_BoundingBox.IsNotNull());
89  BoundingBox::BoundsArrayType bounds = m_BoundingBox->GetBounds();
90 
91  Point3D cornerpoint;
92  cornerpoint[0] = (xFront ? bounds[0] : bounds[1]);
93  cornerpoint[1] = (yFront ? bounds[2] : bounds[3]);
94  cornerpoint[2] = (zFront ? bounds[4] : bounds[5]);
95 
96  return cornerpoint;
97 }
98 
100 {
101  assert(m_BoundingBox.IsNotNull());
102  return m_BoundingBox->GetCenter();
103 }
104 
106 {
107  Vector3D diagonalvector = GetCornerPointInWorld() - GetCornerPointInWorld(false, false, false);
108  return diagonalvector.GetSquaredNorm();
109 }
110 
112 {
113  return sqrt(GetDiagonalLength2InWorld());
114 }
115 
117 {
118  return m_BoundingBox->IsInside(p);
119 }
120 
122 {
123  assert(m_BoundingBox.IsNotNull());
124  typedef BoundingBox::PointsContainer ContainerType;
125 
126  unsigned long lastModifiedTime = 0;
127  unsigned long currentModifiedTime = 0;
128 
130  points->reserve(2 * CountTimeSteps());
131  for (TimeStepType step = 0; step < CountTimeSteps(); ++step)
132  {
133  currentModifiedTime = GetGeometryForTimeStep(step)->GetMTime();
134  if (currentModifiedTime > lastModifiedTime)
135  lastModifiedTime = currentModifiedTime;
136 
137  for (int i = 0; i < 8; ++i)
138  {
139  Point3D cornerPoint = GetGeometryForTimeStep(step)->GetCornerPoint(i);
140  points->push_back(cornerPoint);
141  }
142  }
143  m_BoundingBox->SetPoints(points);
144  m_BoundingBox->ComputeBoundingBox();
145  if (this->GetMTime() < lastModifiedTime)
146  this->Modified();
147 }
148 
150 {
151  assert(direction < 3);
152  assert(m_BoundingBox.IsNotNull());
153  BoundingBox::BoundsArrayType bounds = m_BoundingBox->GetBounds();
154  return bounds[direction * 2 + 1] - bounds[direction * 2];
155 }
156 
158 {
159  this->UpdateBoundingBox();
160  this->UpdateWithoutBoundingBox();
161 }
162 
164 {
165  for (TimeStepType step = 0; step < CountTimeSteps(); ++step)
166  {
167  GetGeometryForTimeStep(step)->ExecuteOperation(op);
168  }
169 }
170 
171 void mitk::TimeGeometry::PrintSelf(std::ostream &os, itk::Indent indent) const
172 {
173  // Superclass::PrintSelf(os,indent);
174  os << indent << " TimeSteps: " << this->CountTimeSteps() << std::endl;
175 
176  os << std::endl;
177  os << indent << " GetGeometryForTimeStep(0): ";
178  if (GetGeometryForTimeStep(0).IsNull())
179  os << "NULL" << std::endl;
180  else
181  GetGeometryForTimeStep(0)->Print(os, indent);
182 }
183 
185 {
186  itk::LightObject::Pointer parent = Superclass::InternalClone();
187  Self::Pointer rval = dynamic_cast<Self *>(parent.GetPointer());
188  if (rval.IsNull())
189  {
190  mitkThrow() << " Downcast to type " << this->GetNameOfClass() << " failed.";
191  }
192  rval->m_BoundingBox = m_BoundingBox->DeepCopy();
193  return parent;
194 }
195 
196 bool mitk::Equal(const TimeGeometry &leftHandSide, const TimeGeometry &rightHandSide, ScalarType eps, bool verbose)
197 {
198  bool result = true;
199 
200  // Compare BoundingBoxInWorld
201  if (!mitk::Equal(*(leftHandSide.GetBoundingBoxInWorld()), *(rightHandSide.GetBoundingBoxInWorld()), eps, verbose))
202  {
203  if (verbose)
204  {
205  MITK_INFO << "[( TimeGeometry )] BoundingBoxInWorld differs.";
206  MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetBoundingBoxInWorld()
207  << " : leftHandSide is " << leftHandSide.GetBoundsInWorld() << " and tolerance is " << eps;
208  }
209  result = false;
210  }
211 
212  if (!mitk::Equal(leftHandSide.CountTimeSteps(), rightHandSide.CountTimeSteps(), eps, verbose))
213  {
214  if (verbose)
215  {
216  MITK_INFO << "[( TimeGeometry )] CountTimeSteps differs.";
217  MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.CountTimeSteps() << " : leftHandSide is "
218  << leftHandSide.CountTimeSteps() << " and tolerance is " << eps;
219  }
220  result = false;
221  }
222 
223  if (!mitk::Equal(leftHandSide.GetMinimumTimePoint(), rightHandSide.GetMinimumTimePoint(), eps, verbose))
224  {
225  if (verbose)
226  {
227  MITK_INFO << "[( TimeGeometry )] MinimumTimePoint differs.";
228  MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetMinimumTimePoint()
229  << " : leftHandSide is " << leftHandSide.GetMinimumTimePoint() << " and tolerance is " << eps;
230  }
231  result = false;
232  }
233 
234  if (!mitk::Equal(leftHandSide.GetMaximumTimePoint(), rightHandSide.GetMaximumTimePoint(), eps, verbose))
235  {
236  if (verbose)
237  {
238  MITK_INFO << "[( TimeGeometry )] MaximumTimePoint differs.";
239  MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.GetMaximumTimePoint()
240  << " : leftHandSide is " << leftHandSide.GetMaximumTimePoint() << " and tolerance is " << eps;
241  }
242  result = false;
243  }
244 
245  if (!result)
246  return false; // further tests require that both parts have identical number of time steps
247 
248  for (mitk::TimeStepType t = 0; t < leftHandSide.CountTimeSteps(); ++t)
249  {
250  if (!mitk::Equal(leftHandSide.TimeStepToTimePoint(t), rightHandSide.TimeStepToTimePoint(t), eps, verbose))
251  {
252  if (verbose)
253  {
254  MITK_INFO << "[( TimeGeometry )] TimeStepToTimePoint(" << t << ") differs.";
255  MITK_INFO << "rightHandSide is " << setprecision(12) << rightHandSide.TimeStepToTimePoint(t)
256  << " : leftHandSide is " << leftHandSide.TimeStepToTimePoint(t) << " and tolerance is " << eps;
257  }
258  result = false;
259  }
260 
261  BaseGeometry::Pointer leftGeometry = leftHandSide.GetGeometryForTimeStep(t);
262  BaseGeometry::Pointer rightGeometry = rightHandSide.GetGeometryForTimeStep(t);
263 
264  if (leftGeometry.IsNotNull() && rightGeometry.IsNull())
265  continue; // identical
266  if (leftGeometry.IsNull())
267  {
268  if (verbose)
269  {
270  MITK_INFO << "[( TimeGeometry )] TimeStepToTimePoint(" << t << ") differs.";
271  MITK_INFO << "rightHandSide is an object : leftHandSide is nullptr";
272  }
273  result = false;
274  continue; // next geometry
275  }
276 
277  if (rightGeometry.IsNull())
278  {
279  if (verbose)
280  {
281  MITK_INFO << "[( TimeGeometry )] TimeStepToTimePoint(" << t << ") differs.";
282  MITK_INFO << "rightHandSide is nullptr : leftHandSide is an object";
283  }
284  result = false;
285  continue; // next geometry
286  }
287 
288  if (!mitk::Equal(*leftGeometry, *rightGeometry, eps, verbose))
289  {
290  if (verbose)
291  {
292  MITK_INFO << "[( TimeGeometry )] GetGeometryForTimeStep(" << t << ") differs.";
293  }
294  result = false;
295  }
296 
297  } // end for each t
298 
299  return result;
300 }
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBox
Standard 3D-BoundingBox typedef.
itk::SmartPointer< Self > Pointer
void UpdateBoundingBox()
Updates the bounding box to cover the area used in all time steps.
#define MITK_INFO
Definition: mitkLogMacros.h:22
BoundingBox * GetBoundingBoxInWorld() const
Returns a bounding box that covers all time steps.
Base class of all Operation-classes.
Definition: mitkOperation.h:33
double ScalarType
virtual void Initialize()
Initializes the TimeGeometry.
virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override
Point3D GetCornerPointInWorld(int id) const
Get the position of the corner number id (in world coordinates)
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:110
double GetDiagonalLengthInWorld() const
Get the length of the diagonal of the bounding-box in mm.
virtual void ExecuteOperation(Operation *op) override
Executes the given operation on all time steps.
#define mitkThrow()
virtual TimePointType TimeStepToTimePoint(TimeStepType timeStep) const =0
Converts a time step to a time point.
std::vcl_size_t TimeStepType
virtual TimePointType GetMaximumTimePoint() const =0
Returns the last time point for which the object is valid.
Point< ScalarType, 3 > Point3D
Definition: mitkPoint.h:99
Point3D GetCenterInWorld() const
Get the center of the bounding-box in mm.
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.
ScalarType GetExtentInWorld(unsigned int direction) const
Returns the Extend of the bounding in the given direction.
bool IsWorldPointInside(const mitk::Point3D &p) const
Test whether the point p (world coordinates in mm) is inside the bounding box.
double GetDiagonalLength2InWorld() const
Get the squared length of the diagonal of the bounding-box in mm.
BoundingBox::BoundsArrayType GetBoundsInWorld() const
Returns the world bounds of the object that cover all time steps.
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
MITKCORE_EXPORT const ScalarType eps
virtual LightObject::Pointer InternalClone() const override
Makes a deep copy of the current object.
void Update()
Updates the geometry.
virtual TimePointType GetMinimumTimePoint() const =0
Returns the first time point for which the object is valid.
BoundingBox::Pointer m_BoundingBox
Contains a bounding box which includes all time steps.
BoundingBoxType::BoundsArrayType BoundsArrayType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.