43 #include <pcl/common/point_tests.h>
45 #include <pcl/type_traits.h>
50 #pragma GCC system_header
52 #include <vtkVersion.h>
53 #include <vtkFloatArray.h>
54 #include <vtkPointData.h>
55 #include <vtkPoints.h>
56 #include <vtkPolyData.h>
57 #include <vtkUnsignedCharArray.h>
58 #include <vtkSmartPointer.h>
59 #include <vtkStructuredGrid.h>
60 #include <vtkVertexGlyphFilter.h>
63 #ifdef vtkGenericDataArray_h
64 #define SetTupleValue SetTypedTuple
65 #define InsertNextTupleValue InsertNextTypedTuple
66 #define GetTupleValue GetTypedTuple
70 template <
typename Po
intT>
void
75 cloud.
width = polydata->GetNumberOfPoints ();
81 std::vector<pcl::PCLPointField> fields;
85 int x_idx = -1, y_idx = -1, z_idx = -1;
86 for (std::size_t d = 0; d < fields.size (); ++d)
88 if (fields[d].name ==
"x")
89 x_idx = fields[d].offset;
90 else if (fields[d].name ==
"y")
91 y_idx = fields[d].offset;
92 else if (fields[d].name ==
"z")
93 z_idx = fields[d].offset;
96 if (x_idx != -1 && y_idx != -1 && z_idx != -1)
98 for (std::size_t i = 0; i < cloud.
size (); ++i)
100 double coordinate[3];
101 polydata->GetPoint (i, coordinate);
102 pcl::setFieldValue<PointT, float> (cloud[i], x_idx, coordinate[0]);
103 pcl::setFieldValue<PointT, float> (cloud[i], y_idx, coordinate[1]);
104 pcl::setFieldValue<PointT, float> (cloud[i], z_idx, coordinate[2]);
109 int normal_x_idx = -1, normal_y_idx = -1, normal_z_idx = -1;
110 for (std::size_t d = 0; d < fields.size (); ++d)
112 if (fields[d].name ==
"normal_x")
113 normal_x_idx = fields[d].offset;
114 else if (fields[d].name ==
"normal_y")
115 normal_y_idx = fields[d].offset;
116 else if (fields[d].name ==
"normal_z")
117 normal_z_idx = fields[d].offset;
120 vtkFloatArray* normals = vtkFloatArray::SafeDownCast (polydata->GetPointData ()->GetNormals ());
121 if (normal_x_idx != -1 && normal_y_idx != -1 && normal_z_idx != -1 && normals)
123 for (std::size_t i = 0; i < cloud.
size (); ++i)
126 normals->GetTupleValue (i, normal);
127 pcl::setFieldValue<PointT, float> (cloud[i], normal_x_idx, normal[0]);
128 pcl::setFieldValue<PointT, float> (cloud[i], normal_y_idx, normal[1]);
129 pcl::setFieldValue<PointT, float> (cloud[i], normal_z_idx, normal[2]);
134 vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
136 for (std::size_t d = 0; d < fields.size (); ++d)
138 if (fields[d].name ==
"rgb" || fields[d].name ==
"rgba")
140 rgb_idx = fields[d].offset;
145 if (rgb_idx != -1 && colors)
147 for (std::size_t i = 0; i < cloud.
size (); ++i)
149 unsigned char color[3];
150 colors->GetTupleValue (i, color);
152 rgb.r = color[0]; rgb.g = color[1]; rgb.b = color[2];
153 pcl::setFieldValue<PointT, std::uint32_t> (cloud[i], rgb_idx, rgb.rgba);
159 template <
typename Po
intT>
void
163 structured_grid->GetDimensions (dimensions);
164 cloud.
width = dimensions[0];
165 cloud.
height = dimensions[1];
170 std::vector<pcl::PCLPointField> fields;
174 int x_idx = -1, y_idx = -1, z_idx = -1;
175 for (std::size_t d = 0; d < fields.size (); ++d)
177 if (fields[d].name ==
"x")
178 x_idx = fields[d].offset;
179 else if (fields[d].name ==
"y")
180 y_idx = fields[d].offset;
181 else if (fields[d].name ==
"z")
182 z_idx = fields[d].offset;
185 if (x_idx != -1 && y_idx != -1 && z_idx != -1)
187 for (std::size_t i = 0; i < cloud.
width; ++i)
189 for (std::size_t j = 0; j < cloud.
height; ++j)
191 int queryPoint[3] = {i, j, 0};
192 vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
193 if (structured_grid->IsPointVisible (pointId))
195 double coordinate[3];
196 structured_grid->GetPoint (pointId, coordinate);
197 pcl::setFieldValue<PointT, float> (cloud (i, j), x_idx, coordinate[0]);
198 pcl::setFieldValue<PointT, float> (cloud (i, j), y_idx, coordinate[1]);
199 pcl::setFieldValue<PointT, float> (cloud (i, j), z_idx, coordinate[2]);
210 int normal_x_idx = -1, normal_y_idx = -1, normal_z_idx = -1;
211 for (std::size_t d = 0; d < fields.size (); ++d)
213 if (fields[d].name ==
"normal_x")
214 normal_x_idx = fields[d].offset;
215 else if (fields[d].name ==
"normal_y")
216 normal_y_idx = fields[d].offset;
217 else if (fields[d].name ==
"normal_z")
218 normal_z_idx = fields[d].offset;
221 vtkFloatArray* normals = vtkFloatArray::SafeDownCast (structured_grid->GetPointData ()->GetNormals ());
223 if (normal_x_idx != -1 && normal_y_idx != -1 && normal_z_idx != -1 && normals)
225 for (std::size_t i = 0; i < cloud.
width; ++i)
227 for (std::size_t j = 0; j < cloud.
height; ++j)
229 int queryPoint[3] = {i, j, 0};
230 vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
231 if (structured_grid->IsPointVisible (pointId))
234 normals->GetTupleValue (i, normal);
235 pcl::setFieldValue<PointT, float> (cloud (i, j), normal_x_idx, normal[0]);
236 pcl::setFieldValue<PointT, float> (cloud (i, j), normal_y_idx, normal[1]);
237 pcl::setFieldValue<PointT, float> (cloud (i, j), normal_z_idx, normal[2]);
248 vtkUnsignedCharArray* colors = vtkUnsignedCharArray::SafeDownCast (structured_grid->GetPointData ()->GetArray (
"Colors"));
250 for (std::size_t d = 0; d < fields.size (); ++d)
252 if (fields[d].name ==
"rgb" || fields[d].name ==
"rgba")
254 rgb_idx = fields[d].offset;
259 if (rgb_idx != -1 && colors)
261 for (std::size_t i = 0; i < cloud.
width; ++i)
263 for (std::size_t j = 0; j < cloud.
height; ++j)
265 int queryPoint[3] = {i, j, 0};
266 vtkIdType pointId = vtkStructuredData::ComputePointId(dimensions, queryPoint);
267 unsigned char color[3];
268 if (structured_grid->IsPointVisible (pointId))
270 colors->GetTupleValue (i, color);
272 rgb.r = color[0]; rgb.g = color[1]; rgb.b = color[2];
273 pcl::setFieldValue<PointT, std::uint32_t> (cloud (i, j), rgb_idx, rgb.rgba);
285 template <
typename Po
intT>
void
289 std::vector<pcl::PCLPointField> fields;
293 vtkIdType nr_points = cloud.
size ();
295 points->SetNumberOfPoints (nr_points);
297 float *data = (
static_cast<vtkFloatArray*
> (points->GetData ()))->GetPointer (0);
302 for (vtkIdType i = 0; i < nr_points; ++i)
303 memcpy (&data[i * 3], &cloud[i].x, 12);
308 for (vtkIdType i = 0; i < nr_points; ++i)
311 if (!std::isfinite (cloud[i].x) ||
312 !std::isfinite (cloud[i].y) ||
313 !std::isfinite (cloud[i].z))
316 memcpy (&data[j * 3], &cloud[i].x, 12);
320 points->SetNumberOfPoints (nr_points);
325 temp_polydata->SetPoints (points);
328 int normal_x_idx = -1, normal_y_idx = -1, normal_z_idx = -1;
329 for (std::size_t d = 0; d < fields.size (); ++d)
331 if (fields[d].name ==
"normal_x")
332 normal_x_idx = fields[d].offset;
333 else if (fields[d].name ==
"normal_y")
334 normal_y_idx = fields[d].offset;
335 else if (fields[d].name ==
"normal_z")
336 normal_z_idx = fields[d].offset;
338 if (normal_x_idx != -1 && normal_y_idx != -1 && normal_z_idx != -1)
341 normals->SetNumberOfComponents (3);
342 normals->SetNumberOfTuples (cloud.
size ());
343 normals->SetName (
"Normals");
345 for (std::size_t i = 0; i < cloud.
size (); ++i)
348 pcl::getFieldValue<PointT, float> (cloud[i], normal_x_idx, normal[0]);
349 pcl::getFieldValue<PointT, float> (cloud[i], normal_y_idx, normal[1]);
350 pcl::getFieldValue<PointT, float> (cloud[i], normal_z_idx, normal[2]);
351 normals->SetTupleValue (i, normal);
353 temp_polydata->GetPointData ()->SetNormals (normals);
358 for (std::size_t d = 0; d < fields.size (); ++d)
360 if (fields[d].name ==
"rgb" || fields[d].name ==
"rgba")
362 rgb_idx = fields[d].offset;
369 colors->SetNumberOfComponents (3);
370 colors->SetNumberOfTuples (cloud.
size ());
371 colors->SetName (
"RGB");
373 for (std::size_t i = 0; i < cloud.
size (); ++i)
375 unsigned char color[3];
377 pcl::getFieldValue<PointT, std::uint32_t> (cloud[i], rgb_idx, rgb.rgba);
378 color[0] = rgb.r; color[1] = rgb.g; color[2] = rgb.b;
379 colors->SetTupleValue (i, color);
381 temp_polydata->GetPointData ()->SetScalars (colors);
386 vertex_glyph_filter->SetInputData (temp_polydata);
387 vertex_glyph_filter->Update ();
389 pdata->DeepCopy (vertex_glyph_filter->GetOutput ());
393 template <
typename Po
intT>
void
397 std::vector<pcl::PCLPointField> fields;
400 int dimensions[3] = {cloud.
width, cloud.
height, 1};
401 structured_grid->SetDimensions (dimensions);
404 points->SetNumberOfPoints (cloud.
width * cloud.
height);
406 for (std::size_t i = 0; i < cloud.
width; ++i)
408 for (std::size_t j = 0; j < cloud.
height; ++j)
410 int queryPoint[3] = {i, j, 0};
411 vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
412 const PointT &point = cloud (i, j);
416 float p[3] = {point.x, point.y, point.z};
417 points->SetPoint (pointId, p);
425 structured_grid->SetPoints (points);
428 int normal_x_idx = -1, normal_y_idx = -1, normal_z_idx = -1;
429 for (std::size_t d = 0; d < fields.size (); ++d)
431 if (fields[d].name ==
"normal_x")
432 normal_x_idx = fields[d].offset;
433 else if (fields[d].name ==
"normal_y")
434 normal_y_idx = fields[d].offset;
435 else if (fields[d].name ==
"normal_z")
436 normal_z_idx = fields[d].offset;
439 if (normal_x_idx != -1 && normal_y_idx != -1 && normal_z_idx != -1)
442 normals->SetNumberOfComponents (3);
443 normals->SetNumberOfTuples (cloud.
width * cloud.
height);
444 normals->SetName (
"Normals");
445 for (std::size_t i = 0; i < cloud.
width; ++i)
447 for (std::size_t j = 0; j < cloud.
height; ++j)
449 int queryPoint[3] = {i, j, 0};
450 vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
451 const PointT &point = cloud (i, j);
454 pcl::getFieldValue<PointT, float> (point, normal_x_idx, normal[0]);
455 pcl::getFieldValue<PointT, float> (point, normal_y_idx, normal[1]);
456 pcl::getFieldValue<PointT, float> (point, normal_z_idx, normal[2]);
457 normals->SetTupleValue (pointId, normal);
461 structured_grid->GetPointData ()->SetNormals (normals);
466 for (std::size_t d = 0; d < fields.size (); ++d)
468 if (fields[d].name ==
"rgb" || fields[d].name ==
"rgba")
470 rgb_idx = fields[d].offset;
478 colors->SetNumberOfComponents (3);
479 colors->SetNumberOfTuples (cloud.
width * cloud.
height);
480 colors->SetName (
"Colors");
481 for (std::size_t i = 0; i < cloud.
width; ++i)
483 for (std::size_t j = 0; j < cloud.
height; ++j)
485 int queryPoint[3] = {i, j, 0};
486 vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
487 const PointT &point = cloud (i, j);
492 unsigned char color[3];
494 pcl::getFieldValue<PointT, std::uint32_t> (cloud[i], rgb_idx, rgb.rgba);
495 color[0] = rgb.r; color[1] = rgb.g; color[2] = rgb.b;
496 colors->SetTupleValue (pointId, color);
503 structured_grid->GetPointData ()->AddArray (colors);
507 #ifdef vtkGenericDataArray_h
509 #undef InsertNextTupleValue
PointCloud represents the base class in PCL for storing collections of 3D points.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
void resize(std::size_t count)
Resizes the container to contain count elements.
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::uint32_t height
The point cloud height (if organized as an image-structure).
Defines all the PCL implemented PointT point type structures.
void vtkPolyDataToPointCloud(vtkPolyData *const polydata, pcl::PointCloud< PointT > &cloud)
Convert a VTK PolyData object to a pcl::PointCloud one.
void vtkStructuredGridToPointCloud(vtkStructuredGrid *const structured_grid, pcl::PointCloud< PointT > &cloud)
Convert a VTK StructuredGrid object to a pcl::PointCloud one.
void pointCloudTovtkStructuredGrid(const pcl::PointCloud< PointT > &cloud, vtkStructuredGrid *const structured_grid)
Convert a pcl::PointCloud object to a VTK StructuredGrid one.
void pointCloudTovtkPolyData(const pcl::PointCloud< PointT > &cloud, vtkPolyData *const polydata)
Convert a pcl::PointCloud object to a VTK PolyData one.
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...
A point structure representing Euclidean xyz coordinates, and the RGB color.
A structure representing RGB color information.