Point Cloud Library (PCL)  1.11.1-dev
pcl_visualizer.hpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2012, Open Perception, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #ifndef PCL_PCL_VISUALIZER_IMPL_H_
39 #define PCL_PCL_VISUALIZER_IMPL_H_
40 
41 #include <vtkVersion.h>
42 #include <vtkSmartPointer.h>
43 #include <vtkCellArray.h>
44 #include <vtkLeaderActor2D.h>
45 #include <vtkVectorText.h>
46 #include <vtkAlgorithmOutput.h>
47 #include <vtkFollower.h>
48 #include <vtkMath.h>
49 #include <vtkSphereSource.h>
50 #include <vtkProperty2D.h>
51 #include <vtkDataSetSurfaceFilter.h>
52 #include <vtkPointData.h>
53 #include <vtkPolyDataMapper.h>
54 #include <vtkProperty.h>
55 #include <vtkMapper.h>
56 #include <vtkCellData.h>
57 #include <vtkDataSetMapper.h>
58 #include <vtkRenderer.h>
59 #include <vtkRendererCollection.h>
60 #include <vtkAppendPolyData.h>
61 #include <vtkTextProperty.h>
62 #include <vtkLODActor.h>
63 #include <vtkLineSource.h>
64 
66 
67 // Support for VTK 7.1 upwards
68 #ifdef vtkGenericDataArray_h
69 #define SetTupleValue SetTypedTuple
70 #define InsertNextTupleValue InsertNextTypedTuple
71 #define GetTupleValue GetTypedTuple
72 #endif
73 
74 //////////////////////////////////////////////////////////////////////////////////////////////
75 template <typename PointT> bool
77  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
78  const std::string &id, int viewport)
79 {
80  // Convert the PointCloud to VTK PolyData
81  PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud);
82  return (addPointCloud<PointT> (cloud, geometry_handler, id, viewport));
83 }
84 
85 //////////////////////////////////////////////////////////////////////////////////////////////
86 template <typename PointT> bool
88  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
89  const PointCloudGeometryHandler<PointT> &geometry_handler,
90  const std::string &id, int viewport)
91 {
92  if (contains (id))
93  {
94  PCL_WARN ("[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
95  return (false);
96  }
97 
98  if (pcl::traits::has_color<PointT>())
99  {
100  PointCloudColorHandlerRGBField<PointT> color_handler_rgb_field (cloud);
101  return (fromHandlersToScreen (geometry_handler, color_handler_rgb_field, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
102  }
103  PointCloudColorHandlerCustom<PointT> color_handler (cloud, 255, 255, 255);
104  return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
105 }
106 
107 //////////////////////////////////////////////////////////////////////////////////////////////
108 template <typename PointT> bool
110  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
111  const GeometryHandlerConstPtr &geometry_handler,
112  const std::string &id, int viewport)
113 {
114  if (contains (id))
115  {
116  // Here we're just pushing the handlers onto the queue. If needed, something fancier could
117  // be done such as checking if a specific handler already exists, etc.
118  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
119  am_it->second.geometry_handlers.push_back (geometry_handler);
120  return (true);
121  }
122 
123  //PointCloudColorHandlerRandom<PointT> color_handler (cloud);
124  PointCloudColorHandlerCustom<PointT> color_handler (cloud, 255, 255, 255);
125  return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
126 }
127 
128 //////////////////////////////////////////////////////////////////////////////////////////////
129 template <typename PointT> bool
131  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
132  const PointCloudColorHandler<PointT> &color_handler,
133  const std::string &id, int viewport)
134 {
135  if (contains (id))
136  {
137  PCL_WARN ("[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
138 
139  // Here we're just pushing the handlers onto the queue. If needed, something fancier could
140  // be done such as checking if a specific handler already exists, etc.
141  //cloud_actor_map_[id].color_handlers.push_back (color_handler);
142  //style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_));
143  return (false);
144  }
145  // Convert the PointCloud to VTK PolyData
146  PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud);
147  return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
148 }
149 
150 //////////////////////////////////////////////////////////////////////////////////////////////
151 template <typename PointT> bool
153  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
154  const ColorHandlerConstPtr &color_handler,
155  const std::string &id, int viewport)
156 {
157  // Check to see if this entry already exists (has it been already added to the visualizer?)
158  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
159  if (am_it != cloud_actor_map_->end ())
160  {
161  // Here we're just pushing the handlers onto the queue. If needed, something fancier could
162  // be done such as checking if a specific handler already exists, etc.
163  am_it->second.color_handlers.push_back (color_handler);
164  return (true);
165  }
166 
167  PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud);
168  return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
169 }
170 
171 //////////////////////////////////////////////////////////////////////////////////////////////
172 template <typename PointT> bool
174  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
175  const GeometryHandlerConstPtr &geometry_handler,
176  const ColorHandlerConstPtr &color_handler,
177  const std::string &id, int viewport)
178 {
179  // Check to see if this entry already exists (has it been already added to the visualizer?)
180  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
181  if (am_it != cloud_actor_map_->end ())
182  {
183  // Here we're just pushing the handlers onto the queue. If needed, something fancier could
184  // be done such as checking if a specific handler already exists, etc.
185  am_it->second.geometry_handlers.push_back (geometry_handler);
186  am_it->second.color_handlers.push_back (color_handler);
187  return (true);
188  }
189  return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
190 }
191 
192 //////////////////////////////////////////////////////////////////////////////////////////////
193 template <typename PointT> bool
195  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
196  const PointCloudColorHandler<PointT> &color_handler,
197  const PointCloudGeometryHandler<PointT> &geometry_handler,
198  const std::string &id, int viewport)
199 {
200  if (contains (id))
201  {
202  PCL_WARN ("[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
203  // Here we're just pushing the handlers onto the queue. If needed, something fancier could
204  // be done such as checking if a specific handler already exists, etc.
205  //cloud_actor_map_[id].geometry_handlers.push_back (geometry_handler);
206  //cloud_actor_map_[id].color_handlers.push_back (color_handler);
207  //style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_));
208  return (false);
209  }
210  return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
211 }
212 
213 //////////////////////////////////////////////////////////////////////////////////////////////
214 template <typename PointT> void
215 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
216  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
219 {
221  if (!polydata)
222  {
223  allocVtkPolyData (polydata);
225  polydata->SetVerts (vertices);
226  }
227 
228  // Create the supporting structures
229  vertices = polydata->GetVerts ();
230  if (!vertices)
232 
233  vtkIdType nr_points = cloud->size ();
234  // Create the point set
235  vtkSmartPointer<vtkPoints> points = polydata->GetPoints ();
236  if (!points)
237  {
239  points->SetDataTypeToFloat ();
240  polydata->SetPoints (points);
241  }
242  points->SetNumberOfPoints (nr_points);
243 
244  // Get a pointer to the beginning of the data array
245  float *data = (static_cast<vtkFloatArray*> (points->GetData ()))->GetPointer (0);
246 
247  // Set the points
248  vtkIdType ptr = 0;
249  if (cloud->is_dense)
250  {
251  for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
252  std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
253  }
254  else
255  {
256  vtkIdType j = 0; // true point index
257  for (vtkIdType i = 0; i < nr_points; ++i)
258  {
259  // Check if the point is invalid
260  if (!std::isfinite ((*cloud)[i].x) ||
261  !std::isfinite ((*cloud)[i].y) ||
262  !std::isfinite ((*cloud)[i].z))
263  continue;
264 
265  std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
266  j++;
267  ptr += 3;
268  }
269  nr_points = j;
270  points->SetNumberOfPoints (nr_points);
271  }
272 
273  vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
274  updateCells (cells, initcells, nr_points);
275 
276  // Set the cells and the vertices
277  vertices->SetCells (nr_points, cells);
278  // Set the cell count explicitly as the array doesn't get modified enough so the above method updates accordingly. See #4001 and #3452
279  vertices->SetNumberOfCells(nr_points);
280 }
281 
282 //////////////////////////////////////////////////////////////////////////////////////////////
283 template <typename PointT> void
284 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
288 {
290  if (!polydata)
291  {
292  allocVtkPolyData (polydata);
294  polydata->SetVerts (vertices);
295  }
296 
297  // Use the handler to obtain the geometry
299  geometry_handler.getGeometry (points);
300  polydata->SetPoints (points);
301 
302  vtkIdType nr_points = points->GetNumberOfPoints ();
303 
304  // Create the supporting structures
305  vertices = polydata->GetVerts ();
306  if (!vertices)
308 
309  vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
310  updateCells (cells, initcells, nr_points);
311  // Set the cells and the vertices
312  vertices->SetCells (nr_points, cells);
313 }
314 
315 ////////////////////////////////////////////////////////////////////////////////////////////
316 template <typename PointT> bool
318  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
319  double r, double g, double b, const std::string &id, int viewport)
320 {
321  vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (cloud);
322  if (!data)
323  return (false);
324 
325  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
326  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
327  if (am_it != shape_actor_map_->end ())
328  {
330 
331  // Add old data
332  all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
333 
334  // Add new data
336  surface_filter->AddInputData (vtkUnstructuredGrid::SafeDownCast (data));
337  vtkSmartPointer<vtkPolyData> poly_data = surface_filter->GetOutput ();
338  all_data->AddInputData (poly_data);
339 
340  // Create an Actor
342  createActorFromVTKDataSet (all_data->GetOutput (), actor);
343  actor->GetProperty ()->SetRepresentationToWireframe ();
344  actor->GetProperty ()->SetColor (r, g, b);
345  actor->GetMapper ()->ScalarVisibilityOff ();
346  removeActorFromRenderer (am_it->second, viewport);
347  addActorToRenderer (actor, viewport);
348 
349  // Save the pointer/ID pair to the global actor map
350  (*shape_actor_map_)[id] = actor;
351  }
352  else
353  {
354  // Create an Actor
356  createActorFromVTKDataSet (data, actor);
357  actor->GetProperty ()->SetRepresentationToWireframe ();
358  actor->GetProperty ()->SetColor (r, g, b);
359  actor->GetMapper ()->ScalarVisibilityOff ();
360  addActorToRenderer (actor, viewport);
361 
362  // Save the pointer/ID pair to the global actor map
363  (*shape_actor_map_)[id] = actor;
364  }
365 
366  return (true);
367 }
368 
369 ////////////////////////////////////////////////////////////////////////////////////////////
370 template <typename PointT> bool
372  const pcl::PlanarPolygon<PointT> &polygon,
373  double r, double g, double b, const std::string &id, int viewport)
374 {
375  vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (polygon);
376  if (!data)
377  return (false);
378 
379  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
380  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
381  if (am_it != shape_actor_map_->end ())
382  {
384 
385  // Add old data
386  all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
387 
388  // Add new data
390  surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
391  vtkSmartPointer<vtkPolyData> poly_data = surface_filter->GetOutput ();
392  all_data->AddInputData (poly_data);
393 
394  // Create an Actor
396  createActorFromVTKDataSet (all_data->GetOutput (), actor);
397  actor->GetProperty ()->SetRepresentationToWireframe ();
398  actor->GetProperty ()->SetColor (r, g, b);
399  actor->GetMapper ()->ScalarVisibilityOn ();
400  actor->GetProperty ()->BackfaceCullingOff ();
401  removeActorFromRenderer (am_it->second, viewport);
402  addActorToRenderer (actor, viewport);
403 
404  // Save the pointer/ID pair to the global actor map
405  (*shape_actor_map_)[id] = actor;
406  }
407  else
408  {
409  // Create an Actor
411  createActorFromVTKDataSet (data, actor);
412  actor->GetProperty ()->SetRepresentationToWireframe ();
413  actor->GetProperty ()->SetColor (r, g, b);
414  actor->GetMapper ()->ScalarVisibilityOn ();
415  actor->GetProperty ()->BackfaceCullingOff ();
416  addActorToRenderer (actor, viewport);
417 
418  // Save the pointer/ID pair to the global actor map
419  (*shape_actor_map_)[id] = actor;
420  }
421  return (true);
422 }
423 
424 ////////////////////////////////////////////////////////////////////////////////////////////
425 template <typename PointT> bool
427  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
428  const std::string &id, int viewport)
429 {
430  return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5, id, viewport));
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////////////////
434 template <typename P1, typename P2> bool
435 pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport)
436 {
437  if (contains (id))
438  {
439  PCL_WARN ("[addLine] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
440  return (false);
441  }
442 
443  vtkSmartPointer<vtkDataSet> data = createLine (pt1.getVector4fMap (), pt2.getVector4fMap ());
444 
445  // Create an Actor
447  createActorFromVTKDataSet (data, actor);
448  actor->GetProperty ()->SetRepresentationToWireframe ();
449  actor->GetProperty ()->SetColor (r, g, b);
450  actor->GetMapper ()->ScalarVisibilityOff ();
451  addActorToRenderer (actor, viewport);
452 
453  // Save the pointer/ID pair to the global actor map
454  (*shape_actor_map_)[id] = actor;
455  return (true);
456 }
457 
458 ////////////////////////////////////////////////////////////////////////////////////////////
459 template <typename P1, typename P2> bool
460 pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport)
461 {
462  if (contains (id))
463  {
464  PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
465  return (false);
466  }
467 
468  // Create an Actor
470  leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
471  leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
472  leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
473  leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
474  leader->SetArrowStyleToFilled ();
475  leader->AutoLabelOn ();
476 
477  leader->GetProperty ()->SetColor (r, g, b);
478  addActorToRenderer (leader, viewport);
479 
480  // Save the pointer/ID pair to the global actor map
481  (*shape_actor_map_)[id] = leader;
482  return (true);
483 }
484 
485 ////////////////////////////////////////////////////////////////////////////////////////////
486 template <typename P1, typename P2> bool
487 pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, bool display_length, const std::string &id, int viewport)
488 {
489  if (contains (id))
490  {
491  PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
492  return (false);
493  }
494 
495  // Create an Actor
497  leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
498  leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
499  leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
500  leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
501  leader->SetArrowStyleToFilled ();
502  leader->SetArrowPlacementToPoint1 ();
503  if (display_length)
504  leader->AutoLabelOn ();
505  else
506  leader->AutoLabelOff ();
507 
508  leader->GetProperty ()->SetColor (r, g, b);
509  addActorToRenderer (leader, viewport);
510 
511  // Save the pointer/ID pair to the global actor map
512  (*shape_actor_map_)[id] = leader;
513  return (true);
514 }
515 ////////////////////////////////////////////////////////////////////////////////////////////
516 template <typename P1, typename P2> bool
517 pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2,
518  double r_line, double g_line, double b_line,
519  double r_text, double g_text, double b_text,
520  const std::string &id, int viewport)
521 {
522  if (contains (id))
523  {
524  PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
525  return (false);
526  }
527 
528  // Create an Actor
530  leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
531  leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
532  leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
533  leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
534  leader->SetArrowStyleToFilled ();
535  leader->AutoLabelOn ();
536 
537  leader->GetLabelTextProperty()->SetColor(r_text, g_text, b_text);
538 
539  leader->GetProperty ()->SetColor (r_line, g_line, b_line);
540  addActorToRenderer (leader, viewport);
541 
542  // Save the pointer/ID pair to the global actor map
543  (*shape_actor_map_)[id] = leader;
544  return (true);
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////////////////
548 template <typename P1, typename P2> bool
549 pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, const std::string &id, int viewport)
550 {
551  return (!addLine (pt1, pt2, 0.5, 0.5, 0.5, id, viewport));
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////////////////
555 template <typename PointT> bool
556 pcl::visualization::PCLVisualizer::addSphere (const PointT &center, double radius, double r, double g, double b, const std::string &id, int viewport)
557 {
558  if (contains (id))
559  {
560  PCL_WARN ("[addSphere] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
561  return (false);
562  }
563 
565  data->SetRadius (radius);
566  data->SetCenter (double (center.x), double (center.y), double (center.z));
567  data->SetPhiResolution (10);
568  data->SetThetaResolution (10);
569  data->LatLongTessellationOff ();
570  data->Update ();
571 
572  // Setup actor and mapper
574  mapper->SetInputConnection (data->GetOutputPort ());
575 
576  // Create an Actor
578  actor->SetMapper (mapper);
579  //createActorFromVTKDataSet (data, actor);
580  actor->GetProperty ()->SetRepresentationToSurface ();
581  actor->GetProperty ()->SetInterpolationToFlat ();
582  actor->GetProperty ()->SetColor (r, g, b);
583 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
584  actor->GetMapper ()->ImmediateModeRenderingOn ();
585 #endif
586  actor->GetMapper ()->StaticOn ();
587  actor->GetMapper ()->ScalarVisibilityOff ();
588  actor->GetMapper ()->Update ();
589  addActorToRenderer (actor, viewport);
590 
591  // Save the pointer/ID pair to the global actor map
592  (*shape_actor_map_)[id] = actor;
593  return (true);
594 }
595 
596 ////////////////////////////////////////////////////////////////////////////////////////////
597 template <typename PointT> bool
598 pcl::visualization::PCLVisualizer::addSphere (const PointT &center, double radius, const std::string &id, int viewport)
599 {
600  return (addSphere (center, radius, 0.5, 0.5, 0.5, id, viewport));
601 }
602 
603 ////////////////////////////////////////////////////////////////////////////////////////////
604 template<typename PointT> bool
605 pcl::visualization::PCLVisualizer::updateSphere (const PointT &center, double radius, double r, double g, double b, const std::string &id)
606 {
607  if (!contains (id))
608  {
609  return (false);
610  }
611 
612  //////////////////////////////////////////////////////////////////////////
613  // Get the actor pointer
614  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
615  vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
616  if (!actor)
617  return (false);
618  vtkAlgorithm *algo = actor->GetMapper ()->GetInputAlgorithm ();
619  vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo);
620  if (!src)
621  return (false);
622 
623  src->SetCenter (double (center.x), double (center.y), double (center.z));
624  src->SetRadius (radius);
625  src->Update ();
626  actor->GetProperty ()->SetColor (r, g, b);
627  actor->Modified ();
628 
629  return (true);
630 }
631 
632 //////////////////////////////////////////////////
633 template <typename PointT> bool
635  const std::string &text,
636  const PointT& position,
637  double textScale,
638  double r,
639  double g,
640  double b,
641  const std::string &id,
642  int viewport)
643 {
644  std::string tid;
645  if (id.empty ())
646  tid = text;
647  else
648  tid = id;
649 
650  if (viewport < 0)
651  return false;
652 
653  // If there is no custom viewport and the viewport number is not 0, exit
654  if (rens_->GetNumberOfItems () <= viewport)
655  {
656  PCL_ERROR ("[addText3D] The viewport [%d] doesn't exist (id <%s>)! \n",
657  viewport,
658  tid.c_str ());
659  return false;
660  }
661 
662  // check all or an individual viewport for a similar id
663  rens_->InitTraversal ();
664  for (std::size_t i = viewport; rens_->GetNextItem (); ++i)
665  {
666  const std::string uid = tid + std::string (i, '*');
667  if (contains (uid))
668  {
669  PCL_ERROR ( "[addText3D] The id <%s> already exists in viewport [%d]! \n"
670  "Please choose a different id and retry.\n",
671  tid.c_str (),
672  i);
673  return false;
674  }
675 
676  if (viewport > 0)
677  break;
678  }
679 
681  textSource->SetText (text.c_str());
682  textSource->Update ();
683 
685  textMapper->SetInputConnection (textSource->GetOutputPort ());
686 
687  // Since each follower may follow a different camera, we need different followers
688  rens_->InitTraversal ();
689  vtkRenderer* renderer;
690  int i = 0;
691  while ((renderer = rens_->GetNextItem ()))
692  {
693  // Should we add the actor to all renderers or just to i-nth renderer?
694  if (viewport == 0 || viewport == i)
695  {
697  textActor->SetMapper (textMapper);
698  textActor->SetPosition (position.x, position.y, position.z);
699  textActor->SetScale (textScale);
700  textActor->GetProperty ()->SetColor (r, g, b);
701  textActor->SetCamera (renderer->GetActiveCamera ());
702 
703  renderer->AddActor (textActor);
704  renderer->Render ();
705 
706  // Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers
707  // for multiple viewport
708  const std::string uid = tid + std::string (i, '*');
709  (*shape_actor_map_)[uid] = textActor;
710  }
711 
712  ++i;
713  }
714 
715  return (true);
716 }
717 
718 //////////////////////////////////////////////////
719 template <typename PointT> bool
721  const std::string &text,
722  const PointT& position,
723  double orientation[3],
724  double textScale,
725  double r,
726  double g,
727  double b,
728  const std::string &id,
729  int viewport)
730 {
731  std::string tid;
732  if (id.empty ())
733  tid = text;
734  else
735  tid = id;
736 
737  if (viewport < 0)
738  return false;
739 
740  // If there is no custom viewport and the viewport number is not 0, exit
741  if (rens_->GetNumberOfItems () <= viewport)
742  {
743  PCL_ERROR ("[addText3D] The viewport [%d] doesn't exist (id <%s>)!\n",
744  viewport,
745  tid.c_str ());
746  return false;
747  }
748 
749  // check all or an individual viewport for a similar id
750  rens_->InitTraversal ();
751  for (std::size_t i = viewport; rens_->GetNextItem (); ++i)
752  {
753  const std::string uid = tid + std::string (i, '*');
754  if (contains (uid))
755  {
756  PCL_ERROR ( "[addText3D] The id <%s> already exists in viewport [%d]! "
757  "Please choose a different id and retry.\n",
758  tid.c_str (),
759  i);
760  return false;
761  }
762 
763  if (viewport > 0)
764  break;
765  }
766 
768  textSource->SetText (text.c_str());
769  textSource->Update ();
770 
772  textMapper->SetInputConnection (textSource->GetOutputPort ());
773 
775  textActor->SetMapper (textMapper);
776  textActor->SetPosition (position.x, position.y, position.z);
777  textActor->SetScale (textScale);
778  textActor->GetProperty ()->SetColor (r, g, b);
779  textActor->SetOrientation (orientation);
780 
781  // Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers
782  rens_->InitTraversal ();
783  int i = 0;
784  for ( vtkRenderer* renderer = rens_->GetNextItem ();
785  renderer;
786  renderer = rens_->GetNextItem (), ++i)
787  {
788  if (viewport == 0 || viewport == i)
789  {
790  renderer->AddActor (textActor);
791  const std::string uid = tid + std::string (i, '*');
792  (*shape_actor_map_)[uid] = textActor;
793  }
794  }
795 
796  return (true);
797 }
798 
799 //////////////////////////////////////////////////////////////////////////////////////////////
800 template <typename PointNT> bool
802  const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
803  int level, float scale, const std::string &id, int viewport)
804 {
805  return (addPointCloudNormals<PointNT, PointNT> (cloud, cloud, level, scale, id, viewport));
806 }
807 
808 //////////////////////////////////////////////////////////////////////////////////////////////
809 template <typename PointT, typename PointNT> bool
811  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
812  const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
813  int level, float scale,
814  const std::string &id, int viewport)
815 {
816  if (normals->size () != cloud->size ())
817  {
818  PCL_ERROR ("[addPointCloudNormals] The number of points differs from the number of normals!\n");
819  return (false);
820  }
821 
822  if (normals->empty ())
823  {
824  PCL_WARN ("[addPointCloudNormals] An empty normal cloud is given! Nothing to display.\n");
825  return (false);
826  }
827 
828  if (contains (id))
829  {
830  PCL_WARN ("[addPointCloudNormals] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
831  return (false);
832  }
833 
836 
837  points->SetDataTypeToFloat ();
839  data->SetNumberOfComponents (3);
840 
841 
842  vtkIdType nr_normals = 0;
843  float* pts = nullptr;
844 
845  // If the cloud is organized, then distribute the normal step in both directions
846  if (cloud->isOrganized () && normals->isOrganized ())
847  {
848  vtkIdType point_step = static_cast<vtkIdType> (sqrt (double (level)));
849  nr_normals = (static_cast<vtkIdType> ((cloud->width - 1)/ point_step) + 1) *
850  (static_cast<vtkIdType> ((cloud->height - 1) / point_step) + 1);
851  pts = new float[2 * nr_normals * 3];
852 
853  vtkIdType cell_count = 0;
854  for (vtkIdType y = 0; y < normals->height; y += point_step)
855  for (vtkIdType x = 0; x < normals->width; x += point_step)
856  {
857  PointT p = (*cloud)(x, y);
858  p.x += (*normals)(x, y).normal[0] * scale;
859  p.y += (*normals)(x, y).normal[1] * scale;
860  p.z += (*normals)(x, y).normal[2] * scale;
861 
862  pts[2 * cell_count * 3 + 0] = (*cloud)(x, y).x;
863  pts[2 * cell_count * 3 + 1] = (*cloud)(x, y).y;
864  pts[2 * cell_count * 3 + 2] = (*cloud)(x, y).z;
865  pts[2 * cell_count * 3 + 3] = p.x;
866  pts[2 * cell_count * 3 + 4] = p.y;
867  pts[2 * cell_count * 3 + 5] = p.z;
868 
869  lines->InsertNextCell (2);
870  lines->InsertCellPoint (2 * cell_count);
871  lines->InsertCellPoint (2 * cell_count + 1);
872  cell_count ++;
873  }
874  }
875  else
876  {
877  nr_normals = (cloud->size () - 1) / level + 1 ;
878  pts = new float[2 * nr_normals * 3];
879 
880  for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level)
881  {
882  PointT p = (*cloud)[i];
883  p.x += (*normals)[i].normal[0] * scale;
884  p.y += (*normals)[i].normal[1] * scale;
885  p.z += (*normals)[i].normal[2] * scale;
886 
887  pts[2 * j * 3 + 0] = (*cloud)[i].x;
888  pts[2 * j * 3 + 1] = (*cloud)[i].y;
889  pts[2 * j * 3 + 2] = (*cloud)[i].z;
890  pts[2 * j * 3 + 3] = p.x;
891  pts[2 * j * 3 + 4] = p.y;
892  pts[2 * j * 3 + 5] = p.z;
893 
894  lines->InsertNextCell (2);
895  lines->InsertCellPoint (2 * j);
896  lines->InsertCellPoint (2 * j + 1);
897  }
898  }
899 
900  data->SetArray (&pts[0], 2 * nr_normals * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
901  points->SetData (data);
902 
904  polyData->SetPoints (points);
905  polyData->SetLines (lines);
906 
908  mapper->SetInputData (polyData);
909  mapper->SetColorModeToMapScalars();
910  mapper->SetScalarModeToUsePointData();
911 
912  // create actor
914  actor->SetMapper (mapper);
915 
916  // Use cloud view point info
918  convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
919  actor->SetUserMatrix (transformation);
920 
921  // Add it to all renderers
922  addActorToRenderer (actor, viewport);
923 
924  // Save the pointer/ID pair to the global actor map
925  (*cloud_actor_map_)[id].actor = actor;
926  return (true);
927 }
928 
929 //////////////////////////////////////////////////////////////////////////////////////////////
930 template <typename PointNT> bool
932  const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
934  int level, float scale,
935  const std::string &id, int viewport)
936 {
937  return (addPointCloudPrincipalCurvatures<PointNT, PointNT> (cloud, cloud, pcs, level, scale, id, viewport));
938 }
939 
940 //////////////////////////////////////////////////////////////////////////////////////////////
941 template <typename PointT, typename PointNT> bool
943  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
944  const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
946  int level, float scale,
947  const std::string &id, int viewport)
948 {
949  if (pcs->size () != cloud->size () || normals->size () != cloud->size ())
950  {
951  pcl::console::print_error ("[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
952  return (false);
953  }
954 
955  if (contains (id))
956  {
957  PCL_WARN ("[addPointCloudPrincipalCurvatures] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
958  return (false);
959  }
960 
963 
964  // Setup two colors - one for each line
965  unsigned char green[3] = {0, 255, 0};
966  unsigned char blue[3] = {0, 0, 255};
967 
968  // Setup the colors array
970  line_1_colors->SetNumberOfComponents (3);
971  line_1_colors->SetName ("Colors");
973  line_2_colors->SetNumberOfComponents (3);
974  line_2_colors->SetName ("Colors");
975 
976  // Create the first sets of lines
977  for (std::size_t i = 0; i < cloud->size (); i+=level)
978  {
979  PointT p = (*cloud)[i];
980  p.x += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[0]) * scale;
981  p.y += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[1]) * scale;
982  p.z += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[2]) * scale;
983 
985  line_1->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
986  line_1->SetPoint2 (p.x, p.y, p.z);
987  line_1->Update ();
988  polydata_1->AddInputData (line_1->GetOutput ());
989  line_1_colors->InsertNextTupleValue (green);
990  }
991  polydata_1->Update ();
992  vtkSmartPointer<vtkPolyData> line_1_data = polydata_1->GetOutput ();
993  line_1_data->GetCellData ()->SetScalars (line_1_colors);
994 
995  // Create the second sets of lines
996  for (std::size_t i = 0; i < cloud->size (); i += level)
997  {
998  Eigen::Vector3f pc ((*pcs)[i].principal_curvature[0],
999  (*pcs)[i].principal_curvature[1],
1000  (*pcs)[i].principal_curvature[2]);
1001  Eigen::Vector3f normal ((*normals)[i].normal[0],
1002  (*normals)[i].normal[1],
1003  (*normals)[i].normal[2]);
1004  Eigen::Vector3f pc_c = pc.cross (normal);
1005 
1006  PointT p = (*cloud)[i];
1007  p.x += ((*pcs)[i].pc2 * pc_c[0]) * scale;
1008  p.y += ((*pcs)[i].pc2 * pc_c[1]) * scale;
1009  p.z += ((*pcs)[i].pc2 * pc_c[2]) * scale;
1010 
1012  line_2->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
1013  line_2->SetPoint2 (p.x, p.y, p.z);
1014  line_2->Update ();
1015  polydata_2->AddInputData (line_2->GetOutput ());
1016 
1017  line_2_colors->InsertNextTupleValue (blue);
1018  }
1019  polydata_2->Update ();
1020  vtkSmartPointer<vtkPolyData> line_2_data = polydata_2->GetOutput ();
1021  line_2_data->GetCellData ()->SetScalars (line_2_colors);
1022 
1023  // Assemble the two sets of lines
1025  alldata->AddInputData (line_1_data);
1026  alldata->AddInputData (line_2_data);
1027 
1028  // Create an Actor
1030  createActorFromVTKDataSet (alldata->GetOutput (), actor);
1031  actor->GetMapper ()->SetScalarModeToUseCellData ();
1032 
1033  // Add it to all renderers
1034  addActorToRenderer (actor, viewport);
1035 
1036  // Save the pointer/ID pair to the global actor map
1037  CloudActor act;
1038  act.actor = actor;
1039  (*cloud_actor_map_)[id] = act;
1040  return (true);
1041 }
1042 
1043 //////////////////////////////////////////////////////////////////////////////////////////////
1044 template <typename PointT, typename GradientT> bool
1046  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1047  const typename pcl::PointCloud<GradientT>::ConstPtr &gradients,
1048  int level, double scale,
1049  const std::string &id, int viewport)
1050 {
1051  if (gradients->size () != cloud->size ())
1052  {
1053  PCL_ERROR ("[addPointCloudGradients] The number of points differs from the number of gradients!\n");
1054  return (false);
1055  }
1056  if (contains (id))
1057  {
1058  PCL_WARN ("[addPointCloudGradients] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
1059  return (false);
1060  }
1061 
1064 
1065  points->SetDataTypeToFloat ();
1067  data->SetNumberOfComponents (3);
1068 
1069  vtkIdType nr_gradients = (cloud->size () - 1) / level + 1 ;
1070  float* pts = new float[2 * nr_gradients * 3];
1071 
1072  for (vtkIdType i = 0, j = 0; j < nr_gradients; j++, i = j * level)
1073  {
1074  PointT p = (*cloud)[i];
1075  p.x += (*gradients)[i].gradient[0] * scale;
1076  p.y += (*gradients)[i].gradient[1] * scale;
1077  p.z += (*gradients)[i].gradient[2] * scale;
1078 
1079  pts[2 * j * 3 + 0] = (*cloud)[i].x;
1080  pts[2 * j * 3 + 1] = (*cloud)[i].y;
1081  pts[2 * j * 3 + 2] = (*cloud)[i].z;
1082  pts[2 * j * 3 + 3] = p.x;
1083  pts[2 * j * 3 + 4] = p.y;
1084  pts[2 * j * 3 + 5] = p.z;
1085 
1086  lines->InsertNextCell(2);
1087  lines->InsertCellPoint(2*j);
1088  lines->InsertCellPoint(2*j+1);
1089  }
1090 
1091  data->SetArray (&pts[0], 2 * nr_gradients * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
1092  points->SetData (data);
1093 
1095  polyData->SetPoints(points);
1096  polyData->SetLines(lines);
1097 
1099  mapper->SetInputData (polyData);
1100  mapper->SetColorModeToMapScalars();
1101  mapper->SetScalarModeToUsePointData();
1102 
1103  // create actor
1105  actor->SetMapper (mapper);
1106 
1107  // Add it to all renderers
1108  addActorToRenderer (actor, viewport);
1109 
1110  // Save the pointer/ID pair to the global actor map
1111  (*cloud_actor_map_)[id].actor = actor;
1112  return (true);
1113 }
1114 
1115 //////////////////////////////////////////////////////////////////////////////////////////////
1116 template <typename PointT> bool
1118  const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1119  const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1120  const std::vector<int> &correspondences,
1121  const std::string &id,
1122  int viewport)
1123 {
1124  pcl::Correspondences corrs;
1125  corrs.resize (correspondences.size ());
1126 
1127  std::size_t index = 0;
1128  for (auto &corr : corrs)
1129  {
1130  corr.index_query = index;
1131  corr.index_match = correspondences[index];
1132  index++;
1133  }
1134 
1135  return (addCorrespondences<PointT> (source_points, target_points, corrs, id, viewport));
1136 }
1137 
1138 //////////////////////////////////////////////////////////////////////////////////////////////
1139 template <typename PointT> bool
1141  const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1142  const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1143  const pcl::Correspondences &correspondences,
1144  int nth,
1145  const std::string &id,
1146  int viewport,
1147  bool overwrite)
1148 {
1149  if (correspondences.empty ())
1150  {
1151  PCL_DEBUG ("[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1152  return (false);
1153  }
1154 
1155  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1156  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
1157  if (am_it != shape_actor_map_->end () && !overwrite)
1158  {
1159  PCL_WARN ("[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
1160  return (false);
1161  }
1162  if (am_it == shape_actor_map_->end () && overwrite)
1163  {
1164  overwrite = false; // Correspondences doesn't exist, add them instead of updating them
1165  }
1166 
1167  int n_corr = int (correspondences.size () / nth);
1169 
1170  // Prepare colors
1172  line_colors->SetNumberOfComponents (3);
1173  line_colors->SetName ("Colors");
1174  line_colors->SetNumberOfTuples (n_corr);
1175 
1176  // Prepare coordinates
1178  line_points->SetNumberOfPoints (2 * n_corr);
1179 
1181  line_cells_id->SetNumberOfComponents (3);
1182  line_cells_id->SetNumberOfTuples (n_corr);
1183  vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
1185 
1187  line_tcoords->SetNumberOfComponents (1);
1188  line_tcoords->SetNumberOfTuples (n_corr * 2);
1189  line_tcoords->SetName ("Texture Coordinates");
1190 
1191  double tc[3] = {0.0, 0.0, 0.0};
1192 
1193  Eigen::Affine3f source_transformation;
1194  source_transformation.linear () = source_points->sensor_orientation_.matrix ();
1195  source_transformation.translation () = source_points->sensor_origin_.head (3);
1196  Eigen::Affine3f target_transformation;
1197  target_transformation.linear () = target_points->sensor_orientation_.matrix ();
1198  target_transformation.translation () = target_points->sensor_origin_.head (3);
1199 
1200  int j = 0;
1201  // Draw lines between the best corresponding points
1202  for (std::size_t i = 0; i < correspondences.size (); i += nth, ++j)
1203  {
1204  if (correspondences[i].index_match == -1)
1205  {
1206  PCL_WARN ("[addCorrespondences] No valid index_match for correspondence %d\n", i);
1207  continue;
1208  }
1209 
1210  PointT p_src ((*source_points)[correspondences[i].index_query]);
1211  PointT p_tgt ((*target_points)[correspondences[i].index_match]);
1212 
1213  p_src.getVector3fMap () = source_transformation * p_src.getVector3fMap ();
1214  p_tgt.getVector3fMap () = target_transformation * p_tgt.getVector3fMap ();
1215 
1216  int id1 = j * 2 + 0, id2 = j * 2 + 1;
1217  // Set the points
1218  line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
1219  line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
1220  // Set the cell ID
1221  *line_cell_id++ = 2;
1222  *line_cell_id++ = id1;
1223  *line_cell_id++ = id2;
1224  // Set the texture coords
1225  tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
1226  tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
1227 
1228  float rgb[3];
1229  rgb[0] = vtkMath::Random (32, 255); // min / max
1230  rgb[1] = vtkMath::Random (32, 255);
1231  rgb[2] = vtkMath::Random (32, 255);
1232  line_colors->InsertTuple (i, rgb);
1233  }
1234  line_colors->SetNumberOfTuples (j);
1235  line_cells_id->SetNumberOfTuples (j);
1236  line_cells->SetCells (n_corr, line_cells_id);
1237  line_points->SetNumberOfPoints (j*2);
1238  line_tcoords->SetNumberOfTuples (j*2);
1239 
1240  // Fill in the lines
1241  line_data->SetPoints (line_points);
1242  line_data->SetLines (line_cells);
1243  line_data->GetPointData ()->SetTCoords (line_tcoords);
1244  line_data->GetCellData ()->SetScalars (line_colors);
1245 
1246  // Create an Actor
1247  if (!overwrite)
1248  {
1250  createActorFromVTKDataSet (line_data, actor);
1251  actor->GetProperty ()->SetRepresentationToWireframe ();
1252  actor->GetProperty ()->SetOpacity (0.5);
1253  addActorToRenderer (actor, viewport);
1254 
1255  // Save the pointer/ID pair to the global actor map
1256  (*shape_actor_map_)[id] = actor;
1257  }
1258  else
1259  {
1260  vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast (am_it->second);
1261  if (!actor)
1262  return (false);
1263  // Update the mapper
1264  reinterpret_cast<vtkPolyDataMapper*> (actor->GetMapper ())->SetInputData (line_data);
1265  }
1266 
1267  return (true);
1268 }
1269 
1270 //////////////////////////////////////////////////////////////////////////////////////////////
1271 template <typename PointT> bool
1273  const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1274  const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1275  const pcl::Correspondences &correspondences,
1276  int nth,
1277  const std::string &id,
1278  int viewport)
1279 {
1280  return (addCorrespondences<PointT> (source_points, target_points, correspondences, nth, id, viewport, true));
1281 }
1282 
1283 //////////////////////////////////////////////////////////////////////////////////////////////
1284 template <typename PointT> bool
1285 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1286  const PointCloudGeometryHandler<PointT> &geometry_handler,
1287  const PointCloudColorHandler<PointT> &color_handler,
1288  const std::string &id,
1289  int viewport,
1290  const Eigen::Vector4f& sensor_origin,
1291  const Eigen::Quaternion<float>& sensor_orientation)
1292 {
1293  if (!geometry_handler.isCapable ())
1294  {
1295  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
1296  return (false);
1297  }
1298 
1299  if (!color_handler.isCapable ())
1300  {
1301  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
1302  return (false);
1303  }
1304 
1307  // Convert the PointCloud to VTK PolyData
1308  convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1309  // use the given geometry handler
1310 
1311  // Get the colors from the handler
1312  bool has_colors = false;
1313  double minmax[2];
1314  if (auto scalars = color_handler.getColor ())
1315  {
1316  polydata->GetPointData ()->SetScalars (scalars);
1317  scalars->GetRange (minmax);
1318  has_colors = true;
1319  }
1320 
1321  // Create an Actor
1323  createActorFromVTKDataSet (polydata, actor);
1324  if (has_colors)
1325  actor->GetMapper ()->SetScalarRange (minmax);
1326 
1327  // Add it to all renderers
1328  addActorToRenderer (actor, viewport);
1329 
1330  // Save the pointer/ID pair to the global actor map
1331  CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1332  cloud_actor.actor = actor;
1333  cloud_actor.cells = initcells;
1334 
1335  // Save the viewpoint transformation matrix to the global actor map
1337  convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1338  cloud_actor.viewpoint_transformation_ = transformation;
1339  cloud_actor.actor->SetUserMatrix (transformation);
1340  cloud_actor.actor->Modified ();
1341 
1342  return (true);
1343 }
1344 
1345 //////////////////////////////////////////////////////////////////////////////////////////////
1346 template <typename PointT> bool
1347 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1348  const PointCloudGeometryHandler<PointT> &geometry_handler,
1349  const ColorHandlerConstPtr &color_handler,
1350  const std::string &id,
1351  int viewport,
1352  const Eigen::Vector4f& sensor_origin,
1353  const Eigen::Quaternion<float>& sensor_orientation)
1354 {
1355  if (!geometry_handler.isCapable ())
1356  {
1357  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
1358  return (false);
1359  }
1360 
1361  if (!color_handler->isCapable ())
1362  {
1363  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ());
1364  return (false);
1365  }
1366 
1369  // Convert the PointCloud to VTK PolyData
1370  convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1371  // use the given geometry handler
1372 
1373  // Get the colors from the handler
1374  bool has_colors = false;
1375  double minmax[2];
1376  if (auto scalars = color_handler->getColor ())
1377  {
1378  polydata->GetPointData ()->SetScalars (scalars);
1379  scalars->GetRange (minmax);
1380  has_colors = true;
1381  }
1382 
1383  // Create an Actor
1385  createActorFromVTKDataSet (polydata, actor);
1386  if (has_colors)
1387  actor->GetMapper ()->SetScalarRange (minmax);
1388 
1389  // Add it to all renderers
1390  addActorToRenderer (actor, viewport);
1391 
1392  // Save the pointer/ID pair to the global actor map
1393  CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1394  cloud_actor.actor = actor;
1395  cloud_actor.cells = initcells;
1396  cloud_actor.color_handlers.push_back (color_handler);
1397 
1398  // Save the viewpoint transformation matrix to the global actor map
1400  convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1401  cloud_actor.viewpoint_transformation_ = transformation;
1402  cloud_actor.actor->SetUserMatrix (transformation);
1403  cloud_actor.actor->Modified ();
1404 
1405  return (true);
1406 }
1407 
1408 //////////////////////////////////////////////////////////////////////////////////////////////
1409 template <typename PointT> bool
1410 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1411  const GeometryHandlerConstPtr &geometry_handler,
1412  const PointCloudColorHandler<PointT> &color_handler,
1413  const std::string &id,
1414  int viewport,
1415  const Eigen::Vector4f& sensor_origin,
1416  const Eigen::Quaternion<float>& sensor_orientation)
1417 {
1418  if (!geometry_handler->isCapable ())
1419  {
1420  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ());
1421  return (false);
1422  }
1423 
1424  if (!color_handler.isCapable ())
1425  {
1426  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
1427  return (false);
1428  }
1429 
1432  // Convert the PointCloud to VTK PolyData
1433  convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
1434  // use the given geometry handler
1435 
1436  // Get the colors from the handler
1437  bool has_colors = false;
1438  double minmax[2];
1439  if (auto scalars = color_handler.getColor ())
1440  {
1441  polydata->GetPointData ()->SetScalars (scalars);
1442  scalars->GetRange (minmax);
1443  has_colors = true;
1444  }
1445 
1446  // Create an Actor
1448  createActorFromVTKDataSet (polydata, actor);
1449  if (has_colors)
1450  actor->GetMapper ()->SetScalarRange (minmax);
1451 
1452  // Add it to all renderers
1453  addActorToRenderer (actor, viewport);
1454 
1455  // Save the pointer/ID pair to the global actor map
1456  CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1457  cloud_actor.actor = actor;
1458  cloud_actor.cells = initcells;
1459  cloud_actor.geometry_handlers.push_back (geometry_handler);
1460 
1461  // Save the viewpoint transformation matrix to the global actor map
1463  convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1464  cloud_actor.viewpoint_transformation_ = transformation;
1465  cloud_actor.actor->SetUserMatrix (transformation);
1466  cloud_actor.actor->Modified ();
1467 
1468  return (true);
1469 }
1470 
1471 //////////////////////////////////////////////////////////////////////////////////////////////
1472 template <typename PointT> bool
1474  const std::string &id)
1475 {
1476  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1477  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1478 
1479  if (am_it == cloud_actor_map_->end ())
1480  return (false);
1481 
1482  vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1483  if (!polydata)
1484  return false;
1485  // Convert the PointCloud to VTK PolyData
1486  convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
1487 
1488  // Set scalars to blank, since there is no way we can update them here.
1490  polydata->GetPointData ()->SetScalars (scalars);
1491  double minmax[2];
1492  minmax[0] = std::numeric_limits<double>::min ();
1493  minmax[1] = std::numeric_limits<double>::max ();
1494 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1495  am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1496 #endif
1497  am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1498 
1499  // Update the mapper
1500  reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1501  return (true);
1502 }
1503 
1504 /////////////////////////////////////////////////////////////////////////////////////////////
1505 template <typename PointT> bool
1507  const PointCloudGeometryHandler<PointT> &geometry_handler,
1508  const std::string &id)
1509 {
1510  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1511  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1512 
1513  if (am_it == cloud_actor_map_->end ())
1514  return (false);
1515 
1516  vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1517  if (!polydata)
1518  return (false);
1519  // Convert the PointCloud to VTK PolyData
1520  convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
1521 
1522  // Set scalars to blank, since there is no way we can update them here.
1524  polydata->GetPointData ()->SetScalars (scalars);
1525  double minmax[2];
1526  minmax[0] = std::numeric_limits<double>::min ();
1527  minmax[1] = std::numeric_limits<double>::max ();
1528 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1529  am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1530 #endif
1531  am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1532 
1533  // Update the mapper
1534  reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1535  return (true);
1536 }
1537 
1538 
1539 /////////////////////////////////////////////////////////////////////////////////////////////
1540 template <typename PointT> bool
1542  const PointCloudColorHandler<PointT> &color_handler,
1543  const std::string &id)
1544 {
1545  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1546  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1547 
1548  if (am_it == cloud_actor_map_->end ())
1549  return (false);
1550 
1551  // Get the current poly data
1552  vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1553  if (!polydata)
1554  return (false);
1555 
1556  convertPointCloudToVTKPolyData<PointT>(cloud, polydata, am_it->second.cells);
1557 
1558  // Get the colors from the handler
1559  bool has_colors = false;
1560  double minmax[2];
1561  if (auto scalars = color_handler.getColor ())
1562  {
1563  // Update the data
1564  polydata->GetPointData ()->SetScalars (scalars);
1565  scalars->GetRange (minmax);
1566  has_colors = true;
1567  }
1568 
1569 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1570  am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1571 #endif
1572 
1573  if (has_colors)
1574  am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1575 
1576  // Update the mapper
1577  reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1578  return (true);
1579 }
1580 
1581 /////////////////////////////////////////////////////////////////////////////////////////////
1582 template <typename PointT> bool
1584  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1585  const std::vector<pcl::Vertices> &vertices,
1586  const std::string &id,
1587  int viewport)
1588 {
1589  if (vertices.empty () || cloud->points.empty ())
1590  return (false);
1591 
1592  if (contains (id))
1593  {
1594  PCL_WARN ("[addPolygonMesh] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
1595  return (false);
1596  }
1597 
1598  int rgb_idx = -1;
1599  std::vector<pcl::PCLPointField> fields;
1601  rgb_idx = pcl::getFieldIndex<PointT> ("rgb", fields);
1602  if (rgb_idx == -1)
1603  rgb_idx = pcl::getFieldIndex<PointT> ("rgba", fields);
1604  if (rgb_idx != -1)
1605  {
1607  colors->SetNumberOfComponents (3);
1608  colors->SetName ("Colors");
1609  std::uint32_t offset = fields[rgb_idx].offset;
1610  for (std::size_t i = 0; i < cloud->size (); ++i)
1611  {
1612  if (!isFinite ((*cloud)[i]))
1613  continue;
1614  const pcl::RGB* const rgb_data = reinterpret_cast<const pcl::RGB*>(reinterpret_cast<const char*> (&(*cloud)[i]) + offset);
1615  unsigned char color[3];
1616  color[0] = rgb_data->r;
1617  color[1] = rgb_data->g;
1618  color[2] = rgb_data->b;
1619  colors->InsertNextTupleValue (color);
1620  }
1621  }
1622 
1623  // Create points from polyMesh.cloud
1625  vtkIdType nr_points = cloud->size ();
1626  points->SetNumberOfPoints (nr_points);
1628 
1629  // Get a pointer to the beginning of the data array
1630  float *data = static_cast<vtkFloatArray*> (points->GetData ())->GetPointer (0);
1631 
1632  vtkIdType ptr = 0;
1633  std::vector<int> lookup;
1634  // If the dataset is dense (no NaNs)
1635  if (cloud->is_dense)
1636  {
1637  for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1638  std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1639  }
1640  else
1641  {
1642  lookup.resize (nr_points);
1643  vtkIdType j = 0; // true point index
1644  for (vtkIdType i = 0; i < nr_points; ++i)
1645  {
1646  // Check if the point is invalid
1647  if (!isFinite ((*cloud)[i]))
1648  continue;
1649 
1650  lookup[i] = static_cast<int> (j);
1651  std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1652  j++;
1653  ptr += 3;
1654  }
1655  nr_points = j;
1656  points->SetNumberOfPoints (nr_points);
1657  }
1658 
1659  // Get the maximum size of a polygon
1660  int max_size_of_polygon = -1;
1661  for (const auto &vertex : vertices)
1662  if (max_size_of_polygon < static_cast<int> (vertex.vertices.size ()))
1663  max_size_of_polygon = static_cast<int> (vertex.vertices.size ());
1664 
1665  if (vertices.size () > 1)
1666  {
1667  // Create polys from polyMesh.polygons
1669  vtkIdType *cell = cell_array->WritePointer (vertices.size (), vertices.size () * (max_size_of_polygon + 1));
1670  int idx = 0;
1671  if (!lookup.empty ())
1672  {
1673  for (std::size_t i = 0; i < vertices.size (); ++i, ++idx)
1674  {
1675  std::size_t n_points = vertices[i].vertices.size ();
1676  *cell++ = n_points;
1677  //cell_array->InsertNextCell (n_points);
1678  for (std::size_t j = 0; j < n_points; j++, ++idx)
1679  *cell++ = lookup[vertices[i].vertices[j]];
1680  //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]);
1681  }
1682  }
1683  else
1684  {
1685  for (std::size_t i = 0; i < vertices.size (); ++i, ++idx)
1686  {
1687  std::size_t n_points = vertices[i].vertices.size ();
1688  *cell++ = n_points;
1689  //cell_array->InsertNextCell (n_points);
1690  for (std::size_t j = 0; j < n_points; j++, ++idx)
1691  *cell++ = vertices[i].vertices[j];
1692  //cell_array->InsertCellPoint (vertices[i].vertices[j]);
1693  }
1694  }
1696  allocVtkPolyData (polydata);
1697  cell_array->GetData ()->SetNumberOfValues (idx);
1698  cell_array->Squeeze ();
1699  polydata->SetPolys (cell_array);
1700  polydata->SetPoints (points);
1701 
1702  if (colors)
1703  polydata->GetPointData ()->SetScalars (colors);
1704 
1705  createActorFromVTKDataSet (polydata, actor, false);
1706  }
1707  else
1708  {
1710  std::size_t n_points = vertices[0].vertices.size ();
1711  polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
1712 
1713  if (!lookup.empty ())
1714  {
1715  for (std::size_t j = 0; j < (n_points - 1); ++j)
1716  polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
1717  }
1718  else
1719  {
1720  for (std::size_t j = 0; j < (n_points - 1); ++j)
1721  polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
1722  }
1724  allocVtkUnstructuredGrid (poly_grid);
1725  poly_grid->Allocate (1, 1);
1726  poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
1727  poly_grid->SetPoints (points);
1728  if (colors)
1729  poly_grid->GetPointData ()->SetScalars (colors);
1730 
1731  createActorFromVTKDataSet (poly_grid, actor, false);
1732  }
1733  addActorToRenderer (actor, viewport);
1734  actor->GetProperty ()->SetRepresentationToSurface ();
1735  // Backface culling renders the visualization slower, but guarantees that we see all triangles
1736  actor->GetProperty ()->BackfaceCullingOff ();
1737  actor->GetProperty ()->SetInterpolationToFlat ();
1738  actor->GetProperty ()->EdgeVisibilityOff ();
1739  actor->GetProperty ()->ShadingOff ();
1740 
1741  // Save the pointer/ID pair to the global actor map
1742  (*cloud_actor_map_)[id].actor = actor;
1743 
1744  // Save the viewpoint transformation matrix to the global actor map
1746  convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
1747  (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
1748 
1749  return (true);
1750 }
1751 
1752 /////////////////////////////////////////////////////////////////////////////////////////////
1753 template <typename PointT> bool
1755  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1756  const std::vector<pcl::Vertices> &verts,
1757  const std::string &id)
1758 {
1759  if (verts.empty ())
1760  {
1761  pcl::console::print_error ("[addPolygonMesh] No vertices given!\n");
1762  return (false);
1763  }
1764 
1765  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1766  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1767  if (am_it == cloud_actor_map_->end ())
1768  return (false);
1769 
1770  // Get the current poly data
1771  vtkSmartPointer<vtkPolyData> polydata = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1772  if (!polydata)
1773  return (false);
1774  vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();
1775  if (!cells)
1776  return (false);
1777  vtkSmartPointer<vtkPoints> points = polydata->GetPoints ();
1778  // Copy the new point array in
1779  vtkIdType nr_points = cloud->size ();
1780  points->SetNumberOfPoints (nr_points);
1781 
1782  // Get a pointer to the beginning of the data array
1783  float *data = (static_cast<vtkFloatArray*> (points->GetData ()))->GetPointer (0);
1784 
1785  int ptr = 0;
1786  std::vector<int> lookup;
1787  // If the dataset is dense (no NaNs)
1788  if (cloud->is_dense)
1789  {
1790  for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1791  std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1792  }
1793  else
1794  {
1795  lookup.resize (nr_points);
1796  vtkIdType j = 0; // true point index
1797  for (vtkIdType i = 0; i < nr_points; ++i)
1798  {
1799  // Check if the point is invalid
1800  if (!isFinite ((*cloud)[i]))
1801  continue;
1802 
1803  lookup [i] = static_cast<int> (j);
1804  std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1805  j++;
1806  ptr += 3;
1807  }
1808  nr_points = j;
1809  points->SetNumberOfPoints (nr_points);
1810  }
1811 
1812  // Update colors
1813  vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
1814  if (!colors)
1815  return (false);
1816  int rgb_idx = -1;
1817  std::vector<pcl::PCLPointField> fields;
1818  rgb_idx = pcl::getFieldIndex<PointT> ("rgb", fields);
1819  if (rgb_idx == -1)
1820  rgb_idx = pcl::getFieldIndex<PointT> ("rgba", fields);
1821  if (rgb_idx != -1 && colors)
1822  {
1823  int j = 0;
1824  std::uint32_t offset = fields[rgb_idx].offset;
1825  for (std::size_t i = 0; i < cloud->size (); ++i)
1826  {
1827  if (!isFinite ((*cloud)[i]))
1828  continue;
1829  const pcl::RGB* const rgb_data = reinterpret_cast<const pcl::RGB*>(reinterpret_cast<const char*> (&(*cloud)[i]) + offset);
1830  unsigned char color[3];
1831  color[0] = rgb_data->r;
1832  color[1] = rgb_data->g;
1833  color[2] = rgb_data->b;
1834  colors->SetTupleValue (j++, color);
1835  }
1836  }
1837 
1838  // Get the maximum size of a polygon
1839  int max_size_of_polygon = -1;
1840  for (const auto &vertex : verts)
1841  if (max_size_of_polygon < static_cast<int> (vertex.vertices.size ()))
1842  max_size_of_polygon = static_cast<int> (vertex.vertices.size ());
1843 
1844  // Update the cells
1846  vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1));
1847  int idx = 0;
1848  if (!lookup.empty ())
1849  {
1850  for (std::size_t i = 0; i < verts.size (); ++i, ++idx)
1851  {
1852  std::size_t n_points = verts[i].vertices.size ();
1853  *cell++ = n_points;
1854  for (std::size_t j = 0; j < n_points; j++, cell++, ++idx)
1855  *cell = lookup[verts[i].vertices[j]];
1856  }
1857  }
1858  else
1859  {
1860  for (std::size_t i = 0; i < verts.size (); ++i, ++idx)
1861  {
1862  std::size_t n_points = verts[i].vertices.size ();
1863  *cell++ = n_points;
1864  for (std::size_t j = 0; j < n_points; j++, cell++, ++idx)
1865  *cell = verts[i].vertices[j];
1866  }
1867  }
1868  cells->GetData ()->SetNumberOfValues (idx);
1869  cells->Squeeze ();
1870  // Set the the vertices
1871  polydata->SetPolys (cells);
1872 
1873  return (true);
1874 }
1875 
1876 #ifdef vtkGenericDataArray_h
1877 #undef SetTupleValue
1878 #undef InsertNextTupleValue
1879 #undef GetTupleValue
1880 #endif
1881 
1882 #endif
pcl::visualization::PCLVisualizer::updateSphere
bool updateSphere(const PointT &center, double radius, double r, double g, double b, const std::string &id="sphere")
Update an existing sphere shape from a point and a radius.
Definition: pcl_visualizer.hpp:605
pcl::visualization::PCLVisualizer::addPointCloudNormals
bool addPointCloudNormals(const typename pcl::PointCloud< PointNT >::ConstPtr &cloud, int level=100, float scale=0.02f, const std::string &id="cloud", int viewport=0)
Add the estimated surface normals of a Point Cloud to screen.
Definition: pcl_visualizer.hpp:801
pcl::PointCloud::height
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:393
pcl::visualization::PointCloudGeometryHandler::getName
virtual std::string getName() const =0
Abstract getName method.
pcl::PointCloud::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:388
pcl::visualization::PCLVisualizer::updatePointCloud
bool updatePointCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::string &id="cloud")
Updates the XYZ data for an existing cloud object id on screen.
Definition: pcl_visualizer.hpp:1473
pcl::isFinite
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
Definition: point_tests.h:55
pcl::visualization::PointCloudColorHandlerCustom
Handler for predefined user colors.
Definition: point_cloud_color_handlers.h:186
pcl::PointCloud::empty
bool empty() const
Definition: point_cloud.h:439
pcl::visualization::PointCloudColorHandler
Base Handler class for PointCloud colors.
Definition: point_cloud_color_handlers.h:65
pcl::visualization::PCLVisualizer::addPointCloud
bool addPointCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::string &id="cloud", int viewport=0)
Add a Point Cloud (templated) to screen.
Definition: pcl_visualizer.hpp:76
pcl::visualization::PointCloudColorHandler::getName
virtual std::string getName() const =0
Abstract getName method.
pcl::visualization::PCLVisualizer::GeometryHandlerConstPtr
GeometryHandler::ConstPtr GeometryHandlerConstPtr
Definition: pcl_visualizer.h:94
pcl::visualization::PCLVisualizer::addPolygon
bool addPolygon(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, double r, double g, double b, const std::string &id="polygon", int viewport=0)
Add a polygon (polyline) that represents the input point cloud (connects all points in order)
Definition: pcl_visualizer.hpp:317
pcl::visualization::PCLVisualizer::updateCorrespondences
bool updateCorrespondences(const typename pcl::PointCloud< PointT >::ConstPtr &source_points, const typename pcl::PointCloud< PointT >::ConstPtr &target_points, const pcl::Correspondences &correspondences, int nth, const std::string &id="correspondences", int viewport=0)
Update the specified correspondences to the display.
Definition: pcl_visualizer.hpp:1272
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition: point_types.hpp:628
pcl::PointCloud::isOrganized
bool isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
Definition: point_cloud.h:309
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:391
pcl::visualization::allocVtkUnstructuredGrid
PCL_EXPORTS void allocVtkUnstructuredGrid(vtkSmartPointer< vtkUnstructuredGrid > &polydata)
Allocate a new unstructured grid smartpointer.
pcl::console::print_error
PCL_EXPORTS void print_error(const char *format,...)
Print an error message on stream with colors.
pcl::visualization::PCLVisualizer::addCorrespondences
bool addCorrespondences(const typename pcl::PointCloud< PointT >::ConstPtr &source_points, const typename pcl::PointCloud< PointT >::ConstPtr &target_points, const std::vector< int > &correspondences, const std::string &id="correspondences", int viewport=0)
Add the specified correspondences to the display.
Definition: pcl_visualizer.hpp:1117
pcl::RGB
A structure representing RGB color information.
Definition: point_types.hpp:345
pcl::PointCloud::sensor_origin_
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
Definition: point_cloud.h:399
pcl::PointCloud::sensor_orientation_
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
Definition: point_cloud.h:401
pcl::visualization::PointCloudGeometryHandler::isCapable
bool isCapable() const
Checl if this handler is capable of handling the input data or not.
Definition: point_cloud_geometry_handlers.h:94
pcl::PointCloud::is_dense
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
Definition: point_cloud.h:396
pcl::visualization::PCLVisualizer::updatePolygonMesh
bool updatePolygonMesh(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::vector< pcl::Vertices > &vertices, const std::string &id="polygon")
Update a PolygonMesh object on screen.
Definition: pcl_visualizer.hpp:1754
pcl::visualization::PointCloudColorHandler::getColor
virtual vtkSmartPointer< vtkDataArray > getColor() const =0
Obtain the actual color for the input dataset as a VTK data array.
pcl::PointCloud::size
std::size_t size() const
Definition: point_cloud.h:436
shapes.h
pcl::visualization::CloudActor
Definition: actor_map.h:57
pcl::visualization::PointCloudColorHandlerRGBField
RGB handler class for colors.
Definition: point_cloud_color_handlers.h:247
pcl::PointCloud::ConstPtr
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:407
pcl::visualization::PCLVisualizer::ColorHandlerConstPtr
ColorHandler::ConstPtr ColorHandlerConstPtr
Definition: pcl_visualizer.h:98
pcl::visualization::CloudActor::actor
vtkSmartPointer< vtkLODActor > actor
The actor holding the data to render.
Definition: actor_map.h:77
pcl::visualization::PCLVisualizer::addText3D
bool addText3D(const std::string &text, const PointT &position, double textScale=1.0, double r=1.0, double g=1.0, double b=1.0, const std::string &id="", int viewport=0)
Add a 3d text to the scene.
Definition: pcl_visualizer.hpp:634
pcl::PlanarPolygon
PlanarPolygon represents a planar (2D) polygon, potentially in a 3D space.
Definition: planar_polygon.h:53
pcl::Correspondences
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
Definition: correspondence.h:89
pcl::visualization::PCLVisualizer::addLine
bool addLine(const P1 &pt1, const P2 &pt2, const std::string &id="line", int viewport=0)
Add a line segment from two points.
Definition: pcl_visualizer.hpp:549
pcl::visualization::PointCloudGeometryHandler
Base handler class for PointCloud geometry.
Definition: point_cloud_geometry_handlers.h:62
pcl::visualization::createLine
PCL_EXPORTS vtkSmartPointer< vtkDataSet > createLine(const Eigen::Vector4f &pt1, const Eigen::Vector4f &pt2)
Create a line shape from two points.
pcl::visualization::PCLVisualizer::addPolygonMesh
bool addPolygonMesh(const pcl::PolygonMesh &polymesh, const std::string &id="polygon", int viewport=0)
Add a PolygonMesh object to screen.
pcl::visualization::PointCloudColorHandler::isCapable
bool isCapable() const
Check if this handler is capable of handling the input data or not.
Definition: point_cloud_color_handlers.h:90
pcl::visualization::PointCloudGeometryHandlerXYZ
XYZ handler class for PointCloud geometry.
Definition: point_cloud_geometry_handlers.h:140
pcl::visualization::PCLVisualizer::addArrow
bool addArrow(const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id="arrow", int viewport=0)
Add a line arrow segment between two points, and display the distance between them.
Definition: pcl_visualizer.hpp:460
pcl::visualization::PCLVisualizer::addPointCloudPrincipalCurvatures
bool addPointCloudPrincipalCurvatures(const typename pcl::PointCloud< PointNT >::ConstPtr &cloud, const typename pcl::PointCloud< pcl::PrincipalCurvatures >::ConstPtr &pcs, int level=100, float scale=1.0f, const std::string &id="cloud", int viewport=0)
Add the estimated principal curvatures of a Point Cloud to screen.
pcl::visualization::PCLVisualizer::addSphere
bool addSphere(const PointT &center, double radius, const std::string &id="sphere", int viewport=0)
Add a sphere shape from a point and a radius.
Definition: pcl_visualizer.hpp:598
vtkSmartPointer< vtkPolyData >
pcl::visualization::PointCloudGeometryHandler::getGeometry
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const =0
Obtain the actual point geometry for the input dataset in VTK format.
pcl::visualization::PCLVisualizer::addPointCloudIntensityGradients
bool addPointCloudIntensityGradients(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const typename pcl::PointCloud< GradientT >::ConstPtr &gradients, int level=100, double scale=1e-6, const std::string &id="cloud", int viewport=0)
Add the estimated surface intensity gradients of a Point Cloud to screen.
Definition: pcl_visualizer.hpp:1045