15 #include "itkCommand.h" 16 #include "itkMutexLockHolder.h" 41 DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New();
42 if (parent !=
nullptr)
43 parents->InsertElement(0, parent);
44 this->
Add(node, parents);
51 for (DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); it++)
69 DataStorage::SetOfObjects::ConstPointer rs = this->
GetSubset(p);
71 return rs->GetElement(0);
78 if (condition ==
nullptr)
81 DataStorage::SetOfObjects::ConstPointer rs = this->
GetSubset(condition);
83 return rs->GetElement(0);
90 bool onlyDirectDerivations)
const 97 DataStorage::SetOfObjects::ConstPointer rs = this->
GetDerivations(sourceNode, p, onlyDirectDerivations);
99 return rs->GetElement(0);
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++)
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)
120 os << indent <<
" Direct sources: ";
121 for (DataStorage::SetOfObjects::ConstIterator parentIt = parents->Begin(); parentIt != parents->End();
123 os << parentIt.Value().GetPointer() <<
", ";
126 DataStorage::SetOfObjects::ConstPointer derivations = this->
GetDerivations(allIt.Value());
127 if (derivations->Size() > 0)
129 os << indent <<
" Direct derivations: ";
130 for (DataStorage::SetOfObjects::ConstIterator derivationIt = derivations->Begin();
131 derivationIt != derivations->End();
133 os << derivationIt.Value().GetPointer() <<
", ";
146 DataStorage::SetOfObjects::Pointer result = DataStorage::SetOfObjects::New();
147 for (DataStorage::SetOfObjects::ConstIterator it = set->Begin(); it !=
set->End(); it++)
148 if (condition ==
nullptr ||
151 result->InsertElement(result->Size(), it.Value());
153 return DataStorage::SetOfObjects::ConstPointer(result);
159 SetOfObjects::ConstPointer all = this->
GetAll();
163 for (DataStorage::SetOfObjects::ConstIterator nodeIt = all->Begin(); nodeIt != all->End();
167 for (
auto propIt = pl->
GetMap()->begin(); propIt != pl->
GetMap()->end();
169 if (dynamic_cast<GroupTagProperty *>(propIt->second.GetPointer()) !=
nullptr)
170 result.insert(propIt->first);
188 const auto *_Node =
dynamic_cast<const DataNode *
>(caller);
200 const auto *_Node =
dynamic_cast<const DataNode *
>(caller);
203 const auto *modEvent =
dynamic_cast<const itk::ModifiedEvent *
>(&event);
215 auto *NonConstNode =
const_cast<DataNode *
>(_Node);
218 itk::MemberCommand<DataStorage>::Pointer nodeModifiedCommand = itk::MemberCommand<DataStorage>::New();
222 itk::MemberCommand<DataStorage>::Pointer interactorChangedCommand =
223 itk::MemberCommand<DataStorage>::New();
226 NonConstNode->AddObserver(DataNode::InteractorChangedEvent(), interactorChangedCommand);
229 itk::MemberCommand<DataStorage>::Pointer deleteCommand = itk::MemberCommand<DataStorage>::New();
240 auto *NonConstNode =
const_cast<DataNode *
>(_Node);
256 const char *boolPropertyKey,
258 const char *boolPropertyKey2)
const 260 if (input ==
nullptr)
261 throw std::invalid_argument(
"DataStorage: input is invalid");
263 BoundingBox::PointsContainer::Pointer pointscontainer = BoundingBox::PointsContainer::New();
265 BoundingBox::PointIdentifier pointid = 0;
272 ScalarType stmin = itk::NumericTraits<ScalarType>::NonpositiveMin();
274 std::set<ScalarType> existingTimePoints;
281 for (SetOfObjects::ConstIterator it = input->Begin(); it != input->End(); ++it)
284 if ((node.IsNotNull()) && (node->GetData() !=
nullptr) && (node->GetData()->IsEmpty() ==
false) &&
285 node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer))
287 const TimeGeometry *timeGeometry = node->GetData()->GetUpdatedTimeGeometry();
289 if (timeGeometry !=
nullptr)
293 if (itkBounds == itkBoundsZero)
299 for (i = 0; i < 8; ++i)
302 if (point[0] * point[0] + point[1] * point[1] + point[2] * point[2] <
large)
303 pointscontainer->InsertElement(pointid++, point);
306 itkGenericOutputMacro(<<
"Unrealistically distant corner point encountered. Ignored. Node: " << node);
322 node->GetData()->GetGeometry(i)->IndexToWorld(spacing, spacing);
323 for (
int axis = 0; axis < 3; ++ axis)
326 if (space < minSpacing[axis])
328 minSpacing[axis] = space;
333 if ((curTimeBounds[0] > stmin) && (curTimeBounds[0] < stmax))
335 existingTimePoints.insert(curTimeBounds[0]);
337 if ((curTimeBounds[1] > maximalTime) && (curTimeBounds[1] < stmax))
339 maximalTime = curTimeBounds[1];
343 catch (
const itk::ExceptionObject &e )
345 MITK_ERROR << e.GetDescription() << std::endl;
351 BoundingBox::Pointer result = BoundingBox::New();
352 result->SetPoints(pointscontainer);
353 result->ComputeBoundingBox();
356 if (existingTimePoints.empty())
358 existingTimePoints.insert(0.0);
363 if (result->GetPoints()->Size() > 0)
367 geometry->Initialize();
371 AffineTransform3D::OutputVectorType
offset;
372 for (
int i = 0; i < 3; ++i)
374 offset[i] = bounds[i * 2];
376 bounds[i * 2 + 1] = (bounds[i * 2 + 1] - offset[i]) / minSpacing[i];
378 geometry->GetIndexToWorldTransform()->SetOffset(offset);
379 geometry->SetBounds(bounds);
380 geometry->SetSpacing(minSpacing);
383 auto tsIterator = existingTimePoints.cbegin();
384 auto tsPredecessor = tsIterator++;
385 auto tsEnd = existingTimePoints.cend();
387 for (; tsIterator != tsEnd; ++tsIterator, ++tsPredecessor)
389 timeGeometry->AppendNewTimeStep(geometry, *tsPredecessor, *tsIterator);
391 timeGeometry->AppendNewTimeStep(geometry, *tsPredecessor, maximalTime);
393 timeGeometry->Update();
395 return timeGeometry.GetPointer();
400 const char *boolPropertyKey2)
const 406 const char *boolPropertyKey)
413 const char *boolPropertyKey2)
415 BoundingBox::PointsContainer::Pointer pointscontainer = BoundingBox::PointsContainer::New();
417 BoundingBox::PointIdentifier pointid = 0;
424 SetOfObjects::ConstPointer all = this->
GetAll();
425 for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
428 if ((node.IsNotNull()) && (node->GetData() !=
nullptr) && (node->GetData()->IsEmpty() ==
false) &&
429 node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer))
431 const TimeGeometry *geometry = node->GetData()->GetUpdatedTimeGeometry();
432 if (geometry !=
nullptr)
436 if (itkBounds == itkBoundsZero)
442 for (i = 0; i < 8; ++i)
445 if (point[0] * point[0] + point[1] * point[1] + point[2] * point[2] <
large)
446 pointscontainer->InsertElement(pointid++, point);
449 itkGenericOutputMacro(<<
"Unrealistically distant corner point encountered. Ignored. Node: " << node);
456 BoundingBox::Pointer result = BoundingBox::New();
457 result->SetPoints(pointscontainer);
458 result->ComputeBoundingBox();
465 const char *boolPropertyKey2)
471 stmin = itk::NumericTraits<ScalarType>::NonpositiveMin();
474 timeBounds[0] = stmax;
475 timeBounds[1] = stmin;
477 SetOfObjects::ConstPointer all = this->
GetAll();
478 for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
481 if ((node.IsNotNull()) && (node->GetData() !=
nullptr) && (node->GetData()->IsEmpty() ==
false) &&
482 node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer))
484 const TimeGeometry *geometry = node->GetData()->GetUpdatedTimeGeometry();
485 if (geometry !=
nullptr)
488 cur = curTimeBounds[0];
490 if ((cur > stmin) && (cur < timeBounds[0]))
493 cur = curTimeBounds[1];
495 if ((cur < stmax) && (cur > timeBounds[1]))
500 if (!(timeBounds[0] < stmax))
502 timeBounds[0] = stmin;
503 timeBounds[1] = stmax;
526 for (
auto node : *nodes)
533 bool isHelperObject =
false;
534 node->GetBoolProperty(
"helper object", isHelperObject);
540 auto data = node->GetData();
546 auto geometry = data->GetGeometry();
547 if (
nullptr == geometry || !geometry->IsInside(worldPosition))
552 auto timeGeometry = data->GetUpdatedTimeGeometry();
553 if (
nullptr == timeGeometry)
558 if (!timeGeometry->IsValidTimePoint(timePoint))
564 if (!node->GetIntProperty(
"layer", layer, baseRender))
569 if (layer <= maxLayer)
574 if (!node->IsVisible(baseRender))
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
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.
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.
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...
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.
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.
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...
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.
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
DataNode * GetNamedNode(const char *name) const
Convenience method to get the first node with a given name.
Class for nodes of the DataTree.
BoundingBoxType::BoundsArrayType BoundsArrayType
const PropertyMap * GetMap() const