supereight
block.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016-2019 Emanuele Vespa
3  * SPDX-FileCopyrightText: 2019-2021 Smart Robotics Lab, Imperial College London, Technical University of Munich
4  * SPDX-FileCopyrightText: 2019-2021 Nils Funk
5  * SPDX-FileCopyrightText: 2019-2021 Sotiris Papatheodorou
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef SE_BLOCK_HPP
10 #define SE_BLOCK_HPP
11 
12 namespace se {
13 
14 
15 
16 // Forward declare Node to avoid depending on the order of includes.
17 template<typename DataT, se::Res ResT>
18 class Node;
19 
20 
21 
25 template<typename DerivedT, typename DataT, int BlockSize>
27  public:
28  typedef DataT DataType;
29 
30  BlockSingleRes(const DataType init_data = DataType());
31 
32  inline const DataType& getData(const int voxel_idx) const;
33 
34  inline DataType& getData(const int voxel_idx);
35 
36  inline const DataType& getData(const Eigen::Vector3i& voxel_coord) const;
37 
38  inline DataType& getData(const Eigen::Vector3i& voxel_coord);
39 
40  inline void setData(const unsigned voxel_idx, const DataT& data);
41 
42  inline void setData(const Eigen::Vector3i& voxel_coord, const DataT& data);
43 
44 
45  static inline int getMinScale()
46  {
47  return min_scale_;
48  }
49 
50  static inline int getCurrentScale()
51  {
52  return curr_scale_;
53  }
54 
55  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
56 
57  private:
58  std::array<DataType, BlockSize * BlockSize * BlockSize> block_data_;
59  static constexpr int min_scale_ = 0;
60  static constexpr int curr_scale_ = 0;
61 
62  DerivedT& underlying()
63  {
64  return static_cast<DerivedT&>(*this);
65  }
66  const DerivedT& underlying() const
67  {
68  return static_cast<const DerivedT&>(*this);
69  }
70 };
71 
72 
73 
74 template<typename DataT, int BlockSize, typename DerivedT>
76 };
77 
78 
79 
80 template<Field FldT, Colour ColB, Semantics SemB, int BlockSize, typename DerivedT>
81 class BlockMultiRes<se::Data<FldT, ColB, SemB>, BlockSize, DerivedT> {
82 };
83 
84 
85 
86 template<Colour ColB, Semantics SemB, int BlockSize, typename DerivedT>
87 class BlockMultiRes<se::Data<se::Field::TSDF, ColB, SemB>, BlockSize, DerivedT> {
88  public:
91 
92  BlockMultiRes(const DataType init_data = DataType());
93 
94  struct DataUnion {
95  DataUnion(){};
96  Eigen::Vector3i coord;
97  int scale;
98 
99  DataType data;
100  PropDataType prop_data;
101 
102  int data_idx;
104  };
105 
107 
108  inline int getVoxelIdx(const Eigen::Vector3i& voxel_coord) const;
109 
110  inline int getVoxelIdx(const Eigen::Vector3i& voxel_coord, const int scale) const;
111 
113 
114  inline const DataType& getData() const;
115 
116  inline DataType& getData();
117 
119 
120  inline const DataType& getData(const int voxel_idx) const;
121 
122  inline DataType& getData(const int voxel_idx);
123 
124  inline const DataType& getData(const Eigen::Vector3i& voxel_coord) const;
125 
126  inline DataType& getData(const Eigen::Vector3i& voxel_coord);
127 
129 
130  inline const DataType&
131  getData(const Eigen::Vector3i& voxel_coord, const int scale_in, int& scale_out) const;
132 
133  inline DataType&
134  getData(const Eigen::Vector3i& voxel_coord, const int scale_in, int& scale_out);
135 
137 
138  inline const DataType& getData(const Eigen::Vector3i& voxel_coord, const int scale) const;
139 
140  inline DataType& getData(const Eigen::Vector3i& voxel_coord, const int scale);
141 
143 
144  inline const DataUnion getDataUnion(const Eigen::Vector3i& voxel_coord, const int scale) const;
145 
146  inline DataUnion getDataUnion(const Eigen::Vector3i& voxel_coord, const int scale);
147 
149 
150  inline void setData(const int voxel_idx, const DataType& data);
151 
152  inline void setData(const Eigen::Vector3i& voxel_coord, const DataType& data);
153 
154  inline void setData(const Eigen::Vector3i& voxel_coord, const int scale, const DataType& data);
155 
156  inline void setDataUnion(const DataUnion& data_union);
157 
158 
160 
161  inline int getMinScale() const
162  {
163  return min_scale_;
164  }
165 
166  inline void setMinScale(const int min_scale)
167  {
168  min_scale_ = min_scale;
169  }
170 
171  static constexpr inline int getMaxScale()
172  {
173  return max_scale_;
174  }
175 
176  inline int getCurrentScale() const
177  {
178  return curr_scale_;
179  }
180 
181  inline void setCurrentScale(const int curr_scale)
182  {
183  curr_scale_ = curr_scale;
184  }
185 
186  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
187 
188  private:
189  static constexpr int max_scale_ = math::log2_const(BlockSize);
190 
191  static constexpr int compute_num_voxels()
192  {
193  size_t voxel_count = 0;
194  unsigned int size_at_scale = BlockSize;
195  while (size_at_scale >= 1) {
196  voxel_count += size_at_scale * size_at_scale * size_at_scale;
197 
198  size_at_scale = size_at_scale >> 1;
199  }
200  return voxel_count;
201  }
202 
203  static constexpr std::array<int, se::math::log2_const(BlockSize) + 1> compute_size_at_scales()
204  {
205  std::array<int, se::math::log2_const(BlockSize) + 1> size_at_scales{};
206 
207  int size_at_scale = BlockSize;
208  int scale = 0;
209  while (size_at_scale >= 1) {
210  size_at_scales[scale] = size_at_scale;
211  size_at_scale = size_at_scale >> 1;
212  scale++;
213  }
214  return size_at_scales;
215  }
216 
217  static constexpr std::array<int, se::math::log2_const(BlockSize) + 1> compute_scale_offsets()
218  {
219  std::array<int, se::math::log2_const(BlockSize) + 1> scale_offsets{};
220 
221  unsigned int size_at_scale = BlockSize;
222  scale_offsets[0] = 0;
223  int scale = 1;
224  while (size_at_scale > 1) {
225  scale_offsets[scale] =
226  scale_offsets[scale - 1] + size_at_scale * size_at_scale * size_at_scale;
227  size_at_scale = size_at_scale >> 1;
228  scale++;
229  }
230  return scale_offsets;
231  }
232 
233  static constexpr int num_voxels_ = compute_num_voxels();
234 
235  static constexpr std::array<int, se::math::log2_const(BlockSize) + 1> size_at_scales_ =
236  compute_size_at_scales();
237 
238  static constexpr std::array<int, se::math::log2_const(BlockSize) + 1> scale_offsets_ =
239  compute_scale_offsets();
240 
241 
242  std::array<DataType, num_voxels_> block_data_;
243  std::array<PropDataType, num_voxels_> block_prop_data_;
244 
245  int min_scale_;
246  int curr_scale_;
247 
248  DerivedT& underlying()
249  {
250  return static_cast<DerivedT&>(*this);
251  }
252  const DerivedT& underlying() const
253  {
254  return static_cast<const DerivedT&>(*this);
255  }
256 };
257 
258 
259 
260 // Forward decleration
261 template<typename DataT,
262  Res ResT = se::Res::Single,
263  int BlockSize = 8,
264  typename PolicyT = std::enable_if_t<math::is_power_of_two(
265  BlockSize)>
266  >
267 class Block;
268 
269 
270 
271 template<Colour ColB, Semantics SemB, int BlockSize, typename DerivedT>
272 class BlockMultiRes<se::Data<se::Field::Occupancy, ColB, SemB>, BlockSize, DerivedT> {
273  public:
276 
277  BlockMultiRes(const DataType init_data = DataType());
278 
281 
282  void operator=(
284 
285  ~BlockMultiRes();
286 
288 
289  inline const DataType& getInitData() const
290  {
291  return init_data_;
292  };
293  inline DataType& getInitData()
294  {
295  return init_data_;
296  };
297 
298  inline void setInitData(const DataType& init_data)
299  {
300  init_data_ = init_data;
301  };
302 
304 
305  inline int getVoxelIdx(const Eigen::Vector3i& voxel_coord) const;
306 
307  inline int getVoxelIdx(const Eigen::Vector3i& voxel_coord, const int scale) const;
308 
309 
310 
312 
313  inline const DataType& getData(const Eigen::Vector3i& voxel_coord) const;
314 
315  inline DataType& getData(const Eigen::Vector3i& voxel_coord);
316 
318 
319  inline const DataType&
320  getData(const Eigen::Vector3i& voxel_coord, const int scale_in, int& scale_out) const;
321 
322  inline DataType&
323  getData(const Eigen::Vector3i& voxel_coord, const int scale_in, int& scale_out);
324 
326 
327  inline const DataType& getData(const Eigen::Vector3i& voxel_coord, const int scale) const;
328 
329  inline DataType& getData(const Eigen::Vector3i& voxel_coord, const int scale);
330 
331  inline const DataType& getMaxData(const Eigen::Vector3i& voxel_coord) const;
332 
333  inline DataType& getMaxData(const Eigen::Vector3i& voxel_coord);
334 
335  inline const DataType&
336  getMaxData(const Eigen::Vector3i& voxel_coord, const int scale_in, int& scale_out) const;
337 
338  inline DataType&
339  getMaxData(const Eigen::Vector3i& voxel_coord, const int scale_in, int& scale_out);
340 
341  inline const DataType& getMaxData(const Eigen::Vector3i& voxel_coord, const int scale) const;
342 
343  inline DataType& getMaxData(const Eigen::Vector3i& voxel_coord, const int scale);
344 
345  inline const DataType& getMinData() const
346  {
347  return min_data_;
348  };
349 
350 
352  inline void setData(const Eigen::Vector3i& voxel_coord, const DataType& data);
353 
354  inline void setData(const Eigen::Vector3i& voxel_coord, const int scale, const DataType& data);
355 
356  inline void setMaxData(const Eigen::Vector3i& voxel_coord, const DataType& data);
357 
358 
359  inline void
360  setMaxData(const Eigen::Vector3i& voxel_coord, const int scale, const DataType& data);
361 
362  void setMinData(const DataType& min_data)
363  {
364  min_data_ = min_data;
365  }
366 
370  void allocateDownTo();
371 
375  inline void allocateDownTo(const int new_min_scale);
376 
380  void deleteUpTo(const int new_min_scale);
381 
389  inline const DataType getData() const
390  {
391  return block_data_[0][0];
392  }
393 
401  inline const DataType getMaxData() const
402  {
403  return block_max_data_[0][0];
404  }
405 
414  {
415  return get_field(getData());
416  }
417 
426  {
427  return get_field(getMaxData());
428  }
429 
430  inline const std::vector<DataType*>& blockData() const
431  {
432  return block_data_;
433  }
434 
435  inline std::vector<DataType*>& blockData()
436  {
437  return block_data_;
438  }
439 
440  inline const std::vector<DataType*>& blockMaxData() const
441  {
442  return block_max_data_;
443  }
444 
445  inline std::vector<DataType*>& blockMaxData()
446  {
447  return block_max_data_;
448  }
449 
453  inline const size_t& currIntegrCount() const
454  {
455  return curr_integr_count_;
456  }
457 
461  inline const size_t& currObservedCount() const
462  {
463  return curr_observed_count_;
464  }
465 
470  {
471  curr_integr_count_++;
472  }
473 
479  void incrCurrObservedCount(bool do_increment = true);
480 
484  void resetCurrCount();
485 
491  void initCurrCout();
492 
496  const int& buffer_scale() const
497  {
498  return buffer_scale_;
499  }
500  const size_t& bufferIntegrCount() const
501  {
502  return buffer_integr_count_;
503  }
504  const size_t& bufferObservedCount() const
505  {
506  return buffer_observed_count_;
507  }
508 
513  void incrBufferIntegrCount(const bool do_increment = true);
514 
515 
521  void incrBufferObservedCount(const bool do_increment = true);
525  void resetBufferCount();
526 
530  void resetBuffer();
531 
537  void initBuffer(const int buffer_scale);
538 
544  bool switchData();
545 
555  DataType& bufferData(const Eigen::Vector3i& voxel_coord) const;
556 
566  DataType& bufferData(const Eigen::Vector3i& voxel_coord);
567 
577  DataType& bufferData(const int voxel_idx) const
578  {
579  return buffer_data_[voxel_idx];
580  }
581 
591  DataType& bufferData(const int voxel_idx)
592  {
593  return buffer_data_[voxel_idx];
594  }
595 
605  DataType& currData(const int voxel_idx) const
606  {
607  return curr_data_[voxel_idx];
608  }
609 
619  DataType& currData(const int voxel_idx)
620  {
621  return curr_data_[voxel_idx];
622  }
623 
632  DataType* blockDataAtScale(const int scale);
633 
642  DataType* blockMaxDataAtScale(const int scale);
643 
645 
646  inline int getMinScale() const
647  {
648  return min_scale_;
649  }
650 
651  inline void setMinScale(const int min_scale)
652  {
653  min_scale_ = min_scale;
654  }
655 
656  static constexpr inline int getMaxScale()
657  {
658  return max_scale_;
659  }
660 
661  inline int getCurrentScale() const
662  {
663  return curr_scale_;
664  }
665 
666  inline void setCurrentScale(const int curr_scale)
667  {
668  curr_scale_ = curr_scale;
669  }
670 
671  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
672 
673  private:
674  static constexpr int max_scale_ = math::log2_const(BlockSize);
675 
677  void initialiseData(DataType* voxel_data, const int num_voxels)
678  {
679  std::fill(voxel_data, voxel_data + num_voxels, init_data_);
680  }
681 
682  std::vector<DataType*> block_data_;
683  std::vector<DataType*> block_max_data_;
684 
685  DataType* curr_data_ = nullptr;
686  size_t curr_integr_count_;
687  size_t curr_observed_count_;
688 
712  int curr_scale_;
713  int min_scale_;
714 
715  DataType* buffer_data_ = nullptr;
716  int buffer_scale_;
717  size_t
718  buffer_integr_count_;
719  size_t buffer_observed_count_;
720 
721  DataType min_data_;
722  DataType init_data_;
723 
724  DerivedT& underlying()
725  {
726  return static_cast<DerivedT&>(*this);
727  }
728  const DerivedT& underlying() const
729  {
730  return static_cast<const DerivedT&>(*this);
731  }
732 };
733 
734 
740 template<typename DataT, Res ResT, int BlockSize, typename PolicyT>
741 class Block
742  : public OctantBase,
743  public std::conditional<ResT == Res::Single,
744  BlockSingleRes<Block<DataT, ResT, BlockSize>, DataT, BlockSize>,
745  BlockMultiRes<DataT, BlockSize, Block<DataT, ResT, BlockSize>>>::
746  type
747 
748 {
749  public:
750  typedef DataT DataType;
751  static constexpr int size = BlockSize;
752  static constexpr int size_qu = BlockSize * BlockSize;
753  static constexpr int size_cu = BlockSize * BlockSize * BlockSize;
754 
762  Block(se::Node<DataT, ResT>* parent_ptr, const int child_idx, const DataT init_data);
763 
764  static constexpr unsigned int getSize()
765  {
766  return BlockSize;
767  }
768 
769  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
770 };
771 
772 
773 
774 } // namespace se
775 
776 
777 
778 #include "impl/block_impl.hpp"
779 
780 
781 
782 #endif // SE_BLOCK_HPP
const std::vector< DataType * > & blockData() const
Definition: block.hpp:430
DataType & bufferData(const int voxel_idx)
Get a reference to the voxel data in the buffer at the voxel index.
Definition: block.hpp:591
Res
Definition: setup_util.hpp:23
BlockSingleRes(const DataType init_data=DataType())
void setData(const unsigned voxel_idx, const DataT &data)
The node type of the octant.
Definition: block.hpp:18
const DataType & getInitData() const
Get init block data.
Definition: block.hpp:289
void setCurrentScale(const int curr_scale)
Definition: block.hpp:181
The base used for single-resolution blocks.
Definition: block.hpp:26
Definition: block.hpp:75
void setInitData(const DataType &init_data)
Definition: block.hpp:298
float field_t
The type of the stored field (e.g. TSDF, ESDF or occupancy)
Definition: type_util.hpp:50
Definition: data.hpp:95
const std::vector< DataType * > & blockMaxData() const
Definition: block.hpp:440
std::vector< DataType * > & blockMaxData()
Definition: block.hpp:445
se::field_t meanValue()
Get the block&#39;s value at the coarsest scale.
Definition: block.hpp:413
void setMinData(const DataType &min_data)
Definition: block.hpp:362
se::Data< se::Field::Occupancy, ColB, SemB > DataType
Definition: block.hpp:274
se::OctantBase * block(const Eigen::Vector3i &voxel_coord, OctreeT &octree, se::OctantBase *base_parent_ptr)
Allocate a block at the provided voxel coordinates.
const DataType getData() const
Get the block&#39;s data at the coarsest scale.
Definition: block.hpp:389
se::DeltaData< se::Field::TSDF, ColB, SemB > PropDataType
Definition: block.hpp:90
DataT DataType
Definition: block.hpp:750
DataType & bufferData(const int voxel_idx) const
Get a const reference to the voxel data in the buffer at the voxel index.
Definition: block.hpp:577
se::field_t maxValue()
Get the block&#39;s max value at the coarsest scale.
Definition: block.hpp:425
The actual block used in the tree.
Definition: block.hpp:267
const DataType getMaxData() const
Get the block&#39;s max data at the coarsest scale.
Definition: block.hpp:401
const DataType & getData(const int voxel_idx) const
const size_t & currIntegrCount() const
Get the number of integrations at the current scale.
Definition: block.hpp:453
std::enable_if_t< OctreeT::DataType::fld_==se::Field::Occupancy, typename OctreeT::DataType > getMaxData(const OctreeT &octree, const Eigen::Vector3i &voxel_coord, const int scale_desired)
Get the max occupancy data at a given scale.
static constexpr unsigned int getSize()
Definition: block.hpp:764
se::DeltaData< se::Field::Occupancy, ColB, SemB > PropDataType
Definition: block.hpp:275
This class only helps to dynamic cast the octant to the right type and builds the base of nodes and b...
Definition: octant.hpp:24
DataT DataType
Definition: block.hpp:28
DataType & currData(const int voxel_idx) const
Get a const reference to the mean voxel data at the current scale via the voxel index.
Definition: block.hpp:605
float get_field(const Data< FldT, ColB, SemB > data)
se::Data< se::Field::TSDF, ColB, SemB > DataType
Definition: block.hpp:89
const size_t & currObservedCount() const
Get the number of observed voxels at the current scale.
Definition: block.hpp:461
static int getMinScale()
Definition: block.hpp:45
DataType & currData(const int voxel_idx)
Get a reference to the mean voxel data at the current scale via the voxel index.
Definition: block.hpp:619
Helper wrapper to allocate and de-allocate octants in the octree.
Definition: colour_utils.hpp:17
void incrCurrIntegrCount()
Increment the number of integrations at the current scale by 1.
Definition: block.hpp:469
constexpr int log2_const(int n)
static const std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > scale
The colours used for the various integration scales.
Definition: colour_utils.hpp:22
static int getCurrentScale()
Definition: block.hpp:50
constexpr bool is_power_of_two(T)