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->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
329 surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
331 all_data->AddInputData (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->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
383 surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
385 all_data->AddInputData (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 ();
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->SetInputData (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->SetInputData (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);
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);
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);
1184 reinterpret_cast<vtkPolyDataMapper*
>(actor->GetMapper ())->SetInputData (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);
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);
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);
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);
1401 polydata->GetPointData ()->SetScalars (scalars);
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 ())->SetInputData (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);
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 ())->SetInputData (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);
1512 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1513 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1516 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInputData (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);
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);
bool isCapable() const
Check if this handler is capable of handling the input data or not.
XYZ handler class for PointCloud geometry.
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested.
boost::shared_ptr< const PointCloud< PointT > > ConstPtr
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)
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
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.
uint32_t width
The point cloud width (if organized as an image-structure).
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) ...
Base Handler class for PointCloud colors.
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
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.
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.
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
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.
A structure representing RGB color information.
Handler for predefined user colors.
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.
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.
PCL_EXPORTS void print_warn(const char *format,...)
Print a warning message on stream with colors.
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.
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 isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
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 ¢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 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.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values).
uint32_t height
The point cloud height (if organized as an image-structure).