21#if defined(__x86_64__)
23#elif defined(__aarch64__) && defined(__ARM_NEON)
26#error "Processor architecture not supported!"
36template <
typename T,
unsigned int d>
91 assert(
data_ !=
nullptr);
92 return (
data_ + i * d);
97 assert(
data_ !=
nullptr);
98 return (
data_ + i * d);
103 return data_[i * d + j];
108 return data_[i * d + j];
125template <
typename T,
unsigned int d>
128template <
typename T,
unsigned int d>
131 data_ = IAllocAligned<T>(n * d, 4);
139template <
typename T,
unsigned int d>
141 : data_(nullptr), nr_points_(n) {
143 data_ = IAllocAligned<T>(n * d, 4);
153template <
typename T,
unsigned int d>
161 T bound_y_min, T bound_y_max, T bound_z_min,
162 T bound_z_max, T voxel_width_x_rec,
163 T voxel_width_y_rec,
int nr_voxel_x,
171 if (x < bound_x_min || x > bound_x_max || y < bound_y_min ||
172 y > bound_y_max || z < bound_z_min || z > bound_z_max) {
177 k =
IMin(nr_voxel_x - 1,
178 static_cast<int>((x - bound_x_min) * voxel_width_x_rec));
179 j =
IMin(nr_voxel_y - 1,
180 static_cast<int>((y - bound_y_min) * voxel_width_y_rec));
181 i = (nr_voxel_x * j) + k;
187 T bound_y_min, T bound_y_max, T bound_z_min,
188 T bound_z_max, T voxel_width_x_rec,
189 T voxel_width_y_rec,
int nr_voxel_x,
197 if (x < bound_x_min || x > bound_x_max || y < bound_y_min ||
198 y > bound_y_max || z < bound_z_min || z > bound_z_max) {
203 k =
IMin(nr_voxel_x - 1,
204 static_cast<int>((x - bound_x_min) * voxel_width_x_rec));
205 j =
IMin(nr_voxel_y - 1,
206 static_cast<int>((y - bound_y_min) * voxel_width_y_rec));
207 i = (nr_voxel_x * j) + k;
228 if (
this != &voxel) {
241 void Init(
const T *v, T dim_x, T dim_y, T dim_z,
int ix,
int iy,
int iz) {
252 void Init(T v_x, T v_y, T v_z, T dim_x, T dim_y, T dim_z,
int ix,
int iy,
296 static const unsigned int s_nr_max_reserved_points_ = 320000;
301 T spatial_bound_x_min, T spatial_bound_x_max,
302 T spatial_bound_y_min, T spatial_bound_y_max,
303 T spatial_bound_z_min, T spatial_bound_z_max);
316 &this->dim_y_[1], &this->dim_z_[0], &this->dim_z_[1]);
317 this->voxels_.resize(vg.
NrVoxel());
318 for (
unsigned int i = 0; i < vg.
NrVoxel(); ++i) {
319 this->voxels_[i] = vg[i];
322 this->AllocAlignedMemory();
330 IFreeAligned<float>(&mem_aligned16_f32_);
331 IFreeAligned<int>(&mem_aligned16_i32_);
335 bool Alloc(
unsigned int nr_voxel_x,
unsigned int nr_voxel_y,
336 T spatial_bound_x_min, T spatial_bound_x_max,
337 T spatial_bound_y_min, T spatial_bound_y_max,
338 T spatial_bound_z_min, T spatial_bound_z_max);
340 bool Set(
const T *data,
const int *semantic_data,
unsigned int nr_points,
341 unsigned int nr_point_element);
344 bool SetS(
const float *data,
const int *semantic_data,
345 unsigned int nr_points,
unsigned int nr_point_element);
347 bool Set(
const T *data,
const int *semantic_data,
348 unsigned int nr_points,
unsigned int nr_point_element,
349 unsigned int nr_voxel_x,
unsigned int nr_voxel_y,
350 T spatial_bound_x_min, T spatial_bound_x_max, T spatial_bound_y_min,
351 T spatial_bound_y_max, T spatial_bound_z_min, T spatial_bound_z_max,
352 bool force_bound =
true);
356 unsigned int NrVoxel()
const {
return (
unsigned int)voxels_.size(); }
358 unsigned int NrVoxelX()
const {
return nr_voxel_x_; }
360 unsigned int NrVoxelY()
const {
return nr_voxel_y_; }
364 unsigned int NrPoints()
const {
return nr_points_; }
375 voxels_.assign(voxels.begin(), voxels.end());
379 T *dim_min_z, T *dim_max_z)
const {
381 dim_min_x = dim_max_x = dim_min_y = dim_max_y = dim_min_z = dim_max_z =
385 *dim_min_x = dim_x_[0];
386 *dim_max_x = dim_x_[1];
387 *dim_min_y = dim_y_[0];
388 *dim_max_y = dim_y_[1];
389 *dim_min_z = dim_z_[0];
390 *dim_max_z = dim_z_[1];
395 T dim_min_z, T dim_max_z) {
396 dim_x_[0] = dim_min_x;
397 dim_x_[1] = dim_max_x;
398 dim_y_[0] = dim_min_y;
399 dim_y_[1] = dim_max_y;
400 dim_z_[0] = dim_min_z;
401 dim_z_[1] = dim_max_z;
405 T *voxel_width_z)
const {
407 *voxel_width_x = *voxel_width_y = *voxel_width_z =
static_cast<T
>(0);
410 *voxel_width_x = voxel_dim_[0];
411 *voxel_width_y = voxel_dim_[1];
412 *voxel_width_z = voxel_dim_[2];
417 voxel_dim_[0] = voxel_width_x;
418 voxel_dim_[1] = voxel_width_y;
419 voxel_dim_[2] = voxel_width_z;
422 void SetNrPoints(
unsigned int nr_points) { nr_points_ = nr_points; }
425 nr_point_element_ = nr_point_element;
428 void SetNrVoxel(
unsigned int nr_voxel_x,
unsigned int nr_voxel_y,
429 unsigned int nr_voxel_z) {
430 nr_voxel_x_ = nr_voxel_x;
431 nr_voxel_y_ = nr_voxel_y;
432 nr_voxel_z_ = nr_voxel_z;
449 assert(i >= 0 && i < voxels_.size());
454 assert(i >= 0 && i < voxels_.size());
459 assert(i >= 0 && i <
static_cast<int>(voxels_.size()));
463 assert(i >= 0 && i <
static_cast<int>(voxels_.size()));
468 assert(iy < nr_voxel_y_ && ix < nr_voxel_x_);
469 unsigned int i = nr_voxel_x_ * iy + ix;
470 assert(i < voxels_.size());
475 assert(iy < nr_voxel_y_ && ix < nr_voxel_x_);
476 unsigned int i = nr_voxel_x_ * iy + ix;
477 assert(i < voxels_.size());
491 bool AllocAlignedMemory();
494 unsigned int nr_points_ = 0;
495 unsigned int nr_point_element_ = 0;
496 unsigned int nr_voxel_x_ = 0;
497 unsigned int nr_voxel_y_ = 0;
498 unsigned int nr_voxel_z_ = 0;
499 const T *data_ =
nullptr;
500 const int* semantic_data_ =
nullptr;
501 bool initialized_ =
false;
502 T dim_x_[2], dim_y_[2], dim_z_[2], voxel_dim_[3];
503 float *mem_aligned16_f32_ =
nullptr;
504 int *mem_aligned16_i32_ =
nullptr;
505 std::vector<Voxel<T>> voxels_;
511 nr_point_element_(0),
516 semantic_data_(nullptr),
518 mem_aligned16_f32_(nullptr),
519 mem_aligned16_i32_(nullptr) {
524 AllocAlignedMemory();
529 initialized_ =
false;
531 semantic_data_ =
nullptr;
532 nr_points_ = nr_point_element_ = nr_voxel_x_ = nr_voxel_y_ = 0;
543 T spatial_bound_x_min, T spatial_bound_x_max,
544 T spatial_bound_y_min, T spatial_bound_y_max,
545 T spatial_bound_z_min, T spatial_bound_z_max) {
546 Alloc(nr_voxel_x, nr_voxel_y, spatial_bound_x_min, spatial_bound_x_max,
547 spatial_bound_y_min, spatial_bound_y_max, spatial_bound_z_min,
548 spatial_bound_z_max);
549 AllocAlignedMemory();
550 initialized_ =
false;
555 int r, c, i = 0, m = 0;
556 unsigned int n = (nr_voxel_x_ * nr_voxel_y_);
558 if (n == 0 || voxels_.size() != n) {
562 double cen_x = (
static_cast<double>(nr_voxel_x_ - 1)) * 0.5;
563 double cen_y = (
static_cast<double>(nr_voxel_y_ - 1)) * 0.5;
567 double sigma =
static_cast<double>(
IAverage(nr_voxel_x_, nr_voxel_y_) / 10.0);
568 double nf =
IDiv(0.5, (sigma * sigma));
569 double dr, drsqr, dc, dcsqr, v, ksum = 0.0;
570 std::vector<double> kernel(n, 0.0);
573 for (r = 0; r < static_cast<int>(nr_voxel_y_); ++r) {
574 dr =
static_cast<double>(r) - cen_y;
576 for (c = 0; c < static_cast<int>(nr_voxel_x_); ++c) {
577 dc =
static_cast<double>(c) - cen_x;
579 v =
IExp(-(drsqr + dcsqr) * nf);
587 for (i = 0; i < static_cast<int>(n); ++i) {
592 for (i = 0; i < static_cast<int>(n); ++i) {
593 m =
IMax(8,
static_cast<int>(s_nr_max_reserved_points_ * kernel[i]));
594 voxels_[i].Reserve(m);
599bool VoxelGridXY<T>::AllocAlignedMemory() {
600 if (!mem_aligned16_f32_) {
601 mem_aligned16_f32_ = IAllocAligned<float>(4, 4);
603 if (!mem_aligned16_i32_) {
604 mem_aligned16_i32_ = IAllocAligned<int>(4, 4);
606 return (mem_aligned16_f32_ !=
nullptr && mem_aligned16_i32_ !=
nullptr &&
618 if (x < dim_x_[0] || x > dim_x_[1] || y < dim_y_[0] || y > dim_y_[1] ||
619 z < dim_z_[0] || z > dim_z_[1]) {
623 k =
static_cast<int>(
IMax(
625 IMin(nr_voxel_x_ - 1, (
unsigned int)((x - dim_x_[0]) / voxel_dim_[0]))));
626 j =
static_cast<int>(
IMax(
628 IMin(nr_voxel_y_ - 1, (
unsigned int)((y - dim_y_[0]) / voxel_dim_[1]))));
629 return (nr_voxel_x_ * j + k);
635 if (x < dim_x_[0] || x > dim_x_[1] || y < dim_y_[0] || y > dim_y_[1]) {
639 *col =
static_cast<int>((x - dim_x_[0]) / voxel_dim_[0]);
640 *row =
static_cast<int>((y - dim_y_[0]) / voxel_dim_[1]);
646 T spatial_bound_x_min, T spatial_bound_x_max,
647 T spatial_bound_y_min, T spatial_bound_y_max,
648 T spatial_bound_z_min, T spatial_bound_z_max) {
649 if (!nr_voxel_x || !nr_voxel_y) {
650 initialized_ =
false;
653 nr_voxel_x_ = nr_voxel_x;
654 nr_voxel_y_ = nr_voxel_y;
656 unsigned int i, j, k, n = 0;
657 unsigned int nr_voxel_xy = (nr_voxel_x_ * nr_voxel_y_);
658 unsigned int nr_voxel = nr_voxel_xy;
660 T vx, vy, vz, voxel_width_x, voxel_width_y, voxel_width_z;
663 voxels_.resize(nr_voxel);
666 dim_x_[0] = spatial_bound_x_min;
667 dim_x_[1] = spatial_bound_x_max;
669 dim_y_[0] = spatial_bound_y_min;
670 dim_y_[1] = spatial_bound_y_max;
672 dim_z_[0] = spatial_bound_z_min;
673 dim_z_[1] = spatial_bound_z_max;
675 T span_x = (dim_x_[1] - dim_x_[0]);
676 T span_y = (dim_y_[1] - dim_y_[0]);
677 T span_z = (dim_z_[1] - dim_z_[0]);
679 assert(span_x > 0 && span_y > 0 && span_z > 0);
681 voxel_dim_[0] = voxel_width_x =
IDiv(span_x,
static_cast<int>(nr_voxel_x_));
682 voxel_dim_[1] = voxel_width_y =
IDiv(span_y,
static_cast<int>(nr_voxel_y_));
683 voxel_dim_[2] = voxel_width_z = span_z;
685 std::vector<T> vxs(nr_voxel_x_);
688 for (i = 1; i < nr_voxel_x_; i++) {
689 vxs[i] = vxs[i - 1] + voxel_width_x;
695 for (j = 0; j < nr_voxel_y_; j++) {
696 for (k = 0; k < nr_voxel_x_; k++) {
698 voxels_[n++].Init(vx, vy, vz, voxel_width_x, voxel_width_y, voxel_width_z,
699 static_cast<int>(k),
static_cast<int>(j), 0);
711 unsigned int nr_points,
unsigned int nr_point_element) {
712 if (!data || !nr_points || !nr_point_element || !nr_voxel_x_ ||
713 !semantic_data || !nr_voxel_y_ || nr_voxel_z_ != 1) {
714 initialized_ =
false;
719 semantic_data_ = semantic_data;
720 nr_points_ = nr_points;
721 nr_point_element_ = nr_point_element;
723 unsigned int nr_voxel = (nr_voxel_x_ * nr_voxel_y_);
724 unsigned int i, nd = 0;
727 T voxel_width_x_rec =
IRec(voxel_dim_[0]);
728 T voxel_width_y_rec =
IRec(voxel_dim_[1]);
730 T bound_x_min = dim_x_[0];
731 T bound_x_max = dim_x_[1];
732 T bound_y_min = dim_y_[0];
733 T bound_y_max = dim_y_[1];
734 T bound_z_min = dim_z_[0];
735 T bound_z_max = dim_z_[1];
738 for (i = 0; i < nr_voxel; ++i) {
739 voxels_[i].indices_.clear();
743 for (; n < static_cast<int>(nr_points_); n++, nd += nr_point_element_) {
745 data_ + nd, bound_x_min, bound_x_max, bound_y_min, bound_y_max,
746 bound_z_min, bound_z_max, voxel_width_x_rec, voxel_width_y_rec,
747 static_cast<int>(nr_voxel_x_),
static_cast<int>(nr_voxel_y_));
750 voxels_[id].indices_.push_back(n);
755 return (initialized_);
760 unsigned int nr_points,
unsigned int nr_point_element) {
761 if (!data || !nr_points || !nr_point_element || !nr_voxel_x_ ||
762 !semantic_data || !nr_voxel_y_ || nr_voxel_z_ != 1) {
763 initialized_ =
false;
768 semantic_data_ = semantic_data;
769 nr_points_ = nr_points;
770 nr_point_element_ = nr_point_element;
772 unsigned int nr_voxel = (nr_voxel_x_ * nr_voxel_y_);
773 unsigned int i, n = 0;
776 float voxel_width_x_rec =
IRec(
static_cast<float>(voxel_dim_[0]));
777 float voxel_width_y_rec =
IRec(
static_cast<float>(voxel_dim_[1]));
780 static_cast<int>(nr_voxel_x_), 0);
794 __m128 v_cmp_x, v_cmp_y, v_cmp_z, v_in_roi;
798 __m128i iv_indices, iv_x_indices, iv_y_indices, iv_v_indices_02,
801 for (i = 0; i < nr_voxel; ++i) {
802 voxels_[i].indices_.clear();
805 unsigned int nr_loops = (nr_points >> 2);
806 unsigned int nr_fast_processed = (nr_loops << 2);
807 unsigned int remainder = nr_points - nr_fast_processed;
809 unsigned int d1 = nr_point_element;
810 unsigned int d2 = (nr_point_element << 1);
811 unsigned int d3 = d1 + d2;
812 unsigned int d4 = (nr_point_element << 2);
815 const float *cptr_x = data;
816 const float *cptr_y = data + 1;
817 const float *cptr_z = data + 2;
818 const float *cptr_remainder = data + (nr_fast_processed * nr_point_element);
820 for (i = 0; i < nr_loops; ++i, n += 4) {
822 v_xs =
_mm_setr_ps(cptr_x[0], cptr_x[d1], cptr_x[d2], cptr_x[d3]);
823 v_ys =
_mm_setr_ps(cptr_y[0], cptr_y[d1], cptr_y[d2], cptr_y[d3]);
824 v_zs =
_mm_setr_ps(cptr_z[0], cptr_z[d1], cptr_z[d2], cptr_z[d3]);
839 iv_x_indices =
_mm_min_epi32(iv_nr_voxel_x_m1, iv_x_indices);
845 iv_y_indices =
_mm_min_epi32(iv_nr_voxel_y_m1, iv_y_indices);
854 iv_indices =
_mm_add_epi32(iv_v_indices_02, iv_v_indices_13);
864 if (mem_aligned16_f32_[0] != 0) {
865 voxels_[mem_aligned16_i32_[0]].indices_.push_back(n);
867 if (mem_aligned16_f32_[1] != 0) {
868 voxels_[mem_aligned16_i32_[1]].indices_.push_back(n + 1);
870 if (mem_aligned16_f32_[2] != 0) {
871 voxels_[mem_aligned16_i32_[2]].indices_.push_back(n + 2);
873 if (mem_aligned16_f32_[3] != 0) {
874 voxels_[mem_aligned16_i32_[3]].indices_.push_back(n + 3);
882 for (i = 0; i < remainder; i++, n++) {
884 dim_y_[1], dim_z_[0], dim_z_[1], voxel_width_x_rec,
885 voxel_width_y_rec,
static_cast<int>(nr_voxel_x_),
886 static_cast<int>(nr_voxel_y_));
889 voxels_[id].indices_.push_back(n);
892 cptr_remainder += nr_point_element;
911 return (initialized_);
916 unsigned int nr_points,
unsigned int nr_point_element,
917 unsigned int nr_voxel_x,
unsigned int nr_voxel_y, T spatial_bound_x_min,
918 T spatial_bound_x_max, T spatial_bound_y_min, T spatial_bound_y_max,
919 T spatial_bound_z_min, T spatial_bound_z_max,
bool force_bound) {
920 if (!data || !nr_points || !nr_point_element || !nr_voxel_x || !nr_voxel_y) {
921 initialized_ =
false;
926 semantic_data_ = semantic_data;
927 nr_points_ = nr_points;
928 nr_point_element_ = nr_point_element;
929 nr_voxel_x_ = nr_voxel_x;
930 nr_voxel_y_ = nr_voxel_y;
933 unsigned int i, j, k, n = 0, nd = 0;
934 unsigned int nr_voxel_xy = (nr_voxel_x_ * nr_voxel_y_);
935 unsigned int nr_voxel = nr_voxel_xy;
936 unsigned int nr_voxel_xm1 = nr_voxel_x - 1;
937 unsigned int nr_voxel_ym1 = nr_voxel_y - 1;
938 T vx, vy, vz, x, y, z;
939 T voxel_width_x, voxel_width_y, voxel_width_z;
942 voxels_.resize(nr_voxel);
947 dim_x_[0] = spatial_bound_x_min;
948 dim_x_[1] = spatial_bound_x_max;
950 dim_y_[0] = spatial_bound_y_min;
951 dim_y_[1] = spatial_bound_y_max;
953 dim_z_[0] = spatial_bound_z_min;
954 dim_z_[1] = spatial_bound_z_max;
957 data_, nr_points_, 0, nr_point_element_, &dim_x_[0], &dim_x_[1],
958 &dim_y_[0], &dim_y_[1], &dim_z_[0], &dim_z_[1], spatial_bound_x_min,
959 spatial_bound_x_max, spatial_bound_y_min, spatial_bound_y_max,
960 spatial_bound_z_min, spatial_bound_z_max);
963 T dim_x_min = dim_x_[0];
964 T dim_x_max = dim_x_[1];
966 T dim_y_min = dim_y_[0];
967 T dim_y_max = dim_y_[1];
969 T dim_z_min = dim_z_[0];
970 T dim_z_max = dim_z_[1];
972 T span_x = (dim_x_max - dim_x_min);
973 T span_y = (dim_y_max - dim_y_min);
974 T span_z = (dim_z_max - dim_z_min);
976 assert(span_x > 0 && span_y > 0 && span_z > 0);
978 voxel_dim_[0] = voxel_width_x =
IDiv(span_x,
static_cast<int>(nr_voxel_x_));
979 voxel_dim_[1] = voxel_width_y =
IDiv(span_y,
static_cast<int>(nr_voxel_y_));
980 voxel_dim_[2] = voxel_width_z = span_z;
982 T voxel_width_x_rec =
IRec(voxel_dim_[0]);
983 T voxel_width_y_rec =
IRec(voxel_dim_[1]);
985 std::vector<T> vxs(nr_voxel_x_);
988 for (i = 1; i < nr_voxel_x_; i++) {
989 vxs[i] = vxs[i - 1] + voxel_width_x;
995 for (j = 0; j < nr_voxel_y_; j++) {
996 for (k = 0; k < nr_voxel_x_; k++) {
998 voxels_[n++].init(vx, vy, vz, voxel_width_x, voxel_width_y, voxel_width_z,
999 static_cast<int>(k),
static_cast<int>(j), 0);
1001 vy += voxel_width_y;
1005 for (; n < nr_points_; n++, nd += nr_point_element_) {
1010 if (x < dim_x_min || x > dim_x_max || y < dim_y_min || y > dim_y_max ||
1011 z < dim_z_min || z > dim_z_max) {
1016 k =
IMax((
unsigned int)0,
1018 (
unsigned int)((x - dim_x_min) * voxel_width_x_rec)));
1019 j =
IMax((
unsigned int)0,
1021 (
unsigned int)((y - dim_y_min) * voxel_width_y_rec)));
1022 i = nr_voxel_x * j + k;
1024 assert(i < nr_voxel);
1025 voxels_[i].indices_.push_back(n);
1027 initialized_ =
true;
1028 return initialized_;
1048template <
typename T>
1050 if (!initialized_) {
1053 unsigned int i, n = 0;
1054 for (i = 0; i < voxels_.size(); ++i) {
1055 n += voxels_[i].indices_.size();
1060template <
typename T>
1061static void IPushBackVectors(
const std::vector<T> &src, std::vector<T> *dst) {
1062 unsigned int i = src.size();
1063 unsigned int j = dst->size();
1067 }
else if (j == 0) {
1068 dst->assign(src.begin(), src.end());
1071 ICopy(src.data(), dst->data() + j,
static_cast<int>(i));
1076template <
typename T>
1078 unsigned int dsf_dim_x,
unsigned int dsf_dim_y) {
1081 }
else if (dsf_dim_x == 0 && dsf_dim_y == 0) {
1093 unsigned int nr_voxel_x_src = src.
NrVoxelX();
1094 unsigned int nr_voxel_y_src = src.
NrVoxelY();
1095 unsigned int nr_voxel_z_src = src.
NrVoxelZ();
1097 assert(nr_voxel_z_src == 1);
1100 unsigned int sf_x = (
unsigned int)
IPow((
unsigned int)2, dsf_dim_x);
1101 unsigned int sf_y = (
unsigned int)
IPow((
unsigned int)2, dsf_dim_y);
1104 unsigned int nr_voxel_x_dst = nr_voxel_x_src / sf_x;
1105 unsigned int nr_voxel_y_dst = nr_voxel_y_src / sf_y;
1106 unsigned int nr_voxel_z_dst = nr_voxel_z_src;
1108 if (!nr_voxel_x_dst || !nr_voxel_y_dst || !nr_voxel_z_dst) {
1112 unsigned int nr_res_voxel_x_dst = (nr_voxel_x_src % sf_x);
1113 unsigned int nr_res_voxel_y_dst = (nr_voxel_y_src % sf_y);
1115 T voxel_width_x_src = 0;
1116 T voxel_width_y_src = 0;
1117 T voxel_width_z_src = 0;
1118 T dim_min_x_src = 0;
1119 T dim_max_x_src = 0;
1120 T dim_min_y_src = 0;
1121 T dim_max_y_src = 0;
1122 T dim_min_z_src = 0;
1123 T dim_max_z_src = 0;
1127 &voxel_width_z_src);
1130 &dim_max_y_src, &dim_min_z_src, &dim_max_z_src);
1133 T voxel_width_x_dst = (sf_x * voxel_width_x_src);
1134 T voxel_width_y_dst = (sf_y * voxel_width_y_src);
1135 T voxel_width_z_dst = voxel_width_z_src;
1138 T dim_x_dst[2], dim_y_dst[2], dim_z_dst[2];
1140 dim_x_dst[0] = dim_min_x_src;
1141 dim_y_dst[0] = dim_min_y_src;
1142 dim_z_dst[0] = dim_min_z_src;
1144 dim_x_dst[1] = (0 == nr_res_voxel_x_dst)
1146 : (voxel_width_x_dst * nr_voxel_x_dst + dim_x_dst[0]);
1147 dim_y_dst[1] = (0 == nr_res_voxel_y_dst)
1149 : (voxel_width_y_dst * nr_voxel_y_dst + dim_y_dst[0]);
1150 dim_z_dst[1] = dim_max_z_src;
1157 dst->
SetGridDimension(dim_x_dst[0], dim_x_dst[1], dim_y_dst[0], dim_y_dst[1],
1158 dim_z_dst[0], dim_z_dst[1]);
1159 dst->
SetNrVoxel(nr_voxel_x_dst, nr_voxel_y_dst, nr_voxel_z_dst);
1162 unsigned int i, j, r, c, rs, cs, rspi, n = 0;
1164 T vy, vz = dim_z_dst[0];
1165 std::vector<T> vxs(nr_voxel_x_dst);
1167 vxs[0] = dim_x_dst[0];
1169 for (i = 1; i < nr_voxel_x_dst; i++) {
1170 vxs[i] = vxs[i - 1] + voxel_width_x_dst;
1173 std::vector<Voxel<T>> voxels(nr_voxel_y_dst * nr_voxel_x_dst);
1175 for (r = 0; r < nr_voxel_y_dst; r++) {
1177 vy = dim_y_dst[0] + (r * voxel_width_y_dst);
1179 for (c = 0; c < nr_voxel_x_dst; c++) {
1181 voxels[n].init(vxs[c], vy, vz, voxel_width_x_dst, voxel_width_y_dst,
1182 voxel_width_z_dst,
static_cast<int>(c),
1183 static_cast<int>(r),
static_cast<int>(0));
1185 for (i = 0; i < sf_y; ++i) {
1187 for (j = 0; j < sf_x; ++j) {
1188 IPushBackVectors(src(rspi, cs + j).indices_, &voxels[n].indices_);
1201template <
typename DATA_TYPE>
1206 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
1207 unsigned int dsf_y, DATA_TYPE spatial_bound_x_min,
1208 DATA_TYPE spatial_bound_x_max,
1209 DATA_TYPE spatial_bound_y_min,
1210 DATA_TYPE spatial_bound_y_max,
1211 DATA_TYPE spatial_bound_z_min,
1212 DATA_TYPE spatial_bound_z_max) {
1213 Alloc(nr_scale, nr_voxel_x_base, nr_voxel_y_base, dsf_x, dsf_y,
1214 spatial_bound_x_min, spatial_bound_x_max, spatial_bound_y_min,
1215 spatial_bound_y_max, spatial_bound_z_min, spatial_bound_z_max);
1222 bool Alloc(
unsigned int nr_scale,
unsigned int nr_voxel_x_base,
1223 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
1224 unsigned int dsf_y, DATA_TYPE spatial_bound_x_min,
1225 DATA_TYPE spatial_bound_x_max, DATA_TYPE spatial_bound_y_min,
1226 DATA_TYPE spatial_bound_y_max, DATA_TYPE spatial_bound_z_min,
1227 DATA_TYPE spatial_bound_z_max);
1230 bool Set(
const DATA_TYPE *pc,
unsigned int nr_points,
1231 unsigned int nr_point_element);
1235 bool SetS(
const float *pc,
unsigned int nr_points,
1236 unsigned int nr_point_element);
1238 bool Set(
const DATA_TYPE *pc,
unsigned int nr_scale,
unsigned int nr_points,
1239 unsigned int nr_point_element,
unsigned int nr_voxel_x_base,
1240 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
unsigned int dsf_y,
1241 DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max,
1242 DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max,
1243 DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max);
1245 unsigned int NrScale()
const {
return (
unsigned int)vgrids_.size(); }
1248 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel() : 0;
1252 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel_x() : 0;
1256 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel_y() : 0;
1260 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel_z() : 0;
1264 return (scale < vgrids_.size()) ? vgrids_[scale].nr_points() : 0;
1278 assert(i >= 0 && i < vgrids_.size());
1283 assert(i >= 0 && i < vgrids_.size());
1288 assert(i >= 0 && i <
static_cast<int>(vgrids_.size()));
1293 assert(i >= 0 && i <
static_cast<int>(vgrids_.size()));
1302 unsigned int nr_points_, nr_point_element_;
1303 unsigned int dsf_x_, dsf_y_, dsf_z_;
1304 const DATA_TYPE *pc_;
1305 std::vector<VoxelGridXY<DATA_TYPE>> vgrids_;
1308template <
typename DATA_TYPE>
1312 nr_point_element_(0),
1317template <
typename DATA_TYPE>
1319 unsigned int nr_scale,
unsigned int nr_voxel_x_base,
1320 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
unsigned int dsf_y,
1321 DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max,
1322 DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max,
1323 DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max) {
1324 if (!nr_scale || !nr_voxel_x_base || !nr_voxel_y_base) {
1329 unsigned int nr_voxel_x = nr_voxel_x_base;
1330 unsigned int nr_voxel_y = nr_voxel_y_base;
1331 unsigned int sf_x = (
unsigned int)
IPow((
unsigned int)2, dsf_x);
1332 unsigned int sf_y = (
unsigned int)
IPow((
unsigned int)2, dsf_y);
1339 vgrids_.resize(nr_scale);
1341 for (scale = 0; scale < nr_scale; ++scale) {
1342 if (!vgrids_[scale].alloc(nr_voxel_x, nr_voxel_y, spatial_bound_x_min,
1343 spatial_bound_x_max, spatial_bound_y_min,
1344 spatial_bound_y_max, spatial_bound_z_min,
1345 spatial_bound_z_max)) {
1356 if (scale != nr_scale) {
1357 vgrids_.resize(scale);
1364template <
typename DATA_TYPE>
1366 unsigned int nr_points,
1367 unsigned int nr_point_element) {
1368 if (!pc || !nr_points || !nr_point_element || vgrids_.empty()) {
1372 unsigned int scale, nr_scale = (
unsigned int)vgrids_.size();
1375 nr_points_ = nr_points;
1376 nr_point_element_ = nr_point_element;
1378 for (scale = 0; scale < nr_scale; ++scale) {
1379 if (!vgrids_[scale].set(pc, nr_points, nr_point_element)) {
1385 if (scale < nr_scale) {
1386 vgrids_.resize(scale);
1389 return (vgrids_.size() == nr_scale);
1392template <
typename DATA_TYPE>
1394 unsigned int nr_points,
1395 unsigned int nr_point_element) {
1396 if (!pc || !nr_points || !nr_point_element || vgrids_.empty()) {
1400 unsigned int scale, nr_scale = (
unsigned int)vgrids_.size();
1403 nr_points_ = nr_points;
1404 nr_point_element_ = nr_point_element;
1406 for (scale = 0; scale < nr_scale; ++scale) {
1407 if (!vgrids_[scale].set_s(pc, nr_points, nr_point_element)) {
1413 if (scale < nr_scale) {
1414 vgrids_.resize(scale);
1417 return (vgrids_.size() == nr_scale);
1420template <
typename DATA_TYPE>
1422 const DATA_TYPE *pc,
unsigned int nr_scale,
unsigned int nr_points,
1423 unsigned int nr_point_element,
unsigned int nr_voxel_x_base,
1424 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
unsigned int dsf_y,
1425 DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max,
1426 DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max,
1427 DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max) {
1428 if (!pc || !nr_scale || !nr_points || !nr_point_element || !nr_voxel_x_base ||
1435 nr_points_ = nr_points;
1436 nr_point_element_ = nr_point_element;
1443 vgrids_.resize(nr_scale);
1446 if (!vgrids_[0].set(pc_, nr_points, nr_point_element, nr_voxel_x_base,
1447 nr_voxel_y_base, spatial_bound_x_min, spatial_bound_x_max,
1448 spatial_bound_y_min, spatial_bound_y_max,
1449 spatial_bound_z_min, spatial_bound_z_max)) {
1454 for (s = 1; s < nr_scale; ++s) {
1461 for (i = 0; i < (nr_scale - s); ++i) {
1466 return (vgrids_.size() == nr_scale);
1469template <
typename DATA_TYPE>
1473 nr_points_ = nr_point_element_ = dsf_x_ = dsf_y_ = dsf_z_ = 0;
1476template <
typename DATA_TYPE>
1479 if (vgrids_.empty()) {
1482 for (i = 0; i < vgrids_.size(); ++i) {
1483 if (!vgrids_[i].initialized()) {
1487 return (i == vgrids_.size());
const T * operator[](unsigned int i) const
PtCluster & operator=(const PtCluster< T, d > &c)
const_iterator Begin() const
const T * ConstData() const
T * operator[](unsigned int i)
reference operator()(unsigned int i, unsigned int j)
const T & const_reference
const_iterator End() const
const_reference operator()(unsigned int i, unsigned int j) const
static unsigned int PointsizeInByte()
PtCluster(const PtCluster< T, d > &c)
unsigned int NrPoints() const
static unsigned int NrPointElement()
unsigned int ClustersizeInByte() const
bool Alloc(unsigned int nr_scale, unsigned int nr_voxel_x_base, unsigned int nr_voxel_y_base, unsigned int dsf_x, unsigned int dsf_y, DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max, DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max, DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max)
unsigned int NrVoxel(unsigned int i=0) const
bool SetS(const float *pc, unsigned int nr_points, unsigned int nr_point_element)
unsigned int NrScale() const
unsigned int NrPointElement() const
unsigned int NrVoxelZ(unsigned int i=0) const
const VoxelGridXY< DATA_TYPE > & operator[](unsigned int i) const
unsigned int NrPoints(unsigned int scale) const
unsigned int GetDsfZ() const
unsigned int NrVoxelX(unsigned int i=0) const
const DATA_TYPE * ConstData() const
unsigned int NrPoints() const
unsigned int NrVoxelY(unsigned int i=0) const
bool Set(const DATA_TYPE *pc, unsigned int nr_points, unsigned int nr_point_element)
unsigned int GetDsfX() const
VoxelGridXY< DATA_TYPE > & operator[](unsigned int i)
VoxelGridXY< DATA_TYPE > & operator[](int i)
const VoxelGridXY< DATA_TYPE > & operator[](int i) const
unsigned int GetDsfY() const
VoxelGridXYPyramid(unsigned int nr_scale, unsigned int nr_voxel_x_base, unsigned int nr_voxel_y_base, unsigned int dsf_x, unsigned int dsf_y, DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max, DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max, DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max)
Voxel< T > & operator()(unsigned int iy, unsigned int ix)
const Voxel< T > & operator[](unsigned int i) const
void SetGridDimension(T dim_min_x, T dim_max_x, T dim_min_y, T dim_max_y, T dim_min_z, T dim_max_z)
void SetInitialized(bool initialized)
const Voxel< T > & operator()(unsigned int iy, unsigned int ix) const
VoxelGridXY & operator=(const VoxelGridXY< T > &vg)
bool Set(const T *data, const int *semantic_data, unsigned int nr_points, unsigned int nr_point_element)
const Voxel< T > & operator[](int i) const
unsigned int NrVoxelX() const
unsigned int NrPoints() const
unsigned int NrVoxel() const
bool GetVoxelDimension(T *voxel_width_x, T *voxel_width_y, T *voxel_width_z) const
unsigned int NrPointElement() const
void SetVoxelDimension(T voxel_width_x, T voxel_width_y, T voxel_width_z)
void SetNrPointElement(unsigned int nr_point_element)
void SetSematicValueData(const int *data)
unsigned int NrVoxelY() const
void SetNrPoints(unsigned int nr_points)
bool GetGridDimension(T *dim_min_x, T *dim_max_x, T *dim_min_y, T *dim_max_y, T *dim_min_z, T *dim_max_z) const
unsigned int NrIndexedPoints() const
bool Set(const T *data, const int *semantic_data, unsigned int nr_points, unsigned int nr_point_element, unsigned int nr_voxel_x, unsigned int nr_voxel_y, T spatial_bound_x_min, T spatial_bound_x_max, T spatial_bound_y_min, T spatial_bound_y_max, T spatial_bound_z_min, T spatial_bound_z_max, bool force_bound=true)
unsigned int NrVoxelZ() const
VoxelGridXY(unsigned int nr_voxel_x, unsigned int nr_voxel_y, T spatial_bound_x_min, T spatial_bound_x_max, T spatial_bound_y_min, T spatial_bound_y_max, T spatial_bound_z_min, T spatial_bound_z_max)
Voxel< T > & operator[](unsigned int i)
void SetPointCloudsData(const T *data)
const std::vector< Voxel< T > > & GetConstVoxels() const
const T * const_data() const
void SetVoxels(const std::vector< Voxel< T > > &voxels)
bool GetVoxelCoordinateXY(T x, T y, int *row, int *col) const
int WhichVoxel(T x, T y, T z) const
bool Alloc(unsigned int nr_voxel_x, unsigned int nr_voxel_y, T spatial_bound_x_min, T spatial_bound_x_max, T spatial_bound_y_min, T spatial_bound_y_max, T spatial_bound_z_min, T spatial_bound_z_max)
Voxel< T > & operator[](int i)
std::vector< Voxel< T > > & GetVoxels()
bool SetS(const float *data, const int *semantic_data, unsigned int nr_points, unsigned int nr_point_element)
void SetNrVoxel(unsigned int nr_voxel_x, unsigned int nr_voxel_y, unsigned int nr_voxel_z)
const int * const_semantic_data() const
Voxel & operator=(const Voxel< T > &voxel)
void Init(T v_x, T v_y, T v_z, T dim_x, T dim_y, T dim_z, int ix, int iy, int iz)
unsigned int NrPoints() const
unsigned int Capacity() const
void Init(const T *v, T dim_x, T dim_y, T dim_z, int ix, int iy, int iz)
Voxel(const Voxel< T > &voxel)
std::vector< int > indices_
void Reserve(unsigned int size)
int AssignPointToVoxel(T xx, T yy, T zz, T bound_x_min, T bound_x_max, T bound_y_min, T bound_y_max, T bound_z_min, T bound_z_max, T voxel_width_x_rec, T voxel_width_y_rec, int nr_voxel_x, int nr_voxel_y)
void IFreeAligned(T **mem)
void ICopy(const T *src, T *dst, int n)
int IAssignPointToVoxel(const T *data, T bound_x_min, T bound_x_max, T bound_y_min, T bound_y_max, T bound_z_min, T bound_z_max, T voxel_width_x_rec, T voxel_width_y_rec, int nr_voxel_x, int nr_voxel_y)
void ICopy3(const T src[3], T dst[3])
int IVerifyAlignment(const T *mem, int alignment_power=4)
float IDiv(float a, float b)
float IPow(float a, float b)
void IGetPointcloudsDimWBound(const T *threeds, int n, int start_offset, int element_size, T *dim_min_x, T *dim_max_x, T *dim_min_y, T *dim_max_y, T *dim_min_z, T *dim_max_z, T bound_min_x, T bound_max_x, T bound_min_y, T bound_max_y, T bound_min_z, T bound_max_z)
bool IDownsampleVoxelGridXY(const VoxelGridXY< T > &src, VoxelGridXY< T > *dst, unsigned int dsf_dim_x, unsigned int dsf_dim_y)
FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b)
FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a)
FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b)
FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x)
FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b)
FORCE_INLINE __m128i _mm_set1_epi32(int)
FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0)
FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b)
FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a)
FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b)
FORCE_INLINE __m128 _mm_set_ps1(float)
FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b)
FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b)
FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b)
#define _MM_SHUFFLE(fp3, fp2, fp1, fp0)
MACRO for shuffle parameter for _mm_shuffle_ps().
FORCE_INLINE void _mm_store_ps(float *p, __m128 a)
#define _mm_shuffle_epi32(a, imm)