00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <pcl/io/vtk_lib_io.h>
00039 #include <pcl/io/impl/vtk_lib_io.hpp>
00040 #include <pcl/PCLPointCloud2.h>
00041 #include <vtkCellArray.h>
00042 #include <vtkCellData.h>
00043 #include <vtkDoubleArray.h>
00044 #include <vtkImageData.h>
00045 #include <vtkImageShiftScale.h>
00046 #include <vtkPNGWriter.h>
00047
00049 int
00050 pcl::io::loadPolygonFile (const std::string &file_name, pcl::PolygonMesh& mesh)
00051 {
00052 std::string extension = file_name.substr (file_name.find_last_of (".") + 1);
00053
00054 if (extension == "pcd")
00055 {
00056 pcl::io::loadPCDFile (file_name, mesh.cloud);
00057 mesh.polygons.resize (0);
00058 return (static_cast<int> (mesh.cloud.width * mesh.cloud.height));
00059 }
00060 else if (extension == "vtk")
00061 return (pcl::io::loadPolygonFileVTK (file_name, mesh));
00062 else if (extension == "ply")
00063 return (pcl::io::loadPolygonFilePLY (file_name, mesh));
00064 else if (extension == "obj")
00065 return (pcl::io::loadPolygonFileOBJ (file_name, mesh));
00066 else if (extension == "stl" )
00067 return (pcl::io::loadPolygonFileSTL (file_name, mesh));
00068 else
00069 {
00070 PCL_ERROR ("[pcl::io::loadPolygonFile]: Unsupported file type (%s)\n", extension.c_str ());
00071 return (0);
00072 }
00073 }
00074
00076 int
00077 pcl::io::savePolygonFile (const std::string &file_name, const pcl::PolygonMesh& mesh)
00078 {
00079
00080
00081
00082 std::string extension = file_name.substr (file_name.find_last_of (".") + 1);
00083 if (extension == ".pcd")
00084 {
00085 int error_code = pcl::io::savePCDFile (file_name, mesh.cloud);
00086 if (error_code != 0)
00087 return (0);
00088 return (static_cast<int> (mesh.cloud.width * mesh.cloud.height));
00089 }
00090 else if (extension == ".vtk")
00091 return (pcl::io::savePolygonFileVTK (file_name, mesh));
00092 else if (extension == ".ply")
00093 return (pcl::io::savePolygonFilePLY (file_name, mesh));
00094 else if (extension == ".stl" )
00095 return (pcl::io::savePolygonFileSTL (file_name, mesh));
00096 else
00097 {
00098 PCL_ERROR ("[pcl::io::savePolygonFile]: Unsupported file type (%s)\n", extension.c_str ());
00099 return (0);
00100 }
00101 }
00102
00104 int
00105 pcl::io::loadPolygonFileVTK (const std::string &file_name, pcl::PolygonMesh& mesh)
00106 {
00107 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
00108
00109 vtkSmartPointer<vtkPolyDataReader> ply_reader = vtkSmartPointer<vtkPolyDataReader>::New ();
00110 ply_reader->SetFileName (file_name.c_str ());
00111 ply_reader->Update ();
00112 poly_data = ply_reader->GetOutput ();
00113
00114 return (pcl::io::vtk2mesh (poly_data, mesh));
00115 }
00116
00118 int
00119 pcl::io::loadPolygonFilePLY (const std::string &file_name, pcl::PolygonMesh& mesh)
00120 {
00121 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New();
00122
00123 vtkSmartPointer<vtkPLYReader> ply_reader = vtkSmartPointer<vtkPLYReader>::New();
00124 ply_reader->SetFileName (file_name.c_str ());
00125 ply_reader->Update ();
00126 poly_data = ply_reader->GetOutput ();
00127
00128 return (pcl::io::vtk2mesh (poly_data, mesh));
00129 }
00130
00132 int
00133 pcl::io::loadPolygonFileOBJ (const std::string &file_name, pcl::PolygonMesh& mesh)
00134 {
00135 vtkSmartPointer<vtkOBJReader> ply_reader = vtkSmartPointer<vtkOBJReader>::New ();
00136 ply_reader->SetFileName (file_name.c_str ());
00137 ply_reader->Update ();
00138
00139 vtkSmartPointer<vtkPolyData> poly_data = ply_reader->GetOutput ();
00140
00141 return (pcl::io::vtk2mesh (poly_data, mesh));
00142 }
00143
00145 int
00146 pcl::io::loadPolygonFileOBJ (const std::string &file_name, pcl::TextureMesh& mesh)
00147 {
00148 vtkSmartPointer<vtkOBJReader> ply_reader = vtkSmartPointer<vtkOBJReader>::New ();
00149 ply_reader->SetFileName (file_name.c_str ());
00150 ply_reader->Update ();
00151
00152 vtkSmartPointer<vtkPolyData> poly_data = ply_reader->GetOutput ();
00153
00154 return (pcl::io::vtk2mesh (poly_data, mesh));
00155 }
00156
00157
00159 int
00160 pcl::io::loadPolygonFileSTL (const std::string &file_name, pcl::PolygonMesh& mesh)
00161 {
00162 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
00163
00164 vtkSmartPointer<vtkSTLReader> ply_reader = vtkSmartPointer<vtkSTLReader>::New ();
00165 ply_reader->SetFileName (file_name.c_str ());
00166 ply_reader->Update ();
00167 poly_data = ply_reader->GetOutput ();
00168
00169 return (pcl::io::vtk2mesh (poly_data, mesh));
00170 }
00171
00173 int
00174 pcl::io::savePolygonFileVTK (const std::string &file_name, const pcl::PolygonMesh& mesh)
00175 {
00176 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
00177
00178 pcl::io::mesh2vtk (mesh, poly_data);
00179
00180 vtkSmartPointer<vtkPolyDataWriter> poly_writer = vtkSmartPointer<vtkPolyDataWriter>::New ();
00181 poly_writer->SetInput (poly_data);
00182 poly_writer->SetFileName (file_name.c_str ());
00183 poly_writer->Write ();
00184
00185 return (static_cast<int> (mesh.cloud.width * mesh.cloud.height));
00186 }
00187
00189 int
00190 pcl::io::savePolygonFilePLY (const std::string &file_name, const pcl::PolygonMesh& mesh)
00191 {
00192 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
00193
00194 pcl::io::mesh2vtk (mesh, poly_data);
00195
00196 vtkSmartPointer<vtkPLYWriter> poly_writer = vtkSmartPointer<vtkPLYWriter>::New ();
00197 poly_writer->SetInput (poly_data);
00198 poly_writer->SetFileName (file_name.c_str ());
00199 poly_writer->SetArrayName ("Colors");
00200 poly_writer->Write ();
00201
00202 return (static_cast<int> (mesh.cloud.width * mesh.cloud.height));
00203 }
00204
00206 int
00207 pcl::io::savePolygonFileSTL (const std::string &file_name, const pcl::PolygonMesh& mesh)
00208 {
00209 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
00210
00211 pcl::io::mesh2vtk (mesh, poly_data);
00212 poly_data->Update ();
00213 vtkSmartPointer<vtkSTLWriter> poly_writer = vtkSmartPointer<vtkSTLWriter>::New ();
00214 poly_writer->SetInput (poly_data);
00215 poly_writer->SetFileName (file_name.c_str ());
00216 poly_writer->Write ();
00217
00218 return (static_cast<int> (mesh.cloud.width * mesh.cloud.height));
00219 }
00220
00222 int
00223 pcl::io::vtk2mesh (const vtkSmartPointer<vtkPolyData>& poly_data, pcl::PolygonMesh& mesh)
00224 {
00225 mesh.polygons.resize (0);
00226 mesh.cloud.data.clear ();
00227 mesh.cloud.width = mesh.cloud.height = 0;
00228 mesh.cloud.is_dense = true;
00229
00230 vtkSmartPointer<vtkPoints> mesh_points = poly_data->GetPoints ();
00231 vtkIdType nr_points = mesh_points->GetNumberOfPoints ();
00232 vtkIdType nr_polygons = poly_data->GetNumberOfPolys ();
00233
00234 if (nr_points == 0)
00235 return (0);
00236
00237
00238
00239 pcl::PointCloud<pcl::PointXYZ>::Ptr xyz_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
00240 xyz_cloud->points.resize (nr_points);
00241 xyz_cloud->width = static_cast<uint32_t> (xyz_cloud->points.size ());
00242 xyz_cloud->height = 1;
00243 xyz_cloud->is_dense = true;
00244 double point_xyz[3];
00245 for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++)
00246 {
00247 mesh_points->GetPoint (i, &point_xyz[0]);
00248 xyz_cloud->points[i].x = static_cast<float> (point_xyz[0]);
00249 xyz_cloud->points[i].y = static_cast<float> (point_xyz[1]);
00250 xyz_cloud->points[i].z = static_cast<float> (point_xyz[2]);
00251 }
00252
00253 pcl::toPCLPointCloud2 (*xyz_cloud, mesh.cloud);
00254
00255
00256
00257 vtkUnsignedCharArray* poly_colors = NULL;
00258 if (poly_data->GetPointData() != NULL)
00259 poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("Colors"));
00260
00261
00262 if (!poly_colors && poly_data->GetPointData () != NULL)
00263 poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("scalars"));
00264
00265 if (!poly_colors && poly_data->GetPointData () != NULL)
00266 poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("RGB"));
00267
00268
00269 if (poly_colors && (poly_colors->GetNumberOfComponents () == 3))
00270 {
00271 pcl::PointCloud<pcl::RGB>::Ptr rgb_cloud (new pcl::PointCloud<pcl::RGB> ());
00272 rgb_cloud->points.resize (nr_points);
00273 rgb_cloud->width = static_cast<uint32_t> (rgb_cloud->points.size ());
00274 rgb_cloud->height = 1;
00275 rgb_cloud->is_dense = true;
00276
00277 unsigned char point_color[3];
00278 for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++)
00279 {
00280 poly_colors->GetTupleValue (i, &point_color[0]);
00281 rgb_cloud->points[i].r = point_color[0];
00282 rgb_cloud->points[i].g = point_color[1];
00283 rgb_cloud->points[i].b = point_color[2];
00284 }
00285
00286 pcl::PCLPointCloud2 rgb_cloud2;
00287 pcl::toPCLPointCloud2 (*rgb_cloud, rgb_cloud2);
00288 pcl::PCLPointCloud2 aux;
00289 pcl::concatenateFields (rgb_cloud2, mesh.cloud, aux);
00290 mesh.cloud = aux;
00291 }
00292
00293
00294
00295 vtkFloatArray* normals = NULL;
00296 if (poly_data->GetPointData () != NULL)
00297 normals = vtkFloatArray::SafeDownCast (poly_data->GetPointData ()->GetNormals ());
00298 if (normals != NULL)
00299 {
00300 pcl::PointCloud<pcl::Normal>::Ptr normal_cloud (new pcl::PointCloud<pcl::Normal> ());
00301 normal_cloud->resize (nr_points);
00302 normal_cloud->width = static_cast<uint32_t> (xyz_cloud->points.size ());
00303 normal_cloud->height = 1;
00304 normal_cloud->is_dense = true;
00305
00306 for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++)
00307 {
00308 float normal[3];
00309 normals->GetTupleValue (i, normal);
00310 normal_cloud->points[i].normal_x = normal[0];
00311 normal_cloud->points[i].normal_y = normal[1];
00312 normal_cloud->points[i].normal_z = normal[2];
00313 }
00314
00315 pcl::PCLPointCloud2 normal_cloud2;
00316 pcl::toPCLPointCloud2 (*normal_cloud, normal_cloud2);
00317 pcl::PCLPointCloud2 aux;
00318 pcl::concatenateFields (normal_cloud2, mesh.cloud, aux);
00319 mesh.cloud = aux;
00320 }
00321
00322
00323
00324
00325 mesh.polygons.resize (nr_polygons);
00326 vtkIdType* cell_points;
00327 vtkIdType nr_cell_points;
00328 vtkCellArray * mesh_polygons = poly_data->GetPolys ();
00329 mesh_polygons->InitTraversal ();
00330 int id_poly = 0;
00331 while (mesh_polygons->GetNextCell (nr_cell_points, cell_points))
00332 {
00333 mesh.polygons[id_poly].vertices.resize (nr_cell_points);
00334 for (int i = 0; i < nr_cell_points; ++i)
00335 mesh.polygons[id_poly].vertices[i] = static_cast<int> (cell_points[i]);
00336 ++id_poly;
00337 }
00338
00339 return (static_cast<int> (nr_points));
00340 }
00341
00342
00344 int
00345 pcl::io::vtk2mesh (const vtkSmartPointer<vtkPolyData>& poly_data, pcl::TextureMesh& mesh)
00346 {
00348 PolygonMesh polygon_mesh;
00349 vtk2mesh (poly_data, polygon_mesh);
00350
00351 mesh.cloud = polygon_mesh.cloud;
00352 mesh.header = polygon_mesh.header;
00354 mesh.tex_polygons.push_back (polygon_mesh.polygons);
00355
00356
00357 mesh.tex_materials.push_back (pcl::TexMaterial ());
00358 std::vector<Eigen::Vector2f> dummy;
00359 mesh.tex_coordinates.push_back (dummy);
00360
00361 vtkIdType nr_points = poly_data->GetNumberOfPoints ();
00362
00363
00364 vtkFloatArray* texture_coords = NULL;
00365 if (poly_data->GetPointData () != NULL)
00366 texture_coords = vtkFloatArray::SafeDownCast (poly_data->GetPointData ()->GetTCoords ());
00367
00368 if (texture_coords != NULL)
00369 {
00370 for (vtkIdType i = 0; i < nr_points; ++i)
00371 {
00372 float tex[2];
00373 texture_coords->GetTupleValue (i, tex);
00374 mesh.tex_coordinates.front ().push_back (Eigen::Vector2f (tex[0], tex[1]));
00375 }
00376 }
00377 else
00378 PCL_ERROR ("Could not find texture coordinates in the polydata\n");
00379
00380 return (static_cast<int> (nr_points));
00381 }
00382
00384 int
00385 pcl::io::mesh2vtk (const pcl::PolygonMesh& mesh, vtkSmartPointer<vtkPolyData>& poly_data)
00386 {
00387 unsigned int nr_points = mesh.cloud.width * mesh.cloud.height;
00388 unsigned int nr_polygons = static_cast<unsigned int> (mesh.polygons.size ());
00389
00390
00391 poly_data = vtkSmartPointer<vtkPolyData>::New ();
00392 vtkSmartPointer<vtkPoints> vtk_mesh_points = vtkSmartPointer<vtkPoints>::New ();
00393 vtkSmartPointer<vtkCellArray> vtk_mesh_polygons = vtkSmartPointer<vtkCellArray>::New ();
00394 poly_data->SetPoints (vtk_mesh_points);
00395
00396
00397 int idx_x = -1, idx_y = -1, idx_z = -1, idx_rgb = -1, idx_rgba = -1, idx_normal_x = -1, idx_normal_y = -1, idx_normal_z = -1;
00398 for (int d = 0; d < static_cast<int> (mesh.cloud.fields.size ()); ++d)
00399 {
00400 if (mesh.cloud.fields[d].name == "x") idx_x = d;
00401 else if (mesh.cloud.fields[d].name == "y") idx_y = d;
00402 else if (mesh.cloud.fields[d].name == "z") idx_z = d;
00403 else if (mesh.cloud.fields[d].name == "rgb") idx_rgb = d;
00404 else if (mesh.cloud.fields[d].name == "rgba") idx_rgba = d;
00405 else if (mesh.cloud.fields[d].name == "normal_x") idx_normal_x = d;
00406 else if (mesh.cloud.fields[d].name == "normal_y") idx_normal_y = d;
00407 else if (mesh.cloud.fields[d].name == "normal_z") idx_normal_z = d;
00408 }
00409 if ( ( idx_x == -1 ) || ( idx_y == -1 ) || ( idx_z == -1 ) )
00410 nr_points = 0;
00411
00412
00413 vtk_mesh_points->SetNumberOfPoints (nr_points);
00414 if (nr_points > 0)
00415 {
00416 Eigen::Vector4f pt = Eigen::Vector4f::Zero ();
00417 Eigen::Array4i xyz_offset (mesh.cloud.fields[idx_x].offset, mesh.cloud.fields[idx_y].offset, mesh.cloud.fields[idx_z].offset, 0);
00418 for (vtkIdType cp = 0; cp < static_cast<vtkIdType> (nr_points); ++cp, xyz_offset += mesh.cloud.point_step)
00419 {
00420 memcpy(&pt[0], &mesh.cloud.data[xyz_offset[0]], sizeof (float));
00421 memcpy(&pt[1], &mesh.cloud.data[xyz_offset[1]], sizeof (float));
00422 memcpy(&pt[2], &mesh.cloud.data[xyz_offset[2]], sizeof (float));
00423 vtk_mesh_points->InsertPoint (cp, pt[0], pt[1], pt[2]);
00424 }
00425 }
00426
00427
00428 if (nr_polygons > 0)
00429 {
00430 for (unsigned int i = 0; i < nr_polygons; i++)
00431 {
00432 unsigned int nr_points_in_polygon = static_cast<unsigned int> (mesh.polygons[i].vertices.size ());
00433 vtk_mesh_polygons->InsertNextCell (nr_points_in_polygon);
00434 for (unsigned int j = 0; j < nr_points_in_polygon; j++)
00435 vtk_mesh_polygons->InsertCellPoint (mesh.polygons[i].vertices[j]);
00436 }
00437 poly_data->SetPolys (vtk_mesh_polygons);
00438 }
00439
00440
00441 if (idx_rgb != -1 || idx_rgba != -1)
00442 {
00443 vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New ();
00444 colors->SetNumberOfComponents (3);
00445 colors->SetName ("Colors");
00446 pcl::RGB rgb;
00447 int offset = (idx_rgb != -1) ? mesh.cloud.fields[idx_rgb].offset : mesh.cloud.fields[idx_rgba].offset;
00448 for (vtkIdType cp = 0; cp < nr_points; ++cp)
00449 {
00450 memcpy (&rgb, &mesh.cloud.data[cp * mesh.cloud.point_step + offset], sizeof (RGB));
00451 const unsigned char color[3] = {rgb.r, rgb.g, rgb.b};
00452 colors->InsertNextTupleValue (color);
00453 }
00454 poly_data->GetPointData ()->SetScalars (colors);
00455 }
00456
00457
00458 if (( idx_normal_x != -1 ) && ( idx_normal_y != -1 ) && ( idx_normal_z != -1 ))
00459 {
00460 vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New ();
00461 normals->SetNumberOfComponents (3);
00462 float nx = 0.0f, ny = 0.0f, nz = 0.0f;
00463 for (vtkIdType cp = 0; cp < nr_points; ++cp)
00464 {
00465 memcpy (&nx, &mesh.cloud.data[cp*mesh.cloud.point_step+mesh.cloud.fields[idx_normal_x].offset], sizeof (float));
00466 memcpy (&ny, &mesh.cloud.data[cp*mesh.cloud.point_step+mesh.cloud.fields[idx_normal_y].offset], sizeof (float));
00467 memcpy (&nz, &mesh.cloud.data[cp*mesh.cloud.point_step+mesh.cloud.fields[idx_normal_z].offset], sizeof (float));
00468 const float normal[3] = {nx, ny, nz};
00469 normals->InsertNextTupleValue (normal);
00470 }
00471 poly_data->GetPointData()->SetNormals (normals);
00472 }
00473
00474 if (poly_data->GetPoints () == NULL)
00475 return (0);
00476 return (static_cast<int> (poly_data->GetPoints ()->GetNumberOfPoints ()));
00477 }
00478
00480 void
00481 pcl::io::saveRangeImagePlanarFilePNG (
00482 const std::string &file_name, const pcl::RangeImagePlanar& range_image)
00483 {
00484 vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
00485 image->SetDimensions(range_image.width, range_image.height, 1);
00486 image->SetNumberOfScalarComponents(1);
00487 image->SetScalarTypeToFloat();
00488 image->AllocateScalars();
00489
00490 int* dims = image->GetDimensions();
00491
00492 for (int y = 0; y < dims[1]; y++)
00493 {
00494 for (int x = 0; x < dims[0]; x++)
00495 {
00496 float* pixel = static_cast<float*>(image->GetScalarPointer(x,y,0));
00497 pixel[0] = range_image(y,x).range;
00498 }
00499 }
00500
00501
00502 float oldRange = static_cast<float> (image->GetScalarRange()[1] - image->GetScalarRange()[0]);
00503 float newRange = 255;
00504
00505 vtkSmartPointer<vtkImageShiftScale> shiftScaleFilter = vtkSmartPointer<vtkImageShiftScale>::New();
00506 shiftScaleFilter->SetOutputScalarTypeToUnsignedChar();
00507 shiftScaleFilter->SetInputConnection(image->GetProducerPort());
00508 shiftScaleFilter->SetShift(-1.0f * image->GetScalarRange()[0]);
00509 shiftScaleFilter->SetScale(newRange/oldRange);
00510 shiftScaleFilter->Update();
00511
00512 vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
00513 writer->SetFileName(file_name.c_str());
00514 writer->SetInputConnection(shiftScaleFilter->GetOutputPort());
00515 writer->Write();
00516 }
00517
00519 void
00520 pcl::io::pointCloudTovtkPolyData(const pcl::PCLPointCloud2Ptr& cloud, vtkSmartPointer<vtkPolyData>& poly_data)
00521 {
00522 if (!poly_data.GetPointer())
00523 poly_data = vtkSmartPointer<vtkPolyData>::New ();
00524
00525
00526
00527 size_t x_idx = pcl::getFieldIndex (*cloud, std::string ("x") );
00528 vtkSmartPointer<vtkPoints> cloud_points = vtkSmartPointer<vtkPoints>::New ();
00529 vtkSmartPointer<vtkCellArray> cloud_vertices = vtkSmartPointer<vtkCellArray>::New ();
00530
00531 vtkIdType pid[1];
00532 for (size_t point_idx = 0; point_idx < cloud->width * cloud->height; point_idx ++)
00533 {
00534 float point[3];
00535
00536 int point_offset = (int (point_idx) * cloud->point_step);
00537 int offset = point_offset + cloud->fields[x_idx].offset;
00538 memcpy (&point, &cloud->data[offset], sizeof (float)*3);
00539
00540 pid[0] = cloud_points->InsertNextPoint (point);
00541 cloud_vertices->InsertNextCell (1, pid);
00542 }
00543
00544
00545 poly_data->SetPoints (cloud_points);
00546 poly_data->SetVerts (cloud_vertices);
00547
00548
00549 int rgb_idx = pcl::getFieldIndex (*cloud, "rgb");
00550 if (rgb_idx != -1)
00551 {
00552
00553 vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New ();
00554
00555 colors->SetNumberOfComponents (3);
00556 colors->SetName ("rgb");
00557
00558 for (size_t point_idx = 0; point_idx < cloud->width * cloud->height; point_idx ++)
00559 {
00560 unsigned char bgr[3];
00561
00562 int point_offset = (int (point_idx) * cloud->point_step);
00563 int offset = point_offset + cloud->fields[rgb_idx].offset;
00564 memcpy (&bgr, &cloud->data[offset], sizeof (unsigned char)*3);
00565
00566 colors->InsertNextTuple3(bgr[2], bgr[1], bgr[0]);
00567 }
00568
00569 poly_data->GetCellData()->SetScalars(colors);
00570 }
00571
00572
00573 int intensity_idx = pcl::getFieldIndex (*cloud, "intensity");
00574 if (intensity_idx != -1)
00575 {
00576
00577 vtkSmartPointer<vtkFloatArray> cloud_intensity = vtkSmartPointer<vtkFloatArray>::New ();
00578 cloud_intensity->SetNumberOfComponents (1);
00579 cloud_intensity->SetName("intensity");
00580
00581 for (size_t point_idx = 0; point_idx < cloud->width * cloud->height; point_idx ++)
00582 {
00583 float intensity;
00584
00585 int point_offset = (int (point_idx) * cloud->point_step);
00586 int offset = point_offset + cloud->fields[intensity_idx].offset;
00587 memcpy (&intensity, &cloud->data[offset], sizeof(float));
00588
00589 cloud_intensity->InsertNextValue(intensity);
00590 }
00591
00592 poly_data->GetCellData()->AddArray(cloud_intensity);
00593 if (rgb_idx == -1)
00594 poly_data->GetCellData()->SetActiveAttribute("intensity", vtkDataSetAttributes::SCALARS);
00595 }
00596
00597
00598 int normal_x_idx = pcl::getFieldIndex (*cloud, std::string ("normal_x") );
00599 if (normal_x_idx != -1)
00600 {
00601
00602 vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
00603 normals->SetNumberOfComponents(3);
00604 normals->SetName("normals");
00605
00606 for (size_t point_idx = 0; point_idx < cloud->width * cloud->height; point_idx ++)
00607 {
00608 float normal[3];
00609
00610 int point_offset = (int (point_idx) * cloud->point_step);
00611 int offset = point_offset + cloud->fields[normal_x_idx].offset;
00612 memcpy (&normal, &cloud->data[offset], sizeof (float)*3);
00613
00614 normals->InsertNextTuple(normal);
00615 }
00616
00617 poly_data->GetCellData()->SetNormals(normals);
00618
00619 }
00620 }