diff --git a/Applications/Tests/QtFreeRender/QtFreeRender.cpp b/Applications/Tests/QtFreeRender/QtFreeRender.cpp index c57e196637..cd3d82fa12 100644 --- a/Applications/Tests/QtFreeRender/QtFreeRender.cpp +++ b/Applications/Tests/QtFreeRender/QtFreeRender.cpp @@ -1,396 +1,396 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 21985 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkRenderWindow.h" #include #include #include #include #include #include #include #include "mitkProperties.h" #include "mitkGeometry2DDataMapper2D.h" #include "mitkGlobalInteraction.h" #include "mitkDisplayInteractor.h" #include "mitkPositionEvent.h" #include "mitkStateEvent.h" #include "mitkLine.h" #include "mitkInteractionConst.h" #include "mitkVtkLayerController.h" #include "mitkPositionTracker.h" #include "mitkDisplayVectorInteractor.h" #include "mitkSlicesRotator.h" #include "mitkSlicesSwiveller.h" #include "mitkRenderWindowFrame.h" #include "mitkGradientBackground.h" #include "mitkCoordinateSupplier.h" #include "mitkDataStorage.h" #include "vtkTextProperty.h" #include "vtkCornerAnnotation.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkAnnotatedCubeActor.h" #include "vtkOrientationMarkerWidget.h" #include "vtkProperty.h" //##Documentation //## @brief Example of a NON QT DEPENDENT MITK RENDERING APPLICATION. mitk::DisplayVectorInteractor::Pointer m_MoveAndZoomInteractor; mitk::CoordinateSupplier::Pointer m_LastLeftClickPositionSupplier; mitk::GradientBackground::Pointer m_GradientBackground4; mitk::RenderWindowFrame::Pointer m_RectangleRendering1; mitk::RenderWindowFrame::Pointer m_RectangleRendering2; mitk::RenderWindowFrame::Pointer m_RectangleRendering3; mitk::RenderWindowFrame::Pointer m_RectangleRendering4; mitk::SliceNavigationController::Pointer m_TimeNavigationController; mitk::DataStorage::Pointer m_DataStorage; mitk::DataNode::Pointer m_PlaneNode1; mitk::DataNode::Pointer m_PlaneNode2; mitk::DataNode::Pointer m_PlaneNode3; mitk::DataNode::Pointer m_Node; mitk::RenderWindow::Pointer mitkWidget1; mitk::RenderWindow::Pointer mitkWidget2; mitk::RenderWindow::Pointer mitkWidget3; mitk::RenderWindow::Pointer mitkWidget4; void InitializeWindows() { // Set default view directions for SNCs mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Transversal ); mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Sagittal ); mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Frontal ); mitkWidget4->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Original ); //initialize m_TimeNavigationController: send time via sliceNavigationControllers m_TimeNavigationController = mitk::SliceNavigationController::New("dummy"); 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->GetVtkRenderWindow())); // Set TimeNavigationController to RenderingManager // (which uses it internally for views initialization!) mitk::RenderingManager::GetInstance()->SetTimeNavigationController( m_TimeNavigationController ); //reverse connection between sliceNavigationControllers and m_TimeNavigationController mitkWidget1->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController.GetPointer(), false); mitkWidget2->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController.GetPointer(), false); mitkWidget3->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController.GetPointer(), false); mitkWidget4->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController.GetPointer(), false); // Let NavigationControllers listen to GlobalInteraction mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); gi->AddListener( m_TimeNavigationController ); m_LastLeftClickPositionSupplier = mitk::CoordinateSupplier::New("navigation", NULL); mitk::GlobalInteraction::GetInstance()->AddListener( m_LastLeftClickPositionSupplier ); m_GradientBackground4 = mitk::GradientBackground::New(); m_GradientBackground4->SetRenderWindow( mitkWidget4->GetVtkRenderWindow() ); m_GradientBackground4->SetGradientColors(0.1,0.1,0.1,0.5,0.5,0.5); m_GradientBackground4->Enable(); m_RectangleRendering1 = mitk::RenderWindowFrame::New(); m_RectangleRendering1->SetRenderWindow( mitkWidget1->GetVtkRenderWindow() ); m_RectangleRendering1->Enable(1.0,0.0,0.0); m_RectangleRendering2 = mitk::RenderWindowFrame::New(); m_RectangleRendering2->SetRenderWindow( mitkWidget2->GetVtkRenderWindow() ); m_RectangleRendering2->Enable(0.0,1.0,0.0); m_RectangleRendering3 = mitk::RenderWindowFrame::New(); m_RectangleRendering3->SetRenderWindow( mitkWidget3->GetVtkRenderWindow() ); m_RectangleRendering3->Enable(0.0,0.0,1.0); m_RectangleRendering4 = mitk::RenderWindowFrame::New(); m_RectangleRendering4->SetRenderWindow( mitkWidget4->GetVtkRenderWindow() ); m_RectangleRendering4->Enable(1.0,1.0,0.0); } void 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::Geometry2DDataMapper2D::Pointer mapper; mitk::IntProperty::Pointer layer = mitk::IntProperty::New(1000); // ... of widget 1 m_PlaneNode1 = (mitk::BaseRenderer::GetInstance(mitkWidget1->GetVtkRenderWindow()))->GetCurrentWorldGeometry2DNode(); m_PlaneNode1->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetVtkRenderWindow())); m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode1->SetProperty("name", mitk::StringProperty::New("widget1Plane")); m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true)); m_PlaneNode1->SetProperty("layer",layer); m_PlaneNode1->SetColor(1.0,0.0,0.0); mapper = mitk::Geometry2DDataMapper2D::New(); m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 2 m_PlaneNode2 =( mitk::BaseRenderer::GetInstance(mitkWidget2->GetVtkRenderWindow()))->GetCurrentWorldGeometry2DNode(); m_PlaneNode2->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetVtkRenderWindow())); m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode2->SetProperty("name", mitk::StringProperty::New("widget2Plane")); m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true)); m_PlaneNode2->SetProperty("layer",layer); m_PlaneNode2->SetColor(0.0,1.0,0.0); mapper = mitk::Geometry2DDataMapper2D::New(); m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 3 m_PlaneNode3 = (mitk::BaseRenderer::GetInstance(mitkWidget3->GetVtkRenderWindow()))->GetCurrentWorldGeometry2DNode(); m_PlaneNode3->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetVtkRenderWindow())); m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode3->SetProperty("name", mitk::StringProperty::New("widget3Plane")); m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true)); m_PlaneNode3->SetProperty("layer",layer); m_PlaneNode3->SetColor(0.0,0.0,1.0); mapper = mitk::Geometry2DDataMapper2D::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)); //AddPlanesToDataStorage if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.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); } } } void Fit() { vtkRenderer * vtkrenderer; mitk::BaseRenderer::GetInstance(mitkWidget1->GetVtkRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget2->GetVtkRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget3->GetVtkRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget4->GetVtkRenderWindow())->GetDisplayGeometry()->Fit(); int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget1->GetVtkRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget2->GetVtkRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget3->GetVtkRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetVtkRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } int main(int argc, char* argv[]) { if(argc<2) { fprintf( stderr, "Usage: %s [filename1] [filename2] ...\n\n", "" ); return 1; } // Create a DataStorage m_DataStorage = mitk::StandaloneDataStorage::New(); //************************************************************************* // Part II: Create some data by reading files //************************************************************************* int i; for(i=1; iSetFileName(filename); nodeReader->Update(); // Since the DataNodeFactory directly creates a node, // use the datastorage to add the read node mitk::DataNode::Pointer node = nodeReader->GetOutput(); m_DataStorage->Add(node); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull()) { // Set the property "volumerendering" to the Boolean value "true" node->SetProperty("volumerendering", mitk::BoolProperty::New(false)); node->SetProperty("name", mitk::StringProperty::New("testimage")); node->SetProperty("layer",mitk::IntProperty::New(1)); } } catch(...) { fprintf( stderr, "Could not open file %s \n\n", filename ); exit(2); } } //************************************************************************* // Part V: Create window and pass the tree to it //************************************************************************* // Global Interaction initialize mitk::GlobalInteraction::GetInstance()->Initialize("global"); // instantiate display interactor m_MoveAndZoomInteractor = mitk::DisplayVectorInteractor::New( "moveNzoom", new mitk::DisplayInteractor() ); mitk::GlobalInteraction::GetInstance()->AddListener(m_MoveAndZoomInteractor); // Create renderwindows mitkWidget1 = mitk::RenderWindow::New(); mitkWidget2 = mitk::RenderWindow::New(); mitkWidget3 = mitk::RenderWindow::New(); mitkWidget4 = mitk::RenderWindow::New(); // Tell the renderwindow which (part of) the datastorage to render mitkWidget1->GetRenderer()->SetDataStorage(m_DataStorage); mitkWidget2->GetRenderer()->SetDataStorage(m_DataStorage); mitkWidget3->GetRenderer()->SetDataStorage(m_DataStorage); mitkWidget4->GetRenderer()->SetDataStorage(m_DataStorage); // Let NavigationControllers listen to GlobalInteraction mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); gi->AddListener( mitkWidget1->GetSliceNavigationController() ); gi->AddListener( mitkWidget2->GetSliceNavigationController() ); gi->AddListener( mitkWidget3->GetSliceNavigationController() ); gi->AddListener( mitkWidget4->GetSliceNavigationController() ); // Use it as a 2D View mitkWidget1->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D); mitkWidget2->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D); mitkWidget3->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D); mitkWidget4->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); mitkWidget1->SetSize(400, 400); mitkWidget2->GetVtkRenderWindow()->SetPosition(mitkWidget1->GetVtkRenderWindow()->GetPosition()[0]+420, mitkWidget1->GetVtkRenderWindow()->GetPosition()[1]); mitkWidget2->SetSize(400, 400); mitkWidget3->GetVtkRenderWindow()->SetPosition(mitkWidget1->GetVtkRenderWindow()->GetPosition()[0], mitkWidget1->GetVtkRenderWindow()->GetPosition()[1]+450); mitkWidget3->SetSize(400, 400); mitkWidget4->GetVtkRenderWindow()->SetPosition(mitkWidget1->GetVtkRenderWindow()->GetPosition()[0]+420, mitkWidget1->GetVtkRenderWindow()->GetPosition()[1]+450); mitkWidget4->SetSize(400, 400); InitializeWindows(); AddDisplayPlaneSubTree(); Fit(); // Initialize the RenderWindows mitk::TimeSlicedGeometry::Pointer geo = m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews( geo ); m_DataStorage->Print( std::cout ); - mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // reinit the mitkVTKEventProvider; // this is only necessary once after calling // ForceImmediateUpdateAll() for the first time mitkWidget1->ReinitEventProvider(); mitkWidget2->ReinitEventProvider(); mitkWidget3->ReinitEventProvider(); mitkWidget1->GetVtkRenderWindow()->Render(); mitkWidget2->GetVtkRenderWindow()->Render(); mitkWidget3->GetVtkRenderWindow()->Render(); mitkWidget4->GetVtkRenderWindow()->Render(); mitkWidget4->GetVtkRenderWindowInteractor()->Start(); return 0; } diff --git a/Applications/mitkDiffusion/target_libraries.cmake b/Applications/mitkDiffusion/target_libraries.cmake index 93c17932c5..cb40c2bcbc 100644 --- a/Applications/mitkDiffusion/target_libraries.cmake +++ b/Applications/mitkDiffusion/target_libraries.cmake @@ -1,10 +1,21 @@ # A list of plug-in targets which should be automatically enabled # (or be available in external projects) for this application. set(target_libraries org_blueberry_compat org_blueberry_ui_qt org_blueberry_ui_qt_help + org_mitk_diffusionimaging + org_mitk_planarfigure org_mitk_gui_qt_diffusionimagingapp + org_mitk_gui_qt_common_legacy + org_mitk_gui_qt_ext + org_mitk_gui_qt_datamanager + org_mitk_gui_qt_segmentation + org_mitk_gui_qt_volumevisualization + org_mitk_gui_qt_diffusionimaging + org_mitk_gui_qt_imagenavigator + org_mitk_gui_qt_moviemaker + org_mitk_gui_qt_measurementtoolbox ) diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake index 2e2aa3409f..66f047558c 100644 --- a/CMakeExternals/CTK.cmake +++ b/CMakeExternals/CTK.cmake @@ -1,67 +1,67 @@ #----------------------------------------------------------------------------- # CTK #----------------------------------------------------------------------------- if(MITK_USE_CTK) # Sanity checks if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR}) message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj CTK) set(proj_DEPENDENCIES ) set(CTK_DEPENDS ${proj}) if(NOT DEFINED CTK_DIR) - set(revision_tag de466419) + set(revision_tag 6925794b) #if(${proj}_REVISION_TAG) # set(revision_tag ${${proj}_REVISION_TAG}) #endif() set(ctk_optional_cache_args ) if(MITK_USE_Python) list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=ON ) endif() foreach(type RUNTIME ARCHIVE LIBRARY) if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) endif() endforeach() ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz - URL_MD5 29d075daa07dbc5618158e4f81d5f431 + URL_MD5 43430cee2dfec2519cbe33cbfebc3eaf UPDATE_COMMAND "" INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${ctk_optional_cache_args} -DDESIRED_QT_VERSION:STRING=4 -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DCTK_LIB_PluginFramework:BOOL=ON -DCTK_LIB_DICOM/Widgets:BOOL=ON -DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON -DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON -DCTK_USE_GIT_PROTOCOL:BOOL=OFF -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz DEPENDS ${proj_DEPENDENCIES} ) set(CTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif() diff --git a/Core/Code/Controllers/mitkRenderingManager.cpp b/Core/Code/Controllers/mitkRenderingManager.cpp index b1dbb86967..c99918f440 100644 --- a/Core/Code/Controllers/mitkRenderingManager.cpp +++ b/Core/Code/Controllers/mitkRenderingManager.cpp @@ -1,1027 +1,1037 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkRenderingManager.h" #include "mitkRenderingManagerFactory.h" #include "mitkBaseRenderer.h" #include "mitkGlobalInteraction.h" #include #include #include "mitkVector.h" #include #include #include #include namespace mitk { RenderingManager::Pointer RenderingManager::s_Instance = 0; RenderingManagerFactory *RenderingManager::s_RenderingManagerFactory = 0; RenderingManager ::RenderingManager() : m_UpdatePending( false ), m_MaxLOD( 1 ), m_LODIncreaseBlocked( false ), m_LODAbortMechanismEnabled( false ), m_ClippingPlaneEnabled( false ), m_TimeNavigationController( NULL ), m_DataStorage( NULL ), m_ConstrainedPaddingZooming ( true ) { m_ShadingEnabled.assign( 3, false ); m_ShadingValues.assign( 4, 0.0 ); m_GlobalInteraction = mitk::GlobalInteraction::GetInstance(); InitializePropertyList(); } RenderingManager ::~RenderingManager() { // Decrease reference counts of all registered vtkRenderWindows for // proper destruction RenderWindowVector::iterator it; for ( it = m_AllRenderWindows.begin(); it != m_AllRenderWindows.end(); ++it ) { (*it)->UnRegister( NULL ); RenderWindowCallbacksList::iterator callbacks_it = this->m_RenderWindowCallbacksList.find(*it); (*it)->RemoveObserver(callbacks_it->second.commands[0u]); (*it)->RemoveObserver(callbacks_it->second.commands[1u]); (*it)->RemoveObserver(callbacks_it->second.commands[2u]); } } void RenderingManager ::SetFactory( RenderingManagerFactory *factory ) { s_RenderingManagerFactory = factory; } const RenderingManagerFactory * RenderingManager ::GetFactory() { return s_RenderingManagerFactory; } bool RenderingManager ::HasFactory() { if ( RenderingManager::s_RenderingManagerFactory ) { return true; } else { return false; } } RenderingManager::Pointer RenderingManager ::New() { const RenderingManagerFactory* factory = GetFactory(); if(factory == NULL) return NULL; return factory->CreateRenderingManager(); } RenderingManager * RenderingManager ::GetInstance() { if ( !RenderingManager::s_Instance ) { if ( s_RenderingManagerFactory ) { s_Instance = s_RenderingManagerFactory->CreateRenderingManager(); } } return s_Instance; } bool RenderingManager ::IsInstantiated() { if ( RenderingManager::s_Instance ) return true; else return false; } void RenderingManager ::AddRenderWindow( vtkRenderWindow *renderWindow ) { if ( renderWindow && (m_RenderWindowList.find( renderWindow ) == m_RenderWindowList.end()) ) { m_RenderWindowList[renderWindow] = RENDERING_INACTIVE; m_AllRenderWindows.push_back( renderWindow ); if ( m_DataStorage.IsNotNull() ) mitk::BaseRenderer::GetInstance( renderWindow )->SetDataStorage( m_DataStorage.GetPointer() ); // Register vtkRenderWindow instance renderWindow->Register( NULL ); typedef itk::MemberCommand< RenderingManager > MemberCommandType; // Add callbacks for rendering abort mechanism //BaseRenderer *renderer = BaseRenderer::GetInstance( renderWindow ); vtkCallbackCommand *startCallbackCommand = vtkCallbackCommand::New(); startCallbackCommand->SetCallback( RenderingManager::RenderingStartCallback ); renderWindow->AddObserver( vtkCommand::StartEvent, startCallbackCommand ); vtkCallbackCommand *progressCallbackCommand = vtkCallbackCommand::New(); progressCallbackCommand->SetCallback( RenderingManager::RenderingProgressCallback ); renderWindow->AddObserver( vtkCommand::AbortCheckEvent, progressCallbackCommand ); vtkCallbackCommand *endCallbackCommand = vtkCallbackCommand::New(); endCallbackCommand->SetCallback( RenderingManager::RenderingEndCallback ); renderWindow->AddObserver( vtkCommand::EndEvent, endCallbackCommand ); RenderWindowCallbacks callbacks; callbacks.commands[0u] = startCallbackCommand; callbacks.commands[1u] = progressCallbackCommand; callbacks.commands[2u] = endCallbackCommand; this->m_RenderWindowCallbacksList[renderWindow] = callbacks; //Delete vtk variables correctly startCallbackCommand->Delete(); progressCallbackCommand->Delete(); endCallbackCommand->Delete(); } } void RenderingManager ::RemoveRenderWindow( vtkRenderWindow *renderWindow ) { if (m_RenderWindowList.erase( renderWindow )) { RenderWindowCallbacksList::iterator callbacks_it = this->m_RenderWindowCallbacksList.find(renderWindow); renderWindow->RemoveObserver(callbacks_it->second.commands[0u]); renderWindow->RemoveObserver(callbacks_it->second.commands[1u]); renderWindow->RemoveObserver(callbacks_it->second.commands[2u]); this->m_RenderWindowCallbacksList.erase(callbacks_it); RenderWindowVector::iterator rw_it = std::find( m_AllRenderWindows.begin(), m_AllRenderWindows.end(), renderWindow ); // Decrease reference count for proper destruction (*rw_it)->UnRegister(NULL); m_AllRenderWindows.erase( rw_it ); } } const RenderingManager::RenderWindowVector& RenderingManager ::GetAllRegisteredRenderWindows() { return m_AllRenderWindows; } void RenderingManager ::RequestUpdate( vtkRenderWindow *renderWindow ) { - // do nothing if the renderWindow is not managed by this instance - RenderWindowVector::iterator iter = std::find( m_AllRenderWindows.begin(), m_AllRenderWindows.end(), renderWindow ); - if ( iter == m_AllRenderWindows.end() ) + // If the renderWindow is not valid, we do not want to inadvertantly create + // an entry in the m_RenderWindowList map. It is possible if the user is + // regularly calling AddRenderer and RemoveRenderer for a rendering update + // to come into this method with a renderWindow pointer that is valid in the + // sense that the window does exist within the application, but that + // renderWindow has been temporarily removed from this RenderingManager for + // performance reasons. + if (m_RenderWindowList.find( renderWindow ) == m_RenderWindowList.end()) { return; } m_RenderWindowList[renderWindow] = RENDERING_REQUESTED; if ( !m_UpdatePending ) { m_UpdatePending = true; this->GenerateRenderingRequestEvent(); } } void RenderingManager ::ForceImmediateUpdate( vtkRenderWindow *renderWindow ) { - // do nothing if the renderWindow is not managed by this instance - RenderWindowVector::iterator iter = std::find( m_AllRenderWindows.begin(), m_AllRenderWindows.end(), renderWindow ); - if ( iter == m_AllRenderWindows.end() ) + // If the renderWindow is not valid, we do not want to inadvertantly create + // an entry in the m_RenderWindowList map. It is possible if the user is + // regularly calling AddRenderer and RemoveRenderer for a rendering update + // to come into this method with a renderWindow pointer that is valid in the + // sense that the window does exist within the application, but that + // renderWindow has been temporarily removed from this RenderingManager for + // performance reasons. + if (m_RenderWindowList.find( renderWindow ) == m_RenderWindowList.end()) { return; } // Erase potentially pending requests for this window m_RenderWindowList[renderWindow] = RENDERING_INACTIVE; m_UpdatePending = false; // Immediately repaint this window (implementation platform specific) // If the size is 0 it crahses int *size = renderWindow->GetSize(); if ( 0 != size[0] && 0 != size[1] ) { //prepare the camera etc. before rendering //Note: this is a very important step which should be called before the VTK render! //If you modify the camera anywhere else or after the render call, the scene cannot be seen. mitk::VtkPropRenderer *vPR = dynamic_cast(mitk::BaseRenderer::GetInstance( renderWindow )); if(vPR) vPR->PrepareRender(); // Execute rendering renderWindow->Render(); } } void RenderingManager ::RequestUpdateAll( RequestType type ) { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { int id = BaseRenderer::GetInstance(it->first)->GetMapperID(); if ( (type == REQUEST_UPDATE_ALL) || ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1)) || ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)) ) { this->RequestUpdate( it->first ); } } } void RenderingManager ::ForceImmediateUpdateAll( RequestType type ) { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { int id = BaseRenderer::GetInstance(it->first)->GetMapperID(); if ( (type == REQUEST_UPDATE_ALL) || ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1)) || ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)) ) { // Immediately repaint this window (implementation platform specific) // If the size is 0, it crashes this->ForceImmediateUpdate(it->first); // int *size = it->first->GetSize(); // if ( 0 != size[0] && 0 != size[1] ) // { // //prepare the camera before rendering // //Note: this is a very important step which should be called before the VTK render! // //If you modify the camera anywhere else or after the render call, the scene cannot be seen. // mitk::VtkPropRenderer *vPR = // dynamic_cast(mitk::BaseRenderer::GetInstance( it->first )); // if(vPR) // vPR->PrepareRender(); // // Execute rendering // it->first->Render(); // } // it->second = RENDERING_INACTIVE; } } //m_UpdatePending = false; } //bool RenderingManager::InitializeViews( const mitk::DataStorage * storage, const DataNode* node = NULL, RequestType type, bool preserveRoughOrientationInWorldSpace ) //{ // mitk::Geometry3D::Pointer geometry; // if ( storage != NULL ) // { // geometry = storage->ComputeVisibleBoundingGeometry3D(node, "visible", NULL, "includeInBoundingBox" ); // // if ( geometry.IsNotNull() ) // { // // let's see if we have data with a limited live-span ... // mitk::TimeBounds timebounds = geometry->GetTimeBounds(); // if ( timebounds[1] < mitk::ScalarTypeNumericTraits::max() ) // { // mitk::ScalarType duration = timebounds[1]-timebounds[0]; // // mitk::TimeSlicedGeometry::Pointer timegeometry = // mitk::TimeSlicedGeometry::New(); // timegeometry->InitializeEvenlyTimed( // geometry, (unsigned int) duration ); // timegeometry->SetTimeBounds( timebounds ); // // timebounds[1] = timebounds[0] + 1.0; // geometry->SetTimeBounds( timebounds ); // // geometry = timegeometry; // } // } // } // // // Use geometry for initialization // return this->InitializeViews( geometry.GetPointer(), type ); //} bool RenderingManager ::InitializeViews( const Geometry3D * dataGeometry, RequestType type, bool preserveRoughOrientationInWorldSpace ) { MITK_DEBUG << "initializing views"; bool boundingBoxInitialized = false; Geometry3D::ConstPointer geometry = dataGeometry; if (dataGeometry && preserveRoughOrientationInWorldSpace) { // clone the input geometry Geometry3D::Pointer modifiedGeometry = dynamic_cast( dataGeometry->Clone().GetPointer() ); assert(modifiedGeometry.IsNotNull()); // construct an affine transform from it AffineGeometryFrame3D::TransformType::Pointer transform = AffineGeometryFrame3D::TransformType::New(); assert( modifiedGeometry->GetIndexToWorldTransform() ); transform->SetMatrix( modifiedGeometry->GetIndexToWorldTransform()->GetMatrix() ); transform->SetOffset( modifiedGeometry->GetIndexToWorldTransform()->GetOffset() ); // get transform matrix AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& oldMatrix = const_cast< AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& > ( transform->GetMatrix().GetVnlMatrix() ); AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType newMatrix(oldMatrix); // get offset and bound Vector3D offset = modifiedGeometry->GetIndexToWorldTransform()->GetOffset(); Geometry3D::BoundsArrayType oldBounds = modifiedGeometry->GetBounds(); Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds(); // get rid of rotation other than pi/2 degree for ( unsigned int i = 0; i < 3; ++i ) { // i-th column of the direction matrix Vector3D currentVector; currentVector[0] = oldMatrix(0,i); currentVector[1] = oldMatrix(1,i); currentVector[2] = oldMatrix(2,i); // matchingRow will store the row that holds the biggest // value in the column unsigned int matchingRow = 0; // maximum value in the column float max = std::numeric_limits::min(); // sign of the maximum value (-1 or 1) int sign = 1; // iterate through the column vector for (unsigned int dim = 0; dim < 3; ++dim) { if ( fabs(currentVector[dim]) > max ) { matchingRow = dim; max = fabs(currentVector[dim]); if(currentVector[dim]<0) sign = -1; else sign = 1; } } // in case we found a negative maximum, // we negate the column and adjust the offset // (in order to run through the dimension in the opposite direction) if(sign == -1) { currentVector *= sign; offset += modifiedGeometry->GetAxisVector(i); } // matchingRow is now used as column index to place currentVector // correctly in the new matrix vnl_vector newMatrixColumn(3); newMatrixColumn[0] = currentVector[0]; newMatrixColumn[1] = currentVector[1]; newMatrixColumn[2] = currentVector[2]; newMatrix.set_column( matchingRow, newMatrixColumn ); // if a column is moved, we also have to adjust the bounding // box accordingly, this is done here newBounds[2*matchingRow ] = oldBounds[2*i ]; newBounds[2*matchingRow+1] = oldBounds[2*i+1]; } // set the newly calculated bounds array modifiedGeometry->SetBounds(newBounds); // set new offset and direction matrix AffineGeometryFrame3D::TransformType::MatrixType newMatrixITK( newMatrix ); transform->SetMatrix( newMatrixITK ); transform->SetOffset( offset ); modifiedGeometry->SetIndexToWorldTransform( transform ); geometry = modifiedGeometry; } int warningLevel = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); if ( (geometry.IsNotNull() ) && (const_cast< mitk::BoundingBox * >( geometry->GetBoundingBox())->GetDiagonalLength2() > mitk::eps) ) { boundingBoxInitialized = true; } if (geometry.IsNotNull() ) {// make sure bounding box has an extent bigger than zero in any direction // clone the input geometry Geometry3D::Pointer modifiedGeometry = dynamic_cast( dataGeometry->Clone().GetPointer() ); assert(modifiedGeometry.IsNotNull()); Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds(); for( unsigned int dimension = 0; ( 2 * dimension ) < newBounds.Size() ; dimension++ ) { //check for equality but for an epsilon if( Equal( newBounds[ 2 * dimension ], newBounds[ 2 * dimension + 1 ] ) ) { newBounds[ 2 * dimension + 1 ] += 1; } } // set the newly calculated bounds array modifiedGeometry->SetBounds(newBounds); geometry = modifiedGeometry; } RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( it->first ); baseRenderer->GetDisplayGeometry()->SetConstrainZoomingAndPanning(m_ConstrainedPaddingZooming); int id = baseRenderer->GetMapperID(); if ( ((type == REQUEST_UPDATE_ALL) || ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1)) || ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2))) ) { this->InternalViewInitialization( baseRenderer, geometry, boundingBoxInitialized, id ); } } if ( m_TimeNavigationController != NULL ) { if ( boundingBoxInitialized ) { m_TimeNavigationController->SetInputWorldGeometry( geometry ); } m_TimeNavigationController->Update(); } this->RequestUpdateAll( type ); vtkObject::SetGlobalWarningDisplay( warningLevel ); // Inform listeners that views have been initialized this->InvokeEvent( mitk::RenderingManagerViewsInitializedEvent() ); return boundingBoxInitialized; } bool RenderingManager ::InitializeViews( RequestType type ) { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( it->first ); int id = baseRenderer->GetMapperID(); if ( (type == REQUEST_UPDATE_ALL) || ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1)) || ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)) ) { mitk::SliceNavigationController *nc = baseRenderer->GetSliceNavigationController(); // Re-initialize view direction nc->SetViewDirectionToDefault(); // Update the SNC nc->Update(); } } this->RequestUpdateAll( type ); return true; } //bool RenderingManager::InitializeView( vtkRenderWindow * renderWindow, const DataStorage* ds, const DataNode node = NULL, bool initializeGlobalTimeSNC ) //{ // mitk::Geometry3D::Pointer geometry; // if ( ds != NULL ) // { // geometry = ds->ComputeVisibleBoundingGeometry3D(node, NULL, "includeInBoundingBox" ); // // if ( geometry.IsNotNull() ) // { // // let's see if we have data with a limited live-span ... // mitk::TimeBounds timebounds = geometry->GetTimeBounds(); // if ( timebounds[1] < mitk::ScalarTypeNumericTraits::max() ) // { // mitk::ScalarType duration = timebounds[1]-timebounds[0]; // // mitk::TimeSlicedGeometry::Pointer timegeometry = // mitk::TimeSlicedGeometry::New(); // timegeometry->InitializeEvenlyTimed( // geometry, (unsigned int) duration ); // timegeometry->SetTimeBounds( timebounds ); // // timebounds[1] = timebounds[0] + 1.0; // geometry->SetTimeBounds( timebounds ); // // geometry = timegeometry; // } // } // } // // // Use geometry for initialization // return this->InitializeView( renderWindow, // geometry.GetPointer(), initializeGlobalTimeSNC ); //} bool RenderingManager::InitializeView( vtkRenderWindow * renderWindow, const Geometry3D * geometry, bool initializeGlobalTimeSNC ) { bool boundingBoxInitialized = false; int warningLevel = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); if ( (geometry != NULL ) && (const_cast< mitk::BoundingBox * >( geometry->GetBoundingBox())->GetDiagonalLength2() > mitk::eps) ) { boundingBoxInitialized = true; } mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( renderWindow ); int id = baseRenderer->GetMapperID(); this->InternalViewInitialization( baseRenderer, geometry, boundingBoxInitialized, id ); if ( m_TimeNavigationController != NULL ) { if ( boundingBoxInitialized && initializeGlobalTimeSNC ) { m_TimeNavigationController->SetInputWorldGeometry( geometry ); } m_TimeNavigationController->Update(); } this->RequestUpdate( renderWindow ); vtkObject::SetGlobalWarningDisplay( warningLevel ); return boundingBoxInitialized; } bool RenderingManager::InitializeView( vtkRenderWindow * renderWindow ) { mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( renderWindow ); mitk::SliceNavigationController *nc = baseRenderer->GetSliceNavigationController(); // Re-initialize view direction nc->SetViewDirectionToDefault(); // Update the SNC nc->Update(); this->RequestUpdate( renderWindow ); return true; } void RenderingManager::InternalViewInitialization(mitk::BaseRenderer *baseRenderer, const mitk::Geometry3D *geometry, bool boundingBoxInitialized, int mapperID ) { mitk::SliceNavigationController *nc = baseRenderer->GetSliceNavigationController(); // Re-initialize view direction nc->SetViewDirectionToDefault(); if ( boundingBoxInitialized ) { // Set geometry for NC nc->SetInputWorldGeometry( geometry ); nc->Update(); if ( mapperID == 1 ) { // For 2D SNCs, steppers are set so that the cross is centered // in the image nc->GetSlice()->SetPos( nc->GetSlice()->GetSteps() / 2 ); } // Fit the render window DisplayGeometry baseRenderer->GetDisplayGeometry()->Fit(); baseRenderer->GetCameraController()->SetViewToAnterior(); } else { nc->Update(); } } void RenderingManager::SetTimeNavigationController( SliceNavigationController *nc ) { m_TimeNavigationController = nc; } const SliceNavigationController* RenderingManager::GetTimeNavigationController() const { return m_TimeNavigationController; } SliceNavigationController* RenderingManager::GetTimeNavigationController() { return m_TimeNavigationController; } void RenderingManager::ExecutePendingRequests() { m_UpdatePending = false; // Satisfy all pending update requests RenderWindowList::iterator it; int i = 0; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it, ++i ) { if ( it->second == RENDERING_REQUESTED ) { this->ForceImmediateUpdate( it->first ); } } } void RenderingManager::RenderingStartCallback( vtkObject *caller, unsigned long , void *, void * ) { vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller ); mitk::RenderingManager* renman = mitk::BaseRenderer::GetInstance(renderWindow)->GetRenderingManager(); RenderWindowList &renderWindowList = renman->m_RenderWindowList; if ( renderWindow ) { renderWindowList[renderWindow] = RENDERING_INPROGRESS; } renman->m_UpdatePending = false; } void RenderingManager ::RenderingProgressCallback( vtkObject *caller, unsigned long , void *, void * ) { vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller ); mitk::RenderingManager* renman = mitk::BaseRenderer::GetInstance(renderWindow)->GetRenderingManager(); if ( renman->m_LODAbortMechanismEnabled ) { vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller ); if ( renderWindow ) { BaseRenderer *renderer = BaseRenderer::GetInstance( renderWindow ); if ( renderer && (renderer->GetNumberOfVisibleLODEnabledMappers() > 0) ) { renman->DoMonitorRendering(); } } } } void RenderingManager ::RenderingEndCallback( vtkObject *caller, unsigned long , void *, void * ) { vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller ); mitk::RenderingManager* renman = mitk::BaseRenderer::GetInstance(renderWindow)->GetRenderingManager(); RenderWindowList &renderWindowList = renman->m_RenderWindowList; RendererIntMap &nextLODMap = renman->m_NextLODMap; if ( renderWindow ) { BaseRenderer *renderer = BaseRenderer::GetInstance( renderWindow ); if ( renderer ) { renderWindowList[renderer->GetRenderWindow()] = RENDERING_INACTIVE; // Level-of-Detail handling if ( renderer->GetNumberOfVisibleLODEnabledMappers() > 0 ) { if(nextLODMap[renderer]==0) renman->StartOrResetTimer(); else nextLODMap[renderer] = 0; } } } } bool RenderingManager ::IsRendering() const { RenderWindowList::const_iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { if ( it->second == RENDERING_INPROGRESS ) { return true; } } return false; } void RenderingManager ::AbortRendering() { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { if ( it->second == RENDERING_INPROGRESS ) { it->first->SetAbortRender( true ); m_RenderingAbortedMap[BaseRenderer::GetInstance(it->first)] = true; } } } int RenderingManager ::GetNextLOD( BaseRenderer *renderer ) { if ( renderer != NULL ) { return m_NextLODMap[renderer]; } else { return 0; } } void RenderingManager ::ExecutePendingHighResRenderingRequest() { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { BaseRenderer *renderer = BaseRenderer::GetInstance( it->first ); if(renderer->GetNumberOfVisibleLODEnabledMappers()>0) { if(m_NextLODMap[renderer]==0) { m_NextLODMap[renderer]=1; RequestUpdate( it->first ); } } } } void RenderingManager ::SetMaximumLOD( unsigned int max ) { m_MaxLOD = max; } //enable/disable shading void RenderingManager ::SetShading(bool state, unsigned int lod) { if(lod>m_MaxLOD) { itkWarningMacro(<<"LOD out of range requested: " << lod << " maxLOD: " << m_MaxLOD); return; } m_ShadingEnabled[lod] = state; } bool RenderingManager ::GetShading(unsigned int lod) { if(lod>m_MaxLOD) { itkWarningMacro(<<"LOD out of range requested: " << lod << " maxLOD: " << m_MaxLOD); return false; } return m_ShadingEnabled[lod]; } //enable/disable the clipping plane void RenderingManager ::SetClippingPlaneStatus(bool status) { m_ClippingPlaneEnabled = status; } bool RenderingManager ::GetClippingPlaneStatus() { return m_ClippingPlaneEnabled; } void RenderingManager ::SetShadingValues(float ambient, float diffuse, float specular, float specpower) { m_ShadingValues[0] = ambient; m_ShadingValues[1] = diffuse; m_ShadingValues[2] = specular; m_ShadingValues[3] = specpower; } RenderingManager::FloatVector & RenderingManager ::GetShadingValues() { return m_ShadingValues; } void RenderingManager::SetDepthPeelingEnabled( bool enabled ) { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( it->first ); baseRenderer->SetDepthPeelingEnabled(enabled); } } void RenderingManager::SetMaxNumberOfPeels( int maxNumber ) { RenderWindowList::iterator it; for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it ) { mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( it->first ); baseRenderer->SetMaxNumberOfPeels(maxNumber); } } void RenderingManager::InitializePropertyList() { if (m_PropertyList.IsNull()) { m_PropertyList = PropertyList::New(); } this->SetProperty("coupled-zoom", BoolProperty::New(false)); this->SetProperty("coupled-plane-rotation", BoolProperty::New(false)); this->SetProperty("MIP-slice-rendering", BoolProperty::New(false)); } PropertyList::Pointer RenderingManager::GetPropertyList() const { return m_PropertyList; } BaseProperty* RenderingManager::GetProperty(const char *propertyKey) const { return m_PropertyList->GetProperty(propertyKey); } void RenderingManager::SetProperty(const char *propertyKey, BaseProperty* propertyValue) { m_PropertyList->SetProperty(propertyKey, propertyValue); } void RenderingManager::SetDataStorage( DataStorage* storage ) { if ( storage != NULL ) { m_DataStorage = storage; RenderingManager::RenderWindowVector::iterator iter; for ( iter = m_AllRenderWindows.begin(); iterSetDataStorage( m_DataStorage.GetPointer() ); } } } mitk::DataStorage* RenderingManager::GetDataStorage() { return m_DataStorage; } void RenderingManager::SetGlobalInteraction( mitk::GlobalInteraction* globalInteraction ) { if ( globalInteraction != NULL ) { m_GlobalInteraction = globalInteraction; } } mitk::GlobalInteraction* RenderingManager::GetGlobalInteraction() { return m_GlobalInteraction; } // Create and register generic RenderingManagerFactory. TestingRenderingManagerFactory renderingManagerFactory; } // namespace diff --git a/Core/Code/Controllers/mitkRenderingManager.h b/Core/Code/Controllers/mitkRenderingManager.h index 53b5489a9a..c6f6906834 100644 --- a/Core/Code/Controllers/mitkRenderingManager.h +++ b/Core/Code/Controllers/mitkRenderingManager.h @@ -1,419 +1,420 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKRENDERINGMANAGER_H_HEADER_INCLUDED_C135A197 #define MITKRENDERINGMANAGER_H_HEADER_INCLUDED_C135A197 #include #include #include #include #include #include "mitkPropertyList.h" #include "mitkProperties.h" class vtkRenderWindow; class vtkObject; namespace mitk { class RenderingManager; class RenderingManagerFactory; class Geometry3D; class SliceNavigationController; class BaseRenderer; class DataStorage; class GlobalInteraction; /** * \brief Manager for coordinating the rendering process. * * RenderingManager is a central instance retrieving and executing * RenderWindow update requests. Its main purpose is to coordinate * distributed requests which cannot be aware of each other - lacking the * knowledge of whether they are really necessary or not. For example, two * objects might determine that a specific RenderWindow needs to be updated. * This would result in one unnecessary update, if both executed the update * on their own. * * The RenderingManager addresses this by letting each such object * request an update, and waiting for other objects to possibly * issue the same request. The actual update will then only be executed at a * well-defined point in the main event loop (this may be each time after * event processing is done). * * Convinience methods for updating all RenderWindows which have been * registered with the RenderingManager exist. If theses methods are not * used, it is not required to register (add) RenderWindows prior to using * the RenderingManager. * * The methods #ForceImmediateUpdate() and #ForceImmediateUpdateAll() can * be used to force the RenderWindow update execution without any delay, * bypassing the request functionality. * * The interface of RenderingManager is platform independent. Platform * specific subclasses have to be implemented, though, to supply an * appropriate event issueing for controlling the update execution process. * See method documentation for a description of how this can be done. * * \sa TestingRenderingManager An "empty" RenderingManager implementation which * can be used in tests etc. * */ class MITK_CORE_EXPORT RenderingManager : public itk::Object { public: mitkClassMacro(RenderingManager,itk::Object); typedef std::vector< vtkRenderWindow* > RenderWindowVector; typedef std::vector< float > FloatVector; typedef std::vector< bool > BoolVector; typedef itk::SmartPointer< DataStorage > DataStoragePointer; typedef itk::SmartPointer< GlobalInteraction > GlobalInteractionPointer; enum RequestType { REQUEST_UPDATE_ALL = 0, REQUEST_UPDATE_2DWINDOWS, REQUEST_UPDATE_3DWINDOWS }; static Pointer New(); /** Set the object factory which produces the desired platform specific * RenderingManager singleton instance. */ static void SetFactory( RenderingManagerFactory *factory ); /** Get the object factory which produces the platform specific * RenderingManager instances. */ static const RenderingManagerFactory *GetFactory(); /** Returns true if a factory has already been set. */ static bool HasFactory(); /** Get the RenderingManager singleton instance. */ static RenderingManager *GetInstance(); /** Returns true if the singleton instance does already exist. */ static bool IsInstantiated(); /** Adds a RenderWindow. This is required if the methods #RequestUpdateAll * or #ForceImmediateUpdate are to be used. */ void AddRenderWindow( vtkRenderWindow *renderWindow ); /** Removes a RenderWindow. */ void RemoveRenderWindow( vtkRenderWindow *renderWindow ); /** Get a list of all registered RenderWindows */ const RenderWindowVector &GetAllRegisteredRenderWindows(); /** Requests an update for the specified RenderWindow, to be executed as * soon as the main loop is ready for rendering. */ void RequestUpdate( vtkRenderWindow *renderWindow ); /** Immediately executes an update of the specified RenderWindow. */ void ForceImmediateUpdate( vtkRenderWindow *renderWindow ); /** Requests all currently registered RenderWindows to be updated. * If only 2D or 3D windows should be updated, this can be specified * via the parameter requestType. */ void RequestUpdateAll( RequestType type = REQUEST_UPDATE_ALL ); /** Immediately executes an update of all registered RenderWindows. * If only 2D or 3D windows should be updated, this can be specified * via the parameter requestType. */ void ForceImmediateUpdateAll( RequestType type = REQUEST_UPDATE_ALL ); /** Initializes the windows specified by requestType to the geometry of the * given DataStorage. */ //virtual bool InitializeViews( const DataStorage *storage, const DataNode* node = NULL, // RequestType type = REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace = false ); /** Initializes the windows specified by requestType to the given * geometry. PLATFORM SPECIFIC. TODO: HOW IS THIS PLATFORM SPECIFIC? */ virtual bool InitializeViews( const Geometry3D *geometry, RequestType type = REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace = false ); /** Initializes the windows to the default viewing direction * (geomtry information is NOT changed). PLATFORM SPECIFIC. */ virtual bool InitializeViews( RequestType type = REQUEST_UPDATE_ALL ); /** Initializes the specified window to the geometry of the given * DataNode. Set "initializeGlobalTimeSNC" to true in order to use this * geometry as global TimeSlicedGeometry. PLATFORM SPECIFIC. */ //virtual bool InitializeView( vtkRenderWindow *renderWindow, const DataStorage* ds, const DataNode* node = NULL, bool initializeGlobalTimeSNC = false ); /** Initializes the specified window to the given geometry. Set * "initializeGlobalTimeSNC" to true in order to use this geometry as * global TimeSlicedGeometry. PLATFORM SPECIFIC. */ virtual bool InitializeView( vtkRenderWindow *renderWindow, const Geometry3D *geometry, bool initializeGlobalTimeSNC = false); /** Initializes the specified window to the default viewing direction * (geomtry information is NOT changed). PLATFORM SPECIFIC. */ virtual bool InitializeView( vtkRenderWindow *renderWindow ); /** Sets the (global) SliceNavigationController responsible for * time-slicing. */ void SetTimeNavigationController( SliceNavigationController *nc ); /** Gets the (global) SliceNavigationController responsible for * time-slicing. */ const SliceNavigationController *GetTimeNavigationController() const; /** Gets the (global) SliceNavigationController responsible for * time-slicing. */ SliceNavigationController *GetTimeNavigationController(); virtual ~RenderingManager(); /** Executes all pending requests. This method has to be called by the * system whenever a RenderingManager induced request event occurs in * the system pipeline (see concrete RenderingManager implementations). */ virtual void ExecutePendingRequests(); bool IsRendering() const; void AbortRendering(); /** En-/Disable LOD increase globally. */ itkSetMacro( LODIncreaseBlocked, bool ); /** En-/Disable LOD increase globally. */ itkGetMacro( LODIncreaseBlocked, bool ); /** En-/Disable LOD increase globally. */ itkBooleanMacro( LODIncreaseBlocked ); /** En-/Disable LOD abort mechanism. */ itkSetMacro( LODAbortMechanismEnabled, bool ); /** En-/Disable LOD abort mechanism. */ itkGetMacro( LODAbortMechanismEnabled, bool ); /** En-/Disable LOD abort mechanism. */ itkBooleanMacro( LODAbortMechanismEnabled ); /** En-/Disable depth peeling for all renderers */ void SetDepthPeelingEnabled(bool enabled); /** Set maximum number of peels for all renderers */ void SetMaxNumberOfPeels(int maxNumber); /** Force a sub-class to start a timer for a pending hires-rendering request */ virtual void StartOrResetTimer() {}; /** To be called by a sub-class from a timer callback */ void ExecutePendingHighResRenderingRequest(); virtual void DoStartRendering() {}; virtual void DoMonitorRendering() {}; virtual void DoFinishAbortRendering() {}; int GetNextLOD( BaseRenderer* renderer ); /** Set current LOD (NULL means all renderers)*/ void SetMaximumLOD( unsigned int max ); void SetShading( bool state, unsigned int lod ); bool GetShading( unsigned int lod ); void SetClippingPlaneStatus( bool status ); bool GetClippingPlaneStatus(); void SetShadingValues( float ambient, float diffuse, float specular, float specpower ); FloatVector &GetShadingValues(); /** Returns a property list */ PropertyList::Pointer GetPropertyList() const; /** Returns a property from m_PropertyList */ BaseProperty* GetProperty(const char *propertyKey) const; /** Sets or adds (if not present) a property in m_PropertyList */ void SetProperty(const char *propertyKey, BaseProperty* propertyValue); /** * \brief Setter / Getter for internal DataStorage * * Sets / returns the mitk::DataStorage that is used internally. This instance holds all mitk::DataNodes that are * rendered by the registered BaseRenderers. * * If this DataStorage is changed at runtime by calling SetDataStorage(), * all currently registered BaseRenderers are automatically given the correct instance. * When a new BaseRenderer is added, it is automatically initialized with the currently active DataStorage. */ void SetDataStorage( mitk::DataStorage* storage ); /** * \brief Setter / Getter for internal DataStorage * * Sets / returns the mitk::DataStorage that is used internally. This instance holds all mitk::DataNodes that are * rendered by the registered BaseRenderers. * * If this DataStorage is changed at runtime by calling SetDataStorage(), * all currently registered BaseRenderers are automatically given the correct instance. * When a new BaseRenderer is added, it is automatically initialized with the currently active DataStorage. */ mitk::DataStorage* GetDataStorage(); /** * \brief Setter / Getter for internal GloabInteraction * * Sets / returns the instance of mitk::GlobalInteraction that is internally held. * It'S not actually used by this class but offers it to all registered BaseRenderers. * These need it for their own internal initialization of the FocusManager and the corresponding EventMappers. */ void SetGlobalInteraction( mitk::GlobalInteraction* globalInteraction ); /** * \brief Setter / Getter for internal GloabInteraction * * Sets / returns the instance of mitk::GlobalInteraction that is internally held. * It'S not actually used by this class but offers it to all registered BaseRenderers. * These need it for their own internal initialization of the FocusManager and the corresponding EventMappers. */ mitk::GlobalInteraction* GetGlobalInteraction(); itkSetMacro(ConstrainedPaddingZooming, bool); protected: enum { RENDERING_INACTIVE = 0, RENDERING_REQUESTED, RENDERING_INPROGRESS }; RenderingManager(); /** Abstract method for generating a system specific event for rendering * request. This method is called whenever an update is requested */ virtual void GenerateRenderingRequestEvent() = 0; virtual void InitializePropertyList(); bool m_UpdatePending; typedef std::map< BaseRenderer *, unsigned int > RendererIntMap; typedef std::map< BaseRenderer *, bool > RendererBoolMap; RendererBoolMap m_RenderingAbortedMap; RendererIntMap m_NextLODMap; unsigned int m_MaxLOD; bool m_LODIncreaseBlocked; bool m_LODAbortMechanismEnabled; BoolVector m_ShadingEnabled; bool m_ClippingPlaneEnabled; FloatVector m_ShadingValues; static void RenderingStartCallback( vtkObject *caller, unsigned long eid, void *clientdata, void *calldata ); static void RenderingProgressCallback( vtkObject *caller, unsigned long eid, void *clientdata, void *calldata ); static void RenderingEndCallback( vtkObject *caller, unsigned long eid, void *clientdata, void *calldata ); typedef std::map< vtkRenderWindow *, int > RenderWindowList; RenderWindowList m_RenderWindowList; RenderWindowVector m_AllRenderWindows; struct RenderWindowCallbacks { vtkCallbackCommand* commands[3u]; }; typedef std::map RenderWindowCallbacksList; RenderWindowCallbacksList m_RenderWindowCallbacksList; SliceNavigationController *m_TimeNavigationController; static RenderingManager::Pointer s_Instance; static RenderingManagerFactory *s_RenderingManagerFactory; PropertyList::Pointer m_PropertyList; DataStoragePointer m_DataStorage; GlobalInteractionPointer m_GlobalInteraction; bool m_ConstrainedPaddingZooming; private: void InternalViewInitialization( mitk::BaseRenderer *baseRenderer, const mitk::Geometry3D *geometry, bool boundingBoxInitialized, int mapperID ); }; #pragma GCC visibility push(default) itkEventMacro( RenderingManagerEvent, itk::AnyEvent ); itkEventMacro( RenderingManagerViewsInitializedEvent, RenderingManagerEvent ); #pragma GCC visibility pop /** * Generic RenderingManager implementation for "non-rendering-plattform", * e.g. for tests. Its factory (TestingRenderingManagerFactory) is * automatically on start-up and is used by default if not other * RenderingManagerFactory is instantiated explicitly thereafter. * (see mitkRenderingManager.cpp) */ class MITK_CORE_EXPORT TestingRenderingManager : public RenderingManager { public: mitkClassMacro(TestingRenderingManager,RenderingManager); itkNewMacro(Self); protected: virtual void GenerateRenderingRequestEvent() { + ForceImmediateUpdateAll(); }; }; } // namespace mitk #endif /* MITKRenderingManager_H_HEADER_INCLUDED_C135A197 */ diff --git a/Core/Code/Testing/mitkRenderingManagerTest.cpp b/Core/Code/Testing/mitkRenderingManagerTest.cpp index 40d4b77501..25bb53a45d 100644 --- a/Core/Code/Testing/mitkRenderingManagerTest.cpp +++ b/Core/Code/Testing/mitkRenderingManagerTest.cpp @@ -1,175 +1,222 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $ Version: $Revision: 7837 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkRenderingManager.h" #include "mitkProperties.h" #include "mitkGlobalInteraction.h" #include "mitkVtkPropRenderer.h" #include "mitkStandaloneDataStorage.h" #include "vtkRenderWindow.h" #include "mitkTestingMacros.h" #include #include "mitkSurface.h" //Propertylist Test /** * Simple example for a test for the class "RenderingManager". * * 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 mitkRenderingManagerTestClass { public: - +class mitkRenderingManagerTestClass +{ +public: static void TestPropertyList(mitk::RenderingManager::Pointer renderingManager) { mitk::PropertyList::Pointer propertyList = renderingManager->GetPropertyList(); MITK_TEST_CONDITION(renderingManager->GetPropertyList().IsNotNull(), "Testing if the constructor set the propertylist" ) //check if the default properties are set renderingManager->SetProperty("booltest", mitk::BoolProperty::New(true)); mitk::BoolProperty* prop = dynamic_cast( renderingManager->GetProperty("booltest") ); MITK_TEST_CONDITION(prop->GetValue(), "Testing if getting the bool property" ) MITK_TEST_CONDITION(propertyList == renderingManager->GetPropertyList(), "Testing if the propertylist has changed during the last tests" ) } static void TestSurfaceLoading( mitk::RenderingManager::Pointer renderingManager ) { // create and render two dimensional surface vtkCubeSource* plane = vtkCubeSource::New(); double planeBounds[] = { -1.0, 1.0, -1.0, 1.0, 0.0, 0.0 }; double cubeBounds[] = { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 }; plane->SetBounds( planeBounds ); plane->SetCenter( 0.0, 0.0, 0.0 ); vtkPolyData* polys = plane->GetOutput(); mitk::Surface::Pointer mitkPlane = mitk::Surface::New(); mitkPlane->SetVtkPolyData( polys ); plane->Delete(); mitk::DataNode::Pointer planeNode = mitk::DataNode::New(); planeNode->SetData( mitkPlane ); renderingManager->GetDataStorage()->Add( planeNode ); mitk::Geometry3D::Pointer planeGeometry = mitk::Geometry3D::New(); planeGeometry->SetFloatBounds( planeBounds ); MITK_TEST_CONDITION( renderingManager->InitializeViews( planeGeometry ), "Testing if two dimensional Geometry3Ds can be displayed" ) //clear rendering renderingManager->GetDataStorage()->Remove( planeNode ); renderingManager->InitializeViews(); // create and render three dimensional surface vtkCubeSource* cube = vtkCubeSource::New(); cube->SetBounds( cubeBounds ); cube->SetCenter( 0.0, 0.0, 0.0 ); vtkPolyData* polyCube = cube->GetOutput(); mitk::Surface::Pointer mitkCube = mitk::Surface::New(); mitkCube->SetVtkPolyData( polyCube ); cube->Delete(); mitk::DataNode::Pointer cubeNode = mitk::DataNode::New(); cubeNode->SetData( mitkCube ); renderingManager->GetDataStorage()->Add( cubeNode ); mitk::Geometry3D::Pointer cubeGeometry = mitk::Geometry3D::New(); cubeGeometry->SetFloatBounds( cubeBounds ); MITK_TEST_CONDITION( renderingManager->InitializeViews( cubeGeometry ), "Testing if three dimensional Geometry3Ds can be displayed" ) //clear rendering renderingManager->GetDataStorage()->Remove( cubeNode ); renderingManager->InitializeViews(); } +static void TestAddRemoveRenderWindow() +{ + mitk::RenderingManager::Pointer myRenderingManager = mitk::RenderingManager::New(); + + + //mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); + + //myRenderingManager->SetDataStorage(ds); + + { + vtkRenderWindow* vtkRenWin = vtkRenderWindow::New(); + + MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 0, "Render window list must be empty") + + // Add Render Window + myRenderingManager->AddRenderWindow(vtkRenWin); + + MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 1, "Render window list must contain one item") + + // Remove Render Window + myRenderingManager->RemoveRenderWindow(vtkRenWin); + + MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 0, "Render window list must be empty") + + // Test if the Render Window was removed properly. This should not do anything + MITK_TEST_OUTPUT(<< "Call RequestUpdate on removed render window") + myRenderingManager->RequestUpdate(vtkRenWin); + MITK_TEST_OUTPUT(<< "Call ForceImmediateUpdate on removed render window") + myRenderingManager->ForceImmediateUpdate(vtkRenWin); + + MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 0, "Render window list must be empty") + + // Delete vtk variable correctly + vtkRenWin->Delete(); + } + + // Check that the previous calls to RequestUpdate and ForceImmediateUpdate + // did not modify the internal vtkRenderWindow list. This should not crash. + MITK_TEST_OUTPUT(<< "Call RequestUpdateAll after deleting render window") + myRenderingManager->RequestUpdateAll(); + MITK_TEST_OUTPUT(<< "Call ForceImmediateUpdateAll after deleting render window") + myRenderingManager->ForceImmediateUpdateAll(); +} + }; //mitkDataNodeTestClass int mitkRenderingManagerTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("RenderingManager") + mitkRenderingManagerTestClass::TestAddRemoveRenderWindow(); + mitk::RenderingManager::Pointer globalRenderingManager = mitk::RenderingManager::GetInstance(); MITK_TEST_CONDITION_REQUIRED(globalRenderingManager.IsNotNull(),"Testing instantiation of global static instance") mitk::RenderingManager::Pointer myRenderingManager = mitk::RenderingManager::New(); MITK_TEST_CONDITION_REQUIRED(myRenderingManager.IsNotNull(),"Testing instantiation of second 'local' instance") MITK_TEST_CONDITION_REQUIRED(myRenderingManager != globalRenderingManager ,"Testing whether global instance equals new local instance (must not be!)") mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); mitk::StandaloneDataStorage::Pointer ds2 = mitk::StandaloneDataStorage::New(); mitk::GlobalInteraction::Pointer gi = mitk::GlobalInteraction::New(); gi->Initialize("global"); myRenderingManager->SetDataStorage(ds); myRenderingManager->SetGlobalInteraction(gi); vtkRenderWindow* vtkRenWin = vtkRenderWindow::New(); mitk::VtkPropRenderer::Pointer br = mitk::VtkPropRenderer::New("testingBR", vtkRenWin, myRenderingManager); mitk::BaseRenderer::AddInstance(vtkRenWin,br); myRenderingManager->AddRenderWindow(vtkRenWin); MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetDataStorage() == ds, "Testing the setter and getter for internal DataStorage") MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetGlobalInteraction() ==gi, "Testing the setter and getter for internal GlobalInteraction") MITK_TEST_CONDITION_REQUIRED(br->GetDataStorage() == ds,"Testing if internal DataStorage has been set correctly for registered BaseRenderer") myRenderingManager->SetDataStorage(ds2); MITK_TEST_CONDITION_REQUIRED(br->GetDataStorage() == ds2,"Testing if change of internal DataStorage has been forwarded correctly to registered BaseRenderer") mitkRenderingManagerTestClass::TestPropertyList(myRenderingManager); mitkRenderingManagerTestClass::TestSurfaceLoading( myRenderingManager ); // 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! //Remove Render Window myRenderingManager->RemoveRenderWindow(vtkRenWin); //Delete vtk variable correctly vtkRenWin->Delete(); // always end with this! MITK_TEST_END() } diff --git a/Core/Code/Testing/mitkRenderingTestHelper.cpp b/Core/Code/Testing/mitkRenderingTestHelper.cpp index bc95059cd6..d41f993c81 100644 --- a/Core/Code/Testing/mitkRenderingTestHelper.cpp +++ b/Core/Code/Testing/mitkRenderingTestHelper.cpp @@ -1,88 +1,88 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 17:34:48 +0200 (Wed, 31 Mar 2010) $ Version: $Revision: 21985 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkRenderingTestHelper.h" #include "mitkStandaloneDataStorage.h" #include #include #include #include #include #include #include #include #include mitkRenderingTestHelper::mitkRenderingTestHelper(int width, int height, mitk::DataStorage *ds) { // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); m_RenderWindow = mitk::RenderWindow::New(); m_RenderWindow->GetRenderer()->SetDataStorage(ds); m_RenderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D); this->GetVtkRenderWindow()->SetSize( width, height ); mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Transversal); mitk::TimeSlicedGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); //Level Window Property // ds->GetNode(mitk::NodePredicateDataType::New("Image"))->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(254.0, 1.0) ) ); mitk::RenderingManager::GetInstance()->InitializeViews( geo ); - mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(m_RenderWindow->GetVtkRenderWindow()); + mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->GetVtkRenderWindow()); //use this to actually show the iamge in a renderwindow // this->GetVtkRenderWindow()->Render(); // this->GetVtkRenderWindow()->GetInteractor()->Start(); } mitkRenderingTestHelper::~mitkRenderingTestHelper() { } vtkRenderer* mitkRenderingTestHelper::GetVtkRenderer() { return m_RenderWindow->GetRenderer()->GetVtkRenderer(); } vtkRenderWindow* mitkRenderingTestHelper::GetVtkRenderWindow() { return m_RenderWindow->GetVtkRenderWindow(); } //method to save a screenshot of the renderwindow (e.g. create a reference screenshot) void mitkRenderingTestHelper::SaveAsPNG(std::string fileName) { vtkSmartPointer renderer = this->GetVtkRenderer(); bool doubleBuffering( renderer->GetRenderWindow()->GetDoubleBuffer() ); renderer->GetRenderWindow()->DoubleBufferOff(); vtkSmartPointer magnifier = vtkSmartPointer::New(); magnifier->SetInput(renderer); magnifier->SetMagnification(1.0); vtkSmartPointer fileWriter = vtkSmartPointer::New(); fileWriter->SetInput(magnifier->GetOutput()); fileWriter->SetFileName(fileName.c_str()); fileWriter->Write(); renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering); } diff --git a/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.cpp b/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.cpp index 858495fcae..4db07950de 100644 --- a/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.cpp +++ b/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.cpp @@ -1,896 +1,886 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkAnalyticalDiffusionQballReconstructionImageFilter_cpp #define __itkAnalyticalDiffusionQballReconstructionImageFilter_cpp #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include #if BOOST_VERSION / 100000 > 0 #if BOOST_VERSION / 100 % 1000 > 34 #include #endif #endif #include "itkPointShell.h" namespace itk { #define QBALL_ANAL_RECON_PI M_PI template< class T, class TG, class TO, int L, int NODF> AnalyticalDiffusionQballReconstructionImageFilter ::AnalyticalDiffusionQballReconstructionImageFilter() : m_GradientDirectionContainer(NULL), m_NumberOfGradientDirections(0), m_NumberOfBaselineImages(1), m_Threshold(NumericTraits< ReferencePixelType >::NonpositiveMin()), m_BValue(1.0), m_Lambda(0.0), - m_DirectionsDuplicated(false) + m_DirectionsDuplicated(false), + m_Delta1(0.001), + m_Delta2(0.001) { // At least 1 inputs is necessary for a vector image. // For images added one at a time we need at least six this->SetNumberOfRequiredInputs( 1 ); } template< class TReferenceImagePixelType, class TGradientImagePixelType, class TOdfPixelType, int NOrderL, int NrOdfDirections> typename itk::AnalyticalDiffusionQballReconstructionImageFilter< TReferenceImagePixelType,TGradientImagePixelType,TOdfPixelType, NOrderL,NrOdfDirections>::OdfPixelType itk::AnalyticalDiffusionQballReconstructionImageFilter ::Normalize( OdfPixelType odf, typename NumericTraits::AccumulateType b0 ) { switch( m_NormalizationMethod ) { case QBAR_STANDARD: { TOdfPixelType sum = 0; for(int i=0; i0) odf /= sum; return odf; break; } case QBAR_B_ZERO_B_VALUE: { for(int i=0; i0) - odf /= sum; break; } case QBAR_NONNEG_SOLID_ANGLE: { break; } } return odf; } template< class TReferenceImagePixelType, class TGradientImagePixelType, class TOdfPixelType, int NOrderL, int NrOdfDirections> vnl_vector itk::AnalyticalDiffusionQballReconstructionImageFilter ::PreNormalize( vnl_vector vec, typename NumericTraits::AccumulateType b0 ) { switch( m_NormalizationMethod ) { case QBAR_STANDARD: { return vec; break; } case QBAR_B_ZERO_B_VALUE: { int n = vec.size(); for(int i=0; i= b0f) - vec[i] = b0f - 0.001; - vec[i] = log(-log(vec[i]/b0f)); + vec[i] = vec[i]/b0f; + + if (vec[i]<0) + vec[i] = m_Delta1; + else if (vec[i]=1) + vec[i] = 1-m_Delta2/2; + else if (vec[i]>=1-m_Delta2) + vec[i] = 1-m_Delta2/2-(1-vec[i])*(1-vec[i])/(2*m_Delta2); + + vec[i] = log(-log(vec[i])); } return vec; break; } } return vec; } template< class T, class TG, class TO, int L, int NODF> void AnalyticalDiffusionQballReconstructionImageFilter ::BeforeThreadedGenerateData() { // If we have more than 2 inputs, then each input, except the first is a // gradient image. The number of gradient images must match the number of // gradient directions. //const unsigned int numberOfInputs = this->GetNumberOfInputs(); // There need to be at least 6 gradient directions to be able to compute the // tensor basis if( m_NumberOfGradientDirections < 6 ) { itkExceptionMacro( << "At least 6 gradient directions are required" ); } // Input must be an itk::VectorImage. std::string gradientImageClassName( this->ProcessObject::GetInput(0)->GetNameOfClass()); if ( strcmp(gradientImageClassName.c_str(),"VectorImage") != 0 ) { itkExceptionMacro( << "There is only one Gradient image. I expect that to be a VectorImage. " << "But its of type: " << gradientImageClassName ); } this->ComputeReconstructionMatrix(); typename GradientImagesType::Pointer img = static_cast< GradientImagesType * >( this->ProcessObject::GetInput(0) ); m_BZeroImage = BZeroImageType::New(); m_BZeroImage->SetSpacing( img->GetSpacing() ); // Set the image spacing m_BZeroImage->SetOrigin( img->GetOrigin() ); // Set the image origin m_BZeroImage->SetDirection( img->GetDirection() ); // Set the image direction m_BZeroImage->SetLargestPossibleRegion( img->GetLargestPossibleRegion()); m_BZeroImage->SetBufferedRegion( img->GetLargestPossibleRegion() ); m_BZeroImage->Allocate(); m_ODFSumImage = BZeroImageType::New(); m_ODFSumImage->SetSpacing( img->GetSpacing() ); // Set the image spacing m_ODFSumImage->SetOrigin( img->GetOrigin() ); // Set the image origin m_ODFSumImage->SetDirection( img->GetDirection() ); // Set the image direction m_ODFSumImage->SetLargestPossibleRegion( img->GetLargestPossibleRegion()); m_ODFSumImage->SetBufferedRegion( img->GetLargestPossibleRegion() ); m_ODFSumImage->Allocate(); m_CoefficientImage = CoefficientImageType::New(); m_CoefficientImage->SetSpacing( img->GetSpacing() ); // Set the image spacing m_CoefficientImage->SetOrigin( img->GetOrigin() ); // Set the image origin m_CoefficientImage->SetDirection( img->GetDirection() ); // Set the image direction m_CoefficientImage->SetLargestPossibleRegion( img->GetLargestPossibleRegion()); m_CoefficientImage->SetBufferedRegion( img->GetLargestPossibleRegion() ); m_CoefficientImage->Allocate(); if(m_NormalizationMethod == QBAR_SOLID_ANGLE || m_NormalizationMethod == QBAR_NONNEG_SOLID_ANGLE) { m_Lambda = 0.0; } } template< class T, class TG, class TO, int L, int NODF> void AnalyticalDiffusionQballReconstructionImageFilter ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int ) { typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); ImageRegionIterator< OutputImageType > oit(outputImage, outputRegionForThread); oit.GoToBegin(); ImageRegionIterator< BZeroImageType > oit2(m_BZeroImage, outputRegionForThread); oit2.GoToBegin(); ImageRegionIterator< FloatImageType > oit3(m_ODFSumImage, outputRegionForThread); oit3.GoToBegin(); ImageRegionIterator< CoefficientImageType > oit4(m_CoefficientImage, outputRegionForThread); oit4.GoToBegin(); typedef ImageRegionConstIterator< GradientImagesType > GradientIteratorType; typedef typename GradientImagesType::PixelType GradientVectorType; typename GradientImagesType::Pointer gradientImagePointer = NULL; // Would have liked a dynamic_cast here, but seems SGI doesn't like it // The enum will ensure that an inappropriate cast is not done gradientImagePointer = static_cast< GradientImagesType * >( this->ProcessObject::GetInput(0) ); GradientIteratorType git(gradientImagePointer, outputRegionForThread ); git.GoToBegin(); // Compute the indicies of the baseline images and gradient images std::vector baselineind; // contains the indicies of // the baseline images std::vector gradientind; // contains the indicies of // the gradient images for(GradientDirectionContainerType::ConstIterator gdcit = this->m_GradientDirectionContainer->Begin(); gdcit != this->m_GradientDirectionContainer->End(); ++gdcit) { if(gdcit.Value().one_norm() <= 0.0) { baselineind.push_back(gdcit.Index()); } else { gradientind.push_back(gdcit.Index()); } } if( m_DirectionsDuplicated ) { int gradIndSize = gradientind.size(); for(int i=0; i::AccumulateType b0 = NumericTraits::Zero; // Average the baseline image pixels for(unsigned int i = 0; i < baselineind.size(); ++i) { b0 += b[baselineind[i]]; } b0 /= this->m_NumberOfBaselineImages; OdfPixelType odf(0.0); typename CoefficientImageType::PixelType coeffPixel(0.0); vnl_vector B(m_NumberOfGradientDirections); if( (b0 != 0) && (b0 >= m_Threshold) ) { for( unsigned int i = 0; i< m_NumberOfGradientDirections; i++ ) { B[i] = static_cast(b[gradientind[i]]); } B = PreNormalize(B, b0); if(m_NormalizationMethod == QBAR_SOLID_ANGLE) { vnl_vector coeffs(m_NumberCoefficients); coeffs = ( (*m_CoeffReconstructionMatrix) * B ); coeffs[0] += 1.0/(2.0*sqrt(QBALL_ANAL_RECON_PI)); odf = ( (*m_SphericalHarmonicBasisMatrix) * coeffs ).data_block(); coeffPixel = coeffs.data_block(); } else if(m_NormalizationMethod == QBAR_NONNEG_SOLID_ANGLE) { /** this would be the place to implement a non-negative * solver for quadratic programming problem: * min .5*|| Bc-s ||^2 subject to -CLPc <= 4*pi*ones * (refer to MICCAI 2009 Goh et al. "Estimating ODFs with PDF constraints") * .5*|| Bc-s ||^2 == .5*c'B'Bc - x'B's + .5*s's */ itkExceptionMacro( << "Nonnegative Solid Angle not yet implemented"); } else { odf = ( (*m_ReconstructionMatrix) * B ).data_block(); } odf = Normalize(odf, b0); } oit.Set( odf ); oit2.Set( b0 ); float sum = 0; for (int k=0; k void AnalyticalDiffusionQballReconstructionImageFilter ::tofile2(vnl_matrix *pA, std::string fname) { vnl_matrix A = (*pA); ofstream myfile; std::locale C("C"); std::locale originalLocale = myfile.getloc(); myfile.imbue(C); myfile.open (fname.c_str()); myfile << "A1=["; for(int i=0; i double AnalyticalDiffusionQballReconstructionImageFilter ::factorial(int number) { if(number <= 1) return 1; double result = 1.0; for(int i=1; i<=number; i++) result *= i; return result; } template< class T, class TG, class TO, int L, int NODF> void AnalyticalDiffusionQballReconstructionImageFilter ::Cart2Sph(double x, double y, double z, double *cart) { double phi, th, rad; rad = sqrt(x*x+y*y+z*z); th = atan2(z,sqrt(x*x+y*y)); phi = atan2(y,x); th = -th+QBALL_ANAL_RECON_PI/2; phi = -phi+QBALL_ANAL_RECON_PI; cart[0] = phi; cart[1] = th; cart[2] = rad; } template< class T, class TG, class TO, int L, int NODF> double AnalyticalDiffusionQballReconstructionImageFilter ::legendre0(int l) { if( l%2 != 0 ) { return 0; } else { double prod1 = 1.0; for(int i=1;i double AnalyticalDiffusionQballReconstructionImageFilter ::spherical_harmonic(int m,int l,double theta,double phi, bool complexPart) { if( theta < 0 || theta > QBALL_ANAL_RECON_PI ) { std::cout << "bad range" << std::endl; return 0; } if( phi < 0 || phi > 2*QBALL_ANAL_RECON_PI ) { std::cout << "bad range" << std::endl; return 0; } double pml = 0; double fac1 = factorial(l+m); double fac2 = factorial(l-m); if( m<0 ) { #if BOOST_VERSION / 100000 > 0 #if BOOST_VERSION / 100 % 1000 > 34 pml = ::boost::math::legendre_p(l, -m, cos(theta)); #else std::cout << "ERROR: Boost 1.35 minimum required" << std::endl; #endif #else std::cout << "ERROR: Boost 1.35 minimum required" << std::endl; #endif double mypow = pow(-1.0,-m); double myfac = (fac1/fac2); pml *= mypow*myfac; } else { #if BOOST_VERSION / 100000 > 0 #if BOOST_VERSION / 100 % 1000 > 34 pml = ::boost::math::legendre_p(l, m, cos(theta)); #endif #endif } //std::cout << "legendre(" << l << "," << m << "," << cos(theta) << ") = " << pml << std::endl; double retval = sqrt(((2.0*(double)l+1.0)/(4.0*QBALL_ANAL_RECON_PI))*(fac2/fac1)) * pml; if( !complexPart ) { retval *= cos(m*phi); } else { retval *= sin(m*phi); } //std::cout << retval << std::endl; return retval; } template< class T, class TG, class TO, int L, int NODF> double AnalyticalDiffusionQballReconstructionImageFilter ::Yj(int m, int k, double theta, double phi) { if( -k <= m && m < 0 ) { return sqrt(2.0) * spherical_harmonic(m,k,theta,phi,false); } if( m == 0 ) return spherical_harmonic(0,k,theta,phi,false); if( 0 < m && m <= k ) { return sqrt(2.0) * spherical_harmonic(m,k,theta,phi,true); } return 0; } template< class T, class TG, class TO, int L, int NODF> void AnalyticalDiffusionQballReconstructionImageFilter ::ComputeReconstructionMatrix() { //for(int i=-6;i<7;i++) // std::cout << boost::math::legendre_p(6, i, 0.65657) << std::endl; if( m_NumberOfGradientDirections < 6 ) { itkExceptionMacro( << "Not enough gradient directions supplied. Need to supply at least 6" ); } { // check for duplicate diffusion gradients bool warning = false; for(GradientDirectionContainerType::ConstIterator gdcit1 = this->m_GradientDirectionContainer->Begin(); gdcit1 != this->m_GradientDirectionContainer->End(); ++gdcit1) { for(GradientDirectionContainerType::ConstIterator gdcit2 = this->m_GradientDirectionContainer->Begin(); gdcit2 != this->m_GradientDirectionContainer->End(); ++gdcit2) { if(gdcit1.Value() == gdcit2.Value() && gdcit1.Index() != gdcit2.Index()) { itkWarningMacro( << "Some of the Diffusion Gradients equal each other. Corresponding image data should be averaged before calling this filter." ); warning = true; break; } } if (warning) break; } // handle acquisition schemes where only half of the spherical // shell is sampled by the gradient directions. In this case, // each gradient direction is duplicated in negative direction. vnl_vector centerMass(3); centerMass.fill(0.0); int count = 0; for(GradientDirectionContainerType::ConstIterator gdcit1 = this->m_GradientDirectionContainer->Begin(); gdcit1 != this->m_GradientDirectionContainer->End(); ++gdcit1) { if(gdcit1.Value().one_norm() > 0.0) { centerMass += gdcit1.Value(); count ++; } } centerMass /= count; if(centerMass.two_norm() > 0.1) { m_DirectionsDuplicated = true; m_NumberOfGradientDirections *= 2; } } vnl_matrix *Q = new vnl_matrix(3, m_NumberOfGradientDirections); { int i = 0; for(GradientDirectionContainerType::ConstIterator gdcit = this->m_GradientDirectionContainer->Begin(); gdcit != this->m_GradientDirectionContainer->End(); ++gdcit) { if(gdcit.Value().one_norm() > 0.0) { double x = gdcit.Value().get(0); double y = gdcit.Value().get(1); double z = gdcit.Value().get(2); double cart[3]; Cart2Sph(x,y,z,cart); (*Q)(0,i) = cart[0]; (*Q)(1,i) = cart[1]; (*Q)(2,i++) = cart[2]; } } if(m_DirectionsDuplicated) { for(GradientDirectionContainerType::ConstIterator gdcit = this->m_GradientDirectionContainer->Begin(); gdcit != this->m_GradientDirectionContainer->End(); ++gdcit) { if(gdcit.Value().one_norm() > 0.0) { double x = gdcit.Value().get(0); double y = gdcit.Value().get(1); double z = gdcit.Value().get(2); double cart[3]; Cart2Sph(x,y,z,cart); (*Q)(0,i) = cart[0]; (*Q)(1,i) = cart[1]; (*Q)(2,i++) = cart[2]; } } } } int l = L; m_NumberCoefficients = (int)(l*l + l + 2.0)/2.0 + l; vnl_matrix* B = new vnl_matrix(m_NumberOfGradientDirections,m_NumberCoefficients); vnl_matrix* _L = new vnl_matrix(m_NumberCoefficients,m_NumberCoefficients); _L->fill(0.0); vnl_matrix* LL = new vnl_matrix(m_NumberCoefficients,m_NumberCoefficients); LL->fill(0.0); vnl_matrix* P = new vnl_matrix(m_NumberCoefficients,m_NumberCoefficients); P->fill(0.0); vnl_matrix* Inv = new vnl_matrix(m_NumberCoefficients,m_NumberCoefficients); P->fill(0.0); vnl_vector* lj = new vnl_vector(m_NumberCoefficients); m_LP = new vnl_vector(m_NumberCoefficients); for(unsigned int i=0; i(B->transpose()); //tofile2(&m_B_t,"m_B_t"); vnl_matrix B_t_B = (*m_B_t) * (*B); //tofile2(&B_t_B,"B_t_B"); vnl_matrix lambdaLL(m_NumberCoefficients,m_NumberCoefficients); lambdaLL.update((*LL)); lambdaLL *= m_Lambda; //tofile2(&lambdaLL,"lLL"); vnl_matrix tmp( B_t_B + lambdaLL); vnl_matrix_inverse *pseudoInverse = new vnl_matrix_inverse( tmp ); (*Inv) = pseudoInverse->pinverse(); //tofile2(Inv,"Inv"); vnl_matrix temp((*Inv) * (*m_B_t)); double fac1 = (1.0/(16.0*QBALL_ANAL_RECON_PI*QBALL_ANAL_RECON_PI)); switch(m_NormalizationMethod) { case QBAR_ADC_ONLY: case QBAR_RAW_SIGNAL: break; case QBAR_STANDARD: case QBAR_B_ZERO_B_VALUE: case QBAR_B_ZERO: case QBAR_NONE: temp = (*P) * temp; break; case QBAR_SOLID_ANGLE: temp = fac1 * (*P) * (*_L) * temp; break; case QBAR_NONNEG_SOLID_ANGLE: break; } //tofile2(&temp,"A"); m_CoeffReconstructionMatrix = new vnl_matrix(m_NumberCoefficients,m_NumberOfGradientDirections); for(int i=0; iodfs later int NOdfDirections = NODF; vnl_matrix_fixed* U = itk::PointShell >::DistributePointShell(); m_SphericalHarmonicBasisMatrix = new vnl_matrix(NOdfDirections,m_NumberCoefficients); vnl_matrix* sphericalHarmonicBasisMatrix2 = new vnl_matrix(NOdfDirections,m_NumberCoefficients); for(int i=0; i(NOdfDirections,m_NumberOfGradientDirections); *m_ReconstructionMatrix = (*m_SphericalHarmonicBasisMatrix) * (*m_CoeffReconstructionMatrix); } template< class T, class TG, class TO, int L, int NODF> void AnalyticalDiffusionQballReconstructionImageFilter ::SetGradientImage( GradientDirectionContainerType *gradientDirection, const GradientImagesType *gradientImage ) { this->m_GradientDirectionContainer = gradientDirection; unsigned int numImages = gradientDirection->Size(); this->m_NumberOfBaselineImages = 0; for(GradientDirectionContainerType::Iterator it = this->m_GradientDirectionContainer->Begin(); it != this->m_GradientDirectionContainer->End(); it++) { if(it.Value().one_norm() <= 0.0) { this->m_NumberOfBaselineImages++; } else // Normalize non-zero gradient directions { it.Value() = it.Value() / it.Value().two_norm(); } } this->m_NumberOfGradientDirections = numImages - this->m_NumberOfBaselineImages; // ensure that the gradient image we received has as many components as // the number of gradient directions if( gradientImage->GetVectorLength() != this->m_NumberOfBaselineImages + m_NumberOfGradientDirections ) { itkExceptionMacro( << m_NumberOfGradientDirections << " gradients + " << this->m_NumberOfBaselineImages << "baselines = " << m_NumberOfGradientDirections + this->m_NumberOfBaselineImages << " directions specified but image has " << gradientImage->GetVectorLength() << " components."); } this->ProcessObject::SetNthInput( 0, const_cast< GradientImagesType* >(gradientImage) ); } template< class T, class TG, class TO, int L, int NODF> void AnalyticalDiffusionQballReconstructionImageFilter ::PrintSelf(std::ostream& os, Indent indent) const { std::locale C("C"); std::locale originalLocale = os.getloc(); os.imbue(C); Superclass::PrintSelf(os,indent); os << indent << "OdfReconstructionMatrix: " << m_ReconstructionMatrix << std::endl; if ( m_GradientDirectionContainer ) { os << indent << "GradientDirectionContainer: " << m_GradientDirectionContainer << std::endl; } else { os << indent << "GradientDirectionContainer: (Gradient directions not set)" << std::endl; } os << indent << "NumberOfGradientDirections: " << m_NumberOfGradientDirections << std::endl; os << indent << "NumberOfBaselineImages: " << m_NumberOfBaselineImages << std::endl; os << indent << "Threshold for reference B0 image: " << m_Threshold << std::endl; os << indent << "BValue: " << m_BValue << std::endl; os.imbue( originalLocale ); } } #endif // __itkAnalyticalDiffusionQballReconstructionImageFilter_cpp diff --git a/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h b/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h index a3ad5cde59..3a4cf2dcf9 100644 --- a/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h +++ b/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h @@ -1,303 +1,305 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkAnalyticalDiffusionQballReconstructionImageFilter_h_ #define __itkAnalyticalDiffusionQballReconstructionImageFilter_h_ #include "itkImageToImageFilter.h" #include "vnl/vnl_vector_fixed.h" #include "vnl/vnl_matrix.h" #include "vnl/algo/vnl_svd.h" #include "itkVectorContainer.h" #include "itkVectorImage.h" namespace itk{ /** \class AnalyticalDiffusionQballReconstructionImageFilter * \brief This class takes as input one or more reference image (acquired in the * absence of diffusion sensitizing gradients) and 'n' diffusion * weighted images and their gradient directions and computes an image of * orientation distribution function coefficients in a spherical harmonic basis. * * \par Inputs and Usage * \par * When you have the 'n' gradient and one or more reference images in a single * multi-component image (VectorImage), you can specify the images as * \code * filter->SetGradientImage( directionsContainer, vectorImage ); * \endcode * Note that this method is used to specify both the reference and gradient images. * This is convenient when the DWI images are read in using the * NRRD * format. Like the Nrrd format, the reference images are those components of the * vectorImage whose gradient direction is (0,0,0). If more than one reference image * is present, they are averaged prior to the reconstruction. * * \par Outputs * The output image is an image of vectors that must be understood as ODFs: * \code * Image< Vector< TPixelType, OdfNrDirections >, 3 > * \endcode * * \par Parameters * \li Threshold - Threshold on the reference image data. The output ODF will * be a null pdf for pixels in the reference image that have a value less * than this. * \li BValue - See the documentation of SetBValue(). * \li At least 6 gradient images must be specified for the filter to be able * to run. If the input gradient directions g_i are majorly sampled on one half * of the sqhere, then each input image I_i will be duplicated and assign -g_i * in order to guarantee stability of the algorithm. * \li OdfDirections - directions of resulting orientation distribution function * \li EquatorNrSamplingPoints - number of sampling points on equator when * performing Funk Radeon Transform (FRT) * \li BasisFunctionCenters - the centers of the basis functions are used for * the sRBF (spherical radial basis functions interpolation). If not set, they * will be defaulted to equal m_EquatorNrSamplingPoints * * \par Template parameters * The class is templated over * \li the pixel type of the reference and gradient images * (expected to be scalar data types) * \li the internal representation of the ODF pixels (double, float etc). * \li the number of OdfDirections * \li the number of basis function centers for the sRBF * * \par References: * \li[1] * Tuch DS, * "Q-ball imaging", Magn Reson Med. 2004 Dec;52(6):1358-72. * */ template< class TReferenceImagePixelType, class TGradientImagePixelType, class TOdfPixelType, int NOrderL, int NrOdfDirections> class AnalyticalDiffusionQballReconstructionImageFilter : public ImageToImageFilter< Image< TReferenceImagePixelType, 3 >, Image< Vector< TOdfPixelType, NrOdfDirections >, 3 > > { public: enum Normalization { QBAR_STANDARD, QBAR_B_ZERO_B_VALUE, QBAR_B_ZERO, QBAR_NONE, QBAR_ADC_ONLY, QBAR_RAW_SIGNAL, QBAR_SOLID_ANGLE, QBAR_NONNEG_SOLID_ANGLE }; typedef AnalyticalDiffusionQballReconstructionImageFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< Image< TReferenceImagePixelType, 3>, Image< Vector< TOdfPixelType, NrOdfDirections >, 3 > > Superclass; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(AnalyticalDiffusionQballReconstructionImageFilter, ImageToImageFilter); typedef TReferenceImagePixelType ReferencePixelType; typedef TGradientImagePixelType GradientPixelType; typedef Vector< TOdfPixelType, NrOdfDirections > OdfPixelType; typedef TOdfPixelType BZeroPixelType; /** Reference image data, This image is aquired in the absence * of a diffusion sensitizing field gradient */ typedef typename Superclass::InputImageType ReferenceImageType; typedef Image< OdfPixelType, 3 > OdfImageType; typedef OdfImageType OutputImageType; typedef Image< Vector< TOdfPixelType, (unsigned int)((NOrderL*NOrderL + NOrderL + 2.0)/2.0 + NOrderL) >, 3 > CoefficientImageType; typedef Image< BZeroPixelType, 3 > BZeroImageType; typedef typename Superclass::OutputImageRegionType OutputImageRegionType; /** Typedef defining one (of the many) gradient images. */ typedef Image< GradientPixelType, 3 > GradientImageType; /** An alternative typedef defining one (of the many) gradient images. * It will be assumed that the vectorImage has the same dimension as the * Reference image and a vector length parameter of \c n (number of * gradient directions)*/ typedef VectorImage< GradientPixelType, 3 > GradientImagesType; /** Holds the ODF reconstruction matrix */ typedef vnl_matrix< TOdfPixelType >* OdfReconstructionMatrixType; typedef vnl_matrix< double > CoefficientMatrixType; /** Holds each magnetic field gradient used to acquire one DWImage */ typedef vnl_vector_fixed< double, 3 > GradientDirectionType; /** Container to hold gradient directions of the 'n' DW measurements */ typedef VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; /** set method to add gradient directions and its corresponding * image. The image here is a VectorImage. The user is expected to pass the * gradient directions in a container. The ith element of the container * corresponds to the gradient direction of the ith component image the * VectorImage. For the baseline image, a vector of all zeros * should be set.*/ void SetGradientImage( GradientDirectionContainerType *, const GradientImagesType *image); /** Get reference image */ virtual ReferenceImageType * GetReferenceImage() { return ( static_cast< ReferenceImageType *>(this->ProcessObject::GetInput(0)) ); } /** Return the gradient direction. idx is 0 based */ virtual GradientDirectionType GetGradientDirection( unsigned int idx) const { if( idx >= m_NumberOfGradientDirections ) { itkExceptionMacro( << "Gradient direction " << idx << "does not exist" ); } return m_GradientDirectionContainer->ElementAt( idx+1 ); } static void tofile2(vnl_matrix *A, std::string fname); static double factorial(int number); static void Cart2Sph(double x, double y, double z, double* cart); static double legendre0(int l); static double spherical_harmonic(int m,int l,double theta,double phi, bool complexPart); static double Yj(int m, int k, double theta, double phi); OdfPixelType Normalize(OdfPixelType odf, typename NumericTraits::AccumulateType b0 ); vnl_vector PreNormalize( vnl_vector vec, typename NumericTraits::AccumulateType b0 ); /** Threshold on the reference image data. The output ODF will be a null * pdf for pixels in the reference image that have a value less than this * threshold. */ itkSetMacro( Threshold, ReferencePixelType ); itkGetMacro( Threshold, ReferencePixelType ); itkSetMacro( NormalizationMethod, Normalization); itkGetMacro( NormalizationMethod, Normalization ); typedef Image FloatImageType; itkGetMacro( BZeroImage, typename BZeroImageType::Pointer); itkGetMacro( ODFSumImage, typename FloatImageType::Pointer); itkGetMacro( CoefficientImage, typename CoefficientImageType::Pointer); itkSetMacro( BValue, TOdfPixelType); #ifdef GetBValue #undef GetBValue #endif itkGetConstReferenceMacro( BValue, TOdfPixelType); itkSetMacro( Lambda, double ); itkGetMacro( Lambda, double ); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(ReferenceEqualityComparableCheck, (Concept::EqualityComparable)); itkConceptMacro(TensorEqualityComparableCheck, (Concept::EqualityComparable)); itkConceptMacro(GradientConvertibleToDoubleCheck, (Concept::Convertible)); itkConceptMacro(DoubleConvertibleToTensorCheck, (Concept::Convertible)); itkConceptMacro(GradientReferenceAdditiveOperatorsCheck, (Concept::AdditiveOperators)); itkConceptMacro(ReferenceOStreamWritableCheck, (Concept::OStreamWritable)); itkConceptMacro(TensorOStreamWritableCheck, (Concept::OStreamWritable)); /** End concept checking */ #endif protected: AnalyticalDiffusionQballReconstructionImageFilter(); ~AnalyticalDiffusionQballReconstructionImageFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const; void ComputeReconstructionMatrix(); void BeforeThreadedGenerateData(); void ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int); private: OdfReconstructionMatrixType m_ReconstructionMatrix; OdfReconstructionMatrixType m_CoeffReconstructionMatrix; OdfReconstructionMatrixType m_SphericalHarmonicBasisMatrix; /** container to hold gradient directions */ GradientDirectionContainerType::Pointer m_GradientDirectionContainer; /** Number of gradient measurements */ unsigned int m_NumberOfGradientDirections; /** Number of baseline images */ unsigned int m_NumberOfBaselineImages; /** Threshold on the reference image data */ ReferencePixelType m_Threshold; /** LeBihan's b-value for normalizing tensors */ TOdfPixelType m_BValue; typename BZeroImageType::Pointer m_BZeroImage; double m_Lambda; bool m_DirectionsDuplicated; Normalization m_NormalizationMethod; int m_NumberCoefficients; vnl_matrix* m_B_t; vnl_vector* m_LP; FloatImageType::Pointer m_ODFSumImage; typename CoefficientImageType::Pointer m_CoefficientImage; + TOdfPixelType m_Delta1; + TOdfPixelType m_Delta2; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkAnalyticalDiffusionQballReconstructionImageFilter.cpp" #endif #endif //__itkAnalyticalDiffusionQballReconstructionImageFilter_h_ diff --git a/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx b/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx index 65638a5a5d..ce854fcf7c 100644 --- a/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx +++ b/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx @@ -1,1015 +1,1015 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-08-25 18:10:57 +0200 (Mo, 25 Aug 2008) $ Version: $Revision: 15062 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __mitkOdfVtkMapper2D_txx__ #define __mitkOdfVtkMapper2D_txx__ #include "mitkOdfVtkMapper2D.h" #include "mitkDataNode.h" #include "mitkBaseRenderer.h" #include "mitkMatrixConvert.h" #include "mitkGeometry3D.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkProperties.h" #include "mitkTensorImage.h" #include "vtkSphereSource.h" #include "vtkPropCollection.h" #include "vtkMaskedGlyph3D.h" #include "vtkGlyph2D.h" #include "vtkGlyph3D.h" #include "vtkMaskedProgrammableGlyphFilter.h" #include "vtkImageData.h" #include "vtkLinearTransform.h" #include "vtkCamera.h" #include "vtkPointData.h" #include "vtkTransformPolyDataFilter.h" #include "vtkTransform.h" #include "vtkOdfSource.h" #include "vtkDoubleArray.h" #include "vtkLookupTable.h" #include "vtkProperty.h" #include "vtkPolyDataNormals.h" #include "vtkLight.h" #include "vtkLightCollection.h" #include "vtkMath.h" #include "vtkFloatArray.h" #include "vtkDelaunay2D.h" #include "vtkMapper.h" #include "vtkRenderer.h" #include "itkOrientationDistributionFunction.h" #include "itkFixedArray.h" #include #include "vtkOpenGLRenderer.h" #define _USE_MATH_DEFINES #include template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfTransform = vtkSmartPointer::New(); template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfVals = vtkSmartPointer::New(); template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfSource = vtkSmartPointer::New(); template float mitk::OdfVtkMapper2D::m_Scaling; template int mitk::OdfVtkMapper2D::m_Normalization; template int mitk::OdfVtkMapper2D::m_ScaleBy; template float mitk::OdfVtkMapper2D::m_IndexParam1; template float mitk::OdfVtkMapper2D::m_IndexParam2; #define ODF_MAPPER_PI M_PI template mitk::OdfVtkMapper2D ::OdfVtkMapper2D() { m_PropAssemblies.push_back(vtkPropAssembly::New()); m_PropAssemblies.push_back(vtkPropAssembly::New()); m_PropAssemblies.push_back(vtkPropAssembly::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes[0]->AddInput(vtkPolyData::New()); m_OdfsPlanes[1]->AddInput(vtkPolyData::New()); m_OdfsPlanes[2]->AddInput(vtkPolyData::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors[0]->GetProperty()->SetInterpolationToGouraud(); m_OdfsActors[1]->GetProperty()->SetInterpolationToGouraud(); m_OdfsActors[2]->GetProperty()->SetInterpolationToGouraud(); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); vtkLookupTable *lut = vtkLookupTable::New(); m_OdfsMappers[0]->SetLookupTable(lut); m_OdfsMappers[1]->SetLookupTable(lut); m_OdfsMappers[2]->SetLookupTable(lut); m_OdfsActors[0]->SetMapper(m_OdfsMappers[0]); m_OdfsActors[1]->SetMapper(m_OdfsMappers[1]); m_OdfsActors[2]->SetMapper(m_OdfsMappers[2]); m_Planes.push_back(vtkPlane::New()); m_Planes.push_back(vtkPlane::New()); m_Planes.push_back(vtkPlane::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters[0]->SetCutFunction( m_Planes[0] ); m_Cutters[0]->GenerateValues( 1, 0, 1 ); m_Cutters[1]->SetCutFunction( m_Planes[1] ); m_Cutters[1]->GenerateValues( 1, 0, 1 ); m_Cutters[2]->SetCutFunction( m_Planes[2] ); m_Cutters[2]->GenerateValues( 1, 0, 1 ); // Windowing the cutted planes in direction 1 m_ThickPlanes1.push_back(vtkThickPlane::New()); m_ThickPlanes1.push_back(vtkThickPlane::New()); m_ThickPlanes1.push_back(vtkThickPlane::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1[0]->SetClipFunction( m_ThickPlanes1[0] ); m_Clippers1[1]->SetClipFunction( m_ThickPlanes1[1] ); m_Clippers1[2]->SetClipFunction( m_ThickPlanes1[2] ); // Windowing the cutted planes in direction 2 m_ThickPlanes2.push_back(vtkThickPlane::New()); m_ThickPlanes2.push_back(vtkThickPlane::New()); m_ThickPlanes2.push_back(vtkThickPlane::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2[0]->SetClipFunction( m_ThickPlanes2[0] ); m_Clippers2[1]->SetClipFunction( m_ThickPlanes2[1] ); m_Clippers2[2]->SetClipFunction( m_ThickPlanes2[2] ); m_TemplateOdf = itk::OrientationDistributionFunction::GetBaseMesh(); m_OdfVals->Allocate(N); m_OdfSource->SetTemplateOdf(m_TemplateOdf); m_OdfSource->SetOdfVals(m_OdfVals); m_ShowMaxNumber = 500; } template mitk::OdfVtkMapper2D ::~OdfVtkMapper2D() { m_PropAssemblies[0]->Delete(); m_PropAssemblies[1]->Delete(); m_PropAssemblies[2]->Delete(); m_OdfsPlanes[0]->Delete(); m_OdfsPlanes[1]->Delete(); m_OdfsPlanes[2]->Delete(); m_OdfsActors[0]->Delete(); m_OdfsActors[1]->Delete(); m_OdfsActors[2]->Delete(); m_OdfsMappers[0]->Delete(); m_OdfsMappers[1]->Delete(); m_OdfsMappers[2]->Delete(); m_Planes[0]->Delete(); m_Planes[1]->Delete(); m_Planes[2]->Delete(); m_Cutters[0]->Delete(); m_Cutters[1]->Delete(); m_Cutters[2]->Delete(); m_ThickPlanes1[0]->Delete(); m_ThickPlanes1[1]->Delete(); m_ThickPlanes1[2]->Delete(); m_ThickPlanes2[0]->Delete(); m_ThickPlanes2[1]->Delete(); m_ThickPlanes2[2]->Delete(); m_Clippers1[0]->Delete(); m_Clippers1[1]->Delete(); m_Clippers1[2]->Delete(); m_Clippers2[0]->Delete(); m_Clippers2[1]->Delete(); m_Clippers2[2]->Delete(); } template mitk::Image* mitk::OdfVtkMapper2D ::GetInput() { return static_cast ( m_DataNode->GetData() ); } template vtkProp* mitk::OdfVtkMapper2D ::GetVtkProp(mitk::BaseRenderer* renderer) { return m_PropAssemblies[GetIndex(renderer)]; } template int mitk::OdfVtkMapper2D ::GetIndex(mitk::BaseRenderer* renderer) { if(!strcmp(renderer->GetName(),"stdmulti.widget1")) return 0; if(!strcmp(renderer->GetName(),"stdmulti.widget2")) return 1; if(!strcmp(renderer->GetName(),"stdmulti.widget3")) return 2; return 0; } template void mitk::OdfVtkMapper2D ::GlyphMethod(void *arg) { vtkMaskedProgrammableGlyphFilter *pfilter=(vtkMaskedProgrammableGlyphFilter*)arg; double point[3]; double debugpoint[3]; pfilter->GetPoint(point); pfilter->GetPoint(debugpoint); itk::Point p(point); Vector3D spacing = pfilter->GetGeometry()->GetSpacing(); p[0] /= spacing[0]; p[1] /= spacing[1]; p[2] /= spacing[2]; mitk::Point3D p2; pfilter->GetGeometry()->IndexToWorld( p, p2 ); point[0] = p2[0]; point[1] = p2[1]; point[2] = p2[2]; vtkPointData* data = pfilter->GetPointData(); vtkDataArray* odfvals = data->GetArray("vector"); vtkIdType id = pfilter->GetPointId(); m_OdfTransform->Identity(); m_OdfTransform->Translate(point[0],point[1],point[2]); typedef itk::OrientationDistributionFunction OdfType; OdfType odf; if(odfvals->GetNumberOfComponents()==6) { float tensorelems[6] = { (float)odfvals->GetComponent(id,0), (float)odfvals->GetComponent(id,1), (float)odfvals->GetComponent(id,2), (float)odfvals->GetComponent(id,3), (float)odfvals->GetComponent(id,4), (float)odfvals->GetComponent(id,5), }; itk::DiffusionTensor3D tensor(tensorelems); odf.InitFromTensor(tensor); } else { for(int i=0; iGetComponent(id,i); } switch(m_Normalization) { case ODFN_MINMAX: odf = odf.MinMaxNormalize(); break; case ODFN_MAX: odf = odf.MaxNormalize(); break; case ODFN_NONE: // nothing break; case ODFN_GLOBAL_MAX: // global max not implemented yet break; default: odf = odf.MinMaxNormalize(); } switch(m_ScaleBy) { case ODFSB_NONE: m_OdfSource->SetAdditionalScale(1.0); break; case ODFSB_GFA: m_OdfSource->SetAdditionalScale(odf.GetGeneralizedGFA(m_IndexParam1, m_IndexParam2)); break; case ODFSB_PC: m_OdfSource->SetAdditionalScale(odf.GetPrincipleCurvature(m_IndexParam1, m_IndexParam2, 0)); break; } for(int i=0; iSetComponent(0,i,0.5*odf[i]*m_Scaling); m_OdfSource->Modified(); } template typename mitk::OdfVtkMapper2D::OdfDisplayGeometry mitk::OdfVtkMapper2D ::MeasureDisplayedGeometry(mitk::BaseRenderer* renderer) { Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); // set up the cutter orientation according to the current geometry of // the renderers plane vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; Point3D point = worldPlaneGeometry->GetOrigin(); Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); vnl2vtk( point.Get_vnl_vector(), vp ); vnl2vtk( normal.Get_vnl_vector(), vnormal ); mitk::DisplayGeometry::Pointer dispGeometry = renderer->GetDisplayGeometry(); mitk::Vector2D size = dispGeometry->GetSizeInMM(); mitk::Vector2D origin = dispGeometry->GetOriginInMM(); // // |------O------| // | d2 | // L d1 M | // | | // |-------------| // mitk::Vector2D M; mitk::Vector2D L; mitk::Vector2D O; M[0] = origin[0] + size[0]/2; M[1] = origin[1] + size[1]/2; L[0] = origin[0]; L[1] = origin[1] + size[1]/2; O[0] = origin[0] + size[0]/2; O[1] = origin[1] + size[1]; mitk::Point2D point1; point1[0] = M[0]; point1[1] = M[1]; mitk::Point3D M3D; dispGeometry->Map(point1, M3D); point1[0] = L[0]; point1[1] = L[1]; mitk::Point3D L3D; dispGeometry->Map(point1, L3D); point1[0] = O[0]; point1[1] = O[1]; mitk::Point3D O3D; dispGeometry->Map(point1, O3D); double d1 = sqrt((M3D[0]-L3D[0])*(M3D[0]-L3D[0]) + (M3D[1]-L3D[1])*(M3D[1]-L3D[1]) + (M3D[2]-L3D[2])*(M3D[2]-L3D[2])); double d2 = sqrt((M3D[0]-O3D[0])*(M3D[0]-O3D[0]) + (M3D[1]-O3D[1])*(M3D[1]-O3D[1]) + (M3D[2]-O3D[2])*(M3D[2]-O3D[2])); double d = d1>d2 ? d1 : d2; d = d2; OdfDisplayGeometry retval; retval.vp[0] = vp[0]; retval.vp[1] = vp[1]; retval.vp[2] = vp[2]; retval.vnormal[0] = vnormal[0]; retval.vnormal[1] = vnormal[1]; retval.vnormal[2] = vnormal[2]; retval.normal[0] = normal[0]; retval.normal[1] = normal[1]; retval.normal[2] = normal[2]; retval.d = d; retval.d1 = d1; retval.d2 = d2; retval.M3D[0] = M3D[0]; retval.M3D[1] = M3D[1]; retval.M3D[2] = M3D[2]; retval.L3D[0] = L3D[0]; retval.L3D[1] = L3D[1]; retval.L3D[2] = L3D[2]; retval.O3D[0] = O3D[0]; retval.O3D[1] = O3D[1]; retval.O3D[2] = O3D[2]; retval.vp_original[0] = vp[0]; retval.vp_original[1] = vp[1]; retval.vp_original[2] = vp[2]; retval.vnormal_original[0] = vnormal[0]; retval.vnormal_original[1] = vnormal[1]; retval.vnormal_original[2] = vnormal[2]; retval.size[0] = size[0]; retval.size[1] = size[1]; retval.origin[0] = origin[0]; retval.origin[1] = origin[1]; return retval; } template void mitk::OdfVtkMapper2D ::Slice(mitk::BaseRenderer* renderer, OdfDisplayGeometry dispGeo) { vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); int index = GetIndex(renderer); vtkTransform* inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; ((vtkTransform*)vtktransform)->GetScale(myscale); inversetransform->PostMultiply(); inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]); inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp ); inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal ); // vtk works in axis align coords // thus the normal also must be axis align, since // we do not allow arbitrary cutting through volume // // vnormal should already be axis align, but in order // to get rid of precision effects, we set the two smaller // components to zero here int dims[3]; m_VtkImage->GetDimensions(dims); double spac[3]; m_VtkImage->GetSpacing(spac); if(fabs(dispGeo.vnormal[0]) > fabs(dispGeo.vnormal[1]) && fabs(dispGeo.vnormal[0]) > fabs(dispGeo.vnormal[2]) ) { if(fabs(dispGeo.vp[0]/spac[0]) < 0.4) dispGeo.vp[0] = 0.4*spac[0]; if(fabs(dispGeo.vp[0]/spac[0]) > (dims[0]-1)-0.4) dispGeo.vp[0] = ((dims[0]-1)-0.4)*spac[0]; dispGeo.vnormal[1] = 0; dispGeo.vnormal[2] = 0; } if(fabs(dispGeo.vnormal[1]) > fabs(dispGeo.vnormal[0]) && fabs(dispGeo.vnormal[1]) > fabs(dispGeo.vnormal[2]) ) { if(fabs(dispGeo.vp[1]/spac[1]) < 0.4) dispGeo.vp[1] = 0.4*spac[1]; if(fabs(dispGeo.vp[1]/spac[1]) > (dims[1]-1)-0.4) dispGeo.vp[1] = ((dims[1]-1)-0.4)*spac[1]; dispGeo.vnormal[0] = 0; dispGeo.vnormal[2] = 0; } if(fabs(dispGeo.vnormal[2]) > fabs(dispGeo.vnormal[1]) && fabs(dispGeo.vnormal[2]) > fabs(dispGeo.vnormal[0]) ) { if(fabs(dispGeo.vp[2]/spac[2]) < 0.4) dispGeo.vp[2] = 0.4*spac[2]; if(fabs(dispGeo.vp[2]/spac[2]) > (dims[2]-1)-0.4) dispGeo.vp[2] = ((dims[2]-1)-0.4)*spac[2]; dispGeo.vnormal[0] = 0; dispGeo.vnormal[1] = 0; } m_Planes[index]->SetTransform( (vtkAbstractTransform*)NULL ); m_Planes[index]->SetOrigin( dispGeo.vp ); m_Planes[index]->SetNormal( dispGeo.vnormal ); vtkPoints* points = NULL; vtkPoints* tmppoints = NULL; vtkPolyData* polydata = NULL; vtkFloatArray* pointdata = NULL; vtkDelaunay2D *delaunay = NULL; vtkPolyData* cuttedPlane = NULL; // the cutter only works if we do not have a 2D-image // or if we have a 2D-image and want to see the whole image. // // for side views of 2D-images, we need some special treatment if(!( (dims[0] == 1 && dispGeo.vnormal[0] != 0) || (dims[1] == 1 && dispGeo.vnormal[1] != 0) || (dims[2] == 1 && dispGeo.vnormal[2] != 0) )) { m_Cutters[index]->SetCutFunction( m_Planes[index] ); m_Cutters[index]->SetInput( m_VtkImage ); m_Cutters[index]->Update(); cuttedPlane = m_Cutters[index]->GetOutput(); } else { // cutting of a 2D-Volume does not work, // so we have to build up our own polydata object cuttedPlane = vtkPolyData::New(); points = vtkPoints::New(); points->SetNumberOfPoints(m_VtkImage->GetNumberOfPoints()); for(int i=0; iGetNumberOfPoints(); i++) { points->SetPoint(i, m_VtkImage->GetPoint(i)); } cuttedPlane->SetPoints(points); pointdata = vtkFloatArray::New(); int comps = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfComponents(); pointdata->SetNumberOfComponents(comps); int tuples = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfTuples(); pointdata->SetNumberOfTuples(tuples); for(int i=0; iSetTuple(i,m_VtkImage->GetPointData()->GetScalars()->GetTuple(i)); pointdata->SetName( "vector" ); cuttedPlane->GetPointData()->AddArray(pointdata); int nZero1, nZero2; if(dims[0]==1) { nZero1 = 1; nZero2 = 2; } else if(dims[1]==1) { nZero1 = 0; nZero2 = 2; } else { nZero1 = 0; nZero2 = 1; } tmppoints = vtkPoints::New(); for(int j=0; jGetNumberOfPoints(); j++){ double pt[3]; m_VtkImage->GetPoint(j,pt); tmppoints->InsertNextPoint(pt[nZero1],pt[nZero2],0); } polydata = vtkPolyData::New(); polydata->SetPoints( tmppoints ); delaunay = vtkDelaunay2D::New(); delaunay->SetInput( polydata ); delaunay->Update(); vtkCellArray* polys = delaunay->GetOutput()->GetPolys(); cuttedPlane->SetPolys(polys); } if(cuttedPlane->GetNumberOfPoints()) { // WINDOWING HERE inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; ((vtkTransform*)vtktransform)->GetScale(myscale); inversetransform->PostMultiply(); inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]); dispGeo.vnormal[0] = dispGeo.M3D[0]-dispGeo.O3D[0]; dispGeo.vnormal[1] = dispGeo.M3D[1]-dispGeo.O3D[1]; dispGeo.vnormal[2] = dispGeo.M3D[2]-dispGeo.O3D[2]; vtkMath::Normalize(dispGeo.vnormal); dispGeo.vp[0] = dispGeo.M3D[0]; dispGeo.vp[1] = dispGeo.M3D[1]; dispGeo.vp[2] = dispGeo.M3D[2]; inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp ); inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal ); m_ThickPlanes1[index]->count = 0; m_ThickPlanes1[index]->SetTransform((vtkAbstractTransform*)NULL ); m_ThickPlanes1[index]->SetPose( dispGeo.vnormal, dispGeo.vp ); m_ThickPlanes1[index]->SetThickness(dispGeo.d2); m_Clippers1[index]->SetClipFunction( m_ThickPlanes1[index] ); m_Clippers1[index]->SetInput( cuttedPlane ); m_Clippers1[index]->SetInsideOut(1); m_Clippers1[index]->Update(); dispGeo.vnormal[0] = dispGeo.M3D[0]-dispGeo.L3D[0]; dispGeo.vnormal[1] = dispGeo.M3D[1]-dispGeo.L3D[1]; dispGeo.vnormal[2] = dispGeo.M3D[2]-dispGeo.L3D[2]; vtkMath::Normalize(dispGeo.vnormal); dispGeo.vp[0] = dispGeo.M3D[0]; dispGeo.vp[1] = dispGeo.M3D[1]; dispGeo.vp[2] = dispGeo.M3D[2]; inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp ); inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal ); m_ThickPlanes2[index]->count = 0; m_ThickPlanes2[index]->SetTransform((vtkAbstractTransform*)NULL ); m_ThickPlanes2[index]->SetPose( dispGeo.vnormal, dispGeo.vp ); m_ThickPlanes2[index]->SetThickness(dispGeo.d1); m_Clippers2[index]->SetClipFunction( m_ThickPlanes2[index] ); m_Clippers2[index]->SetInput( m_Clippers1[index]->GetOutput() ); m_Clippers2[index]->SetInsideOut(1); m_Clippers2[index]->Update(); cuttedPlane = m_Clippers2[index]->GetOutput (); if(cuttedPlane->GetNumberOfPoints()) { m_OdfsPlanes[index]->RemoveAllInputs(); vtkPolyDataNormals* normals = vtkPolyDataNormals::New(); normals->SetInputConnection( m_OdfSource->GetOutputPort() ); normals->SplittingOff(); normals->ConsistencyOff(); normals->AutoOrientNormalsOff(); normals->ComputePointNormalsOn(); normals->ComputeCellNormalsOff(); normals->FlipNormalsOff(); normals->NonManifoldTraversalOff(); vtkTransformPolyDataFilter* trans = vtkTransformPolyDataFilter::New(); trans->SetInputConnection( normals->GetOutputPort() ); trans->SetTransform(m_OdfTransform); vtkMaskedProgrammableGlyphFilter* glyphGenerator = vtkMaskedProgrammableGlyphFilter::New(); glyphGenerator->SetMaximumNumberOfPoints(m_ShowMaxNumber); glyphGenerator->SetRandomMode(1); glyphGenerator->SetUseMaskPoints(1); glyphGenerator->SetSource( trans->GetOutput() ); glyphGenerator->SetInput(cuttedPlane); glyphGenerator->SetColorModeToColorBySource(); glyphGenerator->SetInputArrayToProcess(0,0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector"); glyphGenerator->SetGeometry(this->GetDataNode()->GetData()->GetGeometry()); glyphGenerator->SetGlyphMethod(&(GlyphMethod),(void *)glyphGenerator); try { glyphGenerator->Update(); } catch( itk::ExceptionObject& err ) { std::cout << err << std::endl; } m_OdfsPlanes[index]->AddInput(glyphGenerator->GetOutput()); trans->Delete(); glyphGenerator->Delete(); normals->Delete(); m_OdfsPlanes[index]->Update(); } } m_PropAssemblies[index]->VisibilityOn(); if(m_PropAssemblies[index]->GetParts()->IsItemPresent(m_OdfsActors[index])) m_PropAssemblies[index]->RemovePart(m_OdfsActors[index]); m_OdfsMappers[index]->SetInput(m_OdfsPlanes[index]->GetOutput()); m_PropAssemblies[index]->AddPart(m_OdfsActors[index]); if(inversetransform) inversetransform->Delete(); if(points) points->Delete(); if(pointdata) pointdata->Delete(); if(tmppoints) tmppoints->Delete(); if(polydata) polydata->Delete(); if(delaunay) delaunay->Delete(); } template bool mitk::OdfVtkMapper2D ::IsVisibleOdfs(mitk::BaseRenderer* renderer) { if(this->IsPlaneRotated(renderer)) return false; bool retval = false; switch(GetIndex(renderer)) { case 0: retval = this->IsVisible(renderer, "VisibleOdfs_T"); break; case 1: retval = this->IsVisible(renderer, "VisibleOdfs_S"); break; case 2: retval = this->IsVisible(renderer, "VisibleOdfs_C"); break; } return retval; } template void mitk::OdfVtkMapper2D ::MitkRenderOverlay(mitk::BaseRenderer* renderer) { if ( this->IsVisibleOdfs(renderer)==false ) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) { this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); } } template void mitk::OdfVtkMapper2D ::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer) { if ( this->IsVisibleOdfs( renderer )==false ) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) { // adapt cam pos OdfDisplayGeometry dispGeo = MeasureDisplayedGeometry( renderer); this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); } } template void mitk::OdfVtkMapper2D ::MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer) { if ( this->IsVisibleOdfs(renderer)==false ) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); } template void mitk::OdfVtkMapper2D ::GenerateData() { mitk::Image::Pointer input = const_cast( this->GetInput() ); if ( input.IsNull() ) return ; std::string classname("TensorImage"); if(classname.compare(input->GetNameOfClass())==0) { m_VtkImage = dynamic_cast( this->GetInput() )->GetNonRgbVtkImageData(); } std::string qclassname("QBallImage"); if(qclassname.compare(input->GetNameOfClass())==0) { m_VtkImage = dynamic_cast( this->GetInput() )->GetNonRgbVtkImageData(); } if( m_VtkImage ) { // make sure, that we have point data with more than 1 component (as vectors) vtkPointData* pointData = m_VtkImage->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "m_VtkImage->GetPointData() returns NULL!" ); return ; } if ( pointData->GetNumberOfArrays() == 0 ) { itkWarningMacro( << "m_VtkImage->GetPointData()->GetNumberOfArrays() is 0!" ); return ; } else if ( pointData->GetArray(0)->GetNumberOfComponents() != N && pointData->GetArray(0)->GetNumberOfComponents() != 6 /*for tensor visualization*/) { itkWarningMacro( << "number of components != number of directions in ODF!" ); return; } else if ( pointData->GetArrayName( 0 ) == NULL ) { m_VtkImage->GetPointData()->GetArray(0)->SetName("vector"); } } else { itkWarningMacro( << "m_VtkImage is NULL!" ); return ; } } template void mitk::OdfVtkMapper2D ::AdaptOdfScalingToImageSpacing( int index ) { // Spacing adapted scaling double spacing[3]; m_VtkImage->GetSpacing(spacing); double min; if(index==0) { min = spacing[0]; min = min > spacing[1] ? spacing[1] : min; } if(index==1) { min = spacing[1]; min = min > spacing[2] ? spacing[2] : min; } if(index==2) { min = spacing[0]; min = min > spacing[2] ? spacing[2] : min; } m_OdfSource->SetScale(min); } template void mitk::OdfVtkMapper2D ::SetRendererLightSources( mitk::BaseRenderer *renderer ) { // Light Sources vtkCollectionSimpleIterator sit; vtkLight* light; for(renderer->GetVtkRenderer()->GetLights()->InitTraversal(sit); (light = renderer->GetVtkRenderer()->GetLights()->GetNextLight(sit)); ) { renderer->GetVtkRenderer()->RemoveLight(light); } light = vtkLight::New(); light->SetFocalPoint(0,0,0); light->SetLightTypeToSceneLight(); light->SwitchOn(); light->SetIntensity(1.0); light->PositionalOff(); itk::Point p; int index = GetIndex(renderer); if(index==0) { p[0] = 0; p[1] = 0; p[2] = 10000; } if(index==1) { p[0] = 0; p[1] = 10000; p[2] = 0; } if(index==2) { p[0] = 10000; p[1] = 0; p[2] = 0; } mitk::Point3D p2; this->GetInput()->GetGeometry()->IndexToWorld(p,p2); light->SetPosition(p2[0],p2[1],p2[2]); renderer->GetVtkRenderer()->AddLight(light); } template void mitk::OdfVtkMapper2D ::ApplyPropertySettings() { this->GetDataNode()->GetFloatProperty( "Scaling", m_Scaling ); this->GetDataNode()->GetIntProperty( "ShowMaxNumber", m_ShowMaxNumber ); OdfNormalizationMethodProperty* nmp = dynamic_cast ( this->GetDataNode()->GetProperty( "Normalization" )); if(nmp) { m_Normalization = nmp->GetNormalization(); } OdfScaleByProperty* sbp = dynamic_cast ( this->GetDataNode()->GetProperty( "ScaleBy" )); if(sbp) { m_ScaleBy = sbp->GetScaleBy(); } this->GetDataNode()->GetFloatProperty( "IndexParam1", m_IndexParam1); this->GetDataNode()->GetFloatProperty( "IndexParam2", m_IndexParam2); } template bool mitk::OdfVtkMapper2D ::IsPlaneRotated(mitk::BaseRenderer* renderer) { Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); vtkFloatingPointType vnormal[ 3 ]; Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); vnl2vtk( normal.Get_vnl_vector(), vnormal ); vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); vtkTransform* inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double* n = inversetransform->TransformNormal(vnormal); int nonZeros = 0; for (int j=0; j<3; j++) { if (fabs(n[j])>1e-7){ nonZeros++; } } if(nonZeros>1) return true; return false; } template void mitk::OdfVtkMapper2D ::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { if(!m_VtkImage) { itkWarningMacro( << "m_VtkImage is NULL!" ); return ; } int index = GetIndex(renderer); if(IsVisibleOdfs(renderer)==false) { m_OdfsActors[0]->VisibilityOff(); m_OdfsActors[1]->VisibilityOff(); m_OdfsActors[2]->VisibilityOff(); return; } else { m_OdfsActors[0]->VisibilityOn(); m_OdfsActors[1]->VisibilityOn(); m_OdfsActors[2]->VisibilityOn(); OdfDisplayGeometry dispGeo = MeasureDisplayedGeometry( renderer); AdaptOdfScalingToImageSpacing(index); - SetRendererLightSources(renderer); + //SetRendererLightSources(renderer); ApplyPropertySettings(); Slice(renderer, dispGeo); m_LastDisplayGeometry = dispGeo; } // Get the TimeSlicedGeometry of the input object mitk::Image::Pointer input = const_cast(this->GetInput()); const TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry(); if (( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 )) { m_PropAssemblies[0]->VisibilityOff(); m_PropAssemblies[1]->VisibilityOff(); m_PropAssemblies[2]->VisibilityOff(); return; } if( inputTimeGeometry->IsValidTime( this->GetTimestep() ) == false ) { m_PropAssemblies[0]->VisibilityOff(); m_PropAssemblies[1]->VisibilityOff(); m_PropAssemblies[2]->VisibilityOff(); return; } } template void mitk::OdfVtkMapper2D ::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* /*renderer*/, bool /*overwrite*/) { node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 150 ) ); node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) ); node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New()); node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New()); node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2)); node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1)); node->SetProperty( "visible", mitk::BoolProperty::New( true ) ); node->SetProperty( "VisibleOdfs_T", mitk::BoolProperty::New( false ) ); node->SetProperty( "VisibleOdfs_C", mitk::BoolProperty::New( false ) ); node->SetProperty( "VisibleOdfs_S", mitk::BoolProperty::New( false ) ); node->SetProperty ("layer", mitk::IntProperty::New(100)); node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) ); } #endif // __mitkOdfVtkMapper2D_txx__ diff --git a/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraPlanarFG_Dome.stl b/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraPlanarFG_Dome.stl index 69f10c5dc7..2d41b51fce 100644 Binary files a/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraPlanarFG_Dome.stl and b/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraPlanarFG_Dome.stl differ diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index b71acba70c..de27ac4b0d 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,41 +1,40 @@ # Plug-ins must be ordered according to their dependencies set(MITK_EXT_PLUGINS org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dtiatlasapp:OFF org.mitk.gui.qt.examples:OFF org.mitk.gui.qt.examplesopencv:OFF org.mitk.gui.qt.igtexamples:OFF - org.mitk.gui.qt.igtnavigation:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.python.console:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.volumevisualization:OFF -) +) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index adbadf70d4..114a5262ee 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,925 +1,942 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkDataManagerView.h" #include //# Own Includes //## mitk #include "mitkDataStorageEditorInput.h" #include "mitkIDataStorageReference.h" #include "mitkNodePredicateDataType.h" #include "mitkCoreObjectFactory.h" #include "mitkPACSPlugin.h" #include "mitkDataNodeFactory.h" #include "mitkColorProperty.h" #include "mitkCommon.h" #include "mitkDelegateManager.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateProperty.h" #include "mitkEnumerationProperty.h" #include "mitkProperties.h" #include #include #include #include //## Qmitk #include #include #include #include #include -#include #include #include "src/internal/QmitkNodeTableViewKeyFilter.h" #include "src/internal/QmitkInfoDialog.h" //## Berry #include #include #include #include #include #include //# Toolkit Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkDataNodeObject.h" #include "mitkIContextMenuAction.h" #include "berryIExtensionPointService.h" const std::string QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() { } QmitkDataManagerView::~QmitkDataManagerView() { + //Remove all registered actions from each descriptor + for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++) + { + // first== the NodeDescriptor; second== the registered QAction + (it->first)->RemoveAction(it->second); + } } void QmitkDataManagerView::CreateQtPartControl(QWidget* parent) { m_CurrentRowCount = 0; m_Parent = parent; //# Preferences berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)) .Cast(); assert( prefs ); prefs->OnChanged.AddListener( berry::MessageDelegate1( this , &QmitkDataManagerView::OnPreferencesChanged ) ); //# GUI m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage()); m_NodeTreeModel->setParent( parent ); m_NodeTreeModel->SetPlaceNewNodesOnTop( prefs->GetBool("Place new nodes on top", true) ); m_NodeTreeModel->SetShowHelperObjects( prefs->GetBool("Show helper objects", false) ); m_NodeTreeModel->SetShowNodesContainingNoData( prefs->GetBool("Show nodes containing no data", false) ); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); //# Tree View (experimental) m_NodeTreeView = new QTreeView; m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection ); m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows ); m_NodeTreeView->setAlternatingRowColors(true); m_NodeTreeView->setDragEnabled(true); m_NodeTreeView->setDropIndicatorShown(true); m_NodeTreeView->setAcceptDrops(true); m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_NodeTreeView->setModel(m_NodeTreeModel); m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this)); QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)) , this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeView->selectionModel() , SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) ) , this , SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) ); //# m_NodeMenu m_NodeMenu = new QMenu(m_NodeTreeView); // # Actions berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); std::list editors = editorRegistry->GetEditors("*.mitk"); if (editors.size() > 1) { m_ShowInMapper = new QSignalMapper(this); foreach(berry::IEditorDescriptor::Pointer descriptor, editors) { QAction* action = new QAction(QString::fromStdString(descriptor->GetLabel()), this); m_ShowInActions << action; m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); m_ShowInMapper->setMapping(action, QString::fromStdString(descriptor->GetId())); } connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); } QmitkNodeDescriptor* unknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); QmitkNodeDescriptor* imageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); QmitkNodeDescriptor* surfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); - m_GlobalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this); - QObject::connect( m_GlobalReinitAction, SIGNAL( triggered(bool) ) + QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this); + QObject::connect( globalReinitAction, SIGNAL( triggered(bool) ) , this, SLOT( GlobalReinit(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_GlobalReinitAction); + unknownDataNodeDescriptor->AddAction(globalReinitAction); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, globalReinitAction)); - m_SaveAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), "Save...", this); - QObject::connect( m_SaveAction, SIGNAL( triggered(bool) ) + QAction* saveAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), "Save...", this); + QObject::connect( saveAction, SIGNAL( triggered(bool) ) , this, SLOT( SaveSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_SaveAction); + unknownDataNodeDescriptor->AddAction(saveAction); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,saveAction)); - m_RemoveAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this); - QObject::connect( m_RemoveAction, SIGNAL( triggered(bool) ) + QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this); + QObject::connect( removeAction, SIGNAL( triggered(bool) ) , this, SLOT( RemoveSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_RemoveAction); + unknownDataNodeDescriptor->AddAction(removeAction); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,removeAction)); - m_ReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this); - QObject::connect( m_ReinitAction, SIGNAL( triggered(bool) ) + QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this); + QObject::connect( reinitAction, SIGNAL( triggered(bool) ) , this, SLOT( ReinitSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_ReinitAction); + unknownDataNodeDescriptor->AddAction(reinitAction); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,reinitAction)); // find contextMenuAction extension points and add them to the node descriptor berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService(); berry::IConfigurationElement::vector cmActions( extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") ); berry::IConfigurationElement::vector::iterator cmActionsIt; std::string cmNodeDescriptorName; std::string cmLabel; std::string cmIcon; std::string cmClass; QmitkNodeDescriptor* tmpDescriptor; QAction* contextMenuAction; QVariant cmActionDataIt; m_ConfElements.clear(); int i=1; for (cmActionsIt = cmActions.begin() ; cmActionsIt != cmActions.end() ; ++cmActionsIt) { cmIcon.erase(); if((*cmActionsIt)->GetAttribute("nodeDescriptorName", cmNodeDescriptorName) && (*cmActionsIt)->GetAttribute("label", cmLabel) && (*cmActionsIt)->GetAttribute("class", cmClass)) { (*cmActionsIt)->GetAttribute("icon", cmIcon); // create context menu entry here tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(QString::fromStdString(cmNodeDescriptorName)); if(!tmpDescriptor) { MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist"; continue; } contextMenuAction = new QAction( QString::fromStdString(cmLabel), parent); tmpDescriptor->AddAction(contextMenuAction); + m_DescriptorActionList.push_back(std::pair(tmpDescriptor,contextMenuAction)); m_ConfElements[contextMenuAction] = *cmActionsIt; cmActionDataIt.setValue(i); contextMenuAction->setData( cmActionDataIt ); connect( contextMenuAction, SIGNAL( triggered(bool) ) , this, SLOT( ContextMenuActionTriggered(bool) ) ); ++i; } } m_OpacitySlider = new QSlider; m_OpacitySlider->setMinimum(0); m_OpacitySlider->setMaximum(100); m_OpacitySlider->setOrientation(Qt::Horizontal); QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) , this, SLOT( OpacityChanged(int) ) ); QLabel* _OpacityLabel = new QLabel("Opacity: "); QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout; _OpacityWidgetLayout->setContentsMargins(4,4,4,4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(m_OpacitySlider); QWidget* _OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); - m_OpacityAction = new QWidgetAction(this); - m_OpacityAction->setDefaultWidget(_OpacityWidget); - QObject::connect( m_OpacityAction, SIGNAL( changed() ) + QWidgetAction* opacityAction = new QWidgetAction(this); + opacityAction ->setDefaultWidget(_OpacityWidget); + QObject::connect( opacityAction , SIGNAL( changed() ) , this, SLOT( OpacityActionChanged() ) ); - unknownDataNodeDescriptor->AddAction(m_OpacityAction, false); + unknownDataNodeDescriptor->AddAction(opacityAction , false); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,opacityAction)); m_ColorButton = new QPushButton; m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); //m_ColorButton->setText("Change color"); QObject::connect( m_ColorButton, SIGNAL( clicked() ) , this, SLOT( ColorChanged() ) ); QLabel* _ColorLabel = new QLabel("Color: "); _ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout; _ColorWidgetLayout->setContentsMargins(4,4,4,4); _ColorWidgetLayout->addWidget(_ColorLabel); _ColorWidgetLayout->addWidget(m_ColorButton); QWidget* _ColorWidget = new QWidget; _ColorWidget->setLayout(_ColorWidgetLayout); - m_ColorAction = new QWidgetAction(this); - m_ColorAction->setDefaultWidget(_ColorWidget); - QObject::connect( m_ColorAction, SIGNAL( changed() ) + QWidgetAction* colorAction = new QWidgetAction(this); + colorAction->setDefaultWidget(_ColorWidget); + QObject::connect( colorAction, SIGNAL( changed() ) , this, SLOT( ColorActionChanged() ) ); - unknownDataNodeDescriptor->AddAction(m_ColorAction, false); + unknownDataNodeDescriptor->AddAction(colorAction, false); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,colorAction)); m_TextureInterpolation = new QAction("Texture Interpolation", this); m_TextureInterpolation->setCheckable ( true ); QObject::connect( m_TextureInterpolation, SIGNAL( changed() ) , this, SLOT( TextureInterpolationChanged() ) ); QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) ) , this, SLOT( TextureInterpolationToggled(bool) ) ); imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); + m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,m_TextureInterpolation)); m_SurfaceRepresentation = new QAction("Surface Representation", this); m_SurfaceRepresentation->setMenu(new QMenu); - QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() ) , this, SLOT( SurfaceRepresentationMenuAboutToShow() ) ); surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false); + m_DescriptorActionList.push_back(std::pair(surfaceDataNodeDescriptor, m_SurfaceRepresentation)); - m_ShowOnlySelectedNodes + QAction* showOnlySelectedNodes = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png") , "Show only selected nodes", this); - QObject::connect( m_ShowOnlySelectedNodes, SIGNAL( triggered(bool) ) + QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) ) , this, SLOT( ShowOnlySelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_ShowOnlySelectedNodes); + unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, showOnlySelectedNodes)); - m_ToggleSelectedVisibility + QAction* toggleSelectedVisibility = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png") , "Toggle visibility", this); - QObject::connect( m_ToggleSelectedVisibility, SIGNAL( triggered(bool) ) + QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) ) , this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_ToggleSelectedVisibility); + unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,toggleSelectedVisibility)); - m_ActionShowInfoDialog + QAction* actionShowInfoDialog = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png") , "Details...", this); - QObject::connect( m_ActionShowInfoDialog, SIGNAL( triggered(bool) ) + QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(m_ActionShowInfoDialog); + unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); + m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,actionShowInfoDialog)); - m_OtsuFilterAction = new QAction("Apply Otsu Filter", this); - QObject::connect( m_OtsuFilterAction, SIGNAL( triggered(bool) ) + QAction* otsuFilterAction = new QAction("Apply Otsu Filter", this); + QObject::connect( otsuFilterAction, SIGNAL( triggered(bool) ) , this, SLOT( OtsuFilter(bool) ) ); // Otsu filter does not work properly, remove it temporarily - // imageDataNodeDescriptor->AddAction(m_OtsuFilterAction); + // imageDataNodeDescriptor->AddAction(otsuFilterAction); + // m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,otsuFilterAction)); QGridLayout* _DndFrameWidgetLayout = new QGridLayout; _DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); _DndFrameWidgetLayout->setContentsMargins(0,0,0,0); m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent); m_DndFrameWidget->setLayout(_DndFrameWidgetLayout); QVBoxLayout* layout = new QVBoxLayout(parent); layout->addWidget(m_DndFrameWidget); layout->setContentsMargins(0,0,0,0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } void QmitkDataManagerView::ContextMenuActionTriggered( bool ) { QAction* action = qobject_cast ( sender() ); std::map::iterator it = m_ConfElements.find( action ); if( it == m_ConfElements.end() ) { MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found"; return; } berry::IConfigurationElement::Pointer confElem = it->second; mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension("class"); std::string className; std::string smoothed; confElem->GetAttribute("class", className); confElem->GetAttribute("smoothed", smoothed); if(className == "QmitkThresholdAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); } else if(className == "QmitkCreatePolygonModelAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); if(smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } else if(className == "QmitkStatisticsAction") { contextMenuAction->SetFunctionality(this); } contextMenuAction->Run( this->GetCurrentSelection() ); // run the action } void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) ) m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() ); if( m_NodeTreeModel->GetShowHelperObjectsFlag()!= prefs->GetBool("Show helper objects", false) ) m_NodeTreeModel->SetShowHelperObjects( !m_NodeTreeModel->GetShowHelperObjectsFlag() ); if( m_NodeTreeModel->GetShowNodesContainingNoDataFlag()!= prefs->GetBool("Show nodes containing no data", false) ) m_NodeTreeModel->SetShowNodesContainingNoData( !m_NodeTreeModel->GetShowNodesContainingNoDataFlag() ); m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); this->GlobalReinit(); } void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) { QModelIndex selected = m_NodeTreeView->indexAt ( pos ); mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected); QList selectedNodes = this->GetCurrentSelection(); if(!selectedNodes.isEmpty()) { m_NodeMenu->clear(); QList actions; if(selectedNodes.size() == 1 ) { actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node); for(QList::iterator it = actions.begin(); it != actions.end(); ++it) { (*it)->setData(QVariant::fromValue(node.GetPointer())); } } else actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes); if (!m_ShowInActions.isEmpty()) { QMenu* showInMenu = m_NodeMenu->addMenu("Show In"); showInMenu->addActions(m_ShowInActions); } m_NodeMenu->addActions(actions); m_NodeMenu->popup(QCursor::pos()); } } void QmitkDataManagerView::OpacityChanged(int value) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { float opacity = static_cast(value)/100.0f; node->SetFloatProperty("opacity", opacity); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } MITK_INFO << "slider changed"; } void QmitkDataManagerView::OpacityActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { float opacity = 0.0; if(node->GetFloatProperty("opacity", opacity)) { m_OpacitySlider->setValue(static_cast(opacity*100)); } } MITK_INFO << "changed"; } void QmitkDataManagerView::ColorChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { QColor color = QColorDialog::getColor(); m_ColorButton->setAutoFillBackground(true); node->SetProperty("color",mitk::ColorProperty::New(color.red()/255.0,color.green()/255.0,color.blue()/255.0)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } MITK_INFO << "slider changed"; } void QmitkDataManagerView::ColorActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); m_ColorButton->setStyleSheet(styleSheet); } MITK_INFO << "changed"; } void QmitkDataManagerView::TextureInterpolationChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { bool textureInterpolation = false; node->GetBoolProperty("texture interpolation", textureInterpolation); m_TextureInterpolation->setChecked(textureInterpolation); } } void QmitkDataManagerView::TextureInterpolationToggled( bool checked ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { node->SetBoolProperty("texture interpolation", checked); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; // clear menu m_SurfaceRepresentation->menu()->clear(); QAction* tmp; // create menu entries for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End() ; it++) { tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second)); tmp->setCheckable(true); if(it->second == representationProp->GetValueAsString()) { tmp->setChecked(true); } QObject::connect( tmp, SIGNAL( triggered(bool) ) , this, SLOT( SurfaceRepresentationActionToggled(bool) ) ); } } void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; QAction* senderAction = qobject_cast ( QObject::sender() ); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); if ( activatedItem != representationProp->GetValueAsString() ) { if ( representationProp->IsValidEnumerationValue( activatedItem ) ) { representationProp->SetValue( activatedItem ); representationProp->InvokeEvent( itk::ModifiedEvent() ); representationProp->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkDataManagerView::SaveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRows = m_NodeTreeView->selectionModel()->selectedRows(); mitk::DataNode* node = 0; unsigned int indexesOfSelectedRowsSize = indexesOfSelectedRows.size(); for (unsigned int i = 0; iGetNode(indexesOfSelectedRows.at(i)); // if node is not defined or if the node contains geometry data do not remove it if ( node != 0 ) { mitk::BaseData::Pointer data = node->GetData(); if (data.IsNotNull()) { QString error; try { CommonFunctionality::SaveBaseData( data.GetPointer(), node->GetName().c_str() ); } catch(std::exception& e) { error = e.what(); } catch(...) { error = "Unknown error occured"; } if( !error.isEmpty() ) QMessageBox::critical( m_Parent, "Error saving...", error ); } } } } void QmitkDataManagerView::ReinitSelectedNodes( bool ) { mitk::IRenderWindowPart* renderWindow = this->OpenRenderWindowPart(); QList selectedNodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, selectedNodes) { mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { renderWindow->GetRenderingManager()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); renderWindow->GetRenderingManager()->RequestUpdateAll(); } } } void QmitkDataManagerView::RemoveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRows = m_NodeTreeView->selectionModel()->selectedRows(); if(indexesOfSelectedRows.size() < 1) { return; } std::vector selectedNodes; mitk::DataNode* node = 0; QString question = tr("Do you really want to remove "); for (QModelIndexList::iterator it = indexesOfSelectedRows.begin() ; it != indexesOfSelectedRows.end(); it++) { node = m_NodeTreeModel->GetNode(*it); // if node is not defined or if the node contains geometry data do not remove it if ( node != 0 /*& strcmp(node->GetData()->GetNameOfClass(), "Geometry2DData") != 0*/ ) { selectedNodes.push_back(node); question.append(QString::fromStdString(node->GetName())); question.append(", "); } } // remove the last two characters = ", " question = question.remove(question.size()-2, 2); question.append(" from data storage?"); QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent , tr("DataManager") , question , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(answerButton == QMessageBox::Yes) { for (std::vector::iterator it = selectedNodes.begin() ; it != selectedNodes.end(); it++) { node = *it; this->GetDataStorage()->Remove(node); this->GlobalReinit(false); } } } void QmitkDataManagerView::MakeAllNodesInvisible( bool ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { node->SetVisibility(false); } //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowOnlySelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QList allNodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, allNodes) { node->SetVisibility(selectedNodes.contains(node)); } //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); bool isVisible = false; foreach(mitk::DataNode::Pointer node, selectedNodes) { isVisible = false; node->GetBoolProperty("visible", isVisible); node->SetVisibility(!isVisible); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent); _QmitkInfoDialog.exec(); } void QmitkDataManagerView::Load( bool ) { QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Load data", "", mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); for ( QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it ) { FileOpen((*it).toAscii(), 0); } } void QmitkDataManagerView::FileOpen( const char * fileName, mitk::DataNode* parentNode ) { mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New(); try { factory->SetFileName( fileName ); QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); factory->Update(); for ( unsigned int i = 0 ; i < factory->GetNumberOfOutputs( ); ++i ) { mitk::DataNode::Pointer node = factory->GetOutput( i ); if ( ( node.IsNotNull() ) && ( node->GetData() != NULL ) ) { this->GetDataStorage()->Add(node, parentNode); mitk::BaseData::Pointer basedata = node->GetData(); mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } catch ( itk::ExceptionObject & ex ) { itkGenericOutputMacro( << "Exception during file open: " << ex ); } QApplication::restoreOverrideCursor(); } QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const { return m_NodeTreeView->selectionModel(); } void QmitkDataManagerView::GlobalReinit( bool ) { mitk::IRenderWindowPart* renderWindow = this->OpenRenderWindowPart(); // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeSlicedGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(rs, "visible"); // initialize the views to the bounding geometry renderWindow->GetRenderingManager()->InitializeViews(bounds); } void QmitkDataManagerView::OnSelectionChanged( berry::IWorkbenchPart::Pointer part , const QList& selection ) { if(part.GetPointer() == this) return; QItemSelection newSelection; m_NodeTreeView->selectionModel()->reset(); foreach(mitk::DataNode::Pointer node, selection) { QModelIndex treeIndex = m_NodeTreeModel->GetIndex(node); if(treeIndex.isValid()) newSelection.select(treeIndex, treeIndex); } m_NodeTreeView->selectionModel()->select(newSelection, QItemSelectionModel::SelectCurrent); } void QmitkDataManagerView::OtsuFilter( bool ) { QList selectedNodes = this->GetCurrentSelection(); mitk::Image::Pointer mitkImage = 0; foreach(mitk::DataNode::Pointer node, selectedNodes) { mitkImage = dynamic_cast( node->GetData() ); if(mitkImage.IsNull()) continue; try { // get selected mitk image const unsigned short dim = 3; typedef short InputPixelType; typedef unsigned char OutputPixelType; typedef itk::Image< InputPixelType, dim > InputImageType; typedef itk::Image< OutputPixelType, dim > OutputImageType; typedef itk::OtsuThresholdImageFilter< InputImageType, OutputImageType > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetOutsideValue( 1 ); filter->SetInsideValue( 0 ); InputImageType::Pointer itkImage; mitk::CastToItkImage(mitkImage, itkImage); filter->SetInput( itkImage ); filter->Update(); mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); std::string nameOfResultImage = node->GetName(); nameOfResultImage.append("Otsu"); resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); resultNode->SetProperty("binary", mitk::BoolProperty::New(true) ); resultNode->SetData( mitk::ImportItkImage ( filter->GetOutput() ) ); this->GetDataStorage()->Add(resultNode, node); } catch( std::exception& err ) { MITK_ERROR(this->GetClassName()) << err.what(); } } } void QmitkDataManagerView::NodeTreeViewRowsRemoved ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) { m_NodeTreeView->setExpanded(parent, true); // a new row was inserted if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 ) { this->OpenRenderWindowPart(); m_CurrentRowCount = m_NodeTreeModel->rowCount(); /* std::vector nodes = m_NodeTreeModel->GetNodeSet(); if(nodes.size() == 1) { QModelIndex treeIndex = m_NodeTreeModel->GetIndex(nodes.front()); m_NodeTreeView->selectionModel()->setCurrentIndex( treeIndex, QItemSelectionModel::ClearAndSelect ); } */ } } void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", false); } nodes.clear(); nodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", true); } //changing the selection does NOT require any rendering processes! //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowIn(const QString &editorId) { berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference())); page->OpenEditor(input, editorId.toStdString(), false, berry::IWorkbenchPage::MATCH_ID); } mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart() { return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN); } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h index e3d6cce6b3..18c1e05074 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h @@ -1,270 +1,253 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef QMITKDATAMANAGERVIEW_H_ #define QMITKDATAMANAGERVIEW_H_ // BlueBerry includes #include /// Qmitk #include +#include /// Qt #include #include // Forward declarations class QMenu; class QAction; class QComboBox; class QWidgetAction; class QSlider; class QModelIndex; class QTreeView; class QPushButton; class QToolBar; class QMenu; class QSignalMapper; class QmitkDnDFrameWidget; class QmitkDataStorageTreeModel; /// /// \ingroup org_mitk_gui_qt_datamanager_internal /// /// \brief A View class that can show all data tree nodes of a certain DataStorage /// /// \TODO: complete PACS support, in save dialog show regular filename /// class MITK_QT_DATAMANAGER QmitkDataManagerView : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; // = "org.mitk.extapp.defaultperspective" /// /// \brief Standard ctor. /// QmitkDataManagerView(); /// /// \brief Standard dtor. /// virtual ~QmitkDataManagerView(); public slots: /// /// Invoked when the opacity slider changed /// void OpacityChanged(int value); /// /// Invoked when the opacity action changed /// In this function the the opacity slider is set to the selected nodes opacity value /// void OpacityActionChanged(); /// /// Invoked when the color button is pressed /// void ColorChanged(); /// /// Invoked when the color action changed /// void ColorActionChanged(); /// /// Invoked when the color button is pressed /// void TextureInterpolationChanged(); /// /// Invoked when the color action changed /// void TextureInterpolationToggled ( bool checked ); /// /// SurfaceRepresentationActionToggled /// void SurfaceRepresentationMenuAboutToShow (); ///public /// SurfaceRepresentationActionToggled /// void SurfaceRepresentationActionToggled ( bool checked ); /// /// \brief Shows a node context menu. /// void NodeTableViewContextMenuRequested( const QPoint & index ); /// /// \brief Invoked when an element should be saved. /// void SaveSelectedNodes( bool checked = false ); /// /// \brief Invoked when an element should be removed. /// void RemoveSelectedNodes( bool checked = false ); /// /// \brief Invoked when an element should be reinitiliased. /// void ReinitSelectedNodes( bool checked = false ); /// /// \brief Invoked when the visibility of the selected nodes should be toggled. /// void MakeAllNodesInvisible ( bool checked = false ); /// /// \brief Makes all selected nodes visible, all other nodes invisible. /// void ShowOnlySelectedNodes ( bool checked = false ); /// /// \brief Invoked when the visibility of the selected nodes should be toggled. /// void ToggleVisibilityOfSelectedNodes ( bool checked = false ); /// /// \brief Invoked when infos of the selected nodes should be shown in a dialog. /// void ShowInfoDialogForSelectedNodes ( bool checked = false ); /// /// \brief Shows a load dialog. /// void Load ( bool checked = false ); /// /// \brief Reinits everything. /// void GlobalReinit ( bool checked = false ); /// /// Invoked when the preferences were changed /// void OnPreferencesChanged(const berry::IBerryPreferences*); /// /// \brief will be toggled when a extension point context menu action is toggled /// this is a proxy method which will load the corresponding extension class /// and run IContextMenuAction /// void ContextMenuActionTriggered( bool ); /// /// Invoked when the MITK workbench selection changed /// void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& selection); /// Invoked when the median action is invoked void OtsuFilter( bool checked = false ); /// When rows are inserted auto expand them void NodeTreeViewRowsInserted ( const QModelIndex & parent, int start, int end ); /// will setup m_CurrentRowCount void NodeTreeViewRowsRemoved ( const QModelIndex & parent, int start, int end ); /// Whenever the selection changes set the "selected" property respectively void NodeSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected ); /// Opens the editor with the given id using the current data storage void ShowIn(const QString& editorId); protected: /// /// \brief Create the view here. /// virtual void CreateQtPartControl(QWidget* parent); void SetFocus(); /// /// \brief Shows a file open dialog. /// void FileOpen( const char * fileName, mitk::DataNode* parentNode ); protected: QWidget* m_Parent; QmitkDnDFrameWidget* m_DndFrameWidget; /// /// \brief A plain widget as the base pane. /// QmitkDataStorageTreeModel* m_NodeTreeModel; /// /// Holds the preferences for the datamanager. /// berry::IBerryPreferences::Pointer m_DataManagerPreferencesNode; /// /// saves the configuration elements for the context menu actions from extension points /// std::map m_ConfElements; /// /// \brief The Table view to show the selected nodes. /// QTreeView* m_NodeTreeView; /// /// \brief The context menu that shows up when right clicking on a node. /// QMenu* m_NodeMenu; /// /// \brief flag indicating whether a surface created from a selected decimation is decimated with vtkQuadricDecimation or not /// bool m_SurfaceDecimation; - ///# Actions for the Context Menu - /// Global Reinit Action - QAction* m_GlobalReinitAction; - /// Save Action - QAction* m_SaveAction; - /// Remove Action - QAction* m_RemoveAction; - /// Reinit Action - QAction* m_ReinitAction; + + ///# A list of ALL actions for the Context Menu + std::vector< std::pair< QmitkNodeDescriptor*, QAction* > > m_DescriptorActionList; + /// A Slider widget to change the opacity of a node QSlider* m_OpacitySlider; - /// Opacity action - QWidgetAction* m_OpacityAction; /// button to change the color of a node QPushButton* m_ColorButton; - /// Color action - QWidgetAction* m_ColorAction; /// TextureInterpolation action QAction* m_TextureInterpolation; - /// TextureInterpolation action + /// SurfaceRepresentation action QAction* m_SurfaceRepresentation; - /// Show only selected nodes - QAction* m_ShowOnlySelectedNodes; - /// Toggles visibility of selected nodes - QAction* m_ToggleSelectedVisibility; - /// Shows infos for selected nodes - QAction* m_ActionShowInfoDialog; - /// Special filter action for images - QAction* m_OtsuFilterAction; - /// Maps "Show in" actions to editor ids QSignalMapper* m_ShowInMapper; /// A list of "Show in" actions QList m_ShowInActions; /// saves the current amount of rows shown in the datamanager size_t m_CurrentRowCount; private: QItemSelectionModel* GetDataNodeSelectionModel() const; /// Reopen multi widget editor if it has been closed mitk::IRenderWindowPart *OpenRenderWindowPart(); }; #endif /*QMITKDATAMANAGERVIEW_H_*/ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp index d5acaa8a1f..2e0d524f66 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkODFRenderWidget.cpp @@ -1,131 +1,131 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkODFRenderWidget.h" #include #include #include #include #include QmitkODFRenderWidget::QmitkODFRenderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { //create Layouts QmitkODFRenderWidgetLayout = new QHBoxLayout( this ); //Set Layout to widget this->setLayout(QmitkODFRenderWidgetLayout); //Create RenderWindow m_RenderWindow = new QmitkRenderWindow(this, "odf render widget"); m_RenderWindow->setMaximumSize(300,300); m_RenderWindow->GetRenderer()->SetMapperID( mitk::BaseRenderer::Standard3D ); //m_RenderWindow->SetLayoutIndex( 3 ); QmitkODFRenderWidgetLayout->addWidget( m_RenderWindow ); } QmitkODFRenderWidget::~QmitkODFRenderWidget() { } void QmitkODFRenderWidget::GenerateODF( itk::OrientationDistributionFunction odf ) { m_Surface = mitk::Surface::New(); m_ds = mitk::StandaloneDataStorage::New(); m_Node = mitk::DataNode::New(); vtkPolyData* m_TemplateOdf = itk::OrientationDistributionFunction::GetBaseMesh(); vtkPolyData *polyData = vtkPolyData::New(); vtkPoints *points = vtkPoints::New(); vtkFloatArray *scalars = vtkFloatArray::New(); double max = -10000; double min = 10000; for (int i=0; imax) max = odf[i]; if (std::fabs(max)GetPoints()->GetPoint(i,p); double val = odf[i]; p[0] *= val; p[1] *= val; p[2] *= val; points->InsertPoint(i,p); // scalars->InsertTuple1(i, 1-val/max); scalars->InsertTuple1(i, 1-val/max); } polyData->SetPoints(points); vtkCellArray* polys = m_TemplateOdf->GetPolys(); polyData->SetPolys(polys); polyData->GetPointData()->SetScalars(scalars); polys->Delete(); scalars->Delete(); points->Delete(); m_Surface->SetVtkPolyData(polyData); m_Node->SetData(m_Surface); mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); vtkLookupTable* vtkLut = mitkLut->GetVtkLookupTable(); vtkLut->SetTableRange(0, 1); vtkLut->Build(); mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); mitkLutProp->SetLookupTable(mitkLut); m_Node->SetProperty( "LookupTable", mitkLutProp ); m_Node->SetProperty("scalar visibility", mitk::BoolProperty::New(true)); m_Node->SetProperty("color mode", mitk::BoolProperty::New(true)); m_Node->SetProperty("material.specularCoefficient", mitk::FloatProperty::New(0.5)); m_ds->Add(m_Node); m_RenderWindow->GetRenderer()->SetDataStorage( m_ds ); // adjust camera to current plane rotation mitk::Geometry2D::ConstPointer worldGeometry = mitk::GlobalInteraction::GetInstance()->GetFocus()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); mitk::Vector3D normal = worldPlaneGeometry->GetNormal(); mitk::Vector3D up = worldPlaneGeometry->GetAxisVector(1); normal.Normalize(); up.Normalize(); vtkSmartPointer cam = vtkSmartPointer::New(); const double camPos[3] = {normal[0],normal[1],normal[2]}; const double camUp[3] = {up[0],up[1],up[2]}; cam->SetPosition(camPos); cam->SetViewUp(camUp); cam->SetParallelProjection(1); m_RenderWindow->GetRenderer()->GetVtkRenderer()->SetActiveCamera(cam); } diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.igtnavigation/CMakeLists.txt deleted file mode 100644 index 3a540a2f2c..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(org_mitk_gui_qt_igtnavigation) - -MACRO_CREATE_MITK_CTK_PLUGIN( - EXPORT_DIRECTIVE IGTNAVIGATION_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDENCIES QmitkExt MitkIGT MitkIGTUI -) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.igtnavigation/documentation/UserManual/Manual.dox deleted file mode 100644 index bbbde12782..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/documentation/UserManual/Manual.dox +++ /dev/null @@ -1,11 +0,0 @@ -/** -\bundlemainpage{org_mitk_gui_qt_igtnavigation} Igt Navigation - -This Bundle includes views of specific navigation software. At the moment there is only one navigation software availiable: - -
    -
  • \subpage org_toolpairnavigation -
