diff --git a/Modules/AlgorithmsExt/src/mitkPointLocator.cpp b/Modules/AlgorithmsExt/src/mitkPointLocator.cpp index 9e9963d233..354ba1566e 100644 --- a/Modules/AlgorithmsExt/src/mitkPointLocator.cpp +++ b/Modules/AlgorithmsExt/src/mitkPointLocator.cpp @@ -1,241 +1,241 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkPointLocator.h" #include #include mitk::PointLocator::PointLocator() : m_SearchTreeInitialized(false), m_VtkPoints(nullptr), m_MitkPoints(nullptr), m_ItkPoints(nullptr), m_ANNK(1), m_ANNDimension(3), m_ANNEpsilon(0), m_ANNDataPoints(nullptr), m_ANNQueryPoint(nullptr), m_ANNPointIndexes(nullptr), m_ANNDistances(nullptr), m_ANNTree(nullptr) { } mitk::PointLocator::~PointLocator() { if (m_SearchTreeInitialized) DestroyANN(); } void mitk::PointLocator::SetPoints(vtkPointSet *pointSet) { if (pointSet == nullptr) { itkWarningMacro("Points are nullptr!"); return; } vtkPoints *points = pointSet->GetPoints(); if (m_VtkPoints) { if ((m_VtkPoints == points) && (m_VtkPoints->GetMTime() == points->GetMTime())) { return; // no need to recalculate search tree } } m_VtkPoints = points; size_t size = points->GetNumberOfPoints(); if (m_ANNDataPoints != nullptr) delete[] m_ANNDataPoints; m_ANNDataPoints = annAllocPts(size, m_ANNDimension); m_IndexToPointIdContainer.clear(); m_IndexToPointIdContainer.resize(size); for (vtkIdType i = 0; (unsigned)i < size; ++i) { double *currentPoint = points->GetPoint(i); (m_ANNDataPoints[i])[0] = currentPoint[0]; (m_ANNDataPoints[i])[1] = currentPoint[1]; (m_ANNDataPoints[i])[2] = currentPoint[2]; m_IndexToPointIdContainer[i] = i; } InitANN(); } void mitk::PointLocator::SetPoints(mitk::PointSet *points) { if (points == nullptr) { itkWarningMacro("Points are nullptr!"); return; } if (m_MitkPoints) { if ((m_MitkPoints == points) && (m_MitkPoints->GetMTime() == points->GetMTime())) { return; // no need to recalculate search tree } } m_MitkPoints = points; size_t size = points->GetSize(); if (m_ANNDataPoints != nullptr) delete[] m_ANNDataPoints; m_ANNDataPoints = annAllocPts(size, m_ANNDimension); m_IndexToPointIdContainer.clear(); m_IndexToPointIdContainer.resize(size); size_t counter = 0; mitk::PointSet::PointsContainer *pointsContainer = points->GetPointSet()->GetPoints(); mitk::PointSet::PointsContainer::Iterator it; mitk::PointSet::PointType currentPoint; mitk::PointSet::PointsContainer::ElementIdentifier currentId; for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter) { currentPoint = it->Value(); currentId = it->Index(); (m_ANNDataPoints[counter])[0] = currentPoint[0]; (m_ANNDataPoints[counter])[1] = currentPoint[1]; (m_ANNDataPoints[counter])[2] = currentPoint[2]; m_IndexToPointIdContainer[counter] = currentId; } InitANN(); } void mitk::PointLocator::SetPoints(ITKPointSet *pointSet) { if (pointSet == nullptr) { itkWarningMacro("Points are nullptr!"); return; } if (m_ItkPoints) { if ((m_ItkPoints == pointSet) && (m_ItkPoints->GetMTime() == pointSet->GetMTime())) { return; // no need to recalculate search tree } } m_ItkPoints = pointSet; size_t size = pointSet->GetNumberOfPoints(); if (m_ANNDataPoints != nullptr) delete[] m_ANNDataPoints; m_ANNDataPoints = annAllocPts(size, m_ANNDimension); m_IndexToPointIdContainer.clear(); m_IndexToPointIdContainer.resize(size); size_t counter = 0; ITKPointSet::PointsContainerConstPointer pointsContainer = pointSet->GetPoints(); ITKPointSet::PointsContainer::ConstIterator it; ITKPointSet::PointType currentPoint; ITKPointSet::PointsContainer::ElementIdentifier currentId; for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter) { currentPoint = it->Value(); currentId = it->Index(); (m_ANNDataPoints[counter])[0] = currentPoint[0]; (m_ANNDataPoints[counter])[1] = currentPoint[1]; (m_ANNDataPoints[counter])[2] = currentPoint[2]; m_IndexToPointIdContainer[counter] = currentId; } InitANN(); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint(const double point[3]) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; return FindClosestANNPoint(m_ANNQueryPoint); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint(double x, double y, double z) { m_ANNQueryPoint[0] = x; m_ANNQueryPoint[1] = y; m_ANNQueryPoint[2] = z; return FindClosestANNPoint(m_ANNQueryPoint); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint(mitk::PointSet::PointType point) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; return FindClosestANNPoint(m_ANNQueryPoint); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestANNPoint(const ANNpoint &point) { if (!m_SearchTreeInitialized) return -1; m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances); return m_IndexToPointIdContainer[m_ANNPointIndexes[0]]; } mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance(mitk::PointSet::PointType point) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; return GetMinimalDistance(m_ANNQueryPoint); } -mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance(const ANNpoint &point) +mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance(const MyANNpoint &point) { if (!m_SearchTreeInitialized) return -1; m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances); return m_ANNDistances[0]; } void mitk::PointLocator::InitANN() { if (m_SearchTreeInitialized) DestroyANN(); m_ANNQueryPoint = annAllocPt(m_ANNDimension); m_ANNPointIndexes = new ANNidx[m_ANNK]; m_ANNDistances = new ANNdist[m_ANNK]; m_ANNTree = new ANNkd_tree(m_ANNDataPoints, m_IndexToPointIdContainer.size(), m_ANNDimension); m_SearchTreeInitialized = true; } void mitk::PointLocator::DestroyANN() { m_SearchTreeInitialized = false; if (m_ANNQueryPoint != nullptr) annDeallocPt(m_ANNQueryPoint); if (m_ANNDataPoints != nullptr) annDeallocPts(m_ANNDataPoints); if (m_ANNPointIndexes != nullptr) delete[] m_ANNPointIndexes; if (m_ANNDistances != nullptr) delete[] m_ANNDistances; if (m_ANNTree != nullptr) delete m_ANNTree; } bool mitk::PointLocator::FindClosestPointAndDistance(mitk::PointSet::PointType point, IdType *id, DistanceType *dist) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; m_ANNTree->annkSearch(m_ANNQueryPoint, m_ANNK, m_ANNPointIndexes, m_ANNDistances); *id = m_IndexToPointIdContainer[m_ANNPointIndexes[0]]; *dist = m_ANNDistances[0]; return true; } diff --git a/Modules/Core/include/mitkDataNode.h b/Modules/Core/include/mitkDataNode.h index fd6e62ef21..7199095d72 100644 --- a/Modules/Core/include/mitkDataNode.h +++ b/Modules/Core/include/mitkDataNode.h @@ -1,614 +1,598 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef DATATREENODE_H_HEADER_INCLUDED_C1E14338 #define DATATREENODE_H_HEADER_INCLUDED_C1E14338 #include "mitkBaseData.h" //#include "mitkMapper.h" #include "mitkDataInteractor.h" #include "mitkIdentifiable.h" #include "mitkIPropertyOwner.h" -#ifdef MBI_NO_STD_NAMESPACE -#define MBI_STD -#include -#include -#else -#define MBI_STD std #include #include -#endif #include "mitkColorProperty.h" #include "mitkPropertyList.h" #include "mitkStringProperty.h" //#include "mitkMapper.h" #include "mitkGeometry3D.h" #include "mitkLevelWindow.h" #include #include class vtkLinearTransform; namespace mitk { class BaseRenderer; class Mapper; /** * \brief Class for nodes of the DataTree * * Contains the data (instance of BaseData), a list of mappers, which can * draw the data, a transform (vtkTransform) and a list of properties * (PropertyList). * \ingroup DataManagement * * \todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced * to * bool GetProperty(type&) * * \warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). */ class MITKCORE_EXPORT DataNode : public itk::DataObject, public IPropertyOwner { public: typedef mitk::Geometry3D::Pointer Geometry3DPointer; typedef std::vector> MapperVector; typedef std::map MapOfPropertyLists; typedef std::vector PropertyListKeyNames; typedef std::set GroupTagList; /** * \brief Definition of an itk::Event that is invoked when * a DataInteractor is set on this DataNode. */ itkEventMacro(InteractorChangedEvent, itk::AnyEvent) mitkClassMacroItkParent(DataNode, itk::DataObject); itkFactorylessNewMacro(Self); itkCloneMacro(Self); // IPropertyProvider BaseProperty::ConstPointer GetConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) const override; std::vector GetPropertyKeys(const std::string &contextName = "", bool includeDefaultContext = false) const override; std::vector GetPropertyContextNames() const override; // IPropertyOwner BaseProperty * GetNonConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) override; void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; void RemoveProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; mitk::Mapper *GetMapper(MapperSlotId id) const; /** * \brief Get the data object (instance of BaseData, e.g., an Image) * managed by this DataNode */ BaseData *GetData() const; /** * \brief Get the transformation applied prior to displaying the data as * a vtkTransform * \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead */ vtkLinearTransform *GetVtkTransform(int t = 0) const; /** * \brief Set the data object (instance of BaseData, e.g., an Image) * managed by this DataNode * * Prior set properties are kept if previous data of the node already exists and has the same * type as the new data to be set. Otherwise, the default properties are used. * In case that previous data already exists, the property list of the data node is cleared * before setting new default properties. * * \warning the actor-mode of the vtkInteractor does not work any more, if the transform of the * data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput. */ virtual void SetData(mitk::BaseData *baseData); /** * \brief Set the Interactor. */ virtual void SetDataInteractor(const DataInteractor::Pointer interactor); virtual DataInteractor::Pointer GetDataInteractor() const; mitk::DataNode &operator=(const DataNode &right); mitk::DataNode &operator=(BaseData *right); virtual void SetMapper(MapperSlotId id, mitk::Mapper *mapper); void UpdateOutputInformation() override; void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject *data) override; void CopyInformation(const itk::DataObject *data) override; /** * \brief The "names" used for (renderer-specific) PropertyLists in GetPropertyList(string). * * All possible values for the "renderer" parameters of * the diverse GetProperty/List() methods. */ PropertyListKeyNames GetPropertyListNames() const; /** * \brief Set the property (instance of BaseProperty) with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-value. * * \warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). * * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Replace the property (instance of BaseProperty) with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-reference. * * If \a renderer is \a nullptr the property is set in the BaseRenderer-independent * PropertyList of this DataNode. * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void ReplaceProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Add the property (instance of BaseProperty) if it does * not exist (or always if\a overwrite is\a true) * with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent * PropertyList). This is set-by-value. * * For\a overwrite ==\a false the property is\em not changed * if it already exists. For\a overwrite ==\a true the method * is identical to SetProperty. * * \sa SetProperty * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr, bool overwrite = false); /** * \brief Get the PropertyList of the \a renderer. If \a renderer is \a * nullptr, the BaseRenderer-independent PropertyList of this DataNode * is returned. * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ mitk::PropertyList *GetPropertyList(const mitk::BaseRenderer *renderer = nullptr) const; mitk::PropertyList *GetPropertyList(const std::string &rendererName) const; /** * \brief Add values from another PropertyList. * * Overwrites values in m_PropertyList only when possible (i.e. when types are compatible). * If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty, * set the \param replace. * * \param replace true: if \param pList contains a property "visible" of type ColorProperty and our m_PropertyList * also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects * behind the pointer. * * \sa SetProperty * \sa ReplaceProperty * \sa m_PropertyList */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); /** * \brief Get the property (instance of BaseProperty) with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * * If \a fallBackOnDataProperties is true, the data property list is queried as a last resort. * * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ mitk::BaseProperty *GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr, bool fallBackOnDataProperties = true) const; /** * \brief Get the property of type T with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ template bool GetProperty(itk::SmartPointer &property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property.IsNotNull(); } /** * \brief Get the property of type T with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ template bool GetProperty(T *&property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property != nullptr; } /** * \brief Convenience access method for GenericProperty properties * (T being the type of the second parameter) * \return \a true property was found */ template bool GetPropertyValue(const char *propertyKey, T &value, const mitk::BaseRenderer *renderer = nullptr) const { GenericProperty *gp = dynamic_cast *>(GetProperty(propertyKey, renderer)); if (gp != nullptr) { value = gp->GetValue(); return true; } return false; } /// \brief Get a set of all group tags from this node's property list GroupTagList GetGroupTags() const; /** * \brief Convenience access method for bool properties (instances of * BoolProperty) * \return \a true property was found */ bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for int properties (instances of * IntProperty) * \return \a true property was found */ bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for float properties (instances of * FloatProperty) * \return \a true property was found */ bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for double properties (instances of * DoubleProperty) * * If there is no DoubleProperty for the given\c propertyKey argument, the method * looks for a corresponding FloatProperty instance. * * \return \a true property was found */ bool GetDoubleProperty(const char *propertyKey, double &doubleValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for string properties (instances of * StringProperty) * \return \a true property was found */ bool GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for color properties (instances of * ColorProperty) * \return \a true property was found */ bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color") const; /** * \brief Convenience access method for level-window properties (instances of * LevelWindowProperty) * \return \a true property was found */ bool GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "levelwindow") const; /** * \brief set the node as selected */ void SetSelected(bool selected, const mitk::BaseRenderer *renderer = nullptr); /** * \brief set the node as selected * \return \a true node is selected */ bool IsSelected(const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name") * \return \a true property was found */ bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "name") const { return GetStringProperty(propertyKey, nodeName, renderer); } /** * \brief Extra convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name"). * * This method does not take the renderer specific * propertylists into account, because the name of an object should never be renderer specific. * \returns a std::string with the name of the object (content of "name" Property). * If there is no "name" Property, an empty string will be returned. */ virtual std::string GetName() const { mitk::StringProperty *sp = dynamic_cast(this->GetProperty("name")); if (sp == nullptr) return ""; return sp->GetValue(); } /** Value constant that is used indicate that node names are not set so far.*/ static std::string NO_NAME_VALUE() { return "No Name!"; } /** * \brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const char *name) { if (name == nullptr) return; this->SetProperty("name", StringProperty::New(name)); } /** * \brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const std::string name) { this->SetName(name.c_str()); } /** * \brief Convenience access method for visibility properties (instances * of BoolProperty with property-key "visible") * \return \a true property was found * \sa IsVisible */ bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey = "visible") const { return GetBoolProperty(propertyKey, visible, renderer); } /** * \brief Convenience access method for opacity properties (instances of * FloatProperty) * \return \a true property was found */ bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey = "opacity") const; /** * \brief Convenience access method for boolean properties (instances * of BoolProperty). Return value is the value of the property. If the property is * not found, the value of \a defaultIsOn is returned. * * Thus, the return value has a different meaning than in the * GetBoolProperty method! * \sa GetBoolProperty */ bool IsOn(const char *propertyKey, const mitk::BaseRenderer *renderer, bool defaultIsOn = true) const { if (propertyKey == nullptr) return defaultIsOn; GetBoolProperty(propertyKey, defaultIsOn, renderer); return defaultIsOn; } /** * \brief Convenience access method for visibility properties (instances * of BoolProperty). Return value is the visibility. Default is * visible==true, i.e., true is returned even if the property (\a * propertyKey) is not found. * * Thus, the return value has a different meaning than in the * GetVisibility method! * \sa GetVisibility * \sa IsOn */ bool IsVisible(const mitk::BaseRenderer *renderer, const char *propertyKey = "visible", bool defaultIsOn = true) const { return IsOn(propertyKey, renderer, defaultIsOn); } /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const mitk::Color &color, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(float red, float green, float blue, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting visibility properties (instances * of BoolProperty) * \param visible If set to true, the data will be rendered. If false, the render will skip this data. * \param renderer Specify a renderer if the visibility shall be specific to a renderer * \param propertykey Can be used to specify a user defined name of the visibility propery. */ void SetVisibility(bool visible, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "visible"); /** * \brief Convenience method for setting opacity properties (instances of * FloatProperty) */ void SetOpacity(float opacity, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "opacity"); /** * \brief Convenience method for setting level-window properties * (instances of LevelWindowProperty) */ void SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "levelwindow"); /** * \brief Convenience method for setting int properties (instances of * IntProperty) */ void SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting boolean properties (instances of * BoolProperty) */ void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting float properties (instances of * FloatProperty) */ void SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting double properties (instances of * DoubleProperty) */ void SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting string properties (instances of * StringProperty) */ void SetStringProperty(const char *propertyKey, const char *string, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Get the timestamp of the last change of the contents of this node or * the referenced BaseData. */ unsigned long GetMTime() const override; /** * \brief Get the timestamp of the last change of the reference to the * BaseData. */ unsigned long GetDataReferenceChangedTime() const { return m_DataReferenceChangedTime.GetMTime(); } protected: DataNode(); ~DataNode() override; /// Invoked when the property list was modified. Calls Modified() of the DataNode virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event); /// \brief Mapper-slots mutable MapperVector m_Mappers; /** * \brief The data object (instance of BaseData, e.g., an Image) managed * by this DataNode */ BaseData::Pointer m_Data; /** * \brief BaseRenderer-independent PropertyList * * Properties herein can be overwritten specifically for each BaseRenderer * by the BaseRenderer-specific properties defined in m_MapOfPropertyLists. */ PropertyList::Pointer m_PropertyList; /// \brief Map associating each BaseRenderer with its own PropertyList mutable MapOfPropertyLists m_MapOfPropertyLists; DataInteractor::Pointer m_DataInteractor; /// \brief Timestamp of the last change of m_Data itk::TimeStamp m_DataReferenceChangedTime; unsigned long m_PropertyListModifiedObserverTag; }; -#if (_MSC_VER > 1200) || !defined(_MSC_VER) - MITKCORE_EXPORT MBI_STD::istream &operator>>(MBI_STD::istream &i, DataNode::Pointer &dtn); - - MITKCORE_EXPORT MBI_STD::ostream &operator<<(MBI_STD::ostream &o, DataNode::Pointer &dtn); -#endif + MITKCORE_EXPORT std::istream &operator>>(std::istream &i, DataNode::Pointer &dtn); + MITKCORE_EXPORT std::ostream &operator<<(std::ostream &o, DataNode::Pointer &dtn); } // namespace mitk -#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) -MITKCORE_EXPORT MBI_STD::istream &operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn); - -MITKCORE_EXPORT MBI_STD::ostream &operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn); -#endif - #endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */ diff --git a/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp b/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp index 1519b90c5d..b0656e48f5 100644 --- a/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp +++ b/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp @@ -1,292 +1,292 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkClippedSurfaceBoundsCalculator.h" #include "mitkLine.h" #define ROUND_P(x) ((x) >= 0 ? (int)((x) + 0.5) : (int)((x)-0.5)) mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry *geometry, mitk::Image::Pointer image) : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(nullptr) { this->InitializeOutput(); this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const mitk::BaseGeometry *geometry, mitk::Image::Pointer image) : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(nullptr) { this->InitializeOutput(); this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const PointListType pointlist, mitk::Image::Pointer image) : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(image) { this->InitializeOutput(); m_ObjectPointsInWorldCoordinates = pointlist; } void mitk::ClippedSurfaceBoundsCalculator::InitializeOutput() { // initialize with meaningless slice indices m_MinMaxOutput.clear(); m_MinMaxOutput.reserve(3); for (int i = 0; i < 3; i++) { m_MinMaxOutput.push_back(OutputType(std::numeric_limits::max(), std::numeric_limits::min())); } } mitk::ClippedSurfaceBoundsCalculator::~ClippedSurfaceBoundsCalculator() { } void mitk::ClippedSurfaceBoundsCalculator::SetInput(const mitk::PlaneGeometry *geometry, mitk::Image *image) { if (geometry && image) { this->m_PlaneGeometry = geometry; this->m_Image = image; this->m_Geometry3D = nullptr; // Not possible to set both m_ObjectPointsInWorldCoordinates.clear(); } } void mitk::ClippedSurfaceBoundsCalculator::SetInput(const mitk::BaseGeometry *geometry, mitk::Image *image) { if (geometry && image) { this->m_Geometry3D = geometry; this->m_Image = image; this->m_PlaneGeometry = nullptr; // Not possible to set both m_ObjectPointsInWorldCoordinates.clear(); } } -void mitk::ClippedSurfaceBoundsCalculator::SetInput(const std::vector pointlist, mitk::Image *image) +void mitk::ClippedSurfaceBoundsCalculator::SetInput(const PointListType pointlist, mitk::Image *image) { if (!pointlist.empty() && image) { m_Geometry3D = nullptr; m_PlaneGeometry = nullptr; m_Image = image; m_ObjectPointsInWorldCoordinates = pointlist; } } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() { return this->m_MinMaxOutput[0]; } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() { return this->m_MinMaxOutput[1]; } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() { return this->m_MinMaxOutput[2]; } void mitk::ClippedSurfaceBoundsCalculator::Update() { this->m_MinMaxOutput.clear(); m_MinMaxOutput.reserve(3); for (int i = 0; i < 3; i++) { this->m_MinMaxOutput.push_back(OutputType(std::numeric_limits::max(), std::numeric_limits::min())); } if (m_PlaneGeometry.IsNotNull()) { this->CalculateIntersectionPoints(m_PlaneGeometry); } else if (m_Geometry3D.IsNotNull()) { // go through all slices of the image, ... const auto *slicedGeometry3D = dynamic_cast(m_Geometry3D.GetPointer()); int allSlices = slicedGeometry3D->GetSlices(); this->CalculateIntersectionPoints(dynamic_cast(slicedGeometry3D->GetPlaneGeometry(0))); this->CalculateIntersectionPoints( dynamic_cast(slicedGeometry3D->GetPlaneGeometry(allSlices - 1))); } else if (!m_ObjectPointsInWorldCoordinates.empty()) { this->CalculateIntersectionPoints(m_ObjectPointsInWorldCoordinates); this->EnforceImageBounds(); } } void mitk::ClippedSurfaceBoundsCalculator::CalculateIntersectionPoints(const mitk::PlaneGeometry *geometry) { // SEE HEADER DOCUMENTATION for explanation const mitk::BaseGeometry::Pointer imageGeometry = m_Image->GetGeometry()->Clone(); // the cornerpoint(0) is the corner based Origin, which is original center based Point3D origin = imageGeometry->GetCornerPoint(0); // Left, bottom, front // Get axis vector for the spatial directions const Vector3D xDirection = imageGeometry->GetAxisVector(0); const Vector3D yDirection = imageGeometry->GetAxisVector(1); const Vector3D zDirection = imageGeometry->GetAxisVector(2); const Point3D leftBottomFront = origin; const Point3D leftTopFront = origin + yDirection; const Point3D leftBottomBack = origin + zDirection; const Point3D leftTopBack = origin + yDirection + zDirection; const Point3D rightBottomFront = origin + xDirection; const Point3D rightTopFront = origin + xDirection + yDirection; const Point3D rightBottomBack = origin + xDirection + zDirection; const Point3D rightTopBack = origin + xDirection + yDirection + zDirection; typedef std::vector> EdgesVector; EdgesVector edgesOf3DBox; edgesOf3DBox.reserve(12); edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // x = left=xfront, y=bottom=yfront, z=front=zfront leftTopFront)); // left, top, front edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front leftBottomBack)); // left, bottom, back edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front rightBottomFront)); // right, bottom, front edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front rightTopFront)); // right, top, front edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front leftTopBack)); // left, top, back edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front rightTopBack)); // right, top, back edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front rightBottomFront)); // right, bottom, front edgesOf3DBox.push_back(std::make_pair(rightBottomFront, // right, bottom, front rightBottomBack)); // right, bottom, back edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back leftBottomBack)); // left, bottom, back edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back rightTopBack)); // right, top, back edgesOf3DBox.push_back(std::make_pair(rightTopBack, // right, top, back leftTopBack)); // left, top, back edgesOf3DBox.push_back(std::make_pair(leftTopBack, // left, top, back leftBottomBack)); // left, bottom, back for (auto iterator = edgesOf3DBox.cbegin(); iterator != edgesOf3DBox.cend(); ++iterator) { const Point3D startPoint = (*iterator).first; // start point of the line const Point3D endPoint = (*iterator).second; // end point of the line const Vector3D lineDirection = endPoint - startPoint; const mitk::Line3D line(startPoint, lineDirection); // Get intersection point of line and plane geometry Point3D intersectionWorldPoint(std::numeric_limits::min()); double t = -1.0; bool doesLineIntersectWithPlane(false); const double norm = line.GetDirection().GetNorm(); const double dist = geometry->Distance(line.GetPoint1()); if (norm < mitk::eps && dist < mitk::sqrteps) { t = 1.0; doesLineIntersectWithPlane = true; intersectionWorldPoint = line.GetPoint1(); } else { geometry->IntersectionPoint(line, intersectionWorldPoint); doesLineIntersectWithPlane = geometry->IntersectionPointParam(line, t); } // Get index point mitk::Point3D intersectionIndexPoint; imageGeometry->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint); const bool lowerBoundGood = (0 - mitk::sqrteps) <= t; const bool upperBoundGood = t <= 1.0 + mitk::sqrteps; if (doesLineIntersectWithPlane && lowerBoundGood && upperBoundGood) { for (int dim = 0; dim < 3; ++dim) { m_MinMaxOutput[dim].first = std::min(m_MinMaxOutput[dim].first, ROUND_P(intersectionIndexPoint[dim])); m_MinMaxOutput[dim].second = std::max(m_MinMaxOutput[dim].second, ROUND_P(intersectionIndexPoint[dim])); } this->EnforceImageBounds(); } } } void mitk::ClippedSurfaceBoundsCalculator::CalculateIntersectionPoints(PointListType pointList) { PointListType::const_iterator pointIterator; const mitk::SlicedGeometry3D::Pointer imageGeometry = m_Image->GetSlicedGeometry(); for (pointIterator = pointList.cbegin(); pointIterator != pointList.cend(); ++pointIterator) { mitk::Point3D pntInIndexCoordinates; imageGeometry->WorldToIndex((*pointIterator), pntInIndexCoordinates); m_MinMaxOutput[0].first = pntInIndexCoordinates[0] < m_MinMaxOutput[0].first ? ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].first; m_MinMaxOutput[0].second = pntInIndexCoordinates[0] > m_MinMaxOutput[0].second ? ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].second; m_MinMaxOutput[1].first = pntInIndexCoordinates[1] < m_MinMaxOutput[1].first ? ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].first; m_MinMaxOutput[1].second = pntInIndexCoordinates[1] > m_MinMaxOutput[1].second ? ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].second; m_MinMaxOutput[2].first = pntInIndexCoordinates[2] < m_MinMaxOutput[2].first ? ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].first; m_MinMaxOutput[2].second = pntInIndexCoordinates[2] > m_MinMaxOutput[2].second ? ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].second; } // this->EnforceImageBounds(); } void mitk::ClippedSurfaceBoundsCalculator::EnforceImageBounds() { m_MinMaxOutput[0].first = std::max(m_MinMaxOutput[0].first, 0); m_MinMaxOutput[1].first = std::max(m_MinMaxOutput[1].first, 0); m_MinMaxOutput[2].first = std::max(m_MinMaxOutput[2].first, 0); m_MinMaxOutput[0].first = std::min(m_MinMaxOutput[0].first, (int)m_Image->GetDimension(0) - 1); m_MinMaxOutput[1].first = std::min(m_MinMaxOutput[1].first, (int)m_Image->GetDimension(1) - 1); m_MinMaxOutput[2].first = std::min(m_MinMaxOutput[2].first, (int)m_Image->GetDimension(2) - 1); m_MinMaxOutput[0].second = std::min(m_MinMaxOutput[0].second, (int)m_Image->GetDimension(0) - 1); m_MinMaxOutput[1].second = std::min(m_MinMaxOutput[1].second, (int)m_Image->GetDimension(1) - 1); m_MinMaxOutput[2].second = std::min(m_MinMaxOutput[2].second, (int)m_Image->GetDimension(2) - 1); m_MinMaxOutput[0].second = std::max(m_MinMaxOutput[0].second, 0); m_MinMaxOutput[1].second = std::max(m_MinMaxOutput[1].second, 0); m_MinMaxOutput[2].second = std::max(m_MinMaxOutput[2].second, 0); } diff --git a/Modules/Core/src/DataManagement/mitkDataNode.cpp b/Modules/Core/src/DataManagement/mitkDataNode.cpp index f9f548d0b4..3097aa7f3c 100644 --- a/Modules/Core/src/DataManagement/mitkDataNode.cpp +++ b/Modules/Core/src/DataManagement/mitkDataNode.cpp @@ -1,732 +1,732 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDataNode.h" #include "mitkCoreObjectFactory.h" #include #include "mitkGroupTagProperty.h" #include "mitkProperties.h" #include "mitkSmartPointerProperty.h" #include "mitkStringProperty.h" //#include "mitkMaterialProperty.h" #include "mitkColorProperty.h" #include "mitkCoreObjectFactory.h" #include "mitkGenericProperty.h" #include "mitkGeometry3D.h" #include "mitkImageSource.h" #include "mitkLevelWindowProperty.h" #include "mitkRenderingManager.h" mitk::Mapper *mitk::DataNode::GetMapper(MapperSlotId id) const { if ((id >= m_Mappers.size()) || (m_Mappers[id].IsNull())) { if (id >= m_Mappers.capacity()) { // int i, size=id-m_Mappers.capacity()+10; m_Mappers.resize(id + 10); } m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast(this), id); } return m_Mappers[id]; } mitk::BaseData *mitk::DataNode::GetData() const { return m_Data; } void mitk::DataNode::SetData(mitk::BaseData *baseData) { if (m_Data != baseData) { m_Mappers.clear(); m_Mappers.resize(10); if (m_Data.IsNotNull() && baseData != nullptr) { // Do previous and new data have same type? Keep existing properties. if (0 == strcmp(m_Data->GetNameOfClass(), baseData->GetNameOfClass())) { m_Data = baseData; } else { m_Data = baseData; this->GetPropertyList()->Clear(); mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this); } } else { m_Data = baseData; mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this); } m_DataReferenceChangedTime.Modified(); Modified(); } } mitk::DataNode::DataNode() : m_PropertyList(PropertyList::New()), m_PropertyListModifiedObserverTag(0) { m_Mappers.resize(10); // subscribe for modified event itk::MemberCommand::Pointer _PropertyListModifiedCommand = itk::MemberCommand::New(); _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified); m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand); } mitk::DataNode::~DataNode() { if (m_PropertyList.IsNotNull()) m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag); m_Mappers.clear(); m_Data = nullptr; } mitk::DataNode &mitk::DataNode::operator=(const DataNode &right) { mitk::DataNode *node = mitk::DataNode::New(); node->SetData(right.GetData()); return *node; } mitk::DataNode &mitk::DataNode::operator=(mitk::BaseData *right) { mitk::DataNode *node = mitk::DataNode::New(); node->SetData(right); return *node; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) -MBI_STD::istream &mitk::operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn) +std::istream &mitk::operator>>(std::istream &i, mitk::DataNode::Pointer &dtn) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) - MBI_STD::istream & - operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn) + std::istream & + operator>>(std::istream &i, mitk::DataNode::Pointer &dtn) #endif { dtn = mitk::DataNode::New(); // i >> av.get(); return i; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) -MBI_STD::ostream &mitk::operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn) +std::ostream &mitk::operator<<(std::ostream &o, mitk::DataNode::Pointer &dtn) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) - MBI_STD::ostream & - operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn) + std::ostream & + operator<<(std::ostream &o, mitk::DataNode::Pointer &dtn) #endif { if (dtn->GetData() != nullptr) o << dtn->GetData()->GetNameOfClass(); else o << "empty data"; return o; } void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper *mapper) { m_Mappers[id] = mapper; if (mapper != nullptr) mapper->SetDataNode(this); } void mitk::DataNode::UpdateOutputInformation() { if (this->GetSource()) { this->GetSource()->UpdateOutputInformation(); } } void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::DataNode::VerifyRequestedRegion() { return true; } void mitk::DataNode::SetRequestedRegion(const itk::DataObject * /*data*/) { } mitk::DataNode::PropertyListKeyNames mitk::DataNode::GetPropertyListNames() const { PropertyListKeyNames result; for (auto entries : m_MapOfPropertyLists) result.push_back(entries.first); return result; } void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/) { } mitk::PropertyList *mitk::DataNode::GetPropertyList(const mitk::BaseRenderer *renderer) const { if (renderer == nullptr) return m_PropertyList; return this->GetPropertyList(renderer->GetName()); } mitk::PropertyList *mitk::DataNode::GetPropertyList(const std::string &rendererName) const { if (rendererName.empty()) return m_PropertyList; mitk::PropertyList::Pointer &propertyList = m_MapOfPropertyLists[rendererName]; if (propertyList.IsNull()) propertyList = mitk::PropertyList::New(); assert(m_MapOfPropertyLists[rendererName].IsNotNull()); return propertyList; } void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace) { m_PropertyList->ConcatenatePropertyList(pList, replace); } mitk::BaseProperty *mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer, bool fallBackOnDataProperties) const { if (nullptr == propertyKey) return nullptr; if (nullptr != renderer) { auto it = m_MapOfPropertyLists.find(renderer->GetName()); if (m_MapOfPropertyLists.end() != it) { auto property = it->second->GetProperty(propertyKey); if (nullptr != property) return property; } } auto property = m_PropertyList->GetProperty(propertyKey); if (nullptr == property && fallBackOnDataProperties && m_Data.IsNotNull()) property = m_Data->GetProperty(propertyKey); return property; } mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const { GroupTagList groups; const PropertyList::PropertyMap *propertyMap = m_PropertyList->GetMap(); for (auto groupIter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here groupIter != propertyMap->end(); ++groupIter) { const BaseProperty *bp = groupIter->second; if (dynamic_cast(bp)) { groups.insert(groupIter->first); } } return groups; } bool mitk::DataNode::GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer) const { mitk::BoolProperty::Pointer boolprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } bool mitk::DataNode::GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer) const { mitk::IntProperty::Pointer intprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (intprop.IsNull()) return false; intValue = intprop->GetValue(); return true; } bool mitk::DataNode::GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer) const { mitk::FloatProperty::Pointer floatprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (floatprop.IsNull()) return false; floatValue = floatprop->GetValue(); return true; } bool mitk::DataNode::GetDoubleProperty(const char *propertyKey, double &doubleValue, const mitk::BaseRenderer *renderer) const { mitk::DoubleProperty::Pointer doubleprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (doubleprop.IsNull()) { // try float instead float floatValue = 0; if (this->GetFloatProperty(propertyKey, floatValue, renderer)) { doubleValue = floatValue; return true; } return false; } doubleValue = doubleprop->GetValue(); return true; } bool mitk::DataNode::GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer) const { mitk::StringProperty::Pointer stringProp = dynamic_cast(GetProperty(propertyKey, renderer)); if (stringProp.IsNull()) { return false; } else { // memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous string = stringProp->GetValue(); return true; } } bool mitk::DataNode::GetColor(float rgb[3], const mitk::BaseRenderer *renderer, const char *propertyKey) const { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (colorprop.IsNull()) return false; memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3 * sizeof(float)); return true; } bool mitk::DataNode::GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey) const { mitk::FloatProperty::Pointer opacityprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (opacityprop.IsNull()) return false; opacity = opacityprop->GetValue(); return true; } bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer *renderer, const char *propertyKey) const { mitk::LevelWindowProperty::Pointer levWinProp = dynamic_cast(GetProperty(propertyKey, renderer)); if (levWinProp.IsNull()) return false; levelWindow = levWinProp->GetLevelWindow(); return true; } void mitk::DataNode::SetColor(const mitk::Color &color, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(color); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetColor( float red, float green, float blue, const mitk::BaseRenderer *renderer, const char *propertyKey) { float color[3]; color[0] = red; color[1] = green; color[2] = blue; SetColor(color, renderer, propertyKey); } void mitk::DataNode::SetColor(const float rgb[3], const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(rgb); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetVisibility(bool visible, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::BoolProperty::Pointer prop; prop = mitk::BoolProperty::New(visible); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetOpacity(float opacity, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::FloatProperty::Pointer prop; prop = mitk::FloatProperty::New(opacity); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::LevelWindowProperty::Pointer prop; prop = mitk::LevelWindowProperty::New(levelWindow); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::DataNode::SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer /*=nullptr*/) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::DataNode::SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer /*=nullptr*/) { if (dynamic_cast(this->GetProperty(propertyKey, renderer)) != nullptr) { MITK_WARN << "Setting float property " << propertyKey << " although a double property with the same name already exists"; } GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::DataNode::SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer) { if (dynamic_cast(this->GetProperty(propertyKey, renderer)) != nullptr) { MITK_WARN << "Setting double property " << propertyKey << " although a float property with the same name already exists"; } GetPropertyList(renderer)->SetProperty(propertyKey, mitk::DoubleProperty::New(doubleValue)); } void mitk::DataNode::SetStringProperty(const char *propertyKey, const char *stringValue, const mitk::BaseRenderer *renderer /*=nullptr*/) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void mitk::DataNode::SetProperty(const char *propertyKey, BaseProperty *propertyValue, const mitk::BaseRenderer *renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue); } void mitk::DataNode::ReplaceProperty(const char *propertyKey, BaseProperty *propertyValue, const mitk::BaseRenderer *renderer) { GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue); } void mitk::DataNode::AddProperty(const char *propertyKey, BaseProperty *propertyValue, const mitk::BaseRenderer *renderer, bool overwrite) { if ((overwrite) || (GetProperty(propertyKey, renderer) == nullptr)) { SetProperty(propertyKey, propertyValue, renderer); } } vtkLinearTransform *mitk::DataNode::GetVtkTransform(int t) const { assert(m_Data.IsNotNull()); mitk::BaseGeometry *geometry = m_Data->GetGeometry(t); if (geometry == nullptr) return nullptr; return geometry->GetVtkTransform(); } unsigned long mitk::DataNode::GetMTime() const { unsigned long time = Superclass::GetMTime(); if (m_Data.IsNotNull()) { if ((time < m_Data->GetMTime()) || ((m_Data->GetSource().IsNotNull()) && (time < m_Data->GetSource()->GetMTime()))) { Modified(); return Superclass::GetMTime(); } } return time; } void mitk::DataNode::SetSelected(bool selected, const mitk::BaseRenderer *renderer) { mitk::BoolProperty::Pointer selectedProperty = dynamic_cast(GetProperty("selected")); if (selectedProperty.IsNull()) { selectedProperty = mitk::BoolProperty::New(); selectedProperty->SetValue(false); SetProperty("selected", selectedProperty, renderer); } if (selectedProperty->GetValue() != selected) { selectedProperty->SetValue(selected); itk::ModifiedEvent event; InvokeEvent(event); } } /* class SelectedEvent : public itk::ModifiedEvent { public: typedef SelectedEvent Self; typedef itk::ModifiedEvent Superclass; SelectedEvent(DataNode* dataNode) { m_DataNode = dataNode; }; DataNode* GetDataNode() { return m_DataNode; }; virtual const char * GetEventName() const { return "SelectedEvent"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self(m_DataNode); } private: DataNode* m_DataNode; SelectedEvent(const Self& event) { m_DataNode = event.m_DataNode; }; void operator=(const Self& event) { m_DataNode = event.m_DataNode; } }; */ bool mitk::DataNode::IsSelected(const mitk::BaseRenderer *renderer) { bool selected; if (!GetBoolProperty("selected", selected, renderer)) return false; return selected; } void mitk::DataNode::SetDataInteractor(const DataInteractor::Pointer interactor) { if (m_DataInteractor == interactor) return; m_DataInteractor = interactor; this->Modified(); mitk::DataNode::InteractorChangedEvent changedEvent; this->InvokeEvent(changedEvent); } mitk::DataInteractor::Pointer mitk::DataNode::GetDataInteractor() const { return m_DataInteractor; } void mitk::DataNode::PropertyListModified(const itk::Object * /*caller*/, const itk::EventObject &) { Modified(); } mitk::BaseProperty::ConstPointer mitk::DataNode::GetConstProperty(const std::string &propertyKey, const std::string &contextName, bool fallBackOnDefaultContext) const { if (propertyKey.empty()) return nullptr; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { BaseProperty::ConstPointer property = propertyListIter->second->GetProperty(propertyKey); if (property.IsNotNull()) return property; } } if (contextName.empty() || fallBackOnDefaultContext) { BaseProperty::ConstPointer property = m_PropertyList->GetProperty(propertyKey); if (property.IsNull() && m_Data.IsNotNull()) property = m_Data->GetProperty(propertyKey.c_str()); return property; } return nullptr; } mitk::BaseProperty * mitk::DataNode::GetNonConstProperty(const std::string &propertyKey, const std::string &contextName, bool fallBackOnDefaultContext) { if (propertyKey.empty()) return nullptr; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { auto property = propertyListIter->second->GetProperty(propertyKey); if (nullptr != property) return property; } } if (contextName.empty() || fallBackOnDefaultContext) { auto property = m_PropertyList->GetProperty(propertyKey); if (nullptr == property && m_Data.IsNotNull()) property = m_Data->GetProperty(propertyKey.c_str()); return property; } return nullptr; } void mitk::DataNode::SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName, bool fallBackOnDefaultContext) { if (propertyKey.empty()) mitkThrow() << "Property key is empty."; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { propertyListIter->second->SetProperty(propertyKey, property); return; } } if (contextName.empty() || fallBackOnDefaultContext) { m_PropertyList->SetProperty(propertyKey, property); return; } mitkThrow() << "Unknown property context."; } void mitk::DataNode::RemoveProperty(const std::string &propertyKey, const std::string &contextName, bool fallBackOnDefaultContext) { if (propertyKey.empty()) mitkThrow() << "Property key is empty."; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { propertyListIter->second->RemoveProperty(propertyKey); return; } } if (contextName.empty() || fallBackOnDefaultContext) { m_PropertyList->RemoveProperty(propertyKey); return; } mitkThrow() << "Unknown property context."; } std::vector mitk::DataNode::GetPropertyKeys(const std::string &contextName, bool includeDefaultContext) const { std::vector propertyKeys; if (contextName.empty()) { for (auto property : *m_PropertyList->GetMap()) propertyKeys.push_back(property.first); return propertyKeys; } auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { for (auto property : *propertyListIter->second->GetMap()) propertyKeys.push_back(property.first); } if (includeDefaultContext) { for (auto property : *m_PropertyList->GetMap()) { auto propertyKeyIter = std::find(propertyKeys.begin(), propertyKeys.end(), property.first); if (propertyKeys.end() == propertyKeyIter) propertyKeys.push_back(property.first); } } return propertyKeys; } std::vector mitk::DataNode::GetPropertyContextNames() const { return this->GetPropertyListNames(); } diff --git a/Modules/Core/src/DataManagement/mitkSlicedData.cpp b/Modules/Core/src/DataManagement/mitkSlicedData.cpp index 23ac80f2f0..7d8796581e 100644 --- a/Modules/Core/src/DataManagement/mitkSlicedData.cpp +++ b/Modules/Core/src/DataManagement/mitkSlicedData.cpp @@ -1,361 +1,361 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkSlicedData.h" #include "mitkAbstractTransformGeometry.h" #include "mitkBaseProcess.h" #include mitk::SlicedData::SlicedData() : m_RequestedRegionInitialized(false), m_UseLargestPossibleRegion(false) { unsigned int i; for (i = 0; i < 4; ++i) { m_LargestPossibleRegion.SetIndex(i, 0); m_LargestPossibleRegion.SetSize(i, 1); } } mitk::SlicedData::SlicedData(const SlicedData &other) : BaseData(other), m_LargestPossibleRegion(other.m_LargestPossibleRegion), m_RequestedRegion(other.m_RequestedRegion), m_RequestedRegionInitialized(other.m_RequestedRegionInitialized), m_BufferedRegion(other.m_BufferedRegion), m_UseLargestPossibleRegion(other.m_UseLargestPossibleRegion) { } mitk::SlicedData::~SlicedData() { } void mitk::SlicedData::UpdateOutputInformation() { Superclass::UpdateOutputInformation(); if (this->GetSource().IsNull()) // If we don't have a source, then let's make our Image // span our buffer { m_UseLargestPossibleRegion = true; } // Now we should know what our largest possible region is. If our // requested region was not set yet, (or has been set to something // invalid - with no data in it ) then set it to the largest possible // region. if (!m_RequestedRegionInitialized) { this->SetRequestedRegionToLargestPossibleRegion(); m_RequestedRegionInitialized = true; } m_LastRequestedRegionWasOutsideOfTheBufferedRegion = false; } void mitk::SlicedData::PrepareForNewData() { if (GetUpdateMTime() < GetPipelineMTime() || GetDataReleased()) { ReleaseData(); } } void mitk::SlicedData::SetRequestedRegionToLargestPossibleRegion() { m_UseLargestPossibleRegion = true; if (GetGeometry() == nullptr) return; unsigned int i; const RegionType::IndexType &index = GetLargestPossibleRegion().GetIndex(); const RegionType::SizeType &size = GetLargestPossibleRegion().GetSize(); for (i = 0; i < RegionDimension; ++i) { m_RequestedRegion.SetIndex(i, index[i]); m_RequestedRegion.SetSize(i, size[i]); } } bool mitk::SlicedData::RequestedRegionIsOutsideOfTheBufferedRegion() { // Is the requested region within the currently buffered data? // SlicedData and subclasses store entire volumes or slices. The // methods IsVolumeSet() and IsSliceSet are provided to check, // a volume or slice, respectively, is available. Thus, these // methods used here. const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex(); const SizeType &requestedRegionSize = m_RequestedRegion.GetSize(); const SizeType &largestPossibleRegionSize = GetLargestPossibleRegion().GetSize(); // are whole channels requested? int c, cEnd; c = requestedRegionIndex[4]; cEnd = c + static_cast(requestedRegionSize[4]); if (requestedRegionSize[3] == largestPossibleRegionSize[3]) { for (; c < cEnd; ++c) if (IsChannelSet(c) == false) return true; return false; } // are whole volumes requested? int t, tEnd; t = requestedRegionIndex[3]; tEnd = t + static_cast(requestedRegionSize[3]); if (requestedRegionSize[2] == largestPossibleRegionSize[2]) { for (; c < cEnd; ++c) for (; t < tEnd; ++t) if (IsVolumeSet(t, c) == false) return true; return false; } // ok, only slices are requested. Check if they are available. int s, sEnd; s = requestedRegionIndex[2]; sEnd = s + static_cast(requestedRegionSize[2]); for (; c < cEnd; ++c) for (; t < tEnd; ++t) for (; s < sEnd; ++s) if (IsSliceSet(s, t, c) == false) return true; return false; } bool mitk::SlicedData::VerifyRequestedRegion() { if (GetTimeGeometry() == nullptr) return false; unsigned int i; // Is the requested region within the LargestPossibleRegion? // Note that the test is indeed against the largest possible region // rather than the buffered region; see DataObject::VerifyRequestedRegion. const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex(); const IndexType &largestPossibleRegionIndex = GetLargestPossibleRegion().GetIndex(); const SizeType &requestedRegionSize = m_RequestedRegion.GetSize(); const SizeType &largestPossibleRegionSize = GetLargestPossibleRegion().GetSize(); for (i = 0; i < RegionDimension; ++i) { if ((requestedRegionIndex[i] < largestPossibleRegionIndex[i]) || ((requestedRegionIndex[i] + static_cast(requestedRegionSize[i])) > (largestPossibleRegionIndex[i] + static_cast(largestPossibleRegionSize[i])))) { return false; } } return true; } void mitk::SlicedData::SetRequestedRegion(const itk::DataObject *data) { m_UseLargestPossibleRegion = false; const auto *slicedData = dynamic_cast(data); if (slicedData) { m_RequestedRegion = slicedData->GetRequestedRegion(); m_RequestedRegionInitialized = true; } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::SetRequestedRegion(DataObject*) cannot cast " << typeid(data).name() << " to " << typeid(SlicedData *).name()); } } void mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType *region) { m_UseLargestPossibleRegion = false; if (region != nullptr) { m_RequestedRegion = *region; m_RequestedRegionInitialized = true; } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType*) cannot cast " << typeid(region).name() << " to " << typeid(SlicedData *).name()); } } void mitk::SlicedData::SetLargestPossibleRegion(SlicedData::RegionType *region) { if (region != nullptr) { m_LargestPossibleRegion = *region; m_UseLargestPossibleRegion = true; } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::SetLargestPossibleRegion(SlicedData::RegionType*) cannot cast " << typeid(region).name() << " to " << typeid(SlicedData *).name()); } } void mitk::SlicedData::CopyInformation(const itk::DataObject *data) { // Standard call to the superclass' method Superclass::CopyInformation(data); const mitk::SlicedData *slicedData; slicedData = dynamic_cast(data); if (slicedData) { m_LargestPossibleRegion = slicedData->GetLargestPossibleRegion(); } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::CopyInformation(const DataObject *data) cannot cast " << typeid(data).name() << " to " << typeid(SlicedData *).name()); } } // const mitk::PlaneGeometry* mitk::SlicedData::GetPlaneGeometry(int s, int t) const //{ // const_cast(this)->SetRequestedRegionToLargestPossibleRegion(); // // const_cast(this)->UpdateOutputInformation(); // // return GetSlicedGeometry(t)->GetPlaneGeometry(s); //} // mitk::SlicedGeometry3D *mitk::SlicedData::GetSlicedGeometry(unsigned int t) const { if (GetTimeGeometry() == nullptr) return nullptr; return dynamic_cast(GetTimeGeometry()->GetGeometryForTimeStep(t).GetPointer()); } const mitk::SlicedGeometry3D *mitk::SlicedData::GetUpdatedSlicedGeometry(unsigned int t) { SetRequestedRegionToLargestPossibleRegion(); UpdateOutputInformation(); return GetSlicedGeometry(t); } void mitk::SlicedData::SetGeometry(BaseGeometry *aGeometry3D) { if (aGeometry3D != nullptr) { ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); SlicedGeometry3D::Pointer slicedGeometry = dynamic_cast(aGeometry3D); if (slicedGeometry.IsNull()) { auto *geometry2d = dynamic_cast(aGeometry3D); if (geometry2d != nullptr && dynamic_cast(aGeometry3D) == nullptr) { if ((GetSlicedGeometry()->GetPlaneGeometry(0) == geometry2d) && (GetSlicedGeometry()->GetSlices() == 1)) return; slicedGeometry = SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(geometry2d, 1); } else { slicedGeometry = SlicedGeometry3D::New(); PlaneGeometry::Pointer planeGeometry = PlaneGeometry::New(); planeGeometry->InitializeStandardPlane(aGeometry3D); slicedGeometry->InitializeEvenlySpaced(planeGeometry, (unsigned int)(aGeometry3D->GetExtent(2))); } } assert(slicedGeometry.IsNotNull()); timeGeometry->Initialize(slicedGeometry, 1); Superclass::SetTimeGeometry(timeGeometry); } else { if (GetGeometry() == nullptr) return; Superclass::SetGeometry(nullptr); } } -void mitk::SlicedData::SetSpacing(const ScalarType aSpacing[3]) +void mitk::SlicedData::SetSpacing(const ScalarType aSpacing[]) { this->SetSpacing((mitk::Vector3D)aSpacing); } void mitk::SlicedData::SetOrigin(const mitk::Point3D &origin) { TimeGeometry *timeGeometry = GetTimeGeometry(); assert(timeGeometry != nullptr); mitk::SlicedGeometry3D *slicedGeometry; unsigned int steps = timeGeometry->CountTimeSteps(); for (unsigned int timestep = 0; timestep < steps; ++timestep) { slicedGeometry = GetSlicedGeometry(timestep); if (slicedGeometry != nullptr) { slicedGeometry->SetOrigin(origin); if (slicedGeometry->GetEvenlySpaced()) { mitk::PlaneGeometry *geometry2D = slicedGeometry->GetPlaneGeometry(0); geometry2D->SetOrigin(origin); slicedGeometry->InitializeEvenlySpaced(geometry2D, slicedGeometry->GetSlices()); } } // ProportionalTimeGeometry* timeGeometry = dynamic_cast(GetTimeGeometry()); // if(timeGeometry != nullptr) //{ // timeGeometry->Initialize(slicedGeometry, steps); // break; //} } } void mitk::SlicedData::SetSpacing(mitk::Vector3D aSpacing) { TimeGeometry *timeGeometry = GetTimeGeometry(); assert(timeGeometry != nullptr); unsigned int steps = timeGeometry->CountTimeSteps(); for (unsigned int timestep = 0; timestep < steps; ++timestep) { mitk::SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(timestep); if (slicedGeometry != nullptr) { slicedGeometry->SetSpacing(aSpacing); } } timeGeometry->Update(); }