65 using SurfelT = std::conditional_t<Cached, SurfelCached, Surfel>;
84 [[nodiscard]]
Surfel surfel(Index node)
const
86 auto pos = indices_[node.pos][node.offset];
87 return NULL_POS != pos ? surfel_[pos] :
Surfel{};
90 [[nodiscard]]
Surfel surfel(Node node)
const {
return surfel(derived().
index(node)); }
92 [[nodiscard]]
Surfel surfel(Code code)
const {
return surfel(derived().
index(code)); }
94 [[nodiscard]]
Surfel surfel(Key key)
const {
return surfel(derived().
index(key)); }
96 [[nodiscard]]
Surfel surfel(Point coord, depth_t depth = 0)
const
98 return surfel(derived().
index(coord, depth));
105 [[nodiscard]]
bool surfelEmpty(Index node)
const
107 auto pos = indices_[node.pos][node.offset];
108 return NULL_POS == pos || surfel_[pos].empty();
111 [[nodiscard]]
bool surfelEmpty(Node node)
const
113 return surfelEmpty(derived().
index(node));
116 [[nodiscard]]
bool surfelEmpty(Code code)
const
118 return surfelEmpty(derived().
index(code));
121 [[nodiscard]]
bool surfelEmpty(Key key)
const
123 return surfelEmpty(derived().
index(key));
126 [[nodiscard]]
bool surfelEmpty(Point coord, depth_t depth = 0)
const
128 return surfelEmpty(derived().
index(coord, depth));
135 [[nodiscard]]
decltype(std::declval<Surfel>().mean()) surfelMean(Index node)
const
137 return surfel_[indices_[node.pos][node.offset]].mean();
140 [[nodiscard]]
decltype(std::declval<Surfel>().mean()) surfelMean(Node node)
const
142 return surfelMean(derived().
index(node));
145 [[nodiscard]]
decltype(std::declval<Surfel>().mean()) surfelMean(Code code)
const
147 return surfelMean(derived().
index(code));
150 [[nodiscard]]
decltype(std::declval<Surfel>().mean()) surfelMean(Key key)
const
152 return surfelMean(derived().
index(key));
155 [[nodiscard]]
decltype(std::declval<Surfel>().mean()) surfelMean(
156 Point coord, depth_t depth = 0)
const
158 return surfelMean(derived().
index(coord, depth));
165 [[nodiscard]]
decltype(std::declval<Surfel>().normal()) surfelNormal(Index node)
const
167 return surfel_[indices_[node.pos][node.offset]].normal();
170 [[nodiscard]]
decltype(std::declval<Surfel>().normal()) surfelNormal(Node node)
const
172 return surfelNormal(derived().
index(node));
175 [[nodiscard]]
decltype(std::declval<Surfel>().normal()) surfelNormal(Code code)
const
177 return surfelNormal(derived().
index(code));
180 [[nodiscard]]
decltype(std::declval<Surfel>().normal()) surfelNormal(Key key)
const
182 return surfelNormal(derived().
index(key));
185 [[nodiscard]]
decltype(std::declval<Surfel>().normal()) surfelNormal(
186 Point coord, depth_t depth = 0)
const
188 return surfelNormal(derived().
index(coord, depth));
195 [[nodiscard]]
decltype(std::declval<Surfel>().planarity()) surfelPlanarity(
198 return surfel_[indices_[node.pos][node.offset]].planarity();
201 [[nodiscard]]
decltype(std::declval<Surfel>().planarity()) surfelPlanarity(
204 return surfelPlanarity(derived().
index(node));
207 [[nodiscard]]
decltype(std::declval<Surfel>().planarity()) surfelPlanarity(
210 return surfelPlanarity(derived().
index(code));
213 [[nodiscard]]
decltype(std::declval<Surfel>().planarity()) surfelPlanarity(
216 return surfelPlanarity(derived().
index(key));
219 [[nodiscard]]
decltype(std::declval<Surfel>().planarity()) surfelPlanarity(
220 Point coord, depth_t depth = 0)
const
222 return surfelPlanarity(derived().
index(coord, depth));
229 [[nodiscard]]
decltype(std::declval<Surfel>().covariance()) surfelCovariance(
232 return surfel_[indices_[node.pos][node.offset]].covariance();
235 [[nodiscard]]
decltype(std::declval<Surfel>().covariance()) surfelCovariance(
238 return surfelCovariance(derived().
index(node));
241 [[nodiscard]]
decltype(std::declval<Surfel>().covariance()) surfelCovariance(
244 return surfelCovariance(derived().
index(code));
247 [[nodiscard]]
decltype(std::declval<Surfel>().covariance()) surfelCovariance(
250 return surfelCovariance(derived().
index(key));
253 [[nodiscard]]
decltype(std::declval<Surfel>().covariance()) surfelCovariance(
254 Point coord, depth_t depth = 0)
const
256 return surfelCovariance(derived().
index(coord, depth));
263 [[nodiscard]]
decltype(std::declval<Surfel>().eigenValues()) surfelEigenValues(
266 return surfel_[indices_[node.pos][node.offset]].eigenValues();
269 [[nodiscard]]
decltype(std::declval<Surfel>().eigenValues()) surfelEigenValues(
272 return surfelEigenValues(derived().
index(node));
275 [[nodiscard]]
decltype(std::declval<Surfel>().eigenValues()) surfelEigenValues(
278 return surfelEigenValues(derived().
index(code));
281 [[nodiscard]]
decltype(std::declval<Surfel>().eigenValues()) surfelEigenValues(
284 return surfelEigenValues(derived().
index(key));
287 [[nodiscard]]
decltype(std::declval<Surfel>().eigenValues()) surfelEigenValues(
288 Point coord, depth_t depth = 0)
const
290 return surfelEigenValues(derived().
index(coord, depth));
297 [[nodiscard]]
decltype(std::declval<Surfel>().eigenVectors()) surfelEigenVectors(
300 return surfel_[indices_[node.pos][node.offset]].eigenVectors();
303 [[nodiscard]]
decltype(std::declval<Surfel>().eigenVectors()) surfelEigenVectors(
306 return surfelEigenVectors(derived().
index(node));
309 [[nodiscard]]
decltype(std::declval<Surfel>().eigenVectors()) surfelEigenVectors(
312 return surfelEigenVectors(derived().
index(code));
315 [[nodiscard]]
decltype(std::declval<Surfel>().eigenVectors()) surfelEigenVectors(
318 return surfelEigenVectors(derived().
index(key));
321 [[nodiscard]]
decltype(std::declval<Surfel>().eigenVectors()) surfelEigenVectors(
322 Point coord, depth_t depth = 0)
const
324 return surfelEigenVectors(derived().
index(coord, depth));
331 [[nodiscard]]
decltype(std::declval<Surfel>().numPoints()) surfelNumPoints(
334 return surfel_[indices_[node.pos][node.offset]].numPoints();
337 [[nodiscard]]
decltype(std::declval<Surfel>().numPoints()) surfelNumPoints(
340 return surfelNumPoints(derived().
index(node));
343 [[nodiscard]]
decltype(std::declval<Surfel>().numPoints()) surfelNumPoints(
346 return surfelNumPoints(derived().
index(code));
349 [[nodiscard]]
decltype(std::declval<Surfel>().numPoints()) surfelNumPoints(
352 return surfelNumPoints(derived().
index(key));
355 [[nodiscard]]
decltype(std::declval<Surfel>().numPoints()) surfelNumPoints(
356 Point coord, depth_t depth = 0)
const
358 return surfelNumPoints(derived().
index(coord, depth));
365 [[nodiscard]]
decltype(std::declval<Surfel>().sum()) surfelSum(Index node)
const
367 return surfel_[indices_[node.pos][node.offset]].sum();
370 [[nodiscard]]
decltype(std::declval<Surfel>().sum()) surfelSum(Node node)
const
372 return surfelSum(derived().
index(node));
375 [[nodiscard]]
decltype(std::declval<Surfel>().sum()) surfelSum(Code code)
const
377 return surfelSum(derived().
index(code));
380 [[nodiscard]]
decltype(std::declval<Surfel>().sum()) surfelSum(Key key)
const
382 return surfelSum(derived().
index(key));
385 [[nodiscard]]
decltype(std::declval<Surfel>().sum()) surfelSum(Point coord,
386 depth_t depth = 0)
const
388 return surfelSum(derived().
index(coord, depth));
395 [[nodiscard]]
decltype(std::declval<Surfel>().sumSquares()) surfelSumSquares(
398 return surfel_[indices_[node.pos][node.offset]].sumSquares();
401 [[nodiscard]]
decltype(std::declval<Surfel>().sumSquares()) surfelSumSquares(
404 return surfelSumSquares(derived().
index(node));
407 [[nodiscard]]
decltype(std::declval<Surfel>().sumSquares()) surfelSumSquares(
410 return surfelSumSquares(derived().
index(code));
413 [[nodiscard]]
decltype(std::declval<Surfel>().sumSquares()) surfelSumSquares(
416 return surfelSumSquares(derived().
index(key));
419 [[nodiscard]]
decltype(std::declval<Surfel>().sumSquares()) surfelSumSquares(
420 Point coord, depth_t depth = 0)
const
422 return surfelSumSquares(derived().
index(coord, depth));
429 void surfelSet(Index node,
Surfel const& surfel)
432 node, [
this, &surfel](Index node) { createOrAssignSurfel(node, surfel); },
433 [
this, &surfel](pos_t block) {
434 for (offset_t i{}; N != i; ++i) {
435 createOrAssignSurfel(Index{block, i}, surfel);
440 Node surfelSet(Node node,
Surfel const& surfel,
bool propagate =
true)
442 return derived().apply(
443 node, [
this, &surfel](Index node) { createOrAssignSurfel(node, surfel); },
444 [
this, &surfel](pos_t block) {
445 for (offset_t i{}; N != i; ++i) {
446 createOrAssignSurfel(Index{block, i}, surfel);
452 Node surfelSet(Code code,
Surfel const& surfel,
bool propagate =
true)
454 return derived().apply(
455 code, [
this, &surfel](Index node) { createOrAssignSurfel(node, surfel); },
456 [
this, &surfel](pos_t block) {
457 for (offset_t i{}; N != i; ++i) {
458 createOrAssignSurfel(Index{block, i}, surfel);
464 Node surfelSet(Key key,
Surfel const& surfel,
bool propagate =
true)
466 return surfelSet(derived().toCode(key), surfel, propagate);
469 Node surfelSet(Point coord,
Surfel const& surfel,
bool propagate =
true,
472 return surfelSet(derived().toCode(coord, depth), surfel, propagate);
479 void surfelAdd(Index node,
Surfel const& surfel)
483 [
this, &surfel](Index node) {
484 auto pos = createSurfel(node);
485 surfel_[pos] += surfel;
487 [
this, &surfel](pos_t block) {
488 for (offset_t i{}; N != i; ++i) {
489 auto pos = createSurfel(Index(block, i));
490 surfel_[pos] += surfel;
495 Node surfelAdd(Node node,
Surfel const& surfel,
bool propagate =
true)
497 return derived().apply(
499 [
this, &surfel](Index node) {
500 auto pos = createSurfel(node);
501 surfel_[pos] += surfel;
503 [
this, &surfel](pos_t block) {
504 for (offset_t i{}; N != i; ++i) {
505 auto pos = createSurfel(Index(block, i));
506 surfel_[pos] += surfel;
512 Node surfelAdd(Code code,
Surfel const& surfel,
bool propagate =
true)
514 return derived().apply(
516 [
this, &surfel](Index node) {
517 auto pos = createSurfel(node);
518 surfel_[pos] += surfel;
520 [
this, &surfel](pos_t block) {
521 for (offset_t i{}; N != i; ++i) {
522 auto pos = createSurfel(Index(block, i));
523 surfel_[pos] += surfel;
529 Node surfelAdd(Key key,
Surfel const& surfel,
bool propagate =
true)
531 return surfelAdd(derived().toCode(key), surfel, propagate);
534 Node surfelAdd(Point coord,
Surfel const& surfel,
bool propagate =
true,
537 return surfelAdd(derived().toCode(coord, depth), surfel, propagate);
540 void surfelAdd(Point point,
bool propagate =
true, depth_t depth = 0)
542 surfelAdd(point, point, propagate, depth);
545 template <
class InputIt>
546 void surfelAdd(InputIt first, InputIt last,
bool propagate =
true, depth_t depth = 0)
548 struct CodeOrIndexPoint
551 constexpr CodeOrIndexPoint() =
default;
552 CodeOrIndexPoint(Code code, Point point) : CodeOrIndexPoint(code), Point(point) {}
555 std::vector<CodeOrIndexPoint> data;
556 data.reserve(std::distance(first, last));
558 for (; first != last; ++first) {
559 data.emplace_back(derived().toCode(*first, depth), *first);
562 std::sort(std::begin(data), std::end(data),
563 [](
auto a,
auto b) {
return a.code >
b.code; });
565 derived().createIndicesFromCodes(data);
567 for (
auto it = std::cbegin(data), last = std::cend(data); it != last;) {
568 auto it_end = std::find_if(std::next(it), last,
569 [idx = it->index](
auto v) { return idx != v.index; });
571 surfelAdd(it->index, it, it_end);
575 derived().propagateModified();
579 template <
class Po
intRange>
580 void surfelAdd(PointRange
const& points,
bool propagate =
true, depth_t depth = 0)
582 surfelAdd(std::cbegin(points), std::cend(points), propagate, depth);
585 void surfelAdd(std::initializer_list<Point> points,
bool propagate =
true,
588 surfelAdd(std::cbegin(points), std::cend(points), propagate, depth);
591 void surfelAdd(Index node, Point point)
595 [
this, point](Index node) {
596 auto pos = createSurfel(node);
597 surfel_[pos] += point;
599 [
this, point](pos_t block) {
600 for (offset_t i{}; N != i; ++i) {
601 auto pos = createSurfel(Index{block, i});
602 surfel_[pos] += point;
607 template <
class InputIt>
608 void surfelAdd(Index node, InputIt first, InputIt last)
612 [
this, first, last](Index node) {
613 auto pos = createSurfel(node);
614 surfel_[pos].addPoint(first, last);
616 [
this, first, last](pos_t block) {
617 for (offset_t i{}; N != i; ++i) {
618 auto pos = createSurfel(Index{block, i});
619 surfel_[pos].addPoint(first, last);
624 template <
class Po
intRange>
625 void surfelAdd(Index node, PointRange
const& points)
627 surfelAdd(node, std::cbegin(points), std::cend(points));
630 void surfelAdd(Index node, std::initializer_list<Point> points)
632 surfelAdd(node, std::cbegin(points), std::cend(points));
635 Node surfelAdd(Node node, Point point,
bool propagate =
true)
637 return derived().apply(
639 [
this, point](Index node) {
640 auto pos = createSurfel(node);
641 surfel_[pos] += point;
643 [
this, point](pos_t block) {
644 for (offset_t i{}; N != i; ++i) {
645 auto pos = createSurfel(Index{block, i});
646 surfel_[pos] += point;
652 template <
class InputIt>
653 Node surfelAdd(Node node, InputIt first, InputIt last,
bool propagate =
true)
655 return derived().apply(
657 [
this, first, last](Index node) {
658 auto pos = createSurfel(node);
659 surfel_[pos].addPoint(first, last);
661 [
this, first, last](pos_t block) {
662 for (offset_t i{}; N != i; ++i) {
663 auto pos = createSurfel(Index{block, i});
664 surfel_[pos].addPoint(first, last);
670 template <
class Po
intRange>
671 Node surfelAdd(Node node, PointRange
const& points,
bool propagate =
true)
673 return surfelAdd(node, std::cbegin(points), std::cend(points), propagate);
676 Node surfelAdd(Node node, std::initializer_list<Point> points,
bool propagate =
true)
678 return surfelAdd(node, std::cbegin(points), std::cend(points), propagate);
681 Node surfelAdd(Code code, Point point,
bool propagate =
true)
683 return derived().apply(
685 [
this, point](Index node) {
686 auto pos = createSurfel(node);
687 surfel_[pos] += point;
689 [
this, point](pos_t block) {
690 for (offset_t i{}; N != i; ++i) {
691 auto pos = createSurfel(Index{block, i});
692 surfel_[pos] += point;
698 template <
class InputIt>
699 Node surfelAdd(Code code, InputIt first, InputIt last,
bool propagate =
true)
701 return derived().apply(
703 [
this, first, last](Index node) {
704 auto pos = createSurfel(node);
705 surfel_[pos].addPoint(first, last);
707 [
this, first, last](pos_t block) {
708 for (offset_t i{}; N != i; ++i) {
709 auto pos = createSurfel(Index{block, i});
710 surfel_[pos].addPoint(first, last);
716 template <
class Po
intRange>
717 Node surfelAdd(Code code, PointRange
const& points,
bool propagate =
true)
719 return surfelAdd(code, std::cbegin(points), std::cend(points), propagate);
722 Node surfelAdd(Code code, std::initializer_list<Point> points,
bool propagate =
true)
724 return surfelAdd(code, std::cbegin(points), std::cend(points), propagate);
727 Node surfelAdd(Key key, Point point,
bool propagate =
true)
729 return surfelAdd(derived().toCode(key), point, propagate);
732 template <
class InputIt>
733 Node surfelAdd(Key key, InputIt first, InputIt last,
bool propagate =
true)
735 return surfelAdd(derived().toCode(key), first, last, propagate);
738 template <
class Po
intRange>
739 Node surfelAdd(Key key, PointRange
const& points,
bool propagate =
true)
741 return surfelAdd(key, std::cbegin(points), std::cend(points), propagate);
744 Node surfelAdd(Key key, std::initializer_list<Point> points,
bool propagate =
true)
746 return surfelAdd(key, std::cbegin(points), std::cend(points), propagate);
749 Node surfelAdd(Point coord, Point point,
bool propagate =
true, depth_t depth = 0)
751 return surfelAdd(derived().toCode(coord, depth), point, propagate);
754 template <
class InputIt>
755 Node surfelAdd(Point coord, InputIt first, InputIt last,
bool propagate =
true,
758 return surfelAdd(derived().toCode(coord, depth), first, last, propagate);
761 template <
class Po
intRange>
762 Node surfelAdd(Point coord, PointRange
const& points,
bool propagate =
true,
765 return surfelAdd(coord, std::cbegin(points), std::cend(points), propagate, depth);
768 Node surfelAdd(Point coord, std::initializer_list<Point> points,
bool propagate =
true,
771 return surfelAdd(coord, std::cbegin(points), std::cend(points), propagate, depth);
778 void surfelRemove(Index node,
Surfel const& surfel)
782 [
this, &surfel](Index node) {
783 auto pos = indices_[node.pos][node.offset];
784 if (NULL_POS != pos) {
785 surfel_[pos] -= surfel;
786 if (surfel_[pos].empty()) {
791 [
this, &surfel](pos_t block) {
792 for (offset_t i{}; N != i; ++i) {
793 auto pos = indices_[block][i];
794 if (NULL_POS != pos) {
795 surfel_[pos] -= surfel;
796 if (surfel_[pos].empty()) {
797 deleteSurfel(Index{block, i});
804 Node surfelRemove(Node node,
Surfel const& surfel,
bool propagate =
true)
806 return derived().apply(
808 [
this, &surfel](Index node) {
809 auto pos = indices_[node.pos][node.offset];
810 if (NULL_POS != pos) {
811 surfel_[pos] -= surfel;
812 if (surfel_[pos].empty()) {
817 [
this, &surfel](pos_t block) {
818 for (offset_t i{}; N != i; ++i) {
819 auto pos = indices_[block][i];
820 if (NULL_POS != pos) {
821 surfel_[pos] -= surfel;
822 if (surfel_[pos].empty()) {
823 deleteSurfel(Index{block, i});
831 Node surfelRemove(Code code,
Surfel const& surfel,
bool propagate =
true)
833 return derived().apply(
835 [
this, &surfel](Index node) {
836 auto pos = indices_[node.pos][node.offset];
837 if (NULL_POS != pos) {
838 surfel_[pos] -= surfel;
839 if (surfel_[pos].empty()) {
844 [
this, &surfel](pos_t block) {
845 for (offset_t i{}; N != i; ++i) {
846 auto pos = indices_[block][i];
847 if (NULL_POS != pos) {
848 surfel_[pos] -= surfel;
849 if (surfel_[pos].empty()) {
850 deleteSurfel(Index{block, i});
858 Node surfelRemove(Key key,
Surfel const& surfel,
bool propagate =
true)
860 return surfelRemove(derived().toCode(key), surfel, propagate);
863 Node surfelRemove(Point coord,
Surfel const& surfel,
bool propagate =
true,
866 return surfelRemove(derived().toCode(coord, depth), surfel, propagate);
869 void surfelRemove(Point point,
bool propagate =
true, depth_t depth = 0)
871 surfelRemove(point, point, propagate, depth);
874 template <
class InputIt>
875 void surfelRemove(InputIt first, InputIt last,
bool propagate =
true, depth_t depth = 0)
877 struct CodeOrIndexPoint
880 constexpr CodeOrIndexPoint() =
default;
881 CodeOrIndexPoint(Code code, Point point) : CodeOrIndexPoint(code), Point(point) {}
884 std::vector<CodeOrIndexPoint> data;
885 data.reserve(std::distance(first, last));
887 for (; first != last; ++first) {
888 data.emplace_back(derived().toCode(*first, depth), *first);
891 std::sort(std::begin(data), std::end(data),
892 [](
auto a,
auto b) {
return a.code >
b.code; });
894 derived().createIndicesFromCodes(data);
896 for (
auto it = std::cbegin(data), last = std::cend(data); it != last;) {
897 auto it_end = std::find_if(std::next(it), last,
898 [idx = it->index](
auto v) { return idx != v.index; });
900 surfelRemove(it->index, it, it_end);
904 derived().propagateModified();
908 template <
class Po
intRange>
909 void surfelRemove(PointRange
const& points,
bool propagate =
true, depth_t depth = 0)
911 surfelRemove(std::cbegin(points), std::cend(points), propagate, depth);
914 void surfelRemove(std::initializer_list<Point> points,
bool propagate =
true,
917 surfelRemove(std::cbegin(points), std::cend(points), propagate, depth);
920 void surfelRemove(Index node, Point point)
924 [
this, point](Index node) {
925 auto pos = indices_[node.pos][node.offset];
926 if (NULL_POS != pos) {
927 surfel_[pos] -= point;
928 if (surfel_[pos].empty()) {
933 [
this, point](pos_t block) {
934 for (offset_t i{}; N != i; ++i) {
935 auto pos = indices_[block][i];
936 if (NULL_POS != pos) {
937 surfel_[pos] -= point;
938 if (surfel_[pos].empty()) {
939 deleteSurfel(Index{block, i});
946 template <
class InputIt>
947 void surfelRemove(Index node, InputIt first, InputIt last)
951 [
this, first, last](Index node) {
952 auto pos = indices_[node.pos][node.offset];
953 if (NULL_POS != pos) {
954 surfel_[pos].removePoint(first, last);
955 if (surfel_[pos].empty()) {
960 [
this, first, last](pos_t block) {
961 for (offset_t i{}; N != i; ++i) {
962 auto pos = indices_[block][i];
963 if (NULL_POS != pos) {
964 surfel_[pos].removePoint(first, last);
965 if (surfel_[pos].empty()) {
966 deleteSurfel(Index{block, i});
973 template <
class Po
intRange>
974 void surfelRemove(Index node, PointRange
const& points)
976 surfelRemove(node, std::cbegin(points), std::cend(points));
979 void surfelRemove(Index node, std::initializer_list<Point> points)
981 surfelRemove(node, std::cbegin(points), std::cend(points));
984 Node surfelRemove(Node node, Point point,
bool propagate =
true)
986 return derived().apply(
988 [
this, point](Index node) {
989 auto pos = indices_[node.pos][node.offset];
990 if (NULL_POS != pos) {
991 surfel_[pos] -= point;
992 if (surfel_[pos].empty()) {
997 [
this, point](pos_t block) {
998 for (offset_t i{}; N != i; ++i) {
999 auto pos = indices_[block][i];
1000 if (NULL_POS != pos) {
1001 surfel_[pos] -= point;
1002 if (surfel_[pos].empty()) {
1003 deleteSurfel(Index{block, i});
1011 template <
class InputIt>
1012 Node surfelRemove(Node node, InputIt first, InputIt last,
bool propagate =
true)
1014 return derived().apply(
1016 [
this, first, last](Index node) {
1017 auto pos = indices_[node.pos][node.offset];
1018 if (NULL_POS != pos) {
1019 surfel_[pos].removePoint(first, last);
1020 if (surfel_[pos].empty()) {
1025 [
this, first, last](pos_t block) {
1026 for (offset_t i{}; N != i; ++i) {
1027 auto pos = indices_[block][i];
1028 if (NULL_POS != pos) {
1029 surfel_[pos].removePoint(first, last);
1030 if (surfel_[pos].empty()) {
1031 deleteSurfel(Index{block, i});
1039 template <
class Po
intRange>
1040 Node surfelRemove(Node node, PointRange
const& points,
bool propagate =
true)
1042 return surfelRemove(node, std::cbegin(points), std::cend(points), propagate);
1045 Node surfelRemove(Node node, std::initializer_list<Point> points,
bool propagate =
true)
1047 return surfelRemove(node, std::cbegin(points), std::cend(points), propagate);
1050 Node surfelRemove(Code code, Point point,
bool propagate =
true)
1052 return derived().apply(
1054 [
this, point](Index node) {
1055 auto pos = indices_[node.pos][node.offset];
1056 if (NULL_POS != pos) {
1057 surfel_[pos] -= point;
1058 if (surfel_[pos].empty()) {
1063 [
this, point](pos_t block) {
1064 for (offset_t i{}; N != i; ++i) {
1065 auto pos = indices_[block][i];
1066 if (NULL_POS != pos) {
1067 surfel_[pos] -= point;
1068 if (surfel_[pos].empty()) {
1069 deleteSurfel(Index{block, i});
1077 template <
class InputIt>
1078 Node surfelRemove(Code code, InputIt first, InputIt last,
bool propagate =
true)
1080 return derived().apply(
1082 [
this, first, last](Index node) {
1083 auto pos = indices_[node.pos][node.offset];
1084 if (NULL_POS != pos) {
1085 surfel_[pos].removePoint(first, last);
1086 if (surfel_[pos].empty()) {
1091 [
this, first, last](pos_t block) {
1092 for (offset_t i{}; N != i; ++i) {
1093 auto pos = indices_[block][i];
1094 if (NULL_POS != pos) {
1095 surfel_[pos].removePoint(first, last);
1096 if (surfel_[pos].empty()) {
1097 deleteSurfel(Index{block, i});
1105 template <
class Po
intRange>
1106 Node surfelRemove(Code code, PointRange
const& points,
bool propagate =
true)
1108 return surfelRemove(code, std::cbegin(points), std::cend(points), propagate);
1111 Node surfelRemove(Code code, std::initializer_list<Point> points,
bool propagate =
true)
1113 return surfelRemove(code, std::cbegin(points), std::cend(points), propagate);
1116 Node surfelRemove(Key key, Point point,
bool propagate =
true)
1118 return surfelRemove(derived().toCode(key), point, propagate);
1121 template <
class InputIt>
1122 Node surfelRemove(Key key, InputIt first, InputIt last,
bool propagate =
true)
1124 return surfelRemove(derived().toCode(key), first, last, propagate);
1127 template <
class Po
intRange>
1128 Node surfelRemove(Key key, PointRange
const& points,
bool propagate =
true)
1130 return surfelRemove(key, std::cbegin(points), std::cend(points), propagate);
1133 Node surfelRemove(Key key, std::initializer_list<Point> points,
bool propagate =
true)
1135 return surfelRemove(key, std::cbegin(points), std::cend(points), propagate);
1138 Node surfelRemove(Point coord, Point point,
bool propagate =
true, depth_t depth = 0)
1140 return surfelRemove(derived().toCode(coord, depth), point, propagate);
1143 template <
class InputIt>
1144 Node surfelRemove(Point coord, InputIt first, InputIt last,
bool propagate =
true,
1147 return surfelRemove(derived().toCode(coord, depth), first, last, propagate);
1150 template <
class Po
intRange>
1151 Node surfelRemove(Point coord, PointRange
const& points,
bool propagate =
true,
1154 return surfelRemove(coord, std::cbegin(points), std::cend(points), propagate, depth);
1157 Node surfelRemove(Point coord, std::initializer_list<Point> points,
1158 bool propagate =
true, depth_t depth = 0)
1160 return surfelRemove(coord, std::cbegin(points), std::cend(points), propagate, depth);
1167 template <
class UnaryOp,
1168 std::enable_if_t<std::is_invocable_v<UnaryOp, Surfel>,
bool> =
true>
1169 void surfelUpdate(Index node, UnaryOp unary_op)
1173 [
this, unary_op](Index node) {
1174 auto pos = indices_[node.pos][node.offset];
1175 if (NULL_POS == pos) {
1176 if (
auto s = unary_op(
Surfel{}); !s.empty()) {
1177 createOrAssignSurfel(node, s);
1180 if (
auto s = unary_op(surfel_[pos]); !s.empty()) {
1187 [
this, unary_op](pos_t block) {
1188 for (offset_t i{}; N != i; ++i) {
1189 Index node(block, i);
1190 auto pos = indices_[node.pos][node.offset];
1191 if (NULL_POS == pos) {
1192 if (
auto s = unary_op(
Surfel{}); !s.empty()) {
1193 createOrAssignSurfel(node, s);
1196 if (
auto s = unary_op(surfel_[pos]); !s.empty()) {
1206 template <
class BinaryOp,
1207 std::enable_if_t<std::is_invocable_v<BinaryOp, Index, Surfel>,
bool> =
true>
1208 void surfelUpdate(Index node, BinaryOp binary_op)
1212 [
this, binary_op](Index node) {
1213 auto pos = indices_[node.pos][node.offset];
1214 if (NULL_POS == pos) {
1215 if (
auto s = binary_op(node,
Surfel{}); !s.empty()) {
1216 createOrAssignSurfel(node, s);
1219 if (
auto s = binary_op(node, surfel_[pos]); !s.empty()) {
1226 [
this, binary_op](pos_t block) {
1227 for (offset_t i{}; N != i; ++i) {
1228 Index node(block, i);
1229 auto pos = indices_[node.pos][node.offset];
1230 if (NULL_POS == pos) {
1231 if (
auto s = binary_op(node,
Surfel{}); !s.empty()) {
1232 createOrAssignSurfel(node, s);
1235 if (
auto s = binary_op(node, surfel_[pos]); !s.empty()) {
1245 template <
class UnaryOp,
1246 std::enable_if_t<std::is_invocable_v<UnaryOp, Surfel>,
bool> =
true>
1247 Node surfelUpdate(Node node, UnaryOp unary_op,
bool propagate =
true)
1249 return derived().apply(
1251 [
this, unary_op](Index node) {
1252 auto pos = indices_[node.pos][node.offset];
1253 if (NULL_POS == pos) {
1254 if (
auto s = unary_op(
Surfel{}); !s.empty()) {
1255 createOrAssignSurfel(node, s);
1258 if (
auto s = unary_op(surfel_[pos]); !s.empty()) {
1265 [
this, unary_op](pos_t block) {
1266 for (offset_t i{}; N != i; ++i) {
1267 Index node(block, i);
1268 auto pos = indices_[node.pos][node.offset];
1269 if (NULL_POS == pos) {
1270 if (
auto s = unary_op(
Surfel{}); !s.empty()) {
1271 createOrAssignSurfel(node, s);
1274 if (
auto s = unary_op(surfel_[pos]); !s.empty()) {
1285 template <
class BinaryOp,
1286 std::enable_if_t<std::is_invocable_v<BinaryOp, Index, Surfel>,
bool> =
true>
1287 Node surfelUpdate(Node node, BinaryOp binary_op,
bool propagate =
true)
1289 return derived().apply(
1291 [
this, binary_op](Index node) {
1292 auto pos = indices_[node.pos][node.offset];
1293 if (NULL_POS == pos) {
1294 if (
auto s = binary_op(node,
Surfel{}); !s.empty()) {
1295 createOrAssignSurfel(node, s);
1298 if (
auto s = binary_op(node, surfel_[pos]); !s.empty()) {
1305 [
this, binary_op](pos_t block) {
1306 for (offset_t i{}; N != i; ++i) {
1307 Index node(block, i);
1308 auto pos = indices_[node.pos][node.offset];
1309 if (NULL_POS == pos) {
1310 if (
auto s = binary_op(node,
Surfel{}); !s.empty()) {
1311 createOrAssignSurfel(node, s);
1314 if (
auto s = binary_op(node, surfel_[pos]); !s.empty()) {
1325 template <
class UnaryOp,
1326 std::enable_if_t<std::is_invocable_v<UnaryOp, Surfel>,
bool> =
true>
1327 Node surfelUpdate(Code code, UnaryOp unary_op,
bool propagate =
true)
1329 return derived().apply(
1331 [
this, unary_op](Index node) {
1332 auto pos = indices_[node.pos][node.offset];
1333 if (NULL_POS == pos) {
1334 if (
auto s = unary_op(
Surfel{}); !s.empty()) {
1335 createOrAssignSurfel(node, s);
1338 if (
auto s = unary_op(surfel_[pos]); !s.empty()) {
1345 [
this, unary_op](pos_t block) {
1346 for (offset_t i{}; N != i; ++i) {
1347 Index node(block, i);
1348 auto pos = indices_[node.pos][node.offset];
1349 if (NULL_POS == pos) {
1350 if (
auto s = unary_op(
Surfel{}); !s.empty()) {
1351 createOrAssignSurfel(node, s);
1354 if (
auto s = unary_op(surfel_[pos]); !s.empty()) {
1365 template <
class BinaryOp,
1366 std::enable_if_t<std::is_invocable_v<BinaryOp, Index, Surfel>,
bool> =
true>
1367 Node surfelUpdate(Code code, BinaryOp binary_op,
bool propagate =
true)
1369 return derived().apply(
1371 [
this, binary_op](Index node) {
1372 auto pos = indices_[node.pos][node.offset];
1373 if (NULL_POS == pos) {
1374 if (
auto s = binary_op(node,
Surfel{}); !s.empty()) {
1375 createOrAssignSurfel(node, s);
1378 if (
auto s = binary_op(node, surfel_[pos]); !s.empty()) {
1385 [
this, binary_op](pos_t block) {
1386 for (offset_t i{}; N != i; ++i) {
1387 Index node(block, i);
1388 auto pos = indices_[node.pos][node.offset];
1389 if (NULL_POS == pos) {
1390 if (
auto s = binary_op(node,
Surfel{}); !s.empty()) {
1391 createOrAssignSurfel(node, s);
1394 if (
auto s = binary_op(node, surfel_[pos]); !s.empty()) {
1405 template <
class UnaryOp,
1406 std::enable_if_t<std::is_invocable_v<UnaryOp, Surfel>,
bool> =
true>
1407 Node surfelUpdate(Key key, UnaryOp unary_op,
bool propagate =
true)
1409 return surfelUpdate(derived().toCode(key), unary_op, propagate);
1412 template <
class BinaryOp,
1413 std::enable_if_t<std::is_invocable_v<BinaryOp, Index, Surfel>,
bool> =
true>
1414 Node surfelUpdate(Key key, BinaryOp binary_op,
bool propagate =
true)
1416 return surfelUpdate(derived().toCode(key), binary_op, propagate);
1419 template <
class UnaryOp,
1420 std::enable_if_t<std::is_invocable_v<UnaryOp, Surfel>,
bool> =
true>
1421 Node surfelUpdate(Point coord, UnaryOp unary_op,
bool propagate =
true,
1424 return surfelUpdate(derived().toCode(coord, depth), unary_op, propagate);
1427 template <
class BinaryOp,
1428 std::enable_if_t<std::is_invocable_v<BinaryOp, Index, Surfel>,
bool> =
true>
1429 Node surfelUpdate(Point coord, BinaryOp binary_op,
bool propagate =
true,
1432 return surfelUpdate(derived().toCode(coord, depth), binary_op, propagate);
1439 void surfelClear(Index node)
1442 node, [
this](Index node) { deleteSurfel(node); },
1443 [
this](pos_t block) { clearImpl(block); });
1446 Node surfelClear(Node node,
bool propagate =
true)
1448 return derived().apply(
1449 node, [
this](Index node) { deleteSurfel(node); },
1450 [
this](pos_t block) { clearImpl(block); }, propagate);
1453 Node surfelClear(Code code,
bool propagate =
true)
1455 return derived().apply(
1456 code, [
this](Index node) { deleteSurfel(node); },
1457 [
this](pos_t block) { clearImpl(block); }, propagate);
1460 Node surfelClear(Key key,
bool propagate =
true)
1462 return surfelClear(derived().toCode(key), propagate);
1465 Node surfelClear(Point coord,
bool propagate =
true, depth_t depth = 0)
1467 return surfelClear(derived().toCode(coord, depth), propagate);
1475 SurfelMap() { indices_.emplace_back(); }
1481 template <
class Derived2>
1483 : indices_(other.indices_), surfel_(other.surfel_), free_surfel_(other.free_surfel_)
1487 template <
class Derived2>
1489 : indices_(std::move(other.indices_))
1490 , surfel_(std::move(other.surfel_))
1491 , free_surfel_(std::move(other.free_surfel_))
1495 template <
bool Cached2,
class Derived2>
1497 : indices_(other.indices_)
1498 , surfel_(std::cbegin(other.surfel_), std::cend(other.surfel_))
1499 , free_surfel_(other.free_surfel_)
1503 template <
bool Cached2,
class Derived2>
1505 : indices_(std::move(other.indices_))
1506 , surfel_(std::cbegin(other.surfel_), std::cend(other.surfel_))
1507 , free_surfel_(std::move(other.free_surfel_))
1525 template <
class Derived2>
1528 indices_ = rhs.indices_;
1529 surfel_ = rhs.surfel_;
1530 free_surfel_ = rhs.free_surfel_;
1534 template <
class Derived2>
1537 indices_ = std::move(rhs.indices_);
1538 surfel_ = std::move(rhs.surfel_);
1539 free_surfel_ = std::move(rhs.free_surfel_);
1543 template <
bool Cached2,
class Derived2>
1546 indices_ = rhs.indices_;
1547 surfel_ =
decltype(surfel_)(std::cbegin(rhs.surfel_), std::cend(rhs.surfel_));
1548 free_surfel_ = rhs.free_surfel_;
1552 template <
bool Cached2,
class Derived2>
1555 indices_ = std::move(rhs.indices_);
1556 surfel_ =
decltype(surfel_)(std::cbegin(rhs.surfel_), std::cend(rhs.surfel_));
1557 free_surfel_ = std::move(rhs.free_surfel_);
1567 std::swap(indices_, other.indices_);
1568 std::swap(surfel_, other.surfel_);
1569 std::swap(free_surfel_, other.free_surfel_);
1576 [[nodiscard]]
constexpr Derived& derived() {
return *
static_cast<Derived*
>(
this); }
1578 [[nodiscard]]
constexpr Derived
const& derived()
const
1580 return *
static_cast<Derived const*
>(
this);
1589 auto node = derived().rootIndex();
1590 indices_[node.pos][node.offset] = NULL_POS;
1597 void createBlock(Index node)
1599 auto children_block = indices_.size();
1600 indices_.emplace_back();
1601 auto pos = indices_[node.pos][node.offset];
1602 if (NULL_POS == pos) {
1603 indices_.back().fill(NULL_POS);
1605 for (offset_t i{}; N != i; ++i) {
1606 createOrAssignSurfel(Index{children_block, i}, surfel_[pos]);
1615 void fill(Index node, pos_t children_block)
1617 auto pos = indices_[node.pos][node.offset];
1618 if (NULL_POS == pos) {
1619 indices_.back().fill(NULL_POS);
1621 for (offset_t i{}; N != i; ++i) {
1622 createOrAssignSurfel(Index{children_block, i}, surfel_[pos]);
1631 void resize(std::size_t count)
1633 typename decltype(indices_)::value_type idx;
1635 indices_.resize(count, idx);
1642 void reserveImpl(std::size_t new_cap) { indices_.reserve(new_cap); }
1651 indices_[0].fill(NULL_POS);
1653 free_surfel_ =
decltype(free_surfel_)();
1656 void clearImpl(pos_t block)
1658 for (offset_t i{}; N != i; ++i) {
1659 deleteSurfel(Index{block, i});
1667 void updateBlock(pos_t block, std::array<bool, N> modified_parent)
1669 for (offset_t i{}; N != i; ++i) {
1670 if (modified_parent[i]) {
1671 Index node(block, i);
1672 updateNode(node, derived().children(node));
1677 void updateNode(Index node)
1681 auto children = derived().children(node);
1682 for (std::size_t i{}; N != i; ++i) {
1683 auto pos = indices_[children][i];
1684 if (NULL_POS != pos) {
1685 surfel += surfel_[pos];
1689 if (surfel.
empty()) {
1692 createOrAssignSurfel(node, surfel);
1700 [[nodiscard]]
bool isPrunable(pos_t block)
const
1702 return std::all_of(std::cbegin(indices_[block]) + 1, std::cend(indices_[block]),
1703 [
a = indices_[block].front()](
auto b) {
1713 void preparePrune(Index)
1723 [[nodiscard]] std::size_t sizeofNodeTimesN(Index node)
1725 auto pos = indices_[node.pos][node.offset];
1726 return N * (
sizeof(pos) + (NULL_POS != pos ?
sizeof(surfel_[pos]) : 0));
1729 [[nodiscard]] std::size_t sizeofBlock(pos_t block)
1732 for (offset_t i{}; N != i; ++i) {
1733 auto pos = indices_[block][i];
1734 size +=
sizeof(pos) + (NULL_POS != pos ?
sizeof(surfel_[pos]) : 0);
1739 [[nodiscard]]
static constexpr std::size_t sizeofBlockLowerBound()
noexcept
1741 return sizeof(
typename decltype(indices_)::value_type);
1744 [[nodiscard]]
static constexpr std::size_t sizeofMap()
noexcept
1746 return sizeof(indices_) +
sizeof(surfel_) +
sizeof(free_surfel_);
1753 [[nodiscard]]
static constexpr MapType mapType()
noexcept {
return MapType::SURFEL; }
1755 [[nodiscard]]
constexpr std::size_t serializedSizeBlock(pos_t block)
1757 std::size_t num_surfels{};
1758 for (
auto i : indices_[block]) {
1759 num_surfels += NULL_POS != indices_[block][i];
1764 template <
class Container>
1765 constexpr std::size_t serializedSize(Container
const& c)
const
1768 for (
auto block : c) {
1769 size += serializedSizeBlock(block);
1774 template <
class Container>
1775 void readNodes(
ReadBuffer& in, Container
const& c)
1791 template <
class BlockRange>
1792 void writeBlocks(
WriteBuffer& out, BlockRange
const& blocks)
const
1814 pos_t createSurfel(Index node)
1816 auto pos = indices_[node.pos][node.offset];
1817 if (NULL_POS != pos) {
1821 pos = free_surfel_.empty() ? surfel_.size() : free_surfel_.top();
1822 indices_[node.pos][node.offset] = pos;
1823 if (free_surfel_.empty()) {
1824 surfel_.emplace_back();
1831 pos_t createOrAssignSurfel(Index node,
Surfel const& surfel)
1835 auto pos = indices_[node.pos][node.offset];
1836 if (NULL_POS != pos) {
1837 surfel_[pos] = surfel;
1841 pos = free_surfel_.empty() ? surfel_.size() : free_surfel_.top();
1842 indices_[node.pos][node.offset] = pos;
1843 if (free_surfel_.empty()) {
1844 surfel_.push_back(surfel);
1847 surfel_[pos] = surfel;
1856 void deleteSurfel(Index node)
1858 auto pos = indices_[node.pos][node.offset];
1859 if (NULL_POS == pos) {
1863 free_surfel_.push(pos);
1864 indices_[node.pos][node.offset] = NULL_POS;
1868 Container<DataBlock<pos_t, N>> indices_;
1869 std::deque<SurfelT> surfel_;
1870 std::stack<pos_t> free_surfel_;
1872 template <
class Derived2, std::
size_t N2>