diff --git a/Examples/Interactions/SPH-Obj-SDF/SPH-Obj-SDFInteractionExample.cpp b/Examples/Interactions/SPH-Obj-SDF/SPH-Obj-SDFInteractionExample.cpp
index 1978990498370eeff54da7932fbb9ef75684a36b..7d9c38d14159033560bee60f4dd68e7413277abc 100644
--- a/Examples/Interactions/SPH-Obj-SDF/SPH-Obj-SDFInteractionExample.cpp
+++ b/Examples/Interactions/SPH-Obj-SDF/SPH-Obj-SDFInteractionExample.cpp
@@ -96,7 +96,7 @@ makeSPHBoxObject(const std::string& name, const double particleRadius, const Vec
     imstkNew<SPHModelConfig> sphParams(particleRadius);
     sphParams->m_bNormalizeDensity = true;
     sphParams->m_kernelOverParticleRadiusRatio = 6.0;
-    sphParams->m_viscosityCoeff = 0.5;
+    //sphParams->m_viscosityCoeff = 0.5;
     sphParams->m_surfaceTensionStiffness = 5.0;
     sphParams->m_gravity = Vec3d(0.0, -70.0, 0.0);
 
diff --git a/Examples/Physiology/Fluid.hpp b/Examples/Physiology/Fluid.hpp
index bdb974857280349f703ad914e9d23b2a9714e0de..576632393eac46e849d4c6c160a208022cc818f2 100644
--- a/Examples/Physiology/Fluid.hpp
+++ b/Examples/Physiology/Fluid.hpp
@@ -24,11 +24,13 @@
 #include "imstkMeshIO.h"
 #include "imstkPointSet.h"
 #include "imstkScene.h"
-#include "imstkSimulationManager.h"
 #include "imstkSPHModel.h"
 #include "imstkSPHObject.h"
 #include "imstkSurfaceMesh.h"
 #include "imstkTetrahedralMesh.h"
+#include "imstkSelectEnclosedPoints.h"
+#include "imstkRenderMaterial.h"
+#include "imstkVisualModel.h"
 
 #include <vtkBooleanOperationPolyDataFilter.h>
 #include <vtkCenterOfMass.h>
@@ -54,8 +56,8 @@ generateWallFluidPoints(const double particleRadius, std::shared_ptr<SurfaceMesh
     auto intersectionPolyDataFilter = vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();
     intersectionPolyDataFilter->SetOperationToDifference();
 
-    auto vtkPolySurfMesh = GeometryUtils::convertSurfaceMeshToVtkPolyData(surfMesh);
-    auto vtkPolySurfMeshExpanded = GeometryUtils::convertSurfaceMeshToVtkPolyData(surfMeshExpanded);
+    auto vtkPolySurfMesh = GeometryUtils::copyToVtkPolyData(surfMesh);
+    auto vtkPolySurfMeshExpanded = GeometryUtils::copyToVtkPolyData(surfMeshExpanded);
 
     vtkSmartPointer<vtkTriangleFilter> tri1 =
       vtkSmartPointer<vtkTriangleFilter>::New();
@@ -83,7 +85,7 @@ generateWallFluidPoints(const double particleRadius, std::shared_ptr<SurfaceMesh
 
     auto outputPolyData = intersectionPolyDataFilter->GetOutput();
 
-    std::shared_ptr<SurfaceMesh> subtractedMesh = std::move(GeometryUtils::convertVtkPolyDataToSurfaceMesh(outputPolyData));
+    std::shared_ptr<SurfaceMesh> subtractedMesh = std::move(GeometryUtils::copyToSurfaceMesh(outputPolyData));
 
     return subtractedMesh;
 }
@@ -95,6 +97,9 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
     auto sphModel = std::make_shared<SPHModel>();
     double speedOfSound = 100;
     double restDensity = 1;
+
+    auto selectionFilter = std::shared_ptr<SelectEnclosedPoints>();
+    
     if (SCENE_ID == 1)
     {
       // pipe flow
@@ -126,9 +131,21 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
       auto uniformMesh = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx, ny, nz));
       auto uniformMesh_wall = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx_wall, ny_wall, nz_wall));
 
-      auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+      std::unordered_map<size_t, int> m_inputs;
+      auto s = m_inputs.count(0);
+
+      selectionFilter->setInputMesh(surfMesh);
+      selectionFilter->setInputPoints(uniformMesh);
+      auto enclosedFluidPoints = selectionFilter->getOutputPoints();
+      //auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+
       particles = enclosedFluidPoints->getInitialVertexPositions();
