38 #ifndef PCL_PCL_VISUALIZER_IMPL_H_
39 #define PCL_PCL_VISUALIZER_IMPL_H_
41 #include <vtkSmartPointer.h>
42 #include <vtkCellArray.h>
43 #include <vtkLeaderActor2D.h>
44 #include <vtkVectorText.h>
45 #include <vtkAlgorithmOutput.h>
46 #include <vtkFollower.h>
47 #include <vtkSphereSource.h>
48 #include <vtkProperty2D.h>
49 #include <vtkDataSetSurfaceFilter.h>
50 #include <vtkPointData.h>
51 #include <vtkPolyDataMapper.h>
52 #include <vtkProperty.h>
53 #include <vtkMapper.h>
54 #include <vtkCellData.h>
55 #include <vtkDataSetMapper.h>
56 #include <vtkRenderer.h>
57 #include <vtkRendererCollection.h>
58 #include <vtkAppendPolyData.h>
59 #include <vtkTextProperty.h>
60 #include <vtkLODActor.h>
62 #include <pcl/visualization/common/shapes.h>
65 template <
typename Po
intT>
bool
68 const std::string &
id,
int viewport)
72 return (addPointCloud<PointT> (cloud, geometry_handler,
id, viewport));
76 template <
typename Po
intT>
bool
80 const std::string &
id,
int viewport)
83 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
85 if (am_it != cloud_actor_map_->end ())
87 PCL_WARN (
"[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
97 template <
typename Po
intT>
bool
101 const std::string &
id,
int viewport)
104 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
106 if (am_it != cloud_actor_map_->end ())
110 am_it->second.geometry_handlers.push_back (geometry_handler);
120 template <
typename Po
intT>
bool
124 const std::string &
id,
int viewport)
127 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
129 if (am_it != cloud_actor_map_->end ())
131 PCL_WARN (
"[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
145 template <
typename Po
intT>
bool
149 const std::string &
id,
int viewport)
152 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
153 if (am_it != cloud_actor_map_->end ())
157 am_it->second.color_handlers.push_back (color_handler);
166 template <
typename Po
intT>
bool
171 const std::string &
id,
int viewport)
174 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
175 if (am_it != cloud_actor_map_->end ())
179 am_it->second.geometry_handlers.push_back (geometry_handler);
180 am_it->second.color_handlers.push_back (color_handler);
187 template <
typename Po
intT>
bool
192 const std::string &
id,
int viewport)
195 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
197 if (am_it != cloud_actor_map_->end ())
199 PCL_WARN (
"[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
211 template <
typename Po
intT>
void
212 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
220 allocVtkPolyData (polydata);
222 polydata->SetVerts (vertices);
226 vertices = polydata->GetVerts ();
230 vtkIdType nr_points = cloud->
points.size ();
236 points->SetDataTypeToFloat ();
237 polydata->SetPoints (points);
239 points->SetNumberOfPoints (nr_points);
242 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
247 for (vtkIdType i = 0; i < nr_points; ++i)
248 memcpy (&data[i * 3], &cloud->
points[i].x, 12);
253 for (vtkIdType i = 0; i < nr_points; ++i)
256 if (!pcl_isfinite (cloud->
points[i].x) ||
257 !pcl_isfinite (cloud->
points[i].y) ||
258 !pcl_isfinite (cloud->
points[i].z))
261 memcpy (&data[j * 3], &cloud->
points[i].x, 12);
265 points->SetNumberOfPoints (nr_points);
269 updateCells (cells, initcells, nr_points);
272 vertices->SetCells (nr_points, cells);
276 template <
typename Po
intT>
void
277 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
285 allocVtkPolyData (polydata);
287 polydata->SetVerts (vertices);
293 polydata->SetPoints (points);
295 vtkIdType nr_points = points->GetNumberOfPoints ();
298 vertices = polydata->GetVerts ();
303 updateCells (cells, initcells, nr_points);
305 vertices->SetCells (nr_points, cells);
309 template <
typename Po
intT>
bool
312 double r,
double g,
double b,
const std::string &
id,
int viewport)
319 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
320 if (am_it != shape_actor_map_->end ())
325 all_data->AddInput (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
329 surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data));
331 all_data->AddInput (poly_data);
335 createActorFromVTKDataSet (all_data->GetOutput (), actor);
336 actor->GetProperty ()->SetRepresentationToWireframe ();
337 actor->GetProperty ()->SetColor (r, g, b);
338 actor->GetMapper ()->ScalarVisibilityOff ();
339 removeActorFromRenderer (am_it->second, viewport);
340 addActorToRenderer (actor, viewport);
343 (*shape_actor_map_)[id] = actor;
349 createActorFromVTKDataSet (data, actor);
350 actor->GetProperty ()->SetRepresentationToWireframe ();
351 actor->GetProperty ()->SetColor (r, g, b);
352 actor->GetMapper ()->ScalarVisibilityOff ();
353 addActorToRenderer (actor, viewport);
356 (*shape_actor_map_)[id] = actor;
363 template <
typename Po
intT>
bool
366 double r,
double g,
double b,
const std::string &
id,
int viewport)
373 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
374 if (am_it != shape_actor_map_->end ())
379 all_data->AddInput (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
383 surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data));
385 all_data->AddInput (poly_data);
389 createActorFromVTKDataSet (all_data->GetOutput (), actor);
390 actor->GetProperty ()->SetRepresentationToWireframe ();
391 actor->GetProperty ()->SetColor (r, g, b);
392 actor->GetMapper ()->ScalarVisibilityOn ();
393 actor->GetProperty ()->BackfaceCullingOff ();
394 removeActorFromRenderer (am_it->second, viewport);
395 addActorToRenderer (actor, viewport);
398 (*shape_actor_map_)[id] = actor;
404 createActorFromVTKDataSet (data, actor);
405 actor->GetProperty ()->SetRepresentationToWireframe ();
406 actor->GetProperty ()->SetColor (r, g, b);
407 actor->GetMapper ()->ScalarVisibilityOn ();
408 actor->GetProperty ()->BackfaceCullingOff ();
409 addActorToRenderer (actor, viewport);
412 (*shape_actor_map_)[id] = actor;
418 template <
typename Po
intT>
bool
421 const std::string &
id,
int viewport)
423 return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5,
id, viewport));
427 template <
typename P1,
typename P2>
bool
431 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
432 if (am_it != shape_actor_map_->end ())
434 PCL_WARN (
"[addLine] A shape with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
442 createActorFromVTKDataSet (data, actor);
443 actor->GetProperty ()->SetRepresentationToWireframe ();
444 actor->GetProperty ()->SetColor (r, g, b);
445 actor->GetMapper ()->ScalarVisibilityOff ();
446 addActorToRenderer (actor, viewport);
449 (*shape_actor_map_)[id] = actor;
454 template <
typename P1,
typename P2>
bool
458 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
459 if (am_it != shape_actor_map_->end ())
461 PCL_WARN (
"[addArrow] A shape with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
467 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
468 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
469 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
470 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
471 leader->SetArrowStyleToFilled ();
472 leader->AutoLabelOn ();
474 leader->GetProperty ()->SetColor (r, g, b);
475 addActorToRenderer (leader, viewport);
478 (*shape_actor_map_)[id] = leader;
483 template <
typename P1,
typename P2>
bool
487 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
488 if (am_it != shape_actor_map_->end ())
490 PCL_WARN (
"[addArrow] A shape with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
496 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
497 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
498 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
499 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
500 leader->SetArrowStyleToFilled ();
501 leader->SetArrowPlacementToPoint1 ();
503 leader->AutoLabelOn ();
505 leader->AutoLabelOff ();
507 leader->GetProperty ()->SetColor (r, g, b);
508 addActorToRenderer (leader, viewport);
511 (*shape_actor_map_)[id] = leader;
515 template <
typename P1,
typename P2>
bool
517 double r_line,
double g_line,
double b_line,
518 double r_text,
double g_text,
double b_text,
519 const std::string &
id,
int viewport)
522 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
523 if (am_it != shape_actor_map_->end ())
525 PCL_WARN (
"[addArrow] A shape with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
531 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
532 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
533 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
534 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
535 leader->SetArrowStyleToFilled ();
536 leader->AutoLabelOn ();
538 leader->GetLabelTextProperty()->SetColor(r_text, g_text, b_text);
540 leader->GetProperty ()->SetColor (r_line, g_line, b_line);
541 addActorToRenderer (leader, viewport);
544 (*shape_actor_map_)[id] = leader;
549 template <
typename P1,
typename P2>
bool
552 return (!addLine (pt1, pt2, 0.5, 0.5, 0.5,
id, viewport));
556 template <
typename Po
intT>
bool
560 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
561 if (am_it != shape_actor_map_->end ())
563 PCL_WARN (
"[addSphere] A shape with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
568 data->SetRadius (radius);
569 data->SetCenter (
double (center.x), double (center.y), double (center.z));
570 data->SetPhiResolution (10);
571 data->SetThetaResolution (10);
572 data->LatLongTessellationOff ();
577 mapper->SetInputConnection (data->GetOutputPort ());
581 actor->SetMapper (mapper);
583 actor->GetProperty ()->SetRepresentationToSurface ();
584 actor->GetProperty ()->SetInterpolationToFlat ();
585 actor->GetProperty ()->SetColor (r, g, b);
586 actor->GetMapper ()->ImmediateModeRenderingOn ();
587 actor->GetMapper ()->StaticOn ();
588 actor->GetMapper ()->ScalarVisibilityOff ();
589 actor->GetMapper ()->Update ();
590 addActorToRenderer (actor, viewport);
593 (*shape_actor_map_)[id] = actor;
598 template <
typename Po
intT>
bool
601 return (addSphere (center, radius, 0.5, 0.5, 0.5,
id, viewport));
605 template<
typename Po
intT>
bool
609 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
610 if (am_it == shape_actor_map_->end ())
615 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
616 vtkAlgorithm *algo = actor->GetMapper ()->GetInput ()->GetProducerPort ()->GetProducer ();
617 vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo);
619 src->SetCenter (
double (center.x), double (center.y), double (center.z));
620 src->SetRadius (radius);
622 actor->GetProperty ()->SetColor (r, g, b);
629 template <
typename Po
intT>
bool
631 const std::string &text,
637 const std::string &
id,
647 ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
648 if (am_it != shape_actor_map_->end ())
650 pcl::console::print_warn (stderr,
"[addText3d] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
655 textSource->SetText (text.c_str());
656 textSource->Update ();
659 textMapper->SetInputConnection (textSource->GetOutputPort ());
662 rens_->InitTraversal ();
663 vtkRenderer* renderer = NULL;
665 while ((renderer = rens_->GetNextItem ()) != NULL)
668 if (viewport == 0 || viewport == i)
671 textActor->SetMapper (textMapper);
672 textActor->SetPosition (position.x, position.y, position.z);
673 textActor->SetScale (textScale);
674 textActor->GetProperty ()->SetColor (r, g, b);
675 textActor->SetCamera (renderer->GetActiveCamera ());
677 renderer->AddActor (textActor);
682 std::string alternate_tid = tid;
683 alternate_tid.append(i,
'*');
685 (*shape_actor_map_)[(viewport == 0) ? tid : alternate_tid] = textActor;
695 template <
typename Po
intNT>
bool
698 int level,
float scale,
const std::string &
id,
int viewport)
700 return (addPointCloudNormals<PointNT, PointNT> (cloud, cloud, level, scale,
id, viewport));
704 template <
typename Po
intT,
typename Po
intNT>
bool
708 int level,
float scale,
709 const std::string &
id,
int viewport)
713 PCL_ERROR (
"[addPointCloudNormals] The number of points differs from the number of normals!\n");
717 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
719 if (am_it != cloud_actor_map_->end ())
721 PCL_WARN (
"[addPointCloudNormals] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
728 points->SetDataTypeToFloat ();
730 data->SetNumberOfComponents (3);
733 vtkIdType nr_normals = 0;
739 vtkIdType point_step =
static_cast<vtkIdType
> (sqrt (
double (level)));
740 nr_normals = (
static_cast<vtkIdType
> ((cloud->
width - 1)/ point_step) + 1) *
741 (static_cast<vtkIdType> ((cloud->
height - 1) / point_step) + 1);
742 pts =
new float[2 * nr_normals * 3];
744 vtkIdType cell_count = 0;
745 for (vtkIdType y = 0; y < normals->
height; y += point_step)
746 for (vtkIdType x = 0; x < normals->
width; x += point_step)
748 PointT p = (*cloud)(x, y);
749 p.x += (*normals)(x, y).normal[0] * scale;
750 p.y += (*normals)(x, y).normal[1] * scale;
751 p.z += (*normals)(x, y).normal[2] * scale;
753 pts[2 * cell_count * 3 + 0] = (*cloud)(x, y).x;
754 pts[2 * cell_count * 3 + 1] = (*cloud)(x, y).y;
755 pts[2 * cell_count * 3 + 2] = (*cloud)(x, y).z;
756 pts[2 * cell_count * 3 + 3] = p.x;
757 pts[2 * cell_count * 3 + 4] = p.y;
758 pts[2 * cell_count * 3 + 5] = p.z;
760 lines->InsertNextCell (2);
761 lines->InsertCellPoint (2 * cell_count);
762 lines->InsertCellPoint (2 * cell_count + 1);
768 nr_normals = (cloud->
points.size () - 1) / level + 1 ;
769 pts =
new float[2 * nr_normals * 3];
771 for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level)
774 p.x += normals->
points[i].normal[0] * scale;
775 p.y += normals->
points[i].normal[1] * scale;
776 p.z += normals->
points[i].normal[2] * scale;
778 pts[2 * j * 3 + 0] = cloud->
points[i].x;
779 pts[2 * j * 3 + 1] = cloud->
points[i].y;
780 pts[2 * j * 3 + 2] = cloud->
points[i].z;
781 pts[2 * j * 3 + 3] = p.x;
782 pts[2 * j * 3 + 4] = p.y;
783 pts[2 * j * 3 + 5] = p.z;
785 lines->InsertNextCell (2);
786 lines->InsertCellPoint (2 * j);
787 lines->InsertCellPoint (2 * j + 1);
791 data->SetArray (&pts[0], 2 * nr_normals * 3, 0);
792 points->SetData (data);
795 polyData->SetPoints (points);
796 polyData->SetLines (lines);
799 mapper->SetInput (polyData);
800 mapper->SetColorModeToMapScalars();
801 mapper->SetScalarModeToUsePointData();
805 actor->SetMapper (mapper);
808 addActorToRenderer (actor, viewport);
811 (*cloud_actor_map_)[id].actor = actor;
816 template <
typename Po
intT,
typename GradientT>
bool
820 int level,
double scale,
821 const std::string &
id,
int viewport)
825 PCL_ERROR (
"[addPointCloudGradients] The number of points differs from the number of gradients!\n");
829 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
831 if (am_it != cloud_actor_map_->end ())
833 PCL_WARN (
"[addPointCloudGradients] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
840 points->SetDataTypeToFloat ();
842 data->SetNumberOfComponents (3);
844 vtkIdType nr_gradients = (cloud->
points.size () - 1) / level + 1 ;
845 float* pts =
new float[2 * nr_gradients * 3];
847 for (vtkIdType i = 0, j = 0; j < nr_gradients; j++, i = j * level)
850 p.x += gradients->
points[i].gradient[0] * scale;
851 p.y += gradients->
points[i].gradient[1] * scale;
852 p.z += gradients->
points[i].gradient[2] * scale;
854 pts[2 * j * 3 + 0] = cloud->
points[i].x;
855 pts[2 * j * 3 + 1] = cloud->
points[i].y;
856 pts[2 * j * 3 + 2] = cloud->
points[i].z;
857 pts[2 * j * 3 + 3] = p.x;
858 pts[2 * j * 3 + 4] = p.y;
859 pts[2 * j * 3 + 5] = p.z;
861 lines->InsertNextCell(2);
862 lines->InsertCellPoint(2*j);
863 lines->InsertCellPoint(2*j+1);
866 data->SetArray (&pts[0], 2 * nr_gradients * 3, 0);
867 points->SetData (data);
870 polyData->SetPoints(points);
871 polyData->SetLines(lines);
874 mapper->SetInput (polyData);
875 mapper->SetColorModeToMapScalars();
876 mapper->SetScalarModeToUsePointData();
880 actor->SetMapper (mapper);
883 addActorToRenderer (actor, viewport);
886 (*cloud_actor_map_)[id].actor = actor;
891 template <
typename Po
intT>
bool
895 const std::vector<int> &correspondences,
896 const std::string &
id,
900 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
901 if (am_it != shape_actor_map_->end ())
903 PCL_WARN (
"[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
907 int n_corr = int (correspondences.size ());
912 line_colors->SetNumberOfComponents (3);
913 line_colors->SetName (
"Colors");
914 line_colors->SetNumberOfTuples (n_corr);
915 unsigned char* colors = line_colors->GetPointer (0);
916 memset (colors, 0, line_colors->GetNumberOfTuples () * line_colors->GetNumberOfComponents ());
919 rgb.r = 255; rgb.g = rgb.b = 0;
923 line_points->SetNumberOfPoints (2 * n_corr);
926 line_cells_id->SetNumberOfComponents (3);
927 line_cells_id->SetNumberOfTuples (n_corr);
928 vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
932 line_tcoords->SetNumberOfComponents (1);
933 line_tcoords->SetNumberOfTuples (n_corr * 2);
934 line_tcoords->SetName (
"Texture Coordinates");
936 double tc[3] = {0.0, 0.0, 0.0};
940 for (
size_t i = 0; i < n_corr; ++i)
943 const PointT &p_tgt = target_points->
points[correspondences[i]];
945 int id1 = j * 2 + 0, id2 = j * 2 + 1;
947 line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
948 line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
951 *line_cell_id++ = id1;
952 *line_cell_id++ = id2;
954 tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
955 tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
958 colors[idx+0] = rgb.r;
959 colors[idx+1] = rgb.g;
960 colors[idx+2] = rgb.b;
962 line_colors->SetNumberOfTuples (j);
963 line_cells_id->SetNumberOfTuples (j);
964 line_cells->SetCells (n_corr, line_cells_id);
965 line_points->SetNumberOfPoints (j*2);
966 line_tcoords->SetNumberOfTuples (j*2);
969 line_data->SetPoints (line_points);
970 line_data->SetLines (line_cells);
971 line_data->GetPointData ()->SetTCoords (line_tcoords);
972 line_data->GetCellData ()->SetScalars (line_colors);
973 line_data->Update ();
977 createActorFromVTKDataSet (line_data, actor);
978 actor->GetProperty ()->SetRepresentationToWireframe ();
979 actor->GetProperty ()->SetOpacity (0.5);
980 addActorToRenderer (actor, viewport);
983 (*shape_actor_map_)[id] = actor;
989 template <
typename Po
intT>
bool
995 const std::string &
id,
998 if (correspondences.empty ())
1000 PCL_DEBUG (
"[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1005 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
1006 if (am_it != shape_actor_map_->end ())
1008 PCL_WARN (
"[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
1012 int n_corr = int (correspondences.size () / nth + 1);
1017 line_colors->SetNumberOfComponents (3);
1018 line_colors->SetName (
"Colors");
1019 line_colors->SetNumberOfTuples (n_corr);
1020 unsigned char* colors = line_colors->GetPointer (0);
1021 memset (colors, 0, line_colors->GetNumberOfTuples () * line_colors->GetNumberOfComponents ());
1024 rgb.r = 255; rgb.g = rgb.b = 0;
1028 line_points->SetNumberOfPoints (2 * n_corr);
1031 line_cells_id->SetNumberOfComponents (3);
1032 line_cells_id->SetNumberOfTuples (n_corr);
1033 vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
1037 line_tcoords->SetNumberOfComponents (1);
1038 line_tcoords->SetNumberOfTuples (n_corr * 2);
1039 line_tcoords->SetName (
"Texture Coordinates");
1041 double tc[3] = {0.0, 0.0, 0.0};
1045 for (
size_t i = 0; i < correspondences.size (); i += nth, idx = j * 3, ++j)
1047 const PointT &p_src = source_points->
points[correspondences[i].index_query];
1048 const PointT &p_tgt = target_points->
points[correspondences[i].index_match];
1050 int id1 = j * 2 + 0, id2 = j * 2 + 1;
1052 line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
1053 line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
1055 *line_cell_id++ = 2;
1056 *line_cell_id++ = id1;
1057 *line_cell_id++ = id2;
1059 tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
1060 tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
1063 colors[idx+0] = rgb.r;
1064 colors[idx+1] = rgb.g;
1065 colors[idx+2] = rgb.b;
1067 line_colors->SetNumberOfTuples (j);
1068 line_cells_id->SetNumberOfTuples (j);
1069 line_cells->SetCells (n_corr, line_cells_id);
1070 line_points->SetNumberOfPoints (j*2);
1071 line_tcoords->SetNumberOfTuples (j*2);
1074 line_data->SetPoints (line_points);
1075 line_data->SetLines (line_cells);
1076 line_data->GetPointData ()->SetTCoords (line_tcoords);
1077 line_data->GetCellData ()->SetScalars (line_colors);
1078 line_data->Update ();
1082 createActorFromVTKDataSet (line_data, actor);
1083 actor->GetProperty ()->SetRepresentationToWireframe ();
1084 actor->GetProperty ()->SetOpacity (0.5);
1085 addActorToRenderer (actor, viewport);
1088 (*shape_actor_map_)[id] = actor;
1094 template <
typename Po
intT>
bool
1100 const std::string &
id)
1102 if (correspondences.empty ())
1104 PCL_DEBUG (
"[updateCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1109 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
1110 if (am_it == shape_actor_map_->end ())
1116 int n_corr = int (correspondences.size () / nth + 1);
1120 line_colors->SetNumberOfComponents (3);
1121 line_colors->SetName (
"Colors");
1122 line_colors->SetNumberOfTuples (n_corr);
1123 unsigned char* colors = line_colors->GetPointer (0);
1124 memset (colors, 0, line_colors->GetNumberOfTuples () * line_colors->GetNumberOfComponents ());
1127 rgb.r = 255.0; rgb.g = rgb.b = 0.0;
1131 line_points->SetNumberOfPoints (2 * n_corr);
1134 line_cells_id->SetNumberOfComponents (3);
1135 line_cells_id->SetNumberOfTuples (n_corr);
1136 vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
1140 line_tcoords->SetNumberOfComponents (1);
1141 line_tcoords->SetNumberOfTuples (n_corr * 2);
1142 line_tcoords->SetName (
"Texture Coordinates");
1144 double tc[3] = {0.0, 0.0, 0.0};
1148 for (
size_t i = 0; i < correspondences.size (); i += nth, idx = j * 3, ++j)
1150 const PointT &p_src = source_points->
points[correspondences[i].index_query];
1151 const PointT &p_tgt = target_points->
points[correspondences[i].index_match];
1153 int id1 = j * 2 + 0, id2 = j * 2 + 1;
1155 line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
1156 line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
1158 *line_cell_id++ = 2;
1159 *line_cell_id++ = id1;
1160 *line_cell_id++ = id2;
1162 tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
1163 tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
1166 colors[idx+0] = rgb.r;
1167 colors[idx+1] = rgb.g;
1168 colors[idx+2] = rgb.b;
1170 line_colors->SetNumberOfTuples (j);
1171 line_cells_id->SetNumberOfTuples (j);
1172 line_cells->SetCells (n_corr, line_cells_id);
1173 line_points->SetNumberOfPoints (j*2);
1174 line_tcoords->SetNumberOfTuples (j*2);
1177 line_data->SetPoints (line_points);
1178 line_data->SetLines (line_cells);
1179 line_data->GetPointData ()->SetTCoords (line_tcoords);
1180 line_data->GetCellData ()->SetScalars (line_colors);
1181 line_data->Update ();
1184 reinterpret_cast<vtkPolyDataMapper*
>(actor->GetMapper ())->SetInput (line_data);
1190 template <
typename Po
intT>
bool
1191 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1194 const std::string &
id,
1196 const Eigen::Vector4f& sensor_origin,
1197 const Eigen::Quaternion<float>& sensor_orientation)
1201 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.
getName ().c_str ());
1207 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.
getName ().c_str ());
1214 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1216 polydata->Update ();
1219 bool has_colors =
false;
1222 if (color_handler.
getColor (scalars))
1224 polydata->GetPointData ()->SetScalars (scalars);
1225 scalars->GetRange (minmax);
1231 createActorFromVTKDataSet (polydata, actor);
1233 actor->GetMapper ()->SetScalarRange (minmax);
1236 addActorToRenderer (actor, viewport);
1239 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1240 cloud_actor.actor = actor;
1241 cloud_actor.cells = initcells;
1245 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1246 cloud_actor.viewpoint_transformation_ = transformation;
1247 cloud_actor.actor->SetUserMatrix (transformation);
1248 cloud_actor.actor->Modified ();
1254 template <
typename Po
intT>
bool
1255 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1256 const PointCloudGeometryHandler<PointT> &geometry_handler,
1257 const ColorHandlerConstPtr &color_handler,
1258 const std::string &
id,
1260 const Eigen::Vector4f& sensor_origin,
1261 const Eigen::Quaternion<float>& sensor_orientation)
1263 if (!geometry_handler.isCapable ())
1265 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.getName ().c_str ());
1269 if (!color_handler->isCapable ())
1271 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler->getName ().c_str ());
1278 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1280 polydata->Update ();
1283 bool has_colors =
false;
1286 if (color_handler->getColor (scalars))
1288 polydata->GetPointData ()->SetScalars (scalars);
1289 scalars->GetRange (minmax);
1295 createActorFromVTKDataSet (polydata, actor);
1297 actor->GetMapper ()->SetScalarRange (minmax);
1300 addActorToRenderer (actor, viewport);
1303 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1304 cloud_actor.actor = actor;
1305 cloud_actor.cells = initcells;
1306 cloud_actor.color_handlers.push_back (color_handler);
1310 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1311 cloud_actor.viewpoint_transformation_ = transformation;
1312 cloud_actor.actor->SetUserMatrix (transformation);
1313 cloud_actor.actor->Modified ();
1319 template <
typename Po
intT>
bool
1320 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1321 const GeometryHandlerConstPtr &geometry_handler,
1322 const PointCloudColorHandler<PointT> &color_handler,
1323 const std::string &
id,
1325 const Eigen::Vector4f& sensor_origin,
1326 const Eigen::Quaternion<float>& sensor_orientation)
1328 if (!geometry_handler->isCapable ())
1330 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler->getName ().c_str ());
1334 if (!color_handler.isCapable ())
1336 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.getName ().c_str ());
1343 convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
1345 polydata->Update ();
1348 bool has_colors =
false;
1351 if (color_handler.getColor (scalars))
1353 polydata->GetPointData ()->SetScalars (scalars);
1354 scalars->GetRange (minmax);
1360 createActorFromVTKDataSet (polydata, actor);
1362 actor->GetMapper ()->SetScalarRange (minmax);
1365 addActorToRenderer (actor, viewport);
1368 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1369 cloud_actor.actor = actor;
1370 cloud_actor.cells = initcells;
1371 cloud_actor.geometry_handlers.push_back (geometry_handler);
1375 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1376 cloud_actor.viewpoint_transformation_ = transformation;
1377 cloud_actor.actor->SetUserMatrix (transformation);
1378 cloud_actor.actor->Modified ();
1384 template <
typename Po
intT>
bool
1386 const std::string &
id)
1389 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1391 if (am_it == cloud_actor_map_->end ())
1396 convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
1397 polydata->Update ();
1401 polydata->GetPointData ()->SetScalars (scalars);
1402 polydata->Update ();
1404 minmax[0] = std::numeric_limits<double>::min ();
1405 minmax[1] = std::numeric_limits<double>::max ();
1406 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1407 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1410 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1415 template <
typename Po
intT>
bool
1418 const std::string &
id)
1421 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1423 if (am_it == cloud_actor_map_->end ())
1430 convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
1434 polydata->GetPointData ()->SetScalars (scalars);
1435 polydata->Update ();
1437 minmax[0] = std::numeric_limits<double>::min ();
1438 minmax[1] = std::numeric_limits<double>::max ();
1439 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1440 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1443 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1449 template <
typename Po
intT>
bool
1452 const std::string &
id)
1455 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1457 if (am_it == cloud_actor_map_->end ())
1467 vtkIdType nr_points = cloud->
points.size ();
1468 points->SetNumberOfPoints (nr_points);
1471 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
1477 for (vtkIdType i = 0; i < nr_points; ++i, pts += 3)
1478 memcpy (&data[pts], &cloud->
points[i].x, 12);
1483 for (vtkIdType i = 0; i < nr_points; ++i)
1489 memcpy (&data[pts], &cloud->
points[i].x, 12);
1494 points->SetNumberOfPoints (nr_points);
1498 updateCells (cells, am_it->second.cells, nr_points);
1501 vertices->SetCells (nr_points, cells);
1507 scalars->GetRange (minmax);
1509 polydata->GetPointData ()->SetScalars (scalars);
1510 polydata->Update ();
1512 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1513 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1516 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1521 template <
typename Po
intT>
bool
1524 const std::vector<pcl::Vertices> &vertices,
1525 const std::string &
id,
1528 if (vertices.empty () || cloud->
points.empty ())
1531 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1532 if (am_it != cloud_actor_map_->end ())
1535 "[addPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n",
1541 std::vector<pcl::PCLPointField> fields;
1549 colors->SetNumberOfComponents (3);
1550 colors->SetName (
"Colors");
1553 for (
size_t i = 0; i < cloud->
size (); ++i)
1557 memcpy (&rgb_data, reinterpret_cast<const char*> (&cloud->
points[i]) + fields[rgb_idx].offset, sizeof (
pcl::RGB));
1558 unsigned char color[3];
1559 color[0] = rgb_data.r;
1560 color[1] = rgb_data.g;
1561 color[2] = rgb_data.b;
1562 colors->InsertNextTupleValue (color);
1568 vtkIdType nr_points = cloud->
points.size ();
1569 points->SetNumberOfPoints (nr_points);
1573 float *data =
static_cast<vtkFloatArray*
> (points->GetData ())->GetPointer (0);
1576 std::vector<int> lookup;
1580 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1581 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1585 lookup.resize (nr_points);
1587 for (vtkIdType i = 0; i < nr_points; ++i)
1593 lookup[i] =
static_cast<int> (j);
1594 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1599 points->SetNumberOfPoints (nr_points);
1603 int max_size_of_polygon = -1;
1604 for (
size_t i = 0; i < vertices.size (); ++i)
1605 if (max_size_of_polygon < static_cast<int> (vertices[i].vertices.size ()))
1606 max_size_of_polygon =
static_cast<int> (vertices[i].vertices.size ());
1608 if (vertices.size () > 1)
1612 vtkIdType *cell = cell_array->WritePointer (vertices.size (), vertices.size () * (max_size_of_polygon + 1));
1614 if (lookup.size () > 0)
1616 for (
size_t i = 0; i < vertices.size (); ++i, ++idx)
1618 size_t n_points = vertices[i].vertices.size ();
1621 for (
size_t j = 0; j < n_points; j++, ++idx)
1622 *cell++ = lookup[vertices[i].vertices[j]];
1628 for (
size_t i = 0; i < vertices.size (); ++i, ++idx)
1630 size_t n_points = vertices[i].vertices.size ();
1633 for (
size_t j = 0; j < n_points; j++, ++idx)
1634 *cell++ = vertices[i].vertices[j];
1639 allocVtkPolyData (polydata);
1640 cell_array->GetData ()->SetNumberOfValues (idx);
1641 cell_array->Squeeze ();
1642 polydata->SetStrips (cell_array);
1643 polydata->SetPoints (points);
1646 polydata->GetPointData ()->SetScalars (colors);
1648 createActorFromVTKDataSet (polydata, actor,
false);
1653 size_t n_points = vertices[0].vertices.size ();
1654 polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
1656 if (lookup.size () > 0)
1658 for (
size_t j = 0; j < (n_points - 1); ++j)
1659 polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
1663 for (
size_t j = 0; j < (n_points - 1); ++j)
1664 polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
1668 poly_grid->Allocate (1, 1);
1669 poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
1670 poly_grid->SetPoints (points);
1671 poly_grid->Update ();
1673 poly_grid->GetPointData ()->SetScalars (colors);
1675 createActorFromVTKDataSet (poly_grid, actor,
false);
1677 addActorToRenderer (actor, viewport);
1678 actor->GetProperty ()->SetRepresentationToSurface ();
1680 actor->GetProperty ()->BackfaceCullingOff ();
1681 actor->GetProperty ()->SetInterpolationToFlat ();
1682 actor->GetProperty ()->EdgeVisibilityOff ();
1683 actor->GetProperty ()->ShadingOff ();
1686 (*cloud_actor_map_)[id].actor = actor;
1691 (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
1697 template <
typename Po
intT>
bool
1700 const std::vector<pcl::Vertices> &verts,
1701 const std::string &
id)
1710 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1711 if (am_it == cloud_actor_map_->end ())
1723 vtkIdType nr_points = cloud->
points.size ();
1724 points->SetNumberOfPoints (nr_points);
1727 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
1730 std::vector<int> lookup;
1734 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1735 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1739 lookup.resize (nr_points);
1741 for (vtkIdType i = 0; i < nr_points; ++i)
1747 lookup [i] =
static_cast<int> (j);
1748 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1753 points->SetNumberOfPoints (nr_points);
1757 vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
1759 std::vector<pcl::PCLPointField> fields;
1763 if (rgb_idx != -1 && colors)
1767 for (
size_t i = 0; i < cloud->
size (); ++i)
1772 reinterpret_cast<const char*> (&cloud->
points[i]) + fields[rgb_idx].offset,
1774 unsigned char color[3];
1775 color[0] = rgb_data.r;
1776 color[1] = rgb_data.g;
1777 color[2] = rgb_data.b;
1778 colors->SetTupleValue (j++, color);
1783 int max_size_of_polygon = -1;
1784 for (
size_t i = 0; i < verts.size (); ++i)
1785 if (max_size_of_polygon < static_cast<int> (verts[i].vertices.size ()))
1786 max_size_of_polygon =
static_cast<int> (verts[i].vertices.size ());
1790 vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1));
1792 if (lookup.size () > 0)
1794 for (
size_t i = 0; i < verts.size (); ++i, ++idx)
1796 size_t n_points = verts[i].vertices.size ();
1798 for (
size_t j = 0; j < n_points; j++, cell++, ++idx)
1799 *cell = lookup[verts[i].vertices[j]];
1804 for (
size_t i = 0; i < verts.size (); ++i, ++idx)
1806 size_t n_points = verts[i].vertices.size ();
1808 for (
size_t j = 0; j < n_points; j++, cell++, ++idx)
1809 *cell = verts[i].vertices[j];
1812 cells->GetData ()->SetNumberOfValues (idx);
1815 polydata->SetStrips (cells);
1816 polydata->Update ();
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.
PCL_EXPORTS void getRandomColors(double &r, double &g, double &b, double min=0.2, double max=2.8)
Get (good) random values for R/G/B.
bool updateSphere(const PointT ¢er, 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 addLine(const P1 &pt1, const P2 &pt2, const std::string &id="line", int viewport=0)
Add a line segment from two points.
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 isCapable() const
Checl if this handler is capable of handling the input data or not.
GeometryHandler::ConstPtr GeometryHandlerConstPtr
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const =0
Obtain the actual point geometry for the input dataset in VTK format.
PCL_EXPORTS void print_warn(const char *format,...)
Print a warning message on stream with colors.
XYZ handler class for PointCloud geometry.
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
int getFieldIndex(const pcl::PCLPointCloud2 &cloud, const std::string &field_name)
Get the index of a specified field (i.e., dimension/channel)
PCL_EXPORTS void allocVtkUnstructuredGrid(vtkSmartPointer< vtkUnstructuredGrid > &polydata)
Allocate a new unstructured grid smartpointer.
uint32_t width
The point cloud width (if organized as an image-structure).
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")
Update the specified correspondences to the display.
ColorHandler::ConstPtr ColorHandlerConstPtr
PCL_EXPORTS void print_error(const char *format,...)
Print an error message on stream with colors.
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 isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested.
Base handler class for PointCloud geometry.
virtual std::string getName() const =0
Abstract getName method.
Base Handler class for PointCloud colors.
virtual std::string getName() const =0
Abstract getName method.
A structure representing RGB color information.
bool addPolygonMesh(const pcl::PolygonMesh &polymesh, const std::string &id="polygon", int viewport=0)
Add a PolygonMesh object to screen.
PlanarPolygon represents a planar (2D) polygon, potentially in a 3D space.
uint32_t height
The point cloud height (if organized as an image-structure).
virtual bool getColor(vtkSmartPointer< vtkDataArray > &scalars) const =0
Obtain the actual color for the input dataset as vtk scalars.
bool addSphere(const PointT ¢er, double radius, const std::string &id="sphere", int viewport=0)
Add a sphere shape from a point and a radius.
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.
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.
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
boost::shared_ptr< const PointCloud< PointT > > ConstPtr
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.
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values).
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
bool isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
bool addPointCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::string &id="cloud", int viewport=0)
Add a Point Cloud (templated) to screen.
PCL_EXPORTS vtkSmartPointer< vtkDataSet > createLine(const Eigen::Vector4f &pt1, const Eigen::Vector4f &pt2)
Create a line shape 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.
bool isCapable() const
Check if this handler is capable of handling the input data or not.
A point structure representing Euclidean xyz coordinates, and the RGB color.
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.
Handler for predefined user colors.