7 #include "imstkCamera.h" 8 #include "imstkCapsule.h" 9 #include "imstkDeviceManager.h" 10 #include "imstkDeviceManagerFactory.h" 11 #include "imstkDirectionalLight.h" 12 #include "imstkGeometryUtilities.h" 13 #include "imstkKeyboardDeviceClient.h" 14 #include "imstkKeyboardSceneControl.h" 15 #include "imstkLaparoscopicToolController.h" 16 #include "imstkMeshIO.h" 17 #include "imstkMouseDeviceClient.h" 18 #include "imstkMouseSceneControl.h" 19 #include "imstkPbdModel.h" 20 #include "imstkPbdModelConfig.h" 21 #include "imstkPbdObject.h" 22 #include "imstkPbdObjectCollision.h" 23 #include "imstkPbdObjectGrasping.h" 24 #include "imstkPointwiseMap.h" 25 #include "imstkRenderMaterial.h" 26 #include "imstkScene.h" 27 #include "imstkSceneManager.h" 28 #include "imstkSimulationManager.h" 29 #include "imstkSimulationUtils.h" 30 #include "imstkVisualModel.h" 31 #include "imstkVTKViewer.h" 33 using namespace imstk;
39 setSphereTexCoords(std::shared_ptr<SurfaceMesh> surfMesh,
const double uvScale)
42 surfMesh->computeBoundingBox(min, max);
43 const Vec3d size = max - min;
44 const Vec3d center = (max + min) * 0.5;
46 const double radius = (size * 0.5).norm();
48 auto uvCoordsPtr = std::make_shared<VecDataArray<float, 2>>(surfMesh->getNumVertices());
50 for (
int i = 0; i < surfMesh->getNumVertices(); i++)
52 Vec3d vertex = surfMesh->getVertexPosition(i) - center;
55 const double theta = asin(vertex[0] / radius);
56 const double phi = atan2(vertex[1], vertex[2]);
57 uvCoords[i] = Vec2f(phi / (PI * 2.0) + 0.5, theta / (PI * 2.0) + 0.5) * uvScale;
59 surfMesh->setVertexTCoords(
"tcoords", uvCoordsPtr);
69 static std::shared_ptr<PbdObject>
70 makeTissueObj(
const std::string& name,
71 const Vec3d& size,
const Vec3i& dim,
const Vec3d& center)
75 std::shared_ptr<SurfaceMesh> surfMesh = tissueMesh->extractSurfaceMesh();
76 setSphereTexCoords(surfMesh, 6.0);
79 auto pbdParams = std::make_shared<PbdModelConfig>();
80 const bool useFem =
true;
85 pbdParams->m_femParams->m_YoungModulus = 40000.0;
86 pbdParams->m_femParams->m_PoissonRatio = 0.48;
93 pbdParams->enableFemConstraint(PbdFemConstraint::MaterialType::NeoHookean);
97 pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, 100000.0);
98 pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Volume, 100000.0);
100 pbdParams->m_doPartitioning =
false;
101 pbdParams->m_dt = 0.001;
102 pbdParams->m_iterations = 5;
110 pbdParams->m_gravity = Vec3d::Zero();
111 pbdParams->m_linearDampingCoeff = 0.03;
114 auto pbdModel = std::make_shared<PbdModel>();
115 pbdModel->configure(pbdParams);
118 auto material = std::make_shared<RenderMaterial>();
119 material->setDisplayMode(RenderMaterial::DisplayMode::Surface);
121 material->addTexture(std::make_shared<Texture>(iMSTK_DATA_ROOT
"/textures/fleshDiffuse.jpg",
122 Texture::Type::Diffuse));
123 material->addTexture(std::make_shared<Texture>(iMSTK_DATA_ROOT
"/textures/fleshNormal.jpg",
124 Texture::Type::Normal));
125 material->addTexture(std::make_shared<Texture>(iMSTK_DATA_ROOT
"/textures/fleshORM.jpg",
126 Texture::Type::ORM));
127 material->setNormalStrength(0.3);
130 auto visualModel = std::make_shared<VisualModel>();
131 visualModel->setGeometry(surfMesh);
132 visualModel->setRenderMaterial(material);
135 auto tissueObj = std::make_shared<PbdObject>(name);
136 tissueObj->addVisualModel(visualModel);
137 tissueObj->setPhysicsGeometry(tissueMesh);
138 tissueObj->setCollidingGeometry(surfMesh);
139 tissueObj->setPhysicsToCollidingMap(std::make_shared<PointwiseMap>(tissueMesh, surfMesh));
140 tissueObj->setDynamicalModel(pbdModel);
141 tissueObj->getPbdBody()->uniformMassValue = 100.0;
143 for (
int z = 0; z < dim[2]; z++)
145 for (
int y = 0; y < dim[1]; y++)
147 for (
int x = 0; x < dim[0]; x++)
149 if (x == 0 || x == dim[0] - 1 )
151 tissueObj->getPbdBody()->fixedNodeIds.push_back(x + dim[0] * (y + dim[1] * z));
171 auto scene = std::make_shared<Scene>(
"PbdTissueGrasping");
172 scene->getActiveCamera()->setPosition(0.001, 0.05, 0.15);
173 scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
174 scene->getActiveCamera()->setViewUp(0.0, 0.96, -0.28);
176 auto geomShaft = std::make_shared<Capsule>();
177 geomShaft->setLength(1.0);
178 geomShaft->setRadius(0.005);
179 geomShaft->setOrientation(Quatd(Rotd(PI_2, Vec3d(1.0, 0.0, 0.0))));
180 geomShaft->setTranslation(Vec3d(0.0, 0.0, 0.5));
181 auto objShaft = std::make_shared<CollidingObject>(
"objShaft");
182 objShaft->setVisualGeometry(MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/Surgical Instruments/LapTool/pivot.obj"));
183 objShaft->setCollidingGeometry(geomShaft);
184 scene->addSceneObject(objShaft);
186 auto geomUpperJaw = std::make_shared<Capsule>();
187 geomUpperJaw->setLength(0.05);
188 geomUpperJaw->setTranslation(Vec3d(0.0, 0.0013, -0.016));
189 geomUpperJaw->setRadius(0.004);
190 geomUpperJaw->setOrientation(Quatd(Rotd(PI_2, Vec3d(1.0, 0.0, 0.0))));
191 auto objUpperJaw = std::make_shared<CollidingObject>(
"objUpperJaw");
192 objUpperJaw->setVisualGeometry(MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/Surgical Instruments/LapTool/upper.obj"));
193 objUpperJaw->setCollidingGeometry(geomUpperJaw);
194 scene->addSceneObject(objUpperJaw);
196 auto geomLowerJaw = std::make_shared<Capsule>();
197 geomLowerJaw->setLength(0.05);
198 geomLowerJaw->setTranslation(Vec3d(0.0, -0.0013, -0.016));
199 geomLowerJaw->setRadius(0.004);
200 geomLowerJaw->setOrientation(Quatd(Rotd(PI_2, Vec3d(1.0, 0.0, 0.0))));
201 auto objLowerJaw = std::make_shared<CollidingObject>(
"objLowerJaw");
202 objLowerJaw->setVisualGeometry(MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT
"/Surgical Instruments/LapTool/lower.obj"));
203 objLowerJaw->setCollidingGeometry(geomLowerJaw);
204 scene->addSceneObject(objLowerJaw);
206 auto pickGeom = std::make_shared<Capsule>();
207 pickGeom->setLength(0.05);
208 pickGeom->setTranslation(Vec3d(0.0, 0.0, -0.016));
209 pickGeom->setRadius(0.006);
210 pickGeom->setOrientation(Quatd(Rotd(PI_2, Vec3d(1.0, 0.0, 0.0))));
213 std::shared_ptr<PbdObject> tissueObj = makeTissueObj(
"PbdTissue",
214 Vec3d(0.1, 0.025, 0.1), Vec3i(6, 3, 6), Vec3d(0.0, -0.03, 0.0));
215 scene->addSceneObject(tissueObj);
219 std::shared_ptr<DeviceClient> deviceClient = hapticManager->makeDeviceClient();
222 auto controller = std::make_shared<LaparoscopicToolController>();
223 controller->setParts(objShaft, objUpperJaw, objLowerJaw, pickGeom);
224 controller->setDevice(deviceClient);
225 controller->setJawAngleChange(1.0);
226 scene->addControl(controller);
229 auto upperJawCollision = std::make_shared<PbdObjectCollision>(tissueObj, objUpperJaw);
230 auto lowerJawCollision = std::make_shared<PbdObjectCollision>(tissueObj, objLowerJaw);
231 scene->addInteraction(upperJawCollision);
232 scene->addInteraction(lowerJawCollision);
235 auto jawPicking = std::make_shared<PbdObjectGrasping>(tissueObj);
237 jawPicking->setGeometryToPick(tissueObj->getVisualGeometry(),
238 std::dynamic_pointer_cast<
PointwiseMap>(tissueObj->getPhysicsToCollidingMap()));
239 scene->addInteraction(jawPicking);
242 auto light = std::make_shared<DirectionalLight>();
243 light->setFocalPoint(Vec3d(0.0, -1.0, -1.0));
244 light->setIntensity(1.0);
245 scene->addLight(
"light", light);
250 auto viewer = std::make_shared<VTKViewer>();
251 viewer->setActiveScene(scene);
252 viewer->setDebugAxesLength(0.01, 0.01, 0.01);
255 auto sceneManager = std::make_shared<SceneManager>();
256 sceneManager->setActiveScene(scene);
257 sceneManager->pause();
259 auto driver = std::make_shared<SimulationManager>();
260 driver->addModule(hapticManager);
261 driver->addModule(viewer);
262 driver->addModule(sceneManager);
263 driver->setDesiredDt(0.001);
266 std::shared_ptr<Entity> mouseAndKeyControls =
267 SimulationUtils::createDefaultSceneControl(driver);
268 scene->addSceneObject(mouseAndKeyControls);
270 connect<Event>(sceneManager, &SceneManager::preUpdate,
274 tissueObj->getPbdModel()->getConfig()->m_dt = sceneManager->getDt();
277 connect<Event>(controller, &LaparoscopicToolController::JawClosed,
280 LOG(INFO) <<
"Jaw Closed!";
282 upperJawCollision->setEnabled(
false);
283 lowerJawCollision->setEnabled(
false);
284 jawPicking->beginRayPointGrasp(pickGeom, pickGeom->getPosition(),
285 -pickGeom->getOrientation().toRotationMatrix().col(1), 0.03);
288 connect<Event>(controller, &LaparoscopicToolController::JawOpened,
291 LOG(INFO) <<
"Jaw Opened!";
293 upperJawCollision->setEnabled(
true);
294 lowerJawCollision->setEnabled(
true);
295 jawPicking->endGrasp();
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
std::shared_ptr< TetrahedralMesh > toTetGrid(const Vec3d ¢er, const Vec3d &size, const Vec3i &divisions, const Quatd orientation=Quatd::Identity())
Produces a tetrahedral grid given the OrientedBox with the given divisions.
Simple dynamic array implementation that also supports event posting and viewing/facade.
static std::shared_ptr< DeviceManager > makeDeviceManager()
Attempts to create a new DeviceManager by whichever is default If multiple haptic managers are built ...
PointwiseMap can compute & apply a mapping between parent and child PointSet geometries.
Physically based rendering.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.