Go to the documentation of this file.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
00039
00040 #include <pcl/point_types.h>
00041 #include <pcl/io/vtk_io.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <pcl/common/io.h>
00045
00047 int
00048 pcl::io::saveVTKFile (const std::string &file_name,
00049 const pcl::PolygonMesh &triangles, unsigned precision)
00050 {
00051 if (triangles.cloud.data.empty ())
00052 {
00053 PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no data!\n");
00054 return (-1);
00055 }
00056
00057
00058 std::ofstream fs;
00059 fs.precision (precision);
00060 fs.open (file_name.c_str ());
00061
00062 unsigned int nr_points = triangles.cloud.width * triangles.cloud.height;
00063 unsigned int point_size = static_cast<unsigned int> (triangles.cloud.data.size () / nr_points);
00064
00065
00066 fs << "# vtk DataFile Version 3.0\nvtk output\nASCII\nDATASET POLYDATA\nPOINTS " << nr_points << " float" << std::endl;
00067
00068
00069 for (unsigned int i = 0; i < nr_points; ++i)
00070 {
00071 int xyz = 0;
00072 for (size_t d = 0; d < triangles.cloud.fields.size (); ++d)
00073 {
00074 int count = triangles.cloud.fields[d].count;
00075 if (count == 0)
00076 count = 1;
00077 int c = 0;
00078 if ((triangles.cloud.fields[d].datatype == sensor_msgs::PointField::FLOAT32) && (
00079 triangles.cloud.fields[d].name == "x" ||
00080 triangles.cloud.fields[d].name == "y" ||
00081 triangles.cloud.fields[d].name == "z"))
00082 {
00083 float value;
00084 memcpy (&value, &triangles.cloud.data[i * point_size + triangles.cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
00085 fs << value;
00086 if (++xyz == 3)
00087 break;
00088 }
00089 fs << " ";
00090 }
00091 if (xyz != 3)
00092 {
00093 PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no XYZ data!\n");
00094 return (-2);
00095 }
00096 fs << std::endl;
00097 }
00098
00099
00100 fs << "\nVERTICES " << nr_points << " " << 2*nr_points << std::endl;
00101 for (unsigned int i = 0; i < nr_points; ++i)
00102 fs << "1 " << i << std::endl;
00103
00104
00105
00106 size_t triangle_size = triangles.polygons.size ();
00107 size_t correct_number = triangle_size;
00108 for (size_t i = 0; i < triangle_size; ++i)
00109 correct_number += triangles.polygons[i].vertices.size ();
00110 fs << "\nPOLYGONS " << triangle_size << " " << correct_number << std::endl;
00111 for (size_t i = 0; i < triangle_size; ++i)
00112 {
00113 fs << triangles.polygons[i].vertices.size () << " ";
00114 size_t j = 0;
00115 for (j = 0; j < triangles.polygons[i].vertices.size () - 1; ++j)
00116 fs << triangles.polygons[i].vertices[j] << " ";
00117 fs << triangles.polygons[i].vertices[j] << std::endl;
00118 }
00119
00120
00121 int field_index = getFieldIndex (triangles.cloud, "rgb");
00122 if (field_index != -1)
00123 {
00124 fs << "\nPOINT_DATA " << nr_points << "\nCOLOR_SCALARS scalars 3\n";
00125 for (unsigned int i = 0; i < nr_points; ++i)
00126 {
00127 int count = triangles.cloud.fields[field_index].count;
00128 if (count == 0)
00129 count = 1;
00130 int c = 0;
00131 if (triangles.cloud.fields[field_index].datatype == sensor_msgs::PointField::FLOAT32)
00132 {
00133 pcl::RGB color;
00134 memcpy (&color, &triangles.cloud.data[i * point_size + triangles.cloud.fields[field_index].offset + c * sizeof (float)], sizeof (RGB));
00135 int r = color.r;
00136 int g = color.g;
00137 int b = color.b;
00138 fs << static_cast<float> (r) / 255.0f << " " << static_cast<float> (g) / 255.0f << " " << static_cast<float> (b) / 255.0f;
00139 }
00140 fs << std::endl;
00141 }
00142 }
00143
00144
00145 fs.close ();
00146 return (0);
00147 }
00148
00150 int
00151 pcl::io::saveVTKFile (const std::string &file_name,
00152 const sensor_msgs::PointCloud2 &cloud, unsigned precision)
00153 {
00154 if (cloud.data.empty ())
00155 {
00156 PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no data!\n");
00157 return (-1);
00158 }
00159
00160
00161 std::ofstream fs;
00162 fs.precision (precision);
00163 fs.open (file_name.c_str ());
00164
00165 unsigned int nr_points = cloud.width * cloud.height;
00166 unsigned int point_size = static_cast<unsigned int> (cloud.data.size () / nr_points);
00167
00168
00169 fs << "# vtk DataFile Version 3.0\nvtk output\nASCII\nDATASET POLYDATA\nPOINTS " << nr_points << " float" << std::endl;
00170
00171
00172 for (unsigned int i = 0; i < nr_points; ++i)
00173 {
00174 int xyz = 0;
00175 for (size_t d = 0; d < cloud.fields.size (); ++d)
00176 {
00177 int count = cloud.fields[d].count;
00178 if (count == 0)
00179 count = 1;
00180 int c = 0;
00181 if ((cloud.fields[d].datatype == sensor_msgs::PointField::FLOAT32) && (
00182 cloud.fields[d].name == "x" ||
00183 cloud.fields[d].name == "y" ||
00184 cloud.fields[d].name == "z"))
00185 {
00186 float value;
00187 memcpy (&value, &cloud.data[i * point_size + cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
00188 fs << value;
00189 if (++xyz == 3)
00190 break;
00191 }
00192 fs << " ";
00193 }
00194 if (xyz != 3)
00195 {
00196 PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no XYZ data!\n");
00197 return (-2);
00198 }
00199 fs << std::endl;
00200 }
00201
00202
00203 fs << "\nVERTICES " << nr_points << " " << 2*nr_points << std::endl;
00204 for (unsigned int i = 0; i < nr_points; ++i)
00205 fs << "1 " << i << std::endl;
00206
00207
00208 int field_index = getFieldIndex (cloud, "rgb");
00209 if (field_index != -1)
00210 {
00211 fs << "\nPOINT_DATA " << nr_points << "\nCOLOR_SCALARS scalars 3\n";
00212 for (unsigned int i = 0; i < nr_points; ++i)
00213 {
00214 int count = cloud.fields[field_index].count;
00215 if (count == 0)
00216 count = 1;
00217 int c = 0;
00218 if (cloud.fields[field_index].datatype == sensor_msgs::PointField::FLOAT32)
00219 {
00220 pcl::RGB color;
00221 memcpy (&color, &cloud.data[i * point_size + cloud.fields[field_index].offset + c * sizeof (float)], sizeof (RGB));
00222 int r = color.r;
00223 int g = color.g;
00224 int b = color.b;
00225 fs << static_cast<float> (r) / 255.0f << " " << static_cast<float> (g) / 255.0f << " " << static_cast<float> (b) / 255.0f;
00226 }
00227 fs << std::endl;
00228 }
00229 }
00230
00231
00232 fs.close ();
00233 return (0);
00234 }
00235