19 #include <Eigen/Dense>    31     bool enableTransparency, 
float m_xMin_p, 
float m_xMax_p, 
float m_yMin_p,
    33     : m_enableTransparency(enableTransparency),
    45     enableTextureLinearInterpolation(
true);
    73     const auto cols = Z.cols();
    74     const auto rows = Z.rows();
    77     if (cols == 0 && rows == 0) 
return;  
    84     vertex_normals.assign(
    85         (1 + cols) * (1 + rows),
    86         std::pair<TPoint3D, size_t>(
TPoint3D(0, 0, 0), 0));
    88     if (m_colorFromZ || m_isImage) updateColorsMatrix();
    91     if (mask.cols() != 0 && mask.rows() != 0)
    93         ASSERT_(mask.cols() == cols && mask.rows() == rows);
    96     const float sCellX = (m_xMax - m_xMin) / (rows - 1);
    97     const float sCellY = (m_yMax - m_yMin) / (cols - 1);
   101     for (
int iX = 0; iX < rows - 1; iX++)
   102         for (
int iY = 0; iY < cols - 1; iY++)
   104             if (useMask && (!mask(iX, iY) || !mask(iX + 1, iY + 1))) 
continue;
   105             tri.
x(0) = m_xMin + iX * sCellX;
   106             tri.
y(0) = m_yMin + iY * sCellY;
   107             tri.
z(0) = Z(iX, iY);
   108             tri.
x(2) = tri.
x(0) + sCellX;
   109             tri.
y(2) = tri.
y(0) + sCellY;
   110             tri.
z(2) = Z(iX + 1, iY + 1);
   114             tvi.
vind[0] = iX + rows * iY;
   115             tvi.
vind[2] = (iX + 1) + rows * (iY + 1);
   123             if (!useMask || mask(iX + 1, iY))
   127                 tri.
z(1) = Z(iX + 1, iY);
   129                 for (
int i = 0; i < 3; i++) tri.
a(i) = m_color.A;
   134                     colormap(m_colorMap, C(iX, iY), col.
R, col.
G, col.
B);
   138                     colormap(m_colorMap, C(iX + 1, iY), col.
R, col.
G, col.
B);
   143                         m_colorMap, C(iX + 1, iY + 1), col.
R, col.
G, col.
B);
   150                     if (getTextureImage().isColor())
   152                         tri.
r(0) = tri.
r(1) = tri.
r(2) = C_r(iX, iY);
   153                         tri.
g(0) = tri.
g(1) = tri.
g(2) = C_g(iX, iY);
   154                         tri.
b(0) = tri.
b(1) = tri.
b(2) = C_b(iX, iY);
   158                         tri.
r(0) = tri.
r(1) = tri.
r(2) = C(iX, iY);
   159                         tri.
g(0) = tri.
g(1) = tri.
g(2) = C(iX, iY);
   160                         tri.
b(0) = tri.
b(1) = tri.
b(2) = C(iX, iY);
   165                     tri.
r(0) = tri.
r(1) = tri.
r(2) = m_color.R / 255.f;
   166                     tri.
g(0) = tri.
g(1) = tri.
g(2) = m_color.G / 255.f;
   167                     tri.
b(0) = tri.
b(1) = tri.
b(2) = m_color.B / 255.f;
   173                 float ax = tri.
x(1) - tri.
x(0);
   174                 float bx = tri.
x(2) - tri.
x(0);
   175                 float ay = tri.
y(1) - tri.
y(0);
   176                 float by = tri.
y(2) - tri.
y(0);
   177                 float az = tri.
z(1) - tri.
z(0);
   178                 float bz = tri.
z(2) - tri.
z(0);
   180                     ay * bz - az * by, az * bx - ax * bz, ax * by - ay * bx);
   183                 tvi.
vind[1] = iX + 1 + rows * iY;
   186                 actualMesh.emplace_back(tri, tvi);
   189                 for (
unsigned long k : tvi.
vind)
   191                     vertex_normals[k].first += this_normal;
   192                     vertex_normals[k].second++;
   201             if (!useMask || mask(iX, iY + 1))
   209                 tri.
