7 #include "imstkCamera.h" 8 #include "imstkCapsule.h" 9 #include "imstkControllerForceText.h" 10 #include "imstkDirectionalLight.h" 11 #include "imstkKeyboardDeviceClient.h" 12 #include "imstkMeshIO.h" 13 #include "imstkMouseDeviceClient.h" 14 #include "imstkMouseSceneControl.h" 15 #include "imstkPbdModel.h" 16 #include "imstkPbdModelConfig.h" 17 #include "imstkPbdObject.h" 18 #include "imstkPbdObjectCollision.h" 19 #include "imstkPbdObjectController.h" 20 #include "imstkPbdObjectGrasping.h" 21 #include "imstkRenderMaterial.h" 22 #include "imstkScene.h" 23 #include "imstkSceneManager.h" 24 #include "imstkSimulationManager.h" 25 #include "imstkSimulationUtils.h" 26 #include "imstkTextVisualModel.h" 27 #include "imstkVTKViewer.h" 29 #ifdef iMSTK_USE_HAPTICS 30 #include "imstkDeviceManager.h" 31 #include "imstkDeviceManagerFactory.h" 33 #include "imstkDummyClient.h" 36 using namespace imstk;
45 auto scene = std::make_shared<Scene>(
"PbdRigidInDeformableGrasping");
46 scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
47 scene->getActiveCamera()->setPosition(0.0, 0.004, 0.1);
48 scene->getActiveCamera()->setViewUp(0.0, 1.0, 0.0);
50 auto pbdModel = std::make_shared<PbdModel>();
51 auto pbdConfig = std::make_shared<PbdModelConfig>();
52 pbdConfig->m_gravity = Vec3d(0.0, 0.0, 0.0);
53 pbdConfig->m_dt = 0.001;
54 pbdConfig->m_iterations = 5;
55 pbdConfig->m_linearDampingCoeff = 0.03;
56 pbdConfig->m_angularDampingCoeff = 0.01;
57 pbdConfig->m_doPartitioning =
false;
58 pbdModel->configure(pbdConfig);
60 auto tissueObj = std::make_shared<PbdObject>(
"tissue");
62 auto surfMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/Organs/Vessels/vessel_test.obj");
65 pbdModel->getConfig()->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, 10000.0);
66 pbdModel->getConfig()->enableConstraint(PbdModelConfig::ConstraintGenType::Dihedral, 0.1);
69 auto material = std::make_shared<RenderMaterial>();
70 material->setBackFaceCulling(
false);
71 material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
73 material->setOpacity(0.5);
76 tissueObj->setVisualGeometry(surfMesh);
77 tissueObj->getVisualModel(0)->setRenderMaterial(material);
78 tissueObj->setPhysicsGeometry(surfMesh);
79 tissueObj->setCollidingGeometry(surfMesh);
80 tissueObj->setDynamicalModel(pbdModel);
82 tissueObj->getPbdBody()->uniformMassValue = 1.0;
84 scene->addSceneObject(tissueObj);
86 auto capsule0Obj = std::make_shared<PbdObject>(
"capsule0");
89 auto rigidGeom = std::make_shared<Capsule>(Vec3d(0.0, 0.0, 0.0), 0.004, 0.01);
90 capsule0Obj->setVisualGeometry(rigidGeom);
91 capsule0Obj->setCollidingGeometry(rigidGeom);
92 capsule0Obj->setPhysicsGeometry(rigidGeom);
95 capsule0Obj->getVisualModel(0)->getRenderMaterial()->setColor(
Color(1.0, 0.0, 0.0));
97 capsule0Obj->getVisualModel(0)->getRenderMaterial()->setRoughness(0.5);
98 capsule0Obj->getVisualModel(0)->getRenderMaterial()->setMetalness(1.0);
99 capsule0Obj->getVisualModel(0)->getRenderMaterial()->setIsDynamicMesh(
false);
101 capsule0Obj->setDynamicalModel(pbdModel);
104 const Quatd orientation = Quatd::FromTwoVectors(Vec3d(0.0, 1.0, 0.0), Vec3d(0.0067, 0.0027, 0.0));
105 capsule0Obj->getPbdBody()->setRigid(
106 Vec3d(0.0085, 0.0037, 0.0),
109 Mat3d::Identity() * 0.005);
111 scene->addSceneObject(capsule0Obj);
113 auto collision0 = std::make_shared<PbdObjectCollision>(tissueObj, capsule0Obj);
114 collision0->setRigidBodyCompliance(0.00001);
115 scene->addInteraction(collision0);
117 auto lapTool = std::make_shared<PbdObject>(
"lapTool");
119 const double capsuleLength = 0.3;
120 auto toolGeom = std::make_shared<Capsule>(Vec3d(0.0, 0.0, 0.0),
121 0.002, capsuleLength, Quatd::FromTwoVectors(Vec3d(0.0, 1.0, 0.0), Vec3d(0.0, 0.0, 1.0)));
123 lapTool->setDynamicalModel(pbdModel);
124 lapTool->setPhysicsGeometry(toolGeom);
125 lapTool->setCollidingGeometry(toolGeom);
126 lapTool->setVisualGeometry(toolGeom);
128 std::shared_ptr<RenderMaterial> material = lapTool->getVisualModel(0)->getRenderMaterial();
129 material->setIsDynamicMesh(
false);
130 material->setMetalness(1.0);
131 material->setRoughness(0.2);
134 lapTool->getPbdBody()->setRigid(
135 Vec3d(0.0, 0.0, capsuleLength * 0.5),
137 Quatd::Identity(), Mat3d::Identity() * 10000.0);
140 controller->setControlledObject(lapTool);
141 controller->setLinearKs(1000000.0);
142 controller->setAngularKs(100000000.0);
143 controller->setForceScaling(0.003);
144 controller->setSmoothingKernelSize(15);
145 controller->setUseForceSmoothening(
true);
151 scene->addSceneObject(lapTool);
154 auto grasping = std::make_shared<PbdObjectGrasping>(tissueObj, lapTool);
155 grasping->setStiffness(0.05);
156 scene->addInteraction(grasping);
159 auto light = std::make_shared<DirectionalLight>();
160 light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
161 light->setIntensity(1.0);
162 scene->addLight(
"Light", light);
167 auto viewer = std::make_shared<VTKViewer>();
168 viewer->setVtkLoggerMode(VTKViewer::VTKLoggerMode::MUTE);
169 viewer->setActiveScene(scene);
170 viewer->setDebugAxesLength(0.01, 0.01, 0.01);
173 auto sceneManager = std::make_shared<SceneManager>();
174 sceneManager->setActiveScene(scene);
175 sceneManager->pause();
177 auto driver = std::make_shared<SimulationManager>();
178 driver->addModule(viewer);
179 driver->addModule(sceneManager);
180 driver->setDesiredDt(0.001);
182 #ifdef iMSTK_USE_HAPTICS 184 driver->addModule(hapticManager);
185 if (hapticManager->getTypeName() ==
"HaplyDeviceManager")
188 rightController->setTranslationOffset((*lapTool->getPbdBody()->vertices)[0] +
189 Vec3d(0.1, 0.0, -0.1));
192 std::shared_ptr<DeviceClient> deviceClient = hapticManager->makeDeviceClient();
194 connect<ButtonEvent>(deviceClient, &DeviceClient::buttonStateChanged,
197 if (e->m_button == 1 && e->m_buttonState == BUTTON_PRESSED)
199 LOG(INFO) <<
"Grasp!";
200 grasping->beginVertexGrasp(std::dynamic_pointer_cast<AnalyticalGeometry>(lapTool->getCollidingGeometry()));
203 connect<ButtonEvent>(deviceClient, &DeviceClient::buttonStateChanged,
206 if (e->m_button == 1 && e->m_buttonState == BUTTON_RELEASED)
208 LOG(INFO) <<
"Release!";
209 grasping->endGrasp();
213 auto deviceClient = std::make_shared<DummyClient>();
214 auto dummyClientMovement = lapTool->addComponent<
LambdaBehaviour>(
"DummyClientMovement");
215 dummyClientMovement->setUpdate([ = ](
const double&)
217 const Vec2d mousePos = viewer->getMouseDevice()->getPos();
218 const Vec3d worldPos = Vec3d(mousePos[0] - 0.5, mousePos[1] - 0.5, 0.0) * 0.1;
219 deviceClient->setPosition(worldPos);
221 connect<MouseEvent>(viewer->getMouseDevice(), &MouseDeviceClient::mouseButtonPress,
224 if (e->m_buttonId == 0)
226 LOG(INFO) <<
"Grasp!";
227 grasping->beginVertexGrasp(std::dynamic_pointer_cast<AnalyticalGeometry>(lapTool->getCollidingGeometry()));
230 connect<MouseEvent>(viewer->getMouseDevice(), &MouseDeviceClient::mouseButtonRelease,
233 if (e->m_buttonId == 0)
235 LOG(INFO) <<
"Release!";
236 grasping->endGrasp();
241 rightController->setDevice(deviceClient);
242 rightController->setTranslationOffset((*lapTool->getPbdBody()->vertices)[0]);
245 std::shared_ptr<Entity> mouseAndKeyControls =
246 SimulationUtils::createDefaultSceneControl(driver);
247 auto instructText = mouseAndKeyControls->getComponent<
TextVisualModel>();
248 instructText->
setText(instructText->getText() +
249 "\nPress Haptic Button or Click to grasp" +
250 "\nPress 1 to toggle gravity");
251 scene->addSceneObject(mouseAndKeyControls);
255 mouseControl->setEnabled(
true);
260 connect<KeyEvent>(viewer->getKeyboardDevice(), &KeyboardDeviceClient::keyPress, [&](
KeyEvent* e)
264 if (pbdModel->getConfig()->m_gravity[1] == 0.0)
266 pbdModel->getConfig()->m_gravity = Vec3d(0.0, -1.0, 0.0);
270 pbdModel->getConfig()->m_gravity = Vec3d::Zero();
273 else if (e->m_key ==
'u')
275 scene->advance(sceneManager->getDt());
This class uses the provided device to control the provided rigid object via virtual coupling...
static std::shared_ptr< DeviceManager > makeDeviceManager()
Attempts to create a new DeviceManager by whichever is default If multiple haptic managers are built ...
void setText(const std::string &text)
Text to be plotted.
Provides the information of a key event (press, release, & which key)
Provides the information of a mouse event, this includes button presses/releases and scrolling...
A SceneBehaviour that can update via a lambda function.
Controls the camera using trackball controls Left click rotate, middle click pan. ...
Renders text to the screen.
Physically based rendering.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.
void setController(std::shared_ptr< PbdObjectController > controller)
Get/Set the controller to display the device force of.
Displays virtual coupling force text in the top right.