iMSTK
Interactive Medical Simulation Toolkit
taskGraphConfigureExample.cpp
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 "imstkColorFunction.h"
9 #include "imstkGeometryUtilities.h"
10 #include "imstkKeyboardDeviceClient.h"
11 #include "imstkKeyboardSceneControl.h"
12 #include "imstkMeshIO.h"
13 #include "imstkMouseDeviceClient.h"
14 #include "imstkMouseSceneControl.h"
15 #include "imstkNew.h"
16 #include "imstkPbdModel.h"
17 #include "imstkPbdModelConfig.h"
18 #include "imstkPbdObject.h"
19 #include "imstkRenderMaterial.h"
20 #include "imstkScene.h"
21 #include "imstkSceneManager.h"
22 #include "imstkSimulationManager.h"
23 #include "imstkSimulationUtils.h"
24 #include "imstkSurfaceMesh.h"
25 #include "imstkTaskGraph.h"
26 #include "imstkTaskGraphVizWriter.h"
27 #include "imstkVisualModel.h"
28 #include "imstkVTKViewer.h"
29 
30 using namespace imstk;
31 
32 static std::shared_ptr<PbdObject>
33 makeClothObj(const std::string& name, double width, double height, int nRows, int nCols)
34 {
35  std::shared_ptr<SurfaceMesh> clothMesh =
36  GeometryUtils::toTriangleGrid(Vec3d::Zero(),
37  Vec2d(width, height), Vec2i(nRows, nCols));
38 
39  // Setup the Parameters
40  imstkNew<PbdModelConfig> pbdParams;
41  pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, 1e2);
42  pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Dihedral, 1e1);
43  pbdParams->m_gravity = Vec3d(0, -9.8, 0);
44  pbdParams->m_dt = 0.007;
45  pbdParams->m_iterations = 5;
46 
47  // Setup the Model
48  imstkNew<PbdModel> pbdModel;
49  pbdModel->configure(pbdParams);
50 
51  // Setup visual models
52  imstkNew<VisualModel> clothModel;
53  clothModel->setGeometry(clothMesh);
54  clothModel->getRenderMaterial()->setBackFaceCulling(false);
55  clothModel->getRenderMaterial()->setColor(Color::LightGray);
56  clothModel->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
57 
58  imstkNew<VisualModel> clothSurfaceNormals;
59  clothSurfaceNormals->setGeometry(clothMesh);
60  clothSurfaceNormals->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::SurfaceNormals);
61  clothSurfaceNormals->getRenderMaterial()->setPointSize(0.5);
62 
63  // Setup the Object
64  auto clothObj = std::make_shared<PbdObject>(name);
65  clothObj->addVisualModel(clothModel);
66  clothObj->addVisualModel(clothSurfaceNormals);
67  clothObj->setPhysicsGeometry(clothMesh);
68  clothObj->setDynamicalModel(pbdModel);
69  clothObj->getPbdBody()->fixedNodeIds = { 0, nCols - 1 };
70  clothObj->getPbdBody()->uniformMassValue = width * height / (nRows * nCols);
71  return clothObj;
72 }
73 
77 int
78 main()
79 {
80  // Setup logger (write to file and stdout)
82 
83  imstkNew<Scene> scene("PBDCloth");
84  scene->getActiveCamera()->setFocalPoint(0.0, -5.0, 0.0);
85  scene->getActiveCamera()->setPosition(0.0, 1.5, 25.0);
86  scene->getActiveCamera()->setViewUp(0.0, 1.0, 0.0);
87 
88  std::shared_ptr<PbdObject> clothObj = makeClothObj("Cloth", 10.0, 10.0, 16, 16);
89  scene->addSceneObject(clothObj);
90 
91  // Setup some scalars
92  auto clothGeometry = std::dynamic_pointer_cast<SurfaceMesh>(clothObj->getPhysicsGeometry());
93  auto scalarsPtr = std::make_shared<DataArray<double>>(clothGeometry->getNumVertices());
94  std::fill_n(scalarsPtr->getPointer(), scalarsPtr->size(), 0.0);
95  clothGeometry->setVertexScalars("scalars", scalarsPtr);
96 
97  // Setup the material for the scalars
98  std::shared_ptr<RenderMaterial> material = clothObj->getVisualModel(0)->getRenderMaterial();
99  material->setScalarVisibility(true);
100  std::shared_ptr<ColorFunction> colorFunc = std::make_shared<ColorFunction>();
101  colorFunc->setNumberOfColors(2);
102  colorFunc->setColor(0, Color::Green);
103  colorFunc->setColor(1, Color::Red);
104  colorFunc->setColorSpace(ColorFunction::ColorSpace::RGB);
105  colorFunc->setRange(0.0, 2.0);
106  material->setColorLookupTable(colorFunc);
107 
108  // Adds a custom physics step to print out maximum velocity
109  connect<Event>(scene, &Scene::configureTaskGraph,
110  [&](Event*)
111  {
112  // Get the graph
113  std::shared_ptr<TaskGraph> graph = scene->getTaskGraph();
114 
115  // First write the graph before we make modifications, just to show the changes
117  writer->setInput(graph);
118  writer->setFileName("taskGraphConfigureExampleOld.svg");
119  writer->write();
120 
121  // This node computes displacements and sets the color to the magnitude
122  std::shared_ptr<TaskNode> computeVelocityScalars = std::make_shared<TaskNode>([&]()
123  {
124  const VecDataArray<double, 3>& velocities =
125  *std::dynamic_pointer_cast<VecDataArray<double, 3>>(clothGeometry->getVertexAttribute("Velocities"));
126  DataArray<double>& scalars = *scalarsPtr;
127  for (int i = 0; i < velocities.size(); i++)
128  {
129  scalars[i] = velocities[i].norm();
130  }
131  }, "ComputeVelocityScalars");
132 
133  // After IntegratePosition
134  graph->insertAfter(clothObj->getUpdateGeometryNode(), computeVelocityScalars);
135 
136  // Write the modified graph
137  writer->setFileName("taskGraphConfigureExampleNew.svg");
138  writer->write();
139  });
140 
141  // Run the simulation
142  {
143  // Setup a viewer to render
144  imstkNew<VTKViewer> viewer;
145  viewer->setActiveScene(scene);
146 
147  // Setup a scene manager to advance the scene
148  imstkNew<SceneManager> sceneManager;
149  sceneManager->setActiveScene(scene);
150  sceneManager->pause();
151 
153  driver->addModule(viewer);
154  driver->addModule(sceneManager);
155 
156  // Add default mouse and keyboard controls to the viewer
157  std::shared_ptr<Entity> mouseAndKeyControls =
158  SimulationUtils::createDefaultSceneControl(driver);
159  scene->addSceneObject(mouseAndKeyControls);
160 
161  driver->start();
162  }
163 
164  // Write out simulation geometry
165  MeshIO::write(clothGeometry, "cloth.vtk");
166 
167  return 0;
168 }
void configure(std::shared_ptr< PbdModelConfig > params)
Set simulation parameters.
void setActiveScene(std::shared_ptr< Scene > scene) override
Set scene to be rendered.
std::shared_ptr< SurfaceMesh > toTriangleGrid(const Vec3d &center, const Vec2d &size, const Vec2i &dim, const Quatd orientation=Quatd::Identity(), const double uvScale=1.0)
Produces a triangle grid on a plane given the imstkPlane.
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 enableConstraint(ConstraintGenType type, const double stiffness, const int bodyId=2)
Enables a constraint of type defined by ConstraintGenType with given stiffness. If constraint of that...
void write()
Writes the graph to a file given the filename.
void setFileName(std::string fileName)
The filename and path to write too.
unsigned int m_iterations
Internal constraints pbd solver iterations.
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
Definition: imstkNew.h:29
Represents a set of triangles & vertices via an array of Vec3d double vertices & Vec3i integer indice...
double m_dt
Time step size.
void setInput(std::shared_ptr< TaskGraph > graph)
The graph to write.
void setActiveScene(std::string newSceneName)
Sets the currently updating scene.
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.
Vec3d m_gravity
Gravity acceleration.