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->
size ();
239 points->SetDataTypeToFloat ();
240 polydata->SetPoints (points);
242 points->SetNumberOfPoints (nr_points);
245 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
251 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
252 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
257 for (vtkIdType i = 0; i < nr_points; ++i)
260 if (!std::isfinite ((*cloud)[i].x) ||
261 !std::isfinite ((*cloud)[i].y) ||
262 !std::isfinite ((*cloud)[i].z))
265 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
270 points->SetNumberOfPoints (nr_points);
274 updateCells (cells, initcells, nr_points);
277 vertices->SetCells (nr_points, cells);
279 vertices->SetNumberOfCells(nr_points);
283 template <
typename Po
intT>
void
284 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
292 allocVtkPolyData (polydata);
294 polydata->SetVerts (vertices);
300 polydata->SetPoints (points);
302 vtkIdType nr_points = points->GetNumberOfPoints ();
305 vertices = polydata->GetVerts ();
310 updateCells (cells, initcells, nr_points);
312 vertices->SetCells (nr_points, cells);
316 template <
typename Po
intT>
bool
319 double r,
double g,
double b,
const std::string &
id,
int viewport)
326 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
327 if (am_it != shape_actor_map_->end ())
332 all_data->AddInputData (
reinterpret_cast<vtkPolyDataMapper*
> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
336 surface_filter->AddInputData (vtkUnstructuredGrid::SafeDownCast (data));
338 all_data->AddInputData (poly_data);
342 createActorFromVTKDataSet (all_data->GetOutput (), actor);
343 actor->GetProperty ()->SetRepresentationToWireframe ();
344 actor->GetProperty ()->SetColor (r, g, b);
345 actor->GetMapper ()->ScalarVisibilityOff ();
346 removeActorFromRenderer (am_it->second, viewport);
347 addActorToRenderer (actor, viewport);
350 (*shape_actor_map_)[id] = actor;
356 createActorFromVTKDataSet (data, actor);
357 actor->GetProperty ()->SetRepresentationToWireframe ();
358 actor->GetProperty ()->SetColor (r, g, b);
359 actor->GetMapper ()->ScalarVisibilityOff ();
360 addActorToRenderer (actor, viewport);
363 (*shape_actor_map_)[id] = actor;
370 template <
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 ())
386 all_data->AddInputData (
reinterpret_cast<vtkPolyDataMapper*
> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
390 surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
392 all_data->AddInputData (poly_data);
396 createActorFromVTKDataSet (all_data->GetOutput (), actor);
397 actor->GetProperty ()->SetRepresentationToWireframe ();
398 actor->GetProperty ()->SetColor (r, g, b);
399 actor->GetMapper ()->ScalarVisibilityOn ();
400 actor->GetProperty ()->BackfaceCullingOff ();
401 removeActorFromRenderer (am_it->second, viewport);
402 addActorToRenderer (actor, viewport);
405 (*shape_actor_map_)[id] = actor;
411 createActorFromVTKDataSet (data, actor);
412 actor->GetProperty ()->SetRepresentationToWireframe ();
413 actor->GetProperty ()->SetColor (r, g, b);
414 actor->GetMapper ()->ScalarVisibilityOn ();
415 actor->GetProperty ()->BackfaceCullingOff ();
416 addActorToRenderer (actor, viewport);
419 (*shape_actor_map_)[id] = actor;
425 template <
typename Po
intT>
bool
428 const std::string &
id,
int viewport)
430 return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5,
id, viewport));
434 template <
typename P1,
typename P2>
bool
439 PCL_WARN (
"[addLine] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
447 createActorFromVTKDataSet (data, actor);
448 actor->GetProperty ()->SetRepresentationToWireframe ();
449 actor->GetProperty ()->SetColor (r, g, b);
450 actor->GetMapper ()->ScalarVisibilityOff ();
451 addActorToRenderer (actor, viewport);
454 (*shape_actor_map_)[id] = actor;
459 template <
typename P1,
typename P2>
bool
464 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
470 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
471 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
472 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
473 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
474 leader->SetArrowStyleToFilled ();
475 leader->AutoLabelOn ();
477 leader->GetProperty ()->SetColor (r, g, b);
478 addActorToRenderer (leader, viewport);
481 (*shape_actor_map_)[id] = leader;
486 template <
typename P1,
typename P2>
bool
491 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
497 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
498 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
499 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
500 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
501 leader->SetArrowStyleToFilled ();
502 leader->SetArrowPlacementToPoint1 ();
504 leader->AutoLabelOn ();
506 leader->AutoLabelOff ();
508 leader->GetProperty ()->SetColor (r, g, b);
509 addActorToRenderer (leader, viewport);
512 (*shape_actor_map_)[id] = leader;
516 template <
typename P1,
typename P2>
bool
518 double r_line,
double g_line,
double b_line,
519 double r_text,
double g_text,
double b_text,
520 const std::string &
id,
int viewport)
524 PCL_WARN (
"[addArrow] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
530 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
531 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
532 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
533 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
534 leader->SetArrowStyleToFilled ();
535 leader->AutoLabelOn ();
537 leader->GetLabelTextProperty()->SetColor(r_text, g_text, b_text);
539 leader->GetProperty ()->SetColor (r_line, g_line, b_line);
540 addActorToRenderer (leader, viewport);
543 (*shape_actor_map_)[id] = leader;
548 template <
typename P1,
typename P2>
bool
551 return (!addLine (pt1, pt2, 0.5, 0.5, 0.5,
id, viewport));
555 template <
typename Po
intT>
bool
560 PCL_WARN (
"[addSphere] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
565 data->SetRadius (radius);
566 data->SetCenter (
double (center.x), double (center.y), double (center.z));
567 data->SetPhiResolution (10);
568 data->SetThetaResolution (10);
569 data->LatLongTessellationOff ();
574 mapper->SetInputConnection (data->GetOutputPort ());
578 actor->SetMapper (mapper);
580 actor->GetProperty ()->SetRepresentationToSurface ();
581 actor->GetProperty ()->SetInterpolationToFlat ();
582 actor->GetProperty ()->SetColor (r, g, b);
583 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
584 actor->GetMapper ()->ImmediateModeRenderingOn ();
586 actor->GetMapper ()->StaticOn ();
587 actor->GetMapper ()->ScalarVisibilityOff ();
588 actor->GetMapper ()->Update ();
589 addActorToRenderer (actor, viewport);
592 (*shape_actor_map_)[id] = actor;
597 template <
typename Po
intT>
bool
600 return (addSphere (center, radius, 0.5, 0.5, 0.5,
id, viewport));
604 template<
typename Po
intT>
bool
614 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
615 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
618 vtkAlgorithm *algo = actor->GetMapper ()->GetInputAlgorithm ();
619 vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo);
623 src->SetCenter (
double (center.x), double (center.y), double (center.z));
624 src->SetRadius (radius);
626 actor->GetProperty ()->SetColor (r, g, b);
633 template <
typename Po
intT>
bool
635 const std::string &text,
641 const std::string &
id,
654 if (rens_->GetNumberOfItems () <= viewport)
656 PCL_ERROR (
"[addText3D] The viewport [%d] doesn't exist (id <%s>)! \n",
663 rens_->InitTraversal ();
664 for (std::size_t i = viewport; rens_->GetNextItem (); ++i)
666 const std::string uid = tid + std::string (i,
'*');
669 PCL_ERROR (
"[addText3D] The id <%s> already exists in viewport [%d]! \n"
670 "Please choose a different id and retry.\n",
681 textSource->SetText (text.c_str());
682 textSource->Update ();
685 textMapper->SetInputConnection (textSource->GetOutputPort ());
688 rens_->InitTraversal ();
689 vtkRenderer* renderer;
691 while ((renderer = rens_->GetNextItem ()))
694 if (viewport == 0 || viewport == i)
697 textActor->SetMapper (textMapper);
698 textActor->SetPosition (position.x, position.y, position.z);
699 textActor->SetScale (textScale);
700 textActor->GetProperty ()->SetColor (r, g, b);
701 textActor->SetCamera (renderer->GetActiveCamera ());
703 renderer->AddActor (textActor);
708 const std::string uid = tid + std::string (i,
'*');
709 (*shape_actor_map_)[uid] = textActor;
719 template <
typename Po
intT>
bool
721 const std::string &text,
723 double orientation[3],
728 const std::string &
id,
741 if (rens_->GetNumberOfItems () <= viewport)
743 PCL_ERROR (
"[addText3D] The viewport [%d] doesn't exist (id <%s>)!\n",
750 rens_->InitTraversal ();
751 for (std::size_t i = viewport; rens_->GetNextItem (); ++i)
753 const std::string uid = tid + std::string (i,
'*');
756 PCL_ERROR (
"[addText3D] The id <%s> already exists in viewport [%d]! "
757 "Please choose a different id and retry.\n",
768 textSource->SetText (text.c_str());
769 textSource->Update ();
772 textMapper->SetInputConnection (textSource->GetOutputPort ());
775 textActor->SetMapper (textMapper);
776 textActor->SetPosition (position.x, position.y, position.z);
777 textActor->SetScale (textScale);
778 textActor->GetProperty ()->SetColor (r, g, b);
779 textActor->SetOrientation (orientation);
782 rens_->InitTraversal ();
784 for ( vtkRenderer* renderer = rens_->GetNextItem ();
786 renderer = rens_->GetNextItem (), ++i)
788 if (viewport == 0 || viewport == i)
790 renderer->AddActor (textActor);
791 const std::string uid = tid + std::string (i,
'*');
792 (*shape_actor_map_)[uid] = textActor;
800 template <
typename Po
intNT>
bool
803 int level,
float scale,
const std::string &
id,
int viewport)
805 return (addPointCloudNormals<PointNT, PointNT> (cloud, cloud, level, scale,
id, viewport));
809 template <
typename Po
intT,
typename Po
intNT>
bool
813 int level,
float scale,
814 const std::string &
id,
int viewport)
816 if (normals->
size () != cloud->
size ())
818 PCL_ERROR (
"[addPointCloudNormals] The number of points differs from the number of normals!\n");
822 if (normals->
empty ())
824 PCL_WARN (
"[addPointCloudNormals] An empty normal cloud is given! Nothing to display.\n");
830 PCL_WARN (
"[addPointCloudNormals] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
837 points->SetDataTypeToFloat ();
839 data->SetNumberOfComponents (3);
842 vtkIdType nr_normals = 0;
843 float* pts =
nullptr;
848 vtkIdType point_step =
static_cast<vtkIdType
> (sqrt (
double (level)));
849 nr_normals = (
static_cast<vtkIdType
> ((cloud->
width - 1)/ point_step) + 1) *
850 (
static_cast<vtkIdType
> ((cloud->
height - 1) / point_step) + 1);
851 pts =
new float[2 * nr_normals * 3];
853 vtkIdType cell_count = 0;
854 for (vtkIdType y = 0; y < normals->
height; y += point_step)
855 for (vtkIdType x = 0; x < normals->
width; x += point_step)
857 PointT p = (*cloud)(x, y);
858 p.x += (*normals)(x, y).normal[0] * scale;
859 p.y += (*normals)(x, y).normal[1] * scale;
860 p.z += (*normals)(x, y).normal[2] * scale;
862 pts[2 * cell_count * 3 + 0] = (*cloud)(x, y).x;
863 pts[2 * cell_count * 3 + 1] = (*cloud)(x, y).y;
864 pts[2 * cell_count * 3 + 2] = (*cloud)(x, y).z;
865 pts[2 * cell_count * 3 + 3] = p.x;
866 pts[2 * cell_count * 3 + 4] = p.y;
867 pts[2 * cell_count * 3 + 5] = p.z;
869 lines->InsertNextCell (2);
870 lines->InsertCellPoint (2 * cell_count);
871 lines->InsertCellPoint (2 * cell_count + 1);
877 nr_normals = (cloud->
size () - 1) / level + 1 ;
878 pts =
new float[2 * nr_normals * 3];
880 for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level)
883 p.x += (*normals)[i].normal[0] * scale;
884 p.y += (*normals)[i].normal[1] * scale;
885 p.z += (*normals)[i].normal[2] * scale;
887 pts[2 * j * 3 + 0] = (*cloud)[i].x;
888 pts[2 * j * 3 + 1] = (*cloud)[i].y;
889 pts[2 * j * 3 + 2] = (*cloud)[i].z;
890 pts[2 * j * 3 + 3] = p.x;
891 pts[2 * j * 3 + 4] = p.y;
892 pts[2 * j * 3 + 5] = p.z;
894 lines->InsertNextCell (2);
895 lines->InsertCellPoint (2 * j);
896 lines->InsertCellPoint (2 * j + 1);
900 data->SetArray (&pts[0], 2 * nr_normals * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
901 points->SetData (data);
904 polyData->SetPoints (points);
905 polyData->SetLines (lines);
908 mapper->SetInputData (polyData);
909 mapper->SetColorModeToMapScalars();
910 mapper->SetScalarModeToUsePointData();
914 actor->SetMapper (mapper);
919 actor->SetUserMatrix (transformation);
922 addActorToRenderer (actor, viewport);
925 (*cloud_actor_map_)[id].actor = actor;
930 template <
typename Po
intNT>
bool
934 int level,
float scale,
935 const std::string &
id,
int viewport)
937 return (addPointCloudPrincipalCurvatures<PointNT, PointNT> (cloud, cloud, pcs, level, scale,
id, viewport));
941 template <
typename Po
intT,
typename Po
intNT>
bool
946 int level,
float scale,
947 const std::string &
id,
int viewport)
951 pcl::console::print_error (
"[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
957 PCL_WARN (
"[addPointCloudPrincipalCurvatures] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
965 unsigned char green[3] = {0, 255, 0};
966 unsigned char blue[3] = {0, 0, 255};
970 line_1_colors->SetNumberOfComponents (3);
971 line_1_colors->SetName (
"Colors");
973 line_2_colors->SetNumberOfComponents (3);
974 line_2_colors->SetName (
"Colors");
977 for (std::size_t i = 0; i < cloud->
size (); i+=level)
980 p.x += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[0]) * scale;
981 p.y += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[1]) * scale;
982 p.z += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[2]) * scale;
985 line_1->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
986 line_1->SetPoint2 (p.x, p.y, p.z);
988 polydata_1->AddInputData (line_1->GetOutput ());
989 line_1_colors->InsertNextTupleValue (green);
991 polydata_1->Update ();
993 line_1_data->GetCellData ()->SetScalars (line_1_colors);
996 for (std::size_t i = 0; i < cloud->
size (); i += level)
998 Eigen::Vector3f pc ((*pcs)[i].principal_curvature[0],
999 (*pcs)[i].principal_curvature[1],
1000 (*pcs)[i].principal_curvature[2]);
1001 Eigen::Vector3f normal ((*normals)[i].normal[0],
1002 (*normals)[i].normal[1],
1003 (*normals)[i].normal[2]);
1004 Eigen::Vector3f pc_c = pc.cross (normal);
1007 p.x += ((*pcs)[i].pc2 * pc_c[0]) * scale;
1008 p.y += ((*pcs)[i].pc2 * pc_c[1]) * scale;
1009 p.z += ((*pcs)[i].pc2 * pc_c[2]) * scale;
1012 line_2->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
1013 line_2->SetPoint2 (p.x, p.y, p.z);
1015 polydata_2->AddInputData (line_2->GetOutput ());
1017 line_2_colors->InsertNextTupleValue (blue);
1019 polydata_2->Update ();
1021 line_2_data->GetCellData ()->SetScalars (line_2_colors);
1025 alldata->AddInputData (line_1_data);
1026 alldata->AddInputData (line_2_data);
1030 createActorFromVTKDataSet (alldata->GetOutput (), actor);
1031 actor->GetMapper ()->SetScalarModeToUseCellData ();
1034 addActorToRenderer (actor, viewport);
1039 (*cloud_actor_map_)[id] = act;
1044 template <
typename Po
intT,
typename GradientT>
bool
1048 int level,
double scale,
1049 const std::string &
id,
int viewport)
1051 if (gradients->
size () != cloud->
size ())
1053 PCL_ERROR (
"[addPointCloudGradients] The number of points differs from the number of gradients!\n");
1058 PCL_WARN (
"[addPointCloudGradients] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
1065 points->SetDataTypeToFloat ();
1067 data->SetNumberOfComponents (3);
1069 vtkIdType nr_gradients = (cloud->
size () - 1) / level + 1 ;
1070 float* pts =
new float[2 * nr_gradients * 3];
1072 for (vtkIdType i = 0, j = 0; j < nr_gradients; j++, i = j * level)
1075 p.x += (*gradients)[i].gradient[0] * scale;
1076 p.y += (*gradients)[i].gradient[1] * scale;
1077 p.z += (*gradients)[i].gradient[2] * scale;
1079 pts[2 * j * 3 + 0] = (*cloud)[i].x;
1080 pts[2 * j * 3 + 1] = (*cloud)[i].y;
1081 pts[2 * j * 3 + 2] = (*cloud)[i].z;
1082 pts[2 * j * 3 + 3] = p.x;
1083 pts[2 * j * 3 + 4] = p.y;
1084 pts[2 * j * 3 + 5] = p.z;
1086 lines->InsertNextCell(2);
1087 lines->InsertCellPoint(2*j);
1088 lines->InsertCellPoint(2*j+1);
1091 data->SetArray (&pts[0], 2 * nr_gradients * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
1092 points->SetData (data);
1095 polyData->SetPoints(points);
1096 polyData->SetLines(lines);
1099 mapper->SetInputData (polyData);
1100 mapper->SetColorModeToMapScalars();
1101 mapper->SetScalarModeToUsePointData();
1105 actor->SetMapper (mapper);
1108 addActorToRenderer (actor, viewport);
1111 (*cloud_actor_map_)[id].actor = actor;
1116 template <
typename Po
intT>
bool
1120 const std::vector<int> &correspondences,
1121 const std::string &
id,
1125 corrs.resize (correspondences.size ());
1127 std::size_t index = 0;
1128 for (
auto &corr : corrs)
1130 corr.index_query = index;
1131 corr.index_match = correspondences[index];
1135 return (addCorrespondences<PointT> (source_points, target_points, corrs,
id, viewport));
1139 template <
typename Po
intT>
bool
1145 const std::string &
id,
1149 if (correspondences.empty ())
1151 PCL_DEBUG (
"[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
1156 ShapeActorMap::iterator am_it = shape_actor_map_->find (
id);
1157 if (am_it != shape_actor_map_->end () && !overwrite)
1159 PCL_WARN (
"[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
1162 if (am_it == shape_actor_map_->end () && overwrite)
1167 int n_corr = int (correspondences.size () / nth);
1172 line_colors->SetNumberOfComponents (3);
1173 line_colors->SetName (
"Colors");
1174 line_colors->SetNumberOfTuples (n_corr);
1178 line_points->SetNumberOfPoints (2 * n_corr);
1181 line_cells_id->SetNumberOfComponents (3);
1182 line_cells_id->SetNumberOfTuples (n_corr);
1183 vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
1187 line_tcoords->SetNumberOfComponents (1);
1188 line_tcoords->SetNumberOfTuples (n_corr * 2);
1189 line_tcoords->SetName (
"Texture Coordinates");
1191 double tc[3] = {0.0, 0.0, 0.0};
1193 Eigen::Affine3f source_transformation;
1195 source_transformation.translation () = source_points->
sensor_origin_.head (3);
1196 Eigen::Affine3f target_transformation;
1198 target_transformation.translation () = target_points->
sensor_origin_.head (3);
1202 for (std::size_t i = 0; i < correspondences.size (); i += nth, ++j)
1204 if (correspondences[i].index_match == -1)
1206 PCL_WARN (
"[addCorrespondences] No valid index_match for correspondence %d\n", i);
1210 PointT p_src ((*source_points)[correspondences[i].index_query]);
1211 PointT p_tgt ((*target_points)[correspondences[i].index_match]);
1213 p_src.getVector3fMap () = source_transformation * p_src.getVector3fMap ();
1214 p_tgt.getVector3fMap () = target_transformation * p_tgt.getVector3fMap ();
1216 int id1 = j * 2 + 0, id2 = j * 2 + 1;
1218 line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
1219 line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
1221 *line_cell_id++ = 2;
1222 *line_cell_id++ = id1;
1223 *line_cell_id++ = id2;
1225 tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
1226 tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
1229 rgb[0] = vtkMath::Random (32, 255);
1230 rgb[1] = vtkMath::Random (32, 255);
1231 rgb[2] = vtkMath::Random (32, 255);
1232 line_colors->InsertTuple (i, rgb);
1234 line_colors->SetNumberOfTuples (j);
1235 line_cells_id->SetNumberOfTuples (j);
1236 line_cells->SetCells (n_corr, line_cells_id);
1237 line_points->SetNumberOfPoints (j*2);
1238 line_tcoords->SetNumberOfTuples (j*2);
1241 line_data->SetPoints (line_points);
1242 line_data->SetLines (line_cells);
1243 line_data->GetPointData ()->SetTCoords (line_tcoords);
1244 line_data->GetCellData ()->SetScalars (line_colors);
1250 createActorFromVTKDataSet (line_data, actor);
1251 actor->GetProperty ()->SetRepresentationToWireframe ();
1252 actor->GetProperty ()->SetOpacity (0.5);
1253 addActorToRenderer (actor, viewport);
1256 (*shape_actor_map_)[id] = actor;
1264 reinterpret_cast<vtkPolyDataMapper*
> (actor->GetMapper ())->SetInputData (line_data);
1271 template <
typename Po
intT>
bool
1277 const std::string &
id,
1280 return (addCorrespondences<PointT> (source_points, target_points, correspondences, nth,
id, viewport,
true));
1284 template <
typename Po
intT>
bool
1285 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1288 const std::string &
id,
1290 const Eigen::Vector4f& sensor_origin,
1291 const Eigen::Quaternion<float>& sensor_orientation)
1295 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.
getName ().c_str ());
1301 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.
getName ().c_str ());
1308 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1312 bool has_colors =
false;
1314 if (
auto scalars = color_handler.
getColor ())
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;
1337 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1338 cloud_actor.viewpoint_transformation_ = transformation;
1339 cloud_actor.actor->SetUserMatrix (transformation);
1340 cloud_actor.actor->Modified ();
1346 template <
typename Po
intT>
bool
1347 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1348 const PointCloudGeometryHandler<PointT> &geometry_handler,
1349 const ColorHandlerConstPtr &color_handler,
1350 const std::string &
id,
1352 const Eigen::Vector4f& sensor_origin,
1353 const Eigen::Quaternion<float>& sensor_orientation)
1355 if (!geometry_handler.isCapable ())
1357 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler.getName ().c_str ());
1361 if (!color_handler->isCapable ())
1363 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler->getName ().c_str ());
1370 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
1374 bool has_colors =
false;
1376 if (
auto scalars = color_handler->getColor ())
1378 polydata->GetPointData ()->SetScalars (scalars);
1379 scalars->GetRange (minmax);
1385 createActorFromVTKDataSet (polydata, actor);
1387 actor->GetMapper ()->SetScalarRange (minmax);
1390 addActorToRenderer (actor, viewport);
1393 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1394 cloud_actor.actor = actor;
1395 cloud_actor.cells = initcells;
1396 cloud_actor.color_handlers.push_back (color_handler);
1400 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1401 cloud_actor.viewpoint_transformation_ = transformation;
1402 cloud_actor.actor->SetUserMatrix (transformation);
1403 cloud_actor.actor->Modified ();
1409 template <
typename Po
intT>
bool
1410 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
1411 const GeometryHandlerConstPtr &geometry_handler,
1412 const PointCloudColorHandler<PointT> &color_handler,
1413 const std::string &
id,
1415 const Eigen::Vector4f& sensor_origin,
1416 const Eigen::Quaternion<float>& sensor_orientation)
1418 if (!geometry_handler->isCapable ())
1420 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n",
id.c_str (), geometry_handler->getName ().c_str ());
1424 if (!color_handler.isCapable ())
1426 PCL_WARN (
"[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n",
id.c_str (), color_handler.getName ().c_str ());
1433 convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
1437 bool has_colors =
false;
1439 if (
auto scalars = color_handler.getColor ())
1441 polydata->GetPointData ()->SetScalars (scalars);
1442 scalars->GetRange (minmax);
1448 createActorFromVTKDataSet (polydata, actor);
1450 actor->GetMapper ()->SetScalarRange (minmax);
1453 addActorToRenderer (actor, viewport);
1456 CloudActor& cloud_actor = (*cloud_actor_map_)[id];
1457 cloud_actor.actor = actor;
1458 cloud_actor.cells = initcells;
1459 cloud_actor.geometry_handlers.push_back (geometry_handler);
1463 convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
1464 cloud_actor.viewpoint_transformation_ = transformation;
1465 cloud_actor.actor->SetUserMatrix (transformation);
1466 cloud_actor.actor->Modified ();
1472 template <
typename Po
intT>
bool
1474 const std::string &
id)
1477 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1479 if (am_it == cloud_actor_map_->end ())
1486 convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
1490 polydata->GetPointData ()->SetScalars (scalars);
1492 minmax[0] = std::numeric_limits<double>::min ();
1493 minmax[1] = std::numeric_limits<double>::max ();
1494 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1495 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1497 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1500 reinterpret_cast<vtkPolyDataMapper*
> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1505 template <
typename Po
intT>
bool
1508 const std::string &
id)
1511 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1513 if (am_it == cloud_actor_map_->end ())
1520 convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
1524 polydata->GetPointData ()->SetScalars (scalars);
1526 minmax[0] = std::numeric_limits<double>::min ();
1527 minmax[1] = std::numeric_limits<double>::max ();
1528 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1529 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1531 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1534 reinterpret_cast<vtkPolyDataMapper*
> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1540 template <
typename Po
intT>
bool
1543 const std::string &
id)
1546 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1548 if (am_it == cloud_actor_map_->end ())
1556 convertPointCloudToVTKPolyData<PointT>(cloud, polydata, am_it->second.cells);
1559 bool has_colors =
false;
1561 if (
auto scalars = color_handler.
getColor ())
1564 polydata->GetPointData ()->SetScalars (scalars);
1565 scalars->GetRange (minmax);
1569 #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2
1570 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
1574 am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
1577 reinterpret_cast<vtkPolyDataMapper*
> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
1582 template <
typename Po
intT>
bool
1585 const std::vector<pcl::Vertices> &vertices,
1586 const std::string &
id,
1589 if (vertices.empty () || cloud->
points.empty ())
1594 PCL_WARN (
"[addPolygonMesh] The id <%s> already exists! Please choose a different id and retry.\n",
id.c_str ());
1599 std::vector<pcl::PCLPointField> fields;
1601 rgb_idx = pcl::getFieldIndex<PointT> (
"rgb", fields);
1603 rgb_idx = pcl::getFieldIndex<PointT> (
"rgba", fields);
1607 colors->SetNumberOfComponents (3);
1608 colors->SetName (
"Colors");
1609 std::uint32_t offset = fields[rgb_idx].offset;
1610 for (std::size_t i = 0; i < cloud->
size (); ++i)
1614 const pcl::RGB*
const rgb_data =
reinterpret_cast<const pcl::RGB*
>(
reinterpret_cast<const char*
> (&(*cloud)[i]) + offset);
1615 unsigned char color[3];
1616 color[0] = rgb_data->r;
1617 color[1] = rgb_data->g;
1618 color[2] = rgb_data->b;
1619 colors->InsertNextTupleValue (color);
1625 vtkIdType nr_points = cloud->
size ();
1626 points->SetNumberOfPoints (nr_points);
1630 float *data =
static_cast<vtkFloatArray*
> (points->GetData ())->GetPointer (0);
1633 std::vector<int> lookup;
1637 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1638 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1642 lookup.resize (nr_points);
1644 for (vtkIdType i = 0; i < nr_points; ++i)
1650 lookup[i] =
static_cast<int> (j);
1651 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1656 points->SetNumberOfPoints (nr_points);
1660 int max_size_of_polygon = -1;
1661 for (
const auto &vertex : vertices)
1662 if (max_size_of_polygon <
static_cast<int> (vertex.vertices.size ()))
1663 max_size_of_polygon =
static_cast<int> (vertex.vertices.size ());
1665 if (vertices.size () > 1)
1669 vtkIdType *cell = cell_array->WritePointer (vertices.size (), vertices.size () * (max_size_of_polygon + 1));
1671 if (!lookup.empty ())
1673 for (std::size_t i = 0; i < vertices.size (); ++i, ++idx)
1675 std::size_t n_points = vertices[i].vertices.size ();
1678 for (std::size_t j = 0; j < n_points; j++, ++idx)
1679 *cell++ = lookup[vertices[i].vertices[j]];
1685 for (std::size_t i = 0; i < vertices.size (); ++i, ++idx)
1687 std::size_t n_points = vertices[i].vertices.size ();
1690 for (std::size_t j = 0; j < n_points; j++, ++idx)
1691 *cell++ = vertices[i].vertices[j];
1696 allocVtkPolyData (polydata);
1697 cell_array->GetData ()->SetNumberOfValues (idx);
1698 cell_array->Squeeze ();
1699 polydata->SetPolys (cell_array);
1700 polydata->SetPoints (points);
1703 polydata->GetPointData ()->SetScalars (colors);
1705 createActorFromVTKDataSet (polydata, actor,
false);
1710 std::size_t n_points = vertices[0].vertices.size ();
1711 polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
1713 if (!lookup.empty ())
1715 for (std::size_t j = 0; j < (n_points - 1); ++j)
1716 polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
1720 for (std::size_t j = 0; j < (n_points - 1); ++j)
1721 polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
1725 poly_grid->Allocate (1, 1);
1726 poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
1727 poly_grid->SetPoints (points);
1729 poly_grid->GetPointData ()->SetScalars (colors);
1731 createActorFromVTKDataSet (poly_grid, actor,
false);
1733 addActorToRenderer (actor, viewport);
1734 actor->GetProperty ()->SetRepresentationToSurface ();
1736 actor->GetProperty ()->BackfaceCullingOff ();
1737 actor->GetProperty ()->SetInterpolationToFlat ();
1738 actor->GetProperty ()->EdgeVisibilityOff ();
1739 actor->GetProperty ()->ShadingOff ();
1742 (*cloud_actor_map_)[id].actor = actor;
1747 (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
1753 template <
typename Po
intT>
bool
1756 const std::vector<pcl::Vertices> &verts,
1757 const std::string &
id)
1766 CloudActorMap::iterator am_it = cloud_actor_map_->find (
id);
1767 if (am_it == cloud_actor_map_->end ())
1779 vtkIdType nr_points = cloud->
size ();
1780 points->SetNumberOfPoints (nr_points);
1783 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
1786 std::vector<int> lookup;
1790 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
1791 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1795 lookup.resize (nr_points);
1797 for (vtkIdType i = 0; i < nr_points; ++i)
1803 lookup [i] =
static_cast<int> (j);
1804 std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
1809 points->SetNumberOfPoints (nr_points);
1813 vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
1817 std::vector<pcl::PCLPointField> fields;
1818 rgb_idx = pcl::getFieldIndex<PointT> (
"rgb", fields);
1820 rgb_idx = pcl::getFieldIndex<PointT> (
"rgba", fields);
1821 if (rgb_idx != -1 && colors)
1824 std::uint32_t offset = fields[rgb_idx].offset;
1825 for (std::size_t i = 0; i < cloud->
size (); ++i)
1829 const pcl::RGB*
const rgb_data =
reinterpret_cast<const pcl::RGB*
>(
reinterpret_cast<const char*
> (&(*cloud)[i]) + offset);
1830 unsigned char color[3];
1831 color[0] = rgb_data->r;
1832 color[1] = rgb_data->g;
1833 color[2] = rgb_data->b;
1834 colors->SetTupleValue (j++, color);
1839 int max_size_of_polygon = -1;
1840 for (
const auto &vertex : verts)
1841 if (max_size_of_polygon <
static_cast<int> (vertex.vertices.size ()))
1842 max_size_of_polygon =
static_cast<int> (vertex.vertices.size ());
1846 vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1));
1848 if (!lookup.empty ())
1850 for (std::size_t i = 0; i < verts.size (); ++i, ++idx)
1852 std::size_t n_points = verts[i].vertices.size ();
1854 for (std::size_t j = 0; j < n_points; j++, cell++, ++idx)
1855 *cell = lookup[verts[i].vertices[j]];
1860 for (std::size_t i = 0; i < verts.size (); ++i, ++idx)
1862 std::size_t n_points = verts[i].vertices.size ();
1864 for (std::size_t j = 0; j < n_points; j++, cell++, ++idx)
1865 *cell = verts[i].vertices[j];
1868 cells->GetData ()->SetNumberOfValues (idx);
1871 polydata->SetPolys (cells);
1876 #ifdef vtkGenericDataArray_h
1877 #undef SetTupleValue
1878 #undef InsertNextTupleValue
1879 #undef GetTupleValue