iMSTK
Interactive Medical Simulation Toolkit
pbdClothCollision.cs
1 using System;
2 using Imstk;
3 
4 public class PbdCloth
5 {
6  public static void Main(string[] args)
7  {
8  // Write log to stdout and file
9  Logger.startLogger();
10 
11  Capsule capsule = new Capsule(new Vec3d(0.0, -4.0, 0.0), 2.0, 5.0, new Quatd(new Rotd(1.5708, new Vec3d(0.0, 0.0, 1.0))));
12  Sphere sphere = new Sphere(new Vec3d(0.0, -2.0, 0.0), 2.0);
13  OrientedBox cube = new OrientedBox(new Vec3d(0.0, -4.0, 0.0), new Vec3d(2.5, 2.5, 2.5));
14  Plane plane = new Plane(new Vec3d(0.0, -2.0, 0.0), new Vec3d(0.0, 1.0, 0.0));
15  plane.setWidth(20.0);
16 
17  Geometry[] geometries = new Geometry[] { capsule, sphere, cube, plane };
18 
19  // Setup a scene
20  Scene scene = new Scene("PBDClothCollision");
21  PbdObject clothObj = makeClothObj("Cloth", 10.0, 10.0, 16, 16);
22  scene.addSceneObject(clothObj);
23  CollidingObject collisionObj = new CollidingObject("CollidingObject");
24  collisionObj.setCollidingGeometry(capsule);
25 
26  for (int i = 0; i < 4; ++i)
27  {
28  VisualModel visualModel = new VisualModel();
29  visualModel.setGeometry(geometries[i]);
30  visualModel.getRenderMaterial().setBackFaceCulling(false);
31  visualModel.getRenderMaterial().setOpacity(0.5);
32  visualModel.hide();
33  collisionObj.addVisualModel(visualModel);
34  }
35  collisionObj.getVisualModel(0).show();
36  scene.addSceneObject(collisionObj);
37 
38  PbdObjectCollision pbdInteraction = new PbdObjectCollision(clothObj, collisionObj, "PointSetToCapsuleCD");
39  pbdInteraction.setFriction(0.4);
40  pbdInteraction.setRestitution(0.0);
41  scene.addInteraction(pbdInteraction);
42 
43 
44  // Adjust camera
45  scene.getActiveCamera().setFocalPoint(0.0, -2.0, 0.0);
46  scene.getActiveCamera().setPosition(5.0, 4.0, 18.0);
47 
48  // Run the simulation
49  {
50  // Setup a viewer to render
51  VTKViewer viewer = new VTKViewer("Viewer");
52  viewer.setActiveScene(scene);
53 
54  // Setup a scene manager to advance the scene
55  SceneManager sceneManager = new SceneManager("Scene Manager");
56  sceneManager.setExecutionType(Module.ExecutionType.ADAPTIVE);
57  sceneManager.setActiveScene(scene);
58  sceneManager.pause(); // Start simulation paused
59 
60  SimulationManager driver = new SimulationManager();
61  driver.addModule(viewer);
62  driver.addModule(sceneManager);
63  driver.setDesiredDt(0.001);
64 
65  // Add mouse and keyboard controls to the viewer
66  {
67  MouseSceneControl mouseControl = new MouseSceneControl();
68  mouseControl.setDevice(viewer.getMouseDevice());
69  mouseControl.setSceneManager(sceneManager);
70  scene.addControl(mouseControl);
71 
72  KeyboardSceneControl keyControl = new KeyboardSceneControl();
73  keyControl.setDevice(viewer.getKeyboardDevice());
74  keyControl.setSceneManager(new SceneManagerWeakPtr(sceneManager));
75  keyControl.setModuleDriver(new ModuleDriverWeakPtr(driver));
76  scene.addControl(keyControl);
77  }
78 
79  Utils.connectKeyEvent(viewer.getKeyboardDevice(), Utils.KeyboardDeviceClient_getKeyPress_cb,
80  (KeyEvent e) =>
81  {
82  // Switch to sphere and reset
83  int indexToShow = -1;
84  CollisionDetectionAlgorithm newCDMethod = null;
85  if (e.m_key == '1')
86  {
87  indexToShow = 0;
88  newCDMethod = new PointSetToCapsuleCD();
89  }
90  // Switch to capsule and reset
91  else if (e.m_key == '2')
92  {
93  indexToShow = 1;
94  newCDMethod = new PointSetToSphereCD();
95  }
96  // Switch to cube and reset
97  else if (e.m_key == '3')
98  {
99  indexToShow = 2;
100  newCDMethod = new PointSetToOrientedBoxCD();
101  }
102  // Switch to plane and reset
103  else if (e.m_key == '4')
104  {
105  indexToShow = 3;
106  newCDMethod = new PointSetToPlaneCD();
107  }
108  // Switch to sphere vs surface and reset
109  else if (e.m_key == '5')
110  {
111  indexToShow = 1;
112  newCDMethod = new SurfaceMeshToSphereCD();
113  }
114  // Switch to sphere vs surface and reset
115  else if (e.m_key == '6')
116  {
117  indexToShow = 0;
118  newCDMethod = new SurfaceMeshToCapsuleCD();
119  }
120 
121  if (indexToShow != -1)
122  {
123  // Hide all models
124  for (int i = 0; i < 4; i++)
125  {
126  collisionObj.getVisualModel(i).hide();
127  }
128  // Show the selected one
129  VisualModel visualModel = collisionObj.getVisualModel((int)indexToShow);
130  visualModel.show();
131  collisionObj.setCollidingGeometry(visualModel.getGeometry());
132 
133  newCDMethod.setInputGeometryA(clothObj.getCollidingGeometry());
134  newCDMethod.setInputGeometryB(visualModel.getGeometry());
135  pbdInteraction.setCollisionDetection(newCDMethod);
136  pbdInteraction.getCollisionHandlingA().setInputCollisionData(newCDMethod.getCollisionData());
137 
138  scene.buildTaskGraph();
139  scene.initTaskGraph();
140  scene.reset();
141  }
142  });
143 
144  driver.start();
145  }
146 
147  }
148 
149  public static PbdObject makeClothObj(string name, double width, double height, int rowCount, int colCount)
150  {
151  PbdObject clothObj = new PbdObject(name);
152 
153  // Setup the Geometry
154  SurfaceMesh clothMesh = Utils.toTriangleGrid(new Vec3d(0.0, 0.0, 0.0),
155  new Vec2d(width, height), new Vec2i(rowCount, colCount), new Quatd(0.0, 0.0, 0.0, 1.0), 2.0);
156 
157  // Setup the Parameters
158  PbdModelConfig pbdParams = new PbdModelConfig();
159  pbdParams.enableConstraint(PbdModelConfig.ConstraintGenType.Distance, 1.0e2);
160  pbdParams.enableConstraint(PbdModelConfig.ConstraintGenType.Dihedral, 1.0e1);
161  pbdParams.m_gravity = new Vec3d(0.0, -9.8, 0.0);
162  pbdParams.m_dt = 0.005;
163  pbdParams.m_iterations = 5;
164 
165  // Setup the Model
166  PbdModel pbdModel = new PbdModel();
167  pbdModel.setModelGeometry(clothMesh);
168  pbdModel.configure(pbdParams);
169 
170  // Setup the VisualModel
171  RenderMaterial material = new RenderMaterial();
172  material.setBackFaceCulling(false);
173  material.setDisplayMode(RenderMaterial.DisplayMode.WireframeSurface);
174  material.setColor(Color.Blue);
175 
176  // setFabricTextures(material);
177  VisualModel visualModel = new VisualModel();
178  visualModel.setGeometry(clothMesh);
179  visualModel.setRenderMaterial(material);
180 
181  // Setup the Object
182  clothObj.addVisualModel(visualModel);
183  clothObj.setPhysicsGeometry(clothMesh);
184  clothObj.setCollidingGeometry(clothMesh);
185  clothObj.setDynamicalModel(pbdModel);
186  clothObj.getPbdBody().uniformMassValue = width * height / (rowCount * colCount);
187 
188  return clothObj;
189  }
190 }
lazy initialized singleton