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/type_traits.h>
51 #include <pcl/for_each_type.h>
52 #include <pcl/console/print.h>
59 template<
typename Po
intT>
67 f.
name = pcl::traits::name<PointT, U>::value;
68 f.
offset = pcl::traits::offset<PointT, U>::value;
69 f.
datatype = pcl::traits::datatype<PointT, U>::value;
70 f.
count = pcl::traits::datatype<PointT, U>::size;
78 template<
typename Po
intT>
82 std::vector<FieldMapping>& map)
87 template<
typename Tag>
void
90 for (
const auto& field :
fields_)
96 mapping.
struct_offset = pcl::traits::offset<PointT, Tag>::value;
97 mapping.
size =
sizeof (
typename pcl::traits::datatype<PointT, Tag>::type);
98 map_.push_back (mapping);
103 PCL_WARN (
"Failed to find match for field '%s'.\n", pcl::traits::name<PointT, Tag>::value);
107 const std::vector<pcl::PCLPointField>&
fields_;
108 std::vector<FieldMapping>&
map_;
119 template<
typename Po
intT>
void
124 for_each_type< typename traits::fieldList<PointT>::type > (mapper);
127 if (field_map.size() > 1)
130 MsgFieldMap::iterator i = field_map.begin(), j = i + 1;
131 while (j != field_map.end())
136 if (j->serialized_offset - i->serialized_offset == j->struct_offset - i->struct_offset)
138 i->size += (j->struct_offset + j->size) - (i->struct_offset + i->size);
139 j = field_map.erase(j);
163 template <
typename Po
intT>
void
175 std::uint8_t* cloud_data =
reinterpret_cast<std::uint8_t*
>(&cloud[0]);
180 if (field_map.size() == 1 &&
181 field_map[0].serialized_offset == 0 &&
182 field_map[0].struct_offset == 0 &&
184 field_map[0].size ==
sizeof(
PointT))
186 const auto cloud_row_step = (
sizeof (
PointT) * cloud.
width);
187 const std::uint8_t* msg_data = &msg.
data[0];
191 memcpy (cloud_data, msg_data, msg.
data.size ());
196 memcpy (cloud_data, msg_data, cloud_row_step);
205 const std::uint8_t* row_data = &msg.
data[row * msg.
row_step];
208 const std::uint8_t* msg_data = row_data + col * msg.
point_step;
211 memcpy (cloud_data + mapping.struct_offset, msg_data + mapping.serialized_offset, mapping.size);
213 cloud_data +=
sizeof (
PointT);
223 template<
typename Po
intT>
void
227 createMapping<PointT> (msg.
fields, field_map);
235 template<
typename Po
intT>
void
252 std::size_t data_size =
sizeof (
PointT) * cloud.
size ();
253 msg.
data.resize (data_size);
256 memcpy(&msg.
data[0], &cloud[0], data_size);
276 template<
typename CloudT>
void
280 if (cloud.width == 0 && cloud.height == 0)
281 throw std::runtime_error(
"Needs to be a dense like cloud!!");
284 if (cloud.size () != cloud.width * cloud.height)
285 throw std::runtime_error(
"The width and height do not match the cloud size!");
286 msg.
height = cloud.height;
287 msg.
width = cloud.width;
291 msg.
header = cloud.header;
293 msg.
step = msg.
width *
sizeof (std::uint8_t) * 3;
295 for (std::size_t y = 0; y < cloud.height; y++)
297 for (std::size_t x = 0; x < cloud.width; x++)
299 std::uint8_t * pixel = &(msg.
data[y * msg.
step + x * 3]);
300 memcpy (pixel, &cloud (x, y).rgb, 3 *
sizeof(std::uint8_t));
313 const auto predicate = [](
const auto& field) {
return field.name ==
"rgb"; };
314 const auto result = std::find_if(cloud.
fields.cbegin (), cloud.
fields.cend (), predicate);
315 if (result == cloud.
fields.end ())
316 throw std::runtime_error (
"No rgb field!!");
320 throw std::runtime_error (
"Needs to be a dense like cloud!!");
326 auto rgb_offset = cloud.
fields[rgb_index].offset;
332 msg.
step = (msg.
width *
sizeof (std::uint8_t) * 3);
335 for (std::size_t y = 0; y < cloud.
height; y++)
337 for (std::size_t x = 0; x < cloud.
width; x++, rgb_offset += point_step)
339 std::uint8_t * pixel = &(msg.
data[y * msg.
step + x * 3]);
340 memcpy (pixel, &(cloud.
data[rgb_offset]), 3 * sizeof (std::uint8_t));