UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
query_nearest_iterator.hpp
1
42#ifndef UFO_CONTAINER_TREE_MAP_QUERY_NEAREST_ITERATOR_HPP
43#define UFO_CONTAINER_TREE_MAP_QUERY_NEAREST_ITERATOR_HPP
44
45// UFO
46#include <ufo/container/tree/index.hpp>
47#include <ufo/container/tree/predicate/filter.hpp>
48#include <ufo/container/tree/predicate/predicate.hpp>
49#include <ufo/geometry/distance.hpp>
50#include <ufo/geometry/dynamic_geometry.hpp>
51
52// STL
53#include <cassert>
54#include <cmath>
55#include <cstddef>
56#include <iterator>
57#include <queue>
58
59namespace ufo
60{
61// Forward declare
62template <std::size_t Dim, class T>
63class TreeMap;
64
65template <bool Const, std::size_t Dim, class T,
66 class Predicate = pred::Predicate<TreeMap<Dim, T>>,
67 class Geometry = DynamicGeometry>
69{
70 private:
71 //
72 // Friends
73 //
74
75 template <bool, std::size_t, class, class, class>
76 friend class TreeMapQueryNearestIterator;
77
78 friend class TreeMap<Dim, T>;
79
80 private:
81 static constexpr std::size_t const BF = TreeMap<Dim, T>::branchingFactor();
82
83 using RawIterator =
84 std::conditional_t<Const, typename TreeMap<Dim, T>::container_type::const_iterator,
86
88
89 using Point = typename TreeMap<Dim, T>::Point;
90
91 struct S {
92 float dist_sq;
93 TreeIndex node;
94 RawIterator it;
95
96 S(float dist_sq, TreeIndex node, RawIterator it = {}) noexcept
97 : dist_sq(dist_sq), node(node), it(it)
98 {
99 }
100
101 bool operator>(S const& rhs) const noexcept { return dist_sq > rhs.dist_sq; }
102 };
103
104 using Queue = std::priority_queue<S, std::vector<S>, std::greater<S>>;
105
106 public:
107 //
108 // Tags
109 //
110
111 using iterator_category = std::forward_iterator_tag;
112 using difference_type = std::ptrdiff_t;
113 using value_type = typename std::iterator_traits<RawIterator>::value_type;
114 using reference = typename std::iterator_traits<RawIterator>::reference;
115 using pointer = typename std::iterator_traits<RawIterator>::pointer;
116
117 TreeMapQueryNearestIterator() = default;
118
120
121 // From non-const to const or change of predicate/geometry type
122 template <
123 bool Const2, class Predicate2, class Geometry2,
124 std::enable_if_t<(Const && !Const2) ||
125 (Const == Const2 && (!std::is_same_v<Predicate, Predicate2> ||
126 !std::is_same_v<Geometry, Geometry2>)),
127 bool> = true>
130 : tm_(other.tm_)
131 , pred_(other.pred_)
132 , query_(other.query_)
133 , epsilon_sq_(other.epsilon_sq_)
134 {
135 auto queue = other.queue_;
136 while (!queue.empty()) {
137 queue_.emplace(queue.top().dist_sq, queue.top().node, queue.top().it);
138 queue.pop();
139 }
140 }
141
142 TreeMapQueryNearestIterator& operator++()
143 {
144 queue_.pop();
145 next();
146 return *this;
147 }
148
149 TreeMapQueryNearestIterator operator++(int)
150 {
152 ++*this;
153 return tmp;
154 }
155
156 reference operator*() const { return *queue_.top().it; }
157
158 pointer operator->() const { return &*queue_.top().it; }
159
160 template <bool Const2, class Predicate2, class Geometry2>
161 bool operator==(
163 {
164 return queue_.empty() == other.queue_.empty() &&
165 (queue_.empty() || queue_.top().it == other.queue_.top().it);
166 }
167
168 template <bool Const2, class Predicate2, class Geometry2>
169 bool operator!=(
171 {
172 return !(*this == other);
173 }
174
175 private:
176 [[nodiscard]] bool returnable(
177 typename std::iterator_traits<RawIterator>::value_type const& value) const
178 {
179 return Filter::returnable(pred_, value);
180 }
181
182 [[nodiscard]] bool returnable(TreeIndex node) const
183 {
184 return tm_->isPureLeaf(node) && !tm_->empty(node);
185 }
186
187 [[nodiscard]] bool returnable(S const& s) const { return RawIterator{} != s.it; }
188
189 [[nodiscard]] bool traversable(TreeIndex node) const
190 {
191 return tm_->isParent(node) && Filter::traversable(pred_, *tm_, tm_->node(node));
192 }
193
194 void next()
195 {
196 while (!queue_.empty()) {
197 auto cur = queue_.top();
198 if (returnable(cur)) {
199 return;
200 }
201
202 queue_.pop();
203
204 if (returnable(cur.node)) {
205 auto& v = tm_->values(cur.node);
206 using std::begin;
207 using std::end;
208 for (auto it = begin(v), last = end(v); it != last; ++it) {
209 if (!returnable(*it)) {
210 continue;
211 }
212 Point p = it->first;
213 float dist_sq = distanceSquared(query_, p);
214 queue_.emplace(dist_sq, cur.node, it);
215 }
216 continue;
217 }
218
219 TreeIndex node = tm_->child(cur.node, 0);
220 for (; BF > node.offset; ++node.offset) {
221 if (!traversable(node) && !returnable(node)) {
222 continue;
223 }
224
225 float dist_sq = distanceSquared(query_, tm_->bounds(node)) + epsilon_sq_;
226 queue_.emplace(dist_sq, node);
227 }
228 }
229 }
230
231 [[nodiscard]] RawIterator iterator() { return queue_.top().it; }
232
233 private:
234 TreeMapQueryNearestIterator(TreeMap<Dim, T>* tm, TreeIndex node, Predicate const& pred,
235 Geometry const& query, float epsilon = 0.0f)
236 : tm_(tm), pred_(pred), query_(query), epsilon_sq_(epsilon * epsilon)
237 {
238 Filter::init(pred_, *tm_);
239
240 if (traversable(node) || returnable(node)) {
241 float dist_sq = distanceSquared(query_, tm_->bounds(node));
242 queue_.emplace(dist_sq, node);
243 next();
244 }
245 }
246
247 // From const to non-const
248 template <bool Const2, class Predicate2, class Geometry2,
249 std::enable_if_t<!Const && Const2, bool> = true>
252 : tm_(other.tm)
253 , pred_(other.pred_)
254 , query_(other.query_)
255 , epsilon_sq_(other.epsilon_sq_)
256 {
257 auto queue = other.queue_;
258 while (!queue.empty()) {
259 auto const& cur = queue.top();
260 // Remove const from it
261 queue_.emplace(cur.dist_sq, cur.node, tm_->values(cur.node).erase(cur.it, cur.it));
262 queue.pop();
263 }
264 }
265
266 private:
267 TreeMap<Dim, T>* tm_ = nullptr;
268
269 Predicate pred_{};
270
271 Geometry query_;
272 float epsilon_sq_;
273
274 Queue queue_;
275};
276} // namespace ufo
277
278#endif // UFO_CONTAINER_TREE_MAP_QUERY_ITERATOR_HPP
static constexpr offset_type branchingFactor() noexcept
Returns the branching factor of the tree (i.e., 2 = binary tree, 4 = quadtree, 8 = octree,...
Definition tree.hpp:203
All vision-related classes and functions.
Definition cloud.hpp:49
constexpr auto distanceSquared(A const &a, B const &b)
Computes the minimum squared distance between two shapes.
Definition distance.hpp:80