-      auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
+      selectionFilter->setInputMesh(surfMeshShell);
+      selectionFilter->setInputPoints(uniformMesh_wall);
+      auto enclosedWallPoints = selectionFilter->getOutputPoints();
+      //auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
       StdVectorOfVec3d wallParticles = enclosedWallPoints->getInitialVertexPositions();
 
       std::pair<Vec3d, Vec3d> fluidCoords = std::make_pair(aabbMin, aabbMax);
@@ -153,7 +170,6 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
       auto sphBoundaryConditions = std::make_shared<SPHBoundaryConditions>(inletCoords, outletCoords, fluidCoords, inletNormal, outletNormals, inletRadius, inletCenterPoint, inletFlowRate, particles, wallParticles);
       sphModel->setBoundaryConditions(sphBoundaryConditions);
   }
-
   else if (SCENE_ID == 2)
   {
       // half torus flow
@@ -181,9 +197,18 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
       auto uniformMesh = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx, ny, nz));
       auto uniformMesh_wall = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx_wall, ny_wall, nz_wall));
 
-      auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+      selectionFilter->setInputMesh(surfMesh);
+      selectionFilter->setInputPoints(uniformMesh);
+      auto enclosedFluidPoints = selectionFilter->getOutputPoints();
+      //auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+
       particles = enclosedFluidPoints->getInitialVertexPositions();
-      auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
+      selectionFilter->setInputMesh(surfMeshShell);
+      selectionFilter->setInputPoints(uniformMesh_wall);
+      auto enclosedWallPoints = selectionFilter->getOutputPoints();
+      //auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+      
       StdVectorOfVec3d wallParticles = enclosedWallPoints->getInitialVertexPositions();
 
       std::pair<Vec3d, Vec3d> fluidCoords = std::make_pair(aabbMin, aabbMax);
@@ -239,9 +264,18 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
       auto uniformMesh = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx, ny, nz));
       auto uniformMesh_wall = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx_wall, ny_wall, nz_wall));
 
-      auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+      selectionFilter->setInputMesh(surfMesh);
+      selectionFilter->setInputPoints(uniformMesh);
+      auto enclosedFluidPoints = selectionFilter->getOutputPoints();
+      //auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+
       particles = enclosedFluidPoints->getInitialVertexPositions();
-      auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
+      selectionFilter->setInputMesh(surfMeshShell);
+      selectionFilter->setInputPoints(uniformMesh_wall);
+      auto enclosedWallPoints = selectionFilter->getOutputPoints();
+      //auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
       StdVectorOfVec3d wallParticles = enclosedWallPoints->getInitialVertexPositions();
   
       std::pair<Vec3d, Vec3d> fluidCoords = std::make_pair(aabbMin, aabbMax);
@@ -303,9 +337,18 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
       auto uniformMesh = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx, ny, nz));
       auto uniformMesh_wall = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx_wall, ny_wall, nz_wall));
 
-      auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+      selectionFilter->setInputMesh(surfMesh);
+      selectionFilter->setInputPoints(uniformMesh);
+      auto enclosedFluidPoints = selectionFilter->getOutputPoints();
+      //auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+
       particles = enclosedFluidPoints->getInitialVertexPositions();
-      auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
+      selectionFilter->setInputMesh(surfMeshShell);
+      selectionFilter->setInputPoints(uniformMesh_wall);
+      auto enclosedWallPoints = selectionFilter->getOutputPoints();
+      //auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+      
       StdVectorOfVec3d wallParticles = enclosedWallPoints->getInitialVertexPositions();
 
       std::pair<Vec3d, Vec3d> fluidCoords = std::make_pair(aabbMin, aabbMax);
@@ -369,9 +412,18 @@ generateFluid(const std::shared_ptr<Scene>& scene, const double particleRadius)
       auto uniformMesh = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx, ny, nz));
       auto uniformMesh_wall = std::dynamic_pointer_cast<PointSet>(GeometryUtils::createUniformMesh(aabbMin, aabbMax, nx_wall, ny_wall, nz_wall));
 
-      auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+      selectionFilter->setInputMesh(surfMesh);
+      selectionFilter->setInputPoints(uniformMesh);
+      auto enclosedFluidPoints = selectionFilter->getOutputPoints();
+      //auto enclosedFluidPoints = GeometryUtils::getEnclosedPoints(surfMesh, uniformMesh, false);
+
       particles = enclosedFluidPoints->getInitialVertexPositions();
