iMSTK
Interactive Medical Simulation Toolkit
pbdCutting.cs
1 using System;
2 using Imstk;
3 
4 public class PbdCutting
5 {
6  private static double width = 50.0;
7  private static double height = 50.0;
8  private static int nRows = 12;
9  private static int nCols = 12;
10 
11  public static void Main(string[] args)
12  {
13  // Write log to stdout and file
14  Logger.startLogger();
15 
16  // Setup a scene
17  Scene scene = new Scene("PBDCutting");
18  SurfaceMesh cutGeom = Utils.toTriangleGrid(new Vec3d(0.0, 0.0, 0.0), new Vec2d(40, 40), new Vec2i(2, 2));
19  cutGeom.setTranslation(new Vec3d(-10.0, -20.0, 0.0));
20  cutGeom.updatePostTransformData();
21  CollidingObject cutObj = new CollidingObject("CuttingObject");
22  cutObj.setVisualGeometry(cutGeom);
23  cutObj.setCollidingGeometry(cutGeom);
24  cutObj.getVisualModel(0).getRenderMaterial().setDisplayMode(RenderMaterial.DisplayMode.WireframeSurface);
25  scene.addSceneObject(cutObj);
26 
27  PbdObject clothObj = makeClothObj("Cloth", width, height, nRows, nCols);
28  scene.addSceneObject(clothObj);
29 
30  // Add interaction pair for pbd cutting
31  PbdObjectCutting cuttingPair = new PbdObjectCutting(clothObj, cutObj);
32 
33  DeviceManager hapticManager = DeviceManagerFactory.makeDeviceManager();
34  DeviceClient client = hapticManager.makeDeviceClient();
35 
36  SceneObjectController controller = new SceneObjectController();
37  controller.setControlledObject(cutObj);
38  controller.setDevice(client);
39  scene.addControl(controller);
40 
41  // Adjust camera
42  scene.getActiveCamera().setPosition(100.0, 100.0, 100.0);
43  scene.getActiveCamera().setFocalPoint(0.0, -50.0, 0.0);
44 
45  // Light
46  DirectionalLight light = new DirectionalLight();
47  light.setFocalPoint(new Vec3d(5.0, -8.0, -5.0));
48  light.setIntensity(1.0);
49  scene.addLight("light", light);
50 
51  // Run the simulation
52  {
53  // Setup a viewer to render
54  VTKViewer viewer = new VTKViewer("Viewer");
55  viewer.setActiveScene(scene);
56 
57  // Setup a scene manager to advance the scene
58  SceneManager sceneManager = new SceneManager("Scene Manager");
59  sceneManager.setActiveScene(scene);
60  sceneManager.setExecutionType(Module.ExecutionType.ADAPTIVE);
61  sceneManager.pause(); // Start simulation paused
62 
63  SimulationManager driver = new SimulationManager();
64  driver.addModule(hapticManager);
65  driver.addModule(viewer);
66  driver.addModule(sceneManager);
67  driver.setDesiredDt(0.001);
68 
69  // Add mouse and keyboard controls to the viewer
70  {
71  MouseSceneControl mouseControl = new MouseSceneControl();
72  mouseControl.setDevice(viewer.getMouseDevice());
73  mouseControl.setSceneManager(sceneManager);
74  scene.addControl(mouseControl);
75 
76  KeyboardSceneControl keyControl = new KeyboardSceneControl();
77  keyControl.setDevice(viewer.getKeyboardDevice());
78  keyControl.setSceneManager(new SceneManagerWeakPtr(sceneManager));
79  keyControl.setModuleDriver(new ModuleDriverWeakPtr(driver));
80  scene.addControl(keyControl);
81  }
82 
83  Utils.connectKeyEvent(viewer.getKeyboardDevice(), Utils.KeyboardDeviceClient_getKeyPress_cb,
84  (KeyEvent e) =>
85  {
86  const int KEY_PRESS = 1;
87  // Set new textures
88  if (e.m_key == 'i' && e.m_keyPressType == KEY_PRESS)
89  {
90  cuttingPair.apply();
91  }
92  });
93 
94  driver.start();
95  }
96  }
97 
98  public static PbdObject makeClothObj(string name, double width, double height, int rowCount, int colCount)
99  {
100  PbdObject clothObj = new PbdObject(name);
101 
102  // Setup the Geometry
103  SurfaceMesh clothMesh = Utils.toTriangleGrid(new Vec3d(0.0, 0.0, 0.0),
104  new Vec2d(width, height), new Vec2i(nRows, nCols));
105 
106  // Setup the Parameters
107  PbdModelConfig pbdParams = new PbdModelConfig();
108  pbdParams.enableConstraint(PbdModelConfig.ConstraintGenType.Distance, 1.0e3);
109  pbdParams.enableConstraint(PbdModelConfig.ConstraintGenType.Dihedral, 1.0e3);
110  pbdParams.m_gravity = new Vec3d(0.0, -9.8, 0.0);
111  pbdParams.m_dt = 0.005;
112  pbdParams.m_iterations = 5;
113 
114  // Setup the Model
115  PbdModel pbdModel = new PbdModel();
116  pbdModel.setModelGeometry(clothMesh);
117  pbdModel.configure(pbdParams);
118 
119  // Setup the VisualModel
120  RenderMaterial material = new RenderMaterial();
121  material.setBackFaceCulling(false);
122  material.setDisplayMode(RenderMaterial.DisplayMode.WireframeSurface);
123 
124  VisualModel visualModel = new VisualModel();
125  visualModel.setGeometry(clothMesh);
126  visualModel.setRenderMaterial(material);
127 
128  // Setup the Object
129  clothObj.addVisualModel(visualModel);
130  clothObj.setPhysicsGeometry(clothMesh);
131  clothObj.setCollidingGeometry(clothMesh);
132  clothObj.setDynamicalModel(pbdModel);
133 
134  clothObj.getPbdBody().fixedNodeIds = new VectorInt(2);
135  clothObj.getPbdBody().fixedNodeIds.Add(0);
136  clothObj.getPbdBody().fixedNodeIds.Add(colCount - 1);
137  clothObj.getPbdBody().uniformMassValue = width * height / (rowCount * colCount);
138 
139  return clothObj;
140  }
141 }
lazy initialized singleton