iMSTK
Interactive Medical Simulation Toolkit
imstkVTKRenderer.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkVTKRenderer.h"
8 #include "imstkCamera.h"
9 #include "imstkDirectionalLight.h"
10 #include "imstkPointLight.h"
11 #include "imstkSpotLight.h"
12 #include "imstkLogger.h"
13 #include "imstkScene.h"
14 #include "imstkSceneObject.h"
15 #include "imstkTextureManager.h"
16 #include "imstkVisualModel.h"
17 #include "imstkVTKSurfaceMeshRenderDelegate.h"
18 
19 #include <vtkCameraActor.h>
20 #include <vtkCullerCollection.h>
21 #include <vtkLight.h>
22 #include <vtkLightActor.h>
23 
24 #include <vtkAxis.h>
25 #include <vtkChartXY.h>
26 #include <vtkContextActor.h>
27 #include <vtkContextScene.h>
28 #include <vtkDoubleArray.h>
29 #include <vtkPlotBar.h>
30 #include <vtkStringArray.h>
31 #include <vtkTable.h>
32 #include <vtkTextProperty.h>
33 
34 #include <vtkCameraPass.h>
35 #include <vtkOpenVRCamera.h>
36 #include <vtkOpenVRRenderer.h>
37 #include <vtkRenderPassCollection.h>
38 #include <vtkRenderStepsPass.h>
39 #include <vtkSequencePass.h>
40 #include <vtkSSAOPass.h>
41 #include <vtkProperty.h>
42 
43 namespace imstk
44 {
45 VTKRenderer::VTKRenderer(std::shared_ptr<Scene> scene, const bool enableVR) :
46  m_scene(scene),
47  m_textureManager(std::make_shared<TextureManager<VTKTextureDelegate>>()),
48  m_ssaoPass(vtkSmartPointer<vtkSSAOPass>::New()),
49  m_renderStepsPass(vtkSmartPointer<vtkRenderStepsPass>::New())
50 {
51  // create m_vtkRenderer depending on enableVR
52  m_VrEnabled = enableVR;
53  if (!enableVR)
54  {
55  m_vtkRenderer = vtkSmartPointer<vtkRenderer>::New();
56  }
57  else
58  {
59  m_vtkRenderer = vtkSmartPointer<vtkOpenVRRenderer>::New();
60  vtkOpenVRRenderer::SafeDownCast(m_vtkRenderer)->SetAutomaticLightCreation(false);
61  vtkOpenVRRenderer::SafeDownCast(m_vtkRenderer)->SetLightFollowCamera(false);
62  }
63 }
64 
65 void
67 {
68  // Process all the changes initially (add all the delegates)
69  sceneModifed(nullptr);
70  this->updateRenderDelegates();
71 
72  // Lights and light actors
73  for (const auto& light : m_scene->getLights())
74  {
75  std::string name = light->getTypeName();
76  if (name == DirectionalLight::getStaticTypeName())
77  {
78  auto lightVtk = vtkSmartPointer<vtkLight>::New();
79  lightVtk->SetPositional(false);
80  const Color& color = light->getColor();
81  lightVtk->SetColor(color.r, color.g, color.b);
82  lightVtk->SetIntensity(light->getIntensity());
83  lightVtk->SetFocalPoint(light->getFocalPoint().data());
84  lightVtk->SetPosition(0.0, 0.0, 0.0);
85  lightVtk->SetAttenuationValues(light->getAttenuationValues().data());
86 
87  m_vtkLights.push_back(VtkLightPair(light, lightVtk));
88  }
89  else if (name == SpotLight::getStaticTypeName())
90  {
91  auto lightVtk = vtkSmartPointer<vtkLight>::New();
92  lightVtk->SetPositional(true);
93  const Color& color = light->getColor();
94  lightVtk->SetColor(color.r, color.g, color.b);
95  lightVtk->SetIntensity(light->getIntensity());
96  lightVtk->SetFocalPoint(light->getFocalPoint().data());
97 
98  auto spotLight = std::dynamic_pointer_cast<SpotLight>(light);
99  lightVtk->SetPosition(spotLight->getPosition().data());
100  lightVtk->SetConeAngle(spotLight->getSpotAngle());
101  lightVtk->SetAttenuationValues(light->getAttenuationValues().data());
102 
103  m_vtkLights.push_back(VtkLightPair(light, lightVtk));
104 
105  auto lightActorSpot = vtkSmartPointer<vtkLightActor>::New();
106  lightActorSpot->SetLight(lightVtk);
107  m_debugVtkActors.push_back(lightActorSpot);
108  }
109  else if (name == PointLight::getStaticTypeName())
110  {
111  auto lightVtk = vtkSmartPointer<vtkLight>::New();
112  lightVtk->SetPositional(true);
113  const Color& color = light->getColor();
114  lightVtk->SetColor(color.r, color.g, color.b);
115  lightVtk->SetIntensity(light->getIntensity());
116  lightVtk->SetFocalPoint(light->getFocalPoint().data());
117  lightVtk->SetAttenuationValues(light->getAttenuationValues().data());
118 
119  auto pointLight = std::dynamic_pointer_cast<PointLight>(light);
120  lightVtk->SetPosition(pointLight->getPosition().data());
121 
122  m_vtkLights.push_back(VtkLightPair(light, lightVtk));
123 
124  auto lightActorPoint = vtkSmartPointer<vtkLightActor>::New();
125  lightActorPoint->SetLight(lightVtk);
126  m_debugVtkActors.push_back(lightActorPoint);
127  }
128  else
129  {
130  LOG(WARNING) << "Light type undefined!";
131  }
132  }
133 
134  for (const auto& light : m_vtkLights)
135  {
136  m_vtkRenderer->AddLight(light.second);
137  }
138 
139  // Camera and camera actor
140  if (!m_VrEnabled)
141  {
142  m_camera = vtkSmartPointer<vtkCamera>::New();
143  }
144  else
145  {
146  m_camera = vtkSmartPointer<vtkOpenVRCamera>::New();
147  }
148 
149  updateCamera();
150  vtkNew<vtkCameraActor> camActor;
151  camActor->SetCamera(m_camera);
152  m_debugVtkActors.push_back(camActor);
153 
154  // Customize background colors
155  m_vtkRenderer->SetBackground(m_config->m_BGColor1.r, m_config->m_BGColor1.g, m_config->m_BGColor1.b);
156  m_vtkRenderer->SetBackground2(m_config->m_BGColor2.r, m_config->m_BGColor2.g, m_config->m_BGColor2.b);
157 
158  m_vtkRenderer->GradientBackgroundOn();
159 
161  // Remove culling
162  if (auto culler = m_vtkRenderer->GetCullers()->GetLastItem())
163  {
164  m_vtkRenderer->RemoveCuller(culler);
165  }
166 
167  // Observe changes to the scene
168  connect<Event>(m_scene, &Scene::modified,
169  std::static_pointer_cast<VTKRenderer>(shared_from_this()), &VTKRenderer::sceneModifed);
170 
171  {
172  // Add the benchmarking chart
173  m_timeTableChart = vtkSmartPointer<vtkChartXY>::New();
174  vtkSmartPointer<vtkContextScene> m_benchmarkChartScene = vtkSmartPointer<vtkContextScene>::New();
175  m_timeTableChartActor = vtkSmartPointer<vtkContextActor>::New();
176  m_vtkRenderer->AddActor(m_timeTableChartActor);
177  m_benchmarkChartScene->SetRenderer(m_vtkRenderer);
178 
179  m_timeTableChart->SetAutoSize(true);
180  m_timeTableChart->SetSize(vtkRectf(0.0, 0.0, 600.0, 600.0));
181 
182  m_benchmarkChartScene->AddItem(m_timeTableChart);
183  m_timeTableChartActor->SetScene(m_benchmarkChartScene);
184  m_timeTableChartActor->SetVisibility(false);
185 
186  m_timeTablePlot = vtkPlotBar::SafeDownCast(m_timeTableChart->AddPlot(vtkChart::BAR));
187  m_timeTablePlot->SetColor(0.6, 0.1, 0.1);
188  m_timeTablePlot->SetOrientation(vtkPlotBar::HORIZONTAL);
189  m_timeTableChart->GetAxis(vtkAxis::BOTTOM)->SetTitle("ms");
190  m_timeTableChart->GetAxis(vtkAxis::LEFT)->SetTitle("");
191  m_timeTableChart->GetAxis(vtkAxis::LEFT)->GetLabelProperties()->SetVerticalJustification(VTK_TEXT_CENTERED);
192  m_timeTableChart->GetAxis(vtkAxis::LEFT)->GetLabelProperties()->SetJustification(VTK_TEXT_RIGHT);
193 
194  m_timeTable = vtkSmartPointer<vtkTable>::New();
195  vtkSmartPointer<vtkDoubleArray> xIndices = vtkSmartPointer<vtkDoubleArray>::New();
196  xIndices->SetName("Indices");
197  xIndices->SetNumberOfValues(0);
198  vtkSmartPointer<vtkDoubleArray> yElapsedTimes = vtkSmartPointer<vtkDoubleArray>::New();
199  yElapsedTimes->SetName("Elapsed Times");
200  yElapsedTimes->SetNumberOfValues(0);
201  vtkSmartPointer<vtkStringArray> labels = vtkSmartPointer<vtkStringArray>::New();
202  labels->SetName("Labels");
203  labels->SetNumberOfValues(0);
204  m_timeTable->AddColumn(xIndices);
205  m_timeTable->AddColumn(yElapsedTimes);
206  m_timeTable->AddColumn(labels);
207  m_timeTablePlot->SetInputData(m_timeTable, 0, 1);
208 
209  m_timeTableChart->GetAxis(vtkAxis::BOTTOM)->GetLabelProperties()->SetColor(1.0, 1.0, 1.0);
210  vtkAxis* axisY = m_timeTableChart->GetAxis(vtkAxis::LEFT);
211  axisY->GetLabelProperties()->SetColor(1.0, 1.0, 1.0);
212  axisY->SetGridVisible(false);
213  axisY->SetCustomTickPositions(xIndices, labels);
214  }
215 
216  // Prepare screen space ambient occlusion effect
217  m_ssaoPass->SetDelegatePass(m_renderStepsPass);
218 
219  this->setConfig(this->m_config);
220 
221  m_isInitialized = true;
222 }
223 
224 void
225 VTKRenderer::setMode(const Renderer::Mode mode, const bool enableVR)
226 {
227  if (enableVR)
228  {
229  return;
230  }
231  if (mode == Mode::Empty && m_currentMode != Mode::Empty)
232  {
233  this->removeActors(m_objectVtkActors);
234  m_vtkRenderer->RemoveAllLights();
235 
236  if (m_currentMode == Mode::Debug)
237  {
238  this->removeActors(m_debugVtkActors);
239  }
240  }
241  else if (mode == Mode::Debug && m_currentMode != Mode::Debug)
242  {
243  this->addActors(m_debugVtkActors);
244 
245  if (m_currentMode == Mode::Empty)
246  {
247  this->addActors(m_objectVtkActors);
248  for (const auto& light : m_vtkLights)
249  {
250  m_vtkRenderer->AddLight(light.second);
251  }
252  }
253  }
254  else if (mode == Mode::Simulation && m_currentMode != Mode::Simulation)
255  {
256  if (m_currentMode == Mode::Empty)
257  {
258  this->addActors(m_objectVtkActors);
259  for (const auto& light : m_vtkLights)
260  {
261  m_vtkRenderer->AddLight(light.second);
262  }
263  }
264  else if (m_currentMode == Mode::Debug)
265  {
266  this->removeActors(m_debugVtkActors);
267  }
268  }
269 
270  // Reset the camera
271  m_camera = vtkSmartPointer<vtkCamera>::New();
272 
273  Renderer::setMode(mode, enableVR);
274 }
275 
276 void
277 VTKRenderer::setTimeTable(const std::unordered_map<std::string, double>& timeTable)
278 {
279  // Sort by elapsed times
280  std::vector<std::pair<std::string, double>> nameToTimesVec(timeTable.begin(), timeTable.end());
281  std::sort(nameToTimesVec.begin(), nameToTimesVec.end(),
282  [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) { return a.second < b.second; });
283 
284  // Construct vtkTable from provided data
285  vtkSmartPointer<vtkDoubleArray> xIndices = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(0));
286  vtkSmartPointer<vtkDoubleArray> yElapsedTimes = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(1));
287  vtkSmartPointer<vtkStringArray> labels = vtkStringArray::SafeDownCast(m_timeTable->GetColumn(2));
288 
289  labels->SetNumberOfValues(nameToTimesVec.size());
290  xIndices->SetNumberOfValues(nameToTimesVec.size());
291  yElapsedTimes->SetNumberOfValues(nameToTimesVec.size());
292  for (size_t i = 0; i < nameToTimesVec.size(); i++)
293  {
294  labels->SetValue(i, nameToTimesVec[i].first.c_str());
295  xIndices->SetValue(i, i + 1);
296  yElapsedTimes->SetValue(i, nameToTimesVec[i].second);
297  }
298 
299  // The range for the x axis is based on history of the elapsed times
300  vtkAxis* botAxis = m_timeTableChart->GetAxis(vtkAxis::BOTTOM);
301 
302  // Get the previous and current range
303  double newMaxElapsed = yElapsedTimes->GetRange()[1];
304  yElapsedTimes->Modified();
305  double currMaxElapsed = botAxis->GetMaximum();
306 
307  // Always respect the max as all information should be shown
308  if (newMaxElapsed > currMaxElapsed)
309  {
310  botAxis->SetRange(0.0, newMaxElapsed);
311  }
312  // But if current elapsed is less than the existing one we can lag
313  else
314  {
315  // Lag downscaling by 400 iterations
316  if (m_timeTableIter % 400 == 0)
317  {
318  botAxis->SetRange(0.0, newMaxElapsed);
319  }
320  else
321  {
322  botAxis->SetRange(0.0, currMaxElapsed);
323  }
324  m_timeTableIter++;
325  }
326  botAxis->Modified();
327 
328  vtkAxis* leftAxis = m_timeTableChart->GetAxis(vtkAxis::LEFT);
329  leftAxis->SetRange(xIndices->GetRange());
330  leftAxis->SetCustomTickPositions(xIndices, labels);
331 
332  m_timeTable->Modified();
333 }
334 
335 void
337 {
338  m_timeTableChartActor->SetVisibility(visible);
339 }
340 
341 bool
342 VTKRenderer::getTimeTableVisibility() const
343 {
344  return m_timeTableChartActor->GetVisibility();
345 }
346 
347 void
349 {
350  std::shared_ptr<Camera> cam = m_scene->getActiveCamera();
351  getVtkRenderer()->SetActiveCamera(m_camera);
352 
353  // As long as we don't have a VR camera apply the camera view
354  if (auto vtkVRCam = vtkOpenVRCamera::SafeDownCast(m_camera))
355  {
356  // Copy back the view values from the VR cam to hmd_view in ours
357  vtkMatrix4x4* finalView = m_camera->GetModelViewTransformMatrix();
358  for (int i = 0; i < 4; i++)
359  {
360  for (int j = 0; j < 4; j++)
361  {
362  cam->m_hmdView(i, j) = finalView->GetElement(j, i);
363  }
364  }
365  }
366  else
367  {
368  // Update the camera to obtain corrected view/proj matrices
369  cam->update();
370 
371  // Get the view matrix
372  const Mat4d& invView = cam->getInvView();
373 
374  const double eyePos[3] = { invView(0, 3), invView(1, 3), invView(2, 3) };
375  const double forward[3] = { invView(0, 2), invView(1, 2), invView(2, 2) };
376  const double up[3] = { invView(0, 1), invView(1, 1), invView(2, 1) };
377 
378  m_camera->SetPosition(eyePos);
379  m_camera->SetFocalPoint(eyePos[0] - forward[0], eyePos[1] - forward[1], eyePos[2] - forward[2]);
380  m_camera->SetViewUp(up[0], up[1], up[2]);
381  m_camera->SetViewAngle(cam->getFieldOfView());
382  }
383  m_camera->SetClippingRange(cam->getNearZ(), cam->getFarZ());
384 
385  // Copy the projection back to the camera
386  auto projVtk = vtkSmartPointer<vtkMatrix4x4>::Take(m_camera->GetProjectionTransformMatrix(m_vtkRenderer));
387  for (int i = 0; i < 4; i++)
388  {
389  for (int j = 0; j < 4; j++)
390  {
391  cam->m_proj(i, j) = projVtk->GetElement(j, i);
392  }
393  }
394 }
395 
396 void
398 {
399  // Update their render delegates
400  for (auto delegate : m_renderDelegates)
401  {
402  delegate.second->update();
403  }
404 
405  // Update all lights (we don't use render delegates for these as there usually aren't
406  // all that many lights)
407  for (auto light : m_vtkLights)
408  {
409  std::shared_ptr<Light> lightImstk = light.first;
410  vtkSmartPointer<vtkLight> lightVtk = light.second;
411  std::string lightName = lightImstk->getTypeName();
412  if (lightName == "DirectionalLight")
413  {
414  const Color& color = lightImstk->getColor();
415  lightVtk->SetColor(color.r, color.g, color.b);
416  lightVtk->SetIntensity(lightImstk->getIntensity());
417  lightVtk->SetFocalPoint(lightImstk->getFocalPoint().data());
418  lightVtk->SetPosition(0.0, 0.0, 0.0);
419  lightVtk->SetAttenuationValues(lightImstk->getAttenuationValues().data());
420  }
421  else if (lightName == "SpotLight")
422  {
423  const Color& color = lightImstk->getColor();
424  lightVtk->SetColor(color.r, color.g, color.b);
425  lightVtk->SetIntensity(lightImstk->getIntensity());
426  lightVtk->SetFocalPoint(lightImstk->getFocalPoint().data());
427 
428  auto spotLight = std::dynamic_pointer_cast<SpotLight>(lightImstk);
429  lightVtk->SetPosition(spotLight->getPosition().data());
430  lightVtk->SetConeAngle(spotLight->getSpotAngle());
431  lightVtk->SetAttenuationValues(lightImstk->getAttenuationValues().data());
432  }
433  else if (lightName == "PointLight")
434  {
435  const Color& color = lightImstk->getColor();
436  lightVtk->SetColor(color.r, color.g, color.b);
437  lightVtk->SetIntensity(lightImstk->getIntensity());
438  lightVtk->SetFocalPoint(lightImstk->getFocalPoint().data());
439  lightVtk->SetAttenuationValues(lightImstk->getAttenuationValues().data());
440 
441  auto pointLight = std::dynamic_pointer_cast<PointLight>(lightImstk);
442  lightVtk->SetPosition(pointLight->getPosition().data());
443  }
444  }
445 }
446 
447 void
448 VTKRenderer::removeActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList)
449 {
450  for (const auto& actor : actorList)
451  {
452  m_vtkRenderer->RemoveActor(actor);
453  }
454 }
455 
456 void
457 VTKRenderer::addActors(const std::vector<vtkSmartPointer<vtkProp>>& actorList)
458 {
459  for (const auto& actor : actorList)
460  {
461  m_vtkRenderer->AddActor(actor);
462  }
463 }
464 
465 void
466 VTKRenderer::addEntity(std::shared_ptr<Entity> entity)
467 {
468  m_renderedObjects.insert(entity);
469  m_renderedVisualModels[entity] = std::unordered_set<std::shared_ptr<VisualModel>>();
470  entityModified(entity);
471  // Observe changes on this SceneObject
472  connect<Event>(entity, &Entity::modified,
473  std::static_pointer_cast<VTKRenderer>(shared_from_this()),
475 }
476 
477 void
478 VTKRenderer::addVisualModel(std::shared_ptr<Entity> sceneObject, std::shared_ptr<VisualModel> visualModel)
479 {
480  // Create a delegate for the visual model
481  auto renderDelegate = m_renderDelegates[visualModel] = VTKRenderDelegate::makeDelegate(visualModel);
482  renderDelegate->initialize(visualModel);
483  if (renderDelegate == nullptr)
484  {
485  LOG(WARNING) << "error: Could not create render delegate for '"
486  << sceneObject->getName() << "'.";
487  return;
488  }
489  renderDelegate->setTextureManager(m_textureManager);
490 
491  m_renderedVisualModels[sceneObject].insert(visualModel);
492  m_objectVtkActors.push_back(renderDelegate->getVtkActor());
493  m_vtkRenderer->AddActor(renderDelegate->getVtkActor());
494 
495  if (auto smRenderDelegate = std::dynamic_pointer_cast<VTKSurfaceMeshRenderDelegate>(renderDelegate))
496  {
497  smRenderDelegate->initializeTextures();
498  }
499 
500  visualModel->setRenderDelegateCreated(this, true);
501 }
502 
503 std::unordered_set<std::shared_ptr<VisualModel>>::iterator
504 VTKRenderer::removeVisualModel(std::shared_ptr<Entity> sceneObject, std::shared_ptr<VisualModel> visualModel)
505 {
506  auto renderDelegate = m_renderDelegates[visualModel];
507  auto iter = std::find(m_objectVtkActors.begin(), m_objectVtkActors.end(), renderDelegate->getVtkActor());
508  if (iter != m_objectVtkActors.end())
509  {
510  m_objectVtkActors.erase(iter);
511  }
512  m_vtkRenderer->RemoveActor(renderDelegate->getVtkActor());
513 
514  m_renderDelegates.erase(visualModel);
515  return m_renderedVisualModels[sceneObject].erase(m_renderedVisualModels[sceneObject].find(visualModel));
516 }
517 
518 std::unordered_set<std::shared_ptr<Entity>>::iterator
519 VTKRenderer::removeEntity(std::shared_ptr<Entity> entity)
520 {
521  auto iter = m_renderedObjects.erase(m_renderedObjects.find(entity));
522 
523  // Remove every delegate associated and remove its actors from the scene
524  for (auto visualModel : entity->getComponents<VisualModel>())
525  {
526  removeVisualModel(entity, visualModel);
527  }
528 
529  m_renderedVisualModels.erase(entity);
530 
531  // Stop observing changes on the scene object
532  disconnect(entity, std::static_pointer_cast<VTKRenderer>(shared_from_this()),
533  &SceneObject::modified);
534  return iter;
535 }
536 
537 void
539 {
540  // If the SceneObject is in the scene but not being rendered
541  for (auto ent : m_scene->getSceneObjects())
542  {
543  if (m_renderedObjects.count(ent) == 0)
544  {
545  addEntity(ent);
546  }
547  }
548  // If the SceneObject is being rendered but not in the scene
549  for (auto i = m_renderedObjects.begin(); i != m_renderedObjects.end();)
550  {
551  auto sos = m_scene->getSceneObjects();
552  if (sos.find(*i) == sos.end())
553  {
554  i = removeEntity(*i);
555  }
556  else
557  {
558  i++;
559  }
560  }
561 }
562 
563 void
565 {
566  Entity* sceneObject = static_cast<Entity*>(e->m_sender);
567  if (sceneObject != nullptr)
568  {
569  // Note: All other solutions lead to some ugly variant, I went with this one
570  auto iter = std::find_if(m_renderedObjects.begin(), m_renderedObjects.end(),
571  [sceneObject](const std::shared_ptr<Entity>& i) { return i.get() == sceneObject; });
572  if (iter != m_renderedObjects.end())
573  {
574  entityModified(*iter);
575  }
576  }
577 }
578 
579 void
580 VTKRenderer::entityModified(std::shared_ptr<Entity> sceneObject)
581 {
582  // Only diff a sceneObject being rendered
583  if (m_renderedObjects.count(sceneObject) == 0 || m_renderedVisualModels.count(sceneObject) == 0)
584  {
585  return;
586  }
587 
588  // Now check for added/removed VisualModels
589 
590  // If the VisualModel of the SceneObject is in the SceneObject but not being rendered
591  const auto& visualModels = sceneObject->getComponents<VisualModel>();
592  for (auto visualModel : visualModels)
593  {
594  if (m_renderedVisualModels[sceneObject].count(visualModel) == 0)
595  {
596  addVisualModel(sceneObject, visualModel);
597  }
598  }
599  // If the VisualModel of the SceneObject is being rendered but not part of the SceneObject anymore
600  for (auto i = m_renderedVisualModels[sceneObject].begin(); i != m_renderedVisualModels[sceneObject].end(); i++)
601  {
602  auto iter = std::find(visualModels.begin(), visualModels.end(), *i);
603  if (iter == visualModels.end()) // If end, it is not part of the SceneObject anymore
604  {
605  i = removeVisualModel(sceneObject, *i);
606  }
607  }
608 }
609 
610 void
611 VTKRenderer::updateBackground(const Vec3d backgroundOne, const Vec3d backgroundTwo /*= Vec3d::Zero()*/, const bool gradientBackground /*= false*/)
612 {
613  m_vtkRenderer->SetBackground(backgroundOne.x(), backgroundOne.y(), backgroundOne.z());
614  if (gradientBackground)
615  {
616  m_vtkRenderer->SetBackground2(backgroundTwo.x(), backgroundTwo.y(), backgroundTwo.z());
617  m_vtkRenderer->GradientBackgroundOn();
618  }
619  else
620  {
621  m_vtkRenderer->GradientBackgroundOff();
622  }
623 }
624 
625 void
626 VTKRenderer::setConfig(std::shared_ptr<RendererConfig> config)
627 {
628  m_config = config;
629 
630  // update SSAO if enabled
631  if (m_config->m_ssaoConfig.m_enableSSAO)
632  {
633  m_config->m_ssaoConfig.m_SSAOBlur ? m_ssaoPass->BlurOn() : m_ssaoPass->BlurOff(); // Blur on/off
634  m_ssaoPass->SetRadius(m_config->m_ssaoConfig.m_SSAORadius); // comparison radius
635  m_ssaoPass->SetBias(m_config->m_ssaoConfig.m_SSAOBias); // comparison bias
636  m_ssaoPass->SetKernelSize(m_config->m_ssaoConfig.m_KernelSize); // number of samples used
637 
638  m_ssaoPass->SetDelegatePass(m_renderStepsPass);
639  m_vtkRenderer->SetPass(m_ssaoPass);
640  }
641  else
642  {
643  m_vtkRenderer->SetPass(nullptr);
644  }
645 
646  // update background colors
647  m_vtkRenderer->SetBackground(m_config->m_BGColor1.r, m_config->m_BGColor1.g, m_config->m_BGColor1.b);
648  m_vtkRenderer->SetBackground2(m_config->m_BGColor2.r, m_config->m_BGColor2.g, m_config->m_BGColor2.b);
649 }
650 
651 void
652 VTKRenderer::setDebugActorsVisible(const bool debugActorsVisible)
653 {
654  m_debugActorsVisible = debugActorsVisible;
655  for (auto debugActors : m_debugVtkActors)
656  {
657  debugActors->SetVisibility(debugActorsVisible);
658  }
659 }
660 } // namespace imstk
void updateBackground(const Vec3d color1, const Vec3d color2=Vec3d::Zero(), const bool gradientBackground=false)
Update background colors.
void sceneModifed(Event *e)
Callback for when the scene this renderer renders is modified This involves adding/removing scene obj...
void setTimeTableVisibility(const bool visible) override
Get/Set the visibility of the benchmark graph.
friend void disconnect(std::shared_ptr< EventObject >, std::shared_ptr< EventObject >, std::string(*)())
Remove an observer from the sender.
void addVisualModel(std::shared_ptr< Entity > sceneObject, std::shared_ptr< VisualModel > visualModel)
Add a VisualModel to be rendered, creates a delegate for it.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
void updateCamera()
Updates the camera.
void addEntity(std::shared_ptr< Entity > sceneObject)
Adds an entity to be rendered.
void setTimeTable(const std::unordered_map< std::string, double > &timeTable) override
Sets the benchmarking table using unordered_map.
void addActors(const std::vector< vtkSmartPointer< vtkProp >> &actorList)
Add actors (also called props) from the scene.
Compound Geometry.
std::unordered_set< std::shared_ptr< Entity > >::iterator removeEntity(std::shared_ptr< Entity > sceneObject)
Removes a SceneObject to be rendered.
void setConfig(std::shared_ptr< RendererConfig > config) override
Apply configuration changes.
virtual void setMode(const Renderer::Mode mode, const bool enableVR)
Set rendering mode.
Definition: imstkRenderer.h:64
static std::shared_ptr< VTKRenderDelegate > makeDelegate(std::shared_ptr< VisualModel > visualModel)
Instantiate proper render delegate.
void setMode(const Mode mode, const bool enableVR) override
Set the rendering mode to display debug actors or not.
void entityModified(Event *e)
Callback for when a SceneObject is modified This involves adding/removing visual models to render lis...
vtkSmartPointer< vtkRenderer > getVtkRenderer() const
Returns VTK renderer.
std::unordered_set< std::shared_ptr< VisualModel > >::iterator removeVisualModel(std::shared_ptr< Entity > sceneObject, std::shared_ptr< VisualModel > visualModel)
Remove a VisualModel from rendering.
Top-level class for entities. Entities contain a collection of components which define how to be used...
Definition: imstkEntity.h:26
Color in RGB space.
Definition: imstkColor.h:24
The TextureManager provides delegates for textures, it will create new ones and cache old ones...
couples a imstk texture to a VTK texture
A point light has a position, and it&#39;s range is determined by it&#39;s intensity.
Mode
Enumerations for the render mode.
Definition: imstkRenderer.h:47
VTKRenderer(std::shared_ptr< Scene > scene, const bool enableVR)
Scene is tied to this renderer.
void removeActors(const std::vector< vtkSmartPointer< vtkProp >> &actorList)
Remove actors (also called props) from the scene.
Wraps a vtkRenderer.
Contains geometric, material, and render information.
void initialize() override
Create the rendering delegates and related VTK objects according to the scene.
void updateRenderDelegates()
Updates the render delegates.