diff --git a/CMakeExternals/VTK.cmake b/CMakeExternals/VTK.cmake index 1e27a03e16..abcb30c254 100644 --- a/CMakeExternals/VTK.cmake +++ b/CMakeExternals/VTK.cmake @@ -1,117 +1,118 @@ #----------------------------------------------------------------------------- # VTK #----------------------------------------------------------------------------- if(WIN32) option(VTK_USE_SYSTEM_FREETYPE OFF) else(WIN32) option(VTK_USE_SYSTEM_FREETYPE ON) endif(WIN32) # Sanity checks if(DEFINED VTK_DIR AND NOT EXISTS ${VTK_DIR}) message(FATAL_ERROR "VTK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj VTK) set(proj_DEPENDENCIES ) set(VTK_DEPENDS ${proj}) if(MITK_USE_HDF5) list(APPEND proj_DEPENDENCIES HDF5) endif() if(NOT DEFINED VTK_DIR) set(additional_cmake_args ) if(MINGW) set(additional_cmake_args -DCMAKE_USE_WIN32_THREADS:BOOL=ON -DCMAKE_USE_PTHREADS:BOOL=OFF -DVTK_USE_VIDEO4WINDOWS:BOOL=OFF # no header files provided by MinGW ) endif() # Optionally enable memory leak checks for any objects derived from vtkObject. This # will force unit tests to fail if they have any of these memory leaks. option(MITK_VTK_DEBUG_LEAKS OFF) mark_as_advanced(MITK_VTK_DEBUG_LEAKS) list(APPEND additional_cmake_args -DVTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS} ) if(MITK_USE_Python) if(NOT MITK_USE_SYSTEM_PYTHON) list(APPEND proj_DEPENDENCIES Python) set(_vtk_install_python_dir -DVTK_INSTALL_PYTHON_MODULE_DIR:FILEPATH=${MITK_PYTHON_SITE_DIR}) else() set(_vtk_install_python_dir -DVTK_INSTALL_PYTHON_MODULE_DIR:PATH=${ep_prefix}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) endif() list(APPEND additional_cmake_args -DVTK_WRAP_PYTHON:BOOL=ON -DVTK_USE_TK:BOOL=OFF -DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} ${_vtk_install_python_dir} ) else() list(APPEND additional_cmake_args -DVTK_WRAP_PYTHON:BOOL=OFF -DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF ) endif() if(MITK_USE_Qt5) list(APPEND additional_cmake_args -DVTK_QT_VERSION:STRING=5 -DVTK_Group_Qt:BOOL=ON -DVTK_INSTALL_NO_QT_PLUGIN:BOOL=ON ) endif() if(CTEST_USE_LAUNCHERS) list(APPEND additional_cmake_args "-DCMAKE_PROJECT_${proj}_INCLUDE:FILEPATH=${CMAKE_ROOT}/Modules/CTestUseLaunchers.cmake" ) endif() - set(VTK_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/VTK-7.0.0.tar.gz) - set(VTK_URL_MD5 5fe35312db5fb2341139b8e4955c367d) + #set(VTK_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/VTK-7.0.0.tar.gz) + set(VTK_URL http://www.vtk.org/files/release/7.1/VTK-7.1.0.tar.gz) + set(VTK_URL_MD5 a7e814c1db503d896af72458c2d0228f) ExternalProject_Add(${proj} LIST_SEPARATOR ${sep} URL ${VTK_URL} URL_MD5 ${VTK_URL_MD5} PATCH_COMMAND ${PATCH_COMMAND} -N -p1 -i ${CMAKE_CURRENT_LIST_DIR}/VTK.patch CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} -DVTK_WRAP_TCL:BOOL=OFF -DVTK_WRAP_PYTHON:BOOL=OFF -DVTK_WRAP_JAVA:BOOL=OFF -DVTK_USE_SYSTEM_FREETYPE:BOOL=${VTK_USE_SYSTEM_FREETYPE} -DVTK_LEGACY_REMOVE:BOOL=ON -DModule_vtkTestingRendering:BOOL=ON -DVTK_MAKE_INSTANTIATORS:BOOL=ON -DVTK_USE_CXX11_FEATURES:BOOL=ON - -DVTK_RENDERING_BACKEND:STRING=OpenGL + -DVTK_RENDERING_BACKEND:STRING=OpenGL2 ${additional_cmake_args} CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) set(VTK_DIR ${ep_prefix}) mitkFunctionInstallExternalCMakeProject(${proj}) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() diff --git a/CMakeExternals/VTK.patch b/CMakeExternals/VTK.patch index 26692c93c5..e69de29bb2 100644 --- a/CMakeExternals/VTK.patch +++ b/CMakeExternals/VTK.patch @@ -1,60 +0,0 @@ -diff --git a/CMake/GenerateExportHeader.cmake b/CMake/GenerateExportHeader.cmake -index ecfae31..11e7fad 100644 ---- a/CMake/GenerateExportHeader.cmake -+++ b/CMake/GenerateExportHeader.cmake -@@ -163,10 +163,10 @@ endmacro() - macro(_test_compiler_hidden_visibility) - - if(CMAKE_COMPILER_IS_GNUCXX) -- execute_process(COMMAND ${CMAKE_C_COMPILER} ARGS --version -+ execute_process(COMMAND ${CMAKE_C_COMPILER} --version - OUTPUT_VARIABLE _gcc_version_info - ERROR_VARIABLE _gcc_version_info) -- string(REGEX MATCH "[345]\\.[0-9]\\.[0-9]*" -+ string(REGEX MATCH "[3456]\\.[0-9]\\.[0-9]*" - _gcc_version "${_gcc_version_info}") - # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the - # patch level, handle this here: -@@ -175,13 +175,13 @@ macro(_test_compiler_hidden_visibility) - _gcc_version "${_gcc_version_info}") - endif() - -- if(${_gcc_version} VERSION_LESS "4.2") -+ if(_gcc_version VERSION_LESS "4.2") - set(GCC_TOO_OLD TRUE) - endif() - endif() - - if(CMAKE_CXX_COMPILER_ID MATCHES "Intel") -- execute_process(COMMAND ${CMAKE_CXX_COMPILER} ARGS -V -+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -V - OUTPUT_VARIABLE _intel_version_info - ERROR_VARIABLE _intel_version_info) - string(REGEX REPLACE ".*Version ([0-9]+(\\.[0-9]+)+).*" "\\1" -diff --git a/CMake/vtkCompilerExtras.cmake b/CMake/vtkCompilerExtras.cmake -index e39bd30..68c5980 100644 ---- a/CMake/vtkCompilerExtras.cmake -+++ b/CMake/vtkCompilerExtras.cmake -@@ -28,11 +28,11 @@ if(CMAKE_COMPILER_IS_GNUCXX) - endif() - - # Now check if we can use visibility to selectively export symbols -- execute_process(COMMAND ${CMAKE_C_COMPILER} ARGS --version -+ execute_process(COMMAND ${CMAKE_C_COMPILER} --version - OUTPUT_VARIABLE _gcc_version_info - ERROR_VARIABLE _gcc_version_info) - -- string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]*" -+ string (REGEX MATCH "[3456]\\.[0-9]\\.[0-9]*" - _gcc_version "${_gcc_version_info}") - if(NOT _gcc_version) - string (REGEX REPLACE ".*\\(GCC\\).*([34]\\.[0-9]).*" "\\1.0" -@@ -44,7 +44,7 @@ if(CMAKE_COMPILER_IS_GNUCXX) - option(VTK_USE_GCC_VISIBILITY "Use GCC visibility support if available." OFF) - mark_as_advanced(VTK_USE_GCC_VISIBILITY) - -- if(${_gcc_version} VERSION_GREATER 4.2.0 AND BUILD_SHARED_LIBS -+ if(_gcc_version VERSION_GREATER 4.2.0 AND BUILD_SHARED_LIBS - AND HAVE_GCC_VISIBILITY AND VTK_USE_GCC_VISIBILITY - AND NOT MINGW AND NOT CYGWIN) - # Should only be set if GCC is newer than 4.2.0 diff --git a/Modules/Core/CMakeLists.txt b/Modules/Core/CMakeLists.txt index d0f8703b8e..7d68e30844 100644 --- a/Modules/Core/CMakeLists.txt +++ b/Modules/Core/CMakeLists.txt @@ -1,78 +1,78 @@ set(TOOL_CPPS "") # temporary suppress warnings in the following files until image accessors are fully integrated. set_source_files_properties( src/DataManagement/mitkImage.cpp COMPILE_FLAGS -DMITK_NO_DEPRECATED_WARNINGS ) set_source_files_properties( src/Controllers/mitkSliceNavigationController.cpp COMPILE_FLAGS -DMITK_NO_DEPRECATED_WARNINGS ) MITK_CREATE_MODULE( INCLUDE_DIRS PUBLIC ${MITK_BINARY_DIR} PRIVATE src/Algorithms src/Controllers src/DataManagement src/Interactions src/IO src/Rendering ${OPENGL_INCLUDE_DIR} DEPENDS PUBLIC mbilog CppMicroServices PACKAGE_DEPENDS PRIVATE tinyxml OpenGL # Remove public GDCM and ITKIOGDCM+... dependencies after mitkDicomSeriesReader was removed PUBLIC GDCM PUBLIC ITK|ITKTransform+ITKImageGrid+ITKImageFeature+ITKIOImageBase+ITKIOGDCM+ITKIOHDF5+ITKIOLSM+ITKIOMRC+ITKIOBioRad+ITKIOGE+ITKIOStimulate # We privately use/link all ITK modules in order to support all IO, Transform, etc. # factories from ITK which are registered "automatically" via a factory manager. PRIVATE ITK - PUBLIC VTK|vtkFiltersTexture+vtkFiltersParallel+vtkImagingStencil+vtkImagingMath+vtkInteractionStyle+vtkRenderingOpenGL+vtkRenderingVolumeOpenGL+vtkRenderingFreeType+vtkRenderingLabel+vtkInteractionWidgets+vtkIOGeometry+vtkIOXML + PUBLIC VTK|vtkFiltersTexture+vtkFiltersParallel+vtkImagingStencil+vtkImagingMath+vtkInteractionStyle+vtkRenderingOpenGL2+vtkRenderingVolumeOpenGL2+vtkRenderingFreeType+vtkRenderingLabel+vtkInteractionWidgets+vtkIOGeometry+vtkIOXML PUBLIC Boost WARNINGS_AS_ERRORS SUBPROJECTS MITK-Core # Do not automatically create CppMicroServices initialization code. # Because the VTK 6 "auto-init" functionality injects file-local static # initialization code in every cpp file which includes a VTK header, # static initialization order becomes an issue again. For the Mitk # core library, we need to ensure that the VTK static initialization stuff # happens before the CppMicroServices initialization, since the latter # might already use VTK code which needs to access VTK object factories. # Hence, CppMicroServices initialization code is placed manually within # the mitkCoreActivator.cpp file. NO_INIT ) if(NOT TARGET ${MODULE_TARGET}) message(SEND_ERROR "Core target ${MODULE_TARGET} does not exist") endif() function(_itk_create_factory_register_manager) # In MITK_ITK_Config.cmake, we do *not* include ITK_USE_FILE, which # prevents multiple registrations/unregistrations of ITK IO factories # during library loading/unloading (of MITK libraries). However, we need # "one" place where the IO factories are registered at # least once. This could be the application executable, but every executable would # need to take care of that itself. Instead, we allow the auto registration in the # Mitk Core library. set(NO_DIRECTORY_SCOPED_ITK_COMPILE_DEFINITION 1) find_package(ITK) include(${ITK_USE_FILE}) if(NOT ITK_NO_IO_FACTORY_REGISTER_MANAGER) # We manually add the define which will be of target scope. MITK # patches ITK_USE_FILE to remove the directory scoped compile # definition since it would be propagated to other targets in the # same directory scope but these targets might want to *not* # use the ITK factory manager stuff. target_compile_definitions(${MODULE_TARGET} PRIVATE ITK_IO_FACTORY_REGISTER_MANAGER) endif() endfunction() _itk_create_factory_register_manager() # this is needed for libraries which link to Mitk and need # symbols from explicitly instantiated templates if(MINGW) get_target_property(_mitkCore_MINGW_linkflags ${MODULE_TARGET} LINK_FLAGS) if(NOT _mitkCore_MINGW_linkflags) set(_mitkCore_MINGW_linkflags "") endif(NOT _mitkCore_MINGW_linkflags) set_target_properties(${MODULE_TARGET} PROPERTIES LINK_FLAGS "${_mitkCore_MINGW_linkflags} -Wl,--export-all-symbols") endif(MINGW) if(MSVC_IDE OR MSVC_VERSION OR MINGW) target_link_libraries(${MODULE_TARGET} PRIVATE psapi.lib) endif(MSVC_IDE OR MSVC_VERSION OR MINGW) add_subdirectory(TestingHelper) add_subdirectory(test) diff --git a/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp b/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp index e06da30756..4c2f602277 100644 --- a/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp +++ b/Modules/Core/TestingHelper/src/mitkRenderingTestHelper.cpp @@ -1,308 +1,307 @@ /*=================================================================== 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 gl to read out properties #include -#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) : m_AutomaticallyCloseRenderWindow(true) { this->Initialize(width, height, renderingMode); } mitk::RenderingTestHelper::RenderingTestHelper( int width, int height, int argc, char *argv[], mitk::BaseRenderer::RenderingMode::Type 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) { mitk::UIDGenerator uidGen = mitk::UIDGenerator("UnnamedRenderer_", 8); m_RenderWindow = mitk::RenderWindow::New(NULL, uidGen.GetUID().c_str(), NULL, renderingMode); m_DataStorage = mitk::StandaloneDataStorage::New(); m_RenderWindow->GetRenderer()->SetDataStorage(m_DataStorage); this->SetMapperIDToRender2D(); this->GetVtkRenderWindow()->SetSize(width, height); #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/mitkIShaderRepository.h b/Modules/Core/include/mitkIShaderRepository.h index 749e4adb91..e79cc0797b 100644 --- a/Modules/Core/include/mitkIShaderRepository.h +++ b/Modules/Core/include/mitkIShaderRepository.h @@ -1,136 +1,138 @@ /*=================================================================== 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 MITKISHADERREPOSITORY_H #define MITKISHADERREPOSITORY_H #include #include "mitkCommon.h" #include "mitkServiceInterface.h" #include class vtkActor; -class vtkShaderProgram2; +class vtkShaderProgram; namespace mitk { class DataNode; class BaseRenderer; /** * \ingroup MicroServices_Interfaces * \brief Management class for vtkShader XML descriptions. * * Loads XML shader files from std::istream objects and adds default properties * for each shader object (shader uniforms) to the specified mitk::DataNode. * * Additionally, it provides a utility function for applying properties for shaders * in mappers. */ struct MITKCORE_EXPORT IShaderRepository + { struct ShaderPrivate; class MITKCORE_EXPORT Shader : public itk::LightObject + { public: mitkClassMacroItkParent(Shader, itk::LightObject) itkFactorylessNewMacro(Self) ~Shader(); int GetId() const; std::string GetName() const; std::string GetMaterialXml() const; protected: Shader(); void SetId(int id); void SetName(const std::string &name); void SetMaterialXml(const std::string &xml); private: // not implemented Shader(const Shader &); Shader &operator=(const Shader &); ShaderPrivate *d; }; class MITKCORE_EXPORT ShaderProgram : public itk::LightObject { public: virtual void Activate() = 0; virtual void Deactivate() = 0; mitkClassMacroItkParent(ShaderProgram, itk::LightObject) }; virtual ~IShaderRepository(); virtual std::list GetShaders() const = 0; /** * \brief Return the named shader. * * \param name The shader name. * \return A Shader object. * * Names might not be unique. Use the shader id to uniquely identify a shader. */ virtual Shader::Pointer GetShader(const std::string &name) const = 0; virtual ShaderProgram::Pointer CreateShaderProgram() = 0; /** * \brief Return the shader identified by the given id. * @param id The shader id. * @return The shader object or null if the id is unknown. */ virtual Shader::Pointer GetShader(int id) const = 0; /** \brief Adds all parsed shader uniforms to property list of the given DataNode; * used by mappers. */ virtual void AddDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite) const = 0; /** \brief Applies shader and shader specific variables of the specified DataNode * to the VTK object by updating the shader variables of its vtkProperty. */ virtual void UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram *shaderProgram, mitk::DataNode *node, mitk::BaseRenderer *renderer) const = 0; /** \brief Loads a shader from a given file. Make sure that this stream is in the XML shader format. * * \return A unique id for the loaded shader which can be used to unload it. */ virtual int LoadShader(std::istream &stream, const std::string &name) = 0; /** * \brief Unload a previously loaded shader. * \param id The unique shader id returned by LoadShader. * \return \c true if the shader id was found and the shader was successfully unloaded, * \c false otherwise. */ virtual bool UnloadShader(int id) = 0; }; } MITK_DECLARE_SERVICE_INTERFACE(mitk::IShaderRepository, "org.mitk.services.IShaderRepository/1.0") #endif // MITKISHADERREPOSITORY_H diff --git a/Modules/Core/include/mitkSurfaceVtkMapper3D.h b/Modules/Core/include/mitkSurfaceVtkMapper3D.h index 8d9e4438e7..4a5881c27b 100644 --- a/Modules/Core/include/mitkSurfaceVtkMapper3D.h +++ b/Modules/Core/include/mitkSurfaceVtkMapper3D.h @@ -1,148 +1,147 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkSurfaceVtkMapper3D_h #define mitkSurfaceVtkMapper3D_h #include "mitkBaseRenderer.h" #include "mitkLocalStorageHandler.h" #include "mitkVtkMapper.h" #include #include #include #include -#include #include #include #include #include namespace mitk { /** * @brief Vtk-based mapper for Surfaces. * * The mapper renders a surface in 3D. The actor is adapted according to the geometry in * the base class in mitk::VtkMapper::UpdateVtkTransform(). * * Properties that can be set for surfaces and influence the surfaceVTKMapper3D are: * * - \b "Backface Culling": True enables backface culling, which means only front-facing polygons will be visualized. False/disabled by default. * - \b "color": (ColorProperty) Diffuse color of the surface object (this property will be read when material.diffuseColor is not defined) * - \b "Opacity": (FloatProperty) Opacity of the surface object * - \b "material.ambientColor": (ColorProperty) Ambient color of the surface object * - \b "material.ambientCoefficient": ( FloatProperty) Ambient coefficient of the surface object * - \b "material.diffuseColor": ( ColorProperty) Diffuse color of the surface object * - \b "material.diffuseCoefficient": (FloatProperty) Diffuse coefficient of the surface object * - \b "material.specularColor": (ColorProperty) Specular Color of the surface object * - \b "material.specularCoefficient": (FloatProperty) Specular coefficient of the surface object * - \b "material.specularPower": (FloatProperty) Specular power of the surface object * - \b "material.interpolation": (VtkInterpolationProperty) Interpolation * - \b "material.representation": (VtkRepresentationProperty*) Representation * - \b "material.wireframeLineWidth": (FloatProperty) Width in pixels of the lines drawn. * - \b "material.pointSize": (FloatProperty) Size in pixels of the points drawn. * - \b "scalar visibility": (BoolProperty) If the scarlars of the surface are visible * - \b "Surface.TransferFunction (TransferFunctionProperty) Set a transferfunction for coloring the surface * - \b "LookupTable (LookupTableProperty) LookupTable * Properties to look for are: * * - \b "scalar visibility": if set to on, scalars assigned to the data are shown * Turn this on if using a lookup table. * - \b "ScalarsRangeMinimum": Optional. Can be used to store the scalar min, e.g. * for the level window settings. * - \b "ScalarsRangeMaximum": Optional. See above. * * There might be still some other, deprecated properties. These will not be documented anymore. * Please check the source if you really need them. * * @ingroup Mapper */ class MITKCORE_EXPORT SurfaceVtkMapper3D : public VtkMapper { public: mitkClassMacro(SurfaceVtkMapper3D, VtkMapper); itkFactorylessNewMacro(Self) itkCloneMacro(Self) itkSetMacro(GenerateNormals, bool); itkGetMacro(GenerateNormals, bool); virtual const mitk::Surface *GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override; virtual void ApplyAllProperties(mitk::BaseRenderer *renderer, vtkActor *actor); static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = NULL, bool overwrite = false); protected: SurfaceVtkMapper3D(); virtual ~SurfaceVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; virtual void ResetMapper(mitk::BaseRenderer *renderer) override; /** Checks whether the specified property is a ClippingProperty and if yes, * adds it to m_ClippingPlaneCollection (internal method). */ virtual void CheckForClippingProperty(mitk::BaseRenderer *renderer, mitk::BaseProperty *property); bool m_GenerateNormals; public: class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: vtkSmartPointer m_Actor; - vtkSmartPointer m_VtkPolyDataMapper; + vtkSmartPointer m_VtkPolyDataMapper; vtkSmartPointer m_VtkPolyDataNormals; vtkSmartPointer m_ClippingPlaneCollection; vtkSmartPointer m_DepthSort; itk::TimeStamp m_ShaderTimestampUpdate; LocalStorage() { - m_VtkPolyDataMapper = vtkSmartPointer::New(); + m_VtkPolyDataMapper = vtkSmartPointer::New(); m_VtkPolyDataNormals = vtkSmartPointer::New(); m_Actor = vtkSmartPointer::New(); m_ClippingPlaneCollection = vtkSmartPointer::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); m_DepthSort = vtkSmartPointer::New(); } ~LocalStorage() {} }; mitk::LocalStorageHandler m_LSH; static void ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty *property, mitk::BaseRenderer *renderer); static void SetDefaultPropertiesForVtkProperty(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite); }; } // namespace mitk #endif /* mitkSurfaceVtkMapper3D_h */ diff --git a/Modules/Core/include/vtkNeverTranslucentTexture.h b/Modules/Core/include/vtkNeverTranslucentTexture.h index fcfc29addf..5a62b4aa58 100644 --- a/Modules/Core/include/vtkNeverTranslucentTexture.h +++ b/Modules/Core/include/vtkNeverTranslucentTexture.h @@ -1,102 +1,102 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkNeverTranslucentTexture_h #define mitkNeverTranslucentTexture_h #include #include #include /** \brief VTK Fix to speed up our image rendering. The way we render images while changing the contrast via level/window extremely slows down rendering. The cause of this slowdown is that VTK asks a texture (via a call to IsTranslucent) if it is translucent. When the texture refers to a lookup table this question is answered in a most expensive way: pushing every pixel through the lookup table to see whether it would render translucent. We can speed this up extremely by always answering NO. 2D Image rendering in the context of MITK is still correct. This class is injected into the VTK system by registering it with vtkObjectFactory as a replacement for vtkTexture. We chose vtkOpenGLTexture as super class, because it seems that the other texture super class is deprecated: http://www.cmake.org/Wiki/VTK:How_I_mangled_Mesa \sa ImageVtkMapper2D */ /* NOT exported, this is a 2D image mapper helper */ class MITKCORE_EXPORT vtkNeverTranslucentTexture : public vtkOpenGLTexture { public: static vtkNeverTranslucentTexture *New(); - vtkTypeMacro(vtkNeverTranslucentTexture, vtkTexture); + vtkTypeMacro(vtkNeverTranslucentTexture, vtkOpenGLTexture); void PrintSelf(ostream &os, vtkIndent indent) override; /** \brief The FIX (see class description). VTK Description: Is this Texture Translucent? Returns false (0) if the texture is either fully opaque or has only fully transparent pixels and fully opaque pixels and the Interpolate flag is turn off. */ virtual int IsTranslucent() override; protected: vtkNeverTranslucentTexture(); private: vtkNeverTranslucentTexture(const vtkNeverTranslucentTexture &); // Not implemented. void operator=(const vtkNeverTranslucentTexture &); // Not implemented. }; /** \brief Factory for vtkNeverTranslucentTexture (see this class!). Registered in CoreActivator to replace all instances of vtkTexture with vtkNeverTranslucentTexture. Required to make rendering of images during level/window operations acceptably fast. */ class vtkNeverTranslucentTextureFactory : public vtkObjectFactory { public: vtkNeverTranslucentTextureFactory(); static vtkNeverTranslucentTextureFactory *New(); virtual const char *GetVTKSourceVersion() override; const char *GetDescription() override; protected: vtkNeverTranslucentTextureFactory(const vtkNeverTranslucentTextureFactory &); void operator=(const vtkNeverTranslucentTextureFactory &); }; #endif diff --git a/Modules/Core/src/Rendering/mitkPointSetVtkMapper3D.cpp b/Modules/Core/src/Rendering/mitkPointSetVtkMapper3D.cpp index 79836c6fa1..26b145b95b 100644 --- a/Modules/Core/src/Rendering/mitkPointSetVtkMapper3D.cpp +++ b/Modules/Core/src/Rendering/mitkPointSetVtkMapper3D.cpp @@ -1,706 +1,705 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPointSetVtkMapper3D.h" #include "mitkColorProperty.h" #include "mitkDataNode.h" #include "mitkPointSet.h" #include "mitkProperties.h" #include "mitkVtkPropRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include - #include +#include const mitk::PointSet *mitk::PointSetVtkMapper3D::GetInput() { return static_cast(GetDataNode()->GetData()); } mitk::PointSetVtkMapper3D::PointSetVtkMapper3D() : m_vtkSelectedPointList(NULL), m_vtkUnselectedPointList(NULL), m_VtkSelectedPolyDataMapper(NULL), m_VtkUnselectedPolyDataMapper(NULL), m_vtkTextList(NULL), m_NumberOfSelectedAdded(0), m_NumberOfUnselectedAdded(0), m_PointSize(1.0), m_ContourRadius(0.5), m_VertexRendering(false) { // propassembly m_PointsAssembly = vtkSmartPointer::New(); // creating actors to be able to set transform m_SelectedActor = vtkSmartPointer::New(); m_UnselectedActor = vtkSmartPointer::New(); m_ContourActor = vtkSmartPointer::New(); } mitk::PointSetVtkMapper3D::~PointSetVtkMapper3D() { } void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow *renWin) { m_PointsAssembly->ReleaseGraphicsResources(renWin); m_SelectedActor->ReleaseGraphicsResources(renWin); m_UnselectedActor->ReleaseGraphicsResources(renWin); m_ContourActor->ReleaseGraphicsResources(renWin); } void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(mitk::BaseRenderer *renderer) { m_PointsAssembly->ReleaseGraphicsResources(renderer->GetRenderWindow()); m_SelectedActor->ReleaseGraphicsResources(renderer->GetRenderWindow()); m_UnselectedActor->ReleaseGraphicsResources(renderer->GetRenderWindow()); m_ContourActor->ReleaseGraphicsResources(renderer->GetRenderWindow()); } void mitk::PointSetVtkMapper3D::CreateVTKRenderObjects() { m_vtkSelectedPointList = vtkSmartPointer::New(); m_vtkUnselectedPointList = vtkSmartPointer::New(); m_PointsAssembly->VisibilityOn(); if (m_PointsAssembly->GetParts()->IsItemPresent(m_SelectedActor)) m_PointsAssembly->RemovePart(m_SelectedActor); if (m_PointsAssembly->GetParts()->IsItemPresent(m_UnselectedActor)) m_PointsAssembly->RemovePart(m_UnselectedActor); if (m_PointsAssembly->GetParts()->IsItemPresent(m_ContourActor)) m_PointsAssembly->RemovePart(m_ContourActor); // exceptional displaying for PositionTracker -> MouseOrientationTool int mapperID; bool isInputDevice = false; if (this->GetDataNode()->GetBoolProperty("inputdevice", isInputDevice) && isInputDevice) { if (this->GetDataNode()->GetIntProperty("BaseRendererMapperID", mapperID) && mapperID == BaseRenderer::Standard3D) return; // The event for the PositionTracker came from the 3d widget and not needs to be displayed } // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); /* only update the input data, if the property tells us to */ bool update = true; this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); if (update == true) input->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet(timestep); if (itkPointSet.GetPointer() == NULL) { m_PointsAssembly->VisibilityOff(); return; } // now fill selected and unselected pointList // get size of Points in Property m_PointSize = 2; mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); if (pointSizeProp.IsNotNull()) m_PointSize = pointSizeProp->GetValue(); // get the property for creating a label onto every point only once bool showLabel = true; this->GetDataNode()->GetBoolProperty("show label", showLabel); const char *pointLabel = NULL; if (showLabel) { if (dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label")) != NULL) pointLabel = dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label"))->GetValue(); else showLabel = false; } // whether or not to creat a "contour" - connecting lines between all the points int nbPoints = itkPointSet->GetPointData()->Size(); bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); bool closeContour = false; this->GetDataNode()->GetBoolProperty("close contour", closeContour); int contourPointLimit = 0; // NO contour if (makeContour) { if (closeContour) contourPointLimit = nbPoints; else contourPointLimit = nbPoints - 1; } // build list of all positions for later transform in one go mitk::PointSet::PointsContainer::Iterator pointsIter; int ptIdx; m_NumberOfSelectedAdded = 0; m_NumberOfUnselectedAdded = 0; vtkSmartPointer localPoints = vtkSmartPointer::New(); m_WorldPositions = vtkSmartPointer::New(); m_PointConnections = vtkSmartPointer::New(); // m_PointConnections between points for (ptIdx = 0, pointsIter = itkPointSet->GetPoints()->Begin(); pointsIter != itkPointSet->GetPoints()->End(); pointsIter++, ptIdx++) { itk::Point currentPoint = pointsIter->Value(); localPoints->InsertPoint(ptIdx, currentPoint[0], currentPoint[1], currentPoint[2]); if (makeContour && ptIdx < contourPointLimit) { vtkIdType cell[2] = {(ptIdx + 1) % nbPoints, ptIdx}; m_PointConnections->InsertNextCell(2, cell); } } vtkSmartPointer vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); vtktransform->TransformPoints(localPoints, m_WorldPositions); // create contour if (makeContour) { this->CreateContour(m_WorldPositions, m_PointConnections); } // check if the list for the PointDataContainer is the same size as the PointsContainer. Is not, then the points were // inserted manually and can not be visualized according to the PointData (selected/unselected) bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); // now add an object for each point in data mitk::PointSet::PointDataContainer::Iterator pointDataIter = itkPointSet->GetPointData()->Begin(); for (ptIdx = 0; ptIdx < nbPoints; ++ptIdx) // pointDataIter moved at end of loop { double currentPoint[3]; m_WorldPositions->GetPoint(ptIdx, currentPoint); vtkSmartPointer source; // check for the pointtype in data and decide which geom-object to take and then add to the selected or unselected // list int pointType; if (itkPointSet->GetPointData()->size() == 0 || pointDataBroken) pointType = mitk::PTUNDEFINED; else pointType = pointDataIter.Value().pointSpec; switch (pointType) { case mitk::PTUNDEFINED: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize / 2.0f); sphere->SetCenter(currentPoint); // sphere->SetCenter(pointsIter.Value()[0],pointsIter.Value()[1],pointsIter.Value()[2]); // MouseOrientation Tool (PositionTracker) if (isInputDevice) { sphere->SetThetaResolution(10); sphere->SetPhiResolution(10); } else { sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); } source = sphere; } break; case mitk::PTSTART: { vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetXLength(m_PointSize / 2); cube->SetYLength(m_PointSize / 2); cube->SetZLength(m_PointSize / 2); cube->SetCenter(currentPoint); source = cube; } break; case mitk::PTCORNER: { vtkSmartPointer cone = vtkSmartPointer::New(); cone->SetRadius(m_PointSize / 2.0f); cone->SetCenter(currentPoint); cone->SetResolution(20); source = cone; } break; case mitk::PTEDGE: { vtkSmartPointer cylinder = vtkSmartPointer::New(); cylinder->SetRadius(m_PointSize / 2.0f); cylinder->SetCenter(currentPoint); cylinder->SetResolution(20); source = cylinder; } break; case mitk::PTEND: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize / 2.0f); // no SetCenter?? this functionality should be explained! // otherwise: join with default block! sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; default: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize / 2.0f); sphere->SetCenter(currentPoint); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; } if (pointDataIter.Value().selected && !pointDataBroken) { m_vtkSelectedPointList->AddInputConnection(source->GetOutputPort()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInputConnection(source->GetOutputPort()); ++m_NumberOfUnselectedAdded; } if (showLabel) { char buffer[20]; std::string l = pointLabel; if (input->GetSize() > 1) { sprintf(buffer, "%d", ptIdx + 1); l.append(buffer); } // Define the text for the label vtkSmartPointer label = vtkSmartPointer::New(); label->SetText(l.c_str()); //# Set up a transform to move the label to a new position. vtkSmartPointer aLabelTransform = vtkSmartPointer::New(); aLabelTransform->Identity(); aLabelTransform->Translate(currentPoint[0] + 2, currentPoint[1] + 2, currentPoint[2]); aLabelTransform->Scale(5.7, 5.7, 5.7); //# Move the label to a new position. vtkSmartPointer labelTransform = vtkSmartPointer::New(); labelTransform->SetTransform(aLabelTransform); labelTransform->SetInputConnection(label->GetOutputPort()); // add it to the wright PointList if (pointType) { m_vtkSelectedPointList->AddInputConnection(labelTransform->GetOutputPort()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInputConnection(labelTransform->GetOutputPort()); ++m_NumberOfUnselectedAdded; } } if (pointDataIter != itkPointSet->GetPointData()->End()) pointDataIter++; } // end FOR // now according to number of elements added to selected or unselected, build up the rendering pipeline if (m_NumberOfSelectedAdded > 0) { m_VtkSelectedPolyDataMapper = vtkSmartPointer::New(); m_VtkSelectedPolyDataMapper->SetInputConnection(m_vtkSelectedPointList->GetOutputPort()); // create a new instance of the actor m_SelectedActor = vtkSmartPointer::New(); m_SelectedActor->SetMapper(m_VtkSelectedPolyDataMapper); m_PointsAssembly->AddPart(m_SelectedActor); } if (m_NumberOfUnselectedAdded > 0) { m_VtkUnselectedPolyDataMapper = vtkSmartPointer::New(); m_VtkUnselectedPolyDataMapper->SetInputConnection(m_vtkUnselectedPointList->GetOutputPort()); // create a new instance of the actor m_UnselectedActor = vtkSmartPointer::New(); m_UnselectedActor->SetMapper(m_VtkUnselectedPolyDataMapper); m_PointsAssembly->AddPart(m_UnselectedActor); } } void mitk::PointSetVtkMapper3D::VertexRendering() { // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); /* only update the input data, if the property tells us to */ bool update = true; this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); if (update == true) input->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet(timestep); // turn off standard actors m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); // point size m_PointSize = 2.0; mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); if (pointSizeProp.IsNotNull()) m_PointSize = pointSizeProp->GetValue(); double *color = m_UnselectedActor->GetProperty()->GetColor(); double opacity = m_UnselectedActor->GetProperty()->GetOpacity(); glClearColor(0.0, 0.0, 0.0, 0.0); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); glEnable(GL_POINT_SMOOTH); glPointSize(m_PointSize); glBegin(GL_POINTS); glColor4d(color[0], color[1], color[2], opacity); for (auto pointsIter = itkPointSet->GetPoints()->Begin(); pointsIter != itkPointSet->GetPoints()->End(); pointsIter++) { const itk::Point &point = pointsIter->Value(); glVertex3d(point[0], point[1], point[2]); } glEnd(); // reset context glPointSize(1.0); glDisable(GL_POINT_SMOOTH); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); } void mitk::PointSetVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if (!visible) { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); m_ContourActor->VisibilityOff(); return; } // create new vtk render objects (e.g. sphere for a point) SetVtkMapperImmediateModeRendering(m_VtkSelectedPolyDataMapper); SetVtkMapperImmediateModeRendering(m_VtkUnselectedPolyDataMapper); BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool needGenerateData = ls->IsGenerateDataRequired(renderer, this, GetDataNode()); if (!needGenerateData) { mitk::FloatProperty *pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); mitk::FloatProperty *contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize")); bool useVertexRendering = false; this->GetDataNode()->GetBoolProperty("Vertex Rendering", useVertexRendering); // only create new vtk render objects if property values were changed if (pointSizeProp && m_PointSize != pointSizeProp->GetValue()) needGenerateData = true; if (contourSizeProp && m_ContourRadius != contourSizeProp->GetValue()) needGenerateData = true; // when vertex rendering is enabled the pointset is always // drawn with opengl, thus we leave needGenerateData always false if (useVertexRendering && m_VertexRendering != useVertexRendering) { needGenerateData = false; m_VertexRendering = true; } else if (!useVertexRendering && m_VertexRendering) { m_VertexRendering = false; needGenerateData = true; } } if (needGenerateData) { this->CreateVTKRenderObjects(); ls->UpdateGenerateDataTime(); } this->ApplyAllProperties(renderer, m_ContourActor); bool showPoints = true; this->GetDataNode()->GetBoolProperty("show points", showPoints); m_UnselectedActor->SetVisibility(showPoints && !m_VertexRendering); m_SelectedActor->SetVisibility(showPoints && !m_VertexRendering); if (false && dynamic_cast(this->GetDataNode()->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity = dynamic_cast(this->GetDataNode()->GetProperty("opacity")); float opacity = pointOpacity->GetValue(); m_ContourActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetOpacity(opacity); m_SelectedActor->GetProperty()->SetOpacity(opacity); } bool showContour = false; this->GetDataNode()->GetBoolProperty("show contour", showContour); m_ContourActor->SetVisibility(showContour); // use vertex rendering if (m_VertexRendering) { VertexRendering(); ls->UpdateGenerateDataTime(); } } void mitk::PointSetVtkMapper3D::ResetMapper(BaseRenderer * /*renderer*/) { m_PointsAssembly->VisibilityOff(); } vtkProp *mitk::PointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_PointsAssembly; } void mitk::PointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { } void mitk::PointSetVtkMapper3D::ApplyAllProperties(mitk::BaseRenderer *renderer, vtkActor *actor) { Superclass::ApplyColorAndOpacityProperties(renderer, actor); // check for color props and use it for rendering of selected/unselected points and contour // due to different params in VTK (double/float) we have to convert! // vars to convert to double unselectedColor[4] = {1.0f, 1.0f, 0.0f, 1.0f}; // yellow double selectedColor[4] = {1.0f, 0.0f, 0.0f, 1.0f}; // red double contourColor[4] = {1.0f, 0.0f, 0.0f, 1.0f}; // red // different types for color!!! mitk::Color tmpColor; double opacity = 1.0; // check if there is an unselected property if (dynamic_cast( this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast( this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) ->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else if (dynamic_cast( this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor")) ->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else { // check if the node has a color float unselectedColorTMP[4] = {1.0f, 1.0f, 0.0f, 1.0f}; // yellow m_DataNode->GetColor(unselectedColorTMP, NULL); unselectedColor[0] = unselectedColorTMP[0]; unselectedColor[1] = unselectedColorTMP[1]; unselectedColor[2] = unselectedColorTMP[2]; // unselectedColor[3] stays 1.0f } // get selected property if (dynamic_cast( this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) ->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } else if (dynamic_cast( this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) ->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } // get contour property if (dynamic_cast( this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) ->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast( this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) ->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } // finished color / opacity fishing! // check if a contour shall be drawn bool showContour = false; this->GetDataNode()->GetBoolProperty("show contour", showContour, renderer); if (showContour && (m_ContourActor != NULL)) { this->CreateContour(m_WorldPositions, m_PointConnections); m_ContourActor->GetProperty()->SetColor(contourColor); m_ContourActor->GetProperty()->SetOpacity(opacity); } m_SelectedActor->GetProperty()->SetColor(selectedColor); m_SelectedActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetColor(unselectedColor); m_UnselectedActor->GetProperty()->SetOpacity(opacity); } void mitk::PointSetVtkMapper3D::CreateContour(vtkPoints *points, vtkCellArray *m_PointConnections) { vtkSmartPointer vtkContourPolyData = vtkSmartPointer::New(); vtkSmartPointer vtkContourPolyDataMapper = vtkSmartPointer::New(); vtkSmartPointer contour = vtkSmartPointer::New(); contour->SetPoints(points); contour->SetLines(m_PointConnections); vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetNumberOfSides(12); tubeFilter->SetInputData(contour); // check for property contoursize. m_ContourRadius = 0.5; mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize")); if (contourSizeProp.IsNotNull()) m_ContourRadius = contourSizeProp->GetValue(); tubeFilter->SetRadius(m_ContourRadius); tubeFilter->Update(); // add to pipeline vtkContourPolyData->AddInputConnection(tubeFilter->GetOutputPort()); vtkContourPolyDataMapper->SetInputConnection(vtkContourPolyData->GetOutputPort()); m_ContourActor->SetMapper(vtkContourPolyDataMapper); m_PointsAssembly->AddPart(m_ContourActor); } void mitk::PointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite) { node->AddProperty("line width", mitk::IntProperty::New(2), renderer, overwrite); node->AddProperty("pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite); node->AddProperty("selectedcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); // red node->AddProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); // yellow node->AddProperty("opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite); node->AddProperty("show contour", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("close contour", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); node->AddProperty("contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite); node->AddProperty("show points", mitk::BoolProperty::New(true), renderer, overwrite); node->AddProperty("updateDataOnRender", mitk::BoolProperty::New(true), renderer, overwrite); node->AddProperty("Vertex Rendering", mitk::BoolProperty::New(false), renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/Gizmo/src/mitkGizmoMapper2D.cpp b/Modules/Gizmo/src/mitkGizmoMapper2D.cpp index 39fe9bb696..d0703db556 100644 --- a/Modules/Gizmo/src/mitkGizmoMapper2D.cpp +++ b/Modules/Gizmo/src/mitkGizmoMapper2D.cpp @@ -1,341 +1,341 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGizmoMapper2D.h" #include "mitkGizmo.h" // MITK includes #include #include #include #include #include // VTK includes #include #include #include #include #include #include #include #include #include mitk::GizmoMapper2D::LocalStorage::LocalStorage() { - m_VtkPolyDataMapper = vtkSmartPointer::New(); + m_VtkPolyDataMapper = vtkSmartPointer::New(); m_Actor = vtkSmartPointer::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); } const mitk::Gizmo *mitk::GizmoMapper2D::GetInput() { return static_cast(GetDataNode()->GetData()); } void mitk::GizmoMapper2D::ResetMapper(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_Actor->VisibilityOff(); } namespace { //! Helper method: will assign given value to all points in given polydata object. void AssignScalarValueTo(vtkPolyData *polydata, char value) { vtkSmartPointer pointData = vtkSmartPointer::New(); int numberOfPoints = polydata->GetNumberOfPoints(); pointData->SetNumberOfComponents(1); pointData->SetNumberOfTuples(numberOfPoints); pointData->FillComponent(0, value); polydata->GetPointData()->SetScalars(pointData); } //! Helper method: will create a vtkPolyData representing a disk //! around center, inside the plane defined by viewRight and viewUp, //! and with the given radius. vtkSmartPointer Create2DDisk(mitk::Vector3D viewRight, mitk::Vector3D viewUp, mitk::Point3D center, double radius) { // build the axis itself (as a tube around the line defining the axis) vtkSmartPointer disk = vtkSmartPointer::New(); mitk::Vector3D ringPointer; unsigned int numberOfRingPoints = 36; vtkSmartPointer ringPoints = vtkSmartPointer::New(); vtkSmartPointer ringPoly = vtkSmartPointer::New(); ringPoly->InsertNextCell(numberOfRingPoints + 1); for (unsigned int segment = 0; segment < numberOfRingPoints; ++segment) { double x = std::cos((double)(segment) / (double)numberOfRingPoints * 2.0 * vtkMath::Pi()); double y = std::sin((double)(segment) / (double)numberOfRingPoints * 2.0 * vtkMath::Pi()); ringPointer = viewRight * x + viewUp * y; ringPoints->InsertPoint(segment, (center + ringPointer * radius).GetDataPointer()); ringPoly->InsertCellPoint(segment); } ringPoly->InsertCellPoint(0); disk->SetPoints(ringPoints); disk->SetPolys(ringPoly); return disk; } //! Helper method: will create a vtkPolyData representing a 2D arrow //! that is oriented from arrowStart to arrowTip, orthogonal //! to camera direction. The arrow tip will contain scalar values //! of vertexValueScale, the arrow shaft will contain scalar values //! of vertexValueMove. Those values are used for picking during interaction. vtkSmartPointer Create2DArrow(mitk::Vector3D cameraDirection, mitk::Point3D arrowStart, mitk::Point3D arrowTip, int vertexValueMove, int vertexValueScale) { mitk::Vector3D arrowDirection = arrowTip - arrowStart; mitk::Vector3D arrowOrthogonal = itk::CrossProduct(cameraDirection, arrowDirection); arrowOrthogonal.Normalize(); double triangleFraction = 0.2; vtkSmartPointer arrow = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); // shaft : points 0, 1 points->InsertPoint(0, arrowStart.GetDataPointer()); points->InsertPoint(1, (arrowStart + arrowDirection * (1.0 - triangleFraction)).GetDataPointer()); // tip : points 2, 3, 4 points->InsertPoint(2, arrowTip.GetDataPointer()); points->InsertPoint(3, (arrowStart + (1.0 - triangleFraction) * arrowDirection + arrowOrthogonal * (0.5 * triangleFraction * arrowDirection.GetNorm())) .GetDataPointer()); points->InsertPoint(4, (arrowStart + (1.0 - triangleFraction) * arrowDirection - arrowOrthogonal * (0.5 * triangleFraction * arrowDirection.GetNorm())) .GetDataPointer()); arrow->SetPoints(points); // define line connection for shaft vtkSmartPointer lines = vtkSmartPointer::New(); vtkIdType shaftLinePoints[] = {0, 1}; lines->InsertNextCell(2, shaftLinePoints); arrow->SetLines(lines); // define polygon for triangle vtkSmartPointer polys = vtkSmartPointer::New(); vtkIdType tipLinePoints[] = {2, 3, 4}; polys->InsertNextCell(3, tipLinePoints); arrow->SetPolys(polys); // assign scalar values vtkSmartPointer pointData = vtkSmartPointer::New(); pointData->SetNumberOfComponents(1); pointData->SetNumberOfTuples(5); pointData->FillComponent(0, vertexValueScale); pointData->SetTuple1(0, vertexValueMove); pointData->SetTuple1(1, vertexValueMove); arrow->GetPointData()->SetScalars(pointData); return arrow; } } vtkPolyData *mitk::GizmoMapper2D::GetVtkPolyData(mitk::BaseRenderer *renderer) { return m_LSH.GetLocalStorage(renderer)->m_VtkPolyDataMapper->GetInput(); } void mitk::GizmoMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { auto gizmo = GetInput(); auto node = GetDataNode(); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // check if something important has changed and we need to re-render if ((ls->m_LastUpdateTime >= node->GetMTime()) && (ls->m_LastUpdateTime >= gizmo->GetPipelineMTime()) && (ls->m_LastUpdateTime >= renderer->GetCurrentWorldPlaneGeometryUpdateTime()) && (ls->m_LastUpdateTime >= renderer->GetCurrentWorldPlaneGeometry()->GetMTime()) && (ls->m_LastUpdateTime >= node->GetPropertyList()->GetMTime()) && (ls->m_LastUpdateTime >= node->GetPropertyList(renderer)->GetMTime())) { return; } ls->m_LastUpdateTime.Modified(); // some special handling around visibility: let two properties steer // visibility in 2D instead of many renderer specific "visible" properties bool visible2D = true; this->GetDataNode()->GetBoolProperty("show in 2D", visible2D); if (!visible2D && renderer->GetMapperID() == BaseRenderer::Standard2D) { ls->m_Actor->VisibilityOff(); return; } else { ls->m_Actor->VisibilityOn(); } auto camera = renderer->GetVtkRenderer()->GetActiveCamera(); auto plane = renderer->GetCurrentWorldPlaneGeometry(); Point3D gizmoCenterView = plane->ProjectPointOntoPlane(gizmo->GetCenter()); Vector3D viewUp; camera->GetViewUp(viewUp.GetDataPointer()); Vector3D cameraDirection; camera->GetDirectionOfProjection(cameraDirection.GetDataPointer()); Vector3D viewRight = itk::CrossProduct(viewUp, cameraDirection); auto appender = vtkSmartPointer::New(); double diagonal = std::min(renderer->GetSizeX(), renderer->GetSizeY()); double arrowLength = 0.1 * diagonal; // fixed in relation to window size auto disk = Create2DDisk(viewRight, viewUp, gizmoCenterView - cameraDirection, 0.1 * arrowLength); AssignScalarValueTo(disk, Gizmo::MoveFreely); appender->AddInputData(disk); // loop over directions -1 and +1 for arrows for (double direction = -1.0; direction < 2.0; direction += 2.0) { auto axisX = Create2DArrow(cameraDirection, gizmoCenterView, plane->ProjectPointOntoPlane(gizmo->GetCenter() + (gizmo->GetAxisX() * arrowLength) * direction), Gizmo::MoveAlongAxisX, Gizmo::ScaleX); appender->AddInputData(axisX); auto axisY = Create2DArrow(cameraDirection, gizmoCenterView, plane->ProjectPointOntoPlane(gizmo->GetCenter() + (gizmo->GetAxisY() * arrowLength) * direction), Gizmo::MoveAlongAxisY, Gizmo::ScaleY); appender->AddInputData(axisY); auto axisZ = Create2DArrow(cameraDirection, gizmoCenterView, plane->ProjectPointOntoPlane(gizmo->GetCenter() + (gizmo->GetAxisZ() * arrowLength) * direction), Gizmo::MoveAlongAxisZ, Gizmo::ScaleZ); appender->AddInputData(axisZ); } ls->m_VtkPolyDataMapper->SetInputConnection(appender->GetOutputPort()); ApplyVisualProperties(renderer); } void mitk::GizmoMapper2D::ApplyVisualProperties(BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); float lineWidth = 3.0f; ls->m_Actor->GetProperty()->SetLineWidth(lineWidth); mitk::LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull()) { ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable()); } bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); ls->m_VtkPolyDataMapper->SetScalarVisibility((scalarVisibility ? 1 : 0)); if (scalarVisibility) { mitk::VtkScalarModeProperty *scalarMode; if (this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); else ls->m_VtkPolyDataMapper->SetScalarModeToDefault(); bool colorMode = false; this->GetDataNode()->GetBoolProperty("color mode", colorMode); ls->m_VtkPolyDataMapper->SetColorMode((colorMode ? 1 : 0)); double scalarsMin = 0; this->GetDataNode()->GetDoubleProperty("ScalarsRangeMinimum", scalarsMin, renderer); double scalarsMax = 1.0; this->GetDataNode()->GetDoubleProperty("ScalarsRangeMaximum", scalarsMax, renderer); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin, scalarsMax); } } void mitk::GizmoMapper2D::SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer /*= nullptr*/, bool /*= false*/) { node->SetProperty("color", ColorProperty::New(0.3, 0.3, 0.3)); // a little lighter than the // "plane widgets" of // QmitkStdMultiWidget node->SetProperty("scalar visibility", BoolProperty::New(true), renderer); node->SetProperty("ScalarsRangeMinimum", DoubleProperty::New(0), renderer); node->SetProperty("ScalarsRangeMaximum", DoubleProperty::New((int)Gizmo::NoHandle), renderer); double colorMoveFreely[] = {1, 0, 0, 1}; // RGBA double colorAxisX[] = {0.753, 0, 0, 1}; // colors copied from QmitkStdMultiWidget to double colorAxisY[] = {0, 0.69, 0, 1}; // look alike double colorAxisZ[] = {0, 0.502, 1, 1}; double colorInactive[] = {0.7, 0.7, 0.7, 1}; // build a nice color table vtkSmartPointer lut = vtkSmartPointer::New(); lut->SetNumberOfTableValues((int)Gizmo::NoHandle + 1); lut->SetTableRange(0, (int)Gizmo::NoHandle); lut->SetTableValue(Gizmo::MoveFreely, colorMoveFreely); lut->SetTableValue(Gizmo::MoveAlongAxisX, colorAxisX); lut->SetTableValue(Gizmo::MoveAlongAxisY, colorAxisY); lut->SetTableValue(Gizmo::MoveAlongAxisZ, colorAxisZ); lut->SetTableValue(Gizmo::RotateAroundAxisX, colorAxisX); lut->SetTableValue(Gizmo::RotateAroundAxisY, colorAxisY); lut->SetTableValue(Gizmo::RotateAroundAxisZ, colorAxisZ); lut->SetTableValue(Gizmo::ScaleX, colorAxisX); lut->SetTableValue(Gizmo::ScaleY, colorAxisY); lut->SetTableValue(Gizmo::ScaleZ, colorAxisZ); lut->SetTableValue(Gizmo::NoHandle, colorInactive); mitk::LookupTable::Pointer mlut = mitk::LookupTable::New(); mlut->SetVtkLookupTable(lut); mitk::LookupTableProperty::Pointer lutProp = mitk::LookupTableProperty::New(); lutProp->SetLookupTable(mlut); node->SetProperty("LookupTable", lutProp, renderer); node->SetProperty("helper object", BoolProperty::New(true), renderer); node->SetProperty("visible", BoolProperty::New(true), renderer); node->SetProperty("show in 2D", BoolProperty::New(true), renderer); // no "show in 3D" because this would require a specialized mapper for gizmos in 3D } diff --git a/Modules/Gizmo/src/mitkGizmoMapper2D.h b/Modules/Gizmo/src/mitkGizmoMapper2D.h index 14b4f2834e..83b5e6b59a 100644 --- a/Modules/Gizmo/src/mitkGizmoMapper2D.h +++ b/Modules/Gizmo/src/mitkGizmoMapper2D.h @@ -1,97 +1,97 @@ /*=================================================================== 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 mitkGizmoMapper2D_h #define mitkGizmoMapper2D_h #include -#include +#include namespace mitk { // forward declaration class Gizmo; //! 2D Mapper for mitk::Gimzo. //! //! Paints a similar representation as for 2D (see mitk::Gizmo itself). //! The three axes of the manipulated object are visualized. They are //! pickable and will report "move along axis" or "scale" when clicked //! at the arrow shafts or the arrow tips. //! //! For usability, we removed the circles for rotation because they //! would most often coincide with the arrows, thus distinction is //! complicated. class GizmoMapper2D : public mitk::VtkMapper { public: mitkClassMacro(GizmoMapper2D, VtkMapper); itkFactorylessNewMacro(Self); itkCloneMacro(Self); //! Provides given node with a set of default properties. //! //! \param node The DataNode to decorate with properties. //! \param renderer When not nullptr, generate specific properties for given renderer //! \param overwrite Whether already existing properties shall be overwritten. static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false); //! Return the vtkProp that represents the "rendering result". vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override { return m_LSH.GetLocalStorage(renderer)->m_Actor; } //! "Resets" the mapper, setting its result to invisible. void ResetMapper(mitk::BaseRenderer *renderer) override; //! Return the internal vtkPolyData for given renderer. //! This serves for picking by the associated interactor class. vtkPolyData *GetVtkPolyData(mitk::BaseRenderer *renderer); private: //! Provide the mapping input as a specific RawMesh_C const Gizmo *GetInput(); //! Update the vtkProp, i.e. the contours of a slice through our RawMesh_C. virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; //! Apply visual properties void ApplyVisualProperties(BaseRenderer *renderer); //! (RenderWindow) Instance specific data. class LocalStorage : public Mapper::BaseLocalStorage { public: //! The overall rendering result. vtkSmartPointer m_Actor; //! The mapper of the resulting vtkPolyData //! (3D polygons for 3D mapper, 2D contours for 2D mapper) - vtkSmartPointer m_VtkPolyDataMapper; + vtkSmartPointer m_VtkPolyDataMapper; //! Last time this storage has been updated. itk::TimeStamp m_LastUpdateTime; LocalStorage(); }; //! (RenderWindow) Instance specific data. LocalStorageHandler m_LSH; }; } // namespace #endif diff --git a/Modules/MapperExt/files.cmake b/Modules/MapperExt/files.cmake index 6a072e68b7..1b92156b3e 100644 --- a/Modules/MapperExt/files.cmake +++ b/Modules/MapperExt/files.cmake @@ -1,21 +1,19 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkEnhancedPointSetVtkMapper3D.cpp mitkGPUVolumeMapper3D.cpp mitkMeshMapper2D.cpp mitkMeshVtkMapper3D.cpp mitkSplineVtkMapper3D.cpp mitkUnstructuredGridMapper2D.cpp mitkUnstructuredGridVtkMapper3D.cpp mitkVectorImageMapper2D.cpp vtkMaskedGlyph2D.cpp vtkMaskedGlyph3D.cpp vtkMitkGPUVolumeRayCastMapper.cpp - vtkMitkOpenGLVolumeTextureMapper3D.cpp - vtkMitkVolumeTextureMapper3D.cpp vtkUnstructuredGridMapper.cpp vtkPointSetSlicer.cxx ) diff --git a/Modules/MapperExt/include/mitkGPUVolumeMapper3D.h b/Modules/MapperExt/include/mitkGPUVolumeMapper3D.h index 73b73c1fcf..7b5869eafb 100644 --- a/Modules/MapperExt/include/mitkGPUVolumeMapper3D.h +++ b/Modules/MapperExt/include/mitkGPUVolumeMapper3D.h @@ -1,190 +1,164 @@ /*=================================================================== 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 MITKGPUVOLUMEMAPPER3D_H_HEADER_INCLUDED #define MITKGPUVOLUMEMAPPER3D_H_HEADER_INCLUDED // MITK #include "MitkMapperExtExports.h" #include "mitkBaseRenderer.h" #include "mitkCommon.h" #include "mitkImage.h" #include "mitkVtkMapper.h" -#include "vtkMitkVolumeTextureMapper3D.h" // VTK #include #include #include #include #include #include -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - #include "vtkMitkGPUVolumeRayCastMapper.h" -#endif - namespace mitk { /************************************************************************/ /* Properties that influence the mapper are: * * - \b "level window": for the level window of the volume data * - \b "LookupTable" : for the lookup table of the volume data * - \b "TransferFunction" (mitk::TransferFunctionProperty): for the used transfer function of the volume data ************************************************************************/ //##Documentation //## @brief Vtk-based mapper for VolumeData //## //## @ingroup Mapper class MITKMAPPEREXT_EXPORT GPUVolumeMapper3D : public VtkMapper { public: mitkClassMacro(GPUVolumeMapper3D, VtkMapper); itkFactorylessNewMacro(Self) itkCloneMacro(Self) virtual const mitk::Image *GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override; virtual void ApplyProperties(vtkActor *actor, mitk::BaseRenderer *renderer) override; static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = NULL, bool overwrite = false); /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled(BaseRenderer *renderer = NULL) const override; bool IsMIPEnabled(BaseRenderer *renderer = NULL); bool IsGPUEnabled(BaseRenderer *renderer = NULL); bool IsRAYEnabled(BaseRenderer *renderer = NULL); virtual void MitkRenderVolumetricGeometry(mitk::BaseRenderer *renderer) override; protected: GPUVolumeMapper3D(); virtual ~GPUVolumeMapper3D(); bool IsRenderable(mitk::BaseRenderer *renderer); void InitCommon(); void DeinitCommon(); void InitCPU(mitk::BaseRenderer *renderer); void DeinitCPU(mitk::BaseRenderer *renderer); void GenerateDataCPU(mitk::BaseRenderer *renderer); bool InitGPU(mitk::BaseRenderer *renderer); - void DeinitGPU(mitk::BaseRenderer *renderer); - void GenerateDataGPU(mitk::BaseRenderer *renderer); - -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) + void DeinitGPU(mitk::BaseRenderer *); + void GenerateDataGPU(mitk::BaseRenderer *); bool InitRAY(mitk::BaseRenderer *renderer); void DeinitRAY(mitk::BaseRenderer *renderer); void GenerateDataRAY(mitk::BaseRenderer *renderer); -#endif - void InitVtkMapper(mitk::BaseRenderer *renderer); virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; void CreateDefaultTransferFunctions(); void UpdateTransferFunctions(mitk::BaseRenderer *renderer); vtkSmartPointer m_VolumeNULL; bool m_commonInitialized; vtkSmartPointer m_UnitSpacingImageFilter; vtkSmartPointer m_DefaultOpacityTransferFunction; vtkSmartPointer m_DefaultGradientTransferFunction; vtkSmartPointer m_DefaultColorTransferFunction; vtkSmartPointer m_BinaryOpacityTransferFunction; vtkSmartPointer m_BinaryGradientTransferFunction; vtkSmartPointer m_BinaryColorTransferFunction; class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: // NO SMARTPOINTER HERE vtkRenderWindow *m_VtkRenderWindow; bool m_cpuInitialized; vtkSmartPointer m_VolumeCPU; vtkSmartPointer m_MapperCPU; vtkSmartPointer m_VolumePropertyCPU; bool m_gpuSupported; bool m_gpuInitialized; vtkSmartPointer m_VolumeGPU; - vtkSmartPointer m_MapperGPU; vtkSmartPointer m_VolumePropertyGPU; -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - bool m_raySupported; bool m_rayInitialized; vtkSmartPointer m_VolumeRAY; vtkSmartPointer m_MapperRAY; vtkSmartPointer m_VolumePropertyRAY; -#endif - LocalStorage() { m_VtkRenderWindow = 0; m_cpuInitialized = false; m_gpuInitialized = false; m_gpuSupported = true; // assume initially gpu slicing is supported -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) m_rayInitialized = false; m_raySupported = true; // assume initially gpu raycasting is supported -#endif } ~LocalStorage() { if (m_cpuInitialized && m_MapperCPU && m_VtkRenderWindow) m_MapperCPU->ReleaseGraphicsResources(m_VtkRenderWindow); - if (m_gpuInitialized && m_MapperGPU && m_VtkRenderWindow) - m_MapperGPU->ReleaseGraphicsResources(m_VtkRenderWindow); - -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) if (m_rayInitialized && m_MapperRAY && m_VtkRenderWindow) m_MapperRAY->ReleaseGraphicsResources(m_VtkRenderWindow); -#endif } }; mitk::LocalStorageHandler m_LSH; }; } // namespace mitk #endif /* MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED */ diff --git a/Modules/MapperExt/include/vtkMitkGPUVolumeRayCastMapper.h b/Modules/MapperExt/include/vtkMitkGPUVolumeRayCastMapper.h index cf37c3bb21..a7a6031c65 100644 --- a/Modules/MapperExt/include/vtkMitkGPUVolumeRayCastMapper.h +++ b/Modules/MapperExt/include/vtkMitkGPUVolumeRayCastMapper.h @@ -1,299 +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. ===================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper.h,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME vtkMitkGPUVolumeRayCastMapper - Ray casting performed on the GPU. // .SECTION Description // vtkMitkGPUVolumeRayCastMapper is a volume mapper that performs ray casting on // the GPU using fragment programs. // #ifndef __vtkMitkGPUVolumeRayCastMapper_h #define __vtkMitkGPUVolumeRayCastMapper_h #include "MitkMapperExtExports.h" #include "mitkCommon.h" #include "vtkVersionMacros.h" #include "vtkVolumeMapper.h" -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - class vtkVolumeProperty; class vtkRenderWindow; // class vtkKWAMRVolumeMapper; // friend class. class MITKMAPPEREXT_EXPORT vtkMitkGPUVolumeRayCastMapper : public vtkVolumeMapper { public: vtkTypeMacro(vtkMitkGPUVolumeRayCastMapper, vtkVolumeMapper); void PrintSelf(ostream &os, vtkIndent indent) override; // Description: // If AutoAdjustSampleDistances is on, the the ImageSampleDistance // will be varied to achieve the allocated render time of this // prop (controlled by the desired update rate and any culling in // use). vtkSetClampMacro(AutoAdjustSampleDistances, int, 0, 1); vtkGetMacro(AutoAdjustSampleDistances, int); vtkBooleanMacro(AutoAdjustSampleDistances, int); // Description: // Set/Get the distance between samples used for rendering // when AutoAdjustSampleDistances is off, or when this mapper // has more than 1 second allocated to it for rendering. // Initial value is 1.0. vtkSetMacro(SampleDistance, float); vtkGetMacro(SampleDistance, float); // Description: // Sampling distance in the XY image dimensions. Default value of 1 meaning // 1 ray cast per pixel. If set to 0.5, 4 rays will be cast per pixel. If // set to 2.0, 1 ray will be cast for every 4 (2 by 2) pixels. This value // will be adjusted to meet a desired frame rate when AutoAdjustSampleDistances // is on. vtkSetClampMacro(ImageSampleDistance, float, 0.1f, 100.0f); vtkGetMacro(ImageSampleDistance, float); // Description: // This is the minimum image sample distance allow when the image // sample distance is being automatically adjusted. vtkSetClampMacro(MinimumImageSampleDistance, float, 0.1f, 100.0f); vtkGetMacro(MinimumImageSampleDistance, float); // Description: // This is the maximum image sample distance allow when the image // sample distance is being automatically adjusted. vtkSetClampMacro(MaximumImageSampleDistance, float, 0.1f, 100.0f); vtkGetMacro(MaximumImageSampleDistance, float); // Description: // Set/Get the window / level applied to the final color. // This allows brightness / contrast adjustments on the // final image. // window is the width of the window. // level is the center of the window. // Initial window value is 1.0 // Initial level value is 0.5 // window cannot be null but can be negative, this way // values will be reversed. // |window| can be larger than 1.0 // level can be any real value. vtkSetMacro(FinalColorWindow, float); vtkGetMacro(FinalColorWindow, float); vtkSetMacro(FinalColorLevel, float); vtkGetMacro(FinalColorLevel, float); // Description: // Maximum size of the 3D texture in GPU memory. // Will default to the size computed from the graphics // card. Can be adjusted by the user. vtkSetMacro(MaxMemoryInBytes, vtkIdType); vtkGetMacro(MaxMemoryInBytes, vtkIdType); // Description: // Maximum fraction of the MaxMemoryInBytes that should // be used to hold the texture. Valid values are 0.1 to // 1.0. vtkSetClampMacro(MaxMemoryFraction, float, 0.1f, 1.0f); vtkGetMacro(MaxMemoryFraction, float); // Description: // Tells if the mapper will report intermediate progress. // Initial value is true. As the progress works with a GL blocking // call (glFinish()), this can be useful for huge dataset but can // slow down rendering of small dataset. It should be set to true // for big dataset or complex shading and streaming but to false for // small datasets. vtkSetMacro(ReportProgress, bool); vtkGetMacro(ReportProgress, bool); // Description: // Based on hardware and properties, we may or may not be able to // render using 3D texture mapping. This indicates if 3D texture // mapping is supported by the hardware, and if the other extensions // necessary to support the specific properties are available. virtual int IsRenderSupported(vtkRenderWindow *vtkNotUsed(window), vtkVolumeProperty *vtkNotUsed(property)) { return 0; } void CreateCanonicalView(vtkRenderer *ren, vtkVolume *volume, vtkImageData *image, int blend_mode, double viewDirection[3], double viewUp[3]); void SetMaskInput(vtkImageData *mask); vtkGetObjectMacro(MaskInput, vtkImageData); // Description: // Tells how much mask color transfer function is used compared to the // standard color transfer function when the mask is true. // 0.0 means only standard color transfer function. // 1.0 means only mask color tranfer function. // Initial value is 1.0. vtkSetClampMacro(MaskBlendFactor, float, 0.0f, 1.0f); vtkGetMacro(MaskBlendFactor, float); // BTX // Description: // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE // Initialize rendering for this volume. void Render(vtkRenderer *, vtkVolume *) override; // Description: // Handled in the subclass - the actual render method // \pre input is up-to-date. virtual void GPURender(vtkRenderer *, vtkVolume *) {} // Description: // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE // Release any graphics resources that are being consumed by this mapper. // The parameter window could be used to determine which graphic // resources to release. // \deprecatedSince{2013_12} DEPRECATED(void ReleaseGraphicsResources(vtkWindow *) override){}; // Description: // Return how much the dataset has to be reduced in each dimension to // fit on the GPU. If the value is 1.0, there is no need to reduce the // dataset. // \pre the calling thread has a current OpenGL context. // \pre mapper_supported: IsRenderSupported(renderer->GetRenderWindow(),0) // The computation is based on hardware limits (3D texture indexable size) // and MaxMemoryInBytes. // \post valid_i_ratio: ratio[0]>0 && ratio[0]<=1.0 // \post valid_j_ratio: ratio[1]>0 && ratio[1]<=1.0 // \post valid_k_ratio: ratio[2]>0 && ratio[2]<=1.0 virtual void GetReductionRatio(double ratio[3]) = 0; // ETX protected: vtkMitkGPUVolumeRayCastMapper(); ~vtkMitkGPUVolumeRayCastMapper(); // Check to see that the render will be OK int ValidateRender(vtkRenderer *, vtkVolume *); // Special version of render called during the creation // of a canonical view. void CanonicalViewRender(vtkRenderer *, vtkVolume *); // Methods called by the AMR Volume Mapper. virtual void PreRender(vtkRenderer *ren, vtkVolume *vol, double datasetBounds[6], double scalarRange[2], int numberOfScalarComponents, unsigned int numberOfLevels) = 0; // \pre input is up-to-date virtual void RenderBlock(vtkRenderer *ren, vtkVolume *vol, unsigned int level) = 0; virtual void PostRender(vtkRenderer *ren, int numberOfScalarComponents) = 0; // Description: // Called by the AMR Volume Mapper. // Set the flag that tells if the scalars are on point data (0) or // cell data (1). void SetCellFlag(int cellFlag); // The distance between sample points along the ray float SampleDistance; float ImageSampleDistance; float MinimumImageSampleDistance; float MaximumImageSampleDistance; int AutoAdjustSampleDistances; int SmallVolumeRender; double BigTimeToDraw; double SmallTimeToDraw; float FinalColorWindow; float FinalColorLevel; vtkIdType MaxMemoryInBytes; float MaxMemoryFraction; // 1 if we are generating the canonical image, 0 otherwise int GeneratingCanonicalView; vtkImageData *CanonicalViewImageData; // Description: // Set the mapper in AMR Mode or not. Initial value is false. // Called only by the vtkKWAMRVolumeMapper vtkSetClampMacro(AMRMode, int, 0, 1); vtkGetMacro(AMRMode, int); vtkBooleanMacro(AMRMode, int); int AMRMode; int CellFlag; // point data or cell data (or field data, not handled) ? // Description: // Compute the cropping planes clipped by the bounds of the volume. // The result is put into this->ClippedCroppingRegionPlanes. // NOTE: IT WILL BE MOVED UP TO vtkVolumeMapper after bullet proof usage // in this mapper. Other subclasses will use the ClippedCroppingRegionsPlanes // members instead of CroppingRegionPlanes. // \pre volume_exists: this->GetInput()!=0 // \pre valid_cropping: this->Cropping && // this->CroppingRegionPlanes[0]CroppingRegionPlanes[1] && // this->CroppingRegionPlanes[2]CroppingRegionPlanes[3] && // this->CroppingRegionPlanes[4]CroppingRegionPlanes[5]) virtual void ClipCroppingRegionPlanes(); double ClippedCroppingRegionPlanes[6]; bool ReportProgress; vtkImageData *MaskInput; float MaskBlendFactor; vtkGetObjectMacro(TransformedInput, vtkImageData); void SetTransformedInput(vtkImageData *); vtkImageData *TransformedInput; // Description: // This is needed only to check if the input data has been changed since the last // Render() call. vtkImageData *LastInput; private: vtkMitkGPUVolumeRayCastMapper(const vtkMitkGPUVolumeRayCastMapper &); // Not implemented. void operator=(const vtkMitkGPUVolumeRayCastMapper &); // Not implemented. }; #endif - -#endif diff --git a/Modules/MapperExt/include/vtkMitkOpenGLVolumeTextureMapper3D.h b/Modules/MapperExt/include/vtkMitkOpenGLVolumeTextureMapper3D.h deleted file mode 100644 index e06844a66f..0000000000 --- a/Modules/MapperExt/include/vtkMitkOpenGLVolumeTextureMapper3D.h +++ /dev/null @@ -1,148 +0,0 @@ -/*=================================================================== - -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. - -===================================================================*/ - -// .NAME vtkMitkOpenGLVolumeTextureMapper3D - concrete implementation of 3D volume texture mapping - -// .SECTION Description -// vtkMitkOpenGLVolumeTextureMapper3D renders a volume using 3D texture mapping. -// See vtkMitkVolumeTextureMapper3D for full description. - -// .SECTION see also -// vtkMitkVolumeTextureMapper3D vtkVolumeMapper - -#ifndef __vtkMitkOpenGLVolumeTextureMapper3D_h -#define __vtkMitkOpenGLVolumeTextureMapper3D_h - -#include "MitkMapperExtExports.h" -#include "mitkBaseRenderer.h" -#include "vtkMitkVolumeTextureMapper3D.h" - -#ifndef VTK_IMPLEMENT_MESA_CXX -#include "vtkOpenGL.h" // GLfloat type is used in some method signatures. -#endif - -class vtkRenderWindow; -class vtkVolumeProperty; - -#include "mitkCommon.h" - -class MITKMAPPEREXT_EXPORT vtkMitkOpenGLVolumeTextureMapper3D : public vtkMitkVolumeTextureMapper3D -{ -public: - vtkTypeMacro(vtkMitkOpenGLVolumeTextureMapper3D, vtkMitkVolumeTextureMapper3D); - void PrintSelf(ostream &os, vtkIndent indent) override; - - static vtkMitkOpenGLVolumeTextureMapper3D *New(); - - // Description: - // Is hardware rendering supported? No if the input data is - // more than one independent component, or if the hardware does - // not support the required extensions - // int IsRenderSupported(vtkVolumeProperty *); - int IsRenderSupported(vtkRenderer *ren, vtkVolumeProperty *) override; - - // BTX - - // Description: - // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE - // DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS - // Render the volume - virtual void Render(vtkRenderer *ren, vtkVolume *vol) override; - - // ETX - - // Desciption: - // Initialize when we go to render, or go to answer the - // IsRenderSupported question. Don't call unless we have - // a valid OpenGL context! - vtkGetMacro(Initialized, int); - - // Description: - // Release any graphics resources that are being consumed by this texture. - // The parameter window could be used to determine which graphic - // resources to release. - // deprecatedSince{2013_12} Use ReleaseGraphicsResources(mitk::BaseRenderer* renderer) instead - DEPRECATED(void ReleaseGraphicsResources(vtkWindow *) override); - - // Description: - // Release any graphics resources that are being consumed by this texture. - // The parameter renderer could be used to determine which graphic - // resources to release. - void ReleaseGraphicsResources(mitk::BaseRenderer *renderer); - -protected: - vtkMitkOpenGLVolumeTextureMapper3D(); - ~vtkMitkOpenGLVolumeTextureMapper3D(); - - bool RenderPossible; - - // BTX - - void GetLightInformation(vtkRenderer *ren, - vtkVolume *vol, - GLfloat lightDirection[2][4], - GLfloat lightDiffuseColor[2][4], - GLfloat lightSpecularColor[2][4], - GLfloat halfwayVector[2][4], - GLfloat *ambient); - // ETX - - int Initialized; - GLuint Volume1Index; - GLuint Volume2Index; - GLuint Volume3Index; - GLuint ColorLookupIndex; - GLuint AlphaLookupIndex; - - GLuint prgOneComponentShade; - GLuint prgRGBAShade; - - vtkRenderWindow *RenderWindow; - - bool SupportsCompressedTexture; - - // void Initialize(); - void Initialize(vtkRenderer *r); - - virtual void RenderFP(vtkRenderer *ren, vtkVolume *vol); - - void SetupOneIndependentTextures(vtkRenderer *ren, vtkVolume *vol); - void RenderOneIndependentShadeFP(vtkRenderer *ren, vtkVolume *vol); - - void SetupRGBATextures(vtkRenderer *ren, vtkVolume *vol); - void RenderRGBAShadeFP(vtkRenderer *ren, vtkVolume *vol); - - void DeleteTextureIndex(GLuint *index); - void CreateTextureIndex(GLuint *index); - - void RenderPolygons(vtkRenderer *ren, vtkVolume *vol, int stages[4]); - - void SetupProgramLocalsForShadingFP(vtkRenderer *ren, vtkVolume *vol); - - void Setup3DTextureParameters(bool linear); - - void ComputeVolumeDimensions(); - - bool UpdateVolumes(vtkVolume *); - - bool UpdateVolumesRGBA(vtkVolume *); - -private: - vtkMitkOpenGLVolumeTextureMapper3D(const vtkMitkOpenGLVolumeTextureMapper3D &); // Not implemented. - void operator=(const vtkMitkOpenGLVolumeTextureMapper3D &); // Not implemented. -}; - -#endif diff --git a/Modules/MapperExt/include/vtkMitkVolumeTextureMapper3D.h b/Modules/MapperExt/include/vtkMitkVolumeTextureMapper3D.h deleted file mode 100644 index 7fe2ded61a..0000000000 --- a/Modules/MapperExt/include/vtkMitkVolumeTextureMapper3D.h +++ /dev/null @@ -1,223 +0,0 @@ -/*=================================================================== - -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. - -===================================================================*/ - -// .NAME vtkMitkVolumeTextureMapper3D - volume render with 3D texture mapping - -// .SECTION Description -// vtkMitkVolumeTextureMapper3D renders a volume using 3D texture mapping. -// This class is actually an abstract superclass - with all the actual -// work done by vtkMitkOpenGLVolumeTextureMapper3D. -// -// This mappers currently supports: -// -// - any data type as input -// - one component, or two or four non-independent components -// - composite blending -// - intermixed opaque geometry -// - multiple volumes can be rendered if they can -// be sorted into back-to-front order (use the vtkFrustumCoverageCuller) -// -// This mapper does not support: -// - more than one independent component -// - maximum intensity projection -// -// Internally, this mapper will potentially change the resolution of the -// input data. The data will be resampled to be a power of two in each -// direction, and also no greater than 128*256*256 voxels (any aspect) -// for one or two component data, or 128*128*256 voxels (any aspect) -// for four component data. The limits are currently hardcoded after -// a check using the GL_PROXY_TEXTURE3D because some graphics drivers -// were always responding "yes" to the proxy call despite not being -// able to allocate that much texture memory. -// -// Currently, calculations are computed using 8 bits per RGBA channel. -// In the future this should be expanded to handle newer boards that -// can support 15 bit float compositing. -// -// This mapper supports two main families of graphics hardware: -// nvidia and ATI. There are two different implementations of -// 3D texture mapping used - one based on nvidia's GL_NV_texture_shader2 -// and GL_NV_register_combiners2 extension, and one based on -// ATI's GL_ATI_fragment_shader (supported also by some nvidia boards) -// To use this class in an application that will run on various -// hardware configurations, you should have a back-up volume rendering -// method. You should create a vtkMitkVolumeTextureMapper3D, assign its -// input, make sure you have a current OpenGL context (you've rendered -// at least once), then call IsRenderSupported with a vtkVolumeProperty -// as an argument. This method will return 0 if the input has more than -// one independent component, or if the graphics hardware does not -// support the set of required extensions for using at least one of -// the two implemented methods (nvidia or ati) -// -// .SECTION Thanks -// Thanks to Alexandre Gouaillard at the Megason Lab, Department of Systems -// Biology, Harvard Medical School -// https://wiki.med.harvard.edu/SysBio/Megason/ -// for the idea and initial patch to speed-up rendering with compressed -// textures. -// -// .SECTION see also -// vtkVolumeMapper - -#ifndef __vtkMitkVolumeTextureMapper3D_h -#define __vtkMitkVolumeTextureMapper3D_h - -#include "MitkMapperExtExports.h" -#include "vtkVolumeMapper.h" - -class vtkImageData; -class vtkColorTransferFunction; -class vtkPiecewiseFunction; -class vtkVolumeProperty; - -#include "mitkCommon.h" - -class MITKMAPPEREXT_EXPORT vtkMitkVolumeTextureMapper3D : public vtkVolumeMapper -{ -public: - vtkTypeMacro(vtkMitkVolumeTextureMapper3D, vtkVolumeMapper); - void PrintSelf(ostream &os, vtkIndent indent) override; - - // static vtkMitkVolumeTextureMapper3D *New(); //VTK6_TODO - - // Description: - // The distance at which to space sampling planes. This - // may not be honored for interactive renders. An interactive - // render is defined as one that has less than 1 second of - // allocated render time. - vtkSetMacro(SampleDistance, float); - vtkGetMacro(SampleDistance, float); - - // Description: - // These are the dimensions of the 3D texture - vtkGetVectorMacro(VolumeDimensions, int, 3); - - // Description: - // This is the spacing of the 3D texture - vtkGetVectorMacro(VolumeSpacing, float, 3); - - // Description: - // Based on hardware and properties, we may or may not be able to - // render using 3D texture mapping. This indicates if 3D texture - // mapping is supported by the hardware, and if the other extensions - // necessary to support the specific properties are available. - virtual int IsRenderSupported(vtkRenderer *, vtkVolumeProperty *) = 0; - - // Description: - // Allow access to the number of polygons used for the - // rendering. - vtkGetMacro(NumberOfPolygons, int); - - // Description: - // Allow access to the actual sample distance used to render - // the image. - vtkGetMacro(ActualSampleDistance, float); - - // BTX - - // Description: - // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE - // DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS - // Render the volume - virtual void Render(vtkRenderer *, vtkVolume *) override{}; - - // Description: - // Set/Get if the mapper use compressed textures (if supported by the - // hardware). Initial value is false. - // There are two reasons to use compressed textures: 1. rendering can be 4 - // times faster. 2. It saves some VRAM. - // There is one reason to not use compressed textures: quality may be lower - // than with uncompressed textures. - vtkSetMacro(UseCompressedTexture, bool); - vtkGetMacro(UseCompressedTexture, bool); - - void UpdateMTime(); - -protected: - vtkMitkVolumeTextureMapper3D(); - ~vtkMitkVolumeTextureMapper3D(); - - float *PolygonBuffer; - float *IntersectionBuffer; - int NumberOfPolygons; - int BufferSize; - - /* - unsigned char *Volume1; - unsigned char *Volume2; - unsigned char *Volume3; - */ - /* - int VolumeSize; - int VolumeComponents; - */ - - int VolumeDimensions[3]; - float VolumeSpacing[3]; - - float SampleDistance; - float ActualSampleDistance; - - vtkImageData *SavedTextureInput; - vtkImageData *SavedParametersInput; - - vtkColorTransferFunction *SavedRGBFunction; - vtkPiecewiseFunction *SavedGrayFunction; - vtkPiecewiseFunction *SavedScalarOpacityFunction; - vtkPiecewiseFunction *SavedGradientOpacityFunction; - int SavedColorChannels; - float SavedSampleDistance; - float SavedScalarOpacityDistance; - - unsigned char ColorLookup[65536 * 4]; - unsigned char AlphaLookup[65536]; - float TempArray1[3 * 4096]; - float TempArray2[4096]; - int ColorTableSize; - float ColorTableScale; - float ColorTableOffset; - - unsigned char DiffuseLookup[65536 * 4]; - unsigned char SpecularLookup[65536 * 4]; - - vtkTimeStamp SavedTextureMTime; - vtkTimeStamp SavedParametersMTime; - - bool UseCompressedTexture; - - bool SupportsNonPowerOfTwoTextures; - - // Description: - // For the given viewing direction, compute the set of polygons. - void ComputePolygons(vtkRenderer *ren, vtkVolume *vol, double bounds[6]); - - // Description: - // Update the internal RGBA representation of the volume. Return 1 if - // anything change, 0 if nothing changed. - int UpdateColorLookup(vtkVolume *); - - // Description: - // Impemented in subclass - check is texture size is OK. - // BTX - virtual int IsTextureSizeSupported(int vtkNotUsed(size)[3], int vtkNotUsed(components)) { return 0; } - // ETX - -private: - vtkMitkVolumeTextureMapper3D(const vtkMitkVolumeTextureMapper3D &); // Not implemented. - void operator=(const vtkMitkVolumeTextureMapper3D &); // Not implemented. -}; - -#endif diff --git a/Modules/MapperExt/src/mitkGPUVolumeMapper3D.cpp b/Modules/MapperExt/src/mitkGPUVolumeMapper3D.cpp index bc7b96bcbd..c31aa6c71f 100644 --- a/Modules/MapperExt/src/mitkGPUVolumeMapper3D.cpp +++ b/Modules/MapperExt/src/mitkGPUVolumeMapper3D.cpp @@ -1,708 +1,597 @@ /*=================================================================== 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 GPU_INFO MITK_INFO("mapper.vr") #define GPU_WARN MITK_WARN("mapper.vr") #define GPU_ERROR MITK_ERROR("mapper.vr") -#include -VTK_MODULE_INIT(vtkRenderingVolumeOpenGL); - #include "mitkGPUVolumeMapper3D.h" #include "mitkDataNode.h" #include "mitkColorProperty.h" #include "mitkColorProperty.h" #include "mitkLevelWindow.h" #include "mitkLevelWindowProperty.h" #include "mitkLookupTableProperty.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "mitkTransferFunctionInitializer.h" #include "mitkTransferFunctionProperty.h" #include "mitkVtkPropRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - #include "vtkMitkGPUVolumeRayCastMapper.h" -#endif - -#include "vtkMitkOpenGLVolumeTextureMapper3D.h" #include "vtkOpenGLGPUVolumeRayCastMapper.h" const mitk::Image *mitk::GPUVolumeMapper3D::GetInput() { return static_cast(GetDataNode()->GetData()); } void mitk::GPUVolumeMapper3D::MitkRenderVolumetricGeometry(mitk::BaseRenderer *renderer) { - LocalStorage *ls = m_LSH.GetLocalStorage(renderer); - VtkMapper::MitkRenderVolumetricGeometry(renderer); - if (ls->m_gpuInitialized) - ls->m_MapperGPU->UpdateMTime(); + // if(ls->m_gpuInitialized) + // ls->m_MapperGPU->UpdateMTime(); } -bool mitk::GPUVolumeMapper3D::InitGPU(mitk::BaseRenderer *renderer) +bool mitk::GPUVolumeMapper3D::InitGPU(mitk::BaseRenderer * /*renderer*/) { - LocalStorage *ls = m_LSH.GetLocalStorage(renderer); - - if (ls->m_gpuInitialized) - return ls->m_gpuSupported; - - ls->m_VtkRenderWindow = renderer->GetVtkRenderer()->GetRenderWindow(); - - GPU_INFO << "initializing gpu-slicing-vr (vtkMitkOpenGLVolumeTextureMapper3D)"; - - ls->m_MapperGPU = vtkSmartPointer::New(); - ls->m_MapperGPU->SetUseCompressedTexture(false); - ls->m_MapperGPU->SetSampleDistance(1.0); - - ls->m_VolumePropertyGPU = vtkSmartPointer::New(); - ls->m_VolumePropertyGPU->ShadeOn(); - ls->m_VolumePropertyGPU->SetAmbient(0.25f); // 0.05f - ls->m_VolumePropertyGPU->SetDiffuse(0.50f); // 0.45f - ls->m_VolumePropertyGPU->SetSpecular(0.40f); // 0.50f - ls->m_VolumePropertyGPU->SetSpecularPower(16.0f); - ls->m_VolumePropertyGPU->SetInterpolationTypeToLinear(); - - ls->m_VolumeGPU = vtkSmartPointer::New(); - ls->m_VolumeGPU->SetMapper(ls->m_MapperGPU); - ls->m_VolumeGPU->SetProperty(ls->m_VolumePropertyGPU); - ls->m_VolumeGPU->VisibilityOn(); - - ls->m_MapperGPU->SetInputConnection(this->m_UnitSpacingImageFilter->GetOutputPort()); - - ls->m_gpuSupported = ls->m_MapperGPU->IsRenderSupported(renderer->GetVtkRenderer(), ls->m_VolumePropertyGPU); - - ls->m_gpuInitialized = true; - - return ls->m_gpuSupported; + return false; // TODO 18922 } void mitk::GPUVolumeMapper3D::InitCPU(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if (ls->m_cpuInitialized) return; ls->m_VtkRenderWindow = renderer->GetVtkRenderer()->GetRenderWindow(); ls->m_MapperCPU = vtkSmartPointer::New(); int numThreads = ls->m_MapperCPU->GetNumberOfThreads(); GPU_INFO << "initializing cpu-raycast-vr (vtkFixedPointVolumeRayCastMapper) (" << numThreads << " threads)"; ls->m_MapperCPU->SetSampleDistance(1.0); // ls->m_MapperCPU->LockSampleDistanceToInputSpacingOn(); ls->m_MapperCPU->SetImageSampleDistance(1.0); ls->m_MapperCPU->IntermixIntersectingGeometryOn(); ls->m_MapperCPU->SetAutoAdjustSampleDistances(0); ls->m_VolumePropertyCPU = vtkSmartPointer::New(); ls->m_VolumePropertyCPU->ShadeOn(); ls->m_VolumePropertyCPU->SetAmbient(0.10f); // 0.05f ls->m_VolumePropertyCPU->SetDiffuse(0.50f); // 0.45f ls->m_VolumePropertyCPU->SetSpecular(0.40f); // 0.50f ls->m_VolumePropertyCPU->SetSpecularPower(16.0f); ls->m_VolumePropertyCPU->SetInterpolationTypeToLinear(); ls->m_VolumeCPU = vtkSmartPointer::New(); ls->m_VolumeCPU->SetMapper(ls->m_MapperCPU); ls->m_VolumeCPU->SetProperty(ls->m_VolumePropertyCPU); ls->m_VolumeCPU->VisibilityOn(); ls->m_MapperCPU->SetInputConnection(m_UnitSpacingImageFilter->GetOutputPort()); // m_Resampler->GetOutput()); ls->m_cpuInitialized = true; } -void mitk::GPUVolumeMapper3D::DeinitGPU(mitk::BaseRenderer *renderer) { - LocalStorage *ls = m_LSH.GetLocalStorage(renderer); - - if (ls->m_gpuInitialized) - { - GPU_INFO << "deinitializing gpu-slicing-vr"; - // deinit renderwindow, this is needed to release the memory allocated on the gpu - // to prevent leaking memory on the gpu - ls->m_MapperGPU->ReleaseGraphicsResources(renderer->GetVtkRenderer()->GetVTKWindow()); - ls->m_VolumePropertyGPU = NULL; - ls->m_MapperGPU = NULL; - ls->m_VolumeGPU = NULL; - ls->m_gpuInitialized = false; - } } void mitk::GPUVolumeMapper3D::DeinitCPU(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if (!ls->m_cpuInitialized) return; GPU_INFO << "deinitializing cpu-raycast-vr"; ls->m_VolumePropertyCPU = NULL; ls->m_MapperCPU = NULL; ls->m_VolumeCPU = NULL; ls->m_cpuInitialized = false; } mitk::GPUVolumeMapper3D::GPUVolumeMapper3D() { m_VolumeNULL = 0; m_commonInitialized = false; } mitk::GPUVolumeMapper3D::~GPUVolumeMapper3D() { DeinitCommon(); } void mitk::GPUVolumeMapper3D::InitCommon() { if (m_commonInitialized) return; m_UnitSpacingImageFilter = vtkSmartPointer::New(); m_UnitSpacingImageFilter->SetOutputSpacing(1.0, 1.0, 1.0); CreateDefaultTransferFunctions(); m_commonInitialized = true; } void mitk::GPUVolumeMapper3D::DeinitCommon() { if (!m_commonInitialized) return; m_commonInitialized = false; } bool mitk::GPUVolumeMapper3D::IsRenderable(mitk::BaseRenderer *renderer) { if (!GetDataNode()) return false; DataNode *node = GetDataNode(); bool visible = true; node->GetVisibility(visible, renderer, "visible"); if (!visible) return false; bool value = false; if (!node->GetBoolProperty("volumerendering", value, renderer)) return false; if (!value) return false; mitk::Image *input = const_cast(this->GetInput()); if (!input || !input->IsInitialized()) return false; vtkImageData *inputData = input->GetVtkImageData(this->GetTimestep()); if (inputData == NULL) return false; return true; } void mitk::GPUVolumeMapper3D::InitVtkMapper(mitk::BaseRenderer *renderer) { -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) if (IsRAYEnabled(renderer)) { DeinitCPU(renderer); DeinitGPU(renderer); if (!InitRAY(renderer)) { GPU_WARN << "hardware renderer can't initialize ... falling back to software renderer"; goto fallback; } } - else -#endif - if (IsGPUEnabled(renderer)) + else if (IsGPUEnabled(renderer)) { DeinitCPU(renderer); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) DeinitRAY(renderer); -#endif if (!InitGPU(renderer)) { GPU_WARN << "hardware renderer can't initialize ... falling back to software renderer"; goto fallback; } } else { fallback: DeinitGPU(renderer); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) DeinitRAY(renderer); -#endif InitCPU(renderer); } } vtkProp *mitk::GPUVolumeMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { if (!IsRenderable(renderer)) { if (!m_VolumeNULL) { m_VolumeNULL = vtkSmartPointer::New(); m_VolumeNULL->VisibilityOff(); } return m_VolumeNULL; } InitCommon(); InitVtkMapper(renderer); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) if (ls->m_rayInitialized) return ls->m_VolumeRAY; -#endif if (ls->m_gpuInitialized) return ls->m_VolumeGPU; return ls->m_VolumeCPU; } void mitk::GPUVolumeMapper3D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { if (!IsRenderable(renderer)) return; InitCommon(); InitVtkMapper(renderer); mitk::Image *input = const_cast(this->GetInput()); vtkImageData *inputData = input->GetVtkImageData(this->GetTimestep()); m_UnitSpacingImageFilter->SetInputData(inputData); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) if (ls->m_rayInitialized) { GenerateDataRAY(renderer); } else -#endif if (ls->m_gpuInitialized) { GenerateDataGPU(renderer); } else { GenerateDataCPU(renderer); } // UpdateTransferFunctions UpdateTransferFunctions(renderer); } -void mitk::GPUVolumeMapper3D::GenerateDataGPU(mitk::BaseRenderer *renderer) +void mitk::GPUVolumeMapper3D::GenerateDataGPU(mitk::BaseRenderer * /*renderer*/) { - LocalStorage *ls = m_LSH.GetLocalStorage(renderer); - - bool useCompression = false; - GetDataNode()->GetBoolProperty("volumerendering.gpu.usetexturecompression", useCompression, renderer); - ls->m_MapperGPU->SetUseCompressedTexture(useCompression); - - if (IsLODEnabled(renderer) && mitk::RenderingManager::GetInstance()->GetNextLOD(renderer) == 0) - ls->m_MapperGPU->SetSampleDistance(2.0); - else - ls->m_MapperGPU->SetSampleDistance(1.0); - - // Updating shadings - { - float value = 0; - if (GetDataNode()->GetFloatProperty("volumerendering.gpu.ambient", value, renderer)) - ls->m_VolumePropertyGPU->SetAmbient(value); - if (GetDataNode()->GetFloatProperty("volumerendering.gpu.diffuse", value, renderer)) - ls->m_VolumePropertyGPU->SetDiffuse(value); - if (GetDataNode()->GetFloatProperty("volumerendering.gpu.specular", value, renderer)) - ls->m_VolumePropertyGPU->SetSpecular(value); - if (GetDataNode()->GetFloatProperty("volumerendering.gpu.specular.power", value, renderer)) - ls->m_VolumePropertyGPU->SetSpecularPower(value); - } } void mitk::GPUVolumeMapper3D::GenerateDataCPU(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); int nextLod = mitk::RenderingManager::GetInstance()->GetNextLOD(renderer); if (IsLODEnabled(renderer) && nextLod == 0) { ls->m_MapperCPU->SetImageSampleDistance(3.5); ls->m_MapperCPU->SetSampleDistance(1.25); ls->m_VolumePropertyCPU->SetInterpolationTypeToNearest(); } else { ls->m_MapperCPU->SetImageSampleDistance(1.0); ls->m_MapperCPU->SetSampleDistance(1.0); ls->m_VolumePropertyCPU->SetInterpolationTypeToLinear(); } // Check raycasting mode if (IsMIPEnabled(renderer)) ls->m_MapperCPU->SetBlendModeToMaximumIntensity(); else ls->m_MapperCPU->SetBlendModeToComposite(); // Updating shadings { float value = 0; if (GetDataNode()->GetFloatProperty("volumerendering.cpu.ambient", value, renderer)) ls->m_VolumePropertyCPU->SetAmbient(value); if (GetDataNode()->GetFloatProperty("volumerendering.cpu.diffuse", value, renderer)) ls->m_VolumePropertyCPU->SetDiffuse(value); if (GetDataNode()->GetFloatProperty("volumerendering.cpu.specular", value, renderer)) ls->m_VolumePropertyCPU->SetSpecular(value); if (GetDataNode()->GetFloatProperty("volumerendering.cpu.specular.power", value, renderer)) ls->m_VolumePropertyCPU->SetSpecularPower(value); } } void mitk::GPUVolumeMapper3D::CreateDefaultTransferFunctions() { m_DefaultOpacityTransferFunction = vtkSmartPointer::New(); m_DefaultOpacityTransferFunction->AddPoint(0.0, 0.0); m_DefaultOpacityTransferFunction->AddPoint(255.0, 0.8); m_DefaultOpacityTransferFunction->ClampingOn(); m_DefaultGradientTransferFunction = vtkSmartPointer::New(); m_DefaultGradientTransferFunction->AddPoint(0.0, 0.0); m_DefaultGradientTransferFunction->AddPoint(255.0, 0.8); m_DefaultGradientTransferFunction->ClampingOn(); m_DefaultColorTransferFunction = vtkSmartPointer::New(); m_DefaultColorTransferFunction->AddRGBPoint(0.0, 0.0, 0.0, 0.0); m_DefaultColorTransferFunction->AddRGBPoint(127.5, 1, 1, 0.0); m_DefaultColorTransferFunction->AddRGBPoint(255.0, 0.8, 0.2, 0); m_DefaultColorTransferFunction->ClampingOn(); m_BinaryOpacityTransferFunction = vtkSmartPointer::New(); m_BinaryOpacityTransferFunction->AddPoint(0, 0.0); m_BinaryOpacityTransferFunction->AddPoint(1, 1.0); m_BinaryGradientTransferFunction = vtkSmartPointer::New(); m_BinaryGradientTransferFunction->AddPoint(0.0, 1.0); m_BinaryColorTransferFunction = vtkSmartPointer::New(); } void mitk::GPUVolumeMapper3D::UpdateTransferFunctions(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); vtkPiecewiseFunction *opacityTransferFunction = m_DefaultOpacityTransferFunction; vtkPiecewiseFunction *gradientTransferFunction = m_DefaultGradientTransferFunction; vtkColorTransferFunction *colorTransferFunction = m_DefaultColorTransferFunction; bool isBinary = false; GetDataNode()->GetBoolProperty("binary", isBinary, renderer); if (isBinary) { opacityTransferFunction = m_BinaryOpacityTransferFunction; gradientTransferFunction = m_BinaryGradientTransferFunction; colorTransferFunction = m_BinaryColorTransferFunction; colorTransferFunction->RemoveAllPoints(); float rgb[3]; if (!GetDataNode()->GetColor(rgb, renderer)) rgb[0] = rgb[1] = rgb[2] = 1; colorTransferFunction->AddRGBPoint(0, rgb[0], rgb[1], rgb[2]); colorTransferFunction->Modified(); } else { mitk::TransferFunctionProperty *transferFunctionProp = dynamic_cast(this->GetDataNode()->GetProperty("TransferFunction", renderer)); if (transferFunctionProp) { opacityTransferFunction = transferFunctionProp->GetValue()->GetScalarOpacityFunction(); gradientTransferFunction = transferFunctionProp->GetValue()->GetGradientOpacityFunction(); colorTransferFunction = transferFunctionProp->GetValue()->GetColorTransferFunction(); } } if (ls->m_gpuInitialized) { ls->m_VolumePropertyGPU->SetColor(colorTransferFunction); ls->m_VolumePropertyGPU->SetScalarOpacity(opacityTransferFunction); ls->m_VolumePropertyGPU->SetGradientOpacity(gradientTransferFunction); } -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - if (ls->m_rayInitialized) { ls->m_VolumePropertyRAY->SetColor(colorTransferFunction); ls->m_VolumePropertyRAY->SetScalarOpacity(opacityTransferFunction); ls->m_VolumePropertyRAY->SetGradientOpacity(gradientTransferFunction); } -#endif - if (ls->m_cpuInitialized) { ls->m_VolumePropertyCPU->SetColor(colorTransferFunction); ls->m_VolumePropertyCPU->SetScalarOpacity(opacityTransferFunction); ls->m_VolumePropertyCPU->SetGradientOpacity(gradientTransferFunction); } } void mitk::GPUVolumeMapper3D::ApplyProperties(vtkActor * /*actor*/, mitk::BaseRenderer * /*renderer*/) { // GPU_INFO << "ApplyProperties"; } void mitk::GPUVolumeMapper3D::SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite) { // GPU_INFO << "SetDefaultProperties"; node->AddProperty("volumerendering", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.usemip", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.uselod", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.cpu.ambient", mitk::FloatProperty::New(0.10f), renderer, overwrite); node->AddProperty("volumerendering.cpu.diffuse", mitk::FloatProperty::New(0.50f), renderer, overwrite); node->AddProperty("volumerendering.cpu.specular", mitk::FloatProperty::New(0.40f), renderer, overwrite); node->AddProperty("volumerendering.cpu.specular.power", mitk::FloatProperty::New(16.0f), renderer, overwrite); bool usegpu = true; #ifdef __APPLE__ usegpu = false; node->AddProperty("volumerendering.uselod", mitk::BoolProperty::New(true), renderer, overwrite); #endif node->AddProperty("volumerendering.usegpu", mitk::BoolProperty::New(usegpu), renderer, overwrite); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - node->AddProperty("volumerendering.useray", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.ray.ambient", mitk::FloatProperty::New(0.25f), renderer, overwrite); node->AddProperty("volumerendering.ray.diffuse", mitk::FloatProperty::New(0.50f), renderer, overwrite); node->AddProperty("volumerendering.ray.specular", mitk::FloatProperty::New(0.40f), renderer, overwrite); node->AddProperty("volumerendering.ray.specular.power", mitk::FloatProperty::New(16.0f), renderer, overwrite); -#endif node->AddProperty("volumerendering.gpu.ambient", mitk::FloatProperty::New(0.25f), renderer, overwrite); node->AddProperty("volumerendering.gpu.diffuse", mitk::FloatProperty::New(0.50f), renderer, overwrite); node->AddProperty("volumerendering.gpu.specular", mitk::FloatProperty::New(0.40f), renderer, overwrite); node->AddProperty("volumerendering.gpu.specular.power", mitk::FloatProperty::New(16.0f), renderer, overwrite); node->AddProperty("volumerendering.gpu.usetexturecompression", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.gpu.reducesliceartifacts", mitk::BoolProperty::New(false), renderer, overwrite); node->AddProperty("binary", mitk::BoolProperty::New(false), renderer, overwrite); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if (image.IsNotNull() && image->IsInitialized()) { if ((overwrite) || (node->GetProperty("levelwindow", renderer) == NULL)) { mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelwindow; levelwindow.SetAuto(image); levWinProp->SetLevelWindow(levelwindow); node->SetProperty("levelwindow", levWinProp, renderer); } if ((overwrite) || (node->GetProperty("TransferFunction", renderer) == NULL)) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(tf); tfInit->SetTransferFunctionMode(0); node->SetProperty("TransferFunction", mitk::TransferFunctionProperty::New(tf.GetPointer())); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } bool mitk::GPUVolumeMapper3D::IsLODEnabled(mitk::BaseRenderer *renderer) const { bool value = false; return GetDataNode()->GetBoolProperty("volumerendering.uselod", value, renderer) && value; } bool mitk::GPUVolumeMapper3D::IsMIPEnabled(mitk::BaseRenderer *renderer) { bool value = false; return GetDataNode()->GetBoolProperty("volumerendering.usemip", value, renderer) && value; } bool mitk::GPUVolumeMapper3D::IsGPUEnabled(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool value = false; return ls->m_gpuSupported && GetDataNode()->GetBoolProperty("volumerendering.usegpu", value, renderer) && value; } -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - bool mitk::GPUVolumeMapper3D::InitRAY(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if (ls->m_rayInitialized) return ls->m_raySupported; ls->m_VtkRenderWindow = renderer->GetVtkRenderer()->GetRenderWindow(); GPU_INFO << "initializing gpu-raycast-vr (vtkOpenGLGPUVolumeRayCastMapper)"; ls->m_MapperRAY = vtkSmartPointer::New(); ls->m_MapperRAY->SetAutoAdjustSampleDistances(0); ls->m_MapperRAY->SetSampleDistance(1.0); ls->m_VolumePropertyRAY = vtkSmartPointer::New(); ls->m_VolumePropertyRAY->ShadeOn(); ls->m_VolumePropertyRAY->SetAmbient(0.25f); // 0.05f ls->m_VolumePropertyRAY->SetDiffuse(0.50f); // 0.45f ls->m_VolumePropertyRAY->SetSpecular(0.40f); // 0.50f ls->m_VolumePropertyRAY->SetSpecularPower(16.0f); ls->m_VolumePropertyRAY->SetInterpolationTypeToLinear(); ls->m_VolumeRAY = vtkSmartPointer::New(); ls->m_VolumeRAY->SetMapper(ls->m_MapperRAY); ls->m_VolumeRAY->SetProperty(ls->m_VolumePropertyRAY); ls->m_VolumeRAY->VisibilityOn(); ls->m_MapperRAY->SetInputConnection(this->m_UnitSpacingImageFilter->GetOutputPort()); ls->m_raySupported = ls->m_MapperRAY->IsRenderSupported(renderer->GetRenderWindow(), ls->m_VolumePropertyRAY); ls->m_rayInitialized = true; return ls->m_raySupported; } void mitk::GPUVolumeMapper3D::DeinitRAY(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if (ls->m_rayInitialized) { GPU_INFO << "deinitializing gpu-raycast-vr"; ls->m_MapperRAY = NULL; ls->m_VolumePropertyRAY = NULL; // Here ReleaseGraphicsResources has to be called to avoid VTK error messages. // This seems like a VTK bug, because ReleaseGraphicsResources() is ment for internal use, // but you cannot just delete the object (last smartpointer reference) without getting the // VTK error. ls->m_VolumeRAY->ReleaseGraphicsResources(renderer->GetVtkRenderer()->GetRenderWindow()); ls->m_VolumeRAY = NULL; ls->m_rayInitialized = false; } } void mitk::GPUVolumeMapper3D::GenerateDataRAY(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if (IsLODEnabled(renderer) && mitk::RenderingManager::GetInstance()->GetNextLOD(renderer) == 0) ls->m_MapperRAY->SetImageSampleDistance(4.0); else ls->m_MapperRAY->SetImageSampleDistance(1.0); // Check raycasting mode if (IsMIPEnabled(renderer)) ls->m_MapperRAY->SetBlendModeToMaximumIntensity(); else ls->m_MapperRAY->SetBlendModeToComposite(); // Updating shadings { float value = 0; if (GetDataNode()->GetFloatProperty("volumerendering.ray.ambient", value, renderer)) ls->m_VolumePropertyRAY->SetAmbient(value); if (GetDataNode()->GetFloatProperty("volumerendering.ray.diffuse", value, renderer)) ls->m_VolumePropertyRAY->SetDiffuse(value); if (GetDataNode()->GetFloatProperty("volumerendering.ray.specular", value, renderer)) ls->m_VolumePropertyRAY->SetSpecular(value); if (GetDataNode()->GetFloatProperty("volumerendering.ray.specular.power", value, renderer)) ls->m_VolumePropertyRAY->SetSpecularPower(value); } } bool mitk::GPUVolumeMapper3D::IsRAYEnabled(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool value = false; return ls->m_raySupported && GetDataNode()->GetBoolProperty("volumerendering.useray", value, renderer) && value; } - -#endif diff --git a/Modules/MapperExt/src/vtkMitkGPUVolumeRayCastMapper.cpp b/Modules/MapperExt/src/vtkMitkGPUVolumeRayCastMapper.cpp index c2b916e3ee..d0f2ab40aa 100644 --- a/Modules/MapperExt/src/vtkMitkGPUVolumeRayCastMapper.cpp +++ b/Modules/MapperExt/src/vtkMitkGPUVolumeRayCastMapper.cpp @@ -1,629 +1,626 @@ /*=================================================================== 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. ===================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkMitkGPUVolumeRayCastMapper.h" - -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6))) - #include "vtkCamera.h" #include "vtkCellData.h" #include "vtkCommand.h" // for VolumeMapperRender{Start|End|Progress}Event #include "vtkDataArray.h" #include "vtkGPUInfo.h" #include "vtkGPUInfoList.h" #include "vtkImageData.h" #include "vtkImageResample.h" #include "vtkMultiThreader.h" #include "vtkPointData.h" #include "vtkRenderWindow.h" #include "vtkRenderer.h" #include "vtkRendererCollection.h" #include "vtkTimerLog.h" #include "vtkVolume.h" #include "vtkVolumeProperty.h" #include vtkInstantiatorNewMacro(vtkMitkGPUVolumeRayCastMapper); vtkCxxSetObjectMacro(vtkMitkGPUVolumeRayCastMapper, MaskInput, vtkImageData); vtkCxxSetObjectMacro(vtkMitkGPUVolumeRayCastMapper, TransformedInput, vtkImageData); vtkMitkGPUVolumeRayCastMapper::vtkMitkGPUVolumeRayCastMapper() { this->AutoAdjustSampleDistances = 1; this->ImageSampleDistance = 1.0; this->MinimumImageSampleDistance = 1.0; this->MaximumImageSampleDistance = 10.0; this->SampleDistance = 1.0; this->SmallVolumeRender = 0; this->BigTimeToDraw = 0.0; this->SmallTimeToDraw = 0.0; this->FinalColorWindow = 1.0; this->FinalColorLevel = 0.5; this->GeneratingCanonicalView = 0; this->CanonicalViewImageData = nullptr; this->MaskInput = nullptr; this->MaskBlendFactor = 1.0f; this->AMRMode = 0; this->ClippedCroppingRegionPlanes[0] = VTK_DOUBLE_MAX; this->ClippedCroppingRegionPlanes[1] = VTK_DOUBLE_MIN; this->ClippedCroppingRegionPlanes[2] = VTK_DOUBLE_MAX; this->ClippedCroppingRegionPlanes[3] = VTK_DOUBLE_MIN; this->ClippedCroppingRegionPlanes[4] = VTK_DOUBLE_MAX; this->ClippedCroppingRegionPlanes[5] = VTK_DOUBLE_MIN; this->MaxMemoryInBytes = 0; vtkGPUInfoList *l = vtkGPUInfoList::New(); l->Probe(); if (l->GetNumberOfGPUs() > 0) { vtkGPUInfo *info = l->GetGPUInfo(0); this->MaxMemoryInBytes = info->GetDedicatedVideoMemory(); if (this->MaxMemoryInBytes == 0) { this->MaxMemoryInBytes = info->GetDedicatedSystemMemory(); } // we ignore info->GetSharedSystemMemory(); as this is very slow. } l->Delete(); if (this->MaxMemoryInBytes == 0) // use some default value: 128MB. { this->MaxMemoryInBytes = 128 * 1024 * 1024; } this->MaxMemoryFraction = 0.75; this->ReportProgress = true; this->TransformedInput = nullptr; this->LastInput = nullptr; } // ---------------------------------------------------------------------------- vtkMitkGPUVolumeRayCastMapper::~vtkMitkGPUVolumeRayCastMapper() { this->SetMaskInput(nullptr); this->SetTransformedInput(nullptr); this->LastInput = nullptr; } // ---------------------------------------------------------------------------- // The render method that is called from the volume. If this is a canonical // view render, a specialized version of this method will be called instead. // Otherwise we will // - Invoke a start event // - Start timing // - Check that everything is OK for rendering // - Render // - Stop the timer and record results // - Invoke an end event // ---------------------------------------------------------------------------- void vtkMitkGPUVolumeRayCastMapper::Render(vtkRenderer *ren, vtkVolume *vol) { // Catch renders that are happening due to a canonical view render and // handle them separately. if (this->GeneratingCanonicalView) { this->CanonicalViewRender(ren, vol); return; } // Invoke a VolumeMapperRenderStartEvent this->InvokeEvent(vtkCommand::VolumeMapperRenderStartEvent, nullptr); // Start the timer to time the length of this render vtkTimerLog *timer = vtkTimerLog::New(); timer->StartTimer(); // Make sure everything about this render is OK. // This is where the input is updated. if (this->ValidateRender(ren, vol)) { // Everything is OK - so go ahead and really do the render this->GPURender(ren, vol); } // Stop the timer timer->StopTimer(); double t = timer->GetElapsedTime(); // cout << "Render Timer " << t << " seconds, " << 1.0/t << " frames per second" << endl; this->TimeToDraw = t; timer->Delete(); if (vol->GetAllocatedRenderTime() < 1.0) { this->SmallTimeToDraw = t; } else { this->BigTimeToDraw = t; } // Invoke a VolumeMapperRenderEndEvent this->InvokeEvent(vtkCommand::VolumeMapperRenderEndEvent, nullptr); } // ---------------------------------------------------------------------------- // Special version for rendering a canonical view - we don't do things like // invoke start or end events, and we don't capture the render time. // ---------------------------------------------------------------------------- void vtkMitkGPUVolumeRayCastMapper::CanonicalViewRender(vtkRenderer *ren, vtkVolume *vol) { // Make sure everything about this render is OK if (this->ValidateRender(ren, vol)) { // Everything is OK - so go ahead and really do the render this->GPURender(ren, vol); } } // ---------------------------------------------------------------------------- // This method us used by the render method to validate everything before // attempting to render. This method returns 0 if something is not right - // such as missing input, a null renderer or a null volume, no scalars, etc. // In some cases it will produce a vtkErrorMacro message, and in others // (for example, in the case of cropping planes that define a region with // a volume or 0 or less) it will fail silently. If everything is OK, it will // return with a value of 1. // ---------------------------------------------------------------------------- int vtkMitkGPUVolumeRayCastMapper::ValidateRender(vtkRenderer *ren, vtkVolume *vol) { // Check that we have everything we need to render. int goodSoFar = 1; // Check for a renderer - we MUST have one if (!ren) { goodSoFar = 0; vtkErrorMacro("Renderer cannot be null."); } // Check for the volume - we MUST have one if (goodSoFar && !vol) { goodSoFar = 0; vtkErrorMacro("Volume cannot be null."); } // Don't need to check if we have a volume property // since the volume will create one if we don't. Also // don't need to check for the scalar opacity function // or the RGB transfer function since the property will // create them if they do not yet exist. // However we must currently check that the number of // color channels is 3 // TODO: lift this restriction - should work with // gray functions as well. Right now turning off test // because otherwise 4 component rendering isn't working. // Will revisit. if (goodSoFar && vol->GetProperty()->GetColorChannels() != 3) { // goodSoFar = 0; // vtkErrorMacro("Must have a color transfer function."); } // Check the cropping planes. If they are invalid, just silently // fail. This will happen when an interactive widget is dragged // such that it defines 0 or negative volume - this can happen // and should just not render the volume. // Check the cropping planes if (goodSoFar && this->Cropping && (this->CroppingRegionPlanes[0] >= this->CroppingRegionPlanes[1] || this->CroppingRegionPlanes[2] >= this->CroppingRegionPlanes[3] || this->CroppingRegionPlanes[4] >= this->CroppingRegionPlanes[5])) { // No error message here - we want to be silent goodSoFar = 0; } // Check that we have input data vtkImageData *input = this->GetInput(); // If we have a timestamp change or data change then create a new clone. if (input != this->LastInput || input->GetMTime() > this->TransformedInput->GetMTime()) { this->LastInput = input; vtkImageData *clone; if (!this->TransformedInput) { clone = vtkImageData::New(); this->SetTransformedInput(clone); clone->Delete(); } else { clone = this->TransformedInput; } clone->ShallowCopy(input); // @TODO: This is the workaround to deal with GPUVolumeRayCastMapper // not able to handle extents starting from non zero values. // There is not a easy fix in the GPU volume ray cast mapper hence // this fix has been introduced. // Get the current extents. int extents[6], real_extents[6]; clone->GetExtent(extents); clone->GetExtent(real_extents); // Get the current origin and spacing. double origin[3], spacing[3]; clone->GetOrigin(origin); clone->GetSpacing(spacing); for (int cc = 0; cc < 3; cc++) { // Transform the origin and the extents. origin[cc] = origin[cc] + extents[2 * cc] * spacing[cc]; extents[2 * cc + 1] -= extents[2 * cc]; extents[2 * cc] -= extents[2 * cc]; } clone->SetOrigin(origin); clone->SetExtent(extents); } if (goodSoFar && !this->TransformedInput) { vtkErrorMacro("Input is NULL but is required"); goodSoFar = 0; } // Update the date then make sure we have scalars. Note // that we must have point or cell scalars because field // scalars are not supported. vtkDataArray *scalars = nullptr; if (goodSoFar) { // Here is where we update the input // this->TransformedInput->UpdateInformation(); //VTK6_TODO // this->TransformedInput->SetUpdateExtentToWholeExtent(); // this->TransformedInput->Update(); // Now make sure we can find scalars scalars = this->GetScalars( this->TransformedInput, this->ScalarMode, this->ArrayAccessMode, this->ArrayId, this->ArrayName, this->CellFlag); // We couldn't find scalars if (!scalars) { vtkErrorMacro("No scalars found on input."); goodSoFar = 0; } // Even if we found scalars, if they are field data scalars that isn't good else if (this->CellFlag == 2) { vtkErrorMacro("Only point or cell scalar support - found field scalars instead."); goodSoFar = 0; } } // Make sure the scalar type is actually supported. This mappers supports // almost all standard scalar types. if (goodSoFar) { switch (scalars->GetDataType()) { case VTK_CHAR: vtkErrorMacro(<< "scalar of type VTK_CHAR is not supported " << "because this type is platform dependent. " << "Use VTK_SIGNED_CHAR or VTK_UNSIGNED_CHAR instead."); goodSoFar = 0; break; case VTK_BIT: vtkErrorMacro("scalar of type VTK_BIT is not supported by this mapper."); goodSoFar = 0; break; case VTK_ID_TYPE: vtkErrorMacro("scalar of type VTK_ID_TYPE is not supported by this mapper."); goodSoFar = 0; break; case VTK_STRING: vtkErrorMacro("scalar of type VTK_STRING is not supported by this mapper."); goodSoFar = 0; break; default: // Don't need to do anything here break; } } // Check on the blending type - we support composite and min / max intensity if (goodSoFar) { if (this->BlendMode != vtkVolumeMapper::COMPOSITE_BLEND && this->BlendMode != vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND && this->BlendMode != vtkVolumeMapper::MINIMUM_INTENSITY_BLEND) { goodSoFar = 0; vtkErrorMacro(<< "Selected blend mode not supported. " << "Only Composite and MIP and MinIP modes " << "are supported by the current implementation."); } } // This mapper supports 1 component data, or 4 component if it is not independent // component (i.e. the four components define RGBA) int numberOfComponents = 0; if (goodSoFar) { numberOfComponents = scalars->GetNumberOfComponents(); if (!(numberOfComponents == 1 || (numberOfComponents == 4 && vol->GetProperty()->GetIndependentComponents() == 0))) { goodSoFar = 0; vtkErrorMacro(<< "Only one component scalars, or four " << "component with non-independent components, " << "are supported by this mapper."); } } // If this is four component data, then it better be unsigned char (RGBA). if (goodSoFar && numberOfComponents == 4 && scalars->GetDataType() != VTK_UNSIGNED_CHAR) { goodSoFar = 0; vtkErrorMacro("Only unsigned char is supported for 4-component scalars!"); } // return our status return goodSoFar; } // ---------------------------------------------------------------------------- // Description: // Called by the AMR Volume Mapper. // Set the flag that tells if the scalars are on point data (0) or // cell data (1). void vtkMitkGPUVolumeRayCastMapper::SetCellFlag(int cellFlag) { this->CellFlag = cellFlag; } // ---------------------------------------------------------------------------- void vtkMitkGPUVolumeRayCastMapper::CreateCanonicalView(vtkRenderer *ren, vtkVolume *volume, vtkImageData *image, int vtkNotUsed(blend_mode), double viewDirection[3], double viewUp[3]) { this->GeneratingCanonicalView = 1; int oldSwap = ren->GetRenderWindow()->GetSwapBuffers(); ren->GetRenderWindow()->SwapBuffersOff(); int dim[3]; image->GetDimensions(dim); int *size = ren->GetRenderWindow()->GetSize(); vtkImageData *bigImage = vtkImageData::New(); bigImage->SetDimensions(size[0], size[1], 1); bigImage->AllocateScalars(VTK_UNSIGNED_CHAR, 3); this->CanonicalViewImageData = bigImage; double scale[2]; scale[0] = dim[0] / static_cast(size[0]); scale[1] = dim[1] / static_cast(size[1]); // Save the visibility flags of the renderers and set all to false except // for the ren. vtkRendererCollection *renderers = ren->GetRenderWindow()->GetRenderers(); int numberOfRenderers = renderers->GetNumberOfItems(); auto rendererVisibilities = new bool[numberOfRenderers]; renderers->InitTraversal(); int i = 0; while (i < numberOfRenderers) { vtkRenderer *r = renderers->GetNextItem(); rendererVisibilities[i] = r->GetDraw() == 1; if (r != ren) { r->SetDraw(false); } ++i; } // Save the visibility flags of the props and set all to false except // for the volume. vtkPropCollection *props = ren->GetViewProps(); int numberOfProps = props->GetNumberOfItems(); auto propVisibilities = new bool[numberOfProps]; props->InitTraversal(); i = 0; while (i < numberOfProps) { vtkProp *p = props->GetNextProp(); propVisibilities[i] = p->GetVisibility() == 1; if (p != volume) { p->SetVisibility(false); } ++i; } vtkCamera *savedCamera = ren->GetActiveCamera(); savedCamera->Modified(); vtkCamera *canonicalViewCamera = vtkCamera::New(); // Code from vtkFixedPointVolumeRayCastMapper: double *center = volume->GetCenter(); double bounds[6]; volume->GetBounds(bounds); double d = sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) + (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) + (bounds[5] - bounds[4]) * (bounds[5] - bounds[4])); // For now use x distance - need to change this d = bounds[1] - bounds[0]; // Set up the camera in parallel canonicalViewCamera->SetFocalPoint(center); canonicalViewCamera->ParallelProjectionOn(); canonicalViewCamera->SetPosition( center[0] - d * viewDirection[0], center[1] - d * viewDirection[1], center[2] - d * viewDirection[2]); canonicalViewCamera->SetViewUp(viewUp); canonicalViewCamera->SetParallelScale(d / 2); ren->SetActiveCamera(canonicalViewCamera); ren->GetRenderWindow()->Render(); ren->SetActiveCamera(savedCamera); canonicalViewCamera->Delete(); // Shrink to image to the desired size vtkImageResample *resample = vtkImageResample::New(); resample->SetInputData(bigImage); resample->SetAxisMagnificationFactor(0, scale[0]); resample->SetAxisMagnificationFactor(1, scale[1]); resample->SetAxisMagnificationFactor(2, 1); resample->UpdateWholeExtent(); // Copy the pixels over image->DeepCopy(resample->GetOutput()); bigImage->Delete(); resample->Delete(); // Restore the visibility flags of the props props->InitTraversal(); i = 0; while (i < numberOfProps) { vtkProp *p = props->GetNextProp(); p->SetVisibility(propVisibilities[i]); ++i; } delete[] propVisibilities; // Restore the visibility flags of the renderers renderers->InitTraversal(); i = 0; while (i < numberOfRenderers) { vtkRenderer *r = renderers->GetNextItem(); r->SetDraw(rendererVisibilities[i]); ++i; } delete[] rendererVisibilities; ren->GetRenderWindow()->SetSwapBuffers(oldSwap); this->CanonicalViewImageData = nullptr; this->GeneratingCanonicalView = 0; } // ---------------------------------------------------------------------------- // Print method for vtkMitkGPUVolumeRayCastMapper void vtkMitkGPUVolumeRayCastMapper::PrintSelf(ostream &os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "AutoAdjustSampleDistances: " << this->AutoAdjustSampleDistances << endl; os << indent << "MinimumImageSampleDistance: " << this->MinimumImageSampleDistance << endl; os << indent << "MaximumImageSampleDistance: " << this->MaximumImageSampleDistance << endl; os << indent << "ImageSampleDistance: " << this->ImageSampleDistance << endl; os << indent << "SampleDistance: " << this->SampleDistance << endl; os << indent << "FinalColorWindow: " << this->FinalColorWindow << endl; os << indent << "FinalColorLevel: " << this->FinalColorLevel << endl; os << indent << "MaskInput: " << this->MaskInput << endl; os << indent << "MaskBlendFactor: " << this->MaskBlendFactor << endl; os << indent << "MaxMemoryInBytes: " << this->MaxMemoryInBytes << endl; os << indent << "MaxMemoryFraction: " << this->MaxMemoryFraction << endl; os << indent << "ReportProgress: " << this->ReportProgress << endl; } // ---------------------------------------------------------------------------- // Description: // Compute the cropping planes clipped by the bounds of the volume. // The result is put into this->ClippedCroppingRegionPlanes. // NOTE: IT WILL BE MOVED UP TO vtkVolumeMapper after bullet proof usage // in this mapper. Other subclasses will use the ClippedCroppingRegionsPlanes // members instead of CroppingRegionPlanes. // \pre volume_exists: this->GetInput()!=0 // \pre valid_cropping: this->Cropping && // this->CroppingRegionPlanes[0]CroppingRegionPlanes[1] && // this->CroppingRegionPlanes[2]CroppingRegionPlanes[3] && // this->CroppingRegionPlanes[4]CroppingRegionPlanes[5]) void vtkMitkGPUVolumeRayCastMapper::ClipCroppingRegionPlanes() { assert("pre: volume_exists" && this->GetInput() != nullptr); assert("pre: valid_cropping" && this->Cropping && this->CroppingRegionPlanes[0] < this->CroppingRegionPlanes[1] && this->CroppingRegionPlanes[2] < this->CroppingRegionPlanes[3] && this->CroppingRegionPlanes[4] < this->CroppingRegionPlanes[5]); // vtkVolumeMapper::Render() will have something like: // if(this->Cropping && (this->CroppingRegionPlanes[0]>=this->CroppingRegionPlanes[1] || // this->CroppingRegionPlanes[2]>=this->CroppingRegionPlanes[3] || // this->CroppingRegionPlanes[4]>=this->CroppingRegionPlanes[5])) // { // // silentely stop because the cropping is not valid. // return; // } double volBounds[6]; this->GetInput()->GetBounds(volBounds); int i = 0; while (i < 6) { // max of the mins if (this->CroppingRegionPlanes[i] < volBounds[i]) { this->ClippedCroppingRegionPlanes[i] = volBounds[i]; } else { this->ClippedCroppingRegionPlanes[i] = this->CroppingRegionPlanes[i]; } ++i; // min of the maxs if (this->CroppingRegionPlanes[i] > volBounds[i]) { this->ClippedCroppingRegionPlanes[i] = volBounds[i]; } + else { this->ClippedCroppingRegionPlanes[i] = this->CroppingRegionPlanes[i]; } ++i; } } #endif diff --git a/Modules/MapperExt/src/vtkMitkOpenGLVolumeTextureMapper3D.cpp b/Modules/MapperExt/src/vtkMitkOpenGLVolumeTextureMapper3D.cpp deleted file mode 100644 index a10dda2efd..0000000000 --- a/Modules/MapperExt/src/vtkMitkOpenGLVolumeTextureMapper3D.cpp +++ /dev/null @@ -1,2443 +0,0 @@ -/*=================================================================== - -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. - -===================================================================*/ - -#ifdef _OPENMP -#include -#endif - -#include "vtkWindows.h" -#include "mitkCommon.h" -#include "vtkMitkOpenGLVolumeTextureMapper3D.h" - -#define GPU_INFO MITK_INFO("mapper.vr") -#define GPU_WARN MITK_WARN("mapper.vr") - -#include "vtkCamera.h" -#include "vtkDataArray.h" -#include "vtkImageData.h" -#include "vtkLight.h" -#include "vtkLightCollection.h" -#include "vtkMath.h" -#include "vtkMatrix4x4.h" -#include "vtkObjectFactory.h" -#include "vtkOpenGLExtensionManager.h" -#include "vtkPlane.h" -#include "vtkPlaneCollection.h" -#include "vtkPointData.h" -#include "vtkRenderWindow.h" -#include "vtkRenderer.h" -#include "vtkTimerLog.h" -#include "vtkTransform.h" -#include "vtkVolumeProperty.h" -#include "vtkgl.h" - -#include "vtkOpenGLRenderWindow.h" - -#define myGL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define myGL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - -const char *vtkMitkVolumeTextureMapper3D_FourDependentShadeFP = "!!ARBfp1.0\n" - - //# We need some temporary variables - "TEMP index, normal, finalColor;\n" - "TEMP temp,temp1, temp2, temp3,temp4; \n" - "TEMP sampleColor;\n" - "TEMP ndotl, ndoth, ndotv; \n" - "TEMP lightInfo, lightResult;\n" - - //# We are going to use the first - //# texture coordinate - "ATTRIB tex0 = fragment.texcoord[0];\n" - - //# This is the lighting information - "PARAM lightDirection = program.local[0];\n" - "PARAM halfwayVector = program.local[1];\n" - "PARAM coefficient = program.local[2];\n" - "PARAM lightDiffColor = program.local[3]; \n" - "PARAM lightSpecColor = program.local[4]; \n" - "PARAM viewVector = program.local[5];\n" - "PARAM constants = program.local[6];\n" - - //# This is our output color - "OUTPUT out = result.color;\n" - - //# Look up the gradient direction - //# in the third volume - "TEX temp2, tex0, texture[0], 3D;\n" - - //# This normal is stored 0 to 1, change to -1 to 1 - //# by multiplying by 2.0 then adding -1.0. - "MAD normal, temp2, constants.x, constants.y;\n" - - "DP3 temp4, normal, normal;\n" - "RSQ temp, temp4.x;\n" - "MUL normal, normal, temp;\n" - - //"RCP temp4,temp.x;\n" - - //"MUL temp2.w,temp2.w,temp4.x;\n" - - //"MUL_SAT temp2.w,temp2.w,6.0;\n" - - "TEX sampleColor, tex0, texture[1], 3D;\n" - - //# Take the dot product of the light - //# direction and the normal - "DP3 ndotl, normal, lightDirection;\n" - - //# Take the dot product of the halfway - //# vector and the normal - "DP3 ndoth, normal, halfwayVector;\n" - - "DP3 ndotv, normal, viewVector;\n" - - //# flip if necessary for two sided lighting - "MUL temp3, ndotl, constants.y; \n" - "CMP ndotl, ndotv, ndotl, temp3;\n" - "MUL temp3, ndoth, constants.y; \n" - "CMP ndoth, ndotv, ndoth, temp3;\n" - - //# put the pieces together for a LIT operation - "MOV lightInfo.x, ndotl.x; \n" - "MOV lightInfo.y, ndoth.x; \n" - "MOV lightInfo.w, coefficient.w; \n" - - //# compute the lighting - "LIT lightResult, lightInfo;\n" - - //# COLOR FIX - "MUL lightResult, lightResult, 4.0;\n" - - //# This is the ambient contribution - "MUL finalColor, coefficient.x, sampleColor;\n" - - //# This is the diffuse contribution - "MUL temp3, lightDiffColor, sampleColor;\n" - "MUL temp3, temp3, lightResult.y;\n" - "ADD finalColor, finalColor, temp3;\n" - - //# This is th specular contribution - "MUL temp3, lightSpecColor, lightResult.z; \n" - - //# Add specular into result so far, and replace - //# with the original alpha. - "ADD out, finalColor, temp3;\n" - "MOV out.w, temp2.w;\n" - - "END\n"; - -const char *vtkMitkVolumeTextureMapper3D_OneComponentShadeFP = "!!ARBfp1.0\n" - - //# This is the fragment program for one - //# component data with shading - - //# We need some temporary variables - "TEMP index, normal, finalColor;\n" - "TEMP temp,temp1, temp2, temp3,temp4; \n" - "TEMP sampleColor;\n" - "TEMP ndotl, ndoth, ndotv; \n" - "TEMP lightInfo, lightResult;\n" - - //# We are going to use the first - //# texture coordinate - "ATTRIB tex0 = fragment.texcoord[0];\n" - - //# This is the lighting information - "PARAM lightDirection = program.local[0];\n" - "PARAM halfwayVector = program.local[1];\n" - "PARAM coefficient = program.local[2];\n" - "PARAM lightDiffColor = program.local[3]; \n" - "PARAM lightSpecColor = program.local[4]; \n" - "PARAM viewVector = program.local[5];\n" - "PARAM constants = program.local[6];\n" - - //# This is our output color - "OUTPUT out = result.color;\n" - - //# Look up the gradient direction - //# in the third volume - "TEX temp2, tex0, texture[0], 3D;\n" - - // Gradient Compution - - //# Look up the scalar value / gradient - //# magnitude in the first volume - //"TEX temp1, tex0, texture[0], 3D;\n" - - /* - - "ADD temp3,tex0,{-0.005,0,0};\n" - "TEX temp2,temp3, texture[0], 3D;\n" - - //"ADD temp3,tex0,{ 0.005,0,0};\n" - //"TEX temp1,temp3, texture[0], 3D;\n" - - "SUB normal.x,temp2.y,temp1.y;\n" - - "ADD temp3,tex0,{0,-0.005,0};\n" - "TEX temp2,temp3, texture[0], 3D;\n" - - //"ADD temp3,tex0,{0, 0.005,0};\n" - //"TEX temp1,temp3, texture[0], 3D;\n" - - "SUB normal.y,temp2.y,temp1.y;\n" - - "ADD temp3,tex0,{0,0,-0.005};\n" - "TEX temp2,temp3, texture[0], 3D;\n" - - //"ADD temp3,tex0,{0,0, 0.005};\n" - //"TEX temp1,temp3, texture[0], 3D;\n" - - "SUB normal.z,temp2.y,temp1.y;\n" - - */ - - //"MOV normal,{1,1,1};\n" - - "MOV index.x,temp2.a;\n" - - //# This normal is stored 0 to 1, change to -1 to 1 - //# by multiplying by 2.0 then adding -1.0. - "MAD normal, temp2, constants.x, constants.y;\n" - - //# Swizzle this to use (a,r) as texture - //# coordinates - //"SWZ index, temp1, a, r, 1, 1;\n" - - //# Use this coordinate to look up a - //# final color in the third texture - //# (this is a 2D texture) - - "DP3 temp4, normal, normal;\n" - - "RSQ temp, temp4.x;\n" - - "RCP temp4,temp.x;\n" - - "MUL normal, normal, temp;\n" - - "MOV index.y, temp4.x;\n" - - "TEX sampleColor, index, texture[1], 2D;\n" - - //"MUL sampleColor.w,sampleColor.w,temp4.x;\n" - - //# Take the dot product of the light - //# direction and the normal - "DP3 ndotl, normal, lightDirection;\n" - - //# Take the dot product of the halfway - //# vector and the normal - "DP3 ndoth, normal, halfwayVector;\n" - - "DP3 ndotv, normal, viewVector;\n" - - //# flip if necessary for two sided lighting - "MUL temp3, ndotl, constants.y; \n" - "CMP ndotl, ndotv, ndotl, temp3;\n" - "MUL temp3, ndoth, constants.y; \n" - "CMP ndoth, ndotv, ndoth, temp3;\n" - - //# put the pieces together for a LIT operation - "MOV lightInfo.x, ndotl.x; \n" - "MOV lightInfo.y, ndoth.x; \n" - "MOV lightInfo.w, coefficient.w; \n" - - //# compute the lighting - "LIT lightResult, lightInfo;\n" - - //# COLOR FIX - "MUL lightResult, lightResult, 4.0;\n" - - //# This is the ambient contribution - "MUL finalColor, coefficient.x, sampleColor;\n" - - //# This is the diffuse contribution - "MUL temp3, lightDiffColor, sampleColor;\n" - "MUL temp3, temp3, lightResult.y;\n" - "ADD finalColor, finalColor, temp3;\n" - - //# This is th specular contribution - "MUL temp3, lightSpecColor, lightResult.z; \n" - - //# Add specular into result so far, and replace - //# with the original alpha. - "ADD out, finalColor, temp3;\n" - "MOV out.w, sampleColor.w;\n" - - "END\n"; - -//#ifndef VTK_IMPLEMENT_MESA_CXX -vtkStandardNewMacro(vtkMitkOpenGLVolumeTextureMapper3D); -//#endif - -vtkMitkOpenGLVolumeTextureMapper3D::vtkMitkOpenGLVolumeTextureMapper3D() -{ - // GPU_INFO << "vtkMitkOpenGLVolumeTextureMapper3D"; - - this->Initialized = 0; - this->Volume1Index = 0; - this->Volume2Index = 0; - this->Volume3Index = 0; - this->ColorLookupIndex = 0; - this->AlphaLookupIndex = 0; - this->RenderWindow = NULL; - this->SupportsCompressedTexture = false; - - prgOneComponentShade = 0; - prgRGBAShade = 0; -} - -vtkMitkOpenGLVolumeTextureMapper3D::~vtkMitkOpenGLVolumeTextureMapper3D() -{ - // GPU_INFO << "~vtkMitkOpenGLVolumeTextureMapper3D"; - if (prgOneComponentShade) - vtkgl::DeleteProgramsARB(1, &prgOneComponentShade); - - if (prgRGBAShade) - vtkgl::DeleteProgramsARB(1, &prgRGBAShade); -} - -// Release the graphics resources used by this texture. -void vtkMitkOpenGLVolumeTextureMapper3D::ReleaseGraphicsResources(vtkWindow *renWin) -{ - // GPU_INFO << "ReleaseGraphicsResources"; - - if ((this->Volume1Index || this->Volume2Index || this->Volume3Index || this->ColorLookupIndex) && renWin) - { - static_cast(renWin)->MakeCurrent(); -#ifdef GL_VERSION_1_1 - // free any textures - this->DeleteTextureIndex(&this->Volume1Index); - this->DeleteTextureIndex(&this->Volume2Index); - this->DeleteTextureIndex(&this->Volume3Index); - this->DeleteTextureIndex(&this->ColorLookupIndex); - this->DeleteTextureIndex(&this->AlphaLookupIndex); -#endif - } - this->Volume1Index = 0; - this->Volume2Index = 0; - this->Volume3Index = 0; - this->ColorLookupIndex = 0; - this->RenderWindow = NULL; - this->SupportsCompressedTexture = false; - this->SupportsNonPowerOfTwoTextures = false; - - this->Modified(); -} - -// Release the graphics resources used by this texture. -void vtkMitkOpenGLVolumeTextureMapper3D::ReleaseGraphicsResources(mitk::BaseRenderer *renderer) -{ - // GPU_INFO << "ReleaseGraphicsResources"; - - vtkWindow *renWin = renderer->GetVtkRenderer()->GetRenderWindow(); - - if ((this->Volume1Index || this->Volume2Index || this->Volume3Index || this->ColorLookupIndex) && renWin) - { - static_cast(renWin)->MakeCurrent(); -#ifdef GL_VERSION_1_1 - // free any textures - this->DeleteTextureIndex(&this->Volume1Index); - this->DeleteTextureIndex(&this->Volume2Index); - this->DeleteTextureIndex(&this->Volume3Index); - this->DeleteTextureIndex(&this->ColorLookupIndex); - this->DeleteTextureIndex(&this->AlphaLookupIndex); -#endif - } - this->Volume1Index = 0; - this->Volume2Index = 0; - this->Volume3Index = 0; - this->ColorLookupIndex = 0; - this->RenderWindow = NULL; - this->SupportsCompressedTexture = false; - this->SupportsNonPowerOfTwoTextures = false; - - this->Modified(); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::Render(vtkRenderer *ren, vtkVolume *vol) -{ - // GPU_INFO << "Render"; - - ren->GetRenderWindow()->MakeCurrent(); - - if (!this->Initialized) - { - // this->Initialize(); - this->Initialize(ren); - } - - if (!this->RenderPossible) - { - vtkErrorMacro("required extensions not supported"); - return; - } - - vtkMatrix4x4 *matrix = vtkMatrix4x4::New(); - vtkPlaneCollection *clipPlanes; - vtkPlane *plane; - int numClipPlanes = 0; - double planeEquation[4]; - - // build transformation - vol->GetMatrix(matrix); - matrix->Transpose(); - - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT | - GL_TEXTURE_BIT); - - int i; - - // Use the OpenGL clip planes - clipPlanes = this->ClippingPlanes; - if (clipPlanes) - { - numClipPlanes = clipPlanes->GetNumberOfItems(); - if (numClipPlanes > 6) - { - vtkErrorMacro(<< "OpenGL guarantees only 6 additional clipping planes"); - } - - for (i = 0; i < numClipPlanes; i++) - { - glEnable(static_cast(GL_CLIP_PLANE0 + i)); - - plane = static_cast(clipPlanes->GetItemAsObject(i)); - - planeEquation[0] = plane->GetNormal()[0]; - planeEquation[1] = plane->GetNormal()[1]; - planeEquation[2] = plane->GetNormal()[2]; - planeEquation[3] = -(planeEquation[0] * plane->GetOrigin()[0] + planeEquation[1] * plane->GetOrigin()[1] + - planeEquation[2] * plane->GetOrigin()[2]); - glClipPlane(static_cast(GL_CLIP_PLANE0 + i), planeEquation); - } - } - - // insert model transformation - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glMultMatrixd(matrix->Element[0]); - - glColor4f(1.0, 1.0, 1.0, 1.0); - - // Turn lighting off - the polygon textures already have illumination - glDisable(GL_LIGHTING); - - // vtkGraphicErrorMacro(ren->GetRenderWindow(),"Before actual render method"); - - this->RenderFP(ren, vol); - - // pop transformation matrix - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - matrix->Delete(); - glPopAttrib(); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::RenderFP(vtkRenderer *ren, vtkVolume *vol) -{ - // GPU_INFO << "RenderFP"; - - /* - glAlphaFunc (GL_GREATER, static_cast(1.0/255.0)); - glEnable (GL_ALPHA_TEST); - */ - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - int components = this->GetInput()->GetNumberOfScalarComponents(); - switch (components) - { - case 1: - this->RenderOneIndependentShadeFP(ren, vol); - break; - - case 4: - this->RenderRGBAShadeFP(ren, vol); - break; - } - - vtkgl::ActiveTexture(vtkgl::TEXTURE2); - glDisable(GL_TEXTURE_2D); - glDisable(vtkgl::TEXTURE_3D); - - vtkgl::ActiveTexture(vtkgl::TEXTURE1); - glDisable(GL_TEXTURE_2D); - glDisable(vtkgl::TEXTURE_3D); - - vtkgl::ActiveTexture(vtkgl::TEXTURE0); - glDisable(GL_TEXTURE_2D); - glDisable(vtkgl::TEXTURE_3D); - - glDisable(GL_BLEND); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::DeleteTextureIndex(GLuint *index) -{ - // GPU_INFO << "DeleteTextureIndex"; - - if (glIsTexture(*index)) - { - GLuint tempIndex; - tempIndex = *index; - glDeleteTextures(1, &tempIndex); - *index = 0; - } -} - -void vtkMitkOpenGLVolumeTextureMapper3D::CreateTextureIndex(GLuint *index) -{ - // GPU_INFO << "CreateTextureIndex"; - - GLuint tempIndex = 0; - glGenTextures(1, &tempIndex); - *index = static_cast(tempIndex); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::RenderPolygons(vtkRenderer *ren, vtkVolume *vol, int stages[4]) -{ - // GPU_INFO << "RenderPolygons"; - - vtkRenderWindow *renWin = ren->GetRenderWindow(); - - if (renWin->CheckAbortStatus()) - { - return; - } - - double bounds[27][6]; - float distance2[27]; - - int numIterations; - int i, j, k; - - // No cropping case - render the whole thing - if (!this->Cropping) - { - // Use the input data bounds - we'll take care of the volume's - // matrix during rendering - this->GetInput()->GetBounds(bounds[0]); - numIterations = 1; - } - // Simple cropping case - render the subvolume - else if (this->CroppingRegionFlags == 0x2000) - { - this->GetCroppingRegionPlanes(bounds[0]); - numIterations = 1; - } - // Complex cropping case - render each region in back-to-front order - else - { - // Get the camera position - double camPos[4]; - ren->GetActiveCamera()->GetPosition(camPos); - - double volBounds[6]; - this->GetInput()->GetBounds(volBounds); - - // Pass camera through inverse volume matrix - // so that we are in the same coordinate system - vtkMatrix4x4 *volMatrix = vtkMatrix4x4::New(); - vol->GetMatrix(volMatrix); - camPos[3] = 1.0; - volMatrix->Invert(); - volMatrix->MultiplyPoint(camPos, camPos); - volMatrix->Delete(); - if (camPos[3]) - { - camPos[0] /= camPos[3]; - camPos[1] /= camPos[3]; - camPos[2] /= camPos[3]; - } - - // These are the region limits for x (first four), y (next four) and - // z (last four). The first region limit is the lower bound for - // that axis, the next two are the region planes along that axis, and - // the final one in the upper bound for that axis. - float limit[12]; - for (i = 0; i < 3; i++) - { - limit[i * 4] = volBounds[i * 2]; - limit[i * 4 + 1] = this->CroppingRegionPlanes[i * 2]; - limit[i * 4 + 2] = this->CroppingRegionPlanes[i * 2 + 1]; - limit[i * 4 + 3] = volBounds[i * 2 + 1]; - } - - // For each of the 27 possible regions, find out if it is enabled, - // and if so, compute the bounds and the distance from the camera - // to the center of the region. - int numRegions = 0; - int region; - for (region = 0; region < 27; region++) - { - int regionFlag = 1 << region; - - if (this->CroppingRegionFlags & regionFlag) - { - // what is the coordinate in the 3x3x3 grid - int loc[3]; - loc[0] = region % 3; - loc[1] = (region / 3) % 3; - loc[2] = (region / 9) % 3; - - // compute the bounds and center - float center[3]; - for (i = 0; i < 3; i++) - { - bounds[numRegions][i * 2] = limit[4 * i + loc[i]]; - bounds[numRegions][i * 2 + 1] = limit[4 * i + loc[i] + 1]; - center[i] = (bounds[numRegions][i * 2] + bounds[numRegions][i * 2 + 1]) / 2.0; - } - - // compute the distance squared to the center - distance2[numRegions] = (camPos[0] - center[0]) * (camPos[0] - center[0]) + - (camPos[1] - center[1]) * (camPos[1] - center[1]) + - (camPos[2] - center[2]) * (camPos[2] - center[2]); - - // we've added one region - numRegions++; - } - } - - // Do a quick bubble sort on distance - for (i = 1; i < numRegions; i++) - { - for (j = i; j > 0 && distance2[j] > distance2[j - 1]; j--) - { - float tmpBounds[6]; - float tmpDistance2; - - for (k = 0; k < 6; k++) - { - tmpBounds[k] = bounds[j][k]; - } - tmpDistance2 = distance2[j]; - - for (k = 0; k < 6; k++) - { - bounds[j][k] = bounds[j - 1][k]; - } - distance2[j] = distance2[j - 1]; - - for (k = 0; k < 6; k++) - { - bounds[j - 1][k] = tmpBounds[k]; - } - distance2[j - 1] = tmpDistance2; - } - } - - numIterations = numRegions; - } - - // loop over all regions we need to render - for (int loop = 0; loop < numIterations; loop++) - { - // Compute the set of polygons for this region - // according to the bounds - this->ComputePolygons(ren, vol, bounds[loop]); - - // Loop over the polygons - for (i = 0; i < this->NumberOfPolygons; i++) - { - if (renWin->CheckAbortStatus()) - { - return; - } - - float *ptr = this->PolygonBuffer + 36 * i; - - glBegin(GL_TRIANGLE_FAN); - - for (j = 0; j < 6; j++) - { - if (ptr[0] < 0.0) - { - break; - } - - for (k = 0; k < 4; k++) - { - if (stages[k]) - { - vtkgl::MultiTexCoord3fv(vtkgl::TEXTURE0 + k, ptr); - } - } - glVertex3fv(ptr + 3); - - ptr += 6; - } - glEnd(); - } - } -} - -// This method moves the scalars from the input volume into volume1 (and -// possibly volume2) which are the 3D texture maps used for rendering. -// -// In the case where our volume is a power of two, the copy is done -// directly. If we need to resample, then trilinear interpolation is used. -// -// A shift/scale is applied to the input scalar value to produce an 8 bit -// value for the texture volume. -// -// When the input data is one component, the scalar value is placed in the -// second component of the two component volume1. The first component is -// filled in later with the gradient magnitude. -// -// When the input data is two component non-independent, the first component -// of the input data is placed in the first component of volume1, and the -// second component of the input data is placed in the third component of -// volume1. Volume1 has three components - the second is filled in later with -// the gradient magnitude. -// -// When the input data is four component non-independent, the first three -// components of the input data are placed in volume1 (which has three -// components), and the fourth component is placed in the second component -// of volume2. The first component of volume2 is later filled in with the -// gradient magnitude. - -template -class ScalarGradientCompute -{ - T *dataPtr; - unsigned char *tmpPtr; - unsigned char *tmpPtr2; - int sizeX; - int sizeY; - int sizeZ; - int sizeXY; - int sizeXm1; - int sizeYm1; - int sizeZm1; - int fullX; - int fullY; - int fullZ; - int fullXY; - int currentChunkStart; - int currentChunkEnd; - - int offZ; - - float offset; - float scale; - -public: - ScalarGradientCompute(T *_dataPtr, - unsigned char *_tmpPtr, - unsigned char *_tmpPtr2, - int _sizeX, - int _sizeY, - int _sizeZ, - int _fullX, - int _fullY, - int _fullZ, - float _offset, - float _scale) - { - dataPtr = _dataPtr; - tmpPtr = _tmpPtr; - tmpPtr2 = _tmpPtr2; - sizeX = _sizeX; - sizeY = _sizeY; - sizeZ = _sizeZ; - fullX = _fullX; - fullY = _fullY; - fullZ = _fullZ; - offset = _offset; - scale = _scale; - - sizeXY = sizeX * sizeY; - sizeXm1 = sizeX - 1; - sizeYm1 = sizeY - 1; - sizeZm1 = sizeZ - 1; - - fullXY = fullX * fullY; - } - - inline float sample(int x, int y, int z) { return float(dataPtr[x + y * sizeX + z * sizeXY]); } - inline void fill(int x, int y, int z) - { - int doff = x + y * fullX + (z - offZ) * fullXY; - - tmpPtr[doff * 4 + 0] = 0; - tmpPtr[doff * 4 + 1] = 0; - tmpPtr[doff * 4 + 2] = 0; - tmpPtr[doff * 4 + 3] = 0; - /* -tmpPtr2[doff*3+0]= 0; -tmpPtr2[doff*3+1]= 0; -tmpPtr2[doff*3+2]= 0; -*/ - } - - inline int clamp(int x) - { - if (x < 0) - x = 0; - else if (x > 255) - x = 255; - return x; - } - - inline void write(int x, int y, int z, float grayValue, float gx, float gy, float gz) - { - /* - gx /= aspect[0]; - gy /= aspect[1]; - gz /= aspect[2]; - */ - // Compute the gradient magnitude - - int iGrayValue = static_cast((grayValue + offset) * scale + 0.5f); - - gx *= scale; - gy *= scale; - gz *= scale; - - float t = sqrtf(gx * gx + gy * gy + gz * gz); - - if (t > 0.01f) - { - if (t < 2.0f) - { - float fac = 2.0f / t; - gx *= fac; - gy *= fac; - gz *= fac; - } - else if (t > 255.0f) - { - float fac = 255.0f / t; - gx *= fac; - gy *= fac; - gz *= fac; - } - } - else - { - gx = gy = gz = 0.0f; - } - - int nx = static_cast(0.5f * gx + 127.5f); - int ny = static_cast(0.5f * gy + 127.5f); - int nz = static_cast(0.5f * gz + 127.5f); - - int doff = x + y * fullX + (z - offZ) * fullXY; - - // tmpPtr[doff*2+0]= 0; - - tmpPtr[doff * 4 + 0] = clamp(nx); - tmpPtr[doff * 4 + 1] = clamp(ny); - tmpPtr[doff * 4 + 2] = clamp(nz); - tmpPtr[doff * 4 + 3] = clamp(iGrayValue); - - /* - if( z == fullZ/2 ) - if( y == fullY/2 ) - MITK_INFO << x << " " << y << " " << z << " : " << iGrayValue << " : " << iGradient; - */ - } - - inline void compute(int x, int y, int z) - { - float grayValue = sample(x, y, z); - float gx, gy, gz; - - gx = sample(x + 1, y, z) - sample(x - 1, y, z); - gy = sample(x, y + 1, z) - sample(x, y - 1, z); - gz = sample(x, y, z + 1) - sample(x, y, z - 1); - - write(x, y, z, grayValue, gx, gy, gz); - } - - inline void computeClamp(int x, int y, int z) - { - float grayValue = sample(x, y, z); - float gx, gy, gz; - - if (x == 0) - gx = 2.0f * (sample(x + 1, y, z) - grayValue); - else if (x == sizeXm1) - gx = 2.0f * (grayValue - sample(x - 1, y, z)); - else - gx = sample(x + 1, y, z) - sample(x - 1, y, z); - - if (y == 0) - gy = 2.0f * (sample(x, y + 1, z) - grayValue); - else if (y == sizeYm1) - gy = 2.0f * (grayValue - sample(x, y - 1, z)); - else - gy = sample(x, y + 1, z) - sample(x, y - 1, z); - - if (z == 0) - gz = 2.0f * (sample(x, y, z + 1) - grayValue); - else if (z == sizeZm1) - gz = 2.0f * (grayValue - sample(x, y, z - 1)); - else - gz = sample(x, y, z + 1) - sample(x, y, z - 1); - - write(x, y, z, grayValue, gx, gy, gz); - } - - inline void compute1D(int y, int z) - { - int x; - - x = 0; - computeClamp(x, y, z); - x++; - - while (x < sizeX - 1) - { - compute(x, y, z); - x++; - } - - if (x < sizeX) - { - computeClamp(x, y, z); - x++; - } - - while (x < fullX) - { - fill(x, y, z); - x++; - } - } - - inline void fill1D(int y, int z) - { - int x; - - x = 0; - while (x < fullX) - { - fill(x, y, z); - x++; - } - } - - inline void computeClamp1D(int y, int z) - { - int x; - - x = 0; - - while (x < sizeX) - { - computeClamp(x, y, z); - x++; - } - - while (x < fullX) - { - fill(x, y, z); - x++; - } - } - - inline void computeClamp2D(int z) - { - int y; - - y = 0; - - while (y < sizeY) - { - computeClamp1D(y, z); - y++; - } - - while (y < fullY) - { - fill1D(y, z); - y++; - } - } - - inline void compute2D(int z) - { - int y; - - y = 0; - computeClamp1D(y, z); - y++; - - while (y < sizeY - 1) - { - compute1D(y, z); - y++; - } - - if (y < sizeY) - { - computeClamp1D(y, z); - y++; - } - - while (y < fullY) - { - fill1D(y, z); - y++; - } - } - - inline void fill2D(int z) - { - int y; - - y = 0; - while (y < fullY) - { - fill1D(y, z); - y++; - } - } - - inline void fillSlices(int currentChunkStart, int currentChunkEnd) - { - offZ = currentChunkStart; - -/* - int num = omp_get_num_procs(); - MITK_INFO << "omp uses " << num << " processors"; -*/ - -#pragma omp parallel for - for (int z = currentChunkStart; z <= currentChunkEnd; z++) - { - if (z == 0 || z == sizeZ - 1) - computeClamp2D(z); - else if (z >= sizeZ) - fill2D(z); - else - compute2D(z); - } - } -}; - -template -void vtkVolumeTextureMapper3DComputeScalars( - T *dataPtr, vtkMitkVolumeTextureMapper3D *me, float offset, float scale, GLuint volume1, GLuint /*volume2*/) -{ - // T *inPtr; - // unsigned char *outPtr, *outPtr2; - // int i, j, k; - // int idx; - - int inputDimensions[3]; - double inputSpacing[3]; - vtkImageData *input = me->GetInput(); - - input->GetDimensions(inputDimensions); - input->GetSpacing(inputSpacing); - - int outputDimensions[3]; - float outputSpacing[3]; - me->GetVolumeDimensions(outputDimensions); - me->GetVolumeSpacing(outputSpacing); - - // int components = input->GetNumberOfScalarComponents(); - - // double wx, wy, wz; - // double fx, fy, fz; - // int x, y, z; - - // double sampleRate[3]; - // sampleRate[0] = outputSpacing[0] / static_cast(inputSpacing[0]); - // sampleRate[1] = outputSpacing[1] / static_cast(inputSpacing[1]); - // sampleRate[2] = outputSpacing[2] / static_cast(inputSpacing[2]); - - int fullX = outputDimensions[0]; - int fullY = outputDimensions[1]; - int fullZ = outputDimensions[2]; - - int sizeX = inputDimensions[0]; - int sizeY = inputDimensions[1]; - int sizeZ = inputDimensions[2]; - - int chunkSize = 64; - - if (fullZ < chunkSize) - chunkSize = fullZ; - - int numChunks = (fullZ + (chunkSize - 1)) / chunkSize; - - // inPtr = dataPtr; - - unsigned char *tmpPtr = new unsigned char[fullX * fullY * chunkSize * 4]; - unsigned char *tmpPtr2 = 0; // new unsigned char[fullX*fullY*chunkSize*3]; - - // For each Chunk - { - ScalarGradientCompute sgc(dataPtr, tmpPtr, tmpPtr2, sizeX, sizeY, sizeZ, fullX, fullY, fullZ, offset, scale); - - int currentChunk = 0; - - while (currentChunk < numChunks) - { - int currentChunkStart = currentChunk * chunkSize; - int currentChunkEnd = currentChunkStart + chunkSize - 1; - - if (currentChunkEnd > (fullZ - 1)) - currentChunkEnd = (fullZ - 1); - - int currentChunkSize = currentChunkEnd - currentChunkStart + 1; - - sgc.fillSlices(currentChunkStart, currentChunkEnd); - - glBindTexture(vtkgl::TEXTURE_3D, volume1); - vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D, - 0, - 0, - 0, - currentChunkStart, - fullX, - fullY, - currentChunkSize, - GL_RGBA, - GL_UNSIGNED_BYTE, - tmpPtr); - currentChunk++; - } - } - - delete[] tmpPtr; -} - -class RGBACompute -{ - unsigned char *dataPtr; - unsigned char *tmpPtr; - unsigned char *tmpPtr2; - int sizeX; - int sizeY; - int sizeZ; - int sizeXY; - int sizeXm1; - int sizeYm1; - int sizeZm1; - int fullX; - int fullY; - int fullZ; - int fullXY; - // int currentChunkStart; - // int currentChunkEnd; - - int offZ; - -public: - RGBACompute(unsigned char *_dataPtr, - unsigned char *_tmpPtr, - unsigned char *_tmpPtr2, - int _sizeX, - int _sizeY, - int _sizeZ, - int _fullX, - int _fullY, - int _fullZ) - { - dataPtr = _dataPtr; - tmpPtr = _tmpPtr; - tmpPtr2 = _tmpPtr2; - sizeX = _sizeX; - sizeY = _sizeY; - sizeZ = _sizeZ; - fullX = _fullX; - fullY = _fullY; - fullZ = _fullZ; - - sizeXY = sizeX * sizeY; - sizeXm1 = sizeX - 1; - sizeYm1 = sizeY - 1; - sizeZm1 = sizeZ - 1; - - fullXY = fullX * fullY; - } - - inline int sample(int x, int y, int z) { return dataPtr[(x + y * sizeX + z * sizeXY) * 4 + 3]; } - inline void fill(int x, int y, int z) - { - int doff = x + y * fullX + (z - offZ) * fullXY; - - tmpPtr[doff * 4 + 0] = 0; - tmpPtr[doff * 4 + 1] = 0; - tmpPtr[doff * 4 + 2] = 0; - tmpPtr[doff * 4 + 3] = 0; - - tmpPtr2[doff * 3 + 0] = 0; - tmpPtr2[doff * 3 + 1] = 0; - tmpPtr2[doff * 3 + 2] = 0; - } - - inline int clamp(int x) - { - if (x < 0) - x = 0; - else if (x > 255) - x = 255; - return x; - } - - inline void write(int x, int y, int z, int iGrayValue, int gx, int gy, int gz) - { - /* - gx /= aspect[0]; - gy /= aspect[1]; - gz /= aspect[2]; - */ - int nx = static_cast(0.5f * gx + 127.5f); - int ny = static_cast(0.5f * gy + 127.5f); - int nz = static_cast(0.5f * gz + 127.5f); - - int doff = x + y * fullX + (z - offZ) * fullXY; - - // tmpPtr[doff*2+0]= 0; - - tmpPtr[doff * 4 + 0] = clamp(nx); - tmpPtr[doff * 4 + 1] = clamp(ny); - tmpPtr[doff * 4 + 2] = clamp(nz); - tmpPtr[doff * 4 + 3] = clamp(iGrayValue); - - int soff = x + y * sizeX + z * sizeXY; - - tmpPtr2[doff * 3 + 0] = dataPtr[soff * 4 + 0]; - tmpPtr2[doff * 3 + 1] = dataPtr[soff * 4 + 1]; - tmpPtr2[doff * 3 + 2] = dataPtr[soff * 4 + 2]; - - /* - if( z == fullZ/2 ) - if( y == fullY/2 ) - MITK_INFO << x << " " << y << " " << z << " : " << iGrayValue << " : " << iGradient; - */ - } - - inline void compute(int x, int y, int z) - { - int grayValue = sample(x, y, z); - int gx, gy, gz; - - gx = sample(x + 1, y, z) - sample(x - 1, y, z); - gy = sample(x, y + 1, z) - sample(x, y - 1, z); - gz = sample(x, y, z + 1) - sample(x, y, z - 1); - - write(x, y, z, grayValue, gx, gy, gz); - } - - inline void computeClamp(int x, int y, int z) - { - int grayValue = sample(x, y, z); - int gx, gy, gz; - - if (x == 0) - gx = 2 * (sample(x + 1, y, z) - grayValue); - else if (x == sizeXm1) - gx = 2 * (grayValue - sample(x - 1, y, z)); - else - gx = sample(x + 1, y, z) - sample(x - 1, y, z); - - if (y == 0) - gy = 2 * (sample(x, y + 1, z) - grayValue); - else if (y == sizeYm1) - gy = 2 * (grayValue - sample(x, y - 1, z)); - else - gy = sample(x, y + 1, z) - sample(x, y - 1, z); - - if (z == 0) - gz = 2 * (sample(x, y, z + 1) - grayValue); - else if (z == sizeZm1) - gz = 2 * (grayValue - sample(x, y, z - 1)); - else - gz = sample(x, y, z + 1) - sample(x, y, z - 1); - - write(x, y, z, grayValue, gx, gy, gz); - } - - inline void compute1D(int y, int z) - { - int x = 0; - - computeClamp(x, y, z); - x++; - - while (x < sizeX - 1) - { - compute(x, y, z); - x++; - } - - if (x < sizeX) - { - computeClamp(x, y, z); - x++; - } - - while (x < fullX) - { - fill(x, y, z); - x++; - } - } - - inline void fill1D(int y, int z) - { - int x = 0; - - while (x < fullX) - { - fill(x, y, z); - x++; - } - } - - inline void computeClamp1D(int y, int z) - { - int x = 0; - - while (x < sizeX) - { - computeClamp(x, y, z); - x++; - } - - while (x < fullX) - { - fill(x, y, z); - x++; - } - } - - inline void computeClamp2D(int z) - { - int y = 0; - - while (y < sizeY) - { - computeClamp1D(y, z); - y++; - } - - while (y < fullY) - { - fill1D(y, z); - y++; - } - } - - inline void compute2D(int z) - { - int y = 0; - - computeClamp1D(y, z); - y++; - - while (y < sizeY - 1) - { - compute1D(y, z); - y++; - } - - if (y < sizeY) - { - computeClamp1D(y, z); - y++; - } - - while (y < fullY) - { - fill1D(y, z); - y++; - } - } - - inline void fill2D(int z) - { - int y = 0; - - while (y < fullY) - { - fill1D(y, z); - y++; - } - } - - inline void fillSlices(int currentChunkStart, int currentChunkEnd) - { - offZ = currentChunkStart; - -#pragma omp parallel for - for (int z = currentChunkStart; z <= currentChunkEnd; z++) - { - if (z == 0 || z == sizeZ - 1) - computeClamp2D(z); - else if (z >= sizeZ) - fill2D(z); - else - compute2D(z); - } - } -}; - -void vtkVolumeTextureMapper3DComputeRGBA(unsigned char *dataPtr, - vtkMitkVolumeTextureMapper3D *me, - GLuint volume1, - GLuint volume2) -{ - // unsigned char *inPtr; - // unsigned char *outPtr, *outPtr2; - // int i, j, k; - // int idx; - - int inputDimensions[3]; - double inputSpacing[3]; - vtkImageData *input = me->GetInput(); - - input->GetDimensions(inputDimensions); - input->GetSpacing(inputSpacing); - - int outputDimensions[3]; - float outputSpacing[3]; - me->GetVolumeDimensions(outputDimensions); - me->GetVolumeSpacing(outputSpacing); - - int components = input->GetNumberOfScalarComponents(); - - MITK_INFO << "components are " << components; - - // double wx, wy, wz; - // double fx, fy, fz; - // int x, y, z; - - // double sampleRate[3]; - // sampleRate[0] = outputSpacing[0] / static_cast(inputSpacing[0]); - // sampleRate[1] = outputSpacing[1] / static_cast(inputSpacing[1]); - // sampleRate[2] = outputSpacing[2] / static_cast(inputSpacing[2]); - - int fullX = outputDimensions[0]; - int fullY = outputDimensions[1]; - int fullZ = outputDimensions[2]; - - int sizeX = inputDimensions[0]; - int sizeY = inputDimensions[1]; - int sizeZ = inputDimensions[2]; - - int chunkSize = 64; - - if (fullZ < chunkSize) - chunkSize = fullZ; - - int numChunks = (fullZ + (chunkSize - 1)) / chunkSize; - - // inPtr = dataPtr; - - unsigned char *tmpPtr = new unsigned char[fullX * fullY * chunkSize * 4]; - unsigned char *tmpPtr2 = new unsigned char[fullX * fullY * chunkSize * 3]; - - // For each Chunk - { - RGBACompute sgc(dataPtr, tmpPtr, tmpPtr2, sizeX, sizeY, sizeZ, fullX, fullY, fullZ); - - int currentChunk = 0; - - while (currentChunk < numChunks) - { - // MITK_INFO << "processing chunk " << currentChunk; - - int currentChunkStart = currentChunk * chunkSize; - int currentChunkEnd = currentChunkStart + chunkSize - 1; - - if (currentChunkEnd > (fullZ - 1)) - currentChunkEnd = (fullZ - 1); - - int currentChunkSize = currentChunkEnd - currentChunkStart + 1; - - sgc.fillSlices(currentChunkStart, currentChunkEnd); - - glBindTexture(vtkgl::TEXTURE_3D, volume1); - vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D, - 0, - 0, - 0, - currentChunkStart, - fullX, - fullY, - currentChunkSize, - GL_RGBA, - GL_UNSIGNED_BYTE, - tmpPtr); - - glBindTexture(vtkgl::TEXTURE_3D, volume2); - vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D, - 0, - 0, - 0, - currentChunkStart, - fullX, - fullY, - currentChunkSize, - GL_RGB, - GL_UNSIGNED_BYTE, - tmpPtr2); - - currentChunk++; - } - } - - delete[] tmpPtr; - delete[] tmpPtr2; -} - -//----------------------------------------------------------------------------- -void vtkMitkOpenGLVolumeTextureMapper3D::ComputeVolumeDimensions() -{ - // Get the image data - vtkImageData *input = this->GetInput(); - - // How big does the Volume need to be? - int dim[3]; - input->GetDimensions(dim); - - int powerOfTwoDim[3]; - - if (this->SupportsNonPowerOfTwoTextures) - { - for (int i = 0; i < 3; i++) - powerOfTwoDim[i] = (dim[i] + 1) & ~1; - - // MITK_INFO << "using non-power-two even textures (" << - // (1.0-double(dim[0]*dim[1]*dim[2])/double(powerOfTwoDim[0]*powerOfTwoDim[1]*powerOfTwoDim[2])) * 100.0 << "% - // memory wasted)"; - } - else - { - for (int i = 0; i < 3; i++) - { - powerOfTwoDim[i] = 4; - while (powerOfTwoDim[i] < dim[i]) - powerOfTwoDim[i] *= 2; - } - - MITK_WARN << "using power-two textures (" - << (1.0 - - double(dim[0] * dim[1] * dim[2]) / double(powerOfTwoDim[0] * powerOfTwoDim[1] * powerOfTwoDim[2])) * - 100.0 - << "% memory wasted)"; - } - - // Save the volume size - this->VolumeDimensions[0] = powerOfTwoDim[0]; - this->VolumeDimensions[1] = powerOfTwoDim[1]; - this->VolumeDimensions[2] = powerOfTwoDim[2]; - - // What is the spacing? - double spacing[3]; - input->GetSpacing(spacing); - - // Compute the new spacing - this->VolumeSpacing[0] = (dim[0] - 1.01) * spacing[0] / static_cast(this->VolumeDimensions[0] - 1); - this->VolumeSpacing[1] = (dim[1] - 1.01) * spacing[1] / static_cast(this->VolumeDimensions[1] - 1); - this->VolumeSpacing[2] = ((dim[2]) - 1.01) * spacing[2] / static_cast(this->VolumeDimensions[2] - 1); -} - -//----------------------------------------------------------------------------- -bool vtkMitkOpenGLVolumeTextureMapper3D::UpdateVolumes(vtkVolume *vtkNotUsed(vol)) -{ - // Get the image data - vtkImageData *input = this->GetInput(); - // input->Update(); //VTK6_TODO - - bool needUpdate = false; - - // Has the volume changed in some way? - if (this->SavedTextureInput != input || this->SavedTextureMTime.GetMTime() < input->GetMTime()) - needUpdate = true; - - // Do we have any volume on the gpu already? - if (!this->Volume1Index) - needUpdate = true; - - if (!needUpdate) - return true; - - ComputeVolumeDimensions(); - - int components = input->GetNumberOfScalarComponents(); - - // Find the scalar range - double scalarRange[2]; - input->GetPointData()->GetScalars()->GetRange(scalarRange, components - 1); - - // Is the difference between max and min less than 4096? If so, and if - // the data is not of float or double type, use a simple offset mapping. - // If the difference between max and min is 4096 or greater, or the data - // is of type float or double, we must use an offset / scaling mapping. - // In this case, the array size will be 4096 - we need to figure out the - // offset and scale factor. - float offset; - float scale; - - int arraySizeNeeded; - - int scalarType = input->GetScalarType(); - - if (scalarType == VTK_FLOAT || scalarType == VTK_DOUBLE || scalarRange[1] - scalarRange[0] > 255) - { - arraySizeNeeded = 256; - offset = -scalarRange[0]; - scale = 255.0 / (scalarRange[1] - scalarRange[0]); - } - else - { - arraySizeNeeded = static_cast(scalarRange[1] - scalarRange[0] + 1); - offset = -scalarRange[0]; - scale = 1.0; - } - - this->ColorTableSize = arraySizeNeeded; - this->ColorTableOffset = offset; - this->ColorTableScale = scale; - - // Allocating volume on gpu - { - // Deleting old textures - this->DeleteTextureIndex(&this->Volume1Index); - this->DeleteTextureIndex(&this->Volume2Index); - this->DeleteTextureIndex(&this->Volume3Index); - - this->CreateTextureIndex(&this->Volume1Index); - // this->CreateTextureIndex(&this->Volume2Index); - - int dim[3]; - this->GetVolumeDimensions(dim); - - vtkgl::ActiveTexture(vtkgl::TEXTURE0); - - MITK_INFO << "allocating volume on gpu"; - - GLint gradientScalarTextureFormat = GL_RGBA8; - - if (this->UseCompressedTexture && SupportsCompressedTexture) - gradientScalarTextureFormat = myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - - glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index); - vtkgl::TexImage3D( - vtkgl::TEXTURE_3D, 0, gradientScalarTextureFormat, dim[0], dim[1], dim[2], 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - this->Setup3DTextureParameters(true); - } - - // Transfer the input volume to the RGBA volume - void *dataPtr = input->GetScalarPointer(); - - switch (scalarType) - { - vtkTemplateMacro(vtkVolumeTextureMapper3DComputeScalars( - static_cast(dataPtr), this, offset, scale, this->Volume1Index, this->Volume2Index)); - } - - this->SavedTextureInput = input; - this->SavedTextureMTime.Modified(); - - return true; -} - -//----------------------------------------------------------------------------- -bool vtkMitkOpenGLVolumeTextureMapper3D::UpdateVolumesRGBA(vtkVolume *vtkNotUsed(vol)) -{ - // Get the image data - vtkImageData *input = this->GetInput(); - // input->Update(); //VTK6_TODO - - bool needUpdate = false; - - // Has the volume changed in some way? - if (this->SavedTextureInput != input || this->SavedTextureMTime.GetMTime() < input->GetMTime()) - needUpdate = true; - - // Do we have any volume on the gpu already? - if (!this->Volume1Index) - needUpdate = true; - - if (!needUpdate) - return true; - - MITK_INFO << "updating rgba volume"; - - ComputeVolumeDimensions(); - - // Allocating volume on gpu - { - // Deleting old textures - this->DeleteTextureIndex(&this->Volume1Index); - this->DeleteTextureIndex(&this->Volume2Index); - this->DeleteTextureIndex(&this->Volume3Index); - - this->CreateTextureIndex(&this->Volume1Index); - this->CreateTextureIndex(&this->Volume2Index); - - int dim[3]; - this->GetVolumeDimensions(dim); - - MITK_INFO << "allocating volume on gpu"; - - GLint gradientScalarTextureFormat = GL_RGBA8; - GLint colorTextureFormat = GL_RGB8; - - if (this->UseCompressedTexture && SupportsCompressedTexture) - { - gradientScalarTextureFormat = myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - colorTextureFormat = myGL_COMPRESSED_RGB_S3TC_DXT1_EXT; - } - - vtkgl::ActiveTexture(vtkgl::TEXTURE0); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index); - vtkgl::TexImage3D( - vtkgl::TEXTURE_3D, 0, gradientScalarTextureFormat, dim[0], dim[1], dim[2], 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - this->Setup3DTextureParameters(true); - - glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index); - vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, colorTextureFormat, dim[0], dim[1], dim[2], 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - this->Setup3DTextureParameters(true); - } - - // Transfer the input volume to the RGBA volume - unsigned char *dataPtr = (unsigned char *)input->GetScalarPointer(); - vtkVolumeTextureMapper3DComputeRGBA(dataPtr, this, this->Volume1Index, this->Volume2Index); - - this->SavedTextureInput = input; - this->SavedTextureMTime.Modified(); - - return true; -} - -void vtkMitkOpenGLVolumeTextureMapper3D::Setup3DTextureParameters(bool linear) -{ - // GPU_INFO << "Setup3DTextureParameters"; - - if (linear) - { - glTexParameterf(vtkgl::TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(vtkgl::TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameterf(vtkgl::TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(vtkgl::TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - glTexParameterf(vtkgl::TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(vtkgl::TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::SetupOneIndependentTextures(vtkRenderer *vtkNotUsed(ren), vtkVolume *vol) -{ - // Update the volume containing the 2 byte scalar / gradient magnitude - this->UpdateVolumes(vol); - - // Update the dependent 2D color table mapping scalar value and - // gradient magnitude to RGBA - if (this->UpdateColorLookup(vol) || !this->ColorLookupIndex) - { - this->DeleteTextureIndex(&this->ColorLookupIndex); - this->DeleteTextureIndex(&this->AlphaLookupIndex); - - this->CreateTextureIndex(&this->ColorLookupIndex); - - vtkgl::ActiveTexture(vtkgl::TEXTURE1); - glBindTexture(GL_TEXTURE_2D, this->ColorLookupIndex); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - // MITK_INFO << "uploading transferfunction"; - - GLint colorLookupTextureFormat = GL_RGBA8; - - if (this->UseCompressedTexture && SupportsCompressedTexture) - colorLookupTextureFormat = myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - - glTexImage2D(GL_TEXTURE_2D, 0, colorLookupTextureFormat, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->ColorLookup); - } -} - -void vtkMitkOpenGLVolumeTextureMapper3D::SetupRGBATextures(vtkRenderer *vtkNotUsed(ren), vtkVolume *vol) -{ - MITK_INFO << "SetupFourDependentTextures"; - - this->UpdateVolumesRGBA(vol); - - /* -vtkgl::ActiveTexture( vtkgl::TEXTURE0 ); -glDisable( GL_TEXTURE_2D ); -glEnable( vtkgl::TEXTURE_3D ); - -vtkgl::ActiveTexture( vtkgl::TEXTURE1 ); -glDisable( GL_TEXTURE_2D ); -glEnable( vtkgl::TEXTURE_3D ); - -vtkgl::ActiveTexture( vtkgl::TEXTURE2 ); -glDisable( GL_TEXTURE_2D ); -glEnable( vtkgl::TEXTURE_3D ); - -// Update the volume containing the 3 byte scalars / gradient magnitude -if ( this->UpdateVolumes( vol ) || !this->Volume1Index || - !this->Volume2Index || !this->Volume3Index ) - { - int dim[3]; - this->GetVolumeDimensions(dim); - - vtkgl::ActiveTexture( vtkgl::TEXTURE0 ); - glBindTexture(vtkgl::TEXTURE_3D,0); - this->DeleteTextureIndex(&this->Volume1Index); - this->CreateTextureIndex(&this->Volume1Index); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index); - vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,this->InternalRGB,dim[0],dim[1], - dim[2],0,GL_RGB,GL_UNSIGNED_BYTE,this->Volume1); - - vtkgl::ActiveTexture( vtkgl::TEXTURE1 ); - glBindTexture(vtkgl::TEXTURE_3D,0); - this->DeleteTextureIndex(&this->Volume2Index); - this->CreateTextureIndex(&this->Volume2Index); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index); - vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,this->InternalLA,dim[0],dim[1], - dim[2],0,GL_LUMINANCE_ALPHA,GL_UNSIGNED_BYTE, - this->Volume2); - - vtkgl::ActiveTexture( vtkgl::TEXTURE2 ); - glBindTexture(vtkgl::TEXTURE_3D,0); - this->DeleteTextureIndex(&this->Volume3Index); - this->CreateTextureIndex(&this->Volume3Index); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume3Index); - vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,this->InternalRGB,dim[0],dim[1], - dim[2],0,GL_RGB,GL_UNSIGNED_BYTE,this->Volume3); - } - -vtkgl::ActiveTexture( vtkgl::TEXTURE0 ); -glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index); -this->Setup3DTextureParameters( true ); - -vtkgl::ActiveTexture( vtkgl::TEXTURE1 ); -glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index); -this->Setup3DTextureParameters( true ); - -vtkgl::ActiveTexture( vtkgl::TEXTURE2 ); -glBindTexture(vtkgl::TEXTURE_3D_EXT, this->Volume3Index); -this->Setup3DTextureParameters( true ); - -vtkgl::ActiveTexture( vtkgl::TEXTURE3 ); -glEnable( GL_TEXTURE_2D ); -glDisable( vtkgl::TEXTURE_3D ); - -// Update the dependent 2D table mapping scalar value and -// gradient magnitude to opacity -if ( this->UpdateColorLookup( vol ) || !this->AlphaLookupIndex ) - { - this->DeleteTextureIndex(&this->ColorLookupIndex); - - vtkgl::ActiveTexture( vtkgl::TEXTURE3 ); - glBindTexture(GL_TEXTURE_2D,0); - this->DeleteTextureIndex(&this->AlphaLookupIndex); - this->CreateTextureIndex(&this->AlphaLookupIndex); - glBindTexture(GL_TEXTURE_2D, this->AlphaLookupIndex); - - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); - - //MITK_INFO << "uploading transferfunction"; - - glTexImage2D(GL_TEXTURE_2D,0,this->InternalAlpha, 256, 256, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, this->AlphaLookup ); - } - -vtkgl::ActiveTexture( vtkgl::TEXTURE3 ); -glBindTexture(GL_TEXTURE_2D, this->AlphaLookupIndex); - -*/ -} - -void vtkMitkOpenGLVolumeTextureMapper3D::RenderOneIndependentShadeFP(vtkRenderer *ren, vtkVolume *vol) -{ - // GPU_INFO << "RenderOneIndependentShadeFP"; - - this->SetupOneIndependentTextures(ren, vol); - - glEnable(vtkgl::FRAGMENT_PROGRAM_ARB); - - vtkgl::BindProgramARB(vtkgl::FRAGMENT_PROGRAM_ARB, prgOneComponentShade); - - this->SetupProgramLocalsForShadingFP(ren, vol); - - // Bind Textures - { - vtkgl::ActiveTexture(vtkgl::TEXTURE0); - glDisable(GL_TEXTURE_2D); - glEnable(vtkgl::TEXTURE_3D); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index); - - vtkgl::ActiveTexture(vtkgl::TEXTURE1); - glEnable(GL_TEXTURE_2D); - glDisable(vtkgl::TEXTURE_3D); - glBindTexture(GL_TEXTURE_2D, this->ColorLookupIndex); - - vtkgl::ActiveTexture(vtkgl::TEXTURE2); - glDisable(GL_TEXTURE_2D); - glEnable(vtkgl::TEXTURE_3D); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index); - } - - int stages[4] = {1, 1, 1, 0}; - this->RenderPolygons(ren, vol, stages); - - glDisable(vtkgl::FRAGMENT_PROGRAM_ARB); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::RenderRGBAShadeFP(vtkRenderer *ren, vtkVolume *vol) -{ - this->SetupRGBATextures(ren, vol); - - glEnable(vtkgl::FRAGMENT_PROGRAM_ARB); - - vtkgl::BindProgramARB(vtkgl::FRAGMENT_PROGRAM_ARB, prgRGBAShade); - - this->SetupProgramLocalsForShadingFP(ren, vol); - - // Bind Textures - { - vtkgl::ActiveTexture(vtkgl::TEXTURE0); - glDisable(GL_TEXTURE_2D); - glEnable(vtkgl::TEXTURE_3D); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index); - - vtkgl::ActiveTexture(vtkgl::TEXTURE1); - glDisable(GL_TEXTURE_2D); - glEnable(vtkgl::TEXTURE_3D); - glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index); - } - - int stages[4] = {1, 1, 1, 0}; - this->RenderPolygons(ren, vol, stages); - - glDisable(vtkgl::FRAGMENT_PROGRAM_ARB); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::GetLightInformation(vtkRenderer *ren, - vtkVolume *vol, - GLfloat lightDirection[2][4], - GLfloat lightDiffuseColor[2][4], - GLfloat lightSpecularColor[2][4], - GLfloat halfwayVector[2][4], - GLfloat ambientColor[4]) -{ - // GPU_INFO << "GetLightInformation"; - - float ambient = vol->GetProperty()->GetAmbient(); - float diffuse = vol->GetProperty()->GetDiffuse(); - float specular = vol->GetProperty()->GetSpecular(); - - vtkTransform *volumeTransform = vtkTransform::New(); - - volumeTransform->SetMatrix(vol->GetMatrix()); - volumeTransform->Inverse(); - - vtkLightCollection *lights = ren->GetLights(); - lights->InitTraversal(); - - vtkLight *light[2]; - light[0] = lights->GetNextItem(); - light[1] = lights->GetNextItem(); - - int lightIndex = 0; - - double cameraPosition[3]; - double cameraFocalPoint[3]; - - ren->GetActiveCamera()->GetPosition(cameraPosition); - ren->GetActiveCamera()->GetFocalPoint(cameraFocalPoint); - - double viewDirection[3]; - - volumeTransform->TransformPoint(cameraPosition, cameraPosition); - volumeTransform->TransformPoint(cameraFocalPoint, cameraFocalPoint); - - viewDirection[0] = cameraFocalPoint[0] - cameraPosition[0]; - viewDirection[1] = cameraFocalPoint[1] - cameraPosition[1]; - viewDirection[2] = cameraFocalPoint[2] - cameraPosition[2]; - - vtkMath::Normalize(viewDirection); - - ambientColor[0] = 0.0; - ambientColor[1] = 0.0; - ambientColor[2] = 0.0; - ambientColor[3] = 0.0; - - for (lightIndex = 0; lightIndex < 2; lightIndex++) - { - float dir[3] = {0, 0, 0}; - float half[3] = {0, 0, 0}; - - if (light[lightIndex] == NULL || light[lightIndex]->GetSwitch() == 0) - { - lightDiffuseColor[lightIndex][0] = 0.0; - lightDiffuseColor[lightIndex][1] = 0.0; - lightDiffuseColor[lightIndex][2] = 0.0; - lightDiffuseColor[lightIndex][3] = 0.0; - - lightSpecularColor[lightIndex][0] = 0.0; - lightSpecularColor[lightIndex][1] = 0.0; - lightSpecularColor[lightIndex][2] = 0.0; - lightSpecularColor[lightIndex][3] = 0.0; - } - else - { - float lightIntensity = light[lightIndex]->GetIntensity(); - double lightColor[3]; - - light[lightIndex]->GetDiffuseColor(lightColor); - - double lightPosition[3]; - double lightFocalPoint[3]; - light[lightIndex]->GetTransformedPosition(lightPosition); - light[lightIndex]->GetTransformedFocalPoint(lightFocalPoint); - - volumeTransform->TransformPoint(lightPosition, lightPosition); - volumeTransform->TransformPoint(lightFocalPoint, lightFocalPoint); - - dir[0] = lightPosition[0] - lightFocalPoint[0]; - dir[1] = lightPosition[1] - lightFocalPoint[1]; - dir[2] = lightPosition[2] - lightFocalPoint[2]; - - vtkMath::Normalize(dir); - - lightDiffuseColor[lightIndex][0] = lightColor[0] * diffuse * lightIntensity; - lightDiffuseColor[lightIndex][1] = lightColor[1] * diffuse * lightIntensity; - lightDiffuseColor[lightIndex][2] = lightColor[2] * diffuse * lightIntensity; - lightDiffuseColor[lightIndex][3] = 1.0; - - lightSpecularColor[lightIndex][0] = lightColor[0] * specular * lightIntensity; - lightSpecularColor[lightIndex][1] = lightColor[1] * specular * lightIntensity; - lightSpecularColor[lightIndex][2] = lightColor[2] * specular * lightIntensity; - lightSpecularColor[lightIndex][3] = 0.0; - - half[0] = dir[0] - viewDirection[0]; - half[1] = dir[1] - viewDirection[1]; - half[2] = dir[2] - viewDirection[2]; - - vtkMath::Normalize(half); - - ambientColor[0] += ambient * lightColor[0]; - ambientColor[1] += ambient * lightColor[1]; - ambientColor[2] += ambient * lightColor[2]; - } - - lightDirection[lightIndex][0] = (dir[0] + 1.0) / 2.0; - lightDirection[lightIndex][1] = (dir[1] + 1.0) / 2.0; - lightDirection[lightIndex][2] = (dir[2] + 1.0) / 2.0; - lightDirection[lightIndex][3] = 0.0; - - halfwayVector[lightIndex][0] = (half[0] + 1.0) / 2.0; - halfwayVector[lightIndex][1] = (half[1] + 1.0) / 2.0; - halfwayVector[lightIndex][2] = (half[2] + 1.0) / 2.0; - halfwayVector[lightIndex][3] = 0.0; - } - - volumeTransform->Delete(); -} - -void vtkMitkOpenGLVolumeTextureMapper3D::SetupProgramLocalsForShadingFP(vtkRenderer *ren, vtkVolume *vol) -{ - // GPU_INFO << "SetupProgramLocalsForShadingFP"; - - GLfloat lightDirection[2][4]; - GLfloat lightDiffuseColor[2][4]; - GLfloat lightSpecularColor[2][4]; - GLfloat halfwayVector[2][4]; - GLfloat ambientColor[4]; - - float ambient = vol->GetProperty()->GetAmbient(); - float diffuse = vol->GetProperty()->GetDiffuse(); - float specular = vol->GetProperty()->GetSpecular(); - float specularPower = vol->GetProperty()->GetSpecularPower(); - - vtkTransform *volumeTransform = vtkTransform::New(); - - volumeTransform->SetMatrix(vol->GetMatrix()); - volumeTransform->Inverse(); - - vtkLightCollection *lights = ren->GetLights(); - lights->InitTraversal(); - - vtkLight *light[2]; - light[0] = lights->GetNextItem(); - light[1] = lights->GetNextItem(); - - int lightIndex = 0; - - double cameraPosition[3]; - double cameraFocalPoint[3]; - - ren->GetActiveCamera()->GetPosition(cameraPosition); - ren->GetActiveCamera()->GetFocalPoint(cameraFocalPoint); - - volumeTransform->TransformPoint(cameraPosition, cameraPosition); - volumeTransform->TransformPoint(cameraFocalPoint, cameraFocalPoint); - - double viewDirection[4]; - - viewDirection[0] = cameraFocalPoint[0] - cameraPosition[0]; - viewDirection[1] = cameraFocalPoint[1] - cameraPosition[1]; - viewDirection[2] = cameraFocalPoint[2] - cameraPosition[2]; - viewDirection[3] = 0.0; - - vtkMath::Normalize(viewDirection); - - ambientColor[0] = 0.0; - ambientColor[1] = 0.0; - ambientColor[2] = 0.0; - ambientColor[3] = 0.0; - - for (lightIndex = 0; lightIndex < 2; lightIndex++) - { - float dir[3] = {0, 0, 0}; - float half[3] = {0, 0, 0}; - - if (light[lightIndex] == NULL || light[lightIndex]->GetSwitch() == 0) - { - lightDiffuseColor[lightIndex][0] = 0.0; - lightDiffuseColor[lightIndex][1] = 0.0; - lightDiffuseColor[lightIndex][2] = 0.0; - lightDiffuseColor[lightIndex][3] = 0.0; - - lightSpecularColor[lightIndex][0] = 0.0; - lightSpecularColor[lightIndex][1] = 0.0; - lightSpecularColor[lightIndex][2] = 0.0; - lightSpecularColor[lightIndex][3] = 0.0; - } - else - { - float lightIntensity = light[lightIndex]->GetIntensity(); - double lightColor[3]; - - light[lightIndex]->GetDiffuseColor(lightColor); - - double lightPosition[3]; - double lightFocalPoint[3]; - light[lightIndex]->GetTransformedPosition(lightPosition); - light[lightIndex]->GetTransformedFocalPoint(lightFocalPoint); - - volumeTransform->TransformPoint(lightPosition, lightPosition); - volumeTransform->TransformPoint(lightFocalPoint, lightFocalPoint); - - dir[0] = lightPosition[0] - lightFocalPoint[0]; - dir[1] = lightPosition[1] - lightFocalPoint[1]; - dir[2] = lightPosition[2] - lightFocalPoint[2]; - - vtkMath::Normalize(dir); - - lightDiffuseColor[lightIndex][0] = lightColor[0] * diffuse * lightIntensity; - lightDiffuseColor[lightIndex][1] = lightColor[1] * diffuse * lightIntensity; - lightDiffuseColor[lightIndex][2] = lightColor[2] * diffuse * lightIntensity; - lightDiffuseColor[lightIndex][3] = 0.0; - - lightSpecularColor[lightIndex][0] = lightColor[0] * specular * lightIntensity; - lightSpecularColor[lightIndex][1] = lightColor[1] * specular * lightIntensity; - lightSpecularColor[lightIndex][2] = lightColor[2] * specular * lightIntensity; - lightSpecularColor[lightIndex][3] = 0.0; - - half[0] = dir[0] - viewDirection[0]; - half[1] = dir[1] - viewDirection[1]; - half[2] = dir[2] - viewDirection[2]; - - vtkMath::Normalize(half); - - ambientColor[0] += ambient * lightColor[0]; - ambientColor[1] += ambient * lightColor[1]; - ambientColor[2] += ambient * lightColor[2]; - } - - lightDirection[lightIndex][0] = dir[0]; - lightDirection[lightIndex][1] = dir[1]; - lightDirection[lightIndex][2] = dir[2]; - lightDirection[lightIndex][3] = 0.0; - - halfwayVector[lightIndex][0] = half[0]; - halfwayVector[lightIndex][1] = half[1]; - halfwayVector[lightIndex][2] = half[2]; - halfwayVector[lightIndex][3] = 0.0; - } - - volumeTransform->Delete(); - - vtkgl::ProgramLocalParameter4fARB(vtkgl::FRAGMENT_PROGRAM_ARB, - 0, - lightDirection[0][0], - lightDirection[0][1], - lightDirection[0][2], - lightDirection[0][3]); - - vtkgl::ProgramLocalParameter4fARB( - vtkgl::FRAGMENT_PROGRAM_ARB, 1, halfwayVector[0][0], halfwayVector[0][1], halfwayVector[0][2], halfwayVector[0][3]); - - vtkgl::ProgramLocalParameter4fARB(vtkgl::FRAGMENT_PROGRAM_ARB, 2, ambient, diffuse, specular, specularPower); - - vtkgl::ProgramLocalParameter4fARB(vtkgl::FRAGMENT_PROGRAM_ARB, - 3, - lightDiffuseColor[0][0], - lightDiffuseColor[0][1], - lightDiffuseColor[0][2], - lightDiffuseColor[0][3]); - - vtkgl::ProgramLocalParameter4fARB(vtkgl::FRAGMENT_PROGRAM_ARB, - 4, - lightSpecularColor[0][0], - lightSpecularColor[0][1], - lightSpecularColor[0][2], - lightSpecularColor[0][3]); - - vtkgl::ProgramLocalParameter4fARB( - vtkgl::FRAGMENT_PROGRAM_ARB, 5, viewDirection[0], viewDirection[1], viewDirection[2], viewDirection[3]); - - vtkgl::ProgramLocalParameter4fARB(vtkgl::FRAGMENT_PROGRAM_ARB, 6, 2.0, -1.0, 0.0, 0.0); -} - -int vtkMitkOpenGLVolumeTextureMapper3D::IsRenderSupported(vtkRenderer *renderer, vtkVolumeProperty * /*property*/) -{ - // GPU_INFO << "IsRenderSupported"; - - if (!this->Initialized) - { - // this->Initialize(); - this->Initialize(renderer); - } - - if (!this->RenderPossible) - { - MITK_WARN << "vtkMitkOpenGLVolumeTextureMapper3D::IsRenderSupported Rendering not possible"; - return 0; - } - - if (!this->GetInput()) - { - MITK_WARN << "vtkMitkOpenGLVolumeTextureMapper3D::IsRenderSupported No input available"; - return 0; - } - - return 1; -} - -void vtkMitkOpenGLVolumeTextureMapper3D::Initialize(vtkRenderer *renderer) -{ - // GPU_INFO << "Initialize"; - - this->Initialized = 1; - // vtkOpenGLExtensionManager * extensions = vtkOpenGLExtensionManager::New(); - // extensions->SetRenderWindow(NULL); // set render window to the current one. - vtkOpenGLExtensionManager *extensions = - static_cast(renderer->GetRenderWindow())->GetExtensionManager(); - - int supports_texture3D = extensions->ExtensionSupported("GL_VERSION_1_2"); - if (supports_texture3D) - { - extensions->LoadExtension("GL_VERSION_1_2"); - } - else - { - supports_texture3D = extensions->ExtensionSupported("GL_EXT_texture3D"); - if (supports_texture3D) - { - extensions->LoadCorePromotedExtension("GL_EXT_texture3D"); - } - } - - int supports_multitexture = extensions->ExtensionSupported("GL_VERSION_1_3"); - if (supports_multitexture) - { - extensions->LoadExtension("GL_VERSION_1_3"); - } - else - { - supports_multitexture = extensions->ExtensionSupported("GL_ARB_multitexture"); - if (supports_multitexture) - { - extensions->LoadCorePromotedExtension("GL_ARB_multitexture"); - } - } - - this->SupportsCompressedTexture = extensions->ExtensionSupported("GL_VERSION_1_3") == 1; - if (!this->SupportsCompressedTexture) - { - this->SupportsCompressedTexture = extensions->ExtensionSupported("GL_ARB_texture_compression") == 1; - if (this->SupportsCompressedTexture) - { - extensions->LoadCorePromotedExtension("GL_ARB_texture_compression"); - } - } - // GPU_INFO(this->SupportsCompressedTexture) << "supporting compressed textures"; - - this->SupportsNonPowerOfTwoTextures = extensions->ExtensionSupported("GL_VERSION_2_0") || - extensions->ExtensionSupported("GL_ARB_texture_non_power_of_two"); - - // GPU_INFO << "np2: " << (this->SupportsNonPowerOfTwoTextures?1:0); - - int supports_GL_ARB_fragment_program = extensions->ExtensionSupported("GL_ARB_fragment_program"); - if (supports_GL_ARB_fragment_program) - { - extensions->LoadExtension("GL_ARB_fragment_program"); - } - - int supports_GL_ARB_vertex_program = extensions->ExtensionSupported("GL_ARB_vertex_program"); - if (supports_GL_ARB_vertex_program) - { - extensions->LoadExtension("GL_ARB_vertex_program"); - } - - RenderPossible = 0; - - if (supports_texture3D && supports_multitexture && supports_GL_ARB_fragment_program && - supports_GL_ARB_vertex_program && vtkgl::TexImage3D && vtkgl::ActiveTexture && vtkgl::MultiTexCoord3fv && - vtkgl::GenProgramsARB && vtkgl::DeleteProgramsARB && vtkgl::BindProgramARB && vtkgl::ProgramStringARB && - vtkgl::ProgramLocalParameter4fARB) - { - RenderPossible = 1; - } - else - { - std::string errString = - "no gpu-acceleration possible cause following extensions/methods are missing or unsupported:"; - if (!supports_texture3D) - errString += " EXT_TEXTURE3D"; - if (!supports_multitexture) - errString += " EXT_MULTITEXTURE"; - if (!supports_GL_ARB_fragment_program) - errString += " ARB_FRAGMENT_PROGRAM"; - if (!supports_GL_ARB_vertex_program) - errString += " ARB_VERTEX_PROGRAM"; - if (!vtkgl::TexImage3D) - errString += " glTexImage3D"; - if (!vtkgl::ActiveTexture) - errString += " glActiveTexture"; - if (!vtkgl::MultiTexCoord3fv) - errString += " glMultiTexCoord3fv"; - if (!vtkgl::GenProgramsARB) - errString += " glGenProgramsARB"; - if (!vtkgl::DeleteProgramsARB) - errString += " glDeleteProgramsARB"; - if (!vtkgl::BindProgramARB) - errString += " glBindProgramARB"; - if (!vtkgl::ProgramStringARB) - errString += " glProgramStringARB"; - if (!vtkgl::ProgramLocalParameter4fARB) - errString += " glProgramLocalParameter4fARB"; - GPU_WARN << errString; - }; - - if (RenderPossible) - { - vtkgl::GenProgramsARB(1, &prgOneComponentShade); - vtkgl::BindProgramARB(vtkgl::FRAGMENT_PROGRAM_ARB, prgOneComponentShade); - vtkgl::ProgramStringARB(vtkgl::FRAGMENT_PROGRAM_ARB, - vtkgl::PROGRAM_FORMAT_ASCII_ARB, - static_cast(strlen(vtkMitkVolumeTextureMapper3D_OneComponentShadeFP)), - vtkMitkVolumeTextureMapper3D_OneComponentShadeFP); - - vtkgl::GenProgramsARB(1, &prgRGBAShade); - vtkgl::BindProgramARB(vtkgl::FRAGMENT_PROGRAM_ARB, prgRGBAShade); - vtkgl::ProgramStringARB(vtkgl::FRAGMENT_PROGRAM_ARB, - vtkgl::PROGRAM_FORMAT_ASCII_ARB, - static_cast(strlen(vtkMitkVolumeTextureMapper3D_FourDependentShadeFP)), - vtkMitkVolumeTextureMapper3D_FourDependentShadeFP); - } -} - -// ---------------------------------------------------------------------------- -// Print the vtkMitkOpenGLVolumeTextureMapper3D -void vtkMitkOpenGLVolumeTextureMapper3D::PrintSelf(ostream &os, vtkIndent indent) -{ - // vtkOpenGLExtensionManager * extensions = vtkOpenGLExtensionManager::New(); - // extensions->SetRenderWindow(NULL); // set render window to current render window - - os << indent << "Initialized " << this->Initialized << endl; - /* if ( this->Initialized ) - { - os << indent << "Supports GL_VERSION_1_2:" - << extensions->ExtensionSupported( "GL_VERSION_1_2" ) << endl; - os << indent << "Supports GL_EXT_texture3D:" - << extensions->ExtensionSupported( "GL_EXT_texture3D" ) << endl; - os << indent << "Supports GL_VERSION_1_3:" - << extensions->ExtensionSupported( "GL_VERSION_1_3" ) << endl; - os << indent << "Supports GL_ARB_multitexture: " - << extensions->ExtensionSupported( "GL_ARB_multitexture" ) << endl; - os << indent << "Supports GL_NV_texture_shader2: " - << extensions->ExtensionSupported( "GL_NV_texture_shader2" ) << endl; - os << indent << "Supports GL_NV_register_combiners2: " - << extensions->ExtensionSupported( "GL_NV_register_combiners2" ) - << endl; - os << indent << "Supports GL_ATI_fragment_shader: " - << extensions->ExtensionSupported( "GL_ATI_fragment_shader" ) << endl; - os << indent << "Supports GL_ARB_fragment_program: " - << extensions->ExtensionSupported( "GL_ARB_fragment_program" ) << endl; - os << indent << "Supports GL_ARB_texture_compression: " - << extensions->ExtensionSupported( "GL_ARB_texture_compression" ) - << endl; - os << indent << "Supports GL_VERSION_2_0:" - << extensions->ExtensionSupported( "GL_VERSION_2_0" ) - << endl; - os << indent << "Supports GL_ARB_texture_non_power_of_two:" - << extensions->ExtensionSupported( "GL_ARB_texture_non_power_of_two" ) - << endl; - } - extensions->Delete(); - */ - - if (this->RenderWindow != 0) - { - vtkOpenGLExtensionManager *extensions = - static_cast(this->RenderWindow)->GetExtensionManager(); - - if (this->Initialized) - { - os << indent << "Supports GL_VERSION_1_2:" << extensions->ExtensionSupported("GL_VERSION_1_2") << endl; - os << indent << "Supports GL_EXT_texture3D:" << extensions->ExtensionSupported("GL_EXT_texture3D") << endl; - os << indent << "Supports GL_VERSION_1_3:" << extensions->ExtensionSupported("GL_VERSION_1_3") << endl; - os << indent << "Supports GL_ARB_multitexture: " << extensions->ExtensionSupported("GL_ARB_multitexture") << endl; - os << indent << "Supports GL_NV_texture_shader2: " << extensions->ExtensionSupported("GL_NV_texture_shader2") - << endl; - os << indent - << "Supports GL_NV_register_combiners2: " << extensions->ExtensionSupported("GL_NV_register_combiners2") - << endl; - os << indent << "Supports GL_ATI_fragment_shader: " << extensions->ExtensionSupported("GL_ATI_fragment_shader") - << endl; - os << indent << "Supports GL_ARB_fragment_program: " << extensions->ExtensionSupported("GL_ARB_fragment_program") - << endl; - os << indent - << "Supports GL_ARB_texture_compression: " << extensions->ExtensionSupported("GL_ARB_texture_compression") - << endl; - os << indent << "Supports GL_VERSION_2_0:" << extensions->ExtensionSupported("GL_VERSION_2_0") << endl; - os << indent << "Supports GL_ARB_texture_non_power_of_two:" - << extensions->ExtensionSupported("GL_ARB_texture_non_power_of_two") << endl; - } - } - - this->Superclass::PrintSelf(os, indent); -} diff --git a/Modules/MapperExt/src/vtkMitkVolumeTextureMapper3D.cpp b/Modules/MapperExt/src/vtkMitkVolumeTextureMapper3D.cpp deleted file mode 100644 index 0f47fee154..0000000000 --- a/Modules/MapperExt/src/vtkMitkVolumeTextureMapper3D.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/*=================================================================== - -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 "vtkMitkVolumeTextureMapper3D.h" -#include "mitkCommon.h" - -#define GPU_INFO MITK_INFO("mapper.vr") -#define GPU_WARN MITK_WARN("mapper.vr") - -#include "vtkCamera.h" -#include "vtkColorTransferFunction.h" -#include "vtkDataArray.h" -#include "vtkImageData.h" -#include "vtkMath.h" -#include "vtkMatrix4x4.h" -#include "vtkPiecewiseFunction.h" -#include "vtkPointData.h" -#include "vtkRenderer.h" -#include "vtkVolume.h" -#include "vtkVolumeProperty.h" -//#include "vtkVolumeRenderingFactory.h" //VTK6_TODO - -//---------------------------------------------------------------------------- -// Needed when we don't use the vtkStandardNewMacro. -vtkInstantiatorNewMacro(vtkMitkVolumeTextureMapper3D); -//---------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -vtkMitkVolumeTextureMapper3D::vtkMitkVolumeTextureMapper3D() -{ - // GPU_INFO << "vtkMitkVolumeTextureMapper3D"; - - this->PolygonBuffer = nullptr; - this->IntersectionBuffer = nullptr; - this->NumberOfPolygons = 0; - this->BufferSize = 0; - - // The input used when creating the textures - this->SavedTextureInput = nullptr; - - // The input used when creating the color tables - this->SavedParametersInput = nullptr; - - this->SavedRGBFunction = nullptr; - this->SavedGrayFunction = nullptr; - this->SavedScalarOpacityFunction = nullptr; - this->SavedGradientOpacityFunction = nullptr; - this->SavedColorChannels = 0; - this->SavedSampleDistance = 0; - this->SavedScalarOpacityDistance = 0; - - /* - this->Volume1 = NULL; - this->Volume2 = NULL; - this->Volume3 = NULL; - */ - /* - this->VolumeSize = 0; - this->VolumeComponents = 0; - */ - - this->VolumeSpacing[0] = this->VolumeSpacing[1] = this->VolumeSpacing[2] = 0; - this->VolumeDimensions[0] = 0; - this->VolumeDimensions[1] = 0; - this->VolumeDimensions[2] = 0; - - this->SampleDistance = 1.0; - this->ActualSampleDistance = 1.0; - - this->UseCompressedTexture = false; - this->SupportsNonPowerOfTwoTextures = false; - - // GPU_INFO << "np2: " << (this->SupportsNonPowerOfTwoTextures?1:0); -} - -//----------------------------------------------------------------------------- -vtkMitkVolumeTextureMapper3D::~vtkMitkVolumeTextureMapper3D() -{ - // GPU_INFO << "~vtkMitkVolumeTextureMapper3D"; - - delete[] this->PolygonBuffer; - delete[] this->IntersectionBuffer; - /* - delete [] this->Volume1; - delete [] this->Volume2; - delete [] this->Volume3; - */ -} - -//----------------------------------------------------------------------------- -// vtkMitkVolumeTextureMapper3D *vtkMitkVolumeTextureMapper3D::New() //VTK6_TODO -//{ -// //GPU_INFO << "New"; - -// // First try to create the object from the vtkObjectFactory -// vtkObject* ret = -// vtkVolumeRenderingFactory::CreateInstance("vtkMitkVolumeTextureMapper3D"); -// return static_cast(ret); -//} - -//----------------------------------------------------------------------------- -void vtkMitkVolumeTextureMapper3D::ComputePolygons(vtkRenderer *ren, vtkVolume *vol, double inBounds[6]) -{ - // GPU_INFO << "ComputePolygons"; - - // Get the camera position and focal point - double focalPoint[4], position[4]; - double plane[4]; - vtkCamera *camera = ren->GetActiveCamera(); - - camera->GetPosition(position); - camera->GetFocalPoint(focalPoint); - - position[3] = 1.0; - focalPoint[3] = 1.0; - - // Pass the focal point and position through the inverse of the - // volume's matrix to map back into the data coordinates. We - // are going to compute these polygons in the coordinate system - // of the input data - this is easiest since this data must be - // axis aligned. Then we'll use OpenGL to transform these polygons - // into the world coordinate system through the use of the - // volume's matrix. - vtkMatrix4x4 *matrix = vtkMatrix4x4::New(); - vol->GetMatrix(matrix); - matrix->Invert(); - matrix->MultiplyPoint(position, position); - matrix->MultiplyPoint(focalPoint, focalPoint); - matrix->Delete(); - - if (position[3]) - { - position[0] /= position[3]; - position[1] /= position[3]; - position[2] /= position[3]; - } - - if (focalPoint[3]) - { - focalPoint[0] /= focalPoint[3]; - focalPoint[1] /= focalPoint[3]; - focalPoint[2] /= focalPoint[3]; - } - - // Create a plane equation using the direction and position of the camera - plane[0] = focalPoint[0] - position[0]; - plane[1] = focalPoint[1] - position[1]; - plane[2] = focalPoint[2] - position[2]; - - vtkMath::Normalize(plane); - - plane[3] = -(plane[0] * position[0] + plane[1] * position[1] + plane[2] * position[2]); - - // Find the min and max distances of the boundary points of the volume - double minDistance = VTK_DOUBLE_MAX; - double maxDistance = VTK_DOUBLE_MIN; - - // The inBounds parameter is the bounds we are using for clipping the - // texture planes against. First we need to clip these against the bounds - // of the volume to make sure they don't exceed it. - double volBounds[6]; - this->GetInput()->GetBounds(volBounds); - - double bounds[6]; - bounds[0] = (inBounds[0] > volBounds[0]) ? (inBounds[0]) : (volBounds[0]); - bounds[1] = (inBounds[1] < volBounds[1]) ? (inBounds[1]) : (volBounds[1]); - bounds[2] = (inBounds[2] > volBounds[2]) ? (inBounds[2]) : (volBounds[2]); - bounds[3] = (inBounds[3] < volBounds[3]) ? (inBounds[3]) : (volBounds[3]); - bounds[4] = (inBounds[4] > volBounds[4]) ? (inBounds[4]) : (volBounds[4]); - bounds[5] = (inBounds[5] < volBounds[5]) ? (inBounds[5]) : (volBounds[5]); - - // Create 8 vertices for the bounding box we are rendering - int i, j, k; - double vertices[8][3]; - - int idx = 0; - - for (k = 0; k < 2; k++) - { - for (j = 0; j < 2; j++) - { - for (i = 0; i < 2; i++) - { - vertices[idx][2] = bounds[4 + k]; - vertices[idx][1] = bounds[2 + j]; - vertices[idx][0] = bounds[i]; - - double d = plane[0] * vertices[idx][0] + plane[1] * vertices[idx][1] + plane[2] * vertices[idx][2] + plane[3]; - - idx++; - - // Keep track of closest and farthest point - minDistance = (d < minDistance) ? (d) : (minDistance); - maxDistance = (d > maxDistance) ? (d) : (maxDistance); - } - } - } - - int dim[6]; - this->GetVolumeDimensions(dim); - - float tCoordOffset[3], tCoordScale[3]; - - tCoordOffset[0] = 0.5 / dim[0]; - tCoordOffset[1] = 0.5 / dim[1]; - tCoordOffset[2] = 0.5 / dim[2]; - - tCoordScale[0] = (dim[0] - 1) / static_cast(dim[0]); - tCoordScale[1] = (dim[1] - 1) / static_cast(dim[1]); - tCoordScale[2] = (dim[2] - 1) / static_cast(dim[2]); - - float spacing[3]; - this->GetVolumeSpacing(spacing); - - double offset = 0.333 * 0.5 * (spacing[0] + spacing[1] + spacing[2]); - - minDistance += 0.1 * offset; - maxDistance -= 0.1 * offset; - - minDistance = (minDistance < offset) ? (offset) : (minDistance); - - double stepSize = this->ActualSampleDistance; - - // Determine the number of polygons - int numPolys = static_cast((maxDistance - minDistance) / static_cast(stepSize)); - - // Check if we have space, free old space only if it is too small - if (this->BufferSize < numPolys) - { - delete[] this->PolygonBuffer; - delete[] this->IntersectionBuffer; - - this->BufferSize = numPolys; - - this->PolygonBuffer = new float[36 * this->BufferSize]; - this->IntersectionBuffer = new float[12 * this->BufferSize]; - } - - this->NumberOfPolygons = numPolys; - - // Compute the intersection points for each edge of the volume - int lines[12][2] = {{0, 1}, {1, 3}, {2, 3}, {0, 2}, {4, 5}, {5, 7}, {6, 7}, {4, 6}, {0, 4}, {1, 5}, {3, 7}, {2, 6}}; - - float *iptr, *pptr; - - for (i = 0; i < 12; i++) - { - double line[3]; - - line[0] = vertices[lines[i][1]][0] - vertices[lines[i][0]][0]; - line[1] = vertices[lines[i][1]][1] - vertices[lines[i][0]][1]; - line[2] = vertices[lines[i][1]][2] - vertices[lines[i][0]][2]; - - double d = maxDistance; - - iptr = this->IntersectionBuffer + i; - - double planeDotLineOrigin = vtkMath::Dot(plane, vertices[lines[i][0]]); - double planeDotLine = vtkMath::Dot(plane, line); - - double t, increment; - - if (planeDotLine != 0.0) - { - t = (d - planeDotLineOrigin - plane[3]) / planeDotLine; - increment = -stepSize / planeDotLine; - } - else - { - t = -1.0; - increment = 0.0; - } - - for (j = 0; j < numPolys; j++) - { - *iptr = (t > 0.0 && t < 1.0) ? (t) : (-1.0); - - t += increment; - iptr += 12; - } - } - - // Compute the polygons by determining which edges were intersected - int neighborLines[12][6] = {{1, 2, 3, 4, 8, 9}, - {0, 2, 3, 5, 9, 10}, - {0, 1, 3, 6, 10, 11}, - {0, 1, 2, 7, 8, 11}, - {0, 5, 6, 7, 8, 9}, - {1, 4, 6, 7, 9, 10}, - {2, 4, 5, 7, 10, 11}, - {3, 4, 5, 6, 8, 11}, - {0, 3, 4, 7, 9, 11}, - {0, 1, 4, 5, 8, 10}, - {1, 2, 5, 6, 9, 11}, - {2, 3, 6, 7, 8, 10}}; - - float tCoord[12][4] = {{0, 0, 0, 0}, - {1, 0, 0, 1}, - {0, 1, 0, 0}, - {0, 0, 0, 1}, - {0, 0, 1, 0}, - {1, 0, 1, 1}, - {0, 1, 1, 0}, - {0, 0, 1, 1}, - {0, 0, 0, 2}, - {1, 0, 0, 2}, - {1, 1, 0, 2}, - {0, 1, 0, 2}}; - - double low[3]; - double high[3]; - - low[0] = (bounds[0] - volBounds[0]) / (volBounds[1] - volBounds[0]); - high[0] = (bounds[1] - volBounds[0]) / (volBounds[1] - volBounds[0]); - low[1] = (bounds[2] - volBounds[2]) / (volBounds[3] - volBounds[2]); - high[1] = (bounds[3] - volBounds[2]) / (volBounds[3] - volBounds[2]); - low[2] = (bounds[4] - volBounds[4]) / (volBounds[5] - volBounds[4]); - high[2] = (bounds[5] - volBounds[4]) / (volBounds[5] - volBounds[4]); - - for (i = 0; i < 12; i++) - { - tCoord[i][0] = (tCoord[i][0]) ? (high[0]) : (low[0]); - tCoord[i][1] = (tCoord[i][1]) ? (high[1]) : (low[1]); - tCoord[i][2] = (tCoord[i][2]) ? (high[2]) : (low[2]); - } - - iptr = this->IntersectionBuffer; - pptr = this->PolygonBuffer; - - for (i = 0; i < numPolys; i++) - { - // Look for a starting point - int start = 0; - - while (start < 12 && iptr[start] == -1.0) - { - start++; - } - - if (start == 12) - { - pptr[0] = -1.0; - } - else - { - int current = start; - int previous = -1; - int errFlag = 0; - - idx = 0; - - while (idx < 6 && !errFlag && (idx == 0 || current != start)) - { - double t = iptr[current]; - - *(pptr + idx * 6) = tCoord[current][0] * tCoordScale[0] + tCoordOffset[0]; - *(pptr + idx * 6 + 1) = tCoord[current][1] * tCoordScale[1] + tCoordOffset[1]; - *(pptr + idx * 6 + 2) = tCoord[current][2] * tCoordScale[2] + tCoordOffset[2]; - - int coord = static_cast(tCoord[current][3]); - *(pptr + idx * 6 + coord) = - (low[coord] + t * (high[coord] - low[coord])) * tCoordScale[coord] + tCoordOffset[coord]; - - *(pptr + idx * 6 + 3) = static_cast( - vertices[lines[current][0]][0] + t * (vertices[lines[current][1]][0] - vertices[lines[current][0]][0])); - - *(pptr + idx * 6 + 4) = static_cast( - vertices[lines[current][0]][1] + t * (vertices[lines[current][1]][1] - vertices[lines[current][0]][1])); - - *(pptr + idx * 6 + 5) = static_cast( - vertices[lines[current][0]][2] + t * (vertices[lines[current][1]][2] - vertices[lines[current][0]][2])); - - idx++; - - j = 0; - - while (j < 6 && (*(this->IntersectionBuffer + i * 12 + neighborLines[current][j]) < 0 || - neighborLines[current][j] == previous)) - { - j++; - } - - if (j >= 6) - { - errFlag = 1; - } - else - { - previous = current; - current = neighborLines[current][j]; - } - } - - if (idx < 6) - { - *(pptr + idx * 6) = -1; - } - } - - iptr += 12; - pptr += 36; - } -} - -void vtkMitkVolumeTextureMapper3D::UpdateMTime() -{ - this->SavedTextureMTime.Modified(); -} - -//----------------------------------------------------------------------------- -int vtkMitkVolumeTextureMapper3D::UpdateColorLookup(vtkVolume *vol) -{ - // GPU_INFO << "UpdateColorLookup"; - - int needToUpdate = 0; - - // Get the image data - vtkImageData *input = this->GetInput(); - Update(); - - // Has the volume changed in some way? - if (this->SavedParametersInput != input || this->SavedParametersMTime.GetMTime() < input->GetMTime()) - { - needToUpdate = 1; - } - - // What sample distance are we going to use for rendering? If we - // have to render quickly according to our allocated render time, - // don't necessary obey the sample distance requested by the user. - // Instead set the sample distance to the average spacing. - this->ActualSampleDistance = this->SampleDistance; - if (vol->GetAllocatedRenderTime() < 1.0) - { - float spacing[3]; - this->GetVolumeSpacing(spacing); - this->ActualSampleDistance = - 0.333 * (static_cast(spacing[0]) + static_cast(spacing[1]) + static_cast(spacing[2])); - } - - // How many components? - int components = input->GetNumberOfScalarComponents(); - - // Has the sample distance changed? - if (this->SavedSampleDistance != this->ActualSampleDistance) - { - needToUpdate = 1; - } - - vtkColorTransferFunction *rgbFunc = nullptr; - vtkPiecewiseFunction *grayFunc = nullptr; - - // How many color channels for this component? - int colorChannels = vol->GetProperty()->GetColorChannels(0); - - if (components < 3) - { - // Has the number of color channels changed? - if (this->SavedColorChannels != colorChannels) - { - needToUpdate = 1; - } - - // Has the color transfer function changed in some way, - // and we are using it? - if (colorChannels == 3) - { - rgbFunc = vol->GetProperty()->GetRGBTransferFunction(0); - if (this->SavedRGBFunction != rgbFunc || this->SavedParametersMTime.GetMTime() < rgbFunc->GetMTime()) - { - needToUpdate = 1; - } - } - - // Has the gray transfer function changed in some way, - // and we are using it? - if (colorChannels == 1) - { - grayFunc = vol->GetProperty()->GetGrayTransferFunction(0); - if (this->SavedGrayFunction != grayFunc || this->SavedParametersMTime.GetMTime() < grayFunc->GetMTime()) - { - needToUpdate = 1; - } - } - } - - // Has the scalar opacity transfer function changed in some way? - vtkPiecewiseFunction *scalarOpacityFunc = vol->GetProperty()->GetScalarOpacity(0); - if (this->SavedScalarOpacityFunction != scalarOpacityFunc || - this->SavedParametersMTime.GetMTime() < scalarOpacityFunc->GetMTime()) - { - needToUpdate = 1; - } - - // Has the gradient opacity transfer function changed in some way? - vtkPiecewiseFunction *gradientOpacityFunc = vol->GetProperty()->GetGradientOpacity(0); - if (this->SavedGradientOpacityFunction != gradientOpacityFunc || - this->SavedParametersMTime.GetMTime() < gradientOpacityFunc->GetMTime()) - { - needToUpdate = 1; - } - - double scalarOpacityDistance = vol->GetProperty()->GetScalarOpacityUnitDistance(0); - if (this->SavedScalarOpacityDistance != scalarOpacityDistance) - { - needToUpdate = 1; - } - - // If we have not found any need to update, return now - if (!needToUpdate) - { - return 0; - } - - this->SavedRGBFunction = rgbFunc; - this->SavedGrayFunction = grayFunc; - this->SavedScalarOpacityFunction = scalarOpacityFunc; - this->SavedGradientOpacityFunction = gradientOpacityFunc; - this->SavedColorChannels = colorChannels; - this->SavedSampleDistance = this->ActualSampleDistance; - this->SavedScalarOpacityDistance = scalarOpacityDistance; - this->SavedParametersInput = input; - - this->SavedParametersMTime.Modified(); - - // Find the scalar range - double scalarRange[2]; - input->GetPointData()->GetScalars()->GetRange(scalarRange, components - 1); - - int arraySizeNeeded = this->ColorTableSize; - - if (components < 3) - { - // Sample the transfer functions between the min and max. - if (colorChannels == 1) - { - grayFunc->GetTable(scalarRange[0], scalarRange[1], arraySizeNeeded, this->TempArray1); - } - else - { - rgbFunc->GetTable(scalarRange[0], scalarRange[1], arraySizeNeeded, this->TempArray1); - } - } - - scalarOpacityFunc->GetTable(scalarRange[0], scalarRange[1], arraySizeNeeded, this->TempArray2); - - float goArray[256]; - gradientOpacityFunc->GetTable(0, (scalarRange[1] - scalarRange[0]) * 0.25, 256, goArray); - - // Correct the opacity array for the spacing between the planes. - int i; - - float *fptr2 = this->TempArray2; - double factor = this->ActualSampleDistance / scalarOpacityDistance; - for (i = 0; i < arraySizeNeeded; i++) - { - if (*fptr2 > 0.0001) - { - *fptr2 = 1.0 - pow(static_cast(1.0 - (*fptr2)), factor); - } - fptr2++; - } - - int goLoop; - unsigned char *ptr, *rgbptr, *aptr; - float *fptr1; - - switch (components) - { - case 1: - // Move the two temp float arrays into one RGBA unsigned char array - ptr = this->ColorLookup; - for (goLoop = 0; goLoop < 256; goLoop++) - { - fptr1 = this->TempArray1; - fptr2 = this->TempArray2; - if (colorChannels == 1) - { - for (i = 0; i < arraySizeNeeded; i++) - { - *(ptr++) = static_cast(*(fptr1)*255.0 + 0.5); - *(ptr++) = static_cast(*(fptr1)*255.0 + 0.5); - *(ptr++) = static_cast(*(fptr1++) * 255.0 + 0.5); - *(ptr++) = static_cast(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5); - } - } - else - { - for (i = 0; i < arraySizeNeeded; i++) - { - *(ptr++) = static_cast(*(fptr1++) * 255.0 + 0.5); - *(ptr++) = static_cast(*(fptr1++) * 255.0 + 0.5); - *(ptr++) = static_cast(*(fptr1++) * 255.0 + 0.5); - *(ptr++) = static_cast(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5); - } - } - - for (; i < 256; i++) - { - *(ptr++) = 0; - *(ptr++) = 0; - *(ptr++) = 0; - *(ptr++) = 0; - } - } - break; - - case 2: - // Move the two temp float arrays into one RGB unsigned char array and - // one alpha array. - rgbptr = this->ColorLookup; - aptr = this->AlphaLookup; - - if (colorChannels == 1) - { - for (i = 0; i < arraySizeNeeded; i++) - { - fptr1 = this->TempArray1; - fptr2 = this->TempArray2; - for (goLoop = 0; goLoop < 256; goLoop++) - { - *(rgbptr++) = static_cast(*(fptr1)*255.0 + 0.5); - *(rgbptr++) = static_cast(*(fptr1)*255.0 + 0.5); - *(rgbptr++) = static_cast(*(fptr1++) * 255.0 + 0.5); - *(aptr++) = static_cast(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5); - } - } - } - else - { - fptr1 = this->TempArray1; - fptr2 = this->TempArray2; - for (i = 0; i < arraySizeNeeded; i++) - { - for (goLoop = 0; goLoop < 256; goLoop++) - { - *(rgbptr++) = static_cast(*(fptr1)*255.0 + 0.5); - *(rgbptr++) = static_cast(*(fptr1 + 1) * 255.0 + 0.5); - *(rgbptr++) = static_cast(*(fptr1 + 2) * 255.0 + 0.5); - *(aptr++) = static_cast(*(fptr2)*goArray[goLoop] * 255.0 + 0.5); - } - fptr1 += 3; - fptr2++; - } - } - - for (; i < 256; i++) - { - for (goLoop = 0; goLoop < 256; goLoop++) - { - *(rgbptr++) = 0; - *(rgbptr++) = 0; - *(rgbptr++) = 0; - *(aptr++) = 0; - } - } - break; - - case 3: - case 4: - // Move the two temp float arrays into one alpha array - aptr = this->AlphaLookup; - - for (goLoop = 0; goLoop < 256; goLoop++) - { - fptr2 = this->TempArray2; - for (i = 0; i < arraySizeNeeded; i++) - { - *(aptr++) = static_cast(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5); - } - for (; i < 256; i++) - { - *(aptr++) = 0; - } - } - - break; - } - return 1; -} - -//----------------------------------------------------------------------------- -// Print the vtkMitkVolumeTextureMapper3D -void vtkMitkVolumeTextureMapper3D::PrintSelf(ostream &os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); - - os << indent << "Sample Distance: " << this->SampleDistance << endl; - os << indent << "NumberOfPolygons: " << this->NumberOfPolygons << endl; - os << indent << "ActualSampleDistance: " << this->ActualSampleDistance << endl; - os << indent << "VolumeDimensions: " << this->VolumeDimensions[0] << " " << this->VolumeDimensions[1] << " " - << this->VolumeDimensions[2] << endl; - os << indent << "VolumeSpacing: " << this->VolumeSpacing[0] << " " << this->VolumeSpacing[1] << " " - << this->VolumeSpacing[2] << endl; - - os << indent << "UseCompressedTexture: " << this->UseCompressedTexture << endl; -} diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 6ee8f22a2b..89fc1a74f5 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,83 +1,83 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(mitk_modules Core CommandLine AppUtil DCMTesting RDF LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction LegacyAdaptors SceneSerialization Gizmo GraphAlgorithms Multilabel ImageStatistics ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation - OpenViewCore + #OpenViewCore QtWidgets QtWidgetsExt C3js QmlItems SegmentationUI DiffusionImaging GPGPU OpenIGTLink IGTBase IGT CameraCalibration RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI VtkShaders DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware Classification TumorInvasionAnalysis MatchPointRegistration MatchPointRegistrationUI BoundingShape RenderWindowManager RenderWindowManagerUI ) if(MITK_ENABLE_PIC_READER) list(APPEND mitk_modules IpPicSupportIO) endif() diff --git a/Modules/OpenViewCore/QVTKQuickItem.cxx b/Modules/OpenViewCore/QVTKQuickItem.cxx new file mode 100644 index 0000000000..d08007fdce --- /dev/null +++ b/Modules/OpenViewCore/QVTKQuickItem.cxx @@ -0,0 +1,374 @@ +/*======================================================================== + OpenView -- http://openview.kitware.com + + Copyright 2012 Kitware, Inc. + + Licensed under the BSD license. See LICENSE file for details. + ========================================================================*/ +#include "QVTKQuickItem.h" +#include + +#include +#include +#include +#include +#include +#include + +#include "QVTKInteractor.h" +#include "QVTKInteractorAdapter.h" +#include "vtkGenericOpenGLRenderWindow.h" +#include "vtkEventQtSlotConnect.h" +#include "vtkRenderer.h" +#include "vtkRendererCollection.h" + +#include "vtkCubeSource.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" + +#include + +QVTKQuickItem::QVTKQuickItem(QQuickItem* parent) +:QQuickItem(parent) +,m_InitCalledOnce(false) +{ + setFlag(ItemHasContents); + setAcceptHoverEvents(true); + setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton); + + m_interactor = vtkSmartPointer::New(); + m_interactorAdapter = new QVTKInteractorAdapter(NULL); + m_interactorAdapter->moveToThread(this->thread()); + m_interactorAdapter->setParent(this); + m_connect = vtkSmartPointer::New(); + //m_connect->Connect(m_interactor, vtkCommand::RenderEvent, this, SLOT(paint())); + vtkSmartPointer win = vtkSmartPointer::New(); + this->SetRenderWindow(win); + this->geometryChanged(QRectF(x(), y(), width(), height()), QRectF(0, 0, 100, 100)); +} + +QVTKQuickItem::~QVTKQuickItem() +{ + this->SetRenderWindow(0); +} + +void QVTKQuickItem::SetRenderWindow(vtkGenericOpenGLRenderWindow* win) +{ + if(m_win) + { + m_win->SetMapped(0); + //m_connect->Disconnect(m_win, vtkCommand::StartEvent, this, SLOT(Start())); + //m_connect->Disconnect(m_win, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent())); + //m_connect->Disconnect(m_win, vtkCommand::EndEvent, this, SLOT(End())); + //m_connect->Disconnect(m_win, vtkCommand::WindowFrameEvent, this, SLOT(Update())); + m_connect->Disconnect(m_win, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*))); + m_connect->Disconnect(m_win, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*))); + m_connect->Disconnect(m_win, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*))); + } + + m_interactor->SetRenderWindow(win); + m_win = win; + m_interactor->Initialize(); + + if(m_win) + { + m_win->SetMapped(1); + m_win->SetDoubleBuffer(0); + m_win->SetFrontBuffer(COLOR_ATTACHMENT0_EXT); + m_win->SetFrontLeftBuffer(vtkgl::COLOR_ATTACHMENT0_EXT); + m_win->SetBackBuffer(vtkgl::COLOR_ATTACHMENT0_EXT); + m_win->SetBackLeftBuffer(vtkgl::COLOR_ATTACHMENT0_EXT); + + //m_connect->Connect(m_win, vtkCommand::StartEvent, this, SLOT(Start())); + //m_connect->Connect(m_win, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent())); + //m_connect->Connect(m_win, vtkCommand::EndEvent, this, SLOT(End())); + //m_connect->Connect(m_win, vtkCommand::WindowFrameEvent, this, SLOT(Update())); + // Qt::DirectConnection in order to execute callback immediately. + // This avoids an error when vtkTexture attempts to query driver features and it is unable to determine "IsCurrent" + m_connect->Connect(m_win, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)), NULL, 0.0, Qt::DirectConnection); + m_connect->Connect(m_win, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)), NULL, 0.0, Qt::DirectConnection); + m_connect->Connect(m_win, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)), NULL, 0.0, Qt::DirectConnection); + } +} + +vtkGenericOpenGLRenderWindow* QVTKQuickItem::GetRenderWindow() const +{ + return m_win; +} + +QVTKInteractor* QVTKQuickItem::GetInteractor() const +{ + return m_interactor; +} + +void QVTKQuickItem::itemChange(ItemChange change, const ItemChangeData &) +{ + // The ItemSceneChange event is sent when we are first attached to a canvas. + if (change == ItemSceneChange) { + QQuickWindow *c = window(); + if (!c) + { + return; + } + + // Connect our the beforeRendering signal to our paint function. + // Since this call is executed on the rendering thread it must be + // a Qt::DirectConnection + connect(c, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection); + + // If we allow QML to do the clearing, they would clear what we paint + // and nothing would show. + c->setClearBeforeRendering(false); + } +} + +void QVTKQuickItem::MakeCurrent() +{ + if (!this->window()) + { + m_win->SetAbortRender(1); + cerr << "Could not make current since there is no canvas!" << endl; + return; + } + if (QThread::currentThread() != this->window()->openglContext()->thread()) + { + m_win->SetAbortRender(1); + cerr << "Could not make current since we are on the wrong thread!" << endl; + return; + } + this->window()->openglContext()->makeCurrent(this->window()); +} + +void QVTKQuickItem::Start() +{ + MakeCurrent(); + + if (!m_win->GetAbortRender()) + { + m_win->PushState(); + m_win->OpenGLInitState(); + } +} + +void QVTKQuickItem::End() +{ + if (!m_win->GetAbortRender()) + { + m_win->PopState(); + } + +} + +void QVTKQuickItem::IsCurrent(vtkObject*, unsigned long, void*, void* call_data) +{ + bool* ptr = reinterpret_cast(call_data); + *ptr = QOpenGLContext::currentContext() == this->window()->openglContext(); +} + +void QVTKQuickItem::IsDirect(vtkObject*, unsigned long, void*, void* call_data) +{ + int* ptr = reinterpret_cast(call_data); + *ptr = 1; +} + +void QVTKQuickItem::SupportsOpenGL(vtkObject*, unsigned long, void*, void* call_data) +{ + int* ptr = reinterpret_cast(call_data); + *ptr = true; + //*ptr = QGLFormat::hasOpenGL(); +} + +void QVTKQuickItem::geometryChanged(const QRectF & newGeometry, const QRectF & oldGeometry) +{ + QQuickItem::geometryChanged(newGeometry, oldGeometry); + QSize oldSize(oldGeometry.width(), oldGeometry.height()); + QSize newSize(newGeometry.width(), newGeometry.height()); + QResizeEvent e(newSize, oldSize); + if (m_interactorAdapter) + { + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(&e, m_interactor); + this->m_viewLock.unlock(); + } + if(m_win.GetPointer() && window()) + { + this->m_viewLock.lock(); + m_win->SetSize(window()->width(), window()->height()); + QPointF origin = mapToScene(QPointF(0, 0)); + QPointF minPt(origin.x()/window()->width(), (window()->height() - origin.y() - height())/window()->height()); + QPointF maxPt(minPt.x() + width()/window()->width(), minPt.y() + height()/window()->height()); + if (m_win->GetRenderers()->GetFirstRenderer()) + { + m_win->GetRenderers()->GetFirstRenderer()->SetViewport(minPt.x(), minPt.y(), maxPt.x(), maxPt.y()); + } + this->m_viewLock.unlock(); + update(); + } +} + +void QVTKQuickItem::keyPressEvent(QKeyEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::keyReleaseEvent(QKeyEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::mousePressEvent(QMouseEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::mouseReleaseEvent(QMouseEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::mouseDoubleClickEvent(QMouseEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::mouseMoveEvent(QMouseEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::wheelEvent(QWheelEvent* e) +{ + e->accept(); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(e, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::hoverEnterEvent(QHoverEvent* e) +{ + e->accept(); + QEvent e2(QEvent::Enter); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(&e2, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::hoverLeaveEvent(QHoverEvent* e) +{ + e->accept(); + QEvent e2(QEvent::Leave); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(&e2, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::hoverMoveEvent(QHoverEvent* e) +{ + e->accept(); + QMouseEvent e2(QEvent::MouseMove, e->pos(), Qt::NoButton, Qt::NoButton, e->modifiers()); + this->m_viewLock.lock(); + m_interactorAdapter->ProcessEvent(&e2, m_interactor); + this->m_viewLock.unlock(); + update(); +} + +void QVTKQuickItem::init() +{ +} + +void QVTKQuickItem::prepareForRender() +{ +} + +void QVTKQuickItem::cleanupAfterRender() +{ +} + +QSGNode* QVTKQuickItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) +{ + QSGSimpleRectNode *n = static_cast(oldNode); + if (!n) { + n = new QSGSimpleRectNode(); + } + n->markDirty(QSGNode::DirtyForceUpdate); + return n; +} + + +void QVTKQuickItem::paint() +{ + if (!this->isVisible()) + { + return; + } + + if (!this->m_InitCalledOnce) + { + m_win->GetExtensionManager()->LoadExtension("GL_VERSION_1_4"); + m_win->GetExtensionManager()->LoadExtension("GL_VERSION_2_0"); + + init(); + + this->m_InitCalledOnce = true; + } + + this->m_viewLock.lock(); + + // Let subclasses do something each render + prepareForRender(); + + // Make sure viewport is up to date. + // This is needed because geometryChanged() is not called when parent geometry changes, so we miss when widths/heights + // of surrounding elements change. + m_win->SetSize(window()->width(), window()->height()); + QPointF origin = mapToScene(QPointF(0, 0)); + QPointF minPt(origin.x()/window()->width(), (window()->height() - origin.y() - height())/window()->height()); + QPointF maxPt(minPt.x() + width()/window()->width(), minPt.y() + height()/window()->height()); + if (m_win->GetRenderers()->GetFirstRenderer()) + { + m_win->GetRenderers()->GetFirstRenderer()->SetViewport(minPt.x(), minPt.y(), maxPt.x(), maxPt.y()); + } + + // Turn off any QML shader program + vtkgl::UseProgram(0); + + // Set blending correctly + glEnable(GL_BLEND); + vtkgl::BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + m_win->Render(); + + // Disable alpha test for QML + glDisable(GL_ALPHA_TEST); + + cleanupAfterRender(); + + this->m_viewLock.unlock(); +} diff --git a/Modules/QtWidgets/CMakeLists.txt b/Modules/QtWidgets/CMakeLists.txt index 65a44f75f5..7307928e23 100644 --- a/Modules/QtWidgets/CMakeLists.txt +++ b/Modules/QtWidgets/CMakeLists.txt @@ -1,9 +1,9 @@ MITK_CREATE_MODULE( INCLUDE_DIRS PRIVATE resource # for xpm includes DEPENDS MitkPlanarFigure MitkAnnotation PACKAGE_DEPENDS - PUBLIC ITK|ITKIOImageBase VTK|vtkGUISupportQt+vtkGUISupportQtOpenGL Qt5|Widgets+OpenGL+Core + PUBLIC ITK|ITKIOImageBase VTK|vtkGUISupportQt Qt5|Widgets+OpenGL+Core SUBPROJECTS MITK-CoreUI ) add_subdirectory(test) diff --git a/Modules/VtkShaders/src/mitkVtkShaderProgram.cpp b/Modules/VtkShaders/src/mitkVtkShaderProgram.cpp index b4ba043fe7..70aeeec8ee 100644 --- a/Modules/VtkShaders/src/mitkVtkShaderProgram.cpp +++ b/Modules/VtkShaders/src/mitkVtkShaderProgram.cpp @@ -1,58 +1,58 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkShaderProgram.h" -#include "vtkShader2.h" +#include "vtkShader.h" mitk::VtkShaderProgram::VtkShaderProgram() : m_VtkShaderProgram(NULL) { } mitk::VtkShaderProgram::~VtkShaderProgram() { } void mitk::VtkShaderProgram::Activate() { if (m_VtkShaderProgram) { - m_VtkShaderProgram->Use(); +// m_VtkShaderProgram->Use(); //TODO 18922 } } void mitk::VtkShaderProgram::Deactivate() { if (m_VtkShaderProgram) { - m_VtkShaderProgram->Restore(); +// m_VtkShaderProgram->Restore(); //TODO 18922 } } -void mitk::VtkShaderProgram::SetVtkShaderProgram(vtkSmartPointer p) +void mitk::VtkShaderProgram::SetVtkShaderProgram(vtkSmartPointer p) { m_VtkShaderProgram = p; } -vtkSmartPointer mitk::VtkShaderProgram::GetVtkShaderProgram() const +vtkSmartPointer mitk::VtkShaderProgram::GetVtkShaderProgram() const { return m_VtkShaderProgram; } itk::TimeStamp &mitk::VtkShaderProgram::GetShaderTimestampUpdate() { return m_ShaderTimestampUpdate; } diff --git a/Modules/VtkShaders/src/mitkVtkShaderProgram.h b/Modules/VtkShaders/src/mitkVtkShaderProgram.h index 816c04a619..013a780d83 100644 --- a/Modules/VtkShaders/src/mitkVtkShaderProgram.h +++ b/Modules/VtkShaders/src/mitkVtkShaderProgram.h @@ -1,58 +1,62 @@ /*=================================================================== 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 _MITKVTKSHADERPROGRAM_H_ #define _MITKVTKSHADERPROGRAM_H_ #include -#include +#include #include -namespace mitk +namespace mitk { + +/** + * \brief SHADERTODO + */ +class VtkShaderProgram : public IShaderRepository::ShaderProgram { +public: + + mitkClassMacro( VtkShaderProgram, IShaderRepository::ShaderProgram ) + itkFactorylessNewMacro( Self ) + + /** + * Constructor + */ + VtkShaderProgram(); + /** - * \brief SHADERTODO + * Destructor */ - class VtkShaderProgram : public IShaderRepository::ShaderProgram - { - public: - mitkClassMacro(VtkShaderProgram, IShaderRepository::ShaderProgram) itkFactorylessNewMacro(Self) - - /** - * Constructor - */ - VtkShaderProgram(); - - /** - * Destructor - */ - virtual ~VtkShaderProgram(); - - virtual void Activate() override; - virtual void Deactivate() override; - - void SetVtkShaderProgram(vtkSmartPointer p); - vtkSmartPointer GetVtkShaderProgram() const; - itk::TimeStamp &GetShaderTimestampUpdate(); - - private: - vtkSmartPointer m_VtkShaderProgram; - itk::TimeStamp m_ShaderTimestampUpdate; - }; - -} // end of namespace mitk + virtual ~VtkShaderProgram(); + + virtual void Activate() override; + virtual void Deactivate() override; + + void SetVtkShaderProgram(vtkSmartPointer p); + vtkSmartPointer GetVtkShaderProgram() const; + itk::TimeStamp& GetShaderTimestampUpdate(); + +private: + + vtkSmartPointer m_VtkShaderProgram; + itk::TimeStamp m_ShaderTimestampUpdate; + +}; + +} //end of namespace mitk #endif diff --git a/Modules/VtkShaders/src/mitkVtkShaderRepository.cpp b/Modules/VtkShaders/src/mitkVtkShaderRepository.cpp index 0fb77d6f76..c331847014 100644 --- a/Modules/VtkShaders/src/mitkVtkShaderRepository.cpp +++ b/Modules/VtkShaders/src/mitkVtkShaderRepository.cpp @@ -1,644 +1,617 @@ /*=================================================================== 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 SR_INFO MITK_INFO("shader.repository") #define SR_WARN MITK_WARN("shader.repository") #define SR_ERROR MITK_ERROR("shader.repository") #include "mitkVtkShaderRepository.h" -#include "mitkDataNode.h" -#include "mitkProperties.h" -#include "mitkShaderProperty.h" #include "mitkVtkShaderProgram.h" +#include "mitkShaderProperty.h" +#include "mitkProperties.h" +#include "mitkDataNode.h" -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include int mitk::VtkShaderRepository::shaderId = 0; const bool mitk::VtkShaderRepository::debug = false; mitk::VtkShaderRepository::VtkShaderRepository() { LoadShaders(); } mitk::VtkShaderRepository::~VtkShaderRepository() { } mitk::IShaderRepository::ShaderProgram::Pointer mitk::VtkShaderRepository::CreateShaderProgram() { mitk::IShaderRepository::ShaderProgram::Pointer shaderProg = (mitk::VtkShaderProgram::New()).GetPointer(); return shaderProg; } void mitk::VtkShaderRepository::LoadShaders() { itk::Directory::Pointer dir = itk::Directory::New(); std::string dirPath = "./vtk_shader"; - if (dir->Load(dirPath.c_str())) + if( dir->Load( dirPath.c_str() ) ) { int n = dir->GetNumberOfFiles(); - for (int r = 0; r < n; r++) + for(int r=0;rGetFile(r); + const char *filename = dir->GetFile( r ); std::string extension = itksys::SystemTools::GetFilenameExtension(filename); - if (extension.compare(".xml") == 0) + if(extension.compare(".xml")==0) { - Shader::Pointer element = Shader::New(); + Shader::Pointer element=Shader::New(); element->SetName(itksys::SystemTools::GetFilenameWithoutExtension(filename)); std::string filePath = dirPath + std::string("/") + element->GetName() + std::string(".xml"); SR_INFO(debug) << "found shader '" << element->GetName() << "'"; std::ifstream fileStream(filePath.c_str()); element->LoadXmlShader(fileStream); shaders.push_back(element); } } } } mitk::VtkShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShaderImpl(const std::string &name) const { std::list::const_iterator i = shaders.begin(); - while (i != shaders.end()) + while( i != shaders.end() ) { - if ((*i)->GetName() == name) + if( (*i)->GetName() == name) return (*i); i++; } return Shader::Pointer(); } -int mitk::VtkShaderRepository::LoadShader(std::istream &stream, const std::string &filename) +int mitk::VtkShaderRepository::LoadShader(std::istream& stream, const std::string& filename) { - Shader::Pointer element = Shader::New(); + Shader::Pointer element=Shader::New(); element->SetName(filename); element->SetId(shaderId++); element->LoadXmlShader(stream); shaders.push_back(element); SR_INFO(debug) << "found shader '" << element->GetName() << "'"; return element->GetId(); } bool mitk::VtkShaderRepository::UnloadShader(int id) { - for (std::list::iterator i = shaders.begin(); i != shaders.end(); ++i) + for (std::list::iterator i = shaders.begin(); + i != shaders.end(); ++i) { if ((*i)->GetId() == id) { shaders.erase(i); return true; } } return false; } mitk::VtkShaderRepository::Shader::Shader() { } mitk::VtkShaderRepository::Shader::~Shader() { } -void mitk::VtkShaderRepository::Shader::SetVertexShaderCode(const std::string &code) +void mitk::VtkShaderRepository::Shader::SetVertexShaderCode(const std::string& code) { this->m_VertexShaderCode = code; } std::string mitk::VtkShaderRepository::Shader::GetVertexShaderCode() const { return this->m_VertexShaderCode; } -void mitk::VtkShaderRepository::Shader::SetFragmentShaderCode(const std::string &code) +void mitk::VtkShaderRepository::Shader::SetFragmentShaderCode(const std::string& code) { this->m_FragmentShaderCode = code; } std::string mitk::VtkShaderRepository::Shader::GetFragmentShaderCode() const { return this->m_FragmentShaderCode; } -void mitk::VtkShaderRepository::Shader::SetGeometryShaderCode(const std::string &code) +void mitk::VtkShaderRepository::Shader::SetGeometryShaderCode(const std::string& code) { this->m_GeometryShaderCode = code; } std::string mitk::VtkShaderRepository::Shader::GetGeometryShaderCode() const { return this->m_GeometryShaderCode; } std::list mitk::VtkShaderRepository::Shader::GetUniforms() const { return uniforms; } -void mitk::VtkShaderRepository::Shader::LoadXmlShader(std::istream &stream) +void mitk::VtkShaderRepository::Shader::LoadXmlShader(std::istream& stream) { std::string content; content.reserve(2048); char buffer[2048]; while (stream.read(buffer, sizeof(buffer))) { content.append(buffer, sizeof(buffer)); } content.append(buffer, static_cast(stream.gcount())); - if (content.empty()) - return; + if (content.empty()) return; this->SetMaterialXml(content); - vtkXMLMaterialParser *parser = vtkXMLMaterialParser::New(); - vtkXMLMaterial *material = vtkXMLMaterial::New(); + vtkXMLMaterialParser* parser = vtkXMLMaterialParser::New(); + vtkXMLMaterial* material = vtkXMLMaterial::New(); parser->SetMaterial(material); parser->Parse(content.c_str()); parser->Delete(); - if (material == NULL) - return; + if (material == NULL) return; // Vertexshader uniforms { - vtkXMLShader *s = material->GetVertexShader(); + vtkXMLShader *s=material->GetVertexShader(); if (s) { SetVertexShaderCode(s->GetCode()); - vtkXMLDataElement *x = s->GetRootElement(); - int n = x->GetNumberOfNestedElements(); - for (int r = 0; r < n; r++) + vtkXMLDataElement *x=s->GetRootElement(); + int n=x->GetNumberOfNestedElements(); + for(int r=0;rGetNestedElement(r); - if (strcmp(y->GetName(), "ApplicationUniform") == 0 || strcmp(y->GetName(), "Uniform") == 0) + vtkXMLDataElement *y=x->GetNestedElement(r); + if(strcmp(y->GetName(),"ApplicationUniform") == 0 || + strcmp(y->GetName(), "Uniform") == 0) { - Uniform::Pointer element = Uniform::New(); + Uniform::Pointer element=Uniform::New(); element->LoadFromXML(y); uniforms.push_back(element); } } } } // Fragmentshader uniforms { - vtkXMLShader *s = material->GetFragmentShader(); + vtkXMLShader *s=material->GetFragmentShader(); if (s) { SetFragmentShaderCode(s->GetCode()); - vtkXMLDataElement *x = s->GetRootElement(); - int n = x->GetNumberOfNestedElements(); - for (int r = 0; r < n; r++) + vtkXMLDataElement *x=s->GetRootElement(); + int n=x->GetNumberOfNestedElements(); + for(int r=0;rGetNestedElement(r); - if (strcmp(y->GetName(), "ApplicationUniform") == 0 || strcmp(y->GetName(), "Uniform") == 0) + vtkXMLDataElement *y=x->GetNestedElement(r); + if(strcmp(y->GetName(),"ApplicationUniform") == 0 || + strcmp(y->GetName(), "Uniform") == 0) { - Uniform::Pointer element = Uniform::New(); + Uniform::Pointer element=Uniform::New(); element->LoadFromXML(y); uniforms.push_back(element); } } } } // Geometryshader uniforms { - vtkXMLShader *s = material->GetGeometryShader(); + vtkXMLShader *s=material->GetGeometryShader(); if (s) { SetGeometryShaderCode(s->GetCode()); - vtkXMLDataElement *x = s->GetRootElement(); - int n = x->GetNumberOfNestedElements(); - for (int r = 0; r < n; r++) + vtkXMLDataElement *x=s->GetRootElement(); + int n=x->GetNumberOfNestedElements(); + for(int r=0;rGetNestedElement(r); - if (strcmp(y->GetName(), "ApplicationUniform") == 0 || strcmp(y->GetName(), "Uniform") == 0) + vtkXMLDataElement *y=x->GetNestedElement(r); + if(strcmp(y->GetName(),"ApplicationUniform") == 0 || + strcmp(y->GetName(), "Uniform") == 0) { - Uniform::Pointer element = Uniform::New(); + Uniform::Pointer element=Uniform::New(); element->LoadFromXML(y); uniforms.push_back(element); } } } } material->Delete(); + } mitk::VtkShaderRepository::Shader::Uniform::Uniform() { } mitk::VtkShaderRepository::Shader::Uniform::~Uniform() { } void mitk::VtkShaderRepository::Shader::Uniform::LoadFromXML(vtkXMLDataElement *y) { - // MITK_INFO << "found uniform '" << y->GetAttribute("name") << "' type=" << y->GetAttribute("type");// << " default=" - // << y->GetAttribute("value"); + //MITK_INFO << "found uniform '" << y->GetAttribute("name") << "' type=" << y->GetAttribute("type");// << " default=" << y->GetAttribute("value"); name = y->GetAttribute("name"); - const char *sType = y->GetAttribute("type"); - - if (!strcmp(sType, "float")) - type = glsl_float; - else if (!strcmp(sType, "vec2")) - type = glsl_vec2; - else if (!strcmp(sType, "vec3")) - type = glsl_vec3; - else if (!strcmp(sType, "vec4")) - type = glsl_vec4; - else if (!strcmp(sType, "int")) - type = glsl_int; - else if (!strcmp(sType, "ivec2")) - type = glsl_ivec2; - else if (!strcmp(sType, "ivec3")) - type = glsl_ivec3; - else if (!strcmp(sType, "ivec4")) - type = glsl_ivec4; + const char *sType=y->GetAttribute("type"); + + if(!strcmp(sType,"float")) + type=glsl_float; + else if(!strcmp(sType,"vec2")) + type=glsl_vec2; + else if(!strcmp(sType,"vec3")) + type=glsl_vec3; + else if(!strcmp(sType,"vec4")) + type=glsl_vec4; + else if(!strcmp(sType,"int")) + type=glsl_int; + else if(!strcmp(sType,"ivec2")) + type=glsl_ivec2; + else if(!strcmp(sType,"ivec3")) + type=glsl_ivec3; + else if(!strcmp(sType,"ivec4")) + type=glsl_ivec4; else { - type = glsl_none; - SR_WARN << "unknown type for uniform '" << name << "'"; + type=glsl_none; + SR_WARN << "unknown type for uniform '" << name << "'" ; } - defaultFloat[0] = defaultFloat[1] = defaultFloat[2] = defaultFloat[3] = 0; - const char *sDefault = y->GetAttribute("value"); + defaultFloat[0]=defaultFloat[1]=defaultFloat[2]=defaultFloat[3]=0; - if (sDefault) + const char *sDefault=y->GetAttribute("value"); + + if(sDefault) { - switch (type) + switch(type) { - case glsl_float: - sscanf(sDefault, "%f", &defaultFloat[0]); - break; + case glsl_float: + sscanf(sDefault,"%f",&defaultFloat[0]); + break; - case glsl_vec2: - sscanf(sDefault, "%f %f", &defaultFloat[0], &defaultFloat[1]); - break; + case glsl_vec2: + sscanf(sDefault,"%f %f",&defaultFloat[0],&defaultFloat[1]); + break; - case glsl_vec3: - sscanf(sDefault, "%f %f %f", &defaultFloat[0], &defaultFloat[1], &defaultFloat[2]); - break; + case glsl_vec3: + sscanf(sDefault,"%f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2]); + break; - case glsl_vec4: - sscanf(sDefault, "%f %f %f %f", &defaultFloat[0], &defaultFloat[1], &defaultFloat[2], &defaultFloat[3]); - break; + case glsl_vec4: + sscanf(sDefault,"%f %f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2],&defaultFloat[3]); + break; - case glsl_int: - sscanf(sDefault, "%d", &defaultInt[0]); - break; + case glsl_int: + sscanf(sDefault,"%d",&defaultInt[0]); + break; - case glsl_ivec2: - sscanf(sDefault, "%d %d", &defaultInt[0], &defaultInt[1]); - break; + case glsl_ivec2: + sscanf(sDefault,"%d %d",&defaultInt[0],&defaultInt[1]); + break; - case glsl_ivec3: - sscanf(sDefault, "%d %d %d", &defaultInt[0], &defaultInt[1], &defaultInt[2]); - break; + case glsl_ivec3: + sscanf(sDefault,"%d %d %d",&defaultInt[0],&defaultInt[1],&defaultInt[2]); + break; - case glsl_ivec4: - sscanf(sDefault, "%d %d %d %d", &defaultInt[0], &defaultInt[1], &defaultInt[2], &defaultInt[3]); - break; + case glsl_ivec4: + sscanf(sDefault,"%d %d %d %d",&defaultInt[0],&defaultInt[1],&defaultInt[2],&defaultInt[3]); + break; - case glsl_none: - break; + case glsl_none: + break; } } } -void mitk::VtkShaderRepository::AddDefaultProperties(mitk::DataNode *node, - mitk::BaseRenderer *renderer, - bool overwrite) const +void mitk::VtkShaderRepository::AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) const { - node->AddProperty("shader", mitk::ShaderProperty::New(), renderer, overwrite); + node->AddProperty( "shader", mitk::ShaderProperty::New(), renderer, overwrite ); std::list::const_iterator i = shaders.begin(); - while (i != shaders.end()) + while( i != shaders.end() ) { std::list uniforms = (*i)->GetUniforms(); std::string shaderName = (*i)->GetName(); std::list::const_iterator j = uniforms.begin(); - while (j != uniforms.end()) + while( j != uniforms.end() ) { std::string propertyName = "shader." + shaderName + "." + (*j)->name; - switch ((*j)->type) + switch( (*j)->type ) { case Shader::Uniform::glsl_float: - node->AddProperty(propertyName.c_str(), mitk::FloatProperty::New((*j)->defaultFloat[0]), renderer, overwrite); + node->AddProperty( propertyName.c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); break; case Shader::Uniform::glsl_vec2: - node->AddProperty( - (propertyName + ".x").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[0]), renderer, overwrite); - node->AddProperty( - (propertyName + ".y").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[1]), renderer, overwrite); + node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); + node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite ); break; case Shader::Uniform::glsl_vec3: - node->AddProperty( - (propertyName + ".x").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[0]), renderer, overwrite); - node->AddProperty( - (propertyName + ".y").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[1]), renderer, overwrite); - node->AddProperty( - (propertyName + ".z").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[2]), renderer, overwrite); + node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); + node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite ); + node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite ); break; - case Shader::Uniform::glsl_vec4: - node->AddProperty( - (propertyName + ".x").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[0]), renderer, overwrite); - node->AddProperty( - (propertyName + ".y").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[1]), renderer, overwrite); - node->AddProperty( - (propertyName + ".z").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[2]), renderer, overwrite); - node->AddProperty( - (propertyName + ".w").c_str(), mitk::FloatProperty::New((*j)->defaultFloat[3]), renderer, overwrite); + case Shader::Uniform::glsl_vec4: + node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); + node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite ); + node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite ); + node->AddProperty( (propertyName+".w").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[3] ), renderer, overwrite ); break; - case Shader::Uniform::glsl_int: - node->AddProperty(propertyName.c_str(), mitk::IntProperty::New((*j)->defaultInt[0]), renderer, overwrite); + case Shader::Uniform::glsl_int: + node->AddProperty( propertyName.c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite ); break; - case Shader::Uniform::glsl_ivec2: - node->AddProperty( - (propertyName + ".x").c_str(), mitk::IntProperty::New((*j)->defaultInt[0]), renderer, overwrite); - node->AddProperty( - (propertyName + ".y").c_str(), mitk::IntProperty::New((*j)->defaultInt[1]), renderer, overwrite); + case Shader::Uniform::glsl_ivec2: + node->AddProperty( (propertyName+".x").c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite ); + node->AddProperty( (propertyName+".y").c_str(), mitk::IntProperty::New( (*j)->defaultInt[1] ), renderer, overwrite ); break; case Shader::Uniform::glsl_ivec3: - node->AddProperty( - (propertyName + ".x").c_str(), mitk::IntProperty::New((*j)->defaultInt[0]), renderer, overwrite); - node->AddProperty( - (propertyName + ".y").c_str(), mitk::IntProperty::New((*j)->defaultInt[1]), renderer, overwrite); - node->AddProperty( - (propertyName + ".z").c_str(), mitk::IntProperty::New((*j)->defaultInt[2]), renderer, overwrite); + node->AddProperty( (propertyName+".x").c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite ); + node->AddProperty( (propertyName+".y").c_str(), mitk::IntProperty::New( (*j)->defaultInt[1] ), renderer, overwrite ); + node->AddProperty( (propertyName+".z").c_str(), mitk::IntProperty::New( (*j)->defaultInt[2] ), renderer, overwrite ); break; - case Shader::Uniform::glsl_ivec4: - node->AddProperty( - (propertyName + ".x").c_str(), mitk::IntProperty::New((*j)->defaultInt[0]), renderer, overwrite); - node->AddProperty( - (propertyName + ".y").c_str(), mitk::IntProperty::New((*j)->defaultInt[1]), renderer, overwrite); - node->AddProperty( - (propertyName + ".z").c_str(), mitk::IntProperty::New((*j)->defaultInt[2]), renderer, overwrite); - node->AddProperty( - (propertyName + ".w").c_str(), mitk::IntProperty::New((*j)->defaultInt[3]), renderer, overwrite); + case Shader::Uniform::glsl_ivec4: + node->AddProperty( (propertyName+".x").c_str(), mitk::IntProperty::New( (*j)->defaultInt[0] ), renderer, overwrite ); + node->AddProperty( (propertyName+".y").c_str(), mitk::IntProperty::New( (*j)->defaultInt[1] ), renderer, overwrite ); + node->AddProperty( (propertyName+".z").c_str(), mitk::IntProperty::New( (*j)->defaultInt[2] ), renderer, overwrite ); + node->AddProperty( (propertyName+".w").c_str(), mitk::IntProperty::New( (*j)->defaultInt[3] ), renderer, overwrite ); break; - case Shader::Uniform::glsl_none: + case Shader::Uniform::glsl_none: break; } j++; + } i++; } + + } std::list mitk::VtkShaderRepository::GetShaders() const { std::list result; - for (std::list::const_iterator i = shaders.begin(); i != shaders.end(); ++i) + for (std::list::const_iterator i = shaders.begin(); + i != shaders.end(); ++i) { result.push_back(i->GetPointer()); } return result; } -mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(const std::string &name) const +mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(const std::string& name) const { - for (std::list::const_iterator i = shaders.begin(); i != shaders.end(); ++i) + for (std::list::const_iterator i = shaders.begin(); + i != shaders.end(); ++i) { - if ((*i)->GetName() == name) - return i->GetPointer(); + if ((*i)->GetName() == name) return i->GetPointer(); } return IShaderRepository::Shader::Pointer(); } mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(int id) const { - for (std::list::const_iterator i = shaders.begin(); i != shaders.end(); ++i) + for (std::list::const_iterator i = shaders.begin(); + i != shaders.end(); ++i) { - if ((*i)->GetId() == id) - return i->GetPointer(); + if ((*i)->GetId() == id) return i->GetPointer(); } return IShaderRepository::Shader::Pointer(); } -void mitk::VtkShaderRepository::UpdateShaderProgram(ShaderProgram *shaderProgram, - DataNode *node, - BaseRenderer *renderer) const +void +mitk::VtkShaderRepository::UpdateShaderProgram(ShaderProgram* shaderProgram, + DataNode* node, BaseRenderer* renderer) const { - VtkShaderProgram *mitkVtkShaderProgram = dynamic_cast(shaderProgram); - mitk::ShaderProperty *sep = dynamic_cast(node->GetProperty("shader", renderer)); - if (!sep) + VtkShaderProgram* mitkVtkShaderProgram = dynamic_cast(shaderProgram); + mitk::ShaderProperty *sep= dynamic_cast(node->GetProperty("shader",renderer)); + if(!sep) { mitkVtkShaderProgram->SetVtkShaderProgram(0); return; } Shader::Pointer s = GetShaderImpl(sep->GetValueAsString()); // Need update pipeline mode - if (sep->GetMTime() > mitkVtkShaderProgram->GetShaderTimestampUpdate().GetMTime()) + if(sep->GetMTime() > mitkVtkShaderProgram->GetShaderTimestampUpdate().GetMTime()) { - if (s.IsNull()) + if( s.IsNull() ) { mitkVtkShaderProgram->SetVtkShaderProgram(0); mitkVtkShaderProgram->GetShaderTimestampUpdate().Modified(); return; } - vtkSmartPointer program = vtkSmartPointer::New(); -#if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0))) - program->SetContext(dynamic_cast(renderer->GetRenderWindow())); -#else - program->SetContext(renderer->GetRenderWindow()); -#endif + vtkSmartPointer program = vtkSmartPointer::New(); + +// program->SetContext(renderer->GetRenderWindow());//TODO 18922 // The vertext shader - vtkShader2 *shader = vtkShader2::New(); - shader->SetType(VTK_SHADER_TYPE_VERTEX); - shader->SetSourceCode(s->GetVertexShaderCode().c_str()); -#if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0))) - shader->SetContext(dynamic_cast(renderer->GetRenderWindow())); -#else - shader->SetContext(renderer->GetRenderWindow()); -#endif - program->GetShaders()->AddItem(shader); + vtkShader *shader = vtkShader::New(); +// shader->SetType(VTK_SHADER_TYPE_VERTEX);//TODO 18922 +// shader->SetSourceCode(s->GetVertexShaderCode().c_str());//TODO 18922 +// shader->SetContext(renderer->GetRenderWindow());//TODO 18922 +// program->GetShaders()->AddItem(shader);//TODO 18922 shader->Delete(); // The fragment shader - shader = vtkShader2::New(); - shader->SetType(VTK_SHADER_TYPE_FRAGMENT); - shader->SetSourceCode(s->GetFragmentShaderCode().c_str()); -#if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0))) - shader->SetContext(dynamic_cast(renderer->GetRenderWindow())); -#else - shader->SetContext(renderer->GetRenderWindow()); -#endif - program->GetShaders()->AddItem(shader); + shader = vtkShader::New(); +// shader->SetType(VTK_SHADER_TYPE_FRAGMENT);//TODO 18922 +// shader->SetSourceCode(s->GetFragmentShaderCode().c_str());//TODO 18922 +// shader->SetContext(renderer->GetRenderWindow());//TODO 18922 +// program->GetShaders()->AddItem(shader);//TODO 18922 shader->Delete(); - if (s->GetGeometryShaderCode().size() > 0) + if(s->GetGeometryShaderCode().size()>0) { - // The Geometry shader - shader = vtkShader2::New(); - shader->SetType(VTK_SHADER_TYPE_GEOMETRY); - shader->SetSourceCode(s->GetGeometryShaderCode().c_str()); -#if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0))) - shader->SetContext(dynamic_cast(renderer->GetRenderWindow())); -#else - shader->SetContext(renderer->GetRenderWindow()); -#endif - program->GetShaders()->AddItem(shader); - shader->Delete(); + // The Geometry shader + shader = vtkShader::New(); +// shader->SetType(VTK_SHADER_TYPE_GEOMETRY);//TODO 18922 +// shader->SetSourceCode(s->GetGeometryShaderCode().c_str());//TODO 18922 +// shader->SetContext(renderer->GetRenderWindow());//TODO 18922 +// program->GetShaders()->AddItem(shader);//TODO 18922 + shader->Delete(); } - program->Build(); +// program->Build();//TODO 18922 mitkVtkShaderProgram->SetVtkShaderProgram(program); mitkVtkShaderProgram->GetShaderTimestampUpdate().Modified(); } - if (s.IsNull()) + if(s.IsNull()) return; // update uniforms - vtkShaderProgram2 *p = mitkVtkShaderProgram->GetVtkShaderProgram(); + vtkShaderProgram *p = mitkVtkShaderProgram->GetVtkShaderProgram(); - if (!p) + if(!p) return; std::list::const_iterator j = s->uniforms.begin(); - while (j != s->uniforms.end()) + while( j != s->uniforms.end() ) { std::string propertyName = "shader." + s->GetName() + "." + (*j)->name; // MITK_INFO << "querying property: " << propertyName; // mitk::BaseProperty *p = node->GetProperty( propertyName.c_str(), renderer ); // if( p && p->GetMTime() > MTime.GetMTime() ) { float fval[4]; int ival[4]; // MITK_INFO << "copying property " << propertyName << " ->->- " << (*j)->name << " type=" << (*j)->type ; - switch ((*j)->type) + + switch( (*j)->type ) { - case Shader::Uniform::glsl_float: - node->GetFloatProperty(propertyName.c_str(), fval[0], renderer); - p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 1, fval); - break; + case Shader::Uniform::glsl_float: + node->GetFloatProperty( propertyName.c_str(), fval[0], renderer ); +// p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 1, fval);//TODO 18922 + break; - case Shader::Uniform::glsl_vec2: - node->GetFloatProperty((propertyName + ".x").c_str(), fval[0], renderer); - node->GetFloatProperty((propertyName + ".y").c_str(), fval[1], renderer); - p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 2, fval); - break; + case Shader::Uniform::glsl_vec2: + node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); + node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); +// p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 2, fval);//TODO 18922 + break; - case Shader::Uniform::glsl_vec3: - node->GetFloatProperty((propertyName + ".x").c_str(), fval[0], renderer); - node->GetFloatProperty((propertyName + ".y").c_str(), fval[1], renderer); - node->GetFloatProperty((propertyName + ".z").c_str(), fval[2], renderer); - // p->SetUniform3f( (*j)->name.c_str(), fval ); - p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 3, fval); - break; + case Shader::Uniform::glsl_vec3: + node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); + node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); + node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer ); + //p->SetUniform3f( (*j)->name.c_str(), fval );//TODO 18922 +// p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 3, fval);//TODO 18922 + break; - case Shader::Uniform::glsl_vec4: - node->GetFloatProperty((propertyName + ".x").c_str(), fval[0], renderer); - node->GetFloatProperty((propertyName + ".y").c_str(), fval[1], renderer); - node->GetFloatProperty((propertyName + ".z").c_str(), fval[2], renderer); - node->GetFloatProperty((propertyName + ".w").c_str(), fval[3], renderer); - p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 4, fval); - break; + case Shader::Uniform::glsl_vec4: + node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); + node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); + node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer ); + node->GetFloatProperty( (propertyName+".w").c_str(), fval[3], renderer ); +// p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 4, fval);//TODO 18922 + break; - case Shader::Uniform::glsl_int: - node->GetIntProperty(propertyName.c_str(), ival[0], renderer); - p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 1, ival); - break; + case Shader::Uniform::glsl_int: + node->GetIntProperty( propertyName.c_str(), ival[0], renderer ); +// p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 1, ival);//TODO 18922 + break; - case Shader::Uniform::glsl_ivec2: - node->GetIntProperty((propertyName + ".x").c_str(), ival[0], renderer); - node->GetIntProperty((propertyName + ".y").c_str(), ival[1], renderer); - p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 2, ival); - break; + case Shader::Uniform::glsl_ivec2: + node->GetIntProperty( (propertyName+".x").c_str(), ival[0], renderer ); + node->GetIntProperty( (propertyName+".y").c_str(), ival[1], renderer ); +// p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 2, ival);//TODO 18922 + break; - case Shader::Uniform::glsl_ivec3: - node->GetIntProperty((propertyName + ".x").c_str(), ival[0], renderer); - node->GetIntProperty((propertyName + ".y").c_str(), ival[1], renderer); - node->GetIntProperty((propertyName + ".z").c_str(), ival[2], renderer); - // p->SetUniform3f( (*j)->name.c_str(), fval ); - p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 3, ival); - break; + case Shader::Uniform::glsl_ivec3: + node->GetIntProperty( (propertyName+".x").c_str(), ival[0], renderer ); + node->GetIntProperty( (propertyName+".y").c_str(), ival[1], renderer ); + node->GetIntProperty( (propertyName+".z").c_str(), ival[2], renderer ); + //p->SetUniform3f( (*j)->name.c_str(), fval ); +// p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 3, ival); //TODO 18922 + break; - case Shader::Uniform::glsl_ivec4: - node->GetIntProperty((propertyName + ".x").c_str(), ival[0], renderer); - node->GetIntProperty((propertyName + ".y").c_str(), ival[1], renderer); - node->GetIntProperty((propertyName + ".z").c_str(), ival[2], renderer); - node->GetIntProperty((propertyName + ".w").c_str(), ival[3], renderer); - p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 4, ival); - break; + case Shader::Uniform::glsl_ivec4: + node->GetIntProperty( (propertyName+".x").c_str(), ival[0], renderer ); + node->GetIntProperty( (propertyName+".y").c_str(), ival[1], renderer ); + node->GetIntProperty( (propertyName+".z").c_str(), ival[2], renderer ); + node->GetIntProperty( (propertyName+".w").c_str(), ival[3], renderer ); +// p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 4, ival); //TODO 18922 + break; + + case Shader::Uniform::glsl_none: + break; - case Shader::Uniform::glsl_none: - break; } } j++; } return; } diff --git a/Modules/VtkShaders/src/mitkVtkShaderRepository.h b/Modules/VtkShaders/src/mitkVtkShaderRepository.h index 01f67664e7..14e77220ba 100644 --- a/Modules/VtkShaders/src/mitkVtkShaderRepository.h +++ b/Modules/VtkShaders/src/mitkVtkShaderRepository.h @@ -1,164 +1,164 @@ /*=================================================================== 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 _MITKVTKSHADERREPOSITORY_H_ #define _MITKVTKSHADERREPOSITORY_H_ #include "mitkIShaderRepository.h" -#include +#include #include class vtkXMLDataElement; class vtkXMLMaterial; class vtkProperty; namespace mitk { /** * \brief Management class for vtkShader XML descriptions. * * Looks for all XML shader files in a given directory and adds default properties * for each shader object (shader uniforms) to the specified mitk::DataNode. * * Additionally, it provides a utility function for applying properties for shaders * in mappers. */ class VtkShaderRepository : public IShaderRepository { protected: class Shader : public IShaderRepository::Shader { public: mitkClassMacro(Shader, IShaderRepository::Shader) itkFactorylessNewMacro(Self) class Uniform : public itk::Object { public: mitkClassMacroItkParent(Uniform, itk::Object) itkFactorylessNewMacro(Self) enum Type { glsl_none, glsl_float, glsl_vec2, glsl_vec3, glsl_vec4, glsl_int, glsl_ivec2, glsl_ivec3, glsl_ivec4 }; /** * Constructor */ Uniform(); /** * Destructor */ ~Uniform(); Type type; std::string name; int defaultInt[4]; float defaultFloat[4]; void LoadFromXML(vtkXMLDataElement *e); }; std::list uniforms; /** * Constructor */ Shader(); /** * Destructor */ ~Shader(); void SetVertexShaderCode(const std::string &code); std::string GetVertexShaderCode() const; void SetFragmentShaderCode(const std::string &code); std::string GetFragmentShaderCode() const; void SetGeometryShaderCode(const std::string &code); std::string GetGeometryShaderCode() const; std::list GetUniforms() const; private: friend class VtkShaderRepository; std::string m_VertexShaderCode; std::string m_FragmentShaderCode; std::string m_GeometryShaderCode; void LoadXmlShader(std::istream &stream); }; void LoadShaders(); Shader::Pointer GetShaderImpl(const std::string &name) const; private: std::list shaders; static int shaderId; static const bool debug; public: /** * Constructor */ VtkShaderRepository(); /** * Destructor */ ~VtkShaderRepository(); ShaderProgram::Pointer CreateShaderProgram() override; std::list GetShaders() const override; IShaderRepository::Shader::Pointer GetShader(const std::string &name) const override; IShaderRepository::Shader::Pointer GetShader(int id) const override; /** \brief Adds all parsed shader uniforms to property list of the given DataNode; * used by mappers. */ void AddDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite) const override; /** \brief Applies shader and shader specific variables of the specified DataNode * to the VTK object by updating the shader variables of its vtkProperty. */ int LoadShader(std::istream &stream, const std::string &name) override; bool UnloadShader(int id) override; void UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram *shaderProgram, DataNode *node, BaseRenderer *renderer) const override; }; } // end of namespace mitk #endif diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp index b2e4641fb1..a6c2a72e00 100755 --- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp +++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp @@ -1,350 +1,338 @@ /*=================================================================== 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 "QmitkVolumeVisualizationView.h" #include #include #include #include #include //#include #include #include #include #include #include #include #include "mitkHistogramGenerator.h" #include "QmitkPiecewiseFunctionCanvas.h" #include "QmitkColorTransferFunctionCanvas.h" #include "mitkBaseRenderer.h" #include "mitkVtkVolumeRenderingProperty.h" #include #include const std::string QmitkVolumeVisualizationView::VIEW_ID = "org.mitk.views.volumevisualization"; enum RenderMode { RM_CPU_COMPOSITE_RAYCAST = 0, RM_CPU_MIP_RAYCAST = 1, RM_GPU_COMPOSITE_SLICING = 2, RM_GPU_COMPOSITE_RAYCAST = 3, RM_GPU_MIP_RAYCAST = 4 }; QmitkVolumeVisualizationView::QmitkVolumeVisualizationView() : QmitkAbstractView(), m_Controls(NULL) { } QmitkVolumeVisualizationView::~QmitkVolumeVisualizationView() { } void QmitkVolumeVisualizationView::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { m_Controls = new Ui::QmitkVolumeVisualizationViewControls; m_Controls->setupUi(parent); // Fill the tf presets in the generator widget std::vector names; mitk::TransferFunctionInitializer::GetPresetNames(names); for (std::vector::const_iterator it = names.begin(); it != names.end(); ++it) { m_Controls->m_TransferFunctionGeneratorWidget->AddPreset(QString::fromStdString(*it)); } m_Controls->m_RenderMode->addItem("CPU raycast"); m_Controls->m_RenderMode->addItem("CPU MIP raycast"); m_Controls->m_RenderMode->addItem("GPU slicing"); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_Controls->m_RenderMode->addItem("GPU raycast"); m_Controls->m_RenderMode->addItem("GPU MIP raycast"); -#endif connect( m_Controls->m_EnableRenderingCB, SIGNAL( toggled(bool) ),this, SLOT( OnEnableRendering(bool) )); connect( m_Controls->m_EnableLOD, SIGNAL( toggled(bool) ),this, SLOT( OnEnableLOD(bool) )); connect( m_Controls->m_RenderMode, SIGNAL( activated(int) ),this, SLOT( OnRenderMode(int) )); connect( m_Controls->m_TransferFunctionGeneratorWidget, SIGNAL( SignalUpdateCanvas( ) ), m_Controls->m_TransferFunctionWidget, SLOT( OnUpdateCanvas( ) ) ); connect( m_Controls->m_TransferFunctionGeneratorWidget, SIGNAL(SignalTransferFunctionModeChanged(int)), SLOT(OnMitkInternalPreset(int))); m_Controls->m_EnableRenderingCB->setEnabled(false); m_Controls->m_EnableLOD->setEnabled(false); m_Controls->m_RenderMode->setEnabled(false); m_Controls->m_TransferFunctionWidget->setEnabled(false); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false); m_Controls->m_SelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); } } void QmitkVolumeVisualizationView::OnMitkInternalPreset( int mode ) { if (m_SelectedNode.IsNull()) return; mitk::DataNode::Pointer node(m_SelectedNode.GetPointer()); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction")) { //first item is only information if( --mode == -1 ) return; // -- Creat new TransferFunction mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(transferFuncProp->GetValue()); tfInit->SetTransferFunctionMode(mode); RequestRenderWindowUpdate(); m_Controls->m_TransferFunctionWidget->OnUpdateCanvas(); } } void QmitkVolumeVisualizationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { bool weHadAnImageButItsNotThreeDeeOrFourDee = false; mitk::DataNode::Pointer node; foreach (mitk::DataNode::Pointer currentNode, nodes) { if( currentNode.IsNotNull() && dynamic_cast(currentNode->GetData()) ) { if( dynamic_cast(currentNode->GetData())->GetDimension()>=3 ) { if (node.IsNull()) { node = currentNode; } } else { weHadAnImageButItsNotThreeDeeOrFourDee = true; } } } if( node.IsNotNull() ) { m_Controls->m_NoSelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); m_Controls->m_SelectedImageLabel->show(); std::string infoText; if (node->GetName().empty()) infoText = std::string("Selected Image: [currently selected image has no name]"); else infoText = std::string("Selected Image: ") + node->GetName(); m_Controls->m_SelectedImageLabel->setText( QString( infoText.c_str() ) ); m_SelectedNode = node; } else { if(weHadAnImageButItsNotThreeDeeOrFourDee) { m_Controls->m_NoSelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->show(); std::string infoText; infoText = std::string("only 3D or 4D images are supported"); m_Controls->m_ErrorImageLabel->setText( QString( infoText.c_str() ) ); } else { m_Controls->m_SelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); m_Controls->m_NoSelectedImageLabel->show(); } m_SelectedNode = 0; } UpdateInterface(); } void QmitkVolumeVisualizationView::UpdateInterface() { if(m_SelectedNode.IsNull()) { // turnoff all m_Controls->m_EnableRenderingCB->setChecked(false); m_Controls->m_EnableRenderingCB->setEnabled(false); m_Controls->m_EnableLOD->setChecked(false); m_Controls->m_EnableLOD->setEnabled(false); m_Controls->m_RenderMode->setCurrentIndex(0); m_Controls->m_RenderMode->setEnabled(false); m_Controls->m_TransferFunctionWidget->SetDataNode(0); m_Controls->m_TransferFunctionWidget->setEnabled(false); m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(0); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false); return; } bool enabled = false; m_SelectedNode->GetBoolProperty("volumerendering",enabled); m_Controls->m_EnableRenderingCB->setEnabled(true); m_Controls->m_EnableRenderingCB->setChecked(enabled); if(!enabled) { // turnoff all except volumerendering checkbox m_Controls->m_EnableLOD->setChecked(false); m_Controls->m_EnableLOD->setEnabled(false); m_Controls->m_RenderMode->setCurrentIndex(0); m_Controls->m_RenderMode->setEnabled(false); m_Controls->m_TransferFunctionWidget->SetDataNode(0); m_Controls->m_TransferFunctionWidget->setEnabled(false); m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(0); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false); return; } // otherwise we can activate em all enabled = false; m_SelectedNode->GetBoolProperty("volumerendering.uselod",enabled); m_Controls->m_EnableLOD->setEnabled(true); m_Controls->m_EnableLOD->setChecked(enabled); m_Controls->m_RenderMode->setEnabled(true); // Determine Combo Box mode { bool usegpu=false; bool useray=false; bool usemip=false; m_SelectedNode->GetBoolProperty("volumerendering.usegpu",usegpu); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_SelectedNode->GetBoolProperty("volumerendering.useray",useray); -#endif m_SelectedNode->GetBoolProperty("volumerendering.usemip",usemip); int mode = 0; if(useray) { if(usemip) mode=RM_GPU_MIP_RAYCAST; else mode=RM_GPU_COMPOSITE_RAYCAST; } else if(usegpu) mode=RM_GPU_COMPOSITE_SLICING; else { if(usemip) mode=RM_CPU_MIP_RAYCAST; else mode=RM_CPU_COMPOSITE_RAYCAST; } m_Controls->m_RenderMode->setCurrentIndex(mode); } m_Controls->m_TransferFunctionWidget->SetDataNode(m_SelectedNode); m_Controls->m_TransferFunctionWidget->setEnabled(true); m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(m_SelectedNode); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(true); } void QmitkVolumeVisualizationView::OnEnableRendering(bool state) { if(m_SelectedNode.IsNull()) return; m_SelectedNode->SetProperty("volumerendering",mitk::BoolProperty::New(state)); UpdateInterface(); RequestRenderWindowUpdate(); } void QmitkVolumeVisualizationView::OnEnableLOD(bool state) { if(m_SelectedNode.IsNull()) return; m_SelectedNode->SetProperty("volumerendering.uselod",mitk::BoolProperty::New(state)); RequestRenderWindowUpdate(); } void QmitkVolumeVisualizationView::OnRenderMode(int mode) { if(m_SelectedNode.IsNull()) return; bool usegpu=mode==RM_GPU_COMPOSITE_SLICING; -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool useray=(mode==RM_GPU_COMPOSITE_RAYCAST)||(mode==RM_GPU_MIP_RAYCAST); -#endif bool usemip=(mode==RM_GPU_MIP_RAYCAST)||(mode==RM_CPU_MIP_RAYCAST); m_SelectedNode->SetProperty("volumerendering.usegpu",mitk::BoolProperty::New(usegpu)); -// Only with VTK 5.6 or above -#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_SelectedNode->SetProperty("volumerendering.useray",mitk::BoolProperty::New(useray)); -#endif m_SelectedNode->SetProperty("volumerendering.usemip",mitk::BoolProperty::New(usemip)); RequestRenderWindowUpdate(); } void QmitkVolumeVisualizationView::SetFocus() { } void QmitkVolumeVisualizationView::NodeRemoved(const mitk::DataNode* node) { if(m_SelectedNode == node) { m_SelectedNode=0; m_Controls->m_SelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); m_Controls->m_NoSelectedImageLabel->show(); UpdateInterface(); } }