-      auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+      
+      selectionFilter->setInputMesh(surfMeshShell);
+      selectionFilter->setInputPoints(uniformMesh_wall);
+      auto enclosedWallPoints = selectionFilter->getOutputPoints();
+      //auto enclosedWallPoints = GeometryUtils::getEnclosedPoints(surfMeshShell, uniformMesh_wall, false);
+
       StdVectorOfVec3d wallParticles = enclosedWallPoints->getInitialVertexPositions();
 
       std::pair<Vec3d, Vec3d> fluidCoords = std::make_pair(aabbMin, aabbMax);
diff --git a/Examples/Physiology/Physiology-BifurcationFlow/CMakeLists.txt b/Examples/Physiology/Physiology-BifurcationFlow/CMakeLists.txt
index f47f5a872a87e5d34df11b723e22a88ec87a04af..36419430a75c5128fb0385b259e61cfe74887103 100644
--- a/Examples/Physiology/Physiology-BifurcationFlow/CMakeLists.txt
+++ b/Examples/Physiology/Physiology-BifurcationFlow/CMakeLists.txt
@@ -40,4 +40,4 @@ SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/Physiology)
 #-----------------------------------------------------------------------------
 # Link libraries to executable
 #-----------------------------------------------------------------------------
-target_link_libraries(${PROJECT_NAME} SimulationManager Pulse)
+target_link_libraries(${PROJECT_NAME} Filtering SimulationManager Pulse)
diff --git a/Examples/Physiology/Physiology-FemoralArteryFlow/CMakeLists.txt b/Examples/Physiology/Physiology-FemoralArteryFlow/CMakeLists.txt
index de0f2eecf7600410ffade247431f7046faf364a2..b0a93bc59064dca314392a9ae20acd07c0b4b9d4 100644
--- a/Examples/Physiology/Physiology-FemoralArteryFlow/CMakeLists.txt
+++ b/Examples/Physiology/Physiology-FemoralArteryFlow/CMakeLists.txt
@@ -40,4 +40,4 @@ SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/Physiology)
 #-----------------------------------------------------------------------------
 # Link libraries to executable
 #-----------------------------------------------------------------------------
-target_link_libraries(${PROJECT_NAME} SimulationManager Pulse)
+target_link_libraries(${PROJECT_NAME} Filtering SimulationManager Pulse)
diff --git a/Examples/Physiology/Physiology-HalfTorusFlow/CMakeLists.txt b/Examples/Physiology/Physiology-HalfTorusFlow/CMakeLists.txt
index fdc5a4b3def239a0a72cc490f299ae75424d3089..af8d8422380d9b89a795b3b1cf1c90b519341de2 100644
--- a/Examples/Physiology/Physiology-HalfTorusFlow/CMakeLists.txt
+++ b/Examples/Physiology/Physiology-HalfTorusFlow/CMakeLists.txt
@@ -36,4 +36,4 @@ SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/Physiology)
 #-----------------------------------------------------------------------------
 # Link libraries to executable
 #-----------------------------------------------------------------------------
-target_link_libraries(${PROJECT_NAME} SimulationManager Pulse)
+target_link_libraries(${PROJECT_NAME} Filtering SimulationManager Pulse)
diff --git a/Examples/Physiology/Physiology-LeakFlow/CMakeLists.txt b/Examples/Physiology/Physiology-LeakFlow/CMakeLists.txt
index 7c83cc8f6286189efbf90ac05e5fbde55c219626..ed13b2791f13f344e8e542ab5187acfb31f6b6b6 100644
--- a/Examples/Physiology/Physiology-LeakFlow/CMakeLists.txt
+++ b/Examples/Physiology/Physiology-LeakFlow/CMakeLists.txt
@@ -40,4 +40,4 @@ SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/Physiology)
 #-----------------------------------------------------------------------------
 # Link libraries to executable
 #-----------------------------------------------------------------------------
