1#ifndef TATOOINE_UNIFORM_TREE_HIERARCHY_H
2#define TATOOINE_UNIFORM_TREE_HIERARCHY_H
14template <
floating_po
int Real, std::
size_t NumDims,
typename Derived>
16 template <std::
size_t I>
31 return ipow(2, NumDims);
58 std::size_t
const level,
59 std::size_t
const max_depth)
69 auto as_derived() ->
auto& {
return *
static_cast<Derived*
>(
this); }
71 return *
static_cast<Derived const*
>(
this);
75 template <std::size_t... Seq,
typename... Is>
76 static constexpr auto index(std::index_sequence<Seq...> ,
78 return ((is << Seq) + ...);
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...);
89 static_assert(
sizeof...(is) == NumDims,
90 "Number of indices does not match number of dimensions.");
94 template <std::size_t... Seq>
95 auto split(std::index_sequence<Seq...> seq) {
97 auto it = [&](
auto const... is) {
101 for (
auto const i : std::array{is...}) {
115 template <
typename... Args>
117 split(std::make_index_sequence<NumDims>{});
122 template <
typename... Args>
124 std::size_t
const level, std::size_t
const max_depth)
const
125 -> std::unique_ptr<Derived> {
136template <
typename Geometry>
140 std::size_t SimplexDim>
143template <
floating_po
int Real, std::
size_t NumDims, std::
size_t SimplexDim>
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;
183 std::
size_t const max_depth =
parent_type::default_max_depth)
187 parent_type::operator=(mesh.bounding_box());
192 std::size_t
const max_depth = parent_type::default_max_depth)
197 std::size_t
const level, std::size_t
const max_depth,
202 auto mesh() const -> auto const& {
return *m_mesh; }
210 if (!is_inside(
mesh().vertex_at(v))) {
213 if (holds_vertices()) {
214 if (is_at_max_depth()) {
215 m_vertex_handles.push_back(v);
217 split_and_distribute();
218 distribute_vertex(v);
222 distribute_vertex(v);
224 m_vertex_handles.push_back(v);
231 template <std::size_t... Is>
233 std::index_sequence<Is...> ) ->
bool {
234 auto const vs =
mesh()[c];
235 if (!is_simplex_inside(
mesh()[std::get<Is>(vs)]...)) {
238 if (holds_simplices()) {
239 if (is_at_max_depth()) {
240 m_simplex_handles.push_back(c);
242 split_and_distribute();
243 distribute_simplex(c);
247 distribute_simplex(c);
249 m_simplex_handles.push_back(c);
257 return insert_simplex(
258 c, std::make_index_sequence<mesh_type::num_vertices_per_simplex()>{});
262 if (!m_vertex_handles.empty()) {
263 distribute_vertex(m_vertex_handles.front());
264 m_vertex_handles.clear();
266 if (!m_simplex_handles.empty()) {
267 distribute_simplex(m_simplex_handles.front());
268 m_simplex_handles.clear();
273 std::size_t
const level, std::size_t
const max_depth)
const {
274 return std::unique_ptr<this_type>{
279 for (
auto& child : children()) {
280 child->insert_vertex(v);
285 for (
auto& child : children()) {
286 child->insert_simplex(c);
292 std::set<simplex_handle>& possible_collisions)
const ->
void {
293 if (parent_type::check_intersection(r)) {
295 for (
auto const& child : children()) {
296 child->collect_possible_intersections(r, possible_collisions);
299 std::copy(
begin(m_simplex_handles),
end(m_simplex_handles),
300 std::inserter(possible_collisions,
end(possible_collisions)));
306 std::set<simplex_handle> possible_collisions;
307 collect_possible_intersections(r, possible_collisions);
308 return possible_collisions;
312 std::set<simplex_handle>& simplices)
const
314 if (is_inside(pos)) {
316 for (
auto const& child : children()) {
317 child->collect_nearby_simplices(pos, simplices);
320 if (!m_simplex_handles.empty()) {
321 std::copy(
begin(m_simplex_handles),
end(m_simplex_handles),
322 std::inserter(simplices,
end(simplices)));
329 std::set<simplex_handle> simplices;
330 collect_nearby_simplices(pos, simplices);
335template <
typename Real, std::
size_t NumDimensions, std::
size_t SimplexDim>
345template <
typename Mesh>
354 return is_uniform_tree_hierarchy<std::decay_t<T>>();
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: vertex_handle.h:10
Definition: unstructured_simplicial_grid.h:87
Definition: unstructured_simplicial_grid.h:52
static auto constexpr zeros()
Definition: vec.h:26