Main MRPT website > C++ reference
MRPT logo
CPointCloud.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 
29 #ifndef opengl_CPointCloud_H
30 #define opengl_CPointCloud_H
31 
35 #include <mrpt/utils/adapters.h>
36 
37 namespace mrpt
38 {
39  namespace opengl
40  {
42 
43  // This must be added to any CSerializable derived class:
45 
46 
47  /** A cloud of points, all with the same color or each depending on its value along a particular coordinate axis.
48  * This class is just an OpenGL representation of a point cloud. For operating with maps of points, see mrpt::slam::CPointsMap and derived classes.
49  *
50  * To load from a points-map, CPointCloud::loadFromPointsMap().
51  *
52  * This class uses smart optimizations while rendering to efficiently draw clouds of millions of points,
53  * as described in this page: http://www.mrpt.org/Efficiently_rendering_point_clouds_of_millions_of_points
54  *
55  * \sa opengl::CPlanarLaserScan, opengl::COpenGLScene, opengl::CPointCloudColoured, mrpt::slam::CPointsMap
56  *
57  * <div align="center">
58  * <table border="0" cellspan="4" cellspacing="4" style="border-width: 1px; border-style: solid;">
59  * <tr> <td> mrpt::opengl::CPointCloud </td> <td> \image html preview_CPointCloud.png </td> </tr>
60  * </table>
61  * </div>
62  *
63  * \ingroup mrpt_opengl_grp
64  */
66  public CRenderizable,
68  public mrpt::utils::PLY_Importer,
69  public mrpt::utils::PLY_Exporter
70  {
71  DEFINE_SERIALIZABLE( CPointCloud )
72  protected:
73  enum Axis { None=0, Z, Y, X} m_colorFromDepth;
74  std::vector<float> m_xs,m_ys,m_zs;
75  float m_pointSize; //!< By default is 1.0
76  bool m_pointSmooth; //!< Default: false
77 
78  mutable volatile size_t m_last_rendered_count, m_last_rendered_count_ongoing;
79 
80  void markAllPointsAsNew(); //!< Do needed internal work if all points are new (octree rebuilt,...)
81 
82  protected:
83  /** @name PLY Import virtual methods to implement in base classes
84  @{ */
85  /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex */
86  virtual void PLY_import_set_vertex_count(const size_t N);
87 
88  /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_face */
89  virtual void PLY_import_set_face_count(const size_t N) { }
90 
91  /** In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point.
92  * \param pt_color Will be NULL if the loaded file does not provide color info.
93  */
94  virtual void PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::utils::TColorf *pt_color = NULL);
95  /** @} */
96 
97  /** @name PLY Export virtual methods to implement in base classes
98  @{ */
99 
100  /** In a base class, return the number of vertices */
101  virtual size_t PLY_export_get_vertex_count() const;
102 
103  /** In a base class, return the number of faces */
104  virtual size_t PLY_export_get_face_count() const { return 0; }
105 
106  /** In a base class, will be called after PLY_export_get_vertex_count() once for each exported point.
107  * \param pt_color Will be NULL if the loaded file does not provide color info.
108  */
109  virtual void PLY_export_get_vertex(
110  const size_t idx,
112  bool &pt_has_color,
113  mrpt::utils::TColorf &pt_color) const;
114 
115  /** @} */
116 
117 
118  public:
119 
120  /** @name Read/Write of the list of points to render
121  @{ */
122 
123  inline size_t size() const { return m_xs.size(); }
124 
125  /** Set the number of points (with contents undefined) */
126  inline void resize(size_t N) { m_xs.resize(N); m_ys.resize(N); m_zs.resize(N); m_minmax_valid = false; markAllPointsAsNew(); }
127 
128  /** Like STL std::vector's reserve */
129  inline void reserve(size_t N) { m_xs.reserve(N); m_ys.reserve(N); m_zs.reserve(N); }
130 
131  /** Set the list of (X,Y,Z) point coordinates, all at once, from three vectors with their coordinates */
132  void setAllPoints(const std::vector<float> &x, const std::vector<float> &y, const std::vector<float> &z)
133  {
134  m_xs = x;
135  m_ys = y;
136  m_zs = z;
137  m_minmax_valid = false;
138  markAllPointsAsNew();
139  }
140 
141  /** Set the list of (X,Y,Z) point coordinates, DESTROYING the contents of the input vectors (via swap) */
142  void setAllPointsFast(std::vector<float> &x, std::vector<float> &y, std::vector<float> &z)
143  {
144  this->clear();
145  m_xs.swap(x);
146  m_ys.swap(y);
147  m_zs.swap(z);
148  m_minmax_valid = false;
149  markAllPointsAsNew();
150  }
151 
152  inline const std::vector<float> & getArrayX() const {return m_xs;} //!< Get a const reference to the internal array of X coordinates
153  inline const std::vector<float> & getArrayY() const {return m_ys;} //!< Get a const reference to the internal array of Y coordinates
154  inline const std::vector<float> & getArrayZ() const {return m_zs;} //!< Get a const reference to the internal array of Z coordinates
155 
156  void clear(); //!< Empty the list of points.
157 
158  /** Adds a new point to the cloud */
159  void insertPoint( float x,float y, float z );
160 
161  /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
162  inline mrpt::math::TPoint3D operator [](size_t i) const {
163 #ifdef _DEBUG
164  ASSERT_BELOW_(i,size())
165 #endif
166  return mrpt::math::TPoint3D(m_xs[i],m_ys[i],m_zs[i]);
167  }
168 
169  /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
170  inline mrpt::math::TPoint3D getPoint(size_t i) const {
171 #ifdef _DEBUG
172  ASSERT_BELOW_(i,size())
173 #endif
174  return mrpt::math::TPoint3D(m_xs[i],m_ys[i],m_zs[i]);
175  }
176 
177  /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
178  inline mrpt::math::TPoint3Df getPointf(size_t i) const {
179 #ifdef _DEBUG
180  ASSERT_BELOW_(i,size())
181 #endif
182  return mrpt::math::TPoint3Df(m_xs[i],m_ys[i],m_zs[i]);
183  }
184 
185  /** Write an individual point (checks for "i" in the valid range only in Debug). */
186  void setPoint(size_t i, const float x,const float y, const float z);
187 
188  /** Write an individual point (without checking validity of the index). */
189  inline void setPoint_fast(size_t i, const float x,const float y, const float z)
190  {
191  m_xs[i] = x;
192  m_ys[i] = y;
193  m_zs[i] = z;
194  m_minmax_valid = false;
195  markAllPointsAsNew();
196  }
197 
198 
199  /** Load the points from any other point map class supported by the adapter mrpt::utils::PointCloudAdapter. */
200  template <class POINTSMAP>
201  void loadFromPointsMap( const POINTSMAP *themap);
202  // Must be implemented at the end of the header.
203 
204  /** Load the points from a list of TPoint3D
205  */
206  template<class LISTOFPOINTS> void loadFromPointsList( LISTOFPOINTS &pointsList)
207  {
208  MRPT_START
209  const size_t N = pointsList.size();
210 
211  m_xs.resize(N);
212  m_ys.resize(N);
213  m_zs.resize(N);
214 
215  size_t idx;
216  typename LISTOFPOINTS::const_iterator it;
217  for ( idx=0,it=pointsList.begin() ; idx<N ; ++idx,++it)
218  {
219  m_xs[idx]=it->x;
220  m_ys[idx]=it->y;
221  m_zs[idx]=it->z;
222  }
223  markAllPointsAsNew();
224  MRPT_END
225  }
226 
227  /** Get the number of elements actually rendered in the last render event. */
228  size_t getActuallyRendered() const { return m_last_rendered_count; }
229 
230  /** @} */
231 
232 
233  /** @name Modify the appearance of the rendered points
234  @{ */
235  inline void enableColorFromX(bool v=true) { m_colorFromDepth = v ? CPointCloud::X : CPointCloud::None; }
236  inline void enableColorFromY(bool v=true) { m_colorFromDepth = v ? CPointCloud::Y : CPointCloud::None; }
237  inline void enableColorFromZ(bool v=true) { m_colorFromDepth = v ? CPointCloud::Z : CPointCloud::None; }
238 
239  inline void setPointSize(float p) { m_pointSize=p; } //!< By default is 1.0
240  inline float getPointSize() const { return m_pointSize; }
241 
242  inline void enablePointSmooth(bool enable=true) { m_pointSmooth=enable; }
243  inline void disablePointSmooth() { m_pointSmooth=false; }
244  inline bool isPointSmoothEnabled() const { return m_pointSmooth; }
245 
246  /** Sets the colors used as extremes when colorFromDepth is enabled. */
247  void setGradientColors( const mrpt::utils::TColorf &colorMin, const mrpt::utils::TColorf &colorMax );
248 
249  /** @} */
250 
251  /** Render */
252  void render() const;
253 
254 
255  /** Render a subset of points (required by octree renderer) */
256  void render_subset(const bool all, const std::vector<size_t>& idxs, const float render_area_sqpixels ) const;
257 
258  private:
259  /** Constructor */
260  CPointCloud();
261 
262  /** Private, virtual destructor: only can be deleted from smart pointers */
263  virtual ~CPointCloud() { }
264 
265  mutable float m_min, m_max,m_max_m_min,m_max_m_min_inv; //!< Buffer for min/max coords when m_colorFromDepth is true.
266  mutable mrpt::utils::TColorf m_col_slop,m_col_slop_inv; //!< Color linear function slope
267  mutable bool m_minmax_valid;
268 
269  mrpt::utils::TColorf m_colorFromDepth_min, m_colorFromDepth_max; //!< The colors used to interpolate when m_colorFromDepth is true.
270 
271  inline void internal_render_one_point(size_t i) const;
272  };
273 
274  } // end namespace
275 
276 
277  namespace utils
278  {
279  /** Specialization mrpt::utils::PointCloudAdapter<mrpt::opengl::CPointCloud> \ingroup mrpt_adapters_grp */
280  template <>
281  class PointCloudAdapter<mrpt::opengl::CPointCloud> : public detail::PointCloudAdapterHelperNoRGB<mrpt::opengl::CPointCloud,float>
282  {
283  private:
285  public:
286  typedef float coords_t; //!< The type of each point XYZ coordinates
287  static const int HAS_RGB = 0; //!< Has any color RGB info?
288  static const int HAS_RGBf = 0; //!< Has native RGB info (as floats)?
289  static const int HAS_RGBu8 = 0; //!< Has native RGB info (as uint8_t)?
290 
291  /** Constructor (accept a const ref for convenience) */
292  inline PointCloudAdapter(const mrpt::opengl::CPointCloud &obj) : m_obj(*const_cast<mrpt::opengl::CPointCloud*>(&obj)) { }
293  /** Get number of points */
294  inline size_t size() const { return m_obj.size(); }
295  /** Set number of points (to uninitialized values) */
296  inline void resize(const size_t N) { m_obj.resize(N); }
297 
298  /** Get XYZ coordinates of i'th point */
299  template <typename T>
300  inline void getPointXYZ(const size_t idx, T &x,T &y, T &z) const {
301  x=m_obj.getArrayX()[idx];
302  y=m_obj.getArrayY()[idx];
303  z=m_obj.getArrayZ()[idx];
304  }
305  /** Set XYZ coordinates of i'th point */
306  inline void setPointXYZ(const size_t idx, const coords_t x,const coords_t y, const coords_t z) {
307  m_obj.setPoint_fast(idx,x,y,z);
308  }
309 
310  }; // end of PointCloudAdapter<mrpt::opengl::CPointCloud>
311  }
312 
313  namespace opengl
314  {
315  // After declaring the adapter we can here implement this method:
316  template <class POINTSMAP>
317  void CPointCloud::loadFromPointsMap( const POINTSMAP *themap)
318  {
319  mrpt::utils::PointCloudAdapter<CPointCloud> pc_dst(*this);
320  const mrpt::utils::PointCloudAdapter<POINTSMAP> pc_src(*themap);
321  const size_t N=pc_src.size();
322  pc_dst.resize(N);
323  for (size_t i=0;i<N;i++)
324  {
325  float x,y,z;
326  pc_src.getPointXYZ(i,x,y,z);
327  pc_dst.setPointXYZ(i,x,y,z);
328  }
329  }
330  }
331 
332 } // End of namespace
333 
334 
335 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013