Point Cloud Library (PCL)  1.14.1
point_cloud_geometry_handlers.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2012-, Open Perception, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #pragma once
39 
40 #if defined __GNUC__
41 #pragma GCC system_header
42 #endif
43 
44 // PCL includes
45 #include <pcl/pcl_base.h> // for UNAVAILABLE
46 #include <pcl/point_cloud.h>
47 #include <pcl/common/io.h>
48 // VTK includes
49 #include <vtkSmartPointer.h>
50 #include <vtkPoints.h>
51 #include <vtkFloatArray.h>
52 
53 namespace pcl
54 {
55  namespace visualization
56  {
57  /** \brief Base handler class for PointCloud geometry.
58  * \author Radu B. Rusu
59  * \ingroup visualization
60  */
61  template <typename PointT>
63  {
64  public:
66  using PointCloudPtr = typename PointCloud::Ptr;
68 
69  using Ptr = shared_ptr<PointCloudGeometryHandler<PointT> >;
70  using ConstPtr = shared_ptr<const PointCloudGeometryHandler<PointT> >;
71 
72  /** \brief Constructor. */
74  cloud_ (cloud), capable_ (false),
76  fields_ ()
77  {}
78 
79  /** \brief Destructor. */
80  virtual ~PointCloudGeometryHandler() = default;
81 
82  /** \brief Abstract getName method.
83  * \return the name of the class/object.
84  */
85  virtual std::string
86  getName () const = 0;
87 
88  /** \brief Abstract getFieldName method. */
89  virtual std::string
90  getFieldName () const = 0;
91 
92  /** \brief Check if this handler is capable of handling the input data or not. */
93  inline bool
94  isCapable () const { return (capable_); }
95 
96  /** \brief Obtain the actual point geometry for the input dataset in VTK format.
97  * \param[out] points the resultant geometry
98  */
99  virtual void
100  getGeometry (vtkSmartPointer<vtkPoints> &points) const = 0;
101 
102  /** \brief Set the input cloud to be used.
103  * \param[in] cloud the input cloud to be used by the handler
104  */
105  void
107  {
108  cloud_ = cloud;
109  }
110 
111  protected:
112  /** \brief A pointer to the input dataset. */
114 
115  /** \brief True if this handler is capable of handling the input data, false
116  * otherwise.
117  */
118  bool capable_;
119 
120  /** \brief The index of the field holding the X data. */
122 
123  /** \brief The index of the field holding the Y data. */
125 
126  /** \brief The index of the field holding the Z data. */
128 
129  /** \brief The list of fields available for this PointCloud. */
130  std::vector<pcl::PCLPointField> fields_;
131  };
132 
133  //////////////////////////////////////////////////////////////////////////////////////
134  /** \brief XYZ handler class for PointCloud geometry. Given an input dataset, all XYZ
135  * data present in fields "x", "y", and "z" is extracted and displayed on screen.
136  * \author Radu B. Rusu
137  * \ingroup visualization
138  */
139  template <typename PointT>
141  {
142  public:
144  using PointCloudPtr = typename PointCloud::Ptr;
146 
147  using Ptr = shared_ptr<PointCloudGeometryHandlerXYZ<PointT> >;
148  using ConstPtr = shared_ptr<const PointCloudGeometryHandlerXYZ<PointT> >;
149 
150  /** \brief Constructor. */
152 
153  /** \brief Class getName method. */
154  virtual std::string
155  getName () const { return ("PointCloudGeometryHandlerXYZ"); }
156 
157  /** \brief Get the name of the field used. */
158  virtual std::string
159  getFieldName () const { return ("xyz"); }
160 
161  /** \brief Obtain the actual point geometry for the input dataset in VTK format.
162  * \param[out] points the resultant geometry
163  */
164  virtual void
165  getGeometry (vtkSmartPointer<vtkPoints> &points) const;
166 
167  private:
168  // Members derived from the base class
175  };
176 
177  //////////////////////////////////////////////////////////////////////////////////////
178  /** \brief Surface normal handler class for PointCloud geometry. Given an input
179  * dataset, all data present in fields "normal_x", "normal_y", and "normal_z" is
180  * extracted and displayed on screen as XYZ data.
181  * \author Radu B. Rusu
182  * \ingroup visualization
183  */
184  template <typename PointT>
186  {
187  public:
189  using PointCloudPtr = typename PointCloud::Ptr;
191 
192  using Ptr = shared_ptr<PointCloudGeometryHandlerSurfaceNormal<PointT> >;
193  using ConstPtr = shared_ptr<const PointCloudGeometryHandlerSurfaceNormal<PointT> >;
194 
195  /** \brief Constructor. */
197 
198  /** \brief Class getName method. */
199  virtual std::string
200  getName () const { return ("PointCloudGeometryHandlerSurfaceNormal"); }
201 
202  /** \brief Get the name of the field used. */
203  virtual std::string
204  getFieldName () const { return ("normal_xyz"); }
205 
206  /** \brief Obtain the actual point geometry for the input dataset in VTK format.
207  * \param[out] points the resultant geometry
208  */
209  virtual void
210  getGeometry (vtkSmartPointer<vtkPoints> &points) const;
211 
212  private:
213  // Members derived from the base class
220  };
221 
222  //////////////////////////////////////////////////////////////////////////////////////
223  /** \brief Custom handler class for PointCloud geometry. Given an input dataset and
224  * three user defined fields, all data present in them is extracted and displayed on
225  * screen as XYZ data.
226  * \author Radu B. Rusu
227  * \ingroup visualization
228  */
229  template <typename PointT>
231  {
232  public:
234  using PointCloudPtr = typename PointCloud::Ptr;
236 
237  using Ptr = shared_ptr<PointCloudGeometryHandlerCustom<PointT> >;
238  using ConstPtr = shared_ptr<const PointCloudGeometryHandlerCustom<PointT> >;
239 
240  /** \brief Constructor. */
242  const std::string &x_field_name,
243  const std::string &y_field_name,
244  const std::string &z_field_name)
246  {
247  field_x_idx_ = pcl::getFieldIndex<PointT> (x_field_name, fields_);
248  if (field_x_idx_ == UNAVAILABLE)
249  return;
250  field_y_idx_ = pcl::getFieldIndex<PointT> (y_field_name, fields_);
251  if (field_y_idx_ == UNAVAILABLE)
252  return;
253  field_z_idx_ = pcl::getFieldIndex<PointT> (z_field_name, fields_);
254  if (field_z_idx_ == UNAVAILABLE)
255  return;
256  field_name_ = x_field_name + y_field_name + z_field_name;
257  capable_ = true;
258  }
259 
260  /** \brief Class getName method. */
261  virtual std::string
262  getName () const { return ("PointCloudGeometryHandlerCustom"); }
263 
264  /** \brief Get the name of the field used. */
265  virtual std::string
266  getFieldName () const { return (field_name_); }
267 
268  /** \brief Obtain the actual point geometry for the input dataset in VTK format.
269  * \param[out] points the resultant geometry
270  */
271  virtual void
273  {
274  if (!capable_)
275  return;
276 
277  if (!points)
279  points->SetDataTypeToFloat ();
280  points->SetNumberOfPoints (cloud_->size ());
281 
282  float data;
283  // Add all points
284  double p[3];
285  for (vtkIdType i = 0; i < static_cast<vtkIdType> (cloud_->size ()); ++i)
286  {
287  // Copy the value at the specified field
288  const std::uint8_t* pt_data = reinterpret_cast<const std::uint8_t*> (&(*cloud_)[i]);
289  memcpy (&data, pt_data + fields_[field_x_idx_].offset, sizeof (float));
290  p[0] = data;
291 
292  memcpy (&data, pt_data + fields_[field_y_idx_].offset, sizeof (float));
293  p[1] = data;
294 
295  memcpy (&data, pt_data + fields_[field_z_idx_].offset, sizeof (float));
296  p[2] = data;
297 
298  points->SetPoint (i, p);
299  }
300  }
301 
302  private:
303  // Members derived from the base class
310 
311  /** \brief Name of the field used to create the geometry handler. */
312  std::string field_name_;
313  };
314 
315  ///////////////////////////////////////////////////////////////////////////////////////
316  /** \brief Base handler class for PointCloud geometry.
317  * \author Radu B. Rusu
318  * \ingroup visualization
319  */
320  template <>
322  {
323  public:
327 
328  using Ptr = shared_ptr<PointCloudGeometryHandler<PointCloud> >;
329  using ConstPtr = shared_ptr<const PointCloudGeometryHandler<PointCloud> >;
330 
331  /** \brief Constructor. */
332  PointCloudGeometryHandler (const PointCloudConstPtr &cloud, const Eigen::Vector4f & = Eigen::Vector4f::Zero ())
333  : cloud_ (cloud)
334  , capable_ (false)
335  , field_x_idx_ (UNAVAILABLE)
336  , field_y_idx_ (UNAVAILABLE)
337  , field_z_idx_ (UNAVAILABLE)
338  , fields_ (cloud_->fields)
339  {
340  }
341 
342  /** \brief Destructor. */
343  virtual ~PointCloudGeometryHandler() = default;
344 
345  /** \brief Abstract getName method. */
346  virtual std::string
347  getName () const = 0;
348 
349  /** \brief Abstract getFieldName method. */
350  virtual std::string
351  getFieldName () const = 0;
352 
353  /** \brief Check if this handler is capable of handling the input data or not. */
354  inline bool
355  isCapable () const { return (capable_); }
356 
357  /** \brief Obtain the actual point geometry for the input dataset in VTK format.
358  * \param[out] points the resultant geometry
359  */
360  virtual void
361  getGeometry (vtkSmartPointer<vtkPoints> &points) const;
362 
363  /** \brief Set the input cloud to be used.
364  * \param[in] cloud the input cloud to be used by the handler
365  */
366  void
368  {
369  cloud_ = cloud;
370  }
371 
372  protected:
373  /** \brief A pointer to the input dataset. */
375 
376  /** \brief True if this handler is capable of handling the input data, false
377  * otherwise.
378  */
379  bool capable_;
380 
381  /** \brief The index of the field holding the X data. */
383 
384  /** \brief The index of the field holding the Y data. */
386 
387  /** \brief The index of the field holding the Z data. */
389 
390  /** \brief The list of fields available for this PointCloud. */
391  std::vector<pcl::PCLPointField> fields_;
392  };
393 
394  //////////////////////////////////////////////////////////////////////////////////////
395  /** \brief XYZ handler class for PointCloud geometry. Given an input dataset, all XYZ
396  * data present in fields "x", "y", and "z" is extracted and displayed on screen.
397  * \author Radu B. Rusu
398  * \ingroup visualization
399  */
400  template <>
401  class PCL_EXPORTS PointCloudGeometryHandlerXYZ<pcl::PCLPointCloud2> : public PointCloudGeometryHandler<pcl::PCLPointCloud2>
402  {
403  public:
407 
408  using Ptr = shared_ptr<PointCloudGeometryHandlerXYZ<PointCloud> >;
409  using ConstPtr = shared_ptr<const PointCloudGeometryHandlerXYZ<PointCloud> >;
410 
411  /** \brief Constructor. */
413 
414  /** \brief Class getName method. */
415  virtual std::string
416  getName () const { return ("PointCloudGeometryHandlerXYZ"); }
417 
418  /** \brief Get the name of the field used. */
419  virtual std::string
420  getFieldName () const { return ("xyz"); }
421  };
422 
423  //////////////////////////////////////////////////////////////////////////////////////
424  /** \brief Surface normal handler class for PointCloud geometry. Given an input
425  * dataset, all data present in fields "normal_x", "normal_y", and "normal_z" is
426  * extracted and displayed on screen as XYZ data.
427  * \author Radu B. Rusu
428  * \ingroup visualization
429  */
430  template <>
431  class PCL_EXPORTS PointCloudGeometryHandlerSurfaceNormal<pcl::PCLPointCloud2> : public PointCloudGeometryHandler<pcl::PCLPointCloud2>
432  {
433  public:
437 
438  using Ptr = shared_ptr<PointCloudGeometryHandlerSurfaceNormal<PointCloud> >;
439  using ConstPtr = shared_ptr<const PointCloudGeometryHandlerSurfaceNormal<PointCloud> >;
440 
441  /** \brief Constructor. */
443 
444  /** \brief Class getName method. */
445  virtual std::string
446  getName () const { return ("PointCloudGeometryHandlerSurfaceNormal"); }
447 
448  /** \brief Get the name of the field used. */
449  virtual std::string
450  getFieldName () const { return ("normal_xyz"); }
451  };
452 
453  //////////////////////////////////////////////////////////////////////////////////////
454  /** \brief Custom handler class for PointCloud geometry. Given an input dataset and
455  * three user defined fields, all data present in them is extracted and displayed on
456  * screen as XYZ data.
457  * \author Radu B. Rusu
458  * \ingroup visualization
459  */
460  template <>
461  class PCL_EXPORTS PointCloudGeometryHandlerCustom<pcl::PCLPointCloud2> : public PointCloudGeometryHandler<pcl::PCLPointCloud2>
462  {
463  public:
467 
468  /** \brief Constructor. */
470  const std::string &x_field_name,
471  const std::string &y_field_name,
472  const std::string &z_field_name);
473 
474  /** \brief Class getName method. */
475  virtual std::string
476  getName () const { return ("PointCloudGeometryHandlerCustom"); }
477 
478  /** \brief Get the name of the field used. */
479  virtual std::string
480  getFieldName () const { return (field_name_); }
481 
482  private:
483  /** \brief Name of the field used to create the geometry handler. */
484  std::string field_name_;
485  };
486  }
487 }
488 
489 #ifdef PCL_NO_PRECOMPILE
490 #include <pcl/visualization/impl/point_cloud_geometry_handlers.hpp>
491 #endif
std::vector< pcl::PCLPointField > fields_
The list of fields available for this PointCloud.
PointCloudGeometryHandlerXYZ(const PointCloudConstPtr &cloud)
Constructor.
PointCloudConstPtr cloud_
A pointer to the input dataset.
Custom handler class for PointCloud geometry.
static constexpr index_t UNAVAILABLE
Definition: pcl_base.h:62
virtual std::string getFieldName() const
Get the name of the field used.
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:413
virtual ~PointCloudGeometryHandler()=default
Destructor.
bool capable_
True if this handler is capable of handling the input data, false otherwise.
virtual std::string getFieldName() const
Get the name of the field used.
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const
Obtain the actual point geometry for the input dataset in VTK format.
virtual std::string getFieldName() const
Get the name of the field used.
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
Definition: types.h:112
void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
Surface normal handler class for PointCloud geometry.
virtual std::string getName() const
Class getName method.
PointCloudGeometryHandler(const PointCloudConstPtr &cloud, const Eigen::Vector4f &=Eigen::Vector4f::Zero())
Constructor.
virtual std::string getName() const =0
Abstract getName method.
PointCloudGeometryHandler(const PointCloudConstPtr &cloud)
Constructor.
bool isCapable() const
Check if this handler is capable of handling the input data or not.
PointCloudGeometryHandlerSurfaceNormal(const PointCloudConstPtr &cloud)
Constructor.
virtual std::string getFieldName() const
Get the name of the field used.
virtual std::string getFieldName() const
Get the name of the field used.
PointCloudGeometryHandlerCustom(const PointCloudConstPtr &cloud, const std::string &x_field_name, const std::string &y_field_name, const std::string &z_field_name)
Constructor.
void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
shared_ptr< const PointCloudGeometryHandler< PointT > > ConstPtr
PointCloud represents the base class in PCL for storing collections of 3D points. ...
Definition: distances.h:55
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const
Obtain the actual point geometry for the input dataset in VTK format.
shared_ptr< PointCloudGeometryHandler< PointT > > Ptr
virtual std::string getName() const
Class getName method.
bool isCapable() const
Check if this handler is capable of handling the input data or not.
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:414
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const =0
Obtain the actual point geometry for the input dataset in VTK format.
Base handler class for PointCloud geometry.
index_t field_y_idx_
The index of the field holding the Y data.
A point structure representing Euclidean xyz coordinates, and the RGB color.
virtual std::string getName() const
Class getName method.
std::vector< pcl::PCLPointField > fields_
The list of fields available for this PointCloud.
shared_ptr< const PointCloudGeometryHandler< PointCloud > > ConstPtr
virtual std::string getFieldName() const =0
Abstract getFieldName method.
index_t field_x_idx_
The index of the field holding the X data.
bool capable_
True if this handler is capable of handling the input data, false otherwise.
index_t field_z_idx_
The index of the field holding the Z data.
virtual void getGeometry(vtkSmartPointer< vtkPoints > &points) const
Obtain the actual point geometry for the input dataset in VTK format.