Point Cloud Library (PCL)  1.11.1
register_point_struct.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id$
38  *
39  */
40 
41 #pragma once
42 
43 #ifdef __GNUC__
44 #pragma GCC system_header
45 #endif
46 
47 #if defined _MSC_VER
48  #pragma warning (push, 2)
49  // 4244 : conversion from 'type1' to 'type2', possible loss of data
50  #pragma warning (disable: 4244)
51 #endif
52 
53 //https://bugreports.qt-project.org/browse/QTBUG-22829
54 #ifndef Q_MOC_RUN
55 #include <pcl/point_struct_traits.h> // for pcl::traits::POD, POINT_CLOUD_REGISTER_FIELD_(NAME, OFFSET, DATATYPE), POINT_CLOUD_REGISTER_POINT_FIELD_LIST
56 #include <boost/mpl/assert.hpp> // for BOOST_MPL_ASSERT_MSG
57 #include <boost/preprocessor/seq/for_each.hpp> // for BOOST_PP_SEQ_FOR_EACH
58 #include <boost/preprocessor/seq/transform.hpp> // for BOOST_PP_SEQ_TRANSFORM
59 #include <boost/preprocessor/tuple/elem.hpp> // for BOOST_PP_TUPLE_ELEM
60 #include <boost/preprocessor/cat.hpp> // for BOOST_PP_CAT
61 #endif
62 
63 #include <cstdint> // for std::uint32_t
64 #include <type_traits> // for std::enable_if_t, std::is_array, std::remove_const_t, std::remove_all_extents_t
65 
66 // Must be used in global namespace with name fully qualified
67 #define POINT_CLOUD_REGISTER_POINT_STRUCT(name, fseq) \
68  POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, \
69  BOOST_PP_CAT(POINT_CLOUD_REGISTER_POINT_STRUCT_X fseq, 0))
70  /***/
71 
72 #define POINT_CLOUD_REGISTER_POINT_WRAPPER(wrapper, pod) \
73  BOOST_MPL_ASSERT_MSG(sizeof(wrapper) == sizeof(pod), POINT_WRAPPER_AND_POD_TYPES_HAVE_DIFFERENT_SIZES, (wrapper&, pod&)); \
74  namespace pcl { \
75  namespace traits { \
76  template<> struct POD<wrapper> { using type = pod; }; \
77  } \
78  }
79  /***/
80 
81 // These macros help transform the unusual data structure (type, name, tag)(type, name, tag)...
82 // into a proper preprocessor sequence of 3-tuples ((type, name, tag))((type, name, tag))...
83 #define POINT_CLOUD_REGISTER_POINT_STRUCT_X(type, name, tag) \
84  ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_Y
85 #define POINT_CLOUD_REGISTER_POINT_STRUCT_Y(type, name, tag) \
86  ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_X
87 #define POINT_CLOUD_REGISTER_POINT_STRUCT_X0
88 #define POINT_CLOUD_REGISTER_POINT_STRUCT_Y0
89 
90 namespace pcl
91 {
92  namespace traits
93  {
94  template<typename T> inline
95  std::enable_if_t<!std::is_array<T>::value>
96  plus (T &l, const T &r)
97  {
98  l += r;
99  }
100 
101  template<typename T> inline
102  std::enable_if_t<std::is_array<T>::value>
103  plus (std::remove_const_t<T> &l, const T &r)
104  {
105  using type = std::remove_all_extents_t<T>;
106  static const std::uint32_t count = sizeof (T) / sizeof (type);
107  for (std::uint32_t i = 0; i < count; ++i)
108  l[i] += r[i];
109  }
110 
111  template<typename T1, typename T2> inline
112  std::enable_if_t<!std::is_array<T1>::value>
113  plusscalar (T1 &p, const T2 &scalar)
114  {
115  p += scalar;
116  }
117 
118  template<typename T1, typename T2> inline
119  std::enable_if_t<std::is_array<T1>::value>
120  plusscalar (T1 &p, const T2 &scalar)
121  {
122  using type = std::remove_all_extents_t<T1>;
123  static const std::uint32_t count = sizeof (T1) / sizeof (type);
124  for (std::uint32_t i = 0; i < count; ++i)
125  p[i] += scalar;
126  }
127 
128  template<typename T> inline
129  std::enable_if_t<!std::is_array<T>::value>
130  minus (T &l, const T &r)
131  {
132  l -= r;
133  }
134 
135  template<typename T> inline
136  std::enable_if_t<std::is_array<T>::value>
137  minus (std::remove_const_t<T> &l, const T &r)
138  {
139  using type = std::remove_all_extents_t<T>;
140  static const std::uint32_t count = sizeof (T) / sizeof (type);
141  for (std::uint32_t i = 0; i < count; ++i)
142  l[i] -= r[i];
143  }
144 
145  template<typename T1, typename T2> inline
146  std::enable_if_t<!std::is_array<T1>::value>
147  minusscalar (T1 &p, const T2 &scalar)
148  {
149  p -= scalar;
150  }
151 
152  template<typename T1, typename T2> inline
153  std::enable_if_t<std::is_array<T1>::value>
154  minusscalar (T1 &p, const T2 &scalar)
155  {
156  using type = std::remove_all_extents_t<T1>;
157  static const std::uint32_t count = sizeof (T1) / sizeof (type);
158  for (std::uint32_t i = 0; i < count; ++i)
159  p[i] -= scalar;
160  }
161 
162  template<typename T1, typename T2> inline
163  std::enable_if_t<!std::is_array<T1>::value>
164  mulscalar (T1 &p, const T2 &scalar)
165  {
166  p *= scalar;
167  }
168 
169  template<typename T1, typename T2> inline
170  std::enable_if_t<std::is_array<T1>::value>
171  mulscalar (T1 &p, const T2 &scalar)
172  {
173  using type = std::remove_all_extents_t<T1>;
174  static const std::uint32_t count = sizeof (T1) / sizeof (type);
175  for (std::uint32_t i = 0; i < count; ++i)
176  p[i] *= scalar;
177  }
178 
179  template<typename T1, typename T2> inline
180  std::enable_if_t<!std::is_array<T1>::value>
181  divscalar (T1 &p, const T2 &scalar)
182  {
183  p /= scalar;
184  }
185 
186  template<typename T1, typename T2> inline
187  std::enable_if_t<std::is_array<T1>::value>
188  divscalar (T1 &p, const T2 &scalar)
189  {
190  using type = std::remove_all_extents_t<T1>;
191  static const std::uint32_t count = sizeof (T1) / sizeof (type);
192  for (std::uint32_t i = 0; i < count; ++i)
193  p[i] /= scalar;
194  }
195  }
196 }
197 
198 // Point operators
199 #define PCL_PLUSEQ_POINT_TAG(r, data, elem) \
200  pcl::traits::plus (lhs.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
201  rhs.BOOST_PP_TUPLE_ELEM(3, 1, elem));
202  /***/
203 
204 #define PCL_PLUSEQSC_POINT_TAG(r, data, elem) \
205  pcl::traits::plusscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
206  scalar);
207  /***/
208  //p.BOOST_PP_TUPLE_ELEM(3, 1, elem) += scalar;
209 
210 #define PCL_MINUSEQ_POINT_TAG(r, data, elem) \
211  pcl::traits::minus (lhs.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
212  rhs.BOOST_PP_TUPLE_ELEM(3, 1, elem));
213  /***/
214 
215 #define PCL_MINUSEQSC_POINT_TAG(r, data, elem) \
216  pcl::traits::minusscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
217  scalar);
218  /***/
219  //p.BOOST_PP_TUPLE_ELEM(3, 1, elem) -= scalar;
220 
221 #define PCL_MULEQSC_POINT_TAG(r, data, elem) \
222  pcl::traits::mulscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
223  scalar);
224  /***/
225 
226 #define PCL_DIVEQSC_POINT_TAG(r, data, elem) \
227  pcl::traits::divscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
228  scalar);
229  /***/
230 
231 // Construct type traits given full sequence of (type, name, tag) triples
232 // BOOST_MPL_ASSERT_MSG(std::is_pod<name>::value,
233 // REGISTERED_POINT_TYPE_MUST_BE_PLAIN_OLD_DATA, (name));
234 #define POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, seq) \
235  namespace pcl \
236  { \
237  namespace fields \
238  { \
239  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_TAG, name, seq) \
240  } \
241  namespace traits \
242  { \
243  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_NAME, name, seq) \
244  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_OFFSET, name, seq) \
245  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_DATATYPE, name, seq) \
246  POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, POINT_CLOUD_EXTRACT_TAGS(seq)) \
247  } \
248  namespace common \
249  { \
250  inline const name& \
251  operator+= (name& lhs, const name& rhs) \
252  { \
253  BOOST_PP_SEQ_FOR_EACH(PCL_PLUSEQ_POINT_TAG, _, seq) \
254  return (lhs); \
255  } \
256  inline const name& \
257  operator+= (name& p, const float& scalar) \
258  { \
259  BOOST_PP_SEQ_FOR_EACH(PCL_PLUSEQSC_POINT_TAG, _, seq) \
260  return (p); \
261  } \
262  inline const name operator+ (const name& lhs, const name& rhs) \
263  { name result = lhs; result += rhs; return (result); } \
264  inline const name operator+ (const float& scalar, const name& p) \
265  { name result = p; result += scalar; return (result); } \
266  inline const name operator+ (const name& p, const float& scalar) \
267  { name result = p; result += scalar; return (result); } \
268  inline const name& \
269  operator-= (name& lhs, const name& rhs) \
270  { \
271  BOOST_PP_SEQ_FOR_EACH(PCL_MINUSEQ_POINT_TAG, _, seq) \
272  return (lhs); \
273  } \
274  inline const name& \
275  operator-= (name& p, const float& scalar) \
276  { \
277  BOOST_PP_SEQ_FOR_EACH(PCL_MINUSEQSC_POINT_TAG, _, seq) \
278  return (p); \
279  } \
280  inline const name operator- (const name& lhs, const name& rhs) \
281  { name result = lhs; result -= rhs; return (result); } \
282  inline const name operator- (const float& scalar, const name& p) \
283  { name result = p; result -= scalar; return (result); } \
284  inline const name operator- (const name& p, const float& scalar) \
285  { name result = p; result -= scalar; return (result); } \
286  inline const name& \
287  operator*= (name& p, const float& scalar) \
288  { \
289  BOOST_PP_SEQ_FOR_EACH(PCL_MULEQSC_POINT_TAG, _, seq) \
290  return (p); \
291  } \
292  inline const name operator* (const float& scalar, const name& p) \
293  { name result = p; result *= scalar; return (result); } \
294  inline const name operator* (const name& p, const float& scalar) \
295  { name result = p; result *= scalar; return (result); } \
296  inline const name& \
297  operator/= (name& p, const float& scalar) \
298  { \
299  BOOST_PP_SEQ_FOR_EACH(PCL_DIVEQSC_POINT_TAG, _, seq) \
300  return (p); \
301  } \
302  inline const name operator/ (const float& scalar, const name& p) \
303  { name result = p; result /= scalar; return (result); } \
304  inline const name operator/ (const name& p, const float& scalar) \
305  { name result = p; result /= scalar; return (result); } \
306  } \
307  }
308  /***/
309 
310 #define POINT_CLOUD_REGISTER_FIELD_TAG(r, name, elem) \
311  struct BOOST_PP_TUPLE_ELEM(3, 2, elem); \
312  /***/
313 
314 #define POINT_CLOUD_TAG_OP(s, data, elem) pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)
315 
316 #define POINT_CLOUD_EXTRACT_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_TAG_OP, _, seq)
317 
318 #if defined _MSC_VER
319  #pragma warning (pop)
320 #endif
std::enable_if_t<!std::is_array< T >::value > plus(T &l, const T &r)
std::uint32_t uint32_t
Definition: types.h:58
std::enable_if_t<!std::is_array< T1 >::value > mulscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T1 >::value > plusscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T >::value > minus(T &l, const T &r)
std::enable_if_t<!std::is_array< T1 >::value > minusscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T1 >::value > divscalar(T1 &p, const T2 &scalar)