Main MRPT website > C++ reference for MRPT 1.5.7
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 
12 
15 #include <mrpt/utils/CStream.h>
16 #include <mrpt/utils/round.h> // round()
17 
18 #include "opengl_internals.h"
19 
20 using namespace mrpt;
21 using namespace mrpt::opengl;
22 using namespace mrpt::utils;
23 using namespace mrpt::math;
24 using namespace std;
25 
28 
29 
31 
32 /*---------------------------------------------------------------
33  render
34  ---------------------------------------------------------------*/
36  m_colorFromDepth(CPointCloud::colNone),
37  m_xs(),m_ys(),m_zs(),
38  m_pointSize(1),
39  m_pointSmooth(false),
40  m_last_rendered_count(0),
41  m_last_rendered_count_ongoing(0),
42  m_min(0),
43  m_max(0),
44  m_max_m_min(0),
45  m_max_m_min_inv(0),
46  m_minmax_valid(false),
47  m_colorFromDepth_min(0,0,0),
48  m_colorFromDepth_max(0,0,1)
49 {
50  markAllPointsAsNew();
51 }
52 
53 /*---------------------------------------------------------------
54  render
55  ---------------------------------------------------------------*/
56 void CPointCloud::render() const
57 {
58 #if MRPT_HAS_OPENGL_GLUT
59 
60  ASSERT_(m_xs.size() == m_ys.size());
61  ASSERT_(m_xs.size() == m_zs.size());
62 
63  octree_assure_uptodate(); // Rebuild octree if needed
64  m_last_rendered_count_ongoing = 0;
65 
66  // Info needed by octree renderer:
69 
70  if ( m_colorFromDepth )
71  {
72  if (!m_minmax_valid)
73  {
74  m_minmax_valid = true;
75  if (!m_zs.empty())
77  m_colorFromDepth == CPointCloud::colZ ? m_zs : (m_colorFromDepth == CPointCloud::colY ? m_ys : m_xs),
78  m_min, m_max);
79  else m_max=m_min=0;
80  }
81 
82  m_max_m_min = m_max - m_min;
83  if (std::abs(m_max_m_min)<1e-4)
84  m_max_m_min=-1;
85  else m_min = m_max - m_max_m_min * 1.01f;
86  m_max_m_min_inv = 1.0/m_max_m_min;
87  }
88 
89  if ( m_color.A != 255 )
90  {
93  }
94  else
95  {
97  }
98 
99 
100 
101  // Slopes of color interpolation:
102  m_col_slop.R = m_colorFromDepth_max.R - m_colorFromDepth_min.R;
103  m_col_slop.G = m_colorFromDepth_max.G - m_colorFromDepth_min.G;
104  m_col_slop.B = m_colorFromDepth_max.B - m_colorFromDepth_min.B;
105 
106  m_col_slop_inv.R = m_col_slop.R!=0 ? 1.0f/m_col_slop.R : 0;
107  m_col_slop_inv.G = m_col_slop.G!=0 ? 1.0f/m_col_slop.G : 0;
108  m_col_slop_inv.B = m_col_slop.B!=0 ? 1.0f/m_col_slop.B : 0;
109 
110  glPointSize( m_pointSize );
111  if (m_pointSmooth)
113  else glDisable( GL_POINT_SMOOTH );
114 
115 
116  // Disable lighting for point clouds:
118 
119  glBegin( GL_POINTS );
120  glColor4ub(m_color.R,m_color.G,m_color.B,m_color.A); // The default if m_colorFromDepth=false
121  octree_render(ri); // Render all points recursively:
122  glEnd();
123 
125 
126  if ( m_color.A != 255 )
128 
129  if (m_pointSmooth)
131 
132 
133  m_last_rendered_count = m_last_rendered_count_ongoing;
134 
136 #endif
137 }
138 
139 inline void CPointCloud::internal_render_one_point(size_t i) const
140 {
141 #if MRPT_HAS_OPENGL_GLUT
142  if ( m_colorFromDepth!=colNone && m_max_m_min>0 )
143  {
144  const float depthCol = (m_colorFromDepth==colX ? m_xs[i] : (m_colorFromDepth==colY ? m_ys[i] : m_zs[i]));
145 
146  float f = (depthCol - m_min) * m_max_m_min_inv;
147  f=std::max(0.0f,min(1.0f,f));
148 
149  glColor4f(
150  m_colorFromDepth_min.R + f*m_col_slop_inv.R,
151  m_colorFromDepth_min.G + f*m_col_slop_inv.G,
152  m_colorFromDepth_min.B + f*m_col_slop_inv.B,
153  m_color.A * (1.0f/255.f) );
154  }
155  glVertex3f( m_xs[i],m_ys[i],m_zs[i] );
156 #else
158 #endif
159 }
160 
161 
162 /** Render a subset of points (required by octree renderer) */
163 void CPointCloud::render_subset(const bool all, const std::vector<size_t>& idxs, const float render_area_sqpixels ) const
164 {
165 #if MRPT_HAS_OPENGL_GLUT
166 
167  const size_t N = (all ? m_xs.size() : idxs.size());
168  const size_t decimation = mrpt::utils::round( std::max(1.0f, static_cast<float>(N / (mrpt::global_settings::OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL * render_area_sqpixels)) ) );
169 
170  m_last_rendered_count_ongoing += N/decimation;
171 
172  if (all)
173  {
174  for (size_t i=0;i<N;i++)
175  internal_render_one_point(i);
176  }
177  else
178  {
179  const size_t Np = idxs.size();
180  for (size_t i=0;i<Np;i+=decimation)
181  internal_render_one_point(idxs[i]);
182  }
183 #else
184  MRPT_UNUSED_PARAM(all); MRPT_UNUSED_PARAM(idxs); MRPT_UNUSED_PARAM(render_area_sqpixels);
185 #endif
186 }
187 
188 
189 /*---------------------------------------------------------------
190  Implements the writing to a CStream capability of
191  CSerializable objects
192  ---------------------------------------------------------------*/
194 {
195 
196  if (version)
197  *version = 4;
198  else
199  {
200  writeToStreamRender(out);
201  // Changed from bool to enum/int32_t in version 3.
202  out << static_cast<int32_t>(m_colorFromDepth);
203  out << m_xs << m_ys << m_zs;
204 
205  // Added in version 1.
206  out << m_pointSize;
207 
208  // New in version 2:
209  out << m_colorFromDepth_min.R << m_colorFromDepth_min.G << m_colorFromDepth_min.B;
210  out << m_colorFromDepth_max.R << m_colorFromDepth_max.G << m_colorFromDepth_max.B;
211 
212  // New in version 4:
213  out << m_pointSmooth;
214  }
215 }
216 
217 /*---------------------------------------------------------------
218  Implements the reading from a CStream capability of
219  CSerializable objects
220  ---------------------------------------------------------------*/
222 {
223  switch(version)
224  {
225  case 0:
226  case 1:
227  case 2:
228  case 3:
229  case 4:
230  {
231  readFromStreamRender(in);
232  if (version>=3)
233  {
234  int32_t axis;
235  in >> axis;
236  m_colorFromDepth = Axis(axis);
237  }
238  else
239  {
240  bool colorFromZ;
241  in >> colorFromZ;
242  m_colorFromDepth = colorFromZ ? CPointCloud::colZ : CPointCloud::colNone;
243  }
244  in >> m_xs >> m_ys >> m_zs;
245 
246  if (version>=1)
247  in >> m_pointSize;
248  else m_pointSize = 1;
249 
250  if (version>=2)
251  {
252  in >> m_colorFromDepth_min.R >> m_colorFromDepth_min.G >> m_colorFromDepth_min.B;
253  in >> m_colorFromDepth_max.R >> m_colorFromDepth_max.G >> m_colorFromDepth_max.B;
254  }
255  else
256  {
257  m_colorFromDepth_min = TColorf(0,0,0);
258  m_colorFromDepth_max.R = m_color.R*255.f;
259  m_colorFromDepth_max.G = m_color.G*255.f;
260  m_colorFromDepth_max.B = m_color.B*255.f;
261  }
262 
263  if (version>=4)
264  in >> m_pointSmooth;
265  else m_pointSmooth = false;
266 
267  } break;
268  default:
270 
271  };
272 
273  markAllPointsAsNew();
274 }
275 
276 /*---------------------------------------------------------------
277  clear
278 ---------------------------------------------------------------*/
280 {
281  m_xs.clear();
282  m_ys.clear();
283  m_zs.clear();
284  markAllPointsAsNew();
285 }
286 
287 /*---------------------------------------------------------------
288  insertPoint
289 ---------------------------------------------------------------*/
290 void CPointCloud::insertPoint( float x,float y, float z )
291 {
292  m_xs.push_back(x);
293  m_ys.push_back(y);
294  m_zs.push_back(z);
295 
296  m_minmax_valid = false;
297 
298  // JL: TODO note: Well, this can be clearly done much more efficiently but...I don't have time! :-(
299  markAllPointsAsNew();
300 }
301 
302 /** Write an individual point (checks for "i" in the valid range only in Debug). */
303 void CPointCloud::setPoint(size_t i, const float x,const float y, const float z)
304 {
305 #ifdef _DEBUG
306  ASSERT_BELOW_(i,size())
307 #endif
308  m_xs[i] = x;
309  m_ys[i] = y;
310  m_zs[i] = z;
311 
312  m_minmax_valid = false;
313 
314  // JL: TODO note: Well, this can be clearly done much more efficiently but...I don't have time! :-(
315  markAllPointsAsNew();
316 }
317 
318 /*---------------------------------------------------------------
319  setGradientColors
320 ---------------------------------------------------------------*/
322 {
323  m_colorFromDepth_min = colorMin;
324  m_colorFromDepth_max = colorMax;
325 }
326 
327 // Do needed internal work if all points are new (octree rebuilt,...)
329 {
330  m_minmax_valid = false;
331  octree_mark_as_outdated();
332 }
333 
334 /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex */
336 {
337  this->resize(N);
338 }
339 
340 /** In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point.
341  * \param pt_color Will be NULL if the loaded file does not provide color info.
342  */
343 void CPointCloud::PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::utils::TColorf *pt_color)
344 {
345  MRPT_UNUSED_PARAM(pt_color);
346  this->setPoint(idx,pt.x,pt.y,pt.z);
347 }
348 
349 /** In a base class, return the number of vertices */
351 {
352  return this->size();
353 }
354 
355 /** In a base class, will be called after PLY_export_get_vertex_count() once for each exported point.
356  * \param pt_color Will be NULL if the loaded file does not provide color info.
357  */
359  const size_t idx,
361  bool &pt_has_color,
362  mrpt::utils::TColorf &pt_color) const
363 {
364  MRPT_UNUSED_PARAM(pt_color);
365  pt_has_color=false;
366 
367  pt.x = m_xs[idx];
368  pt.y = m_ys[idx];
369  pt.z = m_zs[idx];
370 }
#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:51
void clear()
Empty the list of points.
void setGradientColors(const mrpt::utils::TColorf &colorMin, const mrpt::utils::TColorf &colorMax)
Sets the colors used as extremes when colorFromDepth is enabled.
virtual void PLY_import_set_vertex_count(const size_t N) MRPT_OVERRIDE
In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex.
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 writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
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::utils::TColorf *pt_color=NULL) MRPT_OVERRIDE
In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point.
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 render() const MRPT_OVERRIDE
Render.
Definition: CPointCloud.cpp:56
void insertPoint(float x, float y, float z)
Adds a new point to the cloud.
void PLY_export_get_vertex(const size_t idx, mrpt::math::TPoint3Df &pt, bool &pt_has_color, mrpt::utils::TColorf &pt_color) const MRPT_OVERRIDE
In a base class, will be called after PLY_export_get_vertex_count() once for each exported point.
size_t PLY_export_get_vertex_count() const MRPT_OVERRIDE
In a base class, return the number of vertices.
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:45
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:39
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_SRC_ALPHA
Definition: glew.h:282
#define GL_POINT_SMOOTH
Definition: glew.h:359
GLAPI void GLAPIENTRY glPointSize(GLfloat size)
#define GL_POINTS
Definition: glew.h:268
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:428
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:283
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:381
GLenum GLint GLint y
Definition: glext.h:3516
GLuint in
Definition: glext.h:6301
GLenum GLint x
Definition: glext.h:3516
GLsizeiptr size
Definition: glext.h:3779
GLdouble GLdouble z
Definition: glext.h:3734
OPENGL_IMPEXP float OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL
Default value = 0.01 points/px^2.
Definition: CPointCloud.cpp:26
OPENGL_IMPEXP size_t OCTREE_RENDER_MAX_POINTS_PER_NODE
Default value = 1e5.
Definition: CPointCloud.cpp:27
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:26
int version
Definition: mrpt_jpeglib.h:898
#define ASSERT_(f)
Definition: mrpt_macros.h:278
#define ASSERT_BELOW_(__A, __B)
Definition: mrpt_macros.h:283
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: mrpt_macros.h:217
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
Definition: mrpt_macros.h:307
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:20
void minimum_maximum(const std::vector< T > &V, T &curMin, T &curMax)
Return the maximum and minimum values of a std::vector.
void OPENGL_IMPEXP checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:134
void OPENGL_IMPEXP getCurrentRenderingInfo(TRenderInfo &ri)
Gather useful information on the render parameters.
Definition: gl_utils.cpp:197
The namespace for 3D scene representation and rendering.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
Definition: zip.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:48
Lightweight 3D point (float version).
Information about the rendering process being issued.
Definition: gl_utils.h:36
A RGB color - floats in the range [0,1].
Definition: TColor.h:81



Page generated by Doxygen 1.9.1 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at mar 26 may 2026 13:12:03 CEST