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



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 63ea9d1f1 Thu Nov 23 00:06:53 2017 +0100 at mar 26 may 2026 12:19:29 CEST