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