30 bool enableTransparency,
float xMin_p,
float xMax_p,
float yMin_p,
32 : m_textureImage(0, 0),
33 m_enableTransparency(enableTransparency),
47 m_modified_Image(false),
52 trianglesUpToDate(false)
75 const auto cols = Z.cols();
76 const auto rows = Z.rows();
79 if (cols == 0 && rows == 0)
return;
82 ASSERT_(xMax > xMin && yMax > yMin);
85 vertex_normals.assign(
86 (1 + cols) * (1 + rows),
87 std::pair<TPoint3D, size_t>(
TPoint3D(0, 0, 0), 0));
89 float cR[3], cG[3], cB[3], cA[3];
90 cA[0] = cA[1] = cA[2] = m_color.A / 255.f;
92 if ((m_colorFromZ) || (m_isImage))
98 cR[0] = cR[1] = cR[2] = m_color.R / 255.f;
99 cG[0] = cG[1] = cG[2] = m_color.G / 255.f;
100 cB[0] = cB[1] = cB[2] = m_color.B / 255.f;
103 bool useMask =
false;
104 if (
mask.cols() != 0 &&
mask.rows() != 0)
109 const float sCellX = (xMax - xMin) / (rows - 1);
110 const float sCellY = (yMax - yMin) / (cols - 1);
113 for (
int iX = 0; iX < rows - 1; iX++)
114 for (
int iY = 0; iY < cols - 1; iY++)
116 if (useMask && (!
mask(iX, iY) || !
mask(iX + 1, iY + 1)))
continue;
117 tri.
x[0] = xMin + iX * sCellX;
118 tri.
y[0] = yMin + iY * sCellY;
119 tri.
z[0] = Z(iX, iY);
120 tri.
x[2] = tri.
x[0] + sCellX;
121 tri.
y[2] = tri.
y[0] + sCellY;
122 tri.
z[2] = Z(iX + 1, iY + 1);
126 tvi.
vind[0] = iX + rows * iY;
127 tvi.
vind[2] = (iX + 1) + rows * (iY + 1);
135 if (!useMask ||
mask(iX + 1, iY))
139 tri.
z[1] = Z(iX + 1, iY);
140 for (
int i = 0; i < 3; i++)
146 m_colorMap, C(iX, iY), tri.
r[0], tri.
g[0], tri.
b[0]);
148 m_colorMap, C(iX + 1, iY), tri.
r[1], tri.
g[1],
151 m_colorMap, C(iX + 1, iY + 1), tri.
r[2], tri.
g[2],
156 if (m_textureImage.isColor())
158 tri.
r[0] = tri.
r[1] = tri.
r[2] = C_r(iX, iY);
159 tri.
g[0] = tri.
g[1] = tri.
g[2] = C_g(iX, iY);
160 tri.
b[0] = tri.
b[1] = tri.
b[2] = C_b(iX, iY);
164 tri.
r[0] = tri.
r[1] = tri.
r[2] = C(iX, iY);
165 tri.
g[0] = tri.
g[1] = tri.
g[2] = C(iX, iY);
166 tri.
b[0] = tri.
b[1] = tri.
b[2] = C(iX, iY);
171 tri.
r[0] = tri.
r[1] = tri.
r[2] = m_color.R / 255.f;
172 tri.
g[0] = tri.
g[1] = tri.
g[2] = m_color.G / 255.f;
173 tri.
b[0] = tri.
b[1] = tri.
b[2] = m_color.B / 255.f;
179 float ax = tri.
x[1] - tri.
x[0];
180 float bx = tri.
x[2] - tri.
x[0];
181 float ay = tri.
y[1] - tri.
y[0];
182 float by = tri.
y[2] - tri.
y[0];
183 float az = tri.
z[1] - tri.
z[0];
184 float bz = tri.
z[2] - tri.
z[0];
186 ay *
bz - az *
by, az * bx - ax *
bz, ax *
by - ay * bx);
189 tvi.
vind[1] = iX + 1 + rows * iY;
192 actualMesh.push_back(
198 for (
int k = 0; k < 3; k++)
200 vertex_normals[tvi.
vind[k]].first += this_normal;
201 vertex_normals[tvi.
vind[k]].second++;
210 if (!useMask ||
mask(iX, iY + 1))
218 tri.
z[2] = Z(iX, iY + 1);
222 m_colorMap, C(iX, iY), tri.
r[0], tri.
g[0], tri.
b[0]);
224 m_colorMap, C(iX + 1, iY + 1), tri.
r[1], tri.
g[1],
227 m_colorMap, C(iX, iY + 1), tri.
r[2], tri.
g[2],
232 if (m_textureImage.isColor())
234 tri.
r[0] = tri.
r[1] = tri.
r[2] = C_r(iX, iY);
235 tri.
g[0] = tri.
g[1] = tri.
g[2] = C_g(iX, iY);
236 tri.
b[0] = tri.
b[1] = tri.
b[2] = C_b(iX, iY);
240 tri.
r[0] = tri.
r[1] = tri.
r[2] = C(iX, iY);
241 tri.
g[0] = tri.
g[1] = tri.
g[2] = C(iX, iY);
242 tri.
b[0] = tri.
b[1] = tri.
b[2] = C(iX, iY);
247 tri.
r[0] = tri.
r[1] = tri.
r[2] = m_color.R / 255.f;
248 tri.
g[0] = tri.
g[1] = tri.
g[2] = m_color.G / 255.f;
249 tri.
b[0] = tri.
b[1] = tri.
b[2] = m_color.B / 255.f;
255 float ax = tri.
x[1] - tri.
x[0];
256 float bx = tri.
x[2] - tri.
x[0];
257 float ay = tri.
y[1] - tri.
y[0];
258 float by = tri.
y[2] - tri.
y[0];
259 float az = tri.
z[1] - tri.
z[0];
260 float bz = tri.
z[2] - tri.
z[0];
262 ay *
bz - az *
by, az * bx - ax *
bz, ax *
by - ay * bx);
266 tvi.
vind[2] = iX + rows * (iY + 1);
269 actualMesh.push_back(
275 for (
int k = 0; k < 3; k++)
277 vertex_normals[tvi.
vind[k]].first += this_normal;
278 vertex_normals[tvi.
vind[k]].second++;
284 for (
size_t i = 0; i < vertex_normals.size(); i++)
286 const size_t N = vertex_normals[i].second;
287 if (N > 0) vertex_normals[i].first *= 1.0 / N;
290 trianglesUpToDate =
true;
291 polygonsUpToDate =
false;
299 #if MRPT_HAS_OPENGL_GLUT 300 if (m_enableTransparency)
315 if (!trianglesUpToDate) updateTriangles();
317 for (
size_t i = 0; i < actualMesh.size(); i++)
327 for (
int k = 0; k < 3; k++)
340 if (!m_isWireFrame)
glEnd();
355 m_textureImage =
img;
358 Z.setSize(
img.getHeight(),
img.getWidth());
361 m_modified_Image =
true;
362 m_enableTransparency =
false;
363 m_colorFromZ =
false;
365 trianglesUpToDate =
false;
378 (
img.getWidth() ==
static_cast<size_t>(in_Z.cols())) &&
379 (
img.getHeight() ==
static_cast<size_t>(in_Z.rows())));
384 m_textureImage =
img;
386 m_modified_Image =
true;
387 m_enableTransparency =
false;
388 m_colorFromZ =
false;
390 trianglesUpToDate =
false;
400 writeToStreamRender(out);
403 out << m_textureImage;
404 out << xMin << xMax << yMin << yMax;
405 out << Z << U << V <<
mask;
406 out << m_enableTransparency;
409 out << m_isWireFrame;
420 readFromStreamRender(
in);
422 in >> m_textureImage;
429 in >> Z >> U >> V >>
mask;
430 in >> m_enableTransparency;
441 m_isWireFrame =
false;
445 trianglesUpToDate =
false;
450 trianglesUpToDate =
false;
456 if ((!m_modified_Z) && (!m_modified_Image))
return;
462 const int cols = m_textureImage.getWidth();
463 const int rows = m_textureImage.getHeight();
465 if ((cols != Z.cols()) || (rows != Z.rows()))
466 printf(
"\nTexture Image and Z sizes have to be equal");
468 else if (m_textureImage.isColor())
470 C_r.setSize(rows, cols);
471 C_g.setSize(rows, cols);
472 C_b.setSize(rows, cols);
473 m_textureImage.getAsRGBMatrices(C_r, C_g, C_b);
477 C.setSize(rows, cols);
478 m_textureImage.getAsMatrix(C);
483 const size_t cols = Z.cols();
484 const size_t rows = Z.rows();
485 C.setSize(rows, cols);
491 if (
mask.empty()) C.normalize(0.01f, 0.99f);
496 float val_max = -std::numeric_limits<float>::max(),
497 val_min = std::numeric_limits<float>::max();
498 bool any_valid =
false;
500 for (
size_t c = 0;
c < cols;
c++)
501 for (
size_t r = 0;
r < rows;
r++)
503 if (!
mask(
r,
c))
continue;
505 const float val = C(
r,
c);
512 float minMaxDelta = val_max - val_min;
513 if (minMaxDelta == 0) minMaxDelta = 1;
514 const float minMaxDelta_ = 1.0f / minMaxDelta;
515 C.array() = (C.array() - val_min) * minMaxDelta_;
520 m_modified_Image =
false;
521 m_modified_Z =
false;
522 trianglesUpToDate =
false;
529 trianglesUpToDate =
false;
540 trianglesUpToDate =
false;
555 if (!trianglesUpToDate || !polygonsUpToDate) updatePolygons();
561 const std::pair<CSetOfTriangles::TTriangle, CMesh::TTriangleVertexIndices>&
565 for (
size_t i = 0; i < 3; i++)
576 if (!trianglesUpToDate) updateTriangles();
577 size_t N = actualMesh.size();
580 actualMesh.begin(), actualMesh.end(), tmpPolys.begin(),
582 polygonsUpToDate =
true;
591 bb_min.
z = Z.minCoeff();
595 bb_max.
z = Z.maxCoeff();
598 m_pose.composePoint(bb_min, bb_min);
599 m_pose.composePoint(bb_max, bb_max);
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.
virtual ~CMesh()
Private, virtual destructor: only can be deleted from smart pointers.
TColormap
Different colormaps for use in mrpt::img::colormap()
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)
This must be inserted in all CSerializable classes implementation files.
void setZ(const mrpt::math::CMatrixTemplateNumeric< float > &in_Z)
This method sets the matrix of heights for each position (cell) in the mesh grid. ...
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
Slightly heavyweight type to speed-up calculations with polygons in 3D.
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.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
#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)
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 assignImageAndZ(const mrpt::img::CImage &img, const mrpt::math::CMatrixTemplateNumeric< float > &in_Z)
Assigns a texture image and Z simultaneously, and disable transparency.
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Trace ray.
double x
X,Y,Z coordinates.
GLAPI void GLAPIENTRY glBegin(GLenum mode)
void updatePolygons() const
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
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)
A matrix of dynamic size.
mrpt::math::TPolygonWithPlane createPolygonFromTriangle(const std::pair< CSetOfTriangles::TTriangle, CMesh::TTriangleVertexIndices > &p)
void setUV(const mrpt::math::CMatrixTemplateNumeric< float > &in_U, const mrpt::math::CMatrixTemplateNumeric< float > &in_V)
Sets the (u,v) texture coordinates (in range [0,1]) for each cell.
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...
void setMask(const mrpt::math::CMatrixTemplateNumeric< float > &in_mask)
This method sets the boolean mask of valid heights for each position (cell) in the mesh grid...
GLuint GLenum GLenum transform
GLAPI void GLAPIENTRY glDisable(GLenum cap)
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.