z(2) = Z(iX, iY + 1);
   214                     colormap(m_colorMap, C(iX, iY), col.
R, col.
G, col.
B);
   219                         m_colorMap, C(iX + 1, iY + 1), col.
R, col.
G, col.
B);
   223                     colormap(m_colorMap, C(iX, iY + 1), col.
R, col.
G, col.
B);
   230                     if (getTextureImage().isColor())
   232                         tri.
r(0) = tri.
r(1) = tri.
r(2) = C_r(iX, iY);
   233                         tri.
g(0) = tri.
g(1) = tri.
g(2) = C_g(iX, iY);
   234                         tri.
b(0) = tri.
b(1) = tri.
b(2) = C_b(iX, iY);
   238                         tri.
r(0) = tri.
r(1) = tri.
r(2) = C(iX, iY);
   239                         tri.
g(0) = tri.
g(1) = tri.
g(2) = C(iX, iY);
   240                         tri.
b(0) = tri.
b(1) = tri.
b(2) = C(iX, iY);
   245                     tri.
r(0) = tri.
r(1) = tri.
r(2) = m_color.R / 255.f;
   246                     tri.
g(0) = tri.
g(1) = tri.
g(2) = m_color.G / 255.f;
   247                     tri.
b(0) = tri.
b(1) = tri.
b(2) = m_color.B / 255.f;
   253                 float ax = tri.
x(1) - tri.
x(0);
   254                 float bx = tri.
x(2) - tri.
x(0);
   255                 float ay = tri.
y(1) - tri.
y(0);
   256                 float by = tri.
y(2) - tri.
y(0);
   257                 float az = tri.
z(1) - tri.
z(0);
   258                 float bz = tri.
z(2) - tri.
z(0);
   260                     ay * bz - az * by, az * bx - ax * bz, ax * by - ay * bx);
   264                 tvi.
vind[2] = iX + rows * (iY + 1);
   267                 actualMesh.emplace_back(tri, tvi);
   270                 for (
unsigned long k : tvi.
vind)
   272                     vertex_normals[k].first += this_normal;
   273                     vertex_normals[k].second++;
   279     for (
auto& vertex_normal : vertex_normals)
   281         const size_t N = vertex_normal.second;
   284             vertex_normal.first *= 1.0 / N;
   285             vertex_normal.first = vertex_normal.first.
unitarize();
   289     m_trianglesUpToDate = 
true;
   290     m_polygonsUpToDate = 
false;
   308     if (!m_trianglesUpToDate) updateTriangles();
   321     for (
auto& i : actualMesh)
   325         for (
int kk = 0; kk <= 3; kk++)
   328             int k1 = (kk + 1) % 3;
   330             vbd.emplace_back(t.
x(k), t.
y(k), t.
z(k));
   331             cbd.emplace_back(t.
r(k), t.
g(k), t.
b(k), t.
a(k));
   333             vbd.emplace_back(t.
x(k1), t.
y(k1), t.
z(k1));
   334             cbd.emplace_back(t.
r(k1), t.
g(k1), t.
b(k1), t.
a(k1));
   344     for (
auto& i : actualMesh)
   349         const auto& n0 = vertex_normals.at(tvi.
vind[0]).first;
   350         const auto& n1 = vertex_normals.at(tvi.
vind[1]).first;
   351         const auto& n2 = vertex_normals.at(tvi.
vind[2]).first;
   356         tri.vertices[1].normal = n1;
   357         tri.vertices[2].normal = n2;
   359         for (
int k = 0; k < 3; k++)
   361             tri.vertices[k].uv.x =
   362                 (tri.vertices[k].xyzrgba.pt.x - m_xMin) / (m_xMax - m_xMin);
   363             tri.vertices[k].uv.y =
   364                 (tri.vertices[k].xyzrgba.pt.y - m_yMin) / (m_yMax - m_yMin);
   367         tris.emplace_back(std::move(tri));
   384     m_modified_Image = 
true;
   385     m_enableTransparency = 
false;
   386     m_colorFromZ = 
false;
   388     m_trianglesUpToDate = 
false;
   409     m_modified_Image = 
true;
   410     m_enableTransparency = 
false;
   411     m_colorFromZ = 
