Medical Imaging Interaction Toolkit  2018.4.99-b7f3afaa
Medical Imaging Interaction Toolkit
mitkDataStorage.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 "mitkDataStorage.h"
14 
15 #include "itkCommand.h"
16 #include "itkMutexLockHolder.h"
17 #include "mitkDataNode.h"
18 #include "mitkGroupTagProperty.h"
19 #include "mitkImage.h"
20 #include "mitkNodePredicateBase.h"
22 #include "mitkProperties.h"
24 
25 mitk::DataStorage::DataStorage() : itk::Object(), m_BlockNodeModifiedEvents(false)
26 {
27 }
28 
30 {
32  // SetOfObjects::ConstPointer all = this->GetAll();
33  // for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
34  // this->RemoveListeners(it->Value());
35  // m_NodeModifiedObserverTags.clear();
36  // m_NodeDeleteObserverTags.clear();
37 }
38 
40 {
41  DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New();
42  if (parent != nullptr) //< Return empty set if parent is null
43  parents->InsertElement(0, parent);
44  this->Add(node, parents);
45 }
46 
48 {
49  if (nodes == nullptr)
50  return;
51  for (DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); it++)
52  this->Remove(it.Value());
53 }
54 
55 mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::GetSubset(const NodePredicateBase *condition) const
56 {
57  DataStorage::SetOfObjects::ConstPointer result = this->FilterSetOfObjects(this->GetAll(), condition);
58  return result;
59 }
60 
62 
63 {
64  if (name == nullptr)
65  return nullptr;
66 
69  DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(p);
70  if (rs->Size() >= 1)
71  return rs->GetElement(0);
72  else
73  return nullptr;
74 }
75 
77 {
78  if (condition == nullptr)
79  return nullptr;
80 
81  DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(condition);
82  if (rs->Size() >= 1)
83  return rs->GetElement(0);
84  else
85  return nullptr;
86 }
87 
89  const DataNode *sourceNode,
90  bool onlyDirectDerivations) const
91 {
92  if (name == nullptr)
93  return nullptr;
94 
97  DataStorage::SetOfObjects::ConstPointer rs = this->GetDerivations(sourceNode, p, onlyDirectDerivations);
98  if (rs->Size() >= 1)
99  return rs->GetElement(0);
100  else
101  return nullptr;
102 }
103 
104 void mitk::DataStorage::PrintSelf(std::ostream &os, itk::Indent indent) const
105 {
106  // Superclass::PrintSelf(os, indent);
107  DataStorage::SetOfObjects::ConstPointer all = this->GetAll();
108  os << indent << "DataStorage " << this << " is managing " << all->Size() << " objects. List of objects:" << std::endl;
109  for (DataStorage::SetOfObjects::ConstIterator allIt = all->Begin(); allIt != all->End(); allIt++)
110  {
111  std::string name;
112  allIt.Value()->GetName(name);
113  std::string datatype;
114  if (allIt.Value()->GetData() != nullptr)
115  datatype = allIt.Value()->GetData()->GetNameOfClass();
116  os << indent << " " << allIt.Value().GetPointer() << "<" << datatype << ">: " << name << std::endl;
117  DataStorage::SetOfObjects::ConstPointer parents = this->GetSources(allIt.Value());
118  if (parents->Size() > 0)
119  {
120  os << indent << " Direct sources: ";
121  for (DataStorage::SetOfObjects::ConstIterator parentIt = parents->Begin(); parentIt != parents->End();
122  parentIt++)
123  os << parentIt.Value().GetPointer() << ", ";
124  os << std::endl;
125  }
126  DataStorage::SetOfObjects::ConstPointer derivations = this->GetDerivations(allIt.Value());
127  if (derivations->Size() > 0)
128  {
129  os << indent << " Direct derivations: ";
130  for (DataStorage::SetOfObjects::ConstIterator derivationIt = derivations->Begin();
131  derivationIt != derivations->End();
132  derivationIt++)
133  os << derivationIt.Value().GetPointer() << ", ";
134  os << std::endl;
135  }
136  }
137  os << std::endl;
138 }
139 
140 mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::FilterSetOfObjects(const SetOfObjects *set,
141  const NodePredicateBase *condition) const
142 {
143  if (set == nullptr)
144  return nullptr;
145 
146  DataStorage::SetOfObjects::Pointer result = DataStorage::SetOfObjects::New();
147  for (DataStorage::SetOfObjects::ConstIterator it = set->Begin(); it != set->End(); it++)
148  if (condition == nullptr ||
149  condition->CheckNode(it.Value()) ==
150  true) // alway copy the set, otherwise the iterator in DataStorage::Remove() will crash
151  result->InsertElement(result->Size(), it.Value());
152 
153  return DataStorage::SetOfObjects::ConstPointer(result);
154 }
155 
157 {
158  DataNode::GroupTagList result;
159  SetOfObjects::ConstPointer all = this->GetAll();
160  if (all.IsNull())
161  return result;
162 
163  for (DataStorage::SetOfObjects::ConstIterator nodeIt = all->Begin(); nodeIt != all->End();
164  nodeIt++) // for each node
165  {
166  PropertyList *pl = nodeIt.Value()->GetPropertyList();
167  for (auto propIt = pl->GetMap()->begin(); propIt != pl->GetMap()->end();
168  ++propIt)
169  if (dynamic_cast<GroupTagProperty *>(propIt->second.GetPointer()) != nullptr)
170  result.insert(propIt->first);
171  }
172 
173  return result;
174 }
175 
177 {
178  AddNodeEvent.Send(node);
179 }
180 
182 {
183  RemoveNodeEvent.Send(node);
184 }
185 
186 void mitk::DataStorage::OnNodeInteractorChanged(itk::Object *caller, const itk::EventObject &)
187 {
188  const auto *_Node = dynamic_cast<const DataNode *>(caller);
189  if (_Node)
190  {
192  }
193 }
194 
195 void mitk::DataStorage::OnNodeModifiedOrDeleted(const itk::Object *caller, const itk::EventObject &event)
196 {
198  return;
199 
200  const auto *_Node = dynamic_cast<const DataNode *>(caller);
201  if (_Node)
202  {
203  const auto *modEvent = dynamic_cast<const itk::ModifiedEvent *>(&event);
204  if (modEvent)
205  ChangedNodeEvent.Send(_Node);
206  else
207  DeleteNodeEvent.Send(_Node);
208  }
209 }
210 
212 {
214  // node must not be 0 and must not be yet registered
215  auto *NonConstNode = const_cast<DataNode *>(_Node);
216  if (_Node && m_NodeModifiedObserverTags.find(NonConstNode) == m_NodeModifiedObserverTags.end())
217  {
218  itk::MemberCommand<DataStorage>::Pointer nodeModifiedCommand = itk::MemberCommand<DataStorage>::New();
219  nodeModifiedCommand->SetCallbackFunction(this, &DataStorage::OnNodeModifiedOrDeleted);
220  m_NodeModifiedObserverTags[NonConstNode] = NonConstNode->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand);
221 
222  itk::MemberCommand<DataStorage>::Pointer interactorChangedCommand =
223  itk::MemberCommand<DataStorage>::New();
224  interactorChangedCommand->SetCallbackFunction(this, &DataStorage::OnNodeInteractorChanged);
226  NonConstNode->AddObserver(DataNode::InteractorChangedEvent(), interactorChangedCommand);
227 
228  // add itk delete listener on datastorage
229  itk::MemberCommand<DataStorage>::Pointer deleteCommand = itk::MemberCommand<DataStorage>::New();
230  deleteCommand->SetCallbackFunction(this, &DataStorage::OnNodeModifiedOrDeleted);
231  // add observer
232  m_NodeDeleteObserverTags[NonConstNode] = NonConstNode->AddObserver(itk::DeleteEvent(), deleteCommand);
233  }
234 }
235 
237 {
239  // node must not be 0 and must be registered
240  auto *NonConstNode = const_cast<DataNode *>(_Node);
241  if (_Node && m_NodeModifiedObserverTags.find(NonConstNode) != m_NodeModifiedObserverTags.end())
242  {
243  // const cast is bad! but sometimes it is necessary. removing an observer does not really
244  // touch the internal state
245  NonConstNode->RemoveObserver(m_NodeModifiedObserverTags.find(NonConstNode)->second);
246  NonConstNode->RemoveObserver(m_NodeDeleteObserverTags.find(NonConstNode)->second);
247  NonConstNode->RemoveObserver(m_NodeInteractorChangedObserverTags.find(NonConstNode)->second);
248 
249  m_NodeModifiedObserverTags.erase(NonConstNode);
250  m_NodeDeleteObserverTags.erase(NonConstNode);
251  m_NodeInteractorChangedObserverTags.erase(NonConstNode);
252  }
253 }
254 
256  const char *boolPropertyKey,
257  const BaseRenderer *renderer,
258  const char *boolPropertyKey2) const
259 {
260  if (input == nullptr)
261  throw std::invalid_argument("DataStorage: input is invalid");
262 
263  BoundingBox::PointsContainer::Pointer pointscontainer = BoundingBox::PointsContainer::New();
264 
265  BoundingBox::PointIdentifier pointid = 0;
266  Point3D point;
267 
268  Vector3D minSpacing;
269  minSpacing.Fill(itk::NumericTraits<ScalarType>::max());
270 
272  ScalarType stmin = itk::NumericTraits<ScalarType>::NonpositiveMin();
273 
274  std::set<ScalarType> existingTimePoints;
275  ScalarType maximalTime = 0;
276 
277  // Needed for check of zero bounding boxes
278  ScalarType nullpoint[] = {0, 0, 0, 0, 0, 0};
279  BoundingBox::BoundsArrayType itkBoundsZero(nullpoint);
280 
281  for (SetOfObjects::ConstIterator it = input->Begin(); it != input->End(); ++it)
282  {
283  DataNode::Pointer node = it->Value();
284  if ((node.IsNotNull()) && (node->GetData() != nullptr) && (node->GetData()->IsEmpty() == false) &&
285  node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer))
286  {
287  const TimeGeometry *timeGeometry = node->GetData()->GetUpdatedTimeGeometry();
288 
289  if (timeGeometry != nullptr)
290  {
291  // bounding box (only if non-zero)
292  BoundingBox::BoundsArrayType itkBounds = timeGeometry->GetBoundingBoxInWorld()->GetBounds();
293  if (itkBounds == itkBoundsZero)
294  {
295  continue;
296  }
297 
298  unsigned char i;
299  for (i = 0; i < 8; ++i)
300  {
301  point = timeGeometry->GetCornerPointInWorld(i);
302  if (point[0] * point[0] + point[1] * point[1] + point[2] * point[2] < large)
303  pointscontainer->InsertElement(pointid++, point);
304  else
305  {
306  itkGenericOutputMacro(<< "Unrealistically distant corner point encountered. Ignored. Node: " << node);
307  }
308  }
309  try
310  {
311  // time bounds
312  // iterate over all time steps
313  // Attention: Objects with zero bounding box are not respected in time bound calculation
314  for (TimeStepType i = 0; i < timeGeometry->CountTimeSteps(); i++)
315  {
316  // We must not use 'node->GetData()->GetGeometry(i)->GetSpacing()' here, as it returns the spacing
317  // in its original space, which, in case of an image geometry, can have the values in different
318  // order than in world space. For the further calculations, we need to have the spacing values
319  // in world coordinate order (sag-cor-ax).
320  Vector3D spacing;
321  spacing.Fill(1.0);
322  node->GetData()->GetGeometry(i)->IndexToWorld(spacing, spacing);
323  for (int axis = 0; axis < 3; ++ axis)
324  {
325  ScalarType space = std::abs(spacing[axis]);
326  if (space < minSpacing[axis])
327  {
328  minSpacing[axis] = space;
329  }
330  }
331 
332  const auto curTimeBounds = timeGeometry->GetTimeBounds(i);
333  if ((curTimeBounds[0] > stmin) && (curTimeBounds[0] < stmax))
334  {
335  existingTimePoints.insert(curTimeBounds[0]);
336  }
337  if ((curTimeBounds[1] > maximalTime) && (curTimeBounds[1] < stmax))
338  {
339  maximalTime = curTimeBounds[1];
340  }
341  }
342  }
343  catch ( const itk::ExceptionObject &e )
344  {
345  MITK_ERROR << e.GetDescription() << std::endl;
346  }
347  }
348  }
349  }
350 
351  BoundingBox::Pointer result = BoundingBox::New();
352  result->SetPoints(pointscontainer);
353  result->ComputeBoundingBox();
354 
355  // compute the number of time steps
356  if (existingTimePoints.empty()) // make sure that there is at least one time sliced geometry in the data storage
357  {
358  existingTimePoints.insert(0.0);
359  maximalTime = 1.0;
360  }
361 
362  ArbitraryTimeGeometry::Pointer timeGeometry = nullptr;
363  if (result->GetPoints()->Size() > 0)
364  {
365  // Initialize a geometry of a single time step
367  geometry->Initialize();
368  // correct bounding-box (is now in mm, should be in index-coordinates)
369  // according to spacing
370  BoundingBox::BoundsArrayType bounds = result->GetBounds();
371  AffineTransform3D::OutputVectorType offset;
372  for (int i = 0; i < 3; ++i)
373  {
374  offset[i] = bounds[i * 2];
375  bounds[i * 2] = 0.0;
376  bounds[i * 2 + 1] = (bounds[i * 2 + 1] - offset[i]) / minSpacing[i];
377  }
378  geometry->GetIndexToWorldTransform()->SetOffset(offset);
379  geometry->SetBounds(bounds);
380  geometry->SetSpacing(minSpacing);
381 
382  // Initialize the time sliced geometry
383  auto tsIterator = existingTimePoints.cbegin();
384  auto tsPredecessor = tsIterator++;
385  auto tsEnd = existingTimePoints.cend();
386  timeGeometry = ArbitraryTimeGeometry::New();
387  for (; tsIterator != tsEnd; ++tsIterator, ++tsPredecessor)
388  {
389  timeGeometry->AppendNewTimeStep(geometry, *tsPredecessor, *tsIterator);
390  }
391  timeGeometry->AppendNewTimeStep(geometry, *tsPredecessor, maximalTime);
392 
393  timeGeometry->Update();
394  }
395  return timeGeometry.GetPointer();
396 }
397 
399  const BaseRenderer *renderer,
400  const char *boolPropertyKey2) const
401 {
402  return this->ComputeBoundingGeometry3D(this->GetAll(), boolPropertyKey, renderer, boolPropertyKey2);
403 }
404 
406  const char *boolPropertyKey)
407 {
408  return ComputeBoundingGeometry3D("visible", renderer, boolPropertyKey);
409 }
410 
411 mitk::BoundingBox::Pointer mitk::DataStorage::ComputeBoundingBox(const char *boolPropertyKey,
412  const BaseRenderer *renderer,
413  const char *boolPropertyKey2)
414 {
415  BoundingBox::PointsContainer::Pointer pointscontainer = BoundingBox::PointsContainer::New();
416 
417  BoundingBox::PointIdentifier pointid = 0;
418  Point3D point;
419 
420  // Needed for check of zero bounding boxes
421  ScalarType nullpoint[] = {0, 0, 0, 0, 0, 0};
422  BoundingBox::BoundsArrayType itkBoundsZero(nullpoint);
423 
424  SetOfObjects::ConstPointer all = this->GetAll();
425  for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
426  {
427  DataNode::Pointer node = it->Value();
428  if ((node.IsNotNull()) && (node->GetData() != nullptr) && (node->GetData()->IsEmpty() == false) &&
429  node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer))
430  {
431  const TimeGeometry *geometry = node->GetData()->GetUpdatedTimeGeometry();
432  if (geometry != nullptr)
433  {
434  // bounding box (only if non-zero)
435  BoundingBox::BoundsArrayType itkBounds = geometry->GetBoundingBoxInWorld()->GetBounds();
436  if (itkBounds == itkBoundsZero)
437  {
438  continue;
439  }
440 
441  unsigned char i;
442  for (i = 0; i < 8; ++i)
443  {
444  point = geometry->GetCornerPointInWorld(i);
445  if (point[0] * point[0] + point[1] * point[1] + point[2] * point[2] < large)
446  pointscontainer->InsertElement(pointid++, point);
447  else
448  {
449  itkGenericOutputMacro(<< "Unrealistically distant corner point encountered. Ignored. Node: " << node);
450  }
451  }
452  }
453  }
454  }
455 
456  BoundingBox::Pointer result = BoundingBox::New();
457  result->SetPoints(pointscontainer);
458  result->ComputeBoundingBox();
459 
460  return result;
461 }
462 
464  const BaseRenderer *renderer,
465  const char *boolPropertyKey2)
466 {
467  TimeBounds timeBounds;
468 
469  ScalarType stmin, stmax, cur;
470 
471  stmin = itk::NumericTraits<ScalarType>::NonpositiveMin();
473 
474  timeBounds[0] = stmax;
475  timeBounds[1] = stmin;
476 
477  SetOfObjects::ConstPointer all = this->GetAll();
478  for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
479  {
480  DataNode::Pointer node = it->Value();
481  if ((node.IsNotNull()) && (node->GetData() != nullptr) && (node->GetData()->IsEmpty() == false) &&
482  node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer))
483  {
484  const TimeGeometry *geometry = node->GetData()->GetUpdatedTimeGeometry();
485  if (geometry != nullptr)
486  {
487  const TimeBounds &curTimeBounds = geometry->GetTimeBounds();
488  cur = curTimeBounds[0];
489  // is it after -infinity, but before everything else that we found until now?
490  if ((cur > stmin) && (cur < timeBounds[0]))
491  timeBounds[0] = cur;
492 
493  cur = curTimeBounds[1];
494  // is it before infinity, but after everything else that we found until now?
495  if ((cur < stmax) && (cur > timeBounds[1]))
496  timeBounds[1] = cur;
497  }
498  }
499  }
500  if (!(timeBounds[0] < stmax))
501  {
502  timeBounds[0] = stmin;
503  timeBounds[1] = stmax;
504  }
505  return timeBounds;
506 }
507 
509 {
511 }
512 
513 mitk::DataNode::Pointer mitk::FindTopmostVisibleNode(const DataStorage::SetOfObjects::ConstPointer nodes,
514  const Point3D worldPosition,
515  const TimePointType timePoint,
516  const BaseRenderer* baseRender)
517 {
518  if (nodes.IsNull())
519  {
520  return nullptr;
521  }
522 
523  mitk::DataNode::Pointer topLayerNode = nullptr;
524  int maxLayer = std::numeric_limits<int>::min();
525 
526  for (auto node : *nodes)
527  {
528  if (node.IsNull())
529  {
530  continue;
531  }
532 
533  bool isHelperObject = false;
534  node->GetBoolProperty("helper object", isHelperObject);
535  if (isHelperObject)
536  {
537  continue;
538  }
539 
540  auto data = node->GetData();
541  if (nullptr == data)
542  {
543  continue;
544  }
545 
546  auto geometry = data->GetGeometry();
547  if (nullptr == geometry || !geometry->IsInside(worldPosition))
548  {
549  continue;
550  }
551 
552  auto timeGeometry = data->GetUpdatedTimeGeometry();
553  if (nullptr == timeGeometry)
554  {
555  continue;
556  }
557 
558  if (!timeGeometry->IsValidTimePoint(timePoint))
559  {
560  continue;
561  }
562 
563  int layer = 0;
564  if (!node->GetIntProperty("layer", layer, baseRender))
565  {
566  continue;
567  }
568 
569  if (layer <= maxLayer)
570  {
571  continue;
572  }
573 
574  if (!node->IsVisible(baseRender))
575  {
576  continue;
577  }
578 
579  topLayerNode = node;
580  maxLayer = layer;
581  }
582 
583  return topLayerNode;
584 }
BoundingBox * GetBoundingBoxInWorld() const
Returns a bounding box that covers all time steps.
void RemoveListeners(const DataNode *_Node)
Removes a Modified-Listener from the given Node.
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)
std::map< const DataNode *, unsigned long > m_NodeInteractorChangedObserverTags
DataNode * GetNode(const NodePredicateBase *condition=nullptr) const
Convenience method to get the first node that matches the predicate condition.
DataStorage()
Standard Constructor for ::New() instantiation.
std::set< std::string > GroupTagList
Definition: mitkDataNode.h:64
virtual SetOfObjects::ConstPointer GetDerivations(const DataNode *node, const NodePredicateBase *condition=nullptr, bool onlyDirectDerivations=true) const =0
returns a set of derived objects for a given node.
itk::FixedArray< ScalarType, 2 > TimeBounds
Standard typedef for time-bounds.
TimeGeometry::ConstPointer ComputeVisibleBoundingGeometry3D(const BaseRenderer *renderer=nullptr, const char *boolPropertyKey=nullptr)
Compute the axis-parallel bounding geometry of all visible parts of the data tree bounding box...
itk::SimpleFastMutexLock m_MutexOne
std::map< const DataNode *, unsigned long > m_NodeDeleteObserverTags
Saves Delete-Observer Tags for each node in order to remove the event listeners again.
#define MITK_ERROR
Definition: mitkLogMacros.h:20
TimeGeometry::ConstPointer ComputeBoundingGeometry3D(const SetOfObjects *input, const char *boolPropertyKey=nullptr, const BaseRenderer *renderer=nullptr, const char *boolPropertyKey2=nullptr) const
Compute the axis-parallel bounding geometry of the input objects.
double ScalarType
Organizes the rendering process.
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Prints the contents of the DataStorage to os. Do not call directly, call ->Print() instead...
void Send(T t)
Definition: mitkMessage.h:602
DataStorageEvent DeleteNodeEvent
DeleteNodeEvent is emitted directly before a node is deleted.
virtual SetOfObjects::ConstPointer GetSources(const DataNode *node, const NodePredicateBase *condition=nullptr, bool onlyDirectSources=true) const =0
returns a set of source objects for a given node that meet the given condition(s).
SetOfObjects::ConstPointer FilterSetOfObjects(const SetOfObjects *set, const NodePredicateBase *condition) const
Filters a SetOfObjects by the condition. If no condition is provided, the original set is returned...
TimeBounds ComputeTimeBounds(const char *boolPropertyKey, const BaseRenderer *renderer, const char *boolPropertyKey2)
Compute the time-bounds of the contents of a data tree structure.
Key-value list holding instances of BaseProperty.
static Pointer New()
DataNode * GetNamedDerivedNode(const char *name, const DataNode *sourceNode, bool onlyDirectDerivations=true) const
Convenience method to get the first node with a given name that is derived from sourceNode.
~DataStorage() override
Standard Destructor.
virtual void Add(DataNode *node, const DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
void EmitAddNodeEvent(const DataNode *node)
EmitAddNodeEvent emits the AddNodeEvent.
virtual bool CheckNode(const mitk::DataNode *node) const =0
This method will be used to evaluate the node. Has to be overwritten in subclasses.
void EmitRemoveNodeEvent(const DataNode *node)
EmitRemoveNodeEvent emits the RemoveNodeEvent.
static Vector3D offset
void BlockNodeModifiedEvents(bool block)
Defines whether or not NodeChangedEvent is invoked .
virtual SetOfObjects::ConstPointer GetAll() const =0
returns a set of all data objects that are stored in the data storage
virtual TimeBounds GetTimeBounds() const =0
Get the time bounds (in ms)
void AddListeners(const DataNode *_Node)
Adds a Modified-Listener to the given Node.
void OnNodeInteractorChanged(itk::Object *caller, const itk::EventObject &event)
SetOfObjects::ConstPointer GetSubset(const NodePredicateBase *condition) const
returns a set of data objects that meet the given condition(s)
DataStorageEvent AddNodeEvent
AddEvent is emitted whenever a new node has been added to the DataStorage.
mitk::ScalarType TimePointType
void OnNodeModifiedOrDeleted(const itk::Object *caller, const itk::EventObject &event)
OnNodeModified listens to modified events of DataNodes.
std::vcl_size_t TimeStepType
std::map< const DataNode *, unsigned long > m_NodeModifiedObserverTags
Saves Modified-Observer Tags for each node in order to remove the event listeners again...
static T max(T x, T y)
Definition: svm.cpp:56
itk::VectorContainer< unsigned int, DataNode::Pointer > SetOfObjects
A Container of objects that is used as a result set of GetSubset() query operations (Set of...
static Pointer New(const char *_arg)
MITKCORE_EXPORT const double large
virtual void Remove(const DataNode *node)=0
Removes node from the DataStorage.
static T min(T x, T y)
Definition: svm.cpp:53
DataStorageEvent RemoveNodeEvent
RemoveEvent is emitted directly before a node is removed from the DataStorage.
const DataNode::GroupTagList GetGroupTags() const
Returns a list of used grouptags.
BoundingBox::Pointer ComputeBoundingBox(const char *boolPropertyKey=nullptr, const BaseRenderer *renderer=nullptr, const char *boolPropertyKey2=nullptr)
Compute the bounding box of data tree structure it -> an iterator to a data tree structure.
DataStorageEvent ChangedNodeEvent
ChangedEvent is emitted directly after a node was changed.
Interface for evaluation conditions used in the DataStorage class GetSubset() method.
bool m_BlockNodeModifiedEvents
If this class changes nodes itself, set this to TRUE in order to suppress NodeChangedEvent to be emit...
MITKCORE_EXPORT DataNode::Pointer FindTopmostVisibleNode(const DataStorage::SetOfObjects::ConstPointer nodes, const Point3D worldPosition, const TimePointType timePoint, const BaseRenderer *baseRender)
returns the topmost visible node of a given list of nodes. The function returns a node that is visibl...
DataStorageEvent InteractorChangedNodeEvent
static Pointer New()
DataNode * GetNamedNode(const char *name) const
Convenience method to get the first node with a given name.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
BoundingBoxType::BoundsArrayType BoundsArrayType
const PropertyMap * GetMap() const