-target_link_libraries(${PROJECT_NAME} SimulationManager Pulse)
+target_link_libraries(${PROJECT_NAME} Filtering SimulationManager Pulse)
diff --git a/Examples/Physiology/Physiology-PipeFlow/CMakeLists.txt b/Examples/Physiology/Physiology-PipeFlow/CMakeLists.txt
index fa53492c44151b849a109ecf7e2ee679fc028867..e975018dc4890141ebd095c3f23bbe1361b8aac7 100644
--- a/Examples/Physiology/Physiology-PipeFlow/CMakeLists.txt
+++ b/Examples/Physiology/Physiology-PipeFlow/CMakeLists.txt
@@ -40,4 +40,4 @@ SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES FOLDER Examples/Physiology)
 #-----------------------------------------------------------------------------
 # Link libraries to executable
 #-----------------------------------------------------------------------------
-target_link_libraries(${PROJECT_NAME} SimulationManager Pulse)
+target_link_libraries(${PROJECT_NAME} Filtering SimulationManager Pulse)
diff --git a/Examples/Physiology/PhysiologyExample.hpp b/Examples/Physiology/PhysiologyExample.hpp
index 063cf30884507f3b9b3a84c0420283027d19b081..799115dc50b994972951736a287db6254e3ba21d 100644
--- a/Examples/Physiology/PhysiologyExample.hpp
+++ b/Examples/Physiology/PhysiologyExample.hpp
@@ -21,6 +21,7 @@
 
 #include "Fluid.hpp"
 
+#include "imstkNew.h"
 #include "imstkCamera.h"
 #include "imstkCollisionDetection.h"
 #include "imstkCollisionGraph.h"
@@ -28,22 +29,27 @@
 #include "imstkLight.h"
 #include "imstkPhysiologyModel.h"
 #include "imstkPhysiologyObject.h"
-#include "imstkPlane.h"
+//#include "imstkPlane.h"
 #include "imstkPointSet.h"
 #include "imstkObjectInteractionFactory.h"
 #include "imstkScene.h"
 #include "imstkSceneManager.h"
-#include "imstkSimulationManager.h"
 #include "imstkSphere.h"
 #include "imstkSPHModel.h"
 #include "imstkSPHObject.h"
 #include "imstkSPHPhysiologyInteraction.h"
 #include "imstkTaskGraph.h"
-#include "imstkVTKTextStatusManager.h"
+//#include "imstkVTKTextStatusManager.h"
+#include "imstkVTKViewer.h"
+#include "imstkMouseSceneControl.h"
+#include "imstkKeyboardSceneControl.h"
+#include "imstkRenderMaterial.h"
+#include "imstkVisualModel.h"
 
 using namespace imstk;
 
-static std::shared_ptr<PhysiologyObject> makePhysiologyObject()
+static std::shared_ptr<PhysiologyObject> 
+makePhysiologyObject()
 {
     // configure model
     auto physiologyParams = std::make_shared<PhysiologyModelConfig>();
@@ -62,7 +68,8 @@ static std::shared_ptr<PhysiologyObject> makePhysiologyObject()
     return physiologyObj;
 }
 
-static void parseArguments(int argc, char* argv[], double& particleRadius, int& numThreads)
+static void 
+parseArguments(int argc, char* argv[], double& particleRadius, int& numThreads)
 {
     if (SCENE_ID == 5)
     {
@@ -93,128 +100,137 @@ static void parseArguments(int argc, char* argv[], double& particleRadius, int&
 int
 main(int argc, char* argv[])
 {
-  // SimulationManager must be created first
-  auto simManager = std::make_shared<SimulationManager>();
-
-  int threads = -1;
-  double particleRadius = 0.04;
-  parseArguments(argc, argv, particleRadius, threads);
-
-  // Set thread pool size (nthreads <= 0 means using all logical cores)
-  simManager->setThreadPoolSize(threads);
-
-  auto scene = simManager->createNewScene("SPHPhysiologyInteraction");
-
-  scene->getConfig()->writeTaskGraph = true;
-  //scene->getConfig()->taskTimingEnabled = true;
-  //scene->getTaskComputeTimes().at("PhysiologyModel_Solve");
-
-  // Get the VTKViewer
-  std::shared_ptr<VTKViewer> viewer = std::make_shared<VTKViewer>(simManager.get(), false);
-  viewer->setWindowTitle("Physiology Example");
-  viewer->getVtkRenderWindow()->SetSize(1920, 1080);
-  auto statusManager = viewer->getTextStatusManager();
-  statusManager->setStatusFontSize(VTKTextStatusManager::Custom, 30);
-  statusManager->setStatusFontColor(VTKTextStatusManager::Custom, Color::Red);
-  simManager->setViewer(viewer);
-
-  // Generate fluid and solid objects
-  auto fluidObj = generateFluid(scene, particleRadius);
-  std::shared_ptr<RenderMaterial> material = fluidObj->getVisualModel(0)->getRenderMaterial();
-  std::shared_ptr<SPHModel> sphModel = fluidObj->getDynamicalSPHModel();
-
-  
-  std::shared_ptr<PhysiologyObject> physioObj = makePhysiologyObject();
-  scene->addSceneObject(physioObj);
-
-  auto interactionPair = std::make_shared<SPHPhysiologyObjectInteractionPair>(fluidObj, physioObj);
-
-  // configure the sph-physiology interaction pair
-  interactionPair->setHemorrhageAction(std::dynamic_pointer_cast<HemorrhageAction>(physioObj->getPhysiologyModel()->getAction("Hemorrhage")));
-  interactionPair->setCompartment(PhysiologyCompartmentType::Liquid, "VascularCompartment::RightLeg");
-
-  scene->getCollisionGraph()->addInteraction(interactionPair);
-
-  // configure camera
-  (SCENE_ID == 5) ? scene->getCamera()->setPosition(0, 1.0, 4.0): scene->getCamera()->setPosition(0, 1.0, 5.0);
-    
-  // configure light (white)
-  auto whiteLight = std::make_shared<DirectionalLight>("whiteLight");
-  whiteLight->setFocalPoint(Vec3d(5, -8, -5));
-  whiteLight->setIntensity(7);
-  scene->addLight(whiteLight);
-
-  ///////////////////////////////////////
-  // Setup some scalars
-  std::shared_ptr<PointSet> fluidGeometry = std::dynamic_pointer_cast<PointSet>(fluidObj->getPhysicsGeometry());
-  std::shared_ptr<StdVectorOfReal> scalarsPtr = std::make_shared<StdVectorOfReal>(fluidGeometry->getNumVertices());
-  std::fill_n(scalarsPtr->data(), scalarsPtr->size(), 0.0);
-  fluidGeometry->setScalars(scalarsPtr);
-
-  // Setup the material for the scalars
-  material->setScalarVisibility(true);
-  std::shared_ptr<ColorFunction> colorFunc = std::make_shared<ColorFunction>();
-  colorFunc->setNumberOfColors(2);
-  colorFunc->setColor(0, Color::Red);
-  colorFunc->setColor(1, Color::Green);
-  colorFunc->setColorSpace(ColorFunction::ColorSpace::RGB);
-  colorFunc->setRange(0, 3);
-  material->setColorLookupTable(colorFunc);
-
-  scene->setTaskGraphConfigureCallback([&](Scene* scene)
+    // Setup logger (write to file and stdout)
+    Logger::startLogger();
+
+    imstkNew<Scene> scene("SPHPhysiologyInteraction");
+
+
+    int threads = -1;
+    double particleRadius = 0.04;
+    parseArguments(argc, argv, particleRadius, threads);
+
+    // Generate fluid and solid objects
+    auto fluidObj = generateFluid(scene, particleRadius);
+    auto material = fluidObj->getVisualModel(0)->getRenderMaterial();
+    auto sphModel = fluidObj->getDynamicalSPHModel();
+
+
+    std::shared_ptr<PhysiologyObject> physioObj = makePhysiologyObject();
+    scene->addSceneObject(physioObj);
+
+    auto interactionPair = std::make_shared<SPHPhysiologyObjectInteractionPair>(fluidObj, physioObj);
+
+    // configure the sph-physiology interaction pair
+    interactionPair->setHemorrhageAction(
+        std::dynamic_pointer_cast<HemorrhageAction>(physioObj->getPhysiologyModel()->getAction("Hemorrhage")));
+    interactionPair->setCompartment(PhysiologyCompartmentType::Liquid, "VascularCompartment::RightLeg");
+
+    scene->getCollisionGraph()->addInteraction(interactionPair);
+
+    // configure camera
+    (SCENE_ID == 5) ? scene->getActiveCamera()->setPosition(0, 1.0, 4.0) : scene->getActiveCamera()->setPosition(0, 1.0, 5.0);
+
+    // configure light (white)
+    auto whiteLight = std::make_shared<DirectionalLight>("whiteLight");
+    whiteLight->setFocalPoint(Vec3d(5, -8, -5));
+    whiteLight->setIntensity(7);
+    scene->addLight(whiteLight);
+
+    ///////////////////////////////////////
+    // Setup some scalars
+    std::shared_ptr<PointSet> fluidGeometry = std::dynamic_pointer_cast<PointSet>(fluidObj->getPhysicsGeometry());
+    std::shared_ptr<StdVectorOfReal> scalarsPtr = std::make_shared<StdVectorOfReal>(fluidGeometry->getNumVertices());
+    std::fill_n(scalarsPtr->data(), scalarsPtr->size(), 0.0);
+    fluidGeometry->setScalars(scalarsPtr);
+
+    // Setup the material for the scalars
+    material->setScalarVisibility(true);
+    std::shared_ptr<ColorFunction> colorFunc = std::make_shared<ColorFunction>();
+    colorFunc->setNumberOfColors(2);
+    colorFunc->setColor(0, Color::Red);
+    colorFunc->setColor(1, Color::Green);
+    colorFunc->setColorSpace(ColorFunction::ColorSpace::RGB);
+    colorFunc->setRange(0, 3);
+    material->setColorLookupTable(colorFunc);
+
+
+    //scene->setTaskGraphConfigureCallback([&](Scene* scene)
+    auto displayColors = [&](Event*)
     {
-      auto taskGraph = scene->getTaskGraph();
-      //taskGraph->removeNode(fluidObj->getDynamicalSPHModel()->getComputeSurfaceTensionNode());
+        auto taskGraph = scene->getTaskGraph();
+        //taskGraph->removeNode(fluidObj->getDynamicalSPHModel()->getComputeSurfaceTensionNode());
 
-      std::shared_ptr<TaskNode> printTotalTime = std::make_shared<TaskNode>([&]()
-        {
-          if (fluidObj->getDynamicalSPHModel()->getTimeStepCount() % 100 == 0)
-          {
-            printf("Total time (s): %f\n", fluidObj->getDynamicalSPHModel()->getTotalTime());
-          }
-        }, "PrintTotalTime");
-      taskGraph->insertAfter(fluidObj->getDynamicalSPHModel()->getMoveParticlesNode(), printTotalTime);
-
-      std::shared_ptr<TaskNode> writeSPHStateToCSV = std::make_shared<TaskNode>([&]() {
-        fluidObj->getDynamicalSPHModel()->writeStateToCSV();
-        }, "WriteStateToCSV");
-      taskGraph->insertAfter(fluidObj->getDynamicalSPHModel()->getMoveParticlesNode(), writeSPHStateToCSV);
-
-      std::shared_ptr<TaskNode> writeSPHStateToVtk = std::make_shared<TaskNode>([&]() {
-        fluidObj->getDynamicalSPHModel()->writeStateToVtk();
-        }, "WriteStateToVtk");
-      taskGraph->insertAfter(fluidObj->getDynamicalSPHModel()->getMoveParticlesNode(), writeSPHStateToVtk);
-
-      // This node colors the fluid points based on their type
-	  std::shared_ptr<TaskNode> computeVelocityScalars = std::make_shared<TaskNode>([&]() {
-          const std::shared_ptr<SPHBoundaryConditions> sphBoundaryConditions = sphModel->getBoundaryConditions();
-          StdVectorOfReal& scalars = *scalarsPtr;
-          for (size_t i = 0; i < sphModel->getCurrentState()->getNumParticles(); i++)
-          {
-            if (sphBoundaryConditions->getParticleTypes()[i] == SPHBoundaryConditions::ParticleType::wall)
+        std::shared_ptr<TaskNode> printTotalTime = std::make_shared<TaskNode>([&]()
             {
-              scalars[i] = 0;
-            }
-            else if (sphBoundaryConditions->getParticleTypes()[i] == SPHBoundaryConditions::ParticleType::inlet)
+                if (fluidObj->getDynamicalSPHModel()->getTimeStepCount() % 100 == 0)
+                {
+                    printf("Total time (s): %f\n", fluidObj->getDynamicalSPHModel()->getTotalTime());
+                }
+            }, "PrintTotalTime");
+        taskGraph->insertAfter(fluidObj->getDynamicalSPHModel()->getMoveParticlesNode(), printTotalTime);
+
+        std::shared_ptr<TaskNode> writeSPHStateToCSV = std::make_shared<TaskNode>([&]() {
+            fluidObj->getDynamicalSPHModel()->writeStateToCSV();
+            }, "WriteStateToCSV");
+        taskGraph->insertAfter(fluidObj->getDynamicalSPHModel()->getMoveParticlesNode(), writeSPHStateToCSV);
+
+        std::shared_ptr<TaskNode> writeSPHStateToVtk = std::make_shared<TaskNode>([&]() {
+            fluidObj->getDynamicalSPHModel()->writeStateToVtk();
+            }, "WriteStateToVtk");
+        taskGraph->insertAfter(fluidObj->getDynamicalSPHModel()->getMoveParticlesNode(), writeSPHStateToVtk);
+
+        // This node colors the fluid points based on their type
+        std::shared_ptr<TaskNode> computeVelocityScalars = std::make_shared<TaskNode>([&]() {
+            const std::shared_ptr<SPHBoundaryConditions> sphBoundaryConditions = sphModel->getBoundaryConditions();
+            StdVectorOfReal& scalars = *scalarsPtr;
+            for (size_t i = 0; i < sphModel->getCurrentState()->getNumParticles(); i++)
             {
-              scalars[i] = 1;
+                if (sphBoundaryConditions->getParticleTypes()[i] == SPHBoundaryConditions::ParticleType::wall)
+                {
+                    scalars[i] = 0;
+                }
+                else if (sphBoundaryConditions->getParticleTypes()[i] == SPHBoundaryConditions::ParticleType::inlet)
+                {
+                    scalars[i] = 1;
+                }
+                else if (sphBoundaryConditions->getParticleTypes()[i] == SPHBoundaryConditions::ParticleType::outlet)
+                {
+                    scalars[i] = 2;
+                }
+                else
+                {
+                    scalars[i] = 3;
+                }
             }
-            else if (sphBoundaryConditions->getParticleTypes()[i] == SPHBoundaryConditions::ParticleType::outlet)
-            {
-              scalars[i] = 2;
-            }
-            else
-            {
-              scalars[i] = 3;
-            }
-		  }
-	  }, "ComputeVelocityScalars");
-      taskGraph->insertAfter(fluidObj->getUpdateGeometryNode(), computeVelocityScalars);
-    });
+            }, "ComputeVelocityScalars");
+        taskGraph->insertAfter(fluidObj->getUpdateGeometryNode(), computeVelocityScalars);
+    };
+
+    // Setup a viewer to render in its own thread
+    imstkNew<VTKViewer> viewer("Viewer");
+    viewer->setActiveScene(scene);
+
+    // Setup a scene manager to advance the scene in its own thread
+    imstkNew<SceneManager> sceneManager("Scene Manager");
+    sceneManager->setActiveScene(scene);
+    viewer->addChildThread(sceneManager); // SceneManager will start/stop with viewer
+    connect<Event>(sceneManager, EventType::PostUpdate, displayColors);
 
-  simManager->setActiveScene(scene);
+    // Add mouse and keyboard controls to the viewer
+    {
+        imstkNew<MouseSceneControl> mouseControl(viewer->getMouseDevice());
+        mouseControl->setSceneManager(sceneManager);
+        viewer->addControl(mouseControl);
+
+        imstkNew<KeyboardSceneControl> keyControl(viewer->getKeyboardDevice());
+        keyControl->setSceneManager(sceneManager);
+        keyControl->setViewer(viewer);
+    }
 
-  simManager->start(SimulationStatus::Paused);
+    // Start viewer running, scene as paused
+    sceneManager->requestStatus(ThreadStatus::Paused);
+    viewer->start();
 
-  return 0;
+    return 0;
 }
diff --git a/Examples/SPH-FEM-PBD/sphFemPbdExample.cpp b/Examples/SPH-FEM-PBD/sphFemPbdExample.cpp
index 22d490fe57830fa3e1cc675f4e825653bb2f6f8b..ed1d3fec140432fff9a826aa79665b0a7abb5e41 100644
--- a/Examples/SPH-FEM-PBD/sphFemPbdExample.cpp
+++ b/Examples/SPH-FEM-PBD/sphFemPbdExample.cpp
@@ -113,7 +113,7 @@ makeSPHBoxObject(const std::string& name, const double particleRadius, const Vec
     imstkNew<SPHModelConfig> sphParams(particleRadius);
     sphParams->m_bNormalizeDensity = true;
     sphParams->m_kernelOverParticleRadiusRatio = 6.0;
-    sphParams->m_viscosityCoeff = 0.5;
+    //sphParams->m_viscosityCoeff = 0.5;
     sphParams->m_surfaceTensionStiffness = 5.0;
 
     // Setup the Model
diff --git a/Examples/SPHFluid/SPHFluidExample.hpp b/Examples/SPHFluid/SPHFluidExample.hpp
index 77a3c2745765e0873725813e22132694be8337e9..01225f9bf99d6537bf444ac1f3e81b84e46a20e4 100644
--- a/Examples/SPHFluid/SPHFluidExample.hpp
+++ b/Examples/SPHFluid/SPHFluidExample.hpp
@@ -75,7 +75,7 @@ main(int argc, char* argv[])
 
     // Generate fluid and solid objects
     std::shared_ptr<SPHObject> fluidObj                  = generateFluid(particleRadius);
-    std::vector<std::shared_ptr<CollidingObject>> solids = generateSolids();
+    std::vector<std::shared_ptr<CollidingObject>> solids = generateSolids(scene);
 
     scene->addSceneObject(fluidObj);
     for (size_t i = 0; i < solids.size(); i++)
diff --git a/Examples/SPHFluid/Solid.hpp b/Examples/SPHFluid/Solid.hpp
index 5cb6cd919b7889d20910c80cbcbc9d9334af2357..fdeb881c15d92a7140c91363329e2518e1d45940 100644
--- a/Examples/SPHFluid/Solid.hpp
+++ b/Examples/SPHFluid/Solid.hpp
@@ -26,8 +26,6 @@
 //#include "imstkVTKMeshIO.h"
 //#include "imstkGeometryUtilities.h"
 
-#include "imstkSimulationManager.h"
-
 #include "imstkPlane.h"
 #include "imstkRenderMaterial.h"
 #include "imstkSphere.h"
@@ -278,7 +276,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolids(const std::shared_p
     case 2:
         return generateSolidsScene2();
     case 3:
-        return generateSolidsScene3(scene);
+        return generateSolidsScene3();
     case 4:
       return generateSolidsScene4(scene);
     default:
diff --git a/Examples/Vessel/vesselExample.cpp b/Examples/Vessel/vesselExample.cpp
index b8ef58135b5fc2fe5b33f2cfe1af366a4176f7bf..e309d78dfd2d46b1a75485365cfb7e662b6dcb63 100644
--- a/Examples/Vessel/vesselExample.cpp
+++ b/Examples/Vessel/vesselExample.cpp
@@ -115,7 +115,7 @@ makeSPHObject(const std::string& name, const double particleRadius, const double
     imstkNew<SPHModelConfig> sphParams(particleRadius);
     sphParams->m_bNormalizeDensity = true;
     sphParams->m_kernelOverParticleRadiusRatio = 6.0;
-    sphParams->m_viscosityCoeff = 0.8;
+    //sphParams->m_viscosityCoeff = 0.8;
     sphParams->m_surfaceTensionStiffness = 5.0;
     sphParams->m_frictionBoundary = 0.1;
 
diff --git a/Source/Geometry/Mesh/imstkSurfaceMesh.cpp b/Source/Geometry/Mesh/imstkSurfaceMesh.cpp
index 1a8e10273a2bfbf20a05d174669989afb9f9a1ac..d01389c7f1155ff4755a694e1219a9b8d470d3ea 100644
--- a/Source/Geometry/Mesh/imstkSurfaceMesh.cpp
+++ b/Source/Geometry/Mesh/imstkSurfaceMesh.cpp
@@ -638,6 +638,7 @@ SurfaceMesh::directionalScale(double s_x, double s_y, double s_z)
     }
 }
 
+void
 SurfaceMesh::deepCopy(std::shared_ptr<SurfaceMesh> srcMesh)
 {
     this->m_trianglesVertices       = srcMesh->m_trianglesVertices;
diff --git a/Source/Pulse/imstkPhysiologyModel.h b/Source/Pulse/imstkPhysiologyModel.h
index 959acbde16c928613b9a567f5f45e1c687185657..3c5ac91ade8bf2921a0d9b19a3ee1399a741fa97 100644
--- a/Source/Pulse/imstkPhysiologyModel.h
+++ b/Source/Pulse/imstkPhysiologyModel.h
@@ -21,6 +21,8 @@
 
 #pragma once
 
+#include <unordered_map>
+
 #include "imstkAbstractDynamicalModel.h"/*
 #include "properties/SEScalarVolumePerTime.h"
 #include "compartment/fluid/SELiquidCompartment.h"*/