diff --git a/Base/Rendering/imstkVTKRenderer.cpp b/Base/Rendering/imstkVTKRenderer.cpp index 918ec2a146fcbf3f706a336a7e062e7c1eed4289..1796aefeacd37aa3e163e055d0428695edbe48a5 100644 --- a/Base/Rendering/imstkVTKRenderer.cpp +++ b/Base/Rendering/imstkVTKRenderer.cpp @@ -210,4 +210,19 @@ VTKRenderer::addActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList) } } +void +VTKRenderer::updateBackground(Vec3d backgroundOne, Vec3d backgroundTwo /*= Vec3d::Zero()*/, bool gradientBackground /*= false*/) +{ + m_vtkRenderer->SetBackground(backgroundOne.x(), backgroundOne.y(), backgroundOne.z()); + if (gradientBackground) + { + m_vtkRenderer->SetBackground2(backgroundTwo.x(), backgroundTwo.y(), backgroundTwo.z()); + m_vtkRenderer->GradientBackgroundOn(); + } + else + { + m_vtkRenderer->GradientBackgroundOff(); + } +} + } // imstk diff --git a/Base/Rendering/imstkVTKRenderer.h b/Base/Rendering/imstkVTKRenderer.h index 67a72e76d9227ef3ea1705c2fe7428a305143876..c21cb158ed37917cd353a0b22e24eb3a65fe2b00 100644 --- a/Base/Rendering/imstkVTKRenderer.h +++ b/Base/Rendering/imstkVTKRenderer.h @@ -25,6 +25,8 @@ #include <memory> #include <vector> +#include "imstkMath.h" + #include "vtkSmartPointer.h" #include "vtkRenderer.h" #include "vtkProp.h" @@ -88,6 +90,10 @@ public: /// vtkSmartPointer<vtkRenderer> getVtkRenderer() const; + /// + /// \brief + void updateBackground(Vec3d color1, Vec3d color2 = Vec3d::Zero(), bool gradientBackground = false); + protected: /// /// \brief diff --git a/Base/SimulationManager/imstkVTKInteractorStyle.cpp b/Base/SimulationManager/imstkVTKInteractorStyle.cpp index 5a6bb07993f9529ba4b70216a44eec1a8ff07892..2fb78b1c8c368604d3b998de37ddcd91d8e1b7fe 100644 --- a/Base/SimulationManager/imstkVTKInteractorStyle.cpp +++ b/Base/SimulationManager/imstkVTKInteractorStyle.cpp @@ -46,6 +46,7 @@ VTKInteractorStyle::VTKInteractorStyle() m_fpsActor = vtkTextActor::New(); m_fpsActor->GetTextProperty()->SetFontSize(60); m_fpsActor->SetVisibility(m_displayFps); + m_screenCapturer = std::make_shared<VTKScreenCaptureUtility>(this->Interactor->GetRenderWindow()); } VTKInteractorStyle::~VTKInteractorStyle() @@ -115,6 +116,13 @@ VTKInteractorStyle::OnTimer() { this->Interactor->CreateOneShotTimer(1); } + + // Call custom behaviour + if (m_onTimerFunction) + { + // Call the custom behaviour to run on every frame + m_onTimerFunction(this); + } } void diff --git a/Base/SimulationManager/imstkVTKInteractorStyle.h b/Base/SimulationManager/imstkVTKInteractorStyle.h index 6ecff274cbefabe6a1a799b007fecac682845958..aea766838546a68a0892029992547e1f6607e718 100644 --- a/Base/SimulationManager/imstkVTKInteractorStyle.h +++ b/Base/SimulationManager/imstkVTKInteractorStyle.h @@ -27,6 +27,7 @@ #include <unordered_map> #include <functional> +#include "imstkVTKScreenCaptureUtility.h" #include "vtkInteractorStyleTrackballCamera.h" class vtkTextActor; @@ -134,8 +135,10 @@ private: VTKEventHandlerFunction m_onRightButtonUpFunction; VTKEventHandlerFunction m_onMouseWheelForwardFunction; VTKEventHandlerFunction m_onMouseWheelBackwardFunction; + VTKEventHandlerFunction m_onTimerFunction; SimulationManager* m_simManager; ///> SimulationManager owning the current simulation being interacted with + std::shared_ptr<VTKScreenCaptureUtility> m_screenCapturer; ///> Screen shot utility double m_targetMS; ///> expected time between each render frame (in ms) std::chrono::high_resolution_clock::time_point m_pre; ///> time point pre-rendering std::chrono::high_resolution_clock::time_point m_post; ///> time point post-rendering diff --git a/Base/SimulationManager/imstkVTKScreenCaptureUtility.cpp b/Base/SimulationManager/imstkVTKScreenCaptureUtility.cpp new file mode 100644 index 0000000000000000000000000000000000000000..517051bd6bcec03b8c31e1674d6db73451054cce --- /dev/null +++ b/Base/SimulationManager/imstkVTKScreenCaptureUtility.cpp @@ -0,0 +1,96 @@ +/*========================================================================= + + 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 "imstkVTKScreenCaptureUtility.h" + +#include "g3log/g3log.hpp" + +namespace imstk +{ + +VTKScreenCaptureUtility::VTKScreenCaptureUtility(vtkRenderWindow* const rw, const std::string prefix /*= "Screenshot-"*/) + :m_screenShotNumber(0) +{ + m_screenShotPrefix = prefix; + if (rw != nullptr) + m_renderWindow = rw; +} + + +void +VTKScreenCaptureUtility::saveScreenShot() +{ + if (m_renderWindow == nullptr) + { + LOG(WARNING) << "Render window has not been set yet! "; + return; + } + + + if (m_windowToImageFilter->GetInput() == nullptr) + { + m_windowToImageFilter->SetInput(m_renderWindow); + + m_windowToImageFilter->SetMagnification(1); + m_windowToImageFilter->SetInputBufferTypeToRGB(); + m_windowToImageFilter->ReadFrontBufferOff(); + m_windowToImageFilter->Update(); + + m_pngWriter->SetInputConnection(m_windowToImageFilter->GetOutputPort()); + } + + m_windowToImageFilter->Modified(); + + std::string captureName = m_screenShotPrefix + std::to_string(m_screenShotNumber) + ".png"; + + m_pngWriter->SetFileName(captureName.data()); + m_pngWriter->Write(); + + LOG(INFO) << "Screen shot " << m_screenShotNumber << " saved as " << captureName << "\n"; + + m_screenShotNumber++; +} + + +unsigned int +VTKScreenCaptureUtility::getScreenShotNumber() const +{ + return m_screenShotNumber; +} + +void +VTKScreenCaptureUtility::setScreenShotPrefix(const std::string newPrefix) +{ + if (m_screenShotPrefix.compare(newPrefix) != 0) + { + m_screenShotPrefix = newPrefix; + m_screenShotNumber = 0; + } +} + +void +VTKScreenCaptureUtility::resetScreenShotNumber() +{ + m_screenShotNumber = 0; +} + + +} // imstk diff --git a/Base/SimulationManager/imstkVTKScreenCaptureUtility.h b/Base/SimulationManager/imstkVTKScreenCaptureUtility.h new file mode 100644 index 0000000000000000000000000000000000000000..986b58c6908828873b5366dbf11c271ebf0550fc --- /dev/null +++ b/Base/SimulationManager/imstkVTKScreenCaptureUtility.h @@ -0,0 +1,81 @@ +/*========================================================================= + + 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 imstkScreenCaptureUtility_h +#define imstkScreenCaptureUtility_h + +#include "vtkNew.h" +#include "vtkRenderWindow.h" +#include "vtkWindowToImageFilter.h" +#include "vtkPNGWriter.h" + +#include <string> + +namespace imstk +{ + +/// +/// \class VTKScreenCaptureUtility +/// +/// \brief Utility class to manage screen capture through VTK +/// +class VTKScreenCaptureUtility +{ +public: + /// + /// \brief Constructor + /// + VTKScreenCaptureUtility(vtkRenderWindow* const rw, const std::string prefix = "Screenshot-"); + + /// + /// \brief Destructor + /// + ~VTKScreenCaptureUtility() = default; + + /// + /// \brief Saves the screenshot as a png file + /// + void saveScreenShot(); + + /// + /// \brief Returns the number of the screenshot + /// + unsigned int getScreenShotNumber() const; + + /// + /// \brief set/reset the prefix amd the count numbers + void setScreenShotPrefix(const std::string newPrefix); + + /// + /// \brief reset the screenshot number indicator + void resetScreenShotNumber(); + +protected: + vtkNew<vtkWindowToImageFilter> m_windowToImageFilter; + vtkNew<vtkPNGWriter> m_pngWriter; //> using vtk's png writer to save the screenshots + vtkRenderWindow* m_renderWindow; //> render window whose screen shot will be taken + unsigned int m_screenShotNumber; //> screen shot number is added to the file prefix, and incremented everytime a screen shot is taken + std::string m_screenShotPrefix; //> the prefix for the screenshots to be saved +}; + +} // imstk + +#endif // ifndef imstkScreenCaptureUtility_h \ No newline at end of file diff --git a/Base/SimulationManager/imstkVTKViewer.cpp b/Base/SimulationManager/imstkVTKViewer.cpp index dbf8a229e76c2455fe0184511e55317f48499ee1..83323a6a7d2e145ea64e2d54f9c9437b1e350ddf 100644 --- a/Base/SimulationManager/imstkVTKViewer.cpp +++ b/Base/SimulationManager/imstkVTKViewer.cpp @@ -134,6 +134,10 @@ VTKViewer::startRenderingLoop() void VTKViewer::endRenderingLoop() { + // close the rendering window + m_vtkRenderWindow->Finalize(); + + // Terminate the interactor m_vtkRenderWindow->GetInteractor()->TerminateApp(); } @@ -239,4 +243,28 @@ VTKViewer::setOnMouseWheelBackwardFunction(VTKEventHandlerFunction func) m_interactorStyle->m_onMouseWheelBackwardFunction = func; } +void +VTKViewer::setOnTimerFunction(VTKEventHandlerFunction func) +{ + m_interactorStyle->m_onTimerFunction = func; +} + +void +VTKViewer::setScreenCapturePrefix(const std::string newPrefix) +{ + m_interactorStyle->m_screenCapturer->setScreenShotPrefix(newPrefix); +} + +void +VTKViewer::captureScreen() const +{ + m_interactorStyle->m_screenCapturer->saveScreenShot(); +} + +void +VTKViewer::resetScreenShotNumber() const +{ + m_interactorStyle->m_screenCapturer->resetScreenShotNumber(); +} + } // imstk diff --git a/Base/SimulationManager/imstkVTKViewer.h b/Base/SimulationManager/imstkVTKViewer.h index 4bf8e399f0cfcb84c43b7dc5adaca0ae5e4ab991..6b258aac11fcf7ca43883f1adb2f5698a626078f 100644 --- a/Base/SimulationManager/imstkVTKViewer.h +++ b/Base/SimulationManager/imstkVTKViewer.h @@ -33,6 +33,9 @@ #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" +//Screenshot utility +#include "imstkVTKScreenCaptureUtility.h" + namespace imstk { @@ -131,7 +134,25 @@ public: void setOnRightButtonUpFunction(VTKEventHandlerFunction func); void setOnMouseWheelForwardFunction(VTKEventHandlerFunction func); void setOnMouseWheelBackwardFunction(VTKEventHandlerFunction func); + // Set custom behaviour to be run on every frame. + // The return of the function will not have any effect. + void setOnTimerFunction(VTKEventHandlerFunction func); + + /// + /// \brief set the screen capture prefix + /// + void setScreenCapturePrefix(const std::string newPrefix); + + /// + /// \brief Call capture screen + /// + void captureScreen() const; + /// + ///\brief reset the screen capture count + /// + void resetScreenShotNumber() const; + protected: vtkSmartPointer<vtkRenderWindow> m_vtkRenderWindow = vtkSmartPointer<vtkRenderWindow>::New();