7 #include "imstkCamera.h" 8 #include "imstkControllerForceText.h" 9 #include "imstkDirectionalLight.h" 10 #include "imstkGeometryUtilities.h" 11 #include "imstkImageData.h" 12 #include "imstkKeyboardDeviceClient.h" 13 #include "imstkKeyboardSceneControl.h" 14 #include "imstkMeshIO.h" 15 #include "imstkMouseDeviceClient.h" 16 #include "imstkMouseSceneControl.h" 17 #include "imstkObjectControllerGhost.h" 18 #include "imstkPbdCollisionHandling.h" 19 #include "imstkPbdModel.h" 20 #include "imstkPbdModelConfig.h" 21 #include "imstkPbdObject.h" 22 #include "imstkPbdObjectCollision.h" 23 #include "imstkPbdObjectController.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 "imstkTextVisualModel.h" 31 #include "imstkVTKViewer.h" 33 #ifdef iMSTK_USE_HAPTICS 34 #include "imstkDeviceManager.h" 35 #include "imstkDeviceManagerFactory.h" 37 #include "imstkDummyClient.h" 40 using namespace imstk;
46 setSphereTexCoords(std::shared_ptr<SurfaceMesh> surfMesh,
const double uvScale)
49 surfMesh->computeBoundingBox(min, max);
50 const Vec3d size = max - min;
51 const Vec3d center = (max + min) * 0.5;
53 const double radius = (size * 0.5).norm();
55 auto uvCoordsPtr = std::make_shared<VecDataArray<float, 2>>(surfMesh->getNumVertices());
57 for (
int i = 0; i < surfMesh->getNumVertices(); i++)
59 Vec3d vertex = surfMesh->getVertexPosition(i) - center;
62 const double theta = asin(vertex[0] / radius);
63 const double phi = atan2(vertex[1], vertex[2]);
64 uvCoords[i] = Vec2f(phi / (PI * 2.0) + 0.5, theta / (PI * 2.0) + 0.5) * uvScale;
66 surfMesh->setVertexTCoords(
"tcoords", uvCoordsPtr);
77 static std::shared_ptr<PbdObject>
78 makeTissueObj(
const std::string& name,
79 const Vec3d& size,
const Vec3i& dim,
const Vec3d& center,
80 std::shared_ptr<PbdModel> model)
84 std::shared_ptr<SurfaceMesh> surfMesh = tissueMesh->extractSurfaceMesh();
85 setSphereTexCoords(surfMesh, 4.0);
88 auto material = std::make_shared<RenderMaterial>();
90 auto diffuseTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshDiffuse.jpg");
91 material->addTexture(std::make_shared<Texture>(diffuseTex, Texture::Type::Diffuse));
92 auto normalTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshNormal.jpg");
93 material->addTexture(std::make_shared<Texture>(normalTex, Texture::Type::Normal));
94 auto ormTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshORM.jpg");
95 material->addTexture(std::make_shared<Texture>(ormTex, Texture::Type::ORM));
98 auto visualModel = std::make_shared<VisualModel>();
99 visualModel->setGeometry(surfMesh);
100 visualModel->setRenderMaterial(material);
103 auto normalsVisualModel = std::make_shared<VisualModel>();
104 normalsVisualModel->setGeometry(surfMesh);
105 normalsVisualModel->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::SurfaceNormals);
106 normalsVisualModel->getRenderMaterial()->setPointSize(0.5);
109 auto tissueObj = std::make_shared<PbdObject>(name);
110 tissueObj->addVisualModel(visualModel);
111 tissueObj->addVisualModel(normalsVisualModel);
112 tissueObj->setPhysicsGeometry(tissueMesh);
113 tissueObj->setCollidingGeometry(surfMesh);
114 tissueObj->setPhysicsToCollidingMap(std::make_shared<PointwiseMap>(tissueMesh, surfMesh));
115 tissueObj->setDynamicalModel(model);
116 tissueObj->getPbdBody()->uniformMassValue = 0.05;
118 for (
int z = 0; z < dim[2]; z++)
120 for (
int y = 0; y < dim[1]; y++)
122 for (
int x = 0; x < dim[0]; x++)
124 if (x == 0 || x == dim[0] - 1 )
126 tissueObj->getPbdBody()->fixedNodeIds.push_back(x + dim[0] * (y + dim[1] * z));
131 model->getConfig()->m_femParams->m_YoungModulus = 50.0;
132 model->getConfig()->m_femParams->m_PoissonRatio = 0.4;
133 model->getConfig()->enableFemConstraint(PbdFemConstraint::MaterialType::NeoHookean);
134 model->getConfig()->setBodyDamping(tissueObj->getPbdBody()->bodyHandle, 0.001);
143 static std::shared_ptr<PbdObject>
144 makeToolObj(std::shared_ptr<PbdModel> model)
146 auto toolGeometry = std::make_shared<LineMesh>();
152 auto toolObj = std::make_shared<PbdObject>(
"Tool");
153 toolObj->setVisualGeometry(toolGeometry);
154 toolObj->setCollidingGeometry(toolGeometry);
155 toolObj->setPhysicsGeometry(toolGeometry);
156 toolObj->setDynamicalModel(model);
157 toolObj->getVisualModel(0)->getRenderMaterial()->setColor(Color::Blue);
158 toolObj->getVisualModel(0)->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
159 toolObj->getVisualModel(0)->getRenderMaterial()->setBackFaceCulling(
false);
160 toolObj->getVisualModel(0)->getRenderMaterial()->setLineWidth(10.0);
162 model->getConfig()->setBodyDamping(toolObj->getPbdBody()->bodyHandle, 0.05, 0.0);
164 toolObj->getPbdBody()->setRigid(Vec3d(0.0, 0.8, 0.0),
167 Mat3d::Identity() * 10.0);
171 controller->setControlledObject(toolObj);
172 controller->setLinearKs(5000.0);
173 controller->setAngularKs(10000.0);
174 controller->setUseCritDamping(
true);
175 controller->setForceScaling(0.0025);
176 controller->setUseForceSmoothening(
true);
180 controllerGhost->setController(controller);
199 auto scene = std::make_shared<Scene>(
"PbdTissueContact");
200 scene->getActiveCamera()->setPosition(0.12, 4.51, 16.51);
201 scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
202 scene->getActiveCamera()->setViewUp(0.0, 0.96, -0.28);
205 auto pbdModel = std::make_shared<PbdModel>();
206 pbdModel->getConfig()->m_doPartitioning =
false;
207 pbdModel->getConfig()->m_gravity = Vec3d(0.0, 0.0, 0.0);
208 pbdModel->getConfig()->m_dt = 0.05;
209 pbdModel->getConfig()->m_iterations = 5;
212 std::shared_ptr<PbdObject> tissueObj = makeTissueObj(
"Tissue",
213 Vec3d(8.0, 2.0, 8.0), Vec3i(6, 5, 6), Vec3d(0.0, -1.0, 0.0), pbdModel);
214 scene->addSceneObject(tissueObj);
217 std::shared_ptr<PbdObject> toolObj = makeToolObj(pbdModel);
218 scene->addSceneObject(toolObj);
221 auto collision = std::make_shared<PbdObjectCollision>(tissueObj, toolObj);
223 scene->addInteraction(collision);
226 auto light = std::make_shared<DirectionalLight>();
227 light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
228 light->setIntensity(1.0);
229 scene->addLight(
"Light", light);
234 auto viewer = std::make_shared<VTKViewer>();
235 viewer->setActiveScene(scene);
236 viewer->setVtkLoggerMode(VTKViewer::VTKLoggerMode::MUTE);
239 auto sceneManager = std::make_shared<SceneManager>();
240 sceneManager->setActiveScene(scene);
241 sceneManager->pause();
243 auto driver = std::make_shared<SimulationManager>();
244 driver->addModule(viewer);
245 driver->addModule(sceneManager);
246 driver->setDesiredDt(0.001);
249 #ifdef iMSTK_USE_HAPTICS 252 std::shared_ptr<DeviceClient> deviceClient = hapticManager->makeDeviceClient();
253 driver->addModule(hapticManager);
255 controller->setTranslationScaling(50.0);
256 if (hapticManager->getTypeName() ==
"HaplyDeviceManager")
258 controller->setTranslationOffset(Vec3d(5.0, -5.0, 0.0));
261 auto deviceClient = std::make_shared<DummyClient>();
262 connect<Event>(sceneManager, &SceneManager::postUpdate, [&](
Event*)
264 const Vec2d mousePos = viewer->getMouseDevice()->getPos();
265 const Vec3d worldPos = Vec3d(mousePos[0] - 0.5, mousePos[1] - 0.5, 0.0) * 10.0;
267 deviceClient->setPosition(worldPos);
270 controller->setTranslationScaling(1.0);
272 controller->setDevice(deviceClient);
274 connect<Event>(sceneManager, &SceneManager::preUpdate, [&](
Event*)
277 pbdModel->getConfig()->m_dt = sceneManager->getDt();
281 std::shared_ptr<Entity> mouseAndKeyControls =
282 SimulationUtils::createDefaultSceneControl(driver);
286 controllerForceTxt->setCollision(collision);
287 scene->addSceneObject(mouseAndKeyControls);
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
This class uses the provided device to control the provided rigid object via virtual coupling...
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 ...
A behaviour that renders a second copy of the controlled object at a lower opacity in the physical po...
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.