iMSTK
Interactive Medical Simulation Toolkit
femDeformable.cs
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 using Imstk;
8 
9 public enum Geom
10 {
11  Dragon,
12  Heart
13 }
14 
15 public class Input
16 {
17  public string meshFileName;
18  public VectorSizet fixedNodeIds;
19 }
20 
21 public class FeDeformable
22 {
23  private const Geom geom = Geom.Heart;
24  private static Input input;
25 
26  public static void Main(string[] args)
27  {
28  // Write log to stdout and file
29  Logger.startLogger();
30 
31  input = new Input();
32  if (geom == Geom.Dragon)
33  {
34  input.meshFileName = "../data/asianDragon/asianDragon.veg";
35  input.fixedNodeIds = new VectorSizet(3);
36  input.fixedNodeIds.Add(50);
37  input.fixedNodeIds.Add(126);
38  input.fixedNodeIds.Add(177);
39  }
40  else if (geom == Geom.Heart)
41  {
42  input.meshFileName = "../data/textured_organs/heart_volume.vtk";
43  input.fixedNodeIds = new VectorSizet(13);
44  input.fixedNodeIds.Add(75);
45  input.fixedNodeIds.Add(82);
46  input.fixedNodeIds.Add(84);
47  input.fixedNodeIds.Add(94);
48  input.fixedNodeIds.Add(95);
49  input.fixedNodeIds.Add(105);
50  input.fixedNodeIds.Add(110);
51  input.fixedNodeIds.Add(124);
52  input.fixedNodeIds.Add(139);
53  input.fixedNodeIds.Add(150);
54  input.fixedNodeIds.Add(161);
55  input.fixedNodeIds.Add(171);
56  input.fixedNodeIds.Add(350);
57  }
58 
59  // Construct the scene
60  Scene scene = new Scene("DeformableBodyFEM");
61  {
62  Camera cam = scene.getActiveCamera();
63  cam.setPosition(0.0, 2.0, -25.0);
64  cam.setFocalPoint(0.0, 0.0, 0.0);
65 
66  // Load a tetrahedral mesh
67  TetrahedralMesh tetMesh = MeshIO.readTetrahedralMesh(input.meshFileName);
68  // CHECK(tetMesh != nullptr) << "Could not read mesh from file.";
69 
70  // Scene object 1: fe-FeDeformableObject
71  FeDeformableObject deformableObj = makeFEDeformableObject(tetMesh);
72  scene.addSceneObject(deformableObj);
73 
74  // Scene object 2: Plane
75  Plane planeGeom = new Plane();
76  planeGeom.setWidth(40.0);
77  planeGeom.setPosition(0.0, -8.0, 0.0);
78  CollidingObject planeObj = new CollidingObject("Plane");
79  planeObj.setVisualGeometry(planeGeom);
80  planeObj.setCollidingGeometry(planeGeom);
81  scene.addSceneObject(planeObj);
82 
83  // Light
84  DirectionalLight light = new DirectionalLight();
85  light.setFocalPoint(new Vec3d(5.0, -8.0, -5.0));
86  light.setIntensity(1);
87  scene.addLight("light", light);
88  }
89 
90  // Run the simulation
91  {
92  // Setup a viewer to render in its own thread
93  VTKViewer viewer = new VTKViewer("Viewer");
94  viewer.setActiveScene(scene);
95 
96  // Setup a scene manager to advance the scene in its own thread
97  SceneManager sceneManager = new SceneManager("Scene Manager");
98  sceneManager.setActiveScene(scene);
99  sceneManager.pause(); // Start simulation paused
100 
101  SimulationManager driver = new SimulationManager();
102  driver.addModule(viewer);
103  driver.addModule(sceneManager);
104 
105  // Add mouse and keyboard controls to the viewer
106  {
107  MouseSceneControl mouseControl = new MouseSceneControl();
108  mouseControl.setDevice(viewer.getMouseDevice());
109  mouseControl.setSceneManager(sceneManager);
110  scene.addControl(mouseControl);
111 
112  KeyboardSceneControl keyControl = new KeyboardSceneControl();
113  keyControl.setDevice(viewer.getKeyboardDevice());
114  keyControl.setSceneManager(new SceneManagerWeakPtr(sceneManager));
115  keyControl.setModuleDriver(new ModuleDriverWeakPtr(driver));
116  scene.addControl(keyControl);
117  }
118 
119  driver.start();
120  }
121  }
122 
123  private static FeDeformableObject makeFEDeformableObject(TetrahedralMesh tetMesh)
124  {
125  SurfaceMesh surfMesh = tetMesh.extractSurfaceMesh();
126  // surfMesh.flipNormals();
127 
128  // Configure dynamic model
129  FemDeformableBodyModel dynaModel = new FemDeformableBodyModel();
130  FemModelConfig config = new FemModelConfig();
131  config.m_fixedNodeIds = input.fixedNodeIds;
132  dynaModel.configure(config);
133  //dynaModel.configure(iMSTK_DATA_ROOT "/asianDragon/asianDragon.config");
134 
135  dynaModel.setTimeStepSizeType(TimeSteppingType.Fixed);
136  dynaModel.setModelGeometry(tetMesh);
137  BackwardEuler timeIntegrator = new BackwardEuler(0.01); // Create and add Backward Euler time integrator
138  dynaModel.setTimeIntegrator(timeIntegrator);
139 
140  RenderMaterial mat = new RenderMaterial();
141  mat.setDisplayMode(RenderMaterial.DisplayMode.WireframeSurface);
142  mat.setPointSize(10.0f);
143  mat.setLineWidth(2.0f);
144  mat.setEdgeColor(Color.Orange);
145  VisualModel surfMeshModel = new VisualModel();
146  surfMeshModel.setGeometry(surfMesh);
147  surfMeshModel.setRenderMaterial(mat);
148 
149  // Scene object 1: Dragon
150  FeDeformableObject deformableObj = new FeDeformableObject("Dragon");
151  deformableObj.addVisualModel(surfMeshModel);
152  deformableObj.setPhysicsGeometry(tetMesh);
153  // Map simulated geometry to visual
154  deformableObj.setPhysicsToVisualMap(new PointwiseMap(tetMesh, surfMesh));
155  deformableObj.setDynamicalModel(dynaModel);
156 
157  return deformableObj;
158  }
159 }
lazy initialized singleton