vtk_lib_io.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Dirk Holz, University of Bonn.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id$
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") // no Polygon, but only a point cloud
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   // TODO: what about binary/ASCII modes?!?!?!
00080   // TODO: what about sensor position and orientation?!?!?!?
00081   // TODO: how to adequately catch exceptions thrown by the vtk writers?!
00082   std::string extension = file_name.substr (file_name.find_last_of (".") + 1);
00083   if (extension == ".pcd") // no Polygon, but only a point cloud
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   // First get the xyz information
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   // And put it in the mesh cloud
00253   pcl::toPCLPointCloud2 (*xyz_cloud, mesh.cloud);
00254 
00255 
00256   // Then the color information, if any
00257   vtkUnsignedCharArray* poly_colors = NULL;
00258   if (poly_data->GetPointData() != NULL)
00259     poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("Colors"));
00260 
00261   // some applications do not save the name of scalars (including PCL's native vtk_io)
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   // TODO: currently only handles rgb values with 3 components
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   // Then handle the normals, if any
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   // Now handle the polygons
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   // Add dummy material
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   // Handle the texture coordinates
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   // reset vtkPolyData object
00391   poly_data = vtkSmartPointer<vtkPolyData>::New (); // OR poly_data->Reset();
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   // get field indices for x, y, z (as well as rgb and/or rgba)
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   // copy point data
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   // copy polygon data
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   // copy color information
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   // copy normal information
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   // Compute the scaling
00502   float oldRange = static_cast<float> (image->GetScalarRange()[1] - image->GetScalarRange()[0]);
00503   float newRange = 255; // We want the output [0,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]); // brings the lower bound to 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 (); // OR poly_data->Reset();
00524 
00525 
00526   // Add Points
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   //set the points and vertices we created as the geometry and topology of the polydata
00545   poly_data->SetPoints (cloud_points);
00546   poly_data->SetVerts (cloud_vertices);
00547 
00548   // Add RGB
00549   int rgb_idx = pcl::getFieldIndex (*cloud, "rgb");
00550   if (rgb_idx != -1)
00551   {
00552     //std::cout << "Adding rgb" << std::endl;
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   // Add Intensity
00573   int intensity_idx = pcl::getFieldIndex (*cloud, "intensity");
00574   if (intensity_idx != -1)
00575   {
00576     //std::cout << "Adding intensity" << std::endl;
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   // Add Normals
00598   int normal_x_idx = pcl::getFieldIndex (*cloud, std::string ("normal_x") );
00599   if (normal_x_idx != -1)
00600   {
00601     //std::cout << "Adding normals" << std::endl;
00602     vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
00603     normals->SetNumberOfComponents(3); //3d normals (ie x,y,z)
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     //poly_data->GetCellData()->SetActiveAttribute("normals", vtkDataSetAttributes::SCALARS);
00619   }
00620 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:38:41