Main MRPT website > C++ reference for MRPT 1.9.9
CMesh3D.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 
12 #include <mrpt/opengl/CMesh3D.h>
13 #include <mrpt/img/color_maps.h>
15 
16 #include "opengl_internals.h"
17 
18 using namespace mrpt;
19 using namespace mrpt::opengl;
20 
21 using namespace mrpt::poses;
22 using namespace mrpt::math;
23 using namespace std;
24 
26 
28  bool enableTransparency, bool antiAliasing, bool enableShowEdges,
29  bool enableShowFaces, bool enableShowVertices)
30  : m_enableTransparency(enableTransparency),
31  m_antiAliasing(antiAliasing),
32  m_showEdges(enableShowEdges),
33  m_showFaces(enableShowFaces),
34  m_showVertices(enableShowVertices),
35  m_computeNormals(true),
36  m_lineWidth(2.f),
37  m_pointSize(6.f),
38  m_colorMap(mrpt::img::cmHOT)
39 {
40  m_color.R = 1.f;
41  m_color.G = 0.f;
42  m_color.B = 0.f;
43  m_color.A = 1.f;
44  edge_color[0] = 0.9f;
45  edge_color[1] = 0.9f;
46  edge_color[2] = 0.9f;
47  edge_color[3] = 1.f;
48  face_color[0] = 0.7f;
49  face_color[1] = 0.7f;
50  face_color[2] = 0.8f;
51  face_color[3] = 1.f;
52  vert_color[0] = 0.3f;
53  vert_color[1] = 0.3f;
54  vert_color[2] = 0.3f;
55  vert_color[3] = 1.f;
56  m_num_faces = 0;
57  m_num_verts = 0;
58 }
59 
62  unsigned int num_verts, unsigned int num_faces, int* verts_per_face,
63  int* face_verts, float* vert_coords)
64 {
65  m_num_verts = num_verts;
66  m_num_faces = num_faces;
67 
68  // Fill number of vertices for each face
69  m_is_quad = new bool[num_faces];
70  for (unsigned int i = 0; i < num_faces; i++)
71  {
72  if (verts_per_face[i] == 3)
73  m_is_quad[i] = false;
74  else if (verts_per_face[i] == 4)
75  m_is_quad[i] = true;
76  else
77  {
78  printf(
79  "\n Incorrect mesh format. It can only be composed of "
80  "triangles and/or quads.");
81  return;
82  }
83  }
84 
85  // Fill the vertices of each face
86  m_face_verts = new f_verts[num_faces];
87  unsigned int count = 0;
88  for (unsigned int f = 0; f < num_faces; f++)
89  {
90  m_face_verts[f][0] = face_verts[count++];
91  m_face_verts[f][1] = face_verts[count++];
92  m_face_verts[f][2] = face_verts[count++];
93  if (m_is_quad[f])
94  m_face_verts[f][3] = face_verts[count++];
95  else
96  m_face_verts[f][3] = -1; // Meaning it is a triangle
97  }
98 
99  // Fill the 3D coordinates of the vertex
100  m_vert_coords = new coord3D[num_verts];
101  for (unsigned int i = 0; i < num_verts; i++)
102  {
103  m_vert_coords[i][0] = vert_coords[3 * i];
104  m_vert_coords[i][1] = vert_coords[3 * i + 1];
105  m_vert_coords[i][2] = vert_coords[3 * i + 2];
106  }
107 
108  // Compute the mesh normals (if on)
109  if (m_computeNormals)
110  {
111  m_normals = new coord3D[num_faces];
112 
113  for (unsigned int f = 0; f < num_faces; f++)
114  {
115  const unsigned int v1 = m_face_verts[f][0];
116  const unsigned int v2 = m_face_verts[f][1];
117  const unsigned int v3 = m_face_verts[f][2];
118  const unsigned int v4 = m_face_verts[f][3];
119 
120  if (m_is_quad[f])
121  {
122  const float vec1[3] = {
123  m_vert_coords[v3][0] - m_vert_coords[v1][0],
124  m_vert_coords[v3][1] - m_vert_coords[v1][1],
125  m_vert_coords[v3][2] - m_vert_coords[v1][2]};
126  const float vec2[3] = {
127  m_vert_coords[v4][0] - m_vert_coords[v2][0],
128  m_vert_coords[v4][1] - m_vert_coords[v2][1],
129  m_vert_coords[v4][2] - m_vert_coords[v2][2]};
130  m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
131  m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
132  m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
133  }
134  else
135  {
136  const float vec1[3] = {
137  m_vert_coords[v2][0] - m_vert_coords[v1][0],
138  m_vert_coords[v2][1] - m_vert_coords[v1][1],
139  m_vert_coords[v2][2] - m_vert_coords[v1][2]};
140  const float vec2[3] = {
141  m_vert_coords[v3][0] - m_vert_coords[v1][0],
142  m_vert_coords[v3][1] - m_vert_coords[v1][1],
143  m_vert_coords[v3][2] - m_vert_coords[v1][2]};
144  m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
145  m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
146  m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
147  }
148  }
149  }
150 
152 }
153 
155  unsigned int num_verts, unsigned int num_faces,
156  const Array<bool, 1, Dynamic>& is_quad,
157  const Array<int, 4, Dynamic>& face_verts,
158  const Array<float, 3, Dynamic>& vert_coords)
159 {
160  m_num_verts = num_verts;
161  m_num_faces = num_faces;
162 
163  // Fill number of vertices for each face
164  m_is_quad = new bool[num_faces];
165  for (unsigned int i = 0; i < num_faces; i++) m_is_quad[i] = is_quad(i);
166 
167  // Fill the vertices of each face
168  m_face_verts = new f_verts[num_faces];
169  for (unsigned int f = 0; f < num_faces; f++)
170  {
171  m_face_verts[f][0] = face_verts(0, f);
172  m_face_verts[f][1] = face_verts(1, f);
173  m_face_verts[f][2] = face_verts(2, f);
174  if (m_is_quad[f])
175  m_face_verts[f][3] = face_verts(3, f);
176  else
177  m_face_verts[f][3] = -1; // Meaning it is a triangle
178  }
179 
180  // Fill the 3D coordinates of the vertex
181  m_vert_coords = new coord3D[num_verts];
182  for (unsigned int i = 0; i < num_verts; i++)
183  {
184  m_vert_coords[i][0] = vert_coords(0, i);
185  m_vert_coords[i][1] = vert_coords(1, i);
186  m_vert_coords[i][2] = vert_coords(2, i);
187  }
188 
189  // Compute the mesh normals (if on)
190  m_normals = new coord3D[num_faces];
191  if (m_computeNormals)
192  for (unsigned int f = 0; f < num_faces; f++)
193  {
194  const unsigned int v1 = m_face_verts[f][0];
195  const unsigned int v2 = m_face_verts[f][1];
196  const unsigned int v3 = m_face_verts[f][2];
197  const unsigned int v4 = m_face_verts[f][3];
198 
199  if (m_is_quad[f])
200  {
201  const float vec1[3] = {
202  m_vert_coords[v3][0] - m_vert_coords[v1][0],
203  m_vert_coords[v3][1] - m_vert_coords[v1][1],
204  m_vert_coords[v3][2] - m_vert_coords[v1][2]};
205  const float vec2[3] = {
206  m_vert_coords[v4][0] - m_vert_coords[v2][0],
207  m_vert_coords[v4][1] - m_vert_coords[v2][1],
208  m_vert_coords[v4][2] - m_vert_coords[v2][2]};
209  m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
210  m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
211  m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
212  }
213  else
214  {
215  const float vec1[3] = {
216  m_vert_coords[v2][0] - m_vert_coords[v1][0],
217  m_vert_coords[v2][1] - m_vert_coords[v1][1],
218  m_vert_coords[v2][2] - m_vert_coords[v1][2]};
219  const float vec2[3] = {
220  m_vert_coords[v3][0] - m_vert_coords[v1][0],
221  m_vert_coords[v3][1] - m_vert_coords[v1][1],
222  m_vert_coords[v3][2] - m_vert_coords[v1][2]};
223  m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
224  m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
225  m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
226  }
227  }
228 
230 }
231 
232 /*---------------------------------------------------------------
233  render
234  ---------------------------------------------------------------*/
235 void CMesh3D::render_dl() const
236 {
237 #if MRPT_HAS_OPENGL_GLUT
238 
239  if (m_enableTransparency || m_antiAliasing)
240  {
243  }
244  else
245  {
248  }
249 
250  glEnable(GL_NORMALIZE); // So the GPU normalizes the normals instead of
251  // doing it in the CPU
254 
255  if (m_num_verts == 0) return;
256 
257  //---------------------------------------------------------------------------------------------------------
258  // Rendering - Test whether changing the rendering mode
259  // continuously
260  // is
261  // very slow (or not)
262  //---------------------------------------------------------------------------------------------------------
263 
264  // Render the faces
265  if (m_showFaces)
266  {
267  glColor4f(face_color[0], face_color[1], face_color[2], face_color[3]);
268 
269  for (unsigned int f = 0; f < m_num_faces; f++)
270  {
271  // Assign normals to faces (if on)
272  if (m_computeNormals)
273  glNormal3f(m_normals[f][0], m_normals[f][1], m_normals[f][2]);
274 
275  // Render Quads
276  if (m_is_quad[f])
277  {
278  glBegin(GL_QUADS);
279  for (int i = 0; i < 4; i++)
280  {
281  const unsigned int vert_ind = m_face_verts[f][i];
282  glVertex3f(
283  m_vert_coords[vert_ind][0], m_vert_coords[vert_ind][1],
284  m_vert_coords[vert_ind][2]);
285  }
286  glEnd();
287  }
288  // Render Triangles
289  else
290  {
292  for (int i = 0; i < 3; i++)
293  {
294  const unsigned int vert_ind = m_face_verts[f][i];
295  glVertex3f(
296  m_vert_coords[vert_ind][0], m_vert_coords[vert_ind][1],
297  m_vert_coords[vert_ind][2]);
298  }
299  glEnd();
300  }
301  }
302  }
303 
304  // Render the edges - They are rendered twice, which is redundant but simple
305  if (m_showEdges)
306  {
307  glColor4f(edge_color[0], edge_color[1], edge_color[2], edge_color[3]);
308  glDisable(GL_LIGHTING); //??
309  glLineWidth(m_lineWidth);
311  glBegin(GL_LINES);
312  for (unsigned int f = 0; f < m_num_faces; f++)
313  {
314  const unsigned char num_vert = 3 + m_is_quad[f];
315  for (int i = 0; i < num_vert - 1; i++)
316  {
317  const unsigned int v_0 = m_face_verts[f][i];
318  const unsigned int v_1 = m_face_verts[f][i + 1];
319 
320  glVertex3f(
321  m_vert_coords[v_0][0], m_vert_coords[v_0][1],
322  m_vert_coords[v_0][2]);
323  glVertex3f(
324  m_vert_coords[v_1][0], m_vert_coords[v_1][1],
325  m_vert_coords[v_1][2]);
326  }
327 
328  // The last vertex of the face needs to be connected to the first as
329  // well
330  const int v_0 = m_face_verts[f][num_vert - 1];
331  const int v_1 = m_face_verts[f][0];
332 
333  glVertex3f(
334  m_vert_coords[v_0][0], m_vert_coords[v_0][1],
335  m_vert_coords[v_0][2]);
336  glVertex3f(
337  m_vert_coords[v_1][0], m_vert_coords[v_1][1],
338  m_vert_coords[v_1][2]);
339  }
340  glEnd();
343  }
344 
345  // Render the vertices
346  if (m_showVertices)
347  {
348  glColor4f(vert_color[0], vert_color[1], vert_color[2], vert_color[3]);
350  glPointSize(m_pointSize);
353  for (unsigned int v = 0; v < m_num_verts; v++)
354  glVertex3f(
355  m_vert_coords[v][0], m_vert_coords[v][1], m_vert_coords[v][2]);
356 
357  glEnd();
360  }
361 
364 
365 #endif
366 }
367 
370 {
371  //********** To do **********
372  THROW_EXCEPTION("not implemented yet!");
373 
374  // writeToStreamRender(out);
375 
376  // // Version 0:
377  // out << m_enableTransparency;
378  // out << m_showEdges;
379  // out << m_showFaces;
380  // out << m_showVertices;
381  // out << m_computeNormals;
382  // out << m_num_verts;
383  // out << m_num_faces;
384 
385  // bool *m_is_quad;
386  // f_verts *m_face_verts;
387  // coord3D *m_vert_coords;
388  // coord3D *m_normals;
389 }
390 
392 {
393  //********** To do ************
394 }
395 
397  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
398 {
399  // Extreme initialization
400  bb_min.x = 10000.f;
401  bb_min.y = 10000.f;
402  bb_min.z = 10000.f;
403  bb_max.x = -10000.f;
404  bb_max.y = -10000.f;
405  bb_max.z = -10000.f;
406 
407  if (m_num_verts == 0)
408  printf(
409  "\n The mesh is empty and has no size. The returned information "
410  "has no meaning.");
411  else
412  {
413  for (unsigned int i = 0; i < m_num_verts; i++)
414  {
415  // Max
416  if (m_vert_coords[i][0] > bb_max.x) bb_max.x = m_vert_coords[i][0];
417  if (m_vert_coords[i][1] > bb_max.y) bb_max.y = m_vert_coords[i][1];
418  if (m_vert_coords[i][2] > bb_max.z) bb_max.z = m_vert_coords[i][2];
419 
420  // Min
421  if (m_vert_coords[i][0] < bb_min.x) bb_min.x = m_vert_coords[i][0];
422  if (m_vert_coords[i][1] < bb_min.y) bb_min.y = m_vert_coords[i][1];
423  if (m_vert_coords[i][2] < bb_min.z) bb_min.z = m_vert_coords[i][2];
424  }
425  }
426 
427  // Convert to coordinates of my parent:
428  m_pose.composePoint(bb_min, bb_min);
429  m_pose.composePoint(bb_max, bb_max);
430 }
431 
432 void CMesh3D::setEdgeColor(float r, float g, float b, float a)
433 {
434  edge_color[0] = r;
435  edge_color[1] = g;
436  edge_color[2] = b;
437  edge_color[3] = a;
438 }
439 
440 void CMesh3D::setFaceColor(float r, float g, float b, float a)
441 {
442  face_color[0] = r;
443  face_color[1] = g;
444  face_color[2] = b;
445  face_color[3] = a;
446 }
447 
448 void CMesh3D::setVertColor(float r, float g, float b, float a)
449 {
450  vert_color[0] = r;
451  vert_color[1] = g;
452  vert_color[2] = b;
453  vert_color[3] = a;
454 }
GLuint GLuint GLsizei count
Definition: glext.h:3528
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
Definition: CMesh3D.cpp:369
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
GLAPI void GLAPIENTRY glPointSize(GLfloat size)
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
Definition: CMesh3D.cpp:391
void render_dl() const override
Render.
Definition: CMesh3D.cpp:235
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
float[3] coord3D
Definition: CMesh3D.h:43
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
#define GL_TRIANGLES
Definition: glew.h:276
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
STL namespace.
#define GL_NORMALIZE
Definition: glew.h:416
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
#define GL_COLOR_MATERIAL
Definition: glew.h:392
#define GL_DEPTH_TEST
Definition: glew.h:401
#define GL_SMOOTH
Definition: glew.h:635
A 3D mesh composed of Triangles and/or Quads.
Definition: CMesh3D.h:38
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
#define GL_LIGHTING
Definition: glew.h:385
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
unsigned char uint8_t
Definition: rptypes.h:41
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
void setVertColor(float r, float g, float b, float a=1.f)
Definition: CMesh3D.cpp:448
This base provides a set of functions for maths stuff.
#define GL_LINE_SMOOTH
Definition: glew.h:367
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
Definition: CMesh3D.cpp:368
[New in MRPT 1.5.0]
Definition: color_maps.h:37
#define GL_QUADS
Definition: glew.h:279
GLint GLvoid * img
Definition: glext.h:3763
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:4109
GLubyte g
Definition: glext.h:6279
GLubyte GLubyte b
Definition: glext.h:6279
double x
X,Y,Z coordinates.
#define GL_POINT_SMOOTH
Definition: glew.h:363
GLAPI void GLAPIENTRY glBegin(GLenum mode)
void loadMesh(unsigned int num_verts, unsigned int num_faces, int *verts_per_face, int *face_verts, float *vert_coords)
Load a 3D mesh.
Definition: CMesh3D.cpp:61
#define GL_BLEND
Definition: glew.h:432
#define GL_POINTS
Definition: glew.h:272
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
void setFaceColor(float r, float g, float b, float a=1.f)
Definition: CMesh3D.cpp:440
#define GL_SRC_ALPHA
Definition: glew.h:286
const GLdouble * v
Definition: glext.h:3678
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:48
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
GLfloat GLfloat v1
Definition: glext.h:4105
virtual ~CMesh3D()
Private, virtual destructor: only can be deleted from smart pointers.
Definition: CMesh3D.cpp:60
GLuint in
Definition: glext.h:7274
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
GLAPI void GLAPIENTRY glEnd(void)
GLfloat GLfloat GLfloat v2
Definition: glext.h:4107
#define GL_LINES
Definition: glew.h:273
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Lightweight 3D point.
void setEdgeColor(float r, float g, float b, float a=1.f)
Definition: CMesh3D.cpp:432
GLAPI void GLAPIENTRY glDisable(GLenum cap)
void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const override
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
Definition: CMesh3D.cpp:396
GLubyte GLubyte GLubyte a
Definition: glext.h:6279



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