iMSTK
Interactive Medical Simulation Toolkit
ReducedFEM.cpp
1 /*=========================================================================
2 
3  Library: iMSTK
4 
5  Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
6  & Imaging in Medicine, Rensselaer Polytechnic Institute.
7 
8  Licensed under the Apache License, Version 2.0 (the "License");
9  you may not use this file except in compliance with the License.
10  You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0.txt
13 
14  Unless required by applicable law or agreed to in writing, software
15  distributed under the License is distributed on an "AS IS" BASIS,
16  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  See the License for the specific language governing permissions and
18  limitations under the License.
19 
20 =========================================================================*/
21 
22 #include "imstkFeDeformableObject.h"
23 #include "imstkRenderMaterial.h"
24 #include "imstkBackwardEuler.h"
25 #include "imstkPlane.h"
26 #include "imstkTetrahedralMesh.h"
27 #include "imstkMeshIO.h"
28 #include "imstkMouseSceneControl.h"
29 #include "imstkNew.h"
30 #include "imstkOneToOneMap.h"
31 #include "imstkDirectionalLight.h"
32 #include "imstkCamera.h"
33 #include "imstkReducedStVKBodyModel.h"
34 #include "imstkReducedFeDeformableObject.h"
35 #include "imstkSurfaceMesh.h"
36 #include "imstkScene.h"
37 #include "imstkSceneManager.h"
38 #include "imstkVisualModel.h"
39 #include "imstkVTKViewer.h"
40 #include "imstkKeyboardSceneControl.h"
41 
42 using namespace imstk;
43 
44 std::shared_ptr<DynamicObject> createAndAddFEDeformable(std::shared_ptr<Scene> scene, std::shared_ptr<TetrahedralMesh> tetMesh);
45 
46 // enum to choose difference cases, currently asianDragon or heart
47 enum Geom
48 {
49  Dragon = 0,
50  Heart
51 };
52 
53 struct Input
54 {
55  std::string meshFileName;
56  std::string cubFileName;
57  std::string modesFileName;
58 };
59 
60 Geom geom = Dragon;
61 // const Geom geom = Heart;
62 Input input;
63 
68 int
69 main()
70 {
71  // Setup logger (write to file and stdout)
73 
74  if (geom == Dragon)
75  {
76  input.meshFileName = iMSTK_DATA_ROOT "asianDragon/asianDragon.veg";
77  input.cubFileName = iMSTK_DATA_ROOT "asianDragon/asianDragon.cub";
78  input.modesFileName = iMSTK_DATA_ROOT "asianDragon/asianDragon.URendering.float";
79  }
80  else if (geom == Heart)
81  {
82  input.meshFileName = iMSTK_DATA_ROOT "/heart/heart.veg";
83  input.cubFileName = iMSTK_DATA_ROOT "heart/heart.cub";
84  input.modesFileName = iMSTK_DATA_ROOT "heart/heart.URendering.float";
85  }
86 
87  // Construct the scene
88  imstkNew<SceneConfig> sceneConfig;
89  sceneConfig->taskParallelizationEnabled = false;
90  imstkNew<Scene> scene("ReducedFEM", sceneConfig);
91 
92  {
93  std::shared_ptr<Camera> cam = scene->getActiveCamera();
94  cam->setPosition(0.0, 2.0, -25.0);
95  cam->setFocalPoint(0.0, 0.0, 0.0);
96 
97  // Load a tetrahedral mesh
98  auto tetMesh = MeshIO::read<TetrahedralMesh>(input.meshFileName);
99  CHECK(tetMesh != nullptr) << "Could not read mesh from file.";
100 
101  // Scene object 1: fe-FeDeformableObject
102  std::shared_ptr<DynamicObject> deformableObj = createAndAddFEDeformable(scene, tetMesh);
103 
104  // Scene object 2: Plane
105  imstkNew<Plane> planeGeom;
106  planeGeom->setWidth(40);
107  planeGeom->setPosition(0, -6, 0);
108  imstkNew<CollidingObject> planeObj("Plane");
109  planeObj->setVisualGeometry(planeGeom);
110  planeObj->setCollidingGeometry(planeGeom);
111  scene->addSceneObject(planeObj);
112 
113  // Light
114  imstkNew<DirectionalLight> light("light");
115  light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
116  light->setIntensity(1);
117  scene->addLight(light);
118  }
119 
120  // Run the simulation
121  {
122  // Setup a viewer to render in its own thread
123  imstkNew<VTKViewer> viewer("Viewer 1");
124  viewer->setActiveScene(scene);
125 
126  // Setup a scene manager to advance the scene in its own thread
127  imstkNew<SceneManager> sceneManager("Scene Manager 1");
128  sceneManager->setActiveScene(scene);
129  viewer->addChildThread(sceneManager); // SceneManager will start/stop with viewer
130 
131  // Add mouse and keyboard controls to the viewer
132  {
133  imstkNew<MouseSceneControl> mouseControl(viewer->getMouseDevice());
134  mouseControl->setSceneManager(sceneManager);
135  viewer->addControl(mouseControl);
136 
137  imstkNew<KeyboardSceneControl> keyControl(viewer->getKeyboardDevice());
138  keyControl->setSceneManager(sceneManager);
139  keyControl->setViewer(viewer);
140  viewer->addControl(keyControl);
141  }
142 
143  // Start viewer running, scene as paused
144  sceneManager->requestStatus(ThreadStatus::Paused);
145  viewer->start();
146  }
147 
148  return 0;
149 }
150 
151 std::shared_ptr<DynamicObject>
152 createAndAddFEDeformable(std::shared_ptr<Scene> scene,
153  std::shared_ptr<TetrahedralMesh> tetMesh)
154 {
155  imstkNew<SurfaceMesh> surfMesh;
156  tetMesh->extractSurfaceMesh(surfMesh, true);
157 
158  // Configure dynamic model
159  imstkNew<ReducedStVK> dynaModel;
161  config->m_cubicPolynomialFilename = input.cubFileName;
162  config->m_modesFileName = input.modesFileName;
163  dynaModel->configure(config);
164  //dynaModel->configure(iMSTK_DATA_ROOT "/asianDragon/asianDragon.config");
165 
166  dynaModel->setTimeStepSizeType(TimeSteppingType::Fixed);
167  dynaModel->setModelGeometry(tetMesh);
168  imstkNew<BackwardEuler> timeIntegrator(0.01); // Create and add Backward Euler time integrator
169  dynaModel->setTimeIntegrator(timeIntegrator);
170 
172  mat->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
173  mat->setPointSize(10.);
174  mat->setLineWidth(4.);
175  mat->setEdgeColor(Color::Orange);
176  imstkNew<VisualModel> surfMeshModel(surfMesh.get());
177  surfMeshModel->setRenderMaterial(mat);
178 
179  // Scene object 1: Dragon
180  imstkNew<ReducedFeDeformableObject> deformableObj("Dragon");
181  deformableObj->addVisualModel(surfMeshModel);
182  deformableObj->setPhysicsGeometry(tetMesh);
183  // Map simulated geometry to visual
184  deformableObj->setPhysicsToVisualMap(std::make_shared<OneToOneMap>(tetMesh, surfMesh));
185  deformableObj->setDynamicalModel(dynaModel);
186  scene->addSceneObject(deformableObj);
187 
188  return deformableObj;
189 }
virtual void setTimeStepSizeType(const TimeSteppingType type)
Get/Set the type of approach used to update the time step size after every frame. ...
Compound Geometry.
void configure(const std::string &configFileName)
Configure the force model from external file.
const std::shared_ptr< T > & get() const
Returns const ref to STL smart pointer.
Definition: imstkNew.h:56
void setTimeIntegrator(std::shared_ptr< TimeIntegrator > timeIntegrator)
Set/Get time integrator.
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
Definition: imstkNew.h:29
void setModelGeometry(std::shared_ptr< Geometry > geometry)
Sets the model geometry.
void setPosition(const Vec3d p)
Set the local position.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.