imstkSimulationManager.cpp 10.2 KB
Newer Older
1
2
/*=========================================================================

Alexis Girault's avatar
Alexis Girault committed
3
   Library: iMSTK
4

Alexis Girault's avatar
Alexis Girault committed
5
6
   Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
   & Imaging in Medicine, Rensselaer Polytechnic Institute.
7

Alexis Girault's avatar
Alexis Girault committed
8
9
10
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
11
12
13

      http://www.apache.org/licenses/LICENSE-2.0.txt

Alexis Girault's avatar
Alexis Girault committed
14
15
16
17
18
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
19

20
=========================================================================*/
21

22
23
#include "imstkSimulationManager.h"

24
25
#include <string>

26
27
#include "g3log/g3log.hpp"

28
29
30
namespace imstk
{

31
32
33
34
35
36
37
const
SimulationStatus& SimulationManager::getStatus() const
{
    return m_status;
}

bool
Alexis Girault's avatar
Alexis Girault committed
38
SimulationManager::isSceneRegistered(std::string sceneName) const
39
{
40
    return m_sceneManagerMap.find(sceneName) != m_sceneManagerMap.end();
41
42
}

43
44
std::shared_ptr<SceneManager>
SimulationManager::getSceneManager(std::string sceneName) const
45
46
47
{
    if (!this->isSceneRegistered(sceneName))
    {
48
        LOG(WARNING) << "No scene named '" << sceneName
49
                     << "' was registered in this simulation";
50
51
52
        return nullptr;
    }

53
54
55
56
57
58
59
60
    return m_sceneManagerMap.at(sceneName);
}

std::shared_ptr<Scene>
SimulationManager::getScene(std::string sceneName) const
{
    auto sceneManager = this->getSceneManager(sceneName);
    return sceneManager ? sceneManager->getScene() : nullptr;
61
62
}

63
64
65
66
67
68
std::shared_ptr<Scene>
SimulationManager::getCurrentScene() const
{
    return this->getScene(m_currentSceneName);
}

69
70
71
72
73
std::shared_ptr<Scene>
SimulationManager::createNewScene(std::string newSceneName)
{
    if (this->isSceneRegistered(newSceneName))
    {
74
        LOG(WARNING) << "Can not create new scene: '" << newSceneName
75
76
                     << "' is already registered in this simulation\n"
                     << "You can create a new scene using an unique name";
77
78
79
        return nullptr;
    }

80
81
    auto newScene = std::make_shared<Scene>(newSceneName);
    m_sceneManagerMap[newSceneName] = std::make_shared<SceneManager>(newScene);
82
    LOG(INFO) << "New scene added: " << newSceneName;
83
    return newScene;
84
85
86
87
88
}

std::shared_ptr<Scene>
SimulationManager::createNewScene()
{
89
    int id = (int)m_sceneManagerMap.size() + 1;
90
91
92
93
94
95
    std::string newSceneName = "Scene_" + std::to_string(id);

    return this->createNewScene(newSceneName);
}

void
96
SimulationManager::addScene(std::shared_ptr<Scene> newScene)
97
98
99
100
101
{
    std::string newSceneName = newScene->getName();

    if (this->isSceneRegistered(newSceneName))
    {
102
        LOG(WARNING) << "Can not add scene: '" << newSceneName
103
104
                     << "' is already registered in this simulation\n"
                     << "Set this scene name to a unique name first";
105
106
107
        return;
    }

108
    m_sceneManagerMap[newSceneName] = std::make_shared<SceneManager>(newScene);
109
    LOG(INFO) << "Scene added: " << newSceneName;
110
111
112
113
114
115
116
}

void
SimulationManager::removeScene(std::string sceneName)
{
    if (!this->isSceneRegistered(sceneName))
    {
117
        LOG(WARNING) << "No scene named '" << sceneName
118
                     << "' was registered in this simulation";
119
120
121
        return;
    }

122
    m_sceneManagerMap.erase(sceneName);
123
    LOG(INFO) << "Scene removed: " << sceneName;
124
125
}

126
bool
Alexis Girault's avatar
Alexis Girault committed
127
SimulationManager::isModuleRegistered(std::string moduleName) const
128
{
Alexis Girault's avatar
Alexis Girault committed
129
    return m_modulesMap.find(moduleName) != m_modulesMap.end();
130
131
}

Alexis Girault's avatar
Alexis Girault committed
132
133
std::shared_ptr<Module>
SimulationManager::getModule(std::string moduleName) const
134
{
Alexis Girault's avatar
Alexis Girault committed
135
    if (!this->isModuleRegistered(moduleName))
136
    {
Alexis Girault's avatar
Alexis Girault committed
137
        LOG(WARNING) << "No module named '" << moduleName
138
139
140
141
                     << "' was registered in this simulation";
        return nullptr;
    }

Alexis Girault's avatar
Alexis Girault committed
142
    return m_modulesMap.at(moduleName);
143
}
144

145
void
Alexis Girault's avatar
Alexis Girault committed
146
SimulationManager::addModule(std::shared_ptr<Module> newModule)
147
{
Alexis Girault's avatar
Alexis Girault committed
148
    std::string newModuleName = newModule->getName();
149

Alexis Girault's avatar
Alexis Girault committed
150
    if (this->isModuleRegistered(newModuleName))
151
    {
Alexis Girault's avatar
Alexis Girault committed
152
153
        LOG(WARNING) << "Can not addmodule: '" << newModuleName
                     << "' is already registered in this simulation\n";
154
155
156
        return;
    }

Alexis Girault's avatar
Alexis Girault committed
157
158
    m_modulesMap[newModuleName] = newModule;
    LOG(INFO) << "Module added: " << newModuleName;
159
160
161
}

void
Alexis Girault's avatar
Alexis Girault committed
162
SimulationManager::removeModule(std::string moduleName)
163
{
Alexis Girault's avatar
Alexis Girault committed
164
    if (!this->isModuleRegistered(moduleName))
165
    {
Alexis Girault's avatar
Alexis Girault committed
166
        LOG(WARNING) << "No module named '" << moduleName
167
168
169
170
                     << "' was registered in this simulation";
        return;
    }

Alexis Girault's avatar
Alexis Girault committed
171
172
    m_modulesMap.erase(moduleName);
    LOG(INFO) << "Module removed: " << moduleName;
173
174
}

175
std::shared_ptr<VTKViewer>
176
177
178
179
180
SimulationManager::getViewer() const
{
    return m_viewer;
}

181
182
183
184
185
186
void
SimulationManager::setCurrentScene(std::shared_ptr<Scene> scene, bool unloadCurrentScene)
{
    setCurrentScene(scene->getName(), unloadCurrentScene);
}

187
void
188
SimulationManager::setCurrentScene(std::string newSceneName, bool unloadCurrentScene)
189
{
190
    LOG(INFO) << "Setting current scene";
191
192
193

    if (newSceneName == m_currentSceneName)
    {
194
        LOG(WARNING) << "Scene '" << newSceneName << "' is already current";
195
196
197
198
199
200
        return;
    }

    std::shared_ptr<Scene> newScene = this->getScene(newSceneName);
    if (!newScene)
    {
201
        LOG(WARNING) << "Can not find scene";
202
203
204
        return;
    }

205
    // Update viewer scene
Alexis Girault's avatar
Alexis Girault committed
206
    m_viewer->setCurrentScene(newScene);
207
208
209
210
211
212
213
214
215
216

    // If not yet rendering: update current scene and return
    if(!m_viewer->isRendering())
    {
        m_currentSceneName = newSceneName;
        return;
    }

    // If rendering and simulation not active:
    // render scene in debug, update current scene, and return
217
218
    if (m_status == SimulationStatus::INACTIVE)
    {
219
        m_viewer->setRenderingMode(VTKRenderer::Mode::DEBUG);
220
221
222
        m_currentSceneName = newSceneName;
        return;
    }
223
224
225

    // If rendering and simulation active:
    // render scene in simulation mode, and update simulation
226
    m_viewer->setRenderingMode(VTKRenderer::Mode::SIMULATION);
227

228
    // Stop/Pause running scene
229
    auto oldSceneManager = m_sceneManagerMap.at(m_currentSceneName);
230
231
    if (unloadCurrentScene)
    {
232
        LOG(INFO) << "Unloading '" << m_currentSceneName << "'";
233
        oldSceneManager->end();
234
235
236
237
        m_threadMap.at(m_currentSceneName).join();
    }
    else
    {
238
        oldSceneManager->pause();
239
240
    }

241
    // Start/Run new scene
242
243
    auto newSceneManager = m_sceneManagerMap.at(newSceneName);
    if (newSceneManager->getStatus() == ModuleStatus::INACTIVE)
244
    {
245
        this->startModuleInNewThread(newSceneManager);
246
    }
247
    else if (newSceneManager->getStatus() == ModuleStatus::PAUSED)
248
    {
249
        newSceneManager->run();
250
251
252
253
    }
    m_currentSceneName = newSceneName;
}

254
255
256
257
258
void
SimulationManager::startSimulation(bool debug)
{
    if (m_status != SimulationStatus::INACTIVE)
    {
259
        LOG(WARNING) << "Simulation already active";
260
261
262
        return;
    }

263
    std::shared_ptr<Scene> startingScene = this->getCurrentScene();
264
265
    if (!startingScene)
    {
266
        LOG(WARNING) << "Simulation canceled";
267
268
269
        return;
    }

270
271
    auto startingSceneManager = m_sceneManagerMap.at(m_currentSceneName);
    if (startingSceneManager->getStatus() != ModuleStatus::INACTIVE)
272
    {
273
        LOG(WARNING) << "Scene '" << m_currentSceneName << "' is already active";
274
275
276
        return;
    }

277
    // Simulation
278
279
    if( !debug )
    {
280
        LOG(INFO) << "Starting simulation";
281
        m_viewer->setRenderingMode(VTKRenderer::Mode::SIMULATION);
282

Alexis Girault's avatar
Alexis Girault committed
283
284
        // Start modules
        for(const auto& pair : m_modulesMap)
285
286
287
288
289
        {
            this->startModuleInNewThread(pair.second);
        }

        // Start scene
290
        this->startModuleInNewThread(startingSceneManager);
291

292
293
        m_status = SimulationStatus::RUNNING;
    }
294
    // Debug
295
296
    else
    {
297
        m_viewer->setRenderingMode(VTKRenderer::Mode::DEBUG);
298
    }
299
300
301
302

    // Start Rendering
    if( !m_viewer->isRendering() )
    {
303
        LOG(INFO) << "Starting viewer";
304
        m_viewer->startRenderingLoop();
305
        LOG(INFO) << "Closing viewer";
306
307
308
309
310
311
312
313
314

        // End simulation if active when loop exits
        if (m_status != SimulationStatus::INACTIVE)
        {
            this->endSimulation();
        }
    }
}

315
316
317
void
SimulationManager::runSimulation()
{
318
    LOG(INFO) << "Running simulation";
319
320
321

    if (m_status != SimulationStatus::PAUSED)
    {
322
        LOG(WARNING) << "Simulation not paused, can not run";
323
324
325
        return;
    }

326
    // Run scene
327
    m_sceneManagerMap.at(m_currentSceneName)->run();
328

Alexis Girault's avatar
Alexis Girault committed
329
330
    // Run modules
    for(const auto& pair : m_modulesMap)
331
332
333
334
    {
        (pair.second)->run();
    }

335
    // Update simulation status
336
337
338
339
340
341
    m_status = SimulationStatus::RUNNING;
}

void
SimulationManager::pauseSimulation()
{
342
    LOG(INFO) << "Pausing simulation";
343
344
345

    if (m_status != SimulationStatus::RUNNING)
    {
346
        LOG(WARNING) << "Simulation not running, can not pause";
347
348
349
350
        return;
    }

    // Pause scene
351
    m_sceneManagerMap.at(m_currentSceneName)->pause();
352

Alexis Girault's avatar
Alexis Girault committed
353
354
    // Pause modules
    for(const auto& pair : m_modulesMap)
355
356
357
358
    {
        (pair.second)->pause();
    }

359
360
361
362
363
364
365
    // Update simulation status
    m_status = SimulationStatus::PAUSED;
}

void
SimulationManager::endSimulation()
{
366
    LOG(INFO) << "Ending simulation";
367
368
369
370

    if ((m_status != SimulationStatus::RUNNING) &&
        (m_status != SimulationStatus::PAUSED))
    {
371
        LOG(WARNING) << "Simulation already terminated";
372
373
374
        return;
    }

375
    // Update Renderer
376
    m_viewer->setRenderingMode(VTKRenderer::Mode::DEBUG);
377

Alexis Girault's avatar
Alexis Girault committed
378
379
    // End modules
    for(const auto& pair : m_modulesMap)
380
381
382
383
384
    {
        (pair.second)->end();
        m_threadMap.at(pair.first).join();
    }

385
    // End all scenes
386
    for (auto pair : m_sceneManagerMap)
387
388
    {
        std::string  sceneName   = pair.first;
389
        ModuleStatus sceneStatus = pair.second->getStatus();
390
391
392

        if (sceneStatus != ModuleStatus::INACTIVE)
        {
393
            m_sceneManagerMap.at(sceneName)->end();
394
395
396
397
398
399
400
401
402
403
404
405
406
            m_threadMap.at(sceneName).join();
        }
    }

    // Update simulation status
    m_status = SimulationStatus::INACTIVE;
}

void
SimulationManager::startModuleInNewThread(std::shared_ptr<Module>module)
{
    m_threadMap[module->getName()] = std::thread([module] { module->start(); });
}
407

Alexis Girault's avatar
Alexis Girault committed
408
} // imstk