6std::vector<int> TetrahedralTree::emptyBlock = {};
17 : m_origin(origin), m_halfDimension(halfDimension) {
18 m_min.x = origin.
x - halfDimension.
x;
19 m_min.y = origin.
y - halfDimension.
y;
20 m_min.z = origin.
z - halfDimension.
z;
21 m_max.x = origin.
x + halfDimension.
x;
22 m_max.y = origin.
y + halfDimension.
y;
23 m_max.z = origin.
z + halfDimension.
z;
26 for (
int i = 0; i < 8; ++i) children[i] =
nullptr;
31 for (
int i = 0; i < 8; ++i)
delete children[i];
35bool TetrahedralTree::DoesBoxOverlap(
const double bb[6])
const {
36 if (m_max.
x < bb[0] || m_max.
y < bb[1] || m_max.
z < bb[2])
return false;
37 if (m_min.
x > bb[3] || m_min.
y > bb[4] || m_min.
z > bb[5])
return false;
42int TetrahedralTree::GetOctantContainingPoint(
const Vec3& point)
const {
44 if (point.x >= m_origin.
x) oct |= 4;
45 if (point.y >= m_origin.
y) oct |= 2;
46 if (point.z >= m_origin.
z) oct |= 1;
50bool TetrahedralTree::IsLeafNode()
const {
53 return children[0] ==
nullptr;
61 int octant = GetOctantContainingPoint(point);
62 children[octant]->InsertMeshNode(point, index);
67 if (nodes.size() < BlockCapacity) {
68 nodes.push_back(std::make_pair(point, index));
73 for (
int i = 0; i < 8; ++i) {
75 Vec3 newOrigin = m_origin;
76 newOrigin.
x += m_halfDimension.x * (i & 4 ? .5f : -.5f);
77 newOrigin.
y += m_halfDimension.y * (i & 2 ? .5f : -.5f);
78 newOrigin.
z += m_halfDimension.z * (i & 1 ? .5f : -.5f);
84 while (!nodes.empty()) {
85 auto node = nodes.back();
87 const int oct = GetOctantContainingPoint(node.first);
88 children[oct]->InsertMeshNode(node.first, node.second);
91 children[GetOctantContainingPoint(point)]->InsertMeshNode(point, index);
97 elements.push_back(index);
101 for (
int i = 0; i < 8; i++) {
102 if (!children[i]->DoesBoxOverlap(bb))
continue;
103 children[i]->InsertMeshElement(bb, index);
114 return octreeNode->elements;
126 const Vec3& point)
const {
127 if (!(m_min.
x <= point.
x && point.
x <= m_max.
x &&
128 m_min.
y <= point.
y && point.
y <= m_max.
y &&
129 m_min.
z <= point.
z && point.
z <= m_max.
z))
132 return GetBlockFromPointHelper(point);
135const TetrahedralTree* TetrahedralTree::GetBlockFromPointHelper(
136 const Vec3& point)
const {
138 if (IsLeafNode())
return this;
141 int octant = GetOctantContainingPoint(point);
142 return children[octant]->GetBlockFromPointHelper(point);
Helper class for searches in field maps.
void InsertMeshElement(const double bb[6], const int index)
Insert a mesh element with given bounding box and index to the tree.
~TetrahedralTree()
Destructor.
TetrahedralTree(const Vec3 &origin, const Vec3 &halfDimension)
Constructor.
void InsertMeshNode(Vec3 point, const int index)
Insert a mesh node (a vertex/point) to the tree.
const std::vector< int > & GetElementsInBlock(const Vec3 &point) const
Get all elements linked to a block corresponding to the given point.