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 }
size_t OCTREE_RENDER_MAX_POINTS_PER_NODE_value
Definition: CPointCloud.cpp:26
float OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL_value
Definition: CPointCloud.cpp:25
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
A cloud of points, all with the same color or each depending on its value along a particular coordina...
Definition: CPointCloud.h:47
void clear()
Empty the list of points.
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
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.
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
size_t PLY_export_get_vertex_count() const override
In a base class, return the number of vertices.
void markAllPointsAsNew()
Do needed internal work if all points are new (octree rebuilt,...)
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 internal_render_one_point(size_t i) const
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.
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
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.
void setGradientColors(const mrpt::img::TColorf &colorMin, const mrpt::img::TColorf &colorMax)
Sets the colors used as extremes when colorFromDepth is enabled.
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).
void insertPoint(float x, float y, float z)
Adds a new point to the cloud.
void render() const override
Render.
Definition: CPointCloud.cpp:75
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:42
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:53
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
#define ASSERT_BELOW_(__A, __B)
Definition: exceptions.h:165
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:90
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_SRC_ALPHA
Definition: glew.h:286
#define GL_POINT_SMOOTH
Definition: glew.h:363
GLAPI void GLAPIENTRY glPointSize(GLfloat size)
#define GL_POINTS
Definition: glew.h:272
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
GLAPI void GLAPIENTRY glBegin(GLenum mode)
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
#define GL_BLEND
Definition: glew.h:432
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
GLAPI void GLAPIENTRY glEnd(void)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
#define GL_LIGHTING
Definition: glew.h:385
GLenum GLint GLint y
Definition: glext.h:3538
GLuint in
Definition: glext.h:7274
GLenum GLint x
Definition: glext.h:3538
GLsizeiptr size
Definition: glext.h:3923
GLdouble GLdouble z
Definition: glext.h:3872
GLsizei const GLfloat * value
Definition: glext.h:4117
void OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL(float value)
Default value = 0.01 points/px^2.
Definition: CPointCloud.cpp:32
size_t OCTREE_RENDER_MAX_POINTS_PER_NODE()
Default value = 1e5.
Definition: CPointCloud.cpp:38
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23
This base provides a set of functions for maths stuff.
void minimum_maximum(const std::vector< T > &V, T &curMin, T &curMax)
Return the maximum and minimum values of a std::vector.
void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:143
void getCurrentRenderingInfo(TRenderInfo &ri)
Gather useful information on the render parameters.
Definition: gl_utils.cpp:216
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:16
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
This file implements several operations that operate element-wise on individual or pairs of container...
#define min(a, b)
__int32 int32_t
Definition: rptypes.h:46
unsigned char uint8_t
Definition: rptypes.h:41
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
Lightweight 3D point (float version).
Information about the rendering process being issued.
Definition: gl_utils.h:31



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST