iMSTK
Interactive Medical Simulation Toolkit
SPHFluidExample.hpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkCamera.h"
8 #include "imstkCollisionDetectionAlgorithm.h"
9 #include "imstkDirectionalLight.h"
10 #include "imstkKeyboardDeviceClient.h"
11 #include "imstkKeyboardSceneControl.h"
12 #include "imstkMouseDeviceClient.h"
13 #include "imstkMouseSceneControl.h"
14 #include "imstkNew.h"
15 #include "imstkSceneManager.h"
16 #include "imstkSimulationManager.h"
17 #include "imstkSimulationUtils.h"
18 #include "imstkSphObject.h"
19 #include "imstkSphObjectCollision.h"
20 #include "imstkTextVisualModel.h"
21 #include "imstkVTKViewer.h"
22 
23 #include "Fluid.hpp"
24 #include "Solid.hpp"
25 
26 using namespace imstk;
27 
32 int
33 main(int argc, char* argv[])
34 {
35  // Setup logger (write to file and stdout)
37 
38  double particleRadius = 0.1;
39 
40  // Parse command line arguments
41  for (int i = 1; i < argc; ++i)
42  {
43  auto param = std::string(argv[i]);
44  if (param.find("radius") == 0
45  && param.find_first_of("=") != std::string::npos)
46  {
47  particleRadius = std::stod(param.substr(param.find_first_of("=") + 1));
48  LOG(INFO) << "Particle radius: " << particleRadius;
49  }
50  else
51  {
52  LOG(FATAL) << "Invalid argument";
53  }
54  }
55 
56  // Override particle radius for scene3 because particles in this scene were pre-generated using particle radius 0.08
57  if (SCENE_ID == 3)
58  {
59  particleRadius = 0.08;
60  }
61 
62  imstkNew<Scene> scene("SPH Fluid");
63 
64  // Generate fluid and solid objects
65  std::shared_ptr<SphObject> fluidObj = generateFluid(particleRadius);
66  std::vector<std::shared_ptr<CollidingObject>> solids = generateSolids(scene);
67 
68  scene->addSceneObject(fluidObj);
69  for (size_t i = 0; i < solids.size(); i++)
70  {
71  scene->addSceneObject(solids[i]);
72  }
73 
74  // Collision between fluid and solid objects
75  for (auto& solid : solids)
76  {
77  scene->addInteraction(
78  std::make_shared<SphObjectCollision>(fluidObj, solid));
79  }
80 
81  // configure camera
82  scene->getActiveCamera()->setPosition(-0.475, 8.116, -6.728);
83 
84  // configure light (white)
85  imstkNew<DirectionalLight> whiteLight;
86  whiteLight->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
87  whiteLight->setIntensity(1.5);
88  scene->addLight("whitelight", whiteLight);
89 
90  // Run the simulation
91  {
92  // Setup a viewer to render
93  imstkNew<VTKViewer> viewer;
94  viewer->setActiveScene(scene);
95  viewer->setWindowTitle("SPH Fluid");
96  viewer->setSize(1920, 1080);
97 
98  // Setup a scene manager to advance the scene
99  imstkNew<SceneManager> sceneManager;
100  sceneManager->setActiveScene(scene);
101  sceneManager->pause();
102 
104  driver->addModule(viewer);
105  driver->addModule(sceneManager);
106  driver->setDesiredDt(0.01);
107 
108  // Add default mouse and keyboard controls to the viewer
109  std::shared_ptr<Entity> mouseAndKeyControls =
110  SimulationUtils::createDefaultSceneControl(driver);
111  auto txtStatus = std::make_shared<TextVisualModel>("StatusText");
112  txtStatus->setPosition(TextVisualModel::DisplayPosition::UpperLeft);
113  txtStatus->setFontSize(30);
114  txtStatus->setTextColor(Color::Red);
115  connect<Event>(viewer, &VTKViewer::preUpdate,
116  [&](Event*)
117  {
118  txtStatus->setText("Number of particles: " +
119  std::to_string(fluidObj->getSphModel()->getCurrentState()->getNumParticles()) +
120  "\nNumber of solids: " + std::to_string(solids.size()));
121  });
122  mouseAndKeyControls->addComponent(txtStatus);
123  scene->addSceneObject(mouseAndKeyControls);
124 
125  driver->start();
126  }
127 
128  MeshIO::write(std::dynamic_pointer_cast<PointSet>(fluidObj->getPhysicsGeometry()), "fluid.vtk");
129 
130  return 0;
131 }
void setDesiredDt(const double dt)
Sets the target fixed timestep (may violate), seconds This ultimately effects the number of iteration...
void setActiveScene(std::shared_ptr< Scene > scene) override
Set scene to be rendered.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
Compound Geometry.
void addModule(std::shared_ptr< Module > module) override
Add a module to run.
void setIntensity(const double intensity)
Set the light intensity. This value is unbounded.
Definition: imstkLight.h:71
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
Definition: imstkNew.h:29
void setFocalPoint(const Vec3d &p)
Get/Set the light focal point.
Definition: imstkLight.h:33
void setActiveScene(std::string newSceneName)
Sets the currently updating scene.
void setSize(const int width, const int height) override
Set the render window size.
static bool write(const std::shared_ptr< imstk::PointSet > imstkMesh, const std::string &filePath)
Write external file.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.
void setWindowTitle(const std::string &title) override
Set the render window title.