38 #ifndef PCL_PCL_VISUALIZER_IMPL_H_ 39 #define PCL_PCL_VISUALIZER_IMPL_H_ 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> 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> 68 #ifdef vtkGenericDataArray_h 69 #define SetTupleValue SetTypedTuple 70 #define InsertNextTupleValue InsertNextTypedTuple 71 #define GetTupleValue GetTypedTuple 75 template <
typename Po
intT>
bool 78 const std::string &
id,
int viewport)
82 return (addPointCloud<PointT> (cloud, geometry_handler,
id, viewport));
86 template <
typename Po
intT>
bool 90 const std::string &
id,
int viewport)
94 PCL_WARN (
"[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
98 if (pcl::traits::has_color<PointT>())
108 template <
typename Po
intT>
bool 112 const std::string &
id,
int viewport)
118 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
119 am_it->second.geometry_handlers.push_back (geometry_handler);
129 template <
typename Po
intT>
bool 133 const std::string &
id,
int viewport)
137 PCL_WARN (
"[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
151 template <
typename Po
intT>
bool 155 const std::string &
id,
int viewport)
158 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
159 if (am_it != cloud_actor_map_->end ())
163 am_it->second.color_handlers.push_back (color_handler);
172 template <
typename Po
intT>
bool 177 const std::string &
id,
int viewport)
180 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
181 if (am_it != cloud_actor_map_->end ())
185 am_it->second.geometry_handlers.push_back (geometry_handler);
186 am_it->second.color_handlers.push_back (color_handler);
193 template <
typename Po
intT>
bool 198 const std::string &
id,
int viewport)
202 PCL_WARN (
"[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
214 template <
typename Po
intT>
void 215 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
223 allocVtkPolyData (polydata);
225 polydata->SetVerts (vertices);
229 vertices = polydata->GetVerts ();
233 vtkIdType nr_points = cloud->
points.size ();
239 points->SetDataTypeToFloat ();
240 polydata->SetPoints (points);
242 points->SetNumberOfPoints (nr_points);
245 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
250 for (vtkIdType i = 0; i < nr_points; ++i)
251 memcpy (&data[i * 3], &cloud->
points[i].x, 12);
256 for (vtkIdType i = 0; i < nr_points; ++i)
259 if (!pcl_isfinite (cloud->
points[i].x) ||
260 !pcl_isfinite (cloud->
points[i].y) ||
261 !pcl_isfinite (cloud->
points[i].z))
264 memcpy (&data[j * 3], &cloud->
points[i].x, 12);
268 points->SetNumberOfPoints (nr_points);
272 updateCells (cells, initcells, nr_points);
275 vertices->SetCells (nr_points, cells);
279 template <
typename Po
intT>
void 280 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
288 allocVtkPolyData (polydata);
290 polydata->SetVerts (vertices);
296 polydata->SetPoints (points);
298 vtkIdType nr_points = points->GetNumberOfPoints ();
301 vertices = polydata->GetVerts ();
306 updateCells (cells, initcells, nr_points);
308 vertices->SetCells (nr_points, cells);
312 template <
typename Po
intT>
bool 315 double r,
double g,
double b,
const std::string &
id,
int viewport)
322 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
323 if (am_it != shape_actor_map_->end ())
328 #if VTK_MAJOR_VERSION < 6 329 all_data->AddInput (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
331 all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
336 #if VTK_MAJOR_VERSION < 6 337 surface_filter->AddInput (vtkUnstructuredGrid::SafeDownCast (data));
339 surface_filter->AddInputData (vtkUnstructuredGrid::SafeDownCast (data));
342 #if VTK_MAJOR_VERSION < 6 343 all_data->AddInput (poly_data);
345 all_data->AddInputData (poly_data);
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);
358 (*shape_actor_map_)[id] = actor;
364 createActorFromVTKDataSet (data, actor);
365 actor->GetProperty ()->SetRepresentationToWireframe ();
366 actor->GetProperty ()->SetColor (r, g, b);
367 actor->GetMapper ()->ScalarVisibilityOff ();
368 addActorToRenderer (actor, viewport);
371 (*shape_actor_map_)[id] = actor;
378 template <
typename Po
intT>
bool 381 double r,
double g,
double b,
const std::string &
id,
int viewport)
388 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
389 if (am_it != shape_actor_map_->end ())
394 #if VTK_MAJOR_VERSION < 6 395 all_data->AddInput (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
397 all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
402 #if VTK_MAJOR_VERSION < 6 403 surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data));
405 surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
408 #if VTK_MAJOR_VERSION < 6 409 all_data->AddInput (poly_data);
411 all_data->AddInputData (poly_data);
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);
425 (*shape_actor_map_)[id] = 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);
439 (*shape_actor_map_)[id] = actor;
445 template <
typename Po
intT>
bool 448 const std::string &
id,
int viewport)
450 return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5,
id, viewport));
454 template <
typename P1,
typename P2>
bool 459 PCL_WARN (
"[addLine] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
467 createActorFromVTKDataSet (data, actor);
468 actor->GetProperty ()->SetRepresentationToWireframe ();
469 actor->GetProperty ()->SetColor (r, g, b);
470 actor->GetMapper ()->ScalarVisibilityOff ();
471 addActorToRenderer (actor, viewport);
474 (*shape_actor_map_)[id] = actor;
479 template <
typename P1,
typename P2>
bool 484 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
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 ();
497 leader->GetProperty ()->SetColor (r, g, b);
498 addActorToRenderer (leader, viewport);
501 (*shape_actor_map_)[id] = leader;
506 template <
typename P1,
typename P2>
bool 511 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
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 ();
524 leader->AutoLabelOn ();
526 leader->AutoLabelOff ();
528 leader->GetProperty ()->SetColor (r, g, b);
529 addActorToRenderer (leader, viewport);
532 (*shape_actor_map_)[id] = leader;
536 template <
typename P1,
typename P2>
bool 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)
544 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
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 ();
557 leader->GetLabelTextProperty()->SetColor(r_text, g_text, b_text);
559 leader->GetProperty ()->SetColor (r_line, g_line, b_line);
560 addActorToRenderer (leader, viewport);
563 (*shape_actor_map_)[id] = leader;
568 template <
typename P1,
typename P2>
bool 571 return (!addLine (pt1, pt2, 0.5, 0.5, 0.5,
id, viewport));
575 template <
typename Po
intT>
bool 580 PCL_WARN (
"[addSphere] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
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 ();
594 mapper->SetInputConnection (data->GetOutputPort ());
598 actor->SetMapper (mapper);
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);
610 (*shape_actor_map_)[id] = actor;
615 template <
typename Po
intT>
bool 618 return (addSphere (center, radius, 0.5, 0.5, 0.5,
id, viewport));
622 template<
typename Po
intT>
bool 632 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
633 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
636 #if VTK_MAJOR_VERSION < 6 637 vtkAlgorithm *algo = actor->GetMapper ()->GetInput ()->GetProducerPort ()->GetProducer ();
639 vtkAlgorithm *algo = actor->GetMapper ()->GetInputAlgorithm ();
641 vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo);
645 src->SetCenter (
double (center.x), double (center.y), double (center.z));
646 src->SetRadius (radius);
648 actor->GetProperty ()->SetColor (r, g, b);
655 template <
typename Po
intT>
bool 657 const std::string &text,
663 const std::string &
id,
674 PCL_WARN (
"[addText3D] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
679 textSource->SetText (text.c_str());
680 textSource->Update ();
683 textMapper->SetInputConnection (textSource->GetOutputPort ());
686 rens_->InitTraversal ();
687 vtkRenderer* renderer = NULL;
689 while ((renderer = rens_->GetNextItem ()) != NULL)
692 if (viewport == 0 || viewport == i)
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 ());
701 renderer->AddActor (textActor);
706 std::string alternate_tid = tid;
707 alternate_tid.append(i,
'*');
709 (*shape_actor_map_)[(viewport == 0) ? tid : alternate_tid] = textActor;
719 template <
typename Po
intNT>
bool 722 int level,
float scale,
const std::string &
id,
int viewport)
724 return (addPointCloudNormals<PointNT, PointNT> (cloud, cloud, level, scale,
id, viewport));
728 template <
typename Po
intT,
typename Po
intNT>
bool 732 int level,
float scale,
733 const std::string &
id,
int viewport)
737 PCL_ERROR (
"[addPointCloudNormals] The number of points differs from the number of normals!\n");
742 PCL_WARN (
"[addPointCloudNormals] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
749 points->SetDataTypeToFloat ();
751 data->SetNumberOfComponents (3);
754 vtkIdType nr_normals = 0;
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];
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)
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;
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;
781 lines->InsertNextCell (2);
782 lines->InsertCellPoint (2 * cell_count);
783 lines->InsertCellPoint (2 * cell_count + 1);
789 nr_normals = (cloud->
points.size () - 1) / level + 1 ;
790 pts =
new float[2 * nr_normals * 3];
792 for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level)
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;
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;
806 lines->InsertNextCell (2);
807 lines->InsertCellPoint (2 * j);
808 lines->InsertCellPoint (2 * j + 1);
812 data->SetArray (&pts[0], 2 * nr_normals * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
813 points->SetData (data);
816 polyData->SetPoints (points);
817 polyData->SetLines (lines);
820 #if VTK_MAJOR_VERSION < 6 821 mapper->SetInput (polyData);
823 mapper->SetInputData (polyData);
825 mapper->SetColorModeToMapScalars();
826 mapper->SetScalarModeToUsePointData();
830 actor->SetMapper (mapper);
835 actor->SetUserMatrix (transformation);
838 addActorToRenderer (actor, viewport);
841 (*cloud_actor_map_)[id].actor = actor;
846 template <
typename Po
intNT>
bool 850 int level,
float scale,
851 const std::string &
id,
int viewport)
853 return (addPointCloudPrincipalCurvatures<PointNT, PointNT> (cloud, cloud, pcs, level, scale,
id, viewport));
857 template <
typename Po
intT,
typename Po
intNT>
bool 862 int level,
float scale,
863 const std::string &
id,
int viewport)
867 pcl::console::print_error (
"[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
873 PCL_WARN (
"[addPointCloudPrincipalCurvatures] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
881 unsigned char green[3] = {0, 255, 0};
882 unsigned char blue[3] = {0, 0, 255};
886 line_1_colors->SetNumberOfComponents (3);
887 line_1_colors->SetName (
"Colors");
889 line_2_colors->SetNumberOfComponents (3);
890 line_2_colors->SetName (
"Colors");
893 for (
size_t i = 0; i < cloud->
points.size (); i+=level)
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;
902 line_1->SetPoint2 (p.x, p.y, p.z);
904 #if VTK_MAJOR_VERSION < 6 905 polydata_1->AddInput (line_1->GetOutput ());
907 polydata_1->AddInputData (line_1->GetOutput ());
909 line_1_colors->InsertNextTupleValue (green);
911 polydata_1->Update ();
913 line_1_data->GetCellData ()->SetScalars (line_1_colors);
916 for (
size_t i = 0; i < cloud->
points.size (); i += level)
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);
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;
933 line_2->SetPoint2 (p.x, p.y, p.z);
935 #if VTK_MAJOR_VERSION < 6 936 polydata_2->AddInput (line_2->GetOutput ());
938 polydata_2->AddInputData (line_2->GetOutput ());
941 line_2_colors->InsertNextTupleValue (blue);
943 polydata_2->Update ();
945 line_2_data->GetCellData ()->SetScalars (line_2_colors);
949 #if VTK_MAJOR_VERSION < 6 950 alldata->AddInput (line_1_data);
951 alldata->AddInput (line_2_data);
953 alldata->AddInputData (line_1_data);
954 alldata->AddInputData (line_2_data);
959 createActorFromVTKDataSet (alldata->GetOutput (), actor);
960 actor->GetMapper ()->SetScalarModeToUseCellData ();
963 addActorToRenderer (actor, viewport);
968 (*cloud_actor_map_)[id] = act;
973 template <
typename Po
intT,
typename GradientT>
bool 977 int level,
double scale,
978 const std::string &
id,
int viewport)
982 PCL_ERROR (
"[addPointCloudGradients] The number of points differs from the number of gradients!\n");
987 PCL_WARN (
"[addPointCloudGradients] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
994 points->SetDataTypeToFloat ();
996 data->SetNumberOfComponents (3);
998 vtkIdType nr_gradients = (cloud->
points.size () - 1) / level + 1 ;
999 float* pts =
new float[2 * nr_gradients * 3];
1001 for (vtkIdType i = 0, j = 0; j < nr_gradients; j++, i = j * level)
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;
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;
1015 lines->InsertNextCell(2);
1016 lines->InsertCellPoint(2*j);
1017 lines->InsertCellPoint(2*j+1);
1020 data->SetArray (&pts[0], 2 * nr_gradients * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
1021 points->SetData (data);
1024 polyData->SetPoints(points);
1025 polyData->SetLines(lines);
1028 #if VTK_MAJOR_VERSION < 6 1029 mapper->SetInput (polyData);
1031 mapper->SetInputData (polyData);
1033 mapper->SetColorModeToMapScalars();
1034 mapper->SetScalarModeToUsePointData();
1038 actor->SetMapper (mapper);
1041 addActorToRenderer (actor, viewport);
1044 (*cloud_actor_map_)[id].actor = actor;
1049 template <
typename Po
intT>
bool 1053 const std::vector<int> &correspondences,
1054 const std::string &
id,
1058 corrs.resize (correspondences.size ());
1061 for (pcl::Correspondences::iterator corrs_it (corrs.begin ()); corrs_it != corrs.end (); ++corrs_it)
1063 corrs_it->index_query = index;
1064 corrs_it->index_match = correspondences[index];
1068 return (addCorrespondences<PointT> (source_points, target_points, corrs,
id, viewport));
1072 template <
typename Po
intT>
bool 1078 const std::string &
id,
1082 if (correspondences.empty ())
1084 PCL_DEBUG (
"[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1089 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
1090 if (am_it != shape_actor_map_->end () && overwrite ==
false)
1092 PCL_WARN (
"[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
1094 }
else if (am_it == shape_actor_map_->end () && overwrite ==
true)
1099 int n_corr = int (correspondences.size () / nth);
1104 line_colors->SetNumberOfComponents (3);
1105 line_colors->SetName (
"Colors");
1106 line_colors->SetNumberOfTuples (n_corr);
1110 line_points->SetNumberOfPoints (2 * n_corr);
1113 line_cells_id->SetNumberOfComponents (3);
1114 line_cells_id->SetNumberOfTuples (n_corr);
1115 vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
1119 line_tcoords->SetNumberOfComponents (1);
1120 line_tcoords->SetNumberOfTuples (n_corr * 2);
1121 line_tcoords->SetName (
"Texture Coordinates");
1123 double tc[3] = {0.0, 0.0, 0.0};
1125 Eigen::Affine3f source_transformation;
1127 source_transformation.translation () = source_points->
sensor_origin_.head (3);
1128 Eigen::Affine3f target_transformation;
1130 target_transformation.translation () = target_points->
sensor_origin_.head (3);
1134 for (
size_t i = 0; i < correspondences.size (); i += nth, ++j)
1136 if (correspondences[i].index_match == -1)
1138 PCL_WARN (
"[addCorrespondences] No valid index_match for correspondence %d\n", i);
1142 PointT p_src (source_points->
points[correspondences[i].index_query]);
1143 PointT p_tgt (target_points->
points[correspondences[i].index_match]);
1145 p_src.getVector3fMap () = source_transformation * p_src.getVector3fMap ();
1146 p_tgt.getVector3fMap () = target_transformation * p_tgt.getVector3fMap ();
1148 int id1 = j * 2 + 0, id2 = j * 2 + 1;
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);
1153 *line_cell_id++ = 2;
1154 *line_cell_id++ = id1;
1155 *line_cell_id++ = id2;
1157 tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
1158 tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
1161 rgb[0] = vtkMath::Random (32, 255);
1162 rgb[1] = vtkMath::Random (32, 255);
1163 rgb[2] = vtkMath::Random (32, 255);
1164 line_colors->InsertTuple (i, rgb);
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);
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);
1182 createActorFromVTKDataSet (line_data, actor);
1183 actor->GetProperty ()->SetRepresentationToWireframe ();
1184 actor->GetProperty ()->SetOpacity (0.5);
1185 addActorToRenderer (actor, viewport);
1188 (*shape_actor_map_)[id] = actor;
1196 #if VTK_MAJOR_VERSION < 6 1197 reinterpret_cast<vtkPolyDataMapper*
>(actor->GetMapper ())->SetInput (line_data);
1199 reinterpret_cast<vtkPolyDataMapper*
> (actor->GetMapper ())->SetInputData (line_data);
1207 template <
typename Po
intT>
bool 1213 const std::string &
id,
1216 return (addCorrespondences<PointT> (source_points, target_points, correspondences, nth,
id, viewport,
true));
1220 template <
typename Po
intT>
bool 1221 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1224 const std::string &
id,
1226 const Eigen::Vector4f& sensor_origin,
1227 const Eigen::Quaternion<float>& sensor_orientation)
1231 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.
getName ().c_str ());
1237 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.
getName ().c_str ());
1244 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1248 bool has_colors =
false;
1251 if (color_handler.
getColor (scalars))
1253 polydata->GetPointData ()->SetScalars (scalars);
1254 scalars->GetRange (minmax);
1260 createActorFromVTKDataSet (polydata, actor);
1262 actor->GetMapper ()->SetScalarRange (minmax);
1265 addActorToRenderer (actor, viewport);
1268 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1269 cloud_actor.actor = actor;
1270 cloud_actor.cells = initcells;
1274 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1275 cloud_actor.viewpoint_transformation_ = transformation;
1276 cloud_actor.actor->SetUserMatrix (transformation);
1277 cloud_actor.actor->Modified ();
1283 template <
typename Po
intT>
bool 1284 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1285 const PointCloudGeometryHandler<PointT> &geometry_handler,
1286 const ColorHandlerConstPtr &color_handler,
1287 const std::string &
id,
1289 const Eigen::Vector4f& sensor_origin,
1290 const Eigen::Quaternion<float>& sensor_orientation)
1292 if (!geometry_handler.isCapable ())
1294 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.getName ().c_str ());
1298 if (!color_handler->isCapable ())
1300 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler->getName ().c_str ());
1307 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1311 bool has_colors =
false;
1314 if (color_handler->getColor (scalars))
1316 polydata->GetPointData ()->SetScalars (scalars);
1317 scalars->GetRange (minmax);
1323 createActorFromVTKDataSet (polydata, actor);
1325 actor->GetMapper ()->SetScalarRange (minmax);
1328 addActorToRenderer (actor, viewport);
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);
1338 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1339 cloud_actor.viewpoint_transformation_ = transformation;
1340 cloud_actor.actor->SetUserMatrix (transformation);
1341 cloud_actor.actor->Modified ();
1347 template <
typename Po
intT>
bool 1348 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1349 const GeometryHandlerConstPtr &geometry_handler,
1350 const PointCloudColorHandler<PointT> &color_handler,
1351 const std::string &
id,
1353 const Eigen::Vector4f& sensor_origin,
1354 const Eigen::Quaternion<float>& sensor_orientation)
1356 if (!geometry_handler->isCapable ())
1358 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler->getName ().c_str ());
1362 if (!color_handler.isCapable ())
1364 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.getName ().c_str ());
1371 convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
1375 bool has_colors =
false;
1378 if (color_handler.getColor (scalars))
1380 polydata->GetPointData ()->SetScalars (scalars);
1381 scalars->GetRange (minmax);
1387 createActorFromVTKDataSet (polydata, actor);
1389 actor->GetMapper ()->SetScalarRange (minmax);
1392 addActorToRenderer (actor, viewport);
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);
1402 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1403 cloud_actor.viewpoint_transformation_ = transformation;
1404 cloud_actor.actor->SetUserMatrix (transformation);
1405 cloud_actor.actor->Modified ();
1411 template <
typename Po
intT>
bool 1413 const std::string &
id)
1416 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1418 if (am_it == cloud_actor_map_->end ())
1423 convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
1427 polydata->GetPointData ()->SetScalars (scalars);
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);
1435 #if VTK_MAJOR_VERSION < 6 1436 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1438 reinterpret_cast<vtkPolyDataMapper*
> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1444 template <
typename Po
intT>
bool 1447 const std::string &
id)
1450 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1452 if (am_it == cloud_actor_map_->end ())
1459 convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
1463 polydata->GetPointData ()->SetScalars (scalars);
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);
1471 #if VTK_MAJOR_VERSION < 6 1472 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1474 reinterpret_cast<vtkPolyDataMapper*
> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1481 template <
typename Po
intT>
bool 1484 const std::string &
id)
1487 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1489 if (am_it == cloud_actor_map_->end ())
1499 vtkIdType nr_points = cloud->
points.size ();
1500 points->SetNumberOfPoints (nr_points);
1503 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
1509 for (vtkIdType i = 0; i < nr_points; ++i, pts += 3)
1510 memcpy (&data[pts], &cloud->
points[i].x, 12);
1515 for (vtkIdType i = 0; i < nr_points; ++i)
1521 memcpy (&data[pts], &cloud->
points[i].x, 12);
1526 points->SetNumberOfPoints (nr_points);
1530 updateCells (cells, am_it->second.cells, nr_points);
1533 vertices->SetCells (nr_points, cells);
1539 scalars->GetRange (minmax);
1541 polydata->GetPointData ()->SetScalars (scalars);
1543 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1544 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1547 #if VTK_MAJOR_VERSION < 6 1548 reinterpret_cast<vtkPolyDataMapper*
>(am_it->second.actor->GetMapper ())->SetInput (polydata);
1550 reinterpret_cast<vtkPolyDataMapper*
> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1556 template <
typename Po
intT>
bool 1559 const std::vector<pcl::Vertices> &vertices,
1560 const std::string &
id,
1563 if (vertices.empty () || cloud->
points.empty ())
1568 PCL_WARN (
"[addPolygonMesh] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
1573 std::vector<pcl::PCLPointField> fields;
1581 colors->SetNumberOfComponents (3);
1582 colors->SetName (
"Colors");
1585 for (
size_t i = 0; i < cloud->
size (); ++i)
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);
1600 vtkIdType nr_points = cloud->
points.size ();
1601 points->SetNumberOfPoints (nr_points);
1605 float *data =
static_cast<vtkFloatArray*
> (points->GetData ())->GetPointer (0);
1608 std::vector<int> lookup;
1612 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1613 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1617 lookup.resize (nr_points);
1619 for (vtkIdType i = 0; i < nr_points; ++i)
1625 lookup[i] =
static_cast<int> (j);
1626 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1631 points->SetNumberOfPoints (nr_points);
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 ());
1640 if (vertices.size () > 1)
1644 vtkIdType *cell = cell_array->WritePointer (vertices.size (), vertices.size () * (max_size_of_polygon + 1));
1646 if (lookup.size () > 0)
1648 for (
size_t i = 0; i < vertices.size (); ++i, ++idx)
1650 size_t n_points = vertices[i].vertices.size ();
1653 for (
size_t j = 0; j < n_points; j++, ++idx)
1654 *cell++ = lookup[vertices[i].vertices[j]];
1660 for (
size_t i = 0; i < vertices.size (); ++i, ++idx)
1662 size_t n_points = vertices[i].vertices.size ();
1665 for (
size_t j = 0; j < n_points; j++, ++idx)
1666 *cell++ = vertices[i].vertices[j];
1671 allocVtkPolyData (polydata);
1672 cell_array->GetData ()->SetNumberOfValues (idx);
1673 cell_array->Squeeze ();
1674 polydata->SetPolys (cell_array);
1675 polydata->SetPoints (points);
1678 polydata->GetPointData ()->SetScalars (colors);
1680 createActorFromVTKDataSet (polydata, actor,
false);
1685 size_t n_points = vertices[0].vertices.size ();
1686 polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
1688 if (lookup.size () > 0)
1690 for (
size_t j = 0; j < (n_points - 1); ++j)
1691 polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
1695 for (
size_t j = 0; j < (n_points - 1); ++j)
1696 polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
1700 poly_grid->Allocate (1, 1);
1701 poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
1702 poly_grid->SetPoints (points);
1704 poly_grid->GetPointData ()->SetScalars (colors);
1706 createActorFromVTKDataSet (poly_grid, actor,
false);
1708 addActorToRenderer (actor, viewport);
1709 actor->GetProperty ()->SetRepresentationToSurface ();
1711 actor->GetProperty ()->BackfaceCullingOff ();
1712 actor->GetProperty ()->SetInterpolationToFlat ();
1713 actor->GetProperty ()->EdgeVisibilityOff ();
1714 actor->GetProperty ()->ShadingOff ();
1717 (*cloud_actor_map_)[id].actor = actor;
1722 (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
1728 template <
typename Po
intT>
bool 1731 const std::vector<pcl::Vertices> &verts,
1732 const std::string &
id)
1741 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1742 if (am_it == cloud_actor_map_->end ())
1754 vtkIdType nr_points = cloud->
points.size ();
1755 points->SetNumberOfPoints (nr_points);
1758 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
1761 std::vector<int> lookup;
1765 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1766 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1770 lookup.resize (nr_points);
1772 for (vtkIdType i = 0; i < nr_points; ++i)
1778 lookup [i] =
static_cast<int> (j);
1779 memcpy (&data[ptr], &cloud->
points[i].x, sizeof (
float) * 3);
1784 points->SetNumberOfPoints (nr_points);
1788 vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
1792 std::vector<pcl::PCLPointField> fields;
1796 if (rgb_idx != -1 && colors)
1800 for (
size_t i = 0; i < cloud->
size (); ++i)
1805 reinterpret_cast<const char*> (&cloud->
points[i]) + fields[rgb_idx].offset,
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);
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 ());
1823 vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1));
1825 if (lookup.size () > 0)
1827 for (
size_t i = 0; i < verts.size (); ++i, ++idx)
1829 size_t n_points = verts[i].vertices.size ();
1831 for (
size_t j = 0; j < n_points; j++, cell++, ++idx)
1832 *cell = lookup[verts[i].vertices[j]];
1837 for (
size_t i = 0; i < verts.size (); ++i, ++idx)
1839 size_t n_points = verts[i].vertices.size ();
1841 for (
size_t j = 0; j < n_points; j++, cell++, ++idx)
1842 *cell = verts[i].vertices[j];
1845 cells->GetData ()->SetNumberOfValues (idx);
1848 polydata->SetPolys (cells);
1853 #ifdef vtkGenericDataArray_h 1854 #undef SetTupleValue 1855 #undef InsertNextTupleValue 1856 #undef GetTupleValue 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 return true if f...
int getFieldIndex(const pcl::PCLPointCloud2 &cloud, const std::string &field_name)
Get the index of a specified field (i.e., dimension/channel)
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
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).
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 isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
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).
A structure representing RGB color information.
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", int viewport=0)
Update the specified correspondences to the display.
Define methods or creating 3D shapes from parametric models.
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
RGB handler class for colors.
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).
vtkSmartPointer< vtkLODActor > actor
The actor holding the data to render.
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.
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).
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 ¢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.