Loading...
Searching...
No Matches
pcl_visualizer.hpp
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2012, Open Perception, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef PCL_PCL_VISUALIZER_IMPL_H_
#define PCL_PCL_VISUALIZER_IMPL_H_
#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkCellArray.h>
#include <vtkLeaderActor2D.h>
#include <vtkVectorText.h>
#include <vtkAlgorithmOutput.h>
#include <vtkFollower.h>
#include <vtkMath.h>
#include <vtkSphereSource.h>
#include <vtkProperty2D.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPointData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkMapper.h>
#include <vtkCellData.h>
#include <vtkDataSetMapper.h>
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkAppendPolyData.h>
#include <vtkTextProperty.h>
#include <vtkLODActor.h>
#include <vtkLineSource.h>
#include <pcl/common/utils.h> // pcl::utils::ignore
#include <pcl/visualization/common/shapes.h>
// Support for VTK 7.1 upwards
#ifdef vtkGenericDataArray_h
#define SetTupleValue SetTypedTuple
#define InsertNextTupleValue InsertNextTypedTuple
#define GetTupleValue GetTypedTuple
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const std::string &id, int viewport)
{
// Convert the PointCloud to VTK PolyData
PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud);
return (addPointCloud<PointT> (cloud, geometry_handler, id, viewport));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const PointCloudGeometryHandler<PointT> &geometry_handler,
const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
if (pcl::traits::has_color<PointT>())
{
PointCloudColorHandlerRGBField<PointT> color_handler_rgb_field (cloud);
return (fromHandlersToScreen (geometry_handler, color_handler_rgb_field, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
PointCloudColorHandlerCustom<PointT> color_handler (cloud, 255, 255, 255);
return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const GeometryHandlerConstPtr &geometry_handler,
const std::string &id, int viewport)
{
if (contains (id))
{
// Here we're just pushing the handlers onto the queue. If needed, something fancier could
// be done such as checking if a specific handler already exists, etc.
auto am_it = cloud_actor_map_->find (id);
am_it->second.geometry_handlers.push_back (geometry_handler);
return (true);
}
//PointCloudColorHandlerRandom<PointT> color_handler (cloud);
PointCloudColorHandlerCustom<PointT> color_handler (cloud, 255, 255, 255);
return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const PointCloudColorHandler<PointT> &color_handler,
const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
// Here we're just pushing the handlers onto the queue. If needed, something fancier could
// be done such as checking if a specific handler already exists, etc.
//cloud_actor_map_[id].color_handlers.push_back (color_handler);
//style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_));
return (false);
}
// Convert the PointCloud to VTK PolyData
PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud);
return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const ColorHandlerConstPtr &color_handler,
const std::string &id, int viewport)
{
// Check to see if this entry already exists (has it been already added to the visualizer?)
auto am_it = cloud_actor_map_->find (id);
if (am_it != cloud_actor_map_->end ())
{
// Here we're just pushing the handlers onto the queue. If needed, something fancier could
// be done such as checking if a specific handler already exists, etc.
am_it->second.color_handlers.push_back (color_handler);
return (true);
}
PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud);
return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const GeometryHandlerConstPtr &geometry_handler,
const ColorHandlerConstPtr &color_handler,
const std::string &id, int viewport)
{
// Check to see if this entry already exists (has it been already added to the visualizer?)
auto am_it = cloud_actor_map_->find (id);
if (am_it != cloud_actor_map_->end ())
{
// Here we're just pushing the handlers onto the queue. If needed, something fancier could
// be done such as checking if a specific handler already exists, etc.
am_it->second.geometry_handlers.push_back (geometry_handler);
am_it->second.color_handlers.push_back (color_handler);
return (true);
}
return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPointCloud (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const PointCloudColorHandler<PointT> &color_handler,
const PointCloudGeometryHandler<PointT> &geometry_handler,
const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addPointCloud] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
// Here we're just pushing the handlers onto the queue. If needed, something fancier could
// be done such as checking if a specific handler already exists, etc.
//cloud_actor_map_[id].geometry_handlers.push_back (geometry_handler);
//cloud_actor_map_[id].color_handlers.push_back (color_handler);
//style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_));
return (false);
}
return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, cloud->sensor_origin_, cloud->sensor_orientation_));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
vtkSmartPointer<vtkPolyData> &polydata,
vtkSmartPointer<vtkIdTypeArray> &initcells)
{
vtkSmartPointer<vtkCellArray> vertices;
if (!polydata)
{
allocVtkPolyData (polydata);
vertices = vtkSmartPointer<vtkCellArray>::New ();
polydata->SetVerts (vertices);
}
// Create the supporting structures
vertices = polydata->GetVerts ();
if (!vertices)
vertices = vtkSmartPointer<vtkCellArray>::New ();
vtkIdType nr_points = cloud->size ();
// Create the point set
vtkSmartPointer<vtkPoints> points = polydata->GetPoints ();
if (!points)
{
points = vtkSmartPointer<vtkPoints>::New ();
points->SetDataTypeToFloat ();
polydata->SetPoints (points);
}
points->SetNumberOfPoints (nr_points);
// Get a pointer to the beginning of the data array
float *data = (dynamic_cast<vtkFloatArray*> (points->GetData ()))->GetPointer (0);
// Set the points
vtkIdType ptr = 0;
if (cloud->is_dense)
{
for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3) {
std::copy(&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
}
}
else
{
vtkIdType j = 0; // true point index
for (vtkIdType i = 0; i < nr_points; ++i)
{
// Check if the point is invalid
if (!std::isfinite ((*cloud)[i].x) ||
!std::isfinite ((*cloud)[i].y) ||
!std::isfinite ((*cloud)[i].z))
continue;
std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
j++;
ptr += 3;
}
nr_points = j;
points->SetNumberOfPoints (nr_points);
}
#ifdef VTK_CELL_ARRAY_V2
// TODO: Remove when VTK 6,7,8 is unsupported
pcl::utils::ignore(initcells);
auto numOfCells = vertices->GetNumberOfCells();
// If we have less cells than points, add new cells.
if (numOfCells < nr_points)
{
for (int i = numOfCells; i < nr_points; i++)
{
vertices->InsertNextCell(1);
vertices->InsertCellPoint(i);
}
}
// if we too many cells than points, set size (doesn't free excessive memory)
else if (numOfCells > nr_points)
{
vertices->ResizeExact(nr_points, nr_points);
}
polydata->SetPoints(points);
polydata->SetVerts(vertices);
#else
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
updateCells (cells, initcells, nr_points);
// Set the cells and the vertices
vertices->SetCells (nr_points, cells);
// Set the cell count explicitly as the array doesn't get modified enough so the above method updates accordingly. See #4001 and #3452
vertices->SetNumberOfCells(nr_points);
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
const pcl::visualization::PointCloudGeometryHandler<PointT> &geometry_handler,
vtkSmartPointer<vtkPolyData> &polydata,
vtkSmartPointer<vtkIdTypeArray> &initcells)
{
vtkSmartPointer<vtkCellArray> vertices;
if (!polydata)
{
allocVtkPolyData (polydata);
vertices = vtkSmartPointer<vtkCellArray>::New ();
polydata->SetVerts (vertices);
}
// Use the handler to obtain the geometry
vtkSmartPointer<vtkPoints> points;
geometry_handler.getGeometry (points);
polydata->SetPoints (points);
vtkIdType nr_points = points->GetNumberOfPoints ();
// Create the supporting structures
vertices = polydata->GetVerts ();
if (!vertices)
vertices = vtkSmartPointer<vtkCellArray>::New ();
#ifdef VTK_CELL_ARRAY_V2
// TODO: Remove when VTK 6,7,8 is unsupported
pcl::utils::ignore(initcells);
auto numOfCells = vertices->GetNumberOfCells();
// If we have less cells than points, add new cells.
if (numOfCells < nr_points)
{
for (int i = numOfCells; i < nr_points; i++)
{
vertices->InsertNextCell(1);
vertices->InsertCellPoint(i);
}
}
// if we too many cells than points, set size (doesn't free excessive memory)
else if (numOfCells > nr_points)
{
vertices->ResizeExact(nr_points, nr_points);
}
polydata->SetPoints(points);
polydata->SetVerts(vertices);
#else
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
updateCells (cells, initcells, nr_points);
// Set the cells and the vertices
vertices->SetCells (nr_points, cells);
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPolygon (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
double r, double g, double b, const std::string &id, int viewport)
{
vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (cloud);
if (!data)
return (false);
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = shape_actor_map_->find (id);
if (am_it != shape_actor_map_->end ())
{
vtkSmartPointer<vtkAppendPolyData> all_data = vtkSmartPointer<vtkAppendPolyData>::New ();
// Add old data
all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
// Add new data
vtkSmartPointer<vtkDataSetSurfaceFilter> surface_filter = vtkSmartPointer<vtkDataSetSurfaceFilter>::New ();
surface_filter->AddInputData (vtkUnstructuredGrid::SafeDownCast (data));
vtkSmartPointer<vtkPolyData> poly_data = surface_filter->GetOutput ();
all_data->AddInputData (poly_data);
// Create an Actor
vtkSmartPointer<vtkActor> actor;
createActorFromVTKDataSet (all_data->GetOutput (), actor);
actor->GetProperty ()->SetRepresentationToWireframe ();
actor->GetProperty ()->SetColor (r, g, b);
actor->GetMapper ()->ScalarVisibilityOff ();
removeActorFromRenderer (am_it->second, viewport);
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
}
else
{
// Create an Actor
vtkSmartPointer<vtkActor> actor;
createActorFromVTKDataSet (data, actor);
actor->GetProperty ()->SetRepresentationToWireframe ();
actor->GetProperty ()->SetColor (r, g, b);
actor->GetMapper ()->ScalarVisibilityOff ();
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
}
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPolygon (
const pcl::PlanarPolygon<PointT> &polygon,
double r, double g, double b, const std::string &id, int viewport)
{
vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (polygon);
if (!data)
return (false);
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = shape_actor_map_->find (id);
if (am_it != shape_actor_map_->end ())
{
vtkSmartPointer<vtkAppendPolyData> all_data = vtkSmartPointer<vtkAppendPolyData>::New ();
// Add old data
all_data->AddInputData (reinterpret_cast<vtkPolyDataMapper*> ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ());
// Add new data
vtkSmartPointer<vtkDataSetSurfaceFilter> surface_filter = vtkSmartPointer<vtkDataSetSurfaceFilter>::New ();
surface_filter->SetInputData (vtkUnstructuredGrid::SafeDownCast (data));
vtkSmartPointer<vtkPolyData> poly_data = surface_filter->GetOutput ();
all_data->AddInputData (poly_data);
// Create an Actor
vtkSmartPointer<vtkActor> actor;
createActorFromVTKDataSet (all_data->GetOutput (), actor);
actor->GetProperty ()->SetRepresentationToWireframe ();
actor->GetProperty ()->SetColor (r, g, b);
actor->GetMapper ()->ScalarVisibilityOn ();
actor->GetProperty ()->BackfaceCullingOff ();
removeActorFromRenderer (am_it->second, viewport);
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
}
else
{
// Create an Actor
vtkSmartPointer<vtkActor> actor;
createActorFromVTKDataSet (data, actor);
actor->GetProperty ()->SetRepresentationToWireframe ();
actor->GetProperty ()->SetColor (r, g, b);
actor->GetMapper ()->ScalarVisibilityOn ();
actor->GetProperty ()->BackfaceCullingOff ();
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
}
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPolygon (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const std::string &id, int viewport)
{
return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5, id, viewport));
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename P1, typename P2> bool
pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addLine] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
vtkSmartPointer<vtkDataSet> data = createLine (pt1.getVector4fMap (), pt2.getVector4fMap ());
// Create an Actor
vtkSmartPointer<vtkLODActor> actor;
createActorFromVTKDataSet (data, actor);
actor->GetProperty ()->SetRepresentationToWireframe ();
actor->GetProperty ()->SetColor (r, g, b);
actor->GetMapper ()->ScalarVisibilityOff ();
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename P1, typename P2> bool
pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
// Create an Actor
vtkSmartPointer<vtkLeaderActor2D> leader = vtkSmartPointer<vtkLeaderActor2D>::New ();
leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
leader->SetArrowStyleToFilled ();
leader->AutoLabelOn ();
leader->GetProperty ()->SetColor (r, g, b);
addActorToRenderer (leader, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = leader;
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename P1, typename P2> bool
pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, bool display_length, const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
// Create an Actor
vtkSmartPointer<vtkLeaderActor2D> leader = vtkSmartPointer<vtkLeaderActor2D>::New ();
leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
leader->SetArrowStyleToFilled ();
leader->SetArrowPlacementToPoint1 ();
if (display_length)
leader->AutoLabelOn ();
else
leader->AutoLabelOff ();
leader->GetProperty ()->SetColor (r, g, b);
addActorToRenderer (leader, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = leader;
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename P1, typename P2> bool
pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2,
double r_line, double g_line, double b_line,
double r_text, double g_text, double b_text,
const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addArrow] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
// Create an Actor
vtkSmartPointer<vtkLeaderActor2D> leader = vtkSmartPointer<vtkLeaderActor2D>::New ();
leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld ();
leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z);
leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld ();
leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z);
leader->SetArrowStyleToFilled ();
leader->AutoLabelOn ();
leader->GetLabelTextProperty()->SetColor(r_text, g_text, b_text);
leader->GetProperty ()->SetColor (r_line, g_line, b_line);
addActorToRenderer (leader, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = leader;
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename P1, typename P2> bool
pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, const std::string &id, int viewport)
{
return (!addLine (pt1, pt2, 0.5, 0.5, 0.5, id, viewport));
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addSphere (const PointT &center, double radius, double r, double g, double b, const std::string &id, int viewport)
{
if (contains (id))
{
PCL_WARN ("[addSphere] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
vtkSmartPointer<vtkSphereSource> data = vtkSmartPointer<vtkSphereSource>::New ();
data->SetRadius (radius);
data->SetCenter (static_cast<double>(center.x), static_cast<double>(center.y), static_cast<double>(center.z));
data->SetPhiResolution (10);
data->SetThetaResolution (10);
data->LatLongTessellationOff ();
data->Update ();
// Setup actor and mapper
vtkSmartPointer <vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
mapper->SetInputConnection (data->GetOutputPort ());
// Create an Actor
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New ();
actor->SetMapper (mapper);
//createActorFromVTKDataSet (data, actor);
actor->GetProperty ()->SetRepresentationToSurface ();
actor->GetProperty ()->SetInterpolationToFlat ();
actor->GetProperty ()->SetColor (r, g, b);
actor->GetMapper ()->StaticOn ();
actor->GetMapper ()->ScalarVisibilityOff ();
actor->GetMapper ()->Update ();
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
return (true);
}
////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addSphere (const PointT &center, double radius, const std::string &id, int viewport)
{
return (addSphere (center, radius, 0.5, 0.5, 0.5, id, viewport));
}
////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT> bool
pcl::visualization::PCLVisualizer::updateSphere (const PointT &center, double radius, double r, double g, double b, const std::string &id)
{
if (!contains (id))
{
return (false);
}
//////////////////////////////////////////////////////////////////////////
// Get the actor pointer
auto am_it = shape_actor_map_->find (id);
vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
if (!actor)
return (false);
vtkAlgorithm *algo = actor->GetMapper ()->GetInputAlgorithm ();
vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo);
if (!src)
return (false);
src->SetCenter (double (center.x), double (center.y), double (center.z));
src->SetRadius (radius);
src->Update ();
actor->GetProperty ()->SetColor (r, g, b);
actor->Modified ();
return (true);
}
//////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addText3D (
const std::string &text,
const PointT& position,
double textScale,
double r,
double g,
double b,
const std::string &id,
int viewport)
{
std::string tid;
if (id.empty ())
tid = text;
else
tid = id;
if (viewport < 0)
return false;
// If there is no custom viewport and the viewport number is not 0, exit
if (rens_->GetNumberOfItems () <= viewport)
{
PCL_ERROR ("[addText3D] The viewport [%d] doesn't exist (id <%s>)! \n",
viewport,
tid.c_str ());
return false;
}
// check all or an individual viewport for a similar id
rens_->InitTraversal ();
for (std::size_t i = viewport; rens_->GetNextItem (); ++i)
{
const std::string uid = tid + std::string (i, '*');
if (contains (uid))
{
PCL_ERROR ( "[addText3D] The id <%s> already exists in viewport [%d]! \n"
"Please choose a different id and retry.\n",
tid.c_str (),
i);
return false;
}
if (viewport > 0)
break;
}
vtkSmartPointer<vtkVectorText> textSource = vtkSmartPointer<vtkVectorText>::New ();
textSource->SetText (text.c_str());
textSource->Update ();
vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
textMapper->SetInputConnection (textSource->GetOutputPort ());
// Since each follower may follow a different camera, we need different followers
rens_->InitTraversal ();
vtkRenderer* renderer;
int i = 0;
while ((renderer = rens_->GetNextItem ()))
{
// Should we add the actor to all renderers or just to i-nth renderer?
if (viewport == 0 || viewport == i)
{
vtkSmartPointer<vtkFollower> textActor = vtkSmartPointer<vtkFollower>::New ();
textActor->SetMapper (textMapper);
textActor->SetPosition (position.x, position.y, position.z);
textActor->SetScale (textScale);
textActor->GetProperty ()->SetColor (r, g, b);
textActor->SetCamera (renderer->GetActiveCamera ());
renderer->AddActor (textActor);
// Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers
// for multiple viewport
const std::string uid = tid + std::string (i, '*');
(*shape_actor_map_)[uid] = textActor;
}
++i;
}
return (true);
}
//////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addText3D (
const std::string &text,
const PointT& position,
double orientation[3],
double textScale,
double r,
double g,
double b,
const std::string &id,
int viewport)
{
std::string tid;
if (id.empty ())
tid = text;
else
tid = id;
if (viewport < 0)
return false;
// If there is no custom viewport and the viewport number is not 0, exit
if (rens_->GetNumberOfItems () <= viewport)
{
PCL_ERROR ("[addText3D] The viewport [%d] doesn't exist (id <%s>)!\n",
viewport,
tid.c_str ());
return false;
}
// check all or an individual viewport for a similar id
rens_->InitTraversal ();
for (std::size_t i = viewport; rens_->GetNextItem (); ++i)
{
const std::string uid = tid + std::string (i, '*');
if (contains (uid))
{
PCL_ERROR ( "[addText3D] The id <%s> already exists in viewport [%d]! "
"Please choose a different id and retry.\n",
tid.c_str (),
i);
return false;
}
if (viewport > 0)
break;
}
vtkSmartPointer<vtkVectorText> textSource = vtkSmartPointer<vtkVectorText>::New ();
textSource->SetText (text.c_str());
textSource->Update ();
vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
textMapper->SetInputConnection (textSource->GetOutputPort ());
vtkSmartPointer<vtkActor> textActor = vtkSmartPointer<vtkActor>::New ();
textActor->SetMapper (textMapper);
textActor->SetPosition (position.x, position.y, position.z);
textActor->SetScale (textScale);
textActor->GetProperty ()->SetColor (r, g, b);
textActor->SetOrientation (orientation);
// Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers
rens_->InitTraversal ();
int i = 0;
for ( vtkRenderer* renderer = rens_->GetNextItem ();
renderer;
renderer = rens_->GetNextItem (), ++i)
{
if (viewport == 0 || viewport == i)
{
renderer->AddActor (textActor);
const std::string uid = tid + std::string (i, '*');
(*shape_actor_map_)[uid] = textActor;
}
}
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT> bool
pcl::visualization::PCLVisualizer::addPointCloudNormals (
const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
int level, float scale, const std::string &id, int viewport)
{
return (addPointCloudNormals<PointNT, PointNT> (cloud, cloud, level, scale, id, viewport));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename PointNT> bool
pcl::visualization::PCLVisualizer::addPointCloudNormals (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
int level, float scale,
const std::string &id, int viewport)
{
if (normals->size () != cloud->size ())
{
PCL_ERROR ("[addPointCloudNormals] The number of points differs from the number of normals!\n");
return (false);
}
if (normals->empty ())
{
PCL_WARN ("[addPointCloudNormals] An empty normal cloud is given! Nothing to display.\n");
return (false);
}
if (contains (id))
{
PCL_WARN ("[addPointCloudNormals] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
points->SetDataTypeToFloat ();
vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New ();
data->SetNumberOfComponents (3);
vtkIdType nr_normals = 0;
float* pts = nullptr;
// If the cloud is organized, then distribute the normal step in both directions
if (cloud->isOrganized () && normals->isOrganized ())
{
auto point_step = static_cast<vtkIdType> (sqrt (static_cast<double>(level)));
nr_normals = (static_cast<vtkIdType> ((cloud->width - 1)/ point_step) + 1) *
(static_cast<vtkIdType> ((cloud->height - 1) / point_step) + 1);
pts = new float[2 * nr_normals * 3];
vtkIdType cell_count = 0;
for (vtkIdType y = 0; y < normals->height; y += point_step)
for (vtkIdType x = 0; x < normals->width; x += point_step)
{
PointT p = (*cloud)(x, y);
if (!pcl::isFinite(p) || !pcl::isNormalFinite((*normals)(x, y)))
continue;
p.x += (*normals)(x, y).normal[0] * scale;
p.y += (*normals)(x, y).normal[1] * scale;
p.z += (*normals)(x, y).normal[2] * scale;
pts[2 * cell_count * 3 + 0] = (*cloud)(x, y).x;
pts[2 * cell_count * 3 + 1] = (*cloud)(x, y).y;
pts[2 * cell_count * 3 + 2] = (*cloud)(x, y).z;
pts[2 * cell_count * 3 + 3] = p.x;
pts[2 * cell_count * 3 + 4] = p.y;
pts[2 * cell_count * 3 + 5] = p.z;
lines->InsertNextCell (2);
lines->InsertCellPoint (2 * cell_count);
lines->InsertCellPoint (2 * cell_count + 1);
cell_count ++;
}
}
else
{
nr_normals = (cloud->size () - 1) / level + 1 ;
pts = new float[2 * nr_normals * 3];
for (vtkIdType i = 0, j = 0; (j < nr_normals) && (i < static_cast<vtkIdType>(cloud->size())); i += level)
{
if (!pcl::isFinite((*cloud)[i]) || !pcl::isNormalFinite((*normals)[i]))
continue;
PointT p = (*cloud)[i];
p.x += (*normals)[i].normal[0] * scale;
p.y += (*normals)[i].normal[1] * scale;
p.z += (*normals)[i].normal[2] * scale;
pts[2 * j * 3 + 0] = (*cloud)[i].x;
pts[2 * j * 3 + 1] = (*cloud)[i].y;
pts[2 * j * 3 + 2] = (*cloud)[i].z;
pts[2 * j * 3 + 3] = p.x;
pts[2 * j * 3 + 4] = p.y;
pts[2 * j * 3 + 5] = p.z;
lines->InsertNextCell (2);
lines->InsertCellPoint (2 * j);
lines->InsertCellPoint (2 * j + 1);
++j;
}
}
data->SetArray (&pts[0], 2 * nr_normals * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
points->SetData (data);
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints (points);
polyData->SetLines (lines);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New ();
mapper->SetInputData (polyData);
mapper->SetColorModeToMapScalars();
mapper->SetScalarModeToUsePointData();
// create actor
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New ();
actor->SetMapper (mapper);
// Use cloud view point info
vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New ();
convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
actor->SetUserMatrix (transformation);
// Add it to all renderers
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*cloud_actor_map_)[id].actor = actor;
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointNT> bool
pcl::visualization::PCLVisualizer::addPointCloudPrincipalCurvatures (
const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
const pcl::PointCloud<pcl::PrincipalCurvatures>::ConstPtr &pcs,
int level, float scale,
const std::string &id, int viewport)
{
return (addPointCloudPrincipalCurvatures<PointNT, PointNT> (cloud, cloud, pcs, level, scale, id, viewport));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename PointNT> bool
pcl::visualization::PCLVisualizer::addPointCloudPrincipalCurvatures (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
const pcl::PointCloud<pcl::PrincipalCurvatures>::ConstPtr &pcs,
int level, float scale,
const std::string &id, int viewport)
{
if (pcs->size () != cloud->size () || normals->size () != cloud->size ())
{
pcl::console::print_error ("[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
return (false);
}
if (contains (id))
{
PCL_WARN ("[addPointCloudPrincipalCurvatures] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
vtkSmartPointer<vtkAppendPolyData> polydata_1 = vtkSmartPointer<vtkAppendPolyData>::New ();
vtkSmartPointer<vtkAppendPolyData> polydata_2 = vtkSmartPointer<vtkAppendPolyData>::New ();
// Setup two colors - one for each line
unsigned char green[3] = {0, 255, 0};
unsigned char blue[3] = {0, 0, 255};
// Setup the colors array
vtkSmartPointer<vtkUnsignedCharArray> line_1_colors =vtkSmartPointer<vtkUnsignedCharArray>::New ();
line_1_colors->SetNumberOfComponents (3);
line_1_colors->SetName ("Colors");
vtkSmartPointer<vtkUnsignedCharArray> line_2_colors =vtkSmartPointer<vtkUnsignedCharArray>::New ();
line_2_colors->SetNumberOfComponents (3);
line_2_colors->SetName ("Colors");
// Create the first sets of lines
for (std::size_t i = 0; i < cloud->size (); i+=level)
{
PointT p = (*cloud)[i];
p.x += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[0]) * scale;
p.y += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[1]) * scale;
p.z += ((*pcs)[i].pc1 * (*pcs)[i].principal_curvature[2]) * scale;
vtkSmartPointer<vtkLineSource> line_1 = vtkSmartPointer<vtkLineSource>::New ();
line_1->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
line_1->SetPoint2 (p.x, p.y, p.z);
line_1->Update ();
polydata_1->AddInputData (line_1->GetOutput ());
line_1_colors->InsertNextTupleValue (green);
}
polydata_1->Update ();
vtkSmartPointer<vtkPolyData> line_1_data = polydata_1->GetOutput ();
line_1_data->GetCellData ()->SetScalars (line_1_colors);
// Create the second sets of lines
for (std::size_t i = 0; i < cloud->size (); i += level)
{
Eigen::Vector3f pc ((*pcs)[i].principal_curvature[0],
(*pcs)[i].principal_curvature[1],
(*pcs)[i].principal_curvature[2]);
Eigen::Vector3f normal ((*normals)[i].normal[0],
(*normals)[i].normal[1],
(*normals)[i].normal[2]);
Eigen::Vector3f pc_c = pc.cross (normal);
PointT p = (*cloud)[i];
p.x += ((*pcs)[i].pc2 * pc_c[0]) * scale;
p.y += ((*pcs)[i].pc2 * pc_c[1]) * scale;
p.z += ((*pcs)[i].pc2 * pc_c[2]) * scale;
vtkSmartPointer<vtkLineSource> line_2 = vtkSmartPointer<vtkLineSource>::New ();
line_2->SetPoint1 ((*cloud)[i].x, (*cloud)[i].y, (*cloud)[i].z);
line_2->SetPoint2 (p.x, p.y, p.z);
line_2->Update ();
polydata_2->AddInputData (line_2->GetOutput ());
line_2_colors->InsertNextTupleValue (blue);
}
polydata_2->Update ();
vtkSmartPointer<vtkPolyData> line_2_data = polydata_2->GetOutput ();
line_2_data->GetCellData ()->SetScalars (line_2_colors);
// Assemble the two sets of lines
vtkSmartPointer<vtkAppendPolyData> alldata = vtkSmartPointer<vtkAppendPolyData>::New ();
alldata->AddInputData (line_1_data);
alldata->AddInputData (line_2_data);
alldata->Update ();
// Create an Actor
vtkSmartPointer<vtkLODActor> actor;
createActorFromVTKDataSet (alldata->GetOutput (), actor);
actor->GetMapper ()->SetScalarModeToUseCellData ();
// Add it to all renderers
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
CloudActor act;
act.actor = actor;
(*cloud_actor_map_)[id] = act;
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename GradientT> bool
pcl::visualization::PCLVisualizer::addPointCloudIntensityGradients (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const typename pcl::PointCloud<GradientT>::ConstPtr &gradients,
int level, double scale,
const std::string &id, int viewport)
{
if (gradients->size () != cloud->size ())
{
PCL_ERROR ("[addPointCloudGradients] The number of points differs from the number of gradients!\n");
return (false);
}
if (contains (id))
{
PCL_WARN ("[addPointCloudGradients] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
points->SetDataTypeToFloat ();
vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New ();
data->SetNumberOfComponents (3);
vtkIdType nr_gradients = (cloud->size () - 1) / level + 1 ;
float* pts = new float[2 * nr_gradients * 3];
for (vtkIdType i = 0, j = 0; j < nr_gradients; j++, i = j * level)
{
PointT p = (*cloud)[i];
p.x += (*gradients)[i].gradient[0] * scale;
p.y += (*gradients)[i].gradient[1] * scale;
p.z += (*gradients)[i].gradient[2] * scale;
pts[2 * j * 3 + 0] = (*cloud)[i].x;
pts[2 * j * 3 + 1] = (*cloud)[i].y;
pts[2 * j * 3 + 2] = (*cloud)[i].z;
pts[2 * j * 3 + 3] = p.x;
pts[2 * j * 3 + 4] = p.y;
pts[2 * j * 3 + 5] = p.z;
lines->InsertNextCell(2);
lines->InsertCellPoint(2*j);
lines->InsertCellPoint(2*j+1);
}
data->SetArray (&pts[0], 2 * nr_gradients * 3, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
points->SetData (data);
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
polyData->SetLines(lines);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New ();
mapper->SetInputData (polyData);
mapper->SetColorModeToMapScalars();
mapper->SetScalarModeToUsePointData();
// create actor
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New ();
actor->SetMapper (mapper);
// Add it to all renderers
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*cloud_actor_map_)[id].actor = actor;
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::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,
int viewport)
{
pcl::Correspondences corrs;
corrs.resize (correspondences.size ());
std::size_t index = 0;
for (auto &corr : corrs)
{
corr.index_query = index;
corr.index_match = correspondences[index];
index++;
}
return (addCorrespondences<PointT> (source_points, target_points, corrs, id, viewport));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addCorrespondences (
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,
int viewport,
bool overwrite)
{
if (correspondences.empty ())
{
PCL_DEBUG ("[addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
return (false);
}
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = shape_actor_map_->find (id);
if (am_it != shape_actor_map_->end () && !overwrite)
{
PCL_WARN ("[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
if (am_it == shape_actor_map_->end () && overwrite)
{
overwrite = false; // Correspondences doesn't exist, add them instead of updating them
}
int n_corr = static_cast<int>(correspondences.size () / nth);
vtkSmartPointer<vtkPolyData> line_data = vtkSmartPointer<vtkPolyData>::New ();
// Prepare colors
vtkSmartPointer<vtkUnsignedCharArray> line_colors = vtkSmartPointer<vtkUnsignedCharArray>::New ();
line_colors->SetNumberOfComponents (3);
line_colors->SetName ("Colors");
line_colors->SetNumberOfTuples (n_corr);
// Prepare coordinates
vtkSmartPointer<vtkPoints> line_points = vtkSmartPointer<vtkPoints>::New ();
line_points->SetNumberOfPoints (2 * n_corr);
vtkSmartPointer<vtkIdTypeArray> line_cells_id = vtkSmartPointer<vtkIdTypeArray>::New ();
line_cells_id->SetNumberOfComponents (3);
line_cells_id->SetNumberOfTuples (n_corr);
vtkIdType *line_cell_id = line_cells_id->GetPointer (0);
vtkSmartPointer<vtkCellArray> line_cells = vtkSmartPointer<vtkCellArray>::New ();
vtkSmartPointer<vtkFloatArray> line_tcoords = vtkSmartPointer<vtkFloatArray>::New ();
line_tcoords->SetNumberOfComponents (1);
line_tcoords->SetNumberOfTuples (n_corr * 2);
line_tcoords->SetName ("Texture Coordinates");
double tc[3] = {0.0, 0.0, 0.0};
Eigen::Affine3f source_transformation;
source_transformation.linear () = source_points->sensor_orientation_.matrix ();
source_transformation.translation () = source_points->sensor_origin_.head (3);
Eigen::Affine3f target_transformation;
target_transformation.linear () = target_points->sensor_orientation_.matrix ();
target_transformation.translation () = target_points->sensor_origin_.head (3);
int j = 0;
// Draw lines between the best corresponding points
for (std::size_t i = 0; i < correspondences.size (); i += nth, ++j)
{
if (correspondences[i].index_match == UNAVAILABLE)
{
PCL_WARN ("[addCorrespondences] No valid index_match for correspondence %d\n", i);
continue;
}
PointT p_src ((*source_points)[correspondences[i].index_query]);
PointT p_tgt ((*target_points)[correspondences[i].index_match]);
p_src.getVector3fMap () = source_transformation * p_src.getVector3fMap ();
p_tgt.getVector3fMap () = target_transformation * p_tgt.getVector3fMap ();
int id1 = j * 2 + 0, id2 = j * 2 + 1;
// Set the points
line_points->SetPoint (id1, p_src.x, p_src.y, p_src.z);
line_points->SetPoint (id2, p_tgt.x, p_tgt.y, p_tgt.z);
// Set the cell ID
*line_cell_id++ = 2;
*line_cell_id++ = id1;
*line_cell_id++ = id2;
// Set the texture coords
tc[0] = 0.; line_tcoords->SetTuple (id1, tc);
tc[0] = 1.; line_tcoords->SetTuple (id2, tc);
float rgb[3];
rgb[0] = vtkMath::Random (32, 255); // min / max
rgb[1] = vtkMath::Random (32, 255);
rgb[2] = vtkMath::Random (32, 255);
line_colors->InsertTuple (i, rgb);
}
line_colors->SetNumberOfTuples (j);
line_cells_id->SetNumberOfTuples (j);
line_cells->SetCells (n_corr, line_cells_id);
line_points->SetNumberOfPoints (j*2);
line_tcoords->SetNumberOfTuples (j*2);
// Fill in the lines
line_data->SetPoints (line_points);
line_data->SetLines (line_cells);
line_data->GetPointData ()->SetTCoords (line_tcoords);
line_data->GetCellData ()->SetScalars (line_colors);
// Create an Actor
if (!overwrite)
{
vtkSmartPointer<vtkLODActor> actor;
createActorFromVTKDataSet (line_data, actor);
actor->GetProperty ()->SetRepresentationToWireframe ();
actor->GetProperty ()->SetOpacity (0.5);
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
(*shape_actor_map_)[id] = actor;
}
else
{
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast (am_it->second);
if (!actor)
return (false);
// Update the mapper
reinterpret_cast<vtkPolyDataMapper*> (actor->GetMapper ())->SetInputData (line_data);
}
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::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,
int viewport)
{
return (addCorrespondences<PointT> (source_points, target_points, correspondences, nth, id, viewport, true));
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::fromHandlersToScreen (
const PointCloudGeometryHandler<PointT> &geometry_handler,
const PointCloudColorHandler<PointT> &color_handler,
const std::string &id,
int viewport,
const Eigen::Vector4f& sensor_origin,
const Eigen::Quaternion<float>& sensor_orientation)
{
if (!geometry_handler.isCapable ())
{
PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
return (false);
}
if (!color_handler.isCapable ())
{
PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
return (false);
}
vtkSmartPointer<vtkPolyData> polydata;
vtkSmartPointer<vtkIdTypeArray> initcells;
// Convert the PointCloud to VTK PolyData
convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
// Get the colors from the handler
bool has_colors = false;
double minmax[2];
if (auto scalars = color_handler.getColor ())
{
polydata->GetPointData ()->SetScalars (scalars);
scalars->GetRange (minmax);
has_colors = true;
}
// Create an Actor
vtkSmartPointer<vtkLODActor> actor;
createActorFromVTKDataSet (polydata, actor);
if (has_colors)
actor->GetMapper ()->SetScalarRange (minmax);
// Add it to all renderers
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
CloudActor& cloud_actor = (*cloud_actor_map_)[id];
cloud_actor.actor = actor;
cloud_actor.cells = initcells;
// Save the viewpoint transformation matrix to the global actor map
vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New();
convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
cloud_actor.viewpoint_transformation_ = transformation;
cloud_actor.actor->SetUserMatrix (transformation);
cloud_actor.actor->Modified ();
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::fromHandlersToScreen (
const PointCloudGeometryHandler<PointT> &geometry_handler,
const ColorHandlerConstPtr &color_handler,
const std::string &id,
int viewport,
const Eigen::Vector4f& sensor_origin,
const Eigen::Quaternion<float>& sensor_orientation)
{
if (!geometry_handler.isCapable ())
{
PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
return (false);
}
if (!color_handler->isCapable ())
{
PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ());
return (false);
}
vtkSmartPointer<vtkPolyData> polydata;
vtkSmartPointer<vtkIdTypeArray> initcells;
// Convert the PointCloud to VTK PolyData
convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
// use the given geometry handler
// Get the colors from the handler
bool has_colors = false;
double minmax[2];
if (auto scalars = color_handler->getColor ())
{
polydata->GetPointData ()->SetScalars (scalars);
scalars->GetRange (minmax);
has_colors = true;
}
// Create an Actor
vtkSmartPointer<vtkLODActor> actor;
createActorFromVTKDataSet (polydata, actor);
if (has_colors)
actor->GetMapper ()->SetScalarRange (minmax);
// Add it to all renderers
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
CloudActor& cloud_actor = (*cloud_actor_map_)[id];
cloud_actor.actor = actor;
cloud_actor.cells = initcells;
cloud_actor.color_handlers.push_back (color_handler);
// Save the viewpoint transformation matrix to the global actor map
vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New();
convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
cloud_actor.viewpoint_transformation_ = transformation;
cloud_actor.actor->SetUserMatrix (transformation);
cloud_actor.actor->Modified ();
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::fromHandlersToScreen (
const GeometryHandlerConstPtr &geometry_handler,
const PointCloudColorHandler<PointT> &color_handler,
const std::string &id,
int viewport,
const Eigen::Vector4f& sensor_origin,
const Eigen::Quaternion<float>& sensor_orientation)
{
if (!geometry_handler->isCapable ())
{
PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ());
return (false);
}
if (!color_handler.isCapable ())
{
PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
return (false);
}
vtkSmartPointer<vtkPolyData> polydata;
vtkSmartPointer<vtkIdTypeArray> initcells;
// Convert the PointCloud to VTK PolyData
convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
// use the given geometry handler
// Get the colors from the handler
bool has_colors = false;
double minmax[2];
if (auto scalars = color_handler.getColor ())
{
polydata->GetPointData ()->SetScalars (scalars);
scalars->GetRange (minmax);
has_colors = true;
}
// Create an Actor
vtkSmartPointer<vtkLODActor> actor;
createActorFromVTKDataSet (polydata, actor);
if (has_colors)
actor->GetMapper ()->SetScalarRange (minmax);
// Add it to all renderers
addActorToRenderer (actor, viewport);
// Save the pointer/ID pair to the global actor map
CloudActor& cloud_actor = (*cloud_actor_map_)[id];
cloud_actor.actor = actor;
cloud_actor.cells = initcells;
cloud_actor.geometry_handlers.push_back (geometry_handler);
// Save the viewpoint transformation matrix to the global actor map
vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New ();
convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
cloud_actor.viewpoint_transformation_ = transformation;
cloud_actor.actor->SetUserMatrix (transformation);
cloud_actor.actor->Modified ();
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const std::string &id)
{
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = cloud_actor_map_->find (id);
if (am_it == cloud_actor_map_->end ())
return (false);
vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
if (!polydata)
return false;
// Convert the PointCloud to VTK PolyData
convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
// Set scalars to blank, since there is no way we can update them here.
vtkSmartPointer<vtkDataArray> scalars;
polydata->GetPointData ()->SetScalars (scalars);
double minmax[2];
minmax[0] = std::numeric_limits<double>::min ();
minmax[1] = std::numeric_limits<double>::max ();
am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
// Update the mapper
reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
return (true);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &,
const PointCloudGeometryHandler<PointT> &geometry_handler,
const std::string &id)
{
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = cloud_actor_map_->find (id);
if (am_it == cloud_actor_map_->end ())
return (false);
vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
if (!polydata)
return (false);
// Convert the PointCloud to VTK PolyData
convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
// Set scalars to blank, since there is no way we can update them here.
vtkSmartPointer<vtkDataArray> scalars;
polydata->GetPointData ()->SetScalars (scalars);
double minmax[2];
minmax[0] = std::numeric_limits<double>::min ();
minmax[1] = std::numeric_limits<double>::max ();
am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
// Update the mapper
reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
return (true);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const PointCloudColorHandler<PointT> &color_handler,
const std::string &id)
{
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = cloud_actor_map_->find (id);
if (am_it == cloud_actor_map_->end ())
return (false);
// Get the current poly data
vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
if (!polydata)
return (false);
convertPointCloudToVTKPolyData<PointT>(cloud, polydata, am_it->second.cells);
// Get the colors from the handler
bool has_colors = false;
double minmax[2];
if (auto scalars = color_handler.getColor ())
{
// Update the data
polydata->GetPointData ()->SetScalars (scalars);
scalars->GetRange (minmax);
has_colors = true;
}
if (has_colors)
am_it->second.actor->GetMapper ()->SetScalarRange (minmax);
// Update the mapper
reinterpret_cast<vtkPolyDataMapper*> (am_it->second.actor->GetMapper ())->SetInputData (polydata);
return (true);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::addPolygonMesh (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const std::vector<pcl::Vertices> &vertices,
const std::string &id,
int viewport)
{
if (vertices.empty () || cloud->points.empty ())
return (false);
if (contains (id))
{
PCL_WARN ("[addPolygonMesh] The id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
return (false);
}
int rgb_idx = -1;
std::vector<pcl::PCLPointField> fields;
vtkSmartPointer<vtkUnsignedCharArray> colors;
rgb_idx = pcl::getFieldIndex<PointT> ("rgb", fields);
if (rgb_idx == -1)
rgb_idx = pcl::getFieldIndex<PointT> ("rgba", fields);
if (rgb_idx != -1)
{
colors = vtkSmartPointer<vtkUnsignedCharArray>::New ();
colors->SetNumberOfComponents (3);
colors->SetName ("Colors");
std::uint32_t offset = fields[rgb_idx].offset;
for (std::size_t i = 0; i < cloud->size (); ++i)
{
if (!isFinite ((*cloud)[i]))
continue;
const auto* const rgb_data = reinterpret_cast<const pcl::RGB*>(reinterpret_cast<const char*> (&(*cloud)[i]) + offset);
unsigned char color[3];
color[0] = rgb_data->r;
color[1] = rgb_data->g;
color[2] = rgb_data->b;
colors->InsertNextTupleValue (color);
}
}
// Create points from polyMesh.cloud
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New ();
vtkIdType nr_points = cloud->size ();
points->SetNumberOfPoints (nr_points);
vtkSmartPointer<vtkLODActor> actor;
// Get a pointer to the beginning of the data array
float *data = dynamic_cast<vtkFloatArray*> (points->GetData ())->GetPointer (0);
vtkIdType ptr = 0;
std::vector<int> lookup;
// If the dataset is dense (no NaNs)
if (cloud->is_dense)
{
for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3) {
std::copy(&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
}
}
else
{
lookup.resize (nr_points);
vtkIdType j = 0; // true point index
for (vtkIdType i = 0; i < nr_points; ++i)
{
// Check if the point is invalid
if (!isFinite ((*cloud)[i]))
continue;
lookup[i] = static_cast<int> (j);
std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
j++;
ptr += 3;
}
nr_points = j;
points->SetNumberOfPoints (nr_points);
}
// Get the maximum size of a polygon
int max_size_of_polygon = -1;
for (const auto &vertex : vertices)
if (max_size_of_polygon < static_cast<int> (vertex.vertices.size ()))
max_size_of_polygon = static_cast<int> (vertex.vertices.size ());
if (vertices.size () > 1)
{
// Create polys from polyMesh.polygons
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New ();
const auto idx = details::fillCells(lookup,vertices,cell_array, max_size_of_polygon);
vtkSmartPointer<vtkPolyData> polydata;
allocVtkPolyData (polydata);
cell_array->GetData ()->SetNumberOfValues (idx);
cell_array->Squeeze ();
polydata->SetPolys (cell_array);
polydata->SetPoints (points);
if (colors)
polydata->GetPointData ()->SetScalars (colors);
createActorFromVTKDataSet (polydata, actor, false);
}
else
{
vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New ();
std::size_t n_points = vertices[0].vertices.size ();
polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
if (!lookup.empty ())
{
for (std::size_t j = 0; j < (n_points - 1); ++j)
polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]);
}
else
{
for (std::size_t j = 0; j < (n_points - 1); ++j)
polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
}
vtkSmartPointer<vtkUnstructuredGrid> poly_grid;
allocVtkUnstructuredGrid (poly_grid);
poly_grid->Allocate (1, 1);
poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
poly_grid->SetPoints (points);
if (colors)
poly_grid->GetPointData ()->SetScalars (colors);
createActorFromVTKDataSet (poly_grid, actor, false);
}
addActorToRenderer (actor, viewport);
actor->GetProperty ()->SetRepresentationToSurface ();
// Backface culling renders the visualization slower, but guarantees that we see all triangles
actor->GetProperty ()->BackfaceCullingOff ();
actor->GetProperty ()->SetInterpolationToFlat ();
actor->GetProperty ()->EdgeVisibilityOff ();
actor->GetProperty ()->ShadingOff ();
// Save the pointer/ID pair to the global actor map
(*cloud_actor_map_)[id].actor = actor;
// Save the viewpoint transformation matrix to the global actor map
vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New();
convertToVtkMatrix (cloud->sensor_origin_, cloud->sensor_orientation_, transformation);
(*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
return (true);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::visualization::PCLVisualizer::updatePolygonMesh (
const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
const std::vector<pcl::Vertices> &verts,
const std::string &id)
{
if (verts.empty ())
{
pcl::console::print_error ("[addPolygonMesh] No vertices given!\n");
return (false);
}
// Check to see if this ID entry already exists (has it been already added to the visualizer?)
auto am_it = cloud_actor_map_->find (id);
if (am_it == cloud_actor_map_->end ())
return (false);
// Get the current poly data
vtkSmartPointer<vtkPolyData> polydata = dynamic_cast<vtkPolyData*>(am_it->second.actor->GetMapper ()->GetInput ());
if (!polydata)
return (false);
vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();
if (!cells)
return (false);
vtkSmartPointer<vtkPoints> points = polydata->GetPoints ();
// Copy the new point array in
vtkIdType nr_points = cloud->size ();
points->SetNumberOfPoints (nr_points);
// Get a pointer to the beginning of the data array
float *data = (dynamic_cast<vtkFloatArray*> (points->GetData ()))->GetPointer (0);
int ptr = 0;
std::vector<int> lookup;
// If the dataset is dense (no NaNs)
if (cloud->is_dense)
{
for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
}
else
{
lookup.resize (nr_points);
vtkIdType j = 0; // true point index
for (vtkIdType i = 0; i < nr_points; ++i)
{
// Check if the point is invalid
if (!isFinite ((*cloud)[i]))
continue;
lookup [i] = static_cast<int> (j);
std::copy (&(*cloud)[i].x, &(*cloud)[i].x + 3, &data[ptr]);
j++;
ptr += 3;
}
nr_points = j;
points->SetNumberOfPoints (nr_points);
}
// Update colors
vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
if (!colors)
return (false);
int rgb_idx = -1;
std::vector<pcl::PCLPointField> fields;
rgb_idx = pcl::getFieldIndex<PointT> ("rgb", fields);
if (rgb_idx == -1)
rgb_idx = pcl::getFieldIndex<PointT> ("rgba", fields);
if (rgb_idx != -1 && colors)
{
int j = 0;
std::uint32_t offset = fields[rgb_idx].offset;
for (std::size_t i = 0; i < cloud->size (); ++i)
{
if (!isFinite ((*cloud)[i]))
continue;
const auto* const rgb_data = reinterpret_cast<const pcl::RGB*>(reinterpret_cast<const char*> (&(*cloud)[i]) + offset);
unsigned char color[3];
color[0] = rgb_data->r;
color[1] = rgb_data->g;
color[2] = rgb_data->b;
colors->SetTupleValue (j++, color);
}
}
// Get the maximum size of a polygon
int max_size_of_polygon = -1;
for (const auto &vertex : verts)
if (max_size_of_polygon < static_cast<int> (vertex.vertices.size ()))
max_size_of_polygon = static_cast<int> (vertex.vertices.size ());
// Update the cells
cells = vtkSmartPointer<vtkCellArray>::New ();
const auto idx = details::fillCells(lookup, verts, cells, max_size_of_polygon);
cells->GetData ()->SetNumberOfValues (idx);
cells->Squeeze ();
// Set the the vertices
polydata->SetPolys (cells);
return (true);
}
#ifdef vtkGenericDataArray_h
#undef SetTupleValue
#undef InsertNextTupleValue
#undef GetTupleValue
#endif
#endif
pcl::PlanarPolygon
PlanarPolygon represents a planar (2D) polygon, potentially in a 3D space.
Definition planar_polygon.h:52
pcl::PointCloud::empty
bool empty() const
Definition point_cloud.h:446
pcl::PointCloud::is_dense
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
Definition point_cloud.h:403
pcl::PointCloud::sensor_orientation_
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
Definition point_cloud.h:408
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition point_cloud.h:398
pcl::PointCloud::isOrganized
bool isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
Definition point_cloud.h:310
pcl::PointCloud::height
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition point_cloud.h:400
pcl::PointCloud::size
std::size_t size() const
Definition point_cloud.h:443
pcl::PointCloud::sensor_origin_
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
Definition point_cloud.h:406
pcl::PointCloud::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition point_cloud.h:395
pcl::PointCloud::ConstPtr
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition point_cloud.h:414
pcl::visualization::CloudActor
Definition actor_map.h:60
pcl::visualization::CloudActor::actor
vtkSmartPointer< vtkLODActor > actor
The actor holding the data to render.
Definition actor_map.h:75
pcl::visualization::PCLVisualizer::addPointCloudIntensityGradients
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.
Definition pcl_visualizer.hpp:1102
pcl::visualization::PCLVisualizer::addPolygonMesh
bool addPolygonMesh(const pcl::PolygonMesh &polymesh, const std::string &id="polygon", int viewport=0)
Add a PolygonMesh object to screen.
pcl::visualization::PCLVisualizer::addSphere
bool addSphere(const PointT &center, double radius, const std::string &id="sphere", int viewport=0)
Add a sphere shape from a point and a radius.
Definition pcl_visualizer.hpp:650
pcl::visualization::PCLVisualizer::addPointCloud
bool addPointCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud, const std::string &id="cloud", int viewport=0)
Add a Point Cloud (templated) to screen.
Definition pcl_visualizer.hpp:77
pcl::visualization::PCLVisualizer::addCorrespondences
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.
Definition pcl_visualizer.hpp:1174
pcl::visualization::PCLVisualizer::addPolygon
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)
Definition pcl_visualizer.hpp:372
pcl::visualization::PCLVisualizer::updatePointCloud
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.
Definition pcl_visualizer.hpp:1529
pcl::visualization::PCLVisualizer::GeometryHandlerConstPtr
GeometryHandler::ConstPtr GeometryHandlerConstPtr
Definition pcl_visualizer.h:101
pcl::visualization::PCLVisualizer::addPointCloudNormals
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.
Definition pcl_visualizer.hpp:852
pcl::visualization::PCLVisualizer::addText3D
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.
Definition pcl_visualizer.hpp:686
pcl::visualization::PCLVisualizer::updateSphere
bool updateSphere(const PointT &center, double radius, double r, double g, double b, const std::string &id="sphere")
Update an existing sphere shape from a point and a radius.
Definition pcl_visualizer.hpp:657
pcl::visualization::PCLVisualizer::ColorHandlerConstPtr
ColorHandler::ConstPtr ColorHandlerConstPtr
Definition pcl_visualizer.h:105
pcl::visualization::PCLVisualizer::addArrow
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.
Definition pcl_visualizer.hpp:515
pcl::visualization::PCLVisualizer::addLine
bool addLine(const P1 &pt1, const P2 &pt2, const std::string &id="line", int viewport=0)
Add a line segment from two points.
Definition pcl_visualizer.hpp:604
pcl::visualization::PCLVisualizer::addPointCloudPrincipalCurvatures
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.
pcl::visualization::PCLVisualizer::updatePolygonMesh
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.
Definition pcl_visualizer.hpp:1778
pcl::visualization::PCLVisualizer::updateCorrespondences
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.
Definition pcl_visualizer.hpp:1329
pcl::visualization::PointCloudColorHandlerCustom
Handler for predefined user colors.
Definition point_cloud_color_handlers.h:187
pcl::visualization::PointCloudColorHandler
Base Handler class for PointCloud colors.
Definition point_cloud_color_handlers.h:66
pcl::visualization::PointCloudColorHandler::getColor
virtual vtkSmartPointer< vtkDataArray > getColor() const =0
Obtain the actual color for the input dataset as a VTK data array.
pcl::visualization::PointCloudColorHandler::isCapable
bool isCapable() const
Check if this handler is capable of handling the input data or not.
Definition point_cloud_color_handlers.h:90
pcl::visualization::PointCloudColorHandler::getName
virtual std::string getName() const =0
Abstract getName method.
pcl::visualization::PointCloudColorHandlerRGBField
RGB handler class for colors.
Definition point_cloud_color_handlers.h:245
pcl::visualization::PointCloudGeometryHandler
Base handler class for PointCloud geometry.
Definition point_cloud_geometry_handlers.h:63
pcl::visualization::PointCloudGeometryHandler::getName
virtual std::string getName() const =0
Abstract getName method.
pcl::visualization::PointCloudGeometryHandler::isCapable
bool isCapable() const
Check if this handler is capable of handling the input data or not.
Definition point_cloud_geometry_handlers.h:94
pcl::visualization::PointCloudGeometryHandler::getGeometry
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const =0
Obtain the actual point geometry for the input dataset in VTK format.
pcl::visualization::PointCloudGeometryHandlerXYZ
XYZ handler class for PointCloud geometry.
Definition point_cloud_geometry_handlers.h:141
vtkSmartPointer
Definition actor_map.h:51
pcl::visualization::createLine
PCL_EXPORTS vtkSmartPointer< vtkDataSet > createLine(const Eigen::Vector4f &pt1, const Eigen::Vector4f &pt2)
Create a line shape from two points.
pcl::console::print_error
PCL_EXPORTS void print_error(const char *format,...)
Print an error message on stream with colors.
pcl::utils::ignore
void ignore(const T &...)
Utility function to eliminate unused variable warnings.
Definition utils.h:62
pcl::visualization::details::fillCells
PCL_EXPORTS vtkIdType fillCells(std::vector< int > &lookup, const std::vector< pcl::Vertices > &vertices, vtkSmartPointer< vtkCellArray > cell_array, int max_size_of_polygon)
pcl::visualization::allocVtkUnstructuredGrid
PCL_EXPORTS void allocVtkUnstructuredGrid(vtkSmartPointer< vtkUnstructuredGrid > &polydata)
Allocate a new unstructured grid smartpointer.
pcl::isFinite
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...
Definition point_tests.h:55
pcl::UNAVAILABLE
static constexpr index_t UNAVAILABLE
Definition pcl_base.h:62
pcl::Correspondences
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
Definition correspondence.h:89
pcl::isNormalFinite
constexpr bool isNormalFinite(const PointT &) noexcept
Definition point_tests.h:131
shapes.h
Define methods or creating 3D shapes from parametric models.
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition point_types.hpp:623
pcl::RGB
A structure representing RGB color information.
Definition point_types.hpp:392