Loading [MathJax]/extensions/tex2jax.js
Tatooine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages Concepts
celltree.h
Go to the documentation of this file.
1#ifndef TATOOINE_CELLTREE_H
2#define TATOOINE_CELLTREE_H
3//==============================================================================
5#include <tatooine/math.h>
7#include <tatooine/utility.h>
8#include <tatooine/vec.h>
10
11#include <cstdint>
12#include <iostream>
13#include <utility>
14#include <vector>
15//==============================================================================
16namespace tatooine {
17//==============================================================================
18namespace detail {
19// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20template <typename Celltree, typename Real, std::size_t NumDimensions,
21 std::size_t NumVerticesPerSimplex>
23// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
24template <typename Celltree, typename real_type>
25struct celltree_parent<Celltree, real_type, 3, 3>
26 : ray_intersectable<real_type, 3> {
28
30 using typename parent_type::ray_type;
31 auto as_celltree() const -> auto const& {
32 return *dynamic_cast<Celltree const*>(this);
33 }
34 auto check_intersection(ray_type const& /*r*/,
35 real_type const /*min_t*/ = 0) const
36 -> optional_intersection_type override {
37 auto const& c = as_celltree();
38 auto cur_aabb = c.axis_aligned_bounding_box();
39
40 return {};
41 }
42 //============================================================================
44 ray<real_type, 3> const& r, std::size_t const ni,
46 std::vector<std::size_t>& possible_collisions) const -> void {
47 auto const& c = as_celltree();
48 auto const& n = c.node(ni);
49 if (n.is_leaf()) {
50 auto const begin_it = begin(c.cell_handles()) + n.as_leaf().start;
51 auto const end_it = begin_it + n.as_leaf().size;
52
53 std::copy(begin_it, end_it, std::back_inserter(possible_collisions));
54 } else {
55 {
56 auto sub_aabb = cur_aabb;
57 sub_aabb.min(n.dim) = n.as_split().right_min;
58 if (sub_aabb.check_intersection(r)) {
59 collect_possible_intersections(r, n.right_child_index(), sub_aabb,
60 possible_collisions);
61 }
62 }
63 {
64 auto sub_aabb = cur_aabb;
65 sub_aabb.max(n.dim) = n.as_split().left_max;
66 if (sub_aabb.check_intersection(r)) {
67 collect_possible_intersections(r, n.left_child_index(), sub_aabb,
68 possible_collisions);
69 }
70 }
71 }
72 }
73 //----------------------------------------------------------------------------
75 auto const& c = as_celltree();
76 auto const cur_aabb = tatooine::axis_aligned_bounding_box{c.m_min, c.m_max};
77 std::vector<std::size_t> possible_collisions;
78 if (cur_aabb.check_intersection(r)) {
79 collect_possible_intersections(r, 0, cur_aabb, possible_collisions);
80 }
81 return possible_collisions;
82 }
83};
84// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
85} // namespace detail
86// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
87template <typename Mesh>
89 : detail::celltree_parent<celltree<Mesh>, typename Mesh::real_type,
90 Mesh::num_dimensions(),
91 Mesh::num_vertices_per_simplex()> {
92 friend struct detail::celltree_parent<
93 celltree<Mesh>, typename Mesh::real_type, Mesh::num_dimensions(),
94 Mesh::num_vertices_per_simplex()>;
95 using real_type = typename Mesh::real_type;
96 static constexpr auto num_dimensions() -> std::size_t { return Mesh::num_dimensions(); }
97 static constexpr auto num_vertices_per_simplex() {
98 return Mesh::num_vertices_per_simplex();
99 }
100
103 //============================================================================
104 struct node_type {
106 using index_type = std::uint32_t;
107 // static_assert(sizeof(float_type) == sizeof(index_type));
110 };
113 };
114 union type_t {
117 };
118
119 std::uint8_t dim; // 0, 1, ..., num_dimensions() - 1 for split node,
120 // num_dimensions() for leaf node
121 private:
123
124 public:
126
127 public:
128 constexpr node_type() = default;
129 constexpr node_type(node_type const& other) noexcept
130 : dim{other.dim}, m_left_child_index{other.m_left_child_index} {
131 if (is_leaf()) {
132 as_leaf().start = other.as_leaf().start;
133 as_leaf().size = other.as_leaf().size;
134 } else {
135 as_split().left_max = other.as_split().left_max;
136 as_split().right_min = other.as_split().right_min;
137 }
138 }
139 constexpr auto operator=(node_type const& other) noexcept -> node_type& {
140 dim = other.dim;
141 m_left_child_index = other.m_left_child_index;
142 if (is_leaf()) {
143 as_leaf().start = other.as_leaf().start;
144 as_leaf().size = other.as_leaf().size;
145 } else {
146 as_split().left_max = other.as_split().left_max;
147 as_split().right_min = other.as_split().right_min;
148 }
149 }
150 constexpr auto is_leaf() const { return dim == num_dimensions(); }
151 auto left_child_index() const {
152 assert(!is_leaf());
153 return m_left_child_index;
154 }
155 auto right_child_index() const {
156 assert(!is_leaf());
157 return m_left_child_index + 1;
158 }
159 auto set_left_child_index(std::size_t const i) { m_left_child_index = i; }
160 auto as_leaf() -> auto& {
161 assert(is_leaf());
162 return type.leaf;
163 }
164 auto as_leaf() const -> auto const& {
165 assert(is_leaf());
166 return type.leaf;
167 }
168 auto as_split() -> auto& {
169 assert(!is_leaf());
170 return type.split;
171 }
172 auto as_split() const -> auto const& {
173 assert(!is_leaf());
174 return type.split;
175 }
176 };
177
178 //============================================================================
179 private:
180 Mesh const* m_mesh;
181 std::vector<node_type> m_nodes;
182 std::vector<std::size_t> m_cell_handles;
184
185 //============================================================================
186 public:
187 celltree(celltree const&) = default;
188 celltree(celltree&&) noexcept = default;
189 auto operator=(celltree const&) -> celltree& = default;
190 auto operator=(celltree&&) noexcept -> celltree& = default;
191 ~celltree() = default;
192 //===========================================================================
193 celltree(Mesh const& mesh)
194 : m_mesh{&mesh}, m_cell_handles(mesh.simplices().size()) {
196 m_min = aabb.min();
197 m_max = aabb.max();
198 std::iota(begin(m_cell_handles), end(m_cell_handles), 0);
199 auto& initial_node = m_nodes.emplace_back();
200 initial_node.dim = num_dimensions();
201 initial_node.as_leaf().start = 0;
202 initial_node.as_leaf().size = static_cast<typename node_type::index_type>(m_cell_handles.size());
203 split_if_necessary(0, 1, 2);
204 }
205 //---------------------------------------------------------------------------
206 celltree(Mesh const& mesh, vec<real_type, num_dimensions()> const& min,
207 vec<real_type, num_dimensions()> const& max)
208 : m_mesh{&mesh},
209 m_cell_handles(mesh.simplices().size()),
210 m_min{min},
211 m_max{max} {
212 std::iota(begin(m_cell_handles), end(m_cell_handles), 0);
213 auto& initial_node = m_nodes.emplace_back();
214 initial_node.dim = num_dimensions();
215 initial_node.as_leaf().start = 0;
216 initial_node.as_leaf().size =
217 static_cast<typename node_type::index_type>(m_cell_handles.size());
218 split_if_necessary(0, 1, 2);
219 }
220 //===========================================================================
221 public:
222 constexpr auto mesh() const -> auto const& { return *m_mesh; }
223 constexpr auto cell_handles() const -> auto const& { return m_cell_handles; }
224 constexpr auto node(std::size_t const i) const -> auto const& {
225 return m_nodes[i];
226 }
227 constexpr auto nodes() const -> auto const& { return m_nodes; }
228 constexpr auto indices() const -> auto const& { return m_cell_handles; }
229
230 private:
231 constexpr auto mesh() -> auto& { return *m_mesh; }
232 constexpr auto cell_handles() -> auto& { return m_cell_handles; }
233 constexpr auto node(std::size_t const i) -> auto& { return m_nodes[i]; }
234 constexpr auto nodes() -> auto& { return m_nodes; }
235 constexpr auto indices() -> auto& { return m_cell_handles; }
236 //===========================================================================
237 public:
238 template <std::size_t... Seq>
239 constexpr auto min_cell_boundary(std::size_t const cell_idx,
240 std::uint8_t const dim,
241 std::index_sequence<Seq...> /*seq*/) const {
242 auto const cell_vertex_handles = mesh().simplex_at(cell_idx);
243 return tatooine::min(mesh()[std::get<Seq>(cell_vertex_handles)](dim)...);
244 }
245 //----------------------------------------------------------------------------
246 template <std::size_t... Seq>
247 constexpr auto max_cell_boundary(std::size_t const cell_idx,
248 std::uint8_t const dim,
249 std::index_sequence<Seq...> /*seq*/) const {
250 auto const cell_vertex_handles = mesh().simplex_at(cell_idx);
251 return tatooine::max(mesh()[std::get<Seq>(cell_vertex_handles)](dim)...);
252 }
253 //----------------------------------------------------------------------------
254 template <std::size_t... Seq>
255 constexpr auto cell_center(std::size_t const cell_idx, std::uint8_t const dim,
256 std::index_sequence<Seq...> /*seq*/) const {
257 auto const cell_vertex_handles = mesh().simplex_at(cell_idx);
258 auto const min =
259 tatooine::min(mesh()[std::get<Seq>(cell_vertex_handles)](dim)...);
260 auto const max =
261 tatooine::max(mesh()[std::get<Seq>(cell_vertex_handles)](dim)...);
262 return (min + max) / 2;
263 }
264 //----------------------------------------------------------------------------
265 constexpr auto axis_aligned_bounding_box() const {
266 return mesh().axis_aligned_bounding_box();
267 }
268 //----------------------------------------------------------------------------
269 auto cells_at(vec_t const& x) const {
270 std::vector<std::size_t> cells;
271 cells_at(x, 0, cells,
272 std::make_index_sequence<num_vertices_per_simplex()>{});
273 return cells;
274 }
275 //----------------------------------------------------------------------------
276 private:
277 template <std::size_t... Seq>
278 auto cells_at(vec_t const& x, std::size_t const cur_node_idx,
279 std::vector<std::size_t>& cells,
280 std::index_sequence<Seq...> seq) const -> void {
281 auto const& n = node(cur_node_idx);
282 if (n.is_leaf()) {
283 auto const vertex_handles = mesh().simplex_at(n.as_leaf().start);
284 auto A = mat<real_type, num_dimensions() + 1,
285 Mesh::num_vertices_per_simplex()>::ones();
286 auto b = vec<real_type, num_dimensions() + 1>::ones();
287 for (std::size_t i = 0; i < num_dimensions(); ++i) {
288 ((A(Seq, i) = mesh()[std::get<Seq>(vertex_handles)](i)), ...);
289 }
290 for (std::size_t i = 0; i < num_dimensions(); ++i) {
291 b(i) = x(i);
292 }
293 auto const barycentric_coordinates = *solve(A, b);
294 auto is_inside = true;
295 constexpr real_type eps = 1e-6;
296 for (std::size_t i = 0; i < Mesh::num_vertices_per_simplex(); ++i) {
297 is_inside &= barycentric_coordinates(0) >= -eps;
298 is_inside &= barycentric_coordinates(0) <= 1 + eps;
299 }
300 if (is_inside) {
301 std::copy(begin(cell_handles()) + n.as_leaf().start,
302 begin(cell_handles()) + n.as_leaf().start + n.as_leaf().size,
303 std::back_inserter(cells));
304 }
305 } else {
306 if (x(n.dim) <= n.as_split().left_max &&
307 x(n.dim) < n.as_split().right_min) {
308 cells_at(x, n.left_child_index(), cells, seq);
309 } else if (x(n.dim) >= n.as_split().right_min &&
310 x(n.dim) > n.as_split().left_max) {
311 cells_at(x, n.right_child_index(), cells, seq);
312 } else if (x(n.dim) <= n.as_split().left_max &&
313 x(n.dim) >= n.as_split().right_min) {
314 // TODO choose best side
315 cells_at(x, n.left_child_index(), cells, seq);
316 cells_at(x, n.right_child_index(), cells, seq);
317 }
318 }
319 }
320 //===========================================================================
322 template <std::size_t... Seq>
323 auto split_dimension(std::size_t const ni,
324 std::index_sequence<Seq...> /*seq*/) const {
325 assert(node(ni).is_leaf());
326 auto aabb = make_array<num_dimensions()>(std::tuple{
327 std::uint8_t{0},
328 std::numeric_limits<typename node_type::float_type>::max(),
329 -std::numeric_limits<typename node_type::float_type>::max()});
330 for (std::size_t dim = 0; dim < num_dimensions(); ++dim) {
331 std::get<0>(aabb[dim]) = static_cast<std::uint8_t>(dim);
332 }
333 auto const begin_it = begin(cell_handles()) + node(ni).as_leaf().start;
334 auto const end_it = begin_it + node(ni).as_leaf().size;
335 for (auto cell_it = begin_it; cell_it != end_it; ++cell_it) {
336 auto const cell_vertex_handles = mesh().simplex_at(*cell_it);
337 for (auto& [dim, min, max] : aabb) {
339 mesh()[std::get<Seq>(cell_vertex_handles)](dim)...);
341 mesh()[std::get<Seq>(cell_vertex_handles)](dim)...);
342 }
343 }
344 auto split_dim = std::numeric_limits<std::uint8_t>::max();
345 auto max_extent = typename node_type::float_type(0);
346
347 for (auto const& [dim, min, max] : aabb) {
348 auto const extent = max - min;
349 if (extent > max_extent) {
350 max_extent = extent;
351 split_dim = dim;
352 }
353 }
354 return aabb[split_dim];
355 }
356 //----------------------------------------------------------------------------
358 auto add_children(std::size_t const ni) {
359 assert(node(ni).is_leaf());
360 std::size_t left_child_index;
361 {
362 // TODO this is a critical region (race condition)
363 left_child_index = nodes().size();
364 node(ni).set_left_child_index(left_child_index);
365 nodes().emplace_back();
366 nodes().emplace_back();
367 }
368 return left_child_index;
369 }
370 //----------------------------------------------------------------------------
371 template <std::size_t... Seq>
372 auto split_if_necessary(std::size_t const ni, std::size_t const level,
373 std::size_t const max_level) {
374 if (node(ni).as_leaf().size > 1 && level < max_level) {
375 std::cout << "splitting node at index " << ni << '\n';
376 split(ni, level, max_level);
377 } else {
378 std::cout << "leaf at level " << level << "[" << node(ni).as_leaf().start
379 << ", " << node(ni).as_leaf().size << "]" << '\n';
380 }
381 }
382 //----------------------------------------------------------------------------
383 template <std::size_t... Seq>
384 auto split(std::size_t const ni, std::size_t const level, std::size_t const max_level) {
385 split(ni, level, max_level,
386 std::make_index_sequence<num_vertices_per_simplex()>{});
387 }
388 //----------------------------------------------------------------------------
389 template <std::size_t... Seq>
390 auto split(std::size_t const ni, std::size_t const level, std::size_t const max_level,
391 std::index_sequence<Seq...> seq) -> void {
392 assert(node(ni).is_leaf());
393 auto const li = add_children(ni);
394 auto const ri = li + 1;
395 // std::cout <<level << ", " << li << ", " << ri << '\n';
396 auto const [split_dim, min, max] = split_dimension(ni, seq);
397
398 // split_with_heuristic(ni, li, ri, split_dim, min, max, seq);
399 split_with_median(ni, li, ri, split_dim, seq);
400
401 split_if_necessary(li, level + 1, max_level);
402 split_if_necessary(ri, level + 1, max_level);
403 }
404 //----------------------------------------------------------------------------
405 template <std::size_t... Seq>
406 auto split_with_median(std::size_t const ni, std::size_t const li, std::size_t const ri,
407 std::uint8_t const split_dim,
408 std::index_sequence<Seq...> seq) {
409 sort_indices(ni, split_dim, seq);
410
411 auto const cur_start = node(ni).as_leaf().start;
412 auto const cur_size = node(ni).as_leaf().size;
413 auto const lstart = cur_start;
414 auto const lsize = cur_size / 2;
415 auto const rstart = lstart + lsize;
416 auto const rsize = cur_size - lsize;
417 auto const lmax = max_cell_boundary(rstart - 1, split_dim, seq);
418 auto const rmin = min_cell_boundary(rstart, split_dim, seq);
419 assert(lsize + rsize == cur_size);
420 assert(rstart + rsize == cur_start + cur_size);
421
422 node(li).dim = num_dimensions();
423 node(li).as_leaf().start = lstart;
424 node(li).as_leaf().size = lsize;
425
426 node(ri).dim = num_dimensions();
427 node(ri).as_leaf().start = rstart;
428 node(ri).as_leaf().size = rsize;
429
430 node(ni).dim = split_dim;
431 node(ni).as_split().left_max = lmax;
432 node(ni).as_split().right_min = rmin;
433 }
434 //----------------------------------------------------------------------------
436 template <std::size_t... Seq>
437 auto split_with_heuristic(std::size_t const ni, std::size_t const li, std::size_t const ri,
438 std::uint8_t const split_dim, real_type const min,
439 real_type const max,
440 std::index_sequence<Seq...> seq) {
441 sort_indices(ni, split_dim, seq);
442
443 auto min_cost = std::numeric_limits<real_type>::max();
444 auto best_lsize = std::numeric_limits<std::uint32_t>::max();
445 auto cur_lsize = std::uint32_t(1);
446 typename node_type::float_type best_lmax = 0, best_rmin = 0;
447 auto const start_it = begin(cell_handles()) + node(ni).as_leaf().start;
448 auto const end_it = start_it + node(ni).as_leaf().size - 1;
449 for (auto cell_it = start_it; cell_it != end_it; ++cell_it) {
450 auto const cur_lmax = max_cell_boundary(*cell_it, split_dim, seq);
451 auto const cur_rmin = min_cell_boundary(*next(cell_it), split_dim, seq);
452 auto const cur_cost =
453 (cur_lmax - min) * cur_lsize -
454 (max - cur_rmin) * (node(ni).as_leaf().size - cur_lsize);
455 // auto const cur_cost = -2 * cur_lsize + node(ni).as_leaf().size;
456 if (cur_cost < min_cost) {
457 min_cost = cur_cost;
458 best_lmax = cur_lmax;
459 best_rmin = cur_rmin;
460 best_lsize = cur_lsize;
461 }
462 ++cur_lsize;
463 }
464
465 node(li).dim = num_dimensions();
466 node(li).as_leaf().start = node(ni).as_leaf().start;
467 node(li).as_leaf().size = best_lsize;
468
469 node(ri).dim = num_dimensions();
470 node(ri).as_leaf().start = node(ni).as_leaf().start + best_lsize;
471 node(ri).as_leaf().size = node(ni).as_leaf().size - best_lsize;
472
473 node(ni).dim = split_dim;
474 node(ni).as_split().left_max = best_lmax;
475 node(ni).as_split().right_min = best_rmin;
476 }
477 //----------------------------------------------------------------------------
479 template <std::size_t... Seq>
480 auto sort_indices(std::size_t const ni, std::uint8_t const dim,
481 std::index_sequence<Seq...> seq) {
482 auto comparator = [this, ni, dim, seq](auto const i, auto const j) {
483 return cell_center(i, dim, seq) < cell_center(j, dim, seq);
484 };
485 auto const begin_it = begin(cell_handles()) + node(ni).as_leaf().start;
486 auto const end_it = begin_it + node(ni).as_leaf().size;
487 std::sort(begin_it, end_it, comparator);
488 }
489 //----------------------------------------------------------------------------
490 public:
491 auto write_vtk(filesystem::path const& path) {
493 f.write_header();
494 std::vector<vec<real_type, 3>> positions;
495 std::vector<std::vector<std::size_t>> indices;
496 auto const parent_bounding_box = tatooine::axis_aligned_bounding_box{m_min, m_max};
498 parent_bounding_box);
499 f.write_points(positions);
500 f.write_lines(indices);
501 }
502 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
503 private:
505 std::vector<vec<real_type, num_dimensions()>>& positions,
506 std::vector<std::vector<std::size_t>>& indices, std::size_t cur_node_idx,
508 aabb,
509 std::size_t cur_level = 0, std::size_t cur_idx = 0) -> std::size_t {
510 if (node(cur_node_idx).is_leaf()) {
511 positions.push_back(vec{aabb.min(0), aabb.min(1), aabb.min(2)});
512 positions.push_back(vec{aabb.max(0), aabb.min(1), aabb.min(2)});
513 positions.push_back(vec{aabb.max(0), aabb.max(1), aabb.min(2)});
514 positions.push_back(vec{aabb.min(0), aabb.max(1), aabb.min(2)});
515 positions.push_back(vec{aabb.min(0), aabb.min(1), aabb.max(2)});
516 positions.push_back(vec{aabb.max(0), aabb.min(1), aabb.max(2)});
517 positions.push_back(vec{aabb.max(0), aabb.max(1), aabb.max(2)});
518 positions.push_back(vec{aabb.min(0), aabb.max(1), aabb.max(2)});
519 indices.push_back(
520 {cur_idx, cur_idx + 1, cur_idx + 2, cur_idx + 3, cur_idx});
521 indices.push_back(
522 {cur_idx + 4, cur_idx + 5, cur_idx + 6, cur_idx + 7, cur_idx + 4});
523 indices.push_back({cur_idx, cur_idx + 4});
524 indices.push_back({cur_idx + 1, cur_idx + 5});
525 indices.push_back({cur_idx + 2, cur_idx + 6});
526 indices.push_back({cur_idx + 3, cur_idx + 7});
527 cur_idx += 8;
528 } else {
529 auto sub_aabb = aabb;
530 sub_aabb.max(node(cur_node_idx).dim) =
531 node(cur_node_idx).as_split().left_max;
533 positions, indices, node(cur_node_idx).left_child_index(), sub_aabb,
534 cur_level + 1, cur_idx);
535
536 sub_aabb.max(node(cur_node_idx).dim) = aabb.max(node(cur_node_idx).dim);
537 sub_aabb.min(node(cur_node_idx).dim) =
538 node(cur_node_idx).as_split().right_min;
540 positions, indices, node(cur_node_idx).right_child_index(), sub_aabb,
541 cur_level + 1, cur_idx);
542 }
543 return cur_idx;
544 }
545};
546
547template <typename Mesh>
549template <typename Mesh, typename Real, std::size_t NumDimensions>
552template <typename T>
553struct is_celltree_impl : std::false_type {};
554template <typename Mesh>
555struct is_celltree_impl<celltree<Mesh>> : std::true_type {};
556template <typename T>
557constexpr auto is_celltree() {
559}
560template <typename T>
561constexpr auto is_celltree(T&&) {
562 return is_celltree<std::decay_t<T>>();
563}
564//==============================================================================
565} // namespace tatooine
566//==============================================================================
567#endif
Definition: mesh.h:16
Definition: vtk_legacy.h:448
Definition: vtp_writer.h:3
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_celltree()
Definition: celltree.h:557
axis_aligned_bounding_box< Real, NumDimensions > aabb
Definition: axis_aligned_bounding_box.h:553
auto solve(polynomial< Real, 1 > const &p) -> std::vector< Real >
solve a + b*x
Definition: polynomial.h:187
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto next(Iter iter)
Definition: iterator_facade.h:325
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
Definition: axis_aligned_bounding_box.h:103
pos_type m_min
Definition: axis_aligned_bounding_box.h:118
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
index_type size
Definition: celltree.h:112
index_type start
Definition: celltree.h:112
float_type left_max
Definition: celltree.h:109
float_type right_min
Definition: celltree.h:109
Definition: celltree.h:104
auto as_leaf() const -> auto const &
Definition: celltree.h:164
type_t type
Definition: celltree.h:125
auto set_left_child_index(std::size_t const i)
Definition: celltree.h:159
double float_type
Definition: celltree.h:105
constexpr auto operator=(node_type const &other) noexcept -> node_type &
Definition: celltree.h:139
constexpr auto is_leaf() const
Definition: celltree.h:150
auto as_split() -> auto &
Definition: celltree.h:168
constexpr node_type()=default
std::uint8_t dim
Definition: celltree.h:119
auto as_leaf() -> auto &
Definition: celltree.h:160
auto right_child_index() const
Definition: celltree.h:155
auto left_child_index() const
Definition: celltree.h:151
constexpr node_type(node_type const &other) noexcept
Definition: celltree.h:129
std::uint32_t index_type
Definition: celltree.h:106
std::size_t m_left_child_index
Definition: celltree.h:122
auto as_split() const -> auto const &
Definition: celltree.h:172
Definition: celltree.h:91
std::vector< std::size_t > m_cell_handles
Definition: celltree.h:182
auto cells_at(vec_t const &x) const
Definition: celltree.h:269
auto write_vtk_collect_positions_and_indices(std::vector< vec< real_type, num_dimensions()> > &positions, std::vector< std::vector< std::size_t > > &indices, std::size_t cur_node_idx, tatooine::axis_aligned_bounding_box< real_type, num_dimensions()> const &aabb, std::size_t cur_level=0, std::size_t cur_idx=0) -> std::size_t
Definition: celltree.h:504
celltree(celltree const &)=default
celltree(celltree &&) noexcept=default
constexpr auto min_cell_boundary(std::size_t const cell_idx, std::uint8_t const dim, std::index_sequence< Seq... >) const
Definition: celltree.h:239
constexpr auto indices() -> auto &
Definition: celltree.h:235
constexpr auto axis_aligned_bounding_box() const
Definition: celltree.h:265
auto cells_at(vec_t const &x, std::size_t const cur_node_idx, std::vector< std::size_t > &cells, std::index_sequence< Seq... > seq) const -> void
Definition: celltree.h:278
Mesh const * m_mesh
Definition: celltree.h:180
static constexpr auto num_vertices_per_simplex()
Definition: celltree.h:97
constexpr auto node(std::size_t const i) const -> auto const &
Definition: celltree.h:224
vec< real_type, num_dimensions()> m_max
Definition: celltree.h:183
auto add_children(std::size_t const ni)
Definition: celltree.h:358
auto split_with_median(std::size_t const ni, std::size_t const li, std::size_t const ri, std::uint8_t const split_dim, std::index_sequence< Seq... > seq)
Definition: celltree.h:406
auto split(std::size_t const ni, std::size_t const level, std::size_t const max_level, std::index_sequence< Seq... > seq) -> void
Definition: celltree.h:390
constexpr auto nodes() const -> auto const &
Definition: celltree.h:227
auto split_with_heuristic(std::size_t const ni, std::size_t const li, std::size_t const ri, std::uint8_t const split_dim, real_type const min, real_type const max, std::index_sequence< Seq... > seq)
TODO heuristic not working correctly.
Definition: celltree.h:437
static constexpr auto num_dimensions() -> std::size_t
Definition: celltree.h:96
celltree(Mesh const &mesh, vec< real_type, num_dimensions()> const &min, vec< real_type, num_dimensions()> const &max)
Definition: celltree.h:206
constexpr auto mesh() -> auto &
Definition: celltree.h:231
auto sort_indices(std::size_t const ni, std::uint8_t const dim, std::index_sequence< Seq... > seq)
Definition: celltree.h:480
auto split_if_necessary(std::size_t const ni, std::size_t const level, std::size_t const max_level)
Definition: celltree.h:372
constexpr auto indices() const -> auto const &
Definition: celltree.h:228
auto write_vtk(filesystem::path const &path)
Definition: celltree.h:491
vec< real_type, num_dimensions()> m_min
Definition: celltree.h:183
constexpr auto nodes() -> auto &
Definition: celltree.h:234
constexpr auto max_cell_boundary(std::size_t const cell_idx, std::uint8_t const dim, std::index_sequence< Seq... >) const
Definition: celltree.h:247
typename Mesh::real_type real_type
Definition: celltree.h:95
constexpr auto node(std::size_t const i) -> auto &
Definition: celltree.h:233
constexpr auto cell_handles() const -> auto const &
Definition: celltree.h:223
auto split_dimension(std::size_t const ni, std::index_sequence< Seq... >) const
Definition: celltree.h:323
constexpr auto cell_center(std::size_t const cell_idx, std::uint8_t const dim, std::index_sequence< Seq... >) const
Definition: celltree.h:255
std::vector< node_type > m_nodes
Definition: celltree.h:181
constexpr auto cell_handles() -> auto &
Definition: celltree.h:232
constexpr auto mesh() const -> auto const &
Definition: celltree.h:222
auto split(std::size_t const ni, std::size_t const level, std::size_t const max_level)
Definition: celltree.h:384
auto as_celltree() const -> auto const &
Definition: celltree.h:31
auto collect_possible_intersections(ray< real_type, 3 > const &r, std::size_t const ni, tatooine::axis_aligned_bounding_box< real_type, 3 > const &cur_aabb, std::vector< std::size_t > &possible_collisions) const -> void
Definition: celltree.h:43
auto collect_possible_intersections(ray< real_type, 3 > const &r) const
Definition: celltree.h:74
auto check_intersection(ray_type const &, real_type const =0) const -> optional_intersection_type override
Definition: celltree.h:34
Definition: celltree.h:22
Definition: celltree.h:553
Definition: mat.h:14
auto axis_aligned_bounding_box() const
Definition: pointset.h:183
Definition: ray_intersectable.h:10
std::optional< intersection_type > optional_intersection_type
Definition: ray_intersectable.h:14
real_type real_type
Definition: ray_intersectable.h:11
Definition: ray.h:10
auto simplices() const
Definition: unstructured_simplicial_grid.h:515
Definition: celltree.h:114
split_node_t split
Definition: celltree.h:115
leaf_node_type leaf
Definition: celltree.h:116