iMSTK
Interactive Medical Simulation Toolkit
Docs/Cutting.md
1 # Cutting
2 
3 Cutting is available in iMSTK. There are a large amount of cutting methods in surgical simulation. iMSTK currently supports a discrete mesh based cutting method in it's `PbdObjectCutting`. Discrete cut meaning it can only cut once in an instance and is not suitable for continuous cutting. The `PBDThinTissueCut` and `PBDTissueCut` examples can be a good first reference for using cutting.
4 
5 ## PbdObjectCutting
6 
7 Setting up a PBD cloth and a cut quad mesh one can configure `PbdObjectCutting` like so:
8 
9 ```cpp
10 auto cutting = std::make_shared<PbdObjectCutting>(tissueObj, toolObj);
11 scene->addSceneObject(cutting);
12 ```
13 
14 It could, for example, be hooked up to a key press `g`.
15 ```cpp
16 connect<KeyEvent>(viewer->getKeyboardDevice(), &KeyboardDeviceClient::keyPress,
17  [&](KeyEvent* e)
18  {
19  if (e->m_key == 'g')
20  {
21  cutting->apply();
22  }
23  });
24 ```
25 
26 This also works for `LineMesh` meshes. Useful for `ConnectiveTissue` cutting.
27 
28 ![type:video](./media/pbdThinTissueCut.mp4)
29 
30 ## PbdObjectTearing
31 
32 ## PbdObjectBurning
33 
34 ## RigidObjectLevelSetCollision
35 
36 The `RigidObjectLevelSetCollision` can be used for material removal. It is good for bone sawing, burring and tooth milling actions where the object being removed from is static. It does this with the `LevelSetModel` in iMSTK, intended for movement of the levelset with a rigid body tool. It can be utilized like so:
37 
38 ```cpp
39 // Setup cutting interaction between level set femur and rigid object tool
40 auto cutting = std::make_shared<RigidObjectLevelSetCollision>(rbdObj, femurObj);
41 scene->addInteraction(cutting);
42 ```
43 
44 It can further be modified with:
45 
46 ```cpp
47 auto colHandlerA = std::dynamic_pointer_cast<RigidBodyCH>(cutting->getCollisionHandlingA());
48 colHandlerA->setUseFriction(false);
49 colHandlerA->setBaumgarteStabilization(0.05); // inelastic collision
50 
51 auto colHandlerB = std::dynamic_pointer_cast<LevelSetCH>(cutting->getCollisionHandlingB());
52 colHandlerB->setLevelSetVelocityScaling(0.01);
53 colHandlerB->setKernel(3, 1.0);
54 //colHandlerB->setLevelSetVelocityScaling(0.0); // Can't push the levelset
55 colHandlerB->setUseProportionalVelocity(true);
56 ```
57 
58 The femurObj here must be setup with a `SignedDistanceField` geometry provided to the `LevelSetModel` for initialization.
59 
60 <p align="center">
61  <img src="media/lsmCutting.gif" alt="level set cutting"/>
62 </p>
63 
64 To visualize the `SignedDistanceField` one can volume render it or isosurface extract it every frame. Doing this every frame for a large image may be costly so iMSTK provides a `LocalMarchingCubes` operation that can be read about in the [Filtering](./Extras/Filtering.md) section of this documentation. It effectively chunks the image and only re-extracts modified portions of it.
65 
66 <p align="center">
67  <img src="media/localmc.gif" alt="level set cutting with chunks"/>
68 </p>