.. _program_listing_file_MRMLDM_vtkMRMLLayerDMLayerManager.cxx: Program Listing for File vtkMRMLLayerDMLayerManager.cxx ======================================================= |exhale_lsh| :ref:`Return to documentation for file ` (``MRMLDM/vtkMRMLLayerDMLayerManager.cxx``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "vtkMRMLLayerDMLayerManager.h" // Layer DM includes #include "vtkMRMLLayerDMPipelineI.h" // VTK includes #include #include #include #include #include #include vtkStandardNewMacro(vtkMRMLLayerDMLayerManager); void vtkMRMLLayerDMLayerManager::AddPipeline(vtkMRMLLayerDMPipelineI* pipeline) { if (!pipeline) { return; } auto key = this->GetPipelineLayerKey(pipeline); if (!this->ContainsLayerKey(key)) { this->m_pipelineLayers[key] = {}; } this->m_pipelineLayers[key].emplace(pipeline); this->UpdateLayers(); } vtkMRMLLayerDMLayerManager::LayerKey vtkMRMLLayerDMLayerManager::GetPipelineLayerKey(vtkMRMLLayerDMPipelineI* pipeline) { if (!pipeline) { return {}; } return { pipeline->GetRenderOrder(), vtkMRMLLayerDMLayerManager::GetCameraId(pipeline->GetCustomCamera()) }; } int vtkMRMLLayerDMLayerManager::GetNumberOfDistinctLayers() const { return static_cast(this->m_pipelineLayers.size()); } int vtkMRMLLayerDMLayerManager::GetNumberOfManagedLayers() const { return this->GetNumberOfDistinctLayers() - 1; } int vtkMRMLLayerDMLayerManager::GetNumberOfRenderers() const { return static_cast(this->m_renderers.size()); } void vtkMRMLLayerDMLayerManager::RemovePipeline(vtkMRMLLayerDMPipelineI* pipeline) { if (!pipeline) { return; } auto key = this->GetPipelineLayerKey(pipeline); if (!this->ContainsLayerKey(key)) { return; } // Remove pipeline from its renderer this->RemovePipelineRenderer(pipeline); // Update the other pipeline layers if needed this->m_pipelineLayers[key].erase(pipeline); this->UpdateLayers(); } void vtkMRMLLayerDMLayerManager::ResetCameraClippingRange() const { // Reset first renderer clipping range if (const auto defaultRenderer = this->GetDefaultRenderer()) { defaultRenderer->ResetCameraClippingRange(); } // Reset the managed renderers grouped by common cameras for (const auto& pair : m_cameraRendererMap) { this->ResetRenderersCameraClippingRange(pair.second, this->ComputeRenderersVisibleBounds(pair.second)); } } void vtkMRMLLayerDMLayerManager::SetRenderWindow(vtkRenderWindow* renderWindow) { if (this->m_renderWindow == renderWindow) { return; } this->RemoveAllLayers(); this->m_renderWindow = renderWindow; this->UpdateLayers(); } void vtkMRMLLayerDMLayerManager::SetDefaultCamera(const vtkSmartPointer& camera) { if (this->m_defaultCamera == camera) { return; } this->m_defaultCamera = camera; this->UpdateLayers(); } vtkMRMLLayerDMLayerManager::vtkMRMLLayerDMLayerManager() : m_emptyPipeline(vtkSmartPointer::New()) { this->AddPipeline(this->m_emptyPipeline); } vtkRenderer* vtkMRMLLayerDMLayerManager::GetRendererMatchingKey(const LayerKey& key) { // If key index matches the default layer, return the render window's first renderer int keyIndex = this->GetKeyIndex(key); if (keyIndex == 0) { return this->GetDefaultRenderer(); } // Otherwise, convert key index to matching managed renderer index and return the associated renderer int rendererIndex = keyIndex - 1; if (rendererIndex < 0 || rendererIndex >= this->GetNumberOfRenderers()) { return nullptr; } return this->m_renderers[rendererIndex]; } vtkRenderer* vtkMRMLLayerDMLayerManager::GetDefaultRenderer() const { if (!this->m_renderWindow) { return nullptr; } return this->m_renderWindow->GetRenderers()->GetFirstRenderer(); } void vtkMRMLLayerDMLayerManager::AddMissingLayers() { while (this->GetNumberOfRenderers() < this->GetNumberOfManagedLayers()) { // Managed renderers are displayed as overlays and should not catch any events. // Events handling is done using the DM mechanism. auto renderer = vtkSmartPointer::New(); renderer->InteractiveOff(); this->m_renderWindow->AddRenderer(renderer); this->m_renderers.emplace_back(renderer); } } std::array vtkMRMLLayerDMLayerManager::ComputeRenderersVisibleBounds(const std::set>& renderers) { vtkBoundingBox bbox; for (const auto& renderer : renderers) { if (!renderer) { continue; } bbox.AddBounds(renderer->ComputeVisiblePropBounds()); } std::array bounds{}; bbox.GetBounds(bounds.data()); return bounds; } bool vtkMRMLLayerDMLayerManager::ContainsLayerKey(const LayerKey& key) { return this->m_pipelineLayers.find(key) != this->m_pipelineLayers.end(); } std::uintptr_t vtkMRMLLayerDMLayerManager::GetCameraId(vtkCamera* camera) { if (!camera) { return 0; } return reinterpret_cast(camera); } vtkCamera* vtkMRMLLayerDMLayerManager::GetCameraForLayer(const LayerKey& key, const std::set>& pipelines) const { if (const auto cameraId = std::get<1>(key); cameraId == 0) { return this->m_defaultCamera; } for (const auto& pipeline : pipelines) { if (pipeline) { return pipeline->GetCustomCamera(); } } return nullptr; } int vtkMRMLLayerDMLayerManager::GetKeyIndex(const LayerKey& key) const { int index = 0; for (const auto& pair : m_pipelineLayers) { if (pair.first == key) { return index; } ++index; } return -1; } void vtkMRMLLayerDMLayerManager::RemoveAllLayers() { for (const auto& renderer : m_renderers) { this->RemoveRenderer(renderer); } this->UpdateRenderWindowNumberOfLayers(); this->m_renderers.clear(); } void vtkMRMLLayerDMLayerManager::RemoveAllPipelineRenderers() { // if the render window is null, notify pipelines for (const auto& [key, pipelines] : m_pipelineLayers) { for (const auto& pipeline : pipelines) { this->RemovePipelineRenderer(pipeline); } } } void vtkMRMLLayerDMLayerManager::RemovePipelineRenderer(vtkMRMLLayerDMPipelineI* pipeline) { if (pipeline) { pipeline->SetRenderer(nullptr); } } void vtkMRMLLayerDMLayerManager::RemoveOutdatedLayers() { while (this->GetNumberOfRenderers() && (this->GetNumberOfRenderers() > this->GetNumberOfManagedLayers())) { this->RemoveRenderer(this->m_renderers[this->GetNumberOfRenderers() - 1]); } } void vtkMRMLLayerDMLayerManager::RemoveOutdatedPipelines() { // Remove pipelines which have been garbage collected for (auto& [key, pipelines] : m_pipelineLayers) { for (const auto& pipeline : pipelines) { if (!pipeline) { pipelines.erase(pipeline); } } if (pipelines.empty()) { this->m_pipelineLayers.erase(key); } } } void vtkMRMLLayerDMLayerManager::RemoveRenderer(const vtkSmartPointer& renderer) { if (this->m_renderWindow && this->m_renderWindow->HasRenderer(renderer)) { this->m_renderWindow->RemoveRenderer(renderer); } this->m_renderers.erase(std::find(this->m_renderers.begin(), this->m_renderers.end(), renderer)); } void vtkMRMLLayerDMLayerManager::ResetRenderersCameraClippingRange(const std::set>& renderers, const std::array& bounds) { for (const auto& renderer : renderers) { if (!renderer) { continue; } renderer->ResetCameraClippingRange(const_cast(bounds.data())); } } void vtkMRMLLayerDMLayerManager::SynchronizePipelineRenderers() { for (const auto& pair : m_pipelineLayers) { auto renderer = this->GetRendererMatchingKey(pair.first); for (const auto& pipeline : pair.second) { if (pipeline) { pipeline->SetRenderer(renderer); } } } } void vtkMRMLLayerDMLayerManager::UpdateRenderWindowNumberOfLayers() const { if (!this->m_renderWindow) { return; } // Synchronize the render window number of layers with its actual number of renderers int numberOfRenderers = this->m_renderWindow->GetRenderers()->GetNumberOfItems(); int iMax = 0; for (int iRenderer = 0; iRenderer < numberOfRenderers; iRenderer++) { if (auto renderer = vtkRenderer::SafeDownCast(this->m_renderWindow->GetRenderers()->GetItemAsObject(iRenderer))) { iMax = std::max(iMax, renderer->GetLayer()); } } this->m_renderWindow->SetNumberOfLayers(iMax + 1); } void vtkMRMLLayerDMLayerManager::UpdateLayers() { if (!this->m_renderWindow) { this->RemoveAllPipelineRenderers(); return; } this->RemoveOutdatedPipelines(); this->RemoveOutdatedLayers(); this->AddMissingLayers(); this->UpdateRendererLayerOrdering(); this->UpdateRendererCamera(); this->SynchronizePipelineRenderers(); this->UpdateRenderWindowNumberOfLayers(); } void vtkMRMLLayerDMLayerManager::UpdateRendererLayerOrdering() const { // Managed layers are always ordered from layer 1 to the number of managed renderers for (int iRenderer = 0; iRenderer < this->GetNumberOfRenderers(); iRenderer++) { this->m_renderers[iRenderer]->SetLayer(iRenderer + 1); } } void vtkMRMLLayerDMLayerManager::UpdateRendererCamera() { // Set the camera for the managed renderers // Layer 0 is unmanaged and its camera is left unchanged by the layer manager // Pipelines with no explicit camera map to the default camera // Pipelines with custom camera are grouped and use their cameras this->m_cameraRendererMap.clear(); int iRenderer = -1; for (const auto& pair : m_pipelineLayers) { if (iRenderer >= 0 && iRenderer < this->GetNumberOfRenderers()) { auto camera = this->GetCameraForLayer(pair.first, pair.second); this->m_renderers[iRenderer]->SetActiveCamera(camera); this->m_cameraRendererMap[camera].emplace(this->m_renderers[iRenderer]); } iRenderer++; } }