43 #pragma GCC system_header 46 #include <pcl/PCLPointField.h> 47 #include <pcl/PCLPointCloud2.h> 48 #include <pcl/PCLImage.h> 49 #include <pcl/point_cloud.h> 50 #include <pcl/point_traits.h> 51 #include <pcl/for_each_type.h> 52 #include <pcl/exceptions.h> 53 #include <pcl/console/print.h> 55 #include <boost/foreach.hpp> 63 template<
typename Po
intT>
82 template<
typename Po
intT>
86 std::vector<FieldMapping>& map)
91 template<
typename Tag>
void 94 for (
const auto& field :
fields_)
102 map_.push_back (mapping);
111 const std::vector<pcl::PCLPointField>&
fields_;
112 std::vector<FieldMapping>&
map_;
123 template<
typename Po
intT>
void 128 for_each_type< typename traits::fieldList<PointT>::type > (mapper);
131 if (field_map.size() > 1)
134 MsgFieldMap::iterator i = field_map.begin(), j = i + 1;
135 while (j != field_map.end())
140 if (j->serialized_offset - i->serialized_offset == j->struct_offset - i->struct_offset)
142 i->size += (j->struct_offset + j->size) - (i->struct_offset + i->size);
143 j = field_map.erase(j);
167 template <
typename Po
intT>
void 179 cloud.
points.resize (num_points);
180 std::uint8_t* cloud_data =
reinterpret_cast<std::uint8_t*
>(&cloud.
points[0]);
185 if (field_map.size() == 1 &&
186 field_map[0].serialized_offset == 0 &&
187 field_map[0].struct_offset == 0 &&
189 field_map[0].size ==
sizeof(
PointT))
191 std::uint32_t cloud_row_step =
static_cast<std::uint32_t
> (
sizeof (
PointT) * cloud.
width);
192 const std::uint8_t* msg_data = &msg.
data[0];
196 memcpy (cloud_data, msg_data, msg.
data.size ());
200 for (std::uint32_t i = 0; i < msg.
height; ++i, cloud_data += cloud_row_step, msg_data += msg.
row_step)
201 memcpy (cloud_data, msg_data, cloud_row_step);
208 for (std::uint32_t row = 0; row < msg.
height; ++row)
210 const std::uint8_t* row_data = &msg.
data[row * msg.
row_step];
211 for (std::uint32_t col = 0; col < msg.
width; ++col)
213 const std::uint8_t* msg_data = row_data + col * msg.
point_step;
216 memcpy (cloud_data + mapping.struct_offset, msg_data + mapping.serialized_offset, mapping.size);
218 cloud_data +=
sizeof (
PointT);
228 template<
typename Po
intT>
void 232 createMapping<PointT> (msg.
fields, field_map);
240 template<
typename Po
intT>
void 246 msg.
width =
static_cast<std::uint32_t
>(cloud.
points.size ());
257 std::size_t data_size =
sizeof (
PointT) * cloud.
points.size ();
258 msg.
data.resize (data_size);
261 memcpy(&msg.
data[0], &cloud.
points[0], data_size);
281 template<
typename CloudT>
void 285 if (cloud.width == 0 && cloud.height == 0)
286 throw std::runtime_error(
"Needs to be a dense like cloud!!");
289 if (cloud.points.size () != cloud.width * cloud.height)
290 throw std::runtime_error(
"The width and height do not match the cloud size!");
291 msg.
height = cloud.height;
292 msg.
width = cloud.width;
297 msg.
step = msg.
width *
sizeof (std::uint8_t) * 3;
299 for (std::size_t y = 0; y < cloud.height; y++)
301 for (std::size_t x = 0; x < cloud.width; x++)
303 std::uint8_t * pixel = &(msg.
data[y * msg.
step + x * 3]);
304 memcpy (pixel, &cloud (x, y).rgb, 3 *
sizeof(std::uint8_t));
317 const auto predicate = [](
const auto& field) {
return field.name ==
"rgb"; };
318 const auto result = std::find_if(cloud.
fields.cbegin (), cloud.
fields.cend (), predicate);
319 if (result == cloud.
fields.end ())
320 throw std::runtime_error (
"No rgb field!!");
324 throw std::runtime_error (
"Needs to be a dense like cloud!!");
330 int rgb_offset = cloud.
fields[rgb_index].offset;
335 msg.
step =
static_cast<std::uint32_t
>(msg.
width *
sizeof (std::uint8_t) * 3);
338 for (std::size_t y = 0; y < cloud.
height; y++)
340 for (std::size_t x = 0; x < cloud.
width; x++, rgb_offset += point_step)
342 std::uint8_t * pixel = &(msg.
data[y * msg.
step + x * 3]);
343 memcpy (pixel, &(cloud.
data[rgb_offset]), 3 * sizeof (std::uint8_t));
void fromPCLPointCloud2(const pcl::PCLPointCloud2 &msg, pcl::PointCloud< PointT > &cloud, const MsgFieldMap &field_map)
Convert a PCLPointCloud2 binary data blob into a pcl::PointCloud<T> object using a field_map...
std::size_t struct_offset
std::vector< detail::FieldMapping > MsgFieldMap
std::vector<::pcl::PCLPointField > fields
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
std::vector< pcl::PCLPointField > & fields_
This file defines compatibility wrappers for low level I/O functions.
bool fieldOrdering(const FieldMapping &a, const FieldMapping &b)
std::size_t serialized_offset
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::vector< std::uint8_t > data
float distance(const PointT &p1, const PointT &p2)
std::uint32_t height
The point cloud height (if organized as an image-structure).
PointCloud represents the base class in PCL for storing collections of 3D points. ...
pcl::PCLHeader header
The point cloud header.
std::vector< std::uint8_t > data
void toPCLPointCloud2(const pcl::PointCloud< PointT > &cloud, pcl::PCLPointCloud2 &msg)
Convert a pcl::PointCloud<T> object to a PCLPointCloud2 binary data blob.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields)...
A point structure representing Euclidean xyz coordinates, and the RGB color.
FieldAdder(std::vector< pcl::PCLPointField > &fields)
std::vector< FieldMapping > & map_
void createMapping(const std::vector< pcl::PCLPointField > &msg_fields, MsgFieldMap &field_map)
const std::vector< pcl::PCLPointField > & fields_
FieldMapper(const std::vector< pcl::PCLPointField > &fields, std::vector< FieldMapping > &map)