Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkSlicedData.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 
17 #include "mitkSlicedData.h"
19 #include "mitkBaseProcess.h"
21 
22 mitk::SlicedData::SlicedData() : m_RequestedRegionInitialized(false), m_UseLargestPossibleRegion(false)
23 {
24  unsigned int i;
25  for (i = 0; i < 4; ++i)
26  {
27  m_LargestPossibleRegion.SetIndex(i, 0);
28  m_LargestPossibleRegion.SetSize(i, 1);
29  }
30 }
31 
33  : BaseData(other),
34  m_LargestPossibleRegion(other.m_LargestPossibleRegion),
35  m_RequestedRegion(other.m_RequestedRegion),
36  m_RequestedRegionInitialized(other.m_RequestedRegionInitialized),
37  m_BufferedRegion(other.m_BufferedRegion),
38  m_UseLargestPossibleRegion(other.m_UseLargestPossibleRegion)
39 {
40 }
42 {
43 }
44 
46 {
47  Superclass::UpdateOutputInformation();
48 
49  if (this->GetSource().IsNull())
50  // If we don't have a source, then let's make our Image
51  // span our buffer
52  {
53  m_UseLargestPossibleRegion = true;
54  }
55 
56  // Now we should know what our largest possible region is. If our
57  // requested region was not set yet, (or has been set to something
58  // invalid - with no data in it ) then set it to the largest possible
59  // region.
60  if (!m_RequestedRegionInitialized)
61  {
62  this->SetRequestedRegionToLargestPossibleRegion();
63  m_RequestedRegionInitialized = true;
64  }
65 
66  m_LastRequestedRegionWasOutsideOfTheBufferedRegion = 0;
67 }
68 
70 {
71  if (GetUpdateMTime() < GetPipelineMTime() || GetDataReleased())
72  {
73  ReleaseData();
74  }
75 }
76 
78 {
79  m_UseLargestPossibleRegion = true;
80  if (GetGeometry() == nullptr)
81  return;
82  unsigned int i;
83  const RegionType::IndexType &index = GetLargestPossibleRegion().GetIndex();
84  const RegionType::SizeType &size = GetLargestPossibleRegion().GetSize();
85  for (i = 0; i < RegionDimension; ++i)
86  {
87  m_RequestedRegion.SetIndex(i, index[i]);
88  m_RequestedRegion.SetSize(i, size[i]);
89  }
90 }
91 
93 {
94  // Is the requested region within the currently buffered data?
95  // SlicedData and subclasses store entire volumes or slices. The
96  // methods IsVolumeSet() and IsSliceSet are provided to check,
97  // a volume or slice, respectively, is available. Thus, these
98  // methods used here.
99  const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex();
100 
101  const SizeType &requestedRegionSize = m_RequestedRegion.GetSize();
102  const SizeType &largestPossibleRegionSize = GetLargestPossibleRegion().GetSize();
103 
104  // are whole channels requested?
105  int c, cEnd;
106  c = requestedRegionIndex[4];
107  cEnd = c + static_cast<long>(requestedRegionSize[4]);
108  if (requestedRegionSize[3] == largestPossibleRegionSize[3])
109  {
110  for (; c < cEnd; ++c)
111  if (IsChannelSet(c) == false)
112  return true;
113  return false;
114  }
115 
116  // are whole volumes requested?
117  int t, tEnd;
118  t = requestedRegionIndex[3];
119  tEnd = t + static_cast<long>(requestedRegionSize[3]);
120  if (requestedRegionSize[2] == largestPossibleRegionSize[2])
121  {
122  for (; c < cEnd; ++c)
123  for (; t < tEnd; ++t)
124  if (IsVolumeSet(t, c) == false)
125  return true;
126  return false;
127  }
128 
129  // ok, only slices are requested. Check if they are available.
130  int s, sEnd;
131  s = requestedRegionIndex[2];
132  sEnd = s + static_cast<long>(requestedRegionSize[2]);
133  for (; c < cEnd; ++c)
134  for (; t < tEnd; ++t)
135  for (; s < sEnd; ++s)
136  if (IsSliceSet(s, t, c) == false)
137  return true;
138 
139  return false;
140 }
141 
143 {
144  if (GetTimeGeometry() == nullptr)
145  return false;
146 
147  unsigned int i;
148 
149  // Is the requested region within the LargestPossibleRegion?
150  // Note that the test is indeed against the largest possible region
151  // rather than the buffered region; see DataObject::VerifyRequestedRegion.
152  const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex();
153  const IndexType &largestPossibleRegionIndex = GetLargestPossibleRegion().GetIndex();
154 
155  const SizeType &requestedRegionSize = m_RequestedRegion.GetSize();
156  const SizeType &largestPossibleRegionSize = GetLargestPossibleRegion().GetSize();
157 
158  for (i = 0; i < RegionDimension; ++i)
159  {
160  if ((requestedRegionIndex[i] < largestPossibleRegionIndex[i]) ||
161  ((requestedRegionIndex[i] + static_cast<long>(requestedRegionSize[i])) >
162  (largestPossibleRegionIndex[i] + static_cast<long>(largestPossibleRegionSize[i]))))
163  {
164  return false;
165  }
166  }
167 
168  return true;
169 }
170 
171 void mitk::SlicedData::SetRequestedRegion(const itk::DataObject *data)
172 {
173  m_UseLargestPossibleRegion = false;
174 
175  const mitk::SlicedData *slicedData = dynamic_cast<const mitk::SlicedData *>(data);
176 
177  if (slicedData)
178  {
179  m_RequestedRegion = slicedData->GetRequestedRegion();
180  m_RequestedRegionInitialized = true;
181  }
182  else
183  {
184  // pointer could not be cast back down
185  itkExceptionMacro(<< "mitk::SlicedData::SetRequestedRegion(DataObject*) cannot cast " << typeid(data).name()
186  << " to "
187  << typeid(SlicedData *).name());
188  }
189 }
190 
192 {
193  m_UseLargestPossibleRegion = false;
194 
195  if (region != nullptr)
196  {
197  m_RequestedRegion = *region;
198  m_RequestedRegionInitialized = true;
199  }
200  else
201  {
202  // pointer could not be cast back down
203  itkExceptionMacro(<< "mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType*) cannot cast "
204  << typeid(region).name()
205  << " to "
206  << typeid(SlicedData *).name());
207  }
208 }
209 
211 {
212  if (region != nullptr)
213  {
214  m_LargestPossibleRegion = *region;
215  m_UseLargestPossibleRegion = true;
216  }
217  else
218  {
219  // pointer could not be cast back down
220  itkExceptionMacro(<< "mitk::SlicedData::SetLargestPossibleRegion(SlicedData::RegionType*) cannot cast "
221  << typeid(region).name()
222  << " to "
223  << typeid(SlicedData *).name());
224  }
225 }
226 
227 void mitk::SlicedData::CopyInformation(const itk::DataObject *data)
228 {
229  // Standard call to the superclass' method
230  Superclass::CopyInformation(data);
231 
232  const mitk::SlicedData *slicedData;
233 
234  slicedData = dynamic_cast<const mitk::SlicedData *>(data);
235 
236  if (slicedData)
237  {
238  m_LargestPossibleRegion = slicedData->GetLargestPossibleRegion();
239  }
240  else
241  {
242  // pointer could not be cast back down
243  itkExceptionMacro(<< "mitk::SlicedData::CopyInformation(const DataObject *data) cannot cast " << typeid(data).name()
244  << " to "
245  << typeid(SlicedData *).name());
246  }
247 }
248 
249 // const mitk::PlaneGeometry* mitk::SlicedData::GetPlaneGeometry(int s, int t) const
250 //{
251 // const_cast<SlicedData*>(this)->SetRequestedRegionToLargestPossibleRegion();
252 //
253 // const_cast<SlicedData*>(this)->UpdateOutputInformation();
254 //
255 // return GetSlicedGeometry(t)->GetPlaneGeometry(s);
256 //}
257 //
259 {
260  if (GetTimeGeometry() == nullptr)
261  return nullptr;
262  return dynamic_cast<SlicedGeometry3D *>(GetTimeGeometry()->GetGeometryForTimeStep(t).GetPointer());
263 }
264 
266 {
267  SetRequestedRegionToLargestPossibleRegion();
268 
269  UpdateOutputInformation();
270 
271  return GetSlicedGeometry(t);
272 }
273 
275 {
276  if (aGeometry3D != nullptr)
277  {
279  SlicedGeometry3D::Pointer slicedGeometry = dynamic_cast<SlicedGeometry3D *>(aGeometry3D);
280  if (slicedGeometry.IsNull())
281  {
282  PlaneGeometry *geometry2d = dynamic_cast<PlaneGeometry *>(aGeometry3D);
283  if (geometry2d != nullptr && dynamic_cast<mitk::AbstractTransformGeometry *>(aGeometry3D) == nullptr)
284  {
285  if ((GetSlicedGeometry()->GetPlaneGeometry(0) == geometry2d) && (GetSlicedGeometry()->GetSlices() == 1))
286  return;
287  slicedGeometry = SlicedGeometry3D::New();
288  slicedGeometry->InitializeEvenlySpaced(geometry2d, 1);
289  }
290  else
291  {
292  slicedGeometry = SlicedGeometry3D::New();
293  PlaneGeometry::Pointer planeGeometry = PlaneGeometry::New();
294  planeGeometry->InitializeStandardPlane(aGeometry3D);
295  slicedGeometry->InitializeEvenlySpaced(planeGeometry, (unsigned int)(aGeometry3D->GetExtent(2)));
296  }
297  }
298  assert(slicedGeometry.IsNotNull());
299 
300  timeGeometry->Initialize(slicedGeometry, 1);
301  Superclass::SetTimeGeometry(timeGeometry);
302  }
303  else
304  {
305  if (GetGeometry() == nullptr)
306  return;
307  Superclass::SetGeometry(nullptr);
308  }
309 }
310 
311 void mitk::SlicedData::SetSpacing(const ScalarType aSpacing[3])
312 {
313  this->SetSpacing((mitk::Vector3D)aSpacing);
314 }
315 
317 {
318  TimeGeometry *timeGeometry = GetTimeGeometry();
319 
320  assert(timeGeometry != nullptr);
321 
322  mitk::SlicedGeometry3D *slicedGeometry;
323 
324  unsigned int steps = timeGeometry->CountTimeSteps();
325 
326  for (unsigned int timestep = 0; timestep < steps; ++timestep)
327  {
328  slicedGeometry = GetSlicedGeometry(timestep);
329  if (slicedGeometry != nullptr)
330  {
331  slicedGeometry->SetOrigin(origin);
332  if (slicedGeometry->GetEvenlySpaced())
333  {
334  mitk::PlaneGeometry *geometry2D = slicedGeometry->GetPlaneGeometry(0);
335  geometry2D->SetOrigin(origin);
336  slicedGeometry->InitializeEvenlySpaced(geometry2D, slicedGeometry->GetSlices());
337  }
338  }
339  // ProportionalTimeGeometry* timeGeometry = dynamic_cast<ProportionalTimeGeometry *>(GetTimeGeometry());
340  // if(timeGeometry != NULL)
341  //{
342  // timeGeometry->Initialize(slicedGeometry, steps);
343  // break;
344  //}
345  }
346 }
347 
349 {
350  TimeGeometry *timeGeometry = GetTimeGeometry();
351 
352  assert(timeGeometry != nullptr);
353 
354  unsigned int steps = timeGeometry->CountTimeSteps();
355 
356  for (unsigned int timestep = 0; timestep < steps; ++timestep)
357  {
358  mitk::SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(timestep);
359  if (slicedGeometry != nullptr)
360  {
361  slicedGeometry->SetSpacing(aSpacing);
362  }
363  }
364  timeGeometry->Update();
365 }
ScalarType GetExtent(unsigned int direction) const
Set the time bounds (in ms)
virtual void SetRequestedRegionToLargestPossibleRegion() override
virtual void SetGeometry(BaseGeometry *aGeometry3D) override
Set the BaseGeometry of the data, which will be referenced (not copied!). It has to be a sub-class of...
void SetSpacing(const mitk::Vector3D &aSpacing, bool enforceSetSpacing=false)
Set the spacing (m_Spacing).
Base of all data objects.
Definition: mitkBaseData.h:39
virtual const RegionType & GetRequestedRegion() const
static Pointer New()
double ScalarType
virtual void SetRequestedRegion(const itk::DataObject *data) override
virtual void PrepareForNewData() override
virtual void InitializeEvenlySpaced(mitk::PlaneGeometry *geometry2D, unsigned int slices)
Completely initialize this instance as evenly-spaced with slices parallel to the provided PlaneGeomet...
itk::Size< RegionDimension > SizeType
void SetLargestPossibleRegion(SlicedData::RegionType *region)
Sets the largest possible region. The largest possible region is the entire region occupied by the da...
virtual void SetOrigin(const Point3D &origin) override
Convenience method for setting the origin of the SlicedGeometry3D instances of all time steps...
virtual bool GetEvenlySpaced() const
Set/Get whether the SlicedGeometry3D is evenly-spaced (m_EvenlySpaced)
Super class of data objects consisting of slices.
itk::ImageRegion< RegionDimension > RegionType
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
virtual mitk::PlaneGeometry * GetPlaneGeometry(int s) const
Returns the PlaneGeometry of the slice (s).
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override
RegionType m_LargestPossibleRegion
const RegionType & GetLargestPossibleRegion() const
virtual unsigned int GetSlices() const
Get the number of slices.
Describes the geometry of a data object consisting of slices.
const SlicedGeometry3D * GetUpdatedSlicedGeometry(unsigned int t=0)
Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it)...
static Pointer New()
SlicedGeometry3D * GetSlicedGeometry(unsigned int t=0) const
Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it)...
Describes a two-dimensional, rectangular plane.
virtual void UpdateOutputInformation() override
virtual void SetSpacing(const ScalarType aSpacing[])
Convenience method for setting the spacing of the SlicedGeometry3D instances of all time steps...
void Update()
Updates the geometry.
virtual bool VerifyRequestedRegion() override
Verify that the RequestedRegion is within the LargestPossibleRegion.
BaseGeometry Describes the geometry of a data object.
virtual void CopyInformation(const itk::DataObject *data) override