diff --git a/Core/Code/Rendering/mitkLabelOverlay3D.cpp b/Core/Code/Rendering/mitkLabelOverlay3D.cpp index 9ec915be17..eb1f072801 100644 --- a/Core/Code/Rendering/mitkLabelOverlay3D.cpp +++ b/Core/Code/Rendering/mitkLabelOverlay3D.cpp @@ -1,144 +1,165 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkLabelOverlay3D.h" #include #include #include #include #include #include #include #include #include #include #include -mitk::LabelOverlay3D::LabelOverlay3D() +mitk::LabelOverlay3D::LabelOverlay3D():m_PointSetModifiedObserverTag(0) { } mitk::LabelOverlay3D::~LabelOverlay3D() { + if(m_LabelCoordinates.IsNotNull()) + m_LabelCoordinates->RemoveObserver(m_PointSetModifiedObserverTag); } mitk::LabelOverlay3D::LocalStorage::~LocalStorage() { } mitk::LabelOverlay3D::LocalStorage::LocalStorage() { m_Points = vtkSmartPointer::New(); // Add label array. m_Labels = vtkSmartPointer::New(); m_Labels->SetNumberOfValues(0); m_Labels->SetName("labels"); // Add priority array. m_Sizes = vtkSmartPointer::New(); m_Sizes->SetNumberOfValues(0); m_Sizes->SetName("sizes"); m_Points->GetPointData()->AddArray(m_Sizes); m_Points->GetPointData()->AddArray(m_Labels); m_PointSetToLabelHierarchyFilter = vtkSmartPointer::New(); m_PointSetToLabelHierarchyFilter->SetInputData(m_Points); m_PointSetToLabelHierarchyFilter->SetLabelArrayName("labels"); m_PointSetToLabelHierarchyFilter->SetPriorityArrayName("sizes"); m_PointSetToLabelHierarchyFilter->Update(); m_LabelMapper = vtkSmartPointer::New(); m_LabelMapper->SetInputConnection(m_PointSetToLabelHierarchyFilter->GetOutputPort()); m_LabelsActor = vtkSmartPointer::New(); m_LabelsActor->SetMapper(m_LabelMapper); } void mitk::LabelOverlay3D::UpdateVtkOverlay(mitk::BaseRenderer *renderer) { if(m_LabelCoordinates.IsNull()) { MITK_WARN << "No pointset defined to print labels!"; return; } LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); if(ls->IsGenerateDataRequired(renderer,this)) { vtkSmartPointer points = vtkSmartPointer::New(); size_t pointsetsize = (size_t) m_LabelCoordinates->GetSize(); ls->m_Labels->SetNumberOfValues(pointsetsize); ls->m_Sizes->SetNumberOfValues(pointsetsize); for(size_t i=0 ; iGetPoint(i); points->InsertNextPoint(coordinate[0]+GetOffsetVector(renderer)[0], coordinate[1]+GetOffsetVector(renderer)[1], coordinate[2]+GetOffsetVector(renderer)[2]); if(m_LabelVector.size()>i) ls->m_Labels->SetValue(i,m_LabelVector[i]); else ls->m_Labels->SetValue(i,""); if(m_PriorityVector.size()>i) ls->m_Sizes->SetValue(i,m_PriorityVector[i]); else ls->m_Sizes->SetValue(i,1); } ls->m_Points->SetPoints(points); ls->m_PointSetToLabelHierarchyFilter->Update(); ls->m_LabelMapper->Update(); float color[3] = {1,1,1}; float opacity = 1.0; GetColor(color,renderer); GetOpacity(opacity,renderer); ls->m_LabelsActor->GetProperty()->SetColor(color[0], color[1], color[2]); ls->m_LabelsActor->GetProperty()->SetOpacity(opacity); ls->UpdateGenerateDataTime(); } } - vtkProp* mitk::LabelOverlay3D::GetVtkProp(BaseRenderer *renderer) const { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); return ls->m_LabelsActor; } void mitk::LabelOverlay3D::SetLabelVector(const std::vector& LabelVector) { m_LabelVector = LabelVector; this->Modified(); } void mitk::LabelOverlay3D::SetPriorityVector(const std::vector& PriorityVector) { m_PriorityVector = PriorityVector; this->Modified(); } void mitk::LabelOverlay3D::SetLabelCoordinates(mitk::PointSet::Pointer LabelCoordinates) { + if(m_LabelCoordinates.IsNotNull()) + { + m_LabelCoordinates->RemoveObserver(m_PointSetModifiedObserverTag); + m_PointSetModifiedObserverTag = 0; + m_LabelCoordinates = NULL; + } + if(LabelCoordinates.IsNull()) + { + return; + } m_LabelCoordinates = LabelCoordinates; + itk::MemberCommand::Pointer _PropertyListModifiedCommand = + itk::MemberCommand::New(); + _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::LabelOverlay3D::PointSetModified); + m_PointSetModifiedObserverTag = m_LabelCoordinates->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand); this->Modified(); } + +void mitk::LabelOverlay3D::PointSetModified( const itk::Object* /*caller*/, const itk::EventObject& ) +{ + this->Modified(); +} + diff --git a/Core/Code/Rendering/mitkLabelOverlay3D.h b/Core/Code/Rendering/mitkLabelOverlay3D.h index 1fa4c4d522..ac88f3315b 100644 --- a/Core/Code/Rendering/mitkLabelOverlay3D.h +++ b/Core/Code/Rendering/mitkLabelOverlay3D.h @@ -1,112 +1,115 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef LabelOverlay3D_H #define LabelOverlay3D_H #include #include #include "MitkExports.h" #include class vtkStringArray; class vtkPolyDataMapper; class vtkPolyData; class vtkActor2D; class vtkProperty2D; class vtkPointSetToLabelHierarchy; class vtkLabelPlacementMapper; class vtkIntArray; namespace mitk { class PointSet; /** \brief Can display a high amount of 3D labels to a PointSet */ class MITK_CORE_EXPORT LabelOverlay3D : public mitk::VtkOverlay3D { public: /** \brief Internal class holding the vtkActor, etc. for each of the render windows */ class LocalStorage : public mitk::Overlay::BaseLocalStorage { public: vtkSmartPointer m_Points; vtkSmartPointer m_LabelsActor; vtkSmartPointer m_Sizes; vtkSmartPointer m_Labels; vtkSmartPointer m_LabelMapper; vtkSmartPointer m_PointSetToLabelHierarchyFilter; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief Default constructor of the local storage. */ LocalStorage(); /** \brief Default deconstructor of the local storage. */ ~LocalStorage(); }; mitkClassMacro(LabelOverlay3D, mitk::VtkOverlay3D); itkNewMacro(LabelOverlay3D); /** \brief Set the vector of labels that are shown to each corresponding point3D. The size has to be equal to the provided LabelCoordinates. */ void SetLabelVector(const std::vector& LabelVector); /** \brief Optional: Provide a vector of priorities. The labels with higher priorities will be visible in lower LOD */ void SetPriorityVector(const std::vector& PriorityVector); /** \brief Coordinates of the labels */ void SetLabelCoordinates(itk::SmartPointer LabelCoordinates); + void PointSetModified(const itk::Object *, const itk::EventObject &); protected: /** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */ mutable mitk::LocalStorageHandler m_LSH; virtual vtkProp *GetVtkProp(BaseRenderer *renderer) const; void UpdateVtkOverlay(mitk::BaseRenderer *renderer); /** \brief explicit constructor which disallows implicit conversions */ explicit LabelOverlay3D(); /** \brief virtual destructor in order to derive from this class */ virtual ~LabelOverlay3D(); private: /** \brief The char arrays in this vector are displayed at the corresponding coordinates.*/ std::vector m_LabelVector; /** \brief values in this array set a priority to each label. Higher priority labels are not covert by labels with lower priority.*/ std::vector m_PriorityVector; /** \brief The coordinates of the labels. Indices must match the labelVector and the priorityVector.*/ itk::SmartPointer m_LabelCoordinates; + unsigned long m_PointSetModifiedObserverTag; + /** \brief copy constructor */ LabelOverlay3D( const LabelOverlay3D &); /** \brief assignment operator */ LabelOverlay3D &operator=(const LabelOverlay3D &); }; } // namespace mitk #endif // LabelOverlay3D_H diff --git a/Core/Code/Rendering/mitkMapper.cpp b/Core/Code/Rendering/mitkMapper.cpp index f2157b2bed..df8c890dfe 100644 --- a/Core/Code/Rendering/mitkMapper.cpp +++ b/Core/Code/Rendering/mitkMapper.cpp @@ -1,165 +1,177 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkMapper.h" #include "mitkDataNode.h" #include "mitkBaseRenderer.h" #include "mitkProperties.h" +#include "mitkOverlayManager.h" mitk::Mapper::Mapper() : m_DataNode(NULL) , m_TimeStep( 0 ) { } mitk::Mapper::~Mapper() { } mitk::BaseData* mitk::Mapper::GetData() const { return m_DataNode == NULL ? NULL : m_DataNode->GetData(); } mitk::DataNode* mitk::Mapper::GetDataNode() const { return this->m_DataNode; } bool mitk::Mapper::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetColor(rgb, renderer, name); } bool mitk::Mapper::GetVisibility(bool &visible, mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetVisibility(visible, renderer, name); } bool mitk::Mapper::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetOpacity(opacity, renderer, name); } bool mitk::Mapper::GetLevelWindow(mitk::LevelWindow& levelWindow, mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetLevelWindow(levelWindow, renderer, name); } bool mitk::Mapper::IsVisible(mitk::BaseRenderer* renderer, const char* name) const { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, name); return visible; } void mitk::Mapper::CalculateTimeStep( mitk::BaseRenderer *renderer ) { if ( ( renderer != NULL ) && ( m_DataNode != NULL ) ) { m_TimeStep = renderer->GetTimeStep(m_DataNode->GetData()); } else { m_TimeStep = 0; } } void mitk::Mapper::Update(mitk::BaseRenderer *renderer) { + if(GetOverlayManager()) + GetOverlayManager()->AddBaseRenderer(renderer); + const DataNode* node = GetDataNode(); assert(node!=NULL); mitk::BaseData * data = static_cast(node->GetData()); if (!data) return; // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); // Check if time step is valid const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->CountTimeSteps() == 0 ) || ( !dataTimeGeometry->IsValidTimeStep( m_TimeStep ) ) ) { // TimeGeometry or time step is not valid for this data: // reset mapper so that nothing is displayed this->ResetMapper( renderer ); return; } this->GenerateDataForRenderer(renderer); + if(GetOverlayManager()) + GetOverlayManager()->UpdateOverlays(renderer); } bool mitk::Mapper::BaseLocalStorage::IsGenerateDataRequired( mitk::BaseRenderer *renderer, mitk::Mapper *mapper, mitk::DataNode *dataNode) const { if( mapper && m_LastGenerateDataTime < mapper -> GetMTime () ) return true; if( dataNode ) { if( m_LastGenerateDataTime < dataNode -> GetDataReferenceChangedTime () ) return true; mitk::BaseData * data = dataNode -> GetData ( ) ; if( data && m_LastGenerateDataTime < data -> GetMTime ( ) ) return true; } if( renderer && m_LastGenerateDataTime < renderer -> GetTimeStepUpdateTime ( ) ) return true; return false; } void mitk::Mapper::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "visible", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "layer", mitk::IntProperty::New(0), renderer, overwrite); node->AddProperty( "name", mitk::StringProperty::New("No Name!"), renderer, overwrite ); } + + +mitk::OverlayManager* mitk::Mapper::GetOverlayManager() const +{ + return NULL; +} diff --git a/Core/Code/Rendering/mitkMapper.h b/Core/Code/Rendering/mitkMapper.h index b0919b6712..1e31953dda 100644 --- a/Core/Code/Rendering/mitkMapper.h +++ b/Core/Code/Rendering/mitkMapper.h @@ -1,239 +1,239 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MAPPER_H_HEADER_INCLUDED_C1E6EA08 #define MAPPER_H_HEADER_INCLUDED_C1E6EA08 #include #include "mitkBaseRenderer.h" #include "mitkVtkPropRenderer.h" #include "mitkLevelWindow.h" #include "mitkCommon.h" #include "mitkLocalStorageHandler.h" #include #include //Just included to get VTK version #include class vtkWindow; class vtkProp; namespace mitk { class BaseRenderer; class BaseData; class DataNode; - + class OverlayManager; /** \brief Base class of all mappers, Vtk as well as OpenGL mappers * * By the help of mappers, the input data is transformed to tangible primitives, * such as surfaces, points, lines, etc. * This is the base class of all mappers, Vtk as well as OpenGL mappers. * Subclasses of mitk::Mapper control the creation of rendering primitives * that interface to the graphics library (e.g., OpenGL, vtk). * * \todo Should Mapper be a subclass of ImageSource? * \ingroup Mapper */ class MITK_CORE_EXPORT Mapper : public itk::Object { public: mitkClassMacro(Mapper, itk::Object); /** \brief Set the DataNode containing the data to map */ itkSetObjectMacro(DataNode, DataNode); /** \brief Get the DataNode containing the data to map. * Method only returns valid DataNode Pointer if the mapper belongs to a data node. * Otherwise, the returned DataNode Pointer might be invalid. */ virtual DataNode* GetDataNode() const; /**\brief Get the data to map * * Returns the mitk::BaseData object associated with this mapper. * \return the mitk::BaseData associated with this mapper. * \deprecatedSince{2013_03} Use GetDataNode()->GetData() instead to access the data */ DEPRECATED(BaseData* GetData() const); /** \brief Convenience access method for color properties (instances of * ColorProperty) * \return \a true property was found * \deprecatedSince{2013_03} Use GetDataNode()->GetColor(...) instead to get the color */ DEPRECATED(virtual bool GetColor(float rgb[3], BaseRenderer* renderer, const char* name = "color") const); /** \brief Convenience access method for visibility properties (instances * of BoolProperty) * \return \a true property was found * \sa IsVisible * \deprecatedSince{2013_03} Use GetDataNode()->GetVisibility(...) instead to get the visibility */ DEPRECATED(virtual bool GetVisibility(bool &visible, BaseRenderer* renderer, const char* name = "visible") const); /** \brief Convenience access method for opacity properties (instances of * FloatProperty) * \return \a true property was found * \deprecatedSince{2013_03} Use GetDataNode()->GetOpacity(...) instead to get the opacity */ DEPRECATED(virtual bool GetOpacity(float &opacity, BaseRenderer* renderer, const char* name = "opacity") const); /** \brief Convenience access method for color properties (instances of * LevelWindoProperty) * \return \a true property was found * \deprecatedSince{2013_03} Use GetDataNode->GetLevelWindow(...) instead to get the levelwindow */ DEPRECATED(virtual bool GetLevelWindow(LevelWindow &levelWindow, BaseRenderer* renderer, const char* name = "levelwindow") const); /** \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 * \deprecatedSince{2013_03} Use GetDataNode()->GetVisibility(...) instead */ DEPRECATED(virtual bool IsVisible(BaseRenderer* renderer, const char* name = "visible") const); /** \brief Returns whether this is an vtk-based mapper * \deprecatedSince{2013_03} All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead */ virtual bool IsVtkBased() const = 0; /** \brief Calls the time step of the input data for the specified renderer and checks * whether the time step is valid and calls method GenerateDataForRenderer() */ virtual void Update(BaseRenderer* renderer); /** \brief Responsible for calling the appropriate render functions. * To be implemented in sub-classes. */ virtual void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type) = 0; /** * \brief Apply specific color and opacity properties read from the PropertyList. * Reimplemented in GLmapper (does not use the actor) and the VtkMapper class. * The function is called by the individual mapper (mostly in the ApplyProperties() or ApplyAllProperties() * method). */ virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL) = 0; /** \brief Set default values of properties used by this mapper * to \a node * * \param node The node for which the properties are set * \param overwrite overwrite existing properties (default: \a false) * \param renderer defines which property list of node is used * (default: \a NULL, i.e. default property list) */ static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); /** \brief Returns the current time step as calculated from the renderer */ int GetTimestep() const { return m_TimeStep; } /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled( BaseRenderer * /*renderer*/ ) const { return false; } protected: /** \brief explicit constructor which disallows implicit conversions */ explicit Mapper(); /** \brief virtual destructor in order to derive from this class */ virtual ~Mapper(); /** \brief Generate the data needed for rendering (independent of a specific renderer) * \deprecatedSince{2013_03} Use GenerateDataForRenderer(BaseRenderer* renderer) instead. */ DEPRECATED( virtual void GenerateData() ) { } /** \brief Generate the data needed for rendering into \a renderer */ virtual void GenerateDataForRenderer(BaseRenderer* /* renderer */) { } /** \brief Updates the time step, which is sometimes needed in subclasses */ virtual void CalculateTimeStep( BaseRenderer* renderer ); /** \brief Reset the mapper (i.e., make sure that nothing is displayed) if no * valid data is present. In most cases the reimplemented function * disables the according actors (toggling visibility off) * * To be implemented in sub-classes. */ virtual void ResetMapper( BaseRenderer* /*renderer*/ ) { } - mitk::DataNode * m_DataNode; + virtual OverlayManager* GetOverlayManager() const; + mitk::DataNode * m_DataNode; private: /** \brief The current time step of the dataset to be rendered, * for use in subclasses. * The current timestep can be accessed via the GetTimestep() method. */ int m_TimeStep; /** \brief copy constructor */ Mapper( const Mapper &); /** \brief assignment operator */ Mapper &operator=(const Mapper &); - public: /** \brief Base class for mapper specific rendering ressources. */ class MITK_CORE_EXPORT BaseLocalStorage { public: bool IsGenerateDataRequired(mitk::BaseRenderer *renderer,mitk::Mapper *mapper,mitk::DataNode *dataNode) const; inline void UpdateGenerateDataTime() { m_LastGenerateDataTime.Modified(); } inline itk::TimeStamp & GetLastGenerateDataTime() { return m_LastGenerateDataTime; } protected: /** \brief timestamp of last update of stored data */ itk::TimeStamp m_LastGenerateDataTime; }; }; } // namespace mitk #endif /* MAPPER_H_HEADER_INCLUDED_C1E6EA08 */ diff --git a/Core/Code/Rendering/mitkOverlay.cpp b/Core/Code/Rendering/mitkOverlay.cpp index 41f2b83f3e..f827c6eb26 100644 --- a/Core/Code/Rendering/mitkOverlay.cpp +++ b/Core/Code/Rendering/mitkOverlay.cpp @@ -1,293 +1,293 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkOverlay.h" mitk::Overlay::Overlay() : m_LayoutedBy(NULL) { m_PropertyList = mitk::PropertyList::New(); } mitk::Overlay::~Overlay() { } void mitk::Overlay::SetProperty(const std::string& propertyKey, const BaseProperty::Pointer& propertyValue, const mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue); this->Modified(); } void mitk::Overlay::ReplaceProperty(const std::string& propertyKey, const BaseProperty::Pointer& propertyValue, const mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue); } void mitk::Overlay::AddProperty(const std::string& propertyKey, const BaseProperty::Pointer& propertyValue, const mitk::BaseRenderer* renderer, bool overwrite) { if((overwrite) || (GetProperty(propertyKey, renderer) == NULL)) { SetProperty(propertyKey, propertyValue, renderer); } } void mitk::Overlay::ConcatenatePropertyList(PropertyList *pList, bool replace) { m_PropertyList->ConcatenatePropertyList(pList, replace); } mitk::BaseProperty* mitk::Overlay::GetProperty(const std::string& propertyKey, const mitk::BaseRenderer* renderer) const { //renderer specified? if (renderer) { std::map::const_iterator it; //check for the renderer specific property it=m_MapOfPropertyLists.find(renderer); if(it!=m_MapOfPropertyLists.end()) //found { mitk::BaseProperty::Pointer property; property=it->second->GetProperty(propertyKey); if(property.IsNotNull())//found an enabled property in the render specific list return property; else //found a renderer specific list, but not the desired property return m_PropertyList->GetProperty(propertyKey); //return renderer unspecific property } else //didn't find the property list of the given renderer { //return the renderer unspecific property if there is one return m_PropertyList->GetProperty(propertyKey); } } else //no specific renderer given; use the renderer independent one { mitk::BaseProperty::Pointer property; property=m_PropertyList->GetProperty(propertyKey); if(property.IsNotNull()) return property; } //only to satisfy compiler! return NULL; } bool mitk::Overlay::GetBoolProperty(const std::string& propertyKey, bool& boolValue, 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::Overlay::GetIntProperty(const std::string& propertyKey, int &intValue, 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::Overlay::GetFloatProperty(const std::string& propertyKey, float &floatValue, 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::Overlay::GetStringProperty(const std::string& propertyKey, std::string& string, 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; } } void mitk::Overlay::SetIntProperty(const std::string& propertyKey, int intValue, mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::Overlay::SetBoolProperty( const std::string& propertyKey, bool boolValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::Overlay::SetFloatProperty( const std::string& propertyKey, float floatValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::Overlay::SetStringProperty( const std::string& propertyKey, const std::string& stringValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } std::string mitk::Overlay::GetName() const { mitk::StringProperty* sp = dynamic_cast(this->GetProperty("name")); if (sp == NULL) return ""; return sp->GetValue(); } void mitk::Overlay::SetName(const std::string& name) { this->SetStringProperty("name", name); } bool mitk::Overlay::GetName(std::string& nodeName, mitk::BaseRenderer* renderer, const std::string& propertyKey) const { return GetStringProperty(propertyKey, nodeName, renderer); } void mitk::Overlay::SetText(std::string text) { SetStringProperty("Overlay.Text", text.c_str()); } std::string mitk::Overlay::GetText() const { std::string text; GetPropertyList()->GetStringProperty("Overlay.Text", text); return text; } void mitk::Overlay::SetFontSize(int fontSize) { SetIntProperty("Overlay.FontSize",fontSize); } int mitk::Overlay::GetFontSize() const { - int fontSize; + int fontSize = 1; GetPropertyList()->GetIntProperty("Overlay.FontSize", fontSize); return fontSize; } bool mitk::Overlay::GetVisibility(bool& visible, mitk::BaseRenderer* renderer, const std::string& propertyKey) const { return GetBoolProperty(propertyKey, visible, renderer); } bool mitk::Overlay::IsVisible(mitk::BaseRenderer* renderer, const std::string& propertyKey, bool defaultIsOn) const { return IsOn(propertyKey, renderer, defaultIsOn); } bool mitk::Overlay::GetColor(float rgb[], mitk::BaseRenderer* renderer, const std::string& 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; } void mitk::Overlay::SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer, const std::string& propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(color); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::Overlay::SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer, const std::string& propertyKey) { float color[3]; color[0]=red; color[1]=green; color[2]=blue; SetColor(color, renderer, propertyKey); } void mitk::Overlay::SetColor(const float rgb[], mitk::BaseRenderer* renderer, const std::string& propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(rgb); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } bool mitk::Overlay::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const std::string& propertyKey) const { mitk::FloatProperty::Pointer opacityprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(opacityprop.IsNull()) return false; opacity=opacityprop->GetValue(); return true; } void mitk::Overlay::SetOpacity(float opacity, mitk::BaseRenderer* renderer, const std::string& propertyKey) { mitk::FloatProperty::Pointer prop; prop = mitk::FloatProperty::New(opacity); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::Overlay::SetVisibility(bool visible, mitk::BaseRenderer *renderer, const std::string& propertyKey) { mitk::BoolProperty::Pointer prop; prop = mitk::BoolProperty::New(visible); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } mitk::PropertyList* mitk::Overlay::GetPropertyList(const mitk::BaseRenderer* renderer) const { if(renderer==NULL) return m_PropertyList; mitk::PropertyList::Pointer & propertyList = m_MapOfPropertyLists[renderer]; if(propertyList.IsNull()) propertyList = mitk::PropertyList::New(); assert(m_MapOfPropertyLists[renderer].IsNotNull()); return propertyList; } bool mitk::Overlay::BaseLocalStorage::IsGenerateDataRequired(mitk::BaseRenderer *renderer, mitk::Overlay *overlay) { if( m_LastGenerateDataTime < overlay -> GetMTime () ) return true; if( renderer && m_LastGenerateDataTime < renderer -> GetTimeStepUpdateTime ( ) ) return true; return false; } diff --git a/Core/Code/Rendering/mitkOverlay.h b/Core/Code/Rendering/mitkOverlay.h index cf9376d83f..026b6b3bfe 100644 --- a/Core/Code/Rendering/mitkOverlay.h +++ b/Core/Code/Rendering/mitkOverlay.h @@ -1,429 +1,427 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef OVERLAY_H #define OVERLAY_H #include #include #include namespace mitk { class AbstractOverlayLayouter; /** \brief Base class for all overlays */ /** This class is to be implemented in order to create overlays which are managed by the OverlayManager and can be placed by a AbstractOverlayLayouter. This class contains an internal Propertylist, and another PropertyList for each BaseRenderer. A property that is specified for a specific renderer always overrides the general internal property of the same name. AddOverlay, RemoveOverlay and UpdateOverlay methods have to be implemented.*/ class MITK_CORE_EXPORT Overlay : public itk::Object { friend class AbstractOverlayLayouter; public: /** \brief Container for position and size on the display.*/ struct Bounds { itk::Point Position; itk::Point Size; }; typedef std::map MapOfPropertyLists; /** \brief Base class for mapper specific rendering ressources. */ class MITK_CORE_EXPORT BaseLocalStorage { public: bool IsGenerateDataRequired(mitk::BaseRenderer *renderer,mitk::Overlay *overlay); inline void UpdateGenerateDataTime() { m_LastGenerateDataTime.Modified(); } inline itk::TimeStamp & GetLastGenerateDataTime() { return m_LastGenerateDataTime; } protected: /** \brief timestamp of last update of stored data */ itk::TimeStamp m_LastGenerateDataTime; }; /** * @brief Set the property (instance of BaseProperty) with key @a propertyKey in the PropertyList * of the @a renderer (if NULL, 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 std::string& propertyKey, const BaseProperty::Pointer& property, const mitk::BaseRenderer* renderer = NULL); /** * @brief Replace the property (instance of BaseProperty) with key @a propertyKey in the PropertyList * of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-reference. * * If @a renderer is @a NULL the property is set in the BaseRenderer-independent * PropertyList of this Overlay. * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void ReplaceProperty(const std::string& propertyKey, const BaseProperty::Pointer& property, const mitk::BaseRenderer* renderer = NULL); /** * @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 NULL, 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 std::string& propertyKey, const BaseProperty::Pointer& property, const mitk::BaseRenderer* renderer = NULL, bool overwrite = false); /** * @brief Get the PropertyList of the @a renderer. If @a renderer is @a * NULL, the BaseRenderer-independent PropertyList of this Overlay * is returned. * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ mitk::PropertyList* GetPropertyList(const mitk::BaseRenderer* renderer = NULL) 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 NULL or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Overlay is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ mitk::BaseProperty* GetProperty(const std::string& propertyKey, const mitk::BaseRenderer* renderer = NULL) 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 NULL or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Overlay is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ template bool GetProperty(itk::SmartPointer &property, const std::string& propertyKey, const mitk::BaseRenderer* renderer = NULL) 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 NULL or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Overlay is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ template bool GetProperty(T* &property, const std::string& propertyKey, const mitk::BaseRenderer* renderer = NULL) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property!=NULL; } /** * @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 std::string& propertyKey, T & value, mitk::BaseRenderer* renderer=NULL) const { GenericProperty* gp= dynamic_cast*>(GetProperty(propertyKey, renderer)); if ( gp != NULL ) { value = gp->GetValue(); return true; } return false; } /** * @brief Convenience access method for bool properties (instances of * BoolProperty) * @return @a true property was found */ bool GetBoolProperty(const std::string& propertyKey, bool &boolValue, mitk::BaseRenderer* renderer = NULL) const; /** * @brief Convenience access method for int properties (instances of * IntProperty) * @return @a true property was found */ bool GetIntProperty(const std::string& propertyKey, int &intValue, mitk::BaseRenderer* renderer=NULL) const; /** * @brief Convenience access method for float properties (instances of * FloatProperty) * @return @a true property was found */ bool GetFloatProperty(const std::string& propertyKey, float &floatValue, mitk::BaseRenderer* renderer = NULL) const; /** * @brief Convenience access method for string properties (instances of * StringProperty) * @return @a true property was found */ bool GetStringProperty(const std::string& propertyKey, std::string& string, mitk::BaseRenderer* renderer = NULL) const; /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetIntProperty(const std::string& propertyKey, int intValue, mitk::BaseRenderer* renderer=NULL); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetBoolProperty(const std::string& propertyKey, bool boolValue, mitk::BaseRenderer* renderer=NULL); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetFloatProperty(const std::string& propertyKey, float floatValue, mitk::BaseRenderer* renderer=NULL); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetStringProperty(const std::string& propertyKey, const std::string& string, mitk::BaseRenderer* renderer=NULL); /** * @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 std::string& propertyKey, mitk::BaseRenderer* renderer, bool defaultIsOn = true) const { GetBoolProperty(propertyKey, defaultIsOn, renderer); return defaultIsOn; } /** * @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, mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "name") const; /** * @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; /** * @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); /** * @brief Convenience access method for color properties (instances of * ColorProperty) * @return @a true property was found */ bool GetColor(float rgb[], mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "color") const; /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "color"); /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "color"); /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const float rgb[], mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "color"); /** * @brief Convenience access method for opacity properties (instances of * FloatProperty) * @return @a true property was found */ bool GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const std::string& propertyKey = "opacity") const; /** * @brief Convenience method for setting opacity properties (instances of * FloatProperty) */ void SetOpacity(float opacity, mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "opacity"); void SetText(std::string text); std::string GetText() const; void SetFontSize(int fontSize); int GetFontSize() const; /** * @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, mitk::BaseRenderer* renderer, const std::string& propertyKey = "visible") const; /** * @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(mitk::BaseRenderer* renderer, const std::string& propertyKey = "visible", bool defaultIsOn = true) const; /** * @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, mitk::BaseRenderer* renderer = NULL, const std::string& propertyKey = "visible"); /** \brief Adds the overlay to the specified renderer. Update Overlay should be called soon in order to apply all properties*/ virtual void AddToBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Removes the overlay from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Applies all properties and should be called before the rendering procedure.*/ virtual void Update(BaseRenderer *renderer) = 0; /** \brief Returns position and size of the overlay on the display.*/ virtual Bounds GetBoundsOnDisplay(BaseRenderer *renderer) const = 0; /** \brief Sets position and size of the overlay on the display.*/ virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds&) = 0; mitkClassMacro(Overlay, itk::Object); protected: /** \brief explicit constructor which disallows implicit conversions */ explicit Overlay(); /** \brief virtual destructor in order to derive from this class */ virtual ~Overlay(); /** * @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; /** * @brief Timestamp of the last change of m_Data */ itk::TimeStamp m_DataReferenceChangedTime; - unsigned long m_PropertyListModifiedObserverTag; - private: /** \brief copy constructor */ Overlay( const Overlay &); /** \brief assignment operator */ Overlay &operator=(const Overlay &); /** \brief Reference to the layouter in which this overlay is managed. */ AbstractOverlayLayouter* m_LayoutedBy; }; } // namespace mitk #endif // OVERLAY_H diff --git a/Core/Code/Rendering/mitkOverlayManager.cpp b/Core/Code/Rendering/mitkOverlayManager.cpp index 1b0e3b3e93..b74124387c 100644 --- a/Core/Code/Rendering/mitkOverlayManager.cpp +++ b/Core/Code/Rendering/mitkOverlayManager.cpp @@ -1,148 +1,166 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkOverlayManager.h" #include "mitkBaseRenderer.h" mitk::OverlayManager::OverlayManager() { } mitk::OverlayManager::~OverlayManager() { + RemoveAllOverlays(); } void mitk::OverlayManager::AddBaseRenderer(mitk::BaseRenderer* renderer) { std::pair inSet; inSet = m_BaseRendererSet.insert(renderer); if(inSet.second) { OverlaySet::iterator it; for ( it=m_OverlaySet.begin() ; it != m_OverlaySet.end(); it++ ) { (*it)->AddToBaseRenderer(renderer); } } } void mitk::OverlayManager::RemoveBaseRenderer(mitk::BaseRenderer* renderer) { if(!renderer) return; std::pair inSet; inSet = m_BaseRendererSet.insert(renderer); m_BaseRendererSet.erase(inSet.first); + + OverlaySet::iterator it; + for ( it=m_OverlaySet.begin() ; it != m_OverlaySet.end(); it++ ) + { + (*it)->RemoveFromBaseRenderer(*inSet.first); + } + } void mitk::OverlayManager::AddOverlay(const Overlay::Pointer& overlay) { std::pair inSet; inSet = m_OverlaySet.insert(overlay); if(inSet.second) { BaseRendererSet::iterator it; for ( it=m_BaseRendererSet.begin() ; it != m_BaseRendererSet.end(); it++ ) { overlay->AddToBaseRenderer(*it); } } } +void mitk::OverlayManager::AddOverlay(const Overlay::Pointer& overlay, BaseRenderer* renderer) +{ + std::pair inSet; + inSet = m_OverlaySet.insert(overlay); + if(inSet.second) + { + overlay->AddToBaseRenderer(renderer); + } +} + void mitk::OverlayManager::RemoveOverlay(const Overlay::Pointer &overlay) { std::pair inSet; inSet = m_OverlaySet.insert(overlay); if(!inSet.second) { BaseRendererSet::iterator it; for ( it=m_BaseRendererSet.begin() ; it != m_BaseRendererSet.end(); it++ ) { overlay->RemoveFromBaseRenderer(*it); } } m_OverlaySet.erase(inSet.first); } void mitk::OverlayManager::RemoveAllOverlays() { OverlaySet::iterator it; for ( it=m_OverlaySet.begin() ; it != m_OverlaySet.end(); it++ ) { RemoveOverlay(*it); } m_OverlaySet.clear(); } void mitk::OverlayManager::UpdateOverlays(mitk::BaseRenderer* baseRenderer) { OverlaySet::iterator it; for ( it=m_OverlaySet.begin() ; it != m_OverlaySet.end(); it++ ) { (*it)->Update(baseRenderer); } UpdateLayouts(baseRenderer); } void mitk::OverlayManager::SetLayouter(Overlay *overlay, const std::string &identifier, mitk::BaseRenderer *renderer) { if(renderer) { AbstractOverlayLayouter::Pointer layouter = GetLayouter(renderer,identifier); if(layouter.IsNull()) { MITK_WARN << "Layouter " << identifier << " cannot be found or created!"; return; } else { layouter->AddOverlay(overlay); } } } void mitk::OverlayManager::UpdateLayouts(mitk::BaseRenderer *renderer) { LayouterMap layouters = m_LayouterMap[renderer]; LayouterMap::iterator it; for ( it=layouters.begin() ; it != layouters.end(); it++ ) { (it->second)->PrepareLayout(); } } mitk::AbstractOverlayLayouter::Pointer mitk::OverlayManager::GetLayouter(mitk::BaseRenderer *renderer, const std::string& identifier) { AbstractOverlayLayouter::Pointer layouter = m_LayouterMap[renderer][identifier]; return layouter; } void mitk::OverlayManager::AddLayouter(const AbstractOverlayLayouter::Pointer& layouter) { if(layouter.IsNotNull()) { AbstractOverlayLayouter::Pointer oldLayouter = m_LayouterMap[layouter->GetBaseRenderer()][layouter->GetIdentifier()]; if(oldLayouter.IsNotNull() && oldLayouter.GetPointer() != layouter.GetPointer()) { MITK_WARN << "Layouter " << layouter->GetIdentifier() << " does already exist!"; } else if(oldLayouter.IsNull()) { m_LayouterMap[layouter->GetBaseRenderer()][layouter->GetIdentifier()] = layouter; } } } diff --git a/Core/Code/Rendering/mitkOverlayManager.h b/Core/Code/Rendering/mitkOverlayManager.h index 57ffcf3c37..c4e854f453 100644 --- a/Core/Code/Rendering/mitkOverlayManager.h +++ b/Core/Code/Rendering/mitkOverlayManager.h @@ -1,97 +1,98 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef OVERLAYMANAGER_H #define OVERLAYMANAGER_H #include "MitkExports.h" #include #include #include "mitkOverlay.h" #include "mitkAbstractOverlayLayouter.h" #include "mitkLocalStorageHandler.h" namespace mitk { class BaseRenderer; /** \brief The OverlayManager updates and manages Overlays and the respective Layouters. */ /** An Instance of the OverlayManager can be registered to several BaseRenderer instances in order to * call the update method of each Overlay during the rendering phase of the renderer. * See \ref OverlaysPage for more info. */ class MITK_CORE_EXPORT OverlayManager : public itk::LightObject { public: typedef std::set BaseRendererSet; typedef std::set OverlaySet; typedef std::map LayouterMap; typedef std::map LayouterRendererMap; mitkClassMacro(OverlayManager, itk::LightObject); itkNewMacro(OverlayManager); void AddOverlay(const Overlay::Pointer& overlay); + void AddOverlay(const Overlay::Pointer& overlay, BaseRenderer* renderer); void RemoveOverlay(const Overlay::Pointer& overlay); /** \brief Clears the manager of all Overlays.*/ void RemoveAllOverlays(); /** \brief Adds the overlay to the layouter specified by identifier and renderer*/ void SetLayouter(Overlay* overlay, const std::string& identifier, BaseRenderer* renderer); /** \brief Calls all layouters to update the position and size of the registered Overlays*/ void UpdateLayouts(BaseRenderer* renderer); /** \brief Returns the Layouter specified by renderer and the identifier*/ AbstractOverlayLayouter::Pointer GetLayouter(BaseRenderer* renderer, const std::string& identifier); /** \brief Add a layouter to provide it with the use of the SetLayouter method*/ void AddLayouter(const AbstractOverlayLayouter::Pointer& layouter); void AddBaseRenderer(BaseRenderer* renderer); /** \brief The layout of each Overlay will be prepared and the properties of each Overlay is updated.*/ void UpdateOverlays(BaseRenderer *baseRenderer); void RemoveBaseRenderer(mitk::BaseRenderer *renderer); protected: /** \brief explicit constructor which disallows implicit conversions */ explicit OverlayManager(); ~OverlayManager(); private: OverlaySet m_OverlaySet; BaseRendererSet m_BaseRendererSet; LayouterRendererMap m_LayouterMap; /** \brief copy constructor */ OverlayManager( const OverlayManager &); /** \brief assignment operator */ OverlayManager &operator=(const OverlayManager &); }; } // namespace mitk #endif // OVERLAYMANAGER_H diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp index d40171d355..dc06cdbd9a 100644 --- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp @@ -1,641 +1,631 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPointSetVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkPointSet.h" +#include "mitkLabelOverlay3D.h" +#include "mitkOverlayManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const mitk::PointSet* mitk::PointSetVtkMapper3D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } mitk::PointSetVtkMapper3D::PointSetVtkMapper3D() : m_vtkSelectedPointList(NULL), m_vtkUnselectedPointList(NULL), m_VtkSelectedPolyDataMapper(NULL), m_VtkUnselectedPolyDataMapper(NULL), m_vtkTextList(NULL), m_NumberOfSelectedAdded(0), m_NumberOfUnselectedAdded(0), m_PointSize(1.0), m_ContourRadius(0.5) { //propassembly m_PointsAssembly = vtkSmartPointer::New(); //creating actors to be able to set transform m_SelectedActor = vtkSmartPointer::New(); m_UnselectedActor = vtkSmartPointer::New(); m_ContourActor = vtkSmartPointer::New(); + + m_OverlayManager = mitk::OverlayManager::New(); + m_LabelOverlay = mitk::LabelOverlay3D::New(); + m_OverlayManager->AddOverlay(m_LabelOverlay.GetPointer()); } mitk::PointSetVtkMapper3D::~PointSetVtkMapper3D() { } void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow *renWin) { m_PointsAssembly->ReleaseGraphicsResources(renWin); m_SelectedActor->ReleaseGraphicsResources(renWin); m_UnselectedActor->ReleaseGraphicsResources(renWin); m_ContourActor->ReleaseGraphicsResources(renWin); } void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(mitk::BaseRenderer* renderer) { m_PointsAssembly->ReleaseGraphicsResources(renderer->GetRenderWindow()); m_SelectedActor->ReleaseGraphicsResources(renderer->GetRenderWindow()); m_UnselectedActor->ReleaseGraphicsResources(renderer->GetRenderWindow()); m_ContourActor->ReleaseGraphicsResources(renderer->GetRenderWindow()); } void mitk::PointSetVtkMapper3D::CreateVTKRenderObjects() { m_vtkSelectedPointList = vtkSmartPointer::New(); m_vtkUnselectedPointList = vtkSmartPointer::New(); m_PointsAssembly->VisibilityOn(); if(m_PointsAssembly->GetParts()->IsItemPresent(m_SelectedActor)) m_PointsAssembly->RemovePart(m_SelectedActor); if(m_PointsAssembly->GetParts()->IsItemPresent(m_UnselectedActor)) m_PointsAssembly->RemovePart(m_UnselectedActor); if(m_PointsAssembly->GetParts()->IsItemPresent(m_ContourActor)) m_PointsAssembly->RemovePart(m_ContourActor); // exceptional displaying for PositionTracker -> MouseOrientationTool int mapperID; bool isInputDevice=false; if( this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice ) { if( this->GetDataNode()->GetIntProperty("BaseRendererMapperID",mapperID) && mapperID == 2) return; //The event for the PositionTracker came from the 3d widget and not needs to be displayed } // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); /* only update the input data, if the property tells us to */ bool update = true; this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); if (update == true) input->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { m_PointsAssembly->VisibilityOff(); return; } mitk::PointSet::PointsContainer::Iterator pointsIter; mitk::PointSet::PointDataContainer::Iterator pointDataIter; int j; m_NumberOfSelectedAdded = 0; m_NumberOfUnselectedAdded = 0; //create contour bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { this->CreateContour(); } //now fill selected and unselected pointList //get size of Points in Property m_PointSize = 2; mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); if ( pointSizeProp.IsNotNull() ) m_PointSize = pointSizeProp->GetValue(); //get the property for creating a label onto every point only once bool showLabel = true; this->GetDataNode()->GetBoolProperty("show label", showLabel); const char * pointLabel=NULL; if(showLabel) { + m_LabelOverlay->SetVisibility(true); if(dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label")) != NULL) pointLabel =dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label"))->GetValue(); else showLabel = false; } - + std::vector labelVector; //check if the list for the PointDataContainer is the same size as the PointsContainer. Is not, then the points were inserted manually and can not be visualized according to the PointData (selected/unselected) bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); //now add an object for each point in data pointDataIter = itkPointSet->GetPointData()->Begin(); for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End(); pointsIter++, j++) { //check for the pointtype in data and decide which geom-object to take and then add to the selected or unselected list int pointType; if(itkPointSet->GetPointData()->size() == 0 || pointDataBroken) pointType = mitk::PTUNDEFINED; else pointType = pointDataIter.Value().pointSpec; vtkSmartPointer source; switch (pointType) { case mitk::PTUNDEFINED: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetCenter(point1[0],point1[1],point1[2]); //sphere->SetCenter(pointsIter.Value()[0],pointsIter.Value()[1],pointsIter.Value()[2]); //MouseOrientation Tool (PositionTracker) if(isInputDevice) { sphere->SetThetaResolution(10); sphere->SetPhiResolution(10); } else { sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); } source = sphere; } break; case mitk::PTSTART: { vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetXLength(m_PointSize/2); cube->SetYLength(m_PointSize/2); cube->SetZLength(m_PointSize/2); itk::Point point1 = pointsIter->Value(); cube->SetCenter(point1[0],point1[1],point1[2]); source = cube; } break; case mitk::PTCORNER: { vtkSmartPointer cone = vtkSmartPointer::New(); cone->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); cone->SetCenter(point1[0],point1[1],point1[2]); cone->SetResolution(20); source = cone; } break; case mitk::PTEDGE: { vtkSmartPointer cylinder = vtkSmartPointer::New(); cylinder->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); cylinder->SetCenter(point1[0],point1[1],point1[2]); cylinder->SetResolution(20); source = cylinder; } break; case mitk::PTEND: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize); //itk::Point point1 = pointsIter->Value(); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; default: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetCenter(point1[0],point1[1],point1[2]); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; } if (!pointDataBroken) { if (pointDataIter.Value().selected) { m_vtkSelectedPointList->AddInputConnection(source->GetOutputPort()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInputConnection(source->GetOutputPort()); ++m_NumberOfUnselectedAdded; } } else { m_vtkUnselectedPointList->AddInputConnection(source->GetOutputPort()); ++m_NumberOfUnselectedAdded; } if (showLabel) { char buffer[20]; std::string l = pointLabel; if ( input->GetSize()>1 ) { sprintf(buffer,"%d",j+1); l.append(buffer); } - // Define the text for the label - vtkSmartPointer label = vtkSmartPointer::New(); - label->SetText(l.c_str()); - - //# Set up a transform to move the label to a new position. - vtkSmartPointer aLabelTransform = vtkSmartPointer::New(); - aLabelTransform->Identity(); - itk::Point point1 = pointsIter->Value(); - aLabelTransform->Translate(point1[0]+2,point1[1]+2,point1[2]); - aLabelTransform->Scale(5.7,5.7,5.7); - - //# Move the label to a new position. - vtkSmartPointer labelTransform = vtkSmartPointer::New(); - labelTransform->SetTransform(aLabelTransform); - labelTransform->SetInputConnection(label->GetOutputPort()); - - //add it to the wright PointList - if (pointType) - { - m_vtkSelectedPointList->AddInputConnection(labelTransform->GetOutputPort()); - ++m_NumberOfSelectedAdded; - } - else - { - m_vtkUnselectedPointList->AddInputConnection(labelTransform->GetOutputPort()); - ++m_NumberOfUnselectedAdded; - } + labelVector.push_back(l); } if(pointDataIter != itkPointSet->GetPointData()->End()) pointDataIter++; } // end FOR + m_LabelOverlay->SetLabelVector(labelVector); //now according to number of elements added to selected or unselected, build up the rendering pipeline if (m_NumberOfSelectedAdded > 0) { m_VtkSelectedPolyDataMapper = vtkSmartPointer::New(); m_VtkSelectedPolyDataMapper->SetInputConnection(m_vtkSelectedPointList->GetOutputPort()); //create a new instance of the actor m_SelectedActor = vtkSmartPointer::New(); m_SelectedActor->SetMapper(m_VtkSelectedPolyDataMapper); m_PointsAssembly->AddPart(m_SelectedActor); } if (m_NumberOfUnselectedAdded > 0) { m_VtkUnselectedPolyDataMapper = vtkSmartPointer::New(); m_VtkUnselectedPolyDataMapper->SetInputConnection(m_vtkUnselectedPointList->GetOutputPort()); //create a new instance of the actor m_UnselectedActor = vtkSmartPointer::New(); m_UnselectedActor->SetMapper(m_VtkUnselectedPolyDataMapper); m_PointsAssembly->AddPart(m_UnselectedActor); } } +mitk::OverlayManager *mitk::PointSetVtkMapper3D::GetOverlayManager() const +{ + return m_OverlayManager.GetPointer(); +} + void mitk::PointSetVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if(!visible) { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); m_ContourActor->VisibilityOff(); + m_LabelOverlay->SetVisibility(false); return; } + m_LabelOverlay->SetLabelCoordinates(dynamic_cast(GetDataNode()->GetData())); + // create new vtk render objects (e.g. sphere for a point) SetVtkMapperImmediateModeRendering(m_VtkSelectedPolyDataMapper); SetVtkMapperImmediateModeRendering(m_VtkUnselectedPolyDataMapper); BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool needGenerateData = ls->IsGenerateDataRequired( renderer, this, GetDataNode() ); if(!needGenerateData) { mitk::FloatProperty * pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); mitk::FloatProperty * contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize")); // only create new vtk render objects if property values were changed if(pointSizeProp && m_PointSize!=pointSizeProp->GetValue() ) needGenerateData = true; if(contourSizeProp && m_ContourRadius!=contourSizeProp->GetValue() ) needGenerateData = true; } if(needGenerateData) { this->CreateVTKRenderObjects(); ls->UpdateGenerateDataTime(); } this->ApplyAllProperties(renderer, m_ContourActor); bool showPoints = true; this->GetDataNode()->GetBoolProperty("show points", showPoints); if(showPoints) { m_UnselectedActor->VisibilityOn(); m_SelectedActor->VisibilityOn(); } else { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); } if(dynamic_cast(this->GetDataNode()->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetProperty("opacity")); float opacity = pointOpacity->GetValue(); m_ContourActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetOpacity(opacity); m_SelectedActor->GetProperty()->SetOpacity(opacity); } bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { m_ContourActor->VisibilityOn(); } else { m_ContourActor->VisibilityOff(); } } void mitk::PointSetVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ ) { m_PointsAssembly->VisibilityOff(); } vtkProp* mitk::PointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_PointsAssembly; } void mitk::PointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { vtkSmartPointer vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); m_SelectedActor->SetUserTransform(vtktransform); m_UnselectedActor->SetUserTransform(vtktransform); m_ContourActor->SetUserTransform(vtktransform); } void mitk::PointSetVtkMapper3D::ApplyAllProperties(mitk::BaseRenderer* renderer, vtkActor* actor) { Superclass::ApplyColorAndOpacityProperties(renderer, actor); //check for color props and use it for rendering of selected/unselected points and contour //due to different params in VTK (double/float) we have to convert! //vars to convert to double unselectedColor[4]={1.0f,1.0f,0.0f,1.0f};//yellow double selectedColor[4]={1.0f,0.0f,0.0f,1.0f};//red double contourColor[4]={1.0f,0.0f,0.0f,1.0f};//red //different types for color!!! mitk::Color tmpColor; double opacity = 1.0; //check if there is an unselected property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else { //check if the node has a color float unselectedColorTMP[4]={1.0f,1.0f,0.0f,1.0f};//yellow m_DataNode->GetColor(unselectedColorTMP, NULL); unselectedColor[0] = unselectedColorTMP[0]; unselectedColor[1] = unselectedColorTMP[1]; unselectedColor[2] = unselectedColorTMP[2]; //unselectedColor[3] stays 1.0f } //get selected property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } //get contour property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } if(dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } else if(dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } //finished color / opacity fishing! //check if a contour shall be drawn bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour, renderer); if(makeContour && (m_ContourActor != NULL) ) { this->CreateContour(); m_ContourActor->GetProperty()->SetColor(contourColor); m_ContourActor->GetProperty()->SetOpacity(opacity); } m_SelectedActor->GetProperty()->SetColor(selectedColor); m_SelectedActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetColor(unselectedColor); m_UnselectedActor->GetProperty()->SetOpacity(opacity); } void mitk::PointSetVtkMapper3D::CreateContour() { vtkSmartPointer vtkContourPolyData = vtkSmartPointer::New(); vtkSmartPointer vtkContourPolyDataMapper = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer polys = vtkSmartPointer::New(); mitk::PointSet::PointsContainer::Iterator pointsIter; // mitk::PointSet::PointDataContainer::Iterator pointDataIter; int j; // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { return; } for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End() ; pointsIter++,j++) { vtkIdType cell[2] = {j-1,j}; itk::Point point1 = pointsIter->Value(); points->InsertPoint(j,point1[0],point1[1],point1[2]); if (j>0) polys->InsertNextCell(2,cell); } bool close = false; this->GetDataNode()->GetBoolProperty("close contour", close); if (close) { vtkIdType cell[2] = {j-1,0}; polys->InsertNextCell(2,cell); } vtkSmartPointer contour = vtkSmartPointer::New(); contour->SetPoints(points); contour->SetLines(polys); vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetNumberOfSides( 12 ); tubeFilter->SetInputData(contour); //check for property contoursize. m_ContourRadius = 0.5; mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize") ); if (contourSizeProp.IsNotNull()) m_ContourRadius = contourSizeProp->GetValue(); tubeFilter->SetRadius( m_ContourRadius ); tubeFilter->Update(); //add to pipeline vtkContourPolyData->AddInputConnection(tubeFilter->GetOutputPort()); vtkContourPolyDataMapper->SetInputConnection(vtkContourPolyData->GetOutputPort()); m_ContourActor->SetMapper(vtkContourPolyDataMapper); m_PointsAssembly->AddPart(m_ContourActor); } void mitk::PointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite); node->AddProperty( "selectedcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); //red node->AddProperty( "color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); //yellow node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); node->AddProperty( "contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "updateDataOnRender", mitk::BoolProperty::New(true), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.h b/Core/Code/Rendering/mitkPointSetVtkMapper3D.h index 12b8481144..69ff5bb1a6 100644 --- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.h +++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.h @@ -1,158 +1,163 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 #define MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 #include #include "mitkVtkMapper.h" #include "mitkBaseRenderer.h" #include class vtkActor; class vtkPropAssembly; class vtkAppendPolyData; class vtkPolyData; class vtkTubeFilter; class vtkPolyDataMapper; namespace mitk { class PointSet; + class LabelOverlay3D; /** * @brief Vtk-based mapper for PointSet * * Due to the need of different colors for selected * and unselected points and the facts, that we also have a contour and * labels for the points, the vtk structure is build up the following way: * * We have two AppendPolyData, one selected, and one unselected and one * for a contour between the points. Each one is connected to an own * PolyDaraMapper and an Actor. The different color for the unselected and * selected state and for the contour is read from properties. * * "unselectedcolor", "selectedcolor" and "contourcolor" are the strings, * that are looked for. Pointlabels are added besides the selected or the * deselected points. * * Then the three Actors are combined inside a vtkPropAssembly and this * object is returned in GetProp() and so hooked up into the rendering * pipeline. * Properties that can be set for point sets and influence the PointSetVTKMapper3D are: * * - \b "color": (ColorProperty*) Color of the point set * - \b "Opacity": (FloatProperty) Opacity of the point set * - \b "show contour": (BoolProperty) If the contour of the points are visible * - \b "contourSizeProp":(FloatProperty) Contour size of the points The default properties are: * - \b "line width": (IntProperty::New(2), renderer, overwrite ) * - \b "pointsize": (FloatProperty::New(1.0), renderer, overwrite) * - \b "selectedcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite) //red * - \b "color": (ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite) //yellow * - \b "show contour": (BoolProperty::New(false), renderer, overwrite ) * - \b "contourcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite) * - \b "contoursize": (FloatProperty::New(0.5), renderer, overwrite ) * - \b "close contour": (BoolProperty::New(false), renderer, overwrite ) * - \b "show points": (BoolProperty::New(true), renderer, overwrite ) * - \b "updateDataOnRender": (BoolProperty::New(true), renderer, overwrite ) *Other properties looked for are: * * - \b "show contour": if set to on, lines between the points are shown * - \b "close contour": if set to on, the open strip is closed (first point * connected with last point) * - \b "pointsize": size of the points mapped * - \b "label": text of the Points to show besides points * - \b "contoursize": size of the contour drawn between the points * (if not set, the pointsize is taken) * * @ingroup Mapper */ class MITK_CORE_EXPORT PointSetVtkMapper3D : public VtkMapper { public: mitkClassMacro(PointSetVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::PointSet* GetInput(); //overwritten from VtkMapper3D to be able to return a //m_PointsAssembly which is much faster than a vtkAssembly virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); virtual void UpdateVtkTransform(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); /* * \deprecatedSince{2013_12} Use ReleaseGraphicsResources(mitk::BaseRenderer* renderer) instead */ DEPRECATED(void ReleaseGraphicsResources(vtkWindow *renWin)); void ReleaseGraphicsResources(mitk::BaseRenderer* renderer); LocalStorageHandler m_LSH; protected: PointSetVtkMapper3D(); virtual ~PointSetVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( BaseRenderer* renderer ); virtual void ApplyAllProperties(mitk::BaseRenderer* renderer, vtkActor* actor); virtual void CreateContour(); virtual void CreateVTKRenderObjects(); + virtual mitk::OverlayManager* GetOverlayManager() const; vtkSmartPointer m_vtkSelectedPointList; vtkSmartPointer m_vtkUnselectedPointList; vtkSmartPointer m_VtkSelectedPolyDataMapper; vtkSmartPointer m_VtkUnselectedPolyDataMapper; vtkSmartPointer m_SelectedActor; vtkSmartPointer m_UnselectedActor; vtkSmartPointer m_ContourActor; vtkSmartPointer m_PointsAssembly; + itk::SmartPointer m_LabelOverlay; + itk::SmartPointer m_OverlayManager; + //help for contour between points vtkSmartPointer m_vtkTextList; //variables to be able to log, how many inputs have been added to PolyDatas unsigned int m_NumberOfSelectedAdded; unsigned int m_NumberOfUnselectedAdded; //variables to check if an update of the vtk objects is needed ScalarType m_PointSize; ScalarType m_ContourRadius; }; } // namespace mitk #endif /* MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 */ diff --git a/Core/Code/Rendering/mitkTextOverlay2D.cpp b/Core/Code/Rendering/mitkTextOverlay2D.cpp index e2b3fa3973..4e75507673 100644 --- a/Core/Code/Rendering/mitkTextOverlay2D.cpp +++ b/Core/Code/Rendering/mitkTextOverlay2D.cpp @@ -1,105 +1,111 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTextOverlay2D.h" #include #include "vtkUnicodeString.h" #include -#include +#include #include #include +#include mitk::TextOverlay2D::TextOverlay2D() { mitk::Point2D position; position[0] = position[1] = 0; SetPosition2D(position); SetOffsetVector(position); } mitk::TextOverlay2D::~TextOverlay2D() { } mitk::Overlay::Bounds mitk::TextOverlay2D::GetBoundsOnDisplay(mitk::BaseRenderer *renderer) const { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); mitk::Overlay::Bounds bounds; bounds.Position = ls->m_textActor->GetPosition(); bounds.Size[0] = ls->m_textImage->GetDimensions()[0]; bounds.Size[1] = ls->m_textImage->GetDimensions()[1]; return bounds; } void mitk::TextOverlay2D::SetBoundsOnDisplay(mitk::BaseRenderer *renderer, const mitk::Overlay::Bounds& bounds) { vtkSmartPointer actor = GetVtkActor2D(renderer); actor->SetDisplayPosition(bounds.Position[0],bounds.Position[1]); - actor->SetWidth(bounds.Size[0]); - actor->SetHeight(bounds.Size[1]); +// actor->SetWidth(bounds.Size[0]); +// actor->SetHeight(bounds.Size[1]); } mitk::TextOverlay2D::LocalStorage::~LocalStorage() { } mitk::TextOverlay2D::LocalStorage::LocalStorage() { m_textActor = vtkSmartPointer::New(); m_textImage = vtkSmartPointer::New(); m_imageMapper = vtkSmartPointer::New(); m_imageMapper->SetInputData(m_textImage); m_textActor->SetMapper(m_imageMapper); } void mitk::TextOverlay2D::UpdateVtkOverlay2D(mitk::BaseRenderer *renderer) { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); if(ls->IsGenerateDataRequired(renderer,this)) { - vtkSmartPointer freetype = vtkSmartPointer::New(); + vtkSmartPointer freetype = vtkSmartPointer::New(); vtkSmartPointer prop = vtkSmartPointer::New(); float color[3] = {1,1,1}; float opacity = 1.0; GetColor(color,renderer); GetOpacity(opacity,renderer); prop->SetColor( color[0], color[1], color[2]); prop->SetFontSize(GetFontSize()); prop->SetOpacity(opacity); + freetype->SetScaleToPowerOfTwo(false); + freetype->RenderString(prop,vtkUnicodeString::from_utf8(GetText().c_str()),ls->m_textImage); +// vtkSmartPointer fds = vtkTextRenderer::New(); +// int bbox[4]; +// fds->GetBoundingBox(prop,vtkUnicodeString::from_utf8(GetText().c_str()),bbox); ls->m_textImage->Modified(); //Levelwindow has to be set to full range, that the colors are displayed properly. ls->m_imageMapper->SetColorWindow(255); ls->m_imageMapper->SetColorLevel(127.5); ls->m_imageMapper->Update(); ls->m_textActor->SetPosition(GetPosition2D(renderer)[0]+GetOffsetVector(renderer)[0], GetPosition2D(renderer)[1]+GetOffsetVector(renderer)[1]); ls->UpdateGenerateDataTime(); } } vtkActor2D* mitk::TextOverlay2D::GetVtkActor2D(BaseRenderer *renderer) const { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); return ls->m_textActor; } diff --git a/Core/Code/Rendering/mitkTextOverlay3D.cpp b/Core/Code/Rendering/mitkTextOverlay3D.cpp index f28ba69fcd..82dc894cef 100644 --- a/Core/Code/Rendering/mitkTextOverlay3D.cpp +++ b/Core/Code/Rendering/mitkTextOverlay3D.cpp @@ -1,81 +1,82 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTextOverlay3D.h" #include #include #include #include #include #include mitk::TextOverlay3D::TextOverlay3D() { } mitk::TextOverlay3D::~TextOverlay3D() { } mitk::TextOverlay3D::LocalStorage::~LocalStorage() { } mitk::TextOverlay3D::LocalStorage::LocalStorage() { // Create some text m_textSource = vtkSmartPointer::New(); // Create a mapper vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection( m_textSource->GetOutputPort() ); // Create a subclass of vtkActor: a vtkFollower that remains facing the camera m_follower = vtkSmartPointer::New(); m_follower->SetMapper( mapper ); m_follower->GetProperty()->SetColor( 1, 0, 0 ); // red m_follower->SetScale(1); } void mitk::TextOverlay3D::UpdateVtkOverlay(mitk::BaseRenderer *renderer) { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); if(ls->IsGenerateDataRequired(renderer,this)) { ls->m_follower->SetPosition( GetPosition3D(renderer)[0]+GetOffsetVector(renderer)[0], GetPosition3D(renderer)[1]+GetOffsetVector(renderer)[1], GetPosition3D(renderer)[2]+GetOffsetVector(renderer)[2]); ls->m_textSource->SetText(GetText().c_str()); float color[3] = {1,1,1}; float opacity = 1.0; GetColor(color,renderer); GetOpacity(opacity,renderer); ls->m_follower->GetProperty()->SetColor(color[0], color[1], color[2]); ls->m_follower->GetProperty()->SetOpacity(opacity); + ls->m_follower->SetScale(this->GetFontSize()); ls->UpdateGenerateDataTime(); } } vtkProp* mitk::TextOverlay3D::GetVtkProp(BaseRenderer *renderer) const { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); ls->m_follower->SetCamera(renderer->GetVtkRenderer()->GetActiveCamera()); return ls->m_follower; } diff --git a/Core/Code/Rendering/mitkVtkOverlay.cpp b/Core/Code/Rendering/mitkVtkOverlay.cpp index b4029923d1..ae22cd6506 100644 --- a/Core/Code/Rendering/mitkVtkOverlay.cpp +++ b/Core/Code/Rendering/mitkVtkOverlay.cpp @@ -1,63 +1,63 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkOverlay.h" #include #include mitk::VtkOverlay::VtkOverlay() { } mitk::VtkOverlay::~VtkOverlay() { } void mitk::VtkOverlay::Update(mitk::BaseRenderer *renderer) { vtkSmartPointer prop = GetVtkProp(renderer); if(!IsVisible(renderer)) { prop->SetVisibility(false); return; } else { prop->SetVisibility(true); UpdateVtkOverlay(renderer); } } void mitk::VtkOverlay::AddToBaseRenderer(mitk::BaseRenderer *renderer) { Update(renderer); vtkSmartPointer vtkProp = GetVtkProp(renderer); if(!renderer->GetVtkRenderer()->HasViewProp(vtkProp)) { renderer->GetVtkRenderer()->AddViewProp(vtkProp); } } void mitk::VtkOverlay::RemoveFromBaseRenderer(mitk::BaseRenderer *renderer) { vtkSmartPointer vtkProp = GetVtkProp(renderer); - if(!renderer->GetVtkRenderer()->HasViewProp(vtkProp)) + if(renderer->GetVtkRenderer()->HasViewProp(vtkProp)) { renderer->GetVtkRenderer()->RemoveViewProp(vtkProp); } }