30 void CGeneralizedCylinder::TQuadrilateral::calculateNormal()
38 normal[0] = az *
by - ay *
bz;
39 normal[1] = ax *
bz - az * bx;
40 normal[2] = ay * bx - ax *
by;
42 for (
size_t i = 0; i < 3; i++)
s += normal[i] * normal[i];
44 for (
size_t i = 0; i < 3; i++) normal[i] /=
s;
47 #if MRPT_HAS_OPENGL_GLUT 48 class FQuadrilateralRenderer
57 for (
int i = 0; i < 4; i++)
61 ~FQuadrilateralRenderer() {}
65 void CGeneralizedCylinder::getMeshIterators(
66 const vector<TQuadrilateral>& m,
78 m.size() / getNumberOfSections();
79 begin = m.begin() + qps * firstSection;
80 end = m.begin() + qps * lastSection;
84 void CGeneralizedCylinder::render_dl()
const 86 #if MRPT_HAS_OPENGL_GLUT 87 if (!meshUpToDate) updateMesh();
93 glColor4ub(m_color.R, m_color.G, m_color.B, m_color.A);
96 for_each(
begin,
end, FQuadrilateralRenderer(m_color));
105 vector<CGeneralizedCylinder::TQuadrilateral>& mesh)
108 for (
size_t i = 0; i <
R; i++)
109 for (
size_t j = 0; j < C; j++)
112 pointsMesh(i, j), pointsMesh(i, j + 1),
113 pointsMesh(i + 1, j + 1), pointsMesh(i + 1, j)));
130 if (!meshUpToDate || !polysUpToDate) updatePolys();
134 void CGeneralizedCylinder::updateMesh()
const 136 CRenderizableDisplayList::notifyChange();
138 size_t A = axis.size();
139 vector<TPoint3D> genX = generatrix;
140 if (closed && genX.size() > 2) genX.push_back(genX[0]);
141 size_t G = genX.size();
146 for (
size_t i = 0; i < A; i++)
147 for (
size_t j = 0; j <
G; j++)
148 axis[i].composePoint(genX[j], pointsMesh.get_unsafe(i, j));
152 polysUpToDate =
false;
155 uint8_t CGeneralizedCylinder::serializeGetVersion()
const {
return 1; }
158 writeToStreamRender(out);
159 out << axis << generatrix;
163 void CGeneralizedCylinder::serializeFrom(
170 readFromStreamRender(
in);
172 in >>
a >> generatrix;
173 generatePoses(
a, axis);
174 meshUpToDate =
false;
175 polysUpToDate =
false;
179 readFromStreamRender(
in);
181 in >> axis >> generatrix;
182 meshUpToDate =
false;
183 polysUpToDate =
false;
188 CRenderizableDisplayList::notifyChange();
196 for (
size_t i = 0; i < profile.size(); i++)
198 profile[i].x, profile[i].y, profile[i].z,
p[i].x,
p[i].y,
p[i].z);
199 vector<math::TPolygon3D> convexPolys;
201 convexPolys.push_back(
p);
202 poly = mrpt::make_aligned_shared<CPolyhedron>(convexPolys);
207 if (!meshUpToDate) updateMesh();
208 if (axis.size() < 2 || generatrix.size() < 3)
209 throw std::logic_error(
"Not enough points.");
210 size_t i = fullyVisible ? 0 : firstSection;
212 poly->setPose(this->m_pose);
213 poly->setColor(getColor());
218 if (!meshUpToDate) updateMesh();
219 if (axis.size() < 2 || generatrix.size() < 3)
220 throw std::logic_error(
"Not enough points.");
221 size_t i = (fullyVisible ? axis.size() : lastSection) - 1;
223 poly->setPose(this->m_pose);
224 poly->setColor(getColor());
227 void CGeneralizedCylinder::generateSetOfPolygons(
228 std::vector<TPolygon3D>&
res)
const 230 if (!meshUpToDate || !polysUpToDate) updatePolys();
231 size_t N = polys.size();
233 for (
size_t i = 0; i < N; i++)
res[i] = polys[i].poly;
236 void CGeneralizedCylinder::getClosedSection(
239 if (index1 > index2) swap(index1, index2);
240 if (index2 >= axis.size() - 1)
throw std::logic_error(
"Out of range");
242 if (!meshUpToDate) updateMesh();
243 pointsMesh.extractRows(index1, index2 + 1, ROIpoints);
249 vector<TPoint3D> vec;
253 vector<TPoint3D> vertices;
255 size_t nr = ROIpoints.
rows() - 1;
256 size_t nc = ROIpoints.
cols() - 1;
257 vector<vector<uint32_t>> faces;
258 faces.reserve(nr * nc + 2);
259 vector<uint32_t> tmp(4);
260 for (
size_t i = 0; i < nr; i++)
261 for (
size_t j = 0; j < nc; j++)
263 size_t base = (nc + 1) * i + j;
266 tmp[2] = base + nc + 2;
267 tmp[3] = base + nc + 1;
268 faces.push_back(tmp);
271 for (
size_t i = 0; i < nr + 1; i++) tmp[i] = i * (nc + 1);
272 faces.push_back(tmp);
273 for (
size_t i = 0; i < nr + 1; i++) tmp[i] = i * (nc + 2) - 1;
274 poly = mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
277 void CGeneralizedCylinder::removeVisibleSectionAtStart()
279 CRenderizableDisplayList::notifyChange();
282 if (!getNumberOfSections())
throw std::logic_error(
"No more sections");
283 fullyVisible =
false;
285 lastSection = getNumberOfSections();
287 else if (firstSection >= lastSection)
288 throw std::logic_error(
"No more sections");
292 void CGeneralizedCylinder::removeVisibleSectionAtEnd()
294 CRenderizableDisplayList::notifyChange();
297 if (!getNumberOfSections())
throw std::logic_error(
"No more sections");
298 fullyVisible =
false;
300 lastSection = getNumberOfSections() - 1;
302 else if (firstSection >= lastSection)
303 throw std::logic_error(
"No more sections");
308 void CGeneralizedCylinder::updatePolys()
const 310 CRenderizableDisplayList::notifyChange();
312 if (!meshUpToDate) updateMesh();
313 size_t N = mesh.size();
316 for (
size_t i = 0; i < N; i++)
318 for (
size_t j = 0; j < 4; j++) tmp[j] = mesh[i].
points[j];
321 polysUpToDate =
true;
324 void CGeneralizedCylinder::generatePoses(
325 const vector<TPoint3D>& pIn,
328 size_t N = pIn.size();
338 if ((it2 = it1 + 1) == pIn.end())
342 yaws.push_back(atan2(it2->y - it1->y, it2->x - it1->x));
345 yaws.push_back(*yaws.rbegin());
347 for (
size_t i = 0; i < N; i++)
350 pOut[i] =
CPose3D(
p.x,
p.y,
p.z, yaws[i], 0, 0);
354 bool CGeneralizedCylinder::getFirstSectionPose(
CPose3D&
p)
356 if (axis.size() <= 0)
return false;
361 bool CGeneralizedCylinder::getLastSectionPose(
CPose3D&
p)
363 if (axis.size() <= 0)
return false;
368 bool CGeneralizedCylinder::getFirstVisibleSectionPose(
CPose3D&
p)
370 if (fullyVisible)
return getFirstSectionPose(
p);
371 if (getVisibleSections() <= 0)
return false;
372 p = axis[firstSection];
376 bool CGeneralizedCylinder::getLastVisibleSectionPose(
CPose3D&
p)
378 if (fullyVisible)
return getLastSectionPose(
p);
379 if (getVisibleSections() <= 0)
return false;
380 p = axis[lastSection];
384 void CGeneralizedCylinder::getBoundingBox(
391 m_pose.composePoint(bb_min, bb_min);
392 m_pose.composePoint(bb_max, bb_max);
void extractCol(size_t nCol, std::vector< T > &out, int startingRow=0) const
Returns a given column to a vector (without modifying the matrix)
bool splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
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.
EIGEN_STRONG_INLINE iterator begin()
This file implements miscelaneous matrix and matrix/vector operations, and internal functions in mrpt...
GLAPI void GLAPIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
#define GL_ONE_MINUS_SRC_ALPHA
std::vector< T, mrpt::aligned_allocator_cpp11< T > > aligned_std_vector
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
GLsizei const GLfloat * points
A renderizable object suitable for rendering with OpenGL's display lists.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
This base provides a set of functions for maths stuff.
size_t rows() const
Number of rows in the matrix.
GLAPI void GLAPIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
void generatePolygon(CPolyhedron::Ptr &poly, const vector< TPoint3D > &profile, const CPose3D &pose)
GLAPI void GLAPIENTRY glBegin(GLenum mode)
IMPLEMENTS_SERIALIZABLE(CGeneralizedCylinder, CRenderizableDisplayList, mrpt::opengl) void CGeneralizedCylinder
size_t cols() const
Number of columns in the matrix.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
void getAsVector(std::vector< T > &out) const
Returns a vector containing the matrix's values.
GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
This template class provides the basic functionality for a general 2D any-size, resizable container o...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
This object represents any figure obtained by extruding any profile along a given axis...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
void appendCol(const std::vector< T > &in)
Appends a new column to the matrix from a vector.
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
The namespace for 3D scene representation and rendering.
GLAPI void GLAPIENTRY glEnd(void)
Auxiliary struct holding any quadrilateral, represented by foour points.
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
const Scalar * const_iterator
3D polygon, inheriting from std::vector<TPoint3D>
void createMesh(const CMatrixTemplate< TPoint3D > &pointsMesh, size_t R, size_t C, vector< CGeneralizedCylinder::TQuadrilateral > &mesh)