18 #include <Eigen/Dense> 31 bool enableTransparency,
float xMin_p,
float xMax_p,
float yMin_p,
33 : m_textureImage(0, 0),
34 m_enableTransparency(enableTransparency),
72 const auto cols = Z.cols();
73 const auto rows = Z.rows();
76 if (cols == 0 && rows == 0)
return;
79 ASSERT_(xMax > xMin && yMax > yMin);
82 vertex_normals.assign(
83 (1 + cols) * (1 + rows),
84 std::pair<TPoint3D, size_t>(
TPoint3D(0, 0, 0), 0));
86 float cR[3], cG[3], cB[3], cA[3];
87 cA[0] = cA[1] = cA[2] = m_color.A / 255.f;
89 if ((m_colorFromZ) || (m_isImage))
95 cR[0] = cR[1] = cR[2] = m_color.R / 255.f;
96 cG[0] = cG[1] = cG[2] = m_color.G / 255.f;
97 cB[0] = cB[1] = cB[2] = m_color.B / 255.f;
100 bool useMask =
false;
101 if (
mask.cols() != 0 &&
mask.rows() != 0)
106 const float sCellX = (xMax - xMin) / (rows - 1);
107 const float sCellY = (yMax - yMin) / (cols - 1);
110 for (
int iX = 0; iX < rows - 1; iX++)
111 for (
int iY = 0; iY < cols - 1; iY++)
113 if (useMask && (!
mask(iX, iY) || !
mask(iX + 1, iY + 1)))
continue;
114 tri.
x[0] = xMin + iX * sCellX;
115 tri.
y[0] = yMin + iY * sCellY;
116 tri.
z[0] = Z(iX, iY);
117 tri.
x[2] = tri.
x[0] + sCellX;
118 tri.
y[2] = tri.
y[0] + sCellY;
119 tri.
z[2] = Z(iX + 1, iY + 1);
123 tvi.
vind[0] = iX + rows * iY;
124 tvi.
vind[2] = (iX + 1) + rows * (iY + 1);
132 if (!useMask ||
mask(iX + 1, iY))
136 tri.
z[1] = Z(iX + 1, iY);
137 for (
int i = 0; i < 3; i++)
143 m_colorMap, C(iX, iY), tri.
r[0], tri.
g[0], tri.
b[0]);
145 m_colorMap, C(iX + 1, iY), tri.
r[1], tri.
g[1],
148 m_colorMap, C(iX + 1, iY + 1), tri.
r[2], tri.
g[2],
153 if (m_textureImage.isColor())
155 tri.
r[0] = tri.
r[1] = tri.
r[2] = C_r(iX, iY);
156 tri.
g[0] = tri.
g[1] = tri.
g[2] = C_g(iX, iY);
157 tri.
b[0] = tri.
b[1] = tri.
b[2] = C_b(iX, iY);
161 tri.
r[0] = tri.
r[1] = tri.
r[2] = C(iX, iY);
162 tri.
g[0] = tri.
g[1] = tri.
g[2] = C(iX, iY);
163 tri.
b[0] = tri.
b[1] = tri.
b[2] = C(iX, iY);
168 tri.
r[0] = tri.
r[1] = tri.
r[2] = m_color.R / 255.f;
169 tri.
g[0] = tri.
g[1] = tri.
g[2] = m_color.G / 255.f;
170 tri.
b[0] = tri.
b[1] = tri.
b[2] = m_color.B / 255.f;
176 float ax = tri.
x[1] - tri.
x[0];
177 float bx = tri.
x[2] - tri.
x[0];
178 float ay = tri.
y[1] - tri.
y[0];
179 float by = tri.
y[2] - tri.
y[0];
180 float az = tri.
z[1] - tri.
z[0];
181 float bz = tri.
z[2] - tri.
z[0];
183 ay *
bz - az *
by, az * bx - ax *
bz, ax *
by - ay * bx);
186 tvi.
vind[1] = iX + 1 + rows * iY;
189 actualMesh.emplace_back(tri, tvi);
192 for (
unsigned long k : tvi.
vind)
194 vertex_normals[k].first += this_normal;
195 vertex_normals[k].second++;
204 if (!useMask ||
mask(iX, iY + 1))
212 tri.
z[2] = Z(iX, iY + 1);
216 m_colorMap, C(iX, iY), tri.
r[0], tri.
g[0], tri.
b[0]);
218 m_colorMap, C(iX + 1, iY + 1), tri.
r[1], tri.
g[1],
221 m_colorMap, C(iX, iY + 1), tri.
r[2], tri.
g[2],
226 if (m_textureImage.isColor())
228 tri.
r[0] = tri.
r[1] = tri.
r[2] = C_r(iX, iY);
229 tri.
g[0] = tri.
g[1] = tri.
g[2] = C_g(iX, iY);
230 tri.
b[0] = tri.
b[1] = tri.
b[2] = C_b(iX, iY);
234 tri.
r[0] = tri.
r[1] = tri.
r[2] = C(iX, iY);
235 tri.
g[0] = tri.
g[1] = tri.
g[2] = C(iX, iY);
236 tri.
b[0] = tri.
b[1] = tri.
b[2] = C(iX, iY);
241 tri.
r[0] = tri.
r[1] = tri.
r[2] = m_color.R / 255.f;
242 tri.
g[0] = tri.
g[1] = tri.
g[2] = m_color.G / 255.f;
243 tri.
b[0] = tri.
b[1] = tri.
b[2] = m_color.B / 255.f;
249 float ax = tri.
x[1] - tri.
x[0];
250 float bx = tri.
x[2] - tri.
x[0];
251 float ay = tri.
y[1] - tri.
y[0];
252 float by = tri.
y[2] - tri.
y[0];
253 float az = tri.
z[1] - tri.
z[0];
254 float bz = tri.
z[2] - tri.
z[0];
256 ay *
bz - az *
by, az * bx - ax *
bz, ax *
by - ay * bx);
260 tvi.
vind[2] = iX + rows * (iY + 1);
263 actualMesh.emplace_back(tri, tvi);
266 for (
unsigned long k : tvi.
vind)
268 vertex_normals[k].first += this_normal;
269 vertex_normals[k].second++;
275 for (
auto& vertex_normal : vertex_normals)
277 const size_t N = vertex_normal.second;
278 if (N > 0) vertex_normal.first *= 1.0 / N;
281 trianglesUpToDate =
true;
282 polygonsUpToDate =
false;
290 #if MRPT_HAS_OPENGL_GLUT 291 if (m_enableTransparency)
306 if (!trianglesUpToDate) updateTriangles();
308 for (
auto& i : actualMesh)
318 for (
int k = 0; k < 3; k++)
331 if (!m_isWireFrame)
glEnd();
346 m_textureImage =
img;
349 Z.setZero(
img.getHeight(),
img.getWidth());
351 m_modified_Image =
true;
352 m_enableTransparency =
false;
353 m_colorFromZ =
false;
355 trianglesUpToDate =
false;
368 (
img.getWidth() ==
static_cast<size_t>(in_Z.
cols())) &&
369 (
img.getHeight() ==
static_cast<size_t>(in_Z.
rows())));
374 m_textureImage =
img;
376 m_modified_Image =
true;
377 m_enableTransparency =
false;
378 m_colorFromZ =
false;
380 trianglesUpToDate =
false;
390 writeToStreamRender(out);
393 out << m_textureImage;
394 out << xMin << xMax << yMin << yMax;
395 out << Z << U << V <<
mask;
396 out << m_enableTransparency;
399 out << m_isWireFrame;
410 readFromStreamRender(
in);
412 in >> m_textureImage;
419 in >> Z >> U >> V >>
mask;
420 in >> m_enableTransparency;
431 m_isWireFrame =
false;
435 trianglesUpToDate =
false;
440 trianglesUpToDate =
false;
446 if ((!m_modified_Z) && (!m_modified_Image))
return;
452 const int cols = m_textureImage.getWidth();
453 const int rows = m_textureImage.getHeight();
455 if ((cols != Z.cols()) || (rows != Z.rows()))
456 printf(
"\nTexture Image and Z sizes have to be equal");
458 else if (m_textureImage.isColor())
460 C_r.setSize(rows, cols);
461 C_g.setSize(rows, cols);
462 C_b.setSize(rows, cols);
463 m_textureImage.getAsRGBMatrices(C_r, C_g, C_b);
467 C.setSize(rows, cols);
468 m_textureImage.getAsMatrix(C);
473 const size_t cols = Z.cols();
474 const size_t rows = Z.rows();
475 C.setSize(rows, cols);
486 float val_max = -std::numeric_limits<float>::max(),
487 val_min = std::numeric_limits<float>::max();
488 bool any_valid =
false;
490 for (
size_t c = 0;
c < cols;
c++)
491 for (
size_t r = 0;
r < rows;
r++)
493 if (!
mask(
r,
c))
continue;
495 const float val = C(
r,
c);
502 float minMaxDelta = val_max - val_min;
503 if (minMaxDelta == 0) minMaxDelta = 1;
504 const float minMaxDelta_ = 1.0f / minMaxDelta;
505 C.array() = (C.array() - val_min) * minMaxDelta_;
510 m_modified_Image =
false;
511 m_modified_Z =
false;
512 trianglesUpToDate =
false;
519 trianglesUpToDate =
false;
530 trianglesUpToDate =
false;
545 if (!trianglesUpToDate || !polygonsUpToDate) updatePolygons();
551 const std::pair<CSetOfTriangles::TTriangle, CMesh::TTriangleVertexIndices>&
555 for (
size_t i = 0; i < 3; i++)
566 if (!trianglesUpToDate) updateTriangles();
567 size_t N = actualMesh.size();
570 actualMesh.begin(), actualMesh.end(), tmpPolys.begin(),
572 polygonsUpToDate =
true;
~CMesh() override
Private, virtual destructor: only can be deleted from smart pointers.
void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
void colormap(const TColormap &color_map, const float color_index, float &r, float &g, float &b)
Transform a float number in the range [0,1] into RGB components.
TColormap
Different colormaps for use in mrpt::img::colormap()
void assignImageAndZ(const mrpt::img::CImage &img, const mrpt::math::CMatrixDynamic< float > &in_Z)
Assigns a texture image and Z simultaneously, and disable transparency.
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
GLAPI void GLAPIENTRY glEnable(GLenum cap)
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::math::TPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
#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)
Slightly heavyweight type to speed-up calculations with polygons in 3D.
This file implements several operations that operate element-wise on individual or pairs of container...
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
void setUV(const mrpt::math::CMatrixDynamic< float > &in_U, const mrpt::math::CMatrixDynamic< float > &in_V)
Sets the (u,v) texture coordinates (in range [0,1]) for each cell.
void render_dl() const override
Render.
#define GL_ONE_MINUS_SRC_ALPHA
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
#define GL_COLOR_MATERIAL
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
void setMask(const mrpt::math::CMatrixDynamic< float > &in_mask)
This method sets the boolean mask of valid heights for each position (cell) in the mesh grid...
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
void assignImage(const mrpt::img::CImage &img)
Assigns a texture image, and disable transparency.
A renderizable object suitable for rendering with OpenGL's display lists.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
#define ASSERT_(f)
Defines an assertion mechanism.
This base provides a set of functions for maths stuff.
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
void normalize(CONTAINER &c, Scalar valMin, Scalar valMax)
Scales all elements such as the minimum & maximum values are shifted to the given values...
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Trace ray.
GLAPI void GLAPIENTRY glBegin(GLenum mode)
void updatePolygons() const
size_type rows() const
Number of rows in the matrix.
size_type cols() const
Number of columns in the matrix.
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 setZ(const mrpt::math::CMatrixDynamic< float > &in_Z)
This method sets the matrix of heights for each position (cell) in the mesh grid. ...
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
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...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
The namespace for 3D scene representation and rendering.
void updateColorsMatrix() const
Called internally to assure C is updated.
GLAPI void GLAPIENTRY glEnd(void)
mrpt::math::TPolygonWithPlane createPolygonFromTriangle(const std::pair< CSetOfTriangles::TTriangle, CMesh::TTriangleVertexIndices > &p)
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
A planar (XY) grid where each cell has an associated height and, optionally, a texture map...
GLuint GLenum GLenum transform
GLAPI void GLAPIENTRY glDisable(GLenum cap)
This template class provides the basic functionality for a general 2D any-size, resizable container o...
static math::TPolygon3D tmpPoly(3)
void updateTriangles() const
Called internally to assure the triangle list is updated.
3D polygon, inheriting from std::vector<TPoint3D>
A class for storing images as grayscale or RGB bitmaps.