MRPT  1.9.9
CDynamicGrid3D.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 #pragma once
10 
11 #include <mrpt/core/round.h>
12 #include <vector>
13 #include <cstdint>
14 #include <cmath>
15 #include <cstddef>
16 
17 namespace mrpt::containers
18 {
19 /** A 3D rectangular grid of dynamic size which stores any kind of data at each
20  * voxel.
21  * \tparam T The type of each voxel in the grid.
22  * \ingroup mrpt_containers_grp
23  */
24 template <class T>
26 {
27  public:
28  /** Constructor */
30  double x_min = -1.0, double x_max = 1.0, double y_min = -1.0,
31  double y_max = +1.0, double z_min = -1.0, double z_max = 1.0,
32  double resolution_xy = 0.5, double resolution_z = 0.5)
33  : m_map()
34  {
35  setSize(
36  x_min, x_max, y_min, y_max, z_min, z_max, resolution_xy,
37  resolution_z);
38  }
39 
40  /** Changes the size of the grid, maintaining previous contents.
41  * \sa setSize
42  */
43  virtual void resize(
44  double new_x_min, double new_x_max, double new_y_min, double new_y_max,
45  double new_z_min, double new_z_max, const T& defaultValueNewCells,
46  double additionalMarginMeters = 2.0)
47  {
48  // Is resize really necesary?
49  if (new_x_min >= m_x_min && new_y_min >= m_y_min &&
50  new_z_min >= m_z_min && new_x_max <= m_x_max &&
51  new_y_max <= m_y_max && new_z_max <= m_z_max)
52  return;
53 
54  if (new_x_min > m_x_min) new_x_min = m_x_min;
55  if (new_x_max < m_x_max) new_x_max = m_x_max;
56  if (new_y_min > m_y_min) new_y_min = m_y_min;
57  if (new_y_max < m_y_max) new_y_max = m_y_max;
58  if (new_z_min > m_z_min) new_z_min = m_z_min;
59  if (new_z_max < m_z_max) new_z_max = m_z_max;
60 
61  // Additional margin:
62  if (additionalMarginMeters > 0)
63  {
64  if (new_x_min < m_x_min)
65  new_x_min = floor(new_x_min - additionalMarginMeters);
66  if (new_x_max > m_x_max)
67  new_x_max = ceil(new_x_max + additionalMarginMeters);
68  if (new_y_min < m_y_min)
69  new_y_min = floor(new_y_min - additionalMarginMeters);
70  if (new_y_max > m_y_max)
71  new_y_max = ceil(new_y_max + additionalMarginMeters);
72  if (new_z_min < m_z_min)
73  new_z_min = floor(new_z_min - additionalMarginMeters);
74  if (new_z_max > m_z_max)
75  new_z_max = ceil(new_z_max + additionalMarginMeters);
76  }
77 
78  // Adjust sizes to adapt them to full sized cells acording to the
79  // resolution:
80  if (fabs(
81  new_x_min / m_resolution_xy -
82  round(new_x_min / m_resolution_xy)) > 0.05)
83  new_x_min = m_resolution_xy * round(new_x_min / m_resolution_xy);
84  if (fabs(
85  new_y_min / m_resolution_xy -
86  round(new_y_min / m_resolution_xy)) > 0.05)
87  new_y_min = m_resolution_xy * round(new_y_min / m_resolution_xy);
88  if (fabs(
89  new_z_min / m_resolution_z -
90  round(new_z_min / m_resolution_z)) > 0.05)
91  new_z_min = m_resolution_z * round(new_z_min / m_resolution_z);
92  if (fabs(
93  new_x_max / m_resolution_xy -
94  round(new_x_max / m_resolution_xy)) > 0.05)
95  new_x_max = m_resolution_xy * round(new_x_max / m_resolution_xy);
96  if (fabs(
97  new_y_max / m_resolution_xy -
98  round(new_y_max / m_resolution_xy)) > 0.05)
99  new_y_max = m_resolution_xy * round(new_y_max / m_resolution_xy);
100  if (fabs(
101  new_z_max / m_resolution_z -
102  round(new_z_max / m_resolution_z)) > 0.05)
103  new_z_max = m_resolution_z * round(new_z_max / m_resolution_z);
104 
105  // Change the map size: Extensions at each side:
106  size_t extra_x_izq = round((m_x_min - new_x_min) / m_resolution_xy);
107  size_t extra_y_arr = round((m_y_min - new_y_min) / m_resolution_xy);
108  size_t extra_z_top = round((m_z_min - new_z_min) / m_resolution_z);
109 
110  size_t new_size_x = round((new_x_max - new_x_min) / m_resolution_xy);
111  size_t new_size_y = round((new_y_max - new_y_min) / m_resolution_xy);
112  size_t new_size_z = round((new_z_max - new_z_min) / m_resolution_z);
113  size_t new_size_x_times_y = new_size_x * new_size_y;
114 
115  // Reserve new memory:
116  typename std::vector<T> new_map;
117  new_map.resize(
118  new_size_x * new_size_y * new_size_z, defaultValueNewCells);
119 
120  // Copy previous rows:
121  size_t x, y, z;
122  typename std::vector<T>::iterator itSrc, itDst;
123  for (z = 0; z < m_size_z; z++)
124  {
125  for (y = 0; y < m_size_y; y++)
126  {
127  for (x = 0,
128  itSrc =
129  (m_map.begin() + y * m_size_x + z * m_size_x_times_y),
130  itDst =
131  (new_map.begin() + extra_x_izq +
132  (y + extra_y_arr) * new_size_x +
133  (z + extra_z_top) * new_size_x_times_y);
134  x < m_size_x; ++x, ++itSrc, ++itDst)
135  {
136  *itDst = *itSrc;
137  }
138  }
139  }
140 
141  // Update the new map limits:
142  m_x_min = new_x_min;
143  m_x_max = new_x_max;
144  m_y_min = new_y_min;
145  m_y_max = new_y_max;
146  m_z_min = new_z_min;
147  m_z_max = new_z_max;
148 
149  m_size_x = new_size_x;
150  m_size_y = new_size_y;
151  m_size_z = new_size_z;
152  m_size_x_times_y = new_size_x_times_y;
153 
154  // Keep the new map only:
155  m_map.swap(new_map);
156  }
157 
158  /** Changes the size of the grid, ERASING all previous contents.
159  * If \a fill_value is left as nullptr, the contents of cells may be
160  * undefined (some will remain with
161  * their old values, the new ones will have the default voxel value, but
162  * the location of old values
163  * may change wrt their old places).
164  * If \a fill_value is not nullptr, it is assured that all cells will have
165  * a copy of that value after resizing.
166  * If `resolution_z`<0, the same resolution will be used for all dimensions
167  * x,y,z as given in `resolution_xy`
168  * \sa resize, fill
169  */
170  virtual void setSize(
171  const double x_min, const double x_max, const double y_min,
172  const double y_max, const double z_min, const double z_max,
173  const double resolution_xy, const double resolution_z_ = -1.0,
174  const T* fill_value = nullptr)
175  {
176  const double resolution_z =
177  resolution_z_ > 0.0 ? resolution_z_ : resolution_xy;
178 
179  // Adjust sizes to adapt them to full sized cells acording to the
180  // resolution:
181  m_x_min = x_min;
182  m_y_min = y_min;
183  m_z_min = z_min;
184 
185  m_x_max =
186  x_min + resolution_xy * round((x_max - x_min) / resolution_xy);
187  m_y_max =
188  y_min + resolution_xy * round((y_max - y_min) / resolution_xy);
189  m_z_max = z_min + resolution_z * round((z_max - z_min) / resolution_z);
190 
191  // Res:
192  m_resolution_xy = resolution_xy;
193  m_resolution_z = resolution_z;
194 
195  // Now the number of cells should be integers:
200 
201  // Cells memory:
202  if (fill_value)
203  m_map.assign(m_size_x * m_size_y * m_size_z, *fill_value);
204  else
205  m_map.resize(m_size_x * m_size_y * m_size_z);
206  }
207 
208  /** Erase the contents of all the cells, setting them to their default
209  * values (default ctor). */
210  virtual void clear()
211  {
212  m_map.clear();
213  m_map.resize(m_size_x * m_size_y * m_size_z);
214  }
215 
216  /** Fills all the cells with the same value
217  */
218  inline void fill(const T& value)
219  {
220  for (typename std::vector<T>::iterator it = m_map.begin();
221  it != m_map.end(); ++it)
222  *it = value;
223  }
224 
225  static const size_t INVALID_VOXEL_IDX = size_t(-1);
226 
227  /** Gets the absolute index of a voxel in the linear container m_map[] from
228  * its cx,cy,cz indices, or -1 if out of map bounds (in any dimension). \sa
229  * x2idx(), y2idx(), z2idx() */
230  inline size_t cellAbsIndexFromCXCYCZ(
231  const int cx, const int cy, const int cz) const
232  {
233  if (cx < 0 || cx >= static_cast<int>(m_size_x))
234  return INVALID_VOXEL_IDX;
235  if (cy < 0 || cy >= static_cast<int>(m_size_y))
236  return INVALID_VOXEL_IDX;
237  if (cz < 0 || cz >= static_cast<int>(m_size_z))
238  return INVALID_VOXEL_IDX;
239  return cx + cy * m_size_x + cz * m_size_x_times_y;
240  }
241 
242  /** Returns a pointer to the contents of a voxel given by its coordinates,
243  * or nullptr if it is out of the map extensions.
244  */
245  inline T* cellByPos(double x, double y, double z)
246  {
247  const size_t cidx =
249  if (cidx == INVALID_VOXEL_IDX) return nullptr;
250  return &m_map[cidx];
251  }
252  /** \overload */
253  inline const T* cellByPos(double x, double y, double z) const
254  {
255  const size_t cidx =
257  if (cidx == INVALID_VOXEL_IDX) return nullptr;
258  return &m_map[cidx];
259  }
260 
261  /** Returns a pointer to the contents of a voxel given by its voxel indexes,
262  * or nullptr if it is out of the map extensions.
263  */
264  inline T* cellByIndex(unsigned int cx, unsigned int cy, unsigned int cz)
265  {
266  const size_t cidx = cellAbsIndexFromCXCYCZ(cx, cy, cz);
267  if (cidx == INVALID_VOXEL_IDX) return nullptr;
268  return &m_map[cidx];
269  }
270 
271  /** Returns a pointer to the contents of a voxel given by its voxel indexes,
272  * or nullptr if it is out of the map extensions.
273  */
274  inline const T* cellByIndex(
275  unsigned int cx, unsigned int cy, unsigned int cz) const
276  {
277  const size_t cidx = cellAbsIndexFromCXCYCZ(cx, cy, cz);
278  if (cidx == INVALID_VOXEL_IDX) return nullptr;
279  return &m_map[cidx];
280  }
281 
282  inline size_t getSizeX() const { return m_size_x; }
283  inline size_t getSizeY() const { return m_size_y; }
284  inline size_t getSizeZ() const { return m_size_z; }
285  inline size_t getVoxelCount() const { return m_size_x_times_y * m_size_z; }
286  inline double getXMin() const { return m_x_min; }
287  inline double getXMax() const { return m_x_max; }
288  inline double getYMin() const { return m_y_min; }
289  inline double getYMax() const { return m_y_max; }
290  inline double getZMin() const { return m_z_min; }
291  inline double getZMax() const { return m_z_max; }
292  inline double getResolutionXY() const { return m_resolution_xy; }
293  inline double getResolutionZ() const { return m_resolution_z; }
294  /** Transform a coordinate values into voxel indexes */
295  inline int x2idx(double x) const
296  {
297  return static_cast<int>((x - m_x_min) / m_resolution_xy);
298  }
299  inline int y2idx(double y) const
300  {
301  return static_cast<int>((y - m_y_min) / m_resolution_xy);
302  }
303  inline int z2idx(double z) const
304  {
305  return static_cast<int>((z - m_z_min) / m_resolution_z);
306  }
307 
308  /** Transform a voxel index into a coordinate value of the voxel central
309  * point */
310  inline double idx2x(int cx) const { return m_x_min + (cx)*m_resolution_xy; }
311  inline double idx2y(int cy) const { return m_y_min + (cy)*m_resolution_xy; }
312  inline double idx2z(int cz) const { return m_z_min + (cz)*m_resolution_z; }
313  protected:
314  /** The cells */
315  mutable std::vector<T> m_map;
316  /** Used only from logically const method that really need to modify the
317  * object */
318  inline std::vector<T>& m_map_castaway_const() const { return m_map; }
322  /** Serialization of all parameters, except the contents of each voxel
323  * (responsability of the derived class) */
324  template <class ARCHIVE>
325  void dyngridcommon_writeToStream(ARCHIVE& out) const
326  {
327  out << m_x_min << m_x_max << m_y_min << m_y_max << m_z_min << m_z_max;
329  out << static_cast<uint32_t>(m_size_x)
330  << static_cast<uint32_t>(m_size_y)
331  << static_cast<uint32_t>(m_size_z);
332  }
333  /** Serialization of all parameters, except the contents of each voxel
334  * (responsability of the derived class) */
335  template <class ARCHIVE>
337  {
338  in >> m_x_min >> m_x_max >> m_y_min >> m_y_max >> m_z_min >> m_z_max;
340 
341  uint32_t nX, nY, nZ;
342  in >> nX >> nY >> nZ;
343  m_size_x = nX;
344  m_size_y = nY;
345  m_size_z = nZ;
346  m_map.resize(nX * nY * nZ);
347  }
348 
349 }; // end of CDynamicGrid3D<>
350 
351 }
352 
Scalar * iterator
Definition: eigen_plugins.h:26
virtual void setSize(const double x_min, const double x_max, const double y_min, const double y_max, const double z_min, const double z_max, const double resolution_xy, const double resolution_z_=-1.0, const T *fill_value=nullptr)
Changes the size of the grid, ERASING all previous contents.
GLdouble GLdouble z
Definition: glext.h:3872
virtual void resize(double new_x_min, double new_x_max, double new_y_min, double new_y_max, double new_z_min, double new_z_max, const T &defaultValueNewCells, double additionalMarginMeters=2.0)
Changes the size of the grid, maintaining previous contents.
size_t cellAbsIndexFromCXCYCZ(const int cx, const int cy, const int cz) const
Gets the absolute index of a voxel in the linear container m_map[] from its cx,cy,cz indices, or -1 if out of map bounds (in any dimension).
const T * cellByIndex(unsigned int cx, unsigned int cy, unsigned int cz) const
Returns a pointer to the contents of a voxel given by its voxel indexes, or nullptr if it is out of t...
T * cellByPos(double x, double y, double z)
Returns a pointer to the contents of a voxel given by its coordinates, or nullptr if it is out of the...
CDynamicGrid3D(double x_min=-1.0, double x_max=1.0, double y_min=-1.0, double y_max=+1.0, double z_min=-1.0, double z_max=1.0, double resolution_xy=0.5, double resolution_z=0.5)
Constructor.
T * cellByIndex(unsigned int cx, unsigned int cy, unsigned int cz)
Returns a pointer to the contents of a voxel given by its voxel indexes, or nullptr if it is out of t...
A 3D rectangular grid of dynamic size which stores any kind of data at each voxel.
int x2idx(double x) const
Transform a coordinate values into voxel indexes.
void dyngridcommon_readFromStream(ARCHIVE &in)
Serialization of all parameters, except the contents of each voxel (responsability of the derived cla...
std::vector< T > m_map
The cells.
const T * cellByPos(double x, double y, double z) const
void fill(const T &value)
Fills all the cells with the same value.
GLuint in
Definition: glext.h:7274
void dyngridcommon_writeToStream(ARCHIVE &out) const
Serialization of all parameters, except the contents of each voxel (responsability of the derived cla...
GLenum GLint GLint y
Definition: glext.h:3538
virtual void clear()
Erase the contents of all the cells, setting them to their default values (default ctor)...
double idx2x(int cx) const
Transform a voxel index into a coordinate value of the voxel central point.
std::vector< T > & m_map_castaway_const() const
Used only from logically const method that really need to modify the object.
GLsizei const GLfloat * value
Definition: glext.h:4117
GLenum GLint x
Definition: glext.h:3538
static const size_t INVALID_VOXEL_IDX
unsigned __int32 uint32_t
Definition: rptypes.h:47
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23



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