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 }
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
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.
Definition: zip.h:16
GLdouble GLdouble z
Definition: glext.h:3734
#define min(a, b)
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.
#define ASSERT_BELOW_(__A, __B)
This file implements several operations that operate element-wise on individual or pairs of container...
void render() const MRPT_OVERRIDE
Render.
Definition: CPointCloud.cpp:56
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:44
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:283
void clear()
Empty the list of points.
#define GL_LIGHTING
Definition: glew.h:381
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:38
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.
OPENGL_IMPEXP float OCTREE_RENDER_MAX_DENSITY_POINTS_PER_SQPIXEL
Default value = 0.01 points/px^2.
Definition: CPointCloud.cpp:26
Information about the rendering process being issued.
Definition: gl_utils.h:35
#define GL_POINT_SMOOTH
Definition: glew.h:359
int version
Definition: mrpt_jpeglib.h:898
GLAPI void GLAPIENTRY glBegin(GLenum mode)
#define GL_BLEND
Definition: glew.h:428
#define GL_POINTS
Definition: glew.h:268
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)
__int32 int32_t
Definition: rptypes.h:48
#define GL_SRC_ALPHA
Definition: glew.h:282
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,...)
size_t PLY_export_get_vertex_count() const MRPT_OVERRIDE
In a base class, return the number of vertices.
OPENGL_IMPEXP size_t OCTREE_RENDER_MAX_POINTS_PER_NODE
Default value = 1e5.
Definition: CPointCloud.cpp:27
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 OPENGL_IMPEXP checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:134
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...
GLuint in
Definition: glext.h:6301
The namespace for 3D scene representation and rendering.
void OPENGL_IMPEXP getCurrentRenderingInfo(TRenderInfo &ri)
Gather useful information on the render parameters.
Definition: gl_utils.cpp:197
#define ASSERT_(f)
A RGB color - floats in the range [0,1].
Definition: TColor.h:80
GLAPI void GLAPIENTRY glEnd(void)
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:26
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:3516
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GLsizeiptr size
Definition: glext.h:3779
GLenum GLint x
Definition: glext.h:3516
GLAPI void GLAPIENTRY glDisable(GLenum cap)
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 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...
A cloud of points, all with the same color or each depending on its value along a particular coordina...
Definition: CPointCloud.h:46



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019