- -*/ - diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/documentation/UserManual/QmitkToolPairNavigation.dox b/Plugins/org.mitk.gui.qt.igtnavigation/documentation/UserManual/QmitkToolPairNavigation.dox deleted file mode 100644 index 01425bcb52..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/documentation/UserManual/QmitkToolPairNavigation.dox +++ /dev/null @@ -1,10 +0,0 @@ -/** -\page org_toolpairnavigation IGT Tool Pair Navigation - - This plugin can be used to guide one tracking tool to another tracking tool. - - The plugin connects to a tracking system and shows the connected/added tools in two 3D widgets (standard 3D widget is interactable, the other (widget2) isn't). - Furthermore it calculates the distance between the two tools and displays it in GUI. - In widget 4 the tool connected on port b is shown from the point of view of the tool in port a. - -*/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.igtnavigation/documentation/doxygen/modules.dox deleted file mode 100644 index c76997c747..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/documentation/doxygen/modules.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** - \defgroup org_mitk_gui_qt_igtnavigation org.mitk.gui.qt.igtnavigation - \ingroup MITKPlugins - - \brief Describe your plugin here. - -*/ - -/** - \defgroup org_mitk_gui_qt_igtnavigation_internal Internal - \ingroup org_mitk_gui_qt_igtnavigation - - \brief This subcategory includes the internal classes of the org.mitk.gui.qt.igtnavigation plugin. Other - plugins must not rely on these classes. They contain implementation details and their interface - may change at any time. We mean it. -*/ diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/files.cmake b/Plugins/org.mitk.gui.qt.igtnavigation/files.cmake deleted file mode 100644 index 4918f68dd1..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/files.cmake +++ /dev/null @@ -1,42 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - mitkPluginActivator.cpp - QmitkToolPairNavigationView.cpp -) - -set(UI_FILES - src/internal/QmitkToolPairNavigationViewControls.ui -) - -set(MOC_H_FILES - src/internal/mitkPluginActivator.h - src/internal/QmitkToolPairNavigationView.h -) - -# list of resource files which can be used by the plug-in -# system without loading the plug-ins shared library, -# for example the icon used in the menu and tabs for the -# plug-in views in the workbench -set(CACHED_RESOURCE_FILES - resources/toolpair.png - plugin.xml -) - -# list of Qt .qrc files which contain additional resources -# specific to this plugin -set(QRC_FILES - resources/QmitkToolPairNavigationView.qrc -) - -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.igtnavigation/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.igtnavigation/manifest_headers.cmake deleted file mode 100644 index 7a6bfededb..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "Igtnavigation") -set(Plugin-Version "0.1") -set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") -set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common.legacy) diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/plugin.xml b/Plugins/org.mitk.gui.qt.igtnavigation/plugin.xml deleted file mode 100644 index d9a4be5af9..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/resources/QmitkToolPairNavigationView.qrc b/Plugins/org.mitk.gui.qt.igtnavigation/resources/QmitkToolPairNavigationView.qrc deleted file mode 100644 index 0ee50f21dc..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/resources/QmitkToolPairNavigationView.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - toolpair.png - - diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/resources/toolpair.png b/Plugins/org.mitk.gui.qt.igtnavigation/resources/toolpair.png deleted file mode 100644 index 6bd3f75f8b..0000000000 Binary files a/Plugins/org.mitk.gui.qt.igtnavigation/resources/toolpair.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationView.cpp b/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationView.cpp deleted file mode 100644 index beef1cf981..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationView.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/*========================================================================= - -Program: Medical Imaging & Interaction Toolkit -Language: C++ -Date: $Date: 2009-05-28 17:19:30 +0200 (Do, 28 Mai 2009) $ -Version: $Revision: 17495 $ - -Copyright (c) German Cancer Research Center, Division of Medical and -Biological Informatics. All rights reserved. -See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. - -This software is distributed WITHOUT ANY WARRANTY; without even -the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -#include "QmitkToolPairNavigationView.h" -#include "QmitkNDIConfigurationWidget.h" -#include "QmitkUpdateTimerWidget.h" -#include "QmitkToolDistanceWidget.h" -#include "mitkNodePredicateDataType.h" -#include "QmitkDataStorageComboBox.h" -#include "QmitkStdMultiWidget.h" -#include -#include -#include -#include -#include -#include -#include - - -#include -#include - - -#define WARN LOG_WARN("ToolPairNavigation") - -const std::string QmitkToolPairNavigationView::VIEW_ID = "org.mitk.views.toolpairnavigation"; - -QmitkToolPairNavigationView::QmitkToolPairNavigationView() -: QmitkFunctionality(), m_MultiWidget(NULL) -{ -} - -QmitkToolPairNavigationView::~QmitkToolPairNavigationView() -{ - - delete m_NDIConfigWidget; - delete m_DistanceWidget; - m_NDIConfigWidget = NULL; - m_DistanceWidget = NULL; - m_Source = NULL; - m_Visualizer = NULL; - m_CameraVisualizer = NULL; - -} - -void QmitkToolPairNavigationView::CreateQtPartControl(QWidget *parent) -{ - // create GUI widgets - m_Controls.setupUi(parent); - this->CreateBundleWidgets(parent); - this->CreateConnections(); -} - -void QmitkToolPairNavigationView::CreateBundleWidgets(QWidget* parent) -{ - //get default data storage - //mitk::DataStorage* ds = this->GetDefaultDataStorage(); - - //instanciate widget - m_NDIConfigWidget = new QmitkNDIConfigurationWidget(parent); - m_DistanceWidget = new QmitkToolDistanceWidget(parent); - - - // removes all placeholder tabs from the toolbox that where created in the qt designer before - int tabnr = this->m_Controls.m_ToolBox->count(); - for(int i=0; i < tabnr ;i++) - { - this->m_Controls.m_ToolBox->removeItem(0); - } - - // inserts this bundle's widgets into the toolbox - this->m_Controls.m_ToolBox->insertItem(0,m_NDIConfigWidget,QString("Configuration")); - this->m_Controls.m_ToolBox->insertItem(1,m_DistanceWidget,QString("Distances")); - -} - -void QmitkToolPairNavigationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) -{ - m_MultiWidget = &stdMultiWidget; -} - -void QmitkToolPairNavigationView::StdMultiWidgetNotAvailable() -{ - m_MultiWidget = NULL; -} - -void QmitkToolPairNavigationView::CreateConnections() -{ - connect( m_NDIConfigWidget, SIGNAL(Connected()), this, SLOT(SetNavigationUp())); - connect( m_NDIConfigWidget, SIGNAL(Connected()), this->m_Controls.m_RenderingTimerWidget, SLOT(EnableWidget())); - connect( m_NDIConfigWidget, SIGNAL(Disconnected()), this, SLOT(Disconnected())); - connect( m_NDIConfigWidget, SIGNAL(Disconnected()), this->m_Controls.m_RenderingTimerWidget, SLOT(DisableWidget())); - - - //to be implemented for tool name changig e.g. - // connect(m_NDIConfigWidget, SIGNAL(ToolsChanged()), this, SLOT(ToolsChanged())); -} - -void QmitkToolPairNavigationView::Activated() -{ - QmitkFunctionality::Activated(); - - //switch to 3D rendering mode in Widget3 - m_LastMapperIDWidget3 = mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget3->GetRenderWindow())->GetMapperID(); - mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget3->GetRenderWindow())->SetMapperID(2); - mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget2->GetRenderWindow())->SetMapperID(2); -} - -void QmitkToolPairNavigationView::Deactivated() -{ - QmitkFunctionality::Deactivated(); - - //switch back cameravisualization view in Widget3 - mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget3->GetRenderWindow())->SetMapperID(m_LastMapperIDWidget3); - mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget2->GetRenderWindow())->SetMapperID(1); -} - -void QmitkToolPairNavigationView::Disconnected() -{ - if(m_Controls.m_RenderingTimerWidget != NULL) - { - this->m_Controls.m_RenderingTimerWidget->StopTimer(); - } - if(m_Source.IsNotNull() && m_Source->IsTracking()) - { - this->m_Source->StopTracking(); - } - this->DestroyIGTPipeline(); - this->RemoveVisualizationObjects(this->GetDefaultDataStorage()); - - if(this->m_DistanceWidget != NULL) - this->m_DistanceWidget->ClearDistanceMatrix(); -} - -void QmitkToolPairNavigationView::ToolsAdded( QStringList /*tools*/ ) -{ - -} - - -void QmitkToolPairNavigationView::SetNavigationUp() -{ - if (m_Source.IsNotNull()) - if (m_Source->IsTracking()) - return; - - mitk::DataStorage* ds = this->GetDefaultDataStorage(); - if (ds == NULL) - { - QMessageBox::warning(NULL, "ToolPairNavigation: Error", "can not access DataStorage. Navigation not possible"); - return; - } - - //1. build up the filter pipeline - try - { - this->SetupIGTPipeline(); - } - catch(std::exception& e) - { - QMessageBox::warning(NULL, "ToolPairNavigation: Error", QString("Error while building the IGT-Pipeline: %1").arg(e.what())); - this->DestroyIGTPipeline(); - return; - } - catch (...) - { - QMessageBox::warning(NULL, "ToolPairNavigation: Error", QString("Error while building the IGT-Pipeline.")); - this->DestroyIGTPipeline(); - return; - } - - //2. start IGT pipeline to display tracking devices (20 Hz update rate -> 50 msec timeout) - try - { - // setup for the bundle's update timer widget - m_Controls.m_RenderingTimerWidget->SetPurposeLabelText(QString("Navigation")); - m_Controls.m_RenderingTimerWidget->SetTimerInterval( 50 ); - - connect( m_Controls.m_RenderingTimerWidget->GetUpdateTimer() , SIGNAL(timeout()) , this, SLOT (RenderScene()) ); - connect( m_Controls.m_RenderingTimerWidget, SIGNAL(Started()), this, SLOT(StartNavigation())); - connect( m_Controls.m_RenderingTimerWidget, SIGNAL(Stopped()) , this, SLOT (StopNavigation())); - connect( m_Controls.m_RenderingTimerWidget, SIGNAL(Stopped()) , m_DistanceWidget, SLOT (SetDistanceLabelValuesInvalid())); - - } - catch(std::exception& e) - { - QMessageBox::warning(NULL, "ToolPairNavigation: Error", QString("Error while starting the IGT-Pipeline: %1").arg(e.what())); - this->m_Controls.m_RenderingTimerWidget->StopTimer(); - this->DestroyIGTPipeline(); - return; - } -} - -void QmitkToolPairNavigationView::StartNavigation() -{ - if(m_Source.IsNotNull() && !m_Source->IsTracking()) - { - m_Source->StartTracking(); - // creates the matrix with distances from the tracking source's outputs - m_DistanceWidget->CreateToolDistanceMatrix(m_Source->GetOutputs()); - } -} - - -// is for tool changing events, like name changes -void QmitkToolPairNavigationView::ToolsChanged() -{ - -} - -void QmitkToolPairNavigationView::StopNavigation() -{ - if(m_Source.IsNotNull() && m_Source->IsTracking()) - { - m_Source->StopTracking(); - } -} - - -void QmitkToolPairNavigationView::SetupIGTPipeline() -{ - mitk::DataStorage* ds = this->GetDefaultDataStorage(); // check if dataStorage is available - if (ds == NULL) - throw std::invalid_argument("DataStorage not available"); - - mitk::TrackingDevice::Pointer tracker = m_NDIConfigWidget->GetTracker(); // get current tracker from the configuration widget - if (tracker.IsNull()) // check if tracker is valid - throw std::invalid_argument("tracking device is NULL."); - - m_Source = mitk::TrackingDeviceSource::New(); // create a new source for the IGT filter pipeline - m_Source->SetTrackingDevice(tracker); // set the found tracker to the source - - m_Visualizer = mitk::NavigationDataObjectVisualizationFilter::New(); // filter to display NDs - m_CameraVisualizer = mitk::CameraVisualization::New(); - //set widget 3 - m_CameraVisualizer->SetRenderer(mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget3->GetRenderWindow())); - - //set viewing direction - mitk::Vector3D viewVector; - mitk::FillVector3D( viewVector, 0.0, 0.0, 1.0 ); - m_CameraVisualizer->SetDirectionOfProjectionInToolCoordinates(viewVector); - - /* prepare visualization objects and filter */ - for (unsigned int i = 0; i < m_Source->GetNumberOfOutputs(); ++i) //for each connected tool - { - m_Visualizer->SetInput(i, m_Source->GetOutput(i)); // set input for visualization filter - - const char* toolName = tracker->GetTool(i)->GetToolName(); - mitk::DataNode::Pointer toolrepresentationNode = ds->GetNamedNode(toolName); - if (toolrepresentationNode.IsNull()) - { - //the first tool represents the tool to guide - //it will be represented as cone wheras the target tools will be represented by a sphere - if (i<1) //tool to guide - { - toolrepresentationNode = this->CreateConeAsInstrumentVisualization(toolName); - m_CameraVisualizer->SetInput(m_Source->GetOutput(i)); - } - else - toolrepresentationNode = this->CreateSphereAsInstrumentVisualization(toolName); - ds->Add(toolrepresentationNode); - } - - m_Visualizer->SetRepresentationObject(i, toolrepresentationNode->GetData()); // set instrument nodes as baseData for visualisation filter - } - - -} - -void QmitkToolPairNavigationView::DestroyIGTPipeline() -{ - if (m_Source.IsNotNull()) - { - m_Source->StopTracking(); - m_Source->Disconnect(); - m_Source = NULL; - } - - m_Visualizer = NULL; - m_CameraVisualizer = NULL; -} - - - -mitk::DataNode::Pointer QmitkToolPairNavigationView::CreateConeAsInstrumentVisualization(const char* label) -{ - //new data - mitk::Cone::Pointer activeToolData = mitk::Cone::New(); - vtkConeSource* vtkData = vtkConeSource::New(); - vtkData->SetRadius(3.0); - vtkData->SetHeight(6.0); - vtkData->SetDirection(0.0, 0.0, 1.0); //(0.0, 0.0, -1.0) for 5DoF - vtkData->SetCenter(0.0, 0.0, 0.0); - vtkData->SetResolution(20); - vtkData->CappingOn(); - vtkData->Update(); - activeToolData->SetVtkPolyData(vtkData->GetOutput()); - vtkData->Delete(); - - //new node - mitk::DataNode::Pointer coneNode = mitk::DataNode::New(); - coneNode->SetData(activeToolData); - coneNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New ( label ) ); - coneNode->GetPropertyList()->SetProperty("layer", mitk::IntProperty::New(0)); - coneNode->GetPropertyList()->SetProperty("visible",mitk::BoolProperty::New(true)); - //don't display in widget 3 (3D camera view) - coneNode->SetVisibility(false, mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget3->GetRenderWindow())); - coneNode->SetColor(1.0,0.0,0.0);//red - coneNode->SetOpacity(0.7); - coneNode->Modified(); - - return coneNode; -} - -mitk::DataNode::Pointer QmitkToolPairNavigationView::CreateSphereAsInstrumentVisualization(const char* label) -{ - //new data - mitk::Ellipsoid::Pointer activeToolData = mitk::Ellipsoid::New(); - vtkSphereSource *vtkData = vtkSphereSource::New(); - vtkData->SetRadius(1.0f); - vtkData->SetCenter(0.0, 0.0, 0.0); - vtkData->Update(); - activeToolData->SetVtkPolyData(vtkData->GetOutput()); - vtkData->Delete(); - - //new node - mitk::DataNode::Pointer sphereNode = mitk::DataNode::New(); - sphereNode->SetData(activeToolData); - sphereNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New ( label ) ); - sphereNode->GetPropertyList()->SetProperty("layer", mitk::IntProperty::New(0)); - sphereNode->GetPropertyList()->SetProperty("visible",mitk::BoolProperty::New(true)); - sphereNode->SetColor(0.0,1.0,0.0);//green - sphereNode->SetOpacity(1.0); - sphereNode->Modified(); - - return sphereNode; -} - - -void QmitkToolPairNavigationView::RenderScene() -{ - try - { - if (m_Visualizer.IsNull() || m_CameraVisualizer.IsNull() || this->GetActiveStdMultiWidget() == NULL) - return; - try - { - m_Visualizer->Update(); - m_CameraVisualizer->Update(); - - //every tenth update - static int counter = 0; - if (counter > 9) - { - this->m_DistanceWidget->ShowDistanceValues(m_Source->GetOutputs()); - counter = 0; - } - else - counter++; - } - catch(std::exception& e) - { - std::cout << "Exception during QmitkToolPairNavigationView::RenderScene():" << e.what() << "\n"; - } - - //update all Widgets - mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); - } - catch (std::exception& e) - { - std::cout << "RenderAll exception: " << e.what() << "\n"; - } - catch (...) - { - std::cout << "RenderAll unknown exception\n"; - } -} - -void QmitkToolPairNavigationView::RemoveVisualizationObjects( mitk::DataStorage* ds ) -{ - if (ds != NULL) - ds->Remove(ds->GetSubset(mitk::NodePredicateProperty::New("ToolPairNavigation", mitk::BoolProperty::New(true)))); // remove all objects that have the ToolPairNavigation tag -} - diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationView.h b/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationView.h deleted file mode 100644 index e3a6db0a7d..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationView.h +++ /dev/null @@ -1,171 +0,0 @@ -/*========================================================================= - -Program: Medical Imaging & Interaction Toolkit -Language: C++ -Date: $Date: 2009-05-28 17:19:30 +0200 (Do, 28 Mai 2009) $ -Version: $Revision: 17495 $ - -Copyright (c) German Cancer Research Center, Division of Medical and -Biological Informatics. All rights reserved. -See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. - -This software is distributed WITHOUT ANY WARRANTY; without even -the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -#ifndef _QMITKTOOLPAIRNAVIGATIONVIEW_H_INCLUDED -#define _QMITKTOOLPAIRNAVIGATIONVIEW_H_INCLUDED - -#include - -#include - -#include "ui_QmitkToolPairNavigationViewControls.h" -#include -#include -#include -#include - - -class QmitkNDIConfigurationWidget; -class QmitkUpdateTimerWidget; -class QmitkToolDistanceWidget; - -/*! - * \ingroup org_mitk_gui_qt_igttoolpairnavigation_internal - * - * \brief This view can be used to guide one tracking tool to another tracking tool. - * The plugin connects to a tracking system and shows the connected/added tools in two 3D widgets (standard 3D widget is interactable, the other (widget2) isn't). - * Furthermore it calculates the distance between the two tools and displays it in GUI. - * In widget 4 the tool connected on port b is shown from the point of view of the tool in port a. - * - * \sa QmitkFunctionality - */ -class QmitkToolPairNavigationView : public QmitkFunctionality -{ - - // 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; - - QmitkToolPairNavigationView(); - QmitkToolPairNavigationView(const QmitkToolPairNavigationView& other) - { - Q_UNUSED(other) - throw std::runtime_error("Copy constructor not implemented"); - } - - virtual ~QmitkToolPairNavigationView(); - - virtual void CreateQtPartControl(QWidget *parent); - - /// \brief Creation of the connections of main and control widget - virtual void CreateConnections(); - - /// \brief Called when the functionality is activated - virtual void Activated(); - - virtual void Deactivated(); - - virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); - virtual void StdMultiWidgetNotAvailable(); - -protected slots: - - void Disconnected(); - void ToolsAdded(QStringList tools); - void ToolsChanged(); - - /** - * @brief starting navigation - **/ - void SetNavigationUp(); - - /** - * @brief stopping navigation - **/ - void StopNavigation(); - - void StartNavigation(); - - - - void RenderScene(); - -protected: - - typedef std::map NameToIndexMap; - typedef std::list StringList; - - /** - * @brief setup the IGT pipeline - **/ - void SetupIGTPipeline(); - - /** - * @brief stops the tracking and deletes all pipeline objects - **/ - void DestroyIGTPipeline(); - - - - /** - * @brief create objects for visualization - **/ - mitk::DataNode::Pointer CreateConeAsInstrumentVisualization(const char* label = ""); - mitk::DataNode::Pointer CreateSphereAsInstrumentVisualization(const char* label = ""); - - /** - * @brief remove the visualized objects - **/ - void RemoveVisualizationObjects( mitk::DataStorage* ds ); - - /** - * @brief MultiWidget for this view - **/ - QmitkStdMultiWidget* m_MultiWidget; - - - /** - * @brief GUI widget with tool distances matrix - **/ - QmitkToolDistanceWidget* m_DistanceWidget; - - /** - * @brief source of the tracking system - **/ - mitk::TrackingDeviceSource::Pointer m_Source; - - /** - * @brief visualizer - **/ - mitk::NavigationDataObjectVisualizationFilter::Pointer m_Visualizer; ///< visualization filter - - mitk::CameraVisualization::Pointer m_CameraVisualizer; - - //GUI widget to connect to a NDI tracker - QmitkNDIConfigurationWidget* m_NDIConfigWidget; - - - /** - *@brief setting up the bundle widgets - **/ - void CreateBundleWidgets(QWidget* parent); - - Ui::QmitkToolPairNavigationViewControls m_Controls; - - int m_LastMapperIDWidget3; - -}; - - - - -#endif // _QMITKTOOLPAIRNAVIGATIONVIEW_H_INCLUDED - diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationViewControls.ui b/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationViewControls.ui deleted file mode 100644 index 8444058051..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/QmitkToolPairNavigationViewControls.ui +++ /dev/null @@ -1,105 +0,0 @@ - - - QmitkToolPairNavigationViewControls - - - - 0 - 0 - 392 - 325 - - - - - 0 - 0 - - - - QmitkTemplate - - - - - - 1 - - - - - 0 - 0 - 98 - 28 - - - - Configuration - - - - - - 0 - 0 - 374 - 69 - - - - Distances - - - - - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - 0 - 80 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - QmitkUpdateTimerWidget - QWidget -
QmitkUpdateTimerWidget.h
- 1 -
-
- - QmitkDataStorageComboBox.h - - - -
diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/mitkPluginActivator.cpp deleted file mode 100644 index 5bea6f4fc2..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/mitkPluginActivator.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*========================================================================= - -Program: Medical Imaging & Interaction Toolkit -Language: C++ -Date: $Date$ -Version: $Revision$ - -Copyright (c) German Cancer Research Center, Division of Medical and -Biological Informatics. All rights reserved. -See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. - -This software is distributed WITHOUT ANY WARRANTY; without even -the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - - -#include "mitkPluginActivator.h" - -#include - -#include "QmitkToolPairNavigationView.h" - -namespace mitk { - -void PluginActivator::start(ctkPluginContext* context) -{ - BERRY_REGISTER_EXTENSION_CLASS(QmitkToolPairNavigationView, context) -} - -void PluginActivator::stop(ctkPluginContext* context) -{ - Q_UNUSED(context) -} - -} - -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igtnavigation, mitk::PluginActivator) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/mitkPluginActivator.h deleted file mode 100644 index 7592169885..0000000000 --- a/Plugins/org.mitk.gui.qt.igtnavigation/src/internal/mitkPluginActivator.h +++ /dev/null @@ -1,41 +0,0 @@ -/*========================================================================= - -Program: Medical Imaging & Interaction Toolkit -Language: C++ -Date: $Date$ -Version: $Revision$ - -Copyright (c) German Cancer Research Center, Division of Medical and -Biological Informatics. All rights reserved. -See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. - -This software is distributed WITHOUT ANY WARRANTY; without even -the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - - -#ifndef MITKPLUGINACTIVATOR_H -#define MITKPLUGINACTIVATOR_H - -#include - -namespace mitk { - -class PluginActivator : - public QObject, public ctkPluginActivator -{ - Q_OBJECT - Q_INTERFACES(ctkPluginActivator) - -public: - - void start(ctkPluginContext* context); - void stop(ctkPluginContext* context); - -}; // PluginActivator - -} - -#endif // MITKPLUGINACTIVATOR_H