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