Main MRPT website > C++ reference for MRPT 1.9.9
CGeneralizedCylinder.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
12 #include <mrpt/poses/CPose3D.h>
13 #include <mrpt/math/geometry.h>
14 #include <mrpt/math/ops_matrices.h> // for extract*()
15 #include <mrpt/utils/CStream.h>
17 
18 #include "opengl_internals.h"
19 
20 using namespace mrpt;
21 using namespace mrpt::math;
22 using namespace mrpt::opengl;
23 using namespace mrpt::poses;
24 using namespace mrpt::utils;
25 using namespace std;
26 
29 
30 void CGeneralizedCylinder::TQuadrilateral::calculateNormal()
31 {
32  double ax = points[1].x - points[0].x;
33  double ay = points[1].y - points[0].y;
34  double az = points[1].z - points[0].z;
35  double bx = points[2].x - points[0].x;
36  double by = points[2].y - points[0].y;
37  double bz = points[2].z - points[0].z;
38  normal[0] = az * by - ay * bz;
39  normal[1] = ax * bz - az * bx;
40  normal[2] = ay * bx - ax * by;
41  double s = 0;
42  for (size_t i = 0; i < 3; i++) s += normal[i] * normal[i];
43  s = sqrt(s);
44  for (size_t i = 0; i < 3; i++) normal[i] /= s;
45 }
46 
47 #if MRPT_HAS_OPENGL_GLUT
48 class FQuadrilateralRenderer
49 {
50  private:
52 
53  public:
54  void operator()(const CGeneralizedCylinder::TQuadrilateral& t) const
55  {
56  glNormal3d(t.normal[0], t.normal[1], t.normal[2]);
57  for (int i = 0; i < 4; i++)
58  glVertex3d(t.points[i].x, t.points[i].y, t.points[i].z);
59  }
60  FQuadrilateralRenderer(const mrpt::utils::TColor& c) : color(c) {}
61  ~FQuadrilateralRenderer() {}
62 };
63 #endif
64 
65 void CGeneralizedCylinder::getMeshIterators(
66  const vector<TQuadrilateral>& m,
69 {
70  if (fullyVisible)
71  {
72  begin = m.begin();
73  end = m.end();
74  }
75  else
76  {
77  size_t qps =
78  m.size() / getNumberOfSections(); // quadrilaterals per section
79  begin = m.begin() + qps * firstSection;
80  end = m.begin() + qps * lastSection;
81  }
82 }
83 
84 void CGeneralizedCylinder::render_dl() const
85 {
86 #if MRPT_HAS_OPENGL_GLUT
87  if (!meshUpToDate) updateMesh();
91 
93  glColor4ub(m_color.R, m_color.G, m_color.B, m_color.A);
95  getMeshIterators(mesh, begin, end);
96  for_each(begin, end, FQuadrilateralRenderer(m_color));
97  glEnd();
98  if (m_color.A != 1.0) glDisable(GL_BLEND);
99 
100 #endif
101 }
102 
103 inline void createMesh(
104  const CMatrixTemplate<TPoint3D>& pointsMesh, size_t R, size_t C,
105  vector<CGeneralizedCylinder::TQuadrilateral>& mesh)
106 {
107  mesh.reserve(R * C);
108  for (size_t i = 0; i < R; i++)
109  for (size_t j = 0; j < C; j++)
110  mesh.push_back(
112  pointsMesh(i, j), pointsMesh(i, j + 1),
113  pointsMesh(i + 1, j + 1), pointsMesh(i + 1, j)));
114 }
115 
116 /*void transformMesh(const CPose3D &pose,const CMatrixTemplate<TPoint3D>
117 &in,CMatrixTemplate<TPoint3D> &out) {
118  size_t R=in.getRowCount();
119  size_t C=in.getColCount();
120  out.setSize(R,C);
121  for (size_t i=0;i<R;i++) for (size_t j=0;j<C;j++) {
122  TPoint3D pIn=in.get_unsafe(i,j);
123  TPoint3D &pOut=out.get_unsafe(i,j);
124  pose.composePoint(pIn.x,pIn.y,pIn.z,pOut.x,pOut.y,pOut.z);
125  }
126 }*/
127 
128 bool CGeneralizedCylinder::traceRay(const CPose3D& o, double& dist) const
129 {
130  if (!meshUpToDate || !polysUpToDate) updatePolys();
131  return math::traceRay(polys, o - this->m_pose, dist);
132 }
133 
134 void CGeneralizedCylinder::updateMesh() const
135 {
136  CRenderizableDisplayList::notifyChange();
137 
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();
142  mesh.clear();
143  if (A > 1 && G > 1)
144  {
145  pointsMesh = CMatrixTemplate<TPoint3D>(A, G);
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));
149  createMesh(pointsMesh, A - 1, G - 1, mesh);
150  }
151  meshUpToDate = true;
152  polysUpToDate = false;
153 }
154 
155 void CGeneralizedCylinder::writeToStream(
156  mrpt::utils::CStream& out, int* version) const
157 {
158  if (version)
159  *version = 1;
160  else
161  {
162  writeToStreamRender(out);
163  out << axis << generatrix; // In version 0, axis was a
164  // vector<TPoint3D>. In version 1, it is a
165  // vector<CPose3D>.
166  }
167 }
168 
169 void CGeneralizedCylinder::readFromStream(mrpt::utils::CStream& in, int version)
170 {
171  switch (version)
172  {
173  case 0:
174  {
175  readFromStreamRender(in);
176  vector<TPoint3D> a;
177  in >> a >> generatrix;
178  generatePoses(a, axis);
179  meshUpToDate = false;
180  polysUpToDate = false;
181  break;
182  }
183  case 1:
184  readFromStreamRender(in);
185  // version 0
186  in >> axis >> generatrix;
187  meshUpToDate = false;
188  polysUpToDate = false;
189  break;
190  default:
192  };
193  CRenderizableDisplayList::notifyChange();
194 }
195 
197  CPolyhedron::Ptr& poly, const vector<TPoint3D>& profile,
198  const CPose3D& pose)
199 {
200  math::TPolygon3D p(profile.size());
201  for (size_t i = 0; i < profile.size(); i++)
202  pose.composePoint(
203  profile[i].x, profile[i].y, profile[i].z, p[i].x, p[i].y, p[i].z);
204  vector<math::TPolygon3D> convexPolys;
205  if (!math::splitInConvexComponents(p, convexPolys))
206  convexPolys.push_back(p);
207  poly = mrpt::make_aligned_shared<CPolyhedron>(convexPolys);
208 }
209 
210 void CGeneralizedCylinder::getOrigin(CPolyhedron::Ptr& poly) const
211 {
212  if (!meshUpToDate) updateMesh();
213  if (axis.size() < 2 || generatrix.size() < 3)
214  throw std::logic_error("Not enough points.");
215  size_t i = fullyVisible ? 0 : firstSection;
216  generatePolygon(poly, generatrix, axis[i]);
217  poly->setPose(this->m_pose);
218  poly->setColor(getColor());
219 }
220 
221 void CGeneralizedCylinder::getEnd(CPolyhedron::Ptr& poly) const
222 {
223  if (!meshUpToDate) updateMesh();
224  if (axis.size() < 2 || generatrix.size() < 3)
225  throw std::logic_error("Not enough points.");
226  size_t i = (fullyVisible ? axis.size() : lastSection) - 1;
227  generatePolygon(poly, generatrix, axis[i]);
228  poly->setPose(this->m_pose);
229  poly->setColor(getColor());
230 }
231 
232 void CGeneralizedCylinder::generateSetOfPolygons(
233  std::vector<TPolygon3D>& res) const
234 {
235  if (!meshUpToDate || !polysUpToDate) updatePolys();
236  size_t N = polys.size();
237  res.resize(N);
238  for (size_t i = 0; i < N; i++) res[i] = polys[i].poly;
239 }
240 
241 void CGeneralizedCylinder::getClosedSection(
242  size_t index1, size_t index2, mrpt::opengl::CPolyhedron::Ptr& poly) const
243 {
244  if (index1 > index2) swap(index1, index2);
245  if (index2 >= axis.size() - 1) throw std::logic_error("Out of range");
246  CMatrixTemplate<TPoint3D> ROIpoints;
247  if (!meshUpToDate) updateMesh();
248  pointsMesh.extractRows(index1, index2 + 1, ROIpoints);
249  // At this point, ROIpoints contains a matrix of TPoints in which the number
250  // of rows equals (index2-index1)+2 and there is a column
251  // for each vertex in the generatrix.
252  if (!closed)
253  {
254  vector<TPoint3D> vec;
255  ROIpoints.extractCol(0, vec);
256  ROIpoints.appendCol(vec);
257  }
258  vector<TPoint3D> vertices;
259  ROIpoints.getAsVector(vertices);
260  size_t nr = ROIpoints.getRowCount() - 1;
261  size_t nc = ROIpoints.getColCount() - 1;
262  vector<vector<uint32_t>> faces;
263  faces.reserve(nr * nc + 2);
264  vector<uint32_t> tmp(4);
265  for (size_t i = 0; i < nr; i++)
266  for (size_t j = 0; j < nc; j++)
267  {
268  size_t base = (nc + 1) * i + j;
269  tmp[0] = base;
270  tmp[1] = base + 1;
271  tmp[2] = base + nc + 2;
272  tmp[3] = base + nc + 1;
273  faces.push_back(tmp);
274  }
275  tmp.resize(nr + 1);
276  for (size_t i = 0; i < nr + 1; i++) tmp[i] = i * (nc + 1);
277  faces.push_back(tmp);
278  for (size_t i = 0; i < nr + 1; i++) tmp[i] = i * (nc + 2) - 1;
279  poly = mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
280 }
281 
282 void CGeneralizedCylinder::removeVisibleSectionAtStart()
283 {
284  CRenderizableDisplayList::notifyChange();
285  if (fullyVisible)
286  {
287  if (!getNumberOfSections()) throw std::logic_error("No more sections");
288  fullyVisible = false;
289  firstSection = 1;
290  lastSection = getNumberOfSections();
291  }
292  else if (firstSection >= lastSection)
293  throw std::logic_error("No more sections");
294  else
295  firstSection++;
296 }
297 void CGeneralizedCylinder::removeVisibleSectionAtEnd()
298 {
299  CRenderizableDisplayList::notifyChange();
300  if (fullyVisible)
301  {
302  if (!getNumberOfSections()) throw std::logic_error("No more sections");
303  fullyVisible = false;
304  firstSection = 0;
305  lastSection = getNumberOfSections() - 1;
306  }
307  else if (firstSection >= lastSection)
308  throw std::logic_error("No more sections");
309  else
310  lastSection--;
311 }
312 
313 void CGeneralizedCylinder::updatePolys() const
314 {
315  CRenderizableDisplayList::notifyChange();
316 
317  if (!meshUpToDate) updateMesh();
318  size_t N = mesh.size();
319  polys.resize(N);
320  TPolygon3D tmp(4);
321  for (size_t i = 0; i < N; i++)
322  {
323  for (size_t j = 0; j < 4; j++) tmp[j] = mesh[i].points[j];
324  polys[i] = tmp;
325  }
326  polysUpToDate = true;
327 }
328 
329 void CGeneralizedCylinder::generatePoses(
330  const vector<TPoint3D>& pIn,
332 {
333  size_t N = pIn.size();
334  if (N == 0)
335  {
336  pOut.resize(0);
337  return;
338  }
339  vector<double> yaws;
340  yaws.reserve(N);
341  vector<TPoint3D>::const_iterator it1 = pIn.begin(), it2;
342  for (;;)
343  if ((it2 = it1 + 1) == pIn.end())
344  break;
345  else
346  {
347  yaws.push_back(atan2(it2->y - it1->y, it2->x - it1->x));
348  it1 = it2;
349  }
350  yaws.push_back(*yaws.rbegin());
351  pOut.resize(N);
352  for (size_t i = 0; i < N; i++)
353  {
354  const TPoint3D& p = pIn[i];
355  pOut[i] = CPose3D(p.x, p.y, p.z, yaws[i], 0, 0);
356  }
357 }
358 
359 bool CGeneralizedCylinder::getFirstSectionPose(CPose3D& p)
360 {
361  if (axis.size() <= 0) return false;
362  p = axis[0];
363  return true;
364 }
365 
366 bool CGeneralizedCylinder::getLastSectionPose(CPose3D& p)
367 {
368  if (axis.size() <= 0) return false;
369  p = *axis.rbegin();
370  return true;
371 }
372 
373 bool CGeneralizedCylinder::getFirstVisibleSectionPose(CPose3D& p)
374 {
375  if (fullyVisible) return getFirstSectionPose(p);
376  if (getVisibleSections() <= 0) return false;
377  p = axis[firstSection];
378  return true;
379 }
380 
381 bool CGeneralizedCylinder::getLastVisibleSectionPose(CPose3D& p)
382 {
383  if (fullyVisible) return getLastSectionPose(p);
384  if (getVisibleSections() <= 0) return false;
385  p = axis[lastSection];
386  return true;
387 }
388 
389 void CGeneralizedCylinder::getBoundingBox(
390  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
391 {
392  bb_min = TPoint3D(0, 0, 0);
393  bb_max = TPoint3D(0, 0, 0);
394 
395  // Convert to coordinates of my parent:
396  m_pose.composePoint(bb_min, bb_min);
397  m_pose.composePoint(bb_max, bb_max);
398 }
void extractCol(size_t nCol, std::vector< T > &out, int startingRow=0) const
Returns a given column to a vector (without modifying the matrix)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLdouble GLdouble t
Definition: glext.h:3689
bool splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
Definition: geometry.cpp:2389
GLbyte GLbyte bz
Definition: glext.h:6105
GLAPI void GLAPIENTRY glEnable(GLenum cap)
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons&#39; properties.
Definition: geometry.cpp:2582
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:29
std::shared_ptr< CPolyhedron > Ptr
Definition: CPolyhedron.h:46
This file implements miscelaneous matrix and matrix/vector operations, and internal functions in mrpt...
GLAPI void GLAPIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
STL namespace.
const Scalar * const_iterator
Definition: eigen_plugins.h:27
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
GLdouble s
Definition: glext.h:3676
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
GLsizei const GLfloat * points
Definition: glext.h:5339
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
GLuint color
Definition: glext.h:8300
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
#define GL_QUADS
Definition: glew.h:279
const GLubyte * c
Definition: glext.h:6313
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
GLuint GLuint end
Definition: glext.h:3528
GLAPI void GLAPIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
void generatePolygon(CPolyhedron::Ptr &poly, const vector< TPoint3D > &profile, const CPose3D &pose)
A RGB color - 8bit.
Definition: TColor.h:25
GLAPI void GLAPIENTRY glBegin(GLenum mode)
IMPLEMENTS_SERIALIZABLE(CGeneralizedCylinder, CRenderizableDisplayList, mrpt::opengl) void CGeneralizedCylinder
#define GL_BLEND
Definition: glew.h:432
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
void getAsVector(std::vector< T > &out) const
Returns a vector containing the matrix&#39;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...
#define GL_SRC_ALPHA
Definition: glew.h:286
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
This object represents any figure obtained by extruding any profile along a given axis...
const float R
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
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...
Definition: CPose3D.cpp:453
void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:140
GLuint in
Definition: glext.h:7274
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
size_t getColCount() const
Number of columns in the matrix.
GLAPI void GLAPIENTRY glEnd(void)
size_t getRowCount() const
Number of rows in the matrix.
GLbyte by
Definition: glext.h:6105
GLuint res
Definition: glext.h:7268
Lightweight 3D point.
Auxiliary struct holding any quadrilateral, represented by foour points.
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLfloat GLfloat p
Definition: glext.h:6305
std::vector< TYPE1, Eigen::aligned_allocator< TYPE1 > > vector_t
3D polygon, inheriting from std::vector<TPoint3D>
void createMesh(const CMatrixTemplate< TPoint3D > &pointsMesh, size_t R, size_t C, vector< CGeneralizedCylinder::TQuadrilateral > &mesh)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019