37 #ifndef MAPPER_POINT_CLOUD_H_
38 #define MAPPER_POINT_CLOUD_H_
41 #include <pcl/conversions.h>
42 #include <pcl/for_each_type.h>
43 #include <pcl/point_cloud.h>
44 #include <pcl/point_traits.h>
46 #include <sensor_msgs/PointCloud2.h>
47 #include <boost/mpl/size.hpp>
48 #include <boost/ref.hpp>
58 template <
typename Stream,
typename Po
intT>
64 const char*
name = traits::name<PointT, U>::value;
65 uint32_t name_length = strlen(
name);
68 memcpy(
stream_.advance(name_length),
name, name_length);
70 uint32_t offset = traits::offset<PointT, U>::value;
73 uint8_t datatype = traits::datatype<PointT, U>::value;
76 uint32_t count = traits::datatype<PointT, U>::size;
83 template <
typename Po
intT>
89 uint32_t name_length = strlen(traits::name<PointT, U>::value);
90 length += name_length + 13;
104 #if ROS_VERSION_MINIMUM(1, 3, 1)
105 template <
typename T>
107 boost::shared_ptr<pcl::MsgFieldMap> mapping_;
109 DefaultMessageCreator() : mapping_(boost::make_shared<pcl::MsgFieldMap>()) {}
111 boost::shared_ptr<pcl::PointCloud<T> > operator()() {
112 boost::shared_ptr<pcl::PointCloud<T> > msg(
new pcl::PointCloud<T>());
113 pcl::detail::getMapping(*msg) = mapping_;
119 namespace message_traits {
120 template <
typename T>
123 return MD5Sum<sensor_msgs::PointCloud2>::value();
125 static const char*
value(
const pcl::PointCloud<T>&) {
return value(); }
127 static const uint64_t static_value1 =
128 MD5Sum<sensor_msgs::PointCloud2>::static_value1;
129 static const uint64_t static_value2 =
130 MD5Sum<sensor_msgs::PointCloud2>::static_value2;
134 ROS_STATIC_ASSERT(static_value1 == 0x1158d486dd51d683ULL);
135 ROS_STATIC_ASSERT(static_value2 == 0xce2f1be655c3c181ULL);
138 template <
typename T>
141 return DataType<sensor_msgs::PointCloud2>::value();
143 static const char*
value(
const pcl::PointCloud<T>&) {
return value(); }
146 template <
typename T>
149 return Definition<sensor_msgs::PointCloud2>::value();
151 static const char*
value(
const pcl::PointCloud<T>&) {
return value(); }
157 template <
typename T>
160 template <
typename T>
168 header_.reset(
new std_msgs::Header());
170 return &(header_->stamp);
173 header_const_.reset(
new std_msgs::Header());
175 return &(header_const_->stamp);
182 static boost::shared_ptr<std_msgs::Header> header_;
183 static boost::shared_ptr<std_msgs::Header> header_const_;
186 template <
typename T>
188 static std::string*
pointer(pcl::PointCloud<T>& m) {
189 return &m.header.frame_id;
191 static std::string
const*
pointer(
const pcl::PointCloud<T>& m) {
192 return &m.header.frame_id;
194 static std::string
value(
const pcl::PointCloud<T>& m) {
195 return m.header.frame_id;
201 namespace serialization {
202 template <
typename T>
204 template <
typename Stream>
205 inline static void write(Stream& stream,
const pcl::PointCloud<T>& m) {
206 stream.next(m.header);
210 uint32_t height = m.height, width = m.width;
211 if (height == 0 && width == 0) {
212 width = m.points.size();
219 typedef typename pcl::traits::fieldList<T>::type FieldList;
220 uint32_t fields_size = boost::mpl::size<FieldList>::value;
221 stream.next(fields_size);
222 pcl::for_each_type<FieldList>(
226 uint8_t is_bigendian =
false;
227 stream.next(is_bigendian);
230 uint32_t point_step =
sizeof(T);
231 stream.next(point_step);
232 uint32_t row_step = point_step * width;
233 stream.next(row_step);
234 uint32_t data_size = row_step * height;
235 stream.next(data_size);
236 memcpy(stream.advance(data_size), &m.points[0], data_size);
238 uint8_t is_dense = m.is_dense;
239 stream.next(is_dense);
242 template <
typename Stream>
243 inline static void read(Stream& stream, pcl::PointCloud<T>& m) {
244 std_msgs::Header header;
247 stream.next(m.height);
248 stream.next(m.width);
251 std::vector<sensor_msgs::PointField> fields;
255 boost::shared_ptr<pcl::MsgFieldMap>& mapping_ptr =
256 pcl::detail::getMapping(m);
260 mapping_ptr = boost::make_shared<pcl::MsgFieldMap>();
262 pcl::MsgFieldMap& mapping = *mapping_ptr;
263 if (mapping.empty()) pcl::createMapping<T>(fields, mapping);
265 uint8_t is_bigendian;
266 stream.next(is_bigendian);
267 uint32_t point_step, row_step;
268 stream.next(point_step);
269 stream.next(row_step);
273 stream.next(data_size);
274 assert(data_size == m.height * m.width * point_step);
275 m.points.resize(m.height * m.width);
276 uint8_t* m_data =
reinterpret_cast<uint8_t*
>(&m.points[0]);
278 if (mapping.size() == 1 && mapping[0].serialized_offset == 0 &&
279 mapping[0].struct_offset == 0 && point_step ==
sizeof(T)) {
280 uint32_t m_row_step =
sizeof(T) * m.width;
282 if (m_row_step == row_step) {
283 memcpy(m_data, stream.advance(data_size), data_size);
285 for (uint32_t i = 0; i < m.height; ++i, m_data += m_row_step)
286 memcpy(m_data, stream.advance(row_step), m_row_step);
290 for (uint32_t row = 0; row < m.height; ++row) {
291 const uint8_t* stream_data = stream.advance(row_step);
292 for (uint32_t col = 0; col < m.width;
293 ++col, stream_data += point_step) {
294 BOOST_FOREACH(
const pcl::detail::FieldMapping& fm, mapping) {
295 memcpy(m_data + fm.struct_offset,
296 stream_data + fm.serialized_offset, fm.size);
304 stream.next(is_dense);
305 m.is_dense = is_dense;
311 length += serializationLength(m.header);
315 typedef typename pcl::traits::fieldList<T>::type FieldList;
316 pcl::for_each_type<FieldList>(boost::ref(fl));
324 length += m.points.size() *
sizeof(T);
336 #endif // MAPPER_POINT_CLOUD_H_