Tatooine
uniform_tree_hierarchy.h
Go to the documentation of this file.
1#ifndef TATOOINE_UNIFORM_TREE_HIERARCHY_H
2#define TATOOINE_UNIFORM_TREE_HIERARCHY_H
3//==============================================================================
5#include <tatooine/for_loop.h>
6#include <tatooine/math.h>
7
8#include <set>
9#include <vector>
10//==============================================================================
11namespace tatooine {
12//==============================================================================
14template <floating_point Real, std::size_t NumDims, typename Derived>
15struct base_uniform_tree_hierarchy : aabb<Real, NumDims> {
16 template <std::size_t I>
17 struct dim {
18 enum e : std::uint8_t { left = 0, right = 1 << I };
19 };
20 using real_type = Real;
25 using parent_type::max;
26 using parent_type::min;
27 using typename parent_type::vec_type;
28 friend class std::unique_ptr<this_type>;
29 static constexpr auto num_dimensions() -> std::size_t { return NumDims; }
30 static constexpr auto num_children() -> std::size_t {
31 return ipow(2, NumDims);
32 }
33
34 std::size_t m_level;
35 std::size_t m_max_depth;
36 std::array<std::unique_ptr<Derived>, num_children()> m_children;
37 static constexpr std::size_t default_max_depth = 4;
38 //============================================================================
42 auto operator =(base_uniform_tree_hierarchy const&)
43 -> base_uniform_tree_hierarchy& = default;
44 auto operator =(base_uniform_tree_hierarchy&&) noexcept
45 -> base_uniform_tree_hierarchy& = default;
46 virtual ~base_uniform_tree_hierarchy() = default;
47 //----------------------------------------------------------------------------
49 std::size_t const max_depth = default_max_depth)
50 : m_level{1}, m_max_depth{max_depth} {}
51 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53 std::size_t const max_depth = default_max_depth)
54 : parent_type{min, max}, m_level{1}, m_max_depth{max_depth} {}
55 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
56 protected:
58 std::size_t const level,
59 std::size_t const max_depth)
60 : parent_type{min, max}, m_level{level}, m_max_depth{max_depth} {}
61 //============================================================================
62 public:
63 constexpr auto is_splitted() const { return m_children.front() != nullptr; }
64 constexpr auto level() const { return m_level; }
65 constexpr auto is_at_max_depth() const { return level() == m_max_depth; }
66 auto children() const -> auto const& { return m_children; }
67 //----------------------------------------------------------------------------
68 private:
69 auto as_derived() -> auto& { return *static_cast<Derived*>(this); }
70 auto as_derived() const -> auto const& {
71 return *static_cast<Derived const*>(this);
72 }
73 //----------------------------------------------------------------------------
74 private:
75 template <std::size_t... Seq, typename... Is>
76 static constexpr auto index(std::index_sequence<Seq...> /*seq*/,
77 Is const... is) {
78 return ((is << Seq) + ...);
79 }
80 //----------------------------------------------------------------------------
81 public:
82 static constexpr auto index(integral auto const... is) {
83 static_assert(sizeof...(is) == NumDims,
84 "Number of indices does not match number of dimensions.");
85 return index(std::make_index_sequence<NumDims>{}, is...);
86 }
87 //------------------------------------------------------------------------------
88 auto child_at(integral auto const... is) const -> auto const& {
89 static_assert(sizeof...(is) == NumDims,
90 "Number of indices does not match number of dimensions.");
91 return m_children[index(is...)];
92 }
93 //------------------------------------------------------------------------------
94 template <std::size_t... Seq>
95 auto split(std::index_sequence<Seq...> seq) {
96 auto const c = center();
97 auto it = [&](auto const... is) {
98 auto cur_min = min();
99 auto cur_max = max();
100 std::size_t dim = 0;
101 for (auto const i : std::array{is...}) {
102 if (i == 0) {
103 cur_max[dim] = c(dim);
104 } else if (i == 1) {
105 cur_min[dim] = c(dim);
106 }
107 ++dim;
108 }
109 m_children[index(seq, is...)] =
110 construct(cur_min, cur_max, level() + 1, m_max_depth);
111 };
112 for_loop(it, ((void)Seq, 2)...);
113 }
114 //------------------------------------------------------------------------------
115 template <typename... Args>
116 auto split() {
117 split(std::make_index_sequence<NumDims>{});
118 }
119 //------------------------------------------------------------------------------
120 auto distribute() { as_derived().distribute(); }
121 //------------------------------------------------------------------------------
122 template <typename... Args>
123 auto construct(vec_type const& min, vec_type const& max,
124 std::size_t const level, std::size_t const max_depth) const
125 -> std::unique_ptr<Derived> {
126 return as_derived().construct(min, max, level, max_depth);
127 }
128 //------------------------------------------------------------------------------
130 split();
131 distribute();
132 }
133};
134//==============================================================================
136template <typename Geometry>
138//==============================================================================
139template <floating_point Real, std::size_t NumDimensions,
140 std::size_t SimplexDim>
142// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
143template <floating_point Real, std::size_t NumDims, std::size_t SimplexDim>
145 unstructured_simplicial_grid<Real, NumDims, SimplexDim>>
147 Real, NumDims,
148 uniform_tree_hierarchy<
149 unstructured_simplicial_grid<Real, NumDims, SimplexDim>>> {
155 using parent_type::children;
156 using parent_type::is_at_max_depth;
157 using parent_type::is_inside;
158 using parent_type::is_simplex_inside;
159 using parent_type::is_splitted;
160 using parent_type::max;
161 using parent_type::min;
162 using parent_type::split_and_distribute;
163
164 using typename parent_type::vec_type;
167
169 std::vector<vertex_handle> m_vertex_handles;
170 std::vector<simplex_handle> m_simplex_handles;
171 //============================================================================
175 auto operator =(uniform_tree_hierarchy const&)
176 -> uniform_tree_hierarchy& = default;
177 auto operator =(uniform_tree_hierarchy&&) noexcept
178 -> uniform_tree_hierarchy& = default;
179 virtual ~uniform_tree_hierarchy() = default;
180 //----------------------------------------------------------------------------
182 mesh_type const& mesh,
183 std::size_t const max_depth = parent_type::default_max_depth)
185 max_depth},
186 m_mesh{&mesh} {
187 parent_type::operator=(mesh.bounding_box());
188 }
189 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
191 vec_type const& min, vec_type const& max, mesh_type const& mesh,
192 std::size_t const max_depth = parent_type::default_max_depth)
193 : parent_type{min, max, 1, max_depth}, m_mesh{&mesh} {}
194 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
195 private:
197 std::size_t const level, std::size_t const max_depth,
198 mesh_type const& mesh)
199 : parent_type{min, max, level, max_depth}, m_mesh{&mesh} {}
200 //============================================================================
201 public:
202 auto mesh() const -> auto const& { return *m_mesh; }
203 auto constexpr holds_vertices() const { return !m_vertex_handles.empty(); }
204 auto constexpr holds_simplices() const { return !m_simplex_handles.empty(); }
205 //----------------------------------------------------------------------------
206 auto num_vertex_handles() const { return size(m_vertex_handles); }
207 auto num_simplex_handles() const { return size(m_simplex_handles); }
208 //----------------------------------------------------------------------------
209 auto insert_vertex(vertex_handle const v) -> bool {
210 if (!is_inside(mesh().vertex_at(v))) {
211 return false;
212 }
213 if (holds_vertices()) {
214 if (is_at_max_depth()) {
215 m_vertex_handles.push_back(v);
216 } else {
217 split_and_distribute();
218 distribute_vertex(v);
219 }
220 } else {
221 if (is_splitted()) {
222 distribute_vertex(v);
223 } else {
224 m_vertex_handles.push_back(v);
225 }
226 }
227 return true;
228 }
229 //------------------------------------------------------------------------------
230 private:
231 template <std::size_t... Is>
233 std::index_sequence<Is...> /*seq*/) -> bool {
234 auto const vs = mesh()[c];
235 if (!is_simplex_inside(mesh()[std::get<Is>(vs)]...)) {
236 return false;
237 }
238 if (holds_simplices()) {
239 if (is_at_max_depth()) {
240 m_simplex_handles.push_back(c);
241 } else {
242 split_and_distribute();
243 distribute_simplex(c);
244 }
245 } else {
246 if (is_splitted()) {
247 distribute_simplex(c);
248 } else {
249 m_simplex_handles.push_back(c);
250 }
251 }
252 return true;
253 }
254 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
255 public:
256 auto insert_simplex(simplex_handle const c) -> bool {
257 return insert_simplex(
258 c, std::make_index_sequence<mesh_type::num_vertices_per_simplex()>{});
259 }
260 //----------------------------------------------------------------------------
261 auto distribute() {
262 if (!m_vertex_handles.empty()) {
263 distribute_vertex(m_vertex_handles.front());
264 m_vertex_handles.clear();
265 }
266 if (!m_simplex_handles.empty()) {
267 distribute_simplex(m_simplex_handles.front());
268 m_simplex_handles.clear();
269 }
270 }
271 //------------------------------------------------------------------------------
272 auto construct(vec_type const& min, vec_type const& max,
273 std::size_t const level, std::size_t const max_depth) const {
274 return std::unique_ptr<this_type>{
275 new this_type{min, max, level, max_depth, mesh()}};
276 }
277 //----------------------------------------------------------------------------
279 for (auto& child : children()) {
280 child->insert_vertex(v);
281 }
282 }
283 //----------------------------------------------------------------------------
285 for (auto& child : children()) {
286 child->insert_simplex(c);
287 }
288 }
289 //============================================================================
291 ray<Real, NumDims> const& r,
292 std::set<simplex_handle>& possible_collisions) const -> void {
293 if (parent_type::check_intersection(r)) {
294 if (is_splitted()) {
295 for (auto const& child : children()) {
296 child->collect_possible_intersections(r, possible_collisions);
297 }
298 } else {
299 std::copy(begin(m_simplex_handles), end(m_simplex_handles),
300 std::inserter(possible_collisions, end(possible_collisions)));
301 }
302 }
303 }
304 //----------------------------------------------------------------------------
306 std::set<simplex_handle> possible_collisions;
307 collect_possible_intersections(r, possible_collisions);
308 return possible_collisions;
309 }
310 //----------------------------------------------------------------------------
312 std::set<simplex_handle>& simplices) const
313 -> void {
314 if (is_inside(pos)) {
315 if (is_splitted()) {
316 for (auto const& child : children()) {
317 child->collect_nearby_simplices(pos, simplices);
318 }
319 } else {
320 if (!m_simplex_handles.empty()) {
321 std::copy(begin(m_simplex_handles), end(m_simplex_handles),
322 std::inserter(simplices, end(simplices)));
323 }
324 }
325 }
326 }
327 //----------------------------------------------------------------------------
328 auto nearby_simplices(vec<Real, NumDims> const& pos) const {
329 std::set<simplex_handle> simplices;
330 collect_nearby_simplices(pos, simplices);
331 return simplices;
332 }
333};
334//==============================================================================
335template <typename Real, std::size_t NumDimensions, std::size_t SimplexDim>
339 std::size_t const)
342//==============================================================================
343template <typename T>
344struct is_uniform_tree_hierarchy_impl : std::false_type {};
345template <typename Mesh>
347 : std::true_type {};
348template <typename T>
351}
352template <typename T>
353constexpr auto is_uniform_tree_hierarchy(T&&) {
354 return is_uniform_tree_hierarchy<std::decay_t<T>>();
355}
356//==============================================================================
357} // namespace tatooine
358//==============================================================================
359#endif
Definition: mesh.h:16
Definition: concepts.h:30
Definition: concepts.h:21
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
constexpr auto is_uniform_tree_hierarchy()
Definition: uniform_tree_hierarchy.h:349
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
constexpr auto ipow(integral auto const base, integral auto const exp)
Definition: math.h:97
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
constexpr auto for_loop(Iteration &&iteration, execution_policy::sequential_t, Ranges(&&... ranges)[2]) -> void
Use this function for creating a sequential nested loop.
Definition: for_loop.h:336
Definition: axis_aligned_bounding_box.h:103
vec< Real, NumDimensions > vec_type
Definition: axis_aligned_bounding_box.h:108
auto constexpr is_inside(pos_type const &p) const
Definition: axis_aligned_bounding_box.h:191
auto constexpr max() const -> auto const &
Definition: axis_aligned_bounding_box.h:156
auto constexpr min() const -> auto const &
Definition: axis_aligned_bounding_box.h:151
Definition: uniform_tree_hierarchy.h:17
e
Definition: uniform_tree_hierarchy.h:18
@ right
Definition: uniform_tree_hierarchy.h:18
@ left
Definition: uniform_tree_hierarchy.h:18
For octrees and quadtrees.
Definition: uniform_tree_hierarchy.h:15
static constexpr auto index(integral auto const ... is)
Definition: uniform_tree_hierarchy.h:82
Real real_type
Definition: uniform_tree_hierarchy.h:20
std::size_t m_max_depth
Definition: uniform_tree_hierarchy.h:35
auto split_and_distribute()
Definition: uniform_tree_hierarchy.h:129
constexpr auto is_splitted() const
Definition: uniform_tree_hierarchy.h:63
base_uniform_tree_hierarchy(base_uniform_tree_hierarchy &&) noexcept=default
std::size_t m_level
Definition: uniform_tree_hierarchy.h:34
auto distribute()
Definition: uniform_tree_hierarchy.h:120
auto constexpr max() const -> auto const &
Definition: axis_aligned_bounding_box.h:156
constexpr auto level() const
Definition: uniform_tree_hierarchy.h:64
auto constexpr center() const
Definition: axis_aligned_bounding_box.h:186
std::array< std::unique_ptr< Derived >, num_children()> m_children
Definition: uniform_tree_hierarchy.h:36
static constexpr auto index(std::index_sequence< Seq... >, Is const ... is)
Definition: uniform_tree_hierarchy.h:76
auto split(std::index_sequence< Seq... > seq)
Definition: uniform_tree_hierarchy.h:95
auto constexpr min() const -> auto const &
Definition: axis_aligned_bounding_box.h:151
auto child_at(integral auto const ... is) const -> auto const &
Definition: uniform_tree_hierarchy.h:88
auto construct(vec_type const &min, vec_type const &max, std::size_t const level, std::size_t const max_depth) const -> std::unique_ptr< Derived >
Definition: uniform_tree_hierarchy.h:123
static constexpr std::size_t default_max_depth
Definition: uniform_tree_hierarchy.h:37
auto children() const -> auto const &
Definition: uniform_tree_hierarchy.h:66
static constexpr auto num_children() -> std::size_t
Definition: uniform_tree_hierarchy.h:30
base_uniform_tree_hierarchy(vec_type const &min, vec_type const &max, std::size_t const level, std::size_t const max_depth)
Definition: uniform_tree_hierarchy.h:57
base_uniform_tree_hierarchy(base_uniform_tree_hierarchy const &)=default
auto as_derived() -> auto &
Definition: uniform_tree_hierarchy.h:69
static constexpr auto num_dimensions() -> std::size_t
Definition: uniform_tree_hierarchy.h:29
auto split()
Definition: uniform_tree_hierarchy.h:116
auto as_derived() const -> auto const &
Definition: uniform_tree_hierarchy.h:70
base_uniform_tree_hierarchy(vec_type const &min, vec_type const &max, std::size_t const max_depth=default_max_depth)
Definition: uniform_tree_hierarchy.h:52
constexpr auto is_at_max_depth() const
Definition: uniform_tree_hierarchy.h:65
Definition: uniform_tree_hierarchy.h:344
Definition: ray.h:10
typename mesh_type::vertex_handle vertex_handle
Definition: uniform_tree_hierarchy.h:165
auto constexpr holds_vertices() const
Definition: uniform_tree_hierarchy.h:203
uniform_tree_hierarchy(vec_type const &min, vec_type const &max, std::size_t const level, std::size_t const max_depth, mesh_type const &mesh)
Definition: uniform_tree_hierarchy.h:196
auto distribute_simplex(simplex_handle const c)
Definition: uniform_tree_hierarchy.h:284
auto constexpr holds_simplices() const
Definition: uniform_tree_hierarchy.h:204
std::vector< simplex_handle > m_simplex_handles
Definition: uniform_tree_hierarchy.h:170
uniform_tree_hierarchy(vec_type const &min, vec_type const &max, mesh_type const &mesh, std::size_t const max_depth=parent_type::default_max_depth)
Definition: uniform_tree_hierarchy.h:190
std::vector< vertex_handle > m_vertex_handles
Definition: uniform_tree_hierarchy.h:169
auto distribute_vertex(vertex_handle const v)
Definition: uniform_tree_hierarchy.h:278
auto mesh() const -> auto const &
Definition: uniform_tree_hierarchy.h:202
auto collect_possible_intersections(ray< Real, NumDims > const &r) const
Definition: uniform_tree_hierarchy.h:305
auto nearby_simplices(vec< Real, NumDims > const &pos) const
Definition: uniform_tree_hierarchy.h:328
auto insert_simplex(simplex_handle const c) -> bool
Definition: uniform_tree_hierarchy.h:256
auto insert_vertex(vertex_handle const v) -> bool
Definition: uniform_tree_hierarchy.h:209
auto collect_possible_intersections(ray< Real, NumDims > const &r, std::set< simplex_handle > &possible_collisions) const -> void
Definition: uniform_tree_hierarchy.h:290
auto insert_simplex(simplex_handle const c, std::index_sequence< Is... >) -> bool
Definition: uniform_tree_hierarchy.h:232
typename parent_type::real_type real_type
Definition: uniform_tree_hierarchy.h:153
auto construct(vec_type const &min, vec_type const &max, std::size_t const level, std::size_t const max_depth) const
Definition: uniform_tree_hierarchy.h:272
typename mesh_type::simplex_handle simplex_handle
Definition: uniform_tree_hierarchy.h:166
auto collect_nearby_simplices(vec< Real, NumDims > const &pos, std::set< simplex_handle > &simplices) const -> void
Definition: uniform_tree_hierarchy.h:311
For octrees and quadtrees.
Definition: uniform_tree_hierarchy.h:137
Definition: unstructured_simplicial_grid.h:87
Definition: unstructured_simplicial_grid.h:52
static auto constexpr zeros()
Definition: vec.h:26