34#include <NDEVR/TreeIterator.h>
35#include <NDEVR/Node.h>
36#include <NDEVR/BaseValues.h>
37#include <NDEVR/Buffer.h>
38#include <NDEVR/Bounds.h>
39#include <NDEVR/InfoPipe.h>
40#include <NDEVR/Vector.h>
41#include <NDEVR/VectorFunctions.h>
42#include <NDEVR/Intersection.h>
43#include <NDEVR/BinaryHeap.h>
53 template<
class t_node_type,
class t_type, u
int01 t_node_child_size>
54 class TreeBase :
public TreeObject
56 static_assert(std::is_base_of<TreeNode, t_node_type>::value,
"t_node_type must inherit from Node");
58 explicit TreeBase(
uint04 bucket_size)
59 : m_indices(bucket_size)
60 , m_nodes(1, t_node_type(0))
61 , m_bucket_size(bucket_size)
63 m_indices.addSpace<
false>(bucket_size);
65 TreeBase(
const TreeBase& tree)
66 : m_indices(tree.m_indices)
67 , m_nodes(tree.m_nodes)
68 , m_available_node_positions(tree.m_available_node_positions)
69 , m_available_indexed_positions(tree.m_available_indexed_positions)
70 , m_bucket_size(tree.m_bucket_size)
72 TreeBase(TreeBase&& tree)
75 , m_available_node_positions()
76 , m_available_indexed_positions()
77 , m_bucket_size(tree.m_bucket_size)
79 std::swap(m_indices, tree.m_indices);
80 std::swap(m_nodes, tree.m_nodes);
81 std::swap(m_available_node_positions, tree.m_available_node_positions);
82 std::swap(m_available_indexed_positions, tree.m_available_indexed_positions);
84 TreeBase(
const Buffer<t_node_type>& nodes,
const Buffer<uint04>& indices,
bool is_read_only)
87 , m_available_node_positions()
88 , m_available_indexed_positions()
94 uint04 getIndex(
uint04 index)
const {
return m_indices[index]; }
98 m_indices.addSpace<
false>(m_bucket_size);
100 m_nodes.add(t_node_type(0));
101 m_available_node_positions.clear();
102 m_available_indexed_positions.clear();
105 uint04 getNumberOfNodes()
const
107 return m_nodes.size();
109 const t_node_type& getNode(
uint04 node_id)
const
111 return m_nodes[node_id];
114 void removeIndices(
const Buffer<bool>& deletion_indices)
116 Buffer<uint04> new_indices(deletion_indices.size());
118 for (
uint04 i = 0; i < deletion_indices.size(); i++)
120 new_indices.add(index);
121 if (!deletion_indices[i])
124 TreeIterator iterator(root_node);
125 while (iterator.valid())
127 uint04 node_index = iterator.get();
128 t_node_type& node = m_nodes[node_index];
132 const uint04 end = node.end();
133 for (
uint04 i = node.begin(); i < end; i++)
135 lib_assert(!deletion_indices[m_indices[i]],
"Must Call remove values prior to removeIndices");
136 m_indices[i] = new_indices[m_indices[i]];
141 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
148 uint04 size = end - begin;
149 TreeIterator iterator(root_node);
150 while (iterator.valid())
152 uint04 node_index = iterator.get();
153 t_node_type& node = m_nodes[node_index];
157 const uint04 node_end = node.end();
158 for (
uint04 i = node.begin(); i < node_end; i++)
160 lib_assert(end <= m_indices[i] || begin > m_indices[i],
"Must Call remove values prior to removeIndices");
161 if (m_indices[i] >= end)
162 m_indices[i] -= size;
167 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
173 void addIndices(
const Buffer<bool>& insertion_indices)
175 Buffer<uint04> index_mapping(m_indices.size());
177 for (
uint04 i = 0; i < insertion_indices.size(); i++)
179 if (!insertion_indices[i])
180 index_mapping.add(index);
183 lib_assert(index_mapping.size() == m_indices.size(),
"Unexpected Insertion Structure");
184 TreeIterator iterator(root_node);
185 while (iterator.valid())
187 uint04 node_index = iterator.get();
188 t_node_type& node = m_nodes[node_index];
192 const uint04 end = node.end();
193 for (
uint04 i = node.begin(); i < end; i++)
195 m_indices[i] = index_mapping[m_indices[i]];
200 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
207 uint04 size = end - begin;
208 TreeIterator iterator(root_node);
209 while (iterator.valid())
211 uint04 node_index = iterator.get();
212 t_node_type& node = m_nodes[node_index];
216 const uint04 node_end = node.end();
217 for (
uint04 i = node.begin(); i < node_end; i++)
219 if (m_indices[i] > end)
220 m_indices[i] += size;
225 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
232 return m_nodes[root_node].size();;
235 void removeIndex(
uint04 index)
const
237 TreeIterator iterator(root_node);
238 while (iterator.valid())
240 const t_node_type& node = m_nodes[iterator.get()];
245 for (
uint04 i = node.begin(); i < end; i++)
247 if (m_indices[index] > index)
249 lib_assert(index != m_indices[index],
"Must Call remove value prior to removeIndex");
253 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
257 template<u
int01 t_dims,
class t_buffer_type>
258 Bounds<t_dims, t_type> _getBounds(
const Buffer<uint04>& indices,
const t_buffer_type& elements,
uint04 start,
uint04 end)
260 Bounds<t_dims, t_type> bounds(Constant<Bounds<t_dims, t_type>>
::Min);
261 for (
uint04 i = start; i < end; i++)
263 bounds.addToBoundingBox(elements[indices[i]]);
268 void addIndex(
uint04 index)
const
270 TreeIterator iterator(index);
271 while (iterator.valid())
273 const t_node_type& node = m_nodes[iterator.get()];
278 for (
uint04 i = node.begin(); i < end; i++)
280 if (m_indices[index] >= index)
285 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
288 const Buffer<uint04>& indices()
const
292 Buffer<uint04>& indices()
298 optimize(m_nodes[root_node].size());
300 void optimize(
uint04 optimized_size)
302 Buffer<uint04> indices(optimized_size);
303 TreeIterator iterator(root_node);
304 while (iterator.valid())
306 uint04 node_index = iterator.get();
308 if (m_nodes[node_index].isLeaf())
310 uint04 begin = indices.size();
311 indices.addAll(m_indices.begin(m_nodes[node_index].begin()), m_nodes[node_index].size());
312 m_nodes[node_index].setBegin(begin);
316 iterator.addAndGoToIndex(m_nodes[node_index].left(), m_nodes[node_index].right());
319 m_available_node_positions.clear(0U);
320 m_available_indexed_positions.clear(0U);
323 template<
class t_buffer_type>
324 void sortVertices(
const t_buffer_type& elements, t_buffer_type& sorted)
const
326 sorted.setSize(indexSize());
327 for (
uint04 i = 0; i < m_indices.size(); ++i)
329 if (m_indices[i] < elements.size())
330 sorted[i] = elements[m_indices[i]];
336 inline TreeBase& operator=(
const TreeBase& value)
338 m_indices = value.m_indices;
339 m_nodes = value.m_nodes;
340 m_available_node_positions = value.m_available_node_positions;
341 m_available_indexed_positions = value.m_available_indexed_positions;
344 inline TreeBase& operator=(TreeBase&& value)
346 std::swap(m_indices, value.m_indices);
347 std::swap(m_nodes, value.m_nodes);
348 std::swap(m_available_node_positions, value.m_available_node_positions);
349 std::swap(m_available_indexed_positions, value.m_available_indexed_positions);
353 template<
bool t_use_values>
354 Buffer<uint04> prepareAddAll(
const Buffer<bool>& index_values)
356 uint04 index_count = index_values.count(
true);
357 Buffer<uint04> indices(t_use_values ? index_count : index_values.size() - index_count);
358 for (
uint04 i = 0; i < index_values.size(); i++)
359 if (t_use_values == index_values[i])
363 template<
class t_buffer_type>
364 Buffer<uint04> prepareAddAll(
uint04 start_index,
uint04 end_index,
const t_buffer_type& elements)
366 Buffer<uint04> indices(end_index - start_index);
367 for (
uint04 i = start_index; i < end_index; i++)
375 uint04 getNumberOfFreeIndices()
377 return m_available_indexed_positions.size() * m_bucket_size;
380 uint04 getNumberOfFreeNodes()
382 return m_available_node_positions.size() * t_node_child_size;
385 void splitLeafNode(
uint04 index)
388 if (m_available_node_positions.size() == 0)
390 child_node_index = m_nodes.size();
391 m_nodes.add(t_node_type(m_nodes[index].begin()));
392 for (
uint04 i = 0; i < t_node_child_size - 1; ++i)
394 if (m_available_indexed_positions.size() == 0)
396 m_nodes.add(t_node_type(m_indices.size()));
397 m_indices.addSpace<
true>(m_bucket_size);
401 m_nodes.add(t_node_type(m_available_indexed_positions.last()));
402 m_available_indexed_positions.removeLast();
408 child_node_index = m_available_node_positions.last();
409 m_available_node_positions.removeLast();
411 m_nodes[child_node_index + 0].clear(m_nodes[index].begin());
412 for (
uint04 i = 1; i < t_node_child_size; ++i)
414 if (m_available_indexed_positions.size() == 0)
416 m_nodes[child_node_index + i].clear(m_indices.size());
417 m_indices.addSpace<
true>(m_bucket_size);
421 m_nodes[child_node_index + i].clear(m_available_indexed_positions.last());
422 m_available_indexed_positions.removeLast();
426 m_nodes[index].setChildNodeStart(child_node_index);
429 void reclaimChildren(
uint04 index)
431 if (!m_nodes[index].isLeaf())
433 TreeIterator iterator(index);
434 while (iterator.valid())
436 uint04 i = iterator.get();
438 if (m_nodes[i].isLeaf())
440 lib_assert(!m_available_indexed_positions.contains(m_nodes[i].begin()),
"Bad contains");
441 m_available_indexed_positions.add(m_nodes[i].begin());
445 m_available_node_positions.add(m_nodes[i].childNodeStart());
446 iterator.addAndGoToIndex(m_nodes[i].left(), m_nodes[i].right());
449 m_nodes[index].setBegin(m_available_indexed_positions.last());
450 m_available_indexed_positions.removeLast();
454 template<
bool t_is_presorted,
bool t_set_true>
455 void _getAllT(
const uint04& node_index, Buffer<bool>& indices)
const
457 TreeIterator iterator(node_index);
458 while (iterator.valid())
460 const t_node_type& node = m_nodes[iterator.get()];
464 const uint04 end = node.end();
465 for (
uint04 i = node.begin(); i < end; i++)
467 if constexpr (t_is_presorted)
468 indices[i] = t_set_true;
470 indices[m_indices[i]] = t_set_true;
475 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
479 template<
bool t_is_presorted>
480 void _getAll(
const uint04& node_index, Buffer<uint04>& indices)
const
482 TreeIterator iterator(node_index);
483 while (iterator.valid())
485 const t_node_type& node = m_nodes[iterator.get()];
489 if constexpr (!t_is_presorted)
491 indices.addAll(m_indices.begin(node.begin()), node.size());
495 const uint04 end = node.begin() + node.size();
496 for(
uint04 i = node.begin(); i < end; i++)
501 iterator.addAndGoToIndices(node.childNodeStart(), t_node_child_size);
507 return m_indices.size();
511 return m_nodes.size();
514 Buffer<uint04> m_indices;
515 PrimitiveBuffer<t_node_type> m_nodes;
516 Buffer<uint04> m_available_node_positions;
517 Buffer<uint04> m_available_indexed_positions;
518 static const uint04 root_node = 0;
522 template<u
int01 t_dims,
class t_type,
class t_child_tree>
523 class Tree :
public t_child_tree
526 explicit Tree(
uint04 bucket_size)
527 : t_child_tree(bucket_size)
529 Tree(
const t_child_tree& tree)
532 Tree(t_child_tree&& tree)
533 : t_child_tree(std::move(tree))
536 void getAll(Buffer<bool>& indices)
const
538 if (t_child_tree::m_indices.size() == 0)
539 t_child_tree::template _getAllT<true, true>(t_child_tree::root_node, indices);
541 t_child_tree::template _getAllT<false, true>(t_child_tree::root_node, indices);
544 void getAll(Buffer<uint04>& indices)
const
546 if (t_child_tree::m_indices.size() == 0)
547 t_child_tree::template _getAll<true>(t_child_tree::root_node, indices);
549 t_child_tree::template _getAll<false>(t_child_tree::root_node, indices);
551 template<
class t_reference_type,
class t_buffer_type>
552 uint04 closestElement(
const t_reference_type& point,
const t_buffer_type& elements, t_type epsilon =
cast<t_type>(0))
const
554 t_type max_distance = Constant<t_type>::Max;
555 return closestElement(point, elements, max_distance, epsilon);
557 template<
class t_reference_type,
class t_buffer_type>
558 uint04 closestElement(
const t_reference_type& point,
const t_buffer_type& elements, t_type& max_distance_squared, t_type epsilon =
cast<t_type>(0))
const
560 uint04 index = Constant<uint04>::Invalid;
561 if (t_child_tree::m_indices.size() == 0)
562 t_child_tree::template _getClosestElement<true>(t_child_tree::root_node, point, elements, max_distance_squared, epsilon, index);
564 t_child_tree::template _getClosestElement<false>(t_child_tree::root_node, point, elements, max_distance_squared, epsilon, index);
567 template<
class t_reference_type,
class t_buffer_type>
568 uint04 closestElementPresorted(
const t_reference_type& point,
const t_buffer_type& elements, t_type epsilon =
cast<t_type>(0))
const
570 t_type max_distance = Constant<t_type>::Max;
571 return closestElementPresorted(point, elements, max_distance, epsilon);
573 template<
class t_reference_type,
class t_buffer_type>
574 uint04 closestElementPresorted(
const t_reference_type& point,
const t_buffer_type& elements, t_type& max_distance_squared, t_type epsilon =
cast<t_type>(0))
const
576 uint04 index = Constant<uint04>::Invalid;
577 t_child_tree::template _getClosestElement<true>(t_child_tree::root_node, point, elements, max_distance_squared, epsilon, index);
580 template<
class t_area_type,
class t_buffer_type>
581 void enclosedElements(
const t_area_type& area, Buffer<uint04>& indices,
const t_buffer_type& elements)
const
583 if (t_child_tree::m_indices.size() == 0)
584 t_child_tree::template _getEnclosedElements<true>(t_child_tree::root_node, area, indices, elements);
586 t_child_tree::template _getEnclosedElements<false>(t_child_tree::root_node, area, indices, elements);
588 template<
class t_area_type,
class t_buffer_type>
589 void presortedEnclosedElements(
const t_area_type& area, Buffer<uint04>& indices,
const t_buffer_type& elements)
const
591 t_child_tree::template _getEnclosedElements<true>(t_child_tree::root_node, area, indices, elements);
595 template<
class t_area_type,
class t_buffer_type>
596 void getChangedElements(
const t_area_type& new_area,
const t_area_type& old_area, Buffer<bool>& indices,
const t_buffer_type& elements,
bool allow_enable,
bool allow_disable)
const
598 if (allow_enable && allow_disable)
600 if (t_child_tree::m_indices.size() == 0)
601 t_child_tree::template _getChangedElements<true, true, true>(t_child_tree::root_node, new_area, old_area, indices, elements);
603 t_child_tree::template _getChangedElements<false, true, true>(t_child_tree::root_node, new_area, old_area, indices, elements);
605 else if (allow_enable)
607 if (t_child_tree::m_indices.size() == 0)
608 t_child_tree::template _getChangedElements<true, true, false>(t_child_tree::root_node, new_area, old_area, indices, elements);
610 t_child_tree::template _getChangedElements<false, true, false>(t_child_tree::root_node, new_area, old_area, indices, elements);
612 else if (allow_disable)
614 if (t_child_tree::m_indices.size() == 0)
615 t_child_tree::template _getChangedElements<true, false, true>(t_child_tree::root_node, new_area, old_area, indices, elements);
617 t_child_tree::template _getChangedElements<false, false, true>(t_child_tree::root_node, new_area, old_area, indices, elements);
620 template<
class t_area_type,
class t_buffer_type>
621 void enclosedElements(
const t_area_type& area, Buffer<bool>& indices,
const t_buffer_type& elements)
const
623 if (t_child_tree::m_indices.size() == 0)
624 t_child_tree::template _getEnclosedElements<true>(t_child_tree::root_node, area, indices, elements);
626 t_child_tree::template _getEnclosedElements<false>(t_child_tree::root_node, area, indices, elements);
628 template<
class t_area_type,
class t_buffer_type>
629 void nearElements(
const t_area_type& area, Buffer<uint04>& indices,
const t_buffer_type& elements, t_type max_distance_sqrd)
const
631 if (t_child_tree::m_indices.size() == 0)
632 t_child_tree::template _getNearElements<true>(t_child_tree::root_node, area, indices, elements, max_distance_sqrd);
634 t_child_tree::template _getNearElements<false>(t_child_tree::root_node, area, indices, elements, max_distance_sqrd);
636 template<
class t_area_type,
class t_buffer_type>
637 uint04 getNumberOfEnclosedElements(
const t_area_type& area,
const t_buffer_type& elements)
const
639 return t_child_tree::_getNumberOfEnclosedElements(t_child_tree::root_node, area, elements);
642 template<
class t_reference_type,
class t_buffer_type>
643 void closestElements(
const t_reference_type& point,
uint04 size, Buffer<uint04>& indices,
const t_buffer_type& elements, t_type& max_distance, t_type epsilon =
cast<t_type>(0))
const
647 uint04 index = closestElement(point, elements, max_distance, epsilon);
652 MaxHeap<t_type, uint04> heap(size + 1);
653 if(t_child_tree::m_indices.size() == 0)
654 t_child_tree::template _getClosestElements<true>(t_child_tree::root_node, point, elements, max_distance, epsilon, heap, size);
656 t_child_tree::template _getClosestElements<false>(t_child_tree::root_node, point, elements, max_distance, epsilon, heap, size);
657 indices.addAll(heap.sortedIndices());
660 template<
class t_reference_type,
class t_buffer_type>
661 void closestElements(
const t_reference_type& point,
uint04 size, MaxHeap<t_type, uint04>& value_heap,
const t_buffer_type& elements, t_type& max_distance, t_type epsilon =
cast<t_type>(0))
const
663 t_child_tree::template _getClosestElements<false>(t_child_tree::root_node, point, elements, max_distance, epsilon, value_heap, size);
665 template<
class t_reference_type,
class t_buffer_type>
666 void presortedClosestElements(
const t_reference_type& point,
uint04 size, MaxHeap<t_type, uint04>& value_heap,
const t_buffer_type& elements, t_type& max_distance, t_type epsilon =
cast<t_type>(0))
const
668 t_child_tree::template _getClosestElements<true>(t_child_tree::root_node, point, elements, max_distance, epsilon, value_heap, size);
672 t_child_tree::m_indices.swapAllElements(index_a, index_b);
676 template<
bool t_has_nans,
bool t_uses_boundary,
class t_buffer_type>
677 void addValue(
uint04 index,
const t_buffer_type& elements,
bool rebalance)
679 t_child_tree::template _addValue<t_has_nans, t_uses_boundary>(t_child_tree::root_node, index, elements, rebalance);
682 template<
bool t_has_nans,
bool t_uses_boundary,
class t_buffer_type>
683 void addValues(
const Buffer<bool>& insertion_indices,
const t_buffer_type& elements,
bool is_precise)
685 if (t_child_tree::useBulkResize(insertion_indices.count(
true)))
687 t_child_tree::template _addValues<t_has_nans, t_uses_boundary>(t_child_tree::root_node, t_child_tree::template prepareAddAll<true>(insertion_indices), elements, is_precise);
691 for (
uint04 i = 0; i < elements.size(); i++)
693 if (insertion_indices[i])
694 addValue<t_has_nans, t_uses_boundary>(i, elements);
698 template<
bool t_has_nans,
bool t_uses_boundary,
class t_buffer_type>
699 void addValues(
const t_buffer_type& elements,
bool is_precise)
701 addValues<t_has_nans, t_uses_boundary>(0, elements.size(), elements, is_precise);
703 template<
bool t_has_nans,
bool t_uses_boundary,
class t_buffer_type>
704 void addValues(
uint04 start_index,
uint04 end_index,
const t_buffer_type& elements,
bool is_precise)
706 if (t_child_tree::useBulkResize(end_index - start_index))
708 t_child_tree::template _addValues<t_has_nans, t_uses_boundary>(t_child_tree::root_node, t_child_tree::prepareAddAll(start_index, end_index, elements), elements, is_precise);
712 for (
uint04 i = start_index; i < end_index; i++)
714 if constexpr (t_has_nans)
719 addValue<t_has_nans, t_uses_boundary>(i, elements, is_precise);
724 template<
bool t_has_nans,
bool t_uses_boundary,
class t_buffer_type>
725 void addValues(
const Buffer<uint04>& indices,
const t_buffer_type& elements,
bool is_precise)
727 if (t_child_tree::useBulkResize(indices.size()))
729 t_child_tree::template _addValues<t_has_nans, t_uses_boundary>(t_child_tree::root_node, indices, elements, is_precise);
733 for (
uint04 i = 0; i < indices.size(); i++)
735 addValue<t_has_nans, t_uses_boundary>(indices[i], elements, is_precise);
742 template<
class t_buffer_type>
743 void removeValue(
uint04 index,
const t_buffer_type& elements)
745 t_child_tree::_removeValue(t_child_tree::root_node, index, elements);
748 template<
class t_buffer_type>
749 void removeValues(
const Buffer<bool>& insertion_indices,
const t_buffer_type& elements)
751 if (t_child_tree::useBulkResize(insertion_indices.count(
true)))
753 t_child_tree::clear();
754 t_child_tree::_addValues(t_child_tree::root_node, t_child_tree::template prepareAddAll<false>(insertion_indices), elements);
758 for (
uint04 i = 0; i < elements.size(); i++)
760 if (insertion_indices[i])
761 t_child_tree::removeValue(i, elements);
766 template<
class t_buffer_type>
767 void removeValues(
uint04 start_index,
uint04 end_index,
const t_buffer_type& elements)
769 if (t_child_tree::useBulkResize(end_index - start_index))
771 t_child_tree::clear();
772 Buffer<uint04> indices(elements.size() - (end_index - start_index));
773 for (
uint04 i = 0; i < start_index; i++)
775 for (
uint04 i = end_index; i < elements.size(); i++)
777 t_child_tree::_addValues(t_child_tree::root_node, indices, elements);
781 for (
uint04 i = start_index; i < end_index; i++)
783 removeValue(i, elements);
812 virtual const char* getTreeType()
const = 0;
The primary namespace for the NDEVR SDK.
static constexpr bool IsValid(const Angle< t_type > &value)
Checks whether the given Angle holds a valid value.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
constexpr HSLColor Constant< HSLColor >::Min
The minimum HSLColor constant with saturation, brightness, and alpha at zero.
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.