diff --git a/CMake/External/External_VTK.cmake b/CMake/External/External_VTK.cmake index fa76b5db9616056532385ee8dc9aa10cf16f598c..06122f9ec4492a82d6b17d1a45d005e6c23abc53 100644 --- a/CMake/External/External_VTK.cmake +++ b/CMake/External/External_VTK.cmake @@ -12,12 +12,6 @@ endif() set(${PROJECT_NAME}_VTK_REPO_SOURCE "9.0" CACHE STRING "Select VTK Source Branch/Tag") set(VTK_SOURCES "9.0;master;release;nightly-master" CACHE INTERNAL "List of available VTK branch,tags to get") set_property(CACHE ${PROJECT_NAME}_VTK_REPO_SOURCE PROPERTY STRINGS ${VTK_SOURCES}) - -if (${${PROJECT_NAME}_ENABLE_OPENVR}) - set(VTK_OPENVR "WANT") -else() - set(VTK_OPENVR "DONT_WANT") -endif() set(VTK_MODULE_SETTINGS -DVTK_MODULE_ENABLE_VTK_ChartsCore:STRING=YES @@ -33,7 +27,7 @@ set(VTK_MODULE_SETTINGS -DVTK_MODULE_ENABLE_VTK_IOGeometry:STRING=YES -DVTK_MODULE_ENABLE_VTK_InteractionStyle:STRING=YES -DVTK_MODULE_ENABLE_VTK_RenderingAnnotation:STRING=YES - -DVTK_MODULE_ENABLE_VTK_RenderingOpenVR:STRING=${VTK_OPENVR} + -DVTK_MODULE_ENABLE_VTK_RenderingOpenVR:STRING=${VTK_ENABLE_OPENVR} -DVTK_MODULE_ENABLE_VTK_InteractionWidgets:STRING=YES -DVTK_MODULE_ENABLE_VTK_glew:STRING=YES -DVTK_MODULE_ENABLE_VTK_RenderingContext2D:STRING=YES diff --git a/CMake/iMSTKConfig.cmake.in b/CMake/iMSTKConfig.cmake.in index 691c06bdcdcc4aa9a34ae9104b1936e8acd2325c..641e239b5325ab2fcdfb179cd1581a6743896b4b 100644 --- a/CMake/iMSTKConfig.cmake.in +++ b/CMake/iMSTKConfig.cmake.in @@ -92,38 +92,35 @@ endif() # VTK set(VTK_DIR @VTK_DIR@) find_dependency(VTK CONFIG) -if (VTK_VERSION VERSION_LESS "8.90") - # Modules are linked via `vtkCommonCore` - # VTK_DEFINITIONS has autoinit information - find_dependency (VTK REQUIRED) - include(${VTK_USE_FILE}) -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 - IOParallel - IOParallelXML - ImagingCore - InteractionStyle - RenderingAnnotation - RenderingContext2D - RenderingContextOpenGL2 - RenderingCore - RenderingOpenGL2 - RenderingVolume - RenderingVolumeOpenGL2 - ViewsContext2D) +# modules are linked via `VTK::CommonCore` +# vtk_module_autoinit is needed +list(APPEND VTK_DEPENDENCIES + ChartsCore + CommonCore + CommonDataModel + FiltersGeneral + FiltersSources + FiltersModeling + FiltersExtraction + IOExport + IOImport + IOPLY + IOParallel + IOParallelXML + ImagingCore + InteractionStyle + RenderingAnnotation + RenderingContext2D + RenderingContextOpenGL2 + RenderingCore + RenderingOpenGL2 + RenderingVolume + RenderingVolumeOpenGL2 + ViewsContext2D) +if (${PROJECT_NAME}_ENABLE_VR) + list(APPEND VTK_DEPENDENCIES vtkRenderingOpenVR) endif() +find_dependency(VTK COMPONENTS ${VTK_DEPENDENCIES}) # glfw, gli if(iMSTK_USE_Vulkan) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52488774396ba1a2c680f3610a02260753ccbb03..354c199af73ec389624b67ccd84cbb076fc32ee3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -276,7 +276,7 @@ endif() find_package(VTK CONFIG) # modules are linked via `VTK::CommonCore` # vtk_module_autoinit is needed -find_package(VTK COMPONENTS +list(APPEND VTK_DEPENDENCIES ChartsCore CommonCore CommonDataModel @@ -299,6 +299,10 @@ find_package(VTK COMPONENTS RenderingVolume RenderingVolumeOpenGL2 ViewsContext2D) +if (${PROJECT_NAME}_ENABLE_VR) + list(APPEND VTK_DEPENDENCIES vtkRenderingOpenVR) +endif() +find_package(VTK COMPONENTS ${VTK_DEPENDENCIES}) # Vulkan set(Vulkan_Dependency) diff --git a/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp b/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp index 4da0b8f5cf78a2602b038c2ef88df03ecfdd3e26..823992faad968ce755ba22ec7130c1cc3dc7b9e2 100644 --- a/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp +++ b/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp @@ -40,7 +40,7 @@ using namespace imstk; /// /// \brief Creates a non-manifold top part of a staircase -//. +// static std::unique_ptr<SurfaceMesh> buildStairs(int nSteps, double width, double height, double depth) { @@ -95,6 +95,9 @@ buildStairs(int nSteps, double width, double height, double depth) return stairMesh; } +//// +/// \brief Creates an Armadillo PbdObject +/// static std::shared_ptr<PbdObject> makeArmadilloPbdObject(const std::string& name) { diff --git a/Examples/PBD/PBDString/pbdStringExample.cpp b/Examples/PBD/PBDString/pbdStringExample.cpp index d59f975374963f11c0d44569947846b1e78d5a9d..2b3e9e8165f298b815bf2ecae5399072156cb977 100644 --- a/Examples/PBD/PBDString/pbdStringExample.cpp +++ b/Examples/PBD/PBDString/pbdStringExample.cpp @@ -98,7 +98,7 @@ makePbdString( material->setEdgeColor(color); material->setLineWidth(2.0f); material->setPointSize(6.0f); - material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface); + material->setDisplayMode(RenderMaterial::DisplayMode::Wireframe); std::shared_ptr<VisualModel> visualModel = std::make_shared<VisualModel>(stringMesh); visualModel->setRenderMaterial(material); diff --git a/Source/Rendering/CMakeLists.txt b/Source/Rendering/CMakeLists.txt index e94b6841418ed96bd8f9ff11fe8a8e21d3496655..52326e9f6b34ee402083b3232cf2c138efc7b713 100644 --- a/Source/Rendering/CMakeLists.txt +++ b/Source/Rendering/CMakeLists.txt @@ -97,6 +97,9 @@ if( NOT iMSTK_USE_Vulkan ) set(RENDERING_DEPENDENCIES #GUIOverlay Materials) + if (iMSTK_ENABLE_VR) + list(APPEND RENDERING_DEPENDENCIES openvr) + endif() else() set(RENDERING_H_FILES ${VULKAN_H_FILES}) set(RENDERING_CPP_FILES ${VULKAN_CPP_FILES}) @@ -111,9 +114,6 @@ else() ${Vulkan} glfw gli) - if (iMSTK_ENABLE_VR) - list(APPEND RENDERING_DEPENDENCIES openvr) - endif() endif() include(imstkAddLibrary) @@ -121,11 +121,9 @@ imstk_add_library( Rendering H_FILES imstkRenderer.h ${RENDERING_H_FILES} - imstkVtkCapsuleSource.h CPP_FILES imstkRenderer.cpp ${RENDERING_CPP_FILES} - imstkVtkCapsuleSource.cpp SUBDIR_LIST ${RENDERING_SUBDIR} DEPENDS diff --git a/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKCapsuleRenderDelegate.cpp b/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKCapsuleRenderDelegate.cpp index 2a565169c0cfff7ced5f2ad6d44b3a36dcdaef42..6b272614f57f0814426b433e216271410f1fe4eb 100644 --- a/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKCapsuleRenderDelegate.cpp +++ b/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKCapsuleRenderDelegate.cpp @@ -21,13 +21,8 @@ #include "imstkVTKCapsuleRenderDelegate.h" #include "imstkCapsule.h" -#include "imstkVtkCapsuleSource.h" - -#include <vtkTransformPolyDataFilter.h> - -#if (VTK_MAJOR_VERSION >= 9) #include <vtkCapsuleSource.h> -#endif +#include <vtkTransformPolyDataFilter.h> namespace imstk { diff --git a/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp b/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp index f2606e9e083bb2fea8e19fc84bf8b8b3ce627464..fef99d9167f28b46497dd8377b25d0b4a2b1f684 100644 --- a/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp +++ b/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp @@ -202,43 +202,19 @@ VTKRenderer::VTKRenderer(std::shared_ptr<Scene> scene, const bool enableVR) : m_ #ifdef iMSTK_ENABLE_VR if (enableVR) { - m_camPos.resize(2); + m_cams.resize(2); // save debug camera m_camPos[0] - m_defaultVtkCamera->GetPosition(m_camPos[0].Position); - m_defaultVtkCamera->GetDirectionOfProjection(m_camPos[0].ViewDirection); - - m_camPos[0].PhysicalViewUp[0] = 0.0; - m_camPos[0].PhysicalViewUp[1] = 1.0; - m_camPos[0].PhysicalViewUp[2] = 0.0; - - m_camPos[0].PhysicalViewDirection[0] = 1.0; - m_camPos[0].PhysicalViewDirection[1] = 0.0; - m_camPos[0].PhysicalViewDirection[2] = 0.0; - - m_camPos[0].Distance = 10; // room scale factor - - m_camPos[0].Translation[0] = 0.0; - m_camPos[0].Translation[1] = 0.0; - m_camPos[0].Translation[2] = 0.0; + m_cams[0] = vtkSmartPointer<vtkOpenVRCamera>::New(); + m_cams[0]->SetPosition(m_defaultVtkCamera->GetPosition()); + m_cams[0]->SetViewUp(0.0, 1.0, 0.0); + m_cams[0]->SetDistance(10.0); // room scale factor // save scene camera m_camPos[1] - m_sceneVtkCamera->GetPosition(m_camPos[1].Position); - m_sceneVtkCamera->GetDirectionOfProjection(m_camPos[1].ViewDirection); - - m_camPos[1].PhysicalViewUp[0] = 0.0; - m_camPos[1].PhysicalViewUp[1] = 1.0; - m_camPos[1].PhysicalViewUp[2] = 0.0; - - m_camPos[1].PhysicalViewDirection[0] = 1.0; - m_camPos[1].PhysicalViewDirection[1] = 0.0; - m_camPos[1].PhysicalViewDirection[2] = 0.0; - - m_camPos[1].Distance = 1.0; // room scale factor of 1 meter - - m_camPos[1].Translation[0] = 0.0; - m_camPos[1].Translation[1] = 0.0; - m_camPos[1].Translation[2] = 0.0; + m_cams[1] = vtkSmartPointer<vtkOpenVRCamera>::New(); + m_cams[1]->SetPosition(m_sceneVtkCamera->GetPosition()); + m_cams[1]->SetViewUp(0.0, 1.0, 0.0); + m_cams[1]->SetDistance(1.0); // room scale factor of 1 meter } #endif @@ -342,7 +318,7 @@ VTKRenderer::setMode(const Renderer::Mode mode, const bool enableVR) #ifdef iMSTK_ENABLE_VR else // go to debug position camera { // apply debug camera - m_camPos[0].Apply(static_cast<vtkOpenVRCamera*>(m_vtkRenderer->GetActiveCamera()), renWin); + static_cast<vtkOpenVRCamera*>(m_vtkRenderer->GetActiveCamera())->DeepCopy(m_cams[0]); m_vtkRenderer->ResetCameraClippingRange(); } #endif @@ -365,9 +341,7 @@ VTKRenderer::setMode(const Renderer::Mode mode, const bool enableVR) // save last debug position camera if (enableVR) { - m_camPos[0].Set( - static_cast<vtkOpenVRCamera*>(m_vtkRenderer->GetActiveCamera()), - vtkOpenVRRenderWindow::SafeDownCast(renWin)); + static_cast<vtkOpenVRCamera*>(m_vtkRenderer->GetActiveCamera())->DeepCopy(m_cams[0]); } #endif } @@ -379,7 +353,7 @@ VTKRenderer::setMode(const Renderer::Mode mode, const bool enableVR) #ifdef iMSTK_ENABLE_VR else // go to Predefined sceneVtkCamera position { // apply scene camera - m_camPos[1].Apply(static_cast<vtkOpenVRCamera*>(m_vtkRenderer->GetActiveCamera()), renWin); + static_cast<vtkOpenVRCamera*>(m_vtkRenderer->GetActiveCamera())->DeepCopy(m_cams[1]); } #endif m_vtkRenderer->ResetCameraClippingRange(); diff --git a/Source/Rendering/VTKRenderer/imstkVTKRenderer.h b/Source/Rendering/VTKRenderer/imstkVTKRenderer.h index 17f0a6382a707f1b96d343ee5e8e7f8c42c1e3a9..8e619b29e5efb23c18639ed1ba9c8e4dee3a2d59 100644 --- a/Source/Rendering/VTKRenderer/imstkVTKRenderer.h +++ b/Source/Rendering/VTKRenderer/imstkVTKRenderer.h @@ -32,7 +32,6 @@ #include <vtkOpenVRRenderWindow.h> #include <vtkOpenVRRenderWindowInteractor.h> #include <vtkInteractorStyle3D.h> -#include <vtkOpenVROverlayInternal.h> #endif #include <unordered_map> @@ -174,7 +173,7 @@ protected: TextureManager<VTKTextureDelegate> m_textureManager; #ifdef iMSTK_ENABLE_VR - std::vector<vtkOpenVRCameraPose> m_camPos; + std::vector<vtkSmartPointer<vtkOpenVRCamera>> m_cams; #endif vtkSmartPointer<vtkChartXY> m_timeTableChart; diff --git a/Source/Rendering/imstkVtkCapsuleSource.cpp b/Source/Rendering/imstkVtkCapsuleSource.cpp deleted file mode 100644 index d1f2ca2d9b79a36f3cf34fd3db68b1dcbd6ec2b3..0000000000000000000000000000000000000000 --- a/Source/Rendering/imstkVtkCapsuleSource.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/*========================================================================= - - 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. - -=========================================================================*/ -// \author Johan Andruejol <johan.andruejol@kitware.com> - -#if (VTK_MAJOR_VERSION < 9) - -#include "vtkCapsuleSource.h" - -#include <vtkCellArray.h> -#include <vtkFloatArray.h> -#include <vtkInformation.h> -#include <vtkInformationVector.h> -#include <vtkMath.h> -#include <vtkObjectFactory.h> -#include <vtkPointData.h> -#include <vtkPoints.h> -#include <vtkPolyData.h> -#include <vtkStreamingDemandDrivenPipeline.h> - -#include <math.h> - -vtkStandardNewMacro(vtkCapsuleSource); - -//---------------------------------------------------------------------------- -// Construct sphere with radius=0.5 and default resolution 8 in both Phi -// and Theta directions. Theta ranges from (0,360) and phi (0,180) degrees. -/// \todo -vtkCapsuleSource::vtkCapsuleSource(int res) -{ - res = res < 8 ? 8 : res; - this->Radius = 0.5; - this->Center[0] = 0.0; - this->Center[1] = 0.0; - this->Center[2] = 0.0; - - this->ThetaResolution = res; - this->PhiResolution = res; - this->LatLongTessellation = 0; - this->CylinderLength = 1.0; - - this->SetNumberOfInputPorts(0); -} - -namespace -{ -void -InsertPole(vtkPoints* points, vtkFloatArray* normals, - double center[3], double radius, double halfHeight) -{ - double x[3]; - x[0] = center[0]; - x[1] = center[1] + halfHeight; - x[2] = center[2] + radius; - points->InsertNextPoint(x); - - x[0] = x[1] = 0.0; - x[2] = (radius > 0 ? 1.0 : -1.0); - normals->InsertNextTuple(x); -} - -void -FillHalfSphere(vtkPoints* points, vtkFloatArray* normals, - double thetaResolution, double phiResolution, - double startAngle /* In radians*/, double sign, - double center[3], double radius, double halfHeight) -{ - double n[3], x[3], norm; - - double deltaTheta = 3.1415926535897932384626 / (thetaResolution - 1); - double deltaPhi = 3.1415926535897932384626 / (phiResolution - 1); - for (int i = 0; i < thetaResolution; ++i) - { - double theta = startAngle + sign * i * deltaTheta; - - for (int j = 1; j < phiResolution - 1; ++j) - { - double phi = j * deltaPhi; - double r = radius * sin(phi); - n[0] = r * cos(theta); - n[1] = r * sin(theta); - n[2] = radius * cos(phi); - x[0] = n[0] + center[0]; - x[1] = n[1] + center[1] + halfHeight; - x[2] = n[2] + center[2]; - points->InsertNextPoint(x); - - if ( (norm = vtkMath::Norm(n)) == 0.0) - { - norm = 1.0; - } - n[0] /= norm; - n[1] /= norm; - n[2] /= norm; - normals->InsertNextTuple(n); - } - } -} - -void -ConnectCylinderSide(vtkCellArray* faces, - int minusPoleId, int plusPoleId, - int clockwise, int increment, bool quadrangle) -{ - vtkIdType pts[4]; - for (int i = 0; i < increment; ++i) - { - pts[0] = minusPoleId + clockwise * i; - pts[1] = plusPoleId + clockwise * i; - - if (!quadrangle) - { - pts[2] = pts[0] + clockwise; - faces->InsertNextCell(3, pts); - - pts[0] = pts[2]; - pts[2] = pts[1] + clockwise; - faces->InsertNextCell(3, pts); - } - else - { - pts[2] = pts[1] + clockwise; - pts[3] = pts[0] + clockwise; - faces->InsertNextCell(4, pts); - } - } -} -} // end namespace - -//---------------------------------------------------------------------------- -int -vtkCapsuleSource::RequestData( - vtkInformation* vtkNotUsed(request), - vtkInformationVector** vtkNotUsed(inputVector), - vtkInformationVector* outputVector) -{ - // get the info object - vtkInformation* outInfo = outputVector->GetInformationObject(0); - - // get the ouptut - vtkPolyData* output = vtkPolyData::SafeDownCast( - outInfo->Get(vtkDataObject::DATA_OBJECT())); - - vtkPoints* newPoints; - vtkFloatArray* newNormals; - vtkCellArray* newPolys; - - // Set number of points.; - int halfSphereNumPts = (this->PhiResolution - 2) * this->ThetaResolution + 2; - int numPts = halfSphereNumPts * 2; - - // Set number of faces - int halfSpheresNumsPolys = (this->ThetaResolution - 1) * 2 //top and bottom - + (this->PhiResolution - 3) * (this->ThetaResolution - 1) * 2; //middle - int cylinderNumPolys = (this->PhiResolution - 1) * 4; - int numPolys = halfSpheresNumsPolys * 2 + cylinderNumPolys; - - // Allocate ! - newPoints = vtkPoints::New(); - newPoints->Allocate(numPts); - newNormals = vtkFloatArray::New(); - newNormals->SetNumberOfComponents(3); - newNormals->Allocate(3 * numPts); - newNormals->SetName("Normals"); - - newPolys = vtkCellArray::New(); - newPolys->Allocate(newPolys->EstimateSize(numPolys, 3)); - - // - // Create half sphere 1, plus side - // - double halfHeight = this->CylinderLength / 2.0; - - // North pole - InsertPole(newPoints, newNormals, this->Center, this->Radius, halfHeight); - this->UpdateProgress(0.05); - - // Create intermediate points - FillHalfSphere(newPoints, newNormals, - this->ThetaResolution, this->PhiResolution, - 0.0, 1.0, - this->Center, this->Radius, halfHeight); - this->UpdateProgress(0.255); - - // South pole - InsertPole(newPoints, newNormals, this->Center, -1 * this->Radius, halfHeight); - this->UpdateProgress(0.30); // First half sphere done ! - - // - // Create half sphere 2, minus side - // - - // North pole - InsertPole(newPoints, newNormals, this->Center, this->Radius, -1 * halfHeight); - this->UpdateProgress(0.305); - - // Create intermediate points - FillHalfSphere(newPoints, newNormals, - this->ThetaResolution, this->PhiResolution, - 6.283185307179586, -1, - this->Center, this->Radius, -1.0 * halfHeight); - this->UpdateProgress(0.555); - - // South pole - InsertPole(newPoints, newNormals, - this->Center, -1 * this->Radius, -1 * halfHeight); - this->UpdateProgress(0.60); // Second half sphere done ! - - // - // Generate mesh connectivity - // - - vtkIdType pts[4]; - // increment represent how many ids have passed every - // time we change by one delta theta - int increment = this->PhiResolution - 2; - // Ids of the poles - int northPoleMinusId = 0; - int southPoleMinusId = halfSphereNumPts - 1; - int northPolePlusId = halfSphereNumPts; - int southPolePlusId = numPts - 1; - - //First half sphere - // Connect the minus side half sphere north pole. - for (int i = 0; i < this->ThetaResolution - 1; ++i) - { - pts[0] = northPoleMinusId; - pts[1] = (i * increment) + 1; - pts[2] = pts[1] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.605); - - // South pole connectivity - for (int i = 1; i < this->ThetaResolution; ++i) - { - pts[0] = i * increment; - pts[1] = southPoleMinusId; - pts[2] = pts[0] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.75); //First half-sphere done ! - - // Seconde half sphere - // North pole connectivity - for (int i = 0; i < this->ThetaResolution - 1; ++i) - { - pts[2] = northPolePlusId; - pts[1] = (i * increment) + 1 + northPolePlusId; - pts[0] = pts[1] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.755); - - // South pole connectivity - for (int i = 1; i < this->ThetaResolution; i++) - { - pts[0] = northPolePlusId + i * increment; - pts[2] = southPolePlusId; - pts[1] = pts[0] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.9); - - // Both half sphere at the same time, connectivity of the band. - vtkIdType ptsOtherSide[4]; - for (int i = 1; i < northPolePlusId - 1 - increment; i += increment) - { - for (int j = 0; j < increment - 1; ++j) - { - pts[0] = j + i; - pts[1] = j + i + 1; - pts[2] = j + i + increment + 1; - - ptsOtherSide[0] = pts[0] + northPolePlusId; - ptsOtherSide[1] = pts[2] + northPolePlusId; - ptsOtherSide[2] = pts[1] + northPolePlusId; - - if (!this->LatLongTessellation) - { - newPolys->InsertNextCell(3, pts); - newPolys->InsertNextCell(3, ptsOtherSide); - pts[1] = pts[2]; - pts[2] = j + i + increment; - - ptsOtherSide[1] = pts[2] + northPolePlusId; - ptsOtherSide[2] = pts[1] + northPolePlusId; - - newPolys->InsertNextCell(3, pts); - newPolys->InsertNextCell(3, ptsOtherSide); - } - else - { - pts[3] = j + i + increment; - - ptsOtherSide[1] = pts[3] + northPolePlusId; - ptsOtherSide[3] = ptsOtherSide[2]; - ptsOtherSide[2] = pts[2] + northPolePlusId; - - newPolys->InsertNextCell(4, pts); - newPolys->InsertNextCell(4, ptsOtherSide); - } - } - } - - // Cylinder pole connectivity - // first side - ConnectCylinderSide(newPolys, - northPoleMinusId, northPolePlusId, 1, - increment, this->LatLongTessellation); - - // second side - ConnectCylinderSide(newPolys, - southPoleMinusId, southPolePlusId, -1, - increment, this->LatLongTessellation); - this->UpdateProgress(0.99); - - // Weird south pole minus face case - pts[0] = northPoleMinusId + increment; - pts[1] = northPolePlusId + increment; - if (!this->LatLongTessellation) - { - pts[2] = southPoleMinusId; - newPolys->InsertNextCell(3, pts); - - pts[0] = pts[1]; - pts[1] = southPolePlusId; - newPolys->InsertNextCell(3, pts); - } - else - { - pts[2] = southPolePlusId; - pts[3] = southPoleMinusId; - newPolys->InsertNextCell(4, pts); - } - - // Weird north pole 2 face case - pts[0] = southPoleMinusId - increment; - pts[1] = southPolePlusId - increment; - if (!this->LatLongTessellation) - { - pts[2] = northPoleMinusId; - newPolys->InsertNextCell(3, pts); - - pts[0] = pts[1]; - pts[1] = northPolePlusId; - newPolys->InsertNextCell(3, pts); - } - else - { - pts[2] = northPolePlusId; - pts[3] = northPoleMinusId; - newPolys->InsertNextCell(4, pts); - } - - // Update ourselves and release memeory - // - newPoints->Squeeze(); - output->SetPoints(newPoints); - newPoints->Delete(); - - newNormals->Squeeze(); - output->GetPointData()->SetNormals(newNormals); - newNormals->Delete(); - - newPolys->Squeeze(); - output->SetPolys(newPolys); - newPolys->Delete(); - - return 1; -} - -//---------------------------------------------------------------------------- -void -vtkCapsuleSource::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); - - os << indent << "Theta Resolution: " << this->ThetaResolution << "\n"; - os << indent << "Phi Resolution: " << this->PhiResolution << "\n"; - os << indent << "Radius: " << this->Radius << "\n"; - os << indent << "Center: (" << this->Center[0] << ", " - << this->Center[1] << ", " << this->Center[2] << ")\n"; - os << indent - << "LatLong Tessellation: " << this->LatLongTessellation << "\n"; - os << indent << "Cylinder Length: " << this->CylinderLength << "\n"; -} - -//---------------------------------------------------------------------------- -#pragma warning(push) -#pragma warning(disable : 4100) -int -vtkCapsuleSource::RequestInformation( - vtkInformation* vtkNotUsed(request), - vtkInformationVector** vtkNotUsed(inputVector), - vtkInformationVector* outputVector) -{ - std::cout << "WARNING-vtkCapsuleSource::RequestInformation is not implemented!" << std::endl; - // get the info object - /*vtkInformation *outInfo = outputVector->GetInformationObject(0); - - outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), - -1); - - double halfLength = this->CylinderLength / 2.0; - outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX(), - this->Center[0] - this->Radius - halfLength, - this->Center[0] + this->Radius + halfLength, - this->Center[1] - this->Radius, - this->Center[1] + this->Radius, - this->Center[2] - this->Radius, - this->Center[2] + this->Radius);*/ - - return 1; -} - -#pragma warning(pop) - -#endif \ No newline at end of file diff --git a/Source/Rendering/imstkVtkCapsuleSource.h b/Source/Rendering/imstkVtkCapsuleSource.h deleted file mode 100644 index 86085932aa3b836ad498557cc2e29a68d771ff13..0000000000000000000000000000000000000000 --- a/Source/Rendering/imstkVtkCapsuleSource.h +++ /dev/null @@ -1,113 +0,0 @@ -/*========================================================================= - - 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. - -=========================================================================*/ -// .NAME vtkCapsuleSource - Generate a capsule centered at the origin -// .SECTION Description -// vtkCapsuleSource creates a capsule (represented by polygons) of specified -// radius centered at the origin. The resolution (polygonal discretization) -// in both the latitude (phi) and longitude (theta) directions can be -// specified as well as the length of the capsule cylinder (CylinderLength). -// By default, the surface tessellation of the sphere uses triangles; -// however you can set LatLongTessellation to -// produce a tessellation using quadrilaterals (except at the poles of the -// capsule). - -// \author Johan Andruejol <johan.andruejol@kitware.com> - -#if (VTK_MAJOR_VERSION < 9) - -#pragma once - -// VTK includes -#include <vtkPolyDataAlgorithm.h> - -#define VTK_MAX_SPHERE_RESOLUTION 1024 - -/// \brief TODO -class vtkCapsuleSource : public vtkPolyDataAlgorithm -{ -public: - vtkTypeMacro(vtkCapsuleSource, vtkPolyDataAlgorithm); - void PrintSelf(ostream& os, vtkIndent indent); - - // Description: - // Construct sphere with radius=0.5 and default resolution 8 in both Phi - // and Theta directions. - static vtkCapsuleSource* New(); - - // Description: - // Set radius of sphere. Default is 0.5. - vtkSetClampMacro(Radius, double, 0.0, VTK_DOUBLE_MAX); - vtkGetMacro(Radius, double); - - // Description: - // Set the center of the sphere. Default is 0,0,0. - vtkSetVector3Macro(Center, double); - vtkGetVectorMacro(Center, double, 3); - - // Description: - // Set the length of the cylinder. Default is 1.0. - vtkSetClampMacro(CylinderLength, double, 0.0, VTK_DOUBLE_MAX); - vtkGetMacro(CylinderLength, double); - - // Description: - // Set the number of points used in the longitude direction - // for the capsule extremities. - vtkSetClampMacro(ThetaResolution, int, 3, VTK_MAX_SPHERE_RESOLUTION); - vtkGetMacro(ThetaResolution, int); - - // Description: - // Set the number of points used in the lattitude direction - // for the capsule extremities. - vtkSetClampMacro(PhiResolution, int, 3, VTK_MAX_SPHERE_RESOLUTION); - vtkGetMacro(PhiResolution, int); - - // Description: - // Cause the sphere to be tessellated with edges along the latitude - // and longitude lines. If off, triangles are generated at non-polar - // regions, which results in edges that are not parallel to latitude and - // longitude lines. If on, quadrilaterals are generated everywhere - // except at the poles. This can be useful for generating a wireframe - // sphere with natural latitude and longitude lines. - vtkSetMacro(LatLongTessellation, int); - vtkGetMacro(LatLongTessellation, int); - vtkBooleanMacro(LatLongTessellation, int); - -protected: - vtkCapsuleSource(int res = 8); - ~vtkCapsuleSource() {} - - int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*); - int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*); - - double Radius; - double Center[3]; - int ThetaResolution; - int PhiResolution; - int LatLongTessellation; - //int FillPoles; - double CylinderLength; - -private: - vtkCapsuleSource(const vtkCapsuleSource&); // Not implemented. - void operator=(const vtkCapsuleSource&); // Not implemented. -}; - -#endif \ No newline at end of file diff --git a/Source/Rendering/vtkCapsuleSource.cpp b/Source/Rendering/vtkCapsuleSource.cpp deleted file mode 100644 index 7798084a54260be5288d086a75b45a425266f0bb..0000000000000000000000000000000000000000 --- a/Source/Rendering/vtkCapsuleSource.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/*========================================================================= - - 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. - -=========================================================================*/ -// \author Johan Andruejol <johan.andruejol@kitware.com> - -#if (VTK_MAJOR_VERSION <= 9) - -#include "imstkVtkCapsuleSource.h" - -#include <vtkCellArray.h> -#include <vtkFloatArray.h> -#include <vtkInformation.h> -#include <vtkInformationVector.h> -#include <vtkMath.h> -#include <vtkObjectFactory.h> -#include <vtkPointData.h> -#include <vtkPoints.h> -#include <vtkPolyData.h> -#include <vtkStreamingDemandDrivenPipeline.h> - -#include <math.h> - -vtkStandardNewMacro(vtkCapsuleSource); - -//---------------------------------------------------------------------------- -// Construct sphere with radius=0.5 and default resolution 8 in both Phi -// and Theta directions. Theta ranges from (0,360) and phi (0,180) degrees. -/// \todo -vtkCapsuleSource::vtkCapsuleSource(int res) -{ - res = res < 8 ? 8 : res; - this->Radius = 0.5; - this->Center[0] = 0.0; - this->Center[1] = 0.0; - this->Center[2] = 0.0; - - this->ThetaResolution = res; - this->PhiResolution = res; - this->LatLongTessellation = 0; - this->CylinderLength = 1.0; - - this->SetNumberOfInputPorts(0); -} - -namespace -{ -void -InsertPole(vtkPoints* points, vtkFloatArray* normals, - double center[3], double radius, double halfHeight) -{ - double x[3]; - x[0] = center[0]; - x[1] = center[1] + halfHeight; - x[2] = center[2] + radius; - points->InsertNextPoint(x); - - x[0] = x[1] = 0.0; - x[2] = (radius > 0 ? 1.0 : -1.0); - normals->InsertNextTuple(x); -} - -void -FillHalfSphere(vtkPoints* points, vtkFloatArray* normals, - double thetaResolution, double phiResolution, - double startAngle /* In radians*/, double sign, - double center[3], double radius, double halfHeight) -{ - double n[3], x[3], norm; - - double deltaTheta = 3.1415926535897932384626 / (thetaResolution - 1); - double deltaPhi = 3.1415926535897932384626 / (phiResolution - 1); - for (int i = 0; i < thetaResolution; ++i) - { - double theta = startAngle + sign * i * deltaTheta; - - for (int j = 1; j < phiResolution - 1; ++j) - { - double phi = j * deltaPhi; - double r = radius * sin(phi); - n[0] = r * cos(theta); - n[1] = r * sin(theta); - n[2] = radius * cos(phi); - x[0] = n[0] + center[0]; - x[1] = n[1] + center[1] + halfHeight; - x[2] = n[2] + center[2]; - points->InsertNextPoint(x); - - if ( (norm = vtkMath::Norm(n)) == 0.0) - { - norm = 1.0; - } - n[0] /= norm; - n[1] /= norm; - n[2] /= norm; - normals->InsertNextTuple(n); - } - } -} - -void -ConnectCylinderSide(vtkCellArray* faces, - int minusPoleId, int plusPoleId, - int clockwise, int increment, bool quadrangle) -{ - vtkIdType pts[4]; - for (int i = 0; i < increment; ++i) - { - pts[0] = minusPoleId + clockwise * i; - pts[1] = plusPoleId + clockwise * i; - - if (!quadrangle) - { - pts[2] = pts[0] + clockwise; - faces->InsertNextCell(3, pts); - - pts[0] = pts[2]; - pts[2] = pts[1] + clockwise; - faces->InsertNextCell(3, pts); - } - else - { - pts[2] = pts[1] + clockwise; - pts[3] = pts[0] + clockwise; - faces->InsertNextCell(4, pts); - } - } -} -} // end namespace - -//---------------------------------------------------------------------------- -int -vtkCapsuleSource::RequestData( - vtkInformation* vtkNotUsed(request), - vtkInformationVector** vtkNotUsed(inputVector), - vtkInformationVector* outputVector) -{ - // get the info object - vtkInformation* outInfo = outputVector->GetInformationObject(0); - - // get the ouptut - vtkPolyData* output = vtkPolyData::SafeDownCast( - outInfo->Get(vtkDataObject::DATA_OBJECT())); - - vtkPoints* newPoints; - vtkFloatArray* newNormals; - vtkCellArray* newPolys; - - // Set number of points.; - int halfSphereNumPts = (this->PhiResolution - 2) * this->ThetaResolution + 2; - int numPts = halfSphereNumPts * 2; - - // Set number of faces - int halfSpheresNumsPolys = (this->ThetaResolution - 1) * 2 //top and bottom - + (this->PhiResolution - 3) * (this->ThetaResolution - 1) * 2; //middle - int cylinderNumPolys = (this->PhiResolution - 1) * 4; - int numPolys = halfSpheresNumsPolys * 2 + cylinderNumPolys; - - // Allocate ! - newPoints = vtkPoints::New(); - newPoints->Allocate(numPts); - newNormals = vtkFloatArray::New(); - newNormals->SetNumberOfComponents(3); - newNormals->Allocate(3 * numPts); - newNormals->SetName("Normals"); - - newPolys = vtkCellArray::New(); - newPolys->Allocate(newPolys->EstimateSize(numPolys, 3)); - - // - // Create half sphere 1, plus side - // - double halfHeight = this->CylinderLength / 2.0; - - // North pole - InsertPole(newPoints, newNormals, this->Center, this->Radius, halfHeight); - this->UpdateProgress(0.05); - - // Create intermediate points - FillHalfSphere(newPoints, newNormals, - this->ThetaResolution, this->PhiResolution, - 0.0, 1.0, - this->Center, this->Radius, halfHeight); - this->UpdateProgress(0.255); - - // South pole - InsertPole(newPoints, newNormals, this->Center, -1 * this->Radius, halfHeight); - this->UpdateProgress(0.30); // First half sphere done ! - - // - // Create half sphere 2, minus side - // - - // North pole - InsertPole(newPoints, newNormals, this->Center, this->Radius, -1 * halfHeight); - this->UpdateProgress(0.305); - - // Create intermediate points - FillHalfSphere(newPoints, newNormals, - this->ThetaResolution, this->PhiResolution, - 6.283185307179586, -1, - this->Center, this->Radius, -1.0 * halfHeight); - this->UpdateProgress(0.555); - - // South pole - InsertPole(newPoints, newNormals, - this->Center, -1 * this->Radius, -1 * halfHeight); - this->UpdateProgress(0.60); // Second half sphere done ! - - // - // Generate mesh connectivity - // - - vtkIdType pts[4]; - // increment represent how many ids have passed every - // time we change by one delta theta - int increment = this->PhiResolution - 2; - // Ids of the poles - int northPoleMinusId = 0; - int southPoleMinusId = halfSphereNumPts - 1; - int northPolePlusId = halfSphereNumPts; - int southPolePlusId = numPts - 1; - - //First half sphere - // Connect the minus side half sphere north pole. - for (int i = 0; i < this->ThetaResolution - 1; ++i) - { - pts[0] = northPoleMinusId; - pts[1] = (i * increment) + 1; - pts[2] = pts[1] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.605); - - // South pole connectivity - for (int i = 1; i < this->ThetaResolution; ++i) - { - pts[0] = i * increment; - pts[1] = southPoleMinusId; - pts[2] = pts[0] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.75); //First half-sphere done ! - - // Seconde half sphere - // North pole connectivity - for (int i = 0; i < this->ThetaResolution - 1; ++i) - { - pts[2] = northPolePlusId; - pts[1] = (i * increment) + 1 + northPolePlusId; - pts[0] = pts[1] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.755); - - // South pole connectivity - for (int i = 1; i < this->ThetaResolution; i++) - { - pts[0] = northPolePlusId + i * increment; - pts[2] = southPolePlusId; - pts[1] = pts[0] + increment; - newPolys->InsertNextCell(3, pts); - } - this->UpdateProgress(0.9); - - // Both half sphere at the same time, connectivity of the band. - vtkIdType ptsOtherSide[4]; - for (int i = 1; i < northPolePlusId - 1 - increment; i += increment) - { - for (int j = 0; j < increment - 1; ++j) - { - pts[0] = j + i; - pts[1] = j + i + 1; - pts[2] = j + i + increment + 1; - - ptsOtherSide[0] = pts[0] + northPolePlusId; - ptsOtherSide[1] = pts[2] + northPolePlusId; - ptsOtherSide[2] = pts[1] + northPolePlusId; - - if (!this->LatLongTessellation) - { - newPolys->InsertNextCell(3, pts); - newPolys->InsertNextCell(3, ptsOtherSide); - pts[1] = pts[2]; - pts[2] = j + i + increment; - - ptsOtherSide[1] = pts[2] + northPolePlusId; - ptsOtherSide[2] = pts[1] + northPolePlusId; - - newPolys->InsertNextCell(3, pts); - newPolys->InsertNextCell(3, ptsOtherSide); - } - else - { - pts[3] = j + i + increment; - - ptsOtherSide[1] = pts[3] + northPolePlusId; - ptsOtherSide[3] = ptsOtherSide[2]; - ptsOtherSide[2] = pts[2] + northPolePlusId; - - newPolys->InsertNextCell(4, pts); - newPolys->InsertNextCell(4, ptsOtherSide); - } - } - } - - // Cylinder pole connectivity - // first side - ConnectCylinderSide(newPolys, - northPoleMinusId, northPolePlusId, 1, - increment, this->LatLongTessellation); - - // second side - ConnectCylinderSide(newPolys, - southPoleMinusId, southPolePlusId, -1, - increment, this->LatLongTessellation); - this->UpdateProgress(0.99); - - // Weird south pole minus face case - pts[0] = northPoleMinusId + increment; - pts[1] = northPolePlusId + increment; - if (!this->LatLongTessellation) - { - pts[2] = southPoleMinusId; - newPolys->InsertNextCell(3, pts); - - pts[0] = pts[1]; - pts[1] = southPolePlusId; - newPolys->InsertNextCell(3, pts); - } - else - { - pts[2] = southPolePlusId; - pts[3] = southPoleMinusId; - newPolys->InsertNextCell(4, pts); - } - - // Weird north pole 2 face case - pts[0] = southPoleMinusId - increment; - pts[1] = southPolePlusId - increment; - if (!this->LatLongTessellation) - { - pts[2] = northPoleMinusId; - newPolys->InsertNextCell(3, pts); - - pts[0] = pts[1]; - pts[1] = northPolePlusId; - newPolys->InsertNextCell(3, pts); - } - else - { - pts[2] = northPolePlusId; - pts[3] = northPoleMinusId; - newPolys->InsertNextCell(4, pts); - } - - // Update ourselves and release memeory - // - newPoints->Squeeze(); - output->SetPoints(newPoints); - newPoints->Delete(); - - newNormals->Squeeze(); - output->GetPointData()->SetNormals(newNormals); - newNormals->Delete(); - - newPolys->Squeeze(); - output->SetPolys(newPolys); - newPolys->Delete(); - - return 1; -} - -//---------------------------------------------------------------------------- -void -vtkCapsuleSource::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); - - os << indent << "Theta Resolution: " << this->ThetaResolution << "\n"; - os << indent << "Phi Resolution: " << this->PhiResolution << "\n"; - os << indent << "Radius: " << this->Radius << "\n"; - os << indent << "Center: (" << this->Center[0] << ", " - << this->Center[1] << ", " << this->Center[2] << ")\n"; - os << indent - << "LatLong Tessellation: " << this->LatLongTessellation << "\n"; - os << indent << "Cylinder Length: " << this->CylinderLength << "\n"; -} - -//---------------------------------------------------------------------------- -#pragma warning(push) -#pragma warning(disable : 4100) -int -vtkCapsuleSource::RequestInformation( - vtkInformation* vtkNotUsed(request), - vtkInformationVector** vtkNotUsed(inputVector), - vtkInformationVector* outputVector) -{ - std::cout << "WARNING-vtkCapsuleSource::RequestInformation is not implemented!" << std::endl; - // get the info object - /*vtkInformation *outInfo = outputVector->GetInformationObject(0); - - outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), - -1); - - double halfLength = this->CylinderLength / 2.0; - outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX(), - this->Center[0] - this->Radius - halfLength, - this->Center[0] + this->Radius + halfLength, - this->Center[1] - this->Radius, - this->Center[1] + this->Radius, - this->Center[2] - this->Radius, - this->Center[2] + this->Radius);*/ - - return 1; -} - -#pragma warning(pop) - -#endif \ No newline at end of file diff --git a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp index e53ca868bf6ea18f80a3479c8f6749eae1ae272e..d9b12fe15baabf6ad63d4895a3d8e428391d62d9 100644 --- a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp +++ b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp @@ -255,7 +255,7 @@ VTKViewer::getTextStatusManager() } void -VTKViewer::timerCallback(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* clientData, void* vtkNotUsed(callData)) +VTKViewer::timerCallback(vtkObject* vtkNotUsed(caller), long unsigned int vtkNotUsed(eventId), void* clientData, void* vtkNotUsed(callData)) { VTKViewer* self = static_cast<VTKViewer*>(clientData); diff --git a/Source/SimulationManager/imstkSimulationManager.cpp b/Source/SimulationManager/imstkSimulationManager.cpp index fa0caca444250f4b1ec44cb9ee0a90f32468427f..f59629c1406b80a2296177dc4331fce02def4a2f 100644 --- a/Source/SimulationManager/imstkSimulationManager.cpp +++ b/Source/SimulationManager/imstkSimulationManager.cpp @@ -47,12 +47,6 @@ SimulationManager::SimulationManager(const std::shared_ptr<SimManagerConfig> con Logger& logger = Logger::getInstance(); m_stdSinkHandle = logger.addStdoutSink(); } - - // create viewer if the selected mode is 'rendering' - if (m_config->simulationMode == SimulationMode::Rendering) - { - createViewer(m_config->VR_Enabled); - } } void @@ -319,6 +313,16 @@ SimulationManager::setActiveScene(const std::string& newSceneName, { LOG(INFO) << "Setting scene '" << newSceneName << "' as active"; + // If the viewer doesn't exist create it + if (m_viewer == nullptr) + { + // create viewer if the selected mode is 'rendering' + if (m_config->simulationMode == SimulationMode::Rendering) + { + createViewer(m_config->VR_Enabled); + } + } + // check if the scene is registered if (!this->isSceneRegistered(newSceneName)) { diff --git a/Source/SimulationManager/imstkSimulationManager.h b/Source/SimulationManager/imstkSimulationManager.h index ba3f080b833bb96ae7ea7f273a272e4bea3c3e89..f9b47ae18143dbb69c1ae24acc3795d9b688e80c 100644 --- a/Source/SimulationManager/imstkSimulationManager.h +++ b/Source/SimulationManager/imstkSimulationManager.h @@ -146,6 +146,11 @@ public: std::shared_ptr<SceneManager> getSceneManager(const std::string& sceneName) const; std::shared_ptr<SceneManager> getSceneManager(std::shared_ptr<Scene> scene) const; + /// + /// \brief Returns the scene manager config + /// + std::shared_ptr<SimManagerConfig> getConfig() const { return m_config; } + /// /// \brief Returns the scene with a given name ///