diff --git a/Modules/Core/TestingHelper/include/mitkRenderingTestHelper.h b/Modules/Core/TestingHelper/include/mitkRenderingTestHelper.h index a7e3f2db28..ee679cf6a2 100644 --- a/Modules/Core/TestingHelper/include/mitkRenderingTestHelper.h +++ b/Modules/Core/TestingHelper/include/mitkRenderingTestHelper.h @@ -1,225 +1,225 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkRenderingTestHelper_h #define mitkRenderingTestHelper_h #include #include #include #include #include class vtkRenderWindow; class vtkRenderer; namespace mitk { class MITKTESTINGHELPER_EXPORT RenderingTestHelper { public: /** @brief Generate a rendering test helper object including a render window of the size width * height (in pixel). @param argc Number of parameters. (here: Images) "Usage: [filename1 filenam2 -V referenceScreenshot (optional -T /directory/to/save/differenceImage)] @param argv Given parameters. If no data is inserted via commandline, you can add data later via AddNodeToDataStorage(). @param renderingMode The rendering mode. **/ RenderingTestHelper( int width, int height, int argc, char *argv[], - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::NoAntiAliasing); + BaseRenderer::RenderingMode renderingMode = BaseRenderer::RenderingMode::NoAntiAliasing); /** @brief Generate a rendering test helper object including a render window of the size width * height (in * pixel).*/ RenderingTestHelper( int width, int height, - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::NoAntiAliasing); + BaseRenderer::RenderingMode renderingMode = BaseRenderer::RenderingMode::NoAntiAliasing); /** Default destructor */ ~RenderingTestHelper(); /** @brief Getter for the vtkRenderer. **/ vtkRenderer *GetVtkRenderer(); /** @brief Getter for the vtkRenderWindow which should be used to call vtkRegressionTestImage. **/ vtkRenderWindow *GetVtkRenderWindow(); /** @brief Method can be used to save a screenshot (e.g. reference screenshot as a .png file. @param fileName The filename of the new screenshot (including path). **/ void SaveAsPNG(std::string fileName); /** * @brief SetStopRenderWindow Convenience method to make the renderwindow hold after rendering. Usefull for * debugging. * @param flag Flag indicating whether the renderwindow should automatically close (false, default) or stay open * (true). Usefull for debugging. */ void SetAutomaticallyCloseRenderWindow(bool automaticallyCloseRenderWindow); /** @brief This method set the property of the member datastorage @param property Set a property for each image in the datastorage m_DataStorage. If you want to set the property for a single data node, use GetDataStorage() and set the property yourself for the destinct node. **/ void SetImageProperty(const char *propertyKey, mitk::BaseProperty *property); /** @brief Set the view direction of the renderwindow (e.g. sagittal, coronal, axial) **/ void SetViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection); /** @brief Reorient the slice (e.g. rotation and translation like the swivel mode). **/ void ReorientSlices(mitk::Point3D origin, mitk::Vector3D rotation); /** @brief Render everything into an mitkRenderWindow. Call SetViewDirection() and SetProperty() before this method. **/ void Render(); /** @brief Returns the datastorage, in order to modify the data inside a rendering test. **/ mitk::DataStorage::Pointer GetDataStorage(); /** * @brief SetMapperID Change between Standard2D and 3D mappers. * @param id Enum mitk::BaseRenderer::StandardMapperSlot which defines the mapper. */ void SetMapperID(mitk::BaseRenderer::StandardMapperSlot id); /** * @brief AddNodeToStorage Add a node to the datastorage and perform a reinit which is necessary for rendering. * @param node The data you want to add. */ void AddNodeToStorage(mitk::DataNode::Pointer node); /** * @brief SetMapperIDToRender3D Convenience method to render in a 3D renderwindow. * @warning Does not add helper objects like the image planes to render images in 3D. */ void SetMapperIDToRender3D(); /** * @brief SetMapperIDToRender2D Convenience method to render in a 2D renderwindow. */ void SetMapperIDToRender2D(); /** * @brief SaveReferenceScreenShot Convenience method to save a reference screen shot. * @param fileName Path/to/save/the/png/file. */ void SaveReferenceScreenShot(std::string fileName); /** * @brief CompareRenderWindowAgainstReference Convenience method to compare the image rendered in the internal renderwindow against a reference screen shot. * Usage of vtkTesting::Test: vtkTesting::Test( argc, argv, vtkRenderWindow, threshold ) Set a vtkRenderWindow containing the desired scene. This is automatically rendered. vtkTesting::Test() automatically searches in argc and argv[] for a path a valid image with -V. If the test failed with the first image (foo.png) it checks if there are images of the form foo_N.png (where N=1,2,3...) and compare against them. This allows for multiple valid images. * @param argc Number of arguments. * @param argv Arguments must(!) contain the term "-V Path/To/Valid/Image.png" * @param threshold Allowed difference between two images. Default = 10.0 and was taken from VTK. * @return True if the images are equal regarding the threshold. False in all other cases. */ bool CompareRenderWindowAgainstReference(int argc, char *argv[], double threshold = 10.0); /** @brief Returns true if the opengl context is compatible for advanced vtk effects **/ bool IsAdvancedOpenGL(); /** * @brief The ArgcHelperClass class is a convinience class to convert a vector * of strings to the standard c++ argv and argc arguments. This is necessary for * the vtkTesting::Test, since is requires the reference image (and other * optional parameters) via command line. */ class ArgcHelperClass { private: /** * Members for conversion. */ std::vector argv; std::vector> argvec; public: ArgcHelperClass(const std::vector &argstrings) : argv(argstrings.size() + 1), argvec(argstrings.size() + 1) { std::vector cmdArgs; cmdArgs.push_back(mitk::IOUtil::GetProgramPath()); cmdArgs.insert(cmdArgs.end(), argstrings.begin(), argstrings.end()); for (std::size_t i = 0; i < cmdArgs.size(); ++i) { argvec[i].assign(cmdArgs[i].begin(), cmdArgs[i].end()); argvec[i].push_back('\0'); argv[i] = &argvec[i][0]; } } char **GetArgv() { return &argv[0]; } int GetArgc() { return argv.size(); } }; protected: /** * @brief Initialize Internal method to initialize the renderwindow and set the datastorage. * @param width Height of renderwindow. * @param height Width of renderwindow. * @param renderingMode The rendering mode. */ void Initialize( int width, int height, - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::NoAntiAliasing); + BaseRenderer::RenderingMode renderingMode = BaseRenderer::RenderingMode::NoAntiAliasing); /** @brief Prints the opengl information, e.g. version, vendor and extensions, * This function can only be called after an opengl context is active. * It only prints the context after the vtkRenderwindow is fully initialized. **/ void PrintGLInfo(); /** @brief This method tries to load the given file into a member datastorage, in order to render it. @param fileName The filename of the file to be loaded (including path). **/ void AddToStorage(const std::string &filename); /** @brief This method tries to parse the given argv for files (e.g. images) and load them into a member datastorage, in order to render it. @param argc Number of parameters. @param argv Given parameters. **/ void SetInputFileNames(int argc, char *argv[]); mitk::RenderWindow::Pointer m_RenderWindow; //<< Contains the mitkRenderWindow into which the test renders the data mitk::DataStorage::Pointer m_DataStorage; //<< Contains the mitkDataStorage which contains the data to be rendered bool m_AutomaticallyCloseRenderWindow; //<< Flag indicating whether the renderwindow should automatically close (true, // default) or stay open (false). Usefull for debugging. }; } // namespace mitk #endif diff --git a/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp b/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp index ee741976fb..bd77175142 100644 --- a/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp +++ b/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp @@ -1,315 +1,315 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // VTK #include #include #include #include #include // MITK #include #include #include #include #include #include #include #include // include gl to read out properties #include #include #if defined _MSC_VER #if _MSC_VER >= 1700 #define RESIZE_WORKAROUND #endif #endif #ifdef RESIZE_WORKAROUND #include "vtkWin32OpenGLRenderWindow.h" #endif // VTK Testing to compare the rendered image pixel-wise against a reference screen shot #include "vtkTesting.h" mitk::RenderingTestHelper::RenderingTestHelper(int width, int height, - mitk::BaseRenderer::RenderingMode::Type renderingMode) + BaseRenderer::RenderingMode renderingMode) : m_AutomaticallyCloseRenderWindow(true) { this->Initialize(width, height, renderingMode); } mitk::RenderingTestHelper::RenderingTestHelper( - int width, int height, int argc, char *argv[], mitk::BaseRenderer::RenderingMode::Type renderingMode) + int width, int height, int argc, char *argv[], BaseRenderer::RenderingMode renderingMode) : m_AutomaticallyCloseRenderWindow(true) { this->Initialize(width, height, renderingMode); this->SetInputFileNames(argc, argv); } -void mitk::RenderingTestHelper::Initialize(int width, int height, mitk::BaseRenderer::RenderingMode::Type renderingMode) +void mitk::RenderingTestHelper::Initialize(int width, int height, BaseRenderer::RenderingMode renderingMode) { mitk::UIDGenerator uidGen = mitk::UIDGenerator("UnnamedRenderer_", 8); m_RenderWindow = mitk::RenderWindow::New(nullptr, uidGen.GetUID().c_str(), nullptr, renderingMode); m_DataStorage = mitk::StandaloneDataStorage::New(); m_RenderWindow->GetRenderer()->SetDataStorage(m_DataStorage); this->SetMapperIDToRender2D(); this->GetVtkRenderWindow()->SetSize(width, height); if (!IsAdvancedOpenGL()) { mitkThrowException(mitk::TestNotRunException) << "Insufficient OpenGL version"; } #ifdef RESIZE_WORKAROUND HWND hWnd = static_cast(this->GetVtkRenderWindow())->GetWindowId(); RECT r; r.left = 10; r.top = 10; r.right = r.left + width; r.bottom = r.top + height; LONG style = GetWindowLong(hWnd, GWL_STYLE); AdjustWindowRect(&r, style, FALSE); MITK_INFO << "WANTED:"; MITK_INFO << r.right - r.left; MITK_INFO << r.bottom - r.top; RECT rect; if (GetWindowRect(hWnd, &rect)) { int width = rect.right - rect.left; int height = rect.bottom - rect.top; MITK_INFO << "ACTUAL:"; MITK_INFO << width; MITK_INFO << height; } SetWindowPos(hWnd, HWND_TOP, 0, 0, r.right - r.left, r.bottom - r.top, SWP_NOZORDER); GetWindowRect(hWnd, &rect); int width2 = rect.right - rect.left; int height2 = rect.bottom - rect.top; MITK_INFO << "ACTUAL2:"; MITK_INFO << width2; MITK_INFO << height2; SetWindowPos(hWnd, HWND_TOP, 0, 0, 2 * (r.right - r.left) - width2, 2 * (r.bottom - r.top) - height2, SWP_NOZORDER); #endif m_RenderWindow->GetRenderer()->Resize(width, height); // Prints the glinfo after creation of the vtkrenderwindow, we always want to do this for debugging. this->PrintGLInfo(); } mitk::RenderingTestHelper::~RenderingTestHelper() { } bool mitk::RenderingTestHelper::IsAdvancedOpenGL() { const GLubyte *version = glGetString(GL_VERSION); if (!version) return false; return *version >= '2'; } void mitk::RenderingTestHelper::PrintGLInfo() { GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); ; //MITK_INFO << "OpenGL Render Context Information: \n" // << "- GL_VENDOR: " << glGetString(GL_VENDOR) << "\n" // << "- GL_RENDERER: " << glGetString(GL_RENDERER) << "\n" // << "- GL_VERSION: " << glGetString(GL_VERSION) << "\n" // << "- GL_MAX_TEXTURE_SIZE: " << maxTextureSize << "\n" // << "- GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS); } void mitk::RenderingTestHelper::SetMapperID(mitk::BaseRenderer::StandardMapperSlot id) { m_RenderWindow->GetRenderer()->SetMapperID(id); } void mitk::RenderingTestHelper::SetMapperIDToRender3D() { this->SetMapperID(mitk::BaseRenderer::Standard3D); mitk::RenderingManager::GetInstance()->InitializeViews( this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll())); } void mitk::RenderingTestHelper::SetMapperIDToRender2D() { this->SetMapperID(mitk::BaseRenderer::Standard2D); } void mitk::RenderingTestHelper::Render() { // if the datastorage is initialized and at least 1 image is loaded render it if (m_DataStorage.IsNotNull() || m_DataStorage->GetAll()->Size() >= 1) { // Prepare the VTK camera before rendering. m_RenderWindow->GetRenderer()->PrepareRender(); this->GetVtkRenderWindow()->Render(); this->GetVtkRenderWindow()->WaitForCompletion(); if (m_AutomaticallyCloseRenderWindow == false) { // Use interaction to stop the test this->GetVtkRenderWindow()->GetInteractor()->Start(); } } else { MITK_ERROR << "No images loaded in data storage!"; } } mitk::DataStorage::Pointer mitk::RenderingTestHelper::GetDataStorage() { return m_DataStorage; } void mitk::RenderingTestHelper::SetInputFileNames(int argc, char *argv[]) { // i is set 1, because 0 is the testname as string // parse parameters for (int i = 1; i < argc; ++i) { // add everything to a list but -T and -V std::string tmp = argv[i]; if ((tmp.compare("-T")) && (tmp.compare("-V"))) { this->AddToStorage(tmp); } else { break; } } } void mitk::RenderingTestHelper::SetViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection) { mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow()) ->GetSliceNavigationController() ->SetDefaultViewDirection(viewDirection); mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll())); } void mitk::RenderingTestHelper::ReorientSlices(mitk::Point3D origin, mitk::Vector3D rotation) { mitk::SliceNavigationController::Pointer sliceNavigationController = mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController(); sliceNavigationController->ReorientSlices(origin, rotation); } vtkRenderer *mitk::RenderingTestHelper::GetVtkRenderer() { return m_RenderWindow->GetRenderer()->GetVtkRenderer(); } void mitk::RenderingTestHelper::SetImageProperty(const char *propertyKey, mitk::BaseProperty *property) { this->m_DataStorage->GetNode(mitk::NodePredicateDataType::New("Image"))->SetProperty(propertyKey, property); } vtkRenderWindow *mitk::RenderingTestHelper::GetVtkRenderWindow() { return m_RenderWindow->GetVtkRenderWindow(); } bool mitk::RenderingTestHelper::CompareRenderWindowAgainstReference(int argc, char *argv[], double threshold) { this->Render(); // retVal meanings: (see VTK/Rendering/vtkTesting.h) // 0 = test failed // 1 = test passed // 2 = test not run // 3 = something with vtkInteraction if (vtkTesting::Test(argc, argv, this->GetVtkRenderWindow(), threshold) == 1) return true; else return false; } // method to save a screenshot of the renderwindow (e.g. create a reference screenshot) void mitk::RenderingTestHelper::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); vtkSmartPointer fileWriter = vtkSmartPointer::New(); fileWriter->SetInputConnection(magnifier->GetOutputPort()); fileWriter->SetFileName(fileName.c_str()); fileWriter->Write(); renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering); } void mitk::RenderingTestHelper::SetAutomaticallyCloseRenderWindow(bool automaticallyCloseRenderWindow) { m_AutomaticallyCloseRenderWindow = automaticallyCloseRenderWindow; } void mitk::RenderingTestHelper::SaveReferenceScreenShot(std::string fileName) { this->SaveAsPNG(fileName); } void mitk::RenderingTestHelper::AddToStorage(const std::string &filename) { try { mitk::IOUtil::Load(filename, *m_DataStorage.GetPointer()); mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll())); } catch (itk::ExceptionObject &e) { MITK_ERROR << "Failed loading test data '" << filename << "': " << e.what(); } } void mitk::RenderingTestHelper::AddNodeToStorage(mitk::DataNode::Pointer node) { this->m_DataStorage->Add(node); mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll())); } diff --git a/Modules/Core/include/mitkBaseRenderer.h b/Modules/Core/include/mitkBaseRenderer.h index 1c8f239dfb..2aa0892a24 100644 --- a/Modules/Core/include/mitkBaseRenderer.h +++ b/Modules/Core/include/mitkBaseRenderer.h @@ -1,558 +1,555 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 #define BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 #include "mitkCameraRotationController.h" #include "mitkDataStorage.h" #include "mitkPlaneGeometry.h" #include "mitkPlaneGeometryData.h" #include "mitkSliceNavigationController.h" #include "mitkTimeGeometry.h" #include "mitkBindDispatcherInteractor.h" #include "mitkDispatcher.h" #include #include #include #include // DEPRECATED #include namespace mitk { class NavigationController; class SliceNavigationController; class CameraRotationController; class CameraController; class DataStorage; class Mapper; class BaseLocalStorageHandler; class KeyEvent; //##Documentation //## @brief Organizes the rendering process //## //## Organizes the rendering process. A Renderer contains a reference to a //## DataStorage and asks the mappers of the data objects to render //## the data into the renderwindow it is associated to. //## //## \#Render() checks if rendering is currently allowed by calling //## RenderWindow::PrepareRendering(). Initialization of a rendering context //## can also be performed in this method. //## //## The actual rendering code has been moved to \#Repaint() //## Both \#Repaint() and \#Update() are declared protected now. //## //## Note: Separation of the Repaint and Update processes (rendering vs //## creating a vtk prop tree) still needs to be worked on. The whole //## rendering process also should be reworked to use VTK based classes for //## both 2D and 3D rendering. //## @ingroup Renderer class MITKCORE_EXPORT BaseRenderer : public itk::Object { public: /** \brief This rendering mode enumeration is specified at various constructors * of the Renderer and RenderWindow classes, which autoconfigures the * respective VTK objects. This has to be done at construction time because later * configuring turns out to be not working on most platforms. */ - struct RenderingMode + enum class RenderingMode : int { - enum Type - { - NoAntiAliasing = 0, - FastApproximateAntiAliasing = 1 // In contrast to MSAA, FXAA works with depth peeling as it is - // applied as a post-processing pass. - }; + NoAntiAliasing = 0, + FastApproximateAntiAliasing = 1 // In contrast to MSAA, FXAA works with depth peeling as it is + // applied in a post-processing pass. }; typedef std::map BaseRendererMapType; static BaseRendererMapType baseRendererMap; static BaseRenderer *GetInstance(vtkRenderWindow *renWin); static void AddInstance(vtkRenderWindow *renWin, BaseRenderer *baseRenderer); static void RemoveInstance(vtkRenderWindow *renWin); static BaseRenderer *GetByName(const std::string &name); static vtkRenderWindow *GetRenderWindowByName(const std::string &name); #pragma GCC visibility push(default) itkEventMacro(RendererResetEvent, itk::AnyEvent); #pragma GCC visibility pop /** Standard class typedefs. */ mitkClassMacroItkParent(BaseRenderer, itk::Object); BaseRenderer(const char *name = nullptr, vtkRenderWindow *renWin = nullptr, mitk::RenderingManager *rm = nullptr, - RenderingMode::Type mode = RenderingMode::FastApproximateAntiAliasing); + RenderingMode mode = RenderingMode::FastApproximateAntiAliasing); //##Documentation //## @brief MapperSlotId defines which kind of mapper (e.g., 2D or 3D) shoud be used. typedef int MapperSlotId; enum StandardMapperSlot { Standard2D = 1, Standard3D = 2 }; virtual void SetDataStorage(DataStorage *storage); ///< set the datastorage that will be used for rendering //##Documentation //## return the DataStorage that is used for rendering virtual DataStorage::Pointer GetDataStorage() const { return m_DataStorage.GetPointer(); } //##Documentation //## @brief Access the RenderWindow into which this renderer renders. vtkRenderWindow *GetRenderWindow() const { return m_RenderWindow; } vtkRenderer *GetVtkRenderer() const { return m_VtkRenderer; } //##Documentation //## @brief Returns the Dispatcher which handles Events for this BaseRenderer Dispatcher::Pointer GetDispatcher() const; //##Documentation //## @brief Default mapper id to use. static const MapperSlotId defaultMapper; //##Documentation //## @brief Do the rendering and flush the result. virtual void Paint(); //##Documentation //## @brief Initialize the RenderWindow. Should only be called from RenderWindow. virtual void Initialize(); //##Documentation //## @brief Called to inform the renderer that the RenderWindow has been resized. virtual void Resize(int w, int h); //##Documentation //## @brief Initialize the renderer with a RenderWindow (@a renderwindow). virtual void InitRenderer(vtkRenderWindow *renderwindow); //##Documentation //## @brief Set the initial size. Called by RenderWindow after it has become //## visible for the first time. virtual void InitSize(int w, int h); //##Documentation //## @brief Draws a point on the widget. //## Should be used during conferences to show the position of the remote mouse virtual void DrawOverlayMouse(Point2D &p2d); //##Documentation //## @brief Set/Get the WorldGeometry (m_WorldGeometry) for 3D and 2D rendering, that describing the //## (maximal) area to be rendered. //## //## Depending of the type of the passed BaseGeometry more or less information can be extracted: //## \li if it is a PlaneGeometry (which is a sub-class of BaseGeometry), m_CurrentWorldPlaneGeometry is //## also set to point to it. m_WorldTimeGeometry is set to nullptr. //## \li if it is a TimeGeometry, m_WorldTimeGeometry is also set to point to it. //## If m_WorldTimeGeometry contains instances of SlicedGeometry3D, m_CurrentWorldPlaneGeometry is set to //## one of geometries stored in the SlicedGeometry3D according to the value of m_Slice; otherwise //## a PlaneGeometry describing the top of the bounding-box of the BaseGeometry is set as the //## m_CurrentWorldPlaneGeometry. //## \li otherwise a PlaneGeometry describing the top of the bounding-box of the BaseGeometry //## is set as the m_CurrentWorldPlaneGeometry. m_WorldTimeGeometry is set to nullptr. //## @todo add calculation of PlaneGeometry describing the top of the bounding-box of the BaseGeometry //## when the passed BaseGeometry is not sliced. //## \sa m_WorldGeometry //## \sa m_WorldTimeGeometry //## \sa m_CurrentWorldPlaneGeometry virtual void SetWorldGeometry3D(const BaseGeometry *geometry); virtual void SetWorldTimeGeometry(const mitk::TimeGeometry *geometry); /** * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(void SetWorldGeometry3D(TimeSlicedGeometry *geometry)); itkGetConstObjectMacro(WorldTimeGeometry, TimeGeometry) //##Documentation //## @brief Get the current 3D-worldgeometry (m_CurrentWorldGeometry) used for 3D-rendering itkGetConstObjectMacro(CurrentWorldGeometry, BaseGeometry) //##Documentation //## @brief Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering itkGetConstObjectMacro(CurrentWorldPlaneGeometry, PlaneGeometry) /** * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometry */ DEPRECATED(const PlaneGeometry *GetCurrentWorldGeometry2D()) { return GetCurrentWorldPlaneGeometry(); }; //##Documentation //## Calculates the bounds of the DataStorage (if it contains any valid data), //## creates a geometry from these bounds and sets it as world geometry of the renderer. //## //## Call this method to re-initialize the renderer to the current DataStorage //## (e.g. after loading an additional dataset), to ensure that the view is //## aligned correctly. //## \warn This is not implemented yet. virtual bool SetWorldGeometryToDataStorageBounds() { return false; } //##Documentation //## @brief Set/Get m_Slice which defines together with m_TimeStep the 2D geometry //## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry //## //## \sa m_Slice virtual void SetSlice(unsigned int slice); itkGetConstMacro(Slice, unsigned int) //##Documentation //## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry //## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry //## //## \sa m_TimeStep virtual void SetTimeStep(unsigned int timeStep); itkGetConstMacro(TimeStep, unsigned int) //##Documentation //## @brief Get the time-step of a BaseData object which //## exists at the time of the currently displayed content //## //## Returns -1 or mitk::BaseData::m_TimeSteps if there //## is no data at the current time. //## \sa GetTimeStep, m_TimeStep int GetTimeStep(const BaseData *data) const; //##Documentation //## @brief Get the time in ms of the currently displayed content //## //## \sa GetTimeStep, m_TimeStep ScalarType GetTime() const; //##Documentation //## @brief SetWorldGeometry is called according to the geometrySliceEvent, //## which is supposed to be a SliceNavigationController::GeometrySendEvent virtual void SetGeometry(const itk::EventObject &geometrySliceEvent); //##Documentation //## @brief UpdateWorldGeometry is called to re-read the 2D geometry from the //## slice navigation controller virtual void UpdateGeometry(const itk::EventObject &geometrySliceEvent); //##Documentation //## @brief SetSlice is called according to the geometrySliceEvent, //## which is supposed to be a SliceNavigationController::GeometrySliceEvent virtual void SetGeometrySlice(const itk::EventObject &geometrySliceEvent); //##Documentation //## @brief SetTimeStep is called according to the geometrySliceEvent, //## which is supposed to be a SliceNavigationController::GeometryTimeEvent virtual void SetGeometryTime(const itk::EventObject &geometryTimeEvent); //##Documentation //## @brief Get a DataNode pointing to a data object containing the current 2D-worldgeometry // m_CurrentWorldPlaneGeometry (for 2D rendering) itkGetObjectMacro(CurrentWorldPlaneGeometryNode, DataNode) /** * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometryNode */ DEPRECATED(DataNode *GetCurrentWorldGeometry2DNode()) { return GetCurrentWorldPlaneGeometryNode(); }; //##Documentation //## @brief Sets timestamp of CurrentWorldPlaneGeometry and forces so reslicing in that renderwindow void SendUpdateSlice(); //##Documentation //## @brief Get timestamp of last call of SetCurrentWorldPlaneGeometry unsigned long GetCurrentWorldPlaneGeometryUpdateTime() { return m_CurrentWorldPlaneGeometryUpdateTime; } /** * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometryUpdateTime */ DEPRECATED(unsigned long GetCurrentWorldGeometry2DUpdateTime()) { return GetCurrentWorldPlaneGeometryUpdateTime(); }; //##Documentation //## @brief Get timestamp of last change of current TimeStep unsigned long GetTimeStepUpdateTime() { return m_TimeStepUpdateTime; } //##Documentation //## @brief Perform a picking: find the x,y,z world coordinate of a //## display x,y coordinate. //## @warning Has to be overwritten in subclasses for the 3D-case. //## //## Implemented here only for 2D-rendering virtual void PickWorldPoint(const Point2D &diplayPosition, Point3D &worldPosition) const = 0; /** \brief Determines the object (mitk::DataNode) closest to the current * position by means of picking * * \warning Implementation currently empty for 2D rendering; intended to be * implemented for 3D renderers */ virtual DataNode *PickObject(const Point2D & /*displayPosition*/, Point3D & /*worldPosition*/) const { return nullptr; } //##Documentation //## @brief Get the MapperSlotId to use. itkGetMacro(MapperID, MapperSlotId) itkGetConstMacro(MapperID, MapperSlotId) //##Documentation //## @brief Set the MapperSlotId to use. itkSetMacro(MapperID, MapperSlotId) virtual int *GetSize() const; virtual int *GetViewportSize() const; void SetSliceNavigationController(SliceNavigationController *SlicenavigationController); itkGetObjectMacro(CameraController, CameraController) itkGetObjectMacro(SliceNavigationController, SliceNavigationController) itkGetObjectMacro(CameraRotationController, CameraRotationController) itkGetMacro(EmptyWorldGeometry, bool) //##Documentation //## @brief Tells if the displayed region is shifted and rescaled if the render window is resized. itkGetMacro(KeepDisplayedRegion, bool) //##Documentation //## @brief Tells if the displayed region should be shifted and rescaled if the render window is resized. itkSetMacro(KeepDisplayedRegion, bool) //##Documentation //## @brief get the name of the Renderer //## @note const char *GetName() const { return m_Name.c_str(); } //##Documentation //## @brief get the x_size of the RendererWindow //## @note int GetSizeX() const { return GetSize()[0]; } //##Documentation //## @brief get the y_size of the RendererWindow //## @note int GetSizeY() const { return GetSize()[1]; } const double *GetBounds() const; void RequestUpdate(); void ForceImmediateUpdate(); /** Returns number of mappers which are visible and have level-of-detail * rendering enabled */ unsigned int GetNumberOfVisibleLODEnabledMappers() const; ///** //* \brief Setter for the RenderingManager that handles this instance of BaseRenderer //*/ // void SetRenderingManager( mitk::RenderingManager* ); /** * \brief Getter for the RenderingManager that handles this instance of BaseRenderer */ virtual mitk::RenderingManager *GetRenderingManager() const; //##Documentation //## @brief This method converts a display point to the 3D world index //## using the geometry of the renderWindow. void DisplayToWorld(const Point2D &displayPoint, Point3D &worldIndex) const; //##Documentation //## @brief This method converts a display point to the 2D world index, mapped onto the display plane //## using the geometry of the renderWindow. void DisplayToPlane(const Point2D &displayPoint, Point2D &planePointInMM) const; //##Documentation //## @brief This method converts a 3D world index to the display point //## using the geometry of the renderWindow. void WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const; //##Documentation //## @brief This method converts a 3D world index to the point on the viewport //## using the geometry of the renderWindow. void WorldToView(const Point3D &worldIndex, Point2D &viewPoint) const; //##Documentation //## @brief This method converts a 2D plane coordinate to the display point //## using the geometry of the renderWindow. void PlaneToDisplay(const Point2D &planePointInMM, Point2D &displayPoint) const; //##Documentation //## @brief This method converts a 2D plane coordinate to the point on the viewport //## using the geometry of the renderWindow. void PlaneToView(const Point2D &planePointInMM, Point2D &viewPoint) const; double GetScaleFactorMMPerDisplayUnit() const; Point2D GetDisplaySizeInMM() const; Point2D GetViewportSizeInMM() const; Point2D GetOriginInMM() const; itkGetConstMacro(ConstrainZoomingAndPanning, bool) virtual void SetConstrainZoomingAndPanning(bool constrain); /** * \brief Provides (1) world coordinates for a given mouse position and (2) * translates mousePosition to Display coordinates * \deprecated Map2DRendererPositionTo3DWorldPosition is deprecated. Please use DisplayToWorld instead. */ DEPRECATED(virtual Point3D Map2DRendererPositionTo3DWorldPosition(const Point2D &mousePosition) const); protected: ~BaseRenderer() override; //##Documentation //## @brief Call update of all mappers. To be implemented in subclasses. virtual void Update() = 0; vtkRenderWindow *m_RenderWindow; vtkRenderer *m_VtkRenderer; //##Documentation //## @brief MapperSlotId to use. Defines which kind of mapper (e.g., 2D or 3D) shoud be used. MapperSlotId m_MapperID; //##Documentation //## @brief The DataStorage that is used for rendering. DataStorage::Pointer m_DataStorage; //##Documentation //## @brief The RenderingManager that manages this instance RenderingManager::Pointer m_RenderingManager; //##Documentation //## @brief Timestamp of last call of Update(). unsigned long m_LastUpdateTime; //##Documentation //## @brief CameraController for 3D rendering //## @note preliminary. itk::SmartPointer m_CameraController; SliceNavigationController::Pointer m_SliceNavigationController; CameraRotationController::Pointer m_CameraRotationController; //##Documentation //## @brief Sets m_CurrentWorldPlaneGeometry virtual void SetCurrentWorldPlaneGeometry(const PlaneGeometry *geometry2d); /** * \deprecatedSince{2014_10} Please use SetCurrentWorldPlaneGeometry */ DEPRECATED(void SetCurrentWorldGeometry2D(PlaneGeometry *geometry2d)) { SetCurrentWorldPlaneGeometry(geometry2d); }; //##Documentation //## @brief Sets m_CurrentWorldGeometry virtual void SetCurrentWorldGeometry(const BaseGeometry *geometry); private: //##Documentation //## m_WorldTimeGeometry is set by SetWorldGeometry if the passed BaseGeometry is a //## TimeGeometry (or a sub-class of it). If it contains instances of SlicedGeometry3D, //## m_Slice and m_TimeStep (set via SetSlice and SetTimeStep, respectively) define //## which 2D geometry stored in m_WorldTimeGeometry (if available) //## is used as m_CurrentWorldPlaneGeometry. //## \sa m_CurrentWorldPlaneGeometry TimeGeometry::ConstPointer m_WorldTimeGeometry; //##Documentation //## Pointer to the current 3D-worldgeometry. BaseGeometry::ConstPointer m_CurrentWorldGeometry; //##Documentation //## Pointer to the current 2D-worldgeometry. The 2D-worldgeometry //## describes the maximal area (2D manifold) to be rendered in case we //## are doing 2D-rendering. //## It is const, since we are not allowed to change it (it may be taken //## directly from the geometry of an image-slice and thus it would be //## very strange when suddenly the image-slice changes its geometry). PlaneGeometry::Pointer m_CurrentWorldPlaneGeometry; //##Documentation //## Defines together with m_Slice which 2D geometry stored in m_WorldTimeGeometry //## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep). //## \sa m_WorldTimeGeometry unsigned int m_Slice; //##Documentation //## Defines together with m_TimeStep which 2D geometry stored in m_WorldTimeGeometry //## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep). //## \sa m_WorldTimeGeometry unsigned int m_TimeStep; //##Documentation //## @brief timestamp of last call of SetWorldGeometry itk::TimeStamp m_CurrentWorldPlaneGeometryUpdateTime; //##Documentation //## @brief timestamp of last change of the current time step itk::TimeStamp m_TimeStepUpdateTime; //##Documentation //## @brief Helper class which establishes connection between Interactors and Dispatcher via a common DataStorage. BindDispatcherInteractor *m_BindDispatcherInteractor; //##Documentation //## @brief Tells if the displayed region should be shifted or rescaled if the render window is resized. bool m_KeepDisplayedRegion; protected: void PrintSelf(std::ostream &os, itk::Indent indent) const override; //##Documentation //## Data object containing the m_CurrentWorldPlaneGeometry defined above. PlaneGeometryData::Pointer m_CurrentWorldPlaneGeometryData; //##Documentation //## DataNode objects containing the m_CurrentWorldPlaneGeometryData defined above. DataNode::Pointer m_CurrentWorldPlaneGeometryNode; //##Documentation //## @brief test only unsigned long m_CurrentWorldPlaneGeometryTransformTime; std::string m_Name; double m_Bounds[6]; bool m_EmptyWorldGeometry; typedef std::set LODEnabledMappersType; /** Number of mappers which are visible and have level-of-detail * rendering enabled */ unsigned int m_NumberOfVisibleLODEnabledMappers; // Local Storage Handling for mappers protected: std::list m_RegisteredLocalStorageHandlers; bool m_ConstrainZoomingAndPanning; public: void RemoveAllLocalStorages(); void RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh); void UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh); }; } // namespace mitk #endif /* BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 */ diff --git a/Modules/Core/include/mitkRenderWindow.h b/Modules/Core/include/mitkRenderWindow.h index fe2522dfbd..29fe7911ac 100644 --- a/Modules/Core/include/mitkRenderWindow.h +++ b/Modules/Core/include/mitkRenderWindow.h @@ -1,100 +1,99 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66ASDF #define MITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66ASDF #include #include "mitkRenderWindowBase.h" namespace mitk { class vtkEventProvider; /** * \brief mitkRenderWindow integrates the MITK rendering mechanism into VTK and * is NOT QT dependent * * * \ingroup Renderer */ class MITKCORE_EXPORT RenderWindow : public mitk::RenderWindowBase, public itk::Object { public: mitkClassMacroItkParent(RenderWindow, itk::Object); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(Self, vtkRenderWindow *); mitkNewMacro2Param(Self, vtkRenderWindow *, const char *); - mitkNewMacro3Param(Self, vtkRenderWindow *, const char *, mitk::RenderingManager *); - mitkNewMacro4Param( - Self, vtkRenderWindow *, const char *, mitk::RenderingManager *, mitk::BaseRenderer::RenderingMode::Type); + mitkNewMacro3Param(Self, vtkRenderWindow *, const char *, RenderingManager *); + mitkNewMacro4Param(Self, vtkRenderWindow *, const char *, RenderingManager *, BaseRenderer::RenderingMode); ~RenderWindow() override; vtkRenderWindow *GetVtkRenderWindow() override; vtkRenderWindowInteractor *GetVtkRenderWindowInteractor() override; // Set Layout Index to define the Layout Type void SetLayoutIndex(unsigned int layoutIndex); // Get Layout Index to define the Layout Type unsigned int GetLayoutIndex(); // MenuWidget need to update the Layout Design List when Layout had changed void LayoutDesignListChanged(int layoutDesignIndex); void FullScreenMode(bool state); /** * \brief Convenience method to set the size of an mitkRenderWindow. * * This method sets the size of the vtkRenderWindow and tells the * rendering that the size has changed -> adapts displayGeometry, etc. */ void SetSize(int width, int height); /** * \brief Initializes the mitkVtkEventProvider to listen to the * currently used vtkInteractorStyle. * * This method makes sure that the internal mitkVtkEventProvider * listens to the correct vtkInteractorStyle. * This makes sure that VTK-Events are correctly translated into * MITK-Events. * * \warn This method needs to be called MANUALLY as soon as the MapperID * for this RenderWindow is changed or the vtkInteractorStyle is modified * somehow else! */ void ReinitEventProvider(); protected: RenderWindow(vtkRenderWindow *existingRenderWindow = nullptr, const char *name = "unnamed renderer", - mitk::RenderingManager *rm = nullptr, - mitk::BaseRenderer::RenderingMode::Type rmtype = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing); + RenderingManager *rm = nullptr, + BaseRenderer::RenderingMode rmtype = BaseRenderer::RenderingMode::FastApproximateAntiAliasing); void ResetView(); vtkRenderWindow *m_vtkRenderWindow; vtkRenderWindowInteractor *m_vtkRenderWindowInteractor; vtkEventProvider *m_vtkMitkEventProvider; private: }; } // namespace #endif /* MITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66ASDF */ diff --git a/Modules/Core/include/mitkRenderWindowBase.h b/Modules/Core/include/mitkRenderWindowBase.h index ef2a23e442..a56f2b6b42 100644 --- a/Modules/Core/include/mitkRenderWindowBase.h +++ b/Modules/Core/include/mitkRenderWindowBase.h @@ -1,83 +1,83 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKRENDERWINDOWBASE_H_HEADER_INCLUDED_C1C40D66ASDF #define MITKRENDERWINDOWBASE_H_HEADER_INCLUDED_C1C40D66ASDF #include #include "mitkCameraRotationController.h" #include "mitkSliceNavigationController.h" #include "mitkVtkPropRenderer.h" #include "vtkMitkRenderProp.h" #include "mitkInteractionEvent.h" namespace mitk { /** * \brief Base class of MITK RenderWindows * * This class sets up the MITK rendering mechanism and it's integration into VTK. * * Currently, there are two specific implementations of this abstract class: * QmitkRenderWindow, inerhits from the QVTKWidget and is the matured way for MITK rendering * mitkRenderWindow is a new, QT-independent RenderWindow implementation * * \ingroup Renderer */ class MITKCORE_EXPORT RenderWindowBase { public: // mitkClassMacroItkParent(RenderWindowBase,itk::Object); // itkFactorylessNewMacro(Self) // itkCloneMacro(Self) virtual ~RenderWindowBase(); void InitRenderer(); virtual mitk::SliceNavigationController *GetSliceNavigationController(); virtual mitk::CameraRotationController *GetCameraRotationController(); virtual mitk::BaseController *GetController(); virtual mitk::VtkPropRenderer *GetRenderer(); virtual vtkRenderWindow *GetVtkRenderWindow() = 0; virtual vtkRenderWindowInteractor *GetVtkRenderWindowInteractor() = 0; virtual bool HandleEvent(InteractionEvent *interactionEvent); protected: RenderWindowBase(); // helper functions: within constructors and destructors classes are not polymorph. void Initialize( - mitk::RenderingManager *renderingManager = nullptr, + RenderingManager *renderingManager = nullptr, const char *name = "unnamed renderer", - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing); + BaseRenderer::RenderingMode renderingMode = BaseRenderer::RenderingMode::FastApproximateAntiAliasing); void Destroy(); mitk::VtkPropRenderer::Pointer m_Renderer; vtkMitkRenderProp *m_RenderProp; bool m_InResize; private: }; } #endif /* MITKRENDERWINDOWBASE_H_HEADER_INCLUDED_C1C40D66ASDF */ diff --git a/Modules/Core/include/mitkVtkPropRenderer.h b/Modules/Core/include/mitkVtkPropRenderer.h index 5eeae29d8f..28b7738229 100644 --- a/Modules/Core/include/mitkVtkPropRenderer.h +++ b/Modules/Core/include/mitkVtkPropRenderer.h @@ -1,258 +1,258 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkVtkPropRenderer_h #define mitkVtkPropRenderer_h #include "mitkBaseRenderer.h" #include #include #include #include #include #include class vtkRenderWindow; class vtkLight; class vtkLightKit; class vtkWorldPointPicker; class vtkPointPicker; class vtkCellPicker; class vtkTextActor; class vtkTextProperty; class vtkAssemblyPath; #include #include namespace mitk { class Mapper; /*! \brief VtkPropRenderer VtkPropRenderer organizes the MITK rendering process. The MITK rendering process is completely integrated into the VTK rendering pipeline. The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes. VtkPropRenderer replaces the old OpenGLRenderer. \sa rendering \ingroup rendering */ class MITKCORE_EXPORT VtkPropRenderer : public BaseRenderer { // Workaround for Displaylistbug private: bool didCount; void checkState(); // Workaround END public: mitkClassMacro(VtkPropRenderer, BaseRenderer); mitkNewMacro3Param(VtkPropRenderer, const char *, vtkRenderWindow *, mitk::RenderingManager *); mitkNewMacro4Param(VtkPropRenderer, const char *, vtkRenderWindow *, mitk::RenderingManager *, - mitk::BaseRenderer::RenderingMode::Type); + mitk::BaseRenderer::RenderingMode); typedef std::map MappersMapType; // Render - called by vtkMitkRenderProp, returns the number of props rendered enum RenderType { Opaque, Translucent, Overlay, Volumetric }; /** \brief Store/propagate vtkInformation during rendering */ void SetPropertyKeys(vtkInformation *info); int Render(RenderType type); /** \brief This methods contains all method neceassary before a VTK Render() call */ virtual void PrepareRender(); // Active current renderwindow virtual void MakeCurrent(); void SetDataStorage( mitk::DataStorage *storage) override; ///< set the datastorage that will be used for rendering void InitRenderer(vtkRenderWindow *renderwindow) override; virtual void Update(mitk::DataNode *datatreenode); void SetMapperID(const MapperSlotId mapperId) override; // Size void InitSize(int w, int h) override; void Resize(int w, int h) override; // Picking enum PickingMode { WorldPointPicking, PointPicking, CellPicking }; /** \brief Set the picking mode. This method is used to set the picking mode for 3D object picking. The user can select one of the three options WorldPointPicking, PointPicking and CellPicking. The first option uses the zBuffer from graphics rendering, the second uses the 3D points from the closest surface mesh, and the third option uses the cells of that mesh. The last option is the slowest, the first one the fastest. However, the first option cannot use transparent data object and the tolerance of the picked position to the selected point should be considered. PointPicking also need a tolerance around the picking position to select the closest point in the mesh. The CellPicker performs very well, if the foreground surface part (i.e. the surfacepart that is closest to the scene's cameras) needs to be picked. */ itkSetEnumMacro(PickingMode, PickingMode); itkGetEnumMacro(PickingMode, PickingMode); void PickWorldPoint(const Point2D &displayPoint, Point3D &worldPoint) const override; mitk::DataNode *PickObject(const Point2D &displayPosition, Point3D &worldPosition) const override; /** * @brief WriteSimpleText Write a text in a renderwindow. * * Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. * * @deprecatedSince{2015_05} Please use mitkTextOverlay2D instead. * See mitkTextOverlay2DRenderingTest for an example. */ DEPRECATED(int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0, float opacity = 1.0)); /** * @brief CGetTextLabelProperty an be used in order to get a vtkTextProperty for * a specific text_id. This property enables the setup of font, font size, etc. * @param text_id the id of the text property. * @deprecatedSince{2015_05} Please use mitkTextOverlay2D instead. * See mitkTextOverlay2DRenderingTest for an example. */ DEPRECATED(vtkTextProperty *GetTextLabelProperty(int text_id)); /** This method calculates the bounds of the DataStorage (if it contains any * valid data), creates a geometry from these bounds and sets it as world * geometry of the renderer. * * Call this method to re-initialize the renderer to the current DataStorage * (e.g. after loading an additional dataset), to ensure that the view is * aligned correctly. */ bool SetWorldGeometryToDataStorageBounds() override; /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ void InitPathTraversal(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ vtkAssemblyPath *GetNextPath(); int GetNumberOfPaths(); const vtkWorldPointPicker *GetWorldPointPicker() const; const vtkPointPicker *GetPointPicker() const; const vtkCellPicker *GetCellPicker() const; /** * \brief Release vtk-based graphics resources. Called by * vtkMitkRenderProp::ReleaseGraphicsResources. */ virtual void ReleaseGraphicsResources(vtkWindow *renWin); MappersMapType GetMappersMap() const; static bool useImmediateModeRendering(); protected: VtkPropRenderer( const char *name = "VtkPropRenderer", vtkRenderWindow *renWin = nullptr, mitk::RenderingManager *rm = nullptr, - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing); + mitk::BaseRenderer::RenderingMode renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing); ~VtkPropRenderer() override; void Update() override; static void RenderingCallback(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata); virtual void UpdatePaths(); // apply transformations and properties recursively private: vtkSmartPointer m_Paths; vtkTimeStamp m_PathTime; // prepare all mitk::mappers for rendering void PrepareMapperQueue(); /** \brief Propagate vtkInformation object to all VTK-based mappers */ void PropagateRenderInfoToMappers(); /** \brief Set parallel projection, remove the interactor and the lights of VTK. */ bool Initialize2DvtkCamera(); bool m_InitNeeded; bool m_ResizeNeeded; MapperSlotId m_CameraInitializedForMapperID; // Picking vtkWorldPointPicker *m_WorldPointPicker; vtkPointPicker *m_PointPicker; vtkCellPicker *m_CellPicker; PickingMode m_PickingMode; // Explicit use of SmartPointer to avoid circular #includes itk::SmartPointer m_CurrentWorldPlaneGeometryMapper; vtkLightKit *m_LightKit; // sorted list of mappers MappersMapType m_MappersMap; // rendering of text vtkRenderer *m_TextRenderer; typedef std::map TextMapType; TextMapType m_TextCollection; /** \brief Information passed from VTK's rendering to props. Used e.g. by vtkDualDepthPeelingPass to pass information. Not passing this to all the MITK generated vktProps will essentially break VTK's depth peeling / transparency. */ vtkInformation* m_VtkRenderInfo = nullptr; }; } // namespace mitk #endif /* mitkVtkPropRenderer_h */ diff --git a/Modules/Core/src/Rendering/mitkBaseRenderer.cpp b/Modules/Core/src/Rendering/mitkBaseRenderer.cpp index b7fec9d925..ed9225bacc 100644 --- a/Modules/Core/src/Rendering/mitkBaseRenderer.cpp +++ b/Modules/Core/src/Rendering/mitkBaseRenderer.cpp @@ -1,787 +1,787 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkBaseRenderer.h" #include "mitkMapper.h" #include "mitkResliceMethodProperty.h" // Geometries #include "mitkPlaneGeometry.h" #include "mitkSlicedGeometry3D.h" // Controllers #include "mitkCameraController.h" #include "mitkCameraRotationController.h" #include "mitkSliceNavigationController.h" #include "mitkVtkLayerController.h" #include "mitkInteractionConst.h" #include "mitkProperties.h" #include "mitkWeakPointerProperty.h" // VTK #include #include #include #include #include #include #include mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::baseRendererMap; mitk::BaseRenderer *mitk::BaseRenderer::GetInstance(vtkRenderWindow *renWin) { for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit) { if ((*mapit).first == renWin) return (*mapit).second; } return nullptr; } void mitk::BaseRenderer::AddInstance(vtkRenderWindow *renWin, BaseRenderer *baseRenderer) { if (renWin == nullptr || baseRenderer == nullptr) return; // ensure that no BaseRenderer is managed twice mitk::BaseRenderer::RemoveInstance(renWin); baseRendererMap.insert(BaseRendererMapType::value_type(renWin, baseRenderer)); } void mitk::BaseRenderer::RemoveInstance(vtkRenderWindow *renWin) { auto mapit = baseRendererMap.find(renWin); if (mapit != baseRendererMap.end()) baseRendererMap.erase(mapit); } mitk::BaseRenderer *mitk::BaseRenderer::GetByName(const std::string &name) { for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit) { if ((*mapit).second->m_Name == name) return (*mapit).second; } return nullptr; } vtkRenderWindow *mitk::BaseRenderer::GetRenderWindowByName(const std::string &name) { for (auto mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); ++mapit) { if ((*mapit).second->m_Name == name) return (*mapit).first; } return nullptr; } mitk::BaseRenderer::BaseRenderer(const char *name, vtkRenderWindow *renWin, mitk::RenderingManager *rm, - RenderingMode::Type renderingMode) + RenderingMode renderingMode) : m_RenderWindow(nullptr), m_VtkRenderer(nullptr), m_MapperID(defaultMapper), m_DataStorage(nullptr), m_RenderingManager(rm), m_LastUpdateTime(0), m_CameraController(nullptr), m_SliceNavigationController(nullptr), m_CameraRotationController(nullptr), m_WorldTimeGeometry(nullptr), m_CurrentWorldGeometry(nullptr), m_CurrentWorldPlaneGeometry(nullptr), m_Slice(0), m_TimeStep(), m_CurrentWorldPlaneGeometryUpdateTime(), m_TimeStepUpdateTime(), m_KeepDisplayedRegion(true), m_CurrentWorldPlaneGeometryData(nullptr), m_CurrentWorldPlaneGeometryNode(nullptr), m_CurrentWorldPlaneGeometryTransformTime(0), m_Name(name), m_EmptyWorldGeometry(true), m_NumberOfVisibleLODEnabledMappers(0) { m_Bounds[0] = 0; m_Bounds[1] = 0; m_Bounds[2] = 0; m_Bounds[3] = 0; m_Bounds[4] = 0; m_Bounds[5] = 0; if (name != nullptr) { m_Name = name; } else { m_Name = "unnamed renderer"; itkWarningMacro(<< "Created unnamed renderer. Bad for serialization. Please choose a name."); } if (renWin != nullptr) { m_RenderWindow = renWin; m_RenderWindow->Register(nullptr); } else { itkWarningMacro(<< "Created mitkBaseRenderer without vtkRenderWindow present."); } // instances.insert( this ); // adding this BaseRenderer to the List of all BaseRenderer m_BindDispatcherInteractor = new mitk::BindDispatcherInteractor(GetName()); WeakPointerProperty::Pointer rendererProp = WeakPointerProperty::New((itk::Object *)this); m_CurrentWorldPlaneGeometry = mitk::PlaneGeometry::New(); m_CurrentWorldPlaneGeometryData = mitk::PlaneGeometryData::New(); m_CurrentWorldPlaneGeometryData->SetPlaneGeometry(m_CurrentWorldPlaneGeometry); m_CurrentWorldPlaneGeometryNode = mitk::DataNode::New(); m_CurrentWorldPlaneGeometryNode->SetData(m_CurrentWorldPlaneGeometryData); m_CurrentWorldPlaneGeometryNode->GetPropertyList()->SetProperty("renderer", rendererProp); m_CurrentWorldPlaneGeometryNode->GetPropertyList()->SetProperty("layer", IntProperty::New(1000)); m_CurrentWorldPlaneGeometryNode->SetProperty("reslice.thickslices", mitk::ResliceMethodProperty::New()); m_CurrentWorldPlaneGeometryNode->SetProperty("reslice.thickslices.num", mitk::IntProperty::New(1)); m_CurrentWorldPlaneGeometryTransformTime = m_CurrentWorldPlaneGeometryNode->GetVtkTransform()->GetMTime(); mitk::SliceNavigationController::Pointer sliceNavigationController = mitk::SliceNavigationController::New(); sliceNavigationController->SetRenderer(this); sliceNavigationController->ConnectGeometrySliceEvent(this); sliceNavigationController->ConnectGeometryUpdateEvent(this); sliceNavigationController->ConnectGeometryTimeEvent(this, false); m_SliceNavigationController = sliceNavigationController; m_CameraRotationController = mitk::CameraRotationController::New(); m_CameraRotationController->SetRenderWindow(m_RenderWindow); m_CameraRotationController->AcquireCamera(); m_CameraController = mitk::CameraController::New(); m_CameraController->SetRenderer(this); m_VtkRenderer = vtkRenderer::New(); m_VtkRenderer->UseDepthPeelingOn(); m_VtkRenderer->UseDepthPeelingForVolumesOn(); m_VtkRenderer->SetMaximumNumberOfPeels(16); // This could be made adjustable in the Preferences m_VtkRenderer->SetOcclusionRatio(0.0); if (RenderingMode::FastApproximateAntiAliasing == renderingMode) m_VtkRenderer->UseFXAAOn(); if (nullptr == mitk::VtkLayerController::GetInstance(m_RenderWindow)) mitk::VtkLayerController::AddInstance(m_RenderWindow, m_VtkRenderer); mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer); } mitk::BaseRenderer::~BaseRenderer() { if (m_VtkRenderer != nullptr) { m_VtkRenderer->Delete(); m_VtkRenderer = nullptr; } if (m_CameraController.IsNotNull()) m_CameraController->SetRenderer(nullptr); mitk::VtkLayerController::RemoveInstance(m_RenderWindow); RemoveAllLocalStorages(); m_DataStorage = nullptr; if (m_BindDispatcherInteractor != nullptr) { delete m_BindDispatcherInteractor; } if (m_RenderWindow != nullptr) { m_RenderWindow->Delete(); m_RenderWindow = nullptr; } } void mitk::BaseRenderer::RemoveAllLocalStorages() { this->InvokeEvent(mitk::BaseRenderer::RendererResetEvent()); std::list::iterator it; for (it = m_RegisteredLocalStorageHandlers.begin(); it != m_RegisteredLocalStorageHandlers.end(); ++it) (*it)->ClearLocalStorage(this, false); m_RegisteredLocalStorageHandlers.clear(); } void mitk::BaseRenderer::RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh) { m_RegisteredLocalStorageHandlers.push_back(lsh); } mitk::Dispatcher::Pointer mitk::BaseRenderer::GetDispatcher() const { return m_BindDispatcherInteractor->GetDispatcher(); } void mitk::BaseRenderer::UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh) { m_RegisteredLocalStorageHandlers.remove(lsh); } void mitk::BaseRenderer::SetDataStorage(DataStorage *storage) { if (storage != m_DataStorage && storage != nullptr) { m_DataStorage = storage; m_BindDispatcherInteractor->SetDataStorage(m_DataStorage); this->Modified(); } } const mitk::BaseRenderer::MapperSlotId mitk::BaseRenderer::defaultMapper = 1; void mitk::BaseRenderer::Paint() { } void mitk::BaseRenderer::Initialize() { } void mitk::BaseRenderer::Resize(int w, int h) { this->m_RenderWindow->SetSize(w, h); } void mitk::BaseRenderer::InitRenderer(vtkRenderWindow *renderwindow) { if (m_RenderWindow != renderwindow) { if (m_RenderWindow != nullptr) { m_RenderWindow->Delete(); } m_RenderWindow = renderwindow; if (m_RenderWindow != nullptr) { m_RenderWindow->Register(nullptr); } } RemoveAllLocalStorages(); if (m_CameraController.IsNotNull()) { m_CameraController->SetRenderer(this); } } void mitk::BaseRenderer::InitSize(int w, int h) { this->m_RenderWindow->SetSize(w, h); } void mitk::BaseRenderer::SetSlice(unsigned int slice) { if (m_Slice != slice) { m_Slice = slice; if (m_WorldTimeGeometry.IsNotNull()) { // get world geometry which may be rotated, for the current time step SlicedGeometry3D *slicedWorldGeometry = dynamic_cast(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer()); if (slicedWorldGeometry != nullptr) { // if slice position is part of the world geometry... if (m_Slice >= slicedWorldGeometry->GetSlices()) // set the current worldplanegeomety as the selected 2D slice of the world geometry m_Slice = slicedWorldGeometry->GetSlices() - 1; SetCurrentWorldPlaneGeometry(slicedWorldGeometry->GetPlaneGeometry(m_Slice)); SetCurrentWorldGeometry(slicedWorldGeometry); } } else Modified(); } } void mitk::BaseRenderer::SetTimeStep(unsigned int timeStep) { if (m_TimeStep != timeStep) { m_TimeStep = timeStep; m_TimeStepUpdateTime.Modified(); if (m_WorldTimeGeometry.IsNotNull()) { if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps()) m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1; SlicedGeometry3D *slicedWorldGeometry = dynamic_cast(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer()); if (slicedWorldGeometry != nullptr) { SetCurrentWorldPlaneGeometry(slicedWorldGeometry->GetPlaneGeometry(m_Slice)); SetCurrentWorldGeometry(slicedWorldGeometry); } } else Modified(); } } int mitk::BaseRenderer::GetTimeStep(const mitk::BaseData *data) const { if ((data == nullptr) || (data->IsInitialized() == false)) { return -1; } return data->GetTimeGeometry()->TimePointToTimeStep(GetTime()); } mitk::ScalarType mitk::BaseRenderer::GetTime() const { if (m_WorldTimeGeometry.IsNull()) { return 0; } else { ScalarType timeInMS = m_WorldTimeGeometry->TimeStepToTimePoint(GetTimeStep()); if (timeInMS == itk::NumericTraits::NonpositiveMin()) return 0; else return timeInMS; } } void mitk::BaseRenderer::SetWorldTimeGeometry(const mitk::TimeGeometry *geometry) { assert(geometry != nullptr); itkDebugMacro("setting WorldTimeGeometry to " << geometry); if (m_WorldTimeGeometry != geometry) { if (geometry->GetBoundingBoxInWorld()->GetDiagonalLength2() == 0) return; m_WorldTimeGeometry = geometry; itkDebugMacro("setting WorldTimeGeometry to " << m_WorldTimeGeometry); if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps()) m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1; BaseGeometry *geometry3d; geometry3d = m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep); SetWorldGeometry3D(geometry3d); } } void mitk::BaseRenderer::SetWorldGeometry3D(const mitk::BaseGeometry *geometry) { itkDebugMacro("setting WorldGeometry3D to " << geometry); if (geometry->GetBoundingBox()->GetDiagonalLength2() == 0) return; const SlicedGeometry3D *slicedWorldGeometry; slicedWorldGeometry = dynamic_cast(geometry); PlaneGeometry::ConstPointer geometry2d; if (slicedWorldGeometry != nullptr) { if (m_Slice >= slicedWorldGeometry->GetSlices() && (m_Slice != 0)) m_Slice = slicedWorldGeometry->GetSlices() - 1; geometry2d = slicedWorldGeometry->GetPlaneGeometry(m_Slice); if (geometry2d.IsNull()) { PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); plane->InitializeStandardPlane(slicedWorldGeometry); geometry2d = plane; } SetCurrentWorldGeometry(slicedWorldGeometry); } else { geometry2d = dynamic_cast(geometry); if (geometry2d.IsNull()) { PlaneGeometry::Pointer plane = PlaneGeometry::New(); plane->InitializeStandardPlane(geometry); geometry2d = plane; } SetCurrentWorldGeometry(geometry); } SetCurrentWorldPlaneGeometry(geometry2d); // calls Modified() if (m_CurrentWorldPlaneGeometry.IsNull()) itkWarningMacro("m_CurrentWorldPlaneGeometry is nullptr"); } void mitk::BaseRenderer::SetCurrentWorldPlaneGeometry(const mitk::PlaneGeometry *geometry2d) { if (m_CurrentWorldPlaneGeometry != geometry2d) { m_CurrentWorldPlaneGeometry = geometry2d->Clone(); m_CurrentWorldPlaneGeometryData->SetPlaneGeometry(m_CurrentWorldPlaneGeometry); m_CurrentWorldPlaneGeometryUpdateTime.Modified(); Modified(); } } void mitk::BaseRenderer::SendUpdateSlice() { m_CurrentWorldPlaneGeometryUpdateTime.Modified(); } int *mitk::BaseRenderer::GetSize() const { return this->m_RenderWindow->GetSize(); } int *mitk::BaseRenderer::GetViewportSize() const { return this->m_VtkRenderer->GetSize(); } void mitk::BaseRenderer::SetCurrentWorldGeometry(const mitk::BaseGeometry *geometry) { m_CurrentWorldGeometry = geometry; if (geometry == nullptr) { m_Bounds[0] = 0; m_Bounds[1] = 0; m_Bounds[2] = 0; m_Bounds[3] = 0; m_Bounds[4] = 0; m_Bounds[5] = 0; m_EmptyWorldGeometry = true; return; } BoundingBox::Pointer boundingBox = m_CurrentWorldGeometry->CalculateBoundingBoxRelativeToTransform(nullptr); const BoundingBox::BoundsArrayType &worldBounds = boundingBox->GetBounds(); m_Bounds[0] = worldBounds[0]; m_Bounds[1] = worldBounds[1]; m_Bounds[2] = worldBounds[2]; m_Bounds[3] = worldBounds[3]; m_Bounds[4] = worldBounds[4]; m_Bounds[5] = worldBounds[5]; if (boundingBox->GetDiagonalLength2() <= mitk::eps) m_EmptyWorldGeometry = true; else m_EmptyWorldGeometry = false; } void mitk::BaseRenderer::SetGeometry(const itk::EventObject &geometrySendEvent) { const auto *sendEvent = dynamic_cast(&geometrySendEvent); assert(sendEvent != nullptr); SetWorldTimeGeometry(sendEvent->GetTimeGeometry()); } void mitk::BaseRenderer::UpdateGeometry(const itk::EventObject &geometryUpdateEvent) { const auto *updateEvent = dynamic_cast(&geometryUpdateEvent); if (updateEvent == nullptr) return; if (m_CurrentWorldGeometry.IsNotNull()) { auto *slicedWorldGeometry = dynamic_cast(m_CurrentWorldGeometry.GetPointer()); if (slicedWorldGeometry) { PlaneGeometry *geometry2D = slicedWorldGeometry->GetPlaneGeometry(m_Slice); SetCurrentWorldPlaneGeometry(geometry2D); // calls Modified() } } } void mitk::BaseRenderer::SetGeometrySlice(const itk::EventObject &geometrySliceEvent) { const auto *sliceEvent = dynamic_cast(&geometrySliceEvent); assert(sliceEvent != nullptr); SetSlice(sliceEvent->GetPos()); } void mitk::BaseRenderer::SetGeometryTime(const itk::EventObject &geometryTimeEvent) { const auto *timeEvent = dynamic_cast(&geometryTimeEvent); assert(timeEvent != nullptr); SetTimeStep(timeEvent->GetPos()); } const double *mitk::BaseRenderer::GetBounds() const { return m_Bounds; } void mitk::BaseRenderer::DrawOverlayMouse(mitk::Point2D &itkNotUsed(p2d)) { MITK_INFO << "BaseRenderer::DrawOverlayMouse()- should be inconcret implementation OpenGLRenderer." << std::endl; } void mitk::BaseRenderer::RequestUpdate() { SetConstrainZoomingAndPanning(true); m_RenderingManager->RequestUpdate(this->m_RenderWindow); } void mitk::BaseRenderer::ForceImmediateUpdate() { m_RenderingManager->ForceImmediateUpdate(this->m_RenderWindow); } unsigned int mitk::BaseRenderer::GetNumberOfVisibleLODEnabledMappers() const { return m_NumberOfVisibleLODEnabledMappers; } mitk::RenderingManager *mitk::BaseRenderer::GetRenderingManager() const { return m_RenderingManager.GetPointer(); } /*! Sets the new Navigation controller */ void mitk::BaseRenderer::SetSliceNavigationController(mitk::SliceNavigationController *SlicenavigationController) { if (SlicenavigationController == nullptr) return; // copy worldgeometry SlicenavigationController->SetInputWorldTimeGeometry(SlicenavigationController->GetCreatedWorldGeometry()); SlicenavigationController->Update(); // set new m_SliceNavigationController = SlicenavigationController; m_SliceNavigationController->SetRenderer(this); if (m_SliceNavigationController.IsNotNull()) { m_SliceNavigationController->ConnectGeometrySliceEvent(this); m_SliceNavigationController->ConnectGeometryUpdateEvent(this); m_SliceNavigationController->ConnectGeometryTimeEvent(this, false); } } void mitk::BaseRenderer::DisplayToWorld(const Point2D &displayPoint, Point3D &worldIndex) const { if (m_MapperID == BaseRenderer::Standard2D) { double display[3], *world; // For the rigth z-position in display coordinates, take the focal point, convert it to display and use it for // correct depth. double *displayCoord; double cameraFP[4]; // Get camera focal point and position. Convert to display (screen) // coordinates. We need a depth value for z-buffer. this->GetVtkRenderer()->GetActiveCamera()->GetFocalPoint(cameraFP); cameraFP[3] = 0.0; this->GetVtkRenderer()->SetWorldPoint(cameraFP[0], cameraFP[1], cameraFP[2], cameraFP[3]); this->GetVtkRenderer()->WorldToDisplay(); displayCoord = this->GetVtkRenderer()->GetDisplayPoint(); // now convert the display point to world coordinates display[0] = displayPoint[0]; display[1] = displayPoint[1]; display[2] = displayCoord[2]; this->GetVtkRenderer()->SetDisplayPoint(display); this->GetVtkRenderer()->DisplayToWorld(); world = this->GetVtkRenderer()->GetWorldPoint(); for (int i = 0; i < 3; i++) { worldIndex[i] = world[i] / world[3]; } } else if (m_MapperID == BaseRenderer::Standard3D) { PickWorldPoint( displayPoint, worldIndex); // Seems to be the same code as above, but subclasses may contain different implementations. } return; } void mitk::BaseRenderer::DisplayToPlane(const Point2D &displayPoint, Point2D &planePointInMM) const { if (m_MapperID == BaseRenderer::Standard2D) { Point3D worldPoint; this->DisplayToWorld(displayPoint, worldPoint); this->m_CurrentWorldPlaneGeometry->Map(worldPoint, planePointInMM); } else if (m_MapperID == BaseRenderer::Standard3D) { MITK_WARN << "No conversion possible with 3D mapper."; return; } return; } void mitk::BaseRenderer::WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const { double world[4], *display; world[0] = worldIndex[0]; world[1] = worldIndex[1]; world[2] = worldIndex[2]; world[3] = 1.0; this->GetVtkRenderer()->SetWorldPoint(world); this->GetVtkRenderer()->WorldToDisplay(); display = this->GetVtkRenderer()->GetDisplayPoint(); displayPoint[0] = display[0]; displayPoint[1] = display[1]; return; } void mitk::BaseRenderer::WorldToView(const mitk::Point3D &worldIndex, mitk::Point2D &viewPoint) const { double world[4], *view; world[0] = worldIndex[0]; world[1] = worldIndex[1]; world[2] = worldIndex[2]; world[3] = 1.0; this->GetVtkRenderer()->SetWorldPoint(world); this->GetVtkRenderer()->WorldToView(); view = this->GetVtkRenderer()->GetViewPoint(); this->GetVtkRenderer()->ViewToNormalizedViewport(view[0], view[1], view[2]); viewPoint[0] = view[0] * this->GetViewportSize()[0]; viewPoint[1] = view[1] * this->GetViewportSize()[1]; return; } void mitk::BaseRenderer::PlaneToDisplay(const Point2D &planePointInMM, Point2D &displayPoint) const { Point3D worldPoint; this->m_CurrentWorldPlaneGeometry->Map(planePointInMM, worldPoint); this->WorldToDisplay(worldPoint, displayPoint); return; } void mitk::BaseRenderer::PlaneToView(const Point2D &planePointInMM, Point2D &viewPoint) const { Point3D worldPoint; this->m_CurrentWorldPlaneGeometry->Map(planePointInMM, worldPoint); this->WorldToView(worldPoint,viewPoint); return; } double mitk::BaseRenderer::GetScaleFactorMMPerDisplayUnit() const { if (this->GetMapperID() == BaseRenderer::Standard2D) { // GetParallelScale returns half of the height of the render window in mm. // Divided by the half size of the Display size in pixel givest the mm per pixel. return this->GetVtkRenderer()->GetActiveCamera()->GetParallelScale() * 2.0 / GetViewportSize()[1]; } else return 1.0; } mitk::Point2D mitk::BaseRenderer::GetDisplaySizeInMM() const { Point2D dispSizeInMM; dispSizeInMM[0] = GetSizeX() * GetScaleFactorMMPerDisplayUnit(); dispSizeInMM[1] = GetSizeY() * GetScaleFactorMMPerDisplayUnit(); return dispSizeInMM; } mitk::Point2D mitk::BaseRenderer::GetViewportSizeInMM() const { Point2D dispSizeInMM; dispSizeInMM[0] = GetViewportSize()[0] * GetScaleFactorMMPerDisplayUnit(); dispSizeInMM[1] = GetViewportSize()[1] * GetScaleFactorMMPerDisplayUnit(); return dispSizeInMM; } mitk::Point2D mitk::BaseRenderer::GetOriginInMM() const { Point2D originPx; originPx[0] = m_VtkRenderer->GetOrigin()[0]; originPx[1] = m_VtkRenderer->GetOrigin()[1]; Point2D displayGeometryOriginInMM; DisplayToPlane(originPx, displayGeometryOriginInMM); // top left of the render window (Origin) return displayGeometryOriginInMM; } void mitk::BaseRenderer::SetConstrainZoomingAndPanning(bool constrain) { m_ConstrainZoomingAndPanning = constrain; if (m_ConstrainZoomingAndPanning) { this->GetCameraController()->AdjustCameraToPlane(); } } mitk::Point3D mitk::BaseRenderer::Map2DRendererPositionTo3DWorldPosition(const Point2D &mousePosition) const { // DEPRECATED: Map2DRendererPositionTo3DWorldPosition is deprecated. use DisplayToWorldInstead Point3D position; DisplayToWorld(mousePosition, position); return position; } void mitk::BaseRenderer::PrintSelf(std::ostream &os, itk::Indent indent) const { os << indent << " MapperID: " << m_MapperID << std::endl; os << indent << " Slice: " << m_Slice << std::endl; os << indent << " TimeStep: " << m_TimeStep << std::endl; os << indent << " CurrentWorldPlaneGeometry: "; if (m_CurrentWorldPlaneGeometry.IsNull()) os << "nullptr" << std::endl; else m_CurrentWorldPlaneGeometry->Print(os, indent); os << indent << " CurrentWorldPlaneGeometryUpdateTime: " << m_CurrentWorldPlaneGeometryUpdateTime << std::endl; os << indent << " CurrentWorldPlaneGeometryTransformTime: " << m_CurrentWorldPlaneGeometryTransformTime << std::endl; Superclass::PrintSelf(os, indent); } diff --git a/Modules/Core/src/Rendering/mitkRenderWindow.cpp b/Modules/Core/src/Rendering/mitkRenderWindow.cpp index d223aa6350..cb9d75a1c1 100644 --- a/Modules/Core/src/Rendering/mitkRenderWindow.cpp +++ b/Modules/Core/src/Rendering/mitkRenderWindow.cpp @@ -1,87 +1,87 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkRenderWindow.h" #include "mitkRenderingManager.h" #include "mitkVtkEventProvider.h" #include "mitkVtkLayerController.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" mitk::RenderWindow::RenderWindow(vtkRenderWindow *renWin, const char *name, mitk::RenderingManager *rm, - mitk::BaseRenderer::RenderingMode::Type rmtype) + mitk::BaseRenderer::RenderingMode renderingMode) : m_vtkRenderWindow(renWin), m_vtkRenderWindowInteractor(nullptr), m_vtkMitkEventProvider(nullptr) { if (nullptr == m_vtkRenderWindow) { m_vtkRenderWindow = vtkRenderWindow::New(); m_vtkRenderWindow->SetMultiSamples(0); // We do not support MSAA as it is incompatible with depth peeling m_vtkRenderWindow->SetAlphaBitPlanes(1); // Necessary for depth peeling } if (m_vtkRenderWindow->GetSize()[0] <= 10) { m_vtkRenderWindow->SetSize(100, 100); } m_vtkRenderWindowInteractor = vtkRenderWindowInteractor::New(); m_vtkRenderWindowInteractor->SetRenderWindow(m_vtkRenderWindow); m_vtkRenderWindowInteractor->Initialize(); // initialize from RenderWindowBase - this->Initialize(rm, name, rmtype); + this->Initialize(rm, name, renderingMode); m_vtkMitkEventProvider = vtkEventProvider::New(); m_vtkMitkEventProvider->SetInteractor(this->GetVtkRenderWindowInteractor()); m_vtkMitkEventProvider->SetMitkRenderWindow(this); m_vtkMitkEventProvider->SetEnabled(1); } mitk::RenderWindow::~RenderWindow() { Destroy(); m_vtkRenderWindow->Delete(); m_vtkRenderWindowInteractor->Delete(); m_vtkMitkEventProvider->Delete(); } vtkRenderWindow *mitk::RenderWindow::GetVtkRenderWindow() { return m_vtkRenderWindow; } vtkRenderWindowInteractor *mitk::RenderWindow::GetVtkRenderWindowInteractor() { return m_vtkRenderWindowInteractor; } void mitk::RenderWindow::SetSize(int width, int height) { this->GetVtkRenderWindow()->SetSize(width, height); } void mitk::RenderWindow::ReinitEventProvider() { m_vtkMitkEventProvider->SetEnabled(0); m_vtkMitkEventProvider->SetInteractor(this->GetVtkRenderWindowInteractor()); m_vtkMitkEventProvider->SetMitkRenderWindow(this); m_vtkMitkEventProvider->SetEnabled(1); } diff --git a/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp b/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp index a405703343..64ba922ed5 100644 --- a/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp +++ b/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp @@ -1,117 +1,117 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkRenderWindowBase.h" #include "mitkRenderingManager.h" #include "mitkVtkLayerController.h" #include "vtkRenderer.h" #include "mitkAnnotationUtils.h" mitk::RenderWindowBase::RenderWindowBase() : m_RenderProp(nullptr), m_InResize(false) { } /* * "Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a * virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from * a destructor, and the object to which the call applies is the object under construction or destruction, the function called is * the one defined in the constructor or destructor's own class or in one of its bases, but not a function overriding it in a class * derived from the constructor or destructor's class, or overriding it in one of the other base classes of the most derived object[..]" * or short: within constructors and destructors classes are not polymorph. */ void mitk::RenderWindowBase::Initialize(mitk::RenderingManager *renderingManager, const char *name, - mitk::BaseRenderer::RenderingMode::Type renderingMode) + mitk::BaseRenderer::RenderingMode renderingMode) { if (nullptr == renderingManager) renderingManager = mitk::RenderingManager::GetInstance(); if (m_Renderer.IsNull()) m_Renderer = mitk::VtkPropRenderer::New(name, GetVtkRenderWindow(), renderingManager, renderingMode); m_Renderer->InitRenderer(this->GetVtkRenderWindow()); mitk::BaseRenderer::AddInstance(GetVtkRenderWindow(), m_Renderer); renderingManager->AddRenderWindow(GetVtkRenderWindow()); // Add previously created overlays to new BaseRenderer mitk::AnnotationUtils::BaseRendererChanged(m_Renderer); m_RenderProp = vtkMitkRenderProp::New(); m_RenderProp->SetPropRenderer(m_Renderer); m_Renderer->GetVtkRenderer()->AddViewProp(m_RenderProp); if ((this->GetVtkRenderWindow()->GetSize()[0] > 10) && (this->GetVtkRenderWindow()->GetSize()[1] > 10)) m_Renderer->InitSize(this->GetVtkRenderWindow()->GetSize()[0], this->GetVtkRenderWindow()->GetSize()[1]); m_InResize = false; } bool mitk::RenderWindowBase::HandleEvent(InteractionEvent *interactionEvent) { return m_Renderer->GetDispatcher()->ProcessEvent(interactionEvent); } void mitk::RenderWindowBase::Destroy() { m_Renderer->GetRenderingManager()->RemoveRenderWindow(GetVtkRenderWindow()); m_Renderer->GetVtkRenderer()->RemoveViewProp(m_RenderProp); m_RenderProp->Delete(); BaseRenderer::RemoveInstance(this->GetVtkRenderWindow()); } mitk::RenderWindowBase::~RenderWindowBase() { } mitk::SliceNavigationController *mitk::RenderWindowBase::GetSliceNavigationController() { return mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow())->GetSliceNavigationController(); } mitk::CameraRotationController *mitk::RenderWindowBase::GetCameraRotationController() { return mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow())->GetCameraRotationController(); } mitk::BaseController *mitk::RenderWindowBase::GetController() { mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetInstance(GetVtkRenderWindow()); switch (renderer->GetMapperID()) { case mitk::BaseRenderer::Standard2D: return GetSliceNavigationController(); case mitk::BaseRenderer::Standard3D: return GetCameraRotationController(); default: return GetSliceNavigationController(); } } mitk::VtkPropRenderer *mitk::RenderWindowBase::GetRenderer() { return m_Renderer; } diff --git a/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp b/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp index 6f0986f708..7abccd72a6 100644 --- a/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp +++ b/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp @@ -1,715 +1,715 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkPropRenderer.h" // MAPPERS #include "mitkCameraController.h" #include "mitkImageVtkMapper2D.h" #include "mitkMapper.h" #include "mitkPlaneGeometryDataVtkMapper3D.h" #include "mitkVtkMapper.h" #include #include #include #include #include #include #include #include #include #include // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::VtkPropRenderer::VtkPropRenderer(const char *name, vtkRenderWindow *renWin, - mitk::RenderingManager *rm, - mitk::BaseRenderer::RenderingMode::Type renderingMode) + RenderingManager *rm, + BaseRenderer::RenderingMode renderingMode) : BaseRenderer(name, renWin, rm, renderingMode), m_CameraInitializedForMapperID(0) { didCount = false; m_WorldPointPicker = vtkWorldPointPicker::New(); m_PointPicker = vtkPointPicker::New(); m_PointPicker->SetTolerance(0.0025); m_CellPicker = vtkCellPicker::New(); m_CellPicker->SetTolerance(0.0025); mitk::PlaneGeometryDataVtkMapper3D::Pointer geometryMapper = mitk::PlaneGeometryDataVtkMapper3D::New(); m_CurrentWorldPlaneGeometryMapper = geometryMapper; m_CurrentWorldPlaneGeometryNode->SetMapper(2, geometryMapper); m_LightKit = vtkLightKit::New(); m_LightKit->AddLightsToRenderer(m_VtkRenderer); m_PickingMode = WorldPointPicking; m_TextRenderer = vtkRenderer::New(); m_TextRenderer->SetRenderWindow(renWin); m_TextRenderer->SetInteractive(0); m_TextRenderer->SetErase(0); } /*! \brief Destructs the VtkPropRenderer. */ mitk::VtkPropRenderer::~VtkPropRenderer() { // Workaround for GLDisplayList Bug { m_MapperID = 0; checkState(); } if (m_LightKit != nullptr) m_LightKit->Delete(); if (m_VtkRenderer != nullptr) { m_CameraController = nullptr; m_VtkRenderer->Delete(); m_VtkRenderer = nullptr; } else m_CameraController = nullptr; if (m_WorldPointPicker != nullptr) m_WorldPointPicker->Delete(); if (m_PointPicker != nullptr) m_PointPicker->Delete(); if (m_CellPicker != nullptr) m_CellPicker->Delete(); if (m_TextRenderer != nullptr) m_TextRenderer->Delete(); } void mitk::VtkPropRenderer::SetDataStorage(mitk::DataStorage *storage) { if (storage == nullptr || storage == m_DataStorage) return; BaseRenderer::SetDataStorage(storage); static_cast(m_CurrentWorldPlaneGeometryMapper.GetPointer()) ->SetDataStorageForTexture(m_DataStorage.GetPointer()); // Compute the geometry from the current data tree bounds and set it as world geometry this->SetWorldGeometryToDataStorageBounds(); } bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds() { if (m_DataStorage.IsNull()) return false; // initialize world geometry auto geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D(nullptr, "includeInBoundingBox"); if (geometry.IsNull()) return false; this->SetWorldTimeGeometry(geometry); this->GetVtkRenderer()->ResetCamera(); this->GetCameraController()->Fit(); this->Modified(); return true; } /*! \brief Called by the vtkMitkRenderProp in order to start MITK rendering process. */ int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type) { // Do we have objects to render? if (this->GetEmptyWorldGeometry()) return 0; if (m_DataStorage.IsNull()) return 0; // Update mappers and prepare mapper queue if (type == VtkPropRenderer::Opaque) { this->PrepareMapperQueue(); // Share vtkInformation, there might be new mappers this->PropagateRenderInfoToMappers(); } // go through the generated list and let the sorted mappers paint for (auto it = m_MappersMap.cbegin(); it != m_MappersMap.cend(); it++) { Mapper *mapper = (*it).second; mapper->MitkRender(this, type); } // Render text if (type == VtkPropRenderer::Overlay) { if (m_TextCollection.size() > 0) { m_TextRenderer->SetViewport(this->GetVtkRenderer()->GetViewport()); for (auto it = m_TextCollection.begin(); it != m_TextCollection.end(); ++it) m_TextRenderer->AddViewProp((*it).second); m_TextRenderer->Render(); } } return 1; } /*! \brief PrepareMapperQueue iterates the datatree PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer. */ void mitk::VtkPropRenderer::PrepareMapperQueue() { // variable for counting LOD-enabled mappers m_NumberOfVisibleLODEnabledMappers = 0; // Do we have to update the mappers ? if (m_LastUpdateTime < GetMTime() || m_LastUpdateTime < this->GetCurrentWorldPlaneGeometry()->GetMTime()) { Update(); } else if (m_MapperID >= 1 && m_MapperID < 6) Update(); // remove all text properties before mappers will add new ones m_TextRenderer->RemoveAllViewProps(); for (unsigned int i = 0; i < m_TextCollection.size(); i++) { m_TextCollection[i]->Delete(); } m_TextCollection.clear(); // clear priority_queue m_MappersMap.clear(); int mapperNo = 0; // DataStorage if (m_DataStorage.IsNull()) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { const DataNode::Pointer node = it->Value(); if (node.IsNull()) continue; const mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID); if (mapper.IsNull()) continue; bool visible = true; node->GetVisibility(visible, this, "visible"); // The information about LOD-enabled mappers is required by RenderingManager if (mapper->IsLODEnabled(this) && visible) { ++m_NumberOfVisibleLODEnabledMappers; } // mapper without a layer property get layer number 1 int layer = 1; node->GetIntProperty("layer", layer, this); int nr = (layer << 16) + mapperNo; m_MappersMap.insert(std::pair(nr, mapper)); mapperNo++; } } void mitk::VtkPropRenderer::SetPropertyKeys(vtkInformation *info) { if (info == m_VtkRenderInfo) return; m_VtkRenderInfo = info; this->PropagateRenderInfoToMappers(); } void mitk::VtkPropRenderer::PropagateRenderInfoToMappers() { if (m_VtkRenderInfo == nullptr) return; for (const auto &mapEntry : m_MappersMap) { auto vtkMapper = dynamic_cast(mapEntry.second); if (nullptr != vtkMapper) { auto prop = vtkMapper->GetVtkProp(this); if (nullptr != prop) prop->SetPropertyKeys(m_VtkRenderInfo); } } } void mitk::VtkPropRenderer::Update(mitk::DataNode *datatreenode) { if (datatreenode != nullptr) { mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID); if (mapper.IsNotNull()) { if (GetCurrentWorldPlaneGeometry()->IsValid()) { mapper->Update(this); { auto *vtkmapper = dynamic_cast(mapper.GetPointer()); if (vtkmapper != nullptr) { vtkmapper->UpdateVtkTransform(this); } } } } } } void mitk::VtkPropRenderer::Update() { if (m_DataStorage.IsNull()) return; mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) Update(it->Value()); Modified(); m_LastUpdateTime = GetMTime(); } /*! \brief This method is called from the two Constructors */ void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow *renderWindow) { BaseRenderer::InitRenderer(renderWindow); vtkCallbackCommand *renderCallbackCommand = vtkCallbackCommand::New(); renderCallbackCommand->SetCallback(VtkPropRenderer::RenderingCallback); renderWindow->GetInteractor()->AddObserver(vtkCommand::RenderEvent, renderCallbackCommand); renderCallbackCommand->Delete(); if (renderWindow == nullptr) { m_InitNeeded = false; m_ResizeNeeded = false; return; } m_InitNeeded = true; m_ResizeNeeded = true; m_LastUpdateTime = 0; } void mitk::VtkPropRenderer::RenderingCallback(vtkObject *caller, unsigned long, void *, void *) { auto *renderWindowInteractor = dynamic_cast(caller); if (!renderWindowInteractor) return; mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetInstance(renderWindowInteractor->GetRenderWindow()); if (renderer) renderer->RequestUpdate(); } /*! \brief Resize the OpenGL Window */ void mitk::VtkPropRenderer::Resize(int w, int h) { BaseRenderer::Resize(w, h); m_RenderingManager->RequestUpdate(this->GetRenderWindow()); } void mitk::VtkPropRenderer::InitSize(int w, int h) { m_RenderWindow->SetSize(w, h); Superclass::InitSize(w, h); Modified(); Update(); if (m_VtkRenderer != nullptr) { int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); m_VtkRenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } this->GetCameraController()->Fit(); } int mitk::VtkPropRenderer::WriteSimpleText( std::string text, double posX, double posY, double color1, double color2, double color3, float opacity) { this->GetVtkRenderer()->ViewToDisplay(); if (!text.empty()) { Point2D p; vtkTextActor *textActor = vtkTextActor::New(); textActor->SetDisplayPosition(posX, posY); textActor->SetInput(text.c_str()); textActor->SetTextScaleModeToNone(); textActor->GetTextProperty()->SetColor(color1, color2, color3); // TODO: Read color from node property textActor->GetTextProperty()->SetOpacity(opacity); int text_id = m_TextCollection.size(); m_TextCollection.insert(TextMapType::value_type(text_id, textActor)); return text_id; } else { return -1; } } void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId) { if (m_MapperID != mapperId) Superclass::SetMapperID(mapperId); // Workaround for GL Displaylist Bug checkState(); } /*! \brief Activates the current renderwindow. */ void mitk::VtkPropRenderer::MakeCurrent() { if (m_RenderWindow != nullptr) m_RenderWindow->MakeCurrent(); } void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D &displayPoint, mitk::Point3D &worldPoint) const { if (this->GetRenderWindow()->GetNeverRendered() != 0) return; // somebody called picking before we ever rendered; cannot have enough information yet switch (m_PickingMode) { case (WorldPointPicking): { m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); break; } case (PointPicking): { m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); break; } case (CellPicking): { m_CellPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_CellPicker->GetPickPosition(), worldPoint); break; } } // todo: is this picking in 2D renderwindows? // Superclass::PickWorldPoint(displayPoint, worldPoint); } mitk::DataNode *mitk::VtkPropRenderer::PickObject(const Point2D &displayPosition, Point3D &worldPosition) const { m_CellPicker->InitializePickList(); // Iterate over all DataStorage objects to determine all vtkProps intended // for picking DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { const DataNode *node = it->Value(); if (node == nullptr) continue; bool pickable = false; node->GetBoolProperty("pickable", pickable); if (!pickable) continue; auto *mapper = dynamic_cast(node->GetMapper(m_MapperID)); if (mapper == nullptr) continue; vtkProp *prop = mapper->GetVtkProp((mitk::BaseRenderer *)this); if (prop == nullptr) continue; m_CellPicker->AddPickList(prop); } // Do the picking and retrieve the picked vtkProp (if any) m_CellPicker->PickFromListOn(); m_CellPicker->Pick(displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer); m_CellPicker->PickFromListOff(); vtk2itk(m_CellPicker->GetPickPosition(), worldPosition); vtkProp *prop = m_CellPicker->GetViewProp(); if (prop == nullptr) { return nullptr; } // Iterate over all DataStorage objects to determine if the retrieved // vtkProp is owned by any associated mapper. for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if (node.IsNull()) continue; mitk::Mapper *mapper = node->GetMapper(m_MapperID); if (mapper == nullptr) continue; auto *vtkmapper = dynamic_cast(mapper); if (vtkmapper) { // if vtk-based, then ... if (vtkmapper->HasVtkProp(prop, const_cast(this))) { return node; } } } return nullptr; } // todo: is this 2D renderwindow picking? // return Superclass::PickObject( displayPosition, worldPosition ); vtkTextProperty *mitk::VtkPropRenderer::GetTextLabelProperty(int text_id) { return this->m_TextCollection[text_id]->GetTextProperty(); } void mitk::VtkPropRenderer::InitPathTraversal() { if (m_DataStorage.IsNotNull()) { this->UpdatePaths(); this->m_Paths->InitTraversal(); } } void mitk::VtkPropRenderer::UpdatePaths() { if (m_DataStorage.IsNull()) { return; } if (GetMTime() > m_PathTime || (m_Paths != nullptr && m_Paths->GetMTime() > m_PathTime)) { // Create the list to hold all the paths m_Paths = vtkSmartPointer::New(); DataStorage::SetOfObjects::ConstPointer objects = m_DataStorage->GetAll(); for (auto iter = objects->begin(); iter != objects->end(); ++iter) { vtkSmartPointer onePath = vtkSmartPointer::New(); Mapper *mapper = (*iter)->GetMapper(BaseRenderer::Standard3D); if (mapper) { auto *vtkmapper = dynamic_cast(mapper); if (nullptr != vtkmapper) { vtkProp *prop = vtkmapper->GetVtkProp(this); if (prop && prop->GetVisibility()) { // add to assembly path onePath->AddNode(prop, prop->GetMatrix()); m_Paths->AddItem(onePath); } } } } m_PathTime.Modified(); } } int mitk::VtkPropRenderer::GetNumberOfPaths() { UpdatePaths(); return m_Paths->GetNumberOfItems(); } vtkAssemblyPath *mitk::VtkPropRenderer::GetNextPath() { return m_Paths ? m_Paths->GetNextItem() : nullptr; } void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow * /*renWin*/) { if (m_DataStorage.IsNull()) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (auto iter = allObjects->begin(); iter != allObjects->end(); ++iter) { DataNode::Pointer node = *iter; if (node.IsNull()) continue; Mapper *mapper = node->GetMapper(m_MapperID); if (mapper) { auto *vtkmapper = dynamic_cast(mapper); if (vtkmapper) vtkmapper->ReleaseGraphicsResources(this); } } } const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const { return m_WorldPointPicker; } const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const { return m_PointPicker; } const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const { return m_CellPicker; } mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const { return m_MappersMap; } // Workaround for GL Displaylist bug static int glWorkAroundGlobalCount = 0; bool mitk::VtkPropRenderer::useImmediateModeRendering() { return glWorkAroundGlobalCount > 1; } void mitk::VtkPropRenderer::checkState() { if (m_MapperID == Standard3D) { if (!didCount) { didCount = true; glWorkAroundGlobalCount++; if (glWorkAroundGlobalCount == 2) { MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOn(); } } } else { if (didCount) { didCount = false; glWorkAroundGlobalCount--; if (glWorkAroundGlobalCount == 1) { MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOff(); } } } } //### Contains all methods which are neceassry before each VTK Render() call void mitk::VtkPropRenderer::PrepareRender() { if (this->GetMapperID() != m_CameraInitializedForMapperID) { Initialize2DvtkCamera(); // Set parallel projection etc. } GetCameraController()->AdjustCameraToPlane(); } bool mitk::VtkPropRenderer::Initialize2DvtkCamera() { if (this->GetMapperID() == Standard3D) { // activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false); vtkSmartPointer style = vtkSmartPointer::New(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); this->GetRenderWindow()->GetInteractor()->EnableRenderOff(); m_CameraInitializedForMapperID = Standard3D; } else if (this->GetMapperID() == Standard2D) { // activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); // turn the light out in the scene in order to render correct grey values. // TODO Implement a property for light in the 2D render windows (in another method) this->GetVtkRenderer()->RemoveAllLights(); vtkSmartPointer style = vtkSmartPointer::New(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); this->GetRenderWindow()->GetInteractor()->EnableRenderOff(); m_CameraInitializedForMapperID = Standard2D; } return true; } diff --git a/Modules/QtWidgets/include/QmitkRenderWindow.h b/Modules/QtWidgets/include/QmitkRenderWindow.h index dee2a9676f..90a3463ca1 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindow.h +++ b/Modules/QtWidgets/include/QmitkRenderWindow.h @@ -1,172 +1,172 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66 #define QMITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66 #include "mitkRenderWindowBase.h" #include "QmitkRenderWindowMenu.h" #include #include #include #include "mitkBaseRenderer.h" #include "mitkInteractionEventConst.h" class QmitkStdMultiWidget; class QDragEnterEvent; class QDropEvent; class QInputEvent; /** * \ingroup QmitkModule * \brief MITK implementation of the QVTKWidget */ class MITKQTWIDGETS_EXPORT QmitkRenderWindow : public QVTKOpenGLWidget, public mitk::RenderWindowBase { Q_OBJECT public: QmitkRenderWindow( QWidget *parent = nullptr, const QString &name = "unnamed renderwindow", mitk::VtkPropRenderer *renderer = nullptr, mitk::RenderingManager *renderingManager = nullptr, - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing); + mitk::BaseRenderer::RenderingMode renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing); ~QmitkRenderWindow() override; /** * \brief Whether Qt events should be passed to parent (default: true) * * With introduction of the QVTKWidget the behaviour regarding Qt events changed. * QVTKWidget "accepts" Qt events like mouse clicks (i.e. set an "accepted" flag). * When this flag is set, Qt fininshed handling of this event -- otherwise it is * reached through to the widget's parent. * * This reaching through to the parent was implicitly required by QmitkMaterialWidget / QmitkMaterialShowCase. *QmitkStdMultiWidget * The default behaviour of QmitkRenderWindow is now to clear the "accepted" flag * of Qt events after they were handled by QVTKWidget. This way parents can also * handle events. * * If you don't want this behaviour, call SetResendQtEvents(true) on your render window. */ virtual void SetResendQtEvents(bool resend); // Set Layout Index to define the Layout Type void SetLayoutIndex(unsigned int layoutIndex); // Get Layout Index to define the Layout Type unsigned int GetLayoutIndex(); // MenuWidget need to update the Layout Design List when Layout had changed void LayoutDesignListChanged(int layoutDesignIndex); void HideRenderWindowMenu(); // Activate or Deactivate MenuWidget. void ActivateMenuWidget(bool state, QmitkStdMultiWidget *stdMultiWidget = nullptr); bool GetActivateMenuWidgetFlag() { return m_MenuWidgetActivated; } // Get it from the QVTKWidget parent vtkRenderWindow *GetVtkRenderWindow() override { return GetRenderWindow(); } vtkRenderWindowInteractor *GetVtkRenderWindowInteractor() override { return nullptr; } void FullScreenMode(bool state); protected: // overloaded move handler void moveEvent(QMoveEvent *event) override; // overloaded show handler void showEvent(QShowEvent *event) override; // overloaded mouse press handler void mousePressEvent(QMouseEvent *event) override; // overloaded mouse double-click handler void mouseDoubleClickEvent(QMouseEvent *event) override; // overloaded mouse move handler void mouseMoveEvent(QMouseEvent *event) override; // overloaded mouse release handler void mouseReleaseEvent(QMouseEvent *event) override; // overloaded key press handler void keyPressEvent(QKeyEvent *event) override; // overloaded enter handler void enterEvent(QEvent *) override; // overloaded leave handler void leaveEvent(QEvent *) override; // Overloaded resize handler, see decs in QVTKOpenGLWidget. // Basically, we have to ensure the VTK rendering is updated for each change in window size. void resizeGL(int w, int h) Q_DECL_OVERRIDE; /// \brief Simply says we accept the event type. void dragEnterEvent(QDragEnterEvent *event) override; /// \brief If the dropped type is application/x-mitk-datanodes we process the request by converting to mitk::DataNode /// pointers and emitting the NodesDropped signal. void dropEvent(QDropEvent *event) override; #ifndef QT_NO_WHEELEVENT // overload wheel mouse event void wheelEvent(QWheelEvent *) override; #endif void AdjustRenderWindowMenuVisibility(const QPoint &pos); signals: void ResetView(); // \brief int parameters are enum from QmitkStdMultiWidget void ChangeCrosshairRotationMode(int); void SignalLayoutDesignChanged(int layoutDesignIndex); void moved(); /// \brief Emits a signal to say that this window has had the following nodes dropped on it. void NodesDropped(QmitkRenderWindow *thisWindow, std::vector nodes); protected slots: void OnChangeLayoutDesign(int layoutDesignIndex); void OnWidgetPlaneModeChanged(int); void DeferredHideMenu(); private: // Helper Functions to Convert Qt-Events to Mitk-Events mitk::Point2D GetMousePosition(QMouseEvent *me) const; mitk::Point2D GetMousePosition(QWheelEvent *we) const; mitk::InteractionEvent::MouseButtons GetEventButton(QMouseEvent *me) const; mitk::InteractionEvent::MouseButtons GetButtonState(QMouseEvent *me) const; mitk::InteractionEvent::ModifierKeys GetModifiers(QInputEvent *me) const; mitk::InteractionEvent::MouseButtons GetButtonState(QWheelEvent *we) const; std::string GetKeyLetter(QKeyEvent *ke) const; int GetDelta(QWheelEvent *we) const; bool m_ResendQtEvents; QmitkRenderWindowMenu *m_MenuWidget; bool m_MenuWidgetActivated; unsigned int m_LayoutIndex; vtkSmartPointer m_InternalRenderWindow; }; #endif diff --git a/Modules/QtWidgets/include/QmitkStdMultiWidget.h b/Modules/QtWidgets/include/QmitkStdMultiWidget.h index 9b3bfccd0e..6f341831c4 100644 --- a/Modules/QtWidgets/include/QmitkStdMultiWidget.h +++ b/Modules/QtWidgets/include/QmitkStdMultiWidget.h @@ -1,431 +1,431 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkStdMultiWidget_h #define QmitkStdMultiWidget_h #include "MitkQtWidgetsExports.h" #include #include #include #include #include #include #include #include #include class QHBoxLayout; class QVBoxLayout; class QGridLayout; class QSpacerItem; class QmitkLevelWindowWidget; class QmitkRenderWindow; class vtkCornerAnnotation; class vtkMitkRectangleProp; namespace mitk { class RenderingManager; } /// \ingroup QmitkModule class MITKQTWIDGETS_EXPORT QmitkStdMultiWidget : public QWidget { Q_OBJECT public: QmitkStdMultiWidget( QWidget *parent = nullptr, Qt::WindowFlags f = nullptr, mitk::RenderingManager *renderingManager = nullptr, - mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing, + mitk::BaseRenderer::RenderingMode renderingMode = mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing, const QString &name = "stdmulti"); ~QmitkStdMultiWidget() override; mitk::SliceNavigationController *GetTimeNavigationController(); void RequestUpdate(); void ForceImmediateUpdate(); mitk::MouseModeSwitcher *GetMouseModeSwitcher(); QmitkRenderWindow *GetRenderWindow1() const; QmitkRenderWindow *GetRenderWindow2() const; QmitkRenderWindow *GetRenderWindow3() const; QmitkRenderWindow *GetRenderWindow4() const; const mitk::Point3D GetCrossPosition() const; void EnablePositionTracking(); void DisablePositionTracking(); int GetLayout() const; bool GetGradientBackgroundFlag() const; /*! \brief Access node of widget plane 1 \return DataNode holding widget plane 1 */ mitk::DataNode::Pointer GetWidgetPlane1(); /*! \brief Access node of widget plane 2 \return DataNode holding widget plane 2 */ mitk::DataNode::Pointer GetWidgetPlane2(); /*! \brief Access node of widget plane 3 \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane3(); /*! \brief Convenience method to access node of widget planes \param id number of widget plane to be returned \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane(int id); bool IsColoredRectanglesEnabled() const; bool IsDepartmentLogoEnabled() const; void InitializeWidget(); /// called when the StdMultiWidget is closed to remove the 3 widget planes and the helper node from the DataStorage void RemovePlanesFromDataStorage(); void AddPlanesToDataStorage(); void SetDataStorage(mitk::DataStorage *ds); /** \brief Listener to the CrosshairPositionEvent Ensures the CrosshairPositionEvent is handled only once and at the end of the Qt-Event loop */ void HandleCrosshairPositionEvent(); /// activate Menu Widget. true: activated, false: deactivated void ActivateMenuWidget(bool state); bool IsMenuWidgetEnabled() const; void SetCornerAnnotationVisibility(bool visibility); bool IsCornerAnnotationVisible(void) const; protected: void UpdateAllWidgets(); void HideAllWidgetToolbars(); public slots: /// Receives the signal from HandleCrosshairPositionEvent, executes the StatusBar update void HandleCrosshairPositionEventDelayed(); void changeLayoutTo2DImagesUp(); void changeLayoutTo2DImagesLeft(); void changeLayoutToDefault(); void changeLayoutToBig3D(); void changeLayoutToWidget1(); void changeLayoutToWidget2(); void changeLayoutToWidget3(); void changeLayoutToRowWidget3And4(); void changeLayoutToColumnWidget3And4(); void changeLayoutToRowWidgetSmall3andBig4(); void changeLayoutToSmallUpperWidget2Big3and4(); void changeLayoutTo2x2Dand3DWidget(); void changeLayoutToLeft2Dand3DRight2D(); /** Changes the layout to one 2D window up and a 3D window down. * The 2D window can be defined by its id (1-3). If MITK default * settings were not changed, 1 is axial, 2 is sagittal and 3 is coronal. */ void changeLayoutTo2DUpAnd3DDown(unsigned int id2Dwindow = 2); void Fit(); void InitPositionTracking(); void AddDisplayPlaneSubTree(); void EnableStandardLevelWindow(); void DisableStandardLevelWindow(); bool InitializeStandardViews(const mitk::Geometry3D *geometry); void wheelEvent(QWheelEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void moveEvent(QMoveEvent *e) override; void EnsureDisplayContainsPoint(mitk::BaseRenderer *renderer, const mitk::Point3D &p); void MoveCrossToPosition(const mitk::Point3D &newPosition); // void EnableNavigationControllerEventListening(); // void DisableNavigationControllerEventListening(); void EnableGradientBackground(); void DisableGradientBackground(); void EnableDepartmentLogo(); void DisableDepartmentLogo(); void EnableColoredRectangles(); void DisableColoredRectangles(); void SetWidgetPlaneVisibility(const char *widgetName, bool visible, mitk::BaseRenderer *renderer = nullptr); void SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer = nullptr); void SetWidgetPlanesLocked(bool locked); void SetWidgetPlanesRotationLocked(bool locked); void SetWidgetPlanesRotationLinked(bool link); void SetWidgetPlaneMode(int mode); void SetGradientBackgroundColors(const mitk::Color &upper, const mitk::Color &lower); void SetDepartmentLogo(const char *path); void SetWidgetPlaneModeToSlicing(bool activate); void SetWidgetPlaneModeToRotation(bool activate); void SetWidgetPlaneModeToSwivel(bool activate); void OnLayoutDesignChanged(int layoutDesignIndex); void ResetCrosshair(); signals: void LeftMouseClicked(mitk::Point3D pointValue); void WheelMoved(QWheelEvent *); void WidgetPlanesRotationLinked(bool); void WidgetPlanesRotationEnabled(bool); void ViewsInitialized(); void WidgetPlaneModeSlicing(bool); void WidgetPlaneModeRotation(bool); void WidgetPlaneModeSwivel(bool); void WidgetPlaneModeChange(int); void WidgetNotifyNewCrossHairMode(int); void Moved(); public: /** Define RenderWindow (public)*/ QmitkRenderWindow *mitkWidget1; QmitkRenderWindow *mitkWidget2; QmitkRenderWindow *mitkWidget3; QmitkRenderWindow *mitkWidget4; QmitkLevelWindowWidget *levelWindowWidget; /********************************/ enum { PLANE_MODE_SLICING = 0, PLANE_MODE_ROTATION, PLANE_MODE_SWIVEL }; enum { LAYOUT_DEFAULT = 0, LAYOUT_2D_IMAGES_UP, LAYOUT_2D_IMAGES_LEFT, LAYOUT_BIG_3D, LAYOUT_WIDGET1, LAYOUT_WIDGET2, LAYOUT_WIDGET3, LAYOUT_2X_2D_AND_3D_WIDGET, LAYOUT_ROW_WIDGET_3_AND_4, LAYOUT_COLUMN_WIDGET_3_AND_4, LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4, LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4, LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET, LAYOUT_2D_UP_AND_3D_DOWN }; enum { AXIAL, SAGITTAL, CORONAL, THREE_D }; /** * @brief SetCornerAnnotation Create a corner annotation for a widget. * @param text The text of the annotation. * @param color The color. * @param widgetNumber The widget (0-3). */ void SetDecorationProperties(std::string text, mitk::Color color, int widgetNumber); /** * @brief GetRenderWindow convinience method to get a widget. * @param number of the widget (0-3) * @return The renderwindow widget. */ QmitkRenderWindow *GetRenderWindow(unsigned int number); /** * @brief SetGradientBackgroundColorForRenderWindow background for a widget. * * If two different input colors are, a gradient background is generated. * * @param upper Upper color of the gradient background. * @param lower Lower color of the gradient background. * @param widgetNumber The widget (0-3). */ void SetGradientBackgroundColorForRenderWindow(const mitk::Color &upper, const mitk::Color &lower, unsigned int widgetNumber); /** * @brief GetDecorationColorForWidget Get the color for annotation, crosshair and rectangle. * @param widgetNumber Number of the renderwindow (0-3). * @return Color in mitk format. */ mitk::Color GetDecorationColor(unsigned int widgetNumber); /** * @brief SetDecorationColor Set the color of the decoration of the 4 widgets. * * This is used to color the frame of the renderwindow and the corner annatation. * For the first 3 widgets, this color is a property of the helper object nodes * which contain the respective plane geometry. For widget 4, this is a member, * since there is no data node for this widget. */ void SetDecorationColor(unsigned int widgetNumber, mitk::Color color); /** * @brief GetCornerAnnotationText Getter for corner annotation text. * @param widgetNumber the widget number (0-3). * @return The text in the corner annotation. */ std::string GetCornerAnnotationText(unsigned int widgetNumber); /** * @brief GetGradientColors Getter for gradientbackground colors. * @param widgetNumber the widget number (0-3). * @return A pair of colors. First: upper, second: lower. */ std::pair GetGradientColors(unsigned int widgetNumber); protected: QHBoxLayout *QmitkStdMultiWidgetLayout; int m_Layout; int m_PlaneMode; mitk::RenderingManager *m_RenderingManager; mitk::LogoAnnotation::Pointer m_LogoRendering; bool m_GradientBackgroundFlag; mitk::MouseModeSwitcher::Pointer m_MouseModeSwitcher; mitk::SliceNavigationController *m_TimeNavigationController; mitk::DataStorage::Pointer m_DataStorage; /** * @brief m_PlaneNode1 the 3 helper objects which contain the plane geometry. */ mitk::DataNode::Pointer m_PlaneNode1; mitk::DataNode::Pointer m_PlaneNode2; mitk::DataNode::Pointer m_PlaneNode3; /** * @brief m_ParentNodeForGeometryPlanes This helper object is added to the datastorage * and contains the 3 planes for displaying the image geometry (crosshair and 3D planes). */ mitk::DataNode::Pointer m_ParentNodeForGeometryPlanes; /** * @brief m_DecorationColorWidget4 color for annotation and rectangle of widget 4. * * For other widgets1-3, the color is a property of the respective data node. * There is no node for widget 4, hence, we need an extra member. */ mitk::Color m_DecorationColorWidget4; /** * @brief m_GradientBackgroundColors Contains the colors of the gradient background. * */ std::pair m_GradientBackgroundColors[4]; QSplitter *m_MainSplit; QSplitter *m_LayoutSplit; QSplitter *m_SubSplit1; QSplitter *m_SubSplit2; QWidget *mitkWidget1Container; QWidget *mitkWidget2Container; QWidget *mitkWidget3Container; QWidget *mitkWidget4Container; vtkSmartPointer m_CornerAnnotations[4]; vtkSmartPointer m_RectangleProps[4]; bool m_PendingCrosshairPositionEvent; bool m_CrosshairNavigationEnabled; /** * @brief CreateCornerAnnotation helper method to create a corner annotation. * @param text of the annotation. * @param color of the annotation. * @return the complete CornerAnnotation. */ vtkSmartPointer CreateCornerAnnotation(std::string text, mitk::Color color); /** * @brief FillGradientBackgroundWithBlack Internal helper method to initialize the * gradient background colors with black. */ void FillGradientBackgroundWithBlack(); }; #endif /*QmitkStdMultiWidget_h*/ diff --git a/Modules/QtWidgets/src/QmitkRenderWindow.cpp b/Modules/QtWidgets/src/QmitkRenderWindow.cpp index 8edf678a5d..e769794d91 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindow.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindow.cpp @@ -1,506 +1,506 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkRenderWindow.h" #include "mitkInteractionKeyEvent.h" #include "mitkInternalEvent.h" #include "mitkMouseDoubleClickEvent.h" #include "mitkMouseMoveEvent.h" #include "mitkMousePressEvent.h" #include "mitkMouseReleaseEvent.h" #include "mitkMouseWheelEvent.h" #include #include #include #include #include #include #include #include #include #include #include "QmitkMimeTypes.h" #include "QmitkRenderWindowMenu.h" -QmitkRenderWindow::QmitkRenderWindow(QWidget *parent, const QString &name, mitk::VtkPropRenderer *, mitk::RenderingManager *renderingManager, mitk::BaseRenderer::RenderingMode::Type renderingMode) +QmitkRenderWindow::QmitkRenderWindow(QWidget *parent, const QString &name, mitk::VtkPropRenderer *, mitk::RenderingManager *renderingManager, mitk::BaseRenderer::RenderingMode renderingMode) : QVTKOpenGLWidget(parent), m_ResendQtEvents(true), m_MenuWidget(nullptr), m_MenuWidgetActivated(false), m_LayoutIndex(0) { m_InternalRenderWindow = vtkSmartPointer::New(); m_InternalRenderWindow->SetMultiSamples(0); m_InternalRenderWindow->SetAlphaBitPlanes(0); this->SetRenderWindow(m_InternalRenderWindow); this->Initialize(renderingManager, name.toStdString().c_str(), renderingMode); this->setFocusPolicy(Qt::StrongFocus); this->setMouseTracking(true); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); this->setSizePolicy(sizePolicy); } QmitkRenderWindow::~QmitkRenderWindow() { Destroy(); // Destroy mitkRenderWindowBase } void QmitkRenderWindow::SetResendQtEvents(bool resend) { m_ResendQtEvents = resend; } void QmitkRenderWindow::SetLayoutIndex(unsigned int layoutIndex) { m_LayoutIndex = layoutIndex; if (m_MenuWidget) m_MenuWidget->SetLayoutIndex(layoutIndex); } unsigned int QmitkRenderWindow::GetLayoutIndex() { if (m_MenuWidget) return m_MenuWidget->GetLayoutIndex(); else return 0; } void QmitkRenderWindow::LayoutDesignListChanged(int layoutDesignIndex) { if (m_MenuWidget) m_MenuWidget->UpdateLayoutDesignList(layoutDesignIndex); } void QmitkRenderWindow::mousePressEvent(QMouseEvent *me) { // Get mouse position in vtk display coordinate system. me contains qt display infos... mitk::Point2D displayPos = GetMousePosition(me); mitk::MousePressEvent::Pointer mPressEvent = mitk::MousePressEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me), GetEventButton(me)); if (!this->HandleEvent(mPressEvent.GetPointer())) { QVTKOpenGLWidget::mousePressEvent(me); } if (m_ResendQtEvents) me->ignore(); } void QmitkRenderWindow::mouseDoubleClickEvent(QMouseEvent *me) { mitk::Point2D displayPos = GetMousePosition(me); mitk::MouseDoubleClickEvent::Pointer mPressEvent = mitk::MouseDoubleClickEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me), GetEventButton(me)); if (!this->HandleEvent(mPressEvent.GetPointer())) { QVTKOpenGLWidget::mousePressEvent(me); } if (m_ResendQtEvents) me->ignore(); } void QmitkRenderWindow::mouseReleaseEvent(QMouseEvent *me) { mitk::Point2D displayPos = GetMousePosition(me); mitk::MouseReleaseEvent::Pointer mReleaseEvent = mitk::MouseReleaseEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me), GetEventButton(me)); if (!this->HandleEvent(mReleaseEvent.GetPointer())) { QVTKOpenGLWidget::mouseReleaseEvent(me); } if (m_ResendQtEvents) me->ignore(); } void QmitkRenderWindow::mouseMoveEvent(QMouseEvent *me) { mitk::Point2D displayPos = GetMousePosition(me); this->AdjustRenderWindowMenuVisibility(me->pos()); mitk::MouseMoveEvent::Pointer mMoveEvent = mitk::MouseMoveEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me)); if (!this->HandleEvent(mMoveEvent.GetPointer())) { QVTKOpenGLWidget::mouseMoveEvent(me); } } void QmitkRenderWindow::wheelEvent(QWheelEvent *we) { mitk::Point2D displayPos = GetMousePosition(we); mitk::MouseWheelEvent::Pointer mWheelEvent = mitk::MouseWheelEvent::New(m_Renderer, displayPos, GetButtonState(we), GetModifiers(we), GetDelta(we)); if (!this->HandleEvent(mWheelEvent.GetPointer())) { QVTKOpenGLWidget::wheelEvent(we); } if (m_ResendQtEvents) we->ignore(); } void QmitkRenderWindow::keyPressEvent(QKeyEvent *ke) { mitk::InteractionEvent::ModifierKeys modifiers = GetModifiers(ke); std::string key = GetKeyLetter(ke); mitk::InteractionKeyEvent::Pointer keyEvent = mitk::InteractionKeyEvent::New(m_Renderer, key, modifiers); if (!this->HandleEvent(keyEvent.GetPointer())) { QVTKOpenGLWidget::keyPressEvent(ke); } if (m_ResendQtEvents) ke->ignore(); } void QmitkRenderWindow::enterEvent(QEvent *e) { // TODO implement new event QVTKOpenGLWidget::enterEvent(e); } void QmitkRenderWindow::DeferredHideMenu() { MITK_DEBUG << "QmitkRenderWindow::DeferredHideMenu"; if (m_MenuWidget) m_MenuWidget->HideMenu(); } void QmitkRenderWindow::leaveEvent(QEvent *e) { mitk::InternalEvent::Pointer internalEvent = mitk::InternalEvent::New(this->m_Renderer, nullptr, "LeaveRenderWindow"); this->HandleEvent(internalEvent.GetPointer()); if (m_MenuWidget) m_MenuWidget->smoothHide(); QVTKOpenGLWidget::leaveEvent(e); } //----------------------------------------------------------------------------- void QmitkRenderWindow::resizeGL(int w, int h) { this->GetRenderer()->GetRenderingManager()->ForceImmediateUpdate(GetRenderWindow()); QVTKOpenGLWidget::resizeGL(w, h); } void QmitkRenderWindow::moveEvent(QMoveEvent *event) { QVTKOpenGLWidget::moveEvent(event); // after a move the overlays need to be positioned emit moved(); } void QmitkRenderWindow::showEvent(QShowEvent *event) { QVTKOpenGLWidget::showEvent(event); // this singleshot is necessary to have the overlays positioned correctly after initial show // simple call of moved() is no use here!! QTimer::singleShot(0, this, SIGNAL(moved())); } void QmitkRenderWindow::ActivateMenuWidget(bool state, QmitkStdMultiWidget *stdMultiWidget) { m_MenuWidgetActivated = state; if (!m_MenuWidgetActivated && m_MenuWidget) { // disconnect Signal/Slot Connection disconnect(m_MenuWidget, SIGNAL(SignalChangeLayoutDesign(int)), this, SLOT(OnChangeLayoutDesign(int))); disconnect(m_MenuWidget, SIGNAL(ResetView()), this, SIGNAL(ResetView())); disconnect(m_MenuWidget, SIGNAL(ChangeCrosshairRotationMode(int)), this, SIGNAL(ChangeCrosshairRotationMode(int))); delete m_MenuWidget; m_MenuWidget = nullptr; } else if (m_MenuWidgetActivated && !m_MenuWidget) { // create render window MenuBar for split, close Window or set new setting. m_MenuWidget = new QmitkRenderWindowMenu(this, nullptr, m_Renderer, stdMultiWidget); m_MenuWidget->SetLayoutIndex(m_LayoutIndex); // create Signal/Slot Connection connect(m_MenuWidget, SIGNAL(SignalChangeLayoutDesign(int)), this, SLOT(OnChangeLayoutDesign(int))); connect(m_MenuWidget, SIGNAL(ResetView()), this, SIGNAL(ResetView())); connect(m_MenuWidget, SIGNAL(ChangeCrosshairRotationMode(int)), this, SIGNAL(ChangeCrosshairRotationMode(int))); } } void QmitkRenderWindow::AdjustRenderWindowMenuVisibility(const QPoint & /*pos*/) { if (m_MenuWidget) { m_MenuWidget->ShowMenu(); m_MenuWidget->MoveWidgetToCorrectPos(1.0f); } } void QmitkRenderWindow::HideRenderWindowMenu() { // DEPRECATED METHOD } void QmitkRenderWindow::OnChangeLayoutDesign(int layoutDesignIndex) { emit SignalLayoutDesignChanged(layoutDesignIndex); } void QmitkRenderWindow::OnWidgetPlaneModeChanged(int mode) { if (m_MenuWidget) m_MenuWidget->NotifyNewWidgetPlanesMode(mode); } void QmitkRenderWindow::FullScreenMode(bool state) { if (m_MenuWidget) m_MenuWidget->ChangeFullScreenMode(state); } void QmitkRenderWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("application/x-mitk-datanodes")) { event->accept(); } } void QmitkRenderWindow::dropEvent(QDropEvent *event) { QList dataNodeList = QmitkMimeTypes::ToDataNodePtrList(event->mimeData()); if (!dataNodeList.empty()) { emit NodesDropped(this, dataNodeList.toVector().toStdVector()); } } mitk::Point2D QmitkRenderWindow::GetMousePosition(QMouseEvent *me) const { mitk::Point2D point; point[0] = me->x(); // We need to convert the y component, as the display and vtk have other definitions for the y direction point[1] = m_Renderer->GetSizeY() - me->y(); return point; } mitk::Point2D QmitkRenderWindow::GetMousePosition(QWheelEvent *we) const { mitk::Point2D point; point[0] = we->x(); // We need to convert the y component, as the display and vtk have other definitions for the y direction point[1] = m_Renderer->GetSizeY() - we->y(); return point; } mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetEventButton(QMouseEvent *me) const { mitk::InteractionEvent::MouseButtons eventButton; switch (me->button()) { case Qt::LeftButton: eventButton = mitk::InteractionEvent::LeftMouseButton; break; case Qt::RightButton: eventButton = mitk::InteractionEvent::RightMouseButton; break; case Qt::MidButton: eventButton = mitk::InteractionEvent::MiddleMouseButton; break; default: eventButton = mitk::InteractionEvent::NoButton; break; } return eventButton; } mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QMouseEvent *me) const { mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton; if (me->buttons() & Qt::LeftButton) { buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton; } if (me->buttons() & Qt::RightButton) { buttonState = buttonState | mitk::InteractionEvent::RightMouseButton; } if (me->buttons() & Qt::MidButton) { buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton; } return buttonState; } mitk::InteractionEvent::ModifierKeys QmitkRenderWindow::GetModifiers(QInputEvent *me) const { mitk::InteractionEvent::ModifierKeys modifiers = mitk::InteractionEvent::NoKey; if (me->modifiers() & Qt::ALT) { modifiers = modifiers | mitk::InteractionEvent::AltKey; } if (me->modifiers() & Qt::CTRL) { modifiers = modifiers | mitk::InteractionEvent::ControlKey; } if (me->modifiers() & Qt::SHIFT) { modifiers = modifiers | mitk::InteractionEvent::ShiftKey; } return modifiers; } mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QWheelEvent *we) const { mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton; if (we->buttons() & Qt::LeftButton) { buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton; } if (we->buttons() & Qt::RightButton) { buttonState = buttonState | mitk::InteractionEvent::RightMouseButton; } if (we->buttons() & Qt::MidButton) { buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton; } return buttonState; } std::string QmitkRenderWindow::GetKeyLetter(QKeyEvent *ke) const { // Converting Qt Key Event to string element. std::string key = ""; int tkey = ke->key(); if (tkey < 128) { // standard ascii letter key = (char)toupper(tkey); } else { // special keys switch (tkey) { case Qt::Key_Return: key = mitk::InteractionEvent::KeyReturn; break; case Qt::Key_Enter: key = mitk::InteractionEvent::KeyEnter; break; case Qt::Key_Escape: key = mitk::InteractionEvent::KeyEsc; break; case Qt::Key_Delete: key = mitk::InteractionEvent::KeyDelete; break; case Qt::Key_Up: key = mitk::InteractionEvent::KeyArrowUp; break; case Qt::Key_Down: key = mitk::InteractionEvent::KeyArrowDown; break; case Qt::Key_Left: key = mitk::InteractionEvent::KeyArrowLeft; break; case Qt::Key_Right: key = mitk::InteractionEvent::KeyArrowRight; break; case Qt::Key_F1: key = mitk::InteractionEvent::KeyF1; break; case Qt::Key_F2: key = mitk::InteractionEvent::KeyF2; break; case Qt::Key_F3: key = mitk::InteractionEvent::KeyF3; break; case Qt::Key_F4: key = mitk::InteractionEvent::KeyF4; break; case Qt::Key_F5: key = mitk::InteractionEvent::KeyF5; break; case Qt::Key_F6: key = mitk::InteractionEvent::KeyF6; break; case Qt::Key_F7: key = mitk::InteractionEvent::KeyF7; break; case Qt::Key_F8: key = mitk::InteractionEvent::KeyF8; break; case Qt::Key_F9: key = mitk::InteractionEvent::KeyF9; break; case Qt::Key_F10: key = mitk::InteractionEvent::KeyF10; break; case Qt::Key_F11: key = mitk::InteractionEvent::KeyF11; break; case Qt::Key_F12: key = mitk::InteractionEvent::KeyF12; break; case Qt::Key_End: key = mitk::InteractionEvent::KeyEnd; break; case Qt::Key_Home: key = mitk::InteractionEvent::KeyPos1; break; case Qt::Key_Insert: key = mitk::InteractionEvent::KeyInsert; break; case Qt::Key_PageDown: key = mitk::InteractionEvent::KeyPageDown; break; case Qt::Key_PageUp: key = mitk::InteractionEvent::KeyPageUp; break; case Qt::Key_Space: key = mitk::InteractionEvent::KeySpace; break; } } return key; } int QmitkRenderWindow::GetDelta(QWheelEvent *we) const { return we->delta(); } diff --git a/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp b/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp index f9e7793ee2..55d7e4bcf1 100644 --- a/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkStdMultiWidget.cpp @@ -1,2034 +1,2034 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #define SMW_INFO MITK_INFO("widget.stdmulti") #include "QmitkStdMultiWidget.h" #include #include #include #include #include #include #include #include "mitkImagePixelReadAccessor.h" #include "mitkPixelTypeMultiplex.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QmitkStdMultiWidget::QmitkStdMultiWidget(QWidget *parent, Qt::WindowFlags f, mitk::RenderingManager *renderingManager, - mitk::BaseRenderer::RenderingMode::Type renderingMode, + mitk::BaseRenderer::RenderingMode renderingMode, const QString &name) : QWidget(parent, f), mitkWidget1(nullptr), mitkWidget2(nullptr), mitkWidget3(nullptr), mitkWidget4(nullptr), levelWindowWidget(nullptr), QmitkStdMultiWidgetLayout(nullptr), m_Layout(LAYOUT_DEFAULT), m_PlaneMode(PLANE_MODE_SLICING), m_RenderingManager(renderingManager), m_GradientBackgroundFlag(true), m_TimeNavigationController(nullptr), m_MainSplit(nullptr), m_LayoutSplit(nullptr), m_SubSplit1(nullptr), m_SubSplit2(nullptr), mitkWidget1Container(nullptr), mitkWidget2Container(nullptr), mitkWidget3Container(nullptr), mitkWidget4Container(nullptr), m_PendingCrosshairPositionEvent(false), m_CrosshairNavigationEnabled(false) { /****************************************************** * Use the global RenderingManager if none was specified * ****************************************************/ if (m_RenderingManager == nullptr) { m_RenderingManager = mitk::RenderingManager::GetInstance(); } m_TimeNavigationController = m_RenderingManager->GetTimeNavigationController(); /*******************************/ // Create Widget manually /*******************************/ // create Layouts QmitkStdMultiWidgetLayout = new QHBoxLayout(this); QmitkStdMultiWidgetLayout->setContentsMargins(0, 0, 0, 0); // Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(Qt::Vertical, m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // creae Widget Container mitkWidget1Container = new QWidget(m_SubSplit1); mitkWidget2Container = new QWidget(m_SubSplit1); mitkWidget3Container = new QWidget(m_SubSplit2); mitkWidget4Container = new QWidget(m_SubSplit2); mitkWidget1Container->setContentsMargins(0, 0, 0, 0); mitkWidget2Container->setContentsMargins(0, 0, 0, 0); mitkWidget3Container->setContentsMargins(0, 0, 0, 0); mitkWidget4Container->setContentsMargins(0, 0, 0, 0); // create Widget Layout QHBoxLayout *mitkWidgetLayout1 = new QHBoxLayout(mitkWidget1Container); QHBoxLayout *mitkWidgetLayout2 = new QHBoxLayout(mitkWidget2Container); QHBoxLayout *mitkWidgetLayout3 = new QHBoxLayout(mitkWidget3Container); QHBoxLayout *mitkWidgetLayout4 = new QHBoxLayout(mitkWidget4Container); m_CornerAnnotations[0] = vtkSmartPointer::New(); m_CornerAnnotations[1] = vtkSmartPointer::New(); m_CornerAnnotations[2] = vtkSmartPointer::New(); m_CornerAnnotations[3] = vtkSmartPointer::New(); m_RectangleProps[0] = vtkSmartPointer::New(); m_RectangleProps[1] = vtkSmartPointer::New(); m_RectangleProps[2] = vtkSmartPointer::New(); m_RectangleProps[3] = vtkSmartPointer::New(); mitkWidgetLayout1->setMargin(0); mitkWidgetLayout2->setMargin(0); mitkWidgetLayout3->setMargin(0); mitkWidgetLayout4->setMargin(0); // set Layout to Widget Container mitkWidget1Container->setLayout(mitkWidgetLayout1); mitkWidget2Container->setLayout(mitkWidgetLayout2); mitkWidget3Container->setLayout(mitkWidgetLayout3); mitkWidget4Container->setLayout(mitkWidgetLayout4); // set SizePolicy mitkWidget1Container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mitkWidget2Container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mitkWidget3Container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mitkWidget4Container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // insert Widget Container into the splitters m_SubSplit1->addWidget(mitkWidget1Container); m_SubSplit1->addWidget(mitkWidget2Container); m_SubSplit2->addWidget(mitkWidget3Container); m_SubSplit2->addWidget(mitkWidget4Container); // Create RenderWindows 1 mitkWidget1 = new QmitkRenderWindow(mitkWidget1Container, name + ".widget1", nullptr, m_RenderingManager, renderingMode); mitkWidget1->SetLayoutIndex(AXIAL); mitkWidgetLayout1->addWidget(mitkWidget1); // Create RenderWindows 2 mitkWidget2 = new QmitkRenderWindow(mitkWidget2Container, name + ".widget2", nullptr, m_RenderingManager, renderingMode); mitkWidget2->setEnabled(true); mitkWidget2->SetLayoutIndex(SAGITTAL); mitkWidgetLayout2->addWidget(mitkWidget2); // Create RenderWindows 3 mitkWidget3 = new QmitkRenderWindow(mitkWidget3Container, name + ".widget3", nullptr, m_RenderingManager, renderingMode); mitkWidget3->SetLayoutIndex(CORONAL); mitkWidgetLayout3->addWidget(mitkWidget3); // Create RenderWindows 4 mitkWidget4 = new QmitkRenderWindow(mitkWidget4Container, name + ".widget4", nullptr, m_RenderingManager, renderingMode); mitkWidget4->SetLayoutIndex(THREE_D); mitkWidgetLayout4->addWidget(mitkWidget4); // create SignalSlot Connection connect(mitkWidget1, SIGNAL(SignalLayoutDesignChanged(int)), this, SLOT(OnLayoutDesignChanged(int))); connect(mitkWidget1, SIGNAL(ResetView()), this, SLOT(ResetCrosshair())); connect(mitkWidget1, SIGNAL(ChangeCrosshairRotationMode(int)), this, SLOT(SetWidgetPlaneMode(int))); connect(this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget1, SLOT(OnWidgetPlaneModeChanged(int))); connect(mitkWidget2, SIGNAL(SignalLayoutDesignChanged(int)), this, SLOT(OnLayoutDesignChanged(int))); connect(mitkWidget2, SIGNAL(ResetView()), this, SLOT(ResetCrosshair())); connect(mitkWidget2, SIGNAL(ChangeCrosshairRotationMode(int)), this, SLOT(SetWidgetPlaneMode(int))); connect(this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget2, SLOT(OnWidgetPlaneModeChanged(int))); connect(mitkWidget3, SIGNAL(SignalLayoutDesignChanged(int)), this, SLOT(OnLayoutDesignChanged(int))); connect(mitkWidget3, SIGNAL(ResetView()), this, SLOT(ResetCrosshair())); connect(mitkWidget3, SIGNAL(ChangeCrosshairRotationMode(int)), this, SLOT(SetWidgetPlaneMode(int))); connect(this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget3, SLOT(OnWidgetPlaneModeChanged(int))); connect(mitkWidget4, SIGNAL(SignalLayoutDesignChanged(int)), this, SLOT(OnLayoutDesignChanged(int))); connect(mitkWidget4, SIGNAL(ResetView()), this, SLOT(ResetCrosshair())); connect(mitkWidget4, SIGNAL(ChangeCrosshairRotationMode(int)), this, SLOT(SetWidgetPlaneMode(int))); connect(this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget4, SLOT(OnWidgetPlaneModeChanged(int))); // Create Level Window Widget levelWindowWidget = new QmitkLevelWindowWidget(m_MainSplit); // this levelWindowWidget->setObjectName(QString::fromUtf8("levelWindowWidget")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(levelWindowWidget->sizePolicy().hasHeightForWidth()); levelWindowWidget->setSizePolicy(sizePolicy); levelWindowWidget->setMaximumWidth(50); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // show mainSplitt and add to Layout m_MainSplit->show(); // resize Image. this->resize(QSize(364, 477).expandedTo(minimumSizeHint())); // Initialize the widgets. this->InitializeWidget(); // Activate Widget Menu this->ActivateMenuWidget(true); } void QmitkStdMultiWidget::InitializeWidget() { // Make all black and overwrite renderwindow 4 this->FillGradientBackgroundWithBlack(); // This is #191919 in hex float tmp1[3] = {0.098f, 0.098f, 0.098f}; // This is #7F7F7F in hex float tmp2[3] = {0.498f, 0.498f, 0.498f}; m_GradientBackgroundColors[3] = std::make_pair(mitk::Color(tmp1), mitk::Color(tmp2)); // Yellow is default color for widget4 m_DecorationColorWidget4[0] = 1.0f; m_DecorationColorWidget4[1] = 1.0f; m_DecorationColorWidget4[2] = 0.0f; // transfer colors in WorldGeometry-Nodes of the associated Renderer mitk::IntProperty::Pointer layer; // of widget 1 m_PlaneNode1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode1->SetColor(GetDecorationColor(0)); layer = mitk::IntProperty::New(1000); m_PlaneNode1->SetProperty("layer", layer); // ... of widget 2 m_PlaneNode2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode2->SetColor(GetDecorationColor(1)); layer = mitk::IntProperty::New(1000); m_PlaneNode2->SetProperty("layer", layer); // ... of widget 3 m_PlaneNode3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode3->SetColor(GetDecorationColor(2)); layer = mitk::IntProperty::New(1000); m_PlaneNode3->SetProperty("layer", layer); // The parent node m_ParentNodeForGeometryPlanes = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); layer = mitk::IntProperty::New(1000); m_ParentNodeForGeometryPlanes->SetProperty("layer", layer); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetMapperID(mitk::BaseRenderer::Standard3D); // Set plane mode (slicing/rotation behavior) to slicing (default) m_PlaneMode = PLANE_MODE_SLICING; // Set default view directions for SNCs mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Frontal); mitkWidget4->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Original); SetDecorationProperties("Axial", GetDecorationColor(0), 0); SetDecorationProperties("Sagittal", GetDecorationColor(1), 1); SetDecorationProperties("Coronal", GetDecorationColor(2), 2); SetDecorationProperties("3D", GetDecorationColor(3), 3); // connect to the "time navigation controller": send time via sliceNavigationControllers m_TimeNavigationController->ConnectGeometryTimeEvent(mitkWidget1->GetSliceNavigationController(), false); m_TimeNavigationController->ConnectGeometryTimeEvent(mitkWidget2->GetSliceNavigationController(), false); m_TimeNavigationController->ConnectGeometryTimeEvent(mitkWidget3->GetSliceNavigationController(), false); m_TimeNavigationController->ConnectGeometryTimeEvent(mitkWidget4->GetSliceNavigationController(), false); mitkWidget1->GetSliceNavigationController()->ConnectGeometrySendEvent( mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); // reverse connection between sliceNavigationControllers and m_TimeNavigationController mitkWidget1->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget2->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget3->GetSliceNavigationController()->ConnectGeometryTimeEvent(m_TimeNavigationController, false); // mitkWidget4->GetSliceNavigationController() // ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); m_MouseModeSwitcher = mitk::MouseModeSwitcher::New(); // setup the department logo rendering m_LogoRendering = mitk::LogoAnnotation::New(); mitk::BaseRenderer::Pointer renderer4 = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()); m_LogoRendering->SetOpacity(0.5); mitk::Point2D offset; offset.Fill(0.03); m_LogoRendering->SetOffsetVector(offset); m_LogoRendering->SetRelativeSize(0.25); m_LogoRendering->SetCornerPosition(1); SetDepartmentLogo(":/org.mitk.gui.qt.stdmultiwidgeteditor/defaultWatermark.png"); mitk::ManualPlacementAnnotationRenderer::AddAnnotation(m_LogoRendering.GetPointer(), renderer4); } void QmitkStdMultiWidget::FillGradientBackgroundWithBlack() { // We have 4 widgets and ... for (unsigned int i = 0; i < 4; ++i) { float black[3] = { 0.0f, 0.0f, 0.0f }; m_GradientBackgroundColors[i] = std::make_pair(mitk::Color(black), mitk::Color(black)); } } std::pair QmitkStdMultiWidget::GetGradientColors(unsigned int widgetNumber) { if (widgetNumber > 3) { MITK_ERROR << "Decoration color for unknown widget!"; float black[3] = { 0.0f, 0.0f, 0.0f }; return std::make_pair(mitk::Color(black), mitk::Color(black)); } return m_GradientBackgroundColors[widgetNumber]; } mitk::Color QmitkStdMultiWidget::GetDecorationColor(unsigned int widgetNumber) { // The implementation looks a bit messy here, but it avoids // synchronization of the color of the geometry nodes and an // internal member here. // Default colors were chosen for decent visibitliy. // Feel free to change your preferences in the workbench. float tmp[3] = {0.0f, 0.0f, 0.0f}; switch (widgetNumber) { case 0: { if (m_PlaneNode1.IsNotNull()) { if (m_PlaneNode1->GetColor(tmp)) { return dynamic_cast(m_PlaneNode1->GetProperty("color"))->GetColor(); } } float red[3] = {0.753f, 0.0f, 0.0f}; // This is #C00000 in hex return mitk::Color(red); } case 1: { if (m_PlaneNode2.IsNotNull()) { if (m_PlaneNode2->GetColor(tmp)) { return dynamic_cast(m_PlaneNode2->GetProperty("color"))->GetColor(); } } float green[3] = {0.0f, 0.69f, 0.0f}; // This is #00B000 in hex return mitk::Color(green); } case 2: { if (m_PlaneNode3.IsNotNull()) { if (m_PlaneNode3->GetColor(tmp)) { return dynamic_cast(m_PlaneNode3->GetProperty("color"))->GetColor(); } } float blue[3] = {0.0, 0.502f, 1.0f}; // This is #0080FF in hex return mitk::Color(blue); } case 3: { return m_DecorationColorWidget4; } default: MITK_ERROR << "Decoration color for unknown widget!"; float black[3] = {0.0f, 0.0f, 0.0f}; return mitk::Color(black); } } std::string QmitkStdMultiWidget::GetCornerAnnotationText(unsigned int widgetNumber) { if (widgetNumber > 3) { MITK_ERROR << "Decoration color for unknown widget!"; return std::string(""); } return std::string(m_CornerAnnotations[widgetNumber]->GetText(0)); } QmitkStdMultiWidget::~QmitkStdMultiWidget() { DisablePositionTracking(); // DisableNavigationControllerEventListening(); m_TimeNavigationController->Disconnect(mitkWidget1->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget2->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget3->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget4->GetSliceNavigationController()); } void QmitkStdMultiWidget::RemovePlanesFromDataStorage() { if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) { if (m_DataStorage.IsNotNull()) { m_DataStorage->Remove(m_PlaneNode1); m_DataStorage->Remove(m_PlaneNode2); m_DataStorage->Remove(m_PlaneNode3); m_DataStorage->Remove(m_ParentNodeForGeometryPlanes); } } } void QmitkStdMultiWidget::AddPlanesToDataStorage() { if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) { if (m_DataStorage.IsNotNull()) { m_DataStorage->Add(m_ParentNodeForGeometryPlanes); m_DataStorage->Add(m_PlaneNode1, m_ParentNodeForGeometryPlanes); m_DataStorage->Add(m_PlaneNode2, m_ParentNodeForGeometryPlanes); m_DataStorage->Add(m_PlaneNode3, m_ParentNodeForGeometryPlanes); } } } void QmitkStdMultiWidget::changeLayoutTo2DImagesUp() { SMW_INFO << "changing layout to 2D images up... " << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(Qt::Vertical, m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // insert Widget Container into splitter top m_SubSplit1->addWidget(mitkWidget1Container); m_SubSplit1->addWidget(mitkWidget2Container); m_SubSplit1->addWidget(mitkWidget3Container); // set SplitterSize for splitter top QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes(splitterSize); // insert Widget Container into splitter bottom m_SubSplit2->addWidget(mitkWidget4Container); // set SplitterSize for splitter m_LayoutSplit splitterSize.clear(); splitterSize.push_back(400); splitterSize.push_back(1000); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt m_MainSplit->show(); // show Widget if hidden if (mitkWidget1->isHidden()) mitkWidget1->show(); if (mitkWidget2->isHidden()) mitkWidget2->show(); if (mitkWidget3->isHidden()) mitkWidget3->show(); if (mitkWidget4->isHidden()) mitkWidget4->show(); // Change Layout Name m_Layout = LAYOUT_2D_IMAGES_UP; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_2D_IMAGES_UP); mitkWidget2->LayoutDesignListChanged(LAYOUT_2D_IMAGES_UP); mitkWidget3->LayoutDesignListChanged(LAYOUT_2D_IMAGES_UP); mitkWidget4->LayoutDesignListChanged(LAYOUT_2D_IMAGES_UP); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2DImagesLeft() { SMW_INFO << "changing layout to 2D images left... " << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(Qt::Vertical, m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // insert Widget into the splitters m_SubSplit1->addWidget(mitkWidget1Container); m_SubSplit1->addWidget(mitkWidget2Container); m_SubSplit1->addWidget(mitkWidget3Container); // set splitterSize of SubSplit1 QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes(splitterSize); m_SubSplit2->addWidget(mitkWidget4Container); // set splitterSize of Layout Split splitterSize.clear(); splitterSize.push_back(400); splitterSize.push_back(1000); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt and add to Layout m_MainSplit->show(); // show Widget if hidden if (mitkWidget1->isHidden()) mitkWidget1->show(); if (mitkWidget2->isHidden()) mitkWidget2->show(); if (mitkWidget3->isHidden()) mitkWidget3->show(); if (mitkWidget4->isHidden()) mitkWidget4->show(); // update Layout Name m_Layout = LAYOUT_2D_IMAGES_LEFT; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_2D_IMAGES_LEFT); mitkWidget2->LayoutDesignListChanged(LAYOUT_2D_IMAGES_LEFT); mitkWidget3->LayoutDesignListChanged(LAYOUT_2D_IMAGES_LEFT); mitkWidget4->LayoutDesignListChanged(LAYOUT_2D_IMAGES_LEFT); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::SetDecorationProperties(std::string text, mitk::Color color, int widgetNumber) { if (widgetNumber > 3) { MITK_ERROR << "Unknown render window for annotation."; return; } vtkRenderer *renderer = this->GetRenderWindow(widgetNumber)->GetRenderer()->GetVtkRenderer(); if (!renderer) return; vtkSmartPointer annotation = m_CornerAnnotations[widgetNumber]; annotation->SetText(0, text.c_str()); annotation->SetMaximumFontSize(12); annotation->GetTextProperty()->SetColor(color[0], color[1], color[2]); if (!renderer->HasViewProp(annotation)) { renderer->AddViewProp(annotation); } vtkSmartPointer frame = m_RectangleProps[widgetNumber]; frame->SetColor(color[0], color[1], color[2]); if (!renderer->HasViewProp(frame)) { renderer->AddViewProp(frame); } } void QmitkStdMultiWidget::SetCornerAnnotationVisibility(bool visibility) { for (int i = 0; i < 4; ++i) { m_CornerAnnotations[i]->SetVisibility(visibility); } } bool QmitkStdMultiWidget::IsCornerAnnotationVisible(void) const { return m_CornerAnnotations[0]->GetVisibility() > 0; } QmitkRenderWindow *QmitkStdMultiWidget::GetRenderWindow(unsigned int number) { switch (number) { case 0: return this->GetRenderWindow1(); case 1: return this->GetRenderWindow2(); case 2: return this->GetRenderWindow3(); case 3: return this->GetRenderWindow4(); default: MITK_ERROR << "Requested unknown render window"; break; } return nullptr; } void QmitkStdMultiWidget::changeLayoutToDefault() { SMW_INFO << "changing layout to default... " << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(Qt::Vertical, m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // insert Widget container into the splitters m_SubSplit1->addWidget(mitkWidget1Container); m_SubSplit1->addWidget(mitkWidget2Container); m_SubSplit2->addWidget(mitkWidget3Container); m_SubSplit2->addWidget(mitkWidget4Container); // set splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes(splitterSize); m_SubSplit2->setSizes(splitterSize); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt and add to Layout m_MainSplit->show(); // show Widget if hidden if (mitkWidget1->isHidden()) mitkWidget1->show(); if (mitkWidget2->isHidden()) mitkWidget2->show(); if (mitkWidget3->isHidden()) mitkWidget3->show(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_DEFAULT; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_DEFAULT); mitkWidget2->LayoutDesignListChanged(LAYOUT_DEFAULT); mitkWidget3->LayoutDesignListChanged(LAYOUT_DEFAULT); mitkWidget4->LayoutDesignListChanged(LAYOUT_DEFAULT); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToBig3D() { SMW_INFO << "changing layout to big 3D ..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // add widget Splitter to main Splitter m_MainSplit->addWidget(mitkWidget4Container); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); mitkWidget3->hide(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_BIG_3D; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_BIG_3D); mitkWidget2->LayoutDesignListChanged(LAYOUT_BIG_3D); mitkWidget3->LayoutDesignListChanged(LAYOUT_BIG_3D); mitkWidget4->LayoutDesignListChanged(LAYOUT_BIG_3D); // update Alle Widgets this->UpdateAllWidgets(); mitk::RenderingManager::GetInstance()->SetRenderWindowFocus(mitkWidget4->GetVtkRenderWindow()); } void QmitkStdMultiWidget::changeLayoutToWidget1() { SMW_INFO << "changing layout to big Widget1 ..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // add widget Splitter to main Splitter m_MainSplit->addWidget(mitkWidget1Container); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets if (mitkWidget1->isHidden()) mitkWidget1->show(); mitkWidget2->hide(); mitkWidget3->hide(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET1; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_WIDGET1); mitkWidget2->LayoutDesignListChanged(LAYOUT_WIDGET1); mitkWidget3->LayoutDesignListChanged(LAYOUT_WIDGET1); mitkWidget4->LayoutDesignListChanged(LAYOUT_WIDGET1); // update Alle Widgets this->UpdateAllWidgets(); mitk::RenderingManager::GetInstance()->SetRenderWindowFocus(mitkWidget1->GetVtkRenderWindow()); } void QmitkStdMultiWidget::changeLayoutToWidget2() { SMW_INFO << "changing layout to big Widget2 ..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // add widget Splitter to main Splitter m_MainSplit->addWidget(mitkWidget2Container); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets mitkWidget1->hide(); if (mitkWidget2->isHidden()) mitkWidget2->show(); mitkWidget3->hide(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET2; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_WIDGET2); mitkWidget2->LayoutDesignListChanged(LAYOUT_WIDGET2); mitkWidget3->LayoutDesignListChanged(LAYOUT_WIDGET2); mitkWidget4->LayoutDesignListChanged(LAYOUT_WIDGET2); // update Alle Widgets this->UpdateAllWidgets(); mitk::RenderingManager::GetInstance()->SetRenderWindowFocus(mitkWidget2->GetVtkRenderWindow()); } void QmitkStdMultiWidget::changeLayoutToWidget3() { SMW_INFO << "changing layout to big Widget3 ..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // add widget Splitter to main Splitter m_MainSplit->addWidget(mitkWidget3Container); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if (mitkWidget3->isHidden()) mitkWidget3->show(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET3; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_WIDGET3); mitkWidget2->LayoutDesignListChanged(LAYOUT_WIDGET3); mitkWidget3->LayoutDesignListChanged(LAYOUT_WIDGET3); mitkWidget4->LayoutDesignListChanged(LAYOUT_WIDGET3); // update Alle Widgets this->UpdateAllWidgets(); mitk::RenderingManager::GetInstance()->SetRenderWindowFocus(mitkWidget3->GetVtkRenderWindow()); } void QmitkStdMultiWidget::changeLayoutToRowWidget3And4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(Qt::Vertical, m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // add Widgets to splitter m_LayoutSplit->addWidget(mitkWidget3Container); m_LayoutSplit->addWidget(mitkWidget4Container); // set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if (mitkWidget3->isHidden()) mitkWidget3->show(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_ROW_WIDGET_3_AND_4; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_ROW_WIDGET_3_AND_4); mitkWidget2->LayoutDesignListChanged(LAYOUT_ROW_WIDGET_3_AND_4); mitkWidget3->LayoutDesignListChanged(LAYOUT_ROW_WIDGET_3_AND_4); mitkWidget4->LayoutDesignListChanged(LAYOUT_ROW_WIDGET_3_AND_4); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToColumnWidget3And4() { SMW_INFO << "changing layout to Widget3 and 4 in one Column..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // add Widgets to splitter m_LayoutSplit->addWidget(mitkWidget3Container); m_LayoutSplit->addWidget(mitkWidget4Container); // set SplitterSize QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if (mitkWidget3->isHidden()) mitkWidget3->show(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_COLUMN_WIDGET_3_AND_4; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_COLUMN_WIDGET_3_AND_4); mitkWidget2->LayoutDesignListChanged(LAYOUT_COLUMN_WIDGET_3_AND_4); mitkWidget3->LayoutDesignListChanged(LAYOUT_COLUMN_WIDGET_3_AND_4); mitkWidget4->LayoutDesignListChanged(LAYOUT_COLUMN_WIDGET_3_AND_4); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToRowWidgetSmall3andBig4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; this->changeLayoutToRowWidget3And4(); m_Layout = LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4; } void QmitkStdMultiWidget::changeLayoutToSmallUpperWidget2Big3and4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(Qt::Vertical, m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(Qt::Vertical, m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // insert Widget into the splitters m_SubSplit1->addWidget(mitkWidget2Container); m_SubSplit2->addWidget(mitkWidget3Container); m_SubSplit2->addWidget(mitkWidget4Container); // set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit2->setSizes(splitterSize); splitterSize.clear(); splitterSize.push_back(500); splitterSize.push_back(1000); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt m_MainSplit->show(); // show Widget if hidden mitkWidget1->hide(); if (mitkWidget2->isHidden()) mitkWidget2->show(); if (mitkWidget3->isHidden()) mitkWidget3->show(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4); mitkWidget2->LayoutDesignListChanged(LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4); mitkWidget3->LayoutDesignListChanged(LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4); mitkWidget4->LayoutDesignListChanged(LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2x2Dand3DWidget() { SMW_INFO << "changing layout to 2 x 2D and 3D Widget" << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(Qt::Vertical, m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // add Widgets to splitter m_SubSplit1->addWidget(mitkWidget1Container); m_SubSplit1->addWidget(mitkWidget2Container); m_SubSplit2->addWidget(mitkWidget4Container); // set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes(splitterSize); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets if (mitkWidget1->isHidden()) mitkWidget1->show(); if (mitkWidget2->isHidden()) mitkWidget2->show(); mitkWidget3->hide(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_2X_2D_AND_3D_WIDGET; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_2X_2D_AND_3D_WIDGET); mitkWidget2->LayoutDesignListChanged(LAYOUT_2X_2D_AND_3D_WIDGET); mitkWidget3->LayoutDesignListChanged(LAYOUT_2X_2D_AND_3D_WIDGET); mitkWidget4->LayoutDesignListChanged(LAYOUT_2X_2D_AND_3D_WIDGET); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToLeft2Dand3DRight2D() { SMW_INFO << "changing layout to 2D and 3D left, 2D right Widget" << std::endl; // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(Qt::Vertical, m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // add Widgets to splitter m_SubSplit1->addWidget(mitkWidget1Container); m_SubSplit1->addWidget(mitkWidget4Container); m_SubSplit2->addWidget(mitkWidget2Container); // set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes(splitterSize); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt and add to Layout m_MainSplit->show(); // show/hide Widgets if (mitkWidget1->isHidden()) mitkWidget1->show(); if (mitkWidget2->isHidden()) mitkWidget2->show(); mitkWidget3->hide(); if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET); mitkWidget2->LayoutDesignListChanged(LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET); mitkWidget3->LayoutDesignListChanged(LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET); mitkWidget4->LayoutDesignListChanged(LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET); // update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2DUpAnd3DDown(unsigned int id2Dwindow) { SMW_INFO << "changing layout to 2D up and 3D down" << std::endl; if (id2Dwindow < 1 || id2Dwindow > 3) { MITK_WARN << "Only 2D render window IDs 1,2 or 3 are valid. Got ID " << id2Dwindow << ". " << "Using default ID 2 instead."; id2Dwindow = 2; } // Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout; // create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout(this); // Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); // create main splitter m_MainSplit = new QSplitter(this); QmitkStdMultiWidgetLayout->addWidget(m_MainSplit); // create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter(Qt::Vertical, m_MainSplit); m_MainSplit->addWidget(m_LayoutSplit); // add LevelWindow Widget to mainSplitter m_MainSplit->addWidget(levelWindowWidget); // create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter(m_LayoutSplit); m_SubSplit2 = new QSplitter(m_LayoutSplit); // insert Widget Container into splitter top switch (id2Dwindow) { case 1: m_SubSplit1->addWidget(mitkWidget1Container); break; case 2: m_SubSplit1->addWidget(mitkWidget2Container); break; case 3: m_SubSplit1->addWidget(mitkWidget3Container); break; } // set SplitterSize for splitter top QList splitterSize; // insert Widget Container into splitter bottom m_SubSplit2->addWidget(mitkWidget4Container); // set SplitterSize for splitter m_LayoutSplit splitterSize.clear(); splitterSize.push_back(700); splitterSize.push_back(700); m_LayoutSplit->setSizes(splitterSize); // show mainSplitt m_MainSplit->show(); // show/hide Widgets switch (id2Dwindow) { case 1: if (mitkWidget1->isHidden()) mitkWidget1->show(); mitkWidget2->hide(); mitkWidget3->hide(); break; case 2: if (mitkWidget2->isHidden()) mitkWidget2->show(); mitkWidget1->hide(); mitkWidget3->hide(); break; case 3: if (mitkWidget3->isHidden()) mitkWidget3->show(); mitkWidget1->hide(); mitkWidget2->hide(); break; } //always show 3D widget if (mitkWidget4->isHidden()) mitkWidget4->show(); m_Layout = LAYOUT_2D_UP_AND_3D_DOWN; // update Layout Design List mitkWidget1->LayoutDesignListChanged(LAYOUT_2D_UP_AND_3D_DOWN); mitkWidget2->LayoutDesignListChanged(LAYOUT_2D_UP_AND_3D_DOWN); mitkWidget3->LayoutDesignListChanged(LAYOUT_2D_UP_AND_3D_DOWN); mitkWidget4->LayoutDesignListChanged(LAYOUT_2D_UP_AND_3D_DOWN); // update all Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::SetDataStorage(mitk::DataStorage *ds) { if (ds == m_DataStorage) { return; } mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetDataStorage(ds); m_DataStorage = ds; } void QmitkStdMultiWidget::Fit() { vtkSmartPointer vtkrenderer; vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetVtkRenderer(); if (vtkrenderer != nullptr) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetVtkRenderer(); if (vtkrenderer != nullptr) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetVtkRenderer(); if (vtkrenderer != nullptr) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetVtkRenderer(); if (vtkrenderer != nullptr) vtkrenderer->ResetCamera(); mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCameraController()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCameraController()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCameraController()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCameraController()->Fit(); int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); vtkObject::SetGlobalWarningDisplay(w); } void QmitkStdMultiWidget::InitPositionTracking() { // TODO POSITIONTRACKER } void QmitkStdMultiWidget::AddDisplayPlaneSubTree() { // add the displayed planes of the multiwidget to a node to which the subtree // @a planesSubTree points ... mitk::PlaneGeometryDataMapper2D::Pointer mapper; // ... of widget 1 mitk::BaseRenderer *renderer1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()); m_PlaneNode1 = renderer1->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode1->SetProperty("name", mitk::StringProperty::New(std::string(renderer1->GetName()) + ".plane")); m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 2 mitk::BaseRenderer *renderer2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow()); m_PlaneNode2 = renderer2->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode2->SetProperty("name", mitk::StringProperty::New(std::string(renderer2->GetName()) + ".plane")); m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 3 mitk::BaseRenderer *renderer3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow()); m_PlaneNode3 = renderer3->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode3->SetProperty("name", mitk::StringProperty::New(std::string(renderer3->GetName()) + ".plane")); m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode3->SetMapper(mitk::BaseRenderer::Standard2D, mapper); m_ParentNodeForGeometryPlanes = mitk::DataNode::New(); m_ParentNodeForGeometryPlanes->SetProperty("name", mitk::StringProperty::New("Widgets")); m_ParentNodeForGeometryPlanes->SetProperty("helper object", mitk::BoolProperty::New(true)); } mitk::SliceNavigationController *QmitkStdMultiWidget::GetTimeNavigationController() { return m_TimeNavigationController; } void QmitkStdMultiWidget::EnableStandardLevelWindow() { levelWindowWidget->disconnect(this); levelWindowWidget->SetDataStorage(mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDataStorage()); levelWindowWidget->show(); } void QmitkStdMultiWidget::DisableStandardLevelWindow() { levelWindowWidget->disconnect(this); levelWindowWidget->hide(); } // CAUTION: Legacy code for enabling Qt-signal-controlled view initialization. // Use RenderingManager::InitializeViews() instead. bool QmitkStdMultiWidget::InitializeStandardViews(const mitk::Geometry3D *geometry) { return m_RenderingManager->InitializeViews(geometry); } void QmitkStdMultiWidget::RequestUpdate() { m_RenderingManager->RequestUpdate(mitkWidget1->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget2->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget3->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget4->GetRenderWindow()); } void QmitkStdMultiWidget::ForceImmediateUpdate() { m_RenderingManager->ForceImmediateUpdate(mitkWidget1->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget2->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget3->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget4->GetRenderWindow()); } void QmitkStdMultiWidget::wheelEvent(QWheelEvent *e) { emit WheelMoved(e); } void QmitkStdMultiWidget::mousePressEvent(QMouseEvent *) { } void QmitkStdMultiWidget::moveEvent(QMoveEvent *e) { QWidget::moveEvent(e); // it is necessary to readjust the position of the Annotation as the StdMultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } QmitkRenderWindow *QmitkStdMultiWidget::GetRenderWindow1() const { return mitkWidget1; } QmitkRenderWindow *QmitkStdMultiWidget::GetRenderWindow2() const { return mitkWidget2; } QmitkRenderWindow *QmitkStdMultiWidget::GetRenderWindow3() const { return mitkWidget3; } QmitkRenderWindow *QmitkStdMultiWidget::GetRenderWindow4() const { return mitkWidget4; } const mitk::Point3D QmitkStdMultiWidget::GetCrossPosition() const { const mitk::PlaneGeometry *plane1 = mitkWidget1->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane2 = mitkWidget2->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane3 = mitkWidget3->GetSliceNavigationController()->GetCurrentPlaneGeometry(); mitk::Line3D line; if ((plane1 != nullptr) && (plane2 != nullptr) && (plane1->IntersectionLine(plane2, line))) { mitk::Point3D point; if ((plane3 != nullptr) && (plane3->IntersectionPoint(line, point))) { return point; } } // TODO BUG POSITIONTRACKER; mitk::Point3D p; return p; // return m_LastLeftClickPositionSupplier->GetCurrentPoint(); } void QmitkStdMultiWidget::EnablePositionTracking() { } void QmitkStdMultiWidget::DisablePositionTracking() { } void QmitkStdMultiWidget::EnsureDisplayContainsPoint(mitk::BaseRenderer *renderer, const mitk::Point3D &p) { mitk::Point2D pointOnDisplay; renderer->WorldToDisplay(p, pointOnDisplay); if (pointOnDisplay[0] < renderer->GetVtkRenderer()->GetOrigin()[0] || pointOnDisplay[1] < renderer->GetVtkRenderer()->GetOrigin()[1] || pointOnDisplay[0] > renderer->GetVtkRenderer()->GetOrigin()[0] + renderer->GetViewportSize()[0] || pointOnDisplay[1] > renderer->GetVtkRenderer()->GetOrigin()[1] + renderer->GetViewportSize()[1]) { mitk::Point2D pointOnPlane; renderer->GetCurrentWorldPlaneGeometry()->Map(p, pointOnPlane); renderer->GetCameraController()->MoveCameraToPoint(pointOnPlane); } } void QmitkStdMultiWidget::MoveCrossToPosition(const mitk::Point3D &newPosition) { mitkWidget1->GetSliceNavigationController()->SelectSliceByPoint(newPosition); mitkWidget2->GetSliceNavigationController()->SelectSliceByPoint(newPosition); mitkWidget3->GetSliceNavigationController()->SelectSliceByPoint(newPosition); m_RenderingManager->RequestUpdateAll(); } void QmitkStdMultiWidget::HandleCrosshairPositionEvent() { if (!m_PendingCrosshairPositionEvent) { m_PendingCrosshairPositionEvent = true; QTimer::singleShot(0, this, SLOT(HandleCrosshairPositionEventDelayed())); } } void QmitkStdMultiWidget::HandleCrosshairPositionEventDelayed() { m_PendingCrosshairPositionEvent = false; // find image with highest layer mitk::TNodePredicateDataType::Pointer isImageData = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = m_DataStorage->GetSubset(isImageData).GetPointer(); mitk::Point3D crosshairPos = GetCrossPosition(); mitk::BaseRenderer* baseRenderer = mitkWidget1->GetSliceNavigationController()->GetRenderer(); auto globalCurrentTimePoint = baseRenderer->GetTime(); mitk::DataNode::Pointer node = mitk::FindTopmostVisibleNode(nodes, crosshairPos, globalCurrentTimePoint, baseRenderer); mitk::DataNode::Pointer topSourceNode; mitk::Image::Pointer image; bool isBinary = false; int component = 0; if (node.IsNotNull()) { node->GetBoolProperty("binary", isBinary); if (isBinary) { mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = m_DataStorage->GetSources(node, nullptr, true); if (!sourcenodes->empty()) { topSourceNode = mitk::FindTopmostVisibleNode(sourcenodes, crosshairPos,globalCurrentTimePoint, baseRenderer); } if (topSourceNode.IsNotNull()) { image = dynamic_cast(topSourceNode->GetData()); topSourceNode->GetIntProperty("Image.Displayed Component", component); } else { image = dynamic_cast(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } else { image = dynamic_cast(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } std::string statusText; std::stringstream stream; itk::Index<3> p; unsigned int timestep = baseRenderer->GetTimeStep(); if (image.IsNotNull() && (image->GetTimeSteps() > timestep)) { image->GetGeometry()->WorldToIndex(crosshairPos, p); stream.precision(2); stream << "Position: <" << std::fixed << crosshairPos[0] << ", " << std::fixed << crosshairPos[1] << ", " << std::fixed << crosshairPos[2] << "> mm"; stream << "; Index: <" << p[0] << ", " << p[1] << ", " << p[2] << "> "; mitk::ScalarType pixelValue; mitkPixelTypeMultiplex5(mitk::FastSinglePixelAccess, image->GetChannelDescriptor().GetPixelType(), image, image->GetVolumeData(image->GetTimeGeometry()->TimePointToTimeStep(globalCurrentTimePoint)), p, pixelValue, component); if (fabs(pixelValue) > 1000000 || fabs(pixelValue) < 0.01) { stream << "; Time: " <DisplayGreyValueText(statusText.c_str()); } int QmitkStdMultiWidget::GetLayout() const { return m_Layout; } bool QmitkStdMultiWidget::GetGradientBackgroundFlag() const { return m_GradientBackgroundFlag; } void QmitkStdMultiWidget::EnableGradientBackground() { // gradient background is by default only in widget 4, otherwise // interferences between 2D rendering and VTK rendering may occur. for (unsigned int i = 0; i < 4; ++i) { GetRenderWindow(i)->GetRenderer()->GetVtkRenderer()->GradientBackgroundOn(); } m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::DisableGradientBackground() { for (unsigned int i = 0; i < 4; ++i) { GetRenderWindow(i)->GetRenderer()->GetVtkRenderer()->GradientBackgroundOff(); } m_GradientBackgroundFlag = false; } void QmitkStdMultiWidget::EnableDepartmentLogo() { m_LogoRendering->SetVisibility(true); RequestUpdate(); } void QmitkStdMultiWidget::DisableDepartmentLogo() { m_LogoRendering->SetVisibility(false); RequestUpdate(); } bool QmitkStdMultiWidget::IsDepartmentLogoEnabled() const { return m_LogoRendering->IsVisible(); } void QmitkStdMultiWidget::SetWidgetPlaneVisibility(const char *widgetName, bool visible, mitk::BaseRenderer *renderer) { if (m_DataStorage.IsNotNull()) { mitk::DataNode *n = m_DataStorage->GetNamedNode(widgetName); if (n != nullptr) n->SetVisibility(visible, renderer); } } void QmitkStdMultiWidget::SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer) { if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetVisibility(visible, renderer); } if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetVisibility(visible, renderer); } if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetVisibility(visible, renderer); } m_RenderingManager->RequestUpdateAll(); } void QmitkStdMultiWidget::SetWidgetPlanesLocked(bool locked) { // do your job and lock or unlock slices. GetRenderWindow1()->GetSliceNavigationController()->SetSliceLocked(locked); GetRenderWindow2()->GetSliceNavigationController()->SetSliceLocked(locked); GetRenderWindow3()->GetSliceNavigationController()->SetSliceLocked(locked); } void QmitkStdMultiWidget::SetWidgetPlanesRotationLocked(bool locked) { // do your job and lock or unlock slices. GetRenderWindow1()->GetSliceNavigationController()->SetSliceRotationLocked(locked); GetRenderWindow2()->GetSliceNavigationController()->SetSliceRotationLocked(locked); GetRenderWindow3()->GetSliceNavigationController()->SetSliceRotationLocked(locked); } void QmitkStdMultiWidget::SetWidgetPlanesRotationLinked(bool link) { emit WidgetPlanesRotationLinked(link); } void QmitkStdMultiWidget::SetWidgetPlaneMode(int userMode) { MITK_DEBUG << "Changing crosshair mode to " << userMode; emit WidgetNotifyNewCrossHairMode(userMode); // Convert user interface mode to actual mode { switch (userMode) { case 0: m_MouseModeSwitcher->SetInteractionScheme(mitk::MouseModeSwitcher::InteractionScheme::MITK); break; case 1: m_MouseModeSwitcher->SetInteractionScheme(mitk::MouseModeSwitcher::InteractionScheme::ROTATION); break; case 2: m_MouseModeSwitcher->SetInteractionScheme(mitk::MouseModeSwitcher::InteractionScheme::ROTATIONLINKED); break; case 3: m_MouseModeSwitcher->SetInteractionScheme(mitk::MouseModeSwitcher::InteractionScheme::SWIVEL); break; } } } void QmitkStdMultiWidget::SetGradientBackgroundColorForRenderWindow(const mitk::Color &upper, const mitk::Color &lower, unsigned int widgetNumber) { if (widgetNumber > 3) { MITK_ERROR << "Gradientbackground for unknown widget!"; return; } m_GradientBackgroundColors[widgetNumber].first = upper; m_GradientBackgroundColors[widgetNumber].second = lower; vtkRenderer *renderer = GetRenderWindow(widgetNumber)->GetRenderer()->GetVtkRenderer(); renderer->SetBackground2(upper[0], upper[1], upper[2]); renderer->SetBackground(lower[0], lower[1], lower[2]); m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::SetGradientBackgroundColors(const mitk::Color &upper, const mitk::Color &lower) { for (unsigned int i = 0; i < 4; ++i) { vtkRenderer *renderer = GetRenderWindow(i)->GetRenderer()->GetVtkRenderer(); renderer->SetBackground2(upper[0], upper[1], upper[2]); renderer->SetBackground(lower[0], lower[1], lower[2]); } m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::SetDepartmentLogo(const char *path) { QImage* qimage = new QImage(path); vtkSmartPointer qImageToVtk; qImageToVtk = vtkSmartPointer::New(); qImageToVtk->SetQImage(qimage); qImageToVtk->Update(); m_LogoRendering->SetLogoImage(qImageToVtk->GetOutput()); mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()); m_LogoRendering->Update(renderer); RequestUpdate(); } void QmitkStdMultiWidget::SetWidgetPlaneModeToSlicing(bool activate) { if (activate) { this->SetWidgetPlaneMode(PLANE_MODE_SLICING); } } void QmitkStdMultiWidget::SetWidgetPlaneModeToRotation(bool activate) { if (activate) { this->SetWidgetPlaneMode(PLANE_MODE_ROTATION); } } void QmitkStdMultiWidget::SetWidgetPlaneModeToSwivel(bool activate) { if (activate) { this->SetWidgetPlaneMode(PLANE_MODE_SWIVEL); } } void QmitkStdMultiWidget::OnLayoutDesignChanged(int layoutDesignIndex) { switch (layoutDesignIndex) { case LAYOUT_DEFAULT: { this->changeLayoutToDefault(); break; } case LAYOUT_2D_IMAGES_UP: { this->changeLayoutTo2DImagesUp(); break; } case LAYOUT_2D_IMAGES_LEFT: { this->changeLayoutTo2DImagesLeft(); break; } case LAYOUT_BIG_3D: { this->changeLayoutToBig3D(); break; } case LAYOUT_WIDGET1: { this->changeLayoutToWidget1(); break; } case LAYOUT_WIDGET2: { this->changeLayoutToWidget2(); break; } case LAYOUT_WIDGET3: { this->changeLayoutToWidget3(); break; } case LAYOUT_2X_2D_AND_3D_WIDGET: { this->changeLayoutTo2x2Dand3DWidget(); break; } case LAYOUT_ROW_WIDGET_3_AND_4: { this->changeLayoutToRowWidget3And4(); break; } case LAYOUT_COLUMN_WIDGET_3_AND_4: { this->changeLayoutToColumnWidget3And4(); break; } case LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4: { this->changeLayoutToRowWidgetSmall3andBig4(); break; } case LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4: { this->changeLayoutToSmallUpperWidget2Big3and4(); break; } case LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET: { this->changeLayoutToLeft2Dand3DRight2D(); break; } }; } void QmitkStdMultiWidget::UpdateAllWidgets() { mitkWidget1->resize(mitkWidget1Container->frameSize().width() - 1, mitkWidget1Container->frameSize().height()); mitkWidget1->resize(mitkWidget1Container->frameSize().width(), mitkWidget1Container->frameSize().height()); mitkWidget2->resize(mitkWidget2Container->frameSize().width() - 1, mitkWidget2Container->frameSize().height()); mitkWidget2->resize(mitkWidget2Container->frameSize().width(), mitkWidget2Container->frameSize().height()); mitkWidget3->resize(mitkWidget3Container->frameSize().width() - 1, mitkWidget3Container->frameSize().height()); mitkWidget3->resize(mitkWidget3Container->frameSize().width(), mitkWidget3Container->frameSize().height()); mitkWidget4->resize(mitkWidget4Container->frameSize().width() - 1, mitkWidget4Container->frameSize().height()); mitkWidget4->resize(mitkWidget4Container->frameSize().width(), mitkWidget4Container->frameSize().height()); } void QmitkStdMultiWidget::HideAllWidgetToolbars() { mitkWidget1->HideRenderWindowMenu(); mitkWidget2->HideRenderWindowMenu(); mitkWidget3->HideRenderWindowMenu(); mitkWidget4->HideRenderWindowMenu(); } void QmitkStdMultiWidget::ActivateMenuWidget(bool state) { mitkWidget1->ActivateMenuWidget(state, this); mitkWidget2->ActivateMenuWidget(state, this); mitkWidget3->ActivateMenuWidget(state, this); mitkWidget4->ActivateMenuWidget(state, this); } bool QmitkStdMultiWidget::IsMenuWidgetEnabled() const { return mitkWidget1->GetActivateMenuWidgetFlag(); } void QmitkStdMultiWidget::SetDecorationColor(unsigned int widgetNumber, mitk::Color color) { switch (widgetNumber) { case 0: if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetColor(color); } break; case 1: if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetColor(color); } break; case 2: if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetColor(color); } break; case 3: m_DecorationColorWidget4 = color; break; default: MITK_ERROR << "Decoration color for unknown widget!"; break; } } void QmitkStdMultiWidget::ResetCrosshair() { if (m_DataStorage.IsNotNull()) { m_RenderingManager->InitializeViewsByBoundingObjects(m_DataStorage); // m_RenderingManager->InitializeViews( m_DataStorage->ComputeVisibleBoundingGeometry3D() ); // reset interactor to normal slicing this->SetWidgetPlaneMode(PLANE_MODE_SLICING); } } void QmitkStdMultiWidget::EnableColoredRectangles() { m_RectangleProps[0]->SetVisibility(1); m_RectangleProps[1]->SetVisibility(1); m_RectangleProps[2]->SetVisibility(1); m_RectangleProps[3]->SetVisibility(1); } void QmitkStdMultiWidget::DisableColoredRectangles() { m_RectangleProps[0]->SetVisibility(0); m_RectangleProps[1]->SetVisibility(0); m_RectangleProps[2]->SetVisibility(0); m_RectangleProps[3]->SetVisibility(0); } bool QmitkStdMultiWidget::IsColoredRectanglesEnabled() const { return m_RectangleProps[0]->GetVisibility() > 0; } mitk::MouseModeSwitcher *QmitkStdMultiWidget::GetMouseModeSwitcher() { return m_MouseModeSwitcher; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane1() { return this->m_PlaneNode1; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane2() { return this->m_PlaneNode2; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane3() { return this->m_PlaneNode3; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane(int id) { switch (id) { case 1: return this->m_PlaneNode1; break; case 2: return this->m_PlaneNode2; break; case 3: return this->m_PlaneNode3; break; default: return nullptr; } } diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp index 5504695e80..c60adf59b3 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/QmitkStdMultiWidgetEditor.cpp @@ -1,557 +1,557 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkStdMultiWidgetEditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class QmitkStdMultiWidgetEditorPrivate { public: QmitkStdMultiWidgetEditorPrivate(); ~QmitkStdMultiWidgetEditorPrivate(); QmitkStdMultiWidget* m_StdMultiWidget; QmitkMouseModeSwitcher* m_MouseModeToolbar; /** * @brief Members for the MultiWidget decorations. */ QString m_WidgetBackgroundColor1[4]; QString m_WidgetBackgroundColor2[4]; QString m_WidgetDecorationColor[4]; QString m_WidgetAnnotation[4]; bool m_MenuWidgetsEnabled; QScopedPointer m_PartListener; QHash m_RenderWindows; - }; struct QmitkStdMultiWidgetPartListener : public berry::IPartListener { QmitkStdMultiWidgetPartListener(QmitkStdMultiWidgetEditorPrivate* dd) : d(dd) {} Events::Types GetPartEventTypes() const override { return Events::CLOSED | Events::HIDDEN | Events::VISIBLE | Events::OPENED; } void PartClosed(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->RemovePlanesFromDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(false); } } } void PartHidden(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { stdMultiWidgetEditor->RequestActivateMenuWidget(false); } } } void PartVisible(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { stdMultiWidgetEditor->RequestActivateMenuWidget(true); } } } void PartOpened(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() == QmitkStdMultiWidgetEditor::EDITOR_ID) { QmitkStdMultiWidgetEditor::Pointer stdMultiWidgetEditor = partRef->GetPart(false).Cast(); if (d->m_StdMultiWidget == stdMultiWidgetEditor->GetStdMultiWidget()) { d->m_StdMultiWidget->AddPlanesToDataStorage(); stdMultiWidgetEditor->RequestActivateMenuWidget(true); } } } private: QmitkStdMultiWidgetEditorPrivate* const d; }; QmitkStdMultiWidgetEditorPrivate::QmitkStdMultiWidgetEditorPrivate() : m_StdMultiWidget(nullptr), m_MouseModeToolbar(nullptr) , m_MenuWidgetsEnabled(false) , m_PartListener(new QmitkStdMultiWidgetPartListener(this)) {} QmitkStdMultiWidgetEditorPrivate::~QmitkStdMultiWidgetEditorPrivate() { } const QString QmitkStdMultiWidgetEditor::EDITOR_ID = "org.mitk.editors.stdmultiwidget"; QmitkStdMultiWidgetEditor::QmitkStdMultiWidgetEditor() : d(new QmitkStdMultiWidgetEditorPrivate) { } QmitkStdMultiWidgetEditor::~QmitkStdMultiWidgetEditor() { this->GetSite()->GetPage()->RemovePartListener(d->m_PartListener.data()); } QmitkStdMultiWidget* QmitkStdMultiWidgetEditor::GetStdMultiWidget() { return d->m_StdMultiWidget; } QmitkRenderWindow *QmitkStdMultiWidgetEditor::GetActiveQmitkRenderWindow() const { if (d->m_StdMultiWidget) return d->m_StdMultiWidget->GetRenderWindow1(); return nullptr; } QHash QmitkStdMultiWidgetEditor::GetQmitkRenderWindows() const { return d->m_RenderWindows; } QmitkRenderWindow *QmitkStdMultiWidgetEditor::GetQmitkRenderWindow(const QString &id) const { if (d->m_RenderWindows.contains(id)) return d->m_RenderWindows[id]; return nullptr; } mitk::Point3D QmitkStdMultiWidgetEditor::GetSelectedPosition(const QString & /*id*/) const { return d->m_StdMultiWidget->GetCrossPosition(); } void QmitkStdMultiWidgetEditor::SetSelectedPosition(const mitk::Point3D &pos, const QString &/*id*/) { d->m_StdMultiWidget->MoveCrossToPosition(pos); } void QmitkStdMultiWidgetEditor::EnableDecorations(bool enable, const QStringList &decorations) { if (decorations.isEmpty() || decorations.contains(DECORATION_BORDER)) { enable ? d->m_StdMultiWidget->EnableColoredRectangles() : d->m_StdMultiWidget->DisableColoredRectangles(); } if (decorations.isEmpty() || decorations.contains(DECORATION_LOGO)) { enable ? d->m_StdMultiWidget->EnableDepartmentLogo() : d->m_StdMultiWidget->DisableDepartmentLogo(); } if (decorations.isEmpty() || decorations.contains(DECORATION_MENU)) { d->m_StdMultiWidget->ActivateMenuWidget(enable); } if (decorations.isEmpty() || decorations.contains(DECORATION_BACKGROUND)) { enable ? d->m_StdMultiWidget->EnableGradientBackground() : d->m_StdMultiWidget->DisableGradientBackground(); } if (decorations.isEmpty() || decorations.contains(DECORATION_CORNER_ANNOTATION)) { enable ? d->m_StdMultiWidget->SetCornerAnnotationVisibility(true) : d->m_StdMultiWidget->SetCornerAnnotationVisibility(false); } } bool QmitkStdMultiWidgetEditor::IsDecorationEnabled(const QString &decoration) const { if (decoration == DECORATION_BORDER) { return d->m_StdMultiWidget->IsColoredRectanglesEnabled(); } else if (decoration == DECORATION_LOGO) { return d->m_StdMultiWidget->IsColoredRectanglesEnabled(); } else if (decoration == DECORATION_MENU) { return d->m_StdMultiWidget->IsMenuWidgetEnabled(); } else if (decoration == DECORATION_BACKGROUND) { return d->m_StdMultiWidget->GetGradientBackgroundFlag(); } else if (decoration == DECORATION_CORNER_ANNOTATION) { return d->m_StdMultiWidget->IsCornerAnnotationVisible(); } return false; } QStringList QmitkStdMultiWidgetEditor::GetDecorations() const { QStringList decorations; decorations << DECORATION_BORDER << DECORATION_LOGO << DECORATION_MENU << DECORATION_BACKGROUND << DECORATION_CORNER_ANNOTATION; return decorations; } void QmitkStdMultiWidgetEditor::EnableSlicingPlanes(bool enable) { d->m_StdMultiWidget->SetWidgetPlanesVisibility(enable); } bool QmitkStdMultiWidgetEditor::IsSlicingPlanesEnabled() const { mitk::DataNode::Pointer node = this->d->m_StdMultiWidget->GetWidgetPlane1(); if (node.IsNotNull()) { bool visible = false; node->GetVisibility(visible, nullptr); return visible; } else { return false; } } void QmitkStdMultiWidgetEditor::CreateQtPartControl(QWidget* parent) { if (d->m_StdMultiWidget == nullptr) { QHBoxLayout* layout = new QHBoxLayout(parent); layout->setContentsMargins(0,0,0,0); if (d->m_MouseModeToolbar == nullptr) { d->m_MouseModeToolbar = new QmitkMouseModeSwitcher(parent); // delete by Qt via parent layout->addWidget(d->m_MouseModeToolbar); } berry::IPreferences::Pointer prefs = this->GetPreferences(); - mitk::BaseRenderer::RenderingMode::Type renderingMode = static_cast(prefs->GetInt( "Rendering Mode" , 0 )); + auto renderingMode = static_cast( + prefs->GetInt("Rendering Mode", static_cast(mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing))); d->m_StdMultiWidget = new QmitkStdMultiWidget(parent,nullptr,nullptr,renderingMode); d->m_RenderWindows.insert("axial", d->m_StdMultiWidget->GetRenderWindow1()); d->m_RenderWindows.insert("sagittal", d->m_StdMultiWidget->GetRenderWindow2()); d->m_RenderWindows.insert("coronal", d->m_StdMultiWidget->GetRenderWindow3()); d->m_RenderWindows.insert("3d", d->m_StdMultiWidget->GetRenderWindow4()); d->m_MouseModeToolbar->setMouseModeSwitcher( d->m_StdMultiWidget->GetMouseModeSwitcher() ); layout->addWidget(d->m_StdMultiWidget); mitk::DataStorage::Pointer ds = this->GetDataStorage(); // Tell the multiWidget which (part of) the tree to render d->m_StdMultiWidget->SetDataStorage(ds); // Initialize views as axial, sagittal, coronar to all data objects in DataStorage // (from top-left to bottom) auto geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); // Initialize bottom-right view as 3D view d->m_StdMultiWidget->GetRenderWindow4()->GetRenderer()->SetMapperID( mitk::BaseRenderer::Standard3D ); // Enable standard handler for levelwindow-slider d->m_StdMultiWidget->EnableStandardLevelWindow(); // Add the displayed views to the tree to see their positions // in 2D and 3D d->m_StdMultiWidget->AddDisplayPlaneSubTree(); //d->m_StdMultiWidget->EnableNavigationControllerEventListening(); // Store the initial visibility status of the menu widget. d->m_MenuWidgetsEnabled = d->m_StdMultiWidget->IsMenuWidgetEnabled(); this->GetSite()->GetPage()->AddPartListener(d->m_PartListener.data()); berry::IBerryPreferences* berryprefs = dynamic_cast(prefs.GetPointer()); InitializePreferences(berryprefs); this->OnPreferencesChanged(berryprefs); this->RequestUpdate(); } } void QmitkStdMultiWidgetEditor::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { // Enable change of logo. If no DepartmentLogo was set explicitly, MBILogo is used. // Set new department logo by prefs->Set("DepartmentLogo", "PathToImage"); // If no logo was set for this plug-in specifically, walk the parent preference nodes // and lookup a logo value there. //We need to disable the logo first, otherwise setting a new logo will have no effect due to how mitkManufacturerLogo works d->m_StdMultiWidget->DisableDepartmentLogo(); d->m_StdMultiWidget->SetDepartmentLogo(qPrintable(":/org.mitk.gui.qt.stdmultiwidgeteditor/defaultWatermark.png")); d->m_StdMultiWidget->EnableDepartmentLogo(); const berry::IPreferences* currentNode = prefs; while(currentNode) { bool logoFound = false; foreach (const QString& key, currentNode->Keys()) { if( key == "DepartmentLogo") { QString departmentLogoLocation = currentNode->Get("DepartmentLogo", ""); if (departmentLogoLocation.isEmpty()) { d->m_StdMultiWidget->DisableDepartmentLogo(); } else { // we need to disable the logo first, otherwise setting a new logo will have // no effect due to how mitkManufacturerLogo works... d->m_StdMultiWidget->DisableDepartmentLogo(); d->m_StdMultiWidget->SetDepartmentLogo(qPrintable(departmentLogoLocation)); d->m_StdMultiWidget->EnableDepartmentLogo(); } logoFound = true; break; } } if (logoFound) break; currentNode = currentNode->Parent().GetPointer(); } //Update internal members this->FillMembersWithCurrentDecorations(); this->GetPreferenceDecorations(prefs); //Now the members can be used to modify the stdmultiwidget mitk::Color upper = HexColorToMitkColor(d->m_WidgetBackgroundColor1[0]); mitk::Color lower = HexColorToMitkColor(d->m_WidgetBackgroundColor2[0]); d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 0); upper = HexColorToMitkColor(d->m_WidgetBackgroundColor1[1]); lower = HexColorToMitkColor(d->m_WidgetBackgroundColor2[1]); d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 1); upper = HexColorToMitkColor(d->m_WidgetBackgroundColor1[2]); lower = HexColorToMitkColor(d->m_WidgetBackgroundColor2[2]); d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 2); upper = HexColorToMitkColor(d->m_WidgetBackgroundColor1[3]); lower = HexColorToMitkColor(d->m_WidgetBackgroundColor2[3]); d->m_StdMultiWidget->SetGradientBackgroundColorForRenderWindow(upper, lower, 3); d->m_StdMultiWidget->EnableGradientBackground(); // preferences for renderWindows mitk::Color colorDecorationWidget1 = HexColorToMitkColor(d->m_WidgetDecorationColor[0]); mitk::Color colorDecorationWidget2 = HexColorToMitkColor(d->m_WidgetDecorationColor[1]); mitk::Color colorDecorationWidget3 = HexColorToMitkColor(d->m_WidgetDecorationColor[2]); mitk::Color colorDecorationWidget4 = HexColorToMitkColor(d->m_WidgetDecorationColor[3]); d->m_StdMultiWidget->SetDecorationColor(0, colorDecorationWidget1); d->m_StdMultiWidget->SetDecorationColor(1, colorDecorationWidget2); d->m_StdMultiWidget->SetDecorationColor(2, colorDecorationWidget3); d->m_StdMultiWidget->SetDecorationColor(3, colorDecorationWidget4); for(unsigned int i = 0; i < 4; ++i) { d->m_StdMultiWidget->SetDecorationProperties(d->m_WidgetAnnotation[i].toStdString(), HexColorToMitkColor(d->m_WidgetDecorationColor[i]), i); } //The crosshair gap int crosshairgapsize = prefs->GetInt("crosshair gap size", 32); d->m_StdMultiWidget->GetWidgetPlane1()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize); d->m_StdMultiWidget->GetWidgetPlane2()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize); d->m_StdMultiWidget->GetWidgetPlane3()->SetIntProperty("Crosshair.Gap Size", crosshairgapsize); //refresh colors of rectangles d->m_StdMultiWidget->EnableColoredRectangles(); // Set preferences respecting zooming and panning bool constrainedZooming = prefs->GetBool("Use constrained zooming and panning", true); mitk::RenderingManager::GetInstance()->SetConstrainedPanningZooming(constrainedZooming); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // level window setting bool showLevelWindowWidget = prefs->GetBool("Show level/window widget", true); if (showLevelWindowWidget) { d->m_StdMultiWidget->EnableStandardLevelWindow(); } else { d->m_StdMultiWidget->DisableStandardLevelWindow(); } // mouse modes toolbar bool newMode = prefs->GetBool("PACS like mouse interaction", false); d->m_MouseModeToolbar->setVisible( newMode ); d->m_StdMultiWidget->GetMouseModeSwitcher()->SetInteractionScheme( newMode ? mitk::MouseModeSwitcher::PACS : mitk::MouseModeSwitcher::MITK ); } mitk::Color QmitkStdMultiWidgetEditor::HexColorToMitkColor(const QString& widgetColorInHex) { QColor qColor(widgetColorInHex); mitk::Color returnColor; float colorMax = 255.0f; if (widgetColorInHex.isEmpty()) // default value { returnColor[0] = 1.0; returnColor[1] = 1.0; returnColor[2] = 1.0; MITK_ERROR << "Using default color for unknown widget " << qPrintable(widgetColorInHex); } else { returnColor[0] = qColor.red() / colorMax; returnColor[1] = qColor.green() / colorMax; returnColor[2] = qColor.blue() / colorMax; } return returnColor; } QString QmitkStdMultiWidgetEditor::MitkColorToHex(const mitk::Color& color) { QColor returnColor; float colorMax = 255.0f; returnColor.setRed(static_cast(color[0]* colorMax + 0.5)); returnColor.setGreen(static_cast(color[1]* colorMax + 0.5)); returnColor.setBlue(static_cast(color[2]* colorMax + 0.5)); return returnColor.name(); } void QmitkStdMultiWidgetEditor::FillMembersWithCurrentDecorations() { //fill members with current values (or default values) from the std multi widget for(unsigned int i = 0; i < 4; ++i) { d->m_WidgetDecorationColor[i] = MitkColorToHex(d->m_StdMultiWidget->GetDecorationColor(i)); d->m_WidgetBackgroundColor1[i] = MitkColorToHex(d->m_StdMultiWidget->GetGradientColors(i).first); d->m_WidgetBackgroundColor2[i] = MitkColorToHex(d->m_StdMultiWidget->GetGradientColors(i).second); d->m_WidgetAnnotation[i] = QString::fromStdString(d->m_StdMultiWidget->GetCornerAnnotationText(i)); } } void QmitkStdMultiWidgetEditor::GetPreferenceDecorations(const berry::IBerryPreferences * preferences) { //overwrite members with values from the preferences, if they the prefrence is defined d->m_WidgetBackgroundColor1[0] = preferences->Get("widget1 first background color", d->m_WidgetBackgroundColor1[0]); d->m_WidgetBackgroundColor2[0] = preferences->Get("widget1 second background color", d->m_WidgetBackgroundColor2[0]); d->m_WidgetBackgroundColor1[1] = preferences->Get("widget2 first background color", d->m_WidgetBackgroundColor1[1]); d->m_WidgetBackgroundColor2[1] = preferences->Get("widget2 second background color", d->m_WidgetBackgroundColor2[1]); d->m_WidgetBackgroundColor1[2] = preferences->Get("widget3 first background color", d->m_WidgetBackgroundColor1[2]); d->m_WidgetBackgroundColor2[2] = preferences->Get("widget3 second background color", d->m_WidgetBackgroundColor2[2]); d->m_WidgetBackgroundColor1[3] = preferences->Get("widget4 first background color", d->m_WidgetBackgroundColor1[3]); d->m_WidgetBackgroundColor2[3] = preferences->Get("widget4 second background color", d->m_WidgetBackgroundColor2[3]); d->m_WidgetDecorationColor[0] = preferences->Get("widget1 decoration color", d->m_WidgetDecorationColor[0]); d->m_WidgetDecorationColor[1] = preferences->Get("widget2 decoration color", d->m_WidgetDecorationColor[1]); d->m_WidgetDecorationColor[2] = preferences->Get("widget3 decoration color", d->m_WidgetDecorationColor[2]); d->m_WidgetDecorationColor[3] = preferences->Get("widget4 decoration color", d->m_WidgetDecorationColor[3]); d->m_WidgetAnnotation[0] = preferences->Get("widget1 corner annotation", d->m_WidgetAnnotation[0]); d->m_WidgetAnnotation[1] = preferences->Get("widget2 corner annotation", d->m_WidgetAnnotation[1]); d->m_WidgetAnnotation[2] = preferences->Get("widget3 corner annotation", d->m_WidgetAnnotation[2]); d->m_WidgetAnnotation[3] = preferences->Get("widget4 corner annotation", d->m_WidgetAnnotation[3]); } void QmitkStdMultiWidgetEditor::InitializePreferences(berry::IBerryPreferences * preferences) { this->FillMembersWithCurrentDecorations(); //fill members this->GetPreferenceDecorations(preferences); //overwrite if preferences are defined //create new preferences preferences->Put("widget1 corner annotation", d->m_WidgetAnnotation[0]); preferences->Put("widget2 corner annotation", d->m_WidgetAnnotation[1]); preferences->Put("widget3 corner annotation", d->m_WidgetAnnotation[2]); preferences->Put("widget4 corner annotation", d->m_WidgetAnnotation[3]); preferences->Put("widget1 decoration color", d->m_WidgetDecorationColor[0]); preferences->Put("widget2 decoration color", d->m_WidgetDecorationColor[1]); preferences->Put("widget3 decoration color", d->m_WidgetDecorationColor[2]); preferences->Put("widget4 decoration color", d->m_WidgetDecorationColor[3]); preferences->Put("widget1 first background color", d->m_WidgetBackgroundColor1[0]); preferences->Put("widget2 first background color", d->m_WidgetBackgroundColor1[1]); preferences->Put("widget3 first background color", d->m_WidgetBackgroundColor1[2]); preferences->Put("widget4 first background color", d->m_WidgetBackgroundColor1[3]); preferences->Put("widget1 second background color", d->m_WidgetBackgroundColor2[0]); preferences->Put("widget2 second background color", d->m_WidgetBackgroundColor2[1]); preferences->Put("widget3 second background color", d->m_WidgetBackgroundColor2[2]); preferences->Put("widget4 second background color", d->m_WidgetBackgroundColor2[3]); } void QmitkStdMultiWidgetEditor::SetFocus() { if (d->m_StdMultiWidget != nullptr) d->m_StdMultiWidget->setFocus(); } void QmitkStdMultiWidgetEditor::RequestActivateMenuWidget(bool on) { if (d->m_StdMultiWidget) { if (on) { d->m_StdMultiWidget->ActivateMenuWidget(d->m_MenuWidgetsEnabled); } else { d->m_MenuWidgetsEnabled = d->m_StdMultiWidget->IsMenuWidgetEnabled(); d->m_StdMultiWidget->ActivateMenuWidget(false); } } } diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp index 17cc90ce91..d4da598c1f 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.cpp @@ -1,267 +1,294 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include #include "QmitkStdMultiWidgetEditorPreferencePage.h" +#include #include +#include + #include #include +#include +#include + #include + +namespace +{ + void ChangeRenderingMode(mitk::BaseRenderer::RenderingMode renderingMode) + { + auto renderingManager = mitk::RenderingManager::GetInstance(); + + if (nullptr == renderingManager) + return; + + auto renderWindows = renderingManager->GetAllRegisteredRenderWindows(); + + for (auto renderWindow : renderWindows) + { + auto renderers = renderWindow->GetRenderers(); + + if (nullptr != renderers) + { + renderers->InitTraversal(); + auto renderer = renderers->GetNextItem(); + + while (nullptr != renderer) + { + renderer->SetUseFXAA(mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing == renderingMode); + renderer = renderers->GetNextItem(); + } + + renderingManager->RequestUpdate(renderWindow); + } + } + } +} + QmitkStdMultiWidgetEditorPreferencePage::QmitkStdMultiWidgetEditorPreferencePage() : m_Preferences(nullptr), m_Ui(new Ui::QmitkStdMultiWidgetEditorPreferencePage), m_Control(nullptr) { } QmitkStdMultiWidgetEditorPreferencePage::~QmitkStdMultiWidgetEditorPreferencePage() { } void QmitkStdMultiWidgetEditorPreferencePage::CreateQtControl(QWidget* parent) { m_Control = new QWidget(parent); m_Ui->setupUi(m_Control); berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); Q_ASSERT(prefService); m_Preferences = prefService->GetSystemPreferences()->Node(QmitkStdMultiWidgetEditor::EDITOR_ID); QObject::connect( m_Ui->m_ColorButton1, SIGNAL( clicked() ) , this, SLOT( ColorChooserButtonClicked() ) ); QObject::connect( m_Ui->m_ColorButton2, SIGNAL( clicked() ) , this, SLOT( ColorChooserButtonClicked() ) ); QObject::connect( m_Ui->m_ResetButton, SIGNAL( clicked() ) , this, SLOT( ResetPreferencesAndGUI() ) ); - QObject::connect( m_Ui->m_RenderingMode, SIGNAL(activated(int) ) - , this, SLOT( ChangeRenderingMode(int) ) ); - QObject::connect( m_Ui->m_RenderWindowDecorationColor, SIGNAL( clicked() ) , this, SLOT( ColorChooserButtonClicked() ) ); QObject::connect( m_Ui->m_RenderWindowChooser, SIGNAL(activated(int) ) , this, SLOT( OnWidgetComboBoxChanged(int) ) ); QObject::connect( m_Ui->m_RenderWindowDecorationText, SIGNAL(textChanged(QString) ) , this, SLOT( AnnotationTextChanged(QString) ) ); this->Update(); } QWidget* QmitkStdMultiWidgetEditorPreferencePage::GetQtControl() const { return m_Control; } void QmitkStdMultiWidgetEditorPreferencePage::Init(berry::IWorkbench::Pointer) { } void QmitkStdMultiWidgetEditorPreferencePage::PerformCancel() { } bool QmitkStdMultiWidgetEditorPreferencePage::PerformOk() { m_Preferences->Put("widget1 corner annotation", m_WidgetAnnotation[0]); m_Preferences->Put("widget2 corner annotation", m_WidgetAnnotation[1]); m_Preferences->Put("widget3 corner annotation", m_WidgetAnnotation[2]); m_Preferences->Put("widget4 corner annotation", m_WidgetAnnotation[3]); m_Preferences->Put("widget1 decoration color", m_WidgetDecorationColor[0]); m_Preferences->Put("widget2 decoration color", m_WidgetDecorationColor[1]); m_Preferences->Put("widget3 decoration color", m_WidgetDecorationColor[2]); m_Preferences->Put("widget4 decoration color", m_WidgetDecorationColor[3]); m_Preferences->Put("widget1 first background color", m_WidgetBackgroundColor1[0]); m_Preferences->Put("widget2 first background color", m_WidgetBackgroundColor1[1]); m_Preferences->Put("widget3 first background color", m_WidgetBackgroundColor1[2]); m_Preferences->Put("widget4 first background color", m_WidgetBackgroundColor1[3]); m_Preferences->Put("widget1 second background color", m_WidgetBackgroundColor2[0]); m_Preferences->Put("widget2 second background color", m_WidgetBackgroundColor2[1]); m_Preferences->Put("widget3 second background color", m_WidgetBackgroundColor2[2]); m_Preferences->Put("widget4 second background color", m_WidgetBackgroundColor2[3]); m_Preferences->PutInt("crosshair gap size", m_Ui->m_CrosshairGapSize->value()); m_Preferences->PutBool("Use constrained zooming and panning" , m_Ui->m_EnableFlexibleZooming->isChecked()); m_Preferences->PutBool("Show level/window widget", m_Ui->m_ShowLevelWindowWidget->isChecked()); m_Preferences->PutBool("PACS like mouse interaction", m_Ui->m_PACSLikeMouseMode->isChecked()); - m_Preferences->PutInt("Rendering Mode", m_Ui->m_RenderingMode->currentIndex()); + + auto renderingMode = static_cast(m_Ui->m_RenderingMode->currentIndex()); + m_Preferences->PutInt("Rendering Mode", static_cast(renderingMode)); + ChangeRenderingMode(renderingMode); // Change the rendering mode now, no restart required return true; } void QmitkStdMultiWidgetEditorPreferencePage::Update() { //Note: there should be default preferences already defined in the //QmitkStdMultiWidgetEditor::InitializePreferences(). Therefore, //all default values here are not relevant. //gradient background colors m_WidgetBackgroundColor1[0] = m_Preferences->Get("widget1 first background color", "#1d1d1c"); m_WidgetBackgroundColor2[0] = m_Preferences->Get("widget1 second background color", "#1d1d1c"); m_WidgetBackgroundColor1[1] = m_Preferences->Get("widget2 first background color", "#1d1d1c"); m_WidgetBackgroundColor2[1] = m_Preferences->Get("widget2 second background color", "#1d1d1c"); m_WidgetBackgroundColor1[2] = m_Preferences->Get("widget3 first background color", "#1d1d1c"); m_WidgetBackgroundColor2[2] = m_Preferences->Get("widget3 second background color", "#1d1d1c"); m_WidgetBackgroundColor1[3] = m_Preferences->Get("widget4 first background color", "#1d1d1c"); m_WidgetBackgroundColor2[3] = m_Preferences->Get("widget4 second background color", "#adb1b6"); //decoration colors m_WidgetDecorationColor[0] = m_Preferences->Get("widget1 decoration color", "#c00000"); m_WidgetDecorationColor[1] = m_Preferences->Get("widget2 decoration color", "#0fad00"); m_WidgetDecorationColor[2] = m_Preferences->Get("widget3 decoration color", "#0080ff"); m_WidgetDecorationColor[3] = m_Preferences->Get("widget4 decoration color", "#fec500"); //annotation text m_WidgetAnnotation[0] = m_Preferences->Get("widget1 corner annotation", "Axial"); m_WidgetAnnotation[1] = m_Preferences->Get("widget2 corner annotation", "Sagittal"); m_WidgetAnnotation[2] = m_Preferences->Get("widget3 corner annotation", "Coronal"); m_WidgetAnnotation[3] = m_Preferences->Get("widget4 corner annotation", "3D"); //Ui stuff int index = m_Ui->m_RenderWindowChooser->currentIndex(); QColor firstBackgroundColor(m_WidgetBackgroundColor1[index]); QColor secondBackgroundColor(m_WidgetBackgroundColor2[index]); QColor widgetColor(m_WidgetDecorationColor[index]); this->SetStyleSheetToColorChooserButton(firstBackgroundColor, m_Ui->m_ColorButton1); this->SetStyleSheetToColorChooserButton(secondBackgroundColor, m_Ui->m_ColorButton2); this->SetStyleSheetToColorChooserButton(widgetColor, m_Ui->m_RenderWindowDecorationColor); m_Ui->m_RenderWindowDecorationText->setText(m_WidgetAnnotation[index]); m_Ui->m_EnableFlexibleZooming->setChecked(m_Preferences->GetBool("Use constrained zooming and panning", true)); m_Ui->m_ShowLevelWindowWidget->setChecked(m_Preferences->GetBool("Show level/window widget", true)); m_Ui->m_PACSLikeMouseMode->setChecked(m_Preferences->GetBool("PACS like mouse interaction", false)); - int mode = m_Preferences->GetInt("Rendering Mode", 1); - m_Ui->m_RenderingMode->setCurrentIndex(mode); m_Ui->m_CrosshairGapSize->setValue(m_Preferences->GetInt("crosshair gap size", 32)); + + auto renderingMode = m_Preferences->GetInt("Rendering Mode", static_cast(mitk::BaseRenderer::RenderingMode::FastApproximateAntiAliasing)); + m_Ui->m_RenderingMode->setCurrentIndex(renderingMode); } void QmitkStdMultiWidgetEditorPreferencePage::ColorChooserButtonClicked() { unsigned int widgetIndex = m_Ui->m_RenderWindowChooser->currentIndex(); if(widgetIndex > 3) { MITK_ERROR << "Selected index for unknown."; return; } QObject *senderObj = sender(); // This will give Sender button //find out last used color and set it QColor initialColor; if( senderObj->objectName() == m_Ui->m_ColorButton1->objectName()) { initialColor = QColor(m_WidgetBackgroundColor1[widgetIndex]); }else if( senderObj->objectName() == m_Ui->m_ColorButton2->objectName()) { initialColor = QColor(m_WidgetBackgroundColor2[widgetIndex]); }else if( senderObj->objectName() == m_Ui->m_RenderWindowDecorationColor->objectName()) { initialColor = QColor(m_WidgetDecorationColor[widgetIndex]); } //get the new color QColor newcolor = QColorDialog::getColor(initialColor); if(!newcolor.isValid()) { newcolor = initialColor; } this->SetStyleSheetToColorChooserButton(newcolor, static_cast(senderObj)); //convert it to std string and apply it if( senderObj->objectName() == m_Ui->m_ColorButton1->objectName()) { m_WidgetBackgroundColor1[widgetIndex] = newcolor.name(); } else if( senderObj->objectName() == m_Ui->m_ColorButton2->objectName()) { m_WidgetBackgroundColor2[widgetIndex] = newcolor.name(); } else if( senderObj->objectName() == m_Ui->m_RenderWindowDecorationColor->objectName()) { m_WidgetDecorationColor[widgetIndex] = newcolor.name(); } } void QmitkStdMultiWidgetEditorPreferencePage::SetStyleSheetToColorChooserButton(QColor backgroundcolor, QPushButton* button) { button->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(backgroundcolor.red())); styleSheet.append(","); styleSheet.append(QString::number(backgroundcolor.green())); styleSheet.append(","); styleSheet.append(QString::number(backgroundcolor.blue())); styleSheet.append(")"); button->setStyleSheet(styleSheet); } void QmitkStdMultiWidgetEditorPreferencePage::AnnotationTextChanged(QString text) { unsigned int widgetIndex = m_Ui->m_RenderWindowChooser->currentIndex(); if( widgetIndex > 3) { MITK_INFO << "Selected index for unknown widget."; return; } m_WidgetAnnotation[widgetIndex] = text; } void QmitkStdMultiWidgetEditorPreferencePage::ResetPreferencesAndGUI() { m_Preferences->Clear(); this->Update(); } void QmitkStdMultiWidgetEditorPreferencePage::OnWidgetComboBoxChanged(int i) { if( i > 3) { MITK_ERROR << "Selected unknown widget."; return; } QColor widgetColor(m_WidgetDecorationColor[i]); QColor gradientBackground1(m_WidgetBackgroundColor1[i]); QColor gradientBackground2(m_WidgetBackgroundColor2[i]); this->SetStyleSheetToColorChooserButton(widgetColor, m_Ui->m_RenderWindowDecorationColor); this->SetStyleSheetToColorChooserButton(gradientBackground1, m_Ui->m_ColorButton1); this->SetStyleSheetToColorChooserButton(gradientBackground2, m_Ui->m_ColorButton2); m_Ui->m_RenderWindowDecorationText->setText(m_WidgetAnnotation[i]); } - -void QmitkStdMultiWidgetEditorPreferencePage::ChangeRenderingMode(int i) -{ - if (0 == i) - { - m_CurrentRenderingMode = "No Anti-aliasing"; - } - else if (1 == i) - { - m_CurrentRenderingMode = "Fast Approximate Anti-Aliasing (FXAA)"; - } -} diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h index a74071032b..6253c9ea67 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.h @@ -1,120 +1,109 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkStdMultiWidgetEditorPreferencePage_h #define QmitkStdMultiWidgetEditorPreferencePage_h #include #include #include #include #include namespace Ui { class QmitkStdMultiWidgetEditorPreferencePage; } class QmitkStdMultiWidgetEditorPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkStdMultiWidgetEditorPreferencePage(); ~QmitkStdMultiWidgetEditorPreferencePage() override; void CreateQtControl(QWidget* parent) override; QWidget* GetQtControl() const override; void Init(berry::IWorkbench::Pointer) override; void PerformCancel() override; bool PerformOk() override; void Update() override; public slots: /** * @brief ResetColors set default colors and refresh the GUI. */ void ResetPreferencesAndGUI(); - /** - * @brief ChangeRenderingMode slot to chose the rendering mode via QComboBox. - * @param i index of the box. - */ - void ChangeRenderingMode(int i); - /** * @brief OnWidgetComboBoxChanged slot called when the QComboBox to chose the widget was modified. * @param i index of the combobox to select the widget (1-4). */ void OnWidgetComboBoxChanged(int i); /** * @brief AnnotationTextChanged called when QLineEdit for the annotation was changed. * @param text The new text. */ void AnnotationTextChanged(QString text); protected: - /** - * @brief m_CurrentRenderingMode String for the rendering mode. - */ - std::string m_CurrentRenderingMode; - /** * @brief m_WidgetBackgroundColor1 the background colors. * * If two different colors are chosen, a gradient background appears. */ QString m_WidgetBackgroundColor1[4]; QString m_WidgetBackgroundColor2[4]; /** * @brief m_WidgetDecorationColor the decoration color. * * The rectangle prop, the crosshair, the 3D planes and the corner annotation use this. */ QString m_WidgetDecorationColor[4]; /** * @brief m_Widget1Annotation the text of the corner annotation. */ QString m_WidgetAnnotation[4]; /** * @brief m_Preferences the berry preferences. */ berry::IPreferences::Pointer m_Preferences; /** * @brief SetStyleSheetToColorChooserButton colorize a button. * @param backgroundcolor color for the button. * @param button the button. */ void SetStyleSheetToColorChooserButton(QColor backgroundcolor, QPushButton* button); protected slots: /** * @brief ColorChooserButtonClicked slot called when a button to choose color was clicked. */ void ColorChooserButtonClicked(); private: QScopedPointer m_Ui; QWidget* m_Control; }; #endif //QmitkStdMultiWidgetEditorPreferencePage_h diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui index e0a9d50f14..8f9ed01e88 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/QmitkStdMultiWidgetEditorPreferencePage.ui @@ -1,217 +1,223 @@ QmitkStdMultiWidgetEditorPreferencePage 0 0 518 - 431 + 730 External Programs - - - - - stdmulti.widget1 - - - - - stdmulti.widget2 - - - - - stdmulti.widget3 - - - - - stdmulti.widget4 - - + + + + The small text on the button left of each renderwindow. + + + Corner annotation + - + <html><head/><body><p>If two colors are set, a gradient background is generated.</p></body></html> Background color - - + + - Reset preferences + - - + + - No anti-aliasing + stdmulti.widget1 - Fast Approximate Anti-Aliasing (FXAA) + stdmulti.widget2 + + + + + stdmulti.widget3 + + + + + stdmulti.widget4 - - + + + + <html><head/><body><p>The color is used for the following decorations (of each renderwindow):</p><p>Rectangle border</p><p>Corner annotation</p><p>Crosshair</p><p>Plane geometry helper objects (3D Planes)</p><p>Image navigator borders</p><p><br/></p></body></html> + - * Changes require restart of MITK. + Decoration color - + 32 - - + + Qt::Horizontal - - - - The small text on the button left of each renderwindow. - - - Corner annotation + + + + Qt::Horizontal - - - - <html><head/><body><p>The gap in the middle of the crosshair in pixels.</p></body></html> + + + + Qt::LeftToRight - Crosshair gap size - - - - - - - <html><head/><body><p>The color is used for the following decorations (of each renderwindow):</p><p>Rectangle border</p><p>Corner annotation</p><p>Crosshair</p><p>Plane geometry helper objects (3D Planes)</p><p>Image navigator borders</p><p><br/></p></body></html> + Use PACS like mouse interaction (select left mouse button action) - - Decoration color + + false - - + + - + Reset preferences - - + + - <html><head/><body><p>Choose the renderwindow from the multi widget.</p></body></html> - - - Render windows + <html><head/><body><p>If activated, zooming and panning is limited to a certain space arround each image.</p></body></html> - - - - Qt::LeftToRight - Show level/window widget + Use constraint zooming and panning true - - - - Qt::LeftToRight + + + + <html><head/><body><p>Choose the renderwindow from the multi widget.</p></body></html> - Use PACS like mouse interaction (select left mouse button action) - - - false + Render windows - - + + - - - - Qt::Horizontal - + + + + + + + + No anti-aliasing + + + + + Fast Approximate Anti-Aliasing (FXAA) + + - - + + + + <html><head/><body><p>The gap in the middle of the crosshair in pixels.</p></body></html> + - Rendering Mode* + Crosshair gap size - - - - + - - - - <html><head/><body><p>If activated, zooming and panning is limited to a certain space arround each image.</p></body></html> + + + + Rendering mode + + + + Qt::LeftToRight - Use constraint zooming and panning + Show level/window widget true + + + + Qt::Vertical + + + + 20 + 40 + + + +