diff --git a/Core/Code/Common/mitkCoreObjectFactory.cpp b/Core/Code/Common/mitkCoreObjectFactory.cpp index efd1d7169a..a4c58847fe 100644 --- a/Core/Code/Common/mitkCoreObjectFactory.cpp +++ b/Core/Code/Common/mitkCoreObjectFactory.cpp @@ -1,453 +1,459 @@ /*=================================================================== 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 "mitkConfig.h" #include "mitkCoreObjectFactory.h" #include "mitkAffineInteractor.h" #include "mitkColorProperty.h" #include "mitkDataNode.h" #include "mitkEnumerationProperty.h" #include "mitkPlaneGeometryData.h" #include "mitkPlaneGeometryDataMapper2D.h" #include "mitkPlaneGeometryDataVtkMapper3D.h" #include "mitkGeometry3D.h" #include "mitkGeometryData.h" #include "mitkImage.h" #include #include "mitkLevelWindowProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkPlaneGeometry.h" #include "mitkPointSet.h" #include "mitkPointSetVtkMapper2D.h" #include "mitkPointSetVtkMapper3D.h" #include "mitkProperties.h" #include "mitkPropertyList.h" #include "mitkSlicedGeometry3D.h" #include "mitkSmartPointerProperty.h" #include "mitkStringProperty.h" #include "mitkSurface.h" #include "mitkSurface.h" -#include "mitkSurfaceGLMapper2D.h" +#include "mitkSurfaceVtkMapper2D.h" #include "mitkSurfaceVtkMapper3D.h" #include "mitkTimeGeometry.h" #include "mitkTransferFunctionProperty.h" #include "mitkVolumeDataVtkMapper3D.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkResliceInterpolationProperty.h" // Legacy Support: #include #include #include void mitk::CoreObjectFactory::RegisterExtraFactory(CoreObjectFactoryBase* factory) { MITK_DEBUG << "CoreObjectFactory: registering extra factory of type " << factory->GetNameOfClass(); m_ExtraFactories.insert(CoreObjectFactoryBase::Pointer(factory)); // Register Legacy Reader and Writer this->RegisterLegacyReaders(factory); this->RegisterLegacyWriters(factory); } void mitk::CoreObjectFactory::UnRegisterExtraFactory(CoreObjectFactoryBase *factory) { MITK_DEBUG << "CoreObjectFactory: un-registering extra factory of type " << factory->GetNameOfClass(); this->UnRegisterLegacyWriters(factory); this->UnRegisterLegacyReaders(factory); try { m_ExtraFactories.erase(factory); } catch( std::exception const& e) { MITK_ERROR << "Caugt exception while unregistering: " << e.what(); } } mitk::CoreObjectFactory::Pointer mitk::CoreObjectFactory::GetInstance() { static mitk::CoreObjectFactory::Pointer instance; if (instance.IsNull()) { instance = mitk::CoreObjectFactory::New(); } return instance; } mitk::CoreObjectFactory::~CoreObjectFactory() { for (std::map >::iterator iter = m_LegacyReaders.begin(); iter != m_LegacyReaders.end(); ++iter) { for (std::list::iterator readerIter = iter->second.begin(), readerIterEnd = iter->second.end(); readerIter != readerIterEnd; ++readerIter) { delete *readerIter; } } for (std::map >::iterator iter = m_LegacyWriters.begin(); iter != m_LegacyWriters.end(); ++iter) { for (std::list::iterator writerIter = iter->second.begin(), writerIterEnd = iter->second.end(); writerIter != writerIterEnd; ++writerIter) { delete *writerIter; } } } void mitk::CoreObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if(node==NULL) return; mitk::DataNode::Pointer nodePointer = node; mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull() && image->IsInitialized()) { mitk::ImageVtkMapper2D::SetDefaultProperties(node); mitk::VolumeDataVtkMapper3D::SetDefaultProperties(node); } + mitk::PlaneGeometryData::Pointer planeGeometry = dynamic_cast(node->GetData()); + if(planeGeometry.IsNotNull()) + { + mitk::PlaneGeometryDataMapper2D::SetDefaultProperties(node); + } + mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { - mitk::SurfaceGLMapper2D::SetDefaultProperties(node); + mitk::SurfaceVtkMapper2D::SetDefaultProperties(node); mitk::SurfaceVtkMapper3D::SetDefaultProperties(node); } mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if(pointSet.IsNotNull()) { mitk::PointSetVtkMapper2D::SetDefaultProperties(node); mitk::PointSetVtkMapper3D::SetDefaultProperties(node); } for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { (*it)->SetDefaultProperties(node); } } mitk::CoreObjectFactory::CoreObjectFactory() { static bool alreadyDone = false; if (!alreadyDone) { CreateFileExtensionsMap(); //RegisterLegacyReaders(this); //RegisterLegacyWriters(this); alreadyDone = true; } } mitk::Mapper::Pointer mitk::CoreObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id) { mitk::Mapper::Pointer newMapper = NULL; mitk::Mapper::Pointer tmpMapper = NULL; // check whether extra factories provide mapper for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { tmpMapper = (*it)->CreateMapper(node,id); if(tmpMapper.IsNotNull()) newMapper = tmpMapper; } if (newMapper.IsNull()) { mitk::BaseData *data = node->GetData(); if ( id == mitk::BaseRenderer::Standard2D ) { if((dynamic_cast(data)!=NULL)) { newMapper = mitk::ImageVtkMapper2D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PlaneGeometryDataMapper2D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { - newMapper = mitk::SurfaceGLMapper2D::New(); + newMapper = mitk::SurfaceVtkMapper2D::New(); // cast because SetDataNode is not virtual - mitk::SurfaceGLMapper2D *castedMapper = dynamic_cast(newMapper.GetPointer()); + mitk::SurfaceVtkMapper2D *castedMapper = dynamic_cast(newMapper.GetPointer()); castedMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PointSetVtkMapper2D::New(); newMapper->SetDataNode(node); } } else if ( id == mitk::BaseRenderer::Standard3D ) { if((dynamic_cast(data) != NULL)) { newMapper = mitk::VolumeDataVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PlaneGeometryDataVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::SurfaceVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PointSetVtkMapper3D::New(); newMapper->SetDataNode(node); } } } return newMapper; } const char* mitk::CoreObjectFactory::GetFileExtensions() { MultimapType aMap; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { aMap = (*it)->GetFileExtensionsMap(); this->MergeFileExtensions(m_FileExtensionsMap, aMap); } this->CreateFileExtensions(m_FileExtensionsMap, m_FileExtensions); return m_FileExtensions.c_str(); } void mitk::CoreObjectFactory::MergeFileExtensions(MultimapType& fileExtensionsMap, MultimapType inputMap) { bool duplicateFound = false; std::pair pairOfIter; for (MultimapType::iterator it = inputMap.begin(); it != inputMap.end(); ++it) { duplicateFound = false; pairOfIter = fileExtensionsMap.equal_range((*it).first); for (MultimapType::iterator it2 = pairOfIter.first; it2 != pairOfIter.second; ++it2) { //cout << " [" << (*it).first << ", " << (*it).second << "]" << endl; std::string aString = (*it2).second; if (aString.compare((*it).second) == 0) { //cout << " DUP!! [" << (*it).first << ", " << (*it).second << "]" << endl; duplicateFound = true; break; } } if (!duplicateFound) { fileExtensionsMap.insert(std::pair((*it).first, (*it).second)); } } } mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } void mitk::CoreObjectFactory::CreateFileExtensionsMap() { /* m_FileExtensionsMap.insert(std::pair("*.dcm", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.DCM", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.dc3", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.DC3", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.gdcm", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.seq", "DKFZ Pic")); m_FileExtensionsMap.insert(std::pair("*.seq.gz", "DKFZ Pic")); m_FileExtensionsMap.insert(std::pair("*.dcm", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.gdcm", "Sets of 2D slices")); */ } const char* mitk::CoreObjectFactory::GetSaveFileExtensions() { MultimapType aMap; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { aMap = (*it)->GetSaveFileExtensionsMap(); this->MergeFileExtensions(m_SaveFileExtensionsMap, aMap); } this->CreateFileExtensions(m_SaveFileExtensionsMap, m_SaveFileExtensions); return m_SaveFileExtensions.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } mitk::CoreObjectFactory::FileWriterList mitk::CoreObjectFactory::GetFileWriters() { FileWriterList allWriters = m_FileWriters; //sort to merge lists later on typedef std::set FileWriterSet; FileWriterSet fileWritersSet; fileWritersSet.insert(allWriters.begin(), allWriters.end()); //collect all extra factories for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); it++ ) { FileWriterList list2 = (*it)->GetFileWriters(); //add them to the sorted set fileWritersSet.insert(list2.begin(), list2.end()); } //write back to allWriters to return a list allWriters.clear(); allWriters.insert(allWriters.end(), fileWritersSet.begin(), fileWritersSet.end()); return allWriters; } void mitk::CoreObjectFactory::MapEvent(const mitk::Event*, const int) { } std::string mitk::CoreObjectFactory::GetDescriptionForExtension(const std::string& extension) { std::multimap fileExtensionMap = GetSaveFileExtensionsMap(); for(std::multimap::iterator it = fileExtensionMap.begin(); it != fileExtensionMap.end(); it++) if (it->first == extension) return it->second; return ""; // If no matching extension was found, return emtpy string } void mitk::CoreObjectFactory::RegisterLegacyReaders(mitk::CoreObjectFactoryBase* factory) { // We are not really interested in the string, just call the method since // many readers initialize the map the first time when this method is called factory->GetFileExtensions(); std::map > extensionsByCategories; std::multimap fileExtensionMap = factory->GetFileExtensionsMap(); for(std::multimap::iterator it = fileExtensionMap.begin(); it != fileExtensionMap.end(); it++) { std::string extension = it->first; // remove "*." extension = extension.erase(0,2); extensionsByCategories[it->second].push_back(extension); } for(std::map >::iterator iter = extensionsByCategories.begin(), endIter = extensionsByCategories.end(); iter != endIter; ++iter) { m_LegacyReaders[factory].push_back(new mitk::LegacyFileReaderService(iter->second, iter->first)); } } void mitk::CoreObjectFactory::UnRegisterLegacyReaders(mitk::CoreObjectFactoryBase* factory) { std::map >::iterator iter = m_LegacyReaders.find(factory); if (iter != m_LegacyReaders.end()) { for (std::list::iterator readerIter = iter->second.begin(), readerIterEnd = iter->second.end(); readerIter != readerIterEnd; ++readerIter) { delete *readerIter; } m_LegacyReaders.erase(iter); } } void mitk::CoreObjectFactory::RegisterLegacyWriters(mitk::CoreObjectFactoryBase* factory) { // Get all external Writers mitk::CoreObjectFactory::FileWriterList writers = factory->GetFileWriters(); // We are not really interested in the string, just call the method since // many writers initialize the map the first time when this method is called factory->GetSaveFileExtensions(); MultimapType fileExtensionMap = factory->GetSaveFileExtensionsMap(); for(mitk::CoreObjectFactory::FileWriterList::iterator it = writers.begin(); it != writers.end(); it++) { std::vector extensions = (*it)->GetPossibleFileExtensions(); if (extensions.empty()) continue; std::string description; for(std::vector::iterator ext = extensions.begin(); ext != extensions.end(); ext++) { if (ext->empty()) continue; std::string extension = *ext; std::string extensionWithStar = extension; if (extension.find_first_of('*') == 0) { // remove "*." extension = extension.substr(0, extension.size()-2); } else { extensionWithStar.insert(extensionWithStar.begin(), '*'); } for(MultimapType::iterator fileExtensionIter = fileExtensionMap.begin(); fileExtensionIter != fileExtensionMap.end(); fileExtensionIter++) { if (fileExtensionIter->first == extensionWithStar) { description = fileExtensionIter->second; break; } } if (!description.empty()) break; } if (description.empty()) { description = std::string("Legacy ") + (*it)->GetNameOfClass() + " Reader"; } mitk::FileWriter::Pointer fileWriter(it->GetPointer()); mitk::LegacyFileWriterService* lfws = new mitk::LegacyFileWriterService(fileWriter, description); m_LegacyWriters[factory].push_back(lfws); } } void mitk::CoreObjectFactory::UnRegisterLegacyWriters(mitk::CoreObjectFactoryBase* factory) { std::map >::iterator iter = m_LegacyWriters.find(factory); if (iter != m_LegacyWriters.end()) { for (std::list::iterator writerIter = iter->second.begin(), writerIterEnd = iter->second.end(); writerIter != writerIterEnd; ++writerIter) { delete *writerIter; } m_LegacyWriters.erase(iter); } } diff --git a/Core/Code/Controllers/mitkVtkLayerController.cpp b/Core/Code/Controllers/mitkVtkLayerController.cpp index 2213b78638..bca29edba0 100644 --- a/Core/Code/Controllers/mitkVtkLayerController.cpp +++ b/Core/Code/Controllers/mitkVtkLayerController.cpp @@ -1,342 +1,342 @@ /*=================================================================== 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 "mitkVtkLayerController.h" #include #include #include #include #include mitk::VtkLayerController::vtkLayerControllerMapType mitk::VtkLayerController::s_LayerControllerMap; -mitk::VtkLayerController * mitk::VtkLayerController::GetInstance(vtkRenderWindow* renWin) +mitk::VtkLayerController* mitk::VtkLayerController::GetInstance(vtkSmartPointer renWin) { for(vtkLayerControllerMapType::iterator mapit = s_LayerControllerMap.begin(); mapit != s_LayerControllerMap.end(); mapit++) { if( (*mapit).first == renWin) return (*mapit).second; } return NULL; } -void mitk::VtkLayerController::AddInstance(vtkRenderWindow* renWin, vtkRenderer * mitkSceneRenderer) +void mitk::VtkLayerController::AddInstance(vtkSmartPointer renWin, + vtkSmartPointer mitkSceneRenderer) { // ensure that no vtkRenderWindow is managed twice mitk::VtkLayerController::RemoveInstance(renWin); // instanciate controller, add it to the map mitk::VtkLayerController* ControllerInstance = new mitk::VtkLayerController(renWin); ControllerInstance->InsertSceneRenderer(mitkSceneRenderer); s_LayerControllerMap.insert(vtkLayerControllerMapType::value_type(renWin,ControllerInstance)); } -void mitk::VtkLayerController::RemoveInstance(vtkRenderWindow* renWin) +void mitk::VtkLayerController::RemoveInstance(vtkSmartPointer renWin) { vtkLayerControllerMapType::iterator mapit = s_LayerControllerMap.find(renWin); if(mapit != s_LayerControllerMap.end()) { delete mapit->second; s_LayerControllerMap.erase( mapit ); } } -mitk::VtkLayerController::VtkLayerController(vtkRenderWindow* renderWindow) +mitk::VtkLayerController::VtkLayerController(vtkSmartPointer renderWindow) { m_RenderWindow = renderWindow; m_RenderWindow->Register( NULL ); m_BackgroundRenderers.clear(); m_ForegroundRenderers.clear(); m_SceneRenderers.clear(); } mitk::VtkLayerController::~VtkLayerController() { if ( m_RenderWindow != NULL ) { m_RenderWindow->UnRegister( NULL ); } } /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the background. * With forceAbsoluteBackground set true a renderer can be placed at the absolute background of the scene. * Multiple calls with forceAbsoluteBackground set true will set the latest registered renderer as background. */ -void mitk::VtkLayerController::InsertBackgroundRenderer(vtkRenderer* renderer, bool forceAbsoluteBackground) +void mitk::VtkLayerController::InsertBackgroundRenderer(vtkSmartPointer + renderer, bool forceAbsoluteBackground) { if(renderer == NULL) return; // Remove renderer if it already exists RemoveRenderer(renderer); if(forceAbsoluteBackground) { RendererVectorType::iterator it = m_BackgroundRenderers.begin(); m_BackgroundRenderers.insert(it,renderer); } else m_BackgroundRenderers.push_back(renderer); UpdateLayers(); } /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the foreground. * With forceAbsoluteBackground set true a renderer can be placed at the absolute foreground of the scene. * Multiple calls with forceAbsoluteForeground set true will set the latest registered renderer as foreground. */ -void mitk::VtkLayerController::InsertForegroundRenderer(vtkRenderer* renderer, bool forceAbsoluteForeground) +void mitk::VtkLayerController::InsertForegroundRenderer(vtkSmartPointer renderer, + bool forceAbsoluteForeground) { if(renderer == NULL) return; // Remove renderer if it already exists RemoveRenderer(renderer); if(forceAbsoluteForeground) { RendererVectorType::iterator it = m_ForegroundRenderers.begin(); m_ForegroundRenderers.insert(it,renderer); } else m_ForegroundRenderers.push_back(renderer); UpdateLayers(); } /** * Returns the Scene Renderer */ -vtkRenderer* mitk::VtkLayerController::GetSceneRenderer() +vtkSmartPointer mitk::VtkLayerController::GetSceneRenderer() { if(m_SceneRenderers.size() > 0) { RendererVectorType::iterator it = m_SceneRenderers.begin(); return (*it); } else return NULL; } /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered between background renderers and * foreground renderers. */ -void mitk::VtkLayerController::InsertSceneRenderer(vtkRenderer* renderer) +void mitk::VtkLayerController::InsertSceneRenderer(vtkSmartPointer renderer) { if(renderer == NULL) return; // Remove renderer if it already exists RemoveRenderer(renderer); m_SceneRenderers.push_back(renderer); UpdateLayers(); } /** * A renderer which has been inserted via a insert... function can be removed from the vtkRenderWindow with * RemoveRenderer. */ -void mitk::VtkLayerController::RemoveRenderer(vtkRenderer* renderer) +void mitk::VtkLayerController::RemoveRenderer(vtkSmartPointer renderer) { RendererVectorType::iterator it; // background layers if(m_BackgroundRenderers.size() > 0) { it = std::find(m_BackgroundRenderers.begin(),m_BackgroundRenderers.end(),renderer); if(it != m_BackgroundRenderers.end()) { m_BackgroundRenderers.erase(it); UpdateLayers(); return; } } // scene layers if(m_SceneRenderers.size() > 0) { it = std::find(m_SceneRenderers.begin(),m_SceneRenderers.end(),renderer); if(it != m_SceneRenderers.end()) { m_SceneRenderers.erase(it); UpdateLayers(); return; } } // foreground layers if(m_ForegroundRenderers.size() > 0 ) { it = std::find(m_ForegroundRenderers.begin(),m_ForegroundRenderers.end(),renderer); if(it != m_ForegroundRenderers.end()) { m_ForegroundRenderers.erase(it); UpdateLayers(); return; } } } /** * Connects a VtkRenderWindow with the layer controller. */ -void mitk::VtkLayerController::SetRenderWindow(vtkRenderWindow* renwin) +void mitk::VtkLayerController::SetRenderWindow(vtkSmartPointer renwin) { if(renwin != NULL) { RendererVectorType::iterator it; // Tell all renderers that there is a new renderwindow for(it = m_BackgroundRenderers.begin(); it != m_BackgroundRenderers.end(); it++) { (*it)->SetRenderWindow(renwin); } for(it = m_SceneRenderers.begin(); it != m_SceneRenderers.end(); it++) { (*it)->SetRenderWindow(renwin); } for(it = m_ForegroundRenderers.begin(); it != m_ForegroundRenderers.end(); it++) { (*it)->SetRenderWindow(renwin); } // Set the new RenderWindow m_RenderWindow = renwin; } // Now sort renderers and add them to the renderwindow UpdateLayers(); } /** * Returns true if a renderer has been inserted */ -bool mitk::VtkLayerController::IsRendererInserted(vtkRenderer* renderer) +bool mitk::VtkLayerController::IsRendererInserted(vtkSmartPointer renderer) { RendererVectorType::iterator it; // background layers if(m_BackgroundRenderers.size() > 0) { it = std::find(m_BackgroundRenderers.begin(),m_BackgroundRenderers.end(),renderer); if ( it != m_BackgroundRenderers.end() ) { return true; } } // scene layers if(m_SceneRenderers.size() > 0) { it = std::find(m_SceneRenderers.begin(),m_SceneRenderers.end(),renderer); if ( it != m_SceneRenderers.end() ) { return true; } } // foreground layers if(m_ForegroundRenderers.size() > 0 ) { it = std::find(m_ForegroundRenderers.begin(),m_ForegroundRenderers.end(),renderer); if ( it != m_ForegroundRenderers.end() ) { return true; } } return false; } /** * Internally used to sort all registered renderers and to connect the with the vtkRenderWindow. * Mention that VTK Version 5 and above is rendering higher numbers in the background and VTK * Verison < 5 in the foreground. */ void mitk::VtkLayerController::UpdateLayers() { // Remove all Renderers from renderwindow - vtkRendererCollection* v = m_RenderWindow->GetRenderers(); + vtkSmartPointer v = m_RenderWindow->GetRenderers(); v->RemoveAllItems(); unsigned int numberOfLayers = static_cast(m_BackgroundRenderers.size() + m_SceneRenderers.size() + m_ForegroundRenderers.size()); int currentLayerNumber; bool traverseUpwards; currentLayerNumber = 0; traverseUpwards = true; m_RenderWindow->SetNumberOfLayers(numberOfLayers); RendererVectorType::iterator it; // assign a layer number for the backround renderers for(it = m_BackgroundRenderers.begin(); it != m_BackgroundRenderers.end(); it++) { (*it)->SetRenderWindow(m_RenderWindow); (*it)->SetLayer(currentLayerNumber); m_RenderWindow->AddRenderer((*it)); if(traverseUpwards) currentLayerNumber++; else currentLayerNumber--; } // assign a layer number for the scene renderers for(it = m_SceneRenderers.begin(); it != m_SceneRenderers.end(); it++) { (*it)->SetRenderWindow(m_RenderWindow); (*it)->SetLayer(currentLayerNumber); m_RenderWindow->AddRenderer((*it)); if(traverseUpwards) currentLayerNumber++; else currentLayerNumber--; } // assign a layer number for the foreground renderers for(it = m_ForegroundRenderers.begin(); it != m_ForegroundRenderers.end(); it++) { (*it)->SetRenderWindow(m_RenderWindow); (*it)->SetLayer(currentLayerNumber); m_RenderWindow->AddRenderer((*it)); if(traverseUpwards) currentLayerNumber++; else currentLayerNumber--; } } /** * Returns the number of renderers in the renderwindow. */ unsigned int mitk::VtkLayerController::GetNumberOfRenderers() { return static_cast(m_BackgroundRenderers.size() + m_SceneRenderers.size() + m_ForegroundRenderers.size()); } void mitk::VtkLayerController::SetEraseForAllRenderers(int i) { - this->m_RenderWindow->SetErase(i); RendererVectorType::iterator it; for(it = m_BackgroundRenderers.begin(); it != m_BackgroundRenderers.end(); it++) (*it)->SetErase(i); for(it = m_SceneRenderers.begin(); it != m_SceneRenderers.end(); it++) - (*it)->SetErase(i); + (*it)->SetErase(i); for(it = m_ForegroundRenderers.begin(); it != m_ForegroundRenderers.end(); it++) - (*it)->SetErase(i); - + (*it)->SetErase(i); } - diff --git a/Core/Code/Controllers/mitkVtkLayerController.h b/Core/Code/Controllers/mitkVtkLayerController.h index 2f73b7b2e6..3c3696f2da 100644 --- a/Core/Code/Controllers/mitkVtkLayerController.h +++ b/Core/Code/Controllers/mitkVtkLayerController.h @@ -1,135 +1,129 @@ /*=================================================================== 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 MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D -#define MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D +#ifndef mitkVtkLayerController_h +#define mitkVtkLayerController_h #include #include #include #include class vtkRenderWindow; class vtkRenderer; namespace mitk { #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4251) #endif /** * Manages the VTK layer hierarchy * of a vtkRenderWindow. * For simple access the layers are divided into three * main groups: background, scene and foreground layers. * Renderers can be registered via the insert... functions and * removed via the RemoveRenderer function. */ class MITK_CORE_EXPORT VtkLayerController { - public: - static VtkLayerController* GetInstance(vtkRenderWindow* renWin); - static void AddInstance(vtkRenderWindow* renWin, vtkRenderer * mitkSceneRenderer); - static void RemoveInstance(vtkRenderWindow* renWin); +public: + static VtkLayerController* GetInstance(vtkSmartPointer renWin); + static void AddInstance(vtkSmartPointer renWin, vtkSmartPointer mitkSceneRenderer); + static void RemoveInstance(vtkSmartPointer renWin); - VtkLayerController(vtkRenderWindow* renderWindow); - virtual ~VtkLayerController(); + VtkLayerController(vtkSmartPointer renderWindow); + virtual ~VtkLayerController(); - /** + /** * Returns the current vtkRenderer of the Scene */ - vtkRenderer* GetSceneRenderer(); + vtkSmartPointer GetSceneRenderer(); - /** + /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the background. * With forceAbsoluteBackground set true a renderer can be placed at the absolute background of the scene. * Multiple calls with forceAbsoluteBackground set true will set the latest registered renderer as background. */ - void InsertBackgroundRenderer(vtkRenderer* renderer, bool forceAbsoluteBackground); + void InsertBackgroundRenderer(vtkSmartPointer renderer, bool forceAbsoluteBackground); - /** + /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the foreground. * With forceAbsoluteBackground set true a renderer can be placed at the absolute foreground of the scene. * Multiple calls with forceAbsoluteForeground set true will set the latest registered renderer as foreground. */ - void InsertForegroundRenderer(vtkRenderer* renderer, bool forceAbsoluteForeground); + void InsertForegroundRenderer(vtkSmartPointer renderer, bool forceAbsoluteForeground); - /** + /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered between background renderers and * foreground renderers. */ - void InsertSceneRenderer(vtkRenderer* renderer); + void InsertSceneRenderer(vtkSmartPointer renderer); - /** + /** * Connects a VtkRenderWindow with the layer controller. */ - void SetRenderWindow(vtkRenderWindow* renwin); + void SetRenderWindow(vtkSmartPointer renwin); - /** + /** * A renderer which has been inserted via a insert... function can be removed from the vtkRenderWindow with * RemoveRenderer. */ - void RemoveRenderer(vtkRenderer* renderer); + void RemoveRenderer(vtkSmartPointer renderer); - /** + /** * Returns true if a renderer has been inserted */ - bool IsRendererInserted(vtkRenderer* renderer); + bool IsRendererInserted(vtkSmartPointer renderer); - /** + /** * Returns the number of renderers in the renderwindow. */ - unsigned int GetNumberOfRenderers(); + unsigned int GetNumberOfRenderers(); - void SetEraseForAllRenderers(int i); - protected: - vtkRenderWindow* m_RenderWindow; + void SetEraseForAllRenderers(int i); +protected: + vtkSmartPointer m_RenderWindow; - private: +private: - /** + /** * Internally used to sort all registered renderers and to connect the with the vtkRenderWindow. * Mention that VTK Version 5 and above is rendering higher numbers in the background and VTK * Verison < 5 in the foreground. */ - void UpdateLayers(); + void UpdateLayers(); - // Layer Management - typedef std::vector< vtkSmartPointer > RendererVectorType; - RendererVectorType m_BackgroundRenderers; - RendererVectorType m_SceneRenderers; - RendererVectorType m_ForegroundRenderers; + // Layer Management + typedef std::vector< vtkSmartPointer > RendererVectorType; + RendererVectorType m_BackgroundRenderers; + RendererVectorType m_SceneRenderers; + RendererVectorType m_ForegroundRenderers; - typedef std::map,mitk::VtkLayerController*> vtkLayerControllerMapType; - static vtkLayerControllerMapType s_LayerControllerMap; + typedef std::map,mitk::VtkLayerController*> vtkLayerControllerMapType; + static vtkLayerControllerMapType s_LayerControllerMap; }; #ifdef _MSC_VER # pragma warning(pop) #endif } // Namespace MITK - - - - -#endif /* MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D */ - - +#endif /* mitkVtkLayerController_h */ diff --git a/Core/Code/DataManagement/mitkColorProperty.h b/Core/Code/DataManagement/mitkColorProperty.h index 5be0217230..69aa7c4235 100644 --- a/Core/Code/DataManagement/mitkColorProperty.h +++ b/Core/Code/DataManagement/mitkColorProperty.h @@ -1,105 +1,105 @@ /*=================================================================== 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 MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 #define MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 #include #include "mitkBaseProperty.h" #include namespace mitk { #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4522) #endif /** * @brief Color Standard RGB color typedef (float) * * Standard RGB color typedef to get rid of template argument (float). - * Color range is from 0.0f to 255.0f for each component. + * Color range is from 0.0f to 1.0f for each component. * * @ingroup Property */ typedef itk::RGBPixel< float > Color; /** * @brief The ColorProperty class RGB color property * @ingroup DataManagement * * @note If you want to apply the mitk::ColorProperty to an mitk::Image * make sure to set the mitk::RenderingModeProperty to a mode which * supports color (e.g. LEVELWINDOW_COLOR). For an example how to use * the mitk::ColorProperty see mitkImageVtkMapper2DColorTest.cpp in * Core\Code\Rendering. */ class MITK_CORE_EXPORT ColorProperty : public BaseProperty { protected: mitk::Color m_Color; ColorProperty(); ColorProperty(const ColorProperty& other); ColorProperty(const float red, const float green, const float blue); ColorProperty(const float color[3]); ColorProperty(const mitk::Color & color); public: mitkClassMacro(ColorProperty, BaseProperty) itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(ColorProperty, const float*); mitkNewMacro1Param(ColorProperty, const mitk::Color&); mitkNewMacro3Param(ColorProperty, const float, const float, const float); typedef mitk::Color ValueType; const mitk::Color & GetColor() const; const mitk::Color & GetValue() const; std::string GetValueAsString() const; void SetColor(const mitk::Color & color ); void SetValue(const mitk::Color & color ); void SetColor( float red, float green, float blue ); using BaseProperty::operator=; private: // purposely not implemented ColorProperty& operator=(const ColorProperty&); virtual itk::LightObject::Pointer InternalClone() const; virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty & property); }; #ifdef _MSC_VER # pragma warning(pop) #endif } // namespace mitk #endif /* MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 */ diff --git a/Core/Code/DataManagement/mitkLine.h b/Core/Code/DataManagement/mitkLine.h index 07a1293578..703be50113 100644 --- a/Core/Code/DataManagement/mitkLine.h +++ b/Core/Code/DataManagement/mitkLine.h @@ -1,424 +1,434 @@ /*=================================================================== 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 MITKLINE_H_HEADER_INCLUDED_C19C01E2 #define MITKLINE_H_HEADER_INCLUDED_C19C01E2 #include "mitkNumericTypes.h" #include #include #include #include namespace mitk { //##Documentation //## @brief Descibes a line //## @ingroup Geometry template class Line { public: Line() { m_Point.Fill(0); m_Direction.Fill(0); } //##Documentation //## @brief Define line by point and direction //## //## Length of direction defines the the length of the line Line( const itk::Point& point, const itk::Vector& direction ) { this->m_Point = point; this->m_Direction = direction; } //##Documentation //## @brief Get start point of the line const itk::Point& GetPoint() const { return m_Point; } //##Documentation //## @brief Get start point of the line itk::Point& GetPoint() { return m_Point; } //##Documentation //## @brief Get point on the line with parameter @a t //## //## @return m_Point+t*m_Direction const itk::Point GetPoint(TCoordRep t) const { return m_Point+m_Direction*t; } //##Documentation //## @brief Set/change start point of the line void SetPoint( const itk::Point& point1 ) { itk::Point point2; point2 = m_Point + m_Direction; m_Point = point1; m_Direction = point2.GetVectorFromOrigin() - point1.GetVectorFromOrigin(); } //##Documentation //## @brief Get the direction vector of the line const itk::Vector& GetDirection() const { return m_Direction; } //##Documentation //## @brief Get the direction vector of the line itk::Vector& GetDirection() { return m_Direction; } //##Documentation //## @brief Set the direction vector of the line void SetDirection( const itk::Vector& direction ) { m_Direction = direction; } //##Documentation //## @brief Define line by point and direction //## //## Length of direction defines the the length of the line void Set( const itk::Point& point, const itk::Vector& direction ) { this->m_Point = point; this->m_Direction = direction; } //##Documentation //## @brief Define line by two points void SetPoints( const itk::Point& point1, const itk::Point& point2 ) { this->m_Point = point1; //this->m_Direction.sub( point2, point1 ); m_Direction = point2 - point1; } //##Documentation //## @brief Set/change start point of the line void SetPoint1( const itk::Point& point1 ) { itk::Vector point2; point2 = m_Point.GetVectorFromOrigin() + m_Direction; m_Point = point1; m_Direction = point2 - point1.GetVectorFromOrigin(); } //##Documentation //## @brief Get start point of the line const itk::Point& GetPoint1() const { return m_Point; } //##Documentation //## @brief Set/change end point of the line void SetPoint2( const itk::Point& point2 ) { m_Direction = point2 - m_Point; } //##Documentation //## @brief Get end point of the line itk::Point GetPoint2() const { itk::Point point2; point2 = m_Point+m_Direction; return point2; } //##Documentation //## @brief Transform the line with a Transform void Transform(itk::Transform& transform) { m_Direction = transform.TransformVector(m_Direction); m_Point = transform.TransformPoint(m_Point); } //##Documentation //## @brief Transform the line with a matrix //## //## Only the direction will be changed, not the start point. void Transform( const itk::Matrix& matrix ) { m_Direction = matrix*m_Direction; } //##Documentation //## @brief Distance of a point from the line double Distance( const itk::Point& point ) const { itk::Vector diff; diff = Project(point)-point; return diff.GetNorm(); } //##Documentation //## @brief Project a point on the line itk::Point Project( const itk::Point& point ) const { if(m_Direction.GetNorm()==0) return this->m_Point; itk::Vector diff; diff = point-this->m_Point; itk::Vector normalizedDirection = m_Direction; normalizedDirection.Normalize(); normalizedDirection *= dot_product(diff.GetVnlVector(), normalizedDirection.GetVnlVector()); return this->m_Point + normalizedDirection; } //##Documentation //## @brief Test if a point is part of the line //## //## Length of the direction vector defines the length of the line bool IsPartOfStraightLine( const itk::Point& point ) const { if( Distance( point ) > eps ) return false; itk::Vector diff; diff = point - this->m_Point; if( diff*m_Direction < 0 ) return false; if( diff.GetSquaredNorm() <= m_Direction.GetSquaredNorm() ) return true; return false; } //##Documentation //## @brief Test if a point is part of the line (line having infinite length) bool IsPartOfLine( const itk::Point& point ) const { if ( Distance( point ) < eps ) return true; return false; } //##Documentation //## @brief Test if a lines is parallel to this line bool IsParallel( const Line& line) const { vnl_vector normal; normal = vnl_cross_3d( m_Direction.GetVnlVector(), line.GetDirection().GetVnlVector() ); if ( normal.squared_magnitude() < eps ) return true; return false; } //##Documentation //## @brief Test if a line is part of the line (line having infinite length) bool IsPartOfLine( const Line& line ) const { return ( Distance( line.GetPoint() ) < 0 ) && ( IsParallel( line ) ); } //##Documentation //## @brief Test if the two lines are identical //## //## Start point and direction and length of direction vector must be //## equal for identical lines. bool operator==( const Line& line ) const { itk::Vector diff; diff = GetPoint1()-line.GetPoint1(); if(diff.GetSquaredNorm() > eps) return false; diff = GetPoint2()-line.GetPoint2(); if(diff.GetSquaredNorm() > eps) return false; return true; } //##Documentation //## @brief Set the line by another line inline const Line& operator=( const Line& line ) { m_Point = line.GetPoint(); m_Direction = line.GetDirection(); return *this; } //##Documentation //## @brief Test if two lines are not identical //## //## \sa operator== bool operator!=( const Line& line ) const { return !((*this)==line); } //##Documentation //## @brief Calculates the intersection points of a straight line in 2D //## with a rectangle //## //## @param x1,y1,x2,y2 rectangle //## @param p,d straight line: p point on it, d direction of line //## @param s1 first intersection point (valid only if s_num>0) //## @param s2 second intersection point (valid only if s_num==2) //## @return number of intersection points (0<=s_num<=2) static int RectangleLineIntersection( TCoordRep x1, TCoordRep y1, TCoordRep x2, TCoordRep y2, itk::Point< TCoordRep, 2 > p, itk::Vector< TCoordRep, 2 > d, itk::Point< TCoordRep, 2 > &s1, itk::Point< TCoordRep, 2 > &s2 ) { int s_num; TCoordRep t; s_num=0; /*test if intersecting with the horizontal axis*/ if(fabs(d[0])>eps) { t=(x1-p[0])/d[0]; itk::Point l=p+d*t; if((l[1]>=y1) && (l[1]eps) { t=(x2-p[0])/d[0]; itk::Point l=p+d*t; if((l[1]>=y1) && (l[1]eps) { t=(y1-p[1])/d[1]; itk::Point l=p+d*t; if((l[0]>=x1) && (l[0]eps) { t=(y2-p[1])/d[1]; itk::Point l=p+d*t; if((l[0]>=x1) && (l[0]0) * \param s2 second intersection point (valid only if s_num==2) * \return number of intersection points (0<=s_num<=2) */ static int BoxLineIntersection( TCoordRep x1, TCoordRep y1, TCoordRep z1, TCoordRep x2, TCoordRep y2, TCoordRep z2, itk::Point< TCoordRep, 3 > p, itk::Vector< TCoordRep, 3 > d, itk::Point< TCoordRep, 3 > &s1, itk::Point< TCoordRep, 3 > &s2 ) { int num = 0; ScalarType box[6]; box[0] = x1; box[1] = x2; box[2] = y1; box[3] = y2; box[4] = z1; box[5] = z2; itk::Point< TCoordRep, 3 > point; int i, j; for ( i = 0; i < 6; ++i ) { j = i / 2; if ( fabs( d[j] ) > eps ) { ScalarType lambda = (box[i] - p[j]) / d[j]; point = p + d * lambda; int k = (j + 1) % 3; int l = (j + 2) % 3; - if ( (point[k] >= box[k*2]) && (point[k] <= box[k*2+1]) - && (point[l] >= box[l*2]) && (point[l] <= box[l*2+1]) ) + if ( + ( + ((point[k] >= box[k*2]) && (point[k] <= box[k*2+1])) + || ((point[k] <= box[k*2]) && (point[k] >= box[k*2+1])) + ) + && + ( + ((point[l] >= box[l*2]) && (point[l] <= box[l*2+1])) + || ((point[l] <= box[l*2]) && (point[l] >= box[l*2+1])) + ) + + ) { if ( num == 0 ) { s1 = point; } else { s2 = point; } ++num; } } } return num; } protected: itk::Point m_Point; itk::Vector m_Direction; }; typedef Line Line3D; } // namespace mitk #endif /* MITKLINE_H_HEADER_INCLUDED_C19C01E2 */ diff --git a/Core/Code/Rendering/mitkGradientBackground.cpp b/Core/Code/Rendering/mitkGradientBackground.cpp index 1cfaf63290..048d350971 100644 --- a/Core/Code/Rendering/mitkGradientBackground.cpp +++ b/Core/Code/Rendering/mitkGradientBackground.cpp @@ -1,239 +1,134 @@ /*=================================================================== 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 "mitkGradientBackground.h" - #include "mitkVtkLayerController.h" - #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - mitk::GradientBackground::GradientBackground() { m_RenderWindow = NULL; - m_Renderer = vtkRenderer::New(); - m_Actor = vtkActor::New(); - m_Mapper = vtkPolyDataMapper::New(); - m_Lut = vtkLookupTable::New(); - m_Plane = vtkPolyData::New(); - - vtkPoints* points = vtkPoints::New( ); - points->InsertPoint(0,-10,0,0); - points->InsertPoint(1,-10,1,0); - points->InsertPoint(2,10,1,0); - points->InsertPoint(3,10,0,0); - - vtkCellArray* cellArray = vtkCellArray::New(); - cellArray->InsertNextCell(4); - cellArray->InsertCellPoint(0); - cellArray->InsertCellPoint(1); - cellArray->InsertCellPoint(2); - cellArray->InsertCellPoint(3); - - vtkUnsignedIntArray* data = vtkUnsignedIntArray::New(); - data->InsertTuple1(0,1); - data->InsertTuple1(1,0); - data->InsertTuple1(2,0); - data->InsertTuple1(3,1); - - m_Plane->SetPoints( points ); - m_Plane->SetPolys( cellArray ); - m_Plane->GetPointData()->SetScalars( data ); - - points->Delete(); - cellArray->Delete(); - data->Delete(); - - m_Lut->SetNumberOfColors( 2 ); - m_Lut->Build(); - m_Lut->SetTableValue( m_Lut->GetIndex(0), 1, 1, 1 ); - m_Lut->SetTableValue( m_Lut->GetIndex(1), 0, 0, 0 ); - - m_Mapper->SetInputData( m_Plane ); - m_Mapper->SetLookupTable( m_Lut ); - - //m_Mapper->ImmediateModeRenderingOn(); - - m_Actor->SetMapper( m_Mapper ); - - m_Renderer->AddActor( m_Actor ); + m_Renderer = vtkSmartPointer::New(); m_Renderer->InteractiveOff(); - m_Renderer->GetActiveCamera()->ParallelProjectionOn(); - m_Renderer->ResetCamera(); - m_Renderer->GetActiveCamera()->SetParallelScale(0.5); } mitk::GradientBackground::~GradientBackground() { if ( m_RenderWindow != NULL ) if ( this->IsEnabled() ) this->Disable(); - - if ( m_Plane != NULL ) - m_Plane->Delete(); - - if( m_Lut != NULL ) - m_Lut->Delete(); - - if ( m_Mapper != NULL ) - m_Mapper->Delete(); - - if ( m_Actor!=NULL ) - m_Actor->Delete(); - - if ( m_Renderer != NULL ) - m_Renderer->Delete(); } /** * Sets the renderwindow, in which the gradient background * will be shown. Make sure, you have called this function * before calling Enable() */ -void mitk::GradientBackground::SetRenderWindow( vtkRenderWindow * renderWindow ) +void mitk::GradientBackground::SetRenderWindow(vtkSmartPointer renderWindow ) { m_RenderWindow = renderWindow; } /** * Returns the vtkRenderWindow, which is used * for displaying the gradient background */ -vtkRenderWindow* mitk::GradientBackground::GetRenderWindow() +vtkSmartPointer mitk::GradientBackground::GetRenderWindow() { return m_RenderWindow; } /** * Returns the renderer responsible for * rendering the color gradient into the * vtkRenderWindow */ -vtkRenderer* mitk::GradientBackground::GetVtkRenderer() +vtkSmartPointer mitk::GradientBackground::GetVtkRenderer() { return m_Renderer; } -/** - * Returns the actor associated with the color gradient - */ -vtkActor* mitk::GradientBackground::GetActor() -{ - return m_Actor; -} - -/** - * Returns the mapper associated with the color - * gradient. - */ -vtkPolyDataMapper* mitk::GradientBackground::GetMapper() -{ - return m_Mapper; -} - - /** * Sets the gradient colors. The gradient * will smoothly fade from color1 to color2 */ void mitk::GradientBackground::SetGradientColors( double r1, double g1, double b1, double r2, double g2, double b2 ) { - m_Lut->SetTableValue( m_Lut->GetIndex(0), r1, g1, b1 ); - m_Lut->SetTableValue( m_Lut->GetIndex(1), r2, g2, b2 ); + this->SetLowerColor(r1, g1, b1); + this->SetUpperColor(r2, g2, b2); } +void mitk::GradientBackground::SetGradientColors(mitk::Color upper, mitk::Color lower) +{ + this->SetGradientColors(upper[0],upper[1],upper[2],lower[0],lower[1],lower[2]); +} void mitk::GradientBackground::SetUpperColor(double r, double g, double b ) { - m_Lut->SetTableValue( m_Lut->GetIndex(0), r, g, b ); + m_Renderer->SetBackground(r,g,b); } - void mitk::GradientBackground::SetLowerColor(double r, double g, double b ) { - m_Lut->SetTableValue( m_Lut->GetIndex(1), r, g, b ); + m_Renderer->SetBackground2(r,g,b); +} + +void mitk::GradientBackground::SetUpperColor(mitk::Color upper) +{ + this->SetUpperColor(upper[0],upper[1],upper[2]); } +void mitk::GradientBackground::SetLowerColor(mitk::Color lower) +{ + this->SetLowerColor(lower[0],lower[1],lower[2]); +} /** * Enables drawing of the color gradient background. * If you want to disable it, call the Disable() function. */ void mitk::GradientBackground::Enable() { + m_Renderer->GradientBackgroundOn(); mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertBackgroundRenderer(m_Renderer,true); } /** * Disables drawing of the color gradient background. * If you want to enable it, call the Enable() function. */ void mitk::GradientBackground::Disable() { if ( this->IsEnabled() ) { + m_Renderer->GradientBackgroundOff(); mitk::VtkLayerController::GetInstance(m_RenderWindow)->RemoveRenderer(m_Renderer); } } - - /** * Checks, if the gradient background is currently * enabled (visible) */ bool mitk::GradientBackground::IsEnabled() { - if ( m_RenderWindow == NULL ) - return false; - else - return ( mitk::VtkLayerController::GetInstance(m_RenderWindow)->IsRendererInserted(m_Renderer)); -} - -void mitk::GradientBackground::SetRequestedRegionToLargestPossibleRegion() -{ - //nothing to do -} - -bool mitk::GradientBackground::RequestedRegionIsOutsideOfTheBufferedRegion() -{ + if ( m_RenderWindow == NULL ) return false; + else + return ( mitk::VtkLayerController::GetInstance(m_RenderWindow)->IsRendererInserted(m_Renderer)); } - -bool mitk::GradientBackground::VerifyRequestedRegion() -{ - return true; -} - -void mitk::GradientBackground::SetRequestedRegion( const itk::DataObject*) -{ - //nothing to do -} - diff --git a/Core/Code/Rendering/mitkGradientBackground.h b/Core/Code/Rendering/mitkGradientBackground.h index 1b56ef0ff8..13a82dc4eb 100644 --- a/Core/Code/Rendering/mitkGradientBackground.h +++ b/Core/Code/Rendering/mitkGradientBackground.h @@ -1,160 +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 _vtk_Gradient_Background_h_ -#define _vtk_Gradient_Background_h_ +#ifndef mitkGradientBackground_h +#define mitkGradientBackground_h - -#include +#include +#include +#include +#include class vtkRenderer; -class vtkMapper; -class vtkActor; -class vtkPolyDataMapper; -class vtkLookupTable; -class vtkPolyData; class vtkRenderWindow; namespace mitk { class RenderWindow; /** * Displays a color gradient in the background * of a vtkRenderWindow. * The gradient ist faked by displaying a non-interactable * smoothly shaded plane in a separate layer behind the * scene. After setting the renderwindow, the gradient may be * activated by calling Enable() */ -class MITK_CORE_EXPORT GradientBackground : public BaseData +class MITK_CORE_EXPORT GradientBackground : public itk::Object { public: - mitkClassMacro( GradientBackground, BaseData ); + mitkClassMacro( GradientBackground, itk::Object ); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * Sets the renderwindow, in which the gradient background * will be shown. Make sure, you have called this function * before calling Enable() */ - virtual void SetRenderWindow( vtkRenderWindow* renderWindow ); + virtual void SetRenderWindow( vtkSmartPointer renderWindow ); /** * Returns the vtkRenderWindow, which is used * for displaying the gradient background */ - virtual vtkRenderWindow* GetRenderWindow(); + virtual vtkSmartPointer GetRenderWindow(); /** * Returns the renderer responsible for * rendering the color gradient into the * vtkRenderWindow */ - virtual vtkRenderer* GetVtkRenderer(); - - /** - * Returns the actor associated with the color gradient - */ - virtual vtkActor* GetActor(); - - /** - * Returns the mapper associated with the color - * gradient. - */ - virtual vtkPolyDataMapper* GetMapper(); + virtual vtkSmartPointer GetVtkRenderer(); /** * Sets the gradient colors. The gradient * will smoothly fade from color1 to color2 */ - virtual void SetGradientColors( double r1, double g1, double b1, double r2, double g2, double b2); + virtual void SetGradientColors(double r1, double g1, double b1, double r2, double g2, double b2); + virtual void SetGradientColors(Color upper, Color lower); virtual void SetUpperColor(double r, double g, double b ); virtual void SetLowerColor(double r, double g, double b ); + virtual void SetUpperColor(Color upper); + virtual void SetLowerColor(Color lower); /** * Enables drawing of the color gradient background. * If you want to disable it, call the Disable() function. */ virtual void Enable(); /** * Disables drawing of the color gradient background. * If you want to enable it, call the Enable() function. */ virtual void Disable(); /** * Checks, if the gradient background is currently * enabled (visible) */ virtual bool IsEnabled(); - /** - * Empty implementation, since the GradientBackground doesn't - * support the requested region concept - */ - virtual void SetRequestedRegionToLargestPossibleRegion(); - - /** - * Empty implementation, since the GradientBackground doesn't - * support the requested region concept - */ - virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); - - /** - * Empty implementation, since the GradientBackground doesn't - * support the requested region concept - */ - virtual bool VerifyRequestedRegion(); - - /** - * Empty implementation, since the GradientBackground doesn't - * support the requested region concept - */ - virtual void SetRequestedRegion( const itk::DataObject*); - protected: - /** - * Constructor - */ GradientBackground(); - - /** - * Destructor - */ ~GradientBackground(); - vtkRenderWindow* m_RenderWindow; + vtkSmartPointer m_RenderWindow; - vtkRenderer* m_Renderer; - - vtkActor* m_Actor; - - vtkPolyDataMapper* m_Mapper; - - vtkLookupTable* m_Lut; - - vtkPolyData* m_Plane; + vtkSmartPointer m_Renderer; }; - } //end of namespace mitk -#endif - - +#endif //mitkGradientBackground_h diff --git a/Core/Code/Rendering/mitkOverlay.cpp b/Core/Code/Rendering/mitkOverlay.cpp index 7c714b386d..13581ad77e 100644 --- a/Core/Code/Rendering/mitkOverlay.cpp +++ b/Core/Code/Rendering/mitkOverlay.cpp @@ -1,315 +1,341 @@ /*=================================================================== 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)); + Modified(); } void mitk::Overlay::SetBoolProperty( const std::string& propertyKey, bool boolValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); + Modified(); } void mitk::Overlay::SetFloatProperty( const std::string& propertyKey, float floatValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); + Modified(); } void mitk::Overlay::SetStringProperty( const std::string& propertyKey, const std::string& stringValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); + Modified(); } 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 = 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; } mitk::Overlay::Bounds mitk::Overlay::GetBoundsOnDisplay(mitk::BaseRenderer*) const { mitk::Overlay::Bounds bounds; bounds.Position[0] = bounds.Position[1] = bounds.Size[0] = bounds.Size[1] = 0; return bounds; } void mitk::Overlay::SetBoundsOnDisplay(mitk::BaseRenderer*, const mitk::Overlay::Bounds&) { } void mitk::Overlay::SetForceInForeground(bool forceForeground) { m_ForceInForeground = forceForeground; } bool mitk::Overlay::IsForceInForeground() const { return m_ForceInForeground; } +mitk::Point2D mitk::Overlay::TransformDisplayPointToViewport( mitk::Point2D point , mitk::BaseRenderer* renderer) +{ + double* iViewport = renderer->GetVtkRenderer()->GetViewport(); + + const mitk::DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry(); + + float displayGeometryWidth = displayGeometry->GetSizeInDisplayUnits()[0]; + float displayGeometryHeight = displayGeometry->GetSizeInDisplayUnits()[1]; + + float viewportWidth = (iViewport[2]-iViewport[0]) * displayGeometryWidth; + float viewportHeight = (iViewport[3]-iViewport[1]) * displayGeometryHeight; // seemingly right + + float zoom = (iViewport[3]-iViewport[1]); + + point[0] += + 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight + - 0.5 * (displayGeometryWidth - displayGeometryHeight); + + point[0] *= zoom; + point[1] *= zoom; + return point; +} diff --git a/Core/Code/Rendering/mitkOverlay.h b/Core/Code/Rendering/mitkOverlay.h index 7c2c875088..b5f39e41c0 100644 --- a/Core/Code/Rendering/mitkOverlay.h +++ b/Core/Code/Rendering/mitkOverlay.h @@ -1,440 +1,442 @@ /*=================================================================== 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 Adds the overlay to the specified renderer. Update Overlay should be called soon in order to apply all properties*/ virtual void AddToRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer) = 0; /** \brief Removes the overlay from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Removes the overlay from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer) = 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; /** \brief Sets position and size of the overlay on the display.*/ virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds&); void SetForceInForeground(bool forceForeground); bool IsForceInForeground() const; mitkClassMacro(Overlay, itk::Object); + static mitk::Point2D TransformDisplayPointToViewport(mitk::Point2D point, mitk::BaseRenderer *renderer); + 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; private: /** \brief render this overlay on a foreground renderer */ bool m_ForceInForeground; /** \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/mitkPlaneGeometryDataMapper2D.cpp b/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.cpp index 1b05a7cdf1..2057bad2dc 100644 --- a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.cpp +++ b/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.cpp @@ -1,672 +1,402 @@ /*=================================================================== 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 "mitkGL.h" #include "mitkPlaneGeometryDataMapper2D.h" -#include "mitkBaseRenderer.h" -#include "mitkPlaneGeometry.h" -#include "mitkColorProperty.h" -#include "mitkProperties.h" -#include "mitkSmartPointerProperty.h" -#include "mitkPlaneOrientationProperty.h" -#include "mitkPlaneGeometryDataToSurfaceFilter.h" -#include "mitkSurfaceGLMapper2D.h" -#include "mitkLine.h" -#include "mitkNodePredicateDataType.h" -#include "mitkSlicedGeometry3D.h" -#include "mitkResliceMethodProperty.h" -#include "mitkAbstractTransformGeometry.h" +//mitk includes +#include "mitkVtkPropRenderer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//vtk includes +#include +#include +#include +#include +#include +#include +#include + +mitk::PlaneGeometryDataMapper2D::AllInstancesContainer mitk::PlaneGeometryDataMapper2D::s_AllInstances; + +// input for this mapper ( = PlaneGeometryData) +const mitk::PlaneGeometryData* mitk::PlaneGeometryDataMapper2D::GetInput() const +{ + return static_cast< PlaneGeometryData * >(GetDataNode()->GetData()); +} mitk::PlaneGeometryDataMapper2D::PlaneGeometryDataMapper2D() -: m_SurfaceMapper( NULL ), m_DataStorage(NULL), m_ParentNode(NULL), - m_OtherPlaneGeometries(), m_RenderOrientationArrows( false ), - m_ArrowOrientationPositive( true ) + : m_RenderOrientationArrows( false ), + m_ArrowOrientationPositive( true ), + m_DepthValue(1.0f) { + s_AllInstances.insert(this); } - mitk::PlaneGeometryDataMapper2D::~PlaneGeometryDataMapper2D() { + s_AllInstances.erase(this); } - -const mitk::PlaneGeometryData* mitk::PlaneGeometryDataMapper2D::GetInput(void) +vtkProp* mitk::PlaneGeometryDataMapper2D::GetVtkProp(mitk::BaseRenderer * renderer) { - return static_cast ( GetDataNode()->GetData() ); + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + return ls->m_CrosshairAssembly; } -void mitk::PlaneGeometryDataMapper2D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) +void mitk::PlaneGeometryDataMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); - if(!ls->IsGenerateDataRequired(renderer,this,GetDataNode())) - return; + // The PlaneGeometryDataMapper2D mapper is special in that the rendering of + // OTHER PlaneGeometryDatas affects how we render THIS PlaneGeometryData + // (for the gap at the point where they intersect). A change in any of the + // other PlaneGeometryData nodes could mean that we render ourself + // differently, so we check for that here. + bool generateDataRequired = false; + for (AllInstancesContainer::iterator it = s_AllInstances.begin(); + it != s_AllInstances.end(); + ++it) + { + generateDataRequired = ls->IsGenerateDataRequired(renderer, this, (*it)->GetDataNode()); + if (generateDataRequired) break; + } ls->UpdateGenerateDataTime(); - // collect all PlaneGeometryDatas accessible from the DataStorage + // Collect all other PlaneGeometryDatas that are being mapped by this mapper m_OtherPlaneGeometries.clear(); - if (m_DataStorage.IsNull()) - return; - mitk::NodePredicateDataType::Pointer p = mitk::NodePredicateDataType::New("PlaneGeometryData"); - mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetDerivations(m_ParentNode, p, false); - for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) + for (AllInstancesContainer::iterator it = s_AllInstances.begin(); it != s_AllInstances.end(); ++it) { - if(it->Value().IsNull()) - continue; + Self *otherInstance = *it; + + // Skip ourself + if (otherInstance == this) continue; + + mitk::DataNode *otherNode = otherInstance->GetDataNode(); + if (!otherNode) continue; - BaseData* data = it->Value()->GetData(); - if (data == NULL) - continue; + // Skip other PlaneGeometryData nodes that are not visible on this renderer + if (!otherNode->IsVisible(renderer)) continue; - PlaneGeometryData* geometry2dData = dynamic_cast(data); - if(geometry2dData == NULL) - continue; + PlaneGeometryData* otherData = dynamic_cast(otherNode->GetData()); + if (!otherData) continue; - PlaneGeometry* planegeometry = dynamic_cast(geometry2dData->GetPlaneGeometry()); - if (planegeometry != NULL && dynamic_cast(geometry2dData->GetPlaneGeometry())==NULL) - m_OtherPlaneGeometries.push_back(it->Value()); + PlaneGeometry* otherGeometry = dynamic_cast(otherData->GetPlaneGeometry()); + if ( otherGeometry && !dynamic_cast(otherData->GetPlaneGeometry()) ) + { + m_OtherPlaneGeometries.push_back(otherNode); + } } -} + CreateVtkCrosshair(renderer); + + ApplyAllProperties(renderer); +} -void mitk::PlaneGeometryDataMapper2D::Paint(BaseRenderer *renderer) +void mitk::PlaneGeometryDataMapper2D::CreateVtkCrosshair(mitk::BaseRenderer *renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if(!visible) return; PlaneGeometryData::Pointer input = const_cast< PlaneGeometryData * >(this->GetInput()); + mitk::DataNode* geometryDataNode = renderer->GetCurrentWorldPlaneGeometryNode(); + const PlaneGeometryData* rendererWorldPlaneGeometryData = dynamic_cast< PlaneGeometryData * >(geometryDataNode->GetData()); // intersecting with ourself? - if ( input.IsNull() || (this->GetInput()->GetPlaneGeometry() == - renderer->GetCurrentWorldPlaneGeometry()) ) + if ( input.IsNull() || input.GetPointer() == rendererWorldPlaneGeometryData) { - return; // do nothing! + return; //nothing to do in this case } - const PlaneGeometry *inputPlaneGeometry = - dynamic_cast< const PlaneGeometry * >( input->GetPlaneGeometry() ); + const PlaneGeometry *inputPlaneGeometry = dynamic_cast< const PlaneGeometry * >( input->GetPlaneGeometry() ); - const PlaneGeometry *worldPlaneGeometry = - dynamic_cast< const PlaneGeometry* >( - renderer->GetCurrentWorldPlaneGeometry() ); + const PlaneGeometry* worldPlaneGeometry = dynamic_cast< const PlaneGeometry* >( + rendererWorldPlaneGeometryData->GetPlaneGeometry() ); - if ( worldPlaneGeometry && dynamic_cast(renderer->GetCurrentWorldPlaneGeometry())==NULL - && inputPlaneGeometry && dynamic_cast(input->GetPlaneGeometry() )==NULL - && inputPlaneGeometry->GetReferenceGeometry() ) + if ( worldPlaneGeometry && dynamic_cast(worldPlaneGeometry)==NULL + && inputPlaneGeometry && dynamic_cast(input->GetPlaneGeometry() )==NULL + && inputPlaneGeometry->GetReferenceGeometry() ) { - DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); - assert( displayGeometry ); - - const BaseGeometry *referenceGeometry = - inputPlaneGeometry->GetReferenceGeometry(); + const BaseGeometry *referenceGeometry = inputPlaneGeometry->GetReferenceGeometry(); // calculate intersection of the plane data with the border of the // world geometry rectangle - Point2D lineFrom, lineTo; - - const Geometry3D::TransformType *transform = dynamic_cast< const Geometry3D::TransformType * >( - referenceGeometry->GetIndexToWorldTransform() ); - - Geometry3D::TransformType::Pointer inverseTransform = Geometry3D::TransformType::New(); - transform->GetInverse( inverseTransform ); + Point3D point1, point2; - Line3D crossLine, otherCrossLine; + Line3D crossLine; // Calculate the intersection line of the input plane with the world plane - if ( worldPlaneGeometry->IntersectionLine( - inputPlaneGeometry, crossLine ) ) + if ( worldPlaneGeometry->IntersectionLine( inputPlaneGeometry, crossLine ) ) { - BoundingBox::PointType boundingBoxMin, boundingBoxMax; - boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum(); - boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum(); - if(referenceGeometry->GetImageGeometry()) - { - for(unsigned int i = 0; i < 3; ++i) - { - boundingBoxMin[i]-=0.5; - boundingBoxMax[i]-=0.5; - } - } - - crossLine.Transform( *inverseTransform ); - Point3D point1, point2; + Point3D boundingBoxMin, boundingBoxMax; + boundingBoxMin = referenceGeometry->GetCornerPoint(0); + boundingBoxMax = referenceGeometry->GetCornerPoint(7); // Then, clip this line with the (transformed) bounding box of the // reference geometry. - if ( crossLine.BoxLineIntersection( - boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], - boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], - crossLine.GetPoint(), crossLine.GetDirection(), - point1, point2 ) == 2 ) - { - // Transform the resulting line start and end points into display - // coordinates. - worldPlaneGeometry->Map( - transform->TransformPoint( point1 ), lineFrom ); - worldPlaneGeometry->Map( - transform->TransformPoint( point2 ), lineTo ); - - Line< ScalarType, 2 > mainLine, otherLine; - Line< ScalarType, 2 > primaryHelperLine, secondaryHelperLine; - mainLine.SetPoints( lineFrom, lineTo ); - primaryHelperLine.SetPoints( lineFrom, lineTo ); - secondaryHelperLine.SetPoints( lineFrom, lineTo ); - - displayGeometry->WorldToDisplay( lineFrom, lineFrom ); - displayGeometry->WorldToDisplay( lineTo, lineTo ); - - ScalarType lengthInDisplayUnits = (lineTo - lineFrom).GetNorm(); - - Vector2D mainLineDirectionOrthogonal; - mainLineDirectionOrthogonal[0] = -mainLine.GetDirection()[1]; - mainLineDirectionOrthogonal[1] = mainLine.GetDirection()[0]; - - - // lineParams stores the individual segments of the line, which are - // separated by a gap each (to mark the intersection with another - // displayed line) - std::vector< ScalarType > mainLineParams; - std::vector< ScalarType > primaryHelperLineParams; - std::vector< ScalarType > secondaryHelperLineParams; - mainLineParams.reserve( m_OtherPlaneGeometries.size() + 2 ); - mainLineParams.push_back( 0.0 ); - mainLineParams.push_back( 1.0 ); - - primaryHelperLineParams.reserve( m_OtherPlaneGeometries.size() + 2 ); - primaryHelperLineParams.push_back( 0.0 ); - primaryHelperLineParams.push_back( 1.0 ); - - secondaryHelperLineParams.reserve( m_OtherPlaneGeometries.size() + 2 ); - secondaryHelperLineParams.push_back( 0.0 ); - secondaryHelperLineParams.push_back( 1.0 ); - - - // Now iterate through all other lines displayed in this window and - // calculate the positions of intersection with the line to be - // rendered; these positions will be stored in lineParams to form a - // gap afterwards. - NodesVectorType::iterator otherPlanesIt = m_OtherPlaneGeometries.begin(); - NodesVectorType::iterator otherPlanesEnd = m_OtherPlaneGeometries.end(); - - DataNode* dataNodeOfInputPlaneGeometry = NULL; - - // Now we have to find the DataNode that contains the inputPlaneGeometry - // in order to determine the state of the thick-slice rendering - while ( otherPlanesIt != otherPlanesEnd ) - { - PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( - static_cast< PlaneGeometryData * >( - (*otherPlanesIt)->GetData() )->GetPlaneGeometry() ); - - // if we have found the correct node - if ( (otherPlane == inputPlaneGeometry) - && worldPlaneGeometry->IntersectionLine( - otherPlane, otherCrossLine ) ) - { - dataNodeOfInputPlaneGeometry = (*otherPlanesIt); -// if( dataNodeOfInputPlaneGeometry ) -// { -// mainLineThickSlicesMode = this->DetermineThickSliceMode(dataNodeOfInputPlaneGeometry, mainLineThickSlicesNum); -// } - break; - } - otherPlanesIt++; - } + crossLine.BoxLineIntersection( + boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], + boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], + crossLine.GetPoint(), crossLine.GetDirection(), + point1, point2 ); - // if we did not find a dataNode for the inputPlaneGeometry there is nothing we can do from here - if ( dataNodeOfInputPlaneGeometry == NULL ) - return; + crossLine.SetPoints(point1,point2); - // Determine if we should draw the area covered by the thick slicing, default is false. - // This will also show the area of slices that do not have thick slice mode enabled - bool showAreaOfThickSlicing = false; - dataNodeOfInputPlaneGeometry->GetBoolProperty( "reslice.thickslices.showarea", showAreaOfThickSlicing ); + vtkSmartPointer lines = vtkSmartPointer::New(); + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer linesPolyData = vtkSmartPointer::New(); - // get the normal of the inputPlaneGeometry - Vector3D normal = inputPlaneGeometry->GetNormal(); - // determine the pixelSpacing in that direction - double thickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); - IntProperty *intProperty=0; - if( dataNodeOfInputPlaneGeometry->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) - thickSliceDistance *= intProperty->GetValue()+0.5; - else - showAreaOfThickSlicing = false; + // Now iterate through all other lines displayed in this window and + // calculate the positions of intersection with the line to be + // rendered; these positions will be stored in lineParams to form a + // gap afterwards. + NodesVectorType::iterator otherPlanesIt = m_OtherPlaneGeometries.begin(); + NodesVectorType::iterator otherPlanesEnd = m_OtherPlaneGeometries.end(); - // not the nicest place to do it, but we have the width of the visible bloc in MM here - // so we store it in this fancy property - dataNodeOfInputPlaneGeometry->SetFloatProperty( "reslice.thickslices.sizeinmm", thickSliceDistance*2 ); + std::vector intersections; - if ( showAreaOfThickSlicing ) - { - // vectorToHelperLine defines how to reach the helperLine from the mainLine - Vector2D vectorToHelperLine; - vectorToHelperLine = mainLineDirectionOrthogonal; - vectorToHelperLine.Normalize(); - // got the right direction, so we multiply the width - vectorToHelperLine *= thickSliceDistance; - - // and create the corresponding points - primaryHelperLine.SetPoints( primaryHelperLine.GetPoint1() - vectorToHelperLine, - primaryHelperLine.GetPoint2() - vectorToHelperLine ); - - secondaryHelperLine.SetPoints( secondaryHelperLine.GetPoint1() + vectorToHelperLine, - secondaryHelperLine.GetPoint2() + vectorToHelperLine ); - } + intersections.push_back(point1); + otherPlanesIt = m_OtherPlaneGeometries.begin(); + int gapsize = 32; + this->GetDataNode()->GetPropertyValue( "Crosshair.Gap Size",gapsize, NULL ); - //int otherLineThickSlicesMode = 0; - int otherLineThickSlicesNum = 0; - // by default, there is no gap for the helper lines - ScalarType gapSize = 0.0; + ScalarType lineLength = point1.EuclideanDistanceTo(point2); + DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); - otherPlanesIt = m_OtherPlaneGeometries.begin(); - while ( otherPlanesIt != otherPlanesEnd ) - { - PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( - static_cast< PlaneGeometryData * >( - (*otherPlanesIt)->GetData() )->GetPlaneGeometry() ); - - - // Just as with the original line, calculate the intersection with - // the world geometry... - if ( (otherPlane != inputPlaneGeometry) - && worldPlaneGeometry->IntersectionLine( - otherPlane, otherCrossLine ) ) - { - //otherLineThickSlicesMode = this->DetermineThickSliceMode((*otherPlanesIt), otherLineThickSlicesNum); - Vector3D normal = otherPlane->GetNormal(); - - double otherLineThickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); - otherLineThickSliceDistance *= (otherLineThickSlicesNum)*2; - - Point2D otherLineFrom, otherLineTo; - - // ... and clip the resulting line segment with the reference - // geometry bounding box. - otherCrossLine.Transform( *inverseTransform ); - if ( otherCrossLine.BoxLineIntersection( - boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], - boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], - otherCrossLine.GetPoint(), otherCrossLine.GetDirection(), - point1, point2 ) == 2 ) - { - worldPlaneGeometry->Map( - transform->TransformPoint( point1 ), otherLineFrom ); - worldPlaneGeometry->Map( - transform->TransformPoint( point2 ), otherLineTo ); - - otherLine.SetPoints( otherLineFrom, otherLineTo ); - - // then we have to determine the gap position of the main line - // by finding the position at which the two lines cross - this->DetermineParametricCrossPositions( mainLine, otherLine, mainLineParams ); - - - // if the other line is also in thick slice mode, we have to determine the - // gapsize considering the width of that other line and the spacing in its direction - if ( showAreaOfThickSlicing ) - { - Vector2D otherLineDirection = otherLine.GetDirection(); - otherLineDirection.Normalize(); - mainLineDirectionOrthogonal.Normalize(); - - // determine the gapsize - gapSize = fabs( otherLineThickSliceDistance / ( otherLineDirection*mainLineDirectionOrthogonal ) ); - gapSize = gapSize / displayGeometry->GetScaleFactorMMPerDisplayUnit(); - - // determine the gap positions for the helper lines as well - this->DetermineParametricCrossPositions( primaryHelperLine, otherLine, primaryHelperLineParams ); - this->DetermineParametricCrossPositions( secondaryHelperLine, otherLine, secondaryHelperLineParams ); - } - } - } - ++otherPlanesIt; - } + ScalarType gapinmm = gapsize * displayGeometry->GetScaleFactorMMPerDisplayUnit(); + + float gapSizeParam = gapinmm / lineLength; - // If we have to draw the helperlines, the mainline will be drawn as a dashed line - // with a fixed gapsize of 10 pixels - this->DrawLine(renderer, - lengthInDisplayUnits, - mainLine, - mainLineParams, - inputPlaneGeometry, - showAreaOfThickSlicing, - 10.0 - ); - - - // If drawn, the helperlines are drawn as a solid line. The gapsize depends on the - // width of the crossed line. - if ( showAreaOfThickSlicing ) + while ( otherPlanesIt != otherPlanesEnd ) + { + PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( + static_cast< PlaneGeometryData * >((*otherPlanesIt)->GetData() )->GetPlaneGeometry() ); + + if (otherPlane != inputPlaneGeometry && otherPlane != worldPlaneGeometry) { - this->DrawLine(renderer, - lengthInDisplayUnits, - primaryHelperLine, - primaryHelperLineParams, - inputPlaneGeometry, - false, - gapSize - ); - - this->DrawLine(renderer, - lengthInDisplayUnits, - secondaryHelperLine, - secondaryHelperLineParams, - inputPlaneGeometry, - false, - gapSize - ); + Point3D planeIntersection; + otherPlane->IntersectionPoint(crossLine,planeIntersection); + ScalarType sectionLength = point1.EuclideanDistanceTo(planeIntersection); + ScalarType lineValue = sectionLength/lineLength; + if(lineValue-gapSizeParam > 0.0) + intersections.push_back(crossLine.GetPoint(lineValue-gapSizeParam)); + else intersections.pop_back(); + if(lineValue+gapSizeParam < 1.0) + intersections.push_back(crossLine.GetPoint(lineValue+gapSizeParam)); } + ++otherPlanesIt; } - } - } - else - { - PlaneGeometryDataToSurfaceFilter::Pointer surfaceCreator; - SmartPointerProperty::Pointer surfacecreatorprop; - surfacecreatorprop = dynamic_cast< SmartPointerProperty * >( - GetDataNode()->GetProperty( - "surfacegeometry", renderer)); - - if( (surfacecreatorprop.IsNull()) || - (surfacecreatorprop->GetSmartPointer().IsNull()) || - ((surfaceCreator = dynamic_cast< PlaneGeometryDataToSurfaceFilter * >( - surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull()) - ) - { - surfaceCreator = PlaneGeometryDataToSurfaceFilter::New(); - surfacecreatorprop = SmartPointerProperty::New(surfaceCreator); - surfaceCreator->PlaceByGeometryOn(); - GetDataNode()->SetProperty( "surfacegeometry", surfacecreatorprop ); - } + if(intersections.size()%2 == 1) + intersections.push_back(point2); - surfaceCreator->SetInput( input ); - - // Clip the PlaneGeometry with the reference geometry bounds (if available) - if ( input->GetPlaneGeometry()->HasReferenceGeometry() ) - { - surfaceCreator->SetBoundingBox( - input->GetPlaneGeometry()->GetReferenceGeometry()->GetBoundingBox() - ); - } - - int res; - bool usegeometryparametricbounds = true; - if ( GetDataNode()->GetIntProperty("xresolution", res, renderer)) - { - surfaceCreator->SetXResolution(res); - usegeometryparametricbounds=false; - } - if (GetDataNode()->GetIntProperty("yresolution", res, renderer)) - { - surfaceCreator->SetYResolution(res); - usegeometryparametricbounds=false; - } - surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds); - - // Calculate the surface of the PlaneGeometry - surfaceCreator->Update(); - - if (m_SurfaceMapper.IsNull()) - { - m_SurfaceMapper=SurfaceGLMapper2D::New(); - } - m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput()); - m_SurfaceMapper->SetDataNode(GetDataNode()); - - m_SurfaceMapper->Paint(renderer); - } -} - -void mitk::PlaneGeometryDataMapper2D::DrawOrientationArrow( mitk::Point2D &outerPoint, mitk::Point2D &innerPoint, - const mitk::PlaneGeometry *planeGeometry, - const mitk::PlaneGeometry *rendererPlaneGeometry, - const mitk::DisplayGeometry *displayGeometry, - bool positiveOrientation ) -{ - // Draw arrows to indicate plane orientation - // Vector along line - Vector2D v1 = innerPoint - outerPoint; - v1.Normalize(); - v1 *= 7.0; - - // Orthogonal vector - Vector2D v2; - v2[0] = v1[1]; - v2[1] = -v1[0]; - - // Calculate triangle tip for one side and project it back into world - // coordinates to determine whether it is above or below the plane - Point2D worldPoint2D; - Point3D worldPoint; - displayGeometry->DisplayToWorld( outerPoint + v1 + v2, worldPoint2D ); - rendererPlaneGeometry->Map( worldPoint2D, worldPoint ); - - // Initialize remaining triangle coordinates accordingly - // (above/below state is XOR'ed with orientation flag) - Point2D p1 = outerPoint + v1 * 2.0; - Point2D p2 = outerPoint + v1 - + ((positiveOrientation ^ planeGeometry->IsAbove( worldPoint )) - ? v2 : -v2); - - // Draw the arrow (triangle) - glBegin( GL_TRIANGLES ); - glVertex2f( outerPoint[0], outerPoint[1] ); - glVertex2f( p1[0], p1[1] ); - glVertex2f( p2[0], p2[1] ); - glEnd(); -} - - -void mitk::PlaneGeometryDataMapper2D::ApplyAllProperties( BaseRenderer *renderer ) -{ - Superclass::ApplyColorAndOpacityProperties(renderer); + if(intersections.empty()) + { + this->DrawLine(point1,point2,lines,points); + } + else + for(unsigned int i = 0 ; i< intersections.size()-1 ; i+=2) + { + this->DrawLine(intersections[i],intersections[i+1],lines,points); + } - PlaneOrientationProperty* decorationProperty; - this->GetDataNode()->GetProperty( decorationProperty, "decoration", renderer ); - if ( decorationProperty != NULL ) - { - if ( decorationProperty->GetPlaneDecoration() == - PlaneOrientationProperty::PLANE_DECORATION_POSITIVE_ORIENTATION ) - { - m_RenderOrientationArrows = true; - m_ArrowOrientationPositive = true; - } - else if ( decorationProperty->GetPlaneDecoration() == - PlaneOrientationProperty::PLANE_DECORATION_NEGATIVE_ORIENTATION ) - { - m_RenderOrientationArrows = true; - m_ArrowOrientationPositive = false; - } - else - { - m_RenderOrientationArrows = false; - } - } -} + // Add the points to the dataset + linesPolyData->SetPoints(points); + // Add the lines to the dataset + linesPolyData->SetLines(lines); -void mitk::PlaneGeometryDataMapper2D::SetDatastorageAndGeometryBaseNode( mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent ) -{ - if (ds.IsNotNull()) - { - m_DataStorage = ds; - } - if (parent.IsNotNull()) - { - m_ParentNode = parent; - } -} + // Visualize + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputData(linesPolyData); -void mitk::PlaneGeometryDataMapper2D::DrawLine( BaseRenderer* renderer, - ScalarType lengthInDisplayUnits, - Line &line, - std::vector &gapPositions, - const PlaneGeometry* inputPlaneGeometry, - bool drawDashed, - ScalarType gapSizeInPixel - ) -{ - DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); - const PlaneGeometry *worldPlaneGeometry = - dynamic_cast< const PlaneGeometry* >( renderer->GetCurrentWorldPlaneGeometry() ); + LocalStorage* ls = m_LSH.GetLocalStorage(renderer); + ls->m_CrosshairActor->SetMapper(mapper); - // Apply color and opacity read from the PropertyList. - this->ApplyAllProperties( renderer ); + // Determine if we should draw the area covered by the thick slicing, default is false. + // This will also show the area of slices that do not have thick slice mode enabled + bool showAreaOfThickSlicing = false; + GetDataNode()->GetBoolProperty( "reslice.thickslices.showarea", showAreaOfThickSlicing ); - ScalarType gapSizeInParamUnits = - 1.0 / lengthInDisplayUnits * gapSizeInPixel; + // get the normal of the inputPlaneGeometry + Vector3D normal = inputPlaneGeometry->GetNormal(); + // determine the pixelSpacing in that direction + double thickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); - std::sort( gapPositions.begin(), gapPositions.end() ); + IntProperty *intProperty=0; + if( GetDataNode()->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) + thickSliceDistance *= intProperty->GetValue()+0.5; + else + showAreaOfThickSlicing = false; - Point2D p1, p2; - ScalarType p1Param, p2Param; + // not the nicest place to do it, but we have the width of the visible bloc in MM here + // so we store it in this fancy property + GetDataNode()->SetFloatProperty( "reslice.thickslices.sizeinmm", thickSliceDistance*2 ); - p1Param = gapPositions[0]; - p1 = line.GetPoint( p1Param ); - displayGeometry->WorldToDisplay( p1, p1 ); + if ( showAreaOfThickSlicing ) + { + vtkSmartPointer helperlines = vtkSmartPointer::New(); + vtkSmartPointer helperlinesPolyData = vtkSmartPointer::New(); + // vectorToHelperLine defines how to reach the helperLine from the mainLine + Vector3D vectorToHelperLine; + vectorToHelperLine = normal; + vectorToHelperLine.Normalize(); + // got the right direction, so we multiply the width + vectorToHelperLine *= thickSliceDistance; - //Workaround to show the crosshair always on top of a 2D render window - //The image is usually located at depth = 0 or negative depth values, and thus, - //the crosshair with depth = 1 is always on top. - float depthPosition = 1.0f; + this->DrawLine(point1 - vectorToHelperLine, point2 - vectorToHelperLine,helperlines,points); + this->DrawLine(point1 + vectorToHelperLine, point2 + vectorToHelperLine,helperlines,points); - if ( drawDashed ) - { - glEnable(GL_LINE_STIPPLE); - glLineStipple(1, 0xF0F0); - } - glEnable(GL_DEPTH_TEST); + // Add the points to the dataset + helperlinesPolyData->SetPoints(points); - // Iterate over all line segments and display each, with a gap - // in between. - unsigned int i, preLastLineParam = gapPositions.size() - 1; - for ( i = 1; i < preLastLineParam; ++i ) - { - p2Param = gapPositions[i] - gapSizeInParamUnits * 0.5; - p2 = line.GetPoint( p2Param ); + // Add the lines to the dataset + helperlinesPolyData->SetLines(helperlines); - if ( p2Param > p1Param ) - { - // Convert intersection points (until now mm) to display - // coordinates (units). - displayGeometry->WorldToDisplay( p2, p2 ); + // Visualize + vtkSmartPointer helperLinesmapper = vtkSmartPointer::New(); + helperLinesmapper->SetInputData(helperlinesPolyData); - // draw - glBegin (GL_LINES); - glVertex3f(p1[0],p1[1], depthPosition); - glVertex3f(p2[0],p2[1], depthPosition); - glEnd (); + ls->m_CrosshairActor->GetProperty()->SetLineStipplePattern(0xf0f0); + ls->m_CrosshairActor->GetProperty()->SetLineStippleRepeatFactor(1); - if ( (i == 1) && (m_RenderOrientationArrows) ) + ls->m_CrosshairHelperLineActor->SetMapper(helperLinesmapper); + ls->m_CrosshairAssembly->AddPart(ls->m_CrosshairHelperLineActor); + } + else { - // Draw orientation arrow for first line segment - this->DrawOrientationArrow( p1, p2, - inputPlaneGeometry, worldPlaneGeometry, displayGeometry, - m_ArrowOrientationPositive ); + ls->m_CrosshairAssembly->RemovePart(ls->m_CrosshairHelperLineActor); + ls->m_CrosshairActor->GetProperty()->SetLineStipplePattern(0xffff); } } - - p1Param = p2Param + gapSizeInParamUnits; - p1 = line.GetPoint( p1Param ); - displayGeometry->WorldToDisplay( p1, p1 ); } +} - // Draw last line segment - p2Param = gapPositions[i]; - p2 = line.GetPoint( p2Param ); - displayGeometry->WorldToDisplay( p2, p2 ); - glBegin( GL_LINES ); - glVertex3f( p1[0], p1[1], depthPosition); - glVertex3f( p2[0], p2[1], depthPosition); - glEnd(); +void mitk::PlaneGeometryDataMapper2D::DrawLine( mitk::Point3D p0,mitk::Point3D p1, + vtkCellArray* lines, + vtkPoints* points + ) +{ + vtkIdType pidStart = points->InsertNextPoint(p0[0],p0[1], p0[2]); + vtkIdType pidEnd = points->InsertNextPoint(p1[0],p1[1], p1[2]); - if ( drawDashed ) - { - glDisable(GL_LINE_STIPPLE); - } + vtkSmartPointer lineVtk = vtkSmartPointer::New(); + lineVtk->GetPointIds()->SetId(0,pidStart); + lineVtk->GetPointIds()->SetId(1,pidEnd); - // Draw orientation arrows - if ( m_RenderOrientationArrows ) - { - this->DrawOrientationArrow( p2, p1, - inputPlaneGeometry, worldPlaneGeometry, displayGeometry, - m_ArrowOrientationPositive ); - if ( preLastLineParam < 2 ) - { - // If we only have one line segment, draw other arrow, too - this->DrawOrientationArrow( p1, p2, - inputPlaneGeometry, worldPlaneGeometry, displayGeometry, - m_ArrowOrientationPositive ); - } - } + lines->InsertNextCell(lineVtk); } int mitk::PlaneGeometryDataMapper2D::DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ) { int thickSlicesMode = 0; // determine the state and the extend of the thick-slice mode mitk::ResliceMethodProperty *resliceMethodEnumProperty=0; if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty ) thickSlicesMode = resliceMethodEnumProperty->GetValueAsId(); IntProperty *intProperty=0; if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) { thickSlicesNum = intProperty->GetValue(); if(thickSlicesNum < 1) thickSlicesNum=0; if(thickSlicesNum > 10) thickSlicesNum=10; } if ( thickSlicesMode == 0 ) thickSlicesNum = 0; return thickSlicesMode; } -void mitk::PlaneGeometryDataMapper2D::DetermineParametricCrossPositions( Line< mitk::ScalarType, 2 > &mainLine, - Line< mitk::ScalarType, 2 > &otherLine, - std::vector< mitk::ScalarType > &crossPositions ) +void mitk::PlaneGeometryDataMapper2D::ApplyAllProperties( BaseRenderer *renderer ) { - Vector2D direction, dOrth; - // By means of the dot product, calculate the gap position as - // parametric value in the range [0, 1] - direction = otherLine.GetDirection(); - dOrth[0] = -direction[1]; dOrth[1] = direction[0]; + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + Superclass::ApplyColorAndOpacityProperties(renderer, ls->m_CrosshairActor); + Superclass::ApplyColorAndOpacityProperties(renderer, ls->m_CrosshairHelperLineActor); + float thickness; + this->GetDataNode()->GetFloatProperty("Line width",thickness,renderer); + ls->m_CrosshairActor->GetProperty()->SetLineWidth(thickness); + ls->m_CrosshairHelperLineActor->GetProperty()->SetLineWidth(thickness); - ScalarType gapPosition = ( otherLine.GetPoint1() - mainLine.GetPoint1() ) * dOrth; - ScalarType norm = mainLine.GetDirection() * dOrth; - - if ( fabs( norm ) > eps ) + PlaneOrientationProperty* decorationProperty; + this->GetDataNode()->GetProperty( decorationProperty, "decoration", renderer ); + if ( decorationProperty != NULL ) { - gapPosition /= norm; - if ( (gapPosition > 0.0) && (gapPosition < 1.0) ) + if ( decorationProperty->GetPlaneDecoration() == + PlaneOrientationProperty::PLANE_DECORATION_POSITIVE_ORIENTATION ) + { + m_RenderOrientationArrows = true; + m_ArrowOrientationPositive = true; + } + else if ( decorationProperty->GetPlaneDecoration() == + PlaneOrientationProperty::PLANE_DECORATION_NEGATIVE_ORIENTATION ) { - crossPositions.push_back(gapPosition); + m_RenderOrientationArrows = true; + m_ArrowOrientationPositive = false; + } + else + { + m_RenderOrientationArrows = false; } } } + +void mitk::PlaneGeometryDataMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) +{ + mitk::IPropertyAliases* aliases = mitk::CoreServices::GetPropertyAliases(); + node->AddProperty( "Line width", mitk::FloatProperty::New(1), renderer, overwrite ); + aliases->AddAlias( "line width", "Crosshair.Line Width", ""); + node->AddProperty( "Crosshair.Gap Size", mitk::IntProperty::New(32), renderer, overwrite ); + node->AddProperty( "decoration", mitk::PlaneOrientationProperty + ::New(PlaneOrientationProperty::PLANE_DECORATION_NONE), renderer, overwrite ); + aliases->AddAlias( "decoration", "Crosshair.Orientation Decoration", ""); + + Superclass::SetDefaultProperties(node, renderer, overwrite); +} + +void mitk::PlaneGeometryDataMapper2D::UpdateVtkTransform(mitk::BaseRenderer* /*renderer*/) +{ +} + +mitk::PlaneGeometryDataMapper2D::LocalStorage::LocalStorage() +{ + m_CrosshairAssembly = vtkSmartPointer ::New(); + m_CrosshairActor = vtkSmartPointer ::New(); + m_CrosshairHelperLineActor = vtkSmartPointer ::New(); + m_CrosshairAssembly->AddPart(m_CrosshairActor); + m_CrosshairAssembly->AddPart(m_CrosshairHelperLineActor); +} + +mitk::PlaneGeometryDataMapper2D::LocalStorage::~LocalStorage() +{ +} diff --git a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h b/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h index a03ed7f84a..00bf45f700 100644 --- a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h +++ b/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h @@ -1,122 +1,133 @@ /*=================================================================== 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 MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB -#define MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB +#ifndef mitkPlaneGeometryDataMapper2D_h +#define mitkPlaneGeometryDataMapper2D_h +#include "mitkVtkMapper.h" +#include "mitkBaseRenderer.h" #include -#include "mitkGLMapper.h" -#include "mitkSurfaceGLMapper2D.h" -#include "mitkDataStorage.h" -#include "mitkDataNode.h" -#include "mitkWeakPointer.h" -#include "mitkLine.h" +#include +#include + +class vtkActor; +class vtkPropAssembly; +class vtkFloatArray; +class vtkCellArray; namespace mitk { - class BaseRenderer; - class PlaneGeometryDataMapper2D; - /** \deprecatedSince{2014_10} This class is deprecated. Please use PlaneGeometryDataMapper2D instead. */ - DEPRECATED( typedef PlaneGeometryDataMapper2D Geometry2DDataMapper2D); - /** - * \brief OpenGL-based mapper to display a PlaneGeometry in a 2D window - * - * Currently implemented for mapping on PlaneGeometry. - * The result is normally a line. An important usage of this class is to show - * the orientation of the slices displayed in other 2D windows. +/** + * @brief Vtk-based 2D mapper for rendering a crosshair with the plane geometry. * + * This mapper uses the mitkPlaneGeometryData from the three helper objects in + * the StdMultiWidget to render a crosshair in all 2D render windows. The crosshair + * is assembled as lines and rendered with a vtkPolyDataMapper. The mapper + * requires multiple plane geometry to compute the correct crosshair position. + * The mapper offers the following properties: + * \b Crosshair.Line width: The thickness of the crosshair. + * \b Crosshair.Gap Size: The gap between the lines in pixels. + * \b Crosshair.Orientation Decoration: Adds a PlaneOrientationProperty, which + * indicates the direction of the plane normal. See mitkPlaneOrientationProperty. * - * Properties that can be set and influence the PlaneGeometryDataMapper2D are: - * - * - \b "PlaneOrientationProperty": (PlaneOrientationProperty) - - * \todo implement for AbstractTransformGeometry. - * \ingroup Mapper + * @ingroup Mapper */ - class MITK_CORE_EXPORT PlaneGeometryDataMapper2D : public GLMapper +class MITK_CORE_EXPORT PlaneGeometryDataMapper2D : public VtkMapper +{ +public: + mitkClassMacro(PlaneGeometryDataMapper2D, VtkMapper); + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + virtual const mitk::PlaneGeometryData* GetInput() const; + + /** \brief returns the a prop assembly */ + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + + /** Applies properties specific to this mapper */ + virtual void ApplyAllProperties( BaseRenderer *renderer ); + + virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); + + /** \brief set the default properties for this mapper */ + static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); + + /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ + class LocalStorage : public mitk::Mapper::BaseLocalStorage { + public: - mitkClassMacro(PlaneGeometryDataMapper2D, GLMapper); - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) + /* constructor */ + LocalStorage(); - /** - * \brief Get the PlaneGeometryData to map - */ - const PlaneGeometryData *GetInput(); + /* destructor */ + ~LocalStorage(); - virtual void Paint( BaseRenderer *renderer ); + // actor + vtkSmartPointer m_CrosshairActor; + vtkSmartPointer m_CrosshairHelperLineActor; + vtkSmartPointer m_CrosshairAssembly; + }; - virtual void SetDatastorageAndGeometryBaseNode(mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent); + /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ + mitk::LocalStorageHandler m_LSH; - /** Applies properties specific to this mapper */ - virtual void ApplyAllProperties( BaseRenderer *renderer ); +protected: - LocalStorageHandler m_LSH; + /* constructor */ + PlaneGeometryDataMapper2D(); - protected: - PlaneGeometryDataMapper2D(); + /* destructor */ + virtual ~PlaneGeometryDataMapper2D(); - virtual ~PlaneGeometryDataMapper2D(); + /* \brief Applies the color and opacity properties and calls CreateVTKRenderObjects */ + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); - virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); - /** + void CreateVtkCrosshair(BaseRenderer *renderer); + + /** * \brief Returns the thick slice mode for the given datanode. * * This method returns the value of the 'reslice.thickslices' property for * the given datanode. * '0': thick slice mode disabled * '1': thick slice mode enabled * * The variable 'thickSlicesNum' contains the value of the 'reslice.thickslices.num' * property that defines how many slices are shown at once. */ - int DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ); + int DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ); - /** - * \brief Determines the cross position of two lines and stores them as parametric coordinates - * - * This method determines the parametric position at which a line 'otherLine' crosses another line - * 'mainLine'. The result is stored in 'crossPositions'. - */ - void DetermineParametricCrossPositions( Line &mainLine, Line &otherLine, std::vector &crossPositions ); - - void DrawLine( BaseRenderer * renderer, ScalarType lengthInDisplayUnits, - Line< ScalarType, 2 > &line, std::vector< ScalarType > &gapPositions, - const PlaneGeometry * inputPlaneGeometry, bool drawDashed, - ScalarType gapSizeInPixel - ); + void DrawLine(Point3D p0, Point3D p1, + vtkCellArray *lines, + vtkPoints *points); - void DrawOrientationArrow( Point2D &outerPoint, Point2D &innerPoint, - const PlaneGeometry *planeGeometry, - const PlaneGeometry *rendererPlaneGeometry, - const DisplayGeometry *displayGeometry, - bool positiveOrientation = true ); + // member variables holding the current value of the properties used in this mapper + typedef std::vector NodesVectorType; + NodesVectorType m_OtherPlaneGeometries; - SurfaceGLMapper2D::Pointer m_SurfaceMapper; + typedef std::set AllInstancesContainer; + static AllInstancesContainer s_AllInstances; - mitk::WeakPointer m_DataStorage; ///< DataStorage that will be searched for sub nodes - DataNode::Pointer m_ParentNode; ///< parent node that will be used to search for sub nodes + bool m_RenderOrientationArrows; + bool m_ArrowOrientationPositive; + mitk::ScalarType m_DepthValue; - typedef std::vector NodesVectorType; - NodesVectorType m_OtherPlaneGeometries; - - bool m_RenderOrientationArrows; - bool m_ArrowOrientationPositive; - }; +}; } // namespace mitk -#endif /* MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB */ +#endif /* mitkPlaneGeometryDataMapper2D_h */ diff --git a/Core/Code/Rendering/mitkRenderWindowFrame.cpp b/Core/Code/Rendering/mitkRenderWindowFrame.cpp index cb483f70b8..80a8432435 100644 --- a/Core/Code/Rendering/mitkRenderWindowFrame.cpp +++ b/Core/Code/Rendering/mitkRenderWindowFrame.cpp @@ -1,150 +1,110 @@ /*=================================================================== 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 "mitkRenderWindowFrame.h" - #include "mitkVtkLayerController.h" - -#include -#include -#include -#include -#include +#include "vtkMitkRectangleProp.h" #include #include -#include -#include - -#include mitk::RenderWindowFrame::RenderWindowFrame() { m_RenderWindow = NULL; - m_RectangleRenderer = vtkRenderer::New(); + m_RectangleRenderer = vtkSmartPointer::New(); m_IsEnabled = false; } mitk::RenderWindowFrame::~RenderWindowFrame() { if ( m_RenderWindow != NULL ) if ( this->IsEnabled() ) this->Disable(); - - if ( m_RectangleRenderer != NULL ) - m_RectangleRenderer->Delete(); - } /** * Sets the renderwindow, in which the text * will be shown. Make sure, you have called this function * before calling Enable() */ -void mitk::RenderWindowFrame::SetRenderWindow( vtkRenderWindow* renderWindow ) +void mitk::RenderWindowFrame::SetRenderWindow(vtkSmartPointer renderWindow ) { m_RenderWindow = renderWindow; } /** * Returns the vtkRenderWindow, which is used * for displaying the text */ -vtkRenderWindow* mitk::RenderWindowFrame::GetRenderWindow() +vtkSmartPointer mitk::RenderWindowFrame::GetRenderWindow() { return m_RenderWindow; } /** * Returns the renderer responsible for * rendering the text into the * vtkRenderWindow */ -vtkRenderer* mitk::RenderWindowFrame::GetVtkRenderer() +vtkSmartPointer mitk::RenderWindowFrame::GetVtkRenderer() { return m_RectangleRenderer; } /** * Disables drawing of the text label collection. * If you want to enable it, call the Enable() function. */ void mitk::RenderWindowFrame::Disable() { if ( this->IsEnabled()) { m_RectangleRenderer->EraseOn(); mitk::VtkLayerController::GetInstance(m_RenderWindow)->RemoveRenderer(m_RectangleRenderer); m_IsEnabled = false; } } /** * Enables drawing of the text label collection. * If you want to disable it, call the Disable() function. */ void mitk::RenderWindowFrame::Enable(float col1, float col2, float col3) { - vtkMitkRectangleProp* rect = vtkMitkRectangleProp::New(); + vtkSmartPointer rect = vtkSmartPointer::New(); rect->SetRenderWindow(m_RenderWindow); rect->SetColor(col1, col2, col3); - m_RectangleRenderer->AddViewProp(rect); - - rect->Delete(); - + m_RectangleRenderer->AddActor(rect); if(!mitk::VtkLayerController::GetInstance(m_RenderWindow)->IsRendererInserted( m_RectangleRenderer )) { - m_RectangleRenderer->EraseOff(); - m_RectangleRenderer->SetInteractive(0); mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertForegroundRenderer(m_RectangleRenderer,true); m_IsEnabled = true; } } /** * Checks, if the text is currently * enabled (visible) */ bool mitk::RenderWindowFrame::IsEnabled() { return m_IsEnabled; } - -void mitk::RenderWindowFrame::SetRequestedRegionToLargestPossibleRegion() -{ - //nothing to do -} - -bool mitk::RenderWindowFrame::RequestedRegionIsOutsideOfTheBufferedRegion() -{ - return false; -} - -bool mitk::RenderWindowFrame::VerifyRequestedRegion() -{ - return true; -} - -void mitk::RenderWindowFrame::SetRequestedRegion( const itk::DataObject*) -{ - //nothing to do -} - diff --git a/Core/Code/Rendering/mitkRenderWindowFrame.h b/Core/Code/Rendering/mitkRenderWindowFrame.h index 49d45d56c7..3ff5b46331 100644 --- a/Core/Code/Rendering/mitkRenderWindowFrame.h +++ b/Core/Code/Rendering/mitkRenderWindowFrame.h @@ -1,133 +1,101 @@ /*=================================================================== 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 _vtk_Colored_Rectangle_Rendering_h_ -#define _vtk_Colored_Rectangle_Rendering_h_ +#ifndef mitkRenderWindowFrame_h +#define mitkRenderWindowFrame_h - -#include -#include - -#include -#include +#include +#include +#include +#include class vtkRenderer; class vtkRenderWindow; -class vtkCamera; -class vtkTextProperty; -class vtkTextActor; - namespace mitk { /** * This is a simple class for rendering colored rectangles * at the boarders of vtkRenderWindows. * The rectangle rendering itself is performed by means of a * vtkProp (vtkMitkRectangleProp). * This class instantiates the vtkProp and a corresponding vtkRenderer instance. */ -class MITK_CORE_EXPORT RenderWindowFrame : public BaseData +class MITK_CORE_EXPORT RenderWindowFrame : public itk::Object { public: - mitkClassMacro( RenderWindowFrame, BaseData ); + mitkClassMacro( RenderWindowFrame, itk::Object ); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * Sets the renderwindow, in which colored rectangle boarders will be shown. * Make sure, you have called this function * before calling Enable() */ - virtual void SetRenderWindow( vtkRenderWindow* renderWindow ); + virtual void SetRenderWindow( vtkSmartPointer renderWindow ); /** * Enables drawing of the colored rectangle. * If you want to disable it, call the Disable() function. */ virtual void Enable(float col1, float col2, float col3); /** * Disables drawing of the colored rectangle. * If you want to enable it, call the Enable() function. */ virtual void Disable(); /** * Checks, if the text is currently * enabled (visible) */ virtual bool IsEnabled(); - /** - * Empty implementation, since the rectangle rendering doesn't - * support the requested region concept - */ - virtual void SetRequestedRegionToLargestPossibleRegion(); - - /** - * Empty implementation, since the rectangle rendering doesn't - * support the requested region concept - */ - virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); - - /** - * Empty implementation, since the rectangle rendering doesn't - * support the requested region concept - */ - virtual bool VerifyRequestedRegion(); - - /** - * Empty implementation, since the rectangle rendering doesn't - * support the requested region concept - */ - virtual void SetRequestedRegion( const itk::DataObject*); - /** * Returns the vtkRenderWindow, which is used * for displaying the text */ - virtual vtkRenderWindow* GetRenderWindow(); + virtual vtkSmartPointer GetRenderWindow(); /** * Returns the renderer responsible for * rendering the text into the * vtkRenderWindow */ - virtual vtkRenderer* GetVtkRenderer(); + virtual vtkSmartPointer GetVtkRenderer(); protected: /** * Constructor */ RenderWindowFrame(); /** * Destructor */ ~RenderWindowFrame(); - vtkRenderWindow* m_RenderWindow; - vtkRenderer* m_RectangleRenderer; + vtkSmartPointer m_RenderWindow; + vtkSmartPointer m_RectangleRenderer; bool m_IsEnabled; - }; - } //end of namespace mitk -#endif +#endif //mitkRenderWindowFrame_h diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper2D.cpp b/Core/Code/Rendering/mitkSurfaceVtkMapper2D.cpp new file mode 100644 index 0000000000..e7819c7bc6 --- /dev/null +++ b/Core/Code/Rendering/mitkSurfaceVtkMapper2D.cpp @@ -0,0 +1,334 @@ +/*=================================================================== + +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 "mitkSurfaceVtkMapper2D.h" + +//mitk includes +#include +#include +#include "mitkVtkPropRenderer.h" +#include +#include +#include +#include +#include +#include + +//vtk includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// constructor LocalStorage +mitk::SurfaceVtkMapper2D::LocalStorage::LocalStorage() +{ + m_Mapper = vtkSmartPointer::New(); + m_Mapper->ScalarVisibilityOff(); + m_Actor = vtkSmartPointer::New(); + m_Actor->SetMapper( m_Mapper ); + m_PropAssembly = vtkSmartPointer ::New(); + m_PropAssembly->AddPart( m_Actor ); + m_CuttingPlane = vtkSmartPointer::New(); + m_Cutter = vtkSmartPointer::New(); + m_Cutter->SetCutFunction(m_CuttingPlane); + m_Mapper->SetInputConnection( m_Cutter->GetOutputPort() ); + + m_NormalGlyph = vtkSmartPointer::New(); + + m_InverseNormalGlyph = vtkSmartPointer::New(); + + // Source for the glyph filter + m_ArrowSource = vtkSmartPointer::New(); + //set small default values for fast rendering + m_ArrowSource->SetTipRadius(0.05); + m_ArrowSource->SetTipLength(0.20); + m_ArrowSource->SetTipResolution(5); + m_ArrowSource->SetShaftResolution(5); + m_ArrowSource->SetShaftRadius(0.01); + + m_NormalGlyph->SetSourceConnection(m_ArrowSource->GetOutputPort()); + m_NormalGlyph->SetVectorModeToUseNormal(); + m_NormalGlyph->OrientOn(); + + m_InverseNormalGlyph->SetSourceConnection(m_ArrowSource->GetOutputPort()); + m_InverseNormalGlyph->SetVectorModeToUseNormal(); + m_InverseNormalGlyph->OrientOn(); + + m_NormalMapper = vtkSmartPointer::New(); + m_NormalMapper->SetInputConnection(m_NormalGlyph->GetOutputPort()); + m_NormalMapper->ScalarVisibilityOff(); + + m_InverseNormalMapper = vtkSmartPointer::New(); + m_InverseNormalMapper->SetInputConnection(m_NormalGlyph->GetOutputPort()); + m_InverseNormalMapper->ScalarVisibilityOff(); + + m_NormalActor = vtkSmartPointer::New(); + m_NormalActor->SetMapper(m_NormalMapper); + + m_InverseNormalActor = vtkSmartPointer::New(); + m_InverseNormalActor->SetMapper(m_InverseNormalMapper); + + m_ReverseSense = vtkSmartPointer::New(); + + m_PropAssembly->AddPart( m_NormalActor ); +} + +// destructor LocalStorage +mitk::SurfaceVtkMapper2D::LocalStorage::~LocalStorage() +{ +} + +const mitk::Surface* mitk::SurfaceVtkMapper2D::GetInput() const +{ + return static_cast ( GetDataNode()->GetData() ); +} + +// constructor PointSetVtkMapper2D +mitk::SurfaceVtkMapper2D::SurfaceVtkMapper2D() +{ +} + +mitk::SurfaceVtkMapper2D::~SurfaceVtkMapper2D() +{ +} + +// reset mapper so that nothing is displayed e.g. toggle visiblity of the propassembly +void mitk::SurfaceVtkMapper2D::ResetMapper( BaseRenderer* renderer ) +{ + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + ls->m_PropAssembly->VisibilityOff(); +} + +vtkProp* mitk::SurfaceVtkMapper2D::GetVtkProp(mitk::BaseRenderer * renderer) +{ + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + return ls->m_PropAssembly; +} + +void mitk::SurfaceVtkMapper2D::Update(mitk::BaseRenderer* renderer) +{ + const mitk::DataNode* node = GetDataNode(); + if( node == NULL ) + return; + bool visible = true; + node->GetVisibility(visible, renderer, "visible"); + if ( !visible ) + return; + + mitk::Surface* surface = static_cast( node->GetData() ); + if ( surface == NULL ) + return; + + // Calculate time step of the input data for the specified renderer (integer value) + this->CalculateTimeStep( renderer ); + + // Check if time step is valid + const mitk::TimeGeometry *dataTimeGeometry = surface->GetTimeGeometry(); + if ( ( dataTimeGeometry == NULL ) + || ( dataTimeGeometry->CountTimeSteps() == 0 ) + || ( !dataTimeGeometry->IsValidTimeStep( this->GetTimestep() ) ) ) + { + return; + } + + surface->UpdateOutputInformation(); + LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer); + + //check if something important has changed and we need to rerender + if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? + || (localStorage->m_LastUpdateTime < surface->GetPipelineMTime()) //Was the data modified? + || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) //was the geometry modified? + || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->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(); +} + +void mitk::SurfaceVtkMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) +{ + const DataNode* node = GetDataNode(); + Surface* surface = static_cast( node->GetData() ); + const TimeGeometry *dataTimeGeometry = surface->GetTimeGeometry(); + LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer); + + ScalarType time =renderer->GetTime(); + int timestep=0; + + if( time > itk::NumericTraits::NonpositiveMin() ) + timestep = dataTimeGeometry->TimePointToTimeStep( time ); + + vtkSmartPointer inputPolyData = surface->GetVtkPolyData( timestep ); + if((inputPolyData==NULL) || (inputPolyData->GetNumberOfPoints() < 1 )) + return; + + //apply color and opacity read from the PropertyList + this->ApplyAllProperties(renderer); + + const PlaneGeometry* planeGeometry = renderer->GetCurrentWorldPlaneGeometry(); + if( ( planeGeometry == NULL ) || ( !planeGeometry->IsValid() ) || ( !planeGeometry->HasReferenceGeometry() )) + { + return; + } + + double origin[3]; + origin[0] = planeGeometry->GetOrigin()[0]; + origin[1] = planeGeometry->GetOrigin()[1]; + origin[2] = planeGeometry->GetOrigin()[2]; + + double normal[3]; + normal[0] = planeGeometry->GetNormal()[0]; + normal[1] = planeGeometry->GetNormal()[1]; + normal[2] = planeGeometry->GetNormal()[2]; + + localStorage->m_CuttingPlane->SetOrigin(origin); + localStorage->m_CuttingPlane->SetNormal(normal); + + localStorage->m_Cutter->SetInputData(inputPolyData); + localStorage->m_Cutter->Update(); + + bool generateNormals = false; + node->GetBoolProperty("draw normals 2D", generateNormals); + if(generateNormals) + { + localStorage->m_NormalGlyph->SetInputConnection( localStorage->m_Cutter->GetOutputPort() ); + localStorage->m_NormalGlyph->Update(); + + localStorage->m_NormalMapper->SetInputConnection( localStorage->m_NormalGlyph->GetOutputPort() ); + + localStorage->m_PropAssembly->AddPart( localStorage->m_NormalActor ); + } + else + { + localStorage->m_NormalGlyph->SetInputConnection( NULL ); + localStorage->m_PropAssembly->RemovePart( localStorage->m_NormalActor ); + } + + bool generateInverseNormals = false; + node->GetBoolProperty("invert normals", generateInverseNormals); + if(generateInverseNormals) + { + + localStorage->m_ReverseSense->SetInputConnection( localStorage->m_Cutter->GetOutputPort() ); + localStorage->m_ReverseSense->ReverseCellsOff(); + localStorage->m_ReverseSense->ReverseNormalsOn(); + + localStorage->m_InverseNormalGlyph->SetInputConnection( localStorage->m_ReverseSense->GetOutputPort() ); + localStorage->m_InverseNormalGlyph->Update(); + + localStorage->m_InverseNormalMapper->SetInputConnection( localStorage->m_InverseNormalGlyph->GetOutputPort() ); + + localStorage->m_PropAssembly->AddPart( localStorage->m_InverseNormalActor ); + } + else + { + localStorage->m_ReverseSense->SetInputConnection( NULL ); + localStorage->m_PropAssembly->RemovePart( localStorage->m_InverseNormalActor ); + } +} + +void mitk::SurfaceVtkMapper2D::ApplyAllProperties(mitk::BaseRenderer* renderer) +{ + const DataNode * node = GetDataNode(); + + if(node == NULL) + { + return; + } + + float lineWidth = 1.0f; + node->GetFloatProperty("line width", lineWidth, renderer); + + LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer); + + // check for color and opacity properties, use it for rendering if they exists + float color[3]= { 1.0f, 1.0f, 1.0f }; + node->GetColor(color, renderer, "color"); + float opacity = 1.0f; + node->GetOpacity(opacity, renderer, "opacity"); + + //Pass properties to VTK + localStorage->m_Actor->GetProperty()->SetColor(color[0], color[1], color[2]); + localStorage->m_Actor->GetProperty()->SetOpacity(opacity); + localStorage->m_NormalActor->GetProperty()->SetOpacity(opacity); + localStorage->m_InverseNormalActor->GetProperty()->SetOpacity(opacity); + localStorage->m_Actor->GetProperty()->SetLineWidth(lineWidth); + //By default, the cutter will also copy/compute normals of the cut + //to the output polydata. The normals will influence the + //vtkPolyDataMapper lightning. To view a clean cut the lighting has + //to be disabled. + localStorage->m_Actor->GetProperty()->SetLighting(0); + + bool scalarVisibility = false; + node->GetBoolProperty("scalar visibility", scalarVisibility); + localStorage->m_Mapper->SetScalarVisibility(scalarVisibility); + + //color for inverse normals + float inverseNormalsColor[3]= { 1.0f, 0.0f, 0.0f }; + node->GetColor(inverseNormalsColor, renderer, "back color"); + localStorage->m_InverseNormalActor->GetProperty()->SetColor(inverseNormalsColor[0], + inverseNormalsColor[1], inverseNormalsColor[2]); + + //color for normals + float normalsColor[3]= { 0.0f, 1.0f, 0.0f }; + node->GetColor(normalsColor, renderer, "front color"); + localStorage->m_NormalActor->GetProperty()->SetColor(normalsColor[0], + normalsColor[1], normalsColor[2]); + + //normals scaling + float normalScaleFactor = 10.0f; + node->GetFloatProperty( "front normal lenth (px)", normalScaleFactor, renderer ); + localStorage->m_NormalGlyph->SetScaleFactor(normalScaleFactor); + + //inverse normals scaling + float inverseNormalScaleFactor = 10.0f; + node->GetFloatProperty( "back normal lenth (px)", inverseNormalScaleFactor, renderer ); + localStorage->m_InverseNormalGlyph->SetScaleFactor(inverseNormalScaleFactor); +} + +void mitk::SurfaceVtkMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) +{ + mitk::IPropertyAliases* aliases = mitk::CoreServices::GetPropertyAliases(); + node->AddProperty( "line width", FloatProperty::New(2.0f), renderer, overwrite ); + aliases->AddAlias( "line width", "Surface.2D.Line Width", "Surface"); + node->AddProperty( "scalar mode", VtkScalarModeProperty::New(), renderer, overwrite ); + node->AddProperty( "draw normals 2D", BoolProperty::New(false), renderer, overwrite ); + aliases->AddAlias( "draw normals 2D", "Surface.2D.Normals.Draw Normals", "Surface"); + node->AddProperty( "invert normals", BoolProperty::New(false), renderer, overwrite ); + aliases->AddAlias( "invert normals", "Surface.2D.Normals.Draw Inverse Normals", "Surface"); + node->AddProperty( "front color", ColorProperty::New(0.0, 1.0, 0.0), renderer, overwrite ); + aliases->AddAlias( "front color", "Surface.2D.Normals.Normals Color", "Surface"); + node->AddProperty( "back color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite ); + aliases->AddAlias( "back color", "Surface.2D.Normals.Inverse Normals Color", "Surface"); + node->AddProperty( "front normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite ); + aliases->AddAlias( "front normal lenth (px)", "Surface.2D.Normals.Normals Scale Factor", "Surface"); + node->AddProperty( "back normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite ); + aliases->AddAlias( "back normal lenth (px)", "Surface.2D.Normals.Inverse Normals Scale Factor", "Surface"); + node->AddProperty( "layer", IntProperty::New(100), renderer, overwrite); + Superclass::SetDefaultProperties(node, renderer, overwrite); +} diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper2D.h b/Core/Code/Rendering/mitkSurfaceVtkMapper2D.h new file mode 100644 index 0000000000..fb05ee37e5 --- /dev/null +++ b/Core/Code/Rendering/mitkSurfaceVtkMapper2D.h @@ -0,0 +1,193 @@ +/*=================================================================== + +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 mitkSurfaceVtkMapper2D_h +#define mitkSurfaceVtkMapper2D_h + +#include +#include "mitkVtkMapper.h" +#include "mitkBaseRenderer.h" +#include "mitkLocalStorageHandler.h" + +//VTK +#include +class vtkPropAssembly; +class vtkCutter; +class vtkPlane; +class vtkLookupTable; +class vtkGlyph3D; +class vtkArrowSource; +class vtkReverseSense; + +namespace mitk { + +class Surface; + +/** + * @brief Vtk-based mapper for cutting 2D slices out of Surfaces. + * + * The mapper uses a vtkCutter filter to cut out slices of the 3D + * volume and render these slices as vtkPolyData. + * + * Properties: + * \b Surface.2D.Line Width: Thickness of the rendered lines in 2D. + * \b Surface.2D.Normals.Draw Normals: enables drawing of normals as 3D arrows + * in the 2D render window. The normals are created with a vtkGlyph3D from + * the vtkPolyData. + * \b Surface.2D.Normals.Draw Inverse Normals: same as normals, but in the + * other direction. The inverse normals are computed with a vtkReverseSense + * filter. + * \b Surface.2D.Normals.(Inverse) Normals Color: Color of the (inverse) normals. + * \b Surface.2D.Normals.(Inverse) Normals Scale Factor: Regulates the size of the normals. + * + * @ingroup Mapper + */ +class MITK_CORE_EXPORT SurfaceVtkMapper2D : public VtkMapper +{ +public: + mitkClassMacro(SurfaceVtkMapper2D, VtkMapper); + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + virtual const mitk::Surface* GetInput() const; + + /** \brief returns the prop assembly */ + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + + /** \brief set the default properties for this mapper */ + static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); + + /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ + class LocalStorage : public mitk::Mapper::BaseLocalStorage + { + public: + /** \brief Timestamp of last update of stored data. */ + itk::TimeStamp m_LastUpdateTime; + /** + * @brief m_PropAssembly Contains all vtkProps for the final rendering. + * + * Consists of 3 actors: + * The surface cut (the slice from the 3D surface). + * The normals and the inverse normals. + */ + vtkSmartPointer m_PropAssembly; + + /** + * @brief m_Actor actor for the surface cut. + */ + vtkSmartPointer m_Actor; + /** + * @brief m_NormalActor actor for the normals. + */ + vtkSmartPointer m_NormalActor; + /** + * @brief m_InverseNormalActor actor for the inverse normals. + */ + vtkSmartPointer m_InverseNormalActor; + /** + * @brief m_Mapper VTK mapper for all types of 2D polydata e.g. werewolves. + */ + vtkSmartPointer m_Mapper; + /** + * @brief m_Cutter Filter to cut out the 2D slice. + */ + vtkSmartPointer m_Cutter; + /** + * @brief m_CuttingPlane The plane where to cut off the 2D slice. + */ + vtkSmartPointer m_CuttingPlane; + + /** + * @brief m_NormalMapper Mapper for the normals. + */ + vtkSmartPointer m_NormalMapper; + + /** + * @brief m_InverseNormalMapper Mapper for the inverse normals. + */ + vtkSmartPointer m_InverseNormalMapper; + + /** + * @brief m_NormalGlyph Glyph for creating normals. + */ + vtkSmartPointer m_NormalGlyph; + + /** + * @brief m_InverseNormalGlyph Glyph for creating inverse normals. + */ + vtkSmartPointer m_InverseNormalGlyph; + + /** + * @brief m_ArrowSource Arrow representation of the normals. + */ + vtkSmartPointer m_ArrowSource; + + /** + * @brief m_ReverseSense Filter to invert the normals. + */ + vtkSmartPointer m_ReverseSense; + + /** \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; + +protected: + /** + * @brief SurfaceVtkMapper2D default constructor. + */ + SurfaceVtkMapper2D(); + + /** + * @brief ~SurfaceVtkMapper2D default destructor. + */ + virtual ~SurfaceVtkMapper2D(); + + /** + * @brief GenerateDataForRenderer produces all the data. + * @param renderer The respective renderer of the mitkRenderWindow. + */ + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); + + /** + * @brief ResetMapper Called in mitk::Mapper::Update to hide objects. + * If TimeSlicedGeometry or time step is not valid, reset the mapper. + * so that nothing is displayed e.g. toggle visiblity of the propassembly. + * + * @param renderer The respective renderer of the mitkRenderWindow. + */ + virtual void ResetMapper( BaseRenderer* renderer ); + + /** + * @brief ApplyAllProperties Pass all the properties to VTK. + * @param renderer The respective renderer of the mitkRenderWindow. + */ + void ApplyAllProperties( BaseRenderer* renderer); + + /** + * @brief Update Check if data should be generated. + * @param renderer The respective renderer of the mitkRenderWindow. + */ + void Update(BaseRenderer* renderer); +}; +} // namespace mitk +#endif /* mitkSurfaceVtkMapper2D_h */ diff --git a/Core/Code/Rendering/mitkVtkOverlay.cpp b/Core/Code/Rendering/mitkVtkOverlay.cpp index 32da4139a4..c39750ece4 100644 --- a/Core/Code/Rendering/mitkVtkOverlay.cpp +++ b/Core/Code/Rendering/mitkVtkOverlay.cpp @@ -1,81 +1,87 @@ /*=================================================================== 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) { if(!renderer) return; AddToRenderer(renderer,renderer->GetVtkRenderer()); } void mitk::VtkOverlay::AddToRenderer(mitk::BaseRenderer *renderer, vtkRenderer *vtkrenderer) { if(!renderer || !vtkrenderer) return; Update(renderer); vtkSmartPointer vtkProp = GetVtkProp(renderer); if(renderer && vtkrenderer && !vtkrenderer->HasViewProp(vtkProp)) { vtkrenderer->AddViewProp(vtkProp); } } void mitk::VtkOverlay::RemoveFromBaseRenderer(mitk::BaseRenderer *renderer) { if(!renderer) return; RemoveFromRenderer(renderer,renderer->GetVtkRenderer()); } void mitk::VtkOverlay::RemoveFromRenderer(mitk::BaseRenderer *renderer, vtkRenderer *vtkrenderer) { if(!renderer || !vtkrenderer) return; vtkSmartPointer vtkProp = GetVtkProp(renderer); if(vtkrenderer->HasViewProp(vtkProp)) { vtkrenderer->RemoveViewProp(vtkProp); } } + +void mitk::VtkOverlay::Paint( BaseRenderer* renderer ) +{ + GetVtkProp( renderer )->RenderOpaqueGeometry(renderer->GetVtkRenderer() ); + GetVtkProp( renderer )->RenderOverlay( renderer->GetVtkRenderer() ); +} diff --git a/Core/Code/Rendering/mitkVtkOverlay.h b/Core/Code/Rendering/mitkVtkOverlay.h index 7d5408cdab..db68cc9611 100644 --- a/Core/Code/Rendering/mitkVtkOverlay.h +++ b/Core/Code/Rendering/mitkVtkOverlay.h @@ -1,71 +1,80 @@ /*=================================================================== 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 VTKOVERLAY_H #define VTKOVERLAY_H #include #include "mitkOverlay.h" #include class vtkProp; namespace mitk { /** * @brief The VtkOverlay class is the base for all Overlays which are using the VTK framework to render *the elements. */ class MITK_CORE_EXPORT VtkOverlay : public Overlay { public: mitkClassMacro(VtkOverlay, Overlay); void Update(BaseRenderer *renderer); void AddToBaseRenderer(BaseRenderer *renderer); void AddToRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer); void RemoveFromRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer); void RemoveFromBaseRenderer(BaseRenderer *renderer); + /** + * \brief Paints the overlay. + * + * This method forces a paint of the overlay as it is configured at the moment. + * \warn Should only be used as alternative to the OverlayManager mechanism + * in GL-Mappers. + */ + void Paint( BaseRenderer* renderer ); + protected: /** * @brief This method is implemented by the specific VTKOverlays in order to create the element as a vtkProp * @param renderer * @return The element that was created by the subclasses as a vtkProp. */ virtual vtkProp* GetVtkProp(BaseRenderer *renderer) const = 0; virtual void UpdateVtkOverlay(BaseRenderer *renderer) = 0; /** \brief explicit constructor which disallows implicit conversions */ explicit VtkOverlay(); /** \brief virtual destructor in order to derive from this class */ virtual ~VtkOverlay(); private: /** \brief copy constructor */ VtkOverlay( const VtkOverlay &); /** \brief assignment operator */ VtkOverlay &operator=(const VtkOverlay &); }; } // namespace mitk #endif // OVERLAY_H diff --git a/Core/Code/Rendering/mitkVtkOverlay2D.h b/Core/Code/Rendering/mitkVtkOverlay2D.h index bc824286e5..eb1778a10a 100644 --- a/Core/Code/Rendering/mitkVtkOverlay2D.h +++ b/Core/Code/Rendering/mitkVtkOverlay2D.h @@ -1,74 +1,74 @@ /*=================================================================== 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 VTKOVERLAY2D_H #define VTKOVERLAY2D_H #include #include "mitkVtkOverlay.h" #include class vtkActor2D; class vtkProperty2D; namespace mitk { /** * @brief The VtkOverlay2D class is the basis for all VTK based Overlays which create * a vtkActor2D element that will be drawn on the renderer. */ class MITK_CORE_EXPORT VtkOverlay2D : public VtkOverlay { public: mitkClassMacro(VtkOverlay2D, VtkOverlay); virtual Overlay::Bounds GetBoundsOnDisplay(BaseRenderer *renderer) const; virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds& bounds); void SetPosition2D(const Point2D& position2D, mitk::BaseRenderer* renderer = NULL); Point2D GetPosition2D(mitk::BaseRenderer* renderer = NULL) const; void SetOffsetVector(const Point2D& OffsetVector, BaseRenderer* renderer = NULL); Point2D GetOffsetVector(mitk::BaseRenderer* renderer = NULL) const; protected: - vtkProp* GetVtkProp(BaseRenderer *renderer) const; + virtual vtkProp* GetVtkProp(BaseRenderer *renderer) const; virtual void UpdateVtkOverlay(BaseRenderer *renderer); virtual void UpdateVtkOverlay2D(BaseRenderer *renderer) = 0; virtual vtkActor2D* GetVtkActor2D(BaseRenderer *renderer) const = 0; /** \brief explicit constructor which disallows implicit conversions */ explicit VtkOverlay2D(); /** \brief virtual destructor in order to derive from this class */ virtual ~VtkOverlay2D(); private: /** \brief copy constructor */ VtkOverlay2D( const VtkOverlay2D &); /** \brief assignment operator */ VtkOverlay2D &operator=(const VtkOverlay2D &); }; } // namespace mitk #endif // VTKOVERLAY2D_H diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.cpp b/Core/Code/Rendering/mitkVtkPropRenderer.cpp index b1dbe8a3a1..70ea49e7f8 100644 --- a/Core/Code/Rendering/mitkVtkPropRenderer.cpp +++ b/Core/Code/Rendering/mitkVtkPropRenderer.cpp @@ -1,1010 +1,824 @@ /*=================================================================== 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 "mitkVtkPropRenderer.h" // MAPPERS #include "mitkMapper.h" #include "mitkImageVtkMapper2D.h" #include "mitkVtkMapper.h" -#include "mitkGLMapper.h" #include "mitkPlaneGeometryDataVtkMapper3D.h" -#include "mitkImageSliceSelector.h" -#include "mitkRenderingManager.h" -#include "mitkGL.h" -#include "mitkGeometry3D.h" -#include "mitkDisplayGeometry.h" -#include "mitkLevelWindow.h" -#include "mitkCameraController.h" -#include "mitkVtkInteractorCameraController.h" -#include "mitkPlaneGeometry.h" -#include "mitkProperties.h" -#include "mitkSurface.h" -#include "mitkNodePredicateDataType.h" -#include "mitkVtkInteractorStyle.h" -#include "mitkAbstractTransformGeometry.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::VtkPropRenderer::VtkPropRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm, mitk::BaseRenderer::RenderingMode::Type renderingMode ) : BaseRenderer(name,renWin, rm, renderingMode ), - m_VtkMapperPresent(false), - m_CameraInitializedForMapperID(0) + m_CameraInitializedForMapperID(0) { didCount=false; m_WorldPointPicker = vtkWorldPointPicker::New(); m_PointPicker = vtkPointPicker::New(); m_PointPicker->SetTolerance( 0.0025 ); m_CellPicker = vtkCellPicker::New(); m_CellPicker->SetTolerance( 0.0025 ); mitk::PlaneGeometryDataVtkMapper3D::Pointer geometryMapper = mitk::PlaneGeometryDataVtkMapper3D::New(); m_CurrentWorldPlaneGeometryMapper = geometryMapper; m_CurrentWorldPlaneGeometryNode->SetMapper(2, geometryMapper); m_LightKit = vtkLightKit::New(); m_LightKit->AddLightsToRenderer(m_VtkRenderer); m_PickingMode = WorldPointPicking; m_TextRenderer = vtkRenderer::New(); m_TextRenderer->SetRenderWindow(renWin); m_TextRenderer->SetInteractive(0); m_TextRenderer->SetErase(0); } /*! \brief Destructs the VtkPropRenderer. */ mitk::VtkPropRenderer::~VtkPropRenderer() { // Workaround for GLDisplayList Bug { m_MapperID=0; checkState(); } if (m_LightKit != NULL) m_LightKit->Delete(); if (m_VtkRenderer!=NULL) { m_CameraController = NULL; m_VtkRenderer->Delete(); m_VtkRenderer = NULL; } else m_CameraController = NULL; if (m_WorldPointPicker != NULL) m_WorldPointPicker->Delete(); if (m_PointPicker != NULL) m_PointPicker->Delete(); if (m_CellPicker != NULL) m_CellPicker->Delete(); if (m_TextRenderer != NULL) m_TextRenderer->Delete(); } void mitk::VtkPropRenderer::SetDataStorage( mitk::DataStorage* storage ) { if ( storage == NULL ) return; BaseRenderer::SetDataStorage(storage); static_cast(m_CurrentWorldPlaneGeometryMapper.GetPointer())->SetDataStorageForTexture( m_DataStorage.GetPointer() ); // Compute the geometry from the current data tree bounds and set it as world geometry this->SetWorldGeometryToDataStorageBounds(); } bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds() { if ( m_DataStorage.IsNull() ) return false; //initialize world geometry mitk::TimeGeometry::Pointer geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D( NULL, "includeInBoundingBox" ); if ( geometry.IsNull() ) return false; this->SetWorldTimeGeometry(geometry); //this->GetDisplayGeometry()->SetSizeInDisplayUnits( this->m_TextRenderer->GetRenderWindow()->GetSize()[0], this->m_TextRenderer->GetRenderWindow()->GetSize()[1] ); this->GetDisplayGeometry()->Fit(); this->GetVtkRenderer()->ResetCamera(); this->Modified(); return true; } /*! \brief Called by the vtkMitkRenderProp in order to start MITK rendering process. */ int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type) { //Update all overlays in any case this->UpdateOverlays(); // Do we have objects to render? if ( this->GetEmptyWorldGeometry()) return 0; if ( m_DataStorage.IsNull()) return 0; // Update mappers and prepare mapper queue if (type == VtkPropRenderer::Opaque) this->PrepareMapperQueue(); //go through the generated list and let the sorted mappers paint - bool lastVtkBased = true; - //bool sthVtkBased = false; - for(MappersMapType::iterator it = m_MappersMap.begin(); it != m_MappersMap.end(); it++) { Mapper * mapper = (*it).second; - - VtkMapper* vtkmapper = dynamic_cast(mapper); - - if(vtkmapper) - { - //sthVtkBased = true; - if(!lastVtkBased) - { - Disable2DOpenGL(); - lastVtkBased = true; - } - } - else if(lastVtkBased) - { - Enable2DOpenGL(); - lastVtkBased = false; - } - mapper->MitkRender(this, type); } //Update overlays in case a mapper has changed them this->UpdateOverlays(); - if (lastVtkBased == false) - Disable2DOpenGL(); - // Render text if (type == VtkPropRenderer::Overlay) { if (m_TextCollection.size() > 0) { m_TextRenderer->SetViewport( this->GetVtkRenderer()->GetViewport() ); for (TextMapType::iterator it = m_TextCollection.begin(); it != m_TextCollection.end() ; it++) m_TextRenderer->AddViewProp((*it).second); m_TextRenderer->Render(); } } return 1; } /*! \brief PrepareMapperQueue iterates the datatree PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer. */ void mitk::VtkPropRenderer::PrepareMapperQueue() { // variable for counting LOD-enabled mappers m_NumberOfVisibleLODEnabledMappers = 0; // Do we have to update the mappers ? if ( m_LastUpdateTime < GetMTime() || m_LastUpdateTime < GetDisplayGeometry()->GetMTime() ) { Update(); } else if (m_MapperID>=1 && m_MapperID < 6) Update(); // remove all text properties before mappers will add new ones m_TextRenderer->RemoveAllViewProps(); for ( unsigned int i=0; iDelete(); } m_TextCollection.clear(); // clear priority_queue m_MappersMap.clear(); int mapperNo = 0; //DataStorage if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID); if ( mapper.IsNull() ) continue; bool visible = true; node->GetVisibility(visible, this, "visible"); // The information about LOD-enabled mappers is required by RenderingManager if ( mapper->IsLODEnabled( this ) && visible ) { ++m_NumberOfVisibleLODEnabledMappers; } // mapper without a layer property get layer number 1 int layer = 1; node->GetIntProperty("layer", layer, this); int nr = (layer<<16) + mapperNo; m_MappersMap.insert( std::pair< int, Mapper * >( nr, mapper ) ); mapperNo++; } } -/*! -\brief - -Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) -*/ -void mitk::VtkPropRenderer::Enable2DOpenGL() -{ - GLint iViewport[4]; - - // Get a copy of the viewport - glGetIntegerv( GL_VIEWPORT, iViewport ); - - // Save a copy of the projection matrix so that we can restore it - // when it's time to do 3D rendering again. - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); - - // Set up the orthographic projection - const DisplayGeometry* displayGeometry = this->GetDisplayGeometry(); - - float displayGeometryWidth = displayGeometry->GetSizeInDisplayUnits()[0]; - float displayGeometryHeight = displayGeometry->GetSizeInDisplayUnits()[1]; - float viewportWidth = iViewport[2]; - float viewportHeight = iViewport[3]; - - /* - The following makes OpenGL mappers draw into the same viewport - that is used by VTK when someone calls vtkRenderer::SetViewport(). - - The parameters of glOrtho describe what "input" coordinates - (display coordinates generated by the OpenGL mappers) are transformed - into the region defined by the viewport. The call has to consider - that the scene is fit vertically and centered horizontally. - - Problem: this is a crude first step towards rendering into viewports. - - mitkViewportRenderingTest demonstrates the non-interactive rendering - that is now possible - - interactors that measure mouse movement in pixels will - probably run into problems with display-to-world transformation - - A proper solution should probably modify the DisplayGeometry to - correctly describe the viewport. - */ - // iViewport is (x,y,width,height) - // glOrtho expects (left,right,bottom,top,znear,zfar) - glOrtho( 0 - - 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight - + 0.5 * (displayGeometryWidth - displayGeometryHeight) - , - displayGeometryWidth - + 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight - - 0.5 * (displayGeometryWidth - displayGeometryHeight) - , - 0, displayGeometryHeight, - -1.0, 1.0 - ); - - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadIdentity(); - - // Make sure depth testing and lighting are disabled for 2D rendering until - // we are finished rendering in 2D - glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_LIGHTING ); - // disable the texturing here so crosshair is painted in the correct colors - // vtk will reenable texturing every time it is needed - glDisable( GL_TEXTURE_1D ); - glDisable( GL_TEXTURE_2D ); - glLineWidth(1.0); -} - -/*! -\brief Initialize the VtkPropRenderer - -Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) -*/ -void mitk::VtkPropRenderer::Disable2DOpenGL() -{ - glPopAttrib(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); -} - void mitk::VtkPropRenderer::Update(mitk::DataNode* datatreenode) { if(datatreenode!=NULL) { mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID); if(mapper.IsNotNull()) { - GLMapper* glmapper=dynamic_cast(mapper.GetPointer()); - if(GetDisplayGeometry()->IsValid()) { - if(glmapper != NULL) - { - glmapper->Update(this); - m_VtkMapperPresent=false; - } - else + mapper->Update(this); { VtkMapper* vtkmapper=dynamic_cast(mapper.GetPointer()); if(vtkmapper != NULL) { - vtkmapper->Update(this); vtkmapper->UpdateVtkTransform(this); - m_VtkMapperPresent=true; } } } } } } void mitk::VtkPropRenderer::Update() { if( m_DataStorage.IsNull() ) return; - m_VtkMapperPresent = false; mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) Update(it->Value()); Modified(); m_LastUpdateTime = GetMTime(); } /*! \brief This method is called from the two Constructors */ void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow* renderWindow) { BaseRenderer::InitRenderer(renderWindow); if(renderWindow == NULL) { m_InitNeeded = false; m_ResizeNeeded = false; return; } m_InitNeeded = true; m_ResizeNeeded = true; m_LastUpdateTime = 0; } /*! \brief Resize the OpenGL Window */ void mitk::VtkPropRenderer::Resize(int w, int h) { BaseRenderer::Resize(w, h); m_RenderingManager->RequestUpdate(this->GetRenderWindow()); } void mitk::VtkPropRenderer::InitSize(int w, int h) { m_RenderWindow->SetSize(w,h); Superclass::InitSize(w, h); Modified(); Update(); if(m_VtkRenderer!=NULL) { int w=vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); m_VtkRenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } } void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId) { if(m_MapperID != mapperId) Superclass::SetMapperID(mapperId); // Workaround for GL Displaylist Bug checkState(); } /*! \brief Activates the current renderwindow. */ void mitk::VtkPropRenderer::MakeCurrent() { if(m_RenderWindow!=NULL) m_RenderWindow->MakeCurrent(); } void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const { - if(m_VtkMapperPresent) + switch ( m_PickingMode ) { - //m_WorldPointPicker->SetTolerance (0.0001); - switch ( m_PickingMode ) - { - case (WorldPointPicking) : - { - m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); - vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); - break; - } - case (PointPicking) : - { - // create a new vtkRenderer - // give it all necessary information (camera position, etc.) - // get all surfaces from datastorage, get actors from them - // add all those actors to the new renderer - // give this new renderer to pointpicker - /* - vtkRenderer* pickingRenderer = vtkRenderer::New(); - pickingRenderer->SetActiveCamera( ); - - DataStorage* dataStorage = m_DataStorage; - TNodePredicateDataType isSurface; - - DataStorage::SetOfObjects::ConstPointer allSurfaces = dataStorage->GetSubset( isSurface ); - MITK_INFO << "in picking: got " << allSurfaces->size() << " surfaces." << std::endl; - - for (DataStorage::SetOfObjects::const_iterator iter = allSurfaces->begin(); - iter != allSurfaces->end(); - ++iter) - { - const DataNode* currentNode = *iter; - VtkMapper3D* baseVtkMapper3D = dynamic_cast( currentNode->GetMapper( BaseRenderer::Standard3D ) ); - if ( baseVtkMapper3D ) - { - vtkActor* actor = dynamic_cast( baseVtkMapper3D->GetViewProp() ); - if (actor) - { - MITK_INFO << "a" << std::flush; - pickingRenderer->AddActor( actor ); - } - } - } - - MITK_INFO << ";" << std::endl; - */ - m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); - vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); - break; - } - case(CellPicking) : - { - m_CellPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); - vtk2itk(m_CellPicker->GetPickPosition(), worldPoint); - break; - } - } + case (WorldPointPicking) : + { + m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); + vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); + break; } - else + case (PointPicking) : + { + m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); + vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); + break; + } + case(CellPicking) : { - Superclass::PickWorldPoint(displayPoint, worldPoint); + m_CellPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); + vtk2itk(m_CellPicker->GetPickPosition(), worldPoint); + break; + } } + //todo: is this picking in 2D renderwindows? + // Superclass::PickWorldPoint(displayPoint, worldPoint); } mitk::DataNode * - mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const +mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const { - if ( m_VtkMapperPresent ) - { - m_CellPicker->InitializePickList(); - - // Iterate over all DataStorage objects to determine all vtkProps intended - // for picking - DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); - for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); - it != allObjects->End(); - ++it ) - { - DataNode *node = it->Value(); - if ( node == NULL ) - continue; - - bool pickable = false; - node->GetBoolProperty( "pickable", pickable ); - if ( !pickable ) - continue; + m_CellPicker->InitializePickList(); - VtkMapper *mapper = dynamic_cast < VtkMapper * > ( node->GetMapper( m_MapperID ) ); - if ( mapper == NULL ) - continue; + // Iterate over all DataStorage objects to determine all vtkProps intended + // for picking + DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); + for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); + it != allObjects->End(); + ++it ) + { + DataNode *node = it->Value(); + if ( node == NULL ) + continue; - vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this ); - if ( prop == NULL ) - continue; + bool pickable = false; + node->GetBoolProperty( "pickable", pickable ); + if ( !pickable ) + continue; - m_CellPicker->AddPickList( prop ); - } + VtkMapper *mapper = dynamic_cast < VtkMapper * > ( node->GetMapper( m_MapperID ) ); + if ( mapper == NULL ) + continue; - // Do the picking and retrieve the picked vtkProp (if any) - m_CellPicker->PickFromListOn(); - m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer ); - m_CellPicker->PickFromListOff(); + vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this ); + if ( prop == NULL ) + continue; - vtk2itk( m_CellPicker->GetPickPosition(), worldPosition ); - vtkProp *prop = m_CellPicker->GetViewProp(); + m_CellPicker->AddPickList( prop ); + } - if ( prop == NULL ) - { - return NULL; - } + // Do the picking and retrieve the picked vtkProp (if any) + m_CellPicker->PickFromListOn(); + m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer ); + m_CellPicker->PickFromListOff(); - // Iterate over all DataStorage objects to determine if the retrieved - // vtkProp is owned by any associated mapper. - for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); - it != allObjects->End(); - ++it) - { - DataNode::Pointer node = it->Value(); - if ( node.IsNull() ) - continue; - - mitk::Mapper * mapper = node->GetMapper( m_MapperID ); - if ( mapper == NULL) - continue; - - mitk::VtkMapper * vtkmapper = dynamic_cast< VtkMapper * >(mapper); - - if(vtkmapper){ - //if vtk-based, then ... - if ( vtkmapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) ) - { - return node; - } - } - } + vtk2itk( m_CellPicker->GetPickPosition(), worldPosition ); + vtkProp *prop = m_CellPicker->GetViewProp(); + if ( prop == NULL ) + { return NULL; } - else + + // Iterate over all DataStorage objects to determine if the retrieved + // vtkProp is owned by any associated mapper. + for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); + it != allObjects->End(); + ++it) { - return Superclass::PickObject( displayPosition, worldPosition ); + DataNode::Pointer node = it->Value(); + if ( node.IsNull() ) + continue; + + mitk::Mapper * mapper = node->GetMapper( m_MapperID ); + if ( mapper == NULL) + continue; + + mitk::VtkMapper * vtkmapper = dynamic_cast< VtkMapper * >(mapper); + + if(vtkmapper){ + //if vtk-based, then ... + if ( vtkmapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) ) + { + return node; + } + } } -}; + return NULL; +} +//todo: is this 2D renderwindow picking? +// return Superclass::PickObject( displayPosition, worldPosition ); -/*! -\brief Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function -in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. -*/ int mitk::VtkPropRenderer::WriteSimpleText(std::string text, double posX, double posY, double color1, double color2, double color3, float opacity) { + this->GetVtkRenderer()->ViewToDisplay(); if(!text.empty()) { Point2D p; p[0] = posX; p[1] = posY; p = TransformOpenGLPointToViewport(p); vtkTextActor* textActor = vtkTextActor::New(); textActor->SetPosition(p[0], p[1]); textActor->SetInput(text.c_str()); textActor->SetTextScaleModeToNone(); textActor->GetTextProperty()->SetColor(color1, color2, color3); //TODO: Read color from node property textActor->GetTextProperty()->SetOpacity( opacity ); int text_id = m_TextCollection.size(); m_TextCollection.insert(TextMapType::value_type(text_id,textActor)); return text_id; } else { return -1; } } -/*! -\brief Can be used in order to get a vtkTextProperty for a specific text_id. This property enables the setup of font, font size, etc. -*/ vtkTextProperty* mitk::VtkPropRenderer::GetTextLabelProperty(int text_id) { return this->m_TextCollection[text_id]->GetTextProperty(); } void mitk::VtkPropRenderer::InitPathTraversal() { if (m_DataStorage.IsNotNull()) { m_PickingObjects = m_DataStorage->GetAll(); m_PickingObjectsIterator = m_PickingObjects->begin(); } } int mitk::VtkPropRenderer::GetNumberOfPaths() { - if (m_DataStorage.IsNull()) { - return 0; - } + if (m_DataStorage.IsNull()) { + return 0; + } - int nPaths = 0; - DataStorage::SetOfObjects::ConstPointer objects = m_DataStorage->GetAll(); - for (DataStorage::SetOfObjects::const_iterator iter = objects->begin(); iter != objects->end(); ++iter) { - Mapper* mapper = (*iter)->GetMapper(BaseRenderer::Standard3D); - if (mapper) + int nPaths = 0; + DataStorage::SetOfObjects::ConstPointer objects = m_DataStorage->GetAll(); + for (DataStorage::SetOfObjects::const_iterator iter = objects->begin(); iter != objects->end(); ++iter) { + Mapper* mapper = (*iter)->GetMapper(BaseRenderer::Standard3D); + if (mapper) + { + VtkMapper* vtkmapper = dynamic_cast(mapper); + if (vtkmapper) + { + vtkProp* prop = vtkmapper->GetVtkProp(this); + if (prop && prop->GetVisibility()) { - VtkMapper* vtkmapper = dynamic_cast(mapper); - if (vtkmapper) - { - vtkProp* prop = vtkmapper->GetVtkProp(this); - if (prop && prop->GetVisibility()) - { - ++nPaths; - } - } + ++nPaths; } + } } + } - return nPaths; + return nPaths; } vtkAssemblyPath* mitk::VtkPropRenderer::GetNextPath() { if (m_DataStorage.IsNull() ) { return NULL; } if ( m_PickingObjectsIterator == m_PickingObjects->end() ) { return NULL; } vtkAssemblyPath* returnPath = vtkAssemblyPath::New(); - //returnPath->Register(NULL); bool success = false; while (!success) { // loop until AddNode can be called successfully const DataNode* node = *m_PickingObjectsIterator; if (node) { Mapper* mapper = node->GetMapper( BaseRenderer::Standard3D ); if (mapper) { VtkMapper* vtkmapper = dynamic_cast( mapper ); if (vtkmapper) { vtkProp* prop = vtkmapper->GetVtkProp(this); if ( prop && prop->GetVisibility() ) { // add to assembly path returnPath->AddNode( prop, prop->GetMatrix() ); success = true; } } } } ++m_PickingObjectsIterator; if ( m_PickingObjectsIterator == m_PickingObjects->end() ) break; } if ( success ) { return returnPath; } else { return NULL; } } void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow* /*renWin*/) { if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::const_iterator iter = allObjects->begin(); iter != allObjects->end(); ++iter) { DataNode::Pointer node = *iter; if ( node.IsNull() ) continue; - Mapper * mapper = node->GetMapper(m_MapperID); + Mapper * mapper = node->GetMapper(m_MapperID); - if (mapper) - { - VtkMapper* vtkmapper = dynamic_cast( mapper ); + if (mapper) + { + VtkMapper* vtkmapper = dynamic_cast( mapper ); - if(vtkmapper) - vtkmapper->ReleaseGraphicsResources(this); - } - } + if(vtkmapper) + vtkmapper->ReleaseGraphicsResources(this); + } + } } const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const { return m_WorldPointPicker; } const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const { return m_PointPicker; } const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const { return m_CellPicker; } mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const { return m_MappersMap; } // Workaround for GL Displaylist bug - static int glWorkAroundGlobalCount = 0; bool mitk::VtkPropRenderer::useImmediateModeRendering() { return glWorkAroundGlobalCount>1; } void mitk::VtkPropRenderer::checkState() { if (m_MapperID == Standard3D) { if (!didCount) { didCount = true; glWorkAroundGlobalCount++; if (glWorkAroundGlobalCount == 2) { MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOn(); } - //MITK_INFO << "GLOBAL 3D INCREASE " << glWorkAroundGlobalCount << "\n"; } } else { if(didCount) { didCount=false; glWorkAroundGlobalCount--; if(glWorkAroundGlobalCount==1) { MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOff(); } - //MITK_INFO << "GLOBAL 3D DECREASE " << glWorkAroundGlobalCount << "\n"; } } } //### Contains all methods which are neceassry before each VTK Render() call void mitk::VtkPropRenderer::PrepareRender() { if ( this->GetMapperID() != m_CameraInitializedForMapperID ) { Initialize2DvtkCamera(); //Set parallel projection etc. } AdjustCameraToScene(); //Prepare camera for 2D render windows } bool mitk::VtkPropRenderer::Initialize2DvtkCamera() { if ( this->GetMapperID() == Standard3D ) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false); vtkSmartPointer style = vtkSmartPointer::New(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); m_CameraInitializedForMapperID = Standard3D; } else if( this->GetMapperID() == Standard2D) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); //turn the light out in the scene in order to render correct grey values. //TODO Implement a property for light in the 2D render windows (in another method) this->GetVtkRenderer()->RemoveAllLights(); vtkSmartPointer style = vtkSmartPointer::New(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); m_CameraInitializedForMapperID = Standard2D; } return true; } void mitk::VtkPropRenderer::AdjustCameraToScene(){ if(this->GetMapperID() == Standard2D) { const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry(); double objectHeightInMM = this->GetCurrentWorldPlaneGeometry()->GetExtentInMM(1);//the height of the current object slice in mm double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in) double zoomFactor = objectHeightInMM/displayHeightInMM; //displayGeometry->GetScaleFactorMMPerDisplayUnit() //determine how much of the object can be displayed Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin) Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2) //Scale the rendered object: //The image is scaled by a single factor, because in an orthographic projection sizes //are preserved (so you cannot scale X and Y axis with different parameters). The //parameter sets the size of the total display-volume. If you set this to the image //height, the image plus a border with the size of the image will be rendered. //Therefore, the size is imageHeightInMM / 2. this->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(objectHeightInMM*0.5 ); //zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely. this->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor); //the center of the view-plane double viewPlaneCenter[3]; viewPlaneCenter[0] = displayGeometryCenterInMM[0]; viewPlaneCenter[1] = displayGeometryCenterInMM[1]; viewPlaneCenter[2] = 0.0; //the view-plane is located in the XY-plane with Z=0.0 //define which direction is "up" for the ciamera (like default for vtk (0.0, 1.0, 0.0) double cameraUp[3]; cameraUp[0] = 0.0; cameraUp[1] = 1.0; cameraUp[2] = 0.0; //the position of the camera (center[0], center[1], 900000) double cameraPosition[3]; cameraPosition[0] = viewPlaneCenter[0]; cameraPosition[1] = viewPlaneCenter[1]; cameraPosition[2] = 900000.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. //set the camera corresponding to the textured plane vtkSmartPointer camera = this->GetVtkRenderer()->GetActiveCamera(); if (camera) { camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal) camera->SetFocalPoint( viewPlaneCenter ); //set the focal point to the center of the textured plane camera->SetViewUp( cameraUp ); //set the view-up for the camera - // double distance = sqrt((cameraPosition[2]-viewPlaneCenter[2])*(cameraPosition[2]-viewPlaneCenter[2])); - // camera->SetClippingRange(distance-50, distance+50); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. camera->SetClippingRange(0.1, 1000000); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. } const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( this->GetCurrentWorldPlaneGeometry() ); const AbstractTransformGeometry *abstractTransformGeometry = dynamic_cast< const AbstractTransformGeometry * >( planeGeometry ); if ( planeGeometry != NULL && !abstractTransformGeometry) { //Transform the camera to the current position (transveral, coronal and saggital plane). //This is necessary, because the SetUserTransform() method does not manipulate the vtkCamera. //(Without not all three planes would be visible). vtkSmartPointer trans = vtkSmartPointer::New(); vtkSmartPointer matrix = vtkSmartPointer::New(); Point3D origin; Vector3D right, bottom, normal; origin = planeGeometry->GetOrigin(); right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace) bottom = planeGeometry->GetAxisVector( 1 ); normal = planeGeometry->GetNormal(); right.Normalize(); bottom.Normalize(); normal.Normalize(); matrix->SetElement(0, 0, right[0]); matrix->SetElement(1, 0, right[1]); matrix->SetElement(2, 0, right[2]); matrix->SetElement(0, 1, bottom[0]); matrix->SetElement(1, 1, bottom[1]); matrix->SetElement(2, 1, bottom[2]); matrix->SetElement(0, 2, normal[0]); matrix->SetElement(1, 2, normal[1]); matrix->SetElement(2, 2, normal[2]); matrix->SetElement(0, 3, origin[0]); matrix->SetElement(1, 3, origin[1]); matrix->SetElement(2, 3, origin[2]); matrix->SetElement(3, 0, 0.0); matrix->SetElement(3, 1, 0.0); matrix->SetElement(3, 2, 0.0); matrix->SetElement(3, 3, 1.0); trans->SetMatrix(matrix); //Transform the camera to the current position (transveral, coronal and saggital plane). this->GetVtkRenderer()->GetActiveCamera()->ApplyTransform(trans); } } } mitk::Point2D mitk::VtkPropRenderer::TransformOpenGLPointToViewport( mitk::Point2D point ) { - GLint iViewport[4]; - // Get a copy of the viewport - glGetIntegerv( GL_VIEWPORT, iViewport ); + double* iViewport = this->GetVtkRenderer()->GetViewport(); + const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry(); float displayGeometryWidth = displayGeometry->GetSizeInDisplayUnits()[0]; float displayGeometryHeight = displayGeometry->GetSizeInDisplayUnits()[1]; - float viewportWidth = iViewport[2]; - float viewportHeight = iViewport[3]; // seemingly right + float viewportWidth = (iViewport[2]-iViewport[0]) * displayGeometryWidth; + float viewportHeight = (iViewport[3]-iViewport[1]) * displayGeometryHeight; // seemingly right - float zoom = viewportHeight / displayGeometryHeight; + float zoom = (iViewport[3]-iViewport[1]); - // see glOrtho call above for more explanation point[0] += 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight - 0.5 * (displayGeometryWidth - displayGeometryHeight) ; point[0] *= zoom; point[1] *= zoom; - return point; } diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.h b/Core/Code/Rendering/mitkVtkPropRenderer.h index 14b82fde55..76aef84329 100644 --- a/Core/Code/Rendering/mitkVtkPropRenderer.h +++ b/Core/Code/Rendering/mitkVtkPropRenderer.h @@ -1,258 +1,265 @@ /*=================================================================== 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 MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D -#define MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D +#ifndef mitkVtkPropRenderer_h +#define mitkVtkPropRenderer_h #include #include "mitkBaseRenderer.h" -#include "mitkDataStorage.h" -#include "mitkRenderingManager.h" - +#include +#include #include #include #include class vtkRenderWindow; class vtkLight; class vtkLightKit; class vtkWorldPointPicker; class vtkPointPicker; class vtkCellPicker; class vtkTextActor; class vtkTextProperty; class vtkAssemblyPath; namespace mitk { class Mapper; /*! \brief VtkPropRenderer VtkPropRenderer organizes the MITK rendering process. The MITK rendering process is completely integrated into the VTK rendering pipeline. The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes. VtkPropRenderer replaces the old OpenGLRenderer. \sa rendering \ingroup rendering */ class MITK_CORE_EXPORT VtkPropRenderer : public BaseRenderer { // Workaround for Displaylistbug private: bool didCount; void checkState(); // Workaround END public: mitkClassMacro(VtkPropRenderer,BaseRenderer); mitkNewMacro3Param(VtkPropRenderer, const char*, vtkRenderWindow *, mitk::RenderingManager* ); mitkNewMacro4Param(VtkPropRenderer, const char*, vtkRenderWindow *, mitk::RenderingManager*, mitk::BaseRenderer::RenderingMode::Type ); typedef std::map MappersMapType; // Render - called by vtkMitkRenderProp, returns the number of props rendered enum RenderType{Opaque,Translucent,Overlay,Volumetric}; int Render(RenderType type); /** \brief This methods contains all method neceassary before a VTK Render() call */ virtual void PrepareRender(); // Active current renderwindow virtual void MakeCurrent(); virtual void SetDataStorage( mitk::DataStorage* storage ); ///< set the datastorage that will be used for rendering virtual void InitRenderer(vtkRenderWindow* renderwindow); virtual void Update(mitk::DataNode* datatreenode); virtual void SetMapperID(const MapperSlotId mapperId); // Size virtual void InitSize(int w, int h); virtual void Resize(int w, int h); // Picking enum PickingMode{ WorldPointPicking, PointPicking, CellPicking}; /** \brief Set the picking mode. This method is used to set the picking mode for 3D object picking. The user can select one of the three options WorldPointPicking, PointPicking and CellPicking. The first option uses the zBuffer from graphics rendering, the second uses the 3D points from the closest surface mesh, and the third option uses the cells of that mesh. The last option is the slowest, the first one the fastest. However, the first option cannot use transparent data object and the tolerance of the picked position to the selected point should be considered. PointPicking also need a tolerance around the picking position to select the closest point in the mesh. The CellPicker performs very well, if the foreground surface part (i.e. the surfacepart that is closest to the scene's cameras) needs to be picked. */ itkSetEnumMacro( PickingMode, PickingMode ); itkGetEnumMacro( PickingMode, PickingMode ); virtual void PickWorldPoint(const Point2D& displayPoint, Point3D& worldPoint) const; virtual mitk::DataNode *PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const; - // Simple text rendering method - int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0, float opacity = 1.0); - - vtkTextProperty * GetTextLabelProperty(int text_id); + /** + * @brief WriteSimpleText Write a text in a renderwindow. + * + * Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function +in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. + * + * @deprecatedSince{next_release} Please use mitkTextOverlay2D instead. + * See mitkTextOverlay2DRenderingTest for an example. + */ + DEPRECATED(int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0, float opacity = 1.0)); - // Initialization / geometry handling + /** + * @brief CGetTextLabelProperty an be used in order to get a vtkTextProperty for + * a specific text_id. This property enables the setup of font, font size, etc. + * @param text_id the id of the text property. + * @deprecatedSince{next_release} Please use mitkTextOverlay2D instead. + * See mitkTextOverlay2DRenderingTest for an example. + */ + DEPRECATED(vtkTextProperty* GetTextLabelProperty(int text_id)); /** This method calculates the bounds of the DataStorage (if it contains any * valid data), creates a geometry from these bounds and sets it as world * geometry of the renderer. * * Call this method to re-initialize the renderer to the current DataStorage * (e.g. after loading an additional dataset), to ensure that the view is * aligned correctly. */ virtual bool SetWorldGeometryToDataStorageBounds(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ void InitPathTraversal(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ vtkAssemblyPath* GetNextPath(); int GetNumberOfPaths(); const vtkWorldPointPicker *GetWorldPointPicker() const; const vtkPointPicker *GetPointPicker() const; const vtkCellPicker *GetCellPicker() const; /** * \brief Release vtk-based graphics resources. Called by * vtkMitkRenderProp::ReleaseGraphicsResources. */ virtual void ReleaseGraphicsResources(vtkWindow *renWin); MappersMapType GetMappersMap() const; static bool useImmediateModeRendering(); protected: VtkPropRenderer( const char* name = "VtkPropRenderer", vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm = NULL, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard ); virtual ~VtkPropRenderer(); virtual void Update(); /** \brief Convert display geometry coordinates to VTK coordinates. For use within WriteSimpleText: the input is display geometry coordinates but the text actor needs positions that fit in a specified viewport. Conversion is done in this method. */ mitk::Point2D TransformOpenGLPointToViewport( mitk::Point2D point ); private: /** \brief This method sets up the camera on the actor (e.g. an image) of all * 2D vtkRenderWindows. The view is centered; zooming and panning of VTK are called inside. * * \image html ImageMapperdisplayGeometry.png * * Similar to the textured plane of an image * (cf. void mitkImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, * double planeBounds[6])), the mitkDisplayGeometry defines a view plane (or * projection plane). This plane is used to set the camera parameters. The view plane * center (VC) is important for camera positioning (cf. the image above). * * The following figure shows the combination of the textured plane and the view plane. * * \image html cameraPositioning.png * * The view plane center (VC) is the center of the textured plane (C) and the focal point * (FP) at the same time. The FP defines the direction the camera faces. Since * the textured plane is always in the XY-plane and orthographic projection is applied, the * distance between camera and plane is theoretically irrelevant (because in the orthographic * projection the center of projection is at infinity and the size of objects depends only on * a scaling parameter). As a consequence, the direction of projection (DOP) is (0; 0; -1). * The camera up vector is always defined as (0; 1; 0). * * \warning Due to a VTK clipping bug the distance between textured plane and camera is really huge. * Otherwise, VTK would clip off some slices. Same applies for the clipping range size. * * \note The camera position is defined through the mitkDisplayGeometry. * This facilitates zooming and panning, because the display * geometry changes and the textured plane does not. * * \image html scaling.png * * The textured plane is scaled to fill the render window via * camera->SetParallelScale( imageHeightInMM / 2). In the orthographic projection all extends, * angles and sizes are preserved. Therefore, the image is scaled by one parameter which defines * the size of the rendered image. A higher value will result in smaller images. In order to render * just the whole image, the scale is set to half of the image height in worldcoordinates * (cf. the picture above). * * For zooming purposes, a factor is computed as follows: * factor = image height / display height (in worldcoordinates). * When the display geometry gets smaller (zoom in), the factor becomes bigger. When the display * geometry gets bigger (zoom out), the factor becomes smaller. The used VTK method * camera->Zoom( factor ) also works with an inverse scale. */ void AdjustCameraToScene(); - // switch between orthogonal opengl projection (2D rendering via mitk::GLMapper2D) and perspective projection (3D rendering) - void Enable2DOpenGL(); - void Disable2DOpenGL(); - // prepare all mitk::mappers for rendering void PrepareMapperQueue(); /** \brief Set parallel projection, remove the interactor and the lights of VTK. */ bool Initialize2DvtkCamera(); bool m_InitNeeded; bool m_ResizeNeeded; - bool m_VtkMapperPresent; MapperSlotId m_CameraInitializedForMapperID; // Picking vtkWorldPointPicker * m_WorldPointPicker; vtkPointPicker * m_PointPicker; vtkCellPicker * m_CellPicker; PickingMode m_PickingMode; // Explicit use of SmartPointer to avoid circular #includes itk::SmartPointer< mitk::Mapper > m_CurrentWorldPlaneGeometryMapper; vtkLightKit* m_LightKit; // sorted list of mappers MappersMapType m_MappersMap; // rendering of text vtkRenderer * m_TextRenderer; typedef std::map TextMapType; TextMapType m_TextCollection; DataStorage::SetOfObjects::ConstPointer m_PickingObjects; DataStorage::SetOfObjects::const_iterator m_PickingObjectsIterator; }; } // namespace mitk -#endif /* MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D */ +#endif /* mitkVtkPropRenderer_h */ diff --git a/Core/Code/Rendering/vtkMitkRectangleProp.cpp b/Core/Code/Rendering/vtkMitkRectangleProp.cpp index 2dcfce782e..09cc21b5c2 100644 --- a/Core/Code/Rendering/vtkMitkRectangleProp.cpp +++ b/Core/Code/Rendering/vtkMitkRectangleProp.cpp @@ -1,129 +1,120 @@ /*=================================================================== 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 "vtkMitkRectangleProp.h" -#include "vtkObjectFactory.h" -#include "mitkGL.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + vtkStandardNewMacro(vtkMitkRectangleProp); vtkMitkRectangleProp::vtkMitkRectangleProp() { + vtkSmartPointer mapper = vtkSmartPointer::New(); + m_RectangleActor = vtkSmartPointer::New(); + m_PolyData = vtkSmartPointer::New(); + + vtkSmartPointer lines = vtkSmartPointer::New(); + vtkSmartPointer points = vtkSmartPointer::New(); + + m_PolyData->SetPoints(points); + m_PolyData->SetLines(lines); + + this->CreateRectangle(); + + mapper->SetInputData(m_PolyData); + m_RectangleActor->SetMapper(mapper); } vtkMitkRectangleProp::~vtkMitkRectangleProp() { } -double *vtkMitkRectangleProp::GetBounds() +int vtkMitkRectangleProp::RenderOverlay(vtkViewport* viewport) { - return NULL; + double right = viewport->GetSize()[0]; + double top = viewport->GetSize()[1]; +// double bottom = 0.0; + double left = viewport->GetOrigin()[0] + 0.5; + double bottom = viewport->GetOrigin()[1] + 0.5; +// double left = 0.0; + double defaultDepth = 0.0; + + vtkSmartPointer points = m_PolyData->GetPoints(); + //change the corners to adapt the size of the renderwindow was resized + points->SetPoint(m_BottomLeft, left, bottom, defaultDepth); + points->SetPoint(m_TopLeft, left, top, defaultDepth); + points->SetPoint(m_TopRight, right, top, defaultDepth); + points->SetPoint(m_BottomRight, right, bottom, defaultDepth); + + //adapt color + m_RectangleActor->GetProperty()->SetColor( m_Color[0], m_Color[1], m_Color[2]); + + //render the actor + m_RectangleActor->RenderOverlay(viewport); + return 1; } -int vtkMitkRectangleProp::RenderOverlay(vtkViewport* /*viewport*/) +void vtkMitkRectangleProp::CreateRectangle() { - m_RenderWindow->MakeCurrent(); - - Enable2DOpenGL(); - - //make it nicer - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); - glDisable(GL_LINE_STIPPLE); - - //size and position - int * i = m_RenderWindow->GetSize(); - GLdouble bbox[8] = {0.f , 0.f, (double)i[0], 0.f, (double)i[0], (double)i[1], 0.f, (double)i[1]}; - - //render rectangle - glLineWidth(5.0f); - glBegin(GL_LINE_LOOP); - for (int j = 0; j < 4; j++) - { - glColor3f(m_Color[0],m_Color[1],m_Color[2]); - glVertex2dv(&bbox[2*j]); - } - glEnd(); - glLineWidth(1.0f); - - glDisable(GL_LINE_SMOOTH); - - Disable2DOpenGL(); - - return 1; + vtkSmartPointer points = m_PolyData->GetPoints(); + vtkSmartPointer lines = m_PolyData->GetLines(); + + //just some default values until a renderwindow/viewport is initialized + double bottom = 0.0; + double left = 0.0; + double right = 200.0; + double top = 200.0; + double defaultDepth = 0.0; + + //4 corner points + m_BottomLeft = points->InsertNextPoint(left, bottom, defaultDepth); + m_BottomRight = points->InsertNextPoint(right, bottom, defaultDepth); + m_TopLeft = points->InsertNextPoint(left, top, defaultDepth); + m_TopRight = points->InsertNextPoint(right, top, defaultDepth); + + vtkSmartPointer lineVtk = vtkSmartPointer::New(); + lineVtk->GetPointIds()->SetNumberOfIds(5); + //connect the lines + lineVtk->GetPointIds()->SetId(0,m_BottomLeft); + lineVtk->GetPointIds()->SetId(1,m_BottomRight); + lineVtk->GetPointIds()->SetId(2,m_TopRight); + lineVtk->GetPointIds()->SetId(3,m_TopLeft); + lineVtk->GetPointIds()->SetId(4,m_BottomLeft); + + lines->InsertNextCell(lineVtk); } -void vtkMitkRectangleProp::SetRenderWindow(vtkRenderWindow* renWin) +void vtkMitkRectangleProp::SetRenderWindow(vtkSmartPointer renWin) { m_RenderWindow = renWin; } void vtkMitkRectangleProp::SetColor(float col1, float col2, float col3) { m_Color[0] = col1; m_Color[1] = col2; m_Color[2] = col3; } - - -int vtkMitkRectangleProp::RenderTranslucentGeometry(vtkViewport* /*viewport*/) -{ - return 0; -} - -int vtkMitkRectangleProp::RenderOpaqueGeometry(vtkViewport* /*viewport*/) -{ - return 0; -} - -void vtkMitkRectangleProp::Enable2DOpenGL() -{ - GLint iViewport[4]; - - // Get a copy of the viewport - glGetIntegerv( GL_VIEWPORT, iViewport ); - - // Save a copy of the projection matrix so that we can restore it - // when it's time to do 3D rendering again. - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); - - // Set up the orthographic projection - glOrtho( iViewport[0], iViewport[0]+iViewport[2], - iViewport[1]+iViewport[3], iViewport[1], -1, 1 ); - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadIdentity(); - - // Make sure depth testing and lighting are disabled for 2D rendering until - // we are finished rendering in 2D - glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT | GL_TEXTURE_2D); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_LIGHTING ); - glDisable( GL_TEXTURE_2D ); -} - -void vtkMitkRectangleProp::Disable2DOpenGL() -{ - glPopAttrib(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); -} - diff --git a/Core/Code/Rendering/vtkMitkRectangleProp.h b/Core/Code/Rendering/vtkMitkRectangleProp.h index b99158283f..642390d929 100644 --- a/Core/Code/Rendering/vtkMitkRectangleProp.h +++ b/Core/Code/Rendering/vtkMitkRectangleProp.h @@ -1,56 +1,95 @@ /*=================================================================== 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 vtkMitkRectangleProp_h +#define vtkMitkRectangleProp_h -#ifndef vtkMitkRectangleProp_H_HEADER_INCLUDED_C1C53723 -#define vtkMitkRectangleProp_H_HEADER_INCLUDED_C1C53723 - -#include "vtkActor2D.h" -#include "vtkRenderWindow.h" #include -class MITK_CORE_EXPORT vtkMitkRectangleProp : public vtkProp -{ - public: - static vtkMitkRectangleProp* New(); - vtkTypeMacro(vtkMitkRectangleProp,vtkProp); - - int RenderOpaqueGeometry(vtkViewport* viewport); - int RenderTranslucentGeometry(vtkViewport* viewport); - int RenderOverlay(vtkViewport* viewport); - - void SetRenderWindow(vtkRenderWindow* renWin); - - void SetColor(float col1, float col2, float col3); - - double* GetBounds(); - - protected: +#include +#include +#include - vtkMitkRectangleProp(); - virtual ~vtkMitkRectangleProp(); +class vtkActor2D; +class vtkPolyData; - void Enable2DOpenGL(); - void Disable2DOpenGL(); - - vtkRenderWindow* m_RenderWindow; - float m_Color[3]; +/** + * @brief The vtkMitkRectangleProp2 class Renders a rectangle into a renderwindow as a frame. + * + * This class is a replacement for the deprecated vtkMitkRectangleProp, which + * used to render the same effect with pure OpenGL. + */ +class MITK_EXPORT vtkMitkRectangleProp : public vtkProp +{ +public: + static vtkMitkRectangleProp* New(); + vtkTypeMacro(vtkMitkRectangleProp,vtkProp); + + /** + * @brief RenderOverlay Calls the render method of the actor and renders it. + * @param viewport viewport of the renderwindow. + * @return + */ + int RenderOverlay(vtkViewport* viewport); + + /** + * @brief SetRenderWindow Set the renderwindow. + * @param renWin + */ + void SetRenderWindow(vtkSmartPointer renWin); + + /** + * @brief SetColor Set the color of the rectangle. + * @param col1 red + * @param col2 green + * @param col3 blue + */ + void SetColor(float col1, float col2, float col3); + +protected: + + vtkMitkRectangleProp(); + virtual ~vtkMitkRectangleProp(); + + /** + * @brief m_RenderWindow renderwindow to add the rectangle to. + */ + vtkSmartPointer m_RenderWindow; + + /** + * @brief m_Color color of the rectangle. + */ + float m_Color[3]; + + /** + * @brief CreateRectangle internal helper to fill a vtkPolydata with a rectangle. + */ + void CreateRectangle(); + /** + * @brief m_PolyData holds the rectangle. + */ + vtkSmartPointer m_PolyData; + /** + * @brief m_RectangleActor actor to render the rectangle. + */ + vtkSmartPointer m_RectangleActor; + + /** + * @brief IDs of the corner points (the corners of the renderwindow). + */ + vtkIdType m_BottomLeft, m_BottomRight, m_TopRight, m_TopLeft; }; - - -#endif /* vtkMitkRectangleProp_H_HEADER_INCLUDED_C1C53723 */ - - +#endif /* vtkMitkRectangleProp_h */ diff --git a/Core/Code/Rendering/vtkMitkRenderProp.cpp b/Core/Code/Rendering/vtkMitkRenderProp.cpp index f696f2c7ea..d650910aad 100644 --- a/Core/Code/Rendering/vtkMitkRenderProp.cpp +++ b/Core/Code/Rendering/vtkMitkRenderProp.cpp @@ -1,113 +1,113 @@ /*=================================================================== 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 "vtkMitkRenderProp.h" #include #include #include #include "mitkVtkMapper.h" -#include "mitkGLMapper.h" +//#include "mitkGLMapper.h" vtkStandardNewMacro(vtkMitkRenderProp); vtkMitkRenderProp::vtkMitkRenderProp() { } vtkMitkRenderProp::~vtkMitkRenderProp() { } double *vtkMitkRenderProp::GetBounds() { return const_cast(m_VtkPropRenderer->GetBounds()); } void vtkMitkRenderProp::SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer) { this->m_VtkPropRenderer = propRenderer; } int vtkMitkRenderProp::RenderOpaqueGeometry(vtkViewport* /*viewport*/) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Opaque); } int vtkMitkRenderProp::RenderOverlay(vtkViewport* /*viewport*/) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Overlay); } void vtkMitkRenderProp::ReleaseGraphicsResources(vtkWindow* window) { m_VtkPropRenderer->ReleaseGraphicsResources(window); } void vtkMitkRenderProp::InitPathTraversal() { m_VtkPropRenderer->InitPathTraversal(); } vtkAssemblyPath* vtkMitkRenderProp::GetNextPath() { return m_VtkPropRenderer->GetNextPath(); } int vtkMitkRenderProp::GetNumberOfPaths() { return m_VtkPropRenderer->GetNumberOfPaths(); } //BUG (#1551) added method depth peeling int vtkMitkRenderProp::HasTranslucentPolygonalGeometry() { typedef std::map MappersMapType; MappersMapType mappersMap = m_VtkPropRenderer->GetMappersMap(); for(MappersMapType::iterator it = mappersMap.begin(); it != mappersMap.end(); it++) { mitk::Mapper * mapper = (*it).second; mitk::VtkMapper::Pointer vtkMapper = dynamic_cast(mapper); if(vtkMapper) { // Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly // manually (see issue #8186 committed to VTK's Mantis issue tracker) // --> VTK bug resolved on 2008-12-01 vtkPropAssembly *propAssembly = dynamic_cast< vtkPropAssembly * >( vtkMapper->GetVtkProp(m_VtkPropRenderer) ); if ( propAssembly ) { propAssembly->InitPathTraversal(); } if (vtkMapper->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1) return 1; } } return 0; } int vtkMitkRenderProp::RenderTranslucentPolygonalGeometry( vtkViewport * ) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Translucent); } int vtkMitkRenderProp::RenderVolumetricGeometry( vtkViewport * ) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Volumetric); } diff --git a/Core/Code/Testing/CMakeLists.txt b/Core/Code/Testing/CMakeLists.txt index 7f5da021d8..05009260b1 100644 --- a/Core/Code/Testing/CMakeLists.txt +++ b/Core/Code/Testing/CMakeLists.txt @@ -1,242 +1,242 @@ # The core tests need relaxed compiler flags... # TODO fix core tests to compile without these additional no-error flags if(MSVC_VERSION) # disable deprecated warnings (they would lead to errors) mitkFunctionCheckCAndCXXCompilerFlags("/wd4996" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated-declarations" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() MITK_CREATE_MODULE_TESTS(US_MODULE) mitk_use_modules(TARGET ${TESTDRIVER} PACKAGES ITK|ITKThresholding) mitkAddCustomModuleTest(mitkVolumeCalculatorTest_Png2D-bw mitkVolumeCalculatorTest ${MITK_DATA_DIR}/Png2D-bw.png ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkEventMapperTest_Test1And2 mitkEventMapperTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml ) mitkAddCustomModuleTest(mitkEventConfigTest_CreateObjectInDifferentWays mitkEventConfigTest ${MITK_SOURCE_DIR}/Core/Code/Testing/Resources/Interactions/StatemachineConfigTest.xml ) mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/BallBinary30x30x30.nrrd ) mitkAddCustomModuleTest(mitkDataStorageTest_US4DCyl mitkDataStorageTest ${MITK_DATA_DIR}/US4DCyl.nrrd ) mitkAddCustomModuleTest(mitkStateMachineFactoryTest_TestStateMachine1_2 mitkStateMachineFactoryTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml ) mitkAddCustomModuleTest(mitkDicomSeriesReaderTest_CTImage mitkDicomSeriesReaderTest ${MITK_DATA_DIR}/TinyCTAbdomen ${MITK_DATA_DIR}/DICOMReader/Broken-Series ) mitkAddCustomModuleTest(mitkPointSetReaderTest mitkPointSetReaderTest ${MITK_DATA_DIR}/PointSetReaderTestData.mps ) mitkAddCustomModuleTest(mitkImageTest_4DImageData mitkImageTest ${MITK_DATA_DIR}/US4DCyl.nrrd ) mitkAddCustomModuleTest(mitkImageTest_2D+tImageData mitkImageTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkImageEqualTest mitkImageEqualTest) mitkAddCustomModuleTest(mitkImageTest_brainImage mitkImageTest ${MITK_DATA_DIR}/brain.mhd ) mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageGeneratorTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkLevelWindowManagerTest mitkLevelWindowManagerTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkMultiComponentImageDataComparisonFilterTest mitkMultiComponentImageDataComparisonFilterTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg ) mitkAddCustomModuleTest(mitkImageToItkTest mitkImageToItkTest ${MITK_DATA_DIR}/Pic3D.nrrd ) mitkAddCustomModuleTest(mitkImageSliceSelectorTest mitkImageSliceSelectorTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd ) if(MITK_ENABLE_RENDERING_TESTING) ### since the rendering test's do not run in ubuntu, yet, we build them only for other systems or if the user explicitly sets the variable MITK_ENABLE_RENDERING_TESTING mitkAddCustomModuleTest(mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/rgbaImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3d640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2DColorTest #test for color property (=blue) Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dColorBlue640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2DLevelWindowTest #test for levelwindow property (=blood) #Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dLevelWindowBlood640x480REF.png #corresponding reference #screenshot ) #mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dOpacity640x480 mitkImageVtkMapper2DOpacityTest #test for opacity (=0.5) Pic3D coronal slice # ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dOpacity640x480REF.png corresponding reference screenshot #) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DSwivelTest #test for a randomly chosen Pic3D swivelled slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dSwivel640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAlone640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2DImageTest ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/PointSetForPic3D.mps #input point set and image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Pic3DPointSetForPic3D640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2DGlyphTypeTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneGlyphType640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 mitkPointSetVtkMapper2DTransformedPointsTest ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneTransformedPoints640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkSurfaceDepthSortingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthSortingTest ${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthSorting640x480REF.png ) if(NOT APPLE) mitkAddCustomModuleTest(mitkSurfaceDepthPeelingTransparency_StanfordBunnySTL640x480 mitkSurfaceDepthPeelingTest ${MITK_DATA_DIR}/RenderingTestData/Stanford_bunny.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Stanford_bunnySTLDepthPeeling640x480REF.png #corresponding reference screenshot ) endif() #Test reslice interpolation #note: nearest mode is already tested by swivel test mitkAddCustomModuleTest(ResliceInterpolationIsLinear mitkImageVtkMapper2DResliceInterpolationPropertyTest 1 #linear ${MITK_DATA_DIR}/Pic3D.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefLinear.png #corresponding reference screenshot LINEAR ) mitkAddCustomModuleTest(ResliceInterpolationIsCubic mitkImageVtkMapper2DResliceInterpolationPropertyTest 3 #cubic ${MITK_DATA_DIR}/Pic3D.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefCubic.png #corresponding reference screenshot CUBIC ) #End test reslice interpolation # Testing of the rendering of binary images #mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImage640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice # ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImage640x480REF.png #corresponding reference screenshot #) #mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImageWithRef640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice # ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage # -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImageWithRef640x480REF.png #corresponding reference screenshot #) # End of binary image tests mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTest_TextureProperty mitkSurfaceVtkMapper3DTest ${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom.vtp ${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom_RGBImage.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedLiver640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-TransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2DOpacityTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DOpacityTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-OpacityTransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) -mitkAddCustomModuleTest(mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceGLMapper2DColorTest +mitkAddCustomModuleTest(mitkSurfaceVtkMapper2DColorTest_RedBall mitkSurfaceVtkMapper2DColorTest ${MITK_DATA_DIR}/ball.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/ballColorRed640x480REF.png #corresponding reference screenshot ) -mitkAddCustomModuleTest(mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest +mitkAddCustomModuleTest(mitkSurfaceVtkMapper2DColorTest_DasArmeSchwein mitkSurfaceVtkMapper2DColorTest ${MITK_DATA_DIR}/binary.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryColorRed640x480REF.png #corresponding reference screenshot ) -mitkAddCustomModuleTest(mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DOpacityTest #opacity = 50% (0.5) +mitkAddCustomModuleTest(mitkSurfaceVtkMapper2DOpacityTest_BallOpacity mitkSurfaceVtkMapper2DOpacityTest #opacity = 50% (0.5) ${MITK_DATA_DIR}/ball.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/ballOpacity640x480REF.png #corresponding reference screenshot ) ############################## DISABLED TESTS #Removed due to high rendering error. #mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTexturedSphereTest_Football mitkSurfaceVtkMapper3DTexturedSphereTest # ${MITK_DATA_DIR}/RenderingTestData/texture.jpg #input texture # -V # ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedSphere640x480REF.png corresponding reference screenshot #) mitkAddCustomModuleTest(mitkImageVtkMapper2DLookupTableTest_Png2D-bw mitkImageVtkMapper2DLookupTableTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-LookupTableRGBImage640x480REF.png #corresponding reference screenshot ) #mitkAddCustomModuleTest(mitkImageTest_color2DImage mitkImageTest # ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg #) #mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest # ${MITK_DATA_DIR}/Pic3D.pic.gz ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz #) SET_PROPERTY(TEST mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw # mitkImageVtkMapper2D_pic3dOpacity640x480 - mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceVtkMapper3DTest_TextureProperty mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 #mitkSurfaceVtkMapper3DTexturedSphereTest_Football + mitkSurfaceVtkMapper2DOpacityTest_BallOpacity mitkSurfaceVtkMapper2DColorTest_DasArmeSchwein mitkSurfaceVtkMapper2DColorTest_RedBall mitkSurfaceVtkMapper3DTest_TextureProperty mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2D_openMeAloneTransformed640x480 #mitkSurfaceVtkMapper3DTexturedSphereTest_Football PROPERTY RUN_SERIAL TRUE) endif() add_test(mitkPointSetLocaleTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkPointSetLocaleTest ${MITK_DATA_DIR}/pointSet.mps) set_property(TEST mitkPointSetLocaleTest PROPERTY LABELS MITK-Core) add_test(mitkImageWriterTest_nrrdImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg) add_test(mitkImageWriterTest_2DPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/Png2D-bw.png) add_test(mitkImageWriterTest_rgbPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/RenderingTestData/rgbImage.png) add_test(mitkImageWriterTest_rgbaPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png) set_property(TEST mitkImageWriterTest_nrrdImage PROPERTY LABELS MITK-Core) set_property(TEST mitkImageWriterTest_2DPNGImage PROPERTY LABELS MITK-Core) set_property(TEST mitkImageWriterTest_rgbPNGImage PROPERTY LABELS MITK-Core) set_property(TEST mitkImageWriterTest_rgbaPNGImage PROPERTY LABELS MITK-Core) add_subdirectory(DCMTesting) diff --git a/Core/Code/Testing/files.cmake b/Core/Code/Testing/files.cmake index 9f9cdaa198..80b985774a 100644 --- a/Core/Code/Testing/files.cmake +++ b/Core/Code/Testing/files.cmake @@ -1,190 +1,190 @@ # tests with no extra command line parameter set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## DISABLED TESTS ################################################# #mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesnt exist any more #mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529 #mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more #mitkSegmentationInterpolationTest.cpp #file doesn't exist! #mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist! #mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK #mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more #mitkTestUtilSharedLibrary.cpp #Linker problem with this test... #mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details. ################# RUNNING TESTS ################################################### mitkAccessByItkTest.cpp mitkCoreObjectFactoryTest.cpp mitkDataNodeTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkDispatcherTest.cpp mitkEnumerationPropertyTest.cpp mitkEventTest.cpp mitkFileReaderRegistryTest.cpp #mitkFileWriterRegistryTest.cpp mitkFocusManagerTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometry3DEqualTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkGlobalInteractionTest.cpp mitkImageCastTest.cpp mitkImageEqualTest.cpp mitkImageDataItemTest.cpp mitkImageGeneratorTest.cpp mitkIOUtilTest.cpp mitkBaseDataTest.cpp mitkImportItkImageTest.cpp mitkGrabItkImageMemoryTest.cpp mitkInstantiateAccessFunctionTest.cpp mitkInteractorTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetTest.cpp mitkPointSetEqualTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetOnEmptyTest.cpp mitkPointSetWriterTest.cpp mitkPointSetReaderTest.cpp mitkPointSetInteractorTest.cpp mitkPointSetPointOperationsTest.cpp mitkProgressBarTest.cpp mitkPropertyTest.cpp mitkPropertyListTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkStateMachineTest.cpp mitkStateTest.cpp mitkSurfaceTest.cpp mitkSurfaceEqualTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeGeometryTest.cpp mitkProportionalTimeGeometryTest.cpp mitkTransitionTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp mitkStepperTest.cpp mitkRenderingManagerTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp mitkVectorTest.cpp mitkClippedSurfaceBoundsCalculatorTest.cpp mitkExceptionTest.cpp mitkExtractSliceFilterTest.cpp mitkLogTest.cpp mitkImageDimensionConverterTest.cpp mitkLoggingAdapterTest.cpp mitkUIDGeneratorTest.cpp mitkShaderRepositoryTest.cpp mitkPlanePositionManagerTest.cpp mitkAffineTransformBaseTest.cpp mitkPropertyAliasesTest.cpp mitkPropertyDescriptionsTest.cpp mitkPropertyExtensionsTest.cpp mitkPropertyFiltersTest.cpp mitkTinyXMLTest.cpp mitkRawImageFileReaderTest.cpp mitkInteractionEventTest.cpp mitkLookupTableTest.cpp mitkSTLFileReaderTest.cpp mitkPointTypeConversionTest.cpp mitkVectorTypeConversionTest.cpp mitkMatrixTypeConversionTest.cpp mitkArrayTypeConversionTest.cpp mitkSurfaceToImageFilterTest.cpp mitkBaseGeometryTest.cpp mitkImageToSurfaceFilterTest.cpp mitkEqualTest.cpp mitkLineTest.cpp ) if(MITK_ENABLE_RENDERING_TESTING) #since mitkInteractionTestHelper is currently creating a vtkRenderWindow set(MODULE_TESTS ${MODULE_TESTS} mitkPointSetDataInteractorTest.cpp ) endif() # test with image filename as an extra command line parameter set(MODULE_IMAGE_TESTS mitkImageTimeSelectorTest.cpp #only runs on images mitkImageAccessorTest.cpp #only runs on images ) set(MODULE_SURFACE_TESTS mitkSurfaceVtkWriterTest.cpp #only runs on surfaces ) # list of images for which the tests are run set(MODULE_TESTIMAGES US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd Png2D-bw.png ) set(MODULE_TESTSURFACES binary.stl ball.stl ) set(MODULE_CUSTOM_TESTS mitkDataStorageTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkDataNodeTest.cpp mitkEventMapperTest.cpp mitkEventConfigTest.cpp mitkNodeDependentPointSetInteractorTest.cpp mitkStateMachineFactoryTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp mitkImageWriterTest.cpp mitkImageVtkMapper2DTest.cpp mitkImageVtkMapper2DLevelWindowTest.cpp mitkImageVtkMapper2DOpacityTest.cpp mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp mitkImageVtkMapper2DColorTest.cpp mitkImageVtkMapper2DSwivelTest.cpp mitkImageVtkMapper2DTransferFunctionTest.cpp mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp mitkImageVtkMapper2DLookupTableTest.cpp mitkSurfaceVtkMapper3DTest mitkSurfaceVtkMapper3DTexturedSphereTest.cpp - mitkSurfaceGLMapper2DColorTest.cpp - mitkSurfaceGLMapper2DOpacityTest.cpp + mitkSurfaceVtkMapper2DColorTest.cpp + mitkSurfaceVtkMapper2DOpacityTest.cpp mitkVolumeCalculatorTest.cpp mitkLevelWindowManagerTest.cpp mitkPointSetVtkMapper2DTest.cpp mitkPointSetVtkMapper2DImageTest.cpp mitkPointSetVtkMapper2DGlyphTypeTest.cpp mitkPointSetVtkMapper2DTransformedPointsTest.cpp mitkVTKRenderWindowSizeTest.cpp mitkMultiComponentImageDataComparisonFilterTest.cpp mitkImageToItkTest.cpp mitkImageSliceSelectorTest.cpp mitkSurfaceDepthPeelingTest.cpp mitkSurfaceDepthSortingTest.cpp ) set(RESOURCE_FILES Interactions/AddAndRemovePoints.xml Interactions/globalConfig.xml Interactions/StatemachineTest.xml Interactions/StatemachineConfigTest.xml ) diff --git a/Core/Code/Testing/mitkDataNodeTest.cpp b/Core/Code/Testing/mitkDataNodeTest.cpp index b2256ce24d..1824b9bb87 100644 --- a/Core/Code/Testing/mitkDataNodeTest.cpp +++ b/Core/Code/Testing/mitkDataNodeTest.cpp @@ -1,298 +1,281 @@ /*=================================================================== 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 "mitkDataNode.h" #include #include "mitkVtkPropRenderer.h" #include "mitkTestingMacros.h" #include "mitkGlobalInteraction.h" #include //Basedata Test -#include #include #include -#include #include #include #include #include //Mapper Test #include -#include #include -#include +#include #include #include #include #include #include //Interactors #include //Propertylist Test /** * Simple example for a test for the (non-existent) class "DataNode". * * argc and argv are the command line parameters which were passed to * the ADD_TEST command in the CMakeLists.txt file. For the automatic * tests, argv is either empty for the simple tests or contains the filename * of a test image for the image tests (see CMakeLists.txt). */ class mitkDataNodeTestClass { public: static void TestDataSetting(mitk::DataNode::Pointer dataNode) { mitk::BaseData::Pointer baseData; //NULL pointer Test dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" ) - baseData = mitk::RenderWindowFrame::New(); - dataNode->SetData(baseData); - MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a RenderWindowFrame object was set correctly" ) -// MITK_TEST_CONDITION( baseData->GetGeometry(0)->GetVtkTransform() == dataNode->GetVtkTransform(0), "Testing if a NULL pointer was set correctly" ) - baseData = mitk::GeometryData::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GeometryData object was set correctly" ) baseData = mitk::PlaneGeometryData::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PlaneGeometryData object was set correctly" ) - baseData = mitk::GradientBackground::New(); - dataNode->SetData(baseData); - MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GradientBackground object was set correctly" ) - baseData = mitk::ManufacturerLogo::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ManufacturerLogo object was set correctly" ) baseData = mitk::PointSet::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PointSet object was set correctly" ) baseData = mitk::Image::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Image object was set correctly" ) baseData = mitk::Surface::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Surface object was set correctly" ) } static void TestMapperSetting(mitk::DataNode::Pointer dataNode) { //tests the SetMapper() method //in dataNode is a mapper vector which can be accessed by index //in this test method we use only slot 0 (filled with null) and slot 1 //so we also test the destructor of the mapper classes mitk::Mapper::Pointer mapper; dataNode->SetMapper(0,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" ) mapper = mitk::PlaneGeometryDataMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PlaneGeometryDataMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::ImageVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ImageVtkMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::PointSetVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) - mapper = mitk::SurfaceGLMapper2D::New(); + mapper = mitk::SurfaceVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceGLMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::PlaneGeometryDataVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PlaneGeometryDataVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::PointSetVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SurfaceVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::VolumeDataVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a VolumeDataVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) - - //linker error - //mapper = mitk::LineVtkMapper3D::New(); - //dataNode->SetMapper(1,mapper); - //MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineVtkMapper3D was set correctly" ) - //MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) } + static void TestInteractorSetting(mitk::DataNode::Pointer dataNode) { //this method tests the SetInteractor() and GetInteractor methods //the DataInteractor base class calls the DataNode->SetInteractor method mitk::DataInteractor::Pointer interactor; MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a NULL pointer was set correctly (DataInteractor)" ) interactor = mitk::PointSetDataInteractor::New(); interactor->SetEventConfig("PointSetConfig.xml"); interactor->SetDataNode(dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" ) interactor = mitk::PointSetDataInteractor::New(); dataNode->SetDataInteractor(interactor); MITK_TEST_CONDITION( interactor == dataNode->GetDataInteractor(), "Testing if a PointSetDataInteractor was set correctly" ) } static void TestPropertyList(mitk::DataNode::Pointer dataNode) { mitk::PropertyList::Pointer propertyList = dataNode->GetPropertyList(); MITK_TEST_CONDITION(dataNode->GetPropertyList() != NULL, "Testing if the constructor set the propertylist" ) dataNode->SetIntProperty("int", -31337); int x; dataNode->GetIntProperty("int", x); MITK_TEST_CONDITION(x == -31337, "Testing Set/GetIntProperty"); dataNode->SetBoolProperty("bool", true); bool b; dataNode->GetBoolProperty("bool", b); MITK_TEST_CONDITION(b == true, "Testing Set/GetBoolProperty"); dataNode->SetFloatProperty("float", -31.337); float y; dataNode->GetFloatProperty("float", y); MITK_TEST_CONDITION(y - -31.337 < 0.01, "Testing Set/GetFloatProperty"); double yd = 0; dataNode->GetDoubleProperty("float", yd); MITK_TEST_CONDITION(mitk::Equal(yd, static_cast(y)), "Testing GetDoubleProperty"); dataNode->SetStringProperty("string", "MITK"); std::string s = "GANZVIELPLATZ"; dataNode->GetStringProperty("string", s); MITK_TEST_CONDITION(s == "MITK", "Testing Set/GetStringProperty"); std::string name = "MyTestName"; dataNode->SetName(name.c_str()); MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName"); name = "MySecondTestName"; dataNode->SetName(name); MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName(std::string)"); MITK_TEST_CONDITION(propertyList == dataNode->GetPropertyList(), "Testing if the propertylist has changed during the last tests" ) } static void TestSelected(mitk::DataNode::Pointer dataNode) { vtkRenderWindow *renderWindow = vtkRenderWindow::New(); mitk::VtkPropRenderer::Pointer base = mitk::VtkPropRenderer::New( "the first renderer", renderWindow, mitk::RenderingManager::GetInstance() ); //with BaseRenderer==Null MITK_TEST_CONDITION(!dataNode->IsSelected(), "Testing if this node is not set as selected" ) dataNode->SetSelected(true); MITK_TEST_CONDITION(dataNode->IsSelected(), "Testing if this node is set as selected" ) dataNode->SetSelected(false); dataNode->SetSelected(true,base); MITK_TEST_CONDITION(dataNode->IsSelected(base), "Testing if this node with right base renderer is set as selected" ) //Delete RenderWindow correctly renderWindow->Delete(); } static void TestGetMTime(mitk::DataNode::Pointer dataNode) { unsigned long time; time = dataNode->GetMTime(); mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); dataNode->SetData(pointSet); MITK_TEST_CONDITION( time != dataNode->GetMTime(), "Testing if the node timestamp is updated after adding data to the node" ) mitk::Point3D point; point.Fill(3.0); pointSet->SetPoint(0,point); //less or equal because dataNode timestamp is little later then the basedata timestamp MITK_TEST_CONDITION( pointSet->GetMTime() <= dataNode->GetMTime(), "Testing if the node timestamp is updated after base data was modified" ) // testing if changing anything in the property list also sets the node in a modified state unsigned long lastModified = dataNode->GetMTime(); dataNode->SetIntProperty("testIntProp", 2344); MITK_TEST_CONDITION( lastModified <= dataNode->GetMTime(), "Testing if the node timestamp is updated after property list was modified" ) } }; //mitkDataNodeTestClass int mitkDataNodeTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("DataNode") // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); // let's create an object of our class mitk::DataNode::Pointer myDataNode = mitk::DataNode::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation") //test setData() Method mitkDataNodeTestClass::TestDataSetting(myDataNode); mitkDataNodeTestClass::TestMapperSetting(myDataNode); // //note, that no data is set to the dataNode mitkDataNodeTestClass::TestInteractorSetting(myDataNode); mitkDataNodeTestClass::TestPropertyList(myDataNode); mitkDataNodeTestClass::TestSelected(myDataNode); mitkDataNodeTestClass::TestGetMTime(myDataNode); // write your own tests here and use the macros from mitkTestingMacros.h !!! // do not write to std::cout and do not return from this function yourself! // always end with this! MITK_TEST_END() } diff --git a/Core/Code/Testing/mitkSurfaceGLMapper2DColorTest.cpp b/Core/Code/Testing/mitkSurfaceVtkMapper2DColorTest.cpp similarity index 93% rename from Core/Code/Testing/mitkSurfaceGLMapper2DColorTest.cpp rename to Core/Code/Testing/mitkSurfaceVtkMapper2DColorTest.cpp index 174a5e98ac..7395d79a62 100644 --- a/Core/Code/Testing/mitkSurfaceGLMapper2DColorTest.cpp +++ b/Core/Code/Testing/mitkSurfaceVtkMapper2DColorTest.cpp @@ -1,51 +1,51 @@ /*=================================================================== 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. ===================================================================*/ //MITK #include "mitkTestingMacros.h" #include "mitkRenderingTestHelper.h" #include //VTK #include -int mitkSurfaceGLMapper2DColorTest(int argc, char* argv[]) +int mitkSurfaceVtkMapper2DColorTest(int argc, char* argv[]) { // load all arguments into a datastorage, take last argument as reference rendering // setup a renderwindow of fixed size X*Y // render the datastorage // compare rendering to reference image - MITK_TEST_BEGIN("mitkSurfaceGLMapper2DColorTest") + MITK_TEST_BEGIN("mitkSurfaceVtkMapper2DColorTest") mitk::RenderingTestHelper renderingHelper(640, 480, argc, argv); //Set the opacity for all images renderingHelper.GetDataStorage()->GetNode(mitk::NodePredicateDataType::New("Surface"))->SetProperty("color", mitk::ColorProperty::New(255.0f, 0.0f, 0.0f)); //### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv) == true, "CompareRenderWindowAgainstReference test result positive?" ); //#################### //Use this to generate a reference screenshot or save the file. //(Only in your local version of the test!) if(false) { renderingHelper.SaveReferenceScreenShot("/home/kilgus/Pictures/RenderingTestData/output.png"); } //#################### MITK_TEST_END(); } diff --git a/Core/Code/Testing/mitkSurfaceGLMapper2DOpacityTest.cpp b/Core/Code/Testing/mitkSurfaceVtkMapper2DOpacityTest.cpp similarity index 93% rename from Core/Code/Testing/mitkSurfaceGLMapper2DOpacityTest.cpp rename to Core/Code/Testing/mitkSurfaceVtkMapper2DOpacityTest.cpp index ad02205ac0..737bca41ab 100644 --- a/Core/Code/Testing/mitkSurfaceGLMapper2DOpacityTest.cpp +++ b/Core/Code/Testing/mitkSurfaceVtkMapper2DOpacityTest.cpp @@ -1,51 +1,51 @@ /*=================================================================== 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. ===================================================================*/ //MITK #include "mitkTestingMacros.h" #include "mitkRenderingTestHelper.h" #include //VTK #include -int mitkSurfaceGLMapper2DOpacityTest(int argc, char* argv[]) +int mitkSurfaceVtkMapper2DOpacityTest(int argc, char* argv[]) { // load all arguments into a datastorage, take last argument as reference rendering // setup a renderwindow of fixed size X*Y // render the datastorage // compare rendering to reference image - MITK_TEST_BEGIN("mitkSurfaceGLMapper2DOpacityTest") + MITK_TEST_BEGIN("mitkSurfaceVtkMapper2DOpacityTest") mitk::RenderingTestHelper renderingHelper(640, 480, argc, argv); //Set the opacity for all images renderingHelper.GetDataStorage()->GetNode(mitk::NodePredicateDataType::New("Surface"))->SetProperty("opacity", mitk::FloatProperty::New(0.5f)); //### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv) == true, "CompareRenderWindowAgainstReference test result positive?" ); //#################### //Use this to generate a reference screenshot or save the file. //(Only in your local version of the test!) if(false) { renderingHelper.SaveReferenceScreenShot("/home/kilgus/Pictures/RenderingTestData/output.png"); } //#################### MITK_TEST_END(); } diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index db43a5072e..80d17da680 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,420 +1,420 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkCommon.h Common/mitkExceptionMacro.h Common/mitkGetClassHierarchy.h DataManagement/mitkProportionalTimeGeometry.h DataManagement/mitkTimeGeometry.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkShaderProperty.h DataManagement/mitkImageToItk.txx DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibility reasons. DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkVectorDeprecated.h DataManagement/mitkArray.h DataManagement/mitkQuaternion.h DataManagement/mitkNumericTypes.h DataManagement/mitkVector.h DataManagement/mitkPoint.h DataManagement/mitkMatrix.h Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Interfaces/mitkIFileWriter.h Interfaces/mitkIFileWriter.cpp Interfaces/mitkIFileReader.h Interfaces/mitkIFileReader.cpp Rendering/mitkLocalStorageHandler.h Rendering/Colortables/HotIron.h Rendering/Colortables/Jet.h Rendering/Colortables/PET20.h Rendering/Colortables/PETColor.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp # DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp # DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLine.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkShaderProperty.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkXML2EventParser.cpp Interfaces/mitkIMimeTypeProvider.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp Interfaces/mitkIPropertyAliases.cpp Interfaces/mitkIPropertyDescriptions.cpp Interfaces/mitkIPropertyExtensions.cpp Interfaces/mitkIPropertyFilters.cpp Interfaces/mitkIPersistenceService.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkAbstractFileIO.cpp IO/mitkCustomMimeType.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkIFileIO.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkIOConstants.cpp IO/mitkIOUtil.cpp IO/mitkIOMimeTypes.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkMimeType.cpp IO/mitkOperation.cpp # IO/mitkPicFileIOFactory.cpp # IO/mitkPicFileReader.cpp # IO/mitkPicFileWriter.cpp # IO/mitkPicHelper.cpp # IO/mitkPicVolumeTimeSeriesIOFactory.cpp # IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkStandardFileLocations.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp - Rendering/mitkGLMapper.cpp + #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp - Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp - Rendering/mitkSurfaceGLMapper2D.cpp + Rendering/mitkSurfaceVtkMapper2D.cpp + #Rendering/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkOverlay.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkAbstractOverlayLayouter.cpp Common/mitkException.cpp Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp Internal/mitkCoreActivator.cpp Internal/mitkDicomSeriesReaderService.cpp Internal/mitkFileReaderWriterBase.cpp Internal/mitkImageVtkLegacyIO.cpp Internal/mitkImageVtkXmlIO.cpp Internal/mitkItkImageIO.cpp Internal/mitkLegacyFileReaderService.cpp Internal/mitkLegacyFileWriterService.cpp Internal/mitkMimeTypeProvider.cpp Internal/mitkPointSetReaderService.cpp Internal/mitkPointSetWriterService.cpp Internal/mitkRawImageFileReader.cpp Internal/mitkSurfaceStlIO.cpp Internal/mitkSurfaceVtkIO.cpp Internal/mitkSurfaceVtkLegacyIO.cpp Internal/mitkSurfaceVtkXmlIO.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml ) diff --git a/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox b/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox index 978c30e49a..032c372b88 100644 --- a/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox +++ b/Documentation/Doxygen/DeveloperManual/Toolkit/ModuleManuals/MITKModuleManualsList.dox @@ -1,27 +1,28 @@ /** \page MITKModuleManualsListPage MITK Module Manuals \section MITKModuleManualsListPageOverview Overview The modules are shared libraries that provide functionality that can be used by developers. \section MITKModuleManualsListPageModuleManualList List of Module Manuals \li \subpage IGTGeneralModulePage \li \subpage MitkOpenCL_Overview + \li \subpage LegacyGLModule \li \subpage GeneratingDeviceModulesPage \li \subpage mitkPython_Overview \li \subpage USModulePage \li \subpage OverlaysModulePage \section MITKModuleManualsListPageAdditionalInformation Additional Information on Certain Modules \li \ref PlanarPropertiesPage \li \subpage DiffusionImagingPropertiesPage \li \subpage ConnectomicsRenderingPropertiesPage \section MITKMigrationGuides Migration Guides \li \subpage InteractionMigration \li \subpage GeometryMigration */ diff --git a/Modules/AlgorithmsExt/CMakeLists.txt b/Modules/AlgorithmsExt/CMakeLists.txt index 4ff9d265be..2f71b9e449 100644 --- a/Modules/AlgorithmsExt/CMakeLists.txt +++ b/Modules/AlgorithmsExt/CMakeLists.txt @@ -1,8 +1,8 @@ -MITK_CREATE_MODULE(DEPENDS MitkDataTypesExt +MITK_CREATE_MODULE(DEPENDS MitkDataTypesExt MitkLegacyGL PACKAGE_DEPENDS ITK|ITKThresholding ANN WARNINGS_AS_ERRORS ) if(BUILD_TESTING) add_subdirectory(Testing) endif() diff --git a/Modules/ContourModel/CMakeLists.txt b/Modules/ContourModel/CMakeLists.txt index 4b43261991..bd9168e7a9 100644 --- a/Modules/ContourModel/CMakeLists.txt +++ b/Modules/ContourModel/CMakeLists.txt @@ -1,8 +1,8 @@ MITK_CREATE_MODULE( INCLUDE_DIRS Algorithms DataManagement IO Rendering - DEPENDS MitkCore MitkSceneSerializationBase + DEPENDS MitkCore MitkSceneSerializationBase MitkLegacyGL MitkOverlays PACKAGE_DEPENDS ITK|ITKReview WARNINGS_AS_ERRORS ) add_subdirectory(Testing) diff --git a/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.cpp b/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.cpp index 073936ea1e..3851c98340 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.cpp @@ -1,329 +1,376 @@ /*=================================================================== 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 "mitkContourModelSetGLMapper2D.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkContourModelSet.h" #include +#include "mitkContourModel.h" +#include "mitkBaseRenderer.h" +#include "mitkOverlayManager.h" +#include "mitkTextOverlay2D.h" + #include "mitkGL.h" mitk::ContourModelGLMapper2DBase::ContourModelGLMapper2DBase() { + m_PointNumbersOverlay = mitk::TextOverlay2D::New(); + m_ControlPointNumbersOverlay = mitk::TextOverlay2D::New(); + } mitk::ContourModelGLMapper2DBase::~ContourModelGLMapper2DBase() { +// RendererListType::const_iterator iter; +// for ( iter=m_RendererList.begin(); iter != m_RendererList.end(); ++iter) +// { +// (*iter)->GetOverlayManager()->RemoveOverlay( m_PointNumbersOverlay.GetPointer() ); +// (*iter)->GetOverlayManager()->RemoveOverlay( m_ControlPointNumbersOverlay.GetPointer() ); +// } +// m_RendererList.clear(); } - void mitk::ContourModelGLMapper2DBase::DrawContour(mitk::ContourModel* renderingContour, mitk::BaseRenderer* renderer) { + if ( std::find( m_RendererList.begin(), m_RendererList.end(), renderer ) == m_RendererList.end() ) + { + m_RendererList.push_back( renderer ); + } + + renderer->GetOverlayManager()->AddOverlay( m_PointNumbersOverlay.GetPointer(), renderer ); + m_PointNumbersOverlay->SetVisibility( false, renderer ); + + renderer->GetOverlayManager()->AddOverlay( m_ControlPointNumbersOverlay.GetPointer(), renderer ); + m_ControlPointNumbersOverlay->SetVisibility( false, renderer ); + + InternalDrawContour( renderingContour, renderer ); +} + +void mitk::ContourModelGLMapper2DBase::InternalDrawContour(mitk::ContourModel* renderingContour, mitk::BaseRenderer* renderer) +{ + if(!renderingContour) return; mitk::DataNode* dataNode = this->GetDataNode(); renderingContour->UpdateOutputInformation(); unsigned int timestep = renderer->GetTimeStep(); if ( !renderingContour->IsEmptyTimeStep(timestep) ) { mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList ApplyColorAndOpacityProperties(renderer); mitk::ColorProperty::Pointer colorprop = dynamic_cast(dataNode->GetProperty("contour.color", renderer)); float opacity = 0.5; dataNode->GetFloatProperty("opacity", opacity, renderer); if(colorprop) { //set the color of the contour double red = colorprop->GetColor().GetRed(); double green = colorprop->GetColor().GetGreen(); double blue = colorprop->GetColor().GetBlue(); glColor4f(red, green, blue, opacity); } mitk::ColorProperty::Pointer selectedcolor = dynamic_cast(dataNode->GetProperty("contour.points.color", renderer)); if(!selectedcolor) { selectedcolor = mitk::ColorProperty::New(1.0,0.0,0.1); } vtkLinearTransform* transform = dataNode->GetVtkTransform(); // ContourModel::OutputType point; mitk::Point3D point; mitk::Point3D p, projected_p; float vtkp[3]; float lineWidth = 3.0; bool drawit=false; bool isHovering = false; dataNode->GetBoolProperty("contour.hovering", isHovering); if (isHovering) dataNode->GetFloatProperty("contour.hovering.width", lineWidth); else dataNode->GetFloatProperty("contour.width", lineWidth); bool showSegments = false; dataNode->GetBoolProperty("contour.segments.show", showSegments); bool showControlPoints = false; dataNode->GetBoolProperty("contour.controlpoints.show", showControlPoints); bool showPoints = false; dataNode->GetBoolProperty("contour.points.show", showPoints); bool showPointsNumbers = false; dataNode->GetBoolProperty("contour.points.text", showPointsNumbers); bool showControlPointsNumbers = false; dataNode->GetBoolProperty("contour.controlpoints.text", showControlPointsNumbers); bool projectmode=false; dataNode->GetVisibility(projectmode, renderer, "contour.project-onto-plane"); mitk::ContourModel::VertexIterator pointsIt = renderingContour->IteratorBegin(timestep); Point2D pt2d; // projected_p in display coordinates Point2D lastPt2d; int index = 0; mitk::ScalarType maxDiff = 0.25; while ( pointsIt != renderingContour->IteratorEnd(timestep) ) { lastPt2d = pt2d; point = (*pointsIt)->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetNorm(); //project to plane if(projectmode) { drawit=true; } else if(scalardiffIteratorBegin(timestep)) ) { glLineWidth(lineWidth); glBegin (GL_LINES); glVertex2f(pt2d[0], pt2d[1]); glVertex2f(lastPt2d[0], lastPt2d[1]); glEnd(); glLineWidth(1); } } if (showControlPoints) { //draw ontrol points if ((*pointsIt)->IsControlPoint) { float pointsize = 4; Point2D tmp; Vector2D horz,vert; horz[1]=0; vert[0]=0; horz[0]=pointsize; vert[1]=pointsize; glColor3f(selectedcolor->GetColor().GetRed(), selectedcolor->GetColor().GetBlue(), selectedcolor->GetColor().GetGreen()); glLineWidth(1); //a rectangle around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2dv(&tmp[0]); tmp=pt2d+vert; glVertex2dv(&tmp[0]); tmp=pt2d+horz; glVertex2dv(&tmp[0]); tmp=pt2d-vert; glVertex2dv(&tmp[0]); glEnd(); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(colorprop->GetColor().GetRed(),colorprop->GetColor().GetGreen(),colorprop->GetColor().GetBlue()); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2dv(&tmp[0]); glEnd (); } } if (showPoints) { float pointsize = 3; Point2D tmp; Vector2D horz,vert; horz[1]=0; vert[0]=0; horz[0]=pointsize; vert[1]=pointsize; glColor3f(0.0, 0.0, 0.0); glLineWidth(1); //a rectangle around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2dv(&tmp[0]); tmp=pt2d+vert; glVertex2dv(&tmp[0]); tmp=pt2d+horz; glVertex2dv(&tmp[0]); tmp=pt2d-vert; glVertex2dv(&tmp[0]); glEnd(); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(colorprop->GetColor().GetRed(),colorprop->GetColor().GetGreen(),colorprop->GetColor().GetBlue()); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2dv(&tmp[0]); glEnd (); } if (showPointsNumbers) { std::string l; std::stringstream ss; ss << index; l.append(ss.str()); - mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3]; rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0; - OpenGLrenderer->WriteSimpleText(l, pt2d[0] + 2, pt2d[1] + 2,rgb[0], rgb[1],rgb[2]); + + WriteTextWithOverlay( m_PointNumbersOverlay, l.c_str(), rgb, pt2d, renderer ); } if (showControlPointsNumbers && (*pointsIt)->IsControlPoint) { std::string l; std::stringstream ss; ss << index; l.append(ss.str()); - mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3]; rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 0.0; - OpenGLrenderer->WriteSimpleText(l, pt2d[0] + 2, pt2d[1] + 2,rgb[0], rgb[1],rgb[2]); + + WriteTextWithOverlay( m_ControlPointNumbersOverlay, l.c_str(), rgb, pt2d, renderer ); } index++; } pointsIt++; }//end while iterate over controlpoints //close contour if necessary if(renderingContour->IsClosed(timestep) && drawit && showSegments) { lastPt2d = pt2d; point = renderingContour->GetVertexAt(0,timestep)->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); glLineWidth(lineWidth); glBegin (GL_LINES); glVertex2f(lastPt2d[0], lastPt2d[1]); glVertex2f( pt2d[0], pt2d[1] ); glEnd(); glLineWidth(1); } //draw selected vertex if exists if(renderingContour->GetSelectedVertex()) { //transform selected vertex point = renderingContour->GetSelectedVertex()->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetNorm(); //---------------------------------- //draw point if close to plane if(scalardiffSetText( text ); + textOverlay->SetColor( rgb ); + textOverlay->SetOpacity( 1 ); + textOverlay->SetFontSize( 16 ); + textOverlay->SetBoolProperty( "drawShadow", false ); + textOverlay->SetVisibility( true, renderer ); + +} diff --git a/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.h b/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.h index 365930421d..c0c5df70b7 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.h +++ b/Modules/ContourModel/Rendering/mitkContourModelGLMapper2DBase.h @@ -1,58 +1,76 @@ /*=================================================================== 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_ContourModelGLMapper2DBase_H_ #define MITK_ContourModelGLMapper2DBase_H_ #include "mitkCommon.h" #include #include "mitkGLMapper.h" -#include "mitkContourModel.h" -#include "mitkBaseRenderer.h" +#include "mitkTextOverlay2D.h" namespace mitk { class BaseRenderer; class ContourModel; /** * @brief Base class for OpenGL based 2D mappers. * Provides functionality to draw a contour. * * @ingroup Mapper */ class MitkContourModel_EXPORT ContourModelGLMapper2DBase : public GLMapper { public: mitkClassMacro(ContourModelGLMapper2DBase, GLMapper); protected: + + typedef TextOverlay2D::Pointer TextOverlayPointerType; + ContourModelGLMapper2DBase(); virtual ~ContourModelGLMapper2DBase(); void DrawContour(mitk::ContourModel* contour, mitk::BaseRenderer* renderer); + + void WriteTextWithOverlay( TextOverlayPointerType textOverlay, + const char* text, + float rgb[3], + Point2D pt2d, + mitk::BaseRenderer* renderer ); + + virtual void InternalDrawContour( mitk::ContourModel* renderingContour, mitk::BaseRenderer* renderer ); + + TextOverlayPointerType m_PointNumbersOverlay; + TextOverlayPointerType m_ControlPointNumbersOverlay; + + typedef std::vector RendererListType; + RendererListType m_RendererList; + + }; } // namespace mitk #endif diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp b/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp index 667410a59c..8ddea9f089 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp @@ -1,383 +1,383 @@ /*=================================================================== 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 "mitkContourModelSetGLMapper2D.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkContourModelSet.h" #include #include "mitkGL.h" mitk::ContourModelSetGLMapper2D::ContourModelSetGLMapper2D() { } mitk::ContourModelSetGLMapper2D::~ContourModelSetGLMapper2D() { } void mitk::ContourModelSetGLMapper2D::Paint(mitk::BaseRenderer * renderer) { BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); mitk::DataNode* dataNode = this->GetDataNode(); bool visible = true; dataNode->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; mitk::ContourModelSet* input = this->GetInput(); mitk::ContourModelSet::ContourModelSetIterator it = input->Begin(); mitk::ContourModelSet::ContourModelSetIterator end = input->End(); while(it!=end) { this->DrawContour(it->GetPointer(), renderer); ++it; } if(input->GetSize() < 1) return; ls->UpdateGenerateDataTime(); } mitk::ContourModelSet* mitk::ContourModelSetGLMapper2D::GetInput(void) { return const_cast(static_cast ( GetDataNode()->GetData() )); } -void mitk::ContourModelSetGLMapper2D::DrawContour(mitk::ContourModel* renderingContour, mitk::BaseRenderer* renderer) +void mitk::ContourModelSetGLMapper2D::InternalDrawContour(mitk::ContourModel* renderingContour, mitk::BaseRenderer* renderer) { if(!renderingContour) return; mitk::DataNode* dataNode = this->GetDataNode(); renderingContour->UpdateOutputInformation(); unsigned int timestep = renderer->GetTimeStep(); if ( !renderingContour->IsEmptyTimeStep(timestep) ) { mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList ApplyColorAndOpacityProperties(renderer); mitk::ColorProperty::Pointer colorprop = dynamic_cast(dataNode->GetProperty("contour.color", renderer)); float opacity = 0.5; dataNode->GetFloatProperty("opacity", opacity, renderer); if(colorprop) { //set the color of the contour double red = colorprop->GetColor().GetRed(); double green = colorprop->GetColor().GetGreen(); double blue = colorprop->GetColor().GetBlue(); glColor4f(red, green, blue, opacity); } mitk::ColorProperty::Pointer selectedcolor = dynamic_cast(dataNode->GetProperty("contour.points.color", renderer)); if(!selectedcolor) { selectedcolor = mitk::ColorProperty::New(1.0,0.0,0.1); } vtkLinearTransform* transform = dataNode->GetVtkTransform(); // ContourModel::OutputType point; mitk::Point3D point; mitk::Point3D p, projected_p; float vtkp[3]; float lineWidth = 3.0; bool drawit=false; bool isHovering = false; dataNode->GetBoolProperty("contour.hovering", isHovering); if (isHovering) dataNode->GetFloatProperty("contour.hovering.width", lineWidth); else dataNode->GetFloatProperty("contour.width", lineWidth); bool showSegments = false; dataNode->GetBoolProperty("contour.segments.show", showSegments); bool showControlPoints = false; dataNode->GetBoolProperty("contour.controlpoints.show", showControlPoints); bool showPoints = false; dataNode->GetBoolProperty("contour.points.show", showPoints); bool showPointsNumbers = false; dataNode->GetBoolProperty("contour.points.text", showPointsNumbers); bool showControlPointsNumbers = false; dataNode->GetBoolProperty("contour.controlpoints.text", showControlPointsNumbers); bool projectmode=false; dataNode->GetVisibility(projectmode, renderer, "contour.project-onto-plane"); mitk::ContourModel::VertexIterator pointsIt = renderingContour->IteratorBegin(timestep); Point2D pt2d; // projected_p in display coordinates Point2D lastPt2d; int index = 0; mitk::ScalarType maxDiff = 0.25; while ( pointsIt != renderingContour->IteratorEnd(timestep) ) { lastPt2d = pt2d; point = (*pointsIt)->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetNorm(); //project to plane if(projectmode) { drawit=true; } else if(scalardiffIteratorBegin(timestep)) ) { glLineWidth(lineWidth); glBegin (GL_LINES); glVertex2f(pt2d[0], pt2d[1]); glVertex2f(lastPt2d[0], lastPt2d[1]); glEnd(); glLineWidth(1); } } if (showControlPoints) { //draw ontrol points if ((*pointsIt)->IsControlPoint) { float pointsize = 4; Point2D tmp; Vector2D horz,vert; horz[1]=0; vert[0]=0; horz[0]=pointsize; vert[1]=pointsize; glColor3f(selectedcolor->GetColor().GetRed(), selectedcolor->GetColor().GetBlue(), selectedcolor->GetColor().GetGreen()); glLineWidth(1); //a rectangle around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2dv(&tmp[0]); tmp=pt2d+vert; glVertex2dv(&tmp[0]); tmp=pt2d+horz; glVertex2dv(&tmp[0]); tmp=pt2d-vert; glVertex2dv(&tmp[0]); glEnd(); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(colorprop->GetColor().GetRed(),colorprop->GetColor().GetGreen(),colorprop->GetColor().GetBlue()); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2dv(&tmp[0]); glEnd (); } } if (showPoints) { float pointsize = 3; Point2D tmp; Vector2D horz,vert; horz[1]=0; vert[0]=0; horz[0]=pointsize; vert[1]=pointsize; glColor3f(0.0, 0.0, 0.0); glLineWidth(1); //a rectangle around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2dv(&tmp[0]); tmp=pt2d+vert; glVertex2dv(&tmp[0]); tmp=pt2d+horz; glVertex2dv(&tmp[0]); tmp=pt2d-vert; glVertex2dv(&tmp[0]); glEnd(); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(colorprop->GetColor().GetRed(),colorprop->GetColor().GetGreen(),colorprop->GetColor().GetBlue()); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2dv(&tmp[0]); glEnd (); } if (showPointsNumbers) { std::string l; std::stringstream ss; ss << index; l.append(ss.str()); - mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3]; rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0; - OpenGLrenderer->WriteSimpleText(l, pt2d[0] + 2, pt2d[1] + 2,rgb[0], rgb[1],rgb[2]); + + WriteTextWithOverlay( m_PointNumbersOverlay, l.c_str(), rgb, pt2d, renderer ); } if (showControlPointsNumbers && (*pointsIt)->IsControlPoint) { std::string l; std::stringstream ss; ss << index; l.append(ss.str()); - mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3]; rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 0.0; - OpenGLrenderer->WriteSimpleText(l, pt2d[0] + 2, pt2d[1] + 2,rgb[0], rgb[1],rgb[2]); + + WriteTextWithOverlay( m_ControlPointNumbersOverlay, l.c_str(), rgb, pt2d, renderer ); } index++; } pointsIt++; }//end while iterate over controlpoints //close contour if necessary if(renderingContour->IsClosed(timestep) && drawit && showSegments) { lastPt2d = pt2d; point = renderingContour->GetVertexAt(0,timestep)->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); glLineWidth(lineWidth); glBegin (GL_LINES); glVertex2f(lastPt2d[0], lastPt2d[1]); glVertex2f( pt2d[0], pt2d[1] ); glEnd(); glLineWidth(1); } //draw selected vertex if exists if(renderingContour->GetSelectedVertex()) { //transform selected vertex point = renderingContour->GetSelectedVertex()->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetNorm(); //---------------------------------- //draw point if close to plane if(scalardiffAddProperty( "contour.color", ColorProperty::New(0.9, 1.0, 0.1), renderer, overwrite ); node->AddProperty( "contour.points.color", ColorProperty::New(1.0, 0.0, 0.1), renderer, overwrite ); node->AddProperty( "contour.points.show", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.segments.show", mitk::BoolProperty::New( true ), renderer, overwrite ); node->AddProperty( "contour.controlpoints.show", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite ); node->AddProperty( "contour.hovering.width", mitk::FloatProperty::New( 3.0 ), renderer, overwrite ); node->AddProperty( "contour.hovering", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.points.text", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.controlpoints.text", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.project-onto-plane", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.h b/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.h index a74f1ece8a..99009885e9 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.h +++ b/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.h @@ -1,76 +1,76 @@ /*=================================================================== 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_ContourModelSetGLMapper2D_H_ #define MITK_ContourModelSetGLMapper2D_H_ #include "mitkCommon.h" #include #include "mitkContourModelGLMapper2DBase.h" #include "mitkContourModelSet.h" #include "mitkBaseRenderer.h" namespace mitk { class BaseRenderer; class ContourModel; /** * @brief OpenGL-based mapper to display a mitk::ContourModelSet object containing several contours in a 2D render window * * * @ingroup Mapper */ class MitkContourModel_EXPORT ContourModelSetGLMapper2D : public ContourModelGLMapper2DBase { public: mitkClassMacro(ContourModelSetGLMapper2D, ContourModelGLMapper2DBase); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * reimplemented from Baseclass */ virtual void Paint(BaseRenderer * renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); LocalStorageHandler m_LSH; protected: ContourModelSetGLMapper2D(); virtual ~ContourModelSetGLMapper2D(); - void DrawContour(mitk::ContourModel* contour, mitk::BaseRenderer* renderer); + void InternalDrawContour(mitk::ContourModel* contour, mitk::BaseRenderer* renderer); private: /** * return a refernce of the rendered data object */ ContourModelSet* GetInput(void); }; } // namespace mitk #endif diff --git a/Modules/LegacyGL/CMakeLists.txt b/Modules/LegacyGL/CMakeLists.txt new file mode 100644 index 0000000000..456bfcb0bb --- /dev/null +++ b/Modules/LegacyGL/CMakeLists.txt @@ -0,0 +1,7 @@ +#This module is deprecated. Please use VTK replacements instead. + +MITK_CREATE_MODULE( + DEPENDS MitkCore + PACKAGE_DEPENDS + DEPRECATED_SINCE next_release + ) diff --git a/Modules/LegacyGL/Documentation/doxygen/LegacyGL.dox b/Modules/LegacyGL/Documentation/doxygen/LegacyGL.dox new file mode 100644 index 0000000000..5c9ba7aadd --- /dev/null +++ b/Modules/LegacyGL/Documentation/doxygen/LegacyGL.dox @@ -0,0 +1,26 @@ +/** +\page LegacyGLModule The legacy OpenGL Module + +\tableofcontents + +\section LegacyGLModuleOverview Reasons for this module + +The new legacy GL module provides support of pure OpenGL rendering for Mitk. It contains all mitkGL.h related classes from the MitkCore. Modules, which used this classes in the past, now have a dependency to LegacyGL. This module is deprecated and should only be used for a short period until all mappers and props are migrated to the VTK-based rendering pipeline. + +Before the integration of this module, there was a lot of code in the Mitk rendering pipeline to enable mitkGLMapper and mitkVtkMapper in parallel. In fact, both mappers render with OpenGL but vtkMapper are compatible to each other. It was not clear for developers how to implement mappers, as there were many negative examples in the form of mitkGLMapper. + +Removing direct rendering of OpenGL makes a lot of code obsolete (e.g. Enable/DisableOpenGL() in VtkPropRenderer) and prevents side effects such as that the level window was sometimes applied to the crosshair etc. Furthermore, the software architecture and design becomes clear. There is now just one way to implement a Mapper in Mitk - the mitkVtkMapper. If you are a developper and want to write GL code, you can simply write a vtkMapper in VTK code and use it inside the mitkVtkMapper. + +\section PortExamples Examples how to port classes from GL to VTK-based mappers + +The following core classes were ported from GL to VTK and may give orientation how to port an existing mapper or prop to the VTK-based rendering pipeline: + +\li mitkSurfaceGLMapper2D -> mitkSurfaceVtkMapper2D +\li mitkPointSetGLMapper2D -> mitkPointSetVtkMapper2D +\li mitkPlaneGeometryGLMapper -> mitkPlaneGeometryMapper +\li vtkMitkRectangleProp -> vtkMitkRectangleProp + +\section mitkVtkGLMapperWrapperDocu The mitkVtkGLMapperWrappper + +LegacyGL also provides a new base class, the mitkVtkGLMapperWrapper, which can be used to wrap existing GLMappers and pretend they are common vtkProps. Examples can be found in the Modules ContourModel and PlanarFigure. +*/ \ No newline at end of file diff --git a/Modules/LegacyGL/files.cmake b/Modules/LegacyGL/files.cmake new file mode 100644 index 0000000000..40b8041b83 --- /dev/null +++ b/Modules/LegacyGL/files.cmake @@ -0,0 +1,15 @@ +#We are deprecated. Please don't use us. + +set(H_FILES + mitkGLMapper2D.h + mitkGL.h +) + +set(CPP_FILES + mitkPlaneGeometryDataGLMapper2D.cpp + mitkGLMapper.cpp + mitkPointSetGLMapper2D.cpp + mitkSurfaceGLMapper2D.cpp + mitkVtkGLMapperWrapper.cpp + vtkGLMapperProp.cpp +) diff --git a/Core/Code/Rendering/mitkGL.h b/Modules/LegacyGL/mitkGL.h similarity index 99% rename from Core/Code/Rendering/mitkGL.h rename to Modules/LegacyGL/mitkGL.h index 4616c02987..a4c99fd896 100644 --- a/Core/Code/Rendering/mitkGL.h +++ b/Modules/LegacyGL/mitkGL.h @@ -1,32 +1,31 @@ /*=================================================================== 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 MITKGL_H_HEADER_INCLUDED_C1C53722 #define MITKGL_H_HEADER_INCLUDED_C1C53722 #ifdef WIN32 #include #endif #ifndef __APPLE__ #include "GL/gl.h" #else #include "OpenGL/gl.h" #endif #endif /* MITKGL_H_HEADER_INCLUDED_C1C53722 */ - diff --git a/Core/Code/Rendering/mitkGLMapper.cpp b/Modules/LegacyGL/mitkGLMapper.cpp similarity index 100% rename from Core/Code/Rendering/mitkGLMapper.cpp rename to Modules/LegacyGL/mitkGLMapper.cpp diff --git a/Core/Code/Rendering/mitkGLMapper.h b/Modules/LegacyGL/mitkGLMapper.h similarity index 91% rename from Core/Code/Rendering/mitkGLMapper.h rename to Modules/LegacyGL/mitkGLMapper.h index a25cfb01fb..56a32540d0 100644 --- a/Core/Code/Rendering/mitkGLMapper.h +++ b/Modules/LegacyGL/mitkGLMapper.h @@ -1,102 +1,108 @@ /*=================================================================== 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 MITKGLMAPPER_H_HEADER_INCLUDED_C197C872 #define MITKGLMAPPER_H_HEADER_INCLUDED_C197C872 -#include +#include #include "mitkMapper.h" #include "mitkBaseRenderer.h" #include "mitkVtkPropRenderer.h" namespace mitk { /** \brief Base class of all OpenGL-based mappers. * * Those must implement the abstract method Paint(BaseRenderer), which is called by * method MitkRender(). * The Paint() method should be used to paint into a renderer via OpenGL-drawing commands. * The OpenGL context matrices (GL_MODELVIEWMATRIX/GL_PROJECTIONMATRIX) are preinitialized by * the mitkVtkPropRenderer so that the origin of the 2D-coordinate system of the 2D render * window is located in the lower left corner and has the width and height in display pixels * of the respective renderwindow. The x-axis is horizontally oriented, while the y-axis is * vertically oriented. The drawing commands are directly interpreted as display coordinates. * ApplyColorAndOpacity() can be used in the subclasses to apply color and opacity properties * read from the PropertyList. * +* @deprecatedSince{2015_03} GLMappers are no longer supported in the rendering pipeline. +* Please use mitkVtkMapper instead or consider writing your own vtk classes, such as vtkActor +* or vtkMapper * \ingroup Mapper */ -class MITK_CORE_EXPORT GLMapper : public Mapper +class MitkLegacyGL_EXPORT GLMapper : public Mapper { public: + + mitkClassMacro(GLMapper, Mapper); + /** \brief Do the painting into the \a renderer */ virtual void Paint(mitk::BaseRenderer *renderer) = 0; /** \brief Apply color and opacity properties read from the PropertyList * \deprecatedSince{2013_03} Use ApplyColorAndOpacityProperties(...) instead */ DEPRECATED(inline virtual void ApplyProperties(mitk::BaseRenderer* renderer)) { ApplyColorAndOpacityProperties(renderer); } /** \brief Apply color and opacity properties read from the PropertyList. * The actor is not used in the GLMappers. Called by mapper subclasses. */ virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL); /** \brief Checks visibility and calls the paint method * * Note: The enumeration is disregarded, since OpenGL rendering only needs a * single render pass. */ void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); /** \brief Returns whether this is a vtk-based mapper * \return false, since all mappers deriving from this class are OpenGL mappers * \deprecatedSince{2013_03} All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead */ DEPRECATED( virtual bool IsVtkBased() const ); /** \brief Returns whether this mapper allows picking in the renderwindow virtual bool IsPickable() const { return false; }*/ protected: /** constructor */ GLMapper(); /** virtual destructor in order to derive from this class */ virtual ~GLMapper(); private: /** copy constructor */ GLMapper( const GLMapper &); /** assignment operator */ GLMapper & operator=(const GLMapper &); }; } // namespace mitk #endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */ diff --git a/Core/Code/Rendering/mitkGLMapper2D.h b/Modules/LegacyGL/mitkGLMapper2D.h similarity index 99% rename from Core/Code/Rendering/mitkGLMapper2D.h rename to Modules/LegacyGL/mitkGLMapper2D.h index cb4cc6fec3..64a85019ff 100644 --- a/Core/Code/Rendering/mitkGLMapper2D.h +++ b/Modules/LegacyGL/mitkGLMapper2D.h @@ -1,35 +1,33 @@ /*=================================================================== 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 MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 #define MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 #include "mitkGLMapper.h" namespace mitk { // typedef allows integration of mappers into the new mapper architecture // \deprecatedSince{2013_03} Use GLMapper instead DEPRECATED(typedef GLMapper GLMapper2D); } // namespace mitk #endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */ - - diff --git a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.cpp b/Modules/LegacyGL/mitkPlaneGeometryDataGLMapper2D.cpp similarity index 95% copy from Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.cpp copy to Modules/LegacyGL/mitkPlaneGeometryDataGLMapper2D.cpp index 1b05a7cdf1..175f35a4af 100644 --- a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.cpp +++ b/Modules/LegacyGL/mitkPlaneGeometryDataGLMapper2D.cpp @@ -1,672 +1,672 @@ /*=================================================================== 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 "mitkGL.h" -#include "mitkPlaneGeometryDataMapper2D.h" +#include "mitkPlaneGeometryDataGLMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkSmartPointerProperty.h" #include "mitkPlaneOrientationProperty.h" #include "mitkPlaneGeometryDataToSurfaceFilter.h" #include "mitkSurfaceGLMapper2D.h" #include "mitkLine.h" #include "mitkNodePredicateDataType.h" #include "mitkSlicedGeometry3D.h" #include "mitkResliceMethodProperty.h" #include "mitkAbstractTransformGeometry.h" -mitk::PlaneGeometryDataMapper2D::PlaneGeometryDataMapper2D() +mitk::PlaneGeometryDataGLMapper2D::PlaneGeometryDataGLMapper2D() : m_SurfaceMapper( NULL ), m_DataStorage(NULL), m_ParentNode(NULL), m_OtherPlaneGeometries(), m_RenderOrientationArrows( false ), m_ArrowOrientationPositive( true ) { } -mitk::PlaneGeometryDataMapper2D::~PlaneGeometryDataMapper2D() +mitk::PlaneGeometryDataGLMapper2D::~PlaneGeometryDataGLMapper2D() { } -const mitk::PlaneGeometryData* mitk::PlaneGeometryDataMapper2D::GetInput(void) +const mitk::PlaneGeometryData* mitk::PlaneGeometryDataGLMapper2D::GetInput(void) { return static_cast ( GetDataNode()->GetData() ); } -void mitk::PlaneGeometryDataMapper2D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) +void mitk::PlaneGeometryDataGLMapper2D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(!ls->IsGenerateDataRequired(renderer,this,GetDataNode())) return; ls->UpdateGenerateDataTime(); // collect all PlaneGeometryDatas accessible from the DataStorage m_OtherPlaneGeometries.clear(); if (m_DataStorage.IsNull()) return; mitk::NodePredicateDataType::Pointer p = mitk::NodePredicateDataType::New("PlaneGeometryData"); mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetDerivations(m_ParentNode, p, false); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) { if(it->Value().IsNull()) continue; BaseData* data = it->Value()->GetData(); if (data == NULL) continue; PlaneGeometryData* geometry2dData = dynamic_cast(data); if(geometry2dData == NULL) continue; PlaneGeometry* planegeometry = dynamic_cast(geometry2dData->GetPlaneGeometry()); if (planegeometry != NULL && dynamic_cast(geometry2dData->GetPlaneGeometry())==NULL) m_OtherPlaneGeometries.push_back(it->Value()); } } -void mitk::PlaneGeometryDataMapper2D::Paint(BaseRenderer *renderer) +void mitk::PlaneGeometryDataGLMapper2D::Paint(BaseRenderer *renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if(!visible) return; PlaneGeometryData::Pointer input = const_cast< PlaneGeometryData * >(this->GetInput()); // intersecting with ourself? if ( input.IsNull() || (this->GetInput()->GetPlaneGeometry() == renderer->GetCurrentWorldPlaneGeometry()) ) { return; // do nothing! } const PlaneGeometry *inputPlaneGeometry = dynamic_cast< const PlaneGeometry * >( input->GetPlaneGeometry() ); const PlaneGeometry *worldPlaneGeometry = dynamic_cast< const PlaneGeometry* >( renderer->GetCurrentWorldPlaneGeometry() ); if ( worldPlaneGeometry && dynamic_cast(renderer->GetCurrentWorldPlaneGeometry())==NULL && inputPlaneGeometry && dynamic_cast(input->GetPlaneGeometry() )==NULL && inputPlaneGeometry->GetReferenceGeometry() ) { DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry ); const BaseGeometry *referenceGeometry = inputPlaneGeometry->GetReferenceGeometry(); // calculate intersection of the plane data with the border of the // world geometry rectangle Point2D lineFrom, lineTo; const Geometry3D::TransformType *transform = dynamic_cast< const Geometry3D::TransformType * >( referenceGeometry->GetIndexToWorldTransform() ); Geometry3D::TransformType::Pointer inverseTransform = Geometry3D::TransformType::New(); transform->GetInverse( inverseTransform ); Line3D crossLine, otherCrossLine; // Calculate the intersection line of the input plane with the world plane if ( worldPlaneGeometry->IntersectionLine( inputPlaneGeometry, crossLine ) ) { BoundingBox::PointType boundingBoxMin, boundingBoxMax; boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum(); boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum(); if(referenceGeometry->GetImageGeometry()) { for(unsigned int i = 0; i < 3; ++i) { boundingBoxMin[i]-=0.5; boundingBoxMax[i]-=0.5; } } crossLine.Transform( *inverseTransform ); Point3D point1, point2; // Then, clip this line with the (transformed) bounding box of the // reference geometry. if ( crossLine.BoxLineIntersection( boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], crossLine.GetPoint(), crossLine.GetDirection(), point1, point2 ) == 2 ) { // Transform the resulting line start and end points into display // coordinates. worldPlaneGeometry->Map( transform->TransformPoint( point1 ), lineFrom ); worldPlaneGeometry->Map( transform->TransformPoint( point2 ), lineTo ); Line< ScalarType, 2 > mainLine, otherLine; Line< ScalarType, 2 > primaryHelperLine, secondaryHelperLine; mainLine.SetPoints( lineFrom, lineTo ); primaryHelperLine.SetPoints( lineFrom, lineTo ); secondaryHelperLine.SetPoints( lineFrom, lineTo ); displayGeometry->WorldToDisplay( lineFrom, lineFrom ); displayGeometry->WorldToDisplay( lineTo, lineTo ); ScalarType lengthInDisplayUnits = (lineTo - lineFrom).GetNorm(); Vector2D mainLineDirectionOrthogonal; mainLineDirectionOrthogonal[0] = -mainLine.GetDirection()[1]; mainLineDirectionOrthogonal[1] = mainLine.GetDirection()[0]; // lineParams stores the individual segments of the line, which are // separated by a gap each (to mark the intersection with another // displayed line) std::vector< ScalarType > mainLineParams; std::vector< ScalarType > primaryHelperLineParams; std::vector< ScalarType > secondaryHelperLineParams; mainLineParams.reserve( m_OtherPlaneGeometries.size() + 2 ); mainLineParams.push_back( 0.0 ); mainLineParams.push_back( 1.0 ); primaryHelperLineParams.reserve( m_OtherPlaneGeometries.size() + 2 ); primaryHelperLineParams.push_back( 0.0 ); primaryHelperLineParams.push_back( 1.0 ); secondaryHelperLineParams.reserve( m_OtherPlaneGeometries.size() + 2 ); secondaryHelperLineParams.push_back( 0.0 ); secondaryHelperLineParams.push_back( 1.0 ); // Now iterate through all other lines displayed in this window and // calculate the positions of intersection with the line to be // rendered; these positions will be stored in lineParams to form a // gap afterwards. NodesVectorType::iterator otherPlanesIt = m_OtherPlaneGeometries.begin(); NodesVectorType::iterator otherPlanesEnd = m_OtherPlaneGeometries.end(); DataNode* dataNodeOfInputPlaneGeometry = NULL; // Now we have to find the DataNode that contains the inputPlaneGeometry // in order to determine the state of the thick-slice rendering while ( otherPlanesIt != otherPlanesEnd ) { PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( static_cast< PlaneGeometryData * >( (*otherPlanesIt)->GetData() )->GetPlaneGeometry() ); // if we have found the correct node if ( (otherPlane == inputPlaneGeometry) && worldPlaneGeometry->IntersectionLine( otherPlane, otherCrossLine ) ) { dataNodeOfInputPlaneGeometry = (*otherPlanesIt); // if( dataNodeOfInputPlaneGeometry ) // { // mainLineThickSlicesMode = this->DetermineThickSliceMode(dataNodeOfInputPlaneGeometry, mainLineThickSlicesNum); // } break; } otherPlanesIt++; } // if we did not find a dataNode for the inputPlaneGeometry there is nothing we can do from here if ( dataNodeOfInputPlaneGeometry == NULL ) return; // Determine if we should draw the area covered by the thick slicing, default is false. // This will also show the area of slices that do not have thick slice mode enabled bool showAreaOfThickSlicing = false; dataNodeOfInputPlaneGeometry->GetBoolProperty( "reslice.thickslices.showarea", showAreaOfThickSlicing ); // get the normal of the inputPlaneGeometry Vector3D normal = inputPlaneGeometry->GetNormal(); // determine the pixelSpacing in that direction double thickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); IntProperty *intProperty=0; if( dataNodeOfInputPlaneGeometry->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) thickSliceDistance *= intProperty->GetValue()+0.5; else showAreaOfThickSlicing = false; // not the nicest place to do it, but we have the width of the visible bloc in MM here // so we store it in this fancy property dataNodeOfInputPlaneGeometry->SetFloatProperty( "reslice.thickslices.sizeinmm", thickSliceDistance*2 ); if ( showAreaOfThickSlicing ) { // vectorToHelperLine defines how to reach the helperLine from the mainLine Vector2D vectorToHelperLine; vectorToHelperLine = mainLineDirectionOrthogonal; vectorToHelperLine.Normalize(); // got the right direction, so we multiply the width vectorToHelperLine *= thickSliceDistance; // and create the corresponding points primaryHelperLine.SetPoints( primaryHelperLine.GetPoint1() - vectorToHelperLine, primaryHelperLine.GetPoint2() - vectorToHelperLine ); secondaryHelperLine.SetPoints( secondaryHelperLine.GetPoint1() + vectorToHelperLine, secondaryHelperLine.GetPoint2() + vectorToHelperLine ); } //int otherLineThickSlicesMode = 0; int otherLineThickSlicesNum = 0; // by default, there is no gap for the helper lines ScalarType gapSize = 0.0; otherPlanesIt = m_OtherPlaneGeometries.begin(); while ( otherPlanesIt != otherPlanesEnd ) { PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( static_cast< PlaneGeometryData * >( (*otherPlanesIt)->GetData() )->GetPlaneGeometry() ); // Just as with the original line, calculate the intersection with // the world geometry... if ( (otherPlane != inputPlaneGeometry) && worldPlaneGeometry->IntersectionLine( otherPlane, otherCrossLine ) ) { //otherLineThickSlicesMode = this->DetermineThickSliceMode((*otherPlanesIt), otherLineThickSlicesNum); Vector3D normal = otherPlane->GetNormal(); double otherLineThickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); otherLineThickSliceDistance *= (otherLineThickSlicesNum)*2; Point2D otherLineFrom, otherLineTo; // ... and clip the resulting line segment with the reference // geometry bounding box. otherCrossLine.Transform( *inverseTransform ); if ( otherCrossLine.BoxLineIntersection( boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], otherCrossLine.GetPoint(), otherCrossLine.GetDirection(), point1, point2 ) == 2 ) { worldPlaneGeometry->Map( transform->TransformPoint( point1 ), otherLineFrom ); worldPlaneGeometry->Map( transform->TransformPoint( point2 ), otherLineTo ); otherLine.SetPoints( otherLineFrom, otherLineTo ); // then we have to determine the gap position of the main line // by finding the position at which the two lines cross this->DetermineParametricCrossPositions( mainLine, otherLine, mainLineParams ); // if the other line is also in thick slice mode, we have to determine the // gapsize considering the width of that other line and the spacing in its direction if ( showAreaOfThickSlicing ) { Vector2D otherLineDirection = otherLine.GetDirection(); otherLineDirection.Normalize(); mainLineDirectionOrthogonal.Normalize(); // determine the gapsize gapSize = fabs( otherLineThickSliceDistance / ( otherLineDirection*mainLineDirectionOrthogonal ) ); gapSize = gapSize / displayGeometry->GetScaleFactorMMPerDisplayUnit(); // determine the gap positions for the helper lines as well this->DetermineParametricCrossPositions( primaryHelperLine, otherLine, primaryHelperLineParams ); this->DetermineParametricCrossPositions( secondaryHelperLine, otherLine, secondaryHelperLineParams ); } } } ++otherPlanesIt; } // If we have to draw the helperlines, the mainline will be drawn as a dashed line // with a fixed gapsize of 10 pixels this->DrawLine(renderer, lengthInDisplayUnits, mainLine, mainLineParams, inputPlaneGeometry, showAreaOfThickSlicing, 10.0 ); // If drawn, the helperlines are drawn as a solid line. The gapsize depends on the // width of the crossed line. if ( showAreaOfThickSlicing ) { this->DrawLine(renderer, lengthInDisplayUnits, primaryHelperLine, primaryHelperLineParams, inputPlaneGeometry, false, gapSize ); this->DrawLine(renderer, lengthInDisplayUnits, secondaryHelperLine, secondaryHelperLineParams, inputPlaneGeometry, false, gapSize ); } } } } else { PlaneGeometryDataToSurfaceFilter::Pointer surfaceCreator; SmartPointerProperty::Pointer surfacecreatorprop; surfacecreatorprop = dynamic_cast< SmartPointerProperty * >( GetDataNode()->GetProperty( "surfacegeometry", renderer)); if( (surfacecreatorprop.IsNull()) || (surfacecreatorprop->GetSmartPointer().IsNull()) || ((surfaceCreator = dynamic_cast< PlaneGeometryDataToSurfaceFilter * >( surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull()) ) { surfaceCreator = PlaneGeometryDataToSurfaceFilter::New(); surfacecreatorprop = SmartPointerProperty::New(surfaceCreator); surfaceCreator->PlaceByGeometryOn(); GetDataNode()->SetProperty( "surfacegeometry", surfacecreatorprop ); } surfaceCreator->SetInput( input ); // Clip the PlaneGeometry with the reference geometry bounds (if available) if ( input->GetPlaneGeometry()->HasReferenceGeometry() ) { surfaceCreator->SetBoundingBox( input->GetPlaneGeometry()->GetReferenceGeometry()->GetBoundingBox() ); } int res; bool usegeometryparametricbounds = true; if ( GetDataNode()->GetIntProperty("xresolution", res, renderer)) { surfaceCreator->SetXResolution(res); usegeometryparametricbounds=false; } if (GetDataNode()->GetIntProperty("yresolution", res, renderer)) { surfaceCreator->SetYResolution(res); usegeometryparametricbounds=false; } surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds); // Calculate the surface of the PlaneGeometry surfaceCreator->Update(); if (m_SurfaceMapper.IsNull()) { m_SurfaceMapper=SurfaceGLMapper2D::New(); } m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput()); m_SurfaceMapper->SetDataNode(GetDataNode()); m_SurfaceMapper->Paint(renderer); } } -void mitk::PlaneGeometryDataMapper2D::DrawOrientationArrow( mitk::Point2D &outerPoint, mitk::Point2D &innerPoint, +void mitk::PlaneGeometryDataGLMapper2D::DrawOrientationArrow( mitk::Point2D &outerPoint, mitk::Point2D &innerPoint, const mitk::PlaneGeometry *planeGeometry, const mitk::PlaneGeometry *rendererPlaneGeometry, const mitk::DisplayGeometry *displayGeometry, bool positiveOrientation ) { // Draw arrows to indicate plane orientation // Vector along line Vector2D v1 = innerPoint - outerPoint; v1.Normalize(); v1 *= 7.0; // Orthogonal vector Vector2D v2; v2[0] = v1[1]; v2[1] = -v1[0]; // Calculate triangle tip for one side and project it back into world // coordinates to determine whether it is above or below the plane Point2D worldPoint2D; Point3D worldPoint; displayGeometry->DisplayToWorld( outerPoint + v1 + v2, worldPoint2D ); rendererPlaneGeometry->Map( worldPoint2D, worldPoint ); // Initialize remaining triangle coordinates accordingly // (above/below state is XOR'ed with orientation flag) Point2D p1 = outerPoint + v1 * 2.0; Point2D p2 = outerPoint + v1 + ((positiveOrientation ^ planeGeometry->IsAbove( worldPoint )) ? v2 : -v2); // Draw the arrow (triangle) glBegin( GL_TRIANGLES ); glVertex2f( outerPoint[0], outerPoint[1] ); glVertex2f( p1[0], p1[1] ); glVertex2f( p2[0], p2[1] ); glEnd(); } -void mitk::PlaneGeometryDataMapper2D::ApplyAllProperties( BaseRenderer *renderer ) +void mitk::PlaneGeometryDataGLMapper2D::ApplyAllProperties( BaseRenderer *renderer ) { Superclass::ApplyColorAndOpacityProperties(renderer); PlaneOrientationProperty* decorationProperty; this->GetDataNode()->GetProperty( decorationProperty, "decoration", renderer ); if ( decorationProperty != NULL ) { if ( decorationProperty->GetPlaneDecoration() == PlaneOrientationProperty::PLANE_DECORATION_POSITIVE_ORIENTATION ) { m_RenderOrientationArrows = true; m_ArrowOrientationPositive = true; } else if ( decorationProperty->GetPlaneDecoration() == PlaneOrientationProperty::PLANE_DECORATION_NEGATIVE_ORIENTATION ) { m_RenderOrientationArrows = true; m_ArrowOrientationPositive = false; } else { m_RenderOrientationArrows = false; } } } -void mitk::PlaneGeometryDataMapper2D::SetDatastorageAndGeometryBaseNode( mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent ) +void mitk::PlaneGeometryDataGLMapper2D::SetDatastorageAndGeometryBaseNode( mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent ) { if (ds.IsNotNull()) { m_DataStorage = ds; } if (parent.IsNotNull()) { m_ParentNode = parent; } } -void mitk::PlaneGeometryDataMapper2D::DrawLine( BaseRenderer* renderer, +void mitk::PlaneGeometryDataGLMapper2D::DrawLine( BaseRenderer* renderer, ScalarType lengthInDisplayUnits, Line &line, std::vector &gapPositions, const PlaneGeometry* inputPlaneGeometry, bool drawDashed, ScalarType gapSizeInPixel ) { DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); const PlaneGeometry *worldPlaneGeometry = dynamic_cast< const PlaneGeometry* >( renderer->GetCurrentWorldPlaneGeometry() ); // Apply color and opacity read from the PropertyList. this->ApplyAllProperties( renderer ); ScalarType gapSizeInParamUnits = 1.0 / lengthInDisplayUnits * gapSizeInPixel; std::sort( gapPositions.begin(), gapPositions.end() ); Point2D p1, p2; ScalarType p1Param, p2Param; p1Param = gapPositions[0]; p1 = line.GetPoint( p1Param ); displayGeometry->WorldToDisplay( p1, p1 ); //Workaround to show the crosshair always on top of a 2D render window //The image is usually located at depth = 0 or negative depth values, and thus, //the crosshair with depth = 1 is always on top. float depthPosition = 1.0f; if ( drawDashed ) { glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0xF0F0); } glEnable(GL_DEPTH_TEST); // Iterate over all line segments and display each, with a gap // in between. unsigned int i, preLastLineParam = gapPositions.size() - 1; for ( i = 1; i < preLastLineParam; ++i ) { p2Param = gapPositions[i] - gapSizeInParamUnits * 0.5; p2 = line.GetPoint( p2Param ); if ( p2Param > p1Param ) { // Convert intersection points (until now mm) to display // coordinates (units). displayGeometry->WorldToDisplay( p2, p2 ); // draw glBegin (GL_LINES); glVertex3f(p1[0],p1[1], depthPosition); glVertex3f(p2[0],p2[1], depthPosition); glEnd (); if ( (i == 1) && (m_RenderOrientationArrows) ) { // Draw orientation arrow for first line segment this->DrawOrientationArrow( p1, p2, inputPlaneGeometry, worldPlaneGeometry, displayGeometry, m_ArrowOrientationPositive ); } } p1Param = p2Param + gapSizeInParamUnits; p1 = line.GetPoint( p1Param ); displayGeometry->WorldToDisplay( p1, p1 ); } // Draw last line segment p2Param = gapPositions[i]; p2 = line.GetPoint( p2Param ); displayGeometry->WorldToDisplay( p2, p2 ); glBegin( GL_LINES ); glVertex3f( p1[0], p1[1], depthPosition); glVertex3f( p2[0], p2[1], depthPosition); glEnd(); if ( drawDashed ) { glDisable(GL_LINE_STIPPLE); } // Draw orientation arrows if ( m_RenderOrientationArrows ) { this->DrawOrientationArrow( p2, p1, inputPlaneGeometry, worldPlaneGeometry, displayGeometry, m_ArrowOrientationPositive ); if ( preLastLineParam < 2 ) { // If we only have one line segment, draw other arrow, too this->DrawOrientationArrow( p1, p2, inputPlaneGeometry, worldPlaneGeometry, displayGeometry, m_ArrowOrientationPositive ); } } } -int mitk::PlaneGeometryDataMapper2D::DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ) +int mitk::PlaneGeometryDataGLMapper2D::DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ) { int thickSlicesMode = 0; // determine the state and the extend of the thick-slice mode mitk::ResliceMethodProperty *resliceMethodEnumProperty=0; if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty ) thickSlicesMode = resliceMethodEnumProperty->GetValueAsId(); IntProperty *intProperty=0; if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) { thickSlicesNum = intProperty->GetValue(); if(thickSlicesNum < 1) thickSlicesNum=0; if(thickSlicesNum > 10) thickSlicesNum=10; } if ( thickSlicesMode == 0 ) thickSlicesNum = 0; return thickSlicesMode; } -void mitk::PlaneGeometryDataMapper2D::DetermineParametricCrossPositions( Line< mitk::ScalarType, 2 > &mainLine, +void mitk::PlaneGeometryDataGLMapper2D::DetermineParametricCrossPositions( Line< mitk::ScalarType, 2 > &mainLine, Line< mitk::ScalarType, 2 > &otherLine, std::vector< mitk::ScalarType > &crossPositions ) { Vector2D direction, dOrth; // By means of the dot product, calculate the gap position as // parametric value in the range [0, 1] direction = otherLine.GetDirection(); dOrth[0] = -direction[1]; dOrth[1] = direction[0]; ScalarType gapPosition = ( otherLine.GetPoint1() - mainLine.GetPoint1() ) * dOrth; ScalarType norm = mainLine.GetDirection() * dOrth; if ( fabs( norm ) > eps ) { gapPosition /= norm; if ( (gapPosition > 0.0) && (gapPosition < 1.0) ) { crossPositions.push_back(gapPosition); } } } diff --git a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h b/Modules/LegacyGL/mitkPlaneGeometryDataGLMapper2D.h similarity index 90% copy from Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h copy to Modules/LegacyGL/mitkPlaneGeometryDataGLMapper2D.h index a03ed7f84a..83de7a79d9 100644 --- a/Core/Code/Rendering/mitkPlaneGeometryDataMapper2D.h +++ b/Modules/LegacyGL/mitkPlaneGeometryDataGLMapper2D.h @@ -1,122 +1,122 @@ /*=================================================================== 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 MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB #define MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB -#include +#include #include "mitkGLMapper.h" #include "mitkSurfaceGLMapper2D.h" #include "mitkDataStorage.h" #include "mitkDataNode.h" #include "mitkWeakPointer.h" #include "mitkLine.h" namespace mitk { class BaseRenderer; - class PlaneGeometryDataMapper2D; - /** \deprecatedSince{2014_10} This class is deprecated. Please use PlaneGeometryDataMapper2D instead. */ - DEPRECATED( typedef PlaneGeometryDataMapper2D Geometry2DDataMapper2D); + class PlaneGeometryDataGLMapper2D; + /** \deprecatedSince{2014_10} This class is deprecated. Please use PlaneGeometryDataGLMapper2D instead. */ + DEPRECATED( typedef PlaneGeometryDataGLMapper2D Geometry2DDataMapper2D); /** * \brief OpenGL-based mapper to display a PlaneGeometry in a 2D window * * Currently implemented for mapping on PlaneGeometry. * The result is normally a line. An important usage of this class is to show * the orientation of the slices displayed in other 2D windows. * * - * Properties that can be set and influence the PlaneGeometryDataMapper2D are: + * Properties that can be set and influence the PlaneGeometryDataGLMapper2D are: * * - \b "PlaneOrientationProperty": (PlaneOrientationProperty) * \todo implement for AbstractTransformGeometry. * \ingroup Mapper */ - class MITK_CORE_EXPORT PlaneGeometryDataMapper2D : public GLMapper + class MitkLegacyGL_EXPORT PlaneGeometryDataGLMapper2D : public GLMapper { public: - mitkClassMacro(PlaneGeometryDataMapper2D, GLMapper); + mitkClassMacro(PlaneGeometryDataGLMapper2D, GLMapper); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * \brief Get the PlaneGeometryData to map */ const PlaneGeometryData *GetInput(); virtual void Paint( BaseRenderer *renderer ); virtual void SetDatastorageAndGeometryBaseNode(mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent); /** Applies properties specific to this mapper */ virtual void ApplyAllProperties( BaseRenderer *renderer ); LocalStorageHandler m_LSH; protected: - PlaneGeometryDataMapper2D(); + PlaneGeometryDataGLMapper2D(); - virtual ~PlaneGeometryDataMapper2D(); + virtual ~PlaneGeometryDataGLMapper2D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); /** * \brief Returns the thick slice mode for the given datanode. * * This method returns the value of the 'reslice.thickslices' property for * the given datanode. * '0': thick slice mode disabled * '1': thick slice mode enabled * * The variable 'thickSlicesNum' contains the value of the 'reslice.thickslices.num' * property that defines how many slices are shown at once. */ int DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ); /** * \brief Determines the cross position of two lines and stores them as parametric coordinates * * This method determines the parametric position at which a line 'otherLine' crosses another line * 'mainLine'. The result is stored in 'crossPositions'. */ void DetermineParametricCrossPositions( Line &mainLine, Line &otherLine, std::vector &crossPositions ); void DrawLine( BaseRenderer * renderer, ScalarType lengthInDisplayUnits, Line< ScalarType, 2 > &line, std::vector< ScalarType > &gapPositions, const PlaneGeometry * inputPlaneGeometry, bool drawDashed, ScalarType gapSizeInPixel ); void DrawOrientationArrow( Point2D &outerPoint, Point2D &innerPoint, const PlaneGeometry *planeGeometry, const PlaneGeometry *rendererPlaneGeometry, const DisplayGeometry *displayGeometry, bool positiveOrientation = true ); SurfaceGLMapper2D::Pointer m_SurfaceMapper; mitk::WeakPointer m_DataStorage; ///< DataStorage that will be searched for sub nodes DataNode::Pointer m_ParentNode; ///< parent node that will be used to search for sub nodes typedef std::vector NodesVectorType; NodesVectorType m_OtherPlaneGeometries; bool m_RenderOrientationArrows; bool m_ArrowOrientationPositive; }; } // namespace mitk #endif /* MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB */ diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp b/Modules/LegacyGL/mitkPointSetGLMapper2D.cpp similarity index 100% rename from Core/Code/Rendering/mitkPointSetGLMapper2D.cpp rename to Modules/LegacyGL/mitkPointSetGLMapper2D.cpp diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.h b/Modules/LegacyGL/mitkPointSetGLMapper2D.h similarity index 96% rename from Core/Code/Rendering/mitkPointSetGLMapper2D.h rename to Modules/LegacyGL/mitkPointSetGLMapper2D.h index 00ddfb1a75..3acd4adeb4 100644 --- a/Core/Code/Rendering/mitkPointSetGLMapper2D.h +++ b/Modules/LegacyGL/mitkPointSetGLMapper2D.h @@ -1,99 +1,99 @@ /*=================================================================== 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 MITKPointSetMAPPER2D_H_HEADER_INCLUDED #define MITKPointSetMAPPER2D_H_HEADER_INCLUDED -#include +#include #include "mitkGLMapper.h" namespace mitk { class BaseRenderer; class PointSet; /** * @brief OpenGL-based mapper to display a mitk::PointSet in a 2D window. * * This mapper can actually more than just draw a number of points of a * mitk::PointSet. If you set the right properties of the mitk::DataNode, * which contains the point set, then this mapper will also draw lines * connecting the points, and calculate and display distances and angles * between adjacent points. Here is a complete list of boolean properties, * which might be of interest: * * - \b "show contour": Draw not only the points but also the connections between * them (default false) * - \b "line width": IntProperty which gives the width of the contour lines * - \b "show points": Wheter or not to draw the actual points (default true) * - \b "show distances": Wheter or not to calculate and print the distance * between adjacent points (default false) * - \b "show angles": Wheter or not to calculate and print the angle between * adjacent points (default false) * - \b "show distant lines": When true, the mapper will also draw contour * lines that are far away form the current slice (default true) * - \b "label": StringProperty with a label for this point set * * BUG 1321 - possible new features: * point-2d-size (length of lines in cross/diamond) * point-linewidth * * @ingroup Mapper */ /** \deprecatedSince{2013_06} This mapper is replaced by PointSetVtkMapper2D. The child classes of this class are deprecated. * To further ensure their functionality PointSetGLMapper2D cannot be removed and is set deprecated too. */ -class MITK_CORE_EXPORT PointSetGLMapper2D : public GLMapper +class MitkLegacyGL_EXPORT PointSetGLMapper2D : public GLMapper { public: mitkClassMacro(PointSetGLMapper2D, GLMapper); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** @brief Get the PointDataList to map */ virtual const mitk::PointSet * GetInput(void); virtual void Paint(mitk::BaseRenderer * renderer); virtual void ApplyAllProperties(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: PointSetGLMapper2D(); virtual ~PointSetGLMapper2D(); bool m_Polygon; bool m_PolygonClosed; bool m_ShowPoints; bool m_ShowDistances; int m_DistancesDecimalDigits; bool m_ShowAngles; bool m_ShowDistantLines; int m_LineWidth; int m_PointLineWidth; int m_Point2DSize; }; } // namespace mitk #endif /* MITKPointSetMapper2D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp b/Modules/LegacyGL/mitkSurfaceGLMapper2D.cpp similarity index 100% rename from Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp rename to Modules/LegacyGL/mitkSurfaceGLMapper2D.cpp diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.h b/Modules/LegacyGL/mitkSurfaceGLMapper2D.h similarity index 98% rename from Core/Code/Rendering/mitkSurfaceGLMapper2D.h rename to Modules/LegacyGL/mitkSurfaceGLMapper2D.h index 310409b441..9f2a2fc3a7 100644 --- a/Core/Code/Rendering/mitkSurfaceGLMapper2D.h +++ b/Modules/LegacyGL/mitkSurfaceGLMapper2D.h @@ -1,156 +1,155 @@ /*=================================================================== 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 MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 #define MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 -#include +#include #include "mitkGLMapper.h" #include "mitkSurface.h" class vtkCutter; class vtkPlane; class vtkLookupTable; class vtkLinearTransform; class vtkPKdTree; class vtkStripper; namespace mitk { class BaseRenderer; class PlaneGeometry; class DisplayGeometry; /** * @brief OpenGL-based mapper to display a Surface in a 2D window. * * Displays a 2D cut through a Surface object (vtkPolyData). This * is basically done in two steps: * * 1. Cut a slice out of a (input) vtkPolyData object. The slice may be a flat plane (PlaneGeometry) * or a curved plane (ThinPlateSplineCurvedGeometry). The actual cutting is done by a vtkCutter. * The result of cutting is a (3D) vtkPolyData object, which contains only points and lines * describing the cut. * * 2. Paint the cut out slice by means of OpenGL. To do this, all lines of the cut object are traversed. * For each line segment, both end points are transformed from 3D into the 2D system of the associated * renderer and then drawn by OpenGL. * * There is a mode to display normals of the input surface object (see properties below). If this mode * is on, then the drawing of the 2D cut is slightly more complicated. For each line segment of the cut, * we take the end point (p2d) of this line and search the input vtkPolyData object for the closest point to p2d (p3D-input). * We then read out the surface normal for p3D-input. We map this normal into our 2D coordinate system and * then draw a line from p2d to (p2d+mapped normal). This drawing of surface normals will only work if the * input vtkPolyData actually HAS normals. If you have a vtkPolyData without normals, use the vtkPolyDataNormals * filter to generate normals. * * Properties that influence rendering are: * * - \b "color": (ColorProperty) Color of surface object * - \b "line width": (IntProperty) Width in pixels of the lines drawn. * - \b "scalar visibility": (BoolProperty) Whether point/cell data values (from vtkPolyData) should be used to influence colors * - \b "scalar mode": (BoolProperty) If "scalar visibility" is on, whether to use point data or cell data for coloring. * - \b "LookupTable": (LookupTableProperty) A lookup table to translate point/cell data values (from vtkPolyData) to colors * - \b "ScalarsRangeMinimum": (FloatProperty) Range of the lookup table * - \b "ScalarsRangeMaximum": (FloatProperty) Range of the lookup table * - \b "draw normals 2D": (BoolProperty) If true, normals are drawn (if present in vtkPolyData) * - \b "invert normals": (BoolProperty) Inverts front/back for display. * - \b "front color": (ColorProperty) Color for normals display on front side of the plane * - \b "front normal length (px)": (FloatProperty) Length of the front side normals in pixels. * - \b "back color": (ColorProperty) Color for normals display on back side of the plane * - \b "back normal length (px)": (FloatProperty) Length of the back side normals in pixels. * */ -class MITK_CORE_EXPORT SurfaceGLMapper2D : public GLMapper +class MitkLegacyGL_EXPORT SurfaceGLMapper2D : public GLMapper { public: mitkClassMacro(SurfaceGLMapper2D, GLMapper); itkFactorylessNewMacro(Self) itkCloneMacro(Self) const Surface* GetInput(void); virtual void Paint(BaseRenderer* renderer); /** * @brief The Surface to map can be explicitly set by this method. * * If it is set, it is used instead of the data stored in the DataNode. * This enables to use the mapper also internally from other mappers. */ itkSetConstObjectMacro(Surface, Surface); /** * @brief Get the Surface set explicitly. * * @return NULL is returned if no Surface is set to be used instead of DataNode::GetData(). * @sa SetSurface */ itkGetConstObjectMacro(Surface, Surface); /** *\brief Overwritten to initialize lookup table for point scalar data */ void SetDataNode( DataNode* node ); /** * \brief Generate OpenGL primitives for the VTK contour held in contour. */ void PaintCells(BaseRenderer* renderer, vtkPolyData* contour, const PlaneGeometry* worldGeometry, const DisplayGeometry* displayGeometry, vtkLinearTransform* vtktransform, vtkLookupTable* lut = NULL, vtkPolyData* original3DObject = NULL); static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); virtual void ApplyAllProperties(BaseRenderer* renderer); protected: SurfaceGLMapper2D(); virtual ~SurfaceGLMapper2D(); vtkPlane* m_Plane; vtkCutter* m_Cutter; Surface::ConstPointer m_Surface; vtkLookupTable* m_LUT; int m_LineWidth; vtkPKdTree* m_PointLocator; vtkStripper* m_Stripper; bool m_DrawNormals; float m_FrontSideColor[4]; float m_BackSideColor[4]; float m_LineColor[4]; float m_FrontNormalLengthInPixels; float m_BackNormalLengthInPixels; }; } // namespace mitk #endif /* MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 */ - diff --git a/Modules/LegacyGL/mitkVtkGLMapperWrapper.cpp b/Modules/LegacyGL/mitkVtkGLMapperWrapper.cpp new file mode 100644 index 0000000000..a543a1f861 --- /dev/null +++ b/Modules/LegacyGL/mitkVtkGLMapperWrapper.cpp @@ -0,0 +1,159 @@ +/*=================================================================== + +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 "mitkVtkGLMapperWrapper.h" + +//mitk includes +#include "mitkDataNode.h" +#include "vtkGLMapperProp.h" +#include "mitkGL.h" + +// constructor LocalStorage +mitk::VtkGLMapperWrapper::LocalStorage::LocalStorage() +{ + m_GLMapperProp = vtkSmartPointer::New(); +} +// destructor LocalStorage +mitk::VtkGLMapperWrapper::LocalStorage::~LocalStorage() +{ +} + +// constructor VtkGLMapperWrapper +mitk::VtkGLMapperWrapper::VtkGLMapperWrapper(GLMapper::Pointer mitkGLMapper) +{ + m_MitkGLMapper = mitkGLMapper; +} + +// destructor +mitk::VtkGLMapperWrapper::~VtkGLMapperWrapper() +{ +} + +// returns propassembly +vtkProp* mitk::VtkGLMapperWrapper::GetVtkProp(mitk::BaseRenderer * renderer) +{ + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + return ls->m_GLMapperProp; +} + +void mitk::VtkGLMapperWrapper::GenerateDataForRenderer(mitk::BaseRenderer *renderer) +{ + m_MitkGLMapper->SetDataNode(GetDataNode()); + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + ls->m_GLMapperProp->SetBaseRenderer(renderer); + ls->m_GLMapperProp->SetWrappedGLMapper(m_MitkGLMapper); +} + +void mitk::VtkGLMapperWrapper::ApplyColorAndOpacityProperties(mitk::BaseRenderer *renderer, vtkActor *actor) +{ + m_MitkGLMapper->ApplyColorAndOpacityProperties(renderer,actor); +} + +void mitk::VtkGLMapperWrapper::MitkRender(mitk::BaseRenderer *renderer, mitk::VtkPropRenderer::RenderType type) +{ + if(type != mitk::VtkPropRenderer::Opaque) + return; + Enable2DOpenGL(renderer); + Superclass::MitkRender(renderer,type); + Disable2DOpenGL(); +} + +/*! +\brief +Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) +*/ +void mitk::VtkGLMapperWrapper::Enable2DOpenGL(mitk::BaseRenderer *renderer) +{ + GLint iViewport[4]; + + // Get a copy of the viewport + glGetIntegerv( GL_VIEWPORT, iViewport ); + + // Save a copy of the projection matrix so that we can restore it + // when it's time to do 3D rendering again. + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + + // Set up the orthographic projection + const mitk::DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry(); + + float displayGeometryWidth = displayGeometry->GetSizeInDisplayUnits()[0]; + float displayGeometryHeight = displayGeometry->GetSizeInDisplayUnits()[1]; + float viewportWidth = iViewport[2]; + float viewportHeight = iViewport[3]; + + /* + The following makes OpenGL mappers draw into the same viewport + that is used by VTK when someone calls vtkRenderer::SetViewport(). + + The parameters of glOrtho describe what "input" coordinates + (display coordinates generated by the OpenGL mappers) are transformed + into the region defined by the viewport. The call has to consider + that the scene is fit vertically and centered horizontally. + + Problem: this is a crude first step towards rendering into viewports. + - mitkViewportRenderingTest demonstrates the non-interactive rendering + that is now possible + - interactors that measure mouse movement in pixels will + probably run into problems with display-to-world transformation + + A proper solution should probably modify the DisplayGeometry to + correctly describe the viewport. + */ + // iViewport is (x,y,width,height) + // glOrtho expects (left,right,bottom,top,znear,zfar) + glOrtho( 0 + - 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight + + 0.5 * (displayGeometryWidth - displayGeometryHeight) + , + displayGeometryWidth + + 0.5 * (viewportWidth/viewportHeight-1.0)*displayGeometryHeight + - 0.5 * (displayGeometryWidth - displayGeometryHeight) + , + 0, displayGeometryHeight, + -1.0, 1.0 + ); + + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + // Make sure depth testing and lighting are disabled for 2D rendering until + // we are finished rendering in 2D + glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT ); + glDisable( GL_DEPTH_TEST ); + glDisable( GL_LIGHTING ); + // disable the texturing here so crosshair is painted in the correct colors + // vtk will reenable texturing every time it is needed + glDisable( GL_TEXTURE_1D ); + glDisable( GL_TEXTURE_2D ); + glLineWidth(1.0); +} + +/*! +\brief Initialize the VtkPropRenderer + +Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) +*/ +void mitk::VtkGLMapperWrapper::Disable2DOpenGL() +{ + glPopAttrib(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); +} diff --git a/Modules/LegacyGL/mitkVtkGLMapperWrapper.h b/Modules/LegacyGL/mitkVtkGLMapperWrapper.h new file mode 100644 index 0000000000..bd93b58187 --- /dev/null +++ b/Modules/LegacyGL/mitkVtkGLMapperWrapper.h @@ -0,0 +1,84 @@ +/*=================================================================== + +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 MITKVtkGLMapperWrapper_H_HEADER +#define MITKVtkGLMapperWrapper_H_HEADER + + +#include +#include "mitkVtkMapper.h" +#include "mitkBaseRenderer.h" +#include "mitkLocalStorageHandler.h" +#include +#include "mitkGLMapper.h" + +class vtkGLMapperProp; + +namespace mitk { + + /** + * @brief Vtk-based 2D mapper for PointSet + */ + class MitkLegacyGL_EXPORT VtkGLMapperWrapper : public VtkMapper + { + public: + mitkClassMacro(VtkGLMapperWrapper, VtkMapper); + + mitkNewMacro1Param(Self,GLMapper::Pointer) + + itkCloneMacro(Self) + + /** \brief returns the a prop assembly */ + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); + + /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ + class LocalStorage : public mitk::Mapper::BaseLocalStorage + { + public: + /* constructor */ + LocalStorage(); + + /* destructor */ + ~LocalStorage(); + vtkSmartPointer m_GLMapperProp; + }; + + virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor); + + void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); + + /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ + mitk::LocalStorageHandler m_LSH; + + protected: + + + GLMapper::Pointer m_MitkGLMapper; + /* constructor */ + VtkGLMapperWrapper(GLMapper::Pointer mitkGLMapper); + + /* destructor */ + virtual ~VtkGLMapperWrapper(); + void Enable2DOpenGL(mitk::BaseRenderer *renderer); + void Disable2DOpenGL(); + }; + +} // namespace mitk + +#endif /* MITKVtkGLMapperWrapper_H_HEADER_INCLUDED_C1902626 */ diff --git a/Modules/LegacyGL/vtkGLMapperProp.cpp b/Modules/LegacyGL/vtkGLMapperProp.cpp new file mode 100644 index 0000000000..44d9bcf12b --- /dev/null +++ b/Modules/LegacyGL/vtkGLMapperProp.cpp @@ -0,0 +1,68 @@ +/*=================================================================== + +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 "vtkGLMapperProp.h" + +#include + + +vtkStandardNewMacro(vtkGLMapperProp); + +vtkGLMapperProp::vtkGLMapperProp() +{ +} + +vtkGLMapperProp::~vtkGLMapperProp() +{ +} + +int vtkGLMapperProp::RenderOpaqueGeometry(vtkViewport *) +{ + if(!m_WrappedGLMapper || !m_BaseRenderer) + return 0; + + this->m_WrappedGLMapper->MitkRender(m_BaseRenderer, mitk::VtkPropRenderer::Opaque); +} + +int vtkGLMapperProp::RenderTranslucentPolygonalGeometry(vtkViewport *) +{ + return 0; +} + +int vtkGLMapperProp::RenderVolumetricGeometry(vtkViewport *) +{ + return 0; +} + +int vtkGLMapperProp::RenderOverlay(vtkViewport *) +{ + return 0; +} + +const mitk::GLMapper *vtkGLMapperProp::GetWrappedGLMapper() const +{ + return m_WrappedGLMapper; +} + +void vtkGLMapperProp::SetWrappedGLMapper(mitk::GLMapper* glMapper) +{ + this->m_WrappedGLMapper = glMapper; +} + +void vtkGLMapperProp::SetBaseRenderer(mitk::BaseRenderer *baseRenderer) +{ + this->m_BaseRenderer = baseRenderer; +} diff --git a/Modules/LegacyGL/vtkGLMapperProp.h b/Modules/LegacyGL/vtkGLMapperProp.h new file mode 100644 index 0000000000..fea9354ca7 --- /dev/null +++ b/Modules/LegacyGL/vtkGLMapperProp.h @@ -0,0 +1,58 @@ +/*=================================================================== + +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 vtkGLMapperProp_h +#define vtkGLMapperProp_h + +#include "MitkLegacyGLExports.h" + +#include +#include +#include "mitkGLMapper.h" + +/** + * @brief The vtkGLMapperProp class is a VtkProp, wrapping a GLMapper + */ +class MitkLegacyGL_EXPORT vtkGLMapperProp : public vtkProp +{ + public: + static vtkGLMapperProp* New(); + vtkTypeMacro(vtkGLMapperProp,vtkProp); + + /** + * @brief RenderOverlay Calls the render method of the actor and renders it. + * @param viewport viewport of the renderwindow. + * @return + */ + int RenderOverlay(vtkViewport* viewport); + int RenderVolumetricGeometry(vtkViewport *); + int RenderTranslucentPolygonalGeometry(vtkViewport *); + int RenderOpaqueGeometry(vtkViewport *); + + const mitk::GLMapper *GetWrappedGLMapper() const; + void SetWrappedGLMapper(mitk::GLMapper *glMapper); + + void SetBaseRenderer(mitk::BaseRenderer* baseRenderer); +protected: + + vtkGLMapperProp(); + virtual ~vtkGLMapperProp(); + + mitk::GLMapper* m_WrappedGLMapper; + mitk::BaseRenderer* m_BaseRenderer; + +}; +#endif /* vtkGLMapperProp2_h */ diff --git a/Modules/MapperExt/CMakeLists.txt b/Modules/MapperExt/CMakeLists.txt index bd6df94343..92f6db34d6 100644 --- a/Modules/MapperExt/CMakeLists.txt +++ b/Modules/MapperExt/CMakeLists.txt @@ -1,8 +1,8 @@ -MITK_CREATE_MODULE(DEPENDS MitkDataTypesExt +MITK_CREATE_MODULE(DEPENDS MitkDataTypesExt MitkLegacyGL PACKAGE_DEPENDS VTK|vtkRenderingVolumeOpenGL WARNINGS_AS_ERRORS ) if(BUILD_TESTING) #add_subdirectory(Testing) endif() diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 9e865cddcc..b6869ffd3e 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,59 +1,60 @@ set(mitk_modules + LegacyGL LegacyIO DataTypesExt AlgorithmsExt MapperExt DICOMReader DICOMTesting Qt4Qt5TestModule SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction ImageStatistics LegacyAdaptors SceneSerialization GraphAlgorithms ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QmlItems Overlays QtWidgets QtWidgetsExt SegmentationUI DiffusionImaging GPGPU IGTBase IGT CameraCalibration RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport QtOverlays InputDevices ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python Persistence IGTUI VtkShaders DicomRT IOExt XNAT ) if(MITK_ENABLE_PIC_READER) list(APPEND mitk_modules IpPicSupportIO) endif() diff --git a/Modules/Overlays/mitkTextOverlay2D.cpp b/Modules/Overlays/mitkTextOverlay2D.cpp index 147182bab0..37a8b85294 100644 --- a/Modules/Overlays/mitkTextOverlay2D.cpp +++ b/Modules/Overlays/mitkTextOverlay2D.cpp @@ -1,113 +1,124 @@ /*=================================================================== 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 -#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]; + bounds.Position = ls->m_TextActor->GetPosition(); + + double size[2]; + ls->m_TextActor->GetSize(renderer->GetVtkRenderer(), size); + bounds.Size[0] = size[0]; + bounds.Size[1] = size[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]); } + 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); + m_TextActor = vtkSmartPointer::New(); + m_TextProp = vtkSmartPointer::New(); + m_STextActor = vtkSmartPointer::New(); + m_STextProp = vtkSmartPointer::New(); + m_TextActor->SetTextProperty( m_TextProp ); + m_STextActor->SetTextProperty( m_STextProp ); + m_Assembly = vtkSmartPointer::New(); + m_Assembly->AddPart(m_STextActor); + m_Assembly->AddPart(m_TextActor); } void mitk::TextOverlay2D::UpdateVtkOverlay2D(mitk::BaseRenderer *renderer) { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); if(ls->IsGenerateDataRequired(renderer,this)) { - vtkSmartPointer freetype = vtkSmartPointer::New(); - vtkSmartPointer prop = vtkSmartPointer::New(); - float color[3] = {1,1,1}; + float color[3] = {0.0,1.0,0.0}; 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->m_TextProp->SetColor( color[0], color[1], color[2]); + ls->m_STextProp->SetColor( 0,0,0 ); + ls->m_TextProp->SetFontSize(GetFontSize()); + ls->m_TextProp->SetOpacity(opacity); + ls->m_STextProp->SetFontSize(GetFontSize()); + ls->m_STextProp->SetOpacity(opacity); + + bool drawShadow; + GetBoolProperty( "drawShadow", drawShadow ); + ls->m_TextProp->SetShadow( false ); + ls->m_STextProp->SetShadow( false ); + ls->m_STextActor->SetVisibility(drawShadow); + + ls->m_TextActor->SetInput( GetText().c_str() ); + ls->m_STextActor->SetInput( GetText().c_str() ); + + mitk::Point2D posT, posS; + posT[0] = GetPosition2D(renderer)[0]+GetOffsetVector(renderer)[0]; + posT[1] = GetPosition2D(renderer)[1]+GetOffsetVector(renderer)[1]; + posS[0] = posT[0]+1; + posS[1] = posT[1]-1; + posT = TransformDisplayPointToViewport(posT,renderer); + posS = TransformDisplayPointToViewport(posS,renderer); + + ls->m_TextActor->SetPosition(posT[0],posT[1]); + ls->m_STextActor->SetPosition(posS[0],posS[1]); ls->UpdateGenerateDataTime(); } } -vtkActor2D* mitk::TextOverlay2D::GetVtkActor2D(BaseRenderer *renderer) const +vtkProp *mitk::TextOverlay2D::GetVtkProp(mitk::BaseRenderer *renderer) const { LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); - return ls->m_textActor; + return ls->m_Assembly; } +vtkActor2D* mitk::TextOverlay2D::GetVtkActor2D(BaseRenderer *renderer) const +{ + LocalStorage* ls = this->m_LSH.GetLocalStorage(renderer); + return ls->m_TextActor; +} diff --git a/Modules/Overlays/mitkTextOverlay2D.h b/Modules/Overlays/mitkTextOverlay2D.h index 7902853043..34be208e4f 100644 --- a/Modules/Overlays/mitkTextOverlay2D.h +++ b/Modules/Overlays/mitkTextOverlay2D.h @@ -1,86 +1,92 @@ /*=================================================================== 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 TEXTOVERLAY2D_H #define TEXTOVERLAY2D_H #include #include #include #include "MitkOverlaysExports.h" class vtkTextActor; -class vtkImageMapper; -class vtkImageData; +class vtkPropAssembly; namespace mitk { /** \brief Displays text on the renderwindow */ class MitkOverlays_EXPORT TextOverlay2D : public mitk::VtkOverlay2D { public: class LocalStorage : public mitk::Overlay::BaseLocalStorage { public: /** \brief Actor of a 2D render window. */ - vtkSmartPointer m_textActor; - vtkSmartPointer m_textImage; - vtkSmartPointer m_imageMapper; + vtkSmartPointer m_TextActor; + + vtkSmartPointer m_TextProp; + + vtkSmartPointer m_STextActor; + + vtkSmartPointer m_STextProp; + + vtkSmartPointer m_Assembly; /** \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(TextOverlay2D, mitk::VtkOverlay2D); itkFactorylessNewMacro(Self) itkCloneMacro(Self) virtual Overlay::Bounds GetBoundsOnDisplay(BaseRenderer *renderer) const; virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds& bounds); + protected: /** \brief The LocalStorageHandler holds all LocalStorages for the render windows. */ mutable mitk::LocalStorageHandler m_LSH; + vtkProp* GetVtkProp(BaseRenderer *renderer) const; virtual vtkActor2D* GetVtkActor2D(BaseRenderer *renderer) const; void UpdateVtkOverlay2D(mitk::BaseRenderer *renderer); /** \brief explicit constructor which disallows implicit conversions */ explicit TextOverlay2D(); /** \brief virtual destructor in order to derive from this class */ virtual ~TextOverlay2D(); private: /** \brief copy constructor */ TextOverlay2D( const TextOverlay2D &); /** \brief assignment operator */ TextOverlay2D &operator=(const TextOverlay2D &); - }; } // namespace mitk #endif // TEXTOVERLAY2D_H diff --git a/Modules/PlanarFigure/Algorithms/mitkPlanarFigureObjectFactory.cpp b/Modules/PlanarFigure/Algorithms/mitkPlanarFigureObjectFactory.cpp index 1b92af848d..d6c7d9794e 100644 --- a/Modules/PlanarFigure/Algorithms/mitkPlanarFigureObjectFactory.cpp +++ b/Modules/PlanarFigure/Algorithms/mitkPlanarFigureObjectFactory.cpp @@ -1,146 +1,147 @@ /*=================================================================== 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 "mitkPlanarFigureObjectFactory.h" #include "mitkPlanarFigureWriter.h" #include "mitkCoreObjectFactory.h" #include "mitkPlanarFigureIOFactory.h" #include "mitkPlanarFigureWriterFactory.h" #include "mitkPlanarFigure.h" #include "mitkPlanarFigureMapper2D.h" #include "mitkPlanarFigureVtkMapper3D.h" +#include "mitkVtkGLMapperWrapper.h" typedef std::multimap MultimapType; mitk::PlanarFigureObjectFactory::PlanarFigureObjectFactory() : m_PlanarFigureIOFactory(PlanarFigureIOFactory::New().GetPointer()) , m_PlanarFigureWriterFactory(PlanarFigureWriterFactory::New().GetPointer()) { static bool alreadyDone = false; if ( !alreadyDone ) { itk::ObjectFactoryBase::RegisterFactory( m_PlanarFigureIOFactory ); itk::ObjectFactoryBase::RegisterFactory( m_PlanarFigureWriterFactory ); m_FileWriters.push_back( PlanarFigureWriter::New().GetPointer() ); CreateFileExtensionsMap(); alreadyDone = true; } } mitk::PlanarFigureObjectFactory::~PlanarFigureObjectFactory() { itk::ObjectFactoryBase::UnRegisterFactory(m_PlanarFigureWriterFactory); itk::ObjectFactoryBase::UnRegisterFactory(m_PlanarFigureIOFactory); } mitk::Mapper::Pointer mitk::PlanarFigureObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id) { mitk::Mapper::Pointer newMapper=NULL; mitk::BaseData *data = node->GetData(); if ( dynamic_cast(data) != NULL ) { if ( id == mitk::BaseRenderer::Standard2D ) { - newMapper = mitk::PlanarFigureMapper2D::New(); + newMapper = mitk::VtkGLMapperWrapper::New(mitk::PlanarFigureMapper2D::New().GetPointer()); newMapper->SetDataNode(node); } else if ( id == mitk::BaseRenderer::Standard3D ) { newMapper = mitk::PlanarFigureVtkMapper3D::New(); newMapper->SetDataNode(node); } } return newMapper; } void mitk::PlanarFigureObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if ( node == NULL ) { return; } mitk::DataNode::Pointer nodePointer = node; mitk::PlanarFigure::Pointer pf = dynamic_cast( node->GetData() ); if ( pf.IsNotNull() ) { mitk::PlanarFigureMapper2D::SetDefaultProperties(node); node->AddProperty( "color", mitk::ColorProperty::New(1.0,1.0,1.0), NULL, true ); node->AddProperty( "opacity", mitk::FloatProperty::New(0.8), NULL, true ); node->AddProperty( "planarfigure.3drendering", mitk::BoolProperty::New(false), NULL, true ); } } const char* mitk::PlanarFigureObjectFactory::GetFileExtensions() { return ""; } mitk::CoreObjectFactoryBase::MultimapType mitk::PlanarFigureObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } const char* mitk::PlanarFigureObjectFactory::GetSaveFileExtensions() { //return ";;Planar Figures (*.pf)"; // for mitk::PlanarFigure and derived classes std::string fileExtension; this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::PlanarFigureObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } void mitk::PlanarFigureObjectFactory::CreateFileExtensionsMap() { m_FileExtensionsMap.insert(std::pair("*.pf", "Planar Figure Files")); m_SaveFileExtensionsMap.insert(std::pair("*.pf", "Planar Figure Files")); } void mitk::PlanarFigureObjectFactory::RegisterIOFactories() { } struct RegisterPlanarFigureObjectFactory{ RegisterPlanarFigureObjectFactory() : m_Factory( mitk::PlanarFigureObjectFactory::New() ) { mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory( m_Factory ); } ~RegisterPlanarFigureObjectFactory() { mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory( m_Factory ); } mitk::PlanarFigureObjectFactory::Pointer m_Factory; }; static RegisterPlanarFigureObjectFactory registerPlanarFigureObjectFactory; diff --git a/Modules/PlanarFigure/CMakeLists.txt b/Modules/PlanarFigure/CMakeLists.txt index b87a8b0fe7..34264f3cfb 100644 --- a/Modules/PlanarFigure/CMakeLists.txt +++ b/Modules/PlanarFigure/CMakeLists.txt @@ -1,9 +1,9 @@ MITK_CREATE_MODULE( INCLUDE_DIRS Algorithms DataManagement Interactions IO Rendering - DEPENDS MitkLegacyIO MitkSceneSerializationBase + DEPENDS MitkLegacyIO MitkSceneSerializationBase MitkLegacyGL MitkOverlays WARNINGS_AS_ERRORS ) IF( BUILD_TESTING ) add_subdirectory(Testing) ENDIF() diff --git a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp index 78a9213403..e8535cc4b6 100644 --- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp +++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp @@ -1,925 +1,932 @@ -/*=================================================================== +/*=================================================================== 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 "mitkPlanarFigureMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkGL.h" -#include "mitkVtkPropRenderer.h" + +#include "mitkTextOverlay2D.h" #define _USE_MATH_DEFINES #include // offset which moves the planarfigures on top of the other content // the crosshair is rendered into the z = 1 layer. static const float PLANAR_OFFSET = 0.5f; mitk::PlanarFigureMapper2D::PlanarFigureMapper2D() : m_NodeModified(true) , m_NodeModifiedObserverTag(0) , m_NodeModifiedObserverAdded(false) { + m_AnnotationOverlay = mitk::TextOverlay2D::New(); + m_QuantityOverlay = mitk::TextOverlay2D::New(); + this->InitializeDefaultPlanarFigureProperties(); } mitk::PlanarFigureMapper2D::~PlanarFigureMapper2D() { if ( m_NodeModifiedObserverAdded && GetDataNode() != NULL ) { GetDataNode()->RemoveObserver( m_NodeModifiedObserverTag ); } } void mitk::PlanarFigureMapper2D::Paint( mitk::BaseRenderer *renderer ) { bool visible = true; + m_AnnotationOverlay->SetVisibility( false, renderer ); + + m_QuantityOverlay->SetVisibility( false, renderer ); + GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; // Get PlanarFigure from input mitk::PlanarFigure *planarFigure = const_cast< mitk::PlanarFigure * >( static_cast< const mitk::PlanarFigure * >( GetDataNode()->GetData() ) ); // Check if PlanarFigure has already been placed; otherwise, do nothing if ( !planarFigure->IsPlaced() ) { return; } // Get 2D geometry frame of PlanarFigure mitk::PlaneGeometry *planarFigurePlaneGeometry = dynamic_cast< PlaneGeometry * >( planarFigure->GetGeometry( 0 ) ); if ( planarFigurePlaneGeometry == NULL ) { MITK_ERROR << "PlanarFigure does not have valid PlaneGeometry!"; return; } // Get current world 2D geometry from renderer const mitk::PlaneGeometry *rendererPlaneGeometry = renderer->GetCurrentWorldPlaneGeometry(); // If the PlanarFigure geometry is a plane geometry, check if current // world plane is parallel to and within the planar figure geometry bounds // (otherwise, display nothing) if ( (planarFigurePlaneGeometry != NULL) && (rendererPlaneGeometry != NULL) ) { double planeThickness = planarFigurePlaneGeometry->GetExtentInMM( 2 ); if ( !planarFigurePlaneGeometry->IsParallel( rendererPlaneGeometry ) || !(planarFigurePlaneGeometry->DistanceFromPlane( rendererPlaneGeometry ) < planeThickness / 3.0) ) { // Planes are not parallel or renderer plane is not within PlanarFigure // geometry bounds --> exit return; } } else { // Plane is not valid (curved reformations are not possible yet) return; } // Get display geometry mitk::DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry != NULL ); // Apply visual appearance properties from the PropertyList ApplyColorAndOpacityProperties( renderer ); // Enable line antialiasing glEnable( GL_LINE_SMOOTH ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); glEnable(GL_DEPTH_TEST); // Get properties from node (if present) const mitk::DataNode* node=this->GetDataNode(); this->InitializePlanarFigurePropertiesFromDataNode( node ); PlanarFigureDisplayMode lineDisplayMode = PF_DEFAULT; if ( m_IsSelected ) { lineDisplayMode = PF_SELECTED; } else if ( m_IsHovering ) { lineDisplayMode = PF_HOVER; } mitk::Point2D anchorPoint; anchorPoint[0] = 0; anchorPoint[1] = 1; // render the actual lines of the PlanarFigure RenderLines(lineDisplayMode, planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry); // position-offset of the annotations, is set in RenderAnnotations() and // used in RenderQuantities() double annotationOffset = 0.0; //Get Global Opacity float globalOpacity = 1.0; node->GetFloatProperty("opacity", globalOpacity); // draw name near the anchor point (point located on the right) std::string name = node->GetName(); if ( m_DrawName && !name.empty() ) { RenderAnnotations(renderer, name, anchorPoint, globalOpacity, lineDisplayMode, annotationOffset); } // draw feature quantities (if requested) next to the anchor point, // but under the name (that is where 'annotationOffset' is used) if ( m_DrawQuantities ) { RenderQuantities(planarFigure, renderer, anchorPoint, annotationOffset, globalOpacity, lineDisplayMode); } if ( m_DrawControlPoints ) { // draw the control-points RenderControlPoints(planarFigure, lineDisplayMode, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry); } glLineWidth( 1.0f ); } void mitk::PlanarFigureMapper2D::PaintPolyLine( mitk::PlanarFigure::PolyLineType vertices, bool closed, Point2D& anchorPoint, const PlaneGeometry* planarFigurePlaneGeometry, const PlaneGeometry* rendererPlaneGeometry, const DisplayGeometry* displayGeometry) { mitk::Point2D rightMostPoint; rightMostPoint.Fill( itk::NumericTraits::min() ); // transform all vertices into Point2Ds in display-Coordinates and store them in vector std::vector pointlist; for ( PlanarFigure::PolyLineType::iterator iter = vertices.begin(); iter!=vertices.end(); iter++ ) { // Draw this 2D point as OpenGL vertex mitk::Point2D displayPoint; this->TransformObjectToDisplay( *iter, displayPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); pointlist.push_back(displayPoint); if ( displayPoint[0] > rightMostPoint[0] ) rightMostPoint = displayPoint; } // If the planarfigure is closed, we add the first control point again. // Thus we can always use 'GL_LINE_STRIP' and get rid of strange flickering // effect when using the MESA OpenGL library. if ( closed ) { mitk::Point2D displayPoint; this->TransformObjectToDisplay( vertices.begin()[0], displayPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); pointlist.push_back( displayPoint ); } // now paint all the points in one run std::vector::iterator pointIter; glBegin( GL_LINE_STRIP ); for ( pointIter = pointlist.begin(); pointIter!=pointlist.end(); pointIter++ ) { glVertex3f( (*pointIter)[0], (*pointIter)[1], PLANAR_OFFSET ); } glEnd(); anchorPoint = rightMostPoint; } void mitk::PlanarFigureMapper2D::DrawMainLines( mitk::PlanarFigure* figure, Point2D& anchorPoint, const PlaneGeometry* planarFigurePlaneGeometry, const PlaneGeometry* rendererPlaneGeometry, const DisplayGeometry* displayGeometry) { unsigned short numberOfPolyLines = figure->GetPolyLinesSize(); for ( unsigned short loop=0; loopGetPolyLine(loop); this->PaintPolyLine( polyline, figure->IsClosed(), anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); } } void mitk::PlanarFigureMapper2D::DrawHelperLines( mitk::PlanarFigure* figure, Point2D& anchorPoint, const PlaneGeometry* planarFigurePlaneGeometry, const PlaneGeometry* rendererPlaneGeometry, const DisplayGeometry* displayGeometry) { unsigned short numberOfHelperPolyLines = figure->GetHelperPolyLinesSize(); // Draw helper objects for ( unsigned int loop=0; loopGetHelperPolyLine(loop, displayGeometry->GetScaleFactorMMPerDisplayUnit(), displayGeometry->GetDisplayHeight() ); // Check if the current helper objects is to be painted if ( !figure->IsHelperToBePainted( loop ) ) { continue; } // ... and once normally above the shadow. this->PaintPolyLine( helperPolyLine, false, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); } } void mitk::PlanarFigureMapper2D::TransformObjectToDisplay( const mitk::Point2D &point2D, mitk::Point2D &displayPoint, const mitk::PlaneGeometry *objectGeometry, const mitk::PlaneGeometry *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ) { mitk::Point3D point3D; // Map circle point from local 2D geometry into 3D world space objectGeometry->Map( point2D, point3D ); // Project 3D world point onto display geometry rendererGeometry->Map( point3D, displayPoint ); displayGeometry->WorldToDisplay( displayPoint, displayPoint ); } void mitk::PlanarFigureMapper2D::DrawMarker( const mitk::Point2D &point, float* lineColor, float lineOpacity, float* markerColor, float markerOpacity, float lineWidth, PlanarFigureControlPointStyleProperty::Shape shape, const mitk::PlaneGeometry *objectGeometry, const mitk::PlaneGeometry *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ) { mitk::Point2D displayPoint; if ( markerOpacity == 0 && lineOpacity == 0 ) return; this->TransformObjectToDisplay( point, displayPoint, objectGeometry, rendererGeometry, displayGeometry ); glColor4f( markerColor[0], markerColor[1], markerColor[2], markerOpacity ); glLineWidth( lineWidth ); switch ( shape ) { case PlanarFigureControlPointStyleProperty::Square: default: { // Paint filled square // Disable line antialiasing (does not look nice for squares) glDisable( GL_LINE_SMOOTH ); if ( markerOpacity > 0 ) { glRectf( displayPoint[0] - 4, displayPoint[1] - 4, displayPoint[0] + 4, displayPoint[1] + 4 ); } // Paint outline glColor4f( lineColor[0], lineColor[1], lineColor[2], lineOpacity ); glBegin( GL_LINE_LOOP ); glVertex3f( displayPoint[0] - 4, displayPoint[1] - 4, PLANAR_OFFSET ); glVertex3f( displayPoint[0] - 4, displayPoint[1] + 4, PLANAR_OFFSET ); glVertex3f( displayPoint[0] + 4, displayPoint[1] + 4, PLANAR_OFFSET ); glVertex3f( displayPoint[0] + 4, displayPoint[1] - 4, PLANAR_OFFSET ); glEnd(); break; } case PlanarFigureControlPointStyleProperty::Circle: { float radius = 4.0; if ( markerOpacity > 0 ) { // Paint filled circle glBegin( GL_POLYGON ); for ( int angle = 0; angle < 8; ++angle ) { float angleRad = angle * (float) 3.14159 / 4.0; float x = displayPoint[0] + radius * (float)cos( angleRad ); float y = displayPoint[1] + radius * (float)sin( angleRad ); glVertex3f(x, y, PLANAR_OFFSET); } glEnd(); } // Paint outline glColor4f( lineColor[0], lineColor[1], lineColor[2], lineOpacity ); glBegin( GL_LINE_LOOP ); for ( int angle = 0; angle < 8; ++angle ) { float angleRad = angle * (float) 3.14159 / 4.0; float x = displayPoint[0] + radius * (float)cos( angleRad ); float y = displayPoint[1] + radius * (float)sin( angleRad ); glVertex3f(x, y, PLANAR_OFFSET); } glEnd(); break; } } // end switch } void mitk::PlanarFigureMapper2D::InitializeDefaultPlanarFigureProperties() { m_IsSelected = false; m_IsHovering = false; m_DrawOutline = false; m_DrawQuantities = false; m_DrawShadow = false; m_DrawControlPoints = false; m_DrawName = true; m_DrawDashed = false; m_DrawHelperDashed = false; m_ShadowWidthFactor = 1.2; m_LineWidth = 1.0; m_OutlineWidth = 4.0; m_HelperlineWidth = 2.0; m_ControlPointShape = PlanarFigureControlPointStyleProperty::Square; this->SetColorProperty( m_LineColor, PF_DEFAULT, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_LineOpacity, PF_DEFAULT, 1.0 ); this->SetColorProperty( m_OutlineColor, PF_DEFAULT, 0.0, 0.0, 1.0 ); this->SetFloatProperty( m_OutlineOpacity, PF_DEFAULT, 1.0 ); this->SetColorProperty( m_HelperlineColor, PF_DEFAULT, 0.4, 0.8, 0.2 ); this->SetFloatProperty( m_HelperlineOpacity, PF_DEFAULT, 0.4 ); this->SetColorProperty( m_MarkerlineColor, PF_DEFAULT, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerlineOpacity, PF_DEFAULT, 1.0 ); this->SetColorProperty( m_MarkerColor, PF_DEFAULT, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerOpacity, PF_DEFAULT, 0.0 ); this->SetColorProperty( m_LineColor, PF_HOVER, 1.0, 0.7, 0.0 ); this->SetFloatProperty( m_LineOpacity, PF_HOVER, 1.0 ); this->SetColorProperty( m_OutlineColor, PF_HOVER, 0.0, 0.0, 1.0 ); this->SetFloatProperty( m_OutlineOpacity, PF_HOVER, 1.0 ); this->SetColorProperty( m_HelperlineColor, PF_HOVER, 0.4, 0.8, 0.2 ); this->SetFloatProperty( m_HelperlineOpacity, PF_HOVER, 0.4 ); this->SetColorProperty( m_MarkerlineColor, PF_HOVER, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerlineOpacity, PF_HOVER, 1.0 ); this->SetColorProperty( m_MarkerColor, PF_HOVER, 1.0, 0.6, 0.0 ); this->SetFloatProperty( m_MarkerOpacity, PF_HOVER, 0.2 ); this->SetColorProperty( m_LineColor, PF_SELECTED, 1.0, 0.0, 0.0 ); this->SetFloatProperty( m_LineOpacity, PF_SELECTED, 1.0 ); this->SetColorProperty( m_OutlineColor, PF_SELECTED, 0.0, 0.0, 1.0 ); this->SetFloatProperty( m_OutlineOpacity, PF_SELECTED, 1.0 ); this->SetColorProperty( m_HelperlineColor, PF_SELECTED, 0.4, 0.8, 0.2 ); this->SetFloatProperty( m_HelperlineOpacity, PF_SELECTED, 0.4 ); this->SetColorProperty( m_MarkerlineColor, PF_SELECTED, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerlineOpacity, PF_SELECTED, 1.0 ); this->SetColorProperty( m_MarkerColor, PF_SELECTED, 1.0, 0.6, 0.0 ); this->SetFloatProperty( m_MarkerOpacity, PF_SELECTED, 1.0 ); } void mitk::PlanarFigureMapper2D::InitializePlanarFigurePropertiesFromDataNode( const mitk::DataNode* node ) { if ( node == NULL ) { return; } // if we have not added an observer for ModifiedEvents on the DataNode, // we add one now. if ( !m_NodeModifiedObserverAdded ) { itk::SimpleMemberCommand::Pointer nodeModifiedCommand = itk::SimpleMemberCommand::New(); nodeModifiedCommand->SetCallbackFunction(this, &mitk::PlanarFigureMapper2D::OnNodeModified); m_NodeModifiedObserverTag = node->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand); m_NodeModifiedObserverAdded = true; } // If the DataNode has not been modified since the last execution of // this method, we do not run it now. if ( !m_NodeModified ) return; // Mark the current properties as unmodified m_NodeModified = false; //Get Global Opacity float globalOpacity = 1.0; node->GetFloatProperty("opacity", globalOpacity); node->GetBoolProperty( "selected", m_IsSelected ); node->GetBoolProperty( "planarfigure.ishovering", m_IsHovering ); node->GetBoolProperty( "planarfigure.drawoutline", m_DrawOutline ); node->GetBoolProperty( "planarfigure.drawshadow", m_DrawShadow ); node->GetBoolProperty( "planarfigure.drawquantities", m_DrawQuantities ); node->GetBoolProperty( "planarfigure.drawcontrolpoints", m_DrawControlPoints ); node->GetBoolProperty( "planarfigure.drawname", m_DrawName ); node->GetBoolProperty( "planarfigure.drawdashed", m_DrawDashed ); node->GetBoolProperty( "planarfigure.helperline.drawdashed", m_DrawHelperDashed ); node->GetFloatProperty( "planarfigure.line.width", m_LineWidth ); node->GetFloatProperty( "planarfigure.shadow.widthmodifier", m_ShadowWidthFactor ); node->GetFloatProperty( "planarfigure.outline.width", m_OutlineWidth ); node->GetFloatProperty( "planarfigure.helperline.width", m_HelperlineWidth ); PlanarFigureControlPointStyleProperty::Pointer styleProperty = dynamic_cast< PlanarFigureControlPointStyleProperty* >( node->GetProperty( "planarfigure.controlpointshape" ) ); if ( styleProperty.IsNotNull() ) { m_ControlPointShape = styleProperty->GetShape(); } //Set default color and opacity //If property "planarfigure.default.*.color" exists, then use that color. Otherwise global "color" property is used. if( !node->GetColor( m_LineColor[PF_DEFAULT], NULL, "planarfigure.default.line.color")) { node->GetColor( m_LineColor[PF_DEFAULT], NULL, "color" ); } node->GetFloatProperty( "planarfigure.default.line.opacity", m_LineOpacity[PF_DEFAULT] ); if( !node->GetColor( m_OutlineColor[PF_DEFAULT], NULL, "planarfigure.default.outline.color")) { node->GetColor( m_OutlineColor[PF_DEFAULT], NULL, "color" ); } node->GetFloatProperty( "planarfigure.default.outline.opacity", m_OutlineOpacity[PF_DEFAULT] ); if( !node->GetColor( m_HelperlineColor[PF_DEFAULT], NULL, "planarfigure.default.helperline.color")) { node->GetColor( m_HelperlineColor[PF_DEFAULT], NULL, "color" ); } node->GetFloatProperty( "planarfigure.default.helperline.opacity", m_HelperlineOpacity[PF_DEFAULT] ); node->GetColor( m_MarkerlineColor[PF_DEFAULT], NULL, "planarfigure.default.markerline.color" ); node->GetFloatProperty( "planarfigure.default.markerline.opacity", m_MarkerlineOpacity[PF_DEFAULT] ); node->GetColor( m_MarkerColor[PF_DEFAULT], NULL, "planarfigure.default.marker.color" ); node->GetFloatProperty( "planarfigure.default.marker.opacity", m_MarkerOpacity[PF_DEFAULT] ); //Set hover color and opacity node->GetColor( m_LineColor[PF_HOVER], NULL, "planarfigure.hover.line.color" ); node->GetFloatProperty( "planarfigure.hover.line.opacity", m_LineOpacity[PF_HOVER] ); node->GetColor( m_OutlineColor[PF_HOVER], NULL, "planarfigure.hover.outline.color" ); node->GetFloatProperty( "planarfigure.hover.outline.opacity", m_OutlineOpacity[PF_HOVER] ); node->GetColor( m_HelperlineColor[PF_HOVER], NULL, "planarfigure.hover.helperline.color" ); node->GetFloatProperty( "planarfigure.hover.helperline.opacity", m_HelperlineOpacity[PF_HOVER] ); node->GetColor( m_MarkerlineColor[PF_HOVER], NULL, "planarfigure.hover.markerline.color" ); node->GetFloatProperty( "planarfigure.hover.markerline.opacity", m_MarkerlineOpacity[PF_HOVER] ); node->GetColor( m_MarkerColor[PF_HOVER], NULL, "planarfigure.hover.marker.color" ); node->GetFloatProperty( "planarfigure.hover.marker.opacity", m_MarkerOpacity[PF_HOVER] ); //Set selected color and opacity node->GetColor( m_LineColor[PF_SELECTED], NULL, "planarfigure.selected.line.color" ); node->GetFloatProperty( "planarfigure.selected.line.opacity", m_LineOpacity[PF_SELECTED] ); node->GetColor( m_OutlineColor[PF_SELECTED], NULL, "planarfigure.selected.outline.color" ); node->GetFloatProperty( "planarfigure.selected.outline.opacity", m_OutlineOpacity[PF_SELECTED] ); node->GetColor( m_HelperlineColor[PF_SELECTED], NULL, "planarfigure.selected.helperline.color" ); node->GetFloatProperty( "planarfigure.selected.helperline.opacity", m_HelperlineOpacity[PF_SELECTED] ); node->GetColor( m_MarkerlineColor[PF_SELECTED], NULL, "planarfigure.selected.markerline.color" ); node->GetFloatProperty( "planarfigure.selected.markerline.opacity", m_MarkerlineOpacity[PF_SELECTED] ); node->GetColor( m_MarkerColor[PF_SELECTED], NULL, "planarfigure.selected.marker.color" ); node->GetFloatProperty( "planarfigure.selected.marker.opacity", m_MarkerOpacity[PF_SELECTED] ); //adapt opacity values to global "opacity" property for( unsigned int i = 0; i < PF_COUNT; ++i ) { m_LineOpacity[i] *= globalOpacity; m_OutlineOpacity[i] *= globalOpacity; m_HelperlineOpacity[i] *= globalOpacity; m_MarkerlineOpacity[i] *= globalOpacity; m_MarkerOpacity[i] *= globalOpacity; } } void mitk::PlanarFigureMapper2D::OnNodeModified() { m_NodeModified = true; } void mitk::PlanarFigureMapper2D::SetDefaultProperties( mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite ) { node->AddProperty( "visible", mitk::BoolProperty::New(true), renderer, overwrite ); //node->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true)); node->AddProperty("planarfigure.isextendable",mitk::BoolProperty::New(false)); //node->AddProperty( "planarfigure.ishovering", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawoutline", mitk::BoolProperty::New(false) ); //node->AddProperty( "planarfigure.drawquantities", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawshadow", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawcontrolpoints", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawname", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawdashed", mitk::BoolProperty::New(false) ); node->AddProperty( "planarfigure.helperline.drawdashed", mitk::BoolProperty::New(false) ); node->AddProperty("planarfigure.line.width", mitk::FloatProperty::New(2.0) ); node->AddProperty("planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(2.0) ); node->AddProperty("planarfigure.outline.width", mitk::FloatProperty::New(2.0) ); node->AddProperty("planarfigure.helperline.width", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.line.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.outline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.helperline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(1.0,1.0,1.0) ); node->AddProperty( "planarfigure.default.markerline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(1.0,1.0,1.0) ); node->AddProperty( "planarfigure.default.marker.opacity",mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.line.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.outline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.helperline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.markerline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.markerline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.marker.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.marker.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.line.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.line.opacity",mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.outline.opacity", mitk::FloatProperty::New(1.0)); node->AddProperty( "planarfigure.selected.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.helperline.opacity",mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.markerline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.markerline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.marker.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.marker.opacity",mitk::FloatProperty::New(1.0)); } void mitk::PlanarFigureMapper2D::RenderControlPoints( mitk::PlanarFigure * planarFigure, PlanarFigureDisplayMode lineDisplayMode, mitk::PlaneGeometry * planarFigurePlaneGeometry, const mitk::PlaneGeometry * rendererPlaneGeometry, mitk::DisplayGeometry * displayGeometry ) { bool isEditable = true; m_DataNode->GetBoolProperty( "planarfigure.iseditable", isEditable ); PlanarFigureDisplayMode pointDisplayMode = PF_DEFAULT; unsigned int selectedControlPointsIdx = (unsigned int) planarFigure->GetSelectedControlPoint(); unsigned int numberOfControlPoints = planarFigure->GetNumberOfControlPoints(); // Draw markers at control points (selected control point will be colored) for ( unsigned int i = 0; i < numberOfControlPoints ; ++i ) { // Only if planar figure is marked as editable: display markers (control points) in a // different style if mouse is over them or they are selected if ( isEditable ) { if ( i == selectedControlPointsIdx ) { pointDisplayMode = PF_SELECTED; } else if ( m_IsHovering && isEditable ) { pointDisplayMode = PF_HOVER; } } if ( m_MarkerOpacity[pointDisplayMode] == 0 && m_MarkerlineOpacity[pointDisplayMode] == 0 ) { continue; } if ( m_DrawOutline ) { // draw outlines for markers as well // linewidth for the contour is only half, as full width looks // much too thick! this->DrawMarker( planarFigure->GetControlPoint( i ), m_OutlineColor[lineDisplayMode], m_MarkerlineOpacity[pointDisplayMode], m_OutlineColor[lineDisplayMode], m_MarkerOpacity[pointDisplayMode], m_OutlineWidth/2, m_ControlPointShape, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); } this->DrawMarker( planarFigure->GetControlPoint( i ), m_MarkerlineColor[pointDisplayMode], m_MarkerlineOpacity[pointDisplayMode], m_MarkerColor[pointDisplayMode], m_MarkerOpacity[pointDisplayMode], m_LineWidth, m_ControlPointShape, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); } if ( planarFigure->IsPreviewControlPointVisible() ) { this->DrawMarker( planarFigure->GetPreviewControlPoint(), m_MarkerlineColor[PF_HOVER], m_MarkerlineOpacity[PF_HOVER], m_MarkerColor[PF_HOVER], m_MarkerOpacity[PF_HOVER], m_LineWidth, m_ControlPointShape, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); } } void mitk::PlanarFigureMapper2D::RenderAnnotations( mitk::BaseRenderer * renderer, std::string name, mitk::Point2D anchorPoint, float globalOpacity, PlanarFigureDisplayMode lineDisplayMode, double &annotationOffset ) { - mitk::VtkPropRenderer* openGLrenderer = dynamic_cast( renderer ); - if ( openGLrenderer ) - { - openGLrenderer->WriteSimpleText( name, - anchorPoint[0] + 6.0, anchorPoint[1] + 4.0, - 0, - 0, - 0, - globalOpacity ); //this is a shadow - - openGLrenderer->WriteSimpleText( name, - anchorPoint[0] + 5.0, anchorPoint[1] + 5.0, - m_LineColor[lineDisplayMode][0], - m_LineColor[lineDisplayMode][1], - m_LineColor[lineDisplayMode][2], - globalOpacity ); - - // If drawing is successful, add approximate height to annotation offset - annotationOffset -= 15.0; - } + m_AnnotationOverlay->SetText( name ); + m_AnnotationOverlay->SetColor( m_LineColor[lineDisplayMode][0], + m_LineColor[lineDisplayMode][1], + m_LineColor[lineDisplayMode][2] ); + m_AnnotationOverlay->SetOpacity( globalOpacity ); + m_AnnotationOverlay->SetFontSize( 12 ); + m_AnnotationOverlay->SetBoolProperty( "drawShadow", m_DrawShadow ); + m_AnnotationOverlay->SetVisibility( true, renderer ); + + mitk::Point2D offset; + offset.Fill(5); + m_AnnotationOverlay->SetPosition2D( anchorPoint ); + m_AnnotationOverlay->SetOffsetVector(offset); + + m_AnnotationOverlay->Update( renderer ); + m_AnnotationOverlay->Paint( renderer ); + annotationOffset -= 15.0; +// annotationOffset -= m_AnnotationOverlay->GetBoundsOnDisplay( renderer ).Size[1]; + } void mitk::PlanarFigureMapper2D::RenderQuantities( mitk::PlanarFigure * planarFigure, mitk::BaseRenderer * renderer, mitk::Point2D anchorPoint, double &annotationOffset, float globalOpacity, PlanarFigureDisplayMode lineDisplayMode ) { std::stringstream quantityString; quantityString.setf( ios::fixed, ios::floatfield ); quantityString.precision( 1 ); bool firstActiveFeature = true; for ( unsigned int i = 0; i < planarFigure->GetNumberOfFeatures(); ++i ) { if( planarFigure->IsFeatureActive(i) && planarFigure->IsFeatureVisible( i ) ) { if ( ! firstActiveFeature ) { quantityString << " x "; } quantityString << planarFigure->GetQuantity( i ) << " "; quantityString << planarFigure->GetFeatureUnit( i ); firstActiveFeature = false; } } - mitk::VtkPropRenderer* openGLrenderer = dynamic_cast( renderer ); - if ( openGLrenderer ) - { - openGLrenderer->WriteSimpleText( quantityString.str().c_str(), - anchorPoint[0] + 6.0, anchorPoint[1] + 4.0 + annotationOffset, - 0, - 0, - 0, - globalOpacity ); //this is a shadow - - openGLrenderer->WriteSimpleText( quantityString.str().c_str(), - anchorPoint[0] + 5.0, anchorPoint[1] + 5.0 + annotationOffset, - m_LineColor[lineDisplayMode][0], - m_LineColor[lineDisplayMode][1], - m_LineColor[lineDisplayMode][2], - globalOpacity ); - - // If drawing is successful, add approximate height to annotation offset - annotationOffset -= 15.0; - } + m_QuantityOverlay->SetColor( m_LineColor[lineDisplayMode][0], + m_LineColor[lineDisplayMode][1], + m_LineColor[lineDisplayMode][2] ); + + m_QuantityOverlay->SetOpacity( globalOpacity ); + m_QuantityOverlay->SetFontSize( 12 ); + m_QuantityOverlay->SetBoolProperty( "drawShadow", m_DrawShadow ); + m_QuantityOverlay->SetVisibility( true, renderer ); + + m_QuantityOverlay->SetText( quantityString.str().c_str() ); + mitk::Point2D offset; + offset.Fill(5); + offset[1]+=annotationOffset; + m_QuantityOverlay->SetPosition2D( anchorPoint ); + m_QuantityOverlay->SetOffsetVector(offset); + + m_QuantityOverlay->Update(renderer); + m_QuantityOverlay->Paint( renderer ); +// annotationOffset -= m_QuantityOverlay->GetBoundsOnDisplay( renderer ).Size[1]; + annotationOffset -= 15.0; } void mitk::PlanarFigureMapper2D::RenderLines( PlanarFigureDisplayMode lineDisplayMode, mitk::PlanarFigure * planarFigure, mitk::Point2D &anchorPoint, mitk::PlaneGeometry * planarFigurePlaneGeometry, const mitk::PlaneGeometry * rendererPlaneGeometry, mitk::DisplayGeometry * displayGeometry ) { glLineStipple(1, 0x00FF); // If we want to draw an outline, we do it here if ( m_DrawOutline ) { float* color = m_OutlineColor[lineDisplayMode]; float opacity = m_OutlineOpacity[lineDisplayMode]; // convert to a float array that also contains opacity, faster GL float* colorVector = new float[4]; colorVector[0] = color[0]; colorVector[1] = color[1]; colorVector[2] = color[2]; colorVector[3] = opacity; // set the color and opacity here as it is common for all outlines glColor4fv( colorVector ); glLineWidth(m_OutlineWidth); if (m_DrawDashed) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); // Draw the outline for all polylines if requested this->DrawMainLines( planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); glLineWidth( m_HelperlineWidth ); if (m_DrawHelperDashed) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); // Draw the outline for all helper objects if requested this->DrawHelperLines( planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); // cleanup delete[] colorVector; } // If we want to draw a shadow, we do it here if ( m_DrawShadow ) { // determine the shadow opacity float opacity = m_OutlineOpacity[lineDisplayMode]; float shadowOpacity = 0.0f; if( opacity > 0.2f ) shadowOpacity = opacity - 0.2f; // convert to a float array that also contains opacity, faster GL float* shadow = new float[4]; shadow[0] = 0; shadow[1] = 0; shadow[2] = 0; shadow[3] = shadowOpacity; // set the color and opacity here as it is common for all shadows glColor4fv( shadow ); glLineWidth( m_OutlineWidth * m_ShadowWidthFactor ); if (m_DrawDashed) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); // Draw the outline for all polylines if requested this->DrawMainLines( planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); glLineWidth( m_HelperlineWidth ); if (m_DrawHelperDashed) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); // Draw the outline for all helper objects if requested this->DrawHelperLines( planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); // cleanup delete[] shadow; } // set this in brackets to avoid duplicate variables in the same scope { float* color = m_LineColor[lineDisplayMode]; float opacity = m_LineOpacity[lineDisplayMode]; // convert to a float array that also contains opacity, faster GL float* colorVector = new float[4]; colorVector[0] = color[0]; colorVector[1] = color[1]; colorVector[2] = color[2]; colorVector[3] = opacity; // set the color and opacity here as it is common for all mainlines glColor4fv( colorVector ); glLineWidth( m_LineWidth ); if (m_DrawDashed) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); // Draw the main line for all polylines this->DrawMainLines( planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); float* helperColor = m_HelperlineColor[lineDisplayMode]; float helperOpacity = m_HelperlineOpacity[lineDisplayMode]; // convert to a float array that also contains opacity, faster GL float* helperColorVector = new float[4]; helperColorVector[0] = helperColor[0]; helperColorVector[1] = helperColor[1]; helperColorVector[2] = helperColor[2]; helperColorVector[3] = helperOpacity; // we only set the color for the helperlines as the linewidth is unchanged glColor4fv( helperColorVector ); glLineWidth( m_HelperlineWidth ); if (m_DrawHelperDashed) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); // Draw helper objects this->DrawHelperLines( planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry ); // cleanup delete[] colorVector; delete[] helperColorVector; } if ( m_DrawDashed || m_DrawHelperDashed ) glDisable(GL_LINE_STIPPLE); } diff --git a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h index 0ed01fe74e..257a3216da 100644 --- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h +++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h @@ -1,309 +1,314 @@ /*=================================================================== 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_PLANAR_FIGURE_MAPPER_2D_H_ #define MITK_PLANAR_FIGURE_MAPPER_2D_H_ #include "mitkCommon.h" #include #include "mitkGLMapper.h" #include "mitkPlanarFigure.h" #include "mitkPlanarFigureControlPointStyleProperty.h" namespace mitk { class BaseRenderer; class Contour; +class TextOverlay2D; /** * \brief OpenGL-based mapper to render display sub-class instances of mitk::PlanarFigure * * The appearance of planar figures can be configured through properties. If no properties are specified, * default values will be used. There are four elements a planar figure consists of: * *
    *
  1. "line": the main line segments of the planar figure (note: text is drawn in the same style) *
  2. "helperline": additional line segments of planar figures, such as arrow tips, arches of angles, etc. *
  3. "outline": background which is drawn behind the lines and helperlines of the planar figure (optional) *
  4. "marker": the markers (control points) of a planar figure *
  5. "markerline": the lines by which markers (control points) are surrounded *
* * In the following, all appearance-related planar figure properties are listed: * *
    *
  1. General properties for the planar figure *
      *
    • "planarfigure.drawoutline": if true, the "outline" lines is drawn *
    • "planarfigure.drawquantities": if true, the quantities (text) associated with the planar figure is drawn *
    • "planarfigure.drawname": if true, the name specified by the dataNode is drawn *
    • "planarfigure.drawshadow": if true, a black shadow is drawn around the planar figure *
    • "planarfigure.controlpointshape": style of the control points (enum) *
    *
  2. Line widths of planar figure elements *
      *
    • "planarfigure.line.width": width of "line" segments (float value, in mm) *
    • "planarfigure.shadow.widthmodifier": the width of the shadow is defined by width of the "line" * this modifier *
    • "planarfigure.outline.width": width of "outline" segments (float value, in mm) *
    • "planarfigure.helperline.width": width of "helperline" segments (float value, in mm) *
    *
  3. Color/opacity of planar figure elements in normal mode (unselected) *
      *
    • "planarfigure.default.line.color" *
    • "planarfigure.default.line.opacity" *
    • "planarfigure.default.outline.color" *
    • "planarfigure.default.outline.opacity" *
    • "planarfigure.default.helperline.color" *
    • "planarfigure.default.helperline.opacity" *
    • "planarfigure.default.markerline.color" *
    • "planarfigure.default.markerline.opacity" *
    • "planarfigure.default.marker.color" *
    • "planarfigure.default.marker.opacity" *
    *
  4. Color/opacity of planar figure elements in hover mode (mouse-over) *
      *
    • "planarfigure.hover.line.color" *
    • "planarfigure.hover.line.opacity" *
    • "planarfigure.hover.outline.color" *
    • "planarfigure.hover.outline.opacity" *
    • "planarfigure.hover.helperline.color" *
    • "planarfigure.hover.helperline.opacity" *
    • "planarfigure.hover.markerline.color" *
    • "planarfigure.hover.markerline.opacity" *
    • "planarfigure.hover.marker.color" *
    • "planarfigure.hover.marker.opacity" *
    *
  5. Color/opacity of planar figure elements in selected mode *
      *
    • "planarfigure.selected.line.color" *
    • "planarfigure.selected.line.opacity" *
    • "planarfigure.selected.outline.color" *
    • "planarfigure.selected.outline.opacity" *
    • "planarfigure.selected.helperline.color" *
    • "planarfigure.selected.helperline.opacity" *
    • "planarfigure.selected.markerline.color;" *
    • "planarfigure.selected.markerline.opacity" *
    • "planarfigure.selected.marker.color" *
    • "planarfigure.selected.marker.opacity" *
    *
* * \ingroup Mapper */ class MitkPlanarFigure_EXPORT PlanarFigureMapper2D : public GLMapper { public: mitkClassMacro(PlanarFigureMapper2D, GLMapper); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * reimplemented from Baseclass */ virtual void Paint(BaseRenderer * renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: enum PlanarFigureDisplayMode { PF_DEFAULT = 0, PF_HOVER = 1, PF_SELECTED = 2, PF_COUNT = 3 //helper variable }; PlanarFigureMapper2D(); virtual ~PlanarFigureMapper2D(); /** * \brief Renders all the lines defined by the PlanarFigure. * * This method renders all the lines that are defined by the PlanarFigure. * That includes the mainlines and helperlines as well as their shadows * and the outlines. * * This method already takes responsibility for the setting of the relevant * openGL attributes to reduce unnecessary setting of these attributes. * (e.g. no need to set color twice if it's the same) */ void RenderLines( PlanarFigureDisplayMode lineDisplayMode, mitk::PlanarFigure * planarFigure, mitk::Point2D &anchorPoint, mitk::PlaneGeometry * planarFigurePlaneGeometry, const mitk::PlaneGeometry * rendererPlaneGeometry, mitk::DisplayGeometry * displayGeometry ); /** * \brief Renders the quantities of the figure below the text annotations. */ void RenderQuantities( mitk::PlanarFigure * planarFigure, mitk::BaseRenderer * renderer, mitk::Point2D anchorPoint, double &annotationOffset, float globalOpacity, PlanarFigureDisplayMode lineDisplayMode ); /** * \brief Renders the text annotations. */ void RenderAnnotations( mitk::BaseRenderer * renderer, std::string name, mitk::Point2D anchorPoint, float globalOpacity, PlanarFigureDisplayMode lineDisplayMode, double &annotationOffset ); /** * \brief Renders the control-points. */ void RenderControlPoints( mitk::PlanarFigure * planarFigure, PlanarFigureDisplayMode lineDisplayMode, mitk::PlaneGeometry * planarFigurePlaneGeometry, const mitk::PlaneGeometry * rendererPlaneGeometry, mitk::DisplayGeometry * displayGeometry ); void TransformObjectToDisplay( const mitk::Point2D &point2D, mitk::Point2D &displayPoint, const mitk::PlaneGeometry *objectGeometry, const mitk::PlaneGeometry *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ); void DrawMarker( const mitk::Point2D &point, float* lineColor, float lineOpacity, float* markerColor, float markerOpacity, float lineWidth, PlanarFigureControlPointStyleProperty::Shape shape, const mitk::PlaneGeometry *objectGeometry, const mitk::PlaneGeometry *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ); /** * \brief Actually paints the polyline defined by the figure. */ void PaintPolyLine( mitk::PlanarFigure::PolyLineType vertices, bool closed, Point2D& anchorPoint, const PlaneGeometry* planarFigurePlaneGeometry, const PlaneGeometry* rendererPlaneGeometry, const DisplayGeometry* displayGeometry); /** * \brief Internally used by RenderLines() to draw the mainlines using * PaintPolyLine(). */ void DrawMainLines( mitk::PlanarFigure* figure, Point2D& anchorPoint, const PlaneGeometry* planarFigurePlaneGeometry, const PlaneGeometry* rendererPlaneGeometry, const DisplayGeometry* displayGeometry) ; /** * \brief Internally used by RenderLines() to draw the helperlines using * PaintPolyLine(). */ void DrawHelperLines( mitk::PlanarFigure* figure, Point2D& anchorPoint, const PlaneGeometry* planarFigurePlaneGeometry, const PlaneGeometry* rendererPlaneGeometry, const DisplayGeometry* displayGeometry) ; void InitializeDefaultPlanarFigureProperties(); void InitializePlanarFigurePropertiesFromDataNode( const mitk::DataNode* node ); void SetColorProperty( float property[3][3], PlanarFigureDisplayMode mode, float red, float green, float blue ) { property[mode][0] = red; property[mode][1] = green; property[mode][2] = blue; } void SetFloatProperty( float* property, PlanarFigureDisplayMode mode, float value ) { property[mode] = value; } /** * \brief Callback that sets m_NodeModified to true. * * This method set the bool flag m_NodeModified to true. It's a callback * that is executed when a itk::ModifiedEvet is invoked on our * DataNode. */ void OnNodeModified(); private: bool m_IsSelected; bool m_IsHovering; bool m_DrawOutline; bool m_DrawQuantities; bool m_DrawShadow; bool m_DrawControlPoints; bool m_DrawName; bool m_DrawDashed; bool m_DrawHelperDashed; // the width of the shadow is defined as 'm_LineWidth * m_ShadowWidthFactor' float m_LineWidth; float m_ShadowWidthFactor; float m_OutlineWidth; float m_HelperlineWidth; //float m_PointWidth; PlanarFigureControlPointStyleProperty::Shape m_ControlPointShape; float m_LineColor[3][3]; float m_LineOpacity[3]; float m_OutlineColor[3][3]; float m_OutlineOpacity[3]; float m_HelperlineColor[3][3]; float m_HelperlineOpacity[3]; float m_MarkerlineColor[3][3]; float m_MarkerlineOpacity[3]; float m_MarkerColor[3][3]; float m_MarkerOpacity[3]; // Bool flag that represents whether or not the DataNode has been modified. bool m_NodeModified; // Observer-tag for listening to itk::ModifiedEvents on the DataNode unsigned long m_NodeModifiedObserverTag; // Bool flag that indicates if a node modified observer was added bool m_NodeModifiedObserverAdded; + + itk::SmartPointer m_AnnotationOverlay; + itk::SmartPointer m_QuantityOverlay; + }; } // namespace mitk #endif /* MITK_PLANAR_FIGURE_MAPPER_2D_H_ */ diff --git a/Modules/QtWidgets/QmitkRenderWindow.h b/Modules/QtWidgets/QmitkRenderWindow.h index 5e0aa84d95..63526772bf 100644 --- a/Modules/QtWidgets/QmitkRenderWindow.h +++ b/Modules/QtWidgets/QmitkRenderWindow.h @@ -1,180 +1,180 @@ /*=================================================================== 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 QMITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66 #define QMITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66 #include "mitkRenderWindowBase.h" #include #include "QVTKWidget2.h" #include #include "QmitkRenderWindowMenu.h" #include "mitkInteractionEventConst.h" #include "mitkBaseRenderer.h" class QmitkStdMultiWidget; class QDragEnterEvent; class QDropEvent; class QInputEvent; /** * \ingroup QmitkModule * \brief MITK implementation of the QVTKWidget */ class QMITK_EXPORT QmitkRenderWindow: public QVTKWidget2, public mitk::RenderWindowBase { -Q_OBJECT + Q_OBJECT public: QmitkRenderWindow(QWidget *parent = 0, QString name = "unnamed renderwindow", mitk::VtkPropRenderer* renderer = NULL, - mitk::RenderingManager* renderingManager = NULL,mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard); + mitk::RenderingManager* renderingManager = NULL,mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard); virtual ~QmitkRenderWindow(); /** * \brief Whether Qt events should be passed to parent (default: true) * * With introduction of the QVTKWidget the behaviour regarding Qt events changed. * QVTKWidget "accepts" Qt events like mouse clicks (i.e. set an "accepted" flag). * When this flag is set, Qt fininshed handling of this event -- otherwise it is * reached through to the widget's parent. * * This reaching through to the parent was implicitly required by QmitkMaterialWidget / QmitkMaterialShowCase. *QmitkStdMultiWidget * The default behaviour of QmitkRenderWindow is now to clear the "accepted" flag * of Qt events after they were handled by QVTKWidget. This way parents can also * handle events. * * If you don't want this behaviour, call SetResendQtEvents(true) on your render window. */ virtual void SetResendQtEvents(bool resend); // Set Layout Index to define the Layout Type void SetLayoutIndex(unsigned int layoutIndex); // Get Layout Index to define the Layout Type unsigned int GetLayoutIndex(); //MenuWidget need to update the Layout Design List when Layout had changed void LayoutDesignListChanged(int layoutDesignIndex); void HideRenderWindowMenu(); //Activate or Deactivate MenuWidget. void ActivateMenuWidget(bool state, QmitkStdMultiWidget* stdMultiWidget = 0); bool GetActivateMenuWidgetFlag() { return m_MenuWidgetActivated; } // Get it from the QVTKWidget parent virtual vtkRenderWindow* GetVtkRenderWindow() { return GetRenderWindow(); } virtual vtkRenderWindowInteractor* GetVtkRenderWindowInteractor() { return NULL; } void FullScreenMode(bool state); protected: // overloaded move handler virtual void moveEvent(QMoveEvent* event); // overloaded show handler void showEvent(QShowEvent* event); // overloaded resize handler virtual void resizeEvent(QResizeEvent* event); // overloaded paint handler virtual void paintEvent(QPaintEvent* event); // overloaded mouse press handler virtual void mousePressEvent(QMouseEvent* event); // overloaded mouse double-click handler virtual void mouseDoubleClickEvent( QMouseEvent *event ); // overloaded mouse move handler virtual void mouseMoveEvent(QMouseEvent* event); // overloaded mouse release handler virtual void mouseReleaseEvent(QMouseEvent* event); // overloaded key press handler virtual void keyPressEvent(QKeyEvent* event); // overloaded enter handler virtual void enterEvent(QEvent*); // overloaded leave handler virtual void leaveEvent(QEvent*); /// \brief Simply says we accept the event type. virtual void dragEnterEvent(QDragEnterEvent *event); /// \brief If the dropped type is application/x-mitk-datanodes we process the request by converting to mitk::DataNode pointers and emitting the NodesDropped signal. virtual void dropEvent(QDropEvent * event); #ifndef QT_NO_WHEELEVENT // overload wheel mouse event virtual void wheelEvent(QWheelEvent*); #endif void AdjustRenderWindowMenuVisibility(const QPoint& pos); signals: void ResetView(); // \brief int parameters are enum from QmitkStdMultiWidget void ChangeCrosshairRotationMode(int); void SignalLayoutDesignChanged(int layoutDesignIndex); void moved(); void resized(); /// \brief Emits a signal to say that this window has had the following nodes dropped on it. void NodesDropped(QmitkRenderWindow *thisWindow, std::vector nodes); protected slots: void OnChangeLayoutDesign(int layoutDesignIndex); void OnWidgetPlaneModeChanged(int); void DeferredHideMenu(); private: // Helper Functions to Convert Qt-Events to Mitk-Events mitk::Point2D GetMousePosition(QMouseEvent* me) const; mitk::Point2D GetMousePosition(QWheelEvent* we) const; mitk::InteractionEvent::MouseButtons GetEventButton(QMouseEvent* me) const; mitk::InteractionEvent::MouseButtons GetButtonState(QMouseEvent* me) const; mitk::InteractionEvent::ModifierKeys GetModifiers(QInputEvent* me) const; mitk::InteractionEvent::MouseButtons GetButtonState(QWheelEvent* we) const; std::string GetKeyLetter(QKeyEvent* ke) const; int GetDelta(QWheelEvent* we) const; bool m_ResendQtEvents; QmitkRenderWindowMenu* m_MenuWidget; bool m_MenuWidgetActivated; unsigned int m_LayoutIndex; }; #endif diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.cpp b/Modules/QtWidgets/QmitkStdMultiWidget.cpp index bf1969311f..f6af353b74 100644 --- a/Modules/QtWidgets/QmitkStdMultiWidget.cpp +++ b/Modules/QtWidgets/QmitkStdMultiWidget.cpp @@ -1,2205 +1,2220 @@ /*=================================================================== 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. ===================================================================*/ #define SMW_INFO MITK_INFO("widget.stdmulti") #include "QmitkStdMultiWidget.h" #include #include #include #include #include #include #include -#include "mitkProperties.h" -#include "mitkPlaneGeometryDataMapper2D.h" -#include "mitkGlobalInteraction.h" -#include "mitkDisplayInteractor.h" -#include "mitkPointSet.h" -#include "mitkPositionEvent.h" -#include "mitkStateEvent.h" -#include "mitkLine.h" -#include "mitkInteractionConst.h" -#include "mitkDataStorage.h" -#include "mitkOverlayManager.h" - -#include "mitkNodePredicateBase.h" -#include "mitkNodePredicateDataType.h" - -#include "mitkNodePredicateNot.h" -#include "mitkNodePredicateProperty.h" -#include "mitkStatusBar.h" -#include "mitkImage.h" - -#include "mitkVtkLayerController.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include QmitkStdMultiWidget::QmitkStdMultiWidget(QWidget* parent, Qt::WindowFlags f, mitk::RenderingManager* renderingManager, mitk::BaseRenderer::RenderingMode::Type renderingMode, const QString& name) : QWidget(parent, f), mitkWidget1(NULL), mitkWidget2(NULL), mitkWidget3(NULL), mitkWidget4(NULL), levelWindowWidget(NULL), QmitkStdMultiWidgetLayout(NULL), m_Layout(LAYOUT_DEFAULT), m_PlaneMode(PLANE_MODE_SLICING), m_RenderingManager(renderingManager), m_GradientBackgroundFlag(true), m_TimeNavigationController(NULL), m_MainSplit(NULL), m_LayoutSplit(NULL), m_SubSplit1(NULL), m_SubSplit2(NULL), mitkWidget1Container(NULL), mitkWidget2Container(NULL), mitkWidget3Container(NULL), mitkWidget4Container(NULL), m_PendingCrosshairPositionEvent(false), m_CrosshairNavigationEnabled(false) { /****************************************************** * Use the global RenderingManager if none was specified * ****************************************************/ if (m_RenderingManager == NULL) { m_RenderingManager = mitk::RenderingManager::GetInstance(); } m_TimeNavigationController = m_RenderingManager->GetTimeNavigationController(); /*******************************/ //Create Widget manually /*******************************/ //create Layouts QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); QmitkStdMultiWidgetLayout->setContentsMargins(0,0,0,0); //Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); -// QmitkNavigationToolBar* toolBar = new QmitkNavigationToolBar(); -// QmitkStdMultiWidgetLayout->addWidget( toolBar ); - //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //creae Widget Container mitkWidget1Container = new QWidget(m_SubSplit1); mitkWidget2Container = new QWidget(m_SubSplit1); mitkWidget3Container = new QWidget(m_SubSplit2); mitkWidget4Container = new QWidget(m_SubSplit2); mitkWidget1Container->setContentsMargins(0,0,0,0); mitkWidget2Container->setContentsMargins(0,0,0,0); mitkWidget3Container->setContentsMargins(0,0,0,0); mitkWidget4Container->setContentsMargins(0,0,0,0); //create Widget Layout QHBoxLayout *mitkWidgetLayout1 = new QHBoxLayout(mitkWidget1Container); QHBoxLayout *mitkWidgetLayout2 = new QHBoxLayout(mitkWidget2Container); QHBoxLayout *mitkWidgetLayout3 = new QHBoxLayout(mitkWidget3Container); QHBoxLayout *mitkWidgetLayout4 = new QHBoxLayout(mitkWidget4Container); mitkWidgetLayout1->setMargin(0); mitkWidgetLayout2->setMargin(0); mitkWidgetLayout3->setMargin(0); mitkWidgetLayout4->setMargin(0); //set Layout to Widget Container mitkWidget1Container->setLayout(mitkWidgetLayout1); mitkWidget2Container->setLayout(mitkWidgetLayout2); mitkWidget3Container->setLayout(mitkWidgetLayout3); mitkWidget4Container->setLayout(mitkWidgetLayout4); //set SizePolicy mitkWidget1Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); mitkWidget2Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); mitkWidget3Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); mitkWidget4Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); //insert Widget Container into the splitters m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget3Container ); m_SubSplit2->addWidget( mitkWidget4Container ); // m_RenderingManager->SetGlobalInteraction( mitk::GlobalInteraction::GetInstance() ); //Create RenderWindows 1 mitkWidget1 = new QmitkRenderWindow(mitkWidget1Container, name + ".widget1", NULL, m_RenderingManager,renderingMode); mitkWidget1->setMaximumSize(2000,2000); mitkWidget1->SetLayoutIndex( AXIAL ); mitkWidgetLayout1->addWidget(mitkWidget1); //Create RenderWindows 2 mitkWidget2 = new QmitkRenderWindow(mitkWidget2Container, name + ".widget2", NULL, m_RenderingManager,renderingMode); mitkWidget2->setMaximumSize(2000,2000); mitkWidget2->setEnabled( true ); mitkWidget2->SetLayoutIndex( SAGITTAL ); mitkWidgetLayout2->addWidget(mitkWidget2); //Create RenderWindows 3 mitkWidget3 = new QmitkRenderWindow(mitkWidget3Container, name + ".widget3", NULL, m_RenderingManager,renderingMode); mitkWidget3->setMaximumSize(2000,2000); mitkWidget3->SetLayoutIndex( CORONAL ); mitkWidgetLayout3->addWidget(mitkWidget3); //Create RenderWindows 4 mitkWidget4 = new QmitkRenderWindow(mitkWidget4Container, name + ".widget4", NULL, m_RenderingManager,renderingMode); mitkWidget4->setMaximumSize(2000,2000); mitkWidget4->SetLayoutIndex( THREE_D ); mitkWidgetLayout4->addWidget(mitkWidget4); //create SignalSlot Connection connect( mitkWidget1, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget1, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget1, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget1, SLOT(OnWidgetPlaneModeChanged(int)) ); connect( mitkWidget2, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget2, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget2, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget2, SLOT(OnWidgetPlaneModeChanged(int)) ); connect( mitkWidget3, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget3, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget3, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget3, SLOT(OnWidgetPlaneModeChanged(int)) ); connect( mitkWidget4, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget4, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget4, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget4, SLOT(OnWidgetPlaneModeChanged(int)) ); //Create Level Window Widget levelWindowWidget = new QmitkLevelWindowWidget( m_MainSplit ); //this levelWindowWidget->setObjectName(QString::fromUtf8("levelWindowWidget")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(levelWindowWidget->sizePolicy().hasHeightForWidth()); levelWindowWidget->setSizePolicy(sizePolicy); levelWindowWidget->setMaximumSize(QSize(50, 2000)); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //resize Image. this->resize( QSize(364, 477).expandedTo(minimumSizeHint()) ); //Initialize the widgets. this->InitializeWidget(); //Activate Widget Menu this->ActivateMenuWidget( true ); } void QmitkStdMultiWidget::InitializeWidget() { m_PositionTracker = NULL; + //Default colors were chosen for decent visibitliy. + //Feel free to change your preferences in the workbench. + //This is #C00000 in hex + m_DecorationColorWidget[0][0] = 0.753f; + m_DecorationColorWidget[0][1] = 0.0f; + m_DecorationColorWidget[0][2] = 0.0f; + //This is #00B000 in hex + m_DecorationColorWidget[1][0] = 0.0f; + m_DecorationColorWidget[1][1] = 0.69f; + m_DecorationColorWidget[1][2] = 0.0f; + //This is #0080FF in hex + m_DecorationColorWidget[2][0] = 0.0f; + m_DecorationColorWidget[2][1] = 0.502f; + m_DecorationColorWidget[2][2] = 1.0f; + //This is #FFFF00 in hex + m_DecorationColorWidget[3][0] = 1.0f; + m_DecorationColorWidget[3][1] = 1.0f; + m_DecorationColorWidget[3][2] = 0.0f; + + //Make all black and overwrite renderwindow 4 + this->FillGradientBackgroundWithBlack(); + //This is #191919 in hex + m_GradientBackgroundColors[3][0][0] = 0.098f; + m_GradientBackgroundColors[3][0][1] = 0.098f; + m_GradientBackgroundColors[3][0][2] = 0.098f; + //This is #7F7F7F in hex + m_GradientBackgroundColors[3][1][0] = 0.498f; + m_GradientBackgroundColors[3][1][1] = 0.498f; + m_GradientBackgroundColors[3][1][2] = 0.498f; + // transfer colors in WorldGeometry-Nodes of the associated Renderer - QColor qcolor; - //float color[3] = {1.0f,1.0f,1.0f}; - mitk::DataNode::Pointer planeNode; mitk::IntProperty::Pointer layer; - // of widget 1 - planeNode = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); - planeNode->SetColor(1.0,0.0,0.0); + m_PlaneNode1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); + m_PlaneNode1->SetColor(m_DecorationColorWidget[0]); layer = mitk::IntProperty::New(1000); - planeNode->SetProperty("layer",layer); + m_PlaneNode1->SetProperty("layer",layer); // ... of widget 2 - planeNode = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); - planeNode->SetColor(0.0,1.0,0.0); + m_PlaneNode2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); + m_PlaneNode2->SetColor(m_DecorationColorWidget[1]); layer = mitk::IntProperty::New(1000); - planeNode->SetProperty("layer",layer); + m_PlaneNode2->SetProperty("layer",layer); // ... of widget 3 - planeNode = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); - planeNode->SetColor(0.0,0.0,1.0); + m_PlaneNode3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); + m_PlaneNode3->SetColor(m_DecorationColorWidget[2]); layer = mitk::IntProperty::New(1000); - planeNode->SetProperty("layer",layer); + m_PlaneNode3->SetProperty("layer",layer); // ... of widget 4 - planeNode = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); - planeNode->SetColor(1.0,1.0,0.0); + m_ParentNodeForGeometryPlanes = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); layer = mitk::IntProperty::New(1000); - planeNode->SetProperty("layer",layer); + m_ParentNodeForGeometryPlanes->SetProperty("layer",layer); mitk::OverlayManager::Pointer OverlayManager = mitk::OverlayManager::New(); mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetMapperID(mitk::BaseRenderer::Standard3D); // Set plane mode (slicing/rotation behavior) to slicing (default) m_PlaneMode = PLANE_MODE_SLICING; // Set default view directions for SNCs mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Axial ); mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Sagittal ); mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Frontal ); mitkWidget4->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Original ); - /*************************************************/ - //Write Layout Names into the viewers -- hardCoded - - //Info for later: - //int view = this->GetRenderWindow1()->GetSliceNavigationController()->GetDefaultViewDirection(); - //QString layoutName; - //if( view == mitk::SliceNavigationController::Axial ) - // layoutName = "Axial"; - //else if( view == mitk::SliceNavigationController::Sagittal ) - // layoutName = "Sagittal"; - //else if( view == mitk::SliceNavigationController::Frontal ) - // layoutName = "Coronal"; - //else if( view == mitk::SliceNavigationController::Original ) - // layoutName = "Original"; - //if( view >= 0 && view < 4 ) - // //write LayoutName --> Viewer 3D shoudn't write the layoutName. - - //Render Window 1 == axial - m_CornerAnnotaions[0].cornerText = vtkCornerAnnotation::New(); - m_CornerAnnotaions[0].cornerText->SetText(0, "Axial"); - m_CornerAnnotaions[0].cornerText->SetMaximumFontSize(12); - m_CornerAnnotaions[0].textProp = vtkTextProperty::New(); - m_CornerAnnotaions[0].textProp->SetColor( 1.0, 0.0, 0.0 ); - m_CornerAnnotaions[0].cornerText->SetTextProperty( m_CornerAnnotaions[0].textProp ); - m_CornerAnnotaions[0].ren = vtkRenderer::New(); - m_CornerAnnotaions[0].ren->AddActor(m_CornerAnnotaions[0].cornerText); - m_CornerAnnotaions[0].ren->InteractiveOff(); - mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[0].ren,true); - - //Render Window 2 == sagittal - m_CornerAnnotaions[1].cornerText = vtkCornerAnnotation::New(); - m_CornerAnnotaions[1].cornerText->SetText(0, "Sagittal"); - m_CornerAnnotaions[1].cornerText->SetMaximumFontSize(12); - m_CornerAnnotaions[1].textProp = vtkTextProperty::New(); - m_CornerAnnotaions[1].textProp->SetColor( 0.0, 1.0, 0.0 ); - m_CornerAnnotaions[1].cornerText->SetTextProperty( m_CornerAnnotaions[1].textProp ); - m_CornerAnnotaions[1].ren = vtkRenderer::New(); - m_CornerAnnotaions[1].ren->AddActor(m_CornerAnnotaions[1].cornerText); - m_CornerAnnotaions[1].ren->InteractiveOff(); - mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[1].ren,true); - - //Render Window 3 == coronal - m_CornerAnnotaions[2].cornerText = vtkCornerAnnotation::New(); - m_CornerAnnotaions[2].cornerText->SetText(0, "Coronal"); - m_CornerAnnotaions[2].cornerText->SetMaximumFontSize(12); - m_CornerAnnotaions[2].textProp = vtkTextProperty::New(); - m_CornerAnnotaions[2].textProp->SetColor( 0.295, 0.295, 1.0 ); - m_CornerAnnotaions[2].cornerText->SetTextProperty( m_CornerAnnotaions[2].textProp ); - m_CornerAnnotaions[2].ren = vtkRenderer::New(); - m_CornerAnnotaions[2].ren->AddActor(m_CornerAnnotaions[2].cornerText); - m_CornerAnnotaions[2].ren->InteractiveOff(); - mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[2].ren,true); - - /*************************************************/ + this->SetCornerAnnotation("Axial", m_DecorationColorWidget[0], 0); + this->SetCornerAnnotation("Sagittal", m_DecorationColorWidget[1], 1); + this->SetCornerAnnotation("Coronal", m_DecorationColorWidget[2], 2); + this->SetCornerAnnotation("3D", m_DecorationColorWidget[3], 3); // create a slice rotator - // m_SlicesRotator = mitk::SlicesRotator::New(); - // @TODO next line causes sure memory leak - // rotator will be created nonetheless (will be switched on and off) m_SlicesRotator = mitk::SlicesRotator::New("slices-rotator"); m_SlicesRotator->AddSliceController( mitkWidget1->GetSliceNavigationController() ); m_SlicesRotator->AddSliceController( mitkWidget2->GetSliceNavigationController() ); m_SlicesRotator->AddSliceController( mitkWidget3->GetSliceNavigationController() ); // create a slice swiveller (using the same state-machine as SlicesRotator) m_SlicesSwiveller = mitk::SlicesSwiveller::New("slices-rotator"); m_SlicesSwiveller->AddSliceController( mitkWidget1->GetSliceNavigationController() ); m_SlicesSwiveller->AddSliceController( mitkWidget2->GetSliceNavigationController() ); m_SlicesSwiveller->AddSliceController( mitkWidget3->GetSliceNavigationController() ); //connect to the "time navigation controller": send time via sliceNavigationControllers m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget1->GetSliceNavigationController() , false); m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget2->GetSliceNavigationController() , false); m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget3->GetSliceNavigationController() , false); m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget4->GetSliceNavigationController() , false); mitkWidget1->GetSliceNavigationController() ->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); //reverse connection between sliceNavigationControllers and m_TimeNavigationController mitkWidget1->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget2->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget3->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget4->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); m_MouseModeSwitcher = mitk::MouseModeSwitcher::New(); m_LastLeftClickPositionSupplier = mitk::CoordinateSupplier::New("navigation", NULL); mitk::GlobalInteraction::GetInstance()->AddListener( m_LastLeftClickPositionSupplier ); - // setup gradient background - m_GradientBackground1 = mitk::GradientBackground::New(); - m_GradientBackground1->SetRenderWindow( - mitkWidget1->GetRenderWindow() ); - m_GradientBackground1->Disable(); - - m_GradientBackground2 = mitk::GradientBackground::New(); - m_GradientBackground2->SetRenderWindow( - mitkWidget2->GetRenderWindow() ); - m_GradientBackground2->Disable(); - - m_GradientBackground3 = mitk::GradientBackground::New(); - m_GradientBackground3->SetRenderWindow( - mitkWidget3->GetRenderWindow() ); - m_GradientBackground3->Disable(); - - m_GradientBackground4 = mitk::GradientBackground::New(); - m_GradientBackground4->SetRenderWindow( - mitkWidget4->GetRenderWindow() ); - m_GradientBackground4->SetGradientColors(0.1,0.1,0.1,0.5,0.5,0.5); - m_GradientBackground4->Enable(); // setup the department logo rendering m_LogoRendering = mitk::LogoOverlay::New(); mitk::BaseRenderer::Pointer renderer4 = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()); m_LogoRendering->SetOpacity(0.5); mitk::Point2D offset; offset.Fill(0.03); m_LogoRendering->SetOffsetVector(offset); m_LogoRendering->SetRelativeSize(0.15); m_LogoRendering->SetCornerPosition(1); renderer4->GetOverlayManager()->AddOverlay(m_LogoRendering.GetPointer(),renderer4); - m_RectangleRendering1 = mitk::RenderWindowFrame::New(); - m_RectangleRendering1->SetRenderWindow( - mitkWidget1->GetRenderWindow() ); - m_RectangleRendering1->Enable(1.0,0.0,0.0); - - m_RectangleRendering2 = mitk::RenderWindowFrame::New(); - m_RectangleRendering2->SetRenderWindow( - mitkWidget2->GetRenderWindow() ); - m_RectangleRendering2->Enable(0.0,1.0,0.0); + // setup gradient background and renderwindow rectangle frame + for(unsigned int i = 0; i < 4; ++i) + { + m_GradientBackground[i] = mitk::GradientBackground::New(); + m_GradientBackground[i]->SetRenderWindow(GetRenderWindow(i)->GetVtkRenderWindow()); + m_GradientBackground[i]->Enable(); + m_RectangleRendering[i] = mitk::RenderWindowFrame::New(); + m_RectangleRendering[i]->SetRenderWindow(GetRenderWindow(i)->GetVtkRenderWindow()); + m_RectangleRendering[i]->Enable(m_DecorationColorWidget[i][0], m_DecorationColorWidget[i][1], m_DecorationColorWidget[i][2]); + } +} - m_RectangleRendering3 = mitk::RenderWindowFrame::New(); - m_RectangleRendering3->SetRenderWindow( - mitkWidget3->GetRenderWindow() ); - m_RectangleRendering3->Enable(0.0,0.0,1.0); +void QmitkStdMultiWidget::FillGradientBackgroundWithBlack() +{ + //We have 4 widgets and ... + for(unsigned int i = 0; i < 4; ++i) + { + //... each has 2 background colors + for(unsigned int j = 0; j < 2; ++j) + { + //Each color element set 0.0f; + for(unsigned int k = 0; k < 3; ++k) + { + m_GradientBackgroundColors[i][j][k] = 0.0f; + } + } + } +} - m_RectangleRendering4 = mitk::RenderWindowFrame::New(); - m_RectangleRendering4->SetRenderWindow( - mitkWidget4->GetRenderWindow() ); - m_RectangleRendering4->Enable(1.0,1.0,0.0); +mitk::Color QmitkStdMultiWidget::GetDecorationColorForWidget(unsigned int widgetNumber) +{ + if(widgetNumber > 3) + { + MITK_ERROR << "Decoration color for unknown widget!"; + float tmp[3] = { 0.0f, 0.0f, 0.0f}; + return mitk::Color(tmp); + } + return m_DecorationColorWidget[widgetNumber]; } QmitkStdMultiWidget::~QmitkStdMultiWidget() { DisablePositionTracking(); DisableNavigationControllerEventListening(); m_TimeNavigationController->Disconnect(mitkWidget1->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget2->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget3->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget4->GetSliceNavigationController()); +} - mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[0].ren ); - mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[1].ren ); - mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[2].ren ); - - //Delete CornerAnnotation - m_CornerAnnotaions[0].cornerText->Delete(); - m_CornerAnnotaions[0].textProp->Delete(); - m_CornerAnnotaions[0].ren->Delete(); - - m_CornerAnnotaions[1].cornerText->Delete(); - m_CornerAnnotaions[1].textProp->Delete(); - m_CornerAnnotaions[1].ren->Delete(); - - m_CornerAnnotaions[2].cornerText->Delete(); - m_CornerAnnotaions[2].textProp->Delete(); - m_CornerAnnotaions[2].ren->Delete(); +QmitkStdMultiWidget::CornerAnnotation QmitkStdMultiWidget::CreateCornerAnnotation(std::string text, mitk::Color color) +{ + CornerAnnotation annotation; + annotation.cornerText = vtkSmartPointer::New(); + annotation.cornerText->SetText(0, text.c_str()); + annotation.cornerText->SetMaximumFontSize(12); + annotation.textProp = vtkSmartPointer::New(); + annotation.textProp->SetColor( color[0],color[1],color[2] ); + annotation.cornerText->SetTextProperty( annotation.textProp ); + annotation.ren = vtkSmartPointer::New(); + annotation.ren->AddActor(annotation.cornerText); + annotation.ren->InteractiveOff(); + return annotation; } void QmitkStdMultiWidget::RemovePlanesFromDataStorage() { - if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull()) + if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) { if(m_DataStorage.IsNotNull()) { m_DataStorage->Remove(m_PlaneNode1); m_DataStorage->Remove(m_PlaneNode2); m_DataStorage->Remove(m_PlaneNode3); - m_DataStorage->Remove(m_Node); + m_DataStorage->Remove(m_ParentNodeForGeometryPlanes); } } } void QmitkStdMultiWidget::AddPlanesToDataStorage() { - if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull()) + if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) { if (m_DataStorage.IsNotNull()) { - m_DataStorage->Add(m_Node); - m_DataStorage->Add(m_PlaneNode1, m_Node); - m_DataStorage->Add(m_PlaneNode2, m_Node); - m_DataStorage->Add(m_PlaneNode3, m_Node); - static_cast(m_PlaneNode1->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node); - static_cast(m_PlaneNode2->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node); - static_cast(m_PlaneNode3->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node); + m_DataStorage->Add(m_ParentNodeForGeometryPlanes); + m_DataStorage->Add(m_PlaneNode1, m_ParentNodeForGeometryPlanes); + m_DataStorage->Add(m_PlaneNode2, m_ParentNodeForGeometryPlanes); + m_DataStorage->Add(m_PlaneNode3, m_ParentNodeForGeometryPlanes); } } } void QmitkStdMultiWidget::changeLayoutTo2DImagesUp() { SMW_INFO << "changing layout to 2D images up... " << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget Container into splitter top m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit1->addWidget( mitkWidget3Container ); //set SplitterSize for splitter top QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); //insert Widget Container into splitter bottom m_SubSplit2->addWidget( mitkWidget4Container ); //set SplitterSize for splitter m_LayoutSplit splitterSize.clear(); splitterSize.push_back(400); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt m_MainSplit->show(); //show Widget if hidden if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); //Change Layout Name m_Layout = LAYOUT_2D_IMAGES_UP; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2DImagesLeft() { SMW_INFO << "changing layout to 2D images left... " << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget into the splitters m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit1->addWidget( mitkWidget3Container ); //set splitterSize of SubSplit1 QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_SubSplit2->addWidget( mitkWidget4Container ); //set splitterSize of Layout Split splitterSize.clear(); splitterSize.push_back(400); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show Widget if hidden if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); //update Layout Name m_Layout = LAYOUT_2D_IMAGES_LEFT; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); //update Alle Widgets this->UpdateAllWidgets(); } +void QmitkStdMultiWidget::SetCornerAnnotation( std::string text, + mitk::Color color, int widgetNumber) +{ + if( widgetNumber > 3) + { + MITK_ERROR << "Unknown render window for annotation."; + return; + } + mitk::VtkLayerController* layercontroller = mitk::VtkLayerController::GetInstance(this->GetRenderWindow(widgetNumber)->GetRenderWindow()); + //remove the old renderer, because the layercontroller holds a list (vector) of all renderes + //which needs to be updated + if(m_CornerAnnotations[widgetNumber].ren != NULL) + { + layercontroller->RemoveRenderer(m_CornerAnnotations[widgetNumber].ren); + } + //make a new one + m_CornerAnnotations[widgetNumber] = this->CreateCornerAnnotation(text, color); + //add it to the list + layercontroller->InsertForegroundRenderer(m_CornerAnnotations[widgetNumber].ren,true); +} + +QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow(unsigned int number) +{ + switch (number) { + case 0: + return this->GetRenderWindow1(); + case 1: + return this->GetRenderWindow2(); + case 2: + return this->GetRenderWindow3(); + case 3: + return this->GetRenderWindow4(); + default: + MITK_ERROR << "Requested unknown render window"; + break; + } + return NULL; +} + void QmitkStdMultiWidget::changeLayoutToDefault() { SMW_INFO << "changing layout to default... " << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget container into the splitters m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget3Container ); m_SubSplit2->addWidget( mitkWidget4Container ); //set splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_SubSplit2->setSizes( splitterSize ); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show Widget if hidden if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_DEFAULT; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_DEFAULT ); mitkWidget2->LayoutDesignListChanged( LAYOUT_DEFAULT ); mitkWidget3->LayoutDesignListChanged( LAYOUT_DEFAULT ); mitkWidget4->LayoutDesignListChanged( LAYOUT_DEFAULT ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToBig3D() { SMW_INFO << "changing layout to big 3D ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget4Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_BIG_3D; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_BIG_3D ); mitkWidget2->LayoutDesignListChanged( LAYOUT_BIG_3D ); mitkWidget3->LayoutDesignListChanged( LAYOUT_BIG_3D ); mitkWidget4->LayoutDesignListChanged( LAYOUT_BIG_3D ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToWidget1() { SMW_INFO << "changing layout to big Widget1 ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget1Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); mitkWidget2->hide(); mitkWidget3->hide(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET1; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET1 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET1 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET1 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET1 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToWidget2() { SMW_INFO << "changing layout to big Widget2 ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget2Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); mitkWidget3->hide(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET2; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET2 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET2 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET2 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET2 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToWidget3() { SMW_INFO << "changing layout to big Widget3 ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget3Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET3; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET3 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET3 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET3 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET3 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToRowWidget3And4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //add Widgets to splitter m_LayoutSplit->addWidget( mitkWidget3Container ); m_LayoutSplit->addWidget( mitkWidget4Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_ROW_WIDGET_3_AND_4; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToColumnWidget3And4() { SMW_INFO << "changing layout to Widget3 and 4 in one Column..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //add Widgets to splitter m_LayoutSplit->addWidget( mitkWidget3Container ); m_LayoutSplit->addWidget( mitkWidget4Container ); //set SplitterSize QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_COLUMN_WIDGET_3_AND_4; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToRowWidgetSmall3andBig4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; this->changeLayoutToRowWidget3And4(); m_Layout = LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4; } void QmitkStdMultiWidget::changeLayoutToSmallUpperWidget2Big3and4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget into the splitters m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget3Container ); m_SubSplit2->addWidget( mitkWidget4Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit2->setSizes( splitterSize ); splitterSize.clear(); splitterSize.push_back(500); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt m_MainSplit->show(); //show Widget if hidden mitkWidget1->hide(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2x2Dand3DWidget() { SMW_INFO << "changing layout to 2 x 2D and 3D Widget" << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //add Widgets to splitter m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget4Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_2X_2D_AND_3D_WIDGET; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToLeft2Dand3DRight2D() { SMW_INFO << "changing layout to 2D and 3D left, 2D right Widget" << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //add Widgets to splitter m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget4Container ); m_SubSplit2->addWidget( mitkWidget2Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2DUpAnd3DDown() { SMW_INFO << "changing layout to 2D up and 3D down" << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget Container into splitter top m_SubSplit1->addWidget( mitkWidget1Container ); //set SplitterSize for splitter top QList splitterSize; -// splitterSize.push_back(1000); -// splitterSize.push_back(1000); -// splitterSize.push_back(1000); -// m_SubSplit1->setSizes( splitterSize ); - //insert Widget Container into splitter bottom m_SubSplit2->addWidget( mitkWidget4Container ); - //set SplitterSize for splitter m_LayoutSplit splitterSize.clear(); splitterSize.push_back(700); splitterSize.push_back(700); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); mitkWidget2->hide(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_2D_UP_AND_3D_DOWN; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); //update all Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::SetDataStorage( mitk::DataStorage* ds ) { mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetDataStorage(ds); m_DataStorage = ds; } void QmitkStdMultiWidget::Fit() { - vtkRenderer * vtkrenderer; + vtkSmartPointer vtkrenderer; mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetDisplayGeometry()->Fit(); int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } void QmitkStdMultiWidget::InitPositionTracking() { //PoinSetNode for MouseOrientation m_PositionTrackerNode = mitk::DataNode::New(); m_PositionTrackerNode->SetProperty("name", mitk::StringProperty::New("Mouse Position")); m_PositionTrackerNode->SetData( mitk::PointSet::New() ); m_PositionTrackerNode->SetColor(1.0,0.33,0.0); m_PositionTrackerNode->SetProperty("layer", mitk::IntProperty::New(1001)); m_PositionTrackerNode->SetVisibility(true); m_PositionTrackerNode->SetProperty("inputdevice", mitk::BoolProperty::New(true) ); m_PositionTrackerNode->SetProperty("BaseRendererMapperID", mitk::IntProperty::New(0) );//point position 2D mouse m_PositionTrackerNode->SetProperty("baserenderer", mitk::StringProperty::New("N/A")); } void QmitkStdMultiWidget::AddDisplayPlaneSubTree() { // add the displayed planes of the multiwidget to a node to which the subtree // @a planesSubTree points ... - float white[3] = {1.0f,1.0f,1.0f}; mitk::PlaneGeometryDataMapper2D::Pointer mapper; // ... of widget 1 mitk::BaseRenderer* renderer1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()); m_PlaneNode1 = renderer1->GetCurrentWorldPlaneGeometryNode(); - m_PlaneNode1->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode1->SetProperty("name", mitk::StringProperty::New(std::string(renderer1->GetName()) + ".plane")); m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 2 mitk::BaseRenderer* renderer2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow()); m_PlaneNode2 = renderer2->GetCurrentWorldPlaneGeometryNode(); - m_PlaneNode2->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode2->SetProperty("name", mitk::StringProperty::New(std::string(renderer2->GetName()) + ".plane")); m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 3 mitk::BaseRenderer* renderer3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow()); m_PlaneNode3 = renderer3->GetCurrentWorldPlaneGeometryNode(); - m_PlaneNode3->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode3->SetProperty("name", mitk::StringProperty::New(std::string(renderer3->GetName()) + ".plane")); m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode3->SetMapper(mitk::BaseRenderer::Standard2D, mapper); - m_Node = mitk::DataNode::New(); - m_Node->SetProperty("name", mitk::StringProperty::New("Widgets")); - m_Node->SetProperty("helper object", mitk::BoolProperty::New(true)); + m_ParentNodeForGeometryPlanes = mitk::DataNode::New(); + m_ParentNodeForGeometryPlanes->SetProperty("name", mitk::StringProperty::New("Widgets")); + m_ParentNodeForGeometryPlanes->SetProperty("helper object", mitk::BoolProperty::New(true)); } mitk::SliceNavigationController* QmitkStdMultiWidget::GetTimeNavigationController() { return m_TimeNavigationController; } void QmitkStdMultiWidget::EnableStandardLevelWindow() { levelWindowWidget->disconnect(this); levelWindowWidget->SetDataStorage(mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDataStorage()); levelWindowWidget->show(); } void QmitkStdMultiWidget::DisableStandardLevelWindow() { levelWindowWidget->disconnect(this); levelWindowWidget->hide(); } // CAUTION: Legacy code for enabling Qt-signal-controlled view initialization. // Use RenderingManager::InitializeViews() instead. bool QmitkStdMultiWidget::InitializeStandardViews( const mitk::Geometry3D * geometry ) { return m_RenderingManager->InitializeViews( geometry ); } void QmitkStdMultiWidget::RequestUpdate() { m_RenderingManager->RequestUpdate(mitkWidget1->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget2->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget3->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget4->GetRenderWindow()); } void QmitkStdMultiWidget::ForceImmediateUpdate() { m_RenderingManager->ForceImmediateUpdate(mitkWidget1->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget2->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget3->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget4->GetRenderWindow()); } void QmitkStdMultiWidget::wheelEvent( QWheelEvent * e ) { emit WheelMoved( e ); } void QmitkStdMultiWidget::mousePressEvent(QMouseEvent * e) { if (e->button() == Qt::LeftButton) { mitk::Point3D pointValue = this->GetLastLeftClickPosition(); emit LeftMouseClicked(pointValue); } } void QmitkStdMultiWidget::moveEvent( QMoveEvent* e ) { QWidget::moveEvent( e ); // it is necessary to readjust the position of the overlays as the StdMultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } void QmitkStdMultiWidget::leaveEvent ( QEvent * /*e*/ ) { //set cursor back to initial state m_SlicesRotator->ResetMouseCursor(); } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow1() const { return mitkWidget1; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow2() const { return mitkWidget2; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow3() const { return mitkWidget3; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow4() const { return mitkWidget4; } const mitk::Point3D& QmitkStdMultiWidget::GetLastLeftClickPosition() const { return m_LastLeftClickPositionSupplier->GetCurrentPoint(); } const mitk::Point3D QmitkStdMultiWidget::GetCrossPosition() const { const mitk::PlaneGeometry *plane1 = mitkWidget1->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane2 = mitkWidget2->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane3 = mitkWidget3->GetSliceNavigationController()->GetCurrentPlaneGeometry(); mitk::Line3D line; if ( (plane1 != NULL) && (plane2 != NULL) && (plane1->IntersectionLine( plane2, line )) ) { mitk::Point3D point; if ( (plane3 != NULL) && (plane3->IntersectionPoint( line, point )) ) { return point; } } return m_LastLeftClickPositionSupplier->GetCurrentPoint(); } void QmitkStdMultiWidget::EnablePositionTracking() { if (!m_PositionTracker) { m_PositionTracker = mitk::PositionTracker::New("PositionTracker", NULL); } mitk::GlobalInteraction* globalInteraction = mitk::GlobalInteraction::GetInstance(); if (globalInteraction) { if(m_DataStorage.IsNotNull()) m_DataStorage->Add(m_PositionTrackerNode); globalInteraction->AddListener(m_PositionTracker); } } void QmitkStdMultiWidget::DisablePositionTracking() { mitk::GlobalInteraction* globalInteraction = mitk::GlobalInteraction::GetInstance(); if(globalInteraction) { if (m_DataStorage.IsNotNull()) m_DataStorage->Remove(m_PositionTrackerNode); globalInteraction->RemoveListener(m_PositionTracker); } } void QmitkStdMultiWidget::EnsureDisplayContainsPoint( mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p) { mitk::Point2D pointOnPlane; displayGeometry->Map( p, pointOnPlane ); // point minus origin < width or height ==> outside ? mitk::Vector2D pointOnRenderWindow_MM; pointOnRenderWindow_MM = pointOnPlane.GetVectorFromOrigin() - displayGeometry->GetOriginInMM(); mitk::Vector2D sizeOfDisplay( displayGeometry->GetSizeInMM() ); if ( sizeOfDisplay[0] < pointOnRenderWindow_MM[0] || 0 > pointOnRenderWindow_MM[0] || sizeOfDisplay[1] < pointOnRenderWindow_MM[1] || 0 > pointOnRenderWindow_MM[1] ) { // point is not visible -> move geometry mitk::Vector2D offset( (pointOnRenderWindow_MM - sizeOfDisplay / 2.0) / displayGeometry->GetScaleFactorMMPerDisplayUnit() ); displayGeometry->MoveBy( offset ); } } void QmitkStdMultiWidget::MoveCrossToPosition(const mitk::Point3D& newPosition) { // create a PositionEvent with the given position and // tell the slice navigation controllers to move there - mitk::Point2D p2d; mitk::PositionEvent event( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()), 0, 0, 0, mitk::Key_unknown, p2d, newPosition ); mitk::StateEvent stateEvent(mitk::EIDLEFTMOUSEBTN, &event); mitk::StateEvent stateEvent2(mitk::EIDLEFTMOUSERELEASE, &event); switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent ); mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent ); mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent ); // just in case SNCs will develop something that depends on the mouse // button being released again mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent2 ); mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent2 ); mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent2 ); break; case PLANE_MODE_ROTATION: m_SlicesRotator->HandleEvent( &stateEvent ); // just in case SNCs will develop something that depends on the mouse // button being released again m_SlicesRotator->HandleEvent( &stateEvent2 ); break; case PLANE_MODE_SWIVEL: m_SlicesSwiveller->HandleEvent( &stateEvent ); // just in case SNCs will develop something that depends on the mouse // button being released again m_SlicesSwiveller->HandleEvent( &stateEvent2 ); break; } // determine if cross is now out of display // if so, move the display window EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()) ->GetDisplayGeometry(), newPosition ); EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow()) ->GetDisplayGeometry(), newPosition ); EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow()) ->GetDisplayGeometry(), newPosition ); // update displays m_RenderingManager->RequestUpdateAll(); } void QmitkStdMultiWidget::HandleCrosshairPositionEvent() { if(!m_PendingCrosshairPositionEvent) { m_PendingCrosshairPositionEvent=true; QTimer::singleShot(0,this,SLOT( HandleCrosshairPositionEventDelayed() ) ); } } mitk::DataNode::Pointer QmitkStdMultiWidget::GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes) { mitk::Point3D crosshairPos = this->GetCrossPosition(); mitk::DataNode::Pointer node; int maxlayer = -32768; if(nodes.IsNotNull()) { mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer(); // find node with largest layer, that is the node shown on top in the render window for (unsigned int x = 0; x < nodes->size(); x++) { if ( (nodes->at(x)->GetData()->GetGeometry() != NULL) && nodes->at(x)->GetData()->GetGeometry()->IsInside(crosshairPos) ) { int layer = 0; if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue; if(layer > maxlayer) { if( static_cast(nodes->at(x))->IsVisible( baseRenderer ) ) { node = nodes->at(x); maxlayer = layer; } } } } } return node; } void QmitkStdMultiWidget::HandleCrosshairPositionEventDelayed() { m_PendingCrosshairPositionEvent = false; // find image with highest layer - mitk::TNodePredicateDataType::Pointer isImageData = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->m_DataStorage->GetSubset(isImageData).GetPointer(); mitk::DataNode::Pointer node; mitk::DataNode::Pointer topSourceNode; mitk::Image::Pointer image; bool isBinary = false; node = this->GetTopLayerNode(nodes); int component = 0; if(node.IsNotNull()) { node->GetBoolProperty("binary",isBinary); if(isBinary) { mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = m_DataStorage->GetSources(node, NULL, true); if(!sourcenodes->empty()) { topSourceNode = this->GetTopLayerNode(sourcenodes); } if(topSourceNode.IsNotNull()) { image = dynamic_cast(topSourceNode->GetData()); topSourceNode->GetIntProperty("Image.Displayed Component", component); } else { image = dynamic_cast(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } else { image = dynamic_cast(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } mitk::Point3D crosshairPos = this->GetCrossPosition(); std::string statusText; std::stringstream stream; itk::Index<3> p; mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer(); unsigned int timestep = baseRenderer->GetTimeStep(); if(image.IsNotNull() && (image->GetTimeSteps() > timestep )) { image->GetGeometry()->WorldToIndex(crosshairPos, p); stream.precision(2); stream<<"Position: <" << std::fixed < mm"; stream<<"; Index: <"< "; mitk::ScalarType pixelValue = image->GetPixelValueByIndex(p, timestep, component); if (fabs(pixelValue)>1000000 || fabs(pixelValue) < 0.01) { stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< std::scientific<< pixelValue <<" "; } else { stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< pixelValue <<" "; } } else { stream << "No image information at this position!"; } statusText = stream.str(); mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str()); } void QmitkStdMultiWidget::EnableNavigationControllerEventListening() { // Let NavigationControllers listen to GlobalInteraction mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); // Listen for SliceNavigationController mitkWidget1->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) ); mitkWidget2->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) ); mitkWidget3->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) ); switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: gi->AddListener( mitkWidget1->GetSliceNavigationController() ); gi->AddListener( mitkWidget2->GetSliceNavigationController() ); gi->AddListener( mitkWidget3->GetSliceNavigationController() ); gi->AddListener( mitkWidget4->GetSliceNavigationController() ); break; case PLANE_MODE_ROTATION: gi->AddListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: gi->AddListener( m_SlicesSwiveller ); break; } gi->AddListener( m_TimeNavigationController ); m_CrosshairNavigationEnabled = true; } void QmitkStdMultiWidget::DisableNavigationControllerEventListening() { // Do not let NavigationControllers listen to GlobalInteraction mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: gi->RemoveListener( mitkWidget1->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget2->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget3->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget4->GetSliceNavigationController() ); break; case PLANE_MODE_ROTATION: m_SlicesRotator->ResetMouseCursor(); gi->RemoveListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: m_SlicesSwiveller->ResetMouseCursor(); gi->RemoveListener( m_SlicesSwiveller ); break; } gi->RemoveListener( m_TimeNavigationController ); m_CrosshairNavigationEnabled = false; } int QmitkStdMultiWidget::GetLayout() const { return m_Layout; } bool QmitkStdMultiWidget::GetGradientBackgroundFlag() const { return m_GradientBackgroundFlag; } void QmitkStdMultiWidget::EnableGradientBackground() { // gradient background is by default only in widget 4, otherwise // interferences between 2D rendering and VTK rendering may occur. - //m_GradientBackground1->Enable(); - //m_GradientBackground2->Enable(); - //m_GradientBackground3->Enable(); - m_GradientBackground4->Enable(); + for(unsigned int i = 0; i < 4; ++i) + { + m_GradientBackground[i]->Enable(); + } m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::DisableGradientBackground() { - //m_GradientBackground1->Disable(); - //m_GradientBackground2->Disable(); - //m_GradientBackground3->Disable(); - m_GradientBackground4->Disable(); + for(unsigned int i = 0; i < 4; ++i) + { + m_GradientBackground[i]->Disable(); + } m_GradientBackgroundFlag = false; } void QmitkStdMultiWidget::EnableDepartmentLogo() { m_LogoRendering->SetVisibility(true); } void QmitkStdMultiWidget::DisableDepartmentLogo() { m_LogoRendering->SetVisibility(false); } bool QmitkStdMultiWidget::IsDepartmentLogoEnabled() const { return m_LogoRendering->IsVisible(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); } bool QmitkStdMultiWidget::IsCrosshairNavigationEnabled() const { return m_CrosshairNavigationEnabled; } mitk::SlicesRotator * QmitkStdMultiWidget::GetSlicesRotator() const { return m_SlicesRotator; } mitk::SlicesSwiveller * QmitkStdMultiWidget::GetSlicesSwiveller() const { return m_SlicesSwiveller; } void QmitkStdMultiWidget::SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer) { if (m_DataStorage.IsNotNull()) { mitk::DataNode* n = m_DataStorage->GetNamedNode(widgetName); if (n != NULL) n->SetVisibility(visible, renderer); } } void QmitkStdMultiWidget::SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer) { if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetVisibility(visible, renderer); } if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetVisibility(visible, renderer); } if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetVisibility(visible, renderer); } m_RenderingManager->RequestUpdateAll(); } void QmitkStdMultiWidget::SetWidgetPlanesLocked(bool locked) { //do your job and lock or unlock slices. GetRenderWindow1()->GetSliceNavigationController()->SetSliceLocked(locked); GetRenderWindow2()->GetSliceNavigationController()->SetSliceLocked(locked); GetRenderWindow3()->GetSliceNavigationController()->SetSliceLocked(locked); } void QmitkStdMultiWidget::SetWidgetPlanesRotationLocked(bool locked) { //do your job and lock or unlock slices. GetRenderWindow1()->GetSliceNavigationController()->SetSliceRotationLocked(locked); GetRenderWindow2()->GetSliceNavigationController()->SetSliceRotationLocked(locked); GetRenderWindow3()->GetSliceNavigationController()->SetSliceRotationLocked(locked); } void QmitkStdMultiWidget::SetWidgetPlanesRotationLinked( bool link ) { m_SlicesRotator->SetLinkPlanes( link ); m_SlicesSwiveller->SetLinkPlanes( link ); emit WidgetPlanesRotationLinked( link ); } void QmitkStdMultiWidget::SetWidgetPlaneMode( int userMode ) { MITK_DEBUG << "Changing crosshair mode to " << userMode; // first of all reset left mouse button interaction to default if PACS interaction style is active m_MouseModeSwitcher->SelectMouseMode( mitk::MouseModeSwitcher::MousePointer ); emit WidgetNotifyNewCrossHairMode( userMode ); int mode = m_PlaneMode; bool link = false; // Convert user interface mode to actual mode { switch(userMode) { case 0: mode = PLANE_MODE_SLICING; link = false; break; case 1: mode = PLANE_MODE_ROTATION; link = false; break; case 2: mode = PLANE_MODE_ROTATION; link = true; break; case 3: mode = PLANE_MODE_SWIVEL; link = false; break; } } // Slice rotation linked m_SlicesRotator->SetLinkPlanes( link ); m_SlicesSwiveller->SetLinkPlanes( link ); // Do nothing if mode didn't change if ( m_PlaneMode == mode ) { return; } mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); // Remove listeners of previous mode switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: // Notify MainTemplate GUI that this mode has been deselected emit WidgetPlaneModeSlicing( false ); gi->RemoveListener( mitkWidget1->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget2->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget3->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget4->GetSliceNavigationController() ); break; case PLANE_MODE_ROTATION: // Notify MainTemplate GUI that this mode has been deselected emit WidgetPlaneModeRotation( false ); m_SlicesRotator->ResetMouseCursor(); gi->RemoveListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: // Notify MainTemplate GUI that this mode has been deselected emit WidgetPlaneModeSwivel( false ); m_SlicesSwiveller->ResetMouseCursor(); gi->RemoveListener( m_SlicesSwiveller ); break; } // Set new mode and add corresponding listener to GlobalInteraction m_PlaneMode = mode; switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: // Notify MainTemplate GUI that this mode has been selected emit WidgetPlaneModeSlicing( true ); // Add listeners gi->AddListener( mitkWidget1->GetSliceNavigationController() ); gi->AddListener( mitkWidget2->GetSliceNavigationController() ); gi->AddListener( mitkWidget3->GetSliceNavigationController() ); gi->AddListener( mitkWidget4->GetSliceNavigationController() ); m_RenderingManager->InitializeViews(); break; case PLANE_MODE_ROTATION: // Notify MainTemplate GUI that this mode has been selected emit WidgetPlaneModeRotation( true ); // Add listener gi->AddListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: // Notify MainTemplate GUI that this mode has been selected emit WidgetPlaneModeSwivel( true ); // Add listener gi->AddListener( m_SlicesSwiveller ); break; } // Notify MainTemplate GUI that mode has changed emit WidgetPlaneModeChange(m_PlaneMode); } +void QmitkStdMultiWidget::SetGradientBackgroundColorForRenderWindow( const mitk::Color & upper, const mitk::Color & lower, unsigned int widgetNumber ) +{ + + if(widgetNumber > 3) + { + MITK_ERROR << "Gradientbackground for unknown widget!"; + return; + } + m_GradientBackground[widgetNumber]->SetGradientColors(upper, lower); + m_GradientBackgroundFlag = true; +} + void QmitkStdMultiWidget::SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower ) { - m_GradientBackground1->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); - m_GradientBackground2->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); - m_GradientBackground3->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); - m_GradientBackground4->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); + for(unsigned int i = 0; i < 4; ++i) + { + m_GradientBackground[i]->SetGradientColors(upper, lower); + } m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::SetDepartmentLogoPath( const char * path ) { m_LogoRendering->SetLogoImagePath(path); mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()); m_LogoRendering->Update(renderer); RequestUpdate(); } void QmitkStdMultiWidget::SetWidgetPlaneModeToSlicing( bool activate ) { if ( activate ) { this->SetWidgetPlaneMode( PLANE_MODE_SLICING ); } } void QmitkStdMultiWidget::SetWidgetPlaneModeToRotation( bool activate ) { if ( activate ) { this->SetWidgetPlaneMode( PLANE_MODE_ROTATION ); } } void QmitkStdMultiWidget::SetWidgetPlaneModeToSwivel( bool activate ) { if ( activate ) { this->SetWidgetPlaneMode( PLANE_MODE_SWIVEL ); } } void QmitkStdMultiWidget::OnLayoutDesignChanged( int layoutDesignIndex ) { switch( layoutDesignIndex ) { case LAYOUT_DEFAULT: { this->changeLayoutToDefault(); break; } case LAYOUT_2D_IMAGES_UP: { this->changeLayoutTo2DImagesUp(); break; } case LAYOUT_2D_IMAGES_LEFT: { this->changeLayoutTo2DImagesLeft(); break; } case LAYOUT_BIG_3D: { this->changeLayoutToBig3D(); break; } case LAYOUT_WIDGET1: { this->changeLayoutToWidget1(); break; } case LAYOUT_WIDGET2: { this->changeLayoutToWidget2(); break; } case LAYOUT_WIDGET3: { this->changeLayoutToWidget3(); break; } case LAYOUT_2X_2D_AND_3D_WIDGET: { this->changeLayoutTo2x2Dand3DWidget(); break; } case LAYOUT_ROW_WIDGET_3_AND_4: { this->changeLayoutToRowWidget3And4(); break; } case LAYOUT_COLUMN_WIDGET_3_AND_4: { this->changeLayoutToColumnWidget3And4(); break; } case LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4: { this->changeLayoutToRowWidgetSmall3andBig4(); break; } case LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4: { this->changeLayoutToSmallUpperWidget2Big3and4(); break; } case LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET: { this->changeLayoutToLeft2Dand3DRight2D(); break; } }; } void QmitkStdMultiWidget::UpdateAllWidgets() { mitkWidget1->resize( mitkWidget1Container->frameSize().width()-1, mitkWidget1Container->frameSize().height() ); mitkWidget1->resize( mitkWidget1Container->frameSize().width(), mitkWidget1Container->frameSize().height() ); mitkWidget2->resize( mitkWidget2Container->frameSize().width()-1, mitkWidget2Container->frameSize().height() ); mitkWidget2->resize( mitkWidget2Container->frameSize().width(), mitkWidget2Container->frameSize().height() ); mitkWidget3->resize( mitkWidget3Container->frameSize().width()-1, mitkWidget3Container->frameSize().height() ); mitkWidget3->resize( mitkWidget3Container->frameSize().width(), mitkWidget3Container->frameSize().height() ); mitkWidget4->resize( mitkWidget4Container->frameSize().width()-1, mitkWidget4Container->frameSize().height() ); mitkWidget4->resize( mitkWidget4Container->frameSize().width(), mitkWidget4Container->frameSize().height() ); } void QmitkStdMultiWidget::HideAllWidgetToolbars() { mitkWidget1->HideRenderWindowMenu(); mitkWidget2->HideRenderWindowMenu(); mitkWidget3->HideRenderWindowMenu(); mitkWidget4->HideRenderWindowMenu(); } void QmitkStdMultiWidget::ActivateMenuWidget( bool state ) { mitkWidget1->ActivateMenuWidget( state, this ); mitkWidget2->ActivateMenuWidget( state, this ); mitkWidget3->ActivateMenuWidget( state, this ); mitkWidget4->ActivateMenuWidget( state, this ); } bool QmitkStdMultiWidget::IsMenuWidgetEnabled() const { return mitkWidget1->GetActivateMenuWidgetFlag(); } +void QmitkStdMultiWidget::SetDecorationColorWidget4(mitk::Color color) +{ + m_DecorationColorWidget[3] = color; +} + +mitk::Color QmitkStdMultiWidget::GetDecorationColorWidget4() +{ + return m_DecorationColorWidget[3]; +} + void QmitkStdMultiWidget::ResetCrosshair() { if (m_DataStorage.IsNotNull()) { m_RenderingManager->InitializeViewsByBoundingObjects(m_DataStorage); //m_RenderingManager->InitializeViews( m_DataStorage->ComputeVisibleBoundingGeometry3D() ); // reset interactor to normal slicing this->SetWidgetPlaneMode(PLANE_MODE_SLICING); } } void QmitkStdMultiWidget::EnableColoredRectangles() { - m_RectangleRendering1->Enable(1.0, 0.0, 0.0); - m_RectangleRendering2->Enable(0.0, 1.0, 0.0); - m_RectangleRendering3->Enable(0.0, 0.0, 1.0); - m_RectangleRendering4->Enable(1.0, 1.0, 0.0); + float colorWidget1[3]= { 1.0f, 0.0f, 0.0f }; + float colorWidget2[3]= { 0.0f, 1.0f, 0.0f }; + float colorWidget3[3]= { 0.0f, 0.0f, 1.0f }; + + m_PlaneNode1->GetColor(colorWidget1); + m_PlaneNode2->GetColor(colorWidget2); + m_PlaneNode3->GetColor(colorWidget3); + m_RectangleRendering[0]->Enable(colorWidget1[0], colorWidget1[1], colorWidget1[2]); + m_RectangleRendering[1]->Enable(colorWidget2[0], colorWidget2[1], colorWidget2[2]); + m_RectangleRendering[2]->Enable(colorWidget3[0], colorWidget3[1], colorWidget3[2]); + m_RectangleRendering[3]->Enable(m_DecorationColorWidget[3][0], m_DecorationColorWidget[3][1], m_DecorationColorWidget[3][2]); } void QmitkStdMultiWidget::DisableColoredRectangles() { - m_RectangleRendering1->Disable(); - m_RectangleRendering2->Disable(); - m_RectangleRendering3->Disable(); - m_RectangleRendering4->Disable(); + m_RectangleRendering[0]->Disable(); + m_RectangleRendering[1]->Disable(); + m_RectangleRendering[2]->Disable(); + m_RectangleRendering[3]->Disable(); } bool QmitkStdMultiWidget::IsColoredRectanglesEnabled() const { - return m_RectangleRendering1->IsEnabled(); + return m_RectangleRendering[0]->IsEnabled(); } mitk::MouseModeSwitcher* QmitkStdMultiWidget::GetMouseModeSwitcher() { return m_MouseModeSwitcher; } void QmitkStdMultiWidget::MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode ) { if ( mouseMode == 0 ) { this->EnableNavigationControllerEventListening(); } else { this->DisableNavigationControllerEventListening(); } } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane1() { return this->m_PlaneNode1; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane2() { return this->m_PlaneNode2; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane3() { return this->m_PlaneNode3; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane(int id) { switch(id) { case 1: return this->m_PlaneNode1; break; case 2: return this->m_PlaneNode2; break; case 3: return this->m_PlaneNode3; break; default: return NULL; } } diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.h b/Modules/QtWidgets/QmitkStdMultiWidget.h index c81a1ca84b..eed6ff2229 100644 --- a/Modules/QtWidgets/QmitkStdMultiWidget.h +++ b/Modules/QtWidgets/QmitkStdMultiWidget.h @@ -1,355 +1,432 @@ /*=================================================================== 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 QMITKSTDMULTIWIDGET_H_ -#define QMITKSTDMULTIWIDGET_H_ +#ifndef QmitkStdMultiWidget_h +#define QmitkStdMultiWidget_h -#include +#include "MitkQtWidgetsExports.h" -#include "mitkPositionTracker.h" -#include "mitkSlicesRotator.h" -#include "mitkSlicesSwiveller.h" -#include "mitkRenderWindowFrame.h" -#include "mitkLogoOverlay.h" -#include "mitkGradientBackground.h" -#include "mitkCoordinateSupplier.h" -#include "mitkDataStorage.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "mitkMouseModeSwitcher.h" +#include #include #include #include #include #include -#include "vtkTextProperty.h" -#include "vtkCornerAnnotation.h" +#include +#include -#include "mitkBaseRenderer.h" +#include class QHBoxLayout; class QVBoxLayout; class QGridLayout; class QSpacerItem; class QmitkLevelWindowWidget; class QmitkRenderWindow; namespace mitk { class RenderingManager; } /// \ingroup QmitkModule class QMITK_EXPORT QmitkStdMultiWidget : public QWidget { Q_OBJECT public: - QmitkStdMultiWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::RenderingManager* renderingManager = 0, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard, const QString& name = "stdmulti"); virtual ~QmitkStdMultiWidget(); mitk::SliceNavigationController* GetTimeNavigationController(); void RequestUpdate(); void ForceImmediateUpdate(); mitk::MouseModeSwitcher* GetMouseModeSwitcher(); QmitkRenderWindow* GetRenderWindow1() const; QmitkRenderWindow* GetRenderWindow2() const; QmitkRenderWindow* GetRenderWindow3() const; QmitkRenderWindow* GetRenderWindow4() const; const mitk::Point3D & GetLastLeftClickPosition() const; const mitk::Point3D GetCrossPosition() const; void EnablePositionTracking(); void DisablePositionTracking(); int GetLayout() const; mitk::SlicesRotator * GetSlicesRotator() const; mitk::SlicesSwiveller * GetSlicesSwiveller() const; bool GetGradientBackgroundFlag() const; /*! \brief Access node of widget plane 1 \return DataNode holding widget plane 1 */ mitk::DataNode::Pointer GetWidgetPlane1(); /*! \brief Access node of widget plane 2 \return DataNode holding widget plane 2 */ mitk::DataNode::Pointer GetWidgetPlane2(); /*! \brief Access node of widget plane 3 \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane3(); /*! \brief Convenience method to access node of widget planes \param id number of widget plane to be returned \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane(int id); bool IsColoredRectanglesEnabled() const; bool IsDepartmentLogoEnabled() const; bool IsCrosshairNavigationEnabled() const; void InitializeWidget(); /// called when the StdMultiWidget is closed to remove the 3 widget planes and the helper node from the DataStorage void RemovePlanesFromDataStorage(); void AddPlanesToDataStorage(); void SetDataStorage( mitk::DataStorage* ds ); /** \brief Listener to the CrosshairPositionEvent Ensures the CrosshairPositionEvent is handled only once and at the end of the Qt-Event loop */ void HandleCrosshairPositionEvent(); /// activate Menu Widget. true: activated, false: deactivated void ActivateMenuWidget( bool state ); bool IsMenuWidgetEnabled() const; + /** + * @brief SetColorWidget4 Get/Set the color of the decoration of the widget 4. + * + * This is used to color the frame of the renderwindow and the corner annatation. + * For the other 3 widgets, this color is a property of the helper object nodes + * which contain the respective plane geometry. The color can be modified via: + * GetWidgetPlane1()->SetColor(); + */ + void SetDecorationColorWidget4(mitk::Color color); + mitk::Color GetDecorationColorWidget4(); + protected: void UpdateAllWidgets(); void HideAllWidgetToolbars(); mitk::DataNode::Pointer GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes); public slots: /// Receives the signal from HandleCrosshairPositionEvent, executes the StatusBar update void HandleCrosshairPositionEventDelayed(); void changeLayoutTo2DImagesUp(); void changeLayoutTo2DImagesLeft(); void changeLayoutToDefault(); void changeLayoutToBig3D(); void changeLayoutToWidget1(); void changeLayoutToWidget2(); void changeLayoutToWidget3(); void changeLayoutToRowWidget3And4(); void changeLayoutToColumnWidget3And4(); void changeLayoutToRowWidgetSmall3andBig4(); void changeLayoutToSmallUpperWidget2Big3and4(); void changeLayoutTo2x2Dand3DWidget(); void changeLayoutToLeft2Dand3DRight2D(); void changeLayoutTo2DUpAnd3DDown(); void Fit(); void InitPositionTracking(); void AddDisplayPlaneSubTree(); void EnableStandardLevelWindow(); void DisableStandardLevelWindow(); bool InitializeStandardViews( const mitk::Geometry3D * geometry ); void wheelEvent( QWheelEvent * e ); void mousePressEvent(QMouseEvent * e); void moveEvent( QMoveEvent* e ); void leaveEvent ( QEvent * e ); void EnsureDisplayContainsPoint( - mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p); + mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p); void MoveCrossToPosition(const mitk::Point3D& newPosition); void EnableNavigationControllerEventListening(); void DisableNavigationControllerEventListening(); void EnableGradientBackground(); void DisableGradientBackground(); void EnableDepartmentLogo(); void DisableDepartmentLogo(); void EnableColoredRectangles(); void DisableColoredRectangles(); void SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer=NULL); void SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer=NULL); void SetWidgetPlanesLocked(bool locked); void SetWidgetPlanesRotationLocked(bool locked); void SetWidgetPlanesRotationLinked( bool link ); void SetWidgetPlaneMode( int mode ); void SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower ); void SetDepartmentLogoPath( const char * path ); void SetWidgetPlaneModeToSlicing( bool activate ); void SetWidgetPlaneModeToRotation( bool activate ); void SetWidgetPlaneModeToSwivel( bool activate ); void OnLayoutDesignChanged( int layoutDesignIndex ); void ResetCrosshair(); void MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode ); signals: void LeftMouseClicked(mitk::Point3D pointValue); void WheelMoved(QWheelEvent*); void WidgetPlanesRotationLinked(bool); void WidgetPlanesRotationEnabled(bool); void ViewsInitialized(); void WidgetPlaneModeSlicing(bool); void WidgetPlaneModeRotation(bool); void WidgetPlaneModeSwivel(bool); void WidgetPlaneModeChange(int); void WidgetNotifyNewCrossHairMode(int); void Moved(); public: /** Define RenderWindow (public)*/ QmitkRenderWindow* mitkWidget1; QmitkRenderWindow* mitkWidget2; QmitkRenderWindow* mitkWidget3; QmitkRenderWindow* mitkWidget4; QmitkLevelWindowWidget* levelWindowWidget; /********************************/ enum { PLANE_MODE_SLICING = 0, PLANE_MODE_ROTATION, PLANE_MODE_SWIVEL }; enum { LAYOUT_DEFAULT = 0, LAYOUT_2D_IMAGES_UP, LAYOUT_2D_IMAGES_LEFT, - LAYOUT_BIG_3D, LAYOUT_WIDGET1, LAYOUT_WIDGET2, LAYOUT_WIDGET3, - LAYOUT_2X_2D_AND_3D_WIDGET, LAYOUT_ROW_WIDGET_3_AND_4, - LAYOUT_COLUMN_WIDGET_3_AND_4, LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4 , - LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4,LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET, - LAYOUT_2D_UP_AND_3D_DOWN}; + LAYOUT_BIG_3D, LAYOUT_WIDGET1, LAYOUT_WIDGET2, LAYOUT_WIDGET3, + LAYOUT_2X_2D_AND_3D_WIDGET, LAYOUT_ROW_WIDGET_3_AND_4, + LAYOUT_COLUMN_WIDGET_3_AND_4, LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4 , + LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4,LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET, + LAYOUT_2D_UP_AND_3D_DOWN}; enum { AXIAL, SAGITTAL, CORONAL, THREE_D }; + /** + * @brief SetCornerAnnotation Create a corner annotation for a widget. + * @param text The text of the annotation. + * @param color The color. + * @param widgetNumber The widget (0-3). + */ + void SetCornerAnnotation(std::string text, mitk::Color color, int widgetNumber); + /** + * @brief GetRenderWindow convinience method to get a widget. + * @param number of the widget (0-3) + * @return The renderwindow widget. + */ + QmitkRenderWindow *GetRenderWindow(unsigned int number); + + /** + * @brief SetGradientBackgroundColorForRenderWindow background for a widget. + * + * If two different input colors are, a gradient background is generated. + * + * @param upper Upper color of the gradient background. + * @param lower Lower color of the gradient background. + * @param widgetNumber The widget (0-3). + */ + void SetGradientBackgroundColorForRenderWindow(const mitk::Color &upper, const mitk::Color &lower, unsigned int widgetNumber); + + /** + * @brief GetDecorationColorForWidget Get the color for annotation, crosshair and rectangle. + * @param widgetNumber Number of the renderwindow (0-3) + * @return Color in mitk format. + */ + mitk::Color GetDecorationColorForWidget(unsigned int widgetNumber); + protected: QHBoxLayout* QmitkStdMultiWidgetLayout; int m_Layout; int m_PlaneMode; mitk::RenderingManager* m_RenderingManager; - mitk::RenderWindowFrame::Pointer m_RectangleRendering3; - mitk::RenderWindowFrame::Pointer m_RectangleRendering2; - mitk::RenderWindowFrame::Pointer m_RectangleRendering1; - mitk::RenderWindowFrame::Pointer m_RectangleRendering4; + /** + * @brief m_RectangleRendering1 the 4 frames of the renderwindow. + */ + mitk::RenderWindowFrame::Pointer m_RectangleRendering[4]; mitk::LogoOverlay::Pointer m_LogoRendering; - mitk::GradientBackground::Pointer m_GradientBackground1; - mitk::GradientBackground::Pointer m_GradientBackground2; - mitk::GradientBackground::Pointer m_GradientBackground4; - mitk::GradientBackground::Pointer m_GradientBackground3; + mitk::GradientBackground::Pointer m_GradientBackground[4]; bool m_GradientBackgroundFlag; mitk::MouseModeSwitcher::Pointer m_MouseModeSwitcher; mitk::CoordinateSupplier::Pointer m_LastLeftClickPositionSupplier; mitk::PositionTracker::Pointer m_PositionTracker; mitk::SliceNavigationController* m_TimeNavigationController; mitk::SlicesRotator::Pointer m_SlicesRotator; mitk::SlicesSwiveller::Pointer m_SlicesSwiveller; mitk::DataNode::Pointer m_PositionTrackerNode; mitk::DataStorage::Pointer m_DataStorage; + /** + * @brief m_PlaneNode1 the 3 helper objects which contain the plane geometry. + */ mitk::DataNode::Pointer m_PlaneNode1; mitk::DataNode::Pointer m_PlaneNode2; mitk::DataNode::Pointer m_PlaneNode3; - mitk::DataNode::Pointer m_Node; + /** + * @brief m_ParentNodeForGeometryPlanes This helper object is added to the datastorage + * and contains the 3 planes for displaying the image geometry (crosshair and 3D planes). + */ + mitk::DataNode::Pointer m_ParentNodeForGeometryPlanes; + + /** + * @brief m_DecorationColorWidget4 color for annotation and rectangle of widget 4. + * + * For other widgets1-3, the color is a property of the respective data node. + * There is no node for widget 4, hence, we need an extra member. + */ + mitk::Color m_DecorationColorWidget[4]; + + /** + * @brief m_GradientBackgroundColors Contains the colors of the gradient background. + * + */ + mitk::Color m_GradientBackgroundColors[4][2]; + QSplitter *m_MainSplit; QSplitter *m_LayoutSplit; QSplitter *m_SubSplit1; QSplitter *m_SubSplit2; QWidget *mitkWidget1Container; QWidget *mitkWidget2Container; QWidget *mitkWidget3Container; QWidget *mitkWidget4Container; - struct + /** + * @brief The CornerAnnotation struct to hold the 4 corner annotations. + */ + struct CornerAnnotation { - vtkCornerAnnotation *cornerText; - vtkTextProperty *textProp; - vtkRenderer *ren; - } m_CornerAnnotaions[3]; + vtkSmartPointer cornerText; + vtkSmartPointer textProp; + vtkSmartPointer ren; + } m_CornerAnnotations[4]; bool m_PendingCrosshairPositionEvent; bool m_CrosshairNavigationEnabled; + /** + * @brief CreateCornerAnnotation helper method to create a corner annotation. + * @param text of the annotation. + * @param color of the annotation. + * @return the complete struct. + */ + CornerAnnotation CreateCornerAnnotation(std::string text, mitk::Color color); + + /** + * @brief FillGradientBackgroundWithBlack Internal helper method to initialize the + * gradient background colors with black. + */ + void FillGradientBackgroundWithBlack(); }; -#endif /*QMITKSTDMULTIWIDGET_H_*/ +#endif /*QmitkStdMultiWidget_h*/ diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp index b8c7837d90..aba253039b 100644 --- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp +++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.cpp @@ -1,407 +1,423 @@ /*=================================================================== 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 "QmitkImageNavigatorView.h" #include #include #include #include #include const std::string QmitkImageNavigatorView::VIEW_ID = "org.mitk.views.imagenavigator"; QmitkImageNavigatorView::QmitkImageNavigatorView() : m_AxialStepper(0) , m_SagittalStepper(0) , m_FrontalStepper(0) , m_TimeStepper(0) , m_Parent(0) , m_IRenderWindowPart(0) { } QmitkImageNavigatorView::~QmitkImageNavigatorView() { } void QmitkImageNavigatorView::CreateQtPartControl(QWidget *parent) { // create GUI widgets m_Parent = parent; m_Controls.setupUi(parent); m_Controls.m_SliceNavigatorAxial->SetInverseDirection(true); connect(m_Controls.m_XWorldCoordinateSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnMillimetreCoordinateValueChanged())); connect(m_Controls.m_YWorldCoordinateSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnMillimetreCoordinateValueChanged())); connect(m_Controls.m_ZWorldCoordinateSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnMillimetreCoordinateValueChanged())); m_Parent->setEnabled(false); mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart(); this->RenderWindowPartActivated(renderPart); } void QmitkImageNavigatorView::SetFocus () { m_Controls.m_XWorldCoordinateSpinBox->setFocus(); } void QmitkImageNavigatorView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if (this->m_IRenderWindowPart != renderWindowPart) { this->m_IRenderWindowPart = renderWindowPart; this->m_Parent->setEnabled(true); QmitkRenderWindow* renderWindow = renderWindowPart->GetQmitkRenderWindow("axial"); if (renderWindow) { if (m_AxialStepper) m_AxialStepper->deleteLater(); m_AxialStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorAxial, renderWindow->GetSliceNavigationController()->GetSlice(), "sliceNavigatorAxialFromSimpleExample"); m_Controls.m_SliceNavigatorAxial->setEnabled(true); m_Controls.m_AxialLabel->setEnabled(true); m_Controls.m_ZWorldCoordinateSpinBox->setEnabled(true); connect(m_AxialStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch())); } else { m_Controls.m_SliceNavigatorAxial->setEnabled(false); m_Controls.m_AxialLabel->setEnabled(false); m_Controls.m_ZWorldCoordinateSpinBox->setEnabled(false); } renderWindow = renderWindowPart->GetQmitkRenderWindow("sagittal"); if (renderWindow) { if (m_SagittalStepper) m_SagittalStepper->deleteLater(); m_SagittalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorSagittal, renderWindow->GetSliceNavigationController()->GetSlice(), "sliceNavigatorSagittalFromSimpleExample"); m_Controls.m_SliceNavigatorSagittal->setEnabled(true); m_Controls.m_SagittalLabel->setEnabled(true); m_Controls.m_YWorldCoordinateSpinBox->setEnabled(true); connect(m_SagittalStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch())); } else { m_Controls.m_SliceNavigatorSagittal->setEnabled(false); m_Controls.m_SagittalLabel->setEnabled(false); m_Controls.m_YWorldCoordinateSpinBox->setEnabled(false); } renderWindow = renderWindowPart->GetQmitkRenderWindow("coronal"); if (renderWindow) { if (m_FrontalStepper) m_FrontalStepper->deleteLater(); m_FrontalStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorFrontal, renderWindow->GetSliceNavigationController()->GetSlice(), "sliceNavigatorFrontalFromSimpleExample"); m_Controls.m_SliceNavigatorFrontal->setEnabled(true); m_Controls.m_CoronalLabel->setEnabled(true); m_Controls.m_XWorldCoordinateSpinBox->setEnabled(true); connect(m_FrontalStepper, SIGNAL(Refetch()), this, SLOT(OnRefetch())); } else { m_Controls.m_SliceNavigatorFrontal->setEnabled(false); m_Controls.m_CoronalLabel->setEnabled(false); m_Controls.m_XWorldCoordinateSpinBox->setEnabled(false); } mitk::SliceNavigationController* timeController = renderWindowPart->GetTimeNavigationController(); if (timeController) { if (m_TimeStepper) m_TimeStepper->deleteLater(); m_TimeStepper = new QmitkStepperAdapter(m_Controls.m_SliceNavigatorTime, timeController->GetTime(), "sliceNavigatorTimeFromSimpleExample"); m_Controls.m_SliceNavigatorTime->setEnabled(true); m_Controls.m_TimeLabel->setEnabled(true); } else { m_Controls.m_SliceNavigatorTime->setEnabled(false); m_Controls.m_TimeLabel->setEnabled(false); } } } void QmitkImageNavigatorView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/) { m_IRenderWindowPart = 0; m_Parent->setEnabled(false); } int QmitkImageNavigatorView::GetSizeFlags(bool width) { if(!width) { return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL; } else { return 0; } } int QmitkImageNavigatorView::ComputePreferredSize(bool width, int /*availableParallel*/, int /*availablePerpendicular*/, int preferredResult) { if(width==false) { return 200; } else { return preferredResult; } } int QmitkImageNavigatorView::GetClosestAxisIndex(mitk::Vector3D normal) { // cos(theta) = normal . axis // cos(theta) = (a, b, c) . (d, e, f) // cos(theta) = (a, b, c) . (1, 0, 0) = a // cos(theta) = (a, b, c) . (0, 1, 0) = b // cos(theta) = (a, b, c) . (0, 0, 1) = c double absCosThetaWithAxis[3]; for (int i = 0; i < 3; i++) { absCosThetaWithAxis[i] = fabs(normal[i]); } int largestIndex = 0; double largestValue = absCosThetaWithAxis[0]; for (int i = 1; i < 3; i++) { if (absCosThetaWithAxis[i] > largestValue) { largestValue = absCosThetaWithAxis[i]; largestIndex = i; } } return largestIndex; } void QmitkImageNavigatorView::SetBorderColors() { if (m_IRenderWindowPart) { QmitkRenderWindow* renderWindow = m_IRenderWindowPart->GetQmitkRenderWindow("axial"); + QString decoColor = GetDecorationColorOfGeometry(renderWindow); if (renderWindow) { mitk::PlaneGeometry::ConstPointer geometry = renderWindow->GetSliceNavigationController()->GetCurrentPlaneGeometry(); if (geometry.IsNotNull()) { mitk::Vector3D normal = geometry->GetNormal(); int axis = this->GetClosestAxisIndex(normal); - this->SetBorderColor(axis, QString("red")); + this->SetBorderColor(axis, decoColor); } } renderWindow = m_IRenderWindowPart->GetQmitkRenderWindow("sagittal"); + decoColor = GetDecorationColorOfGeometry(renderWindow); if (renderWindow) { mitk::PlaneGeometry::ConstPointer geometry = renderWindow->GetSliceNavigationController()->GetCurrentPlaneGeometry(); if (geometry.IsNotNull()) { mitk::Vector3D normal = geometry->GetNormal(); int axis = this->GetClosestAxisIndex(normal); - this->SetBorderColor(axis, QString("green")); + this->SetBorderColor(axis, decoColor); } } renderWindow = m_IRenderWindowPart->GetQmitkRenderWindow("coronal"); + decoColor = GetDecorationColorOfGeometry(renderWindow); if (renderWindow) { mitk::PlaneGeometry::ConstPointer geometry = renderWindow->GetSliceNavigationController()->GetCurrentPlaneGeometry(); if (geometry.IsNotNull()) { mitk::Vector3D normal = geometry->GetNormal(); int axis = this->GetClosestAxisIndex(normal); - this->SetBorderColor(axis, QString("blue")); + this->SetBorderColor(axis, decoColor); } } } } +QString QmitkImageNavigatorView::GetDecorationColorOfGeometry(QmitkRenderWindow* renderWindow) +{ + QColor color; + float rgb[3] = {1.0f, 1.0f, 1.0f}; + float rgbMax = 255.0f; + mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow())->GetCurrentWorldPlaneGeometryNode()->GetColor(rgb); + color.setRed(static_cast(rgb[0]*rgbMax + 0.5)); + color.setGreen(static_cast(rgb[1]*rgbMax + 0.5)); + color.setBlue(static_cast(rgb[2]*rgbMax + 0.5)); + QString colorAsString = QString(color.name()); + return colorAsString; +} + void QmitkImageNavigatorView::SetBorderColor(int axis, QString colorAsStyleSheetString) { if (axis == 0) { this->SetBorderColor(m_Controls.m_XWorldCoordinateSpinBox, colorAsStyleSheetString); } else if (axis == 1) { this->SetBorderColor(m_Controls.m_YWorldCoordinateSpinBox, colorAsStyleSheetString); } else if (axis == 2) { this->SetBorderColor(m_Controls.m_ZWorldCoordinateSpinBox, colorAsStyleSheetString); } } void QmitkImageNavigatorView::SetBorderColor(QDoubleSpinBox *spinBox, QString colorAsStyleSheetString) { assert(spinBox); spinBox->setStyleSheet(QString("border: 2px solid ") + colorAsStyleSheetString + ";"); } void QmitkImageNavigatorView::SetStepSizes() { this->SetStepSize(0); this->SetStepSize(1); this->SetStepSize(2); } void QmitkImageNavigatorView::SetStepSize(int axis) { if (m_IRenderWindowPart) { mitk::BaseGeometry::ConstPointer geometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldGeometry3D(); if (geometry.IsNotNull()) { mitk::Point3D crossPositionInIndexCoordinates; mitk::Point3D crossPositionInIndexCoordinatesPlus1; mitk::Point3D crossPositionInMillimetresPlus1; mitk::Vector3D transformedAxisDirection; mitk::Point3D crossPositionInMillimetres = m_IRenderWindowPart->GetSelectedPosition(); geometry->WorldToIndex(crossPositionInMillimetres, crossPositionInIndexCoordinates); crossPositionInIndexCoordinatesPlus1 = crossPositionInIndexCoordinates; crossPositionInIndexCoordinatesPlus1[axis] += 1; geometry->IndexToWorld(crossPositionInIndexCoordinatesPlus1, crossPositionInMillimetresPlus1); transformedAxisDirection = crossPositionInMillimetresPlus1 - crossPositionInMillimetres; int closestAxisInMillimetreSpace = this->GetClosestAxisIndex(transformedAxisDirection); double stepSize = transformedAxisDirection.GetNorm(); this->SetStepSize(closestAxisInMillimetreSpace, stepSize); } } } void QmitkImageNavigatorView::SetStepSize(int axis, double stepSize) { if (axis == 0) { m_Controls.m_XWorldCoordinateSpinBox->setSingleStep(stepSize); } else if (axis == 1) { m_Controls.m_YWorldCoordinateSpinBox->setSingleStep(stepSize); } else if (axis == 2) { m_Controls.m_ZWorldCoordinateSpinBox->setSingleStep(stepSize); } } void QmitkImageNavigatorView::OnMillimetreCoordinateValueChanged() { if (m_IRenderWindowPart) { mitk::TimeGeometry::ConstPointer geometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldTimeGeometry(); if (geometry.IsNotNull()) { mitk::Point3D positionInWorldCoordinates; positionInWorldCoordinates[0] = m_Controls.m_XWorldCoordinateSpinBox->value(); positionInWorldCoordinates[1] = m_Controls.m_YWorldCoordinateSpinBox->value(); positionInWorldCoordinates[2] = m_Controls.m_ZWorldCoordinateSpinBox->value(); m_IRenderWindowPart->SetSelectedPosition(positionInWorldCoordinates); } } } void QmitkImageNavigatorView::OnRefetch() { if (m_IRenderWindowPart) { mitk::BaseGeometry::ConstPointer geometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldGeometry3D(); mitk::TimeGeometry::ConstPointer timeGeometry = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetInputWorldTimeGeometry(); if (geometry.IsNull() && timeGeometry.IsNotNull()) { mitk::TimeStepType timeStep = m_IRenderWindowPart->GetActiveQmitkRenderWindow()->GetSliceNavigationController()->GetTime()->GetPos(); geometry = timeGeometry->GetGeometryForTimeStep(timeStep); } if (geometry.IsNotNull()) { mitk::BoundingBox::BoundsArrayType bounds = geometry->GetBounds(); mitk::Point3D cornerPoint1InIndexCoordinates; cornerPoint1InIndexCoordinates[0] = bounds[0]; cornerPoint1InIndexCoordinates[1] = bounds[2]; cornerPoint1InIndexCoordinates[2] = bounds[4]; mitk::Point3D cornerPoint2InIndexCoordinates; cornerPoint2InIndexCoordinates[0] = bounds[1]; cornerPoint2InIndexCoordinates[1] = bounds[3]; cornerPoint2InIndexCoordinates[2] = bounds[5]; if (!geometry->GetImageGeometry()) { cornerPoint1InIndexCoordinates[0] += 0.5; cornerPoint1InIndexCoordinates[1] += 0.5; cornerPoint1InIndexCoordinates[2] += 0.5; cornerPoint2InIndexCoordinates[0] -= 0.5; cornerPoint2InIndexCoordinates[1] -= 0.5; cornerPoint2InIndexCoordinates[2] -= 0.5; } mitk::Point3D crossPositionInWorldCoordinates = m_IRenderWindowPart->GetSelectedPosition(); mitk::Point3D cornerPoint1InWorldCoordinates; mitk::Point3D cornerPoint2InWorldCoordinates; geometry->IndexToWorld(cornerPoint1InIndexCoordinates, cornerPoint1InWorldCoordinates); geometry->IndexToWorld(cornerPoint2InIndexCoordinates, cornerPoint2InWorldCoordinates); m_Controls.m_XWorldCoordinateSpinBox->blockSignals(true); m_Controls.m_YWorldCoordinateSpinBox->blockSignals(true); m_Controls.m_ZWorldCoordinateSpinBox->blockSignals(true); m_Controls.m_XWorldCoordinateSpinBox->setMinimum(std::min(cornerPoint1InWorldCoordinates[0], cornerPoint2InWorldCoordinates[0])); m_Controls.m_YWorldCoordinateSpinBox->setMinimum(std::min(cornerPoint1InWorldCoordinates[1], cornerPoint2InWorldCoordinates[1])); m_Controls.m_ZWorldCoordinateSpinBox->setMinimum(std::min(cornerPoint1InWorldCoordinates[2], cornerPoint2InWorldCoordinates[2])); m_Controls.m_XWorldCoordinateSpinBox->setMaximum(std::max(cornerPoint1InWorldCoordinates[0], cornerPoint2InWorldCoordinates[0])); m_Controls.m_YWorldCoordinateSpinBox->setMaximum(std::max(cornerPoint1InWorldCoordinates[1], cornerPoint2InWorldCoordinates[1])); m_Controls.m_ZWorldCoordinateSpinBox->setMaximum(std::max(cornerPoint1InWorldCoordinates[2], cornerPoint2InWorldCoordinates[2])); m_Controls.m_XWorldCoordinateSpinBox->setValue(crossPositionInWorldCoordinates[0]); m_Controls.m_YWorldCoordinateSpinBox->setValue(crossPositionInWorldCoordinates[1]); m_Controls.m_ZWorldCoordinateSpinBox->setValue(crossPositionInWorldCoordinates[2]); m_Controls.m_XWorldCoordinateSpinBox->blockSignals(false); m_Controls.m_YWorldCoordinateSpinBox->blockSignals(false); m_Controls.m_ZWorldCoordinateSpinBox->blockSignals(false); } this->SetBorderColors(); } } diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.h b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.h index fc63852157..3835bac90a 100644 --- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.h +++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/QmitkImageNavigatorView.h @@ -1,96 +1,102 @@ /*=================================================================== 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 _QMITKIMAGENAVIGATORVIEW_H_INCLUDED #define _QMITKIMAGENAVIGATORVIEW_H_INCLUDED #include #include #include #include "ui_QmitkImageNavigatorViewControls.h" class QmitkStepperAdapter; /*! * \ingroup org_mitk_gui_qt_imagenavigator_internal * * \class QmitkImageNavigatorView * * \brief Provides a means to scan quickly through a dataset via Axial, * Coronal and Sagittal sliders, displaying millimetre location and stepper position. * * For images, the stepper position corresponds to a voxel index. For other datasets * such as a surface, it corresponds to a sub-division of the bounding box. * * \sa QmitkAbstractView */ class QmitkImageNavigatorView : public QmitkAbstractView, public mitk::IRenderWindowPartListener, public berry::ISizeProvider { // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkImageNavigatorView(); virtual ~QmitkImageNavigatorView(); virtual void CreateQtPartControl(QWidget *parent); virtual int GetSizeFlags(bool width); virtual int ComputePreferredSize(bool width, int /*availableParallel*/, int /*availablePerpendicular*/, int preferredResult); protected slots: void OnMillimetreCoordinateValueChanged(); void OnRefetch(); protected: void SetFocus(); void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart); void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart); void SetBorderColors(); void SetBorderColor(QDoubleSpinBox *spinBox, QString colorAsStyleSheetString); void SetBorderColor(int axis, QString colorAsStyleSheetString); void SetStepSizes(); void SetStepSize(int axis); void SetStepSize(int axis, double stepSize); int GetClosestAxisIndex(mitk::Vector3D normal); Ui::QmitkImageNavigatorViewControls m_Controls; QmitkStepperAdapter* m_AxialStepper; QmitkStepperAdapter* m_SagittalStepper; QmitkStepperAdapter* m_FrontalStepper; QmitkStepperAdapter* m_TimeStepper; QWidget* m_Parent; mitk::IRenderWindowPart* m_IRenderWindowPart; + /** + * @brief GetDecorationColorOfGeometry helper method to get the color of a helper geometry node. + * @param renderWindow The renderwindow of the geometry + * @return the color for decoration in QString format (#RRGGBB). + */ + QString GetDecorationColorOfGeometry(QmitkRenderWindow *renderWindow); }; #endif // _QMITKIMAGENAVIGATORVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/files.cmake b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/files.cmake index 9c3e10fa7b..b8f7c67c31 100755 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/files.cmake +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/files.cmake @@ -1,36 +1,36 @@ set(SRC_CPP_FILES QmitkStdMultiWidgetEditor.cpp ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp QmitkStdMultiWidgetEditorPreferencePage.cpp ) set(MOC_H_FILES src/QmitkStdMultiWidgetEditor.h src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h src/internal/QmitkStdMultiWidgetEditorPreferencePage.h ) set(UI_FILES - + src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui ) set(CACHED_RESOURCE_FILES plugin.xml ) set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp index 90faecd9cb..1ae50254c4 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp @@ -1,452 +1,535 @@ /*=================================================================== 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 "QmitkStdMultiWidgetEditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include class QmitkStdMultiWidgetEditorPrivate { public: QmitkStdMultiWidgetEditorPrivate(); ~QmitkStdMultiWidgetEditorPrivate(); QmitkStdMultiWidget* m_StdMultiWidget; QmitkMouseModeSwitcher* m_MouseModeToolbar; std::string m_FirstBackgroundColor; std::string m_SecondBackgroundColor; bool m_MenuWidgetsEnabled; berry::IPartListener::Pointer m_PartListener; QHash m_RenderWindows; }; struct QmitkStdMultiWidgetPartListener : public berry::IPartListener { berryObjectMacro(QmitkStdMultiWidgetPartListener) QmitkStdMultiWidgetPartListener(QmitkStdMultiWidgetEditorPrivate* dd) : d(dd) {} Events::Types GetPartEventTypes() const { return Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartClosed (berry::IWorkbenchPartReference::Pointer partRef) { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->RemovePlanesFromDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(false); } } } void PartHidden (berry::IWorkbenchPartReference::Pointer partRef) { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->RemovePlanesFromDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(false); } } } void PartVisible (berry::IWorkbenchPartReference::Pointer partRef) { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->AddPlanesToDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(true); } } } private: QmitkStdMultiWidgetEditorPrivate* const d; }; QmitkStdMultiWidgetEditorPrivate::QmitkStdMultiWidgetEditorPrivate() : m_StdMultiWidget(0), m_MouseModeToolbar(0) , m_MenuWidgetsEnabled(false) , m_PartListener(new QmitkStdMultiWidgetPartListener(this)) {} QmitkStdMultiWidgetEditorPrivate::~QmitkStdMultiWidgetEditorPrivate() { } const std::string QmitkStdMultiWidgetEditor::EDITOR_ID = "org.mitk.editors.stdmultiwidget"; QmitkStdMultiWidgetEditor::QmitkStdMultiWidgetEditor() : d(new QmitkStdMultiWidgetEditorPrivate) { } QmitkStdMultiWidgetEditor::~QmitkStdMultiWidgetEditor() { this->GetSite()->GetPage()->RemovePartListener(d->m_PartListener); } QmitkStdMultiWidget* QmitkStdMultiWidgetEditor::GetStdMultiWidget() { return d->m_StdMultiWidget; } QmitkRenderWindow *QmitkStdMultiWidgetEditor::GetActiveQmitkRenderWindow() const { if (d->m_StdMultiWidget) return d->m_StdMultiWidget->GetRenderWindow1(); return 0; } QHash QmitkStdMultiWidgetEditor::GetQmitkRenderWindows() const { return d->m_RenderWindows; } QmitkRenderWindow *QmitkStdMultiWidgetEditor::GetQmitkRenderWindow(const QString &id) const { if (d->m_RenderWindows.contains(id)) return d->m_RenderWindows[id]; return 0; } mitk::Point3D QmitkStdMultiWidgetEditor::GetSelectedPosition(const QString & /*id*/) const { return d->m_StdMultiWidget->GetCrossPosition(); } void QmitkStdMultiWidgetEditor::SetSelectedPosition(const mitk::Point3D &pos, const QString &/*id*/) { d->m_StdMultiWidget->MoveCrossToPosition(pos); } void QmitkStdMultiWidgetEditor::EnableDecorations(bool enable, const QStringList &decorations) { if (decorations.isEmpty() || decorations.contains(DECORATION_BORDER)) { enable ? d->m_StdMultiWidget->EnableColoredRectangles() : d->m_StdMultiWidget->DisableColoredRectangles(); } if (decorations.isEmpty() || decorations.contains(DECORATION_LOGO)) { enable ? d->m_StdMultiWidget->EnableDepartmentLogo() : d->m_StdMultiWidget->DisableDepartmentLogo(); } if (decorations.isEmpty() || decorations.contains(DECORATION_MENU)) { d->m_StdMultiWidget->ActivateMenuWidget(enable); } if (decorations.isEmpty() || decorations.contains(DECORATION_BACKGROUND)) { enable ? d->m_StdMultiWidget->EnableGradientBackground() : d->m_StdMultiWidget->DisableGradientBackground(); } } bool QmitkStdMultiWidgetEditor::IsDecorationEnabled(const QString &decoration) const { if (decoration == DECORATION_BORDER) { return d->m_StdMultiWidget->IsColoredRectanglesEnabled(); } else if (decoration == DECORATION_LOGO) { return d->m_StdMultiWidget->IsColoredRectanglesEnabled(); } else if (decoration == DECORATION_MENU) { return d->m_StdMultiWidget->IsMenuWidgetEnabled(); } else if (decoration == DECORATION_BACKGROUND) { return d->m_StdMultiWidget->GetGradientBackgroundFlag(); } return false; } QStringList QmitkStdMultiWidgetEditor::GetDecorations() const { QStringList decorations; decorations << DECORATION_BORDER << DECORATION_LOGO << DECORATION_MENU << DECORATION_BACKGROUND; return decorations; } mitk::SlicesRotator* QmitkStdMultiWidgetEditor::GetSlicesRotator() const { return d->m_StdMultiWidget->GetSlicesRotator(); } mitk::SlicesSwiveller* QmitkStdMultiWidgetEditor::GetSlicesSwiveller() const { return d->m_StdMultiWidget->GetSlicesSwiveller(); } void QmitkStdMultiWidgetEditor::EnableSlicingPlanes(bool enable) { d->m_StdMultiWidget->SetWidgetPlanesVisibility(enable); } bool QmitkStdMultiWidgetEditor::IsSlicingPlanesEnabled() const { mitk::DataNode::Pointer node = this->d->m_StdMultiWidget->GetWidgetPlane1(); if (node.IsNotNull()) { bool visible = false; node->GetVisibility(visible, 0); return visible; } else { return false; } } void QmitkStdMultiWidgetEditor::EnableLinkedNavigation(bool enable) { enable ? d->m_StdMultiWidget->EnableNavigationControllerEventListening() : d->m_StdMultiWidget->DisableNavigationControllerEventListening(); } bool QmitkStdMultiWidgetEditor::IsLinkedNavigationEnabled() const { return d->m_StdMultiWidget->IsCrosshairNavigationEnabled(); } void QmitkStdMultiWidgetEditor::CreateQtPartControl(QWidget* parent) { if (d->m_StdMultiWidget == 0) { QHBoxLayout* layout = new QHBoxLayout(parent); layout->setContentsMargins(0,0,0,0); if (d->m_MouseModeToolbar == NULL) { d->m_MouseModeToolbar = new QmitkMouseModeSwitcher(parent); // delete by Qt via parent layout->addWidget(d->m_MouseModeToolbar); } berry::IPreferences::Pointer prefs = this->GetPreferences(); mitk::BaseRenderer::RenderingMode::Type renderingMode = static_cast(prefs->GetInt( "Rendering Mode" , 0 )); d->m_StdMultiWidget = new QmitkStdMultiWidget(parent,0,0,renderingMode); d->m_RenderWindows.insert("axial", d->m_StdMultiWidget->GetRenderWindow1()); d->m_RenderWindows.insert("sagittal", d->m_StdMultiWidget->GetRenderWindow2()); d->m_RenderWindows.insert("coronal", d->m_StdMultiWidget->GetRenderWindow3()); d->m_RenderWindows.insert("3d", d->m_StdMultiWidget->GetRenderWindow4()); d->m_MouseModeToolbar->setMouseModeSwitcher( d->m_StdMultiWidget->GetMouseModeSwitcher() ); connect( d->m_MouseModeToolbar, SIGNAL( MouseModeSelected(mitk::MouseModeSwitcher::MouseMode) ), - d->m_StdMultiWidget, SLOT( MouseModeSelected(mitk::MouseModeSwitcher::MouseMode) ) ); + d->m_StdMultiWidget, SLOT( MouseModeSelected(mitk::MouseModeSwitcher::MouseMode) ) ); layout->addWidget(d->m_StdMultiWidget); mitk::DataStorage::Pointer ds = this->GetDataStorage(); // Tell the multiWidget which (part of) the tree to render d->m_StdMultiWidget->SetDataStorage(ds); // Initialize views as axial, sagittal, coronar to all data objects in DataStorage // (from top-left to bottom) mitk::TimeGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); // Initialize bottom-right view as 3D view d->m_StdMultiWidget->GetRenderWindow4()->GetRenderer()->SetMapperID( - mitk::BaseRenderer::Standard3D ); + mitk::BaseRenderer::Standard3D ); // Enable standard handler for levelwindow-slider d->m_StdMultiWidget->EnableStandardLevelWindow(); // Add the displayed views to the tree to see their positions // in 2D and 3D d->m_StdMultiWidget->AddDisplayPlaneSubTree(); d->m_StdMultiWidget->EnableNavigationControllerEventListening(); // Store the initial visibility status of the menu widget. d->m_MenuWidgetsEnabled = d->m_StdMultiWidget->IsMenuWidgetEnabled(); this->GetSite()->GetPage()->AddPartListener(d->m_PartListener); - this->OnPreferencesChanged(dynamic_cast(prefs.GetPointer())); + berry::IBerryPreferences* berryprefs = dynamic_cast(prefs.GetPointer()); + InitializePreferences(berryprefs); + this->OnPreferencesChanged(berryprefs); this->RequestUpdate(); } } void QmitkStdMultiWidgetEditor::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { // Enable change of logo. If no DepartmentLogo was set explicitly, MBILogo is used. // Set new department logo by prefs->Set("DepartmentLogo", "PathToImage"); - // If no logo was set for this plug-in specifically, walk the parent preference nodes // and lookup a logo value there. - const berry::IPreferences* currentNode = prefs; while(currentNode) { std::vector keys = currentNode->Keys(); bool logoFound = false; for( std::size_t i = 0; i < keys.size(); ++i ) { if( keys[i] == "DepartmentLogo") { std::string departmentLogoLocation = currentNode->Get("DepartmentLogo", ""); if (departmentLogoLocation.empty()) { d->m_StdMultiWidget->DisableDepartmentLogo(); } else { // we need to disable the logo first, otherwise setting a new logo will have // no effect due to how mitkManufacturerLogo works... d->m_StdMultiWidget->DisableDepartmentLogo(); d->m_StdMultiWidget->SetDepartmentLogoPath(departmentLogoLocation.c_str()); d->m_StdMultiWidget->EnableDepartmentLogo(); } logoFound = true; break; } } if (logoFound) break; currentNode = currentNode->Parent().GetPointer(); } // preferences for gradient background - float color = 255.0; - QString firstColorName = QString::fromStdString (prefs->GetByteArray("first background color", "")); - QColor firstColor(firstColorName); - mitk::Color upper; - if (firstColorName=="") // default values - { - upper[0] = 0.1; - upper[1] = 0.1; - upper[2] = 0.1; - } - else - { - upper[0] = firstColor.red() / color; - upper[1] = firstColor.green() / color; - upper[2] = firstColor.blue() / color; - } - - QString secondColorName = QString::fromStdString (prefs->GetByteArray("second background color", "")); - QColor secondColor(secondColorName); - mitk::Color lower; - if (secondColorName=="") // default values - { - lower[0] = 0.5; - lower[1] = 0.5; - lower[2] = 0.5; - } - else - { - lower[0] = secondColor.red() / color; - lower[1] = secondColor.green() / color; - lower[2] = secondColor.blue() / color; - } - d->m_StdMultiWidget->SetGradientBackgroundColors(upper, lower); + mitk::Color upper = HexColorToMitkColor(prefs->GetByteArray("widget1 first background color", "#000000")); + mitk::Color lower = HexColorToMitkColor(prefs->GetByteArray("widget1 second background color", "#000000")); + d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 0); + upper = HexColorToMitkColor(prefs->GetByteArray("widget2 first background color", "#000000")); + lower = HexColorToMitkColor(prefs->GetByteArray("widget2 second background color", "#000000")); + d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 1); + upper = HexColorToMitkColor(prefs->GetByteArray("widget3 first background color", "#000000")); + lower = HexColorToMitkColor(prefs->GetByteArray("widget3 second background color", "#000000")); + d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 2); + upper = HexColorToMitkColor(prefs->GetByteArray("widget4 first background color", "#191919")); + lower = HexColorToMitkColor(prefs->GetByteArray("widget4 second background color", "#7F7F7F")); + d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 3); d->m_StdMultiWidget->EnableGradientBackground(); + // preferences for renderWindows + mitk::Color colorDecorationWidget1 = HexColorToMitkColor(prefs->GetByteArray("widget1 decoration color", "#FF0000")); + mitk::Color colorDecorationWidget2 = HexColorToMitkColor(prefs->GetByteArray("widget2 decoration color", "#00FF00")); + mitk::Color colorDecorationWidget3 = HexColorToMitkColor(prefs->GetByteArray("widget3 decoration color", "#0000FF")); + mitk::Color colorDecorationWidget4 = HexColorToMitkColor(prefs->GetByteArray("widget4 decoration color", "#FFFF00")); + mitk::BaseRenderer::GetInstance(d->m_StdMultiWidget->GetRenderWindow1()->GetVtkRenderWindow()) + ->GetCurrentWorldPlaneGeometryNode()->SetColor(colorDecorationWidget1); + mitk::BaseRenderer::GetInstance(d->m_StdMultiWidget->GetRenderWindow2()->GetVtkRenderWindow()) + ->GetCurrentWorldPlaneGeometryNode()->SetColor(colorDecorationWidget2); + mitk::BaseRenderer::GetInstance(d->m_StdMultiWidget->GetRenderWindow3()->GetVtkRenderWindow()) + ->GetCurrentWorldPlaneGeometryNode()->SetColor(colorDecorationWidget3); + d->m_StdMultiWidget->SetDecorationColorWidget4(colorDecorationWidget4); + + //The crosshair gap + int crosshairgapsize = prefs->GetInt("crosshair gap size", 32); + mitk::BaseRenderer::GetInstance(d->m_StdMultiWidget->GetRenderWindow1()->GetVtkRenderWindow()) + ->GetCurrentWorldPlaneGeometryNode()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize); + mitk::BaseRenderer::GetInstance(d->m_StdMultiWidget->GetRenderWindow2()->GetVtkRenderWindow()) + ->GetCurrentWorldPlaneGeometryNode()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize); + mitk::BaseRenderer::GetInstance(d->m_StdMultiWidget->GetRenderWindow3()->GetVtkRenderWindow()) + ->GetCurrentWorldPlaneGeometryNode()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize); + + //refresh colors of rectangles + d->m_StdMultiWidget->EnableColoredRectangles(); + // Set preferences respecting zooming and padding bool constrainedZooming = prefs->GetBool("Use constrained zooming and padding", false); mitk::RenderingManager::GetInstance()->SetConstrainedPaddingZooming(constrainedZooming); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // level window setting bool showLevelWindowWidget = prefs->GetBool("Show level/window widget", true); if (showLevelWindowWidget) { d->m_StdMultiWidget->EnableStandardLevelWindow(); } else { d->m_StdMultiWidget->DisableStandardLevelWindow(); } // mouse modes toolbar bool newMode = prefs->GetBool("PACS like mouse interaction", false); d->m_MouseModeToolbar->setVisible( newMode ); d->m_StdMultiWidget->GetMouseModeSwitcher()->SetInteractionScheme( newMode ? mitk::MouseModeSwitcher::PACS : mitk::MouseModeSwitcher::MITK ); + + d->m_StdMultiWidget->SetCornerAnnotation( + prefs->GetByteArray("widget1 corner annotation", "Axial"), colorDecorationWidget1, 0); + d->m_StdMultiWidget->SetCornerAnnotation( + prefs->GetByteArray("widget2 corner annotation", "Sagittal"), colorDecorationWidget2, 1); + d->m_StdMultiWidget->SetCornerAnnotation( + prefs->GetByteArray("widget3 corner annotation", "Coronal"), colorDecorationWidget3, 2); + d->m_StdMultiWidget->SetCornerAnnotation( + prefs->GetByteArray("widget4 corner annotation", "3D"), colorDecorationWidget4, 3); +} + +mitk::Color QmitkStdMultiWidgetEditor::HexColorToMitkColor(std::string widgetColorInHex) +{ + QString widgetColorQt = QString::fromStdString(widgetColorInHex); + QColor qColor(widgetColorQt); + mitk::Color returnColor; + float colorMax = 255.0f; + if (widgetColorQt=="") // default value + { + returnColor[0] = 1.0; + returnColor[1] = 1.0; + returnColor[2] = 1.0; + MITK_ERROR << "Using default color for unknown widget " << widgetColorInHex; + } + else + { + returnColor[0] = qColor.red() / colorMax; + returnColor[1] = qColor.green() / colorMax; + returnColor[2] = qColor.blue() / colorMax; + } + return returnColor; +} + +void QmitkStdMultiWidgetEditor::InitializePreferences(berry::IBerryPreferences * preferences) +{ + std::string widgetBackgroundColor1[4]; + std::string widgetBackgroundColor2[4]; + std::string widgetDecorationColor[4]; + std::string widgetAnnotation[4]; + widgetBackgroundColor1[0] = preferences->GetByteArray("widget1 first background color", "#000000"); + widgetBackgroundColor2[0] = preferences->GetByteArray("widget1 second background color", "#000000"); + widgetBackgroundColor1[1] = preferences->GetByteArray("widget2 first background color", "#000000"); + widgetBackgroundColor2[1] = preferences->GetByteArray("widget2 second background color", "#000000"); + widgetBackgroundColor1[2] = preferences->GetByteArray("widget3 first background color", "#000000"); + widgetBackgroundColor2[2] = preferences->GetByteArray("widget3 second background color", "#000000"); + widgetBackgroundColor1[3] = preferences->GetByteArray("widget4 first background color", "#191919"); + widgetBackgroundColor2[3] = preferences->GetByteArray("widget4 second background color", "#7F7F7F"); + + //decoration colors + widgetDecorationColor[0] = preferences->GetByteArray("widget1 decoration color", "#C00000"); + widgetDecorationColor[1] = preferences->GetByteArray("widget2 decoration color", "#00B000"); + widgetDecorationColor[2] = preferences->GetByteArray("widget3 decoration color", "#0080FF"); + widgetDecorationColor[3] = preferences->GetByteArray("widget4 decoration color", "#FFFF00"); + + //annotation text + widgetAnnotation[0] = preferences->GetByteArray("widget1 corner annotation", "Axial"); + widgetAnnotation[1] = preferences->GetByteArray("widget2 corner annotation", "Sagittal"); + widgetAnnotation[2] = preferences->GetByteArray("widget3 corner annotation", "Coronal"); + widgetAnnotation[3] = preferences->GetByteArray("widget4 corner annotation", "3D"); + + preferences->PutByteArray("widget1 corner annotation", widgetAnnotation[0]); + preferences->PutByteArray("widget2 corner annotation", widgetAnnotation[1]); + preferences->PutByteArray("widget3 corner annotation", widgetAnnotation[2]); + preferences->PutByteArray("widget4 corner annotation", widgetAnnotation[3]); + + preferences->PutByteArray("widget1 decoration color", widgetDecorationColor[0]); + preferences->PutByteArray("widget2 decoration color", widgetDecorationColor[1]); + preferences->PutByteArray("widget3 decoration color", widgetDecorationColor[2]); + preferences->PutByteArray("widget4 decoration color", widgetDecorationColor[3]); + + preferences->PutByteArray("widget1 first background color", widgetBackgroundColor1[0]); + preferences->PutByteArray("widget2 first background color", widgetBackgroundColor1[1]); + preferences->PutByteArray("widget3 first background color", widgetBackgroundColor1[2]); + preferences->PutByteArray("widget4 first background color", widgetBackgroundColor1[3]); + preferences->PutByteArray("widget1 second background color", widgetBackgroundColor2[0]); + preferences->PutByteArray("widget2 second background color", widgetBackgroundColor2[1]); + preferences->PutByteArray("widget3 second background color", widgetBackgroundColor2[2]); + preferences->PutByteArray("widget4 second background color", widgetBackgroundColor2[3]); } void QmitkStdMultiWidgetEditor::SetFocus() { if (d->m_StdMultiWidget != 0) d->m_StdMultiWidget->setFocus(); } void QmitkStdMultiWidgetEditor::RequestActivateMenuWidget(bool on) { if (d->m_StdMultiWidget) { if (on) { d->m_StdMultiWidget->ActivateMenuWidget(d->m_MenuWidgetsEnabled); } else { d->m_MenuWidgetsEnabled = d->m_StdMultiWidget->IsMenuWidgetEnabled(); d->m_StdMultiWidget->ActivateMenuWidget(false); } } } diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h index d13ba1055d..ab30293355 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.h @@ -1,120 +1,126 @@ /*=================================================================== 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 QMITKSTDMULTIWIDGETEDITOR_H_ -#define QMITKSTDMULTIWIDGETEDITOR_H_ +#ifndef QmitkStdMultiWidgetEditor_h +#define QmitkStdMultiWidgetEditor_h #include #include #include class QmitkStdMultiWidget; class QmitkMouseModeSwitcher; class QmitkStdMultiWidgetEditorPrivate; /** * \ingroup org_mitk_gui_qt_stdmultiwidgeteditor */ class ORG_MITK_GUI_QT_STDMULTIWIDGETEDITOR QmitkStdMultiWidgetEditor : public QmitkAbstractRenderEditor, public mitk::ILinkedRenderWindowPart { Q_OBJECT public: berryObjectMacro(QmitkStdMultiWidgetEditor); static const std::string EDITOR_ID; QmitkStdMultiWidgetEditor(); ~QmitkStdMultiWidgetEditor(); QmitkStdMultiWidget* GetStdMultiWidget(); /// \brief If on=true will request the QmitkStdMultiWidget set the Menu widget to /// whatever was the last known enabled state, and if on=false will turn the Menu widget off. void RequestActivateMenuWidget(bool on); // ------------------- mitk::IRenderWindowPart ---------------------- /** * \see mitk::IRenderWindowPart::GetActiveQmitkRenderWindow() */ QmitkRenderWindow* GetActiveQmitkRenderWindow() const; /** * \see mitk::IRenderWindowPart::GetQmitkRenderWindows() */ QHash GetQmitkRenderWindows() const; /** * \see mitk::IRenderWindowPart::GetQmitkRenderWindow(QString) */ QmitkRenderWindow* GetQmitkRenderWindow(const QString& id) const; /** * \see mitk::IRenderWindowPart::GetSelectionPosition() */ mitk::Point3D GetSelectedPosition(const QString& id = QString()) const; /** * \see mitk::IRenderWindowPart::SetSelectedPosition() */ void SetSelectedPosition(const mitk::Point3D& pos, const QString& id = QString()); /** * \see mitk::IRenderWindowPart::EnableDecorations() */ void EnableDecorations(bool enable, const QStringList& decorations = QStringList()); /** * \see mitk::IRenderWindowPart::IsDecorationEnabled() */ bool IsDecorationEnabled(const QString& decoration) const; /** * \see mitk::IRenderWindowPart::GetDecorations() */ QStringList GetDecorations() const; // ------------------- mitk::ILinkedRenderWindowPart ---------------------- mitk::SlicesRotator* GetSlicesRotator() const; mitk::SlicesSwiveller* GetSlicesSwiveller() const; void EnableSlicingPlanes(bool enable); bool IsSlicingPlanesEnabled() const; void EnableLinkedNavigation(bool enable); bool IsLinkedNavigationEnabled() const; protected: void SetFocus(); void OnPreferencesChanged(const berry::IBerryPreferences*); void CreateQtPartControl(QWidget* parent); + /** + * @brief GetColorForWidget helper method to convert a saved color string to mitk::Color. + * @param widgetColorInHex color in hex format (#12356) where each diget is in the form (0-F). + * @return the color in mitk format. + */ + mitk::Color HexColorToMitkColor(std::string widgetColorInHex); private: - const QScopedPointer d; + void InitializePreferences(berry::IBerryPreferences *preferences); + const QScopedPointer d; }; - -#endif /*QMITKSTDMULTIWIDGETEDITOR_H_*/ +#endif /*QmitkStdMultiWidgetEditor_h*/ diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp index 05db5f1c94..93835ac970 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp @@ -1,263 +1,275 @@ /*=================================================================== 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 "QmitkStdMultiWidgetEditorPreferencePage.h" -#include "QmitkStdMultiWidgetEditor.h" - -#include -#include -#include -#include -#include -#include - #include #include +#include +#include +#include +#include +#include "QmitkStdMultiWidgetEditorPreferencePage.h" + +#include QmitkStdMultiWidgetEditorPreferencePage::QmitkStdMultiWidgetEditorPreferencePage() -: m_MainControl(0) + : m_Preferences(NULL), + m_Ui(new Ui::QmitkStdMultiWidgetEditorPreferencePage), + m_Control(NULL) { } -void QmitkStdMultiWidgetEditorPreferencePage::Init(berry::IWorkbench::Pointer ) +QmitkStdMultiWidgetEditorPreferencePage::~QmitkStdMultiWidgetEditorPreferencePage() { } void QmitkStdMultiWidgetEditorPreferencePage::CreateQtControl(QWidget* parent) { + m_Control = new QWidget(parent); + + m_Ui->setupUi(m_Control); + berry::IPreferencesService::Pointer prefService - = berry::Platform::GetServiceRegistry() - .GetServiceById(berry::IPreferencesService::ID); - - m_StdMultiWidgetEditorPreferencesNode = prefService->GetSystemPreferences()->Node(QmitkStdMultiWidgetEditor::EDITOR_ID); - - m_MainControl = new QWidget(parent); - m_EnableFlexibleZooming = new QCheckBox; - m_ShowLevelWindowWidget = new QCheckBox; - m_PACSLikeMouseMode = new QCheckBox; - - QFormLayout *formLayout = new QFormLayout; - formLayout->addRow("&Use constrained zooming and padding", m_EnableFlexibleZooming); - formLayout->addRow("&Show level/window widget", m_ShowLevelWindowWidget); - formLayout->addRow("&PACS like mouse interactions (select left mouse button action)", m_PACSLikeMouseMode); - - // gradient background - QLabel* gBName = new QLabel; - gBName->setText("Gradient background"); - formLayout->addRow(gBName); - - // color - m_ColorButton1 = new QPushButton; - m_ColorButton1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); - m_ColorButton2 = new QPushButton; - m_ColorButton2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); - QPushButton* resetButton = new QPushButton; - resetButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); - resetButton->setText("Reset"); - - QLabel* colorLabel1 = new QLabel("first color : "); - colorLabel1->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - QLabel* colorLabel2 = new QLabel("second color: "); - colorLabel2->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - - QHBoxLayout* colorWidgetLayout = new QHBoxLayout; - colorWidgetLayout->setContentsMargins(4,4,4,4); - colorWidgetLayout->addWidget(colorLabel1); - colorWidgetLayout->addWidget(m_ColorButton1); - colorWidgetLayout->addWidget(colorLabel2); - colorWidgetLayout->addWidget(m_ColorButton2); - colorWidgetLayout->addWidget(resetButton); - - QWidget* colorWidget = new QWidget; - colorWidget->setLayout(colorWidgetLayout); - - QLabel* renderLabel = new QLabel; - renderLabel->setText("Rendering Mode* "); - - m_RenderingMode = new QComboBox; - m_RenderingMode->addItem("Standard Rendering"); - m_RenderingMode->addItem("Enable Multisampling (Antialiasing)" ); - m_RenderingMode->addItem("Enable Depth Peeling" ); - - QLabel* cBHint = new QLabel; - cBHint->setText("* Changes require restart of MITK. \n Depth Peeling is only supported by Windows. \n For other OS, use Standard Rendering and enable \n the property 'Depth Sorting' in the property list of the surface data node."); - - QSpacerItem *spacer1 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - - QHBoxLayout* renderingWidgetLayout = new QHBoxLayout; - renderingWidgetLayout->setContentsMargins(4,4,4,4); - renderingWidgetLayout->addWidget(renderLabel); - renderingWidgetLayout->addWidget(m_RenderingMode); - renderingWidgetLayout->addWidget(cBHint); - renderingWidgetLayout->addSpacerItem(spacer1); - - QWidget* renderingWidget = new QWidget; - renderingWidget->setLayout(renderingWidgetLayout); - - //spacer - QSpacerItem *spacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); - QVBoxLayout* vBoxLayout = new QVBoxLayout; - vBoxLayout->addLayout(formLayout); - vBoxLayout->addWidget(colorWidget); - vBoxLayout->addWidget(renderingWidget); - vBoxLayout->addSpacerItem(spacer); - - m_MainControl->setLayout(vBoxLayout); - - QObject::connect( m_ColorButton1, SIGNAL( clicked() ) - , this, SLOT( FirstColorChanged() ) ); - - QObject::connect( m_ColorButton2, SIGNAL( clicked() ) - , this, SLOT( SecondColorChanged() ) ); - - QObject::connect( resetButton, SIGNAL( clicked() ) - , this, SLOT( ResetColors() ) ); - - QObject::connect( m_RenderingMode, SIGNAL(activated(int) ) - , this, SLOT( ChangeRenderingMode(int) ) ); + = berry::Platform::GetServiceRegistry() + .GetServiceById(berry::IPreferencesService::ID); + + m_Preferences = prefService->GetSystemPreferences()->Node(QmitkStdMultiWidgetEditor::EDITOR_ID); + + QObject::connect( m_Ui->m_ColorButton1, SIGNAL( clicked() ) + , this, SLOT( ColorChooserButtonClicked() ) ); + + QObject::connect( m_Ui->m_ColorButton2, SIGNAL( clicked() ) + , this, SLOT( ColorChooserButtonClicked() ) ); + + QObject::connect( m_Ui->m_ResetButton, SIGNAL( clicked() ) + , this, SLOT( ResetPreferencesAndGUI() ) ); + + QObject::connect( m_Ui->m_RenderingMode, SIGNAL(activated(int) ) + , this, SLOT( ChangeRenderingMode(int) ) ); + + QObject::connect( m_Ui->m_RenderWindowDecorationColor, SIGNAL( clicked() ) + , this, SLOT( ColorChooserButtonClicked() ) ); + + QObject::connect( m_Ui->m_RenderWindowChooser, SIGNAL(activated(int) ) + , this, SLOT( OnWidgetComboBoxChanged(int) ) ); + QObject::connect( m_Ui->m_RenderWindowDecorationText, SIGNAL(textChanged(QString) ) + , this, SLOT( AnnotationTextChanged(QString) ) ); this->Update(); } QWidget* QmitkStdMultiWidgetEditorPreferencePage::GetQtControl() const { - return m_MainControl; + return m_Control; +} + +void QmitkStdMultiWidgetEditorPreferencePage::Init(berry::IWorkbench::Pointer) +{ +} + +void QmitkStdMultiWidgetEditorPreferencePage::PerformCancel() +{ } bool QmitkStdMultiWidgetEditorPreferencePage::PerformOk() { - m_StdMultiWidgetEditorPreferencesNode->Put("first background color style sheet", m_FirstColorStyleSheet.toStdString()); - m_StdMultiWidgetEditorPreferencesNode->Put("second background color style sheet", m_SecondColorStyleSheet.toStdString()); - m_StdMultiWidgetEditorPreferencesNode->PutByteArray("first background color", m_FirstColor); - m_StdMultiWidgetEditorPreferencesNode->PutByteArray("second background color", m_SecondColor); - m_StdMultiWidgetEditorPreferencesNode->PutBool("Use constrained zooming and padding" - , m_EnableFlexibleZooming->isChecked()); - m_StdMultiWidgetEditorPreferencesNode->PutBool("Show level/window widget", m_ShowLevelWindowWidget->isChecked()); - m_StdMultiWidgetEditorPreferencesNode->PutBool("PACS like mouse interaction", m_PACSLikeMouseMode->isChecked()); - m_StdMultiWidgetEditorPreferencesNode->PutInt("Rendering Mode", m_RenderingMode->currentIndex()); + m_Preferences->PutByteArray("widget1 corner annotation", m_WidgetAnnotation[0]); + m_Preferences->PutByteArray("widget2 corner annotation", m_WidgetAnnotation[1]); + m_Preferences->PutByteArray("widget3 corner annotation", m_WidgetAnnotation[2]); + m_Preferences->PutByteArray("widget4 corner annotation", m_WidgetAnnotation[3]); + + m_Preferences->PutByteArray("widget1 decoration color", m_WidgetDecorationColor[0]); + m_Preferences->PutByteArray("widget2 decoration color", m_WidgetDecorationColor[1]); + m_Preferences->PutByteArray("widget3 decoration color", m_WidgetDecorationColor[2]); + m_Preferences->PutByteArray("widget4 decoration color", m_WidgetDecorationColor[3]); + + m_Preferences->PutByteArray("widget1 first background color", m_WidgetBackgroundColor1[0]); + m_Preferences->PutByteArray("widget2 first background color", m_WidgetBackgroundColor1[1]); + m_Preferences->PutByteArray("widget3 first background color", m_WidgetBackgroundColor1[2]); + m_Preferences->PutByteArray("widget4 first background color", m_WidgetBackgroundColor1[3]); + m_Preferences->PutByteArray("widget1 second background color", m_WidgetBackgroundColor2[0]); + m_Preferences->PutByteArray("widget2 second background color", m_WidgetBackgroundColor2[1]); + m_Preferences->PutByteArray("widget3 second background color", m_WidgetBackgroundColor2[2]); + m_Preferences->PutByteArray("widget4 second background color", m_WidgetBackgroundColor2[3]); + m_Preferences->PutInt("crosshair gap size", m_Ui->m_CrosshairGapSize->value()); + + m_Preferences->PutBool("Use constrained zooming and padding" + , m_Ui->m_EnableFlexibleZooming->isChecked()); + m_Preferences->PutBool("Show level/window widget", m_Ui->m_ShowLevelWindowWidget->isChecked()); + m_Preferences->PutBool("PACS like mouse interaction", m_Ui->m_PACSLikeMouseMode->isChecked()); + m_Preferences->PutInt("Rendering Mode", m_Ui->m_RenderingMode->currentIndex()); return true; } -void QmitkStdMultiWidgetEditorPreferencePage::PerformCancel() +void QmitkStdMultiWidgetEditorPreferencePage::Update() { + //gradient background colors + m_WidgetBackgroundColor1[0] = m_Preferences->GetByteArray("widget1 first background color", "#000000"); + m_WidgetBackgroundColor2[0] = m_Preferences->GetByteArray("widget1 second background color", "#000000"); + m_WidgetBackgroundColor1[1] = m_Preferences->GetByteArray("widget2 first background color", "#000000"); + m_WidgetBackgroundColor2[1] = m_Preferences->GetByteArray("widget2 second background color", "#000000"); + m_WidgetBackgroundColor1[2] = m_Preferences->GetByteArray("widget3 first background color", "#000000"); + m_WidgetBackgroundColor2[2] = m_Preferences->GetByteArray("widget3 second background color", "#000000"); + m_WidgetBackgroundColor1[3] = m_Preferences->GetByteArray("widget4 first background color", "#191919"); + m_WidgetBackgroundColor2[3] = m_Preferences->GetByteArray("widget4 second background color", "#7F7F7F"); + + //decoration colors + m_WidgetDecorationColor[0] = m_Preferences->GetByteArray("widget1 decoration color", "#FF0000"); + m_WidgetDecorationColor[1] = m_Preferences->GetByteArray("widget2 decoration color", "#00FF00"); + m_WidgetDecorationColor[2] = m_Preferences->GetByteArray("widget3 decoration color", "#0000FF"); + m_WidgetDecorationColor[3] = m_Preferences->GetByteArray("widget4 decoration color", "#FFFF00"); + + //annotation text + m_WidgetAnnotation[0] = m_Preferences->GetByteArray("widget1 corner annotation", "Axial"); + m_WidgetAnnotation[1] = m_Preferences->GetByteArray("widget2 corner annotation", "Sagittal"); + m_WidgetAnnotation[2] = m_Preferences->GetByteArray("widget3 corner annotation", "Coronal"); + m_WidgetAnnotation[3] = m_Preferences->GetByteArray("widget4 corner annotation", "3D"); + + + //Ui stuff + int index = m_Ui->m_RenderWindowChooser->currentIndex(); + QColor firstBackgroundColor = this->HexStringToQtColor(m_WidgetBackgroundColor1[index]); + QColor secondBackgroundColor = this->HexStringToQtColor(m_WidgetBackgroundColor2[index]); + QColor widgetColor = this->HexStringToQtColor(m_WidgetDecorationColor[index]); + + this->SetStyleSheetToColorChooserButton(firstBackgroundColor, m_Ui->m_ColorButton1); + this->SetStyleSheetToColorChooserButton(secondBackgroundColor, m_Ui->m_ColorButton2); + this->SetStyleSheetToColorChooserButton(widgetColor, m_Ui->m_RenderWindowDecorationColor); + + m_Ui->m_RenderWindowDecorationText->setText(QString::fromStdString(m_WidgetAnnotation[index])); + + m_Ui->m_EnableFlexibleZooming->setChecked(m_Preferences->GetBool("Use constrained zooming and padding", true)); + m_Ui->m_ShowLevelWindowWidget->setChecked(m_Preferences->GetBool("Show level/window widget", true)); + m_Ui->m_PACSLikeMouseMode->setChecked(m_Preferences->GetBool("PACS like mouse interaction", false)); + int mode= m_Preferences->GetInt("Rendering Mode",0); + m_Ui->m_RenderingMode->setCurrentIndex(mode); + m_Ui->m_CrosshairGapSize->setValue(m_Preferences->GetInt("crosshair gap size", 32)); } -void QmitkStdMultiWidgetEditorPreferencePage::Update() +QColor QmitkStdMultiWidgetEditorPreferencePage::HexStringToQtColor(std::string colorInHex) { - m_EnableFlexibleZooming->setChecked(m_StdMultiWidgetEditorPreferencesNode->GetBool("Use constrained zooming and padding", true)); - m_ShowLevelWindowWidget->setChecked(m_StdMultiWidgetEditorPreferencesNode->GetBool("Show level/window widget", true)); - m_PACSLikeMouseMode->setChecked(m_StdMultiWidgetEditorPreferencesNode->GetBool("PACS like mouse interaction", false)); - m_FirstColorStyleSheet = QString::fromStdString(m_StdMultiWidgetEditorPreferencesNode->Get("first background color style sheet", "")); - m_SecondColorStyleSheet = QString::fromStdString(m_StdMultiWidgetEditorPreferencesNode->Get("second background color style sheet", "")); - m_FirstColor = m_StdMultiWidgetEditorPreferencesNode->GetByteArray("first background color", ""); - m_SecondColor = m_StdMultiWidgetEditorPreferencesNode->GetByteArray("second background color", ""); - int index=m_StdMultiWidgetEditorPreferencesNode->GetInt("Rendering Mode",0); - m_RenderingMode->setCurrentIndex(index); - - if (m_FirstColorStyleSheet=="") + QColor returncol; + returncol.setNamedColor(QString::fromStdString(colorInHex)); + return returncol; +} + +void QmitkStdMultiWidgetEditorPreferencePage::ColorChooserButtonClicked() +{ + unsigned int widgetIndex = m_Ui->m_RenderWindowChooser->currentIndex(); + if(widgetIndex > 3) { - m_FirstColorStyleSheet = "background-color:rgb(25,25,25)"; + MITK_ERROR << "Selected index for unknown."; + return; } - if (m_SecondColorStyleSheet=="") + QObject *senderObj = sender(); // This will give Sender button + //find out last used color and set it + QColor initialColor; + if( senderObj->objectName() == m_Ui->m_ColorButton1->objectName()) + { + initialColor = HexStringToQtColor(m_WidgetBackgroundColor1[widgetIndex]); + }else if( senderObj->objectName() == m_Ui->m_ColorButton2->objectName()) { - m_SecondColorStyleSheet = "background-color:rgb(127,127,127)"; + initialColor = HexStringToQtColor(m_WidgetBackgroundColor2[widgetIndex]); + }else if( senderObj->objectName() == m_Ui->m_RenderWindowDecorationColor->objectName()) + { + initialColor = HexStringToQtColor(m_WidgetDecorationColor[widgetIndex]); } - if (m_FirstColor=="") + + //get the new color + QColor newcolor = QColorDialog::getColor(initialColor); + if(!newcolor.isValid()) { - m_FirstColor = "#191919"; + newcolor = initialColor; } - if (m_SecondColor=="") + this->SetStyleSheetToColorChooserButton(newcolor, static_cast(senderObj)); + + //convert it to std string and apply it + if( senderObj->objectName() == m_Ui->m_ColorButton1->objectName()) + { + m_WidgetBackgroundColor1[widgetIndex] = newcolor.name().toStdString(); + }else if( senderObj->objectName() == m_Ui->m_ColorButton2->objectName()) + { + m_WidgetBackgroundColor2[widgetIndex] = newcolor.name().toStdString(); + }else if( senderObj->objectName() == m_Ui->m_RenderWindowDecorationColor->objectName()) { - m_SecondColor = "#7F7F7F"; + m_WidgetDecorationColor[widgetIndex] = newcolor.name().toStdString(); } - m_ColorButton1->setStyleSheet(m_FirstColorStyleSheet); - m_ColorButton2->setStyleSheet(m_SecondColorStyleSheet); } -void QmitkStdMultiWidgetEditorPreferencePage::FirstColorChanged() +void QmitkStdMultiWidgetEditorPreferencePage::SetStyleSheetToColorChooserButton(QColor backgroundcolor, + QPushButton* button) { - QColor color = QColorDialog::getColor(); - m_ColorButton1->setAutoFillBackground(true); + button->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; - styleSheet.append(QString::number(color.red())); + styleSheet.append(QString::number(backgroundcolor.red())); styleSheet.append(","); - styleSheet.append(QString::number(color.green())); + styleSheet.append(QString::number(backgroundcolor.green())); styleSheet.append(","); - styleSheet.append(QString::number(color.blue())); + styleSheet.append(QString::number(backgroundcolor.blue())); styleSheet.append(")"); - m_ColorButton1->setStyleSheet(styleSheet); - - m_FirstColorStyleSheet = styleSheet; - QStringList firstColor; - firstColor << color.name(); - m_FirstColor = firstColor.replaceInStrings(";","\\;").join(";").toStdString(); - } + button->setStyleSheet(styleSheet); +} -void QmitkStdMultiWidgetEditorPreferencePage::SecondColorChanged() +void QmitkStdMultiWidgetEditorPreferencePage::AnnotationTextChanged(QString text) { - QColor color = QColorDialog::getColor(); - m_ColorButton2->setAutoFillBackground(true); - QString styleSheet = "background-color:rgb("; - - styleSheet.append(QString::number(color.red())); - styleSheet.append(","); - styleSheet.append(QString::number(color.green())); - styleSheet.append(","); - styleSheet.append(QString::number(color.blue())); - styleSheet.append(")"); - m_ColorButton2->setStyleSheet(styleSheet); + unsigned int widgetIndex = m_Ui->m_RenderWindowChooser->currentIndex(); + if( widgetIndex > 3) + { + MITK_INFO << "Selected index for unknown widget."; + return; + } + m_WidgetAnnotation[widgetIndex] = text.toStdString(); +} - m_SecondColorStyleSheet = styleSheet; - QStringList secondColor; - secondColor << color.name(); - m_SecondColor = secondColor.replaceInStrings(";","\\;").join(";").toStdString(); - } +void QmitkStdMultiWidgetEditorPreferencePage::ResetPreferencesAndGUI() +{ + m_Preferences->Clear(); + this->Update(); +} -void QmitkStdMultiWidgetEditorPreferencePage::ResetColors() +void QmitkStdMultiWidgetEditorPreferencePage::OnWidgetComboBoxChanged(int i) { - m_FirstColorStyleSheet = "background-color:rgb(25,25,25)"; - m_SecondColorStyleSheet = "background-color:rgb(127,127,127)"; - m_FirstColor = "#191919"; - m_SecondColor = "#7F7F7F"; - m_ColorButton1->setStyleSheet(m_FirstColorStyleSheet); - m_ColorButton2->setStyleSheet(m_SecondColorStyleSheet); + if( i > 3) + { + MITK_ERROR << "Selected unknown widget."; + return; + } + QColor widgetColor, gradientBackground1, gradientBackground2; + widgetColor = HexStringToQtColor(m_WidgetDecorationColor[i]); + gradientBackground1 = HexStringToQtColor(m_WidgetBackgroundColor1[i]); + gradientBackground2 = HexStringToQtColor(m_WidgetBackgroundColor2[i]); + this->SetStyleSheetToColorChooserButton(widgetColor, m_Ui->m_RenderWindowDecorationColor); + this->SetStyleSheetToColorChooserButton(gradientBackground1, m_Ui->m_ColorButton1); + this->SetStyleSheetToColorChooserButton(gradientBackground2, m_Ui->m_ColorButton2); + m_Ui->m_RenderWindowDecorationText->setText(QString::fromStdString(m_WidgetAnnotation[i])); } void QmitkStdMultiWidgetEditorPreferencePage::ChangeRenderingMode(int i) { if( i == 0 ) { m_CurrentRenderingMode = "Standard"; } else if( i == 1 ) { - m_CurrentRenderingMode = "Multisampling"; + m_CurrentRenderingMode = "Multisampling"; } else if( i == 2 ) { m_CurrentRenderingMode = "DepthPeeling"; } } - -void QmitkStdMultiWidgetEditorPreferencePage::UseGradientBackgroundSelected() -{ -} - -void QmitkStdMultiWidgetEditorPreferencePage::ColorActionChanged() -{ -} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h index c17ed09b31..c9185d0a8d 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h @@ -1,91 +1,127 @@ /*=================================================================== 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 QMITKSTDMULTIWIDGETEDITORPREFERENCEPAGE_H_ -#define QMITKSTDMULTIWIDGETEDITORPREFERENCEPAGE_H_ +#ifndef QmitkStdMultiWidgetEditorPreferencePage_h +#define QmitkStdMultiWidgetEditorPreferencePage_h -#include "berryIQtPreferencePage.h" #include +#include +#include +#include +#include -class QWidget; -class QCheckBox; -class QPushButton; -class QWidgetAction; -class QComboBox; +namespace Ui +{ +class QmitkStdMultiWidgetEditorPreferencePage; +} -struct QmitkStdMultiWidgetEditorPreferencePage : public QObject, public berry::IQtPreferencePage +class QmitkStdMultiWidgetEditorPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkStdMultiWidgetEditorPreferencePage(); + ~QmitkStdMultiWidgetEditorPreferencePage(); - void Init(berry::IWorkbench::Pointer workbench); - - void CreateQtControl(QWidget* widget); - + void CreateQtControl(QWidget* parent); QWidget* GetQtControl() const; - - /// - /// \see IPreferencePage::PerformOk() - /// - virtual bool PerformOk(); - - /// - /// \see IPreferencePage::PerformCancel() - /// - virtual void PerformCancel(); - - /// - /// \see IPreferencePage::Update() - /// - virtual void Update(); + void Init(berry::IWorkbench::Pointer); + void PerformCancel(); + bool PerformOk(); + void Update(); public slots: - void FirstColorChanged(); - - void SecondColorChanged(); - - void UseGradientBackgroundSelected(); - - void ColorActionChanged(); + /** + * @brief ResetColors set default colors and refresh the GUI. + */ + void ResetPreferencesAndGUI(); + + /** + * @brief ChangeRenderingMode slot to chose the rendering mode via QComboBox. + * @param i index of the box. + */ + void ChangeRenderingMode(int i); - void ResetColors(); + /** + * @brief OnWidgetComboBoxChanged slot called when the QComboBox to chose the widget was modified. + * @param i index of the combobox to select the widget (1-4). + */ + void OnWidgetComboBoxChanged(int i); - void ChangeRenderingMode(int i); + /** + * @brief AnnotationTextChanged called when QLineEdit for the annotation was changed. + * @param text The new text. + */ + void AnnotationTextChanged(QString text); protected: - QWidget* m_MainControl; - QCheckBox* m_EnableFlexibleZooming; - QCheckBox* m_ShowLevelWindowWidget; - QCheckBox* m_UseGradientBackground; - QCheckBox* m_ChangeBackgroundColors; - QCheckBox* m_PACSLikeMouseMode; - QComboBox* m_RenderingMode; - + /** + * @brief m_CurrentRenderingMode String for the rendering mode. + */ std::string m_CurrentRenderingMode; - QPushButton* m_ColorButton1; - QPushButton* m_ColorButton2; - std::string m_FirstColor; - std::string m_SecondColor; - QString m_FirstColorStyleSheet; - QString m_SecondColorStyleSheet; - berry::IPreferences::Pointer m_StdMultiWidgetEditorPreferencesNode; + /** + * @brief m_WidgetBackgroundColor1 the background colors. + * + * If two different colors are chosen, a gradient background appears. + */ + std::string m_WidgetBackgroundColor1[4]; + std::string m_WidgetBackgroundColor2[4]; + + /** + * @brief m_WidgetDecorationColor the decoration color. + * + * The rectangle prop, the crosshair, the 3D planes and the corner annotation use this. + */ + std::string m_WidgetDecorationColor[4]; + + /** + * @brief m_Widget1Annotation the text of the corner annotation. + */ + std::string m_WidgetAnnotation[4]; + + /** + * @brief m_Preferences the berry preferences. + */ + berry::IPreferences::Pointer m_Preferences; + + /** + * @brief SetStyleSheetToColorChooserButton colorize a button. + * @param backgroundcolor color for the button. + * @param button the button. + */ + void SetStyleSheetToColorChooserButton(QColor backgroundcolor, QPushButton* button); + + /** + * @brief StringToColor convert a hexadecimal std::string to QColor. + * @param colorInHex string in the form of "#123456" where each digit is a hex value (0-F). + * @return color in Qt format. + */ + QColor HexStringToQtColor(std::string colorInHex); + +protected slots: + + /** + * @brief ColorChooserButtonClicked slot called when a button to choose color was clicked. + */ + void ColorChooserButtonClicked(); + +private: + QScopedPointer m_Ui; + QWidget* m_Control; }; - -#endif /* QMITKDATAMANAGERPREFERENCEPAGE_H_ */ \ No newline at end of file +#endif //QmitkStdMultiWidgetEditorPreferencePage_h diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui new file mode 100644 index 0000000000..37b5fc9585 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui @@ -0,0 +1,225 @@ + + + QmitkStdMultiWidgetEditorPreferencePage + + + + 0 + 0 + 518 + 431 + + + + External Programs + + + + + + + stdmulti.widget1 + + + + + stdmulti.widget2 + + + + + stdmulti.widget3 + + + + + stdmulti.widget4 + + + + + + + + <html><head/><body><p>If two colors are set, a gradient background is generated.</p></body></html> + + + Background color + + + + + + + Reset preferences + + + + + + + + Standard Rendering + + + + + Enable Multisampling (Antialiasing) + + + + + Enable Depth Peeling + + + + + + + + * Changes require restart of MITK. + Depth Peeling is only supported by Windows. + For other OS, use Standard Rendering and enable + the property 'Depth Sorting' in the property list of the surface data node. + + + + + + + 32 + + + + + + + Qt::Horizontal + + + + + + + The small text on the button left of each renderwindow. + + + Corner annotation + + + + + + + <html><head/><body><p>The gap in the middle of the crosshair in pixels.</p></body></html> + + + Crosshair gap size + + + + + + + <html><head/><body><p>The color is used for the following decorations (of each renderwindow):</p><p>Rectangle border</p><p>Corner annotation</p><p>Crosshair</p><p>Plane geometry helper objects (3D Planes)</p><p>Image navigator borders</p><p><br/></p></body></html> + + + Decoration color + + + + + + + + + + + + + + <html><head/><body><p>Choose the renderwindow from the multi widget.</p></body></html> + + + Render windows + + + + + + + Qt::LeftToRight + + + Show level/window widget + + + true + + + + + + + Qt::LeftToRight + + + Use PACS like mouse interaction (select left mouse button action) + + + false + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + Rendering Mode* + + + + + + + + + + + + + + + + + <html><head/><body><p>If activated, zooming and panning is limited to a certain space arround each image.</p></body></html> + + + Qt::LeftToRight + + + Use constraint zooming and padding + + + true + + + + + + + +