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>
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>
65#include <pcl/common/utils.h>
69#ifdef vtkGenericDataArray_h
70#define SetTupleValue SetTypedTuple
71#define InsertNextTupleValue InsertNextTypedTuple
72#define GetTupleValue GetTypedTuple
76template <
typename Po
intT>
bool
87template <
typename Po
intT>
bool
95 PCL_WARN (
"[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
99 if (pcl::traits::has_color<PointT>())
109template <
typename Po
intT>
bool
113 const std::string &
id,
int viewport)
119 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
130template <
typename Po
intT>
bool
134 const std::string &
id,
int viewport)
138 PCL_WARN (
"[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
152template <
typename Po
intT>
bool
156 const std::string &
id,
int viewport)
159 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
160 if (
am_it != cloud_actor_map_->end ())
173template <
typename Po
intT>
bool
178 const std::string &
id,
int viewport)
181 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
182 if (
am_it != cloud_actor_map_->end ())
194template <
typename Po
intT>
bool
199 const std::string &
id,
int viewport)
203 PCL_WARN (
"[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
215template <
typename Po
intT>
void
216pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
240 points->SetDataTypeToFloat ();
243 points->SetNumberOfPoints (nr_points);
246 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
252 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
253 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
258 for (vtkIdType i = 0; i < nr_points; ++i)
261 if (!std::isfinite ((*cloud)[i].x) ||
262 !std::isfinite ((*cloud)[i].y) ||
263 !std::isfinite ((*cloud)[i].z))
266 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
271 points->SetNumberOfPoints (nr_points);
274#ifdef VTK_CELL_ARRAY_V2
278 auto numOfCells = vertices->GetNumberOfCells();
281 if (numOfCells < nr_points)
283 for (
int i = numOfCells; i < nr_points; i++)
285 vertices->InsertNextCell(1);
286 vertices->InsertCellPoint(i);
290 else if (numOfCells > nr_points)
292 vertices->ResizeExact(nr_points, nr_points);
295 polydata->SetPoints(points);
296 polydata->SetVerts(vertices);
300 updateCells (cells, initcells, nr_points);
303 vertices->SetCells (nr_points, cells);
306 vertices->SetNumberOfCells(nr_points);
311template <
typename Po
intT>
void
312pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
320 allocVtkPolyData (polydata);
322 polydata->SetVerts (vertices);
328 polydata->SetPoints (points);
330 vtkIdType nr_points = points->GetNumberOfPoints ();
333 vertices = polydata->GetVerts ();
337#ifdef VTK_CELL_ARRAY_V2
341 auto numOfCells = vertices->GetNumberOfCells();
344 if (numOfCells < nr_points)
346 for (
int i = numOfCells; i < nr_points; i++)
348 vertices->InsertNextCell(1);
349 vertices->InsertCellPoint(i);
353 else if (numOfCells > nr_points)
355 vertices->ResizeExact(nr_points, nr_points);
358 polydata->SetPoints(points);
359 polydata->SetVerts(vertices);
363 updateCells (cells, initcells, nr_points);
365 vertices->SetCells (nr_points, cells);
370template <
typename Po
intT>
bool
373 double r,
double g,
double b,
const std::string &
id,
int viewport)
380 ShapeActorMap::iterator
am_it = shape_actor_map_->find (
id);
381 if (
am_it != shape_actor_map_->end ())
390 surface_filter->AddInputData (vtkUnstructuredGrid::SafeDownCast (data));
396 createActorFromVTKDataSet (
all_data->GetOutput (), actor);
397 actor->GetProperty ()->SetRepresentationToWireframe ();
398 actor->GetProperty ()->SetColor (r, g, b);
399 actor->GetMapper ()->ScalarVisibilityOff ();
401 addActorToRenderer (actor,
viewport);
404 (*shape_actor_map_)[id] = actor;
410 createActorFromVTKDataSet (data, actor);
411 actor->GetProperty ()->SetRepresentationToWireframe ();
412 actor->GetProperty ()->SetColor (r, g, b);
413 actor->GetMapper ()->ScalarVisibilityOff ();
414 addActorToRenderer (actor,
viewport);
417 (*shape_actor_map_)[id] = actor;
424template <
typename Po
intT>
bool
427 double r,
double g,
double b,
const std::string &
id,
int viewport)
434 ShapeActorMap::iterator
am_it = shape_actor_map_->find (
id);
435 if (
am_it != shape_actor_map_->end ())
444 surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
450 createActorFromVTKDataSet (
all_data->GetOutput (), actor);
451 actor->GetProperty ()->SetRepresentationToWireframe ();
452 actor->GetProperty ()->SetColor (r, g, b);
453 actor->GetMapper ()->ScalarVisibilityOn ();
454 actor->GetProperty ()->BackfaceCullingOff ();
456 addActorToRenderer (actor,
viewport);
459 (*shape_actor_map_)[id] = actor;
465 createActorFromVTKDataSet (data, actor);
466 actor->GetProperty ()->SetRepresentationToWireframe ();
467 actor->GetProperty ()->SetColor (r, g, b);
468 actor->GetMapper ()->ScalarVisibilityOn ();
469 actor->GetProperty ()->BackfaceCullingOff ();
470 addActorToRenderer (actor,
viewport);
473 (*shape_actor_map_)[id] = actor;
479template <
typename Po
intT>
bool
482 const std::string &
id,
int viewport)
488template <
typename P1,
typename P2>
bool
493 PCL_WARN (
"[addLine] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
501 createActorFromVTKDataSet (data, actor);
502 actor->GetProperty ()->SetRepresentationToWireframe ();
503 actor->GetProperty ()->SetColor (r, g, b);
504 actor->GetMapper ()->ScalarVisibilityOff ();
505 addActorToRenderer (actor,
viewport);
508 (*shape_actor_map_)[id] = actor;
513template <
typename P1,
typename P2>
bool
518 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
524 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
526 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
528 leader->SetArrowStyleToFilled ();
531 leader->GetProperty ()->SetColor (r, g, b);
535 (*shape_actor_map_)[id] =
leader;
540template <
typename P1,
typename P2>
bool
545 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
551 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
553 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
555 leader->SetArrowStyleToFilled ();
556 leader->SetArrowPlacementToPoint1 ();
562 leader->GetProperty ()->SetColor (r, g, b);
566 (*shape_actor_map_)[id] =
leader;
570template <
typename P1,
typename P2>
bool
574 const std::string &
id,
int viewport)
578 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
584 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
586 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
588 leader->SetArrowStyleToFilled ();
597 (*shape_actor_map_)[id] =
leader;
602template <
typename P1,
typename P2>
bool
609template <
typename Po
intT>
bool
614 PCL_WARN (
"[addSphere] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
619 data->SetRadius (radius);
621 data->SetPhiResolution (10);
622 data->SetThetaResolution (10);
623 data->LatLongTessellationOff ();
628 mapper->SetInputConnection (data->GetOutputPort ());
632 actor->SetMapper (
mapper);
634 actor->GetProperty ()->SetRepresentationToSurface ();
635 actor->GetProperty ()->SetInterpolationToFlat ();
636 actor->GetProperty ()->SetColor (r, g, b);
637#if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
638 actor->GetMapper ()->ImmediateModeRenderingOn ();
640 actor->GetMapper ()->StaticOn ();
641 actor->GetMapper ()->ScalarVisibilityOff ();
642 actor->GetMapper ()->Update ();
643 addActorToRenderer (actor,
viewport);
646 (*shape_actor_map_)[id] = actor;
651template <
typename Po
intT>
bool
658template<
typename Po
intT>
bool
668 ShapeActorMap::iterator
am_it = shape_actor_map_->find (
id);
678 src->SetRadius (radius);
680 actor->GetProperty ()->SetColor (r, g, b);
687template <
typename Po
intT>
bool
689 const std::string &text,
695 const std::string &
id,
708 if (rens_->GetNumberOfItems () <=
viewport)
710 PCL_ERROR (
"[addText3D] The viewport [%d] doesn't exist (id <%s>)! \n",
717 rens_->InitTraversal ();
718 for (std::size_t i =
viewport; rens_->GetNextItem (); ++i)
720 const std::string uid =
tid + std::string (i,
'*');
723 PCL_ERROR (
"[addText3D] The id <%s> already exists in viewport [%d]! \n"
724 "Please choose a different id and retry.\n",
742 rens_->InitTraversal ();
745 while ((
renderer = rens_->GetNextItem ()))
752 textActor->SetPosition (position.x, position.y, position.z);
754 textActor->GetProperty ()->SetColor (r, g, b);
762 const std::string uid =
tid + std::string (i,
'*');
773template <
typename Po
intT>
bool
775 const std::string &text,
777 double orientation[3],
782 const std::string &
id,
795 if (rens_->GetNumberOfItems () <=
viewport)
797 PCL_ERROR (
"[addText3D] The viewport [%d] doesn't exist (id <%s>)!\n",
804 rens_->InitTraversal ();
805 for (std::size_t i =
viewport; rens_->GetNextItem (); ++i)
807 const std::string uid =
tid + std::string (i,
'*');
810 PCL_ERROR (
"[addText3D] The id <%s> already exists in viewport [%d]! "
811 "Please choose a different id and retry.\n",
830 textActor->SetPosition (position.x, position.y, position.z);
832 textActor->GetProperty ()->SetColor (r, g, b);
836 rens_->InitTraversal ();
840 renderer = rens_->GetNextItem (), ++i)
845 const std::string uid =
tid + std::string (i,
'*');
854template <
typename Po
intNT>
bool
857 int level,
float scale,
const std::string &
id,
int viewport)
863template <
typename Po
intT,
typename Po
intNT>
bool
867 int level,
float scale,
868 const std::string &
id,
int viewport)
870 if (normals->size () != cloud->size ())
872 PCL_ERROR (
"[addPointCloudNormals] The number of points differs from the number of normals!\n");
876 if (normals->empty ())
878 PCL_WARN (
"[addPointCloudNormals] An empty normal cloud is given! Nothing to display.\n");
884 PCL_WARN (
"[addPointCloudNormals] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
891 points->SetDataTypeToFloat ();
893 data->SetNumberOfComponents (3);
897 float*
pts =
nullptr;
900 if (cloud->isOrganized () && normals->isOrganized ())
904 (
static_cast<vtkIdType> ((cloud->height - 1) / point_step) + 1);
908 for (
vtkIdType y = 0; y < normals->height; y += point_step)
909 for (
vtkIdType x = 0; x < normals->width; x += point_step)
911 PointT p = (*cloud)(x, y);
912 p.x += (*normals)(x, y).normal[0] * scale;
913 p.y += (*normals)(x, y).normal[1] * scale;
914 p.z += (*normals)(x, y).normal[2] * scale;
923 lines->InsertNextCell (2);
931 nr_normals = (cloud->size () - 1) / level + 1 ;
937 p.x += (*normals)[i].normal[0] * scale;
938 p.y += (*normals)[i].normal[1] * scale;
939 p.z += (*normals)[i].normal[2] * scale;
941 pts[2 * j * 3 + 0] = (*cloud)[i].x;
942 pts[2 * j * 3 + 1] = (*cloud)[i].y;
943 pts[2 * j * 3 + 2] = (*cloud)[i].z;
944 pts[2 * j * 3 + 3] = p.x;
945 pts[2 * j * 3 + 4] = p.y;
946 pts[2 * j * 3 + 5] = p.z;
948 lines->InsertNextCell (2);
949 lines->InsertCellPoint (2 * j);
950 lines->InsertCellPoint (2 * j + 1);
954 data->SetArray (&
pts[0], 2 *
nr_normals * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
955 points->SetData (data);
963 mapper->SetColorModeToMapScalars();
964 mapper->SetScalarModeToUsePointData();
968 actor->SetMapper (
mapper);
972 convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
973 actor->SetUserMatrix (transformation);
976 addActorToRenderer (actor,
viewport);
979 (*cloud_actor_map_)[id].actor = actor;
984template <
typename Po
intNT>
bool
988 int level,
float scale,
989 const std::string &
id,
int viewport)
995template <
typename Po
intT,
typename Po
intNT>
bool
1000 int level,
float scale,
1001 const std::string &
id,
int viewport)
1003 if (
pcs->
size () != cloud->size () || normals->size () != cloud->size ())
1005 pcl::console::print_error (
"[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
1011 PCL_WARN (
"[addPointCloudPrincipalCurvatures] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
1019 unsigned char green[3] = {0, 255, 0};
1020 unsigned char blue[3] = {0, 0, 255};
1031 for (std::size_t i = 0; i < cloud->size (); i+=level)
1034 p.x += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[0]) * scale;
1035 p.y += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[1]) * scale;
1036 p.z += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[2]) * scale;
1039 line_1->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
1040 line_1->SetPoint2 (p.x, p.y, p.z);
1050 for (std::size_t i = 0; i < cloud->size (); i += level)
1052 Eigen::Vector3f
pc ((*
pcs)[i].principal_curvature[0],
1053 (*
pcs)[i].principal_curvature[1],
1054 (*
pcs)[i].principal_curvature[2]);
1055 Eigen::Vector3f normal ((*normals)[i].normal[0],
1056 (*normals)[i].normal[1],
1057 (*normals)[i].normal[2]);
1058 Eigen::Vector3f
pc_c =
pc.cross (normal);
1061 p.x += ((*pcs)[i].pc2 *
pc_c[0]) * scale;
1062 p.y += ((*pcs)[i].pc2 *
pc_c[1]) * scale;
1063 p.z += ((*pcs)[i].pc2 *
pc_c[2]) * scale;
1066 line_2->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
1067 line_2->SetPoint2 (p.x, p.y, p.z);
1084 createActorFromVTKDataSet (
alldata->GetOutput (), actor);
1085 actor->GetMapper ()->SetScalarModeToUseCellData ();
1088 addActorToRenderer (actor,
viewport);
1093 (*cloud_actor_map_)[id] =
act;
1098template <
typename Po
intT,
typename GradientT>
bool
1102 int level,
double scale,
1103 const std::string &
id,
int viewport)
1107 PCL_ERROR (
"[addPointCloudGradients] The number of points differs from the number of gradients!\n");
1112 PCL_WARN (
"[addPointCloudGradients] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
1119 points->SetDataTypeToFloat ();
1121 data->SetNumberOfComponents (3);
1129 p.x += (*gradients)[i].gradient[0] * scale;
1130 p.y += (*gradients)[i].gradient[1] * scale;
1131 p.z += (*gradients)[i].gradient[2] * scale;
1133 pts[2 * j * 3 + 0] = (*cloud)[i].x;
1134 pts[2 * j * 3 + 1] = (*cloud)[i].y;
1135 pts[2 * j * 3 + 2] = (*cloud)[i].z;
1136 pts[2 * j * 3 + 3] = p.x;
1137 pts[2 * j * 3 + 4] = p.y;
1138 pts[2 * j * 3 + 5] = p.z;
1140 lines->InsertNextCell(2);
1141 lines->InsertCellPoint(2*j);
1142 lines->InsertCellPoint(2*j+1);
1145 data->SetArray (&
pts[0], 2 *
nr_gradients * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
1146 points->SetData (data);
1154 mapper->SetColorModeToMapScalars();
1155 mapper->SetScalarModeToUsePointData();
1159 actor->SetMapper (
mapper);
1162 addActorToRenderer (actor,
viewport);
1165 (*cloud_actor_map_)[id].actor = actor;
1170template <
typename Po
intT>
bool
1174 const std::vector<int> &correspondences,
1175 const std::string &
id,
1179 corrs.resize (correspondences.size ());
1181 std::size_t index = 0;
1184 corr.index_query = index;
1185 corr.index_match = correspondences[index];
1193template <
typename Po
intT>
bool
1199 const std::string &
id,
1203 if (correspondences.empty ())
1205 PCL_DEBUG (
"[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1210 ShapeActorMap::iterator
am_it = shape_actor_map_->find (
id);
1213 PCL_WARN (
"[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
1245 double tc[3] = {0.0, 0.0, 0.0};
1256 for (std::size_t i = 0; i < correspondences.size (); i +=
nth, ++j)
1258 if (correspondences[i].index_match ==
UNAVAILABLE)
1260 PCL_WARN (
"[addCorrespondences] No valid index_match for correspondence %d\n", i);
1270 int id1 = j * 2 + 0,
id2 = j * 2 + 1;
1283 rgb[0] = vtkMath::Random (32, 255);
1284 rgb[1] = vtkMath::Random (32, 255);
1285 rgb[2] = vtkMath::Random (32, 255);
1304 createActorFromVTKDataSet (
line_data, actor);
1305 actor->GetProperty ()->SetRepresentationToWireframe ();
1306 actor->GetProperty ()->SetOpacity (0.5);
1307 addActorToRenderer (actor,
viewport);
1310 (*shape_actor_map_)[id] = actor;
1325template <
typename Po
intT>
bool
1331 const std::string &
id,
1338template <
typename Po
intT>
bool
1339pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1342 const std::string &
id,
1349 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.
c_str (),
geometry_handler.getName ().c_str ());
1355 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.
c_str (),
color_handler.getName ().c_str ());
1362 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1365 bool has_colors =
false;
1367 if (
auto scalars = color_handler.getColor ())
1369 polydata->GetPointData ()->SetScalars (scalars);
1370 scalars->GetRange (minmax);
1376 createActorFromVTKDataSet (polydata, actor);
1378 actor->GetMapper ()->SetScalarRange (minmax);
1381 addActorToRenderer (actor, viewport);
1384 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1385 cloud_actor.actor = actor;
1386 cloud_actor.cells = initcells;
1390 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1391 cloud_actor.viewpoint_transformation_ = transformation;
1392 cloud_actor.actor->SetUserMatrix (transformation);
1393 cloud_actor.actor->Modified ();
1399template <
typename Po
intT>
bool
1400pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1401 const PointCloudGeometryHandler<PointT> &geometry_handler,
1402 const ColorHandlerConstPtr &color_handler,
1403 const std::string &
id,
1405 const Eigen::Vector4f& sensor_origin,
1406 const Eigen::Quaternion<float>& sensor_orientation)
1408 if (!geometry_handler.isCapable ())
1410 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.getName ().c_str ());
1414 if (!color_handler->isCapable ())
1416 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler->getName ().c_str ());
1423 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1427 bool has_colors =
false;
1429 if (
auto scalars = color_handler->getColor ())
1431 polydata->GetPointData ()->SetScalars (scalars);
1432 scalars->GetRange (minmax);
1438 createActorFromVTKDataSet (polydata, actor);
1440 actor->GetMapper ()->SetScalarRange (minmax);
1443 addActorToRenderer (actor, viewport);
1446 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1447 cloud_actor.actor = actor;
1448 cloud_actor.cells = initcells;
1449 cloud_actor.color_handlers.push_back (color_handler);
1453 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1454 cloud_actor.viewpoint_transformation_ = transformation;
1455 cloud_actor.actor->SetUserMatrix (transformation);
1456 cloud_actor.actor->Modified ();
1462template <
typename Po
intT>
bool
1463pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1464 const GeometryHandlerConstPtr &geometry_handler,
1465 const PointCloudColorHandler<PointT> &color_handler,
1466 const std::string &
id,
1468 const Eigen::Vector4f& sensor_origin,
1469 const Eigen::Quaternion<float>& sensor_orientation)
1471 if (!geometry_handler->isCapable ())
1473 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler->getName ().c_str ());
1477 if (!color_handler.isCapable ())
1479 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.getName ().c_str ());
1486 convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
1490 bool has_colors =
false;
1492 if (
auto scalars = color_handler.getColor ())
1494 polydata->GetPointData ()->SetScalars (scalars);
1495 scalars->GetRange (minmax);
1501 createActorFromVTKDataSet (polydata, actor);
1503 actor->GetMapper ()->SetScalarRange (minmax);
1506 addActorToRenderer (actor, viewport);
1509 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1510 cloud_actor.actor = actor;
1511 cloud_actor.cells = initcells;
1512 cloud_actor.geometry_handlers.push_back (geometry_handler);
1516 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1517 cloud_actor.viewpoint_transformation_ = transformation;
1518 cloud_actor.actor->SetUserMatrix (transformation);
1519 cloud_actor.actor->Modified ();
1525template <
typename Po
intT>
bool
1527 const std::string &
id)
1530 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
1532 if (
am_it == cloud_actor_map_->end ())
1545 minmax[0] = std::numeric_limits<double>::min ();
1546 minmax[1] = std::numeric_limits<double>::max ();
1547#if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1548 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1550 am_it->second.actor->GetMapper ()->SetScalarRange (
minmax);
1558template <
typename Po
intT>
bool
1561 const std::string &
id)
1564 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
1566 if (
am_it == cloud_actor_map_->end ())
1579 minmax[0] = std::numeric_limits<double>::min ();
1580 minmax[1] = std::numeric_limits<double>::max ();
1581#if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1582 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1584 am_it->second.actor->GetMapper ()->SetScalarRange (
minmax);
1593template <
typename Po
intT>
bool
1596 const std::string &
id)
1599 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
1601 if (
am_it == cloud_actor_map_->end ())
1622#if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1623 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1627 am_it->second.actor->GetMapper ()->SetScalarRange (
minmax);
1635template <
typename Po
intT>
bool
1638 const std::vector<pcl::Vertices> &vertices,
1639 const std::string &
id,
1642 if (vertices.empty () || cloud->points.empty ())
1647 PCL_WARN (
"[addPolygonMesh] The id <%s> already exists! Please choose a different id and retry.\n",
id.
c_str ());
1652 std::vector<pcl::PCLPointField> fields;
1660 colors->SetNumberOfComponents (3);
1661 colors->SetName (
"Colors");
1662 std::uint32_t offset = fields[
rgb_idx].offset;
1663 for (std::size_t i = 0; i < cloud->size (); ++i)
1667 const pcl::RGB*
const rgb_data =
reinterpret_cast<const pcl::RGB*
>(
reinterpret_cast<const char*
> (&(*cloud)[i]) + offset);
1668 unsigned char color[3];
1672 colors->InsertNextTupleValue (
color);
1679 points->SetNumberOfPoints (nr_points);
1686 std::vector<int> lookup;
1688 if (cloud->is_dense)
1690 for (
vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1691 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1695 lookup.resize (nr_points);
1697 for (
vtkIdType i = 0; i < nr_points; ++i)
1703 lookup[i] =
static_cast<int> (j);
1704 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1709 points->SetNumberOfPoints (nr_points);
1714 for (
const auto &
vertex : vertices)
1718 if (vertices.size () > 1)
1727 cell_array->GetData ()->SetNumberOfValues (idx);
1733 polydata->GetPointData ()->SetScalars (colors);
1735 createActorFromVTKDataSet (
polydata, actor,
false);
1740 std::size_t
n_points = vertices[0].vertices.size ();
1743 if (!lookup.empty ())
1745 for (std::size_t j = 0; j < (
n_points - 1); ++j)
1746 polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
1750 for (std::size_t j = 0; j < (
n_points - 1); ++j)
1751 polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
1759 poly_grid->GetPointData ()->SetScalars (colors);
1761 createActorFromVTKDataSet (
poly_grid, actor,
false);
1763 addActorToRenderer (actor,
viewport);
1764 actor->GetProperty ()->SetRepresentationToSurface ();
1766 actor->GetProperty ()->BackfaceCullingOff ();
1767 actor->GetProperty ()->SetInterpolationToFlat ();
1768 actor->GetProperty ()->EdgeVisibilityOff ();
1769 actor->GetProperty ()->ShadingOff ();
1772 (*cloud_actor_map_)[id].actor = actor;
1776 convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
1777 (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
1783template <
typename Po
intT>
bool
1786 const std::vector<pcl::Vertices> &
verts,
1787 const std::string &
id)
1796 CloudActorMap::iterator
am_it = cloud_actor_map_->find (
id);
1797 if (
am_it == cloud_actor_map_->end ())
1810 points->SetNumberOfPoints (nr_points);
1813 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
1816 std::vector<int> lookup;
1818 if (cloud->is_dense)
1820 for (
vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1821 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1825 lookup.resize (nr_points);
1827 for (
vtkIdType i = 0; i < nr_points; ++i)
1833 lookup [i] =
static_cast<int> (j);
1834 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1839 points->SetNumberOfPoints (nr_points);
1847 std::vector<pcl::PCLPointField> fields;
1854 std::uint32_t offset = fields[
rgb_idx].offset;
1855 for (std::size_t i = 0; i < cloud->size (); ++i)
1859 const pcl::RGB*
const rgb_data =
reinterpret_cast<const pcl::RGB*
>(
reinterpret_cast<const char*
> (&(*cloud)[i]) + offset);
1860 unsigned char color[3];
1864 colors->SetTupleValue (j++,
color);
1879 cells->GetData ()->SetNumberOfValues (idx);
1887#ifdef vtkGenericDataArray_h
1889#undef InsertNextTupleValue
Iterator class for point clouds with or without given indices.
std::size_t size() const
Size of the range the iterator is going through.
shared_ptr< const PointCloud< PointT > > ConstPtr
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 addPolygonMesh(const pcl::PolygonMesh &polymesh, const std::string &id="polygon", int viewport=0)
Add a PolygonMesh object to screen.
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 addPointCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::string &id="cloud", int viewport=0)
Add a Point Cloud (templated) to screen.
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 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 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.
GeometryHandler::ConstPtr GeometryHandlerConstPtr
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.
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 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.
ColorHandler::ConstPtr ColorHandlerConstPtr
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.
bool addLine(const P1 &pt1, const P2 &pt2, const std::string &id="line", int viewport=0)
Add a line segment from two points.
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.
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.
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.
Base handler class for PointCloud geometry.
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const =0
Obtain the actual point geometry for the input dataset in VTK format.
PCL_EXPORTS vtkSmartPointer< vtkDataSet > createLine(const Eigen::Vector4f &pt1, const Eigen::Vector4f &pt2)
Create a line shape from two points.
PCL_EXPORTS void print_error(const char *format,...)
Print an error message on stream with colors.
void ignore(const T &...)
Utility function to eliminate unused variable warnings.
PCL_EXPORTS vtkIdType fillCells(std::vector< int > &lookup, const std::vector< pcl::Vertices > &vertices, vtkSmartPointer< vtkCellArray > cell_array, int max_size_of_polygon)
PCL_EXPORTS void allocVtkUnstructuredGrid(vtkSmartPointer< vtkUnstructuredGrid > &polydata)
Allocate a new unstructured grid smartpointer.
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...
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
static constexpr index_t UNAVAILABLE
Define methods or creating 3D shapes from parametric models.
A point structure representing Euclidean xyz coordinates, and the RGB color.
A structure representing RGB color information.