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);
315 &this->dim_y_[1], &this->dim_z_[0], &this->dim_z_[1]);
316 this->voxels_.resize(vg.
NrVoxel());
317 for (
unsigned int i = 0; i < vg.
NrVoxel(); ++i) {
318 this->voxels_[i] = vg[i];
321 this->AllocAlignedMemory();
329 IFreeAligned<float>(&mem_aligned16_f32_);
330 IFreeAligned<int>(&mem_aligned16_i32_);
334 bool Alloc(
unsigned int nr_voxel_x,
unsigned int nr_voxel_y,
335 T spatial_bound_x_min, T spatial_bound_x_max,
336 T spatial_bound_y_min, T spatial_bound_y_max,
337 T spatial_bound_z_min, T spatial_bound_z_max);
339 bool Set(
const T *data,
unsigned int nr_points,
340 unsigned int nr_point_element);
343 bool SetS(
const float *data,
unsigned int nr_points,
344 unsigned int nr_point_element);
346 bool Set(
const T *data,
unsigned int nr_points,
unsigned int nr_point_element,
347 unsigned int nr_voxel_x,
unsigned int nr_voxel_y,
348 T spatial_bound_x_min, T spatial_bound_x_max, T spatial_bound_y_min,
349 T spatial_bound_y_max, T spatial_bound_z_min, T spatial_bound_z_max,
350 bool force_bound =
true);
354 unsigned int NrVoxel()
const {
return (
unsigned int)voxels_.size(); }
356 unsigned int NrVoxelX()
const {
return nr_voxel_x_; }
358 unsigned int NrVoxelY()
const {
return nr_voxel_y_; }
362 unsigned int NrPoints()
const {
return nr_points_; }
373 voxels_.assign(voxels.begin(), voxels.end());
377 T *dim_min_z, T *dim_max_z)
const {
379 dim_min_x = dim_max_x = dim_min_y = dim_max_y = dim_min_z = dim_max_z =
383 *dim_min_x = dim_x_[0];
384 *dim_max_x = dim_x_[1];
385 *dim_min_y = dim_y_[0];
386 *dim_max_y = dim_y_[1];
387 *dim_min_z = dim_z_[0];
388 *dim_max_z = dim_z_[1];
393 T dim_min_z, T dim_max_z) {
394 dim_x_[0] = dim_min_x;
395 dim_x_[1] = dim_max_x;
396 dim_y_[0] = dim_min_y;
397 dim_y_[1] = dim_max_y;
398 dim_z_[0] = dim_min_z;
399 dim_z_[1] = dim_max_z;
403 T *voxel_width_z)
const {
405 *voxel_width_x = *voxel_width_y = *voxel_width_z =
static_cast<T
>(0);
408 *voxel_width_x = voxel_dim_[0];
409 *voxel_width_y = voxel_dim_[1];
410 *voxel_width_z = voxel_dim_[2];
415 voxel_dim_[0] = voxel_width_x;
416 voxel_dim_[1] = voxel_width_y;
417 voxel_dim_[2] = voxel_width_z;
420 void SetNrPoints(
unsigned int nr_points) { nr_points_ = nr_points; }
423 nr_point_element_ = nr_point_element;
426 void SetNrVoxel(
unsigned int nr_voxel_x,
unsigned int nr_voxel_y,
427 unsigned int nr_voxel_z) {
428 nr_voxel_x_ = nr_voxel_x;
429 nr_voxel_y_ = nr_voxel_y;
430 nr_voxel_z_ = nr_voxel_z;
445 assert(i >= 0 && i < voxels_.size());
450 assert(i >= 0 && i < voxels_.size());
455 assert(i >= 0 && i <
static_cast<int>(voxels_.size()));
459 assert(i >= 0 && i <
static_cast<int>(voxels_.size()));
464 assert(iy < nr_voxel_y_ && ix < nr_voxel_x_);
465 unsigned int i = nr_voxel_x_ * iy + ix;
466 assert(i < voxels_.size());
471 assert(iy < nr_voxel_y_ && ix < nr_voxel_x_);
472 unsigned int i = nr_voxel_x_ * iy + ix;
473 assert(i < voxels_.size());
483 bool AllocAlignedMemory();
486 unsigned int nr_points_ = 0;
487 unsigned int nr_point_element_ = 0;
488 unsigned int nr_voxel_x_ = 0;
489 unsigned int nr_voxel_y_ = 0;
490 unsigned int nr_voxel_z_ = 0;
491 const T *data_ =
nullptr;
492 bool initialized_ =
false;
493 T dim_x_[2], dim_y_[2], dim_z_[2], voxel_dim_[3];
494 float *mem_aligned16_f32_ =
nullptr;
495 int *mem_aligned16_i32_ =
nullptr;
496 std::vector<Voxel<T>> voxels_;
502 nr_point_element_(0),
508 mem_aligned16_f32_(nullptr),
509 mem_aligned16_i32_(nullptr) {
514 AllocAlignedMemory();
519 initialized_ =
false;
521 nr_points_ = nr_point_element_ = nr_voxel_x_ = nr_voxel_y_ = 0;
532 T spatial_bound_x_min, T spatial_bound_x_max,
533 T spatial_bound_y_min, T spatial_bound_y_max,
534 T spatial_bound_z_min, T spatial_bound_z_max) {
535 Alloc(nr_voxel_x, nr_voxel_y, spatial_bound_x_min, spatial_bound_x_max,
536 spatial_bound_y_min, spatial_bound_y_max, spatial_bound_z_min,
537 spatial_bound_z_max);
538 AllocAlignedMemory();
539 initialized_ =
false;
544 int r, c, i = 0, m = 0;
545 unsigned int n = (nr_voxel_x_ * nr_voxel_y_);
547 if (n == 0 || voxels_.size() != n) {
551 double cen_x = (
static_cast<double>(nr_voxel_x_ - 1)) * 0.5;
552 double cen_y = (
static_cast<double>(nr_voxel_y_ - 1)) * 0.5;
556 double sigma =
static_cast<double>(
IAverage(nr_voxel_x_, nr_voxel_y_) / 10.0);
557 double nf =
IDiv(0.5, (sigma * sigma));
558 double dr, drsqr, dc, dcsqr, v, ksum = 0.0;
559 std::vector<double> kernel(n, 0.0);
562 for (r = 0; r < static_cast<int>(nr_voxel_y_); ++r) {
563 dr =
static_cast<double>(r) - cen_y;
565 for (c = 0; c < static_cast<int>(nr_voxel_x_); ++c) {
566 dc =
static_cast<double>(c) - cen_x;
568 v =
IExp(-(drsqr + dcsqr) * nf);
576 for (i = 0; i < static_cast<int>(n); ++i) {
581 for (i = 0; i < static_cast<int>(n); ++i) {
582 m =
IMax(8,
static_cast<int>(s_nr_max_reserved_points_ * kernel[i]));
583 voxels_[i].Reserve(m);
588bool VoxelGridXY<T>::AllocAlignedMemory() {
589 if (!mem_aligned16_f32_) {
590 mem_aligned16_f32_ = IAllocAligned<float>(4, 4);
592 if (!mem_aligned16_i32_) {
593 mem_aligned16_i32_ = IAllocAligned<int>(4, 4);
595 return (mem_aligned16_f32_ !=
nullptr && mem_aligned16_i32_ !=
nullptr &&
607 if (x < dim_x_[0] || x > dim_x_[1] || y < dim_y_[0] || y > dim_y_[1] ||
608 z < dim_z_[0] || z > dim_z_[1]) {
612 k =
static_cast<int>(
IMax(
614 IMin(nr_voxel_x_ - 1, (
unsigned int)((x - dim_x_[0]) / voxel_dim_[0]))));
615 j =
static_cast<int>(
IMax(
617 IMin(nr_voxel_y_ - 1, (
unsigned int)((y - dim_y_[0]) / voxel_dim_[1]))));
618 return (nr_voxel_x_ * j + k);
624 if (x < dim_x_[0] || x > dim_x_[1] || y < dim_y_[0] || y > dim_y_[1]) {
628 *col =
static_cast<int>((x - dim_x_[0]) / voxel_dim_[0]);
629 *row =
static_cast<int>((y - dim_y_[0]) / voxel_dim_[1]);
635 T spatial_bound_x_min, T spatial_bound_x_max,
636 T spatial_bound_y_min, T spatial_bound_y_max,
637 T spatial_bound_z_min, T spatial_bound_z_max) {
638 if (!nr_voxel_x || !nr_voxel_y) {
639 initialized_ =
false;
642 nr_voxel_x_ = nr_voxel_x;
643 nr_voxel_y_ = nr_voxel_y;
645 unsigned int i, j, k, n = 0;
646 unsigned int nr_voxel_xy = (nr_voxel_x_ * nr_voxel_y_);
647 unsigned int nr_voxel = nr_voxel_xy;
649 T vx, vy, vz, voxel_width_x, voxel_width_y, voxel_width_z;
652 voxels_.resize(nr_voxel);
655 dim_x_[0] = spatial_bound_x_min;
656 dim_x_[1] = spatial_bound_x_max;
658 dim_y_[0] = spatial_bound_y_min;
659 dim_y_[1] = spatial_bound_y_max;
661 dim_z_[0] = spatial_bound_z_min;
662 dim_z_[1] = spatial_bound_z_max;
664 T span_x = (dim_x_[1] - dim_x_[0]);
665 T span_y = (dim_y_[1] - dim_y_[0]);
666 T span_z = (dim_z_[1] - dim_z_[0]);
668 assert(span_x > 0 && span_y > 0 && span_z > 0);
670 voxel_dim_[0] = voxel_width_x =
IDiv(span_x,
static_cast<int>(nr_voxel_x_));
671 voxel_dim_[1] = voxel_width_y =
IDiv(span_y,
static_cast<int>(nr_voxel_y_));
672 voxel_dim_[2] = voxel_width_z = span_z;
674 std::vector<T> vxs(nr_voxel_x_);
677 for (i = 1; i < nr_voxel_x_; i++) {
678 vxs[i] = vxs[i - 1] + voxel_width_x;
684 for (j = 0; j < nr_voxel_y_; j++) {
685 for (k = 0; k < nr_voxel_x_; k++) {
687 voxels_[n++].Init(vx, vy, vz, voxel_width_x, voxel_width_y, voxel_width_z,
688 static_cast<int>(k),
static_cast<int>(j), 0);
700 unsigned int nr_point_element) {
701 if (!data || !nr_points || !nr_point_element || !nr_voxel_x_ ||
702 !nr_voxel_y_ || nr_voxel_z_ != 1) {
703 initialized_ =
false;
708 nr_points_ = nr_points;
709 nr_point_element_ = nr_point_element;
711 unsigned int nr_voxel = (nr_voxel_x_ * nr_voxel_y_);
712 unsigned int i, nd = 0;
715 T voxel_width_x_rec =
IRec(voxel_dim_[0]);
716 T voxel_width_y_rec =
IRec(voxel_dim_[1]);
718 T bound_x_min = dim_x_[0];
719 T bound_x_max = dim_x_[1];
720 T bound_y_min = dim_y_[0];
721 T bound_y_max = dim_y_[1];
722 T bound_z_min = dim_z_[0];
723 T bound_z_max = dim_z_[1];
726 for (i = 0; i < nr_voxel; ++i) {
727 voxels_[i].indices_.clear();
731 for (; n < static_cast<int>(nr_points_); n++, nd += nr_point_element_) {
733 data_ + nd, bound_x_min, bound_x_max, bound_y_min, bound_y_max,
734 bound_z_min, bound_z_max, voxel_width_x_rec, voxel_width_y_rec,
735 static_cast<int>(nr_voxel_x_),
static_cast<int>(nr_voxel_y_));
738 voxels_[id].indices_.push_back(n);
743 return (initialized_);
748 unsigned int nr_point_element) {
749 if (!data || !nr_points || !nr_point_element || !nr_voxel_x_ ||
750 !nr_voxel_y_ || nr_voxel_z_ != 1) {
751 initialized_ =
false;
756 nr_points_ = nr_points;
757 nr_point_element_ = nr_point_element;
759 unsigned int nr_voxel = (nr_voxel_x_ * nr_voxel_y_);
760 unsigned int i, n = 0;
763 float voxel_width_x_rec =
IRec(
static_cast<float>(voxel_dim_[0]));
764 float voxel_width_y_rec =
IRec(
static_cast<float>(voxel_dim_[1]));
767 static_cast<int>(nr_voxel_x_), 0);
781 __m128 v_cmp_x, v_cmp_y, v_cmp_z, v_in_roi;
785 __m128i iv_indices, iv_x_indices, iv_y_indices, iv_v_indices_02,
788 for (i = 0; i < nr_voxel; ++i) {
789 voxels_[i].indices_.clear();
792 unsigned int nr_loops = (nr_points >> 2);
793 unsigned int nr_fast_processed = (nr_loops << 2);
794 unsigned int remainder = nr_points - nr_fast_processed;
796 unsigned int d1 = nr_point_element;
797 unsigned int d2 = (nr_point_element << 1);
798 unsigned int d3 = d1 + d2;
799 unsigned int d4 = (nr_point_element << 2);
802 const float *cptr_x = data;
803 const float *cptr_y = data + 1;
804 const float *cptr_z = data + 2;
805 const float *cptr_remainder = data + (nr_fast_processed * nr_point_element);
807 for (i = 0; i < nr_loops; ++i, n += 4) {
809 v_xs =
_mm_setr_ps(cptr_x[0], cptr_x[d1], cptr_x[d2], cptr_x[d3]);
810 v_ys =
_mm_setr_ps(cptr_y[0], cptr_y[d1], cptr_y[d2], cptr_y[d3]);
811 v_zs =
_mm_setr_ps(cptr_z[0], cptr_z[d1], cptr_z[d2], cptr_z[d3]);
826 iv_x_indices =
_mm_min_epi32(iv_nr_voxel_x_m1, iv_x_indices);
832 iv_y_indices =
_mm_min_epi32(iv_nr_voxel_y_m1, iv_y_indices);
841 iv_indices =
_mm_add_epi32(iv_v_indices_02, iv_v_indices_13);
851 if (mem_aligned16_f32_[0] != 0) {
852 voxels_[mem_aligned16_i32_[0]].indices_.push_back(n);
854 if (mem_aligned16_f32_[1] != 0) {
855 voxels_[mem_aligned16_i32_[1]].indices_.push_back(n + 1);
857 if (mem_aligned16_f32_[2] != 0) {
858 voxels_[mem_aligned16_i32_[2]].indices_.push_back(n + 2);
860 if (mem_aligned16_f32_[3] != 0) {
861 voxels_[mem_aligned16_i32_[3]].indices_.push_back(n + 3);
869 for (i = 0; i < remainder; i++, n++) {
871 dim_y_[1], dim_z_[0], dim_z_[1], voxel_width_x_rec,
872 voxel_width_y_rec,
static_cast<int>(nr_voxel_x_),
873 static_cast<int>(nr_voxel_y_));
876 voxels_[id].indices_.push_back(n);
879 cptr_remainder += nr_point_element;
898 return (initialized_);
903 unsigned int nr_point_element,
unsigned int nr_voxel_x,
904 unsigned int nr_voxel_y, T spatial_bound_x_min,
905 T spatial_bound_x_max, T spatial_bound_y_min,
906 T spatial_bound_y_max, T spatial_bound_z_min,
907 T spatial_bound_z_max,
bool force_bound) {
908 if (!data || !nr_points || !nr_point_element || !nr_voxel_x || !nr_voxel_y) {
909 initialized_ =
false;
914 nr_points_ = nr_points;
915 nr_point_element_ = nr_point_element;
916 nr_voxel_x_ = nr_voxel_x;
917 nr_voxel_y_ = nr_voxel_y;
920 unsigned int i, j, k, n = 0, nd = 0;
921 unsigned int nr_voxel_xy = (nr_voxel_x_ * nr_voxel_y_);
922 unsigned int nr_voxel = nr_voxel_xy;
923 unsigned int nr_voxel_xm1 = nr_voxel_x - 1;
924 unsigned int nr_voxel_ym1 = nr_voxel_y - 1;
925 T vx, vy, vz, x, y, z;
926 T voxel_width_x, voxel_width_y, voxel_width_z;
929 voxels_.resize(nr_voxel);
934 dim_x_[0] = spatial_bound_x_min;
935 dim_x_[1] = spatial_bound_x_max;
937 dim_y_[0] = spatial_bound_y_min;
938 dim_y_[1] = spatial_bound_y_max;
940 dim_z_[0] = spatial_bound_z_min;
941 dim_z_[1] = spatial_bound_z_max;
944 data_, nr_points_, 0, nr_point_element_, &dim_x_[0], &dim_x_[1],
945 &dim_y_[0], &dim_y_[1], &dim_z_[0], &dim_z_[1], spatial_bound_x_min,
946 spatial_bound_x_max, spatial_bound_y_min, spatial_bound_y_max,
947 spatial_bound_z_min, spatial_bound_z_max);
950 T dim_x_min = dim_x_[0];
951 T dim_x_max = dim_x_[1];
953 T dim_y_min = dim_y_[0];
954 T dim_y_max = dim_y_[1];
956 T dim_z_min = dim_z_[0];
957 T dim_z_max = dim_z_[1];
959 T span_x = (dim_x_max - dim_x_min);
960 T span_y = (dim_y_max - dim_y_min);
961 T span_z = (dim_z_max - dim_z_min);
963 assert(span_x > 0 && span_y > 0 && span_z > 0);
965 voxel_dim_[0] = voxel_width_x =
IDiv(span_x,
static_cast<int>(nr_voxel_x_));
966 voxel_dim_[1] = voxel_width_y =
IDiv(span_y,
static_cast<int>(nr_voxel_y_));
967 voxel_dim_[2] = voxel_width_z = span_z;
969 T voxel_width_x_rec =
IRec(voxel_dim_[0]);
970 T voxel_width_y_rec =
IRec(voxel_dim_[1]);
972 std::vector<T> vxs(nr_voxel_x_);
975 for (i = 1; i < nr_voxel_x_; i++) {
976 vxs[i] = vxs[i - 1] + voxel_width_x;
982 for (j = 0; j < nr_voxel_y_; j++) {
983 for (k = 0; k < nr_voxel_x_; k++) {
985 voxels_[n++].init(vx, vy, vz, voxel_width_x, voxel_width_y, voxel_width_z,
986 static_cast<int>(k),
static_cast<int>(j), 0);
992 for (; n < nr_points_; n++, nd += nr_point_element_) {
997 if (x < dim_x_min || x > dim_x_max || y < dim_y_min || y > dim_y_max ||
998 z < dim_z_min || z > dim_z_max) {
1003 k =
IMax((
unsigned int)0,
1005 (
unsigned int)((x - dim_x_min) * voxel_width_x_rec)));
1006 j =
IMax((
unsigned int)0,
1008 (
unsigned int)((y - dim_y_min) * voxel_width_y_rec)));
1009 i = nr_voxel_x * j + k;
1011 assert(i < nr_voxel);
1012 voxels_[i].indices_.push_back(n);
1014 initialized_ =
true;
1015 return initialized_;
1035template <
typename T>
1037 if (!initialized_) {
1040 unsigned int i, n = 0;
1041 for (i = 0; i < voxels_.size(); ++i) {
1042 n += voxels_[i].indices_.size();
1047template <
typename T>
1048static void IPushBackVectors(
const std::vector<T> &src, std::vector<T> *dst) {
1049 unsigned int i = src.size();
1050 unsigned int j = dst->size();
1054 }
else if (j == 0) {
1055 dst->assign(src.begin(), src.end());
1058 ICopy(src.data(), dst->data() + j,
static_cast<int>(i));
1063template <
typename T>
1065 unsigned int dsf_dim_x,
unsigned int dsf_dim_y) {
1068 }
else if (dsf_dim_x == 0 && dsf_dim_y == 0) {
1080 unsigned int nr_voxel_x_src = src.
NrVoxelX();
1081 unsigned int nr_voxel_y_src = src.
NrVoxelY();
1082 unsigned int nr_voxel_z_src = src.
NrVoxelZ();
1084 assert(nr_voxel_z_src == 1);
1087 unsigned int sf_x = (
unsigned int)
IPow((
unsigned int)2, dsf_dim_x);
1088 unsigned int sf_y = (
unsigned int)
IPow((
unsigned int)2, dsf_dim_y);
1091 unsigned int nr_voxel_x_dst = nr_voxel_x_src / sf_x;
1092 unsigned int nr_voxel_y_dst = nr_voxel_y_src / sf_y;
1093 unsigned int nr_voxel_z_dst = nr_voxel_z_src;
1095 if (!nr_voxel_x_dst || !nr_voxel_y_dst || !nr_voxel_z_dst) {
1099 unsigned int nr_res_voxel_x_dst = (nr_voxel_x_src % sf_x);
1100 unsigned int nr_res_voxel_y_dst = (nr_voxel_y_src % sf_y);
1102 T voxel_width_x_src = 0;
1103 T voxel_width_y_src = 0;
1104 T voxel_width_z_src = 0;
1105 T dim_min_x_src = 0;
1106 T dim_max_x_src = 0;
1107 T dim_min_y_src = 0;
1108 T dim_max_y_src = 0;
1109 T dim_min_z_src = 0;
1110 T dim_max_z_src = 0;
1114 &voxel_width_z_src);
1117 &dim_max_y_src, &dim_min_z_src, &dim_max_z_src);
1120 T voxel_width_x_dst = (sf_x * voxel_width_x_src);
1121 T voxel_width_y_dst = (sf_y * voxel_width_y_src);
1122 T voxel_width_z_dst = voxel_width_z_src;
1125 T dim_x_dst[2], dim_y_dst[2], dim_z_dst[2];
1127 dim_x_dst[0] = dim_min_x_src;
1128 dim_y_dst[0] = dim_min_y_src;
1129 dim_z_dst[0] = dim_min_z_src;
1131 dim_x_dst[1] = (0 == nr_res_voxel_x_dst)
1133 : (voxel_width_x_dst * nr_voxel_x_dst + dim_x_dst[0]);
1134 dim_y_dst[1] = (0 == nr_res_voxel_y_dst)
1136 : (voxel_width_y_dst * nr_voxel_y_dst + dim_y_dst[0]);
1137 dim_z_dst[1] = dim_max_z_src;
1144 dst->
SetGridDimension(dim_x_dst[0], dim_x_dst[1], dim_y_dst[0], dim_y_dst[1],
1145 dim_z_dst[0], dim_z_dst[1]);
1146 dst->
SetNrVoxel(nr_voxel_x_dst, nr_voxel_y_dst, nr_voxel_z_dst);
1149 unsigned int i, j, r, c, rs, cs, rspi, n = 0;
1151 T vy, vz = dim_z_dst[0];
1152 std::vector<T> vxs(nr_voxel_x_dst);
1154 vxs[0] = dim_x_dst[0];
1156 for (i = 1; i < nr_voxel_x_dst; i++) {
1157 vxs[i] = vxs[i - 1] + voxel_width_x_dst;
1160 std::vector<Voxel<T>> voxels(nr_voxel_y_dst * nr_voxel_x_dst);
1162 for (r = 0; r < nr_voxel_y_dst; r++) {
1164 vy = dim_y_dst[0] + (r * voxel_width_y_dst);
1166 for (c = 0; c < nr_voxel_x_dst; c++) {
1168 voxels[n].init(vxs[c], vy, vz, voxel_width_x_dst, voxel_width_y_dst,
1169 voxel_width_z_dst,
static_cast<int>(c),
1170 static_cast<int>(r),
static_cast<int>(0));
1172 for (i = 0; i < sf_y; ++i) {
1174 for (j = 0; j < sf_x; ++j) {
1175 IPushBackVectors(src(rspi, cs + j).indices_, &voxels[n].indices_);
1188template <
typename DATA_TYPE>
1193 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
1194 unsigned int dsf_y, DATA_TYPE spatial_bound_x_min,
1195 DATA_TYPE spatial_bound_x_max,
1196 DATA_TYPE spatial_bound_y_min,
1197 DATA_TYPE spatial_bound_y_max,
1198 DATA_TYPE spatial_bound_z_min,
1199 DATA_TYPE spatial_bound_z_max) {
1200 Alloc(nr_scale, nr_voxel_x_base, nr_voxel_y_base, dsf_x, dsf_y,
1201 spatial_bound_x_min, spatial_bound_x_max, spatial_bound_y_min,
1202 spatial_bound_y_max, spatial_bound_z_min, spatial_bound_z_max);
1209 bool Alloc(
unsigned int nr_scale,
unsigned int nr_voxel_x_base,
1210 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
1211 unsigned int dsf_y, DATA_TYPE spatial_bound_x_min,
1212 DATA_TYPE spatial_bound_x_max, DATA_TYPE spatial_bound_y_min,
1213 DATA_TYPE spatial_bound_y_max, DATA_TYPE spatial_bound_z_min,
1214 DATA_TYPE spatial_bound_z_max);
1217 bool Set(
const DATA_TYPE *pc,
unsigned int nr_points,
1218 unsigned int nr_point_element);
1222 bool SetS(
const float *pc,
unsigned int nr_points,
1223 unsigned int nr_point_element);
1225 bool Set(
const DATA_TYPE *pc,
unsigned int nr_scale,
unsigned int nr_points,
1226 unsigned int nr_point_element,
unsigned int nr_voxel_x_base,
1227 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
unsigned int dsf_y,
1228 DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max,
1229 DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max,
1230 DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max);
1232 unsigned int NrScale()
const {
return (
unsigned int)vgrids_.size(); }
1235 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel() : 0;
1239 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel_x() : 0;
1243 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel_y() : 0;
1247 return (i < vgrids_.size()) ? vgrids_[i].nr_voxel_z() : 0;
1251 return (scale < vgrids_.size()) ? vgrids_[scale].nr_points() : 0;
1265 assert(i >= 0 && i < vgrids_.size());
1270 assert(i >= 0 && i < vgrids_.size());
1275 assert(i >= 0 && i <
static_cast<int>(vgrids_.size()));
1280 assert(i >= 0 && i <
static_cast<int>(vgrids_.size()));
1289 unsigned int nr_points_, nr_point_element_;
1290 unsigned int dsf_x_, dsf_y_, dsf_z_;
1291 const DATA_TYPE *pc_;
1292 std::vector<VoxelGridXY<DATA_TYPE>> vgrids_;
1295template <
typename DATA_TYPE>
1299 nr_point_element_(0),
1304template <
typename DATA_TYPE>
1306 unsigned int nr_scale,
unsigned int nr_voxel_x_base,
1307 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
unsigned int dsf_y,
1308 DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max,
1309 DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max,
1310 DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max) {
1311 if (!nr_scale || !nr_voxel_x_base || !nr_voxel_y_base) {
1316 unsigned int nr_voxel_x = nr_voxel_x_base;
1317 unsigned int nr_voxel_y = nr_voxel_y_base;
1318 unsigned int sf_x = (
unsigned int)
IPow((
unsigned int)2, dsf_x);
1319 unsigned int sf_y = (
unsigned int)
IPow((
unsigned int)2, dsf_y);
1326 vgrids_.resize(nr_scale);
1328 for (scale = 0; scale < nr_scale; ++scale) {
1329 if (!vgrids_[scale].alloc(nr_voxel_x, nr_voxel_y, spatial_bound_x_min,
1330 spatial_bound_x_max, spatial_bound_y_min,
1331 spatial_bound_y_max, spatial_bound_z_min,
1332 spatial_bound_z_max)) {
1343 if (scale != nr_scale) {
1344 vgrids_.resize(scale);
1351template <
typename DATA_TYPE>
1353 unsigned int nr_points,
1354 unsigned int nr_point_element) {
1355 if (!pc || !nr_points || !nr_point_element || vgrids_.empty()) {
1359 unsigned int scale, nr_scale = (
unsigned int)vgrids_.size();
1362 nr_points_ = nr_points;
1363 nr_point_element_ = nr_point_element;
1365 for (scale = 0; scale < nr_scale; ++scale) {
1366 if (!vgrids_[scale].set(pc, nr_points, nr_point_element)) {
1372 if (scale < nr_scale) {
1373 vgrids_.resize(scale);
1376 return (vgrids_.size() == nr_scale);
1379template <
typename DATA_TYPE>
1381 unsigned int nr_points,
1382 unsigned int nr_point_element) {
1383 if (!pc || !nr_points || !nr_point_element || vgrids_.empty()) {
1387 unsigned int scale, nr_scale = (
unsigned int)vgrids_.size();
1390 nr_points_ = nr_points;
1391 nr_point_element_ = nr_point_element;
1393 for (scale = 0; scale < nr_scale; ++scale) {
1394 if (!vgrids_[scale].set_s(pc, nr_points, nr_point_element)) {
1400 if (scale < nr_scale) {
1401 vgrids_.resize(scale);
1404 return (vgrids_.size() == nr_scale);
1407template <
typename DATA_TYPE>
1409 const DATA_TYPE *pc,
unsigned int nr_scale,
unsigned int nr_points,
1410 unsigned int nr_point_element,
unsigned int nr_voxel_x_base,
1411 unsigned int nr_voxel_y_base,
unsigned int dsf_x,
unsigned int dsf_y,
1412 DATA_TYPE spatial_bound_x_min, DATA_TYPE spatial_bound_x_max,
1413 DATA_TYPE spatial_bound_y_min, DATA_TYPE spatial_bound_y_max,
1414 DATA_TYPE spatial_bound_z_min, DATA_TYPE spatial_bound_z_max) {
1415 if (!pc || !nr_scale || !nr_points || !nr_point_element || !nr_voxel_x_base ||
1422 nr_points_ = nr_points;
1423 nr_point_element_ = nr_point_element;
1430 vgrids_.resize(nr_scale);
1433 if (!vgrids_[0].set(pc_, nr_points, nr_point_element, nr_voxel_x_base,
1434 nr_voxel_y_base, spatial_bound_x_min, spatial_bound_x_max,
1435 spatial_bound_y_min, spatial_bound_y_max,
1436 spatial_bound_z_min, spatial_bound_z_max)) {
1441 for (s = 1; s < nr_scale; ++s) {
1448 for (i = 0; i < (nr_scale - s); ++i) {
1453 return (vgrids_.size() == nr_scale);
1456template <
typename DATA_TYPE>
1460 nr_points_ = nr_point_element_ = dsf_x_ = dsf_y_ = dsf_z_ = 0;
1463template <
typename DATA_TYPE>
1466 if (vgrids_.empty()) {
1469 for (i = 0; i < vgrids_.size(); ++i) {
1470 if (!vgrids_[i].initialized()) {
1474 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)
bool Set(const T *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)
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)
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)
unsigned int NrVoxelY() const
void SetNrPoints(unsigned int nr_points)
bool SetS(const float *data, unsigned int nr_points, unsigned int nr_point_element)
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, unsigned int nr_points, unsigned int nr_point_element)
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()
void SetNrVoxel(unsigned int nr_voxel_x, unsigned int nr_voxel_y, unsigned int nr_voxel_z)
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)