MRPT  1.9.9
CAngularObservationMesh.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, 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 #ifndef opengl_CAngularObservationMesh_H
10 #define opengl_CAngularObservationMesh_H
11 
15 #include <mrpt/math/CMatrixB.h>
17 #include <mrpt/maps/CPointsMap.h>
19 
20 #include <mrpt/math/geometry.h>
21 
22 namespace mrpt::opengl
23 {
24 /**
25  * A mesh built from a set of 2D laser scan observations.
26  * Each element of this set is a single scan through the yaw, given a specific
27  * pitch.
28  * Each scan has a mrpt::poses::CPose3D identifying the origin of the scan,
29  * which ideally is the
30  * same for every one of them.
31  *
32  * <div align="center">
33  * <table border="0" cellspan="4" cellspacing="4" style="border-width: 1px;
34  * border-style: solid;">
35  * <tr> <td> mrpt::opengl::CAngularObservationMesh </td> <td> \image html
36  * preview_CAngularObservationMesh.png </td> </tr>
37  * </table>
38  * </div>
39  *
40  * \ingroup mrpt_maps_grp
41  */
43 {
45  public:
46  /**
47  * Range specification type, with several uses.
48  */
49  struct TDoubleRange
50  {
51  private:
52  /**
53  * Range type.
54  * If 0, it's specified by an initial and a final value, and an
55  * increment.
56  * If 1, it's specified by an initial and a final value, and a fixed
57  * size of samples.
58  * If 2, it's specified by an aperture, a fixed size of samples and a
59  * boolean variable controlling direction. This type is always
60  * zero-centered.
61  */
62  char rangeType;
63  /**
64  * Union type with the actual data.
65  * \sa rangeType
66  */
67  union rd {
68  struct
69  {
70  double initial;
71  double final;
72  double increment;
73  } mode0;
74  struct
75  {
76  double initial;
77  double final;
78  size_t amount;
79  } mode1;
80  struct
81  {
82  double aperture;
83  size_t amount;
84  bool negToPos;
85  } mode2;
86  } rangeData;
87 
88  public:
89  /**
90  * Constructor from initial value, final value and range.
91  */
92  TDoubleRange(double a, double b, double c) : rangeType(0)
93  {
97  }
98  /**
99  * Constructor from initial value, final value and amount of samples.
100  */
101  TDoubleRange(double a, double b, size_t c) : rangeType(1)
102  {
106  }
107  /**
108  * Constructor from aperture, amount of samples and scan direction.
109  */
110  TDoubleRange(double a, size_t b, bool c) : rangeType(2)
111  {
115  }
116  /**
117  * Creates a range of values from the initial value, the final value
118  * and the increment.
119  * \throw std::logic_error if the increment is zero.
120  */
122  double initial, double final, double increment)
123  {
124  if (increment == 0)
125  throw std::logic_error("Invalid increment value.");
126  return TDoubleRange(initial, final, increment);
127  }
128  /**
129  * Creates a range of values from the initial value, the final value
130  * and a desired amount of samples.
131  */
133  double initial, double final, size_t amount)
134  {
135  return TDoubleRange(initial, final, amount);
136  }
137  /**
138  * Creates a zero-centered range of values from an aperture, an amount
139  * of samples and a direction.
140  */
142  double aperture, size_t amount, bool negToPos = true)
143  {
145  }
146  /**
147  * Returns the total aperture of the range.
148  * \throw std::logic_error on invalid range type.
149  */
150  inline double aperture() const
151  {
152  switch (rangeType)
153  {
154  case 0:
155  return (mrpt::sign(rangeData.mode0.increment) ==
156  mrpt::sign(
159  ? fabs(
162  : 0;
163  case 1:
165  case 2:
166  return rangeData.mode2.aperture;
167  default:
168  throw std::logic_error("Unknown range type.");
169  }
170  }
171  /**
172  * Returns the first value of the range.
173  * \throw std::logic_error on invalid range type.
174  */
175  inline double initialValue() const
176  {
177  switch (rangeType)
178  {
179  case 0:
180  case 1:
181  return rangeData.mode0.initial;
182  case 2:
183  return rangeData.mode2.negToPos
184  ? -rangeData.mode2.aperture / 2
185  : rangeData.mode2.aperture / 2;
186  default:
187  throw std::logic_error("Unknown range type.");
188  }
189  }
190  /**
191  * Returns the last value of the range.
192  * \throw std::logic_error on invalid range type.
193  */
194  inline double finalValue() const
195  {
196  switch (rangeType)
197  {
198  case 0:
199  return (mrpt::sign(rangeData.mode0.increment) ==
200  mrpt::sign(
205  case 1:
206  return rangeData.mode1.final;
207  case 2:
208  return rangeData.mode2.negToPos
209  ? rangeData.mode2.aperture / 2
210  : -rangeData.mode2.aperture / 2;
211  default:
212  throw std::logic_error("Unknown range type.");
213  }
214  }
215  /**
216  * Returns the increment between two consecutive values of the range.
217  * \throw std::logic_error on invalid range type.
218  */
219  inline double increment() const
220  {
221  switch (rangeType)
222  {
223  case 0:
224  return rangeData.mode0.increment;
225  case 1:
227  static_cast<double>(rangeData.mode1.amount - 1);
228  case 2:
229  return rangeData.mode2.negToPos
231  static_cast<double>(
232  rangeData.mode2.amount - 1)
234  static_cast<double>(
235  rangeData.mode2.amount - 1);
236  default:
237  throw std::logic_error("Unknown range type.");
238  }
239  }
240  /**
241  * Returns the total amount of values in this range.
242  * \throw std::logic_error on invalid range type.
243  */
244  inline size_t amount() const
245  {
246  switch (rangeType)
247  {
248  case 0:
249  return (mrpt::sign(rangeData.mode0.increment) ==
250  mrpt::sign(
253  ? 1 + static_cast<size_t>(
254  ceil(
258  : 1;
259  case 1:
260  return rangeData.mode1.amount;
261  case 2:
262  return rangeData.mode2.amount;
263  default:
264  throw std::logic_error("Unknown range type.");
265  }
266  }
267  /**
268  * Gets a vector with every value in the range.
269  * \throw std::logic_error on invalid range type.
270  */
271  void values(std::vector<double>& vals) const;
272  /**
273  * Returns the direction of the scan. True if the increment is
274  * positive, false otherwise.
275  * \throw std::logic_error on invalid range type.
276  */
277  inline bool negToPos() const
278  {
279  switch (rangeType)
280  {
281  case 0:
282  return mrpt::sign(rangeData.mode0.increment) > 0;
283  case 1:
284  return mrpt::sign(
286  rangeData.mode1.initial) > 0;
287  case 2:
288  return rangeData.mode2.negToPos;
289  default:
290  throw std::logic_error("Unknown range type.");
291  }
292  }
293  };
294 
295  void getBoundingBox(
296  mrpt::math::TPoint3D& bb_min,
297  mrpt::math::TPoint3D& bb_max) const override;
298 
299  protected:
300  /** Updates the mesh, if needed. It's a const method, but modifies mutable
301  * content. */
302  void updateMesh() const;
303  /** Actual set of triangles to be displayed. */
304  mutable std::vector<CSetOfTriangles::TTriangle> triangles;
305  /** Internal method to add a triangle to the mutable mesh. */
306  void addTriangle(
307  const mrpt::math::TPoint3D& p1, const mrpt::math::TPoint3D& p2,
308  const mrpt::math::TPoint3D& p3) const;
309  /** Whether the mesh will be displayed wireframe or solid. */
311  /** Mutable variable which controls if the object has suffered any change
312  * since last time the mesh was updated. */
313  mutable bool meshUpToDate;
314  /** Whether the object may present transparencies or not. */
316  /** Mutable object with the mesh's points. */
318  /** Scan validity matrix. */
320  /** Observation pitch range. When containing exactly two elements, they
321  * represent the bounds. */
322  std::vector<double> pitchBounds;
323  /** Actual scan set which is used to generate the mesh. */
324  std::vector<mrpt::obs::CObservation2DRangeScan> scanSet;
325 
326  public:
327  /**
328  * Basic constructor.
329  */
331  : mWireframe(true),
332  meshUpToDate(false),
333  mEnableTransparency(true),
334  actualMesh(0, 0),
335  validityMatrix(0, 0),
336  pitchBounds(),
337  scanSet()
338  {
339  }
340  /** Empty destructor. */
342  /**
343  * Returns whether the object is configured as wireframe or solid.
344  */
345  inline bool isWireframe() const { return mWireframe; }
346  /**
347  * Sets the display mode for the object. True=wireframe, False=solid.
348  */
349  inline void setWireframe(bool enabled = true)
350  {
351  mWireframe = enabled;
353  }
354  /**
355  * Returns whether the object may be transparent or not.
356  */
357  inline bool isTransparencyEnabled() const { return mEnableTransparency; }
358  /**
359  * Enables or disables transparencies.
360  */
361  inline void enableTransparency(bool enabled = true)
362  {
363  mEnableTransparency = enabled;
365  }
366  /**
367  * Renderizes the object.
368  * \sa mrpt::opengl::CRenderizable
369  */
370  virtual void render_dl() const override;
371  /**
372  * Traces a ray to the object, returning the distance to a given pose
373  * through its X axis.
374  * \sa mrpt::opengl::CRenderizable,trace2DSetOfRays,trace1DSetOfRays
375  */
376  bool traceRay(const mrpt::poses::CPose3D& o, double& dist) const override;
377  /**
378  * Sets the pitch bounds for this range.
379  */
380  void setPitchBounds(const double initial, const double final);
381  /**
382  * Sets the pitch bounds for this range.
383  */
384  void setPitchBounds(const std::vector<double>& bounds);
385  /**
386  * Gets the initial and final pitch bounds for this range.
387  */
388  void getPitchBounds(double& initial, double& final) const;
389  /**
390  * Gets the pitch bounds for this range.
391  */
392  void getPitchBounds(std::vector<double>& bounds) const;
393  /**
394  * Gets the scan set.
395  */
396  void getScanSet(
397  std::vector<mrpt::obs::CObservation2DRangeScan>& scans) const;
398  /**
399  * Sets the scan set.
400  */
401  bool setScanSet(
402  const std::vector<mrpt::obs::CObservation2DRangeScan>& scans);
403  /**
404  * Gets the mesh as a set of triangles, for displaying them.
405  * \sa generateSetOfTriangles(std::vector<TPolygon3D>
406  * &),mrpt::opengl::CSetOfTriangles,mrpt::opengl::CSetOfTriangles::TTriangle
407  */
409  /**
410  * Returns the scanned points as a 3D point cloud. The target pointmap must
411  * be passed as a pointer to allow the use of any derived class.
412  */
413  void generatePointCloud(mrpt::maps::CPointsMap* out_map) const;
414  /**
415  * Gets a set of lines containing the traced rays, for displaying them.
416  * \sa getUntracedRays,mrpt::opengl::CSetOfLines
417  */
418  void getTracedRays(CSetOfLines::Ptr& res) const;
419  /**
420  * Gets a set of lines containing the untraced rays, up to a specified
421  * distance, for displaying them.
422  * \sa getTracedRays,mrpt::opengl::CSetOfLines
423  */
424  void getUntracedRays(CSetOfLines::Ptr& res, double dist) const;
425  /**
426  * Gets the mesh as a set of polygons, to work with them.
427  * \sa generateSetOfTriangles(mrpt::opengl::CSetOfTriangles &)
428  */
429  void generateSetOfTriangles(std::vector<mrpt::math::TPolygon3D>& res) const;
430  /**
431  * Retrieves the full mesh, along with the validity matrix.
432  */
435  mrpt::math::CMatrixBool& validity) const
436  {
437  if (!meshUpToDate) updateMesh();
438  pts = actualMesh;
439  validity = validityMatrix;
440  }
441 
442  private:
443  /**
444  * Internal functor class to trace a ray.
445  */
446  template <class T>
447  class FTrace1D
448  {
449  protected:
451  const T& e;
452  std::vector<double>& values;
453  std::vector<char>& valid;
454 
455  public:
457  const T& s, const mrpt::poses::CPose3D& p, std::vector<double>& v,
458  std::vector<char>& v2)
459  : initial(p), e(s), values(v), valid(v2)
460  {
461  }
462  void operator()(double yaw)
463  {
464  double dist;
465  const mrpt::poses::CPose3D pNew =
466  initial + mrpt::poses::CPose3D(0.0, 0.0, 0.0, yaw, 0.0, 0.0);
467  if (e->traceRay(pNew, dist))
468  {
469  values.push_back(dist);
470  valid.push_back(1);
471  }
472  else
473  {
474  values.push_back(0);
475  valid.push_back(0);
476  }
477  }
478  };
479  /**
480  * Internal functor class to trace a set of rays.
481  */
482  template <class T>
483  class FTrace2D
484  {
485  protected:
486  const T& e;
490  std::vector<mrpt::obs::CObservation2DRangeScan>& vObs;
492 
493  public:
495  const T& s, const mrpt::poses::CPose3D& p,
498  std::vector<mrpt::obs::CObservation2DRangeScan>& obs,
499  const mrpt::poses::CPose3D& b)
500  : e(s), initial(p), caom(om), yaws(y), vObs(obs), pBase(b)
501  {
502  }
503  void operator()(double pitch)
504  {
505  std::vector<double> yValues;
506  yaws.values(yValues);
509  const mrpt::poses::CPose3D pNew =
510  initial + mrpt::poses::CPose3D(0, 0, 0, 0, pitch, 0);
511  std::vector<double> values;
512  std::vector<char> valid;
513  size_t nY = yValues.size();
514  values.reserve(nY);
515  valid.reserve(nY);
516  for_each(
517  yValues.begin(), yValues.end(),
518  FTrace1D<T>(e, pNew, values, valid));
519  o.aperture = yaws.aperture();
520  o.rightToLeft = yaws.negToPos();
521  o.maxRange = 10000;
522  o.sensorPose = pNew;
523  o.deltaPitch = 0;
524  o.resizeScan(values.size());
525  for (size_t i = 0; i < values.size(); i++)
526  {
527  o.setScanRange(i, values[i]);
528  o.setScanRangeValidity(i, valid[i] != 0);
529  }
530  vObs.push_back(o);
531  }
532  };
533 
534  public:
535  /**
536  * 2D ray tracing (will generate a 3D mesh). Given an object and two
537  * ranges, realizes a scan from the initial pose and stores it in a
538  * CAngularObservationMesh object.
539  * The objective may be a COpenGLScene, a CRenderizable or any children of
540  * its.
541  * \sa mrpt::opengl::CRenderizable,mrpt::opengl::COpenGLScene.
542  */
543  template <class T>
544  static void trace2DSetOfRays(
545  const T& e, const mrpt::poses::CPose3D& initial,
546  CAngularObservationMesh::Ptr& caom, const TDoubleRange& pitchs,
547  const TDoubleRange& yaws);
548  /**
549  * 2D ray tracing (will generate a vectorial mesh inside a plane). Given an
550  * object and a range, realizes a scan from the initial pose and stores it
551  * in a CObservation2DRangeScan object.
552  * The objective may be a COpenGLScene, a CRenderizable or any children of
553  * its.
554  * \sa mrpt::opengl::CRenderizable,mrpt::opengl::COpenGLScene.
555  */
556  template <class T>
557  static void trace1DSetOfRays(
558  const T& e, const mrpt::poses::CPose3D& initial,
560  {
561  std::vector<double> yValues;
562  yaws.values(yValues);
565  size_t nV = yaws.amount();
566  scanValues.reserve(nV);
567  valid.reserve(nV);
568  for_each(
569  yValues.begin(), yValues.end(),
570  FTrace1D<T>(e, initial, scanValues, valid));
571  obs.aperture = yaws.aperture();
572  obs.rightToLeft = yaws.negToPos();
573  obs.maxRange = 10000;
574  obs.sensorPose = initial;
575  obs.deltaPitch = 0;
576  obs.scan = scanValues;
577  obs.validRange = valid;
578  }
579 };
580 
581 template <class T>
583  const T& e, const mrpt::poses::CPose3D& initial,
584  CAngularObservationMesh::Ptr& caom, const TDoubleRange& pitchs,
585  const TDoubleRange& yaws)
586 {
587  std::vector<double> pValues;
588  pitchs.values(pValues);
589  std::vector<mrpt::obs::CObservation2DRangeScan> vObs;
590  vObs.reserve(pValues.size());
591  for_each(
592  pValues.begin(), pValues.end(),
593  FTrace2D<T>(e, initial, caom, yaws, vObs, initial));
594  caom->mWireframe = false;
595  caom->mEnableTransparency = false;
596  caom->setPitchBounds(pValues);
597  caom->setScanSet(vObs);
598 }
599 }
600 #endif
601 
602 
void getUntracedRays(CSetOfLines::Ptr &res, double dist) const
Gets a set of lines containing the untraced rays, up to a specified distance, for displaying them...
bool meshUpToDate
Mutable variable which controls if the object has suffered any change since last time the mesh was up...
bool negToPos() const
Returns the direction of the scan.
void getActualMesh(mrpt::math::CMatrixTemplate< mrpt::math::TPoint3D > &pts, mrpt::math::CMatrixBool &validity) const
Retrieves the full mesh, along with the validity matrix.
A mesh built from a set of 2D laser scan observations.
Internal functor class to trace a set of rays.
Internal functor class to trace a ray.
Declares a matrix of booleans (non serializable).
FTrace2D(const T &s, const mrpt::poses::CPose3D &p, CAngularObservationMesh::Ptr &om, const CAngularObservationMesh::TDoubleRange &y, std::vector< mrpt::obs::CObservation2DRangeScan > &obs, const mrpt::poses::CPose3D &b)
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:3582
TDoubleRange(double a, size_t b, bool c)
Constructor from aperture, amount of samples and scan direction.
virtual ~CAngularObservationMesh()
Empty destructor.
void setScanRange(const size_t i, const float val)
mrpt::math::CMatrixTemplate< mrpt::math::TPoint3D > actualMesh
Mutable object with the mesh&#39;s points.
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Traces a ray to the object, returning the distance to a given pose through its X axis.
struct mrpt::opengl::CAngularObservationMesh::TDoubleRange::rd::@11 mode1
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
std::vector< T, mrpt::aligned_allocator_cpp11< T > > aligned_std_vector
std::vector< mrpt::obs::CObservation2DRangeScan > & vObs
GLdouble s
Definition: glext.h:3676
bool mEnableTransparency
Whether the object may present transparencies or not.
void setWireframe(bool enabled=true)
Sets the display mode for the object.
void getTracedRays(CSetOfLines::Ptr &res) const
Gets a set of lines containing the traced rays, for displaying them.
bool isTransparencyEnabled() const
Returns whether the object may be transparent or not.
mrpt::containers::ContainerReadOnlyProxyAccessor< mrpt::aligned_std_vector< char > > validRange
It&#39;s false (=0) on no reflected rays, referenced to elements in scan.
void getScanSet(std::vector< mrpt::obs::CObservation2DRangeScan > &scans) const
Gets the scan set.
void values(std::vector< double > &vals) const
Gets a vector with every value in the range.
float maxRange
The maximum range allowed by the device, in meters (e.g.
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
double finalValue() const
Returns the last value of the range.
void getPitchBounds(double &initial, double &final) const
Gets the initial and final pitch bounds for this range.
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans or other sensors...
Definition: CPointsMap.h:64
mrpt::math::CMatrixB validityMatrix
Scan validity matrix.
void generateSetOfTriangles(CSetOfTriangles::Ptr &res) const
Gets the mesh as a set of triangles, for displaying them.
mrpt::containers::ContainerReadOnlyProxyAccessor< mrpt::aligned_std_vector< float > > scan
The range values of the scan, in meters.
const GLubyte * c
Definition: glext.h:6313
double initialValue() const
Returns the first value of the range.
size_t amount() const
Returns the total amount of values in this range.
FTrace1D(const T &s, const mrpt::poses::CPose3D &p, std::vector< double > &v, std::vector< char > &v2)
GLubyte GLubyte b
Definition: glext.h:6279
struct mrpt::opengl::CAngularObservationMesh::TDoubleRange::rd::@10 mode0
double increment() const
Returns the increment between two consecutive values of the range.
const GLdouble * v
Definition: glext.h:3678
#define DEFINE_SERIALIZABLE(class_name)
This declaration must be inserted in all CSerializable classes definition, within the class declarati...
static TDoubleRange CreateFromIncrement(double initial, double final, double increment)
Creates a range of values from the initial value, the final value and the increment.
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
static void trace1DSetOfRays(const T &e, const mrpt::poses::CPose3D &initial, mrpt::obs::CObservation2DRangeScan &obs, const TDoubleRange &yaws)
2D ray tracing (will generate a vectorial mesh inside a plane).
static TDoubleRange CreateFromAmount(double initial, double final, size_t amount)
Creates a range of values from the initial value, the final value and a desired amount of samples...
const CAngularObservationMesh::TDoubleRange & yaws
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
bool mWireframe
Whether the mesh will be displayed wireframe or solid.
void resizeScan(const size_t len)
Resizes all data vectors to allocate a given number of scan rays.
void generatePointCloud(mrpt::maps::CPointsMap *out_map) const
Returns the scanned points as a 3D point cloud.
static TDoubleRange CreateFromAperture(double aperture, size_t amount, bool negToPos=true)
Creates a zero-centered range of values from an aperture, an amount of samples and a direction...
void addTriangle(const mrpt::math::TPoint3D &p1, const mrpt::math::TPoint3D &p2, const mrpt::math::TPoint3D &p3) const
Internal method to add a triangle to the mutable mesh.
double deltaPitch
If the laser gathers data by sweeping in the pitch/elevation angle, this holds the increment in "pitc...
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
union mrpt::opengl::CAngularObservationMesh::TDoubleRange::rd rangeData
float aperture
The "aperture" or field-of-view of the range finder, in radians (typically M_PI = 180 degrees)...
double aperture() const
Returns the total aperture of the range.
std::vector< mrpt::obs::CObservation2DRangeScan > scanSet
Actual scan set which is used to generate the mesh.
Range specification type, with several uses.
TDoubleRange(double a, double b, size_t c)
Constructor from initial value, final value and amount of samples.
This class is a "CSerializable" wrapper for "CMatrixBool".
Definition: CMatrixB.h:21
GLenum GLint GLint y
Definition: glext.h:3538
TDoubleRange(double a, double b, double c)
Constructor from initial value, final value and range.
int sign(T x)
Returns the sign of X as "1" or "-1".
void updateMesh() const
Updates the mesh, if needed.
virtual void render_dl() const override
Renderizes the object.
bool setScanSet(const std::vector< mrpt::obs::CObservation2DRangeScan > &scans)
Sets the scan set.
struct mrpt::opengl::CAngularObservationMesh::TDoubleRange::rd::@12 mode2
GLfloat GLfloat GLfloat v2
Definition: glext.h:4107
GLuint res
Definition: glext.h:7268
Lightweight 3D point.
void enableTransparency(bool enabled=true)
Enables or disables transparencies.
void setPitchBounds(const double initial, const double final)
Sets the pitch bounds for this range.
static void trace2DSetOfRays(const T &e, const mrpt::poses::CPose3D &initial, CAngularObservationMesh::Ptr &caom, const TDoubleRange &pitchs, const TDoubleRange &yaws)
2D ray tracing (will generate a 3D mesh).
std::vector< CSetOfTriangles::TTriangle > triangles
Actual set of triangles to be displayed.
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLfloat GLfloat p
Definition: glext.h:6305
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot at the moment of starting the scan.
std::vector< double > pitchBounds
Observation pitch range.
bool isWireframe() const
Returns whether the object is configured as wireframe or solid.
bool rightToLeft
The scanning direction: true=counterclockwise; false=clockwise.
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 setScanRangeValidity(const size_t i, const bool val)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020