Nektar++
Octree.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: Octree.h
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Octree header.
32//
33///////////////////////////////////////////////////////////////////////////////
34
36#include <limits>
37#include <memory>
38#include <vector>
39
40namespace Nektar::FieldUtils
41{
42
43class Octree
44{
45 class Octant;
46 using OctantSharedPtr = std::shared_ptr<Octant>;
47 using OctantWeakPtr = std::weak_ptr<Octant>;
48
49public:
50 // Empty constructor
51 Octree();
52 // Constructor with bounds
53 Octree(const Array<OneD, Array<OneD, NekDouble>> &pts, int maxPts,
54 const Array<OneD, NekDouble> &bounds);
55 // Constructor without bounds
56 Octree(const Array<OneD, Array<OneD, NekDouble>> &pts, int maxPts);
57
58 // Returns the ID of the leaf node that contains 'coords'
59 int QueryNode(const Array<OneD, NekDouble> &coords,
60 int depth = std::numeric_limits<int>::max());
61 // Returns the ID of the point in 'pts' closest to 'coords'
63 const Array<OneD, NekDouble> &coords, double &distance,
64 int pointInd = -1);
65
66 // Returns the ID of the points inside the node 'nodeID'
67 std::vector<int> QueryPoints(int nodeID);
68 // Returns the IDs of the leaf nodes neighbouring 'nodeID'
69 std::vector<int> QueryNeighbours(int nodeID);
70
71 int QueryNpoints(int nodeID)
72 {
73 return m_nodes[nodeID]->GetNpoints();
74 }
75 int QueryLocation(int nodeID)
76 {
77 return m_nodes[nodeID]->GetLoc();
78 }
79 int QueryDepth(int nodeID)
80 {
81 return m_nodes[nodeID]->GetDepth();
82 }
83 int QueryDelta(int nodeID)
84 {
85 return m_nodes[nodeID]->GetDelta();
86 }
87
88 // Get some statistics about the octree
89 void GetStats(int &maxPts, int &nPts, int &nNodes, int &nLeaves,
90 int &depth);
91
92private:
93 class Octant : public std::enable_shared_from_this<Octant>
94 {
95 public:
96 // Empty constructor
97 Octant();
98 // Constructor
99 Octant(int loc, int depth, int id,
100 const Array<OneD, NekDouble> &bounds);
101 // Copy constructor
102 Octant(int loc, Octant &parent);
103
104 int GetNpoints() const
105 {
106 return m_nPts;
107 }
108 int GetLoc() const
109 {
110 return m_loc;
111 }
112 int GetDepth() const
113 {
114 return m_depth;
115 }
116 double GetDelta() const
117 {
118 return m_delta;
119 }
120 int GetID() const
121 {
122 return m_id;
123 }
124 bool IsLeaf() const
125 {
126 return m_isLeaf;
127 }
129 {
130 return m_centre;
131 }
133 {
134 return m_bounds;
135 }
136 std::vector<int> &GetIndices()
137 {
138 return m_pointInd;
139 }
141 {
142 return m_children;
143 }
144 std::vector<OctantWeakPtr> &GetNeighbours()
145 {
146 return m_neighbours;
147 }
148
149 void SetID(int id)
150 {
151 m_id = id;
152 }
153
154 void GetLeaves(std::vector<OctantSharedPtr> &leaves);
155 void SetIndices(const std::vector<int> &indices);
156 void AddNeighbours(const std::vector<OctantSharedPtr> &neighbours);
157 void AddPoints(const Array<OneD, Array<OneD, NekDouble>> &pts,
158 const std::vector<int> &indices);
159 void Subdivide(int maxPts,
160 const Array<OneD, Array<OneD, NekDouble>> &pts,
161 std::vector<OctantSharedPtr> &nodes);
162 int GetLocInNode(const Array<OneD, NekDouble> &coords);
163
164 private:
165 /// Number of points in the octant
167 /// Position in the father octant (1-8)
168 int m_loc;
169 /// Depth in octree (root is 1)
171 /// ID of the octant (index in 'm_nodes' vector)
172 int m_id;
173 /// Length of the octant side
174 double m_delta;
175 /// Coordinates of the centre of the octant
177 /// Min/max coordinates of the octant (x, y, z)
179 /// Indices of the points comprised by the octant
180 std::vector<int> m_pointInd;
181 /// True for a leaf octant, false otherwise
183
184 /// Vector of pointers to the children octants
186 /// Vector of pointers to the neighbouring octants
187 std::vector<OctantWeakPtr> m_neighbours;
188 };
189
190 /// Max points allowed in each octant
192 /// Number of points in the mesh
194 /// Number of octants in the tree
196 /// Number of leaf nodes in the tree
198 /// Maximum depth of the tree
200
201 /// First node of the tree, linked to the rest
203 /// Vector of pointers to every octant in the tree
204 std::vector<OctantSharedPtr> m_nodes;
205
206 void AdvanceToStats(int nodeID);
207 void SetNeighbours(int nodeID);
208};
209} // namespace Nektar::FieldUtils
std::vector< OctantWeakPtr > & GetNeighbours()
Definition: Octree.h:144
Array< OneD, NekDouble > & GetCentre()
Definition: Octree.h:128
Array< OneD, NekDouble > m_centre
Coordinates of the centre of the octant.
Definition: Octree.h:176
void AddPoints(const Array< OneD, Array< OneD, NekDouble > > &pts, const std::vector< int > &indices)
Adds to 'm_pointInd' the IDs of the points in 'pts' that fall inside the octant.
Definition: Octree.cpp:554
Array< OneD, OctantSharedPtr > & GetChildren()
Definition: Octree.h:140
int m_depth
Depth in octree (root is 1)
Definition: Octree.h:170
double m_delta
Length of the octant side.
Definition: Octree.h:174
void AddNeighbours(const std::vector< OctantSharedPtr > &neighbours)
Adds to 'm_neighbours' the octants that are not already in the list.
Definition: Octree.cpp:526
int m_loc
Position in the father octant (1-8)
Definition: Octree.h:168
void GetLeaves(std::vector< OctantSharedPtr > &leaves)
Updates 'leaves' so that it contains all the leaf nodes belonging to the octant.
Definition: Octree.cpp:492
void SetIndices(const std::vector< int > &indices)
Sets the values of 'm_pointInd' to those in 'indices'.
Definition: Octree.cpp:512
std::vector< int > m_pointInd
Indices of the points comprised by the octant.
Definition: Octree.h:180
std::vector< OctantWeakPtr > m_neighbours
Vector of pointers to the neighbouring octants.
Definition: Octree.h:187
int m_nPts
Number of points in the octant.
Definition: Octree.h:166
void Subdivide(int maxPts, const Array< OneD, Array< OneD, NekDouble > > &pts, std::vector< OctantSharedPtr > &nodes)
Recursively divides the octant into 8 children and fills the leaf nodes with their corresponding poin...
Definition: Octree.cpp:591
Array< OneD, NekDouble > m_bounds
Min/max coordinates of the octant (x, y, z)
Definition: Octree.h:178
bool m_isLeaf
True for a leaf octant, false otherwise.
Definition: Octree.h:182
std::vector< int > & GetIndices()
Definition: Octree.h:136
int GetLocInNode(const Array< OneD, NekDouble > &coords)
Returns the position inside an octant in the range (1-8). The name convention is as follows: let be ...
Definition: Octree.cpp:634
Array< OneD, NekDouble > & GetBounds()
Definition: Octree.h:132
int m_id
ID of the octant (index in 'm_nodes' vector)
Definition: Octree.h:172
Array< OneD, OctantSharedPtr > m_children
Vector of pointers to the children octants.
Definition: Octree.h:185
Octant()
Construct a new Octree::Octant object.
Definition: Octree.cpp:358
void SetNeighbours(int nodeID)
Once the nodes of the octree are created, sets their neighbours as explained in 'Octree::QueryNeighbo...
Definition: Octree.cpp:312
int QueryDepth(int nodeID)
Definition: Octree.h:79
OctantSharedPtr m_root
First node of the tree, linked to the rest.
Definition: Octree.h:202
std::vector< int > QueryNeighbours(int nodeID)
Returns the IDs of the octants that surround the queried node. First, it finds the neighbouring nodes...
Definition: Octree.cpp:250
std::vector< int > QueryPoints(int nodeID)
Returns the indices of the points of the mesh contained in the tree.
Definition: Octree.cpp:235
int m_nNodes
Number of octants in the tree.
Definition: Octree.h:195
void GetStats(int &maxPts, int &nPts, int &nNodes, int &nLeaves, int &depth)
Returns some characteristic values of the tree.
Definition: Octree.cpp:269
int m_nLeaves
Number of leaf nodes in the tree.
Definition: Octree.h:197
std::shared_ptr< Octant > OctantSharedPtr
Definition: Octree.h:46
int QueryClosest(const Array< OneD, Array< OneD, NekDouble > > &pts, const Array< OneD, NekDouble > &coords, double &distance, int pointInd=-1)
Finds the ID of the closest point in 'pts' to the one specified by 'coords'. It also returns the dist...
Definition: Octree.cpp:176
std::weak_ptr< Octant > OctantWeakPtr
Definition: Octree.h:47
int m_maxPts
Max points allowed in each octant.
Definition: Octree.h:191
int m_maxDepth
Maximum depth of the tree.
Definition: Octree.h:199
int QueryDelta(int nodeID)
Definition: Octree.h:83
int QueryLocation(int nodeID)
Definition: Octree.h:75
void AdvanceToStats(int nodeID)
Goes through all the nodes of the octree counting the number of octants and the maximum depth reached...
Definition: Octree.cpp:285
int QueryNpoints(int nodeID)
Definition: Octree.h:71
Octree()
Construct a new octree object.
Definition: Octree.cpp:46
int m_nMshPts
Number of points in the mesh.
Definition: Octree.h:193
std::vector< OctantSharedPtr > m_nodes
Vector of pointers to every octant in the tree.
Definition: Octree.h:204
int QueryNode(const Array< OneD, NekDouble > &coords, int depth=std::numeric_limits< int >::max())
Given the coordinates 'coords' of a point, returns the leaf octant that contains it....
Definition: Octree.cpp:137