diff --git a/Modules/Core/include/mitkVtkPropRenderer.h b/Modules/Core/include/mitkVtkPropRenderer.h index 1f8df0c9d0..46420520d1 100644 --- a/Modules/Core/include/mitkVtkPropRenderer.h +++ b/Modules/Core/include/mitkVtkPropRenderer.h @@ -1,258 +1,258 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkVtkPropRenderer_h #define mitkVtkPropRenderer_h #include "mitkBaseRenderer.h" #include #include #include #include #include #include class vtkRenderWindow; class vtkLight; class vtkLightKit; class vtkWorldPointPicker; class vtkPointPicker; class vtkCellPicker; class vtkTextActor; class vtkTextProperty; class vtkAssemblyPath; #include #include namespace mitk { class Mapper; /*! \brief VtkPropRenderer VtkPropRenderer organizes the MITK rendering process. The MITK rendering process is completely integrated into the VTK rendering pipeline. The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes. VtkPropRenderer replaces the old OpenGLRenderer. \sa rendering \ingroup rendering */ class MITKCORE_EXPORT VtkPropRenderer : public BaseRenderer { // Workaround for Displaylistbug private: bool didCount; void checkState(); // Workaround END public: mitkClassMacro(VtkPropRenderer, BaseRenderer); mitkNewMacro3Param(VtkPropRenderer, const char *, vtkRenderWindow *, mitk::RenderingManager *); mitkNewMacro4Param(VtkPropRenderer, const char *, vtkRenderWindow *, mitk::RenderingManager *, mitk::BaseRenderer::RenderingMode::Type); typedef std::map MappersMapType; // Render - called by vtkMitkRenderProp, returns the number of props rendered enum RenderType { Opaque, Translucent, Overlay, Volumetric }; - /** \brief store/propagate vtkInformation during rendering */ + /** \brief Store/propagate vtkInformation during rendering */ void SetPropertyKeys(vtkInformation *info); int Render(RenderType type); /** \brief This methods contains all method neceassary before a VTK Render() call */ virtual void PrepareRender(); // Active current renderwindow virtual void MakeCurrent(); void SetDataStorage( mitk::DataStorage *storage) override; ///< set the datastorage that will be used for rendering void InitRenderer(vtkRenderWindow *renderwindow) override; virtual void Update(mitk::DataNode *datatreenode); void SetMapperID(const MapperSlotId mapperId) override; // Size void InitSize(int w, int h) override; void Resize(int w, int h) override; // Picking enum PickingMode { WorldPointPicking, PointPicking, CellPicking }; /** \brief Set the picking mode. This method is used to set the picking mode for 3D object picking. The user can select one of the three options WorldPointPicking, PointPicking and CellPicking. The first option uses the zBuffer from graphics rendering, the second uses the 3D points from the closest surface mesh, and the third option uses the cells of that mesh. The last option is the slowest, the first one the fastest. However, the first option cannot use transparent data object and the tolerance of the picked position to the selected point should be considered. PointPicking also need a tolerance around the picking position to select the closest point in the mesh. The CellPicker performs very well, if the foreground surface part (i.e. the surfacepart that is closest to the scene's cameras) needs to be picked. */ itkSetEnumMacro(PickingMode, PickingMode); itkGetEnumMacro(PickingMode, PickingMode); void PickWorldPoint(const Point2D &displayPoint, Point3D &worldPoint) const override; mitk::DataNode *PickObject(const Point2D &displayPosition, Point3D &worldPosition) const override; /** * @brief WriteSimpleText Write a text in a renderwindow. * * Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. * * @deprecatedSince{2015_05} Please use mitkTextOverlay2D instead. * See mitkTextOverlay2DRenderingTest for an example. */ DEPRECATED(int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0, float opacity = 1.0)); /** * @brief CGetTextLabelProperty an be used in order to get a vtkTextProperty for * a specific text_id. This property enables the setup of font, font size, etc. * @param text_id the id of the text property. * @deprecatedSince{2015_05} Please use mitkTextOverlay2D instead. * See mitkTextOverlay2DRenderingTest for an example. */ DEPRECATED(vtkTextProperty *GetTextLabelProperty(int text_id)); /** This method calculates the bounds of the DataStorage (if it contains any * valid data), creates a geometry from these bounds and sets it as world * geometry of the renderer. * * Call this method to re-initialize the renderer to the current DataStorage * (e.g. after loading an additional dataset), to ensure that the view is * aligned correctly. */ bool SetWorldGeometryToDataStorageBounds() override; /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ void InitPathTraversal(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ vtkAssemblyPath *GetNextPath(); int GetNumberOfPaths(); const vtkWorldPointPicker *GetWorldPointPicker() const; const vtkPointPicker *GetPointPicker() const; const vtkCellPicker *GetCellPicker() const; /** * \brief Release vtk-based graphics resources. Called by * vtkMitkRenderProp::ReleaseGraphicsResources. */ virtual void ReleaseGraphicsResources(vtkWindow *renWin); MappersMapType GetMappersMap() const; static bool useImmediateModeRendering(); protected: VtkPropRenderer( const char *name = "VtkPropRenderer", vtkRenderWindow *renWin = nullptr, mitk::RenderingManager *rm = nullptr, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard); ~VtkPropRenderer() override; void Update() override; static void RenderingCallback(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata); virtual void UpdatePaths(); // apply transformations and properties recursively private: vtkSmartPointer m_Paths; vtkTimeStamp m_PathTime; // prepare all mitk::mappers for rendering void PrepareMapperQueue(); /** \brief Propagate vtkInformation object to all VTK-based mappers */ void PropagateRenderInfoToMappers(); /** \brief Set parallel projection, remove the interactor and the lights of VTK. */ bool Initialize2DvtkCamera(); bool m_InitNeeded; bool m_ResizeNeeded; MapperSlotId m_CameraInitializedForMapperID; // Picking vtkWorldPointPicker *m_WorldPointPicker; vtkPointPicker *m_PointPicker; vtkCellPicker *m_CellPicker; PickingMode m_PickingMode; // Explicit use of SmartPointer to avoid circular #includes itk::SmartPointer m_CurrentWorldPlaneGeometryMapper; vtkLightKit *m_LightKit; // sorted list of mappers MappersMapType m_MappersMap; // rendering of text vtkRenderer *m_TextRenderer; typedef std::map TextMapType; TextMapType m_TextCollection; /** \brief Information passed from VTK's rendering to props. Used e.g. by vtkDualDepthPeelingPass to pass information. Not passing this to all the MITK generated vktProps will essentially break VTK's depth peeling / transparency. */ vtkInformation* m_VtkRenderInfo = nullptr; }; } // namespace mitk #endif /* mitkVtkPropRenderer_h */ diff --git a/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp b/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp index 01f008e09f..6f0986f708 100644 --- a/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp +++ b/Modules/Core/src/Rendering/mitkVtkPropRenderer.cpp @@ -1,719 +1,715 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkPropRenderer.h" // MAPPERS #include "mitkCameraController.h" #include "mitkImageVtkMapper2D.h" #include "mitkMapper.h" #include "mitkPlaneGeometryDataVtkMapper3D.h" #include "mitkVtkMapper.h" #include #include #include #include #include #include #include #include #include #include // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::VtkPropRenderer::VtkPropRenderer(const char *name, vtkRenderWindow *renWin, mitk::RenderingManager *rm, mitk::BaseRenderer::RenderingMode::Type renderingMode) : BaseRenderer(name, renWin, rm, renderingMode), m_CameraInitializedForMapperID(0) { didCount = false; m_WorldPointPicker = vtkWorldPointPicker::New(); m_PointPicker = vtkPointPicker::New(); m_PointPicker->SetTolerance(0.0025); m_CellPicker = vtkCellPicker::New(); m_CellPicker->SetTolerance(0.0025); mitk::PlaneGeometryDataVtkMapper3D::Pointer geometryMapper = mitk::PlaneGeometryDataVtkMapper3D::New(); m_CurrentWorldPlaneGeometryMapper = geometryMapper; m_CurrentWorldPlaneGeometryNode->SetMapper(2, geometryMapper); m_LightKit = vtkLightKit::New(); m_LightKit->AddLightsToRenderer(m_VtkRenderer); m_PickingMode = WorldPointPicking; m_TextRenderer = vtkRenderer::New(); m_TextRenderer->SetRenderWindow(renWin); m_TextRenderer->SetInteractive(0); m_TextRenderer->SetErase(0); } /*! \brief Destructs the VtkPropRenderer. */ mitk::VtkPropRenderer::~VtkPropRenderer() { // Workaround for GLDisplayList Bug { m_MapperID = 0; checkState(); } if (m_LightKit != nullptr) m_LightKit->Delete(); if (m_VtkRenderer != nullptr) { m_CameraController = nullptr; m_VtkRenderer->Delete(); m_VtkRenderer = nullptr; } else m_CameraController = nullptr; if (m_WorldPointPicker != nullptr) m_WorldPointPicker->Delete(); if (m_PointPicker != nullptr) m_PointPicker->Delete(); if (m_CellPicker != nullptr) m_CellPicker->Delete(); if (m_TextRenderer != nullptr) m_TextRenderer->Delete(); } void mitk::VtkPropRenderer::SetDataStorage(mitk::DataStorage *storage) { if (storage == nullptr || storage == m_DataStorage) return; BaseRenderer::SetDataStorage(storage); static_cast(m_CurrentWorldPlaneGeometryMapper.GetPointer()) ->SetDataStorageForTexture(m_DataStorage.GetPointer()); // Compute the geometry from the current data tree bounds and set it as world geometry this->SetWorldGeometryToDataStorageBounds(); } bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds() { if (m_DataStorage.IsNull()) return false; // initialize world geometry auto geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D(nullptr, "includeInBoundingBox"); if (geometry.IsNull()) return false; this->SetWorldTimeGeometry(geometry); this->GetVtkRenderer()->ResetCamera(); this->GetCameraController()->Fit(); this->Modified(); return true; } /*! \brief Called by the vtkMitkRenderProp in order to start MITK rendering process. */ int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type) { // Do we have objects to render? if (this->GetEmptyWorldGeometry()) return 0; if (m_DataStorage.IsNull()) return 0; // Update mappers and prepare mapper queue if (type == VtkPropRenderer::Opaque) { this->PrepareMapperQueue(); // Share vtkInformation, there might be new mappers this->PropagateRenderInfoToMappers(); } // go through the generated list and let the sorted mappers paint for (auto it = m_MappersMap.cbegin(); it != m_MappersMap.cend(); it++) { Mapper *mapper = (*it).second; mapper->MitkRender(this, type); } // Render text if (type == VtkPropRenderer::Overlay) { if (m_TextCollection.size() > 0) { m_TextRenderer->SetViewport(this->GetVtkRenderer()->GetViewport()); for (auto it = m_TextCollection.begin(); it != m_TextCollection.end(); ++it) m_TextRenderer->AddViewProp((*it).second); m_TextRenderer->Render(); } } return 1; } /*! \brief PrepareMapperQueue iterates the datatree PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer. */ void mitk::VtkPropRenderer::PrepareMapperQueue() { // variable for counting LOD-enabled mappers m_NumberOfVisibleLODEnabledMappers = 0; // Do we have to update the mappers ? if (m_LastUpdateTime < GetMTime() || m_LastUpdateTime < this->GetCurrentWorldPlaneGeometry()->GetMTime()) { Update(); } else if (m_MapperID >= 1 && m_MapperID < 6) Update(); // remove all text properties before mappers will add new ones m_TextRenderer->RemoveAllViewProps(); for (unsigned int i = 0; i < m_TextCollection.size(); i++) { m_TextCollection[i]->Delete(); } m_TextCollection.clear(); // clear priority_queue m_MappersMap.clear(); int mapperNo = 0; // DataStorage if (m_DataStorage.IsNull()) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { const DataNode::Pointer node = it->Value(); if (node.IsNull()) continue; const mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID); if (mapper.IsNull()) continue; bool visible = true; node->GetVisibility(visible, this, "visible"); // The information about LOD-enabled mappers is required by RenderingManager if (mapper->IsLODEnabled(this) && visible) { ++m_NumberOfVisibleLODEnabledMappers; } // mapper without a layer property get layer number 1 int layer = 1; node->GetIntProperty("layer", layer, this); int nr = (layer << 16) + mapperNo; m_MappersMap.insert(std::pair(nr, mapper)); mapperNo++; } } void mitk::VtkPropRenderer::SetPropertyKeys(vtkInformation *info) { if (info == m_VtkRenderInfo) - { return; - } m_VtkRenderInfo = info; - PropagateRenderInfoToMappers(); + this->PropagateRenderInfoToMappers(); } void mitk::VtkPropRenderer::PropagateRenderInfoToMappers() { if (m_VtkRenderInfo == nullptr) - { return; - } - // propagate information to all mappers' vtkProps - for (auto &mapEntry : m_MappersMap) + for (const auto &mapEntry : m_MappersMap) { - if (auto vtkMapper = dynamic_cast(mapEntry.second)) + auto vtkMapper = dynamic_cast(mapEntry.second); + + if (nullptr != vtkMapper) { - vtkProp *prop = vtkMapper->GetVtkProp(this); - if (prop) - { + auto prop = vtkMapper->GetVtkProp(this); + + if (nullptr != prop) prop->SetPropertyKeys(m_VtkRenderInfo); - } } } } void mitk::VtkPropRenderer::Update(mitk::DataNode *datatreenode) { if (datatreenode != nullptr) { mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID); if (mapper.IsNotNull()) { if (GetCurrentWorldPlaneGeometry()->IsValid()) { mapper->Update(this); { auto *vtkmapper = dynamic_cast(mapper.GetPointer()); if (vtkmapper != nullptr) { vtkmapper->UpdateVtkTransform(this); } } } } } } void mitk::VtkPropRenderer::Update() { if (m_DataStorage.IsNull()) return; mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) Update(it->Value()); Modified(); m_LastUpdateTime = GetMTime(); } /*! \brief This method is called from the two Constructors */ void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow *renderWindow) { BaseRenderer::InitRenderer(renderWindow); vtkCallbackCommand *renderCallbackCommand = vtkCallbackCommand::New(); renderCallbackCommand->SetCallback(VtkPropRenderer::RenderingCallback); renderWindow->GetInteractor()->AddObserver(vtkCommand::RenderEvent, renderCallbackCommand); renderCallbackCommand->Delete(); if (renderWindow == nullptr) { m_InitNeeded = false; m_ResizeNeeded = false; return; } m_InitNeeded = true; m_ResizeNeeded = true; m_LastUpdateTime = 0; } void mitk::VtkPropRenderer::RenderingCallback(vtkObject *caller, unsigned long, void *, void *) { auto *renderWindowInteractor = dynamic_cast(caller); if (!renderWindowInteractor) return; mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetInstance(renderWindowInteractor->GetRenderWindow()); if (renderer) renderer->RequestUpdate(); } /*! \brief Resize the OpenGL Window */ void mitk::VtkPropRenderer::Resize(int w, int h) { BaseRenderer::Resize(w, h); m_RenderingManager->RequestUpdate(this->GetRenderWindow()); } void mitk::VtkPropRenderer::InitSize(int w, int h) { m_RenderWindow->SetSize(w, h); Superclass::InitSize(w, h); Modified(); Update(); if (m_VtkRenderer != nullptr) { int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); m_VtkRenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } this->GetCameraController()->Fit(); } int mitk::VtkPropRenderer::WriteSimpleText( std::string text, double posX, double posY, double color1, double color2, double color3, float opacity) { this->GetVtkRenderer()->ViewToDisplay(); if (!text.empty()) { Point2D p; vtkTextActor *textActor = vtkTextActor::New(); textActor->SetDisplayPosition(posX, posY); textActor->SetInput(text.c_str()); textActor->SetTextScaleModeToNone(); textActor->GetTextProperty()->SetColor(color1, color2, color3); // TODO: Read color from node property textActor->GetTextProperty()->SetOpacity(opacity); int text_id = m_TextCollection.size(); m_TextCollection.insert(TextMapType::value_type(text_id, textActor)); return text_id; } else { return -1; } } void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId) { if (m_MapperID != mapperId) Superclass::SetMapperID(mapperId); // Workaround for GL Displaylist Bug checkState(); } /*! \brief Activates the current renderwindow. */ void mitk::VtkPropRenderer::MakeCurrent() { if (m_RenderWindow != nullptr) m_RenderWindow->MakeCurrent(); } void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D &displayPoint, mitk::Point3D &worldPoint) const { if (this->GetRenderWindow()->GetNeverRendered() != 0) return; // somebody called picking before we ever rendered; cannot have enough information yet switch (m_PickingMode) { case (WorldPointPicking): { m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); break; } case (PointPicking): { m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); break; } case (CellPicking): { m_CellPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_CellPicker->GetPickPosition(), worldPoint); break; } } // todo: is this picking in 2D renderwindows? // Superclass::PickWorldPoint(displayPoint, worldPoint); } mitk::DataNode *mitk::VtkPropRenderer::PickObject(const Point2D &displayPosition, Point3D &worldPosition) const { m_CellPicker->InitializePickList(); // Iterate over all DataStorage objects to determine all vtkProps intended // for picking DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { const DataNode *node = it->Value(); if (node == nullptr) continue; bool pickable = false; node->GetBoolProperty("pickable", pickable); if (!pickable) continue; auto *mapper = dynamic_cast(node->GetMapper(m_MapperID)); if (mapper == nullptr) continue; vtkProp *prop = mapper->GetVtkProp((mitk::BaseRenderer *)this); if (prop == nullptr) continue; m_CellPicker->AddPickList(prop); } // Do the picking and retrieve the picked vtkProp (if any) m_CellPicker->PickFromListOn(); m_CellPicker->Pick(displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer); m_CellPicker->PickFromListOff(); vtk2itk(m_CellPicker->GetPickPosition(), worldPosition); vtkProp *prop = m_CellPicker->GetViewProp(); if (prop == nullptr) { return nullptr; } // Iterate over all DataStorage objects to determine if the retrieved // vtkProp is owned by any associated mapper. for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if (node.IsNull()) continue; mitk::Mapper *mapper = node->GetMapper(m_MapperID); if (mapper == nullptr) continue; auto *vtkmapper = dynamic_cast(mapper); if (vtkmapper) { // if vtk-based, then ... if (vtkmapper->HasVtkProp(prop, const_cast(this))) { return node; } } } return nullptr; } // todo: is this 2D renderwindow picking? // return Superclass::PickObject( displayPosition, worldPosition ); vtkTextProperty *mitk::VtkPropRenderer::GetTextLabelProperty(int text_id) { return this->m_TextCollection[text_id]->GetTextProperty(); } void mitk::VtkPropRenderer::InitPathTraversal() { if (m_DataStorage.IsNotNull()) { this->UpdatePaths(); this->m_Paths->InitTraversal(); } } void mitk::VtkPropRenderer::UpdatePaths() { if (m_DataStorage.IsNull()) { return; } if (GetMTime() > m_PathTime || (m_Paths != nullptr && m_Paths->GetMTime() > m_PathTime)) { // Create the list to hold all the paths m_Paths = vtkSmartPointer::New(); DataStorage::SetOfObjects::ConstPointer objects = m_DataStorage->GetAll(); for (auto iter = objects->begin(); iter != objects->end(); ++iter) { vtkSmartPointer onePath = vtkSmartPointer::New(); Mapper *mapper = (*iter)->GetMapper(BaseRenderer::Standard3D); if (mapper) { auto *vtkmapper = dynamic_cast(mapper); if (nullptr != vtkmapper) { vtkProp *prop = vtkmapper->GetVtkProp(this); if (prop && prop->GetVisibility()) { // add to assembly path onePath->AddNode(prop, prop->GetMatrix()); m_Paths->AddItem(onePath); } } } } m_PathTime.Modified(); } } int mitk::VtkPropRenderer::GetNumberOfPaths() { UpdatePaths(); return m_Paths->GetNumberOfItems(); } vtkAssemblyPath *mitk::VtkPropRenderer::GetNextPath() { return m_Paths ? m_Paths->GetNextItem() : nullptr; } void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow * /*renWin*/) { if (m_DataStorage.IsNull()) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (auto iter = allObjects->begin(); iter != allObjects->end(); ++iter) { DataNode::Pointer node = *iter; if (node.IsNull()) continue; Mapper *mapper = node->GetMapper(m_MapperID); if (mapper) { auto *vtkmapper = dynamic_cast(mapper); if (vtkmapper) vtkmapper->ReleaseGraphicsResources(this); } } } const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const { return m_WorldPointPicker; } const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const { return m_PointPicker; } const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const { return m_CellPicker; } mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const { return m_MappersMap; } // Workaround for GL Displaylist bug static int glWorkAroundGlobalCount = 0; bool mitk::VtkPropRenderer::useImmediateModeRendering() { return glWorkAroundGlobalCount > 1; } void mitk::VtkPropRenderer::checkState() { if (m_MapperID == Standard3D) { if (!didCount) { didCount = true; glWorkAroundGlobalCount++; if (glWorkAroundGlobalCount == 2) { MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOn(); } } } else { if (didCount) { didCount = false; glWorkAroundGlobalCount--; if (glWorkAroundGlobalCount == 1) { MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOff(); } } } } //### Contains all methods which are neceassry before each VTK Render() call void mitk::VtkPropRenderer::PrepareRender() { if (this->GetMapperID() != m_CameraInitializedForMapperID) { Initialize2DvtkCamera(); // Set parallel projection etc. } GetCameraController()->AdjustCameraToPlane(); } bool mitk::VtkPropRenderer::Initialize2DvtkCamera() { if (this->GetMapperID() == Standard3D) { // activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false); vtkSmartPointer style = vtkSmartPointer::New(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); this->GetRenderWindow()->GetInteractor()->EnableRenderOff(); m_CameraInitializedForMapperID = Standard3D; } else if (this->GetMapperID() == Standard2D) { // activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); // turn the light out in the scene in order to render correct grey values. // TODO Implement a property for light in the 2D render windows (in another method) this->GetVtkRenderer()->RemoveAllLights(); vtkSmartPointer style = vtkSmartPointer::New(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); this->GetRenderWindow()->GetInteractor()->EnableRenderOff(); m_CameraInitializedForMapperID = Standard2D; } return true; } diff --git a/Modules/Core/src/Rendering/vtkMitkRenderProp.cpp b/Modules/Core/src/Rendering/vtkMitkRenderProp.cpp index 215f9a12a1..eaf97d9faf 100644 --- a/Modules/Core/src/Rendering/vtkMitkRenderProp.cpp +++ b/Modules/Core/src/Rendering/vtkMitkRenderProp.cpp @@ -1,113 +1,113 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "vtkMitkRenderProp.h" #include #include #include #include "mitkVtkMapper.h" vtkStandardNewMacro(vtkMitkRenderProp); vtkMitkRenderProp::vtkMitkRenderProp() { } vtkMitkRenderProp::~vtkMitkRenderProp() { } double *vtkMitkRenderProp::GetBounds() { return const_cast(m_VtkPropRenderer->GetBounds()); } void vtkMitkRenderProp::SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer) { this->m_VtkPropRenderer = propRenderer; } void vtkMitkRenderProp::SetPropertyKeys(vtkInformation *keys) { - // store information as a regular vtkProp Superclass::SetPropertyKeys(keys); - if (m_VtkPropRenderer != nullptr) - { + + if (nullptr != m_VtkPropRenderer) m_VtkPropRenderer->SetPropertyKeys(keys); - } } int vtkMitkRenderProp::RenderOpaqueGeometry(vtkViewport * /*viewport*/) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Opaque); } int vtkMitkRenderProp::RenderOverlay(vtkViewport * /*viewport*/) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Overlay); } void vtkMitkRenderProp::ReleaseGraphicsResources(vtkWindow *window) { m_VtkPropRenderer->ReleaseGraphicsResources(window); } void vtkMitkRenderProp::InitPathTraversal() { m_VtkPropRenderer->InitPathTraversal(); } vtkAssemblyPath *vtkMitkRenderProp::GetNextPath() { return m_VtkPropRenderer->GetNextPath(); } int vtkMitkRenderProp::GetNumberOfPaths() { return m_VtkPropRenderer->GetNumberOfPaths(); } int vtkMitkRenderProp::HasTranslucentPolygonalGeometry() { - for (auto &mapEntry : m_VtkPropRenderer->GetMappersMap()) + for (const auto &mapEntry : m_VtkPropRenderer->GetMappersMap()) { - if (auto vtkMapper = dynamic_cast(mapEntry.second)) + auto vtkMapper = dynamic_cast(mapEntry.second); + + if (nullptr != vtkMapper) { // Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly // manually (see issue #8186 committed to VTK's Mantis issue tracker) // --> VTK bug resolved on 2008-12-01 - auto *propAssembly = dynamic_cast(vtkMapper->GetVtkProp(m_VtkPropRenderer)); - if (propAssembly) - { + auto propAssembly = dynamic_cast(vtkMapper->GetVtkProp(m_VtkPropRenderer)); + + if (nullptr != propAssembly) propAssembly->InitPathTraversal(); - } - if (vtkMapper->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry() == 1) + if (1 == vtkMapper->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()) return 1; } } + return 0; } int vtkMitkRenderProp::RenderTranslucentPolygonalGeometry(vtkViewport *) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Translucent); } int vtkMitkRenderProp::RenderVolumetricGeometry(vtkViewport *) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Volumetric); }