From 7dffdcbc80e9723c5b2161134d87e37baabd6132 Mon Sep 17 00:00:00 2001 From: Alexis Girault <alexis.girault@kitware.com> Date: Thu, 7 Apr 2016 14:47:20 -0400 Subject: [PATCH] ENH: add Render mode option - SIMULATION adds the object actors and set the interactor style to no interactions. - DEBUG adds additional actors to visualize lights, the camera, axis, and set the interactor style to trackball to interact with the scene. --- Base/Rendering/CMakeLists.txt | 2 + Base/Rendering/imstkRenderer.cpp | 149 ++++++++++++++++++ Base/Rendering/imstkRenderer.h | 70 ++++++++ Base/Rendering/imstkViewer.cpp | 121 +++++++------- Base/Rendering/imstkViewer.h | 25 +-- .../imstkSimulationManager.cpp | 10 +- .../imstkSimulationManager.h | 3 +- Examples/Sandbox/main.cpp | 4 +- 8 files changed, 298 insertions(+), 86 deletions(-) create mode 100644 Base/Rendering/imstkRenderer.cpp create mode 100644 Base/Rendering/imstkRenderer.h diff --git a/Base/Rendering/CMakeLists.txt b/Base/Rendering/CMakeLists.txt index 489aa5c56..f9e62a9e3 100644 --- a/Base/Rendering/CMakeLists.txt +++ b/Base/Rendering/CMakeLists.txt @@ -5,12 +5,14 @@ include(imstkAddLibrary) imstk_add_library( Rendering H_FILES imstkViewer.h + imstkRenderer.h imstkRenderDelegate.h imstkPlaneRenderDelegate.h imstkSphereRenderDelegate.h imstkCubeRenderDelegate.h CPP_FILES imstkViewer.cpp + imstkRenderer.cpp imstkRenderDelegate.cpp imstkPlaneRenderDelegate.cpp imstkSphereRenderDelegate.cpp diff --git a/Base/Rendering/imstkRenderer.cpp b/Base/Rendering/imstkRenderer.cpp new file mode 100644 index 000000000..39537e516 --- /dev/null +++ b/Base/Rendering/imstkRenderer.cpp @@ -0,0 +1,149 @@ +/*========================================================================= + + Library: iMSTK + + Copyright (c) Kitware, Inc. & Center for Modeling, Simulation, + & Imaging in Medicine, Rensselaer Polytechnic Institute. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0.txt + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + =========================================================================*/ + +#include "imstkRenderer.h" + +#include "imstkRenderDelegate.h" + +#include "vtkLight.h" +#include "vtkLightActor.h" +#include "vtkCamera.h" +#include "vtkCameraActor.h" +#include "vtkAxesActor.h" + +#include "g3log/g3log.hpp" + + +namespace imstk { +Renderer::Renderer(std::shared_ptr<Scene> scene) +{ + // Object actors + for ( const auto& obj : scene->getSceneObjects() ) + { + auto geom = obj->getVisualGeometry(); + auto delegate = RenderDelegate::make_delegate( geom ); + m_objectVtkActors.push_back( delegate->getVtkActor() ); + } + + // Lights and light actors + for ( const auto& light : scene->getLights() ) + { + m_vtkLights.push_back( light->getVtkLight() ); + if( light->isPositional() ) + { + auto lightActor = vtkSmartPointer<vtkLightActor>::New(); + lightActor->SetLight( light->getVtkLight() ); + m_debugVtkActors.push_back( lightActor ); + } + } + + // Camera and camera actor + m_sceneVtkCamera = scene->getCamera()->getVtkCamera(); + auto camActor = vtkSmartPointer<vtkCameraActor>::New(); + camActor->SetCamera( m_sceneVtkCamera ); + m_debugVtkActors.push_back( camActor ); + + // Global Axis + auto axes = vtkSmartPointer<vtkAxesActor>::New(); + m_debugVtkActors.push_back( axes ); + + ///TODO : based on scene properties + // Customize background colors + m_vtkRenderer->SetBackground(0.66,0.66,0.66); + m_vtkRenderer->SetBackground2(157.0/255.0*0.66,186/255.0*0.66,192.0/255.0*0.66); + m_vtkRenderer->GradientBackgroundOn(); +} + +vtkSmartPointer<vtkRenderer> +Renderer::getVtkRenderer() const +{ + return m_vtkRenderer; +} + +void +Renderer::setup(Mode mode) +{ + if( mode == Mode::EMPTY && m_currentMode != Mode::EMPTY ) + { + m_vtkRenderer->SetActiveCamera(m_defaultVtkCamera); + + this->removeActors(m_objectVtkActors); + m_vtkRenderer->RemoveAllLights(); + + if( m_currentMode == Mode::DEBUG ) + { + this->removeActors(m_debugVtkActors); + } + } + else if( mode == Mode::DEBUG && m_currentMode != Mode::DEBUG ) + { + m_vtkRenderer->SetActiveCamera(m_defaultVtkCamera); + + this->addActors(m_debugVtkActors); + + if( m_currentMode == Mode::EMPTY ) + { + this->addActors(m_objectVtkActors); + for ( const auto& light : m_vtkLights ) + { + m_vtkRenderer->AddLight(light); + } + } + } + else if ( mode == Mode::SIMULATION && m_currentMode != Mode::SIMULATION ) + { + m_vtkRenderer->SetActiveCamera(m_sceneVtkCamera); + + if( m_currentMode == Mode::EMPTY ) + { + this->addActors(m_objectVtkActors); + for ( const auto& light : m_vtkLights ) + { + m_vtkRenderer->AddLight(light); + } + } + else if( m_currentMode == Mode::DEBUG ) + { + this->removeActors(m_debugVtkActors); + } + } + + m_currentMode = mode; +} + +void +Renderer::removeActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList) +{ + for ( const auto& actor : actorList ) + { + m_vtkRenderer->RemoveActor(actor); + } +} + +void +Renderer::addActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList) +{ + for ( const auto& actor : actorList ) + { + m_vtkRenderer->AddActor(actor); + } +} +} diff --git a/Base/Rendering/imstkRenderer.h b/Base/Rendering/imstkRenderer.h new file mode 100644 index 000000000..8804cfea6 --- /dev/null +++ b/Base/Rendering/imstkRenderer.h @@ -0,0 +1,70 @@ +/*========================================================================= + + Library: iMSTK + + Copyright (c) Kitware, Inc. & Center for Modeling, Simulation, + & Imaging in Medicine, Rensselaer Polytechnic Institute. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0.txt + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + =========================================================================*/ + +#ifndef imstkRenderer_h +#define imstkRenderer_h + +#include <memory> +#include <vector> + +#include "imstkScene.h" + +#include "vtkSmartPointer.h" +#include "vtkRenderer.h" +#include "vtkProp.h" + +namespace imstk { + +class Renderer +{ +public: + + enum Mode + { + EMPTY, + DEBUG, + SIMULATION + }; + + Renderer(std::shared_ptr<Scene> scene); + ~ Renderer() = default; + + void setup(Mode mode); + + vtkSmartPointer<vtkRenderer> getVtkRenderer() const; + +protected: + + void removeActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList); + void addActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList); + + vtkSmartPointer<vtkRenderer> m_vtkRenderer = vtkSmartPointer<vtkRenderer>::New(); + vtkSmartPointer<vtkCamera> m_defaultVtkCamera = vtkSmartPointer<vtkCamera>::New(); + vtkSmartPointer<vtkCamera> m_sceneVtkCamera; + std::vector<vtkSmartPointer<vtkLight>> m_vtkLights; + std::vector<vtkSmartPointer<vtkProp>> m_objectVtkActors; + std::vector<vtkSmartPointer<vtkProp>> m_debugVtkActors; + + Mode m_currentMode = Mode::EMPTY; +}; +} + +#endif // ifndef imstkRenderer_h diff --git a/Base/Rendering/imstkViewer.cpp b/Base/Rendering/imstkViewer.cpp index a12eb89a6..10e3458a4 100644 --- a/Base/Rendering/imstkViewer.cpp +++ b/Base/Rendering/imstkViewer.cpp @@ -21,12 +21,6 @@ #include "imstkViewer.h" -#include "vtkRenderer.h" -#include "vtkLight.h" -#include "vtkLightActor.h" -#include "vtkCamera.h" -#include "vtkCameraActor.h" -#include "vtkAxesActor.h" #include "vtkInteractorStyleTrackballCamera.h" #include "g3log/g3log.hpp" @@ -34,96 +28,87 @@ #include "imstkRenderDelegate.h" namespace imstk { +std::shared_ptr<Scene> +Viewer::getCurrentScene() const +{ + return m_currentScene; +} + void -Viewer::initRenderer() +Viewer::setCurrentScene(std::shared_ptr<Scene>scene) { - // Check current Scene - if (m_currentScene == nullptr) + // If already current scene + if( scene == m_currentScene ) { - LOG(WARNING) << "No scene specified, nothing to render."; + LOG(WARNING) << scene->getName() << " already is the viewer current scene."; return; } - // Create and add renderer - auto renderer = vtkSmartPointer<vtkRenderer>::New(); - //renderer->UseShadowsOn(); - m_renderWindow->AddRenderer(renderer); - - // Create and add actors - for (const auto& obj : m_currentScene->getSceneObjects()) - { - auto geom = obj->getVisualGeometry(); - auto delegate = RenderDelegate::make_delegate(geom); - renderer->AddActor(delegate->getVtkActor()); - } - - // Add lights - for (const auto& light : m_currentScene->getLights()) + // If the current scene has a renderer, remove it + if( m_currentScene ) { - renderer->AddLight( light->getVtkLight() ); - if( light->isPositional() ) + auto vtkRenderer = m_rendererMap.at(m_currentScene)->getVtkRenderer(); + if(m_vtkRenderWindow->HasRenderer(vtkRenderer)) { - auto lightActor = vtkSmartPointer<vtkLightActor>::New(); - lightActor->SetLight( light->getVtkLight() ); - renderer->AddActor( lightActor ); + m_vtkRenderWindow->RemoveRenderer(vtkRenderer); } } - // Add camera - //auto camActor = vtkSmartPointer<vtkCameraActor>::New(); - //camActor->SetCamera( m_currentScene->getCamera()->getVtkCamera() ); - //renderer->AddActor( camActor ); - //renderer->GetActiveCamera()->SetFocalPoint(0,0,0); - renderer->SetActiveCamera( m_currentScene->getCamera()->getVtkCamera() ); - renderer->ResetCameraClippingRange(); - + // Update current scene + m_currentScene = scene; - // Global Axis - auto axes = vtkSmartPointer<vtkAxesActor>::New(); - renderer->AddActor(axes); + // Create renderer if it doesn't exist + if (!m_rendererMap.count(m_currentScene)) + { + m_rendererMap[m_currentScene] = std::make_shared<Renderer>(m_currentScene); + } - // Customize background colors - renderer->SetBackground(0.66,0.66,0.66); - renderer->SetBackground2(157.0/255.0*0.66,186/255.0*0.66,192.0/255.0*0.66); - renderer->GradientBackgroundOn(); + // Set renderer to renderWindow + m_vtkRenderWindow->AddRenderer(m_rendererMap.at(m_currentScene)->getVtkRenderer()); } void -Viewer::startRenderingLoop() +Viewer::setRenderingMode(Renderer::Mode mode) { - auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); - m_interactor->SetInteractorStyle( style ); - m_interactor->SetRenderWindow( m_renderWindow ); - m_interactor->Start(); -} + if( !m_currentScene ) + { + LOG(WARNING) << "Missing scene, can not set rendering mode.\n" + << "Use Viewer::setCurrentScene to setup scene."; + return; + } -void -Viewer::endRenderingLoop() -{ - m_interactor->TerminateApp(); -} + // Setup renderer + m_rendererMap.at(m_currentScene)->setup(mode); -vtkSmartPointer<vtkRenderWindow> -Viewer::getRenderWindow() const -{ - return m_renderWindow; + // Setup interactor style + if( mode == Renderer::Mode::DEBUG ) + { + auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); + m_vtkInteractor->SetInteractorStyle( style ); + } + else if( mode == Renderer::Mode::SIMULATION ) + { + auto style = vtkSmartPointer<vtkInteractorStyle>::New(); + m_vtkInteractor->SetInteractorStyle( style ); + } } void -Viewer::setRenderWindow(vtkSmartPointer<vtkRenderWindow>renWin) +Viewer::startRenderingLoop() { - m_renderWindow = renWin; + // Start interaction loop + m_vtkInteractor->Start(); } -std::shared_ptr<Scene> -Viewer::getCurrentScene() const +void +Viewer::endRenderingLoop() { - return m_currentScene; + m_vtkInteractor->TerminateApp(); } -void -Viewer::setCurrentScene(std::shared_ptr<Scene>scene) +vtkSmartPointer<vtkRenderWindow> +Viewer::getVtkRenderWindow() const { - m_currentScene = scene; + return m_vtkRenderWindow; } } diff --git a/Base/Rendering/imstkViewer.h b/Base/Rendering/imstkViewer.h index 574f089ef..ad892398b 100644 --- a/Base/Rendering/imstkViewer.h +++ b/Base/Rendering/imstkViewer.h @@ -23,8 +23,10 @@ #define imstkViewer_h #include <memory> +#include <unordered_map> #include "imstkScene.h" +#include "imstkRenderer.h" #include "vtkSmartPointer.h" #include "vtkRenderWindow.h" @@ -37,27 +39,28 @@ public: Viewer(std::string name = "iMSTK Viewer") { - m_renderWindow->SetWindowName(name.data()); - m_renderWindow->SetSize(1000,800); + m_vtkInteractor->SetRenderWindow( m_vtkRenderWindow ); + m_vtkRenderWindow->SetWindowName(name.data()); + m_vtkRenderWindow->SetSize(1000,800); } ~Viewer() = default; - void initRenderer(); - void startRenderingLoop(); - void endRenderingLoop(); + std::shared_ptr<Scene> getCurrentScene() const; + void setCurrentScene(std::shared_ptr<Scene>scene); + void setRenderingMode(Renderer::Mode mode); + void startRenderingLoop(); + void endRenderingLoop(); - vtkSmartPointer<vtkRenderWindow>getRenderWindow() const; - void setRenderWindow(vtkSmartPointer<vtkRenderWindow>renWin); + vtkSmartPointer<vtkRenderWindow>getVtkRenderWindow() const; - std::shared_ptr<Scene> getCurrentScene() const; - void setCurrentScene(std::shared_ptr<Scene>scene); protected: - vtkSmartPointer<vtkRenderWindow> m_renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); - vtkSmartPointer<vtkRenderWindowInteractor> m_interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); + vtkSmartPointer<vtkRenderWindow> m_vtkRenderWindow = vtkSmartPointer<vtkRenderWindow>::New(); + vtkSmartPointer<vtkRenderWindowInteractor> m_vtkInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); std::shared_ptr<Scene> m_currentScene; + std::unordered_map<std::shared_ptr<Scene>, std::shared_ptr<Renderer>> m_rendererMap; }; } diff --git a/Base/SimulationManager/imstkSimulationManager.cpp b/Base/SimulationManager/imstkSimulationManager.cpp index 835e06583..770fb4f88 100644 --- a/Base/SimulationManager/imstkSimulationManager.cpp +++ b/Base/SimulationManager/imstkSimulationManager.cpp @@ -114,7 +114,7 @@ SimulationManager::getViewer() const } void -SimulationManager::startSimulation(std::string sceneName) +SimulationManager::startSimulation(std::string sceneName, Renderer::Mode renderMode) { LOG(INFO) << "Starting simulation."; @@ -139,9 +139,9 @@ SimulationManager::startSimulation(std::string sceneName) return; } - // Init viewer renderer + // Init viewer m_viewer->setCurrentScene(startingScene); - m_viewer->initRenderer(); + m_viewer->setRenderingMode(renderMode); // Start scene this->startModuleInNewThread(startingScene); @@ -181,7 +181,9 @@ SimulationManager::switchScene(std::string newSceneName, bool unloadCurrentScene return; } - // TODO : update viewer + // Update viewer + m_viewer->setCurrentScene(newScene); + m_viewer->setRenderingMode(Renderer::Mode::SIMULATION); if (unloadCurrentScene) { diff --git a/Base/SimulationManager/imstkSimulationManager.h b/Base/SimulationManager/imstkSimulationManager.h index 1efdc3c54..4a03c8e36 100644 --- a/Base/SimulationManager/imstkSimulationManager.h +++ b/Base/SimulationManager/imstkSimulationManager.h @@ -60,7 +60,8 @@ public: std::shared_ptr<Viewer> getViewer() const; // Simulation - void startSimulation(std::string sceneName); + void startSimulation(std::string sceneName, + Renderer::Mode renderMode = Renderer::Mode::SIMULATION); void switchScene(std::string newSceneName, bool unloadCurrentScene); void runSimulation(); diff --git a/Examples/Sandbox/main.cpp b/Examples/Sandbox/main.cpp index 7468d1d90..ebf83c03f 100644 --- a/Examples/Sandbox/main.cpp +++ b/Examples/Sandbox/main.cpp @@ -34,7 +34,7 @@ int main() auto planeGeom = std::make_shared<imstk::Plane>(); - planeGeom->scale(8); + planeGeom->scale(10); auto planeObj = std::make_shared<imstk::VisualObject>("VisualPlane"); planeObj->setVisualGeometry(planeGeom); @@ -75,7 +75,7 @@ int main() cam1->setPosition(imstk::Vec3d(-5.5, 2.5, 32)); cam1->setFocalPoint(imstk::Vec3d(1, 1, 0)); - sdk->startSimulation("SceneTest"); + sdk->startSimulation("SceneTest", imstk::Renderer::Mode::DEBUG ); /* -- GitLab