ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
vtkCustomInteractorStyle.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #ifdef _MSC_VER
9 #pragma warning(disable : 4996) // Use of [[deprecated]] feature
10 #endif
11 
12 // LOCAL
14 
15 #include <FileSystem.h>
16 
17 #include "vtkCameraManipulator.h"
18 
19 // CV_CORE_LIB
20 #include <CVLog.h>
21 #include <pcl/visualization/common/io.h>
22 #include <vtkAbstractPicker.h>
23 #include <vtkAbstractPropPicker.h>
24 #include <vtkActorCollection.h>
25 #include <vtkAreaPicker.h>
26 #include <vtkAssemblyPath.h>
27 #include <vtkCamera.h>
28 #include <vtkCellArray.h>
29 #include <vtkCollection.h>
30 #include <vtkCollectionIterator.h>
31 #include <vtkLODActor.h>
32 #include <vtkLegendScaleActor.h>
33 #include <vtkLight.h>
34 #include <vtkLightCollection.h>
35 #include <vtkObjectFactory.h>
36 #include <vtkPNGWriter.h>
37 #include <vtkPointData.h>
38 #include <vtkPointPicker.h>
39 #include <vtkPolyData.h>
40 #include <vtkPolyDataMapper.h>
41 #include <vtkProperty.h>
42 #include <vtkRenderWindow.h>
43 #include <vtkRenderWindowInteractor.h>
44 #include <vtkRenderer.h>
45 #include <vtkRendererCollection.h>
46 #include <vtkScalarBarActor.h>
47 #include <vtkTextProperty.h>
48 #include <vtkVersion.h>
49 #include <vtkWindowToImageFilter.h>
50 
51 #include <list>
52 
53 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
54 #include <pcl/visualization/vtk/vtkVertexBufferObjectMapper.h>
55 #endif
56 
57 #define ORIENT_MODE 0
58 #define SELECT_MODE 1
59 
60 #define VTKISRBP_ORIENT 0
61 #define VTKISRBP_SELECT 1
62 
63 namespace VTKExtensions {
65  : pcl::visualization::PCLVisualizerInteractorStyle(),
66  CameraManipulators(vtkCollection::New()),
67  CurrentManipulator(nullptr),
68  RotationFactor(1.0),
69  lut_actor_id_("") {
70  this->CenterOfRotation[0] = this->CenterOfRotation[1] =
71  this->CenterOfRotation[2] = 0;
72 }
73 
74 //-------------------------------------------------------------------------
76  this->CameraManipulators->Delete();
77  this->CameraManipulators = nullptr;
78 }
79 
80 //-------------------------------------------------------------------------
82  this->CameraManipulators->RemoveAllItems();
83 }
84 
85 //-------------------------------------------------------------------------
87  this->CameraManipulators->AddItem(m);
88 }
89 
92  FindPokedRenderer(Interactor->GetEventPosition()[0],
93  Interactor->GetEventPosition()[1]);
94  // Zoom in
95  StartDolly();
96  double factor = 10.0 * 0.2 * .5;
97  Dolly(pow(1.1, factor));
98  EndDolly();
99 }
100 
103  FindPokedRenderer(Interactor->GetEventPosition()[0],
104  Interactor->GetEventPosition()[1]);
105  // Zoom out
106  StartDolly();
107  double factor = 10.0 * -0.2 * .5;
108  Dolly(pow(1.1, factor));
109  EndDolly();
110 }
111 
113  CurrentMode = (CurrentMode == ORIENT_MODE) ? SELECT_MODE : ORIENT_MODE;
114  if (CurrentMode == SELECT_MODE) {
115  // Save the point picker
116  point_picker_ = static_cast<vtkPointPicker*>(Interactor->GetPicker());
117  // Switch for an area picker
118  vtkSmartPointer<vtkAreaPicker> area_picker =
120  Interactor->SetPicker(area_picker);
121  } else {
122  // Restore point picker
123  Interactor->SetPicker(point_picker_);
124  }
125 }
126 
129  // Make sure we ignore the same events we handle in OnKeyDown to avoid
130  // calling things twice
131  FindPokedRenderer(Interactor->GetEventPosition()[0],
132  Interactor->GetEventPosition()[1]);
133  if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9')
134  return;
135  std::string key(Interactor->GetKeySym());
136  if (key.find("XF86ZoomIn") != std::string::npos)
137  zoomIn();
138  else if (key.find("XF86ZoomOut") != std::string::npos)
139  zoomOut();
140 
141  bool keymod = false;
142  switch (modifier_) {
143  case pcl::visualization::INTERACTOR_KB_MOD_ALT: {
144  keymod = Interactor->GetAltKey();
145  break;
146  }
147  case pcl::visualization::InteractorKeyboardModifier::
148  INTERACTOR_KB_MOD_CTRL: {
149  keymod = Interactor->GetControlKey();
150  break;
151  }
152  case pcl::visualization::InteractorKeyboardModifier::
153  INTERACTOR_KB_MOD_SHIFT: {
154  keymod = Interactor->GetShiftKey();
155  break;
156  }
157  }
158 
159  switch (Interactor->GetKeyCode()) {
160  // All of the options below simply exit
161  case 'a':
162  case 'A':
163  case 'h':
164  case 'H':
165  case 'l':
166  case 'L':
167  case 'p':
168  case 'P':
169  case 'j':
170  case 'J':
171  case 'c':
172  case 'C':
173  // Note: KEY_PLUS (43) and KEY_MINUS (45) are removed from exit list
174  // to allow grow/shrink selection shortcuts to work
175  // case 43: // KEY_PLUS - reserved for grow selection
176  // case 45: // KEY_MINUS - reserved for shrink selection
177  case 'f':
178  case 'F':
179  case 'g':
180  case 'G':
181  case 'o':
182  case 'O':
183  case 'u':
184  case 'U':
185  case 'q':
186  case 'Q':
187  case 'x':
188  case 'X':
189  case 'r':
190  case 'R': {
191  break;
192  }
193  // S have special !ALT case
194  case 's':
195  case 'S': {
196  if (!keymod) vtkInteractorStyleRubberBandPick::OnChar();
197  break;
198  }
199  default: {
200  vtkInteractorStyleRubberBandPick::OnChar();
201  break;
202  }
203  }
204 }
205 
208  if (!rens_) {
209  CVLog::Error(
210  "[vtkCustomInteractorStyle] No renderer collection given! Use "
211  "SetRendererCollection () before continuing.");
212  return;
213  }
214 
215  // Look for a matching camera interactor.
216  this->CameraManipulators->InitTraversal();
217  vtkCameraManipulator* manipulator = NULL;
218  while ((manipulator = (vtkCameraManipulator*)this->CameraManipulators
219  ->GetNextItemAsObject())) {
220  manipulator->OnKeyDown(this->Interactor);
221  }
222 
223  FindPokedRenderer(Interactor->GetEventPosition()[0],
224  Interactor->GetEventPosition()[1]);
225 
226  if (wif_->GetInput() == NULL) {
227  wif_->SetInput(Interactor->GetRenderWindow());
228  wif_->Modified();
229  snapshot_writer_->Modified();
230  }
231 
232  // Save the initial windows width/height
233  if (win_height_ == -1 || win_width_ == -1) {
234  int* win_size = Interactor->GetRenderWindow()->GetSize();
235  win_height_ = win_size[0];
236  win_width_ = win_size[1];
237  }
238 
239  // Get the status of special keys (Cltr+Alt+Shift)
240  bool shift = Interactor->GetShiftKey();
241  bool ctrl = Interactor->GetControlKey();
242  bool alt = Interactor->GetAltKey();
243 
244  bool keymod = false;
245  switch (modifier_) {
246  case pcl::visualization::INTERACTOR_KB_MOD_ALT: {
247  keymod = alt;
248  break;
249  }
250  case pcl::visualization::INTERACTOR_KB_MOD_CTRL: {
251  keymod = ctrl;
252  break;
253  }
254  case pcl::visualization::INTERACTOR_KB_MOD_SHIFT: {
255  keymod = shift;
256  break;
257  }
258  }
259 
260  // ---[ Check the rest of the key codes
261 
262  // Save camera parameters
263  if ((Interactor->GetKeySym()[0] == 'S' ||
264  Interactor->GetKeySym()[0] == 's') &&
265  ctrl && !alt && !shift) {
266  if (camera_file_.empty()) {
267  getCameraParameters(camera_);
268  camera_saved_ = true;
269  CVLog::Print(
270  "Camera parameters saved, you can press CTRL + R to "
271  "restore.");
272  } else {
273  if (saveCameraParameters(camera_file_)) {
274  CVLog::Print(
275  "Save camera parameters to %s, you can press CTRL + R "
276  "to restore.",
277  camera_file_.c_str());
278  } else {
279  CVLog::Error(
280  "[vtkCustomInteractorStyle] Can't save camera "
281  "parameters to file: %s.",
282  camera_file_.c_str());
283  }
284  }
285  }
286 
287  // Restore camera parameters
288  if ((Interactor->GetKeySym()[0] == 'R' ||
289  Interactor->GetKeySym()[0] == 'r') &&
290  ctrl && !alt && !shift) {
291  if (camera_file_.empty()) {
292  if (camera_saved_) {
293  setCameraParameters(camera_);
294  CVLog::Print("Camera parameters restored.");
295  } else {
296  CVLog::Print("No camera parameters saved for restoring.");
297  }
298  } else {
300  if (loadCameraParameters(camera_file_)) {
301  CVLog::Print("Restore camera parameters from %s.",
302  camera_file_.c_str());
303  } else {
304  CVLog::Error(
305  "Can't restore camera parameters from file: %s.",
306  camera_file_.c_str());
307  }
308  } else {
309  CVLog::Print("No camera parameters saved in %s for restoring.",
310  camera_file_.c_str());
311  }
312  }
313  }
314 
315  // Switch between point color/geometry handlers
316  if (Interactor->GetKeySym() && Interactor->GetKeySym()[0] >= '0' &&
317  Interactor->GetKeySym()[0] <= '9') {
318  pcl::visualization::CloudActorMap::iterator it;
319  int index = Interactor->GetKeySym()[0] - '0' - 1;
320  if (index == -1) index = 9;
321 
322  // Add 10 more for CTRL+0..9 keys
323  if (ctrl) index += 10;
324 
325  // Geometry ?
326  if (keymod) {
327  for (it = cloud_actors_->begin(); it != cloud_actors_->end();
328  ++it) {
329  pcl::visualization::CloudActor* act = &(*it).second;
330  if (index >= static_cast<int>(act->geometry_handlers.size()))
331  continue;
332 
333  // Save the geometry handler index for later usage
334  act->geometry_handler_index_ = index;
335 
336  // Create the new geometry
337  pcl::visualization::PointCloudGeometryHandler<
338  pcl::PCLPointCloud2>::ConstPtr geometry_handler =
339  act->geometry_handlers[index];
340 
341  // Use the handler to obtain the geometry
343  geometry_handler->getGeometry(points);
344 
345  // Set the vertices
348  for (vtkIdType i = 0;
349  i < static_cast<vtkIdType>(points->GetNumberOfPoints());
350  ++i)
351  vertices->InsertNextCell(static_cast<vtkIdType>(1), &i);
352 
353  // Create the data
356  data->SetPoints(points);
357  data->SetVerts(vertices);
358  // Modify the mapper
359 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
360  if (use_vbos_) {
361  vtkVertexBufferObjectMapper* mapper =
362  static_cast<vtkVertexBufferObjectMapper*>(
363  act->actor->GetMapper());
364  mapper->SetInput(data);
365  // Modify the actor
366  act->actor->SetMapper(mapper);
367  } else
368 #endif
369  {
370  vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(
371  act->actor->GetMapper());
372 #if VTK_MAJOR_VERSION < 6
373  mapper->SetInput(data);
374 #else
375  mapper->SetInputData(data);
376 #endif
377  // Modify the actor
378  act->actor->SetMapper(mapper);
379  }
380  act->actor->Modified();
381  }
382  } else {
383  for (it = cloud_actors_->begin(); it != cloud_actors_->end();
384  ++it) {
385  pcl::visualization::CloudActor* act = &(*it).second;
386  // Check for out of bounds
387  if (index >= static_cast<int>(act->color_handlers.size()))
388  continue;
389 
390  // Save the color handler index for later usage
391  act->color_handler_index_ = index;
392 
393  // Get the new color
394  pcl::visualization::PointCloudColorHandler<
395  pcl::PCLPointCloud2>::ConstPtr color_handler =
396  act->color_handlers[index];
397 
399  color_handler->getColor();
400 
401  double minmax[2];
402  scalars->GetRange(minmax);
403  // Update the data
404  vtkPolyData* data = static_cast<vtkPolyData*>(
405  act->actor->GetMapper()->GetInput());
406  data->GetPointData()->SetScalars(scalars);
407  // Modify the mapper
408 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
409  if (use_vbos_) {
410  vtkVertexBufferObjectMapper* mapper =
411  static_cast<vtkVertexBufferObjectMapper*>(
412  act->actor->GetMapper());
413  mapper->SetScalarRange(minmax);
414  mapper->SetScalarModeToUsePointData();
415  mapper->SetInput(data);
416  // Modify the actor
417  act->actor->SetMapper(mapper);
418  } else
419 #endif
420  {
421  vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(
422  act->actor->GetMapper());
423  mapper->SetScalarRange(minmax);
424  mapper->SetScalarModeToUsePointData();
425 #if VTK_MAJOR_VERSION < 6
426  mapper->SetInput(data);
427 #else
428  mapper->SetInputData(data);
429 #endif
430  // Modify the actor
431  act->actor->SetMapper(mapper);
432  }
433  act->actor->Modified();
434  }
435  }
436 
437  Interactor->Render();
438  return;
439  }
440 
441  std::string key(Interactor->GetKeySym());
442  if (key.find("XF86ZoomIn") != std::string::npos)
443  zoomIn();
444  else if (key.find("XF86ZoomOut") != std::string::npos)
445  zoomOut();
446 
447  switch (Interactor->GetKeyCode()) {
448  case 'h':
449  case 'H': {
450  CVLog::Print(
451  "| Help:"
452  "-------"
453  " CTRL + SHIFT + p, P : switch to a point-based "
454  "representation"
455  " CTRL + SHIFT + w, W : switch to a "
456  "wireframe-based "
457  "representation (where available)"
458  " CTRL + SHIFT + s, S : switch to a "
459  "surface-based "
460  "representation (where available)"
461  ""
462  " CTRL + ALT + j, J : take a .PNG snapshot of "
463  "the current "
464  "window view"
465  " CTRL + ALT + c, C : display current "
466  "camera/window "
467  "parameters"
468  " f, F : fly to point mode"
469  ""
470  " e, E : exit the interactor"
471  " q, Q : stop and call VTK's TerminateApp"
472  ""
473  " CTRL + SHIFT + +/- : increment/decrement "
474  "overall point size"
475  " CTRL + ALT + +/-: zoom in/out "
476  ""
477  " CTRL + ALT + g, G : display scale grid "
478  "(on/off)"
479  " CTRL + ALT + u, U : display lookup table "
480  "(on/off)"
481  ""
482  " CTRL + ALT + o, O : switch between "
483  "perspective/parallel "
484  "projection (default = perspective)"
485  " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} "
486  "-> center_{x, y, z}]"
487  " CTRL + s, S : save camera parameters"
488  " CTRL + r, R : restore camera parameters"
489  ""
490  " CTRL + ALT + s, S : turn stereo mode on/off"
491  " CTRL + ALT + f, F : switch between maximized window "
492  "mode "
493  "and original size"
494  ""
495  " l, L : list all available geometric "
496  "and color handlers for the current actor map"
497  " ALT + 0..9 [+ CTRL] : switch between different "
498  "geometric handlers (where available)"
499  " 0..9 [+ CTRL] : switch between different color "
500  "handlers (where available)"
501  ""
502  " SHIFT + left click : select a point (start with "
503  "-use_point_picking)"
504  ""
505  " a, A : toggle rubber band selection mode for "
506  "left mouse button");
507  break;
508  }
509 
510  // Get the list of available handlers
511  case 'l':
512  case 'L': {
513  // Iterate over the entire actors list and extract the
514  // geomotry/color handlers list
515  for (pcl::visualization::CloudActorMap::iterator it =
516  cloud_actors_->begin();
517  it != cloud_actors_->end(); ++it) {
518  std::list<std::string> geometry_handlers_list,
519  color_handlers_list;
520  pcl::visualization::CloudActor* act = &(*it).second;
521  for (size_t i = 0; i < act->geometry_handlers.size(); ++i)
522  geometry_handlers_list.push_back(
523  act->geometry_handlers[i]->getFieldName());
524  for (size_t i = 0; i < act->color_handlers.size(); ++i)
525  color_handlers_list.push_back(
526  act->color_handlers[i]->getFieldName());
527 
528  if (!geometry_handlers_list.empty()) {
529  int i = 0;
530  CVLog::Print(
531  "List of available geometry handlers for actor ");
532  CVLog::Print("%s: ", (*it).first.c_str());
533  for (std::list<std::string>::iterator git =
534  geometry_handlers_list.begin();
535  git != geometry_handlers_list.end(); ++git)
536  CVLog::Print("%s(%d) ", (*git).c_str(), ++i);
537  }
538  if (!color_handlers_list.empty()) {
539  int i = 0;
540  CVLog::Print("List of available color handlers for actor ");
541  CVLog::Print("%s: ", (*it).first.c_str());
542  for (std::list<std::string>::iterator cit =
543  color_handlers_list.begin();
544  cit != color_handlers_list.end(); ++cit)
545  CVLog::Print("%s(%d) ", (*cit).c_str(), ++i);
546  }
547  }
548 
549  break;
550  }
551 
552  // Switch representation to points
553  case 'p':
554  case 'P': {
555  if (shift && ctrl) {
557  CurrentRenderer->GetActors();
558  vtkCollectionSimpleIterator ait;
559  for (ac->InitTraversal(ait);
560  vtkActor* actor = ac->GetNextActor(ait);) {
561  for (actor->InitPathTraversal();
562  vtkAssemblyPath* path = actor->GetNextPath();) {
564  reinterpret_cast<vtkActor*>(
565  path->GetLastNode()->GetViewProp());
566  apart->GetProperty()->SetRepresentationToPoints();
567  }
568  }
569  }
570  break;
571  }
572 
573  // Switch representation to wireframe (override default behavior)
574  case 'w':
575  case 'W': {
576  if (shift && ctrl) {
578  CurrentRenderer->GetActors();
579  vtkCollectionSimpleIterator ait;
580  for (ac->InitTraversal(ait);
581  vtkActor* actor = ac->GetNextActor(ait);) {
582  for (actor->InitPathTraversal();
583  vtkAssemblyPath* path = actor->GetNextPath();) {
585  reinterpret_cast<vtkActor*>(
586  path->GetLastNode()->GetViewProp());
587  apart->GetProperty()->SetRepresentationToWireframe();
588  apart->GetProperty()->SetLighting(false);
589  }
590  }
591  }
592  break;
593  }
594 
595  // Save a PNG snapshot with the current screen
596  case 'j':
597  case 'J': {
598  if (alt && ctrl) {
599  char cam_fn[80], snapshot_fn[80];
600  unsigned t = static_cast<unsigned>(time(0));
601  sprintf(snapshot_fn, "screenshot-%d.png", t);
602  saveScreenshot(snapshot_fn);
603 
604  sprintf(cam_fn, "screenshot-%d.cam", t);
605  saveCameraParameters(cam_fn);
606 
607  CVLog::Print(
608  "Screenshot (%s) and camera information (%s) "
609  "successfully "
610  "captured.",
611  snapshot_fn, cam_fn);
612  }
613  break;
614  }
615  // display current camera settings/parameters
616  case 'c':
617  case 'C': {
618  if (alt && ctrl) {
619  vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()
620  ->GetRenderers()
621  ->GetFirstRenderer()
622  ->GetActiveCamera();
623  double clip[2], focal[3], pos[3], view[3];
624  cam->GetClippingRange(clip);
625  cam->GetFocalPoint(focal);
626  cam->GetPosition(pos);
627  cam->GetViewUp(view);
628  int* win_pos = Interactor->GetRenderWindow()->GetPosition();
629  int* win_size = Interactor->GetRenderWindow()->GetSize();
630  std::cerr << "Clipping plane [near,far] " << clip[0] << ", "
631  << clip[1] << endl
632  << "Focal point [x,y,z] " << focal[0] << ", "
633  << focal[1] << ", " << focal[2] << endl
634  << "Position [x,y,z] " << pos[0] << ", " << pos[1]
635  << ", " << pos[2] << endl
636  << "View up [x,y,z] " << view[0] << ", " << view[1]
637  << ", " << view[2] << endl
638  << "Camera view angle [degrees] "
639  << cam->GetViewAngle() << endl
640  << "Window size [x,y] " << win_size[0] << ", "
641  << win_size[1] << endl
642  << "Window position [x,y] " << win_pos[0] << ", "
643  << win_pos[1] << endl;
644  }
645  break;
646  }
647  case '=': {
648  // Zoom in with = key (requires modifier to avoid conflict with grow
649  // selection)
650  if (alt || ctrl) {
651  zoomIn();
652  }
653  break;
654  }
655  case 43: // KEY_PLUS
656  {
657  // Plus key: only handle with modifiers to avoid conflict with grow
658  // selection Grow selection uses plain '+' key, so we skip it here
659  if (alt && ctrl) {
660  zoomIn();
661  } else if (shift && ctrl) {
663  CurrentRenderer->GetActors();
664  vtkCollectionSimpleIterator ait;
665  for (ac->InitTraversal(ait);
666  vtkActor* actor = ac->GetNextActor(ait);) {
667  for (actor->InitPathTraversal();
668  vtkAssemblyPath* path = actor->GetNextPath();) {
670  reinterpret_cast<vtkActor*>(
671  path->GetLastNode()->GetViewProp());
672  float psize = apart->GetProperty()->GetPointSize();
673  if (psize < 63.0f)
674  apart->GetProperty()->SetPointSize(psize + 1.0f);
675  }
676  }
677  }
678  // Plain '+' is reserved for grow selection, do nothing
679  break;
680  }
681  case 45: // KEY_MINUS
682  {
683  // Minus key: only handle with modifiers to avoid conflict with
684  // shrink selection Shrink selection uses plain '-' key, so we skip
685  // it here
686  if (alt && ctrl) {
687  zoomOut();
688  } else if (shift && ctrl) {
690  CurrentRenderer->GetActors();
691  vtkCollectionSimpleIterator ait;
692  for (ac->InitTraversal(ait);
693  vtkActor* actor = ac->GetNextActor(ait);) {
694  for (actor->InitPathTraversal();
695  vtkAssemblyPath* path = actor->GetNextPath();) {
697  static_cast<vtkActor*>(
698  path->GetLastNode()->GetViewProp());
699  float psize = apart->GetProperty()->GetPointSize();
700  if (psize > 1.0f)
701  apart->GetProperty()->SetPointSize(psize - 1.0f);
702  }
703  }
704  }
705  // Plain '-' is reserved for shrink selection, do nothing
706  break;
707  }
708  // Switch between maximize and original window size
709  case 'f':
710  case 'F': {
711  if (keymod) {
712  if (alt && ctrl) {
713  // Get screen size
714  int* temp = Interactor->GetRenderWindow()->GetScreenSize();
715  int scr_size[2];
716  scr_size[0] = temp[0];
717  scr_size[1] = temp[1];
718 
719  // Get window size
720  temp = Interactor->GetRenderWindow()->GetSize();
721  int win_size[2];
722  win_size[0] = temp[0];
723  win_size[1] = temp[1];
724  // Is window size = max?
725  if (win_size[0] == max_win_height_ &&
726  win_size[1] == max_win_width_) {
727  // Set the previously saved 'current' window size
728  Interactor->GetRenderWindow()->SetSize(win_height_,
729  win_width_);
730  // Set the previously saved window position
731  Interactor->GetRenderWindow()->SetPosition(win_pos_x_,
732  win_pos_y_);
733  Interactor->GetRenderWindow()->Render();
734  Interactor->Render();
735  } else { // Set to max
736  int* win_pos =
737  Interactor->GetRenderWindow()->GetPosition();
738  // Save the current window position
739  win_pos_x_ = win_pos[0];
740  win_pos_y_ = win_pos[1];
741  // Save the current window size
742  win_height_ = win_size[0];
743  win_width_ = win_size[1];
744  // Set the maximum window size
745  Interactor->GetRenderWindow()->SetSize(scr_size[0],
746  scr_size[1]);
747  Interactor->GetRenderWindow()->Render();
748  Interactor->Render();
749  int* win_size =
750  Interactor->GetRenderWindow()->GetSize();
751  // Save the maximum window size
752  max_win_height_ = win_size[0];
753  max_win_width_ = win_size[1];
754  }
755  }
756  } else {
757  AnimState = VTKIS_ANIM_ON;
758  vtkAssemblyPath* path = NULL;
759  Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0],
760  Interactor->GetEventPosition()[1],
761  0.0, CurrentRenderer);
762  vtkAbstractPropPicker* picker;
763  if ((picker = vtkAbstractPropPicker::SafeDownCast(
764  Interactor->GetPicker())))
765  path = picker->GetPath();
766  if (path != NULL)
767  Interactor->FlyTo(CurrentRenderer,
768  picker->GetPickPosition());
769  AnimState = VTKIS_ANIM_OFF;
770  }
771  break;
772  }
773  // 's'/'S' w/out ALT + CTRL
774  case 's':
775  case 'S': {
776  if (alt && ctrl) {
777  int stereo_render =
778  Interactor->GetRenderWindow()->GetStereoRender();
779  if (!stereo_render) {
780  if (stereo_anaglyph_mask_default_) {
781  Interactor->GetRenderWindow()->SetAnaglyphColorMask(4,
782  3);
783  stereo_anaglyph_mask_default_ = false;
784  } else {
785  Interactor->GetRenderWindow()->SetAnaglyphColorMask(2,
786  5);
787  stereo_anaglyph_mask_default_ = true;
788  }
789  }
790  Interactor->GetRenderWindow()->SetStereoRender(!stereo_render);
791  Interactor->GetRenderWindow()->Render();
792  Interactor->Render();
793  } else if (shift && ctrl) {
794  vtkInteractorStyleRubberBandPick::OnKeyDown();
796  CurrentRenderer->GetActors();
797  vtkCollectionSimpleIterator ait;
798  for (ac->InitTraversal(ait);
799  vtkActor* actor = ac->GetNextActor(ait);) {
800  for (actor->InitPathTraversal();
801  vtkAssemblyPath* path = actor->GetNextPath();) {
803  reinterpret_cast<vtkActor*>(
804  path->GetLastNode()->GetViewProp());
805  apart->GetProperty()->SetRepresentationToSurface();
806  apart->GetProperty()->SetLighting(true);
807  }
808  }
809  }
810  break;
811  }
812 
813  // Display a grid/scale over the screen
814  case 'g':
815  case 'G': {
816  if (alt && ctrl) {
817  if (!grid_enabled_) {
818  grid_actor_->TopAxisVisibilityOn();
819  CurrentRenderer->AddViewProp(grid_actor_);
820  grid_enabled_ = true;
821  } else {
822  CurrentRenderer->RemoveViewProp(grid_actor_);
823  grid_enabled_ = false;
824  }
825  }
826  break;
827  }
828 
829  case 'o':
830  case 'O': {
831  if (alt && ctrl) {
833  CurrentRenderer->GetActiveCamera();
834  int flag = cam->GetParallelProjection();
835  cam->SetParallelProjection(!flag);
836 
837  CurrentRenderer->SetActiveCamera(cam);
838  CurrentRenderer->Render();
839  }
840  break;
841  }
842  // Display a LUT actor on screen
843  case 'u':
844  case 'U': {
845  if (alt && ctrl) {
846  this->updateLookUpTableDisplay(true);
847  }
848  break;
849  }
850 
851  // Overwrite the camera reset
852  case 'r':
853  case 'R': {
854  if (!keymod) {
855  FindPokedRenderer(Interactor->GetEventPosition()[0],
856  Interactor->GetEventPosition()[1]);
857  if (CurrentRenderer != 0)
858  CurrentRenderer->ResetCamera();
859  else
860  PCL_WARN("no current renderer on the interactor style.");
861 
862  CurrentRenderer->Render();
863  break;
864  }
865 
866  vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
867 
868  static pcl::visualization::CloudActorMap::iterator it =
869  cloud_actors_->begin();
870  // it might be that some actors don't have a valid
871  // transformation set -> we skip them to avoid a seg fault.
872  bool found_transformation = false;
873  for (unsigned idx = 0; idx < cloud_actors_->size(); ++idx, ++it) {
874  if (it == cloud_actors_->end()) it = cloud_actors_->begin();
875 
876  const pcl::visualization::CloudActor& actor = it->second;
877  if (actor.viewpoint_transformation_.GetPointer()) {
878  found_transformation = true;
879  break;
880  }
881  }
882 
883  // if a valid transformation was found, use it otherwise fall
884  // back to default view point.
885  if (found_transformation) {
886  const pcl::visualization::CloudActor& actor = it->second;
887  cam->SetPosition(
888  actor.viewpoint_transformation_->GetElement(0, 3),
889  actor.viewpoint_transformation_->GetElement(1, 3),
890  actor.viewpoint_transformation_->GetElement(2, 3));
891 
892  cam->SetFocalPoint(
893  actor.viewpoint_transformation_->GetElement(0, 3) -
894  actor.viewpoint_transformation_->GetElement(0,
895  2),
896  actor.viewpoint_transformation_->GetElement(1, 3) -
897  actor.viewpoint_transformation_->GetElement(1,
898  2),
899  actor.viewpoint_transformation_->GetElement(2, 3) -
900  actor.viewpoint_transformation_->GetElement(2,
901  2));
902 
903  cam->SetViewUp(
904  actor.viewpoint_transformation_->GetElement(0, 1),
905  actor.viewpoint_transformation_->GetElement(1, 1),
906  actor.viewpoint_transformation_->GetElement(2, 1));
907  } else {
908  cam->SetPosition(0, 0, 0);
909  cam->SetFocalPoint(0, 0, 1);
910  cam->SetViewUp(0, -1, 0);
911  }
912 
913  // go to the next actor for the next key-press event.
914  if (it != cloud_actors_->end())
915  ++it;
916  else
917  it = cloud_actors_->begin();
918 
919  CurrentRenderer->SetActiveCamera(cam);
920  CurrentRenderer->ResetCameraClippingRange();
921  CurrentRenderer->Render();
922  break;
923  }
924 
925  case 'a':
926  case 'A': {
927  CurrentMode =
928  (CurrentMode == ORIENT_MODE) ? SELECT_MODE : ORIENT_MODE;
929  if (CurrentMode == SELECT_MODE) {
930  // Save the point picker
931  point_picker_ =
932  static_cast<vtkPointPicker*>(Interactor->GetPicker());
933  // Switch for an area picker
934  vtkSmartPointer<vtkAreaPicker> area_picker =
936  Interactor->SetPicker(area_picker);
937  } else {
938  // Restore point picker
939  Interactor->SetPicker(point_picker_);
940  }
941  break;
942  }
943 
944  case 'q':
945  case 'Q': {
946  Interactor->ExitCallback();
947  return;
948  }
949  default: {
950  vtkInteractorStyleRubberBandPick::OnKeyDown();
951  break;
952  }
953  }
954 
955  pcl::visualization::KeyboardEvent event(
956  true, Interactor->GetKeySym(), Interactor->GetKeyCode(),
957  Interactor->GetAltKey(), Interactor->GetControlKey(),
958  Interactor->GetShiftKey());
959  keyboard_signal_(event);
960 
961  rens_->Render();
962  Interactor->Render();
963 }
964 
967  pcl::visualization::KeyboardEvent event(
968  false, Interactor->GetKeySym(), Interactor->GetKeyCode(),
969  Interactor->GetAltKey(), Interactor->GetControlKey(),
970  Interactor->GetShiftKey());
971  keyboard_signal_(event);
972 
973  // Look for a matching camera interactor.
974  this->CameraManipulators->InitTraversal();
975  vtkCameraManipulator* manipulator = NULL;
976  while ((manipulator = (vtkCameraManipulator*)this->CameraManipulators
977  ->GetNextItemAsObject())) {
978  manipulator->OnKeyUp(this->Interactor);
979  }
980 
981  vtkInteractorStyleRubberBandPick::OnKeyUp();
982 }
983 
986  int x = this->Interactor->GetEventPosition()[0];
987  int y = this->Interactor->GetEventPosition()[1];
988  pcl::visualization::MouseEvent event(
989  pcl::visualization::MouseEvent::MouseMove,
990  pcl::visualization::MouseEvent::NoButton, x, y,
991  Interactor->GetAltKey(), Interactor->GetControlKey(),
992  Interactor->GetShiftKey(),
993  vtkInteractorStyleRubberBandPick::CurrentMode);
994  mouse_signal_(event);
995 
996  if (this->CurrentMode != VTKISRBP_SELECT/* && !Interactor->GetControlKey() && !Interactor->GetShiftKey()*/)
997  {
998  if (this->CurrentRenderer && this->CurrentManipulator) {
999  // When an interaction is active, we should not change the
1000  // renderer being interacted with.
1001  } else {
1002  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
1003  this->Interactor->GetEventPosition()[1]);
1004  }
1005 
1006  if (this->CurrentManipulator) {
1008  this->Interactor->GetEventPosition()[0],
1009  this->Interactor->GetEventPosition()[1],
1010  this->CurrentRenderer, this->Interactor);
1011  this->InvokeEvent(vtkCommand::InteractionEvent);
1012  }
1013  } else {
1014  vtkInteractorStyleRubberBandPick::OnMouseMove();
1015  }
1016 }
1017 
1020  int x = this->Interactor->GetEventPosition()[0];
1021  int y = this->Interactor->GetEventPosition()[1];
1022 
1023  if (Interactor->GetRepeatCount() == 0) {
1024  pcl::visualization::MouseEvent event(
1025  pcl::visualization::MouseEvent::MouseButtonPress,
1026  pcl::visualization::MouseEvent::LeftButton, x, y,
1027  Interactor->GetAltKey(), Interactor->GetControlKey(),
1028  Interactor->GetShiftKey(),
1029  vtkInteractorStyleRubberBandPick::CurrentMode);
1030  mouse_signal_(event);
1031  } else {
1032  pcl::visualization::MouseEvent event(
1033  pcl::visualization::MouseEvent::MouseDblClick,
1034  pcl::visualization::MouseEvent::LeftButton, x, y,
1035  Interactor->GetAltKey(), Interactor->GetControlKey(),
1036  Interactor->GetShiftKey(),
1037  vtkInteractorStyleRubberBandPick::CurrentMode);
1038  mouse_signal_(event);
1039  }
1040  this->OnButtonDown(1, this->Interactor->GetShiftKey(),
1041  this->Interactor->GetControlKey());
1042  vtkInteractorStyleRubberBandPick::OnLeftButtonDown();
1043 }
1044 
1047  int x = this->Interactor->GetEventPosition()[0];
1048  int y = this->Interactor->GetEventPosition()[1];
1049  pcl::visualization::MouseEvent event(
1050  pcl::visualization::MouseEvent::MouseButtonRelease,
1051  pcl::visualization::MouseEvent::LeftButton, x, y,
1052  Interactor->GetAltKey(), Interactor->GetControlKey(),
1053  Interactor->GetShiftKey(),
1054  vtkInteractorStyleRubberBandPick::CurrentMode);
1055  mouse_signal_(event);
1056  this->OnButtonUp(1);
1057  vtkInteractorStyleRubberBandPick::OnLeftButtonUp();
1058 }
1059 
1062  int x = this->Interactor->GetEventPosition()[0];
1063  int y = this->Interactor->GetEventPosition()[1];
1064  if (Interactor->GetRepeatCount() == 0) {
1065  pcl::visualization::MouseEvent event(
1066  pcl::visualization::MouseEvent::MouseButtonPress,
1067  pcl::visualization::MouseEvent::MiddleButton, x, y,
1068  Interactor->GetAltKey(), Interactor->GetControlKey(),
1069  Interactor->GetShiftKey(),
1070  vtkInteractorStyleRubberBandPick::CurrentMode);
1071  mouse_signal_(event);
1072  } else {
1073  pcl::visualization::MouseEvent event(
1074  pcl::visualization::MouseEvent::MouseDblClick,
1075  pcl::visualization::MouseEvent::MiddleButton, x, y,
1076  Interactor->GetAltKey(), Interactor->GetControlKey(),
1077  Interactor->GetShiftKey(),
1078  vtkInteractorStyleRubberBandPick::CurrentMode);
1079  mouse_signal_(event);
1080  }
1081  this->OnButtonDown(2, this->Interactor->GetShiftKey(),
1082  this->Interactor->GetControlKey());
1083  vtkInteractorStyleRubberBandPick::OnMiddleButtonDown();
1084 }
1085 
1088  int x = this->Interactor->GetEventPosition()[0];
1089  int y = this->Interactor->GetEventPosition()[1];
1090  pcl::visualization::MouseEvent event(
1091  pcl::visualization::MouseEvent::MouseButtonRelease,
1092  pcl::visualization::MouseEvent::MiddleButton, x, y,
1093  Interactor->GetAltKey(), Interactor->GetControlKey(),
1094  Interactor->GetShiftKey(),
1095  vtkInteractorStyleRubberBandPick::CurrentMode);
1096  mouse_signal_(event);
1097  this->OnButtonUp(2);
1098  vtkInteractorStyleRubberBandPick::OnMiddleButtonUp();
1099 }
1100 
1103  int x = this->Interactor->GetEventPosition()[0];
1104  int y = this->Interactor->GetEventPosition()[1];
1105  if (Interactor->GetRepeatCount() == 0) {
1106  pcl::visualization::MouseEvent event(
1107  pcl::visualization::MouseEvent::MouseButtonPress,
1108  pcl::visualization::MouseEvent::RightButton, x, y,
1109  Interactor->GetAltKey(), Interactor->GetControlKey(),
1110  Interactor->GetShiftKey(),
1111  vtkInteractorStyleRubberBandPick::CurrentMode);
1112  mouse_signal_(event);
1113  } else {
1114  pcl::visualization::MouseEvent event(
1115  pcl::visualization::MouseEvent::MouseDblClick,
1116  pcl::visualization::MouseEvent::RightButton, x, y,
1117  Interactor->GetAltKey(), Interactor->GetControlKey(),
1118  Interactor->GetShiftKey(),
1119  vtkInteractorStyleRubberBandPick::CurrentMode);
1120  mouse_signal_(event);
1121  }
1122 
1123  this->OnButtonDown(3, this->Interactor->GetShiftKey(),
1124  this->Interactor->GetControlKey());
1125  vtkInteractorStyleRubberBandPick::OnRightButtonDown();
1126 }
1127 
1130  int x = this->Interactor->GetEventPosition()[0];
1131  int y = this->Interactor->GetEventPosition()[1];
1132  pcl::visualization::MouseEvent event(
1133  pcl::visualization::MouseEvent::MouseButtonRelease,
1134  pcl::visualization::MouseEvent::RightButton, x, y,
1135  Interactor->GetAltKey(), Interactor->GetControlKey(),
1136  Interactor->GetShiftKey(),
1137  vtkInteractorStyleRubberBandPick::CurrentMode);
1138  mouse_signal_(event);
1139  this->OnButtonUp(3);
1140  vtkInteractorStyleRubberBandPick::OnRightButtonUp();
1141 }
1142 
1145  int x = this->Interactor->GetEventPosition()[0];
1146  int y = this->Interactor->GetEventPosition()[1];
1147  pcl::visualization::MouseEvent event(
1148  pcl::visualization::MouseEvent::MouseScrollUp,
1149  pcl::visualization::MouseEvent::VScroll, x, y,
1150  Interactor->GetAltKey(), Interactor->GetControlKey(),
1151  Interactor->GetShiftKey(),
1152  vtkInteractorStyleRubberBandPick::CurrentMode);
1153  mouse_signal_(event);
1154  if (Interactor->GetRepeatCount()) mouse_signal_(event);
1155 
1156  if (Interactor->GetAltKey()) {
1157  // zoom
1158  vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
1159  double opening_angle = cam->GetViewAngle();
1160  if (opening_angle > 15.0) opening_angle -= 1.0;
1161 
1162  cam->SetViewAngle(opening_angle);
1163  cam->Modified();
1164  CurrentRenderer->SetActiveCamera(cam);
1165  CurrentRenderer->ResetCameraClippingRange();
1166  CurrentRenderer->Modified();
1167  CurrentRenderer->Render();
1168  rens_->Render();
1169  Interactor->Render();
1170  } else
1171  vtkInteractorStyleRubberBandPick::OnMouseWheelForward();
1172 }
1173 
1176  int x = this->Interactor->GetEventPosition()[0];
1177  int y = this->Interactor->GetEventPosition()[1];
1178  pcl::visualization::MouseEvent event(
1179  pcl::visualization::MouseEvent::MouseScrollDown,
1180  pcl::visualization::MouseEvent::VScroll, x, y,
1181  Interactor->GetAltKey(), Interactor->GetControlKey(),
1182  Interactor->GetShiftKey(),
1183  vtkInteractorStyleRubberBandPick::CurrentMode);
1184  mouse_signal_(event);
1185  if (Interactor->GetRepeatCount()) mouse_signal_(event);
1186 
1187  if (Interactor->GetAltKey()) {
1188  // zoom
1189  vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
1190  double opening_angle = cam->GetViewAngle();
1191  if (opening_angle < 170.0) opening_angle += 1.0;
1192 
1193  cam->SetViewAngle(opening_angle);
1194  cam->Modified();
1195  CurrentRenderer->SetActiveCamera(cam);
1196  CurrentRenderer->ResetCameraClippingRange();
1197  CurrentRenderer->Modified();
1198  CurrentRenderer->Render();
1199  rens_->Render();
1200  Interactor->Render();
1201  } else
1202  vtkInteractorStyleRubberBandPick::OnMouseWheelBackward();
1203 }
1204 
1205 //-------------------------------------------------------------------------
1207  if (!this->CurrentRenderer) {
1208  return;
1209  }
1210 
1211  vtkLight* light;
1212 
1213  vtkLightCollection* lights = this->CurrentRenderer->GetLights();
1214  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
1215 
1216  lights->InitTraversal();
1217  light = lights->GetNextItem();
1218  if (!light) {
1219  return;
1220  }
1221  light->SetPosition(camera->GetPosition());
1222  light->SetFocalPoint(camera->GetFocalPoint());
1223 }
1224 
1225 //-------------------------------------------------------------------------
1227  int shift,
1228  int control) {
1229  // Must not be processing an interaction to start another.
1230  if (this->CurrentManipulator) {
1231  return;
1232  }
1233 
1234  // Get the renderer.
1235  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
1236  this->Interactor->GetEventPosition()[1]);
1237  if (this->CurrentRenderer == NULL) {
1238  return;
1239  }
1240 
1241  // Look for a matching camera interactor.
1242  this->CurrentManipulator = this->FindManipulator(button, shift, control);
1243  if (this->CurrentManipulator) {
1244  this->CurrentManipulator->Register(this);
1245  this->InvokeEvent(vtkCommand::StartInteractionEvent);
1246  this->CurrentManipulator->SetCenter(this->CenterOfRotation);
1247  this->CurrentManipulator->SetRotationFactor(this->RotationFactor);
1250  this->Interactor->GetEventPosition()[0],
1251  this->Interactor->GetEventPosition()[1], this->CurrentRenderer,
1252  this->Interactor);
1253  }
1254 }
1255 
1256 //-------------------------------------------------------------------------
1258  if (this->CurrentManipulator == NULL) {
1259  return;
1260  }
1261  if (this->CurrentManipulator->GetButton() == button) {
1263  this->Interactor->GetEventPosition()[0],
1264  this->Interactor->GetEventPosition()[1], this->CurrentRenderer,
1265  this->Interactor);
1267  this->InvokeEvent(vtkCommand::EndInteractionEvent);
1268  this->CurrentManipulator->UnRegister(this);
1269  this->CurrentManipulator = NULL;
1270  }
1271 }
1272 
1273 //-------------------------------------------------------------------------
1275  int shift,
1276  int control) {
1277  // Look for a matching camera interactor.
1278  this->CameraManipulators->InitTraversal();
1279  vtkCameraManipulator* manipulator = NULL;
1280  while ((manipulator = (vtkCameraManipulator*)this->CameraManipulators
1281  ->GetNextItemAsObject())) {
1282  if (manipulator->GetButton() == button &&
1283  manipulator->GetShift() == shift &&
1284  manipulator->GetControl() == control) {
1285  return manipulator;
1286  }
1287  }
1288  return NULL;
1289 }
1290 
1292  if (this->Interactor->GetControlKey()) {
1294  fact, this->Interactor->GetEventPosition(),
1295  this->CurrentRenderer);
1296  } else {
1297  this->vtkInteractorStyleRubberBandPick::Dolly(fact);
1298  }
1299 }
1300 
1301 //-------------------------------------------------------------------------
1303  int* position,
1304  vtkRenderer* renderer) {
1305  vtkCamera* cam = renderer->GetActiveCamera();
1306  if (cam->GetParallelProjection()) {
1307  int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
1308  // Zoom relatively to the cursor
1309  int* aSize = renderer->GetRenderWindow()->GetSize();
1310  int w = aSize[0];
1311  int h = aSize[1];
1312  x0 = w / 2;
1313  y0 = h / 2;
1314  x1 = position[0];
1315  y1 = position[1];
1316  vtkCustomInteractorStyle::TranslateCamera(renderer, x0, y0, x1, y1);
1317  cam->SetParallelScale(cam->GetParallelScale() / fact);
1318  vtkCustomInteractorStyle::TranslateCamera(renderer, x1, y1, x0, y0);
1319  } else {
1320  // Zoom relatively to the cursor position
1321  double viewFocus[4], originalViewFocus[3], cameraPos[3],
1322  newCameraPos[3];
1323  double newFocalPoint[4], norm[3];
1324 
1325  // Move focal point to cursor position
1326  cam->GetPosition(cameraPos);
1327  cam->GetFocalPoint(viewFocus);
1328  cam->GetFocalPoint(originalViewFocus);
1329  cam->GetViewPlaneNormal(norm);
1330 
1331  vtkCustomInteractorStyle::ComputeWorldToDisplay(
1332  renderer, viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
1333 
1334  vtkCustomInteractorStyle::ComputeDisplayToWorld(
1335  renderer, double(position[0]), double(position[1]),
1336  viewFocus[2], newFocalPoint);
1337 
1338  cam->SetFocalPoint(newFocalPoint);
1339 
1340  // Move camera in/out along projection direction
1341  cam->Dolly(fact);
1342 
1343  // Find new focal point
1344  cam->GetPosition(newCameraPos);
1345 
1346  double newPoint[3];
1347  newPoint[0] = originalViewFocus[0] + newCameraPos[0] - cameraPos[0];
1348  newPoint[1] = originalViewFocus[1] + newCameraPos[1] - cameraPos[1];
1349  newPoint[2] = originalViewFocus[2] + newCameraPos[2] - cameraPos[2];
1350 
1351  cam->SetFocalPoint(newPoint);
1352  }
1353 }
1354 
1355 //-------------------------------------------------------------------------
1357  vtkRenderer* renderer, int toX, int toY, int fromX, int fromY) {
1358  vtkCamera* cam = renderer->GetActiveCamera();
1359  double viewFocus[4], focalDepth, viewPoint[3];
1360  double newPickPoint[4], oldPickPoint[4], motionVector[3];
1361  cam->GetFocalPoint(viewFocus);
1362 
1363  vtkCustomInteractorStyle::ComputeWorldToDisplay(
1364  renderer, viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
1365  focalDepth = viewFocus[2];
1366 
1367  vtkCustomInteractorStyle::ComputeDisplayToWorld(
1368  renderer, double(toX), double(toY), focalDepth, newPickPoint);
1369  vtkCustomInteractorStyle::ComputeDisplayToWorld(
1370  renderer, double(fromX), double(fromY), focalDepth, oldPickPoint);
1371 
1372  // camera motion is reversed
1373  motionVector[0] = oldPickPoint[0] - newPickPoint[0];
1374  motionVector[1] = oldPickPoint[1] - newPickPoint[1];
1375  motionVector[2] = oldPickPoint[2] - newPickPoint[2];
1376 
1377  cam->GetFocalPoint(viewFocus);
1378  cam->GetPosition(viewPoint);
1379  cam->SetFocalPoint(motionVector[0] + viewFocus[0],
1380  motionVector[1] + viewFocus[1],
1381  motionVector[2] + viewFocus[2]);
1382 
1383  cam->SetPosition(motionVector[0] + viewPoint[0],
1384  motionVector[1] + viewPoint[1],
1385  motionVector[2] + viewPoint[2]);
1386 }
1387 
1389 // Update the look up table displayed when 'u' is pressed
1391  pcl::visualization::CloudActorMap::iterator am_it;
1392  pcl::visualization::ShapeActorMap::iterator sm_it;
1393  bool actor_found = false;
1394 
1395  if (!lut_enabled_ && !add_lut) return;
1396 
1397  if (lut_actor_id_ != "") // Search if provided actor id is in
1398  // CloudActorMap or ShapeActorMap
1399  {
1400  am_it = cloud_actors_->find(lut_actor_id_);
1401  if (am_it == cloud_actors_->end()) {
1402  sm_it = shape_actors_->find(lut_actor_id_);
1403  if (sm_it == shape_actors_->end()) {
1404  PCL_WARN(
1405  "[updateLookUpTableDisplay] Could not find any "
1406  "actor "
1407  "with id <%s>!",
1408  lut_actor_id_.c_str());
1409  if (lut_enabled_) { // Remove LUT and exit
1410  CurrentRenderer->RemoveActor(lut_actor_);
1411  lut_enabled_ = false;
1412  }
1413  return;
1414  }
1415 
1416  // ShapeActor found
1417  vtkSmartPointer<vtkProp>* act = &(*sm_it).second;
1418  vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(*act);
1419  if (!actor ||
1420  !actor->GetMapper()->GetInput()->GetPointData()->GetScalars()) {
1421  PCL_WARN(
1422  "[updateLookUpTableDisplay] id <%s> does not hold "
1423  "any "
1424  "color information!",
1425  lut_actor_id_.c_str());
1426  if (lut_enabled_) { // Remove LUT and exit
1427  CurrentRenderer->RemoveActor(lut_actor_);
1428  lut_enabled_ = false;
1429  }
1430  return;
1431  }
1432 
1433  lut_actor_->SetLookupTable(actor->GetMapper()->GetLookupTable());
1434  lut_actor_->Modified();
1435  actor_found = true;
1436  } else {
1437  // CloudActor
1438  pcl::visualization::CloudActor* act = &(*am_it).second;
1439  if (!act->actor->GetMapper()->GetLookupTable() &&
1440  !act->actor->GetMapper()
1441  ->GetInput()
1442  ->GetPointData()
1443  ->GetScalars()) {
1444  PCL_WARN(
1445  "[updateLookUpTableDisplay] id <%s> does not hold "
1446  "any "
1447  "color information!",
1448  lut_actor_id_.c_str());
1449  if (lut_enabled_) { // Remove LUT and exit
1450  CurrentRenderer->RemoveActor(lut_actor_);
1451  lut_enabled_ = false;
1452  }
1453  return;
1454  }
1455 
1456  vtkScalarsToColors* lut = act->actor->GetMapper()->GetLookupTable();
1457  lut_actor_->SetLookupTable(lut);
1458  lut_actor_->Modified();
1459  actor_found = true;
1460  }
1461  } else // lut_actor_id_ == "", the user did not specify which
1462  // cloud/shape LUT should be displayed
1463  // Circling through all clouds/shapes and displaying first LUT found
1464  {
1465  for (am_it = cloud_actors_->begin(); am_it != cloud_actors_->end();
1466  ++am_it) {
1467  pcl::visualization::CloudActor* act = &(*am_it).second;
1468  if (!act->actor->GetMapper()->GetLookupTable()) continue;
1469 
1470  if (!act->actor->GetMapper()
1471  ->GetInput()
1472  ->GetPointData()
1473  ->GetScalars())
1474  continue;
1475 
1476  vtkScalarsToColors* lut = act->actor->GetMapper()->GetLookupTable();
1477  lut_actor_->SetLookupTable(lut);
1478  lut_actor_->Modified();
1479  actor_found = true;
1480  break;
1481  }
1482 
1483  if (!actor_found) {
1484  for (sm_it = shape_actors_->begin(); sm_it != shape_actors_->end();
1485  ++sm_it) {
1486  vtkSmartPointer<vtkProp>* act = &(*sm_it).second;
1487  vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(*act);
1488  if (!actor) continue;
1489 
1490  if (!actor->GetMapper()
1491  ->GetInput()
1492  ->GetPointData()
1493  ->GetScalars()) // Check if actor has scalars
1494  continue;
1495  lut_actor_->SetLookupTable(
1496  actor->GetMapper()->GetLookupTable());
1497  lut_actor_->Modified();
1498  actor_found = true;
1499  break;
1500  }
1501  }
1502  }
1503 
1504  if ((!actor_found && lut_enabled_) ||
1505  (lut_enabled_ && add_lut)) // Remove actor
1506  {
1507  CurrentRenderer->RemoveActor(lut_actor_);
1508  lut_enabled_ = false;
1509  } else if (!lut_enabled_ && add_lut && actor_found) // Add actor
1510  {
1511  CurrentRenderer->AddActor(lut_actor_);
1512  lut_actor_->SetVisibility(true);
1513  lut_enabled_ = true;
1514  } else if (lut_enabled_) // Update actor (if displayed)
1515  {
1516  CurrentRenderer->RemoveActor(lut_actor_);
1517  CurrentRenderer->AddActor(lut_actor_);
1518  } else
1519  return;
1520 
1521  CurrentRenderer->Render();
1522  return;
1523 }
1524 
1525 //-------------------------------------------------------------------------
1526 void vtkCustomInteractorStyle::PrintSelf(ostream& os, vtkIndent indent) {
1527  this->vtkInteractorStyleRubberBandPick::PrintSelf(os, indent);
1528  os << indent << "CenterOfRotation: " << this->CenterOfRotation[0] << ", "
1529  << this->CenterOfRotation[1] << ", " << this->CenterOfRotation[2]
1530  << endl;
1531  os << indent << "RotationFactor: " << this->RotationFactor << endl;
1532  os << indent << "CameraManipulators: " << this->CameraManipulators << endl;
1533 }
1534 
1535 } // namespace VTKExtensions
1536 
1537 namespace VTKExtensions {
1538 // Standard VTK macro for *New ()
1540 } // namespace VTKExtensions
MouseEvent event
int points
math::float3 position
#define NULL
static bool Print(const char *format,...)
Prints out a formatted message in console.
Definition: CVLog.cpp:113
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
vtkCustomInteractorStyle defines an unique, custom VTK based interactory style for PCL Visualizer app...
virtual ~vtkCustomInteractorStyle() override
Empty destructor.
virtual void OnChar() override
Interactor style internal method. Gets called whenever a key is pressed.
void zoomOut()
Interactor style internal method. Zoom out.
void zoomIn()
Interactor style internal method. Zoom in.
std::string lut_actor_id_
ID used to fetch/display the look up table on the visualizer It should be set by PCLVisualizer setLoo...
void OnButtonDown(int button, int shift, int control)
static void DollyToPosition(double fact, int *position, vtkRenderer *renderer)
static void TranslateCamera(vtkRenderer *renderer, int toX, int toY, int fromX, int fromY)
void PrintSelf(ostream &os, vtkIndent indent) override
virtual vtkCameraManipulator * FindManipulator(int button, int shift, int control)
void updateLookUpTableDisplay(bool add_lut=false)
Add/remove the look up table displayed when 'u' is pressed, can also be used to update the current LU...
virtual void OnButtonUp(int x, int y, vtkRenderer *ren, vtkRenderWindowInteractor *iren)
virtual void OnMouseMove(int x, int y, vtkRenderer *ren, vtkRenderWindowInteractor *iren)
virtual void OnButtonDown(int x, int y, vtkRenderer *ren, vtkRenderWindowInteractor *iren)
virtual void OnKeyDown(vtkRenderWindowInteractor *iren)
virtual void OnKeyUp(vtkRenderWindowInteractor *iren)
GraphType data
Definition: graph_cut.cc:138
normal_z y
normal_z x
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
vtkStandardNewMacro(vtkCustomInteractorStyle)
static const std::string path
Definition: PointCloud.cpp:59
bool FileExists(const std::string &filename)
Definition: FileSystem.cpp:524
constexpr Rgbaf light(0.66f, 0.66f, 0.66f, 1.00f)
#define VTKISRBP_SELECT
#define SELECT_MODE
#define ORIENT_MODE