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_SET_QUERY_NEAREST_ITERATOR_HPP
43#define UFO_CONTAINER_TREE_SET_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#include <utility>
59
60namespace ufo
61{
62// Forward declare
63template <std::size_t Dim>
64class TreeSet;
65
66template <bool Const, std::size_t Dim, class Predicate = pred::Predicate<TreeSet<Dim>>,
67 class Geometry = DynamicGeometry>
69{
70 private:
71 //
72 // Friends
73 //
74
75 template <bool, std::size_t, class, class>
76 friend class TreeSetQueryNearestIterator;
77
78 friend class TreeSet<Dim>;
79
80 private:
81 static constexpr std::size_t const BF = TreeSet<Dim>::branchingFactor();
82
83 using RawIterator =
84 std::conditional_t<Const, typename TreeSet<Dim>::container_type::const_iterator,
86
88
89 using Point = typename TreeSet<Dim>::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 =
114 std::pair<typename std::iterator_traits<RawIterator>::value_type, float>;
115 using reference = value_type const&;
116 using pointer = value_type const*;
117
118 TreeSetQueryNearestIterator() = default;
119
121
122 // From non-const to const or change of predicate/geometry type
123 template <
124 bool Const2, class Predicate2, class Geometry2,
125 std::enable_if_t<(Const && !Const2) ||
126 (Const == Const2 && (!std::is_same_v<Predicate, Predicate2> ||
127 !std::is_same_v<Geometry, Geometry2>)),
128 bool> = true>
131 : ts_(other.ts_)
132 , pred_(other.pred_)
133 , query_(other.query_)
134 , epsilon_sq_(other.epsilon_sq_)
135 , ret_(other.ret_)
136 {
137 auto queue = other.queue_;
138 while (!queue.empty()) {
139 queue_.emplace(queue.top().dist_sq, queue.top().node, queue.top().it);
140 queue.pop();
141 }
142 }
143
144 TreeSetQueryNearestIterator& operator++()
145 {
146 queue_.pop();
147 next();
148 return *this;
149 }
150
151 TreeSetQueryNearestIterator operator++(int)
152 {
154 ++*this;
155 return tmp;
156 }
157
158 reference operator*() const { return ret_; }
159
160 pointer operator->() const { return &ret_; }
161
162 template <bool Const2, class Predicate2, class Geometry2>
163 bool operator==(
165 {
166 return queue_.empty() == other.queue_.empty() &&
167 (queue_.empty() || queue_.top().it == other.queue_.top().it);
168 }
169
170 template <bool Const2, class Predicate2, class Geometry2>
171 bool operator!=(
173 {
174 return !(*this == other);
175 }
176
177 private:
178 [[nodiscard]] bool returnable(
179 typename std::iterator_traits<RawIterator>::value_type const& value) const
180 {
181 return Filter::returnable(pred_, value);
182 }
183
184 [[nodiscard]] bool returnable(TreeIndex node) const
185 {
186 return ts_->isPureLeaf(node) && !ts_->empty(node);
187 }
188
189 [[nodiscard]] bool returnable(S const& s) const { return RawIterator{} != s.it; }
190
191 [[nodiscard]] bool traversable(TreeIndex node) const
192 {
193 return ts_->isParent(node) && Filter::traversable(pred_, *ts_, ts_->node(node));
194 }
195
196 void next()
197 {
198 while (!queue_.empty()) {
199 S cur = queue_.top();
200 if (returnable(cur)) {
201 ret_.first = *cur.it;
202 ret_.second = std::sqrt(cur.dist_sq);
203 return;
204 }
205
206 queue_.pop();
207
208 if (returnable(cur.node)) {
209 auto& v = ts_->values(cur.node);
210 using std::begin;
211 using std::end;
212 for (auto it = begin(v), last = end(v); it != last; ++it) {
213 if (!returnable(*it)) {
214 continue;
215 }
216 Point p = *it;
217 float dist_sq = distanceSquared(query_, p);
218 queue_.emplace(dist_sq, cur.node, it);
219 }
220 continue;
221 }
222
223 TreeIndex node = ts_->child(cur.node, 0);
224 for (; BF > node.offset; ++node.offset) {
225 if (!traversable(node) && !returnable(node)) {
226 continue;
227 }
228
229 float dist_sq = distanceSquared(query_, ts_->bounds(node)) + epsilon_sq_;
230 queue_.emplace(dist_sq, node);
231 }
232 }
233 }
234
235 [[nodiscard]] RawIterator iterator() { return queue_.top().it; }
236
237 private:
238 TreeSetQueryNearestIterator(TreeSet<Dim>* ts, TreeIndex node, Predicate const& pred,
239 Geometry const& query, float epsilon = 0.0f)
240 : ts_(ts), pred_(pred), query_(query), epsilon_sq_(epsilon * epsilon)
241 {
242 Filter::init(pred_, *ts_);
243
244 if (traversable(node) || returnable(node)) {
245 float dist_sq = distanceSquared(query_, ts_->bounds(node));
246 queue_.emplace(dist_sq, node);
247 next();
248 }
249 }
250
251 // From const to non-const
252 template <bool Const2, class Predicate2, class Geometry2,
253 std::enable_if_t<!Const && Const2, bool> = true>
256 : ts_(other.ts)
257 , pred_(other.pred_)
258 , query_(other.query_)
259 , epsilon_sq_(other.epsilon_sq_)
260 , ret_(other.ret_)
261 {
262 auto queue = other.queue_;
263 while (!queue.empty()) {
264 auto const& cur = queue.top();
265 // Remove const from it
266 queue_.emplace(cur.dist_sq, cur.node, ts_->values(cur.node).erase(cur.it, cur.it));
267 queue.pop();
268 }
269 }
270
271 private:
272 TreeSet<Dim>* ts_ = nullptr;
273
274 Predicate pred_{};
275
276 Geometry query_;
277 float epsilon_sq_;
278
279 Queue queue_;
280 value_type ret_;
281};
282} // namespace ufo
283
284#endif // UFO_CONTAINER_TREE_SET_QUERY_ITERATOR_HPP
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