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-2018, 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 
15 #include <mrpt/core/round.h> // round()
16 
17 #include "opengl_internals.h"
18 
19 using namespace mrpt;
20 using namespace mrpt::opengl;
21 using namespace mrpt::img;
22 using namespace mrpt::math;
23 using namespace std;
24 
27 
29 {
31 }
33  float value)
34 {
36 }
37 
39 {
41 }
43 {
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::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 
219 {
220  writeToStreamRender(out);
221  // Changed from bool to enum/int32_t in version 3.
222  out << static_cast<int32_t>(m_colorFromDepth);
223  out << m_xs << m_ys << m_zs;
224 
225  // Added in version 1.
226  out << m_pointSize;
227 
228  // New in version 2:
229  out << m_colorFromDepth_min.R << m_colorFromDepth_min.G
230  << m_colorFromDepth_min.B;
231  out << m_colorFromDepth_max.R << m_colorFromDepth_max.G
232  << m_colorFromDepth_max.B;
233 
234  // New in version 4:
235  out << m_pointSmooth;
236 }
237 
240 {
241  switch (version)
242  {
243  case 0:
244  case 1:
245  case 2:
246  case 3:
247  case 4:
248  {
249  readFromStreamRender(in);
250  if (version >= 3)
251  {
252  int32_t axis;
253  in >> axis;
254  m_colorFromDepth = Axis(axis);
255  }
256  else
257  {
258  bool colorFromZ;
259  in >> colorFromZ;
260  m_colorFromDepth =
262  }
263  in >> m_xs >> m_ys >> m_zs;
264 
265  if (version >= 1)
266  in >> m_pointSize;
267  else
268  m_pointSize = 1;
269 
270  if (version >= 2)
271  {
272  in >> m_colorFromDepth_min.R >> m_colorFromDepth_min.G >>
273  m_colorFromDepth_min.B;
274  in >> m_colorFromDepth_max.R >> m_colorFromDepth_max.G >>
275  m_colorFromDepth_max.B;
276  }
277  else
278  {
279  m_colorFromDepth_min = TColorf(0, 0, 0);
280  m_colorFromDepth_max.R = m_color.R * 255.f;
281  m_colorFromDepth_max.G = m_color.G * 255.f;
282  m_colorFromDepth_max.B = m_color.B * 255.f;
283  }
284 
285  if (version >= 4)
286  in >> m_pointSmooth;
287  else
288  m_pointSmooth = false;
289  }
290  break;
291  default:
293  };
294 
295  markAllPointsAsNew();
296 }
297 
298 /*---------------------------------------------------------------
299  clear
300 ---------------------------------------------------------------*/
302 {
303  m_xs.clear();
304  m_ys.clear();
305  m_zs.clear();
306  markAllPointsAsNew();
307 }
308 
309 /*---------------------------------------------------------------
310  insertPoint
311 ---------------------------------------------------------------*/
312 void CPointCloud::insertPoint(float x, float y, float z)
313 {
314  m_xs.push_back(x);
315  m_ys.push_back(y);
316  m_zs.push_back(z);
317 
318  m_minmax_valid = false;
319 
320  // JL: TODO note: Well, this can be clearly done much more efficiently
321  // but...I don't have time! :-(
322  markAllPointsAsNew();
323 }
324 
325 /** Write an individual point (checks for "i" in the valid range only in Debug).
326  */
328  size_t i, const float x, const float y, const float z)
329 {
330 #ifdef _DEBUG
331  ASSERT_BELOW_(i, size());
332 #endif
333  m_xs[i] = x;
334  m_ys[i] = y;
335  m_zs[i] = z;
336 
337  m_minmax_valid = false;
338 
339  // JL: TODO note: Well, this can be clearly done much more efficiently
340  // but...I don't have time! :-(
341  markAllPointsAsNew();
342 }
343 
344 /*---------------------------------------------------------------
345  setGradientColors
346 ---------------------------------------------------------------*/
348  const mrpt::img::TColorf& colorMin, const mrpt::img::TColorf& colorMax)
349 {
350  m_colorFromDepth_min = colorMin;
351  m_colorFromDepth_max = colorMax;
352 }
353 
354 // Do needed internal work if all points are new (octree rebuilt,...)
356 {
357  m_minmax_valid = false;
358  octree_mark_as_outdated();
359 }
360 
361 /** In a base class, reserve memory to prepare subsequent calls to
362  * PLY_import_set_vertex */
364 {
365  this->resize(N);
366 }
367 
368 /** In a base class, will be called after PLY_import_set_vertex_count() once for
369  * each loaded point.
370  * \param pt_color Will be nullptr if the loaded file does not provide color
371  * info.
372  */
374  const size_t idx, const mrpt::math::TPoint3Df& pt,
375  const mrpt::img::TColorf* pt_color)
376 {
377  MRPT_UNUSED_PARAM(pt_color);
378  this->setPoint(idx, pt.x, pt.y, pt.z);
379 }
380 
381 /** In a base class, return the number of vertices */
382 size_t CPointCloud::PLY_export_get_vertex_count() const { return this->size(); }
383 /** In a base class, will be called after PLY_export_get_vertex_count() once for
384  * each exported point.
385  * \param pt_color Will be nullptr if the loaded file does not provide color
386  * info.
387  */
389  const size_t idx, mrpt::math::TPoint3Df& pt, bool& pt_has_color,
390  mrpt::img::TColorf& pt_color) const
391 {
392  MRPT_UNUSED_PARAM(pt_color);
393  pt_has_color = false;
394 
395  pt.x = m_xs[idx];
396  pt.y = m_ys[idx];
397  pt.z = m_zs[idx];
398 }
void render() const override
Render.
Definition: CPointCloud.cpp:75
void insertPoint(float x, float y, float z)
Adds a new point to the cloud.
GLdouble GLdouble z
Definition: glext.h:3872
#define min(a, b)
float OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL_value
Definition: CPointCloud.cpp:25
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
GLAPI void GLAPIENTRY glEnable(GLenum cap)
GLAPI void GLAPIENTRY glPointSize(GLfloat size)
#define ASSERT_BELOW_(__A, __B)
Definition: exceptions.h:165
#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:38
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
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
void setGradientColors(const mrpt::img::TColorf &colorMin, const mrpt::img::TColorf &colorMax)
Sets the colors used as extremes when colorFromDepth is enabled.
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
unsigned char uint8_t
Definition: rptypes.h:41
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:90
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
This base provides a set of functions for maths stuff.
Lightweight 3D point (float version).
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:30
#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)
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.
virtual void PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::img::TColorf *pt_color=nullptr) override
In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point...
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
__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)
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:48
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:143
A RGB color - floats in the range [0,1].
Definition: TColor.h:79
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:216
size_t PLY_export_get_vertex_count() const override
In a base class, return the number of vertices.
void PLY_export_get_vertex(const size_t idx, mrpt::math::TPoint3Df &pt, bool &pt_has_color, mrpt::img::TColorf &pt_color) const override
In a base class, will be called after PLY_export_get_vertex_count() once for each exported point...
GLAPI void GLAPIENTRY glEnd(void)
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)
A cloud of points, all with the same color or each depending on its value along a particular coordina...
Definition: CPointCloud.h:45
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at lun oct 28 00:14:14 CET 2019