false;
   413     m_trianglesUpToDate = 
false;
   423     writeToStreamRender(
out);
   424     writeToStreamTexturedObject(
out);
   427     out << m_xMin << m_xMax << m_yMin << m_yMax;
   429     out << m_enableTransparency;
   432     out << m_isWireFrame;
   433     out << int16_t(m_colorMap);
   443             readFromStreamRender(in);
   444             readFromStreamTexturedObject(in);
   452             in >> m_enableTransparency;
   463                 m_isWireFrame = 
false;
   467             m_trianglesUpToDate = 
false;
   472     m_trianglesUpToDate = 
false;
   478     if ((!m_modified_Z) && (!m_modified_Image)) 
return;
   484         const int cols = getTextureImage().getWidth();
   485         const int rows = getTextureImage().getHeight();
   487         if ((cols != Z.cols()) || (rows != Z.rows()))
   488             printf(
"\nTexture Image and Z sizes have to be equal");
   490         else if (getTextureImage().isColor())
   492             C_r.setSize(rows, cols);
   493             C_g.setSize(rows, cols);
   494             C_b.setSize(rows, cols);
   495             getTextureImage().getAsRGBMatrices(C_r, C_g, C_b);
   499             C.setSize(rows, cols);
   500             getTextureImage().getAsMatrix(C);
   505         const size_t cols = Z.cols();
   506         const size_t rows = Z.rows();
   507         C.setSize(rows, cols);
   518             float val_max = -std::numeric_limits<float>::max(),
   519                   val_min = std::numeric_limits<float>::max();
   520             bool any_valid = 
false;
   522             for (
size_t c = 0; c < cols; c++)
   523                 for (
size_t r = 0; r < rows; r++)
   525                     if (!mask(r, c)) 
continue;
   527                     const float val = C(r, c);
   534                 float minMaxDelta = val_max - val_min;
   535                 if (minMaxDelta == 0) minMaxDelta = 1;
   536                 const float minMaxDelta_ = 1.0f / minMaxDelta;
   537                 C.array() = (C.array() - val_min) * minMaxDelta_;
   542     m_modified_Image = 
false;
   543     m_modified_Z = 
false;
   544     m_trianglesUpToDate = 
false;
   551     m_trianglesUpToDate = 
false;
   562     m_trianglesUpToDate = 
false;
   568     if (!m_trianglesUpToDate || !m_polygonsUpToDate) updatePolygons();
   574     const std::pair<mrpt::opengl::TTriangle, CMesh::TTriangleVertexIndices>& p)
   583     if (!m_trianglesUpToDate) updateTriangles();
   584     size_t N = actualMesh.size();
   587         actualMesh.begin(), actualMesh.end(), tmpPolys.begin(),
   589     m_polygonsUpToDate = 
true;
   612     const float ycenter = 0.5f * (m_yMin + m_yMax);
   613     const float xwidth = m_xMax - m_xMin;
   614     const float newratio = float(getTextureImage().getWidth()) /
   616     m_yMax = ycenter + 0.5f * newratio * xwidth;
   617     m_yMin = ycenter - 0.5f * newratio * xwidth;
 virtual ~CMesh() override
 
mrpt::math::TPoint3Df & vertex(size_t i)
 
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...
 
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 renderUpdateBuffers() const override
Called whenever m_outdatedBuffers is true: used to re-generate OpenGL vertex buffers, etc. 
 
const uint8_t & b(size_t i) const
 
void assignImageAndZ(const mrpt::img::CImage &img, const mrpt::math::CMatrixDynamic< float > &in_Z)
Assigns a texture image and Z simultaneously, and disable transparency. 
 
static constexpr shader_id_t TEXTURED_TRIANGLES
 
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object. 
 
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. 
 
const uint8_t & r(size_t i) const
 
void notifyChange() const
Call to enable calling renderUpdateBuffers() before the next render() rendering iteration. 
 
const float & x(size_t i) const
 
A triangle (float coordinates) with RGBA colors (u8) and UV (texture coordinates) for each vertex...
 
Slightly heavyweight type to speed-up calculations with polygons in 3D. 
 
mrpt::opengl::shader_id_t shader_id
 
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. 
 
The base class of 3D objects that can be directly rendered through OpenGL. 
 
const uint8_t & g(size_t i) const
 
size_t getHeight() const override
Returns the height of the image in pixels. 
 
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...
 
Context for calls to render() 
 
std::vector< mrpt::math::TPoint3Df > m_vertex_buffer_data
 
void assignImage(const mrpt::img::CImage &img)
Assigns a texture image. 
 
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations. 
 
const uint8_t & a(size_t i) const
 
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive. 
 
std::array< Vertex, 3 > vertices
 
#define ASSERT_(f)
Defines an assertion mechanism. 
 
This base provides a set of functions for maths stuff. 
 
size_t getWidth() const override
Returns the width of the image in pixels. 
 
void normalize(CONTAINER &c, Scalar valMin, Scalar valMax)
Scales all elements such as the minimum & maximum values are shifted to the given values...
 
static constexpr shader_id_t WIREFRAME
 
void render(const RenderContext &rc) const override
Implements the rendering of 3D objects in each class derived from CRenderizable. 
 
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Trace ray. 
 
TPoint3D_< double > TPoint3D
Lightweight 3D point. 
 
void updatePolygons() const
 
mrpt::math::TPolygonWithPlane createPolygonFromTriangle(const std::pair< mrpt::opengl::TTriangle, CMesh::TTriangleVertexIndices > &p)
 
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...
 
void render(const RenderContext &rc) const override
Implements the rendering of 3D objects in each class derived from CRenderizable. 
 
void setZ(const mrpt::math::CMatrixDynamic< float > &in_Z)
This method sets the matrix of heights for each position (cell) in the mesh grid. ...
 
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...
 
TPoint3D_< T > unitarize() const
Returns this vector with unit length: v/norm(v) 
 
std::vector< mrpt::img::TColor > m_color_buffer_data
 
uint8_t f2u8(const float f)
converts a float [0,1] into an uint8_t [0,255] (without checking for out of bounds) ...
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
const float & y(size_t i) const
 
Virtual base class for "archives": classes abstracting I/O streams. 
 
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...
 
void onUpdateBuffers_Wireframe() override
Must be implemented in derived classes to update the geometric entities to be drawn in "m_*_buffer" f...
 
A class used to store a 3D pose (a 3D translation + a rotation in 3D). 
 
mrpt::vision::TStereoCalibResults out
 
const float & z(size_t i) const
 
#define ASSERT_ABOVE_(__A, __B)
 
An RGBA color - floats in the range [0,1]. 
 
The namespace for 3D scene representation and rendering. 
 
void updateColorsMatrix() const
Called internally to assure C is updated. 
 
void adjustGridToImageAR()
Adjust grid limits according to the image aspect ratio, maintaining the X limits and resizing in the ...
 
void onUpdateBuffers_TexturedTriangles() override
Must be implemented in derived classes to update the geometric entities to be drawn in "m_*_buffer" f...
 
A planar (XY) grid where each cell has an associated height and, optionally, a texture map...
 
std::vector< mrpt::opengl::TTriangle > m_triangles
List of triangles. 
 
double getHeight(const TPolygon3D &p, const TPoint3D &c)
 
This template class provides the basic functionality for a general 2D any-size, resizable container o...
 
void render(const RenderContext &rc) const override
Implements the rendering of 3D objects in each class derived from CRenderizable. 
 
static math::TPolygon3D tmpPoly(3)
 
void updateTriangles() const
Called internally to assure the triangle list is updated. 
 
void assignImage(const mrpt::img::CImage &img, const mrpt::img::CImage &imgAlpha)
Assigns a texture and a transparency image, and enables transparency (If the images are not 2^N x 2^M...
 
3D polygon, inheriting from std::vector<TPoint3D> 
 
void renderUpdateBuffers() const override
Called whenever m_outdatedBuffers is true: used to re-generate OpenGL vertex buffers, etc. 
 
A class for storing images as grayscale or RGB bitmaps. 
 
void renderUpdateBuffers() const override
Called whenever m_outdatedBuffers is true: used to re-generate OpenGL vertex buffers, etc.