Point Cloud Library (PCL)  1.8.1
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->points.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  if (cloud->is_dense)
249  {
250  for (vtkIdType i = 0; i < nr_points; ++i)
251  memcpy (&data[i * 3], &cloud->points[i].x, 12); // sizeof (float) * 3
252  }
253  else
254  {
255  vtkIdType j = 0; // true point index
256  for (vtkIdType i = 0; i < nr_points; ++i)
257  {
258  // Check if the point is invalid
259  if (!pcl_isfinite (cloud->points[i].x) ||
260  !pcl_isfinite (cloud->points[i].y) ||
261  !pcl_isfinite (cloud->points[i].z))
262  continue;
263 
264  memcpy (&data[j * 3], &cloud->points[i].x, 12); // sizeof (float) * 3
265  j++;
266  }
267  nr_points = j;
268  points->SetNumberOfPoints (nr_points);
269  }
270 
271  vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
272  updateCells (cells, initcells, nr_points);
273 
274  // Set the cells and the vertices
275  vertices->SetCells (nr_points, cells);
276 }
277 
278 //////////////////////////////////////////////////////////////////////////////////////////////
279 template <typename PointT> void
280 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
284 {
286  if (!polydata)
287  {
288  allocVtkPolyData (polydata);
290  polydata->SetVerts (vertices);
291  }
292 
293  // Use the handler to obtain the geometry
295  geometry_handler.getGeometry (points);
296  polydata->SetPoints (points);
297 
298  vtkIdType nr_points = points->GetNumberOfPoints ();
299 
300  // Create the supporting structures
301  vertices = polydata->GetVerts ();
302  if (!vertices)
304 
305  vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
306  updateCells (cells, initcells, nr_points);
307  // Set the cells and the vertices
308  vertices->SetCells (nr_points, cells);
309 }
310 
311 ////////////////////////////////////////////////////////////////////////////////////////////
312 template <typename PointT> bool
314  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
315  double r, double g, double b, const std::string &id, int viewport)
316 {
317  vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (cloud);
318  if (!data)
319  return (false);
320 
321  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
322  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
323  if (am_it != shape_actor_map_->end ())
324  {
326 
327  // Add old data
328 #if VTK_MAJOR_VERSION < 6
329  all_data->AddInput (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
330 #else
331  all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
332 #endif
333 
334  // Add new data
336 #if VTK_MAJOR_VERSION < 6
337  surface_filter->AddInput (vtkUnstructuredGrid::SafeDownCast (data));
338 #else
339  surface_filter->AddInputData (vtkUnstructuredGrid::SafeDownCast (data));
340 #endif
341  vtkSmartPointer<vtkPolyData> poly_data = surface_filter->GetOutput ();
342 #if VTK_MAJOR_VERSION < 6
343  all_data->AddInput (poly_data);
344 #else
345  all_data->AddInputData (poly_data);
346 #endif
347 
348  // Create an Actor
350  createActorFromVTKDataSet (all_data->GetOutput (), actor);
351  actor->GetProperty ()->SetRepresentationToWireframe ();
352  actor->GetProperty ()->SetColor (r, g, b);
353  actor->GetMapper ()->ScalarVisibilityOff ();
354  removeActorFromRenderer (am_it->second, viewport);
355  addActorToRenderer (actor, viewport);
356 
357  // Save the pointer/ID pair to the global actor map
358  (*shape_actor_map_)[id] = actor;
359  }
360  else
361  {
362  // Create an Actor
364  createActorFromVTKDataSet (data, actor);
365  actor->GetProperty ()->SetRepresentationToWireframe ();
366  actor->GetProperty ()->SetColor (r, g, b);
367  actor->GetMapper ()->ScalarVisibilityOff ();
368  addActorToRenderer (actor, viewport);
369 
370  // Save the pointer/ID pair to the global actor map
371  (*shape_actor_map_)[id] = actor;
372  }
373 
374  return (true);
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////////////////
378 template <typename PointT> bool
380  const pcl::PlanarPolygon<PointT> &polygon,
381  double r, double g, double b, const std::string &id, int viewport)
382 {
383  vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (polygon);
384  if (!data)
385  return (false);
386 
387  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
388  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
389  if (am_it != shape_actor_map_->end ())
390  {
392 
393  // Add old data
394 #if VTK_MAJOR_VERSION < 6
395  all_data->AddInput (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
396 #else
397  all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
398 #endif
399 
400  // Add new data
402 #if VTK_MAJOR_VERSION < 6
403  surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data));
404 #else
405  surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
406 #endif
407  vtkSmartPointer<vtkPolyData> poly_data = surface_filter->GetOutput ();
408 #if VTK_MAJOR_VERSION < 6
409  all_data->AddInput (poly_data);
410 #else
411  all_data->AddInputData (poly_data);
412 #endif
413 
414  // Create an Actor
416  createActorFromVTKDataSet (all_data->GetOutput (), actor);
417  actor->GetProperty ()->SetRepresentationToWireframe ();
418  actor->GetProperty ()->SetColor (r, g, b);
419  actor->GetMapper ()->ScalarVisibilityOn ();
420  actor->GetProperty ()->BackfaceCullingOff ();
421  removeActorFromRenderer (am_it->second, viewport);
422  addActorToRenderer (actor, viewport);
423 
424  // Save the pointer/ID pair to the global actor map
425  (*shape_actor_map_)[id] = actor;
426  }
427  else
428  {
429  // Create an Actor
431  createActorFromVTKDataSet (data, actor);
432  actor->GetProperty ()->SetRepresentationToWireframe ();
433  actor->GetProperty ()->SetColor (r, g, b);
434  actor->GetMapper ()->ScalarVisibilityOn ();
435  actor->GetProperty ()->BackfaceCullingOff ();
436  addActorToRenderer (actor, viewport);
437 
438  // Save the pointer/ID pair to the global actor map
439  (*shape_actor_map_)[id] = actor;
440  }
441  return (true);
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////////////////
445 template <typename PointT> bool
447  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
448  const std::string &id, int viewport)
449 {
450  return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5, id, viewport));
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////////////////
454 template <typename P1, typename P2> bool
455 pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport)
456 {
457  if (contains (id))
458  {
459  PCL_WARN ("[addLine] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
460  return (false);
461  }
462 
463  vtkSmartPointer<vtkDataSet> data = createLine (pt1.getVector4fMap (), pt2.getVector4fMap ());
464 
465  // Create an Actor
467  createActorFromVTKDataSet (data, actor);
468  actor->GetProperty ()->SetRepresentationToWireframe ();
469  actor->GetProperty ()->SetColor (r, g, b);
470  actor->GetMapper ()->ScalarVisibilityOff ();
471  addActorToRenderer (actor, viewport);
472 
473  // Save the pointer/ID pair to the global actor map
474  (*shape_actor_map_)[id] = actor;
475  return (true);
476 }
477 
478 ////////////////////////////////////////////////////////////////////////////////////////////
479 template <typename P1, typename P2> bool
480 pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport)
481 {
482  if (contains (id))
483  {
484  PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
485  return (false);
486  }
487 
488  // Create an Actor
490  leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
491  leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
492  leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
493  leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
494  leader->SetArrowStyleToFilled ();
495  leader->AutoLabelOn ();
496 
497  leader->GetProperty ()->SetColor (r, g, b);
498  addActorToRenderer (leader, viewport);
499 
500  // Save the pointer/ID pair to the global actor map
501  (*shape_actor_map_)[id] = leader;
502  return (true);
503 }
504 
505 ////////////////////////////////////////////////////////////////////////////////////////////
506 template <typename P1, typename P2> bool
507 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)
508 {
509  if (contains (id))
510  {
511  PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
512  return (false);
513  }
514 
515  // Create an Actor
517  leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
518  leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
519  leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
520  leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
521  leader->SetArrowStyleToFilled ();
522  leader->SetArrowPlacementToPoint1 ();
523  if (display_length)
524  leader->AutoLabelOn ();
525  else
526  leader->AutoLabelOff ();
527 
528  leader->GetProperty ()->SetColor (r, g, b);
529  addActorToRenderer (leader, viewport);
530 
531  // Save the pointer/ID pair to the global actor map
532  (*shape_actor_map_)[id] = leader;
533  return (true);
534 }
535 ////////////////////////////////////////////////////////////////////////////////////////////
536 template <typename P1, typename P2> bool
537 pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2,
538  double r_line, double g_line, double b_line,
539  double r_text, double g_text, double b_text,
540  const std::string &id, int viewport)
541 {
542  if (contains (id))
543  {
544  PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
545  return (false);
546  }
547 
548  // Create an Actor
550  leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
551  leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
552  leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
553  leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
554  leader->SetArrowStyleToFilled ();
555  leader->AutoLabelOn ();
556 
557  leader->GetLabelTextProperty()->SetColor(r_text, g_text, b_text);
558 
559  leader->GetProperty ()->SetColor (r_line, g_line, b_line);
560  addActorToRenderer (leader, viewport);
561 
562  // Save the pointer/ID pair to the global actor map
563  (*shape_actor_map_)[id] = leader;
564  return (true);
565 }
566 
567 ////////////////////////////////////////////////////////////////////////////////////////////
568 template <typename P1, typename P2> bool
569 pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, const std::string &id, int viewport)
570 {
571  return (!addLine (pt1, pt2, 0.5, 0.5, 0.5, id, viewport));
572 }
573 
574 ////////////////////////////////////////////////////////////////////////////////////////////
575 template <typename PointT> bool
576 pcl::visualization::PCLVisualizer::addSphere (const PointT &center, double radius, double r, double g, double b, const std::string &id, int viewport)
577 {
578  if (contains (id))
579  {
580  PCL_WARN ("[addSphere] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
581  return (false);
582  }
583 
585  data->SetRadius (radius);
586  data->SetCenter (double (center.x), double (center.y), double (center.z));
587  data->SetPhiResolution (10);
588  data->SetThetaResolution (10);
589  data->LatLongTessellationOff ();
590  data->Update ();
591 
592  // Setup actor and mapper
594  mapper->SetInputConnection (data->GetOutputPort ());
595 
596  // Create an Actor
598  actor->SetMapper (mapper);
599  //createActorFromVTKDataSet (data, actor);
600  actor->GetProperty ()->SetRepresentationToSurface ();
601  actor->GetProperty ()->SetInterpolationToFlat ();
602  actor->GetProperty ()->SetColor (r, g, b);
603  actor->GetMapper ()->ImmediateModeRenderingOn ();
604  actor->GetMapper ()->StaticOn ();
605  actor->GetMapper ()->ScalarVisibilityOff ();
606  actor->GetMapper ()->Update ();
607  addActorToRenderer (actor, viewport);
608 
609  // Save the pointer/ID pair to the global actor map
610  (*shape_actor_map_)[id] = actor;
611  return (true);
612 }
613 
614 ////////////////////////////////////////////////////////////////////////////////////////////
615 template <typename PointT> bool
616 pcl::visualization::PCLVisualizer::addSphere (const PointT &center, double radius, const std::string &id, int viewport)
617 {
618  return (addSphere (center, radius, 0.5, 0.5, 0.5, id, viewport));
619 }
620 
621 ////////////////////////////////////////////////////////////////////////////////////////////
622 template<typename PointT> bool
623 pcl::visualization::PCLVisualizer::updateSphere (const PointT &center, double radius, double r, double g, double b, const std::string &id)
624 {
625  if (!contains (id))
626  {
627  return (false);
628  }
629 
630  //////////////////////////////////////////////////////////////////////////
631  // Get the actor pointer
632  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
633  vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
634  if (!actor)
635  return (false);
636 #if VTK_MAJOR_VERSION < 6
637  vtkAlgorithm *algo = actor->GetMapper ()->GetInput ()->GetProducerPort ()->GetProducer ();
638 #else
639  vtkAlgorithm *algo = actor->GetMapper ()->GetInputAlgorithm ();
640 #endif
641  vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo);
642  if (!src)
643  return (false);
644 
645  src->SetCenter (double (center.x), double (center.y), double (center.z));
646  src->SetRadius (radius);
647  src->Update ();
648  actor->GetProperty ()->SetColor (r, g, b);
649  actor->Modified ();
650 
651  return (true);
652 }
653 
654 //////////////////////////////////////////////////
655 template <typename PointT> bool
657  const std::string &text,
658  const PointT& position,
659  double textScale,
660  double r,
661  double g,
662  double b,
663  const std::string &id,
664  int viewport)
665 {
666  std::string tid;
667  if (id.empty ())
668  tid = text;
669  else
670  tid = id;
671 
672  if (contains (tid))
673  {
674  PCL_WARN ("[addText3D] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
675  return (false);
676  }
677 
679  textSource->SetText (text.c_str());
680  textSource->Update ();
681 
683  textMapper->SetInputConnection (textSource->GetOutputPort ());
684 
685  // Since each follower may follow a different camera, we need different followers
686  rens_->InitTraversal ();
687  vtkRenderer* renderer = NULL;
688  int i = 0;
689  while ((renderer = rens_->GetNextItem ()) != NULL)
690  {
691  // Should we add the actor to all renderers or just to i-nth renderer?
692  if (viewport == 0 || viewport == i)
693  {
695  textActor->SetMapper (textMapper);
696  textActor->SetPosition (position.x, position.y, position.z);
697  textActor->SetScale (textScale);
698  textActor->GetProperty ()->SetColor (r, g, b);
699  textActor->SetCamera (renderer->GetActiveCamera ());
700 
701  renderer->AddActor (textActor);
702  renderer->Render ();
703 
704  // Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers
705  // for multiple viewport
706  std::string alternate_tid = tid;
707  alternate_tid.append(i, '*');
708 
709  (*shape_actor_map_)[(viewport == 0) ? tid : alternate_tid] = textActor;
710  }
711 
712  ++i;
713  }
714 
715  return (true);
716 }
717 
718 //////////////////////////////////////////////////////////////////////////////////////////////
719 template <typename PointNT> bool
721  const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
722  int level, float scale, const std::string &id, int viewport)
723 {
724  return (addPointCloudNormals<PointNT, PointNT> (cloud, cloud, level, scale, id, viewport));
725 }
726 
727 //////////////////////////////////////////////////////////////////////////////////////////////
728 template <typename PointT, typename PointNT> bool
730  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
731  const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
732  int level, float scale,
733  const std::string &id, int viewport)
734 {
735  if (normals->points.size () != cloud->points.size ())
736  {
737  PCL_ERROR ("[addPointCloudNormals] The number of points differs from the number of normals!\n");
738  return (false);
739  }
740  if (contains (id))
741  {
742  PCL_WARN ("[addPointCloudNormals] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
743  return (false);
744  }
745 
748 
749  points->SetDataTypeToFloat ();
751  data->SetNumberOfComponents (3);
752 
753 
754  vtkIdType nr_normals = 0;
755  float* pts = 0;
756 
757  // If the cloud is organized, then distribute the normal step in both directions
758  if (cloud->isOrganized () && normals->isOrganized ())
759  {
760  vtkIdType point_step = static_cast<vtkIdType> (sqrt (double (level)));
761  nr_normals = (static_cast<vtkIdType> ((cloud->width - 1)/ point_step) + 1) *
762  (static_cast<vtkIdType> ((cloud->height - 1) / point_step) + 1);
763  pts = new float[2 * nr_normals * 3];
764 
765  vtkIdType cell_count = 0;
766  for (vtkIdType y = 0; y < normals->height; y += point_step)
767  for (vtkIdType x = 0; x < normals->width; x += point_step)
768  {
769  PointT p = (*cloud)(x, y);
770  p.x += (*normals)(x, y).normal[0] * scale;
771  p.y += (*normals)(x, y).normal[1] * scale;
772  p.z += (*normals)(x, y).normal[2] * scale;
773 
774  pts[2 * cell_count * 3 + 0] = (*cloud)(x, y).x;
775  pts[2 * cell_count * 3 + 1] = (*cloud)(x, y).y;
776  pts[2 * cell_count * 3 + 2] = (*cloud)(x, y).z;
777  pts[2 * cell_count * 3 + 3] = p.x;
778  pts[2 * cell_count * 3 + 4] = p.y;
779  pts[2 * cell_count * 3 + 5] = p.z;
780 
781  lines->InsertNextCell (2);
782  lines->InsertCellPoint (2 * cell_count);
783  lines->InsertCellPoint (2 * cell_count + 1);
784  cell_count ++;
785  }
786  }
787  else
788  {
789  nr_normals = (cloud->points.size () - 1) / level + 1 ;
790  pts = new float[2 * nr_normals * 3];
791 
792  for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level)
793  {
794  PointT p = cloud->points[i];
795  p.x += normals->points[i].normal[0] * scale;
796  p.y += normals->points[i].normal[1] * scale;
797  p.z += normals->points[i].normal[2] * scale;
798 
799  pts[2 * j * 3 + 0] = cloud->points[i].x;
800  pts[2 * j * 3 + 1] = cloud->points[i].y;
801  pts[2 * j * 3 + 2] = cloud->points[i].z;
802  pts[2 * j * 3 + 3] = p.x;
803  pts[2 * j * 3 + 4] = p.y;
804  pts[2 * j * 3 + 5] = p.z;
805 
806  lines->InsertNextCell (2);
807  lines->InsertCellPoint (2 * j);
808  lines->InsertCellPoint (2 * j + 1);
809  }
810  }
811 
812  data->SetArray (&pts[0], 2 * nr_normals * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
813  points->SetData (data);
814 
816  polyData->SetPoints (points);
817  polyData->SetLines (lines);
818 
820 #if VTK_MAJOR_VERSION < 6
821  mapper->SetInput (polyData);
822 #else
823  mapper->SetInputData (polyData);
824 #endif
825  mapper->SetColorModeToMapScalars();
826  mapper->SetScalarModeToUsePointData();
827 
828  // create actor
830  actor->SetMapper (mapper);
831 
832  // Use cloud view point info
834  convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
835  actor->SetUserMatrix (transformation);
836 
837  // Add it to all renderers
838  addActorToRenderer (actor, viewport);
839 
840  // Save the pointer/ID pair to the global actor map
841  (*cloud_actor_map_)[id].actor = actor;
842  return (true);
843 }
844 
845 //////////////////////////////////////////////////////////////////////////////////////////////
846 template <typename PointNT> bool
848  const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
850  int level, float scale,
851  const std::string &id, int viewport)
852 {
853  return (addPointCloudPrincipalCurvatures<PointNT, PointNT> (cloud, cloud, pcs, level, scale, id, viewport));
854 }
855 
856 //////////////////////////////////////////////////////////////////////////////////////////////
857 template <typename PointT, typename PointNT> bool
859  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
860  const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
862  int level, float scale,
863  const std::string &id, int viewport)
864 {
865  if (pcs->points.size () != cloud->points.size () || normals->points.size () != cloud->points.size ())
866  {
867  pcl::console::print_error ("[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
868  return (false);
869  }
870 
871  if (contains (id))
872  {
873  PCL_WARN ("[addPointCloudPrincipalCurvatures] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
874  return (false);
875  }
876 
879 
880  // Setup two colors - one for each line
881  unsigned char green[3] = {0, 255, 0};
882  unsigned char blue[3] = {0, 0, 255};
883 
884  // Setup the colors array
886  line_1_colors->SetNumberOfComponents (3);
887  line_1_colors->SetName ("Colors");
889  line_2_colors->SetNumberOfComponents (3);
890  line_2_colors->SetName ("Colors");
891 
892  // Create the first sets of lines
893  for (size_t i = 0; i < cloud->points.size (); i+=level)
894  {
895  PointT p = cloud->points[i];
896  p.x += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[0]) * scale;
897  p.y += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[1]) * scale;
898  p.z += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[2]) * scale;
899 
901  line_1->SetPoint1 (cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
902  line_1->SetPoint2 (p.x, p.y, p.z);
903  line_1->Update ();
904 #if VTK_MAJOR_VERSION < 6
905  polydata_1->AddInput (line_1->GetOutput ());
906 #else
907  polydata_1->AddInputData (line_1->GetOutput ());
908 #endif
909  line_1_colors->InsertNextTupleValue (green);
910  }
911  polydata_1->Update ();
912  vtkSmartPointer<vtkPolyData> line_1_data = polydata_1->GetOutput ();
913  line_1_data->GetCellData ()->SetScalars (line_1_colors);
914 
915  // Create the second sets of lines
916  for (size_t i = 0; i < cloud->points.size (); i += level)
917  {
918  Eigen::Vector3f pc (pcs->points[i].principal_curvature[0],
919  pcs->points[i].principal_curvature[1],
920  pcs->points[i].principal_curvature[2]);
921  Eigen::Vector3f normal (normals->points[i].normal[0],
922  normals->points[i].normal[1],
923  normals->points[i].normal[2]);
924  Eigen::Vector3f pc_c = pc.cross (normal);
925 
926  PointT p = cloud->points[i];
927  p.x += (pcs->points[i].pc2 * pc_c[0]) * scale;
928  p.y += (pcs->points[i].pc2 * pc_c[1]) * scale;
929  p.z += (pcs->points[i].pc2 * pc_c[2]) * scale;
930 
932  line_2->SetPoint1 (cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
933  line_2->SetPoint2 (p.x, p.y, p.z);
934  line_2->Update ();
935 #if VTK_MAJOR_VERSION < 6
936  polydata_2->AddInput (line_2->GetOutput ());
937 #else
938  polydata_2->AddInputData (line_2->GetOutput ());
939 #endif
940 
941  line_2_colors->InsertNextTupleValue (blue);
942  }
943  polydata_2->Update ();
944  vtkSmartPointer<vtkPolyData> line_2_data = polydata_2->GetOutput ();
945  line_2_data->GetCellData ()->SetScalars (line_2_colors);
946 
947  // Assemble the two sets of lines
949 #if VTK_MAJOR_VERSION < 6
950  alldata->AddInput (line_1_data);
951  alldata->AddInput (line_2_data);
952 #else
953  alldata->AddInputData (line_1_data);
954  alldata->AddInputData (line_2_data);
955 #endif
956 
957  // Create an Actor
959  createActorFromVTKDataSet (alldata->GetOutput (), actor);
960  actor->GetMapper ()->SetScalarModeToUseCellData ();
961 
962  // Add it to all renderers
963  addActorToRenderer (actor, viewport);
964 
965  // Save the pointer/ID pair to the global actor map
966  CloudActor act;
967  act.actor = actor;
968  (*cloud_actor_map_)[id] = act;
969  return (true);
970 }
971 
972 //////////////////////////////////////////////////////////////////////////////////////////////
973 template <typename PointT, typename GradientT> bool
975  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
976  const typename pcl::PointCloud<GradientT>::ConstPtr &gradients,
977  int level, double scale,
978  const std::string &id, int viewport)
979 {
980  if (gradients->points.size () != cloud->points.size ())
981  {
982  PCL_ERROR ("[addPointCloudGradients] The number of points differs from the number of gradients!\n");
983  return (false);
984  }
985  if (contains (id))
986  {
987  PCL_WARN ("[addPointCloudGradients] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
988  return (false);
989  }
990 
993 
994  points->SetDataTypeToFloat ();
996  data->SetNumberOfComponents (3);
997 
998  vtkIdType nr_gradients = (cloud->points.size () - 1) / level + 1 ;
999  float* pts = new float[2 * nr_gradients * 3];
1000 
1001  for (vtkIdType i = 0, j = 0; j < nr_gradients; j++, i = j * level)
1002  {
1003  PointT p = cloud->points[i];
1004  p.x += gradients->points[i].gradient[0] * scale;
1005  p.y += gradients->points[i].gradient[1] * scale;
1006  p.z += gradients->points[i].gradient[2] * scale;
1007 
1008  pts[2 * j * 3 + 0] = cloud->points[i].x;
1009  pts[2 * j * 3 + 1] = cloud->points[i].y;
1010  pts[2 * j * 3 + 2] = cloud->points[i].z;
1011  pts[2 * j * 3 + 3] = p.x;
1012  pts[2 * j * 3 + 4] = p.y;
1013  pts[2 * j * 3 + 5] = p.z;
1014 
1015  lines->InsertNextCell(2);
1016  lines->InsertCellPoint(2*j);
1017  lines->InsertCellPoint(2*j+1);
1018  }
1019 
1020  data->SetArray (&pts[0], 2 * nr_gradients * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
1021  points->SetData (data);
1022 
1024  polyData->SetPoints(points);
1025  polyData->SetLines(lines);
1026 
1028 #if VTK_MAJOR_VERSION < 6
1029  mapper->SetInput (polyData);
1030 #else
1031  mapper->SetInputData (polyData);
1032 #endif
1033  mapper->SetColorModeToMapScalars();
1034  mapper->SetScalarModeToUsePointData();
1035 
1036  // create actor
1038  actor->SetMapper (mapper);
1039 
1040  // Add it to all renderers
1041  addActorToRenderer (actor, viewport);
1042 
1043  // Save the pointer/ID pair to the global actor map
1044  (*cloud_actor_map_)[id].actor = actor;
1045  return (true);
1046 }
1047 
1048 //////////////////////////////////////////////////////////////////////////////////////////////
1049 template <typename PointT> bool
1051  const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1052  const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1053  const std::vector<int> &correspondences,
1054  const std::string &id,
1055  int viewport)
1056 {
1057  pcl::Correspondences corrs;
1058  corrs.resize (correspondences.size ());
1059 
1060  size_t index = 0;
1061  for (pcl::Correspondences::iterator corrs_it (corrs.begin ()); corrs_it != corrs.end (); ++corrs_it)
1062  {
1063  corrs_it->index_query = index;
1064  corrs_it->index_match = correspondences[index];
1065  index++;
1066  }
1067 
1068  return (addCorrespondences<PointT> (source_points, target_points, corrs, id, viewport));
1069 }
1070 
1071 //////////////////////////////////////////////////////////////////////////////////////////////
1072 template <typename PointT> bool
1074  const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1075  const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1076  const pcl::Correspondences &correspondences,
1077  int nth,
1078  const std::string &id,
1079  int viewport,
1080  bool overwrite)
1081 {
1082  if (correspondences.empty ())
1083  {
1084  PCL_DEBUG ("[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1085  return (false);
1086  }
1087 
1088  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1089  ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
1090  if (am_it != shape_actor_map_->end () && overwrite == false)
1091  {
1092  PCL_WARN ("[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
1093  return (false);
1094  } else if (am_it == shape_actor_map_->end () && overwrite == true)
1095  {
1096  overwrite = false; // Correspondences doesn't exist, add them instead of updating them
1097  }
1098 
1099  int n_corr = int (correspondences.size () / nth);
1101 
1102  // Prepare colors
1104  line_colors->SetNumberOfComponents (3);
1105  line_colors->SetName ("Colors");
1106  line_colors->SetNumberOfTuples (n_corr);
1107 
1108  // Prepare coordinates
1110  line_points->SetNumberOfPoints (2 * n_corr);
1111 
1113  line_cells_id->SetNumberOfComponents (3);
1114  line_cells_id->SetNumberOfTuples (n_corr);
1115  vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
1117 
1119  line_tcoords->SetNumberOfComponents (1);
1120  line_tcoords->SetNumberOfTuples (n_corr * 2);
1121  line_tcoords->SetName ("Texture Coordinates");
1122 
1123  double tc[3] = {0.0, 0.0, 0.0};
1124 
1125  Eigen::Affine3f source_transformation;
1126  source_transformation.linear () = source_points->sensor_orientation_.matrix ();
1127  source_transformation.translation () = source_points->sensor_origin_.head (3);
1128  Eigen::Affine3f target_transformation;
1129  target_transformation.linear () = target_points->sensor_orientation_.matrix ();
1130  target_transformation.translation () = target_points->sensor_origin_.head (3);
1131 
1132  int j = 0;
1133  // Draw lines between the best corresponding points
1134  for (size_t i = 0; i < correspondences.size (); i += nth, ++j)
1135  {
1136  if (correspondences[i].index_match == -1)
1137  {
1138  PCL_WARN ("[addCorrespondences] No valid index_match for correspondence %d\n", i);
1139  continue;
1140  }
1141 
1142  PointT p_src (source_points->points[correspondences[i].index_query]);
1143  PointT p_tgt (target_points->points[correspondences[i].index_match]);
1144 
1145  p_src.getVector3fMap () = source_transformation * p_src.getVector3fMap ();
1146  p_tgt.getVector3fMap () = target_transformation * p_tgt.getVector3fMap ();
1147 
1148  int id1 = j * 2 + 0, id2 = j * 2 + 1;
1149  // Set the points
1150  line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
1151  line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
1152  // Set the cell ID
1153  *line_cell_id++ = 2;
1154  *line_cell_id++ = id1;
1155  *line_cell_id++ = id2;
1156  // Set the texture coords
1157  tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
1158  tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
1159 
1160  float rgb[3];
1161  rgb[0] = vtkMath::Random (32, 255); // min / max
1162  rgb[1] = vtkMath::Random (32, 255);
1163  rgb[2] = vtkMath::Random (32, 255);
1164  line_colors->InsertTuple (i, rgb);
1165  }
1166  line_colors->SetNumberOfTuples (j);
1167  line_cells_id->SetNumberOfTuples (j);
1168  line_cells->SetCells (n_corr, line_cells_id);
1169  line_points->SetNumberOfPoints (j*2);
1170  line_tcoords->SetNumberOfTuples (j*2);
1171 
1172  // Fill in the lines
1173  line_data->SetPoints (line_points);
1174  line_data->SetLines (line_cells);
1175  line_data->GetPointData ()->SetTCoords (line_tcoords);
1176  line_data->GetCellData ()->SetScalars (line_colors);
1177 
1178  // Create an Actor
1179  if (!overwrite)
1180  {
1182  createActorFromVTKDataSet (line_data, actor);
1183  actor->GetProperty ()->SetRepresentationToWireframe ();
1184  actor->GetProperty ()->SetOpacity (0.5);
1185  addActorToRenderer (actor, viewport);
1186 
1187  // Save the pointer/ID pair to the global actor map
1188  (*shape_actor_map_)[id] = actor;
1189  }
1190  else
1191  {
1192  vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast (am_it->second);
1193  if (!actor)
1194  return (false);
1195  // Update the mapper
1196 #if VTK_MAJOR_VERSION < 6
1197  reinterpret_cast<vtkPolyDataMapper*>(actor->GetMapper ())->SetInput (line_data);
1198 #else
1199  reinterpret_cast<vtkPolyDataMapper*> (actor->GetMapper ())->SetInputData (line_data);
1200 #endif
1201  }
1202 
1203  return (true);
1204 }
1205 
1206 //////////////////////////////////////////////////////////////////////////////////////////////
1207 template <typename PointT> bool
1209  const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1210  const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1211  const pcl::Correspondences &correspondences,
1212  int nth,
1213  const std::string &id,
1214  int viewport)
1215 {
1216  return (addCorrespondences<PointT> (source_points, target_points, correspondences, nth, id, viewport, true));
1217 }
1218 
1219 //////////////////////////////////////////////////////////////////////////////////////////////
1220 template <typename PointT> bool
1221 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1222  const PointCloudGeometryHandler<PointT> &geometry_handler,
1223  const PointCloudColorHandler<PointT> &color_handler,
1224  const std::string &id,
1225  int viewport,
1226  const Eigen::Vector4f& sensor_origin,
1227  const Eigen::Quaternion<float>& sensor_orientation)
1228 {
1229  if (!geometry_handler.isCapable ())
1230  {
1231  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
1232  return (false);
1233  }
1234 
1235  if (!color_handler.isCapable ())
1236  {
1237  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
1238  return (false);
1239  }
1240 
1243  // Convert the PointCloud to VTK PolyData
1244  convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1245  // use the given geometry handler
1246 
1247  // Get the colors from the handler
1248  bool has_colors = false;
1249  double minmax[2];
1251  if (color_handler.getColor (scalars))
1252  {
1253  polydata->GetPointData ()->SetScalars (scalars);
1254  scalars->GetRange (minmax);
1255  has_colors = true;
1256  }
1257 
1258  // Create an Actor
1260  createActorFromVTKDataSet (polydata, actor);
1261  if (has_colors)
1262  actor->GetMapper ()->SetScalarRange (minmax);
1263 
1264  // Add it to all renderers
1265  addActorToRenderer (actor, viewport);
1266 
1267  // Save the pointer/ID pair to the global actor map
1268  CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1269  cloud_actor.actor = actor;
1270  cloud_actor.cells = initcells;
1271 
1272  // Save the viewpoint transformation matrix to the global actor map
1274  convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1275  cloud_actor.viewpoint_transformation_ = transformation;
1276  cloud_actor.actor->SetUserMatrix (transformation);
1277  cloud_actor.actor->Modified ();
1278 
1279  return (true);
1280 }
1281 
1282 //////////////////////////////////////////////////////////////////////////////////////////////
1283 template <typename PointT> bool
1284 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1285  const PointCloudGeometryHandler<PointT> &geometry_handler,
1286  const ColorHandlerConstPtr &color_handler,
1287  const std::string &id,
1288  int viewport,
1289  const Eigen::Vector4f& sensor_origin,
1290  const Eigen::Quaternion<float>& sensor_orientation)
1291 {
1292  if (!geometry_handler.isCapable ())
1293  {
1294  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
1295  return (false);
1296  }
1297 
1298  if (!color_handler->isCapable ())
1299  {
1300  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ());
1301  return (false);
1302  }
1303 
1306  // Convert the PointCloud to VTK PolyData
1307  convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1308  // use the given geometry handler
1309 
1310  // Get the colors from the handler
1311  bool has_colors = false;
1312  double minmax[2];
1314  if (color_handler->getColor (scalars))
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  cloud_actor.color_handlers.push_back (color_handler);
1335 
1336  // Save the viewpoint transformation matrix to the global actor map
1338  convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1339  cloud_actor.viewpoint_transformation_ = transformation;
1340  cloud_actor.actor->SetUserMatrix (transformation);
1341  cloud_actor.actor->Modified ();
1342 
1343  return (true);
1344 }
1345 
1346 //////////////////////////////////////////////////////////////////////////////////////////////
1347 template <typename PointT> bool
1348 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1349  const GeometryHandlerConstPtr &geometry_handler,
1350  const PointCloudColorHandler<PointT> &color_handler,
1351  const std::string &id,
1352  int viewport,
1353  const Eigen::Vector4f& sensor_origin,
1354  const Eigen::Quaternion<float>& sensor_orientation)
1355 {
1356  if (!geometry_handler->isCapable ())
1357  {
1358  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ());
1359  return (false);
1360  }
1361 
1362  if (!color_handler.isCapable ())
1363  {
1364  PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
1365  return (false);
1366  }
1367 
1370  // Convert the PointCloud to VTK PolyData
1371  convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
1372  // use the given geometry handler
1373 
1374  // Get the colors from the handler
1375  bool has_colors = false;
1376  double minmax[2];
1378  if (color_handler.getColor (scalars))
1379  {
1380  polydata->GetPointData ()->SetScalars (scalars);
1381  scalars->GetRange (minmax);
1382  has_colors = true;
1383  }
1384 
1385  // Create an Actor
1387  createActorFromVTKDataSet (polydata, actor);
1388  if (has_colors)
1389  actor->GetMapper ()->SetScalarRange (minmax);
1390 
1391  // Add it to all renderers
1392  addActorToRenderer (actor, viewport);
1393 
1394  // Save the pointer/ID pair to the global actor map
1395  CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1396  cloud_actor.actor = actor;
1397  cloud_actor.cells = initcells;
1398  cloud_actor.geometry_handlers.push_back (geometry_handler);
1399 
1400  // Save the viewpoint transformation matrix to the global actor map
1402  convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1403  cloud_actor.viewpoint_transformation_ = transformation;
1404  cloud_actor.actor->SetUserMatrix (transformation);
1405  cloud_actor.actor->Modified ();
1406 
1407  return (true);
1408 }
1409 
1410 //////////////////////////////////////////////////////////////////////////////////////////////
1411 template <typename PointT> bool
1413  const std::string &id)
1414 {
1415  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1416  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1417 
1418  if (am_it == cloud_actor_map_->end ())
1419  return (false);
1420 
1421  vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1422  // Convert the PointCloud to VTK PolyData
1423  convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
1424 
1425  // Set scalars to blank, since there is no way we can update them here.
1427  polydata->GetPointData ()->SetScalars (scalars);
1428  double minmax[2];
1429  minmax[0] = std::numeric_limits<double>::min ();
1430  minmax[1] = std::numeric_limits<double>::max ();
1431  am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1432  am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1433 
1434  // Update the mapper
1435 #if VTK_MAJOR_VERSION < 6
1436  reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1437 #else
1438  reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1439 #endif
1440  return (true);
1441 }
1442 
1443 /////////////////////////////////////////////////////////////////////////////////////////////
1444 template <typename PointT> bool
1446  const PointCloudGeometryHandler<PointT> &geometry_handler,
1447  const std::string &id)
1448 {
1449  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1450  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1451 
1452  if (am_it == cloud_actor_map_->end ())
1453  return (false);
1454 
1455  vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1456  if (!polydata)
1457  return (false);
1458  // Convert the PointCloud to VTK PolyData
1459  convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
1460 
1461  // Set scalars to blank, since there is no way we can update them here.
1463  polydata->GetPointData ()->SetScalars (scalars);
1464  double minmax[2];
1465  minmax[0] = std::numeric_limits<double>::min ();
1466  minmax[1] = std::numeric_limits<double>::max ();
1467  am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1468  am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1469 
1470  // Update the mapper
1471 #if VTK_MAJOR_VERSION < 6
1472  reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1473 #else
1474  reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1475 #endif
1476  return (true);
1477 }
1478 
1479 
1480 /////////////////////////////////////////////////////////////////////////////////////////////
1481 template <typename PointT> bool
1483  const PointCloudColorHandler<PointT> &color_handler,
1484  const std::string &id)
1485 {
1486  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1487  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1488 
1489  if (am_it == cloud_actor_map_->end ())
1490  return (false);
1491 
1492  // Get the current poly data
1493  vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1494  if (!polydata)
1495  return (false);
1496  vtkSmartPointer<vtkCellArray> vertices = polydata->GetVerts ();
1497  vtkSmartPointer<vtkPoints> points = polydata->GetPoints ();
1498  // Copy the new point array in
1499  vtkIdType nr_points = cloud->points.size ();
1500  points->SetNumberOfPoints (nr_points);
1501 
1502  // Get a pointer to the beginning of the data array
1503  float *data = (static_cast<vtkFloatArray*> (points->GetData ()))->GetPointer (0);
1504 
1505  int pts = 0;
1506  // If the dataset is dense (no NaNs)
1507  if (cloud->is_dense)
1508  {
1509  for (vtkIdType i = 0; i < nr_points; ++i, pts += 3)
1510  memcpy (&data[pts], &cloud->points[i].x, 12); // sizeof (float) * 3
1511  }
1512  else
1513  {
1514  vtkIdType j = 0; // true point index
1515  for (vtkIdType i = 0; i < nr_points; ++i)
1516  {
1517  // Check if the point is invalid
1518  if (!isFinite (cloud->points[i]))
1519  continue;
1520 
1521  memcpy (&data[pts], &cloud->points[i].x, 12); // sizeof (float) * 3
1522  pts += 3;
1523  j++;
1524  }
1525  nr_points = j;
1526  points->SetNumberOfPoints (nr_points);
1527  }
1528 
1529  vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
1530  updateCells (cells, am_it->second.cells, nr_points);
1531 
1532  // Set the cells and the vertices
1533  vertices->SetCells (nr_points, cells);
1534 
1535  // Get the colors from the handler
1537  color_handler.getColor (scalars);
1538  double minmax[2];
1539  scalars->GetRange (minmax);
1540  // Update the data
1541  polydata->GetPointData ()->SetScalars (scalars);
1542 
1543  am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1544  am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1545 
1546  // Update the mapper
1547 #if VTK_MAJOR_VERSION < 6
1548  reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1549 #else
1550  reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1551 #endif
1552  return (true);
1553 }
1554 
1555 /////////////////////////////////////////////////////////////////////////////////////////////
1556 template <typename PointT> bool
1558  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1559  const std::vector<pcl::Vertices> &vertices,
1560  const std::string &id,
1561  int viewport)
1562 {
1563  if (vertices.empty () || cloud->points.empty ())
1564  return (false);
1565 
1566  if (contains (id))
1567  {
1568  PCL_WARN ("[addPolygonMesh] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
1569  return (false);
1570  }
1571 
1572  int rgb_idx = -1;
1573  std::vector<pcl::PCLPointField> fields;
1575  rgb_idx = pcl::getFieldIndex (*cloud, "rgb", fields);
1576  if (rgb_idx == -1)
1577  rgb_idx = pcl::getFieldIndex (*cloud, "rgba", fields);
1578  if (rgb_idx != -1)
1579  {
1581  colors->SetNumberOfComponents (3);
1582  colors->SetName ("Colors");
1583 
1584  pcl::RGB rgb_data;
1585  for (size_t i = 0; i < cloud->size (); ++i)
1586  {
1587  if (!isFinite (cloud->points[i]))
1588  continue;
1589  memcpy (&rgb_data, reinterpret_cast<const char*> (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (pcl::RGB));
1590  unsigned char color[3];
1591  color[0] = rgb_data.r;
1592  color[1] = rgb_data.g;
1593  color[2] = rgb_data.b;
1594  colors->InsertNextTupleValue (color);
1595  }
1596  }
1597 
1598  // Create points from polyMesh.cloud
1600  vtkIdType nr_points = cloud->points.size ();
1601  points->SetNumberOfPoints (nr_points);
1603 
1604  // Get a pointer to the beginning of the data array
1605  float *data = static_cast<vtkFloatArray*> (points->GetData ())->GetPointer (0);
1606 
1607  int ptr = 0;
1608  std::vector<int> lookup;
1609  // If the dataset is dense (no NaNs)
1610  if (cloud->is_dense)
1611  {
1612  for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1613  memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3);
1614  }
1615  else
1616  {
1617  lookup.resize (nr_points);
1618  vtkIdType j = 0; // true point index
1619  for (vtkIdType i = 0; i < nr_points; ++i)
1620  {
1621  // Check if the point is invalid
1622  if (!isFinite (cloud->points[i]))
1623  continue;
1624 
1625  lookup[i] = static_cast<int> (j);
1626  memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3);
1627  j++;
1628  ptr += 3;
1629  }
1630  nr_points = j;
1631  points->SetNumberOfPoints (nr_points);
1632  }
1633 
1634  // Get the maximum size of a polygon
1635  int max_size_of_polygon = -1;
1636  for (size_t i = 0; i < vertices.size (); ++i)
1637  if (max_size_of_polygon < static_cast<int> (vertices[i].vertices.size ()))
1638  max_size_of_polygon = static_cast<int> (vertices[i].vertices.size ());
1639 
1640  if (vertices.size () > 1)
1641  {
1642  // Create polys from polyMesh.polygons
1644  vtkIdType *cell = cell_array->WritePointer (vertices.size (), vertices.size () * (max_size_of_polygon + 1));
1645  int idx = 0;
1646  if (lookup.size () > 0)
1647  {
1648  for (size_t i = 0; i < vertices.size (); ++i, ++idx)
1649  {
1650  size_t n_points = vertices[i].vertices.size ();
1651  *cell++ = n_points;
1652  //cell_array->InsertNextCell (n_points);
1653  for (size_t j = 0; j < n_points; j++, ++idx)
1654  *cell++ = lookup[vertices[i].vertices[j]];
1655  //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]);
1656  }
1657  }
1658  else
1659  {
1660  for (size_t i = 0; i < vertices.size (); ++i, ++idx)
1661  {
1662  size_t n_points = vertices[i].vertices.size ();
1663  *cell++ = n_points;
1664  //cell_array->InsertNextCell (n_points);
1665  for (size_t j = 0; j < n_points; j++, ++idx)
1666  *cell++ = vertices[i].vertices[j];
1667  //cell_array->InsertCellPoint (vertices[i].vertices[j]);
1668  }
1669  }
1671  allocVtkPolyData (polydata);
1672  cell_array->GetData ()->SetNumberOfValues (idx);
1673  cell_array->Squeeze ();
1674  polydata->SetPolys (cell_array);
1675  polydata->SetPoints (points);
1676 
1677  if (colors)
1678  polydata->GetPointData ()->SetScalars (colors);
1679 
1680  createActorFromVTKDataSet (polydata, actor, false);
1681  }
1682  else
1683  {
1685  size_t n_points = vertices[0].vertices.size ();
1686  polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
1687 
1688  if (lookup.size () > 0)
1689  {
1690  for (size_t j = 0; j < (n_points - 1); ++j)
1691  polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
1692  }
1693  else
1694  {
1695  for (size_t j = 0; j < (n_points - 1); ++j)
1696  polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
1697  }
1699  allocVtkUnstructuredGrid (poly_grid);
1700  poly_grid->Allocate (1, 1);
1701  poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
1702  poly_grid->SetPoints (points);
1703  if (colors)
1704  poly_grid->GetPointData ()->SetScalars (colors);
1705 
1706  createActorFromVTKDataSet (poly_grid, actor, false);
1707  }
1708  addActorToRenderer (actor, viewport);
1709  actor->GetProperty ()->SetRepresentationToSurface ();
1710  // Backface culling renders the visualization slower, but guarantees that we see all triangles
1711  actor->GetProperty ()->BackfaceCullingOff ();
1712  actor->GetProperty ()->SetInterpolationToFlat ();
1713  actor->GetProperty ()->EdgeVisibilityOff ();
1714  actor->GetProperty ()->ShadingOff ();
1715 
1716  // Save the pointer/ID pair to the global actor map
1717  (*cloud_actor_map_)[id].actor = actor;
1718 
1719  // Save the viewpoint transformation matrix to the global actor map
1721  convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
1722  (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
1723 
1724  return (true);
1725 }
1726 
1727 /////////////////////////////////////////////////////////////////////////////////////////////
1728 template <typename PointT> bool
1730  const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1731  const std::vector<pcl::Vertices> &verts,
1732  const std::string &id)
1733 {
1734  if (verts.empty ())
1735  {
1736  pcl::console::print_error ("[addPolygonMesh] No vertices given!\n");
1737  return (false);
1738  }
1739 
1740  // Check to see if this ID entry already exists (has it been already added to the visualizer?)
1741  CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
1742  if (am_it == cloud_actor_map_->end ())
1743  return (false);
1744 
1745  // Get the current poly data
1746  vtkSmartPointer<vtkPolyData> polydata = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
1747  if (!polydata)
1748  return (false);
1749  vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();
1750  if (!cells)
1751  return (false);
1752  vtkSmartPointer<vtkPoints> points = polydata->GetPoints ();
1753  // Copy the new point array in
1754  vtkIdType nr_points = cloud->points.size ();
1755  points->SetNumberOfPoints (nr_points);
1756 
1757  // Get a pointer to the beginning of the data array
1758  float *data = (static_cast<vtkFloatArray*> (points->GetData ()))->GetPointer (0);
1759 
1760  int ptr = 0;
1761  std::vector<int> lookup;
1762  // If the dataset is dense (no NaNs)
1763  if (cloud->is_dense)
1764  {
1765  for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1766  memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3);
1767  }
1768  else
1769  {
1770  lookup.resize (nr_points);
1771  vtkIdType j = 0; // true point index
1772  for (vtkIdType i = 0; i < nr_points; ++i)
1773  {
1774  // Check if the point is invalid
1775  if (!isFinite (cloud->points[i]))
1776  continue;
1777 
1778  lookup [i] = static_cast<int> (j);
1779  memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3);
1780  j++;
1781  ptr += 3;
1782  }
1783  nr_points = j;
1784  points->SetNumberOfPoints (nr_points);
1785  }
1786 
1787  // Update colors
1788  vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
1789  if (!colors)
1790  return (false);
1791  int rgb_idx = -1;
1792  std::vector<pcl::PCLPointField> fields;
1793  rgb_idx = pcl::getFieldIndex (*cloud, "rgb", fields);
1794  if (rgb_idx == -1)
1795  rgb_idx = pcl::getFieldIndex (*cloud, "rgba", fields);
1796  if (rgb_idx != -1 && colors)
1797  {
1798  pcl::RGB rgb_data;
1799  int j = 0;
1800  for (size_t i = 0; i < cloud->size (); ++i)
1801  {
1802  if (!isFinite (cloud->points[i]))
1803  continue;
1804  memcpy (&rgb_data,
1805  reinterpret_cast<const char*> (&cloud->points[i]) + fields[rgb_idx].offset,
1806  sizeof (pcl::RGB));
1807  unsigned char color[3];
1808  color[0] = rgb_data.r;
1809  color[1] = rgb_data.g;
1810  color[2] = rgb_data.b;
1811  colors->SetTupleValue (j++, color);
1812  }
1813  }
1814 
1815  // Get the maximum size of a polygon
1816  int max_size_of_polygon = -1;
1817  for (size_t i = 0; i < verts.size (); ++i)
1818  if (max_size_of_polygon < static_cast<int> (verts[i].vertices.size ()))
1819  max_size_of_polygon = static_cast<int> (verts[i].vertices.size ());
1820 
1821  // Update the cells
1823  vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1));
1824  int idx = 0;
1825  if (lookup.size () > 0)
1826  {
1827  for (size_t i = 0; i < verts.size (); ++i, ++idx)
1828  {
1829  size_t n_points = verts[i].vertices.size ();
1830  *cell++ = n_points;
1831  for (size_t j = 0; j < n_points; j++, cell++, ++idx)
1832  *cell = lookup[verts[i].vertices[j]];
1833  }
1834  }
1835  else
1836  {
1837  for (size_t i = 0; i < verts.size (); ++i, ++idx)
1838  {
1839  size_t n_points = verts[i].vertices.size ();
1840  *cell++ = n_points;
1841  for (size_t j = 0; j < n_points; j++, cell++, ++idx)
1842  *cell = verts[i].vertices[j];
1843  }
1844  }
1845  cells->GetData ()->SetNumberOfValues (idx);
1846  cells->Squeeze ();
1847  // Set the the vertices
1848  polydata->SetPolys (cells);
1849 
1850  return (true);
1851 }
1852 
1853 #ifdef vtkGenericDataArray_h
1854 #undef SetTupleValue
1855 #undef InsertNextTupleValue
1856 #undef GetTupleValue
1857 #endif
1858 
1859 #endif
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:54
int getFieldIndex(const pcl::PCLPointCloud2 &cloud, const std::string &field_name)
Get the index of a specified field (i.e., dimension/channel)
Definition: io.h:59
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:410
ColorHandler::ConstPtr ColorHandlerConstPtr
bool addPointCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::string &id="cloud", int viewport=0)
Add a Point Cloud (templated) to screen.
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const =0
Obtain the actual point geometry for the input dataset in VTK format.
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.
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)
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.
Base Handler class for PointCloud colors.
uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:415
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.
bool isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
Definition: point_cloud.h:331
bool isCapable() const
Checl if this handler is capable of handling the input data or not.
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.
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
Definition: point_cloud.h:421
A structure representing RGB color information.
uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:413
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.
Define methods or creating 3D shapes from parametric models.
PlanarPolygon represents a planar (2D) polygon, potentially in a 3D space.
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
bool addPolygonMesh(const pcl::PolygonMesh &polymesh, const std::string &id="polygon", int viewport=0)
Add a PolygonMesh object to screen.
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
Definition: point_cloud.h:423
vtkSmartPointer< vtkLODActor > actor
The actor holding the data to render.
Definition: actor_map.h:78
boost::shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:429
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.
PCL_EXPORTS void allocVtkUnstructuredGrid(vtkSmartPointer< vtkUnstructuredGrid > &polydata)
Allocate a new unstructured grid smartpointer.
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.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values).
Definition: point_cloud.h:418
bool isCapable() const
Check if this handler is capable of handling the input data or not.
Base handler class for PointCloud geometry.
virtual std::string getName() const =0
Abstract getName method.
GeometryHandler::ConstPtr GeometryHandlerConstPtr
bool addLine(const P1 &pt1, const P2 &pt2, const std::string &id="line", int viewport=0)
Add a line segment from two points.
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.
A point structure representing Euclidean xyz coordinates, and the RGB color.
virtual std::string getName() const =0
Abstract getName method.
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.
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.
virtual bool getColor(vtkSmartPointer< vtkDataArray > &scalars) const =0
Obtain the actual color for the input dataset as vtk scalars.
PCL_EXPORTS vtkSmartPointer< vtkDataSet > createLine(const Eigen::Vector4f &pt1, const Eigen::Vector4f &pt2)
Create a line shape from two points.
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.
PCL_EXPORTS void print_error(const char *format,...)
Print an error message on stream with colors.
size_t size() const
Definition: point_cloud.h:448