Main MRPT website > C++ reference for MRPT 1.9.9
CPointCloud.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
14 #include <mrpt/utils/CStream.h>
15 #include <mrpt/utils/round.h> // round()
16 
17 #include "opengl_internals.h"
18 
19 using namespace mrpt;
20 using namespace mrpt::opengl;
21 using namespace mrpt::utils;
22 using namespace mrpt::math;
23 using namespace std;
24 
27 
29 {
31 }
33 {
35 }
36 
38 {
40 }
42 {
44 }
45 
46 
48 
49 /*---------------------------------------------------------------
50  render
51  ---------------------------------------------------------------*/
53  : m_colorFromDepth(CPointCloud::colNone),
54  m_xs(),
55  m_ys(),
56  m_zs(),
57  m_pointSize(1),
58  m_pointSmooth(false),
59  m_last_rendered_count(0),
60  m_last_rendered_count_ongoing(0),
61  m_min(0),
62  m_max(0),
63  m_max_m_min(0),
64  m_max_m_min_inv(0),
65  m_minmax_valid(false),
66  m_colorFromDepth_min(0, 0, 0),
67  m_colorFromDepth_max(0, 0, 1)
68 {
69  markAllPointsAsNew();
70 }
71 
72 /*---------------------------------------------------------------
73  render
74  ---------------------------------------------------------------*/
75 void CPointCloud::render() const
76 {
77 #if MRPT_HAS_OPENGL_GLUT
78 
79  ASSERT_(m_xs.size() == m_ys.size());
80  ASSERT_(m_xs.size() == m_zs.size());
81 
82  octree_assure_uptodate(); // Rebuild octree if needed
83  m_last_rendered_count_ongoing = 0;
84 
85  // Info needed by octree renderer:
88 
89  if (m_colorFromDepth)
90  {
91  if (!m_minmax_valid)
92  {
93  m_minmax_valid = true;
94  if (!m_zs.empty())
96  m_colorFromDepth == CPointCloud::colZ
97  ? m_zs
98  : (m_colorFromDepth == CPointCloud::colY ? m_ys : m_xs),
99  m_min, m_max);
100  else
101  m_max = m_min = 0;
102  }
103 
104  m_max_m_min = m_max - m_min;
105  if (std::abs(m_max_m_min) < 1e-4)
106  m_max_m_min = -1;
107  else
108  m_min = m_max - m_max_m_min * 1.01f;
109  m_max_m_min_inv = 1.0 / m_max_m_min;
110  }
111 
112  if (m_color.A != 255)
113  {
116  }
117  else
118  {
120  }
121 
122  // Slopes of color interpolation:
123  m_col_slop.R = m_colorFromDepth_max.R - m_colorFromDepth_min.R;
124  m_col_slop.G = m_colorFromDepth_max.G - m_colorFromDepth_min.G;
125  m_col_slop.B = m_colorFromDepth_max.B - m_colorFromDepth_min.B;
126 
127  m_col_slop_inv.R = m_col_slop.R != 0 ? 1.0f / m_col_slop.R : 0;
128  m_col_slop_inv.G = m_col_slop.G != 0 ? 1.0f / m_col_slop.G : 0;
129  m_col_slop_inv.B = m_col_slop.B != 0 ? 1.0f / m_col_slop.B : 0;
130 
131  glPointSize(m_pointSize);
132  if (m_pointSmooth)
134  else
136 
137  // Disable lighting for point clouds:
139 
141  glColor4ub(
142  m_color.R, m_color.G, m_color.B,
143  m_color.A); // The default if m_colorFromDepth=false
144  octree_render(ri); // Render all points recursively:
145  glEnd();
146 
148 
149  if (m_color.A != 255) glDisable(GL_BLEND);
150 
151  if (m_pointSmooth) glDisable(GL_POINT_SMOOTH);
152 
153  m_last_rendered_count = m_last_rendered_count_ongoing;
154 
156 #endif
157 }
158 
159 inline void CPointCloud::internal_render_one_point(size_t i) const
160 {
161 #if MRPT_HAS_OPENGL_GLUT
162  if (m_colorFromDepth != colNone && m_max_m_min > 0)
163  {
164  const float depthCol =
165  (m_colorFromDepth == colX
166  ? m_xs[i]
167  : (m_colorFromDepth == colY ? m_ys[i] : m_zs[i]));
168 
169  float f = (depthCol - m_min) * m_max_m_min_inv;
170  f = std::max(0.0f, min(1.0f, f));
171 
172  glColor4f(
173  m_colorFromDepth_min.R + f * m_col_slop_inv.R,
174  m_colorFromDepth_min.G + f * m_col_slop_inv.G,
175  m_colorFromDepth_min.B + f * m_col_slop_inv.B,
176  m_color.A * (1.0f / 255.f));
177  }
178  glVertex3f(m_xs[i], m_ys[i], m_zs[i]);
179 #else
181 #endif
182 }
183 
184 /** Render a subset of points (required by octree renderer) */
186  const bool all, const std::vector<size_t>& idxs,
187  const float render_area_sqpixels) const
188 {
189 #if MRPT_HAS_OPENGL_GLUT
190 
191  const size_t N = (all ? m_xs.size() : idxs.size());
192  const size_t decimation = mrpt::utils::round(
193  std::max(
194  1.0f, static_cast<float>(
196  render_area_sqpixels))));
197 
198  m_last_rendered_count_ongoing += N / decimation;
199 
200  if (all)
201  {
202  for (size_t i = 0; i < N; i++) internal_render_one_point(i);
203  }
204  else
205  {
206  const size_t Np = idxs.size();
207  for (size_t i = 0; i < Np; i += decimation)
208  internal_render_one_point(idxs[i]);
209  }
210 #else
211  MRPT_UNUSED_PARAM(all);
212  MRPT_UNUSED_PARAM(idxs);
213  MRPT_UNUSED_PARAM(render_area_sqpixels);
214 #endif
215 }
216 
217 /*---------------------------------------------------------------
218  Implements the writing to a CStream capability of
219  CSerializable objects
220  ---------------------------------------------------------------*/
221 void CPointCloud::writeToStream(mrpt::utils::CStream& out, int* version) const
222 {
223  if (version)
224  *version = 4;
225  else
226  {
227  writeToStreamRender(out);
228  // Changed from bool to enum/int32_t in version 3.
229  out << static_cast<int32_t>(m_colorFromDepth);
230  out << m_xs << m_ys << m_zs;
231 
232  // Added in version 1.
233  out << m_pointSize;
234 
235  // New in version 2:
236  out << m_colorFromDepth_min.R << m_colorFromDepth_min.G
237  << m_colorFromDepth_min.B;
238  out << m_colorFromDepth_max.R << m_colorFromDepth_max.G
239  << m_colorFromDepth_max.B;
240 
241  // New in version 4:
242  out << m_pointSmooth;
243  }
244 }
245 
246 /*---------------------------------------------------------------
247  Implements the reading from a CStream capability of
248  CSerializable objects
249  ---------------------------------------------------------------*/
251 {
252  switch (version)
253  {
254  case 0:
255  case 1:
256  case 2:
257  case 3:
258  case 4:
259  {
260  readFromStreamRender(in);
261  if (version >= 3)
262  {
263  int32_t axis;
264  in >> axis;
265  m_colorFromDepth = Axis(axis);
266  }
267  else
268  {
269  bool colorFromZ;
270  in >> colorFromZ;
271  m_colorFromDepth =
273  }
274  in >> m_xs >> m_ys >> m_zs;
275 
276  if (version >= 1)
277  in >> m_pointSize;
278  else
279  m_pointSize = 1;
280 
281  if (version >= 2)
282  {
283  in >> m_colorFromDepth_min.R >> m_colorFromDepth_min.G >>
284  m_colorFromDepth_min.B;
285  in >> m_colorFromDepth_max.R >> m_colorFromDepth_max.G >>
286  m_colorFromDepth_max.B;
287  }
288  else
289  {
290  m_colorFromDepth_min = TColorf(0, 0, 0);
291  m_colorFromDepth_max.R = m_color.R * 255.f;
292  m_colorFromDepth_max.G = m_color.G * 255.f;
293  m_colorFromDepth_max.B = m_color.B * 255.f;
294  }
295 
296  if (version >= 4)
297  in >> m_pointSmooth;
298  else
299  m_pointSmooth = false;
300  }
301  break;
302  default:
304  };
305 
306  markAllPointsAsNew();
307 }
308 
309 /*---------------------------------------------------------------
310  clear
311 ---------------------------------------------------------------*/
313 {
314  m_xs.clear();
315  m_ys.clear();
316  m_zs.clear();
317  markAllPointsAsNew();
318 }
319 
320 /*---------------------------------------------------------------
321  insertPoint
322 ---------------------------------------------------------------*/
323 void CPointCloud::insertPoint(float x, float y, float z)
324 {
325  m_xs.push_back(x);
326  m_ys.push_back(y);
327  m_zs.push_back(z);
328 
329  m_minmax_valid = false;
330 
331  // JL: TODO note: Well, this can be clearly done much more efficiently
332  // but...I don't have time! :-(
333  markAllPointsAsNew();
334 }
335 
336 /** Write an individual point (checks for "i" in the valid range only in Debug).
337  */
339  size_t i, const float x, const float y, const float z)
340 {
341 #ifdef _DEBUG
342  ASSERT_BELOW_(i, size())
343 #endif
344  m_xs[i] = x;
345  m_ys[i] = y;
346  m_zs[i] = z;
347 
348  m_minmax_valid = false;
349 
350  // JL: TODO note: Well, this can be clearly done much more efficiently
351  // but...I don't have time! :-(
352  markAllPointsAsNew();
353 }
354 
355 /*---------------------------------------------------------------
356  setGradientColors
357 ---------------------------------------------------------------*/
359  const mrpt::utils::TColorf& colorMin, const mrpt::utils::TColorf& colorMax)
360 {
361  m_colorFromDepth_min = colorMin;
362  m_colorFromDepth_max = colorMax;
363 }
364 
365 // Do needed internal work if all points are new (octree rebuilt,...)
367 {
368  m_minmax_valid = false;
369  octree_mark_as_outdated();
370 }
371 
372 /** In a base class, reserve memory to prepare subsequent calls to
373  * PLY_import_set_vertex */
375 {
376  this->resize(N);
377 }
378 
379 /** In a base class, will be called after PLY_import_set_vertex_count() once for
380  * each loaded point.
381  * \param pt_color Will be nullptr if the loaded file does not provide color
382  * info.
383  */
385  const size_t idx, const mrpt::math::TPoint3Df& pt,
386  const mrpt::utils::TColorf* pt_color)
387 {
388  MRPT_UNUSED_PARAM(pt_color);
389  this->setPoint(idx, pt.x, pt.y, pt.z);
390 }
391 
392 /** In a base class, return the number of vertices */
393 size_t CPointCloud::PLY_export_get_vertex_count() const { return this->size(); }
394 /** In a base class, will be called after PLY_export_get_vertex_count() once for
395  * each exported point.
396  * \param pt_color Will be nullptr if the loaded file does not provide color
397  * info.
398  */
400  const size_t idx, mrpt::math::TPoint3Df& pt, bool& pt_has_color,
401  mrpt::utils::TColorf& pt_color) const
402 {
403  MRPT_UNUSED_PARAM(pt_color);
404  pt_has_color = false;
405 
406  pt.x = m_xs[idx];
407  pt.y = m_ys[idx];
408  pt.z = m_zs[idx];
409 }
void render() const override
Render.
Definition: CPointCloud.cpp:75
void insertPoint(float x, float y, float z)
Adds a new point to the cloud.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLdouble GLdouble z
Definition: glext.h:3872
#define min(a, b)
float OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL_value
Definition: CPointCloud.cpp:25
GLAPI void GLAPIENTRY glEnable(GLenum cap)
GLAPI void GLAPIENTRY glPointSize(GLfloat size)
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
size_t OCTREE_RENDER_MAX_POINTS_PER_NODE()
Default value = 1e5.
Definition: CPointCloud.cpp:37
#define ASSERT_BELOW_(__A, __B)
This file implements several operations that operate element-wise on individual or pairs of container...
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:43
void setGradientColors(const mrpt::utils::TColorf &colorMin, const mrpt::utils::TColorf &colorMax)
Sets the colors used as extremes when colorFromDepth is enabled.
STL namespace.
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
void clear()
Empty the list of points.
#define GL_LIGHTING
Definition: glew.h:385
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
Lightweight 3D point (float version).
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
void PLY_export_get_vertex(const size_t idx, mrpt::math::TPoint3Df &pt, bool &pt_has_color, mrpt::utils::TColorf &pt_color) const override
In a base class, will be called after PLY_export_get_vertex_count() once for each exported point...
void OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL(float value)
Default value = 0.01 points/px^2.
Definition: CPointCloud.cpp:32
Information about the rendering process being issued.
Definition: gl_utils.h:34
#define GL_POINT_SMOOTH
Definition: glew.h:363
GLAPI void GLAPIENTRY glBegin(GLenum mode)
size_t OCTREE_RENDER_MAX_POINTS_PER_NODE_value
Definition: CPointCloud.cpp:26
#define GL_BLEND
Definition: glew.h:432
#define GL_POINTS
Definition: glew.h:272
void internal_render_one_point(size_t i) const
void minimum_maximum(const std::vector< T > &V, T &curMin, T &curMax)
Return the maximum and minimum values of a std::vector.
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
virtual void PLY_import_set_vertex_count(const size_t N) override
In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex.
__int32 int32_t
Definition: rptypes.h:46
#define GL_SRC_ALPHA
Definition: glew.h:286
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void render_subset(const bool all, const std::vector< size_t > &idxs, const float render_area_sqpixels) const
Render a subset of points (required by octree renderer)
void markAllPointsAsNew()
Do needed internal work if all points are new (octree rebuilt,...)
void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:140
GLuint in
Definition: glext.h:7274
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
void getCurrentRenderingInfo(TRenderInfo &ri)
Gather useful information on the render parameters.
Definition: gl_utils.cpp:213
size_t PLY_export_get_vertex_count() const override
In a base class, return the number of vertices.
#define ASSERT_(f)
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
GLAPI void GLAPIENTRY glEnd(void)
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:25
void setPoint(size_t i, const float x, const float y, const float z)
Write an individual point (checks for "i" in the valid range only in Debug).
GLenum GLint GLint y
Definition: glext.h:3538
GLsizei const GLfloat * value
Definition: glext.h:4117
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GLsizeiptr size
Definition: glext.h:3923
GLenum GLint x
Definition: glext.h:3538
GLAPI void GLAPIENTRY glDisable(GLenum cap)
virtual void PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::utils::TColorf *pt_color=nullptr) override
In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point...
A cloud of points, all with the same color or each depending on its value along a particular coordina...
Definition: CPointCloud.h:47



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019