iMSTK
Interactive Medical Simulation Toolkit
levelsetExample.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 "imstkDirectionalLight.h"
9 #include "imstkKeyboardDeviceClient.h"
10 #include "imstkKeyboardSceneControl.h"
11 #include "imstkLevelSetDeformableObject.h"
12 #include "imstkLevelSetModel.h"
13 #include "imstkMeshIO.h"
14 #include "imstkMouseDeviceClient.h"
15 #include "imstkMouseSceneControl.h"
16 #include "imstkScene.h"
17 #include "imstkSceneManager.h"
18 #include "imstkSimulationManager.h"
19 #include "imstkSimulationUtils.h"
20 #include "imstkSurfaceMesh.h"
21 #include "imstkSurfaceMeshDistanceTransform.h"
22 #include "imstkVisualModel.h"
23 #include "imstkVolumeRenderMaterial.h"
24 #include "imstkVTKViewer.h"
25 
26 #include <vtkColorTransferFunction.h>
27 #include <vtkPiecewiseFunction.h>
28 #include <vtkVolumeProperty.h>
29 
30 using namespace imstk;
31 
35 std::shared_ptr<LevelSetDeformableObject>
36 makeLevelsetObj(const std::string& name)
37 {
38  auto levelSetObj = std::make_shared<LevelSetDeformableObject>(name);
39 
40  // Setup the Geometry (read dragon mesh)
41  auto dragonSurfMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj");
42  //dragonSurfMesh->translate(position, Geometry::TransformType::ApplyToData);
44  computeSdf.setInputMesh(dragonSurfMesh);
45  computeSdf.setDimensions(50, 50, 50);
46  computeSdf.update();
47  std::shared_ptr<ImageData> initLvlsetImage = computeSdf.getOutputImage();
48 
49  // Setup the Model
50  auto dynamicalModel = std::make_shared<LevelSetModel>();
51  dynamicalModel->getConfig()->m_sparseUpdate = false;
52  dynamicalModel->getConfig()->m_dt = 0.003;
53  dynamicalModel->getConfig()->m_constantVelocity = -1.0;
54  dynamicalModel->setModelGeometry(initLvlsetImage);
55 
56  // Setup the VisualModel
57  auto visualModel = levelSetObj->addComponent<VisualModel>();
58  visualModel->setGeometry(initLvlsetImage);
59  auto mat = std::make_shared<VolumeRenderMaterial>();
60  vtkNew<vtkColorTransferFunction> color;
61  color->AddRGBPoint(0.0, 0.0, 0.0, 1.0);
62  color->AddRGBPoint(-0.01, 0.0, 0.0, 1.0);
63  mat->getVolumeProperty()->SetColor(color);
64  vtkNew<vtkPiecewiseFunction> opacity;
65  opacity->AddPoint(0.0, 0.0);
66  opacity->AddPoint(-0.01, 1.0);
67  mat->getVolumeProperty()->SetScalarOpacity(opacity);
68  mat->getVolumeProperty()->SetInterpolationTypeToLinear();
69  mat->getVolumeProperty()->ShadeOn();
70  visualModel->setRenderMaterial(mat);
71 
72  // Setup the Object
73  levelSetObj->setPhysicsGeometry(initLvlsetImage);
74  levelSetObj->setDynamicalModel(dynamicalModel);
75 
76  return levelSetObj;
77 }
78 
82 int
83 main()
84 {
85  // Log to file and stdout
87 
88  // Setup the scene
89  auto scene = std::make_shared<Scene>("LevelSetExample");
90 
91  scene->addSceneObject(makeLevelsetObj("DragonLevelset"));
92 
93  // Light (white)
94  auto whiteLight = std::make_shared<DirectionalLight>();
95  whiteLight->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
96  whiteLight->setIntensity(1.0);
97  scene->addLight("whitelight", whiteLight);
98 
99  // Adjust camera
100  scene->getActiveCamera()->setPosition(0.0, 10.0, -10.0);
101 
102  // Run the simulation
103 
104  // Setup a viewer to render in its own thread
105  auto viewer = std::make_shared<VTKViewer>();
106  viewer->setActiveScene(scene);
107 
108  // Setup a scene manager to advance the scene in its own thread
109  auto sceneManager = std::make_shared<SceneManager>();
110  sceneManager->setActiveScene(scene);
111  sceneManager->pause();
112 
113  auto driver = std::make_shared<SimulationManager>();
114  driver->addModule(viewer);
115  driver->addModule(sceneManager);
116  driver->setDesiredDt(0.01);
117 
118  // Add default mouse and keyboard controls to the viewer
119  std::shared_ptr<Entity> mouseAndKeyControls =
120  SimulationUtils::createDefaultSceneControl(driver);
121  scene->addSceneObject(mouseAndKeyControls);
122 
123  driver->start();
124 
125  return 0;
126 }
Compound Geometry.
This filter computes exact signed distance fields using octrees and pseudonormal computations. One might need to adjust the tolerance depending on dataset scale. The bounds for the image can be set in the filter, when none are set the bounding box of the mesh is used, the margin. When providing your own bounds a box larger than the original object might be necessary depending on shape.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.
Contains geometric, material, and render information.
void setInputMesh(std::shared_ptr< SurfaceMesh > surfMesh)
Required input, port 0.