diff --git a/CMake/External/External_VTK.cmake b/CMake/External/External_VTK.cmake index c9a55f7313cb6cf38f7d3ad8a1e96ce77450e552..fa76b5db9616056532385ee8dc9aa10cf16f598c 100644 --- a/CMake/External/External_VTK.cmake +++ b/CMake/External/External_VTK.cmake @@ -21,7 +21,8 @@ endif() set(VTK_MODULE_SETTINGS -DVTK_MODULE_ENABLE_VTK_ChartsCore:STRING=YES - -DVTK_MODULE_ENABLE_VTK_RenderingOpenGL2:STRING=YES + -DVTK_MODULE_ENABLE_MODULE_FiltersExtraction:STRING=YES + -DVTK_MODULE_ENABLE_MODULE_FiltersModeling:STRING=YES -DVTK_MODULE_ENABLE_VTK_IOExport:STRING=YES -DVTK_MODULE_ENABLE_VTK_IOImport:STRING=YES -DVTK_MODULE_ENABLE_VTK_IOParallel:STRING=YES @@ -36,15 +37,14 @@ set(VTK_MODULE_SETTINGS -DVTK_MODULE_ENABLE_VTK_InteractionWidgets:STRING=YES -DVTK_MODULE_ENABLE_VTK_glew:STRING=YES -DVTK_MODULE_ENABLE_VTK_RenderingContext2D:STRING=YES + -DVTK_MODULE_ENABLE_VTK_RenderingContextOpenGL2:STRING=YES + -DVTK_MODULE_ENABLE_VTK_RenderingOpenGL2:STRING=YES -DVTK_MODULE_ENABLE_VTK_RenderingVolumeOpenGL2:STRING=YES -DVTK_MODULE_ENABLE_VTK_ViewsContext2D:STRING=YES -DVTK_BUILD_EXAMPLES:STRING=DONT_WANT -DVTK_BUILD_TESTING:STRING=OFF -DVTK_GROUP_ENABLE_StandAlone:STRING=DONT_WANT - -DVTK_GROUP_ENABLE_Rendering:STRING=DONT_WANT --DVTK_MODULE_ENABLE_MODULE_FiltersModeling:STRING=YES --DVTK_MODULE_ENABLE_MODULE_FiltersExtraction:STRING=YES - ) + -DVTK_GROUP_ENABLE_Rendering:STRING=DONT_WANT) set(${PROJECT_NAME}_VTK_SOURCE GIT_REPOSITORY https://gitlab.kitware.com/vtk/vtk.git) if(${PROJECT_NAME}_VTK_REPO_SOURCE EQUAL "9.0") diff --git a/CMake/iMSTKConfig.cmake.in b/CMake/iMSTKConfig.cmake.in index d786876fc47d125cd2ada5f0e18a6b15cd5f305d..691c06bdcdcc4aa9a34ae9104b1936e8acd2325c 100644 --- a/CMake/iMSTKConfig.cmake.in +++ b/CMake/iMSTKConfig.cmake.in @@ -101,10 +101,13 @@ else() # modules are linked via `VTK::CommonCore` # vtk_module_autoinit is needed find_dependency(VTK COMPONENTS + ChartsCore CommonCore CommonDataModel FiltersGeneral FiltersSources + FiltersModeling + FiltersExtraction IOExport IOImport IOPLY @@ -113,10 +116,13 @@ else() ImagingCore InteractionStyle RenderingAnnotation + RenderingContext2D + RenderingContextOpenGL2 RenderingCore RenderingOpenGL2 RenderingVolume - RenderingVolumeOpenGL2) + RenderingVolumeOpenGL2 + ViewsContext2D) endif() # glfw, gli diff --git a/CMakeLists.txt b/CMakeLists.txt index c1f28d9cf750c655f7e9068e9d423071bfabc46c..52488774396ba1a2c680f3610a02260753ccbb03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,8 +282,8 @@ find_package(VTK COMPONENTS CommonDataModel FiltersGeneral FiltersSources -FiltersModeling -FiltersExtraction + FiltersModeling + FiltersExtraction IOExport IOImport IOPLY @@ -292,12 +292,13 @@ FiltersExtraction ImagingCore InteractionStyle RenderingAnnotation + RenderingContext2D + RenderingContextOpenGL2 RenderingCore RenderingOpenGL2 RenderingVolume RenderingVolumeOpenGL2 - ViewsContext2D -) + ViewsContext2D) # Vulkan set(Vulkan_Dependency) diff --git a/Source/Rendering/CMakeLists.txt b/Source/Rendering/CMakeLists.txt index fffe47d6cd413c2d3dc0eb2b71d8193e8b5ca9d3..e94b6841418ed96bd8f9ff11fe8a8e21d3496655 100644 --- a/Source/Rendering/CMakeLists.txt +++ b/Source/Rendering/CMakeLists.txt @@ -134,9 +134,12 @@ imstk_add_library( Rendering Animation glm ${VTK_LIBRARIES} - ${RENDERING_LIBRARIES} - #VERBOSE - ) + ${RENDERING_LIBRARIES}) + #VERBOSE) + +if( NOT iMSTK_USE_Vulkan ) + vtk_module_autoinit(TARGETS Rendering MODULES ${VTK_LIBRARIES}) +endif() #----------------------------------------------------------------------------- # Testing diff --git a/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp b/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp index 60a92b28d55a506065484e52917880b4fe17fe07..f2606e9e083bb2fea8e19fc84bf8b8b3ce627464 100644 --- a/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp +++ b/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp @@ -419,76 +419,76 @@ VTKRenderer::getAxesVisibility() const return m_AxesActor->GetVisibility(); } -//void -//VTKRenderer::setTimeTable(const std::unordered_map<std::string, double>& timeTable) -//{ -// // Sort by elapsed times -// std::vector<std::pair<std::string, double>> nameToTimesVec(timeTable.begin(), timeTable.end()); -// std::sort(nameToTimesVec.begin(), nameToTimesVec.end(), -// [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) { return a.second < b.second; }); -// -// // Construct vtkTable from provided data -// vtkSmartPointer<vtkDoubleArray> xIndices = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(0)); -// vtkSmartPointer<vtkDoubleArray> yElapsedTimes = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(1)); -// vtkSmartPointer<vtkStringArray> labels = vtkStringArray::SafeDownCast(m_timeTable->GetColumn(2)); -// -// labels->SetNumberOfValues(nameToTimesVec.size()); -// xIndices->SetNumberOfValues(nameToTimesVec.size()); -// yElapsedTimes->SetNumberOfValues(nameToTimesVec.size()); -// for (size_t i = 0; i < nameToTimesVec.size(); i++) -// { -// labels->SetValue(i, nameToTimesVec[i].first.c_str()); -// xIndices->SetValue(i, i + 1); -// yElapsedTimes->SetValue(i, nameToTimesVec[i].second); -// } -// -// // The range for the x axis is based on history of the elapsed times -// vtkAxis* botAxis = m_timeTableChart->GetAxis(vtkAxis::BOTTOM); -// -// // Get the previous and current range -// double newMaxElapsed = yElapsedTimes->GetRange()[1]; -// yElapsedTimes->Modified(); -// double currMaxElapsed = botAxis->GetMaximum(); -// -// // Always respect the max as all information should be shown -// if (newMaxElapsed > currMaxElapsed) -// { -// botAxis->SetRange(0.0, newMaxElapsed); -// } -// // But if current elapsed is less than the existing one we can lag -// else -// { -// // Lag downscaling by 400 iterations -// if (m_timeTableIter % 400 == 0) -// { -// botAxis->SetRange(0.0, newMaxElapsed); -// } -// else -// { -// botAxis->SetRange(0.0, currMaxElapsed); -// } -// m_timeTableIter++; -// } -// botAxis->Modified(); -// -// vtkAxis* leftAxis = m_timeTableChart->GetAxis(vtkAxis::LEFT); -// leftAxis->SetRange(xIndices->GetRange()); -// leftAxis->SetCustomTickPositions(xIndices, labels); -// -// m_timeTable->Modified(); -//} -// -//void -//VTKRenderer::setTimeTableVisibility(const bool visible) -//{ -// m_timeTableChartActor->SetVisibility(visible); -//} -// -//bool -//VTKRenderer::getTimeTableVisibility() const -//{ -// return m_timeTableChartActor->GetVisibility(); -//} +void +VTKRenderer::setTimeTable(const std::unordered_map<std::string, double>& timeTable) +{ + // Sort by elapsed times + std::vector<std::pair<std::string, double>> nameToTimesVec(timeTable.begin(), timeTable.end()); + std::sort(nameToTimesVec.begin(), nameToTimesVec.end(), + [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) { return a.second < b.second; }); + + // Construct vtkTable from provided data + vtkSmartPointer<vtkDoubleArray> xIndices = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(0)); + vtkSmartPointer<vtkDoubleArray> yElapsedTimes = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(1)); + vtkSmartPointer<vtkStringArray> labels = vtkStringArray::SafeDownCast(m_timeTable->GetColumn(2)); + + labels->SetNumberOfValues(nameToTimesVec.size()); + xIndices->SetNumberOfValues(nameToTimesVec.size()); + yElapsedTimes->SetNumberOfValues(nameToTimesVec.size()); + for (size_t i = 0; i < nameToTimesVec.size(); i++) + { + labels->SetValue(i, nameToTimesVec[i].first.c_str()); + xIndices->SetValue(i, i + 1); + yElapsedTimes->SetValue(i, nameToTimesVec[i].second); + } + + // The range for the x axis is based on history of the elapsed times + vtkAxis* botAxis = m_timeTableChart->GetAxis(vtkAxis::BOTTOM); + + // Get the previous and current range + double newMaxElapsed = yElapsedTimes->GetRange()[1]; + yElapsedTimes->Modified(); + double currMaxElapsed = botAxis->GetMaximum(); + + // Always respect the max as all information should be shown + if (newMaxElapsed > currMaxElapsed) + { + botAxis->SetRange(0.0, newMaxElapsed); + } + // But if current elapsed is less than the existing one we can lag + else + { + // Lag downscaling by 400 iterations + if (m_timeTableIter % 400 == 0) + { + botAxis->SetRange(0.0, newMaxElapsed); + } + else + { + botAxis->SetRange(0.0, currMaxElapsed); + } + m_timeTableIter++; + } + botAxis->Modified(); + + vtkAxis* leftAxis = m_timeTableChart->GetAxis(vtkAxis::LEFT); + leftAxis->SetRange(xIndices->GetRange()); + leftAxis->SetCustomTickPositions(xIndices, labels); + + m_timeTable->Modified(); +} + +void +VTKRenderer::setTimeTableVisibility(const bool visible) +{ + m_timeTableChartActor->SetVisibility(visible); +} + +bool +VTKRenderer::getTimeTableVisibility() const +{ + return m_timeTableChartActor->GetVisibility(); +} void VTKRenderer::updateSceneCamera(std::shared_ptr<Camera> imstkCam) diff --git a/Source/Rendering/VTKRenderer/imstkVTKRenderer.h b/Source/Rendering/VTKRenderer/imstkVTKRenderer.h index fca9a81520cdc09d76844786d3480b34732e0499..17f0a6382a707f1b96d343ee5e8e7f8c42c1e3a9 100644 --- a/Source/Rendering/VTKRenderer/imstkVTKRenderer.h +++ b/Source/Rendering/VTKRenderer/imstkVTKRenderer.h @@ -102,17 +102,17 @@ public: /// /// \brief Sets the benchmarking table using unordered_map /// - //void setTimeTable(const std::unordered_map<std::string, double>& timeTable); + void setTimeTable(const std::unordered_map<std::string, double>& timeTable); /// /// \brief Set the visibility of the benchmark graph /// - //void setTimeTableVisibility(const bool visible); + void setTimeTableVisibility(const bool visible); /// /// \brief Get the visibility of the benchmark graph /// - //bool getTimeTableVisibility() const; + bool getTimeTableVisibility() const; /// /// \brief Updates the scene camera's position and orientation diff --git a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp index d5ab9f6b983c4d52c82ff1f0134a3b480bfacf23..e53ca868bf6ea18f80a3479c8f6749eae1ae272e 100644 --- a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp +++ b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp @@ -80,9 +80,9 @@ VTKViewer::VTKViewer(SimulationManager* manager /*= nullptr*/, bool enableVR /*= #endif // Setup callback for timer on the interactor - /*timerCallbackCommand = vtkSmartPointer<vtkCallbackCommand>::New(); + timerCallbackCommand = vtkSmartPointer<vtkCallbackCommand>::New(); timerCallbackCommand->SetCallback(timerCallback); - timerCallbackCommand->SetClientData(this);*/ + timerCallbackCommand->SetClientData(this); } void @@ -190,13 +190,13 @@ VTKViewer::startRenderingLoop() m_vtkRenderWindow->GetInteractor()->CreateOneShotTimer(0); // If the Scene wants benchmarking hookup timer to update the table - /*auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(getActiveRenderer()); + auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(getActiveRenderer()); vtkRen->setTimeTableVisibility(m_activeScene->getConfig()->taskTimingEnabled); if (m_activeScene->getConfig()->taskTimingEnabled) { m_vtkRenderWindow->GetInteractor()->AddObserver(vtkCommand::TimerEvent, timerCallbackCommand); m_vtkRenderWindow->GetInteractor()->CreateRepeatingTimer(500); - }*/ + } m_vtkRenderWindow->SetWindowName(m_config->m_windowName.c_str()); m_vtkRenderWindow->GetInteractor()->Start(); @@ -254,17 +254,17 @@ VTKViewer::getTextStatusManager() return m_vtkInteractorStyle->getTextStatusManager(); } -//void -//VTKViewer::timerCallback(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* clientData, void* vtkNotUsed(callData)) -//{ -// VTKViewer* self = static_cast<VTKViewer*>(clientData); -// -// if (self->getActiveScene()->getConfig()->taskTimingEnabled) -// { -// auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(self->getActiveRenderer()); -// self->getActiveScene()->lockComputeTimes(); -// vtkRen->setTimeTable(self->getActiveScene()->getTaskComputeTimes()); -// self->getActiveScene()->unlockComputeTimes(); -// } -//} +void +VTKViewer::timerCallback(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* clientData, void* vtkNotUsed(callData)) +{ + VTKViewer* self = static_cast<VTKViewer*>(clientData); + + if (self->getActiveScene()->getConfig()->taskTimingEnabled) + { + auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(self->getActiveRenderer()); + self->getActiveScene()->lockComputeTimes(); + vtkRen->setTimeTable(self->getActiveScene()->getTaskComputeTimes()); + self->getActiveScene()->unlockComputeTimes(); + } +} } // imstk diff --git a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h index 2cc0c11031e4f73775d04d3e31c919adbc423eef..a762bcae464ad529da08501784250c965d4dca52 100644 --- a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h +++ b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h @@ -110,14 +110,14 @@ public: const std::shared_ptr<VTKTextStatusManager>& getTextStatusManager(); protected: - /// \brief TODO - //static void timerCallback(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData); + /// \brief VTKTimer callback, every 500ms + static void timerCallback(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData); vtkSmartPointer<vtkRenderWindow> m_vtkRenderWindow; std::shared_ptr<VTKInteractorStyle> m_vtkInteractorStyle; bool m_enableVR; - //vtkSmartPointer<vtkCallbackCommand> timerCallbackCommand; + vtkSmartPointer<vtkCallbackCommand> timerCallbackCommand; #ifdef iMSTK_ENABLE_VR vtkSmartPointer<OpenVRCommand> m_openVRCommand;