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);
mrpt::math::TPolygonWithPlane createPolygonFromTriangle(const std::pair< CSetOfTriangles::TTriangle, CMesh::TTriangleVertexIndices > &p)
static math::TPolygon3D tmpPoly(3)
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
A class for storing images as grayscale or RGB bitmaps.
A matrix of dynamic size.
3D polygon, inheriting from std::vector<TPoint3D>
Slightly heavyweight type to speed-up calculations with polygons in 3D.
A planar (XY) grid where each cell has an associated height and, optionally, a texture map.
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Trace ray.
void updateColorsMatrix() const
Called internally to assure C is updated.
virtual ~CMesh()
Private, virtual destructor: only can be deleted from smart pointers.
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
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 updatePolygons() const
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
void setZ(const mrpt::math::CMatrixTemplateNumeric< float > &in_Z)
This method sets the matrix of heights for each position (cell) in the mesh grid.
void assignImage(const mrpt::img::CImage &img)
Assigns a texture image, and disable transparency.
void updateTriangles() const
Called internally to assure the triangle list is updated.
void assignImageAndZ(const mrpt::img::CImage &img, const mrpt::math::CMatrixTemplateNumeric< float > &in_Z)
Assigns a texture image and Z simultaneously, and disable transparency.
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.
void render_dl() const override
Render.
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.
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
A renderizable object suitable for rendering with OpenGL's display lists.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated)
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Virtual base class for "archives": classes abstracting I/O streams.
#define ASSERT_(f)
Defines an assertion mechanism.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
GLAPI void GLAPIENTRY glEnable(GLenum cap)
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
GLAPI void GLAPIENTRY glBegin(GLenum mode)
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
#define GL_COLOR_MATERIAL
#define GL_ONE_MINUS_SRC_ALPHA
GLAPI void GLAPIENTRY glEnd(void)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
GLuint GLenum GLenum transform
GLdouble GLdouble GLdouble r
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()
@ cmHOT
[New in MRPT 1.5.0]
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::math::TPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
This base provides a set of functions for maths stuff.
The namespace for 3D scene representation and rendering.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
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 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.
double x
X,Y,Z coordinates.