iMSTK
Interactive Medical Simulation Toolkit
pbdCloth.cs
1 using System;
2 using Imstk;
3 
4 public class PbdCloth
5 {
6  private static string dataPath = "../data/";
7 
8  public static void Main(string[] args)
9  {
10  // Write log to stdout and file
11  Logger.startLogger();
12 
13  // Setup a scene
14  Scene scene = new Scene("PBDCloth");
15  PbdObject clothObj = makeClothObj("Cloth", 10.0, 10.0, 16, 16);
16  scene.addSceneObject(clothObj);
17 
18  // Adjust camera
19  scene.getActiveCamera().setFocalPoint(0.0, -5.0, 5.0);
20  scene.getActiveCamera().setPosition(-15.0, -5.0, 25.0);
21 
22  // Run the simulation
23  {
24  // Setup a viewer to render
25  VTKViewer viewer = new VTKViewer("Viewer");
26  viewer.setActiveScene(scene);
27 
28  // Setup a scene manager to advance the scene
29  SceneManager sceneManager = new SceneManager("Scene Manager");
30  sceneManager.setExecutionType(Module.ExecutionType.ADAPTIVE);
31  sceneManager.setActiveScene(scene);
32  sceneManager.pause(); // Start simulation paused
33 
34  SimulationManager driver = new SimulationManager();
35  driver.addModule(viewer);
36  driver.addModule(sceneManager);
37  driver.setDesiredDt(0.001);
38 
39  // Add mouse and keyboard controls to the viewer
40  {
41  MouseSceneControl mouseControl = new MouseSceneControl();
42  mouseControl.setDevice(viewer.getMouseDevice());
43  mouseControl.setSceneManager(sceneManager);
44  scene.addControl(mouseControl);
45 
46  KeyboardSceneControl keyControl = new KeyboardSceneControl();
47  keyControl.setDevice(viewer.getKeyboardDevice());
48  keyControl.setSceneManager(new SceneManagerWeakPtr(sceneManager));
49  keyControl.setModuleDriver(new ModuleDriverWeakPtr(driver));
50  scene.addControl(keyControl);
51  }
52 
53  Utils.connectKeyEvent(viewer.getKeyboardDevice(), Utils.KeyboardDeviceClient_getKeyPress_cb,
54  (KeyEvent e) =>
55  {
56  // Set new textures
57  if (e.m_key == '1')
58  {
59  setFleshTextures(clothObj.getVisualModel(0).getRenderMaterial());
60  }
61  else if (e.m_key == '2')
62  {
63  setFabricTextures(clothObj.getVisualModel(0).getRenderMaterial());
64  }
65  // Darken the texture pixel values
66  else if (e.m_key == 'h')
67  {
68  ImageData imageData = clothObj.getVisualModel(0).getRenderMaterial().getTexture(Texture.Type.Diffuse).getImageData();
69  VecDataArray3uc scalars = Utils.CastTo<VecDataArray3uc>(imageData.getScalars());
70  byte[] newScalars = new byte[3 * scalars.size()];
71  scalars.getValues(newScalars);
72 
73  for (int i = 0; i < newScalars.Length; i++)
74  {
75  newScalars[i] = (byte)(newScalars[i] * 0.8);
76  }
77  scalars.setValues(newScalars);
78  clothObj.getVisualModel(0).getRenderMaterial().getTexture(Texture.Type.Diffuse).postModified();
79  }
80  });
81 
82  driver.start();
83  }
84  }
85 
86  public static PbdObject makeClothObj(string name, double width, double height, int rowCount, int colCount)
87  {
88  PbdObject clothObj = new PbdObject(name);
89 
90  // Setup the Geometry
91  SurfaceMesh clothMesh = Utils.toTriangleGrid(new Vec3d(0.0, 0.0, 0.0),
92  new Vec2d(10.0, 10.0), new Vec2i(16, 16), new Quatd(0.0, 0.0, 0.0, 1.0), 2.0);
93 
94  // Setup the Parameters
95  PbdModelConfig pbdParams = new PbdModelConfig();
96  pbdParams.enableConstraint(PbdModelConfig.ConstraintGenType.Distance, 1.0e2);
97  pbdParams.enableConstraint(PbdModelConfig.ConstraintGenType.Dihedral, 1.0e1);
98  pbdParams.m_gravity = new Vec3d(0.0, -9.8, 0.0);
99  pbdParams.m_dt = 0.005;
100  pbdParams.m_iterations = 5;
101 
102  // Setup the Model
103  PbdModel pbdModel = new PbdModel();
104  pbdModel.setModelGeometry(clothMesh);
105  pbdModel.configure(pbdParams);
106 
107  // Setup the VisualModel
108  RenderMaterial material = new RenderMaterial();
109  material.setBackFaceCulling(false);
110  material.setDisplayMode(RenderMaterial.DisplayMode.Surface);
111  // material.setDisplayMode(RenderMaterial.DisplayMode.Wireframe);
112  material.setShadingModel(RenderMaterial.ShadingModel.PBR);
113 
114  setFleshTextures(material);
115  // setFabricTextures(material);
116  VisualModel visualModel = new VisualModel();
117  visualModel.setGeometry(clothMesh);
118  visualModel.setRenderMaterial(material);
119 
120  // Setup the Object
121  clothObj.addVisualModel(visualModel);
122  clothObj.setPhysicsGeometry(clothMesh);
123  clothObj.setDynamicalModel(pbdModel);
124 
125  clothObj.getPbdBody().fixedNodeIds = new VectorInt(2);
126  clothObj.getPbdBody().fixedNodeIds.Add(0);
127  clothObj.getPbdBody().fixedNodeIds.Add(colCount - 1);
128  clothObj.getPbdBody().uniformMassValue = width * height / (rowCount * colCount);
129 
130  return clothObj;
131  }
132 
133  private static void setFabricTextures(RenderMaterial material)
134  {
135  ImageData diffuseTex = MeshIO.readImageData(dataPath + "textures/fabricDiffuse.jpg");
136  material.addTexture(new Texture(diffuseTex, Texture.Type.Diffuse));
137  ImageData normalTex = MeshIO.readImageData(dataPath + "textures/fabricNormal.jpg");
138  material.addTexture(new Texture(normalTex, Texture.Type.Normal));
139  ImageData ormTex = MeshIO.readImageData(dataPath + "textures/fabricORM.jpg");
140  material.addTexture(new Texture(ormTex, Texture.Type.ORM));
141  }
142 
143  private static void setFleshTextures(RenderMaterial material)
144  {
145  ImageData diffuseTex = MeshIO.readImageData(dataPath + "textures/fleshDiffuse.jpg");
146  material.addTexture(new Texture(diffuseTex, Texture.Type.Diffuse));
147  ImageData normalTex = MeshIO.readImageData(dataPath + "textures/fleshNormal.jpg");
148  material.addTexture(new Texture(normalTex, Texture.Type.Normal));
149  ImageData ormTex = MeshIO.readImageData(dataPath + "textures/fleshORM.jpg");
150  material.addTexture(new Texture(ormTex, Texture.Type.ORM));
151  }
152 }
lazy initialized singleton