diff --git a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp index 72f287b658..ef5a654b68 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp @@ -1,244 +1,242 @@ /*=================================================================== 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 #include #include #include #include #include mitk::ContourModelMapper3D::ContourModelMapper3D() { } mitk::ContourModelMapper3D::~ContourModelMapper3D() { } const mitk::ContourModel* mitk::ContourModelMapper3D::GetInput( void ) { //convient way to get the data from the dataNode return static_cast< const mitk::ContourModel * >( GetDataNode()->GetData() ); } vtkProp* mitk::ContourModelMapper3D::GetVtkProp(mitk::BaseRenderer* renderer) { //return the actor corresponding to the renderer return m_LSH.GetLocalStorage(renderer)->m_Actor; } void mitk::ContourModelMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { /* First convert the contourModel to vtkPolyData, then tube filter it and * set it input for our mapper */ LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); mitk::ContourModel* inputContour = static_cast< mitk::ContourModel* >( GetDataNode()->GetData() ); localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour); this->ApplyContourProperties(renderer); //tube filter the polyData localStorage->m_TubeFilter->SetInputData(localStorage->m_OutlinePolyData); float lineWidth(1.0); if (this->GetDataNode()->GetFloatProperty( "contour.3D.width", lineWidth, renderer )) { - localStorage->m_TubeFilter->SetRadius(lineWidth); + localStorage->m_TubeFilter->SetWidth(lineWidth); }else { - localStorage->m_TubeFilter->SetRadius(0.5); + localStorage->m_TubeFilter->SetWidth(0.5); } - localStorage->m_TubeFilter->CappingOn(); - localStorage->m_TubeFilter->SetNumberOfSides(10); localStorage->m_TubeFilter->Update(); localStorage->m_Mapper->SetInputConnection(localStorage->m_TubeFilter->GetOutputPort()); } void mitk::ContourModelMapper3D::Update(mitk::BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); mitk::ContourModel* data = static_cast< mitk::ContourModel*>( GetDataNode()->GetData() ); if ( data == NULL ) { return; } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); // Check if time step is valid const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->CountTimeSteps() == 0 ) || ( !dataTimeGeometry->IsValidTimeStep( renderer->GetTimeStep() ) ) || ( this->GetTimestep() == -1 ) ) { //clear the rendered polydata localStorage->m_Mapper->SetInputData(vtkSmartPointer::New()); return; } const DataNode *node = this->GetDataNode(); data->UpdateOutputInformation(); //check if something important has changed and we need to rerender if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { this->GenerateDataForRenderer( renderer ); } // since we have checked that nothing important has changed, we can set // m_LastUpdateTime to the current time localStorage->m_LastUpdateTime.Modified(); } vtkSmartPointer mitk::ContourModelMapper3D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour) { unsigned int timestep = this->GetTimestep(); //the points to draw vtkSmartPointer points = vtkSmartPointer::New(); //the lines to connect the points vtkSmartPointer lines = vtkSmartPointer::New(); // Create a polydata to store everything in vtkSmartPointer polyData = vtkSmartPointer::New(); //iterate over the control points mitk::ContourModel::VertexIterator current = inputContour->IteratorBegin(timestep); mitk::ContourModel::VertexIterator next = inputContour->IteratorBegin(timestep); if(next != inputContour->IteratorEnd(timestep)) { next++; mitk::ContourModel::VertexIterator end = inputContour->IteratorEnd(timestep); while(next != end) { mitk::ContourModel::VertexType* currentControlPoint = *current; mitk::ContourModel::VertexType* nextControlPoint = *next; if( !(currentControlPoint->Coordinates[0] == nextControlPoint->Coordinates[0] && currentControlPoint->Coordinates[1] == nextControlPoint->Coordinates[1] && currentControlPoint->Coordinates[2] == nextControlPoint->Coordinates[2])) { vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]); vtkIdType p2 = points->InsertNextPoint(nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]); //add the line between both contorlPoints lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } current++; next++; } if(inputContour->IsClosed(timestep)) { // If the contour is closed add a line from the last to the first control point mitk::ContourModel::VertexType* firstControlPoint = *(inputContour->IteratorBegin(timestep)); mitk::ContourModel::VertexType* lastControlPoint = *(--(inputContour->IteratorEnd(timestep))); if( lastControlPoint->Coordinates[0] != firstControlPoint->Coordinates[0] || lastControlPoint->Coordinates[1] != firstControlPoint->Coordinates[1] || lastControlPoint->Coordinates[2] != firstControlPoint->Coordinates[2]) { vtkIdType p2 = points->InsertNextPoint(lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]); vtkIdType p1 = points->InsertNextPoint(firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]); //add the line to the cellArray lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } } // Add the points to the dataset polyData->SetPoints(points); // Add the lines to the dataset polyData->SetLines(lines); } return polyData; } void mitk::ContourModelMapper3D::ApplyContourProperties(mitk::BaseRenderer* renderer) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); float color[3]; this->GetDataNode()->GetColor(color, renderer); localStorage->m_Actor->GetProperty()->SetColor(color[0], color[1], color[2]); } /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/ mitk::ContourModelMapper3D::LocalStorage* mitk::ContourModelMapper3D::GetLocalStorage(mitk::BaseRenderer* renderer) { return m_LSH.GetLocalStorage(renderer); } mitk::ContourModelMapper3D::LocalStorage::LocalStorage() { m_Mapper = vtkSmartPointer::New(); m_Actor = vtkSmartPointer::New(); m_OutlinePolyData = vtkSmartPointer::New(); - m_TubeFilter = vtkSmartPointer::New(); + m_TubeFilter = vtkSmartPointer::New(); //set the mapper for the actor m_Actor->SetMapper(m_Mapper); } void mitk::ContourModelMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "contour.3D.width", mitk::FloatProperty::New( 0.5 ), renderer, overwrite ); IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); if(aliases != NULL) { aliases->AddAlias("color", "contour.color", "ContourModel"); } Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h index d94c66219b..7bc0c17146 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h +++ b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h @@ -1,111 +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. ===================================================================*/ #ifndef _MITK_CONTOURMODEL_MAPPER_3D_H_ #define _MITK_CONTOURMODEL_MAPPER_3D_H_ #include "mitkCommon.h" #include #include "mitkBaseRenderer.h" #include "mitkVtkMapper.h" #include "mitkContourModel.h" //#include "mitkContourModelToVtkPolyDataFilter.h" #include #include #include #include #include -#include +#include namespace mitk { class MitkContourModel_EXPORT ContourModelMapper3D : public VtkMapper { public: /** Standard class typedefs. */ mitkClassMacro( ContourModelMapper3D,VtkMapper ); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) const mitk::ContourModel* GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ virtual void Update(mitk::BaseRenderer * renderer); /*+++ methods of MITK-VTK rendering pipeline +++*/ virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); /*+++ END methods of MITK-VTK rendering pipeline +++*/ class MitkContourModel_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Actor of a 2D render window. */ vtkSmartPointer m_Actor; /** \brief Mapper of a 2D render window. */ vtkSmartPointer m_Mapper; - vtkSmartPointer m_TubeFilter; + vtkSmartPointer m_TubeFilter; //mitk::ContourModelToVtkPolyDataFilter::Pointer m_contourToPolyData; vtkSmartPointer m_OutlinePolyData; /** \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() { } }; /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: ContourModelMapper3D(); virtual ~ContourModelMapper3D(); void GenerateDataForRenderer( mitk::BaseRenderer *renderer ); virtual vtkSmartPointer CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour); virtual void ApplyContourProperties(mitk::BaseRenderer* renderer); }; } #endif diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp index 25174f4684..736175a7f0 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp @@ -1,208 +1,206 @@ /*=================================================================== 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 #include #include #include #include #include #include mitk::ContourModelSetMapper3D::ContourModelSetMapper3D() { } mitk::ContourModelSetMapper3D::~ContourModelSetMapper3D() { } const mitk::ContourModelSet* mitk::ContourModelSetMapper3D::GetInput( void ) { //convient way to get the data from the dataNode return static_cast< const mitk::ContourModelSet * >( GetDataNode()->GetData() ); } vtkProp* mitk::ContourModelSetMapper3D::GetVtkProp(mitk::BaseRenderer* renderer) { //return the actor corresponding to the renderer return m_LSH.GetLocalStorage(renderer)->m_Assembly; } void mitk::ContourModelSetMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { /* First convert the contourModel to vtkPolyData, then tube filter it and * set it input for our mapper */ LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); mitk::ContourModelSet* contourSet = static_cast< mitk::ContourModelSet* >( GetDataNode()->GetData() ); mitk::ContourModelSet::ContourModelSetIterator it = contourSet->Begin(); mitk::ContourModelSet::ContourModelSetIterator end = contourSet->End(); while(it!=end) { mitk::ContourModel* inputContour = it->GetPointer(); vtkSmartPointer polyData = this->CreateVtkPolyDataFromContour(inputContour, renderer); - vtkSmartPointer tubeFilter = vtkSmartPointer::New(); - tubeFilter->SetInputData(polyData); + vtkSmartPointer tubeFilter = vtkSmartPointer::New(); + tubeFilter->SetInput(polyData); float lineWidth(1.0); if (this->GetDataNode()->GetFloatProperty( "contour.3D.width", lineWidth, renderer )) { - tubeFilter->SetRadius(lineWidth); + tubeFilter->SetWidth(lineWidth); }else { - tubeFilter->SetRadius(0.5); + tubeFilter->SetWidth(0.5); } - tubeFilter->CappingOn(); - tubeFilter->SetNumberOfSides(10); tubeFilter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); mapper->SetInputConnection(tubeFilter->GetOutputPort()); //mapper->SetInput(polyData); localStorage->m_Assembly->AddPart(actor); ++it; } this->ApplyColorAndOpacityProperties(renderer); } void mitk::ContourModelSetMapper3D::Update(mitk::BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); mitk::ContourModel* data = static_cast< mitk::ContourModel*>( GetDataNode()->GetData() ); if ( data == NULL ) { return; } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); if ( this->GetTimestep() == -1 ) { return; } const DataNode *node = this->GetDataNode(); data->UpdateOutputInformation(); //check if something important has changed and we need to rerender if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { this->GenerateDataForRenderer( renderer ); } // since we have checked that nothing important has changed, we can set // m_LastUpdateTime to the current time localStorage->m_LastUpdateTime.Modified(); } vtkSmartPointer mitk::ContourModelSetMapper3D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour, mitk::BaseRenderer* renderer) { unsigned int timestep = this->GetTimestep(); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); localStorage->m_contourToPolyData->SetInput(inputContour); localStorage->m_contourToPolyData->Update(); vtkSmartPointer polyData = vtkSmartPointer::New(); polyData = localStorage->m_contourToPolyData->GetOutput()->GetVtkPolyData(timestep); return polyData; } void mitk::ContourModelSetMapper3D::ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor*) { MITK_INFO << "ApplyColorAndOpacityProperties()"; LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); float color[3]; this->GetDataNode()->GetColor(color, renderer); vtkSmartPointer collection = vtkSmartPointer::New(); localStorage->m_Assembly->GetActors(collection); collection->InitTraversal(); for(vtkIdType i = 0; i < collection->GetNumberOfItems(); i++) { vtkActor::SafeDownCast(collection->GetNextProp())->GetProperty()->SetColor(color[0], color[1], color[2]); } } /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/ mitk::ContourModelSetMapper3D::LocalStorage* mitk::ContourModelSetMapper3D::GetLocalStorage(mitk::BaseRenderer* renderer) { return m_LSH.GetLocalStorage(renderer); } mitk::ContourModelSetMapper3D::LocalStorage::LocalStorage() { m_Assembly = vtkSmartPointer::New(); m_contourToPolyData = mitk::ContourModelToSurfaceFilter::New(); } void mitk::ContourModelSetMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", ColorProperty::New(1.0,1.0,0.0), renderer, overwrite ); node->AddProperty( "contour.3D.width", mitk::FloatProperty::New( 0.5 ), renderer, overwrite ); IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); if (aliases != NULL) { aliases->AddAlias("color", "contour.color", "ContourModelSet"); } Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h index 9546f65700..247d99db8e 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h +++ b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h @@ -1,107 +1,107 @@ /*=================================================================== 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 _MITK_CONTOURMODELSET_MAPPER_3D_H_ #define _MITK_CONTOURMODELSET_MAPPER_3D_H_ #include "mitkCommon.h" #include #include "mitkBaseRenderer.h" #include "mitkVtkMapper.h" #include "mitkContourModel.h" #include "mitkContourModelSet.h" #include "mitkContourModelToSurfaceFilter.h" #include #include #include #include #include #include -#include +#include namespace mitk { class MitkContourModel_EXPORT ContourModelSetMapper3D : public VtkMapper { public: /** Standard class typedefs. */ mitkClassMacro( ContourModelSetMapper3D,VtkMapper ); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) const mitk::ContourModelSet* GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ virtual void Update(mitk::BaseRenderer * renderer); /*+++ methods of MITK-VTK rendering pipeline +++*/ virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); /*+++ END methods of MITK-VTK rendering pipeline +++*/ class MitkContourModel_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Assembly of contours. */ vtkSmartPointer m_Assembly; mitk::ContourModelToSurfaceFilter::Pointer m_contourToPolyData; /** \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() { } }; /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: ContourModelSetMapper3D(); virtual ~ContourModelSetMapper3D(); void GenerateDataForRenderer( mitk::BaseRenderer *renderer ); virtual vtkSmartPointer CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour,mitk::BaseRenderer* renderer); virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL); }; } #endif diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp index 1f8114b401..e07c114a52 100644 --- a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp @@ -1,768 +1,809 @@ /*=================================================================== 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. ===================================================================*/ // Qt #include #include // Blueberry #include #include // MITK #include #include #include // Qmitk #include "RTDoseVisualizer.h" #include #include #include #include #include #include #include #include #include #include #include "org_mitk_gui_qt_rt_dosevisualization_Activator.h" #include #include #include #include #include #include "QmitkRenderWindow.h" #include #include "mitkSurfaceGLMapper2D.h" #include "mitkPolyDataGLMapper2D.h" #include "mitkSurfaceVtkMapper3D.h" #include "mitkSliceNavigationController.h" const std::string RTDoseVisualizer::VIEW_ID = "org.mitk.views.rt.dosevisualization"; RTDoseVisualizer::RTDoseVisualizer() { m_freeIsoValues = mitk::IsoDoseLevelVector::New(); m_selectedNodeIsoSet = mitk::IsoDoseLevelSet::New(); m_freeIsoFilter = vtkSmartPointer::New(); + m_FreeIsoAdded = false; m_selectedNode = NULL; m_selectedPresetName = ""; m_internalUpdate = false; m_PrescribedDose_Data = 0.0; } RTDoseVisualizer::~RTDoseVisualizer() { delete m_LevelSetModel; delete m_DoseColorDelegate; delete m_DoseValueDelegate; delete m_DoseVisualDelegate; } void RTDoseVisualizer::InitScrolling(){ QmitkRenderWindow* rw = this->GetRenderWindowPart()->GetQmitkRenderWindow("axial"); itk::MemberCommand::Pointer sliceChangedCommand = itk::MemberCommand::New(); sliceChangedCommand->SetCallbackFunction(this, &RTDoseVisualizer::OnSliceChanged); rw->GetSliceNavigationController()->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(NULL,0), sliceChangedCommand); } void RTDoseVisualizer::SetFocus(){} void RTDoseVisualizer::OnSliceChanged(itk::Object *sender, const itk::EventObject &e) { for(int i=0; iRemove(m_StdIsoLines.at(i)); } m_StdIsoLines.clear(); this->UpdateStdIsolines(); + + if(m_FreeIsoAdded) + { +// float pref; +// m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); +// mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); +// mitk::Image::Pointer slicedImage = this->GetExtractedSlice(image); + +// m_Filters.at(0)->SetInput(slicedImage->GetVtkImageData()); +// m_Filters.at(0)->GenerateValues(1,pref,level->GetDoseValue()*pref); +// m_Filters.at(0)->Update(); + +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } } void RTDoseVisualizer::CreateQtPartControl( QWidget *parent ) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); m_LevelSetModel = new QmitkIsoDoseLevelSetModel(this); m_LevelSetModel->setVisibilityEditOnly(true); m_DoseColorDelegate = new QmitkDoseColorDelegate(this); m_DoseValueDelegate = new QmitkDoseValueDelegate(this); m_DoseVisualDelegate = new QmitkDoseVisualStyleDelegate(this); this->UpdateByPreferences(); this->ActualizeIsoLevelsForAllDoseDataNodes(); this->ActualizeReferenceDoseForAllDoseDataNodes(); this->ActualizeDisplayStyleForAllDoseDataNodes(); this->m_Controls.isoLevelSetView->setModel(m_LevelSetModel); this->m_Controls.isoLevelSetView->setItemDelegateForColumn(0,m_DoseColorDelegate); this->m_Controls.isoLevelSetView->setItemDelegateForColumn(1,m_DoseValueDelegate); this->m_Controls.isoLevelSetView->setItemDelegateForColumn(2,m_DoseVisualDelegate); this->m_Controls.isoLevelSetView->setItemDelegateForColumn(3,m_DoseVisualDelegate); this->m_Controls.isoLevelSetView->setContextMenuPolicy(Qt::CustomContextMenu); this->m_Controls.btnRemoveFreeValue->setDisabled(true); connect(m_Controls.btnConvert, SIGNAL(clicked()), this, SLOT(OnConvertButtonClicked())); connect(m_Controls.spinReferenceDose, SIGNAL(valueChanged(double)), this, SLOT(OnReferenceDoseChanged(double))); connect(m_Controls.spinReferenceDose, SIGNAL(valueChanged(double)), m_LevelSetModel, SLOT(setReferenceDose(double))); connect(m_Controls.radioAbsDose, SIGNAL(toggled(bool)), m_LevelSetModel, SLOT(setShowAbsoluteDose(bool))); connect(m_Controls.radioAbsDose, SIGNAL(toggled(bool)), this, SLOT(OnAbsDoseToggled(bool))); connect(m_Controls.btnAddFreeValue, SIGNAL(clicked()), this, SLOT(OnAddFreeValueClicked())); connect(m_Controls.btnRemoveFreeValue, SIGNAL(clicked()), this, SLOT(OnRemoveFreeValueClicked())); connect(m_Controls.checkGlobalVisColorWash, SIGNAL(toggled(bool)), this, SLOT(OnGlobalVisColorWashToggled(bool))); connect(m_Controls.checkGlobalVisIsoLine, SIGNAL(toggled(bool)), this, SLOT(OnGlobalVisIsoLineToggled(bool))); connect(m_Controls.isoLevelSetView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnShowContextMenuIsoSet(const QPoint&))); connect(m_Controls.comboPresets, SIGNAL(currentIndexChanged ( const QString&)), this, SLOT(OnCurrentPresetChanged(const QString&))); connect(m_Controls.btnUsePrescribedDose, SIGNAL(clicked()), this, SLOT(OnUsePrescribedDoseClicked())); ctkServiceReference ref = mitk::org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext()->getServiceReference(); ctkDictionary propsForSlot; if (ref) { ctkEventAdmin* eventAdmin = mitk::org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext()->getService(ref); propsForSlot[ctkEventConstants::EVENT_TOPIC] = mitk::rt::CTKEventConstants::TOPIC_ISO_DOSE_LEVEL_PRESETS_CHANGED.c_str(); eventAdmin->subscribeSlot(this, SLOT(OnHandleCTKEventPresetsChanged(ctkEvent)), propsForSlot); propsForSlot[ctkEventConstants::EVENT_TOPIC] = mitk::rt::CTKEventConstants::TOPIC_REFERENCE_DOSE_CHANGED.c_str(); eventAdmin->subscribeSlot(this, SLOT(OnHandleCTKEventReferenceDoseChanged(ctkEvent)), propsForSlot); } this->UpdateBySelectedNode(); } void RTDoseVisualizer::OnReferenceDoseChanged(double value) { if (! m_internalUpdate) { mitk::DoseValueAbs referenceDose = 0.0; bool globalSync = mitk::rt::GetReferenceDoseValue(referenceDose); if (globalSync) { mitk::rt::SetReferenceDoseValue(globalSync, value); this->ActualizeReferenceDoseForAllDoseDataNodes(); } else { if (this->m_selectedNode.IsNotNull()) { this->m_selectedNode->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), value); } } if (this->m_selectedNode.IsNotNull()) { mitk::TransferFunction::ControlPoints scalarOpacityPoints; scalarOpacityPoints.push_back( std::make_pair(0, 1 ) ); vtkSmartPointer transferFunction = vtkSmartPointer::New(); mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = this->m_Presets[this->m_selectedPresetName]; for(mitk::IsoDoseLevelSet::ConstIterator setIT = isoDoseLevelSet->Begin(); setIT != isoDoseLevelSet->End(); ++setIT) { float *hsv = new float[3]; vtkSmartPointer cCalc = vtkSmartPointer::New(); if(setIT->GetVisibleColorWash()){ cCalc->RGBToHSV(setIT->GetColor()[0],setIT->GetColor()[1],setIT->GetColor()[2],&hsv[0],&hsv[1],&hsv[2]); transferFunction->AddHSVPoint(setIT->GetDoseValue()*value,hsv[0],hsv[1],hsv[2],1.0,1.0); } else { scalarOpacityPoints.push_back( std::make_pair(setIT->GetDoseValue()*value, 1 ) ); } } mitk::TransferFunction::Pointer mitkTransFunc = mitk::TransferFunction::New(); mitk::TransferFunctionProperty::Pointer mitkTransFuncProp = mitk::TransferFunctionProperty::New(); mitkTransFunc->SetColorTransferFunction(transferFunction); mitkTransFunc->SetScalarOpacityPoints(scalarOpacityPoints); mitkTransFuncProp->SetValue(mitkTransFunc); mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); renderingMode->SetValue(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR); m_selectedNode->SetProperty("Image Rendering.Transfer Function", mitkTransFuncProp); m_selectedNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); mitk::TimeGeometry::Pointer geo3 = this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews( geo3 ); } } } void RTDoseVisualizer::OnAddFreeValueClicked() { QColor newColor; //Use HSV schema of QColor to calculate a different color depending on the //number of already existing free iso lines. newColor.setHsv((m_freeIsoValues->Size()*85)%360,255,255); + mitk::Color mColor; + mColor[0]=newColor.redF(); + mColor[1]=newColor.greenF(); + mColor[2]=newColor.blueF(); mitk::DataNode::Pointer isoNode = this->UpdatePolyData(1,m_Controls.spinReferenceDose->value()*0.5,m_Controls.spinReferenceDose->value()*0.5); + isoNode->SetColor(mColor); m_FreeIsoLines.push_back(isoNode); mitk::IsoDoseLevel::ColorType color; color[0] = newColor.redF(); color[1] = newColor.greenF(); color[2] = newColor.blueF(); m_freeIsoValues->push_back(mitk::IsoDoseLevel::New(0.5,color,true,false)); UpdateFreeIsoValues(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); - if(m_FreeIsoLines.size()>=3) + if(m_FreeIsoLines.size()>=1) + { this->m_Controls.btnAddFreeValue->setDisabled(true); + m_FreeIsoAdded = true; + } this->m_Controls.btnRemoveFreeValue->setEnabled(true); } void RTDoseVisualizer::OnRemoveFreeValueClicked() { m_freeIsoValues->pop_back(); mitk::DataNode::Pointer isoNode = m_FreeIsoLines.at(m_FreeIsoLines.size()-1); m_FreeIsoLines.pop_back(); m_Filters.pop_back(); if(m_FreeIsoLines.empty()) this->m_Controls.btnRemoveFreeValue->setDisabled(true); - if(m_FreeIsoLines.size()<3) + if(m_FreeIsoLines.size()<1) + { + m_FreeIsoAdded = false; this->m_Controls.btnAddFreeValue->setEnabled(true); + } this->GetDataStorage()->Remove(isoNode); UpdateFreeIsoValues(); } void RTDoseVisualizer::OnUsePrescribedDoseClicked() { m_Controls.spinReferenceDose->setValue(this->m_PrescribedDose_Data); }; void RTDoseVisualizer::OnShowContextMenuIsoSet(const QPoint& pos) { QPoint globalPos = m_Controls.isoLevelSetView->viewport()->mapToGlobal(pos); QMenu viewMenu; QAction* invertIsoLineAct = viewMenu.addAction("Invert iso line visibility"); QAction* activateIsoLineAct = viewMenu.addAction("Activate all iso lines"); QAction* deactivateIsoLineAct = viewMenu.addAction("Deactivate all iso lines"); viewMenu.addSeparator(); QAction* invertColorWashAct = viewMenu.addAction("Invert color wash visibility"); QAction* activateColorWashAct = viewMenu.addAction("Activate all color wash levels"); QAction* deactivateColorWashAct = viewMenu.addAction("Deactivate all color wash levels"); viewMenu.addSeparator(); QAction* swapAct = viewMenu.addAction("Swap iso line/color wash visibility"); // ... QAction* selectedItem = viewMenu.exec(globalPos); if (selectedItem == invertIsoLineAct) { this->m_LevelSetModel->invertVisibilityIsoLines(); } else if (selectedItem == activateIsoLineAct) { this->m_LevelSetModel->switchVisibilityIsoLines(true); } else if (selectedItem == deactivateIsoLineAct) { this->m_LevelSetModel->switchVisibilityIsoLines(false); } else if (selectedItem == invertColorWashAct) { this->m_LevelSetModel->invertVisibilityColorWash(); } else if (selectedItem == activateColorWashAct) { this->m_LevelSetModel->switchVisibilityColorWash(true); } else if (selectedItem == deactivateColorWashAct) { this->m_LevelSetModel->switchVisibilityColorWash(false); } else if (selectedItem == swapAct) { this->m_LevelSetModel->swapVisibility(); } } void RTDoseVisualizer::UpdateFreeIsoValues() { this->m_Controls.listFreeValues->clear(); for (mitk::IsoDoseLevelVector::Iterator pos = this->m_freeIsoValues->Begin(); pos != this->m_freeIsoValues->End(); ++pos) { QListWidgetItem* item = new QListWidgetItem; item->setSizeHint(QSize(0,25)); QmitkFreeIsoDoseLevelWidget* widget = new QmitkFreeIsoDoseLevelWidget; float pref; m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); widget->setIsoDoseLevel(pos->Value().GetPointer()); widget->setReferenceDose(pref); connect(m_Controls.spinReferenceDose, SIGNAL(valueChanged(double)), widget, SLOT(setReferenceDose(double))); + connect(widget,SIGNAL(ColorChanged(mitk::IsoDoseLevel*)), this, SLOT(UpdateFreeIsoLineColor(mitk::IsoDoseLevel*))); connect(widget,SIGNAL(ValueChanged(mitk::IsoDoseLevel*,mitk::DoseValueRel)), this, SLOT(UpdateFreeIsoLine(mitk::IsoDoseLevel*,mitk::DoseValueRel))); this->m_Controls.listFreeValues->addItem(item); this->m_Controls.listFreeValues->setItemWidget(item,widget); } } +void RTDoseVisualizer::UpdateFreeIsoLineColor(mitk::IsoDoseLevel *level) +{ + //push it in and get the key! +// m_freeIsoValues + ::itk::RGBPixel color = level->GetColor(); + mitk::Color mColor; + mColor[0]=color.GetRed(); + mColor[1]=color.GetGreen(); + mColor[2]=color.GetBlue(); + m_FreeIsoline->SetColor(mColor); +} + void RTDoseVisualizer::UpdateFreeIsoLine(mitk::IsoDoseLevel * level, mitk::DoseValueRel old) { float pref; m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); mitk::Image::Pointer slicedImage = this->GetExtractedSlice(image); m_Filters.at(0)->SetInputData(slicedImage->GetVtkImageData()); m_Filters.at(0)->GenerateValues(1,level->GetDoseValue()*pref,level->GetDoseValue()*pref); m_Filters.at(0)->Update(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void RTDoseVisualizer::OnAbsDoseToggled(bool showAbs) { if (! m_internalUpdate) { mitk::rt::SetDoseDisplayAbsolute(showAbs); this->ActualizeDisplayStyleForAllDoseDataNodes(); } } void RTDoseVisualizer::OnGlobalVisColorWashToggled(bool showColorWash) { if (m_selectedNode.IsNotNull()) { m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(), showColorWash); } } void RTDoseVisualizer::OnGlobalVisIsoLineToggled(bool showIsoLines) { if (m_selectedNode.IsNotNull()) { m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME.c_str(), showIsoLines); mitk::NodePredicateProperty::Pointer isoProp = mitk::NodePredicateProperty:: New(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer isoSet = this->GetDataStorage()->GetSubset(isoProp); for(mitk::DataStorage::SetOfObjects::ConstIterator iso = isoSet->Begin(); iso!=isoSet->End(); ++iso) { mitk::DataNode::Pointer node = iso.Value(); node->SetVisibility(showIsoLines); } mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void RTDoseVisualizer::OnConvertButtonClicked() { this->InitScrolling(); QList dataNodes = this->GetDataManagerSelection(); mitk::DataNode* selectedNode = NULL; if (!dataNodes.empty()) { selectedNode = dataNodes[0]; } if(selectedNode) { selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), true); selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(), true); selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME.c_str(), true); selectedNode->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), m_Controls.spinReferenceDose->value()); mitk::IsoDoseLevelSet::Pointer clonedPreset = this->m_Presets[this->m_selectedPresetName]->Clone(); mitk::IsoDoseLevelSetProperty::Pointer levelSetProp = mitk::IsoDoseLevelSetProperty::New(clonedPreset); selectedNode->SetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),levelSetProp); double hsvValue = 0.002778; float prescribed; m_selectedNode->GetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescribed); vtkSmartPointer transferFunction = vtkSmartPointer::New(); mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = this->m_Presets[this->m_selectedPresetName]; MITK_INFO << "FUNCTION PRESCRIBE " << prescribed << endl; float pref; m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); mitk::Image::Pointer reslicedImage = this->GetExtractedSlice(image); //Generating the Colorwash for(mitk::IsoDoseLevelSet::ConstIterator setIT = isoDoseLevelSet->Begin(); setIT != isoDoseLevelSet->End(); ++setIT) { float *hsv = new float[3]; //used for transfer rgb to hsv vtkSmartPointer cCalc = vtkSmartPointer::New(); if(setIT->GetVisibleColorWash()){ cCalc->RGBToHSV(setIT->GetColor()[0],setIT->GetColor()[1],setIT->GetColor()[2],&hsv[0],&hsv[1],&hsv[2]); transferFunction->AddHSVPoint(setIT->GetDoseValue()*pref,hsv[0],hsv[1],hsv[2],1.0,1.0); } } //Generating the standard isolines this->UpdateStdIsolines(); mitk::TransferFunction::Pointer mitkTransFunc = mitk::TransferFunction::New(); mitk::TransferFunctionProperty::Pointer mitkTransFuncProp = mitk::TransferFunctionProperty::New(); mitkTransFunc->SetColorTransferFunction(transferFunction); mitkTransFuncProp->SetValue(mitkTransFunc); mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); renderingMode->SetValue(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR); selectedNode->SetProperty("Image Rendering.Transfer Function", mitkTransFuncProp); selectedNode->SetProperty("Image Rendering.Mode", renderingMode); m_selectedNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); mitk::IsoDoseLevelVector::Pointer levelVector = mitk::IsoDoseLevelVector::New(); mitk::IsoDoseLevelVectorProperty::Pointer levelVecProp = mitk::IsoDoseLevelVectorProperty::New(levelVector); selectedNode->SetProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),levelVecProp); UpdateBySelectedNode(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } const mitk::Geometry2D* RTDoseVisualizer::GetGeometry2D(char* dim) { QmitkRenderWindow* rw = this->GetRenderWindowPart()->GetQmitkRenderWindow(dim); const mitk::Geometry2D* worldGeo = rw->GetRenderer()->GetCurrentWorldGeometry2D(); return worldGeo; } mitk::Image::Pointer RTDoseVisualizer::GetExtractedSlice(mitk::Image::Pointer image) { mitk::ExtractSliceFilter::Pointer extractFilter = mitk::ExtractSliceFilter::New(); extractFilter->SetInput(image); extractFilter->SetWorldGeometry(this->GetGeometry2D("axial")); extractFilter->SetResliceTransformByGeometry( image->GetGeometry() ); extractFilter->Update(); mitk::Image::Pointer reslicedImage = extractFilter->GetOutput(); return reslicedImage; } mitk::DataNode::Pointer RTDoseVisualizer::UpdatePolyData(int num, double min, double max) { mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); mitk::Image::Pointer reslicedImage = this->GetExtractedSlice(image); vtkSmartPointer contourFilter = vtkSmartPointer::New(); m_Filters.push_back(contourFilter); contourFilter->SetInputData(reslicedImage->GetVtkImageData()); contourFilter->GenerateValues(num,min,max); contourFilter->Update(); vtkSmartPointer polyData = vtkSmartPointer::New(); polyData =contourFilter->GetOutput(); mitk::Surface::Pointer isoline = mitk::Surface::New(); isoline->SetVtkPolyData(polyData); isoline->SetGeometry(const_cast(this->GetGeometry2D("axial"))->Clone()); isoline->GetGeometry()->SetSpacing(image->GetGeometry()->GetSpacing()); isoline->SetOrigin(reslicedImage->GetGeometry()->GetOrigin()); mitk::DataNode::Pointer isolineNode = mitk::DataNode::New(); isolineNode->SetData(isoline); mitk::SurfaceVtkMapper3D::Pointer mapper = mitk::SurfaceVtkMapper3D::New(); isolineNode->SetMapper(1, mapper); isolineNode->SetName("Isoline1"); + isolineNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); isolineNode->SetBoolProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),true); + m_FreeIsoline = isolineNode; this->GetDataStorage()->Add(isolineNode); return isolineNode; } void RTDoseVisualizer::UpdateStdIsolines() { mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = this->m_Presets[this->m_selectedPresetName]; mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); mitk::Image::Pointer reslicedImage = this->GetExtractedSlice(image); float pref; m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); for(mitk::IsoDoseLevelSet::ConstIterator doseIT = isoDoseLevelSet->Begin(); doseIT!=isoDoseLevelSet->End();++doseIT) { if(doseIT->GetVisibleIsoLine()){ vtkSmartPointer isolineFilter = vtkSmartPointer::New(); isolineFilter->SetInputData(reslicedImage->GetVtkImageData()); isolineFilter->GenerateValues(1,doseIT->GetDoseValue()*pref,doseIT->GetDoseValue()*pref); isolineFilter->Update(); vtkSmartPointer polyData = vtkSmartPointer::New(); polyData=isolineFilter->GetOutput(); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(polyData); surface->SetGeometry(const_cast(this->GetGeometry2D("axial"))->Clone()); surface->GetGeometry()->SetSpacing(image->GetGeometry()->GetSpacing()); surface->SetOrigin(reslicedImage->GetGeometry()->GetOrigin()); mitk::DataNode::Pointer isoNode = mitk::DataNode::New(); isoNode->SetData(surface); mitk::SurfaceVtkMapper3D::Pointer mapper = mitk::SurfaceVtkMapper3D::New(); mitk::Color color; color[0]=doseIT->GetColor()[0];color[1]=doseIT->GetColor()[1];color[2]=doseIT->GetColor()[2]; isoNode->SetMapper(1,mapper); isoNode->SetColor(color); isoNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); isoNode->SetName("StdIsoline"); isoNode->SetBoolProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),true); m_StdIsoLines.push_back(isoNode); this->GetDataStorage()->Add(isoNode); } } } void RTDoseVisualizer::HideIsoline() { mitk::NodePredicateProperty::Pointer isoProp = mitk::NodePredicateProperty:: New(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer isoSet = this->GetDataStorage()->GetSubset(isoProp); for(mitk::DataStorage::SetOfObjects::ConstIterator iso = isoSet->Begin(); iso!=isoSet->End(); ++iso) { } } void RTDoseVisualizer::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, const QList& nodes ) { QList dataNodes = this->GetDataManagerSelection(); mitk::DataNode* selectedNode = NULL; if (!dataNodes.empty()) { bool isDoseNode = false; dataNodes[0]->GetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),isDoseNode); if (isDoseNode) { selectedNode = dataNodes[0]; } } if (selectedNode != m_selectedNode.GetPointer()) { m_selectedNode = selectedNode; } UpdateBySelectedNode(); } void RTDoseVisualizer::UpdateBySelectedNode() { m_Controls.groupNodeSpecific->setEnabled(m_selectedNode.IsNotNull()); m_Controls.groupFreeValues->setEnabled(m_selectedNode.IsNotNull()); if(m_selectedNode.IsNull()) { m_Controls.NrOfFractions->setText(QString("N/A. No dose selected")); m_Controls.prescribedDoseSpecific->setText(QString("N/A. No dose selected")); m_freeIsoValues = mitk::IsoDoseLevelVector::New(); UpdateFreeIsoValues(); } else { //dose specific information int fracCount = 1; m_selectedNode->GetIntProperty(mitk::rt::Constants::DOSE_FRACTION_COUNT_PROPERTY_NAME.c_str(),fracCount); m_Controls.NrOfFractions->setText(QString::number(fracCount)); m_PrescribedDose_Data = 0.0; float tmp; m_selectedNode->GetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),tmp); m_PrescribedDose_Data = (double)tmp; m_Controls.prescribedDoseSpecific->setText(QString::number(m_PrescribedDose_Data)); //free iso lines mitk::IsoDoseLevelVectorProperty::Pointer propIsoVector; m_selectedNode->GetProperty(propIsoVector, mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str()); if (propIsoVector.IsNull()) { m_freeIsoValues = mitk::IsoDoseLevelVector::New(); propIsoVector = mitk::IsoDoseLevelVectorProperty::New(m_freeIsoValues); m_selectedNode->SetProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),propIsoVector); } else { m_freeIsoValues = propIsoVector->GetValue(); } UpdateFreeIsoValues(); //global dose issues bool showIsoLine = false; m_selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(),showIsoLine); m_Controls.checkGlobalVisIsoLine->setChecked(showIsoLine); bool showColorWash = false; m_selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(),showColorWash); m_Controls.checkGlobalVisColorWash->setChecked(showColorWash); float referenceDose = 0.0; m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),referenceDose); m_Controls.spinReferenceDose->setValue(referenceDose); mitk::IsoDoseLevelSetProperty::Pointer propIsoSet = dynamic_cast(m_selectedNode->GetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str())); if (propIsoSet) { this->m_selectedNodeIsoSet = propIsoSet->GetValue(); this->m_LevelSetModel->setIsoDoseLevelSet(m_selectedNodeIsoSet); } } } void RTDoseVisualizer::UpdateByPreferences() { m_Presets = mitk::rt::LoadPresetsMap(); m_internalUpdate = true; m_Controls.comboPresets->clear(); this->m_selectedPresetName = mitk::rt::GetSelectedPresetName(); int index = 0; int selectedIndex = -1; for (mitk::rt::PresetMapType::const_iterator pos = m_Presets.begin(); pos != m_Presets.end(); ++pos, ++index) { m_Controls.comboPresets->addItem(QString(pos->first.c_str())); if (this->m_selectedPresetName == pos->first) { selectedIndex = index; } } if (selectedIndex == -1) { selectedIndex = 0; MITK_WARN << "Error. Cannot iso dose level preset specified in preferences does not exist. Preset name: "<m_selectedPresetName; this->m_selectedPresetName = m_Presets.begin()->first; mitk::rt::SetSelectedPresetName(this->m_selectedPresetName); MITK_INFO << "Changed selected iso dose level preset to first existing preset. New preset name: "<m_selectedPresetName; } m_Controls.comboPresets->setCurrentIndex(selectedIndex); this->m_selectedNodeIsoSet = this->m_Presets[this->m_selectedPresetName]; this->m_LevelSetModel->setIsoDoseLevelSet(m_selectedNodeIsoSet); mitk::DoseValueAbs referenceDose = 0.0; bool globalSync = mitk::rt::GetReferenceDoseValue(referenceDose); if (globalSync || this->m_selectedNode.IsNull()) { m_Controls.spinReferenceDose->setValue(referenceDose); } bool displayAbsoluteDose = mitk::rt::GetDoseDisplayAbsolute(); m_Controls.radioAbsDose->setChecked(displayAbsoluteDose); m_Controls.radioRelDose->setChecked(!displayAbsoluteDose); this->m_LevelSetModel->setShowAbsoluteDose(displayAbsoluteDose); m_internalUpdate = false; } void RTDoseVisualizer::OnCurrentPresetChanged(const QString& presetName) { if (! m_internalUpdate) { mitk::rt::SetSelectedPresetName(presetName.toStdString()); this->UpdateByPreferences(); this->ActualizeIsoLevelsForAllDoseDataNodes(); this->UpdateBySelectedNode(); } } void RTDoseVisualizer::ActualizeIsoLevelsForAllDoseDataNodes() { std::string presetName = mitk::rt::GetSelectedPresetName(); mitk::rt::PresetMapType presetMap = mitk::rt::LoadPresetsMap(); mitk::NodePredicateProperty::Pointer isDoseNode = mitk::NodePredicateProperty::New(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetSubset(isDoseNode); mitk::IsoDoseLevelSet* selectedPreset = presetMap[presetName]; if (!selectedPreset) { mitkThrow() << "Error. Cannot actualize iso dose level preset. Selected preset idoes not exist. Preset name: "<begin(); pos != nodes->end(); ++pos) { mitk::IsoDoseLevelSet::Pointer clonedPreset = selectedPreset->Clone(); mitk::IsoDoseLevelSetProperty::Pointer propIsoSet = mitk::IsoDoseLevelSetProperty::New(clonedPreset); (*pos)->SetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),propIsoSet); } } void RTDoseVisualizer::ActualizeReferenceDoseForAllDoseDataNodes() { /** @TODO Klären ob diese präsentations info genauso wie*/ mitk::DoseValueAbs value = 0; bool sync = mitk::rt::GetReferenceDoseValue(value); if (sync) { mitk::NodePredicateProperty::Pointer isDoseNode = mitk::NodePredicateProperty::New(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetSubset(isDoseNode); for(mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); ++pos) { (*pos)->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), value); } } } void RTDoseVisualizer::ActualizeDisplayStyleForAllDoseDataNodes() { /** @TODO Klären ob diese präsentations info global oder auch per node gespeichert wird*/ } void RTDoseVisualizer::OnHandleCTKEventReferenceDoseChanged(const ctkEvent& event) { mitk::DoseValueAbs referenceDose = 0.0; bool globalSync = mitk::rt::GetReferenceDoseValue(referenceDose); this->m_Controls.spinReferenceDose->setValue(referenceDose); } void RTDoseVisualizer::OnHandleCTKEventPresetsChanged(const ctkEvent& event) { std::string currentPresetName = mitk::rt::GetSelectedPresetName(); this->OnCurrentPresetChanged(QString::fromStdString(currentPresetName)); } diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h index 85d96a07c0..dcb0062f4b 100644 --- a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h @@ -1,175 +1,178 @@ /*=================================================================== 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 RTDoseVisualizer_h #define RTDoseVisualizer_h #include #include #include #include #include "ui_RTDoseVisualizerControls.h" #include #include #include "mitkDoseVisPreferenceHelper.h" // Shader #include #include #include #include /*forward declarations*/ class QmitkIsoDoseLevelSetModel; class QmitkDoseColorDelegate; class QmitkDoseValueDelegate; class QmitkDoseVisualStyleDelegate; class ctkEvent; /** \brief RTDoseVisualizer \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \sa QmitkAbstractView \ingroup ${plugin_target}_internal */ class RTDoseVisualizer : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: RTDoseVisualizer(); virtual ~RTDoseVisualizer(); static const std::string VIEW_ID; void OnSliceChanged(itk::Object *sender, const itk::EventObject &e); protected slots: void OnConvertButtonClicked(); void OnAddFreeValueClicked(); void OnRemoveFreeValueClicked(); void OnUsePrescribedDoseClicked(); void OnAbsDoseToggled(bool); void OnGlobalVisColorWashToggled(bool); void OnGlobalVisIsoLineToggled(bool); void OnShowContextMenuIsoSet(const QPoint&); void OnCurrentPresetChanged(const QString&); void OnReferenceDoseChanged(double); void OnHandleCTKEventReferenceDoseChanged(const ctkEvent& event); void OnHandleCTKEventPresetsChanged(const ctkEvent& event); void UpdateFreeIsoLine(mitk::IsoDoseLevel*level, mitk::DoseValueRel old); + void UpdateFreeIsoLineColor(mitk::IsoDoseLevel* level); + protected: void InitScrolling(); virtual void CreateQtPartControl(QWidget *parent); virtual void SetFocus(); /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, const QList& nodes ); /** Method updates the list widget according to the current m_freeIsoValues.*/ void UpdateFreeIsoValues(); /** Update the members according to the currently selected node */ void UpdateBySelectedNode(); /** Update the member widgets according to the information stored in the application preferences*/ void UpdateByPreferences(); /**helper function that iterates throug all data nodes and sets there iso level set property according to the selected preset. @TODO: should be moved outside the class, to be available for other classes at well.*/ void ActualizeIsoLevelsForAllDoseDataNodes(); /**helper function that iterates throug all data nodes and sets there reference dose value according to the preference. @TODO: should be moved outside the class, to be available for other classes at well.*/ void ActualizeReferenceDoseForAllDoseDataNodes(); /**helper function that iterates through all data nodes and sets there dose display style (relative/absolute) according to the preference. @TODO: should be moved outside the class, to be available for other classes at well.*/ void ActualizeDisplayStyleForAllDoseDataNodes(); mitk::DataNode::Pointer UpdatePolyData(int num, double min, double max); void UpdateStdIsolines(); void HideIsoline(); mitk::Image::Pointer GetExtractedSlice(mitk::Image::Pointer image); const mitk::Geometry2D* GetGeometry2D(char* dim); Ui::RTDoseVisualizerControls m_Controls; mitk::DataNode::Pointer m_selectedNode; mitk::IsoDoseLevelVector::Pointer m_freeIsoValues; std::vector m_FreeIsoLines; std::vector m_StdIsoLines; /** Iso level set of the current node. Should normaly be a clone of the * current iso preset. It held as own member because visibility * settings may differ.*/ mitk::IsoDoseLevelSet::Pointer m_selectedNodeIsoSet; mitk::rt::PresetMapType m_Presets; std::string m_selectedPresetName; mitk::DataNode::Pointer m_FreeIsoline; + bool m_FreeIsoAdded; /** Prescribed Dose of the selected data.*/ mitk::DoseValueAbs m_PrescribedDose_Data; QmitkIsoDoseLevelSetModel* m_LevelSetModel; QmitkDoseColorDelegate* m_DoseColorDelegate; QmitkDoseValueDelegate* m_DoseValueDelegate; QmitkDoseVisualStyleDelegate* m_DoseVisualDelegate; vtkSmartPointer m_freeIsoFilter; std::vector< vtkSmartPointer > m_Filters; bool m_internalUpdate; }; #endif // RTDoseVisualizer_h diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui index 1d91926b68..2fd012975b 100644 --- a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui @@ -1,508 +1,514 @@ RTDoseVisualizerControls 0 0 421 651 0 0 QmitkTemplate 5 5 5 5 5 Dose specific information: 5 5 5 5 5 Qt::Horizontal 40 20 true 30 Gy Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Number of fractions: Prescribed dose [Gy]: Use as reference dose true 0 0 Free iso lines: 5 5 5 5 5 0 0 0 40 16777215 110 0 25 Qt::Horizontal 40 20 Add Remove Global iso dose visualization: 5 5 5 5 5 0 0 65 0 Dose display: 0 0 65 0 Preset style: 0 0 105 0 Qt::NoFocus Reference dose [Gy]: 1 0.100000000000000 9999.000000000000000 0.100000000000000 relative [%] true absolute [Gy] false true QAbstractItemView::SingleSelection QAbstractItemView::SelectRows 30 20 80 Global visibility: Qt::Horizontal 40 20 + + false + Isolines :/RTUI/eye_open.png 24 16 + + false + Colorwash :/RTUI/eye_open.png 24 16 255 0 0 255 0 0 255 0 0 255 0 0 120 120 120 120 120 120 Convert nod to dose node (for testing only!)