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