27 bool enableTransparency,
bool antiAliasing,
bool enableShowEdges,
28 bool enableShowFaces,
bool enableShowVertices)
29 : m_enableTransparency(enableTransparency),
30 m_antiAliasing(antiAliasing),
31 m_showEdges(enableShowEdges),
32 m_showFaces(enableShowFaces),
33 m_showVertices(enableShowVertices)
59 unsigned int num_verts,
unsigned int num_faces,
int* verts_per_face,
60 int* face_verts,
float* vert_coords)
62 m_num_verts = num_verts;
63 m_num_faces = num_faces;
66 m_is_quad.resize(num_faces);
67 for (
unsigned int i = 0; i < num_faces; i++)
69 if (verts_per_face[i] == 3)
71 else if (verts_per_face[i] == 4)
76 "\n Incorrect mesh format. It can only be composed of " 77 "triangles and/or quads.");
83 m_face_verts.resize(num_faces);
84 unsigned int count = 0;
85 for (
unsigned int f = 0; f < num_faces; f++)
87 m_face_verts[f][0] = face_verts[
count++];
88 m_face_verts[f][1] = face_verts[
count++];
89 m_face_verts[f][2] = face_verts[
count++];
91 m_face_verts[f][3] = face_verts[
count++];
93 m_face_verts[f][3] = -1;
97 m_vert_coords.resize(num_verts);
98 for (
unsigned int i = 0; i < num_verts; i++)
100 m_vert_coords[i][0] = vert_coords[3 * i];
101 m_vert_coords[i][1] = vert_coords[3 * i + 1];
102 m_vert_coords[i][2] = vert_coords[3 * i + 2];
106 if (m_computeNormals)
108 m_normals.resize(num_faces);
110 for (
unsigned int f = 0; f < num_faces; f++)
112 const unsigned int v1 = m_face_verts[f][0];
113 const unsigned int v2 = m_face_verts[f][1];
114 const unsigned int v3 = m_face_verts[f][2];
115 const unsigned int v4 = m_face_verts[f][3];
119 const float vec1[3] = {
120 m_vert_coords[
v3][0] - m_vert_coords[
v1][0],
121 m_vert_coords[
v3][1] - m_vert_coords[
v1][1],
122 m_vert_coords[
v3][2] - m_vert_coords[
v1][2]};
123 const float vec2[3] = {
124 m_vert_coords[v4][0] - m_vert_coords[
v2][0],
125 m_vert_coords[v4][1] - m_vert_coords[
v2][1],
126 m_vert_coords[v4][2] - m_vert_coords[
v2][2]};
127 m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
128 m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
129 m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
133 const float vec1[3] = {
134 m_vert_coords[
v2][0] - m_vert_coords[
v1][0],
135 m_vert_coords[
v2][1] - m_vert_coords[
v1][1],
136 m_vert_coords[
v2][2] - m_vert_coords[
v1][2]};
137 const float vec2[3] = {
138 m_vert_coords[
v3][0] - m_vert_coords[
v1][0],
139 m_vert_coords[
v3][1] - m_vert_coords[
v1][1],
140 m_vert_coords[
v3][2] - m_vert_coords[
v1][2]};
141 m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
142 m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
143 m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
152 unsigned int num_verts,
unsigned int num_faces,
157 MRPT_TODO(
"Refactor: one STL container of faces & another vertices");
158 m_num_verts = num_verts;
159 m_num_faces = num_faces;
162 m_is_quad.resize(num_faces);
163 for (
unsigned int i = 0; i < num_faces; i++) m_is_quad[i] = is_quad(i, 0);
166 m_face_verts.
resize(num_faces);
167 for (
unsigned int f = 0; f < num_faces; f++)
169 m_face_verts[f][0] = face_verts(0, f);
170 m_face_verts[f][1] = face_verts(1, f);
171 m_face_verts[f][2] = face_verts(2, f);
173 m_face_verts[f][3] = face_verts(3, f);
175 m_face_verts[f][3] = -1;
179 m_vert_coords.resize(num_verts);
180 for (
unsigned int i = 0; i < num_verts; i++)
182 m_vert_coords[i][0] = vert_coords(0, i);
183 m_vert_coords[i][1] = vert_coords(1, i);
184 m_vert_coords[i][2] = vert_coords(2, i);
188 m_normals.resize(num_faces);
189 if (m_computeNormals)
190 for (
unsigned int f = 0; f < num_faces; f++)
192 const unsigned int v1 = m_face_verts[f][0];
193 const unsigned int v2 = m_face_verts[f][1];
194 const unsigned int v3 = m_face_verts[f][2];
195 const unsigned int v4 = m_face_verts[f][3];
199 const float vec1[3] = {
200 m_vert_coords[
v3][0] - m_vert_coords[
v1][0],
201 m_vert_coords[
v3][1] - m_vert_coords[
v1][1],
202 m_vert_coords[
v3][2] - m_vert_coords[
v1][2]};
203 const float vec2[3] = {
204 m_vert_coords[v4][0] - m_vert_coords[
v2][0],
205 m_vert_coords[v4][1] - m_vert_coords[
v2][1],
206 m_vert_coords[v4][2] - m_vert_coords[
v2][2]};
207 m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
208 m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
209 m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
213 const float vec1[3] = {
214 m_vert_coords[
v2][0] - m_vert_coords[
v1][0],
215 m_vert_coords[
v2][1] - m_vert_coords[
v1][1],
216 m_vert_coords[
v2][2] - m_vert_coords[
v1][2]};
217 const float vec2[3] = {
218 m_vert_coords[
v3][0] - m_vert_coords[
v1][0],
219 m_vert_coords[
v3][1] - m_vert_coords[
v1][1],
220 m_vert_coords[
v3][2] - m_vert_coords[
v1][2]};
221 m_normals[f][0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
222 m_normals[f][1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
223 m_normals[f][2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
235 #if MRPT_HAS_OPENGL_GLUT 237 if (m_enableTransparency || m_antiAliasing)
253 if (m_num_verts == 0)
return;
265 glColor4f(face_color[0], face_color[1], face_color[2], face_color[3]);
267 for (
unsigned int f = 0; f < m_num_faces; f++)
270 if (m_computeNormals)
271 glNormal3f(m_normals[f][0], m_normals[f][1], m_normals[f][2]);
277 for (
int i = 0; i < 4; i++)
279 const unsigned int vert_ind = m_face_verts[f][i];
281 m_vert_coords[vert_ind][0], m_vert_coords[vert_ind][1],
282 m_vert_coords[vert_ind][2]);
290 for (
int i = 0; i < 3; i++)
292 const unsigned int vert_ind = m_face_verts[f][i];
294 m_vert_coords[vert_ind][0], m_vert_coords[vert_ind][1],
295 m_vert_coords[vert_ind][2]);
305 glColor4f(edge_color[0], edge_color[1], edge_color[2], edge_color[3]);
310 for (
unsigned int f = 0; f < m_num_faces; f++)
312 const unsigned char num_vert = 3 + m_is_quad[f];
313 for (
int i = 0; i < num_vert - 1; i++)
315 const unsigned int v_0 = m_face_verts[f][i];
316 const unsigned int v_1 = m_face_verts[f][i + 1];
319 m_vert_coords[v_0][0], m_vert_coords[v_0][1],
320 m_vert_coords[v_0][2]);
322 m_vert_coords[v_1][0], m_vert_coords[v_1][1],
323 m_vert_coords[v_1][2]);
328 const int v_0 = m_face_verts[f][num_vert - 1];
329 const int v_1 = m_face_verts[f][0];
332 m_vert_coords[v_0][0], m_vert_coords[v_0][1],
333 m_vert_coords[v_0][2]);
335 m_vert_coords[v_1][0], m_vert_coords[v_1][1],
336 m_vert_coords[v_1][2]);
346 glColor4f(vert_color[0], vert_color[1], vert_color[2], vert_color[3]);
351 for (
unsigned int v = 0;
v < m_num_verts;
v++)
353 m_vert_coords[
v][0], m_vert_coords[
v][1], m_vert_coords[
v][2]);
405 if (m_num_verts == 0)
407 "\n The mesh is empty and has no size. The returned information " 411 for (
unsigned int i = 0; i < m_num_verts; i++)
414 if (m_vert_coords[i][0] >
bb_max.x)
bb_max.x = m_vert_coords[i][0];
415 if (m_vert_coords[i][1] >
bb_max.y)
bb_max.y = m_vert_coords[i][1];
416 if (m_vert_coords[i][2] >
bb_max.z)
bb_max.z = m_vert_coords[i][2];
419 if (m_vert_coords[i][0] <
bb_min.x)
bb_min.x = m_vert_coords[i][0];
420 if (m_vert_coords[i][1] <
bb_min.y)
bb_min.y = m_vert_coords[i][1];
421 if (m_vert_coords[i][2] <
bb_min.z)
bb_min.z = m_vert_coords[i][2];
GLuint GLuint GLsizei count
void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
void resize(size_t row, size_t col)
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define THROW_EXCEPTION(msg)
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.
void render_dl() const override
Render.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
#define GL_ONE_MINUS_SRC_ALPHA
#define GL_COLOR_MATERIAL
A 3D mesh composed of Triangles and/or Quads.
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
A renderizable object suitable for rendering with OpenGL's display lists.
void setVertColor(float r, float g, float b, float a=1.f)
This base provides a set of functions for maths stuff.
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
GLfloat GLfloat GLfloat GLfloat v3
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.
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)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
GLdouble GLdouble GLdouble r
~CMesh3D() override
Private, virtual destructor: only can be deleted from smart pointers.
The namespace for 3D scene representation and rendering.
GLAPI void GLAPIENTRY glEnd(void)
GLfloat GLfloat GLfloat v2
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
void setEdgeColor(float r, float g, float b, float a=1.f)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
This template class provides the basic functionality for a general 2D any-size, resizable container o...
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...
GLubyte GLubyte GLubyte a