1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26 #include "egvtkobject.h"
28 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
39 vec3_t
& getPosition() { return m_Position
; }
40 void setPosition(const vec3_t
& x
) { m_Position
= x
; }
44 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 * A cell of an octree.<br/>
49 * <b>The node numbering is as follows:</b><br/>
60 * <b>The face numbering is as follows:</b><br/>
69 * Child cells are numbered in the same way as the nodes.
86 int getNode (int i
) { return m_Node
[i
]; }
87 bool hasChildren () { return m_Child
[0] != -1; }
88 int getParent () { return m_Parent
; }
89 int getNeighbour(int i
) { return m_Neighbour
[i
]; }
92 * Find a node by global index.
93 * @param octree the octree which holds this cell
94 * @param the global node index in the octree
95 * @return the local node index (0-7)
97 int findNode(int i_node
);
100 * Get the 'middle' node of an edge.
101 * @param octree the octree which holds this cell
102 * @param n1 the first node of the edge in local coordinates (0 <= n1 <= 7)
103 * @param n2 the second node of the edge in local coordinates (0 <= n2 <= 7)
104 * @param this_cell_only if set to true the search will be restricted to this cell
106 int getEdgeNode(Octree
* octree
, int n1
, int n2
, bool this_cell_only
= false);
108 void getFaceNodes(int i
, Octree
* octree
, QVector
<int>& face_nodes
, bool reverse
= false);
110 void getFaceNodes(int i
, Octree
* octree
, QVector
<QVector
<int> >& face_nodes
, bool reverse
= false);
115 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
117 class Octree
: public EgVtkObject
120 friend class OctreeCell
;
130 private: // attributes
132 vec3_t m_Origin
; ///< origin of internal coordinate system
133 mat3_t m_Base
; ///< base vectors of internal coordinate system
134 mat3_t m_InvBase
; ///< inverted base of internal coordiante system
135 vec3_t m_Corner1
; ///< first corner of extend box of the whole domain (in internal coordinates)
136 vec3_t m_Corner2
; ///< second corner of extend box of the whole domain (in internal coordinates)
137 double m_Dx
; ///< extend in x direction
138 double m_Dy
; ///< extend in y direction
139 double m_Dz
; ///< extend in z direction
141 bool m_SmoothTransition
;
143 QVector
<OctreeNode
> m_Nodes
;
144 QVector
<OctreeCell
> m_Cells
;
145 QVector
<bool> m_ToRefine
;
146 QVector
<int> m_SameNodes
;
148 QVector
<QList
<int> > m_Node2Cell
;
152 void mergeNodes_identifyDuplicates();
153 void mergeNodes_compactNodes();
154 void mergeNodes_updateCells();
156 void checkNeighbours();
157 void buildNode2Cell();
159 int opposingFace(int i
);
166 void setOrigin(vec3_t x0
);
167 void setBase(vec3_t g1
, vec3_t g2
, vec3_t g3
);
168 void setBounds(vec3_t corner1
, vec3_t corner2
, int num_i
= 1, int num_j
= 1, int num_k
= 1);
170 int getNeighbour(int cell
, int neigh
) { return m_Cells
[cell
].m_Neighbour
[neigh
]; }
171 void getFinestChildren(int cell
, QList
<int> &finest_children
);
173 void markToRefine(int cell
);
174 void markAllToRefine();
175 bool markedForRefine(int cell
) { return m_ToRefine
[cell
]; }
177 void resetRefineMarks();
178 void setSmoothTransitionOn() { m_SmoothTransition
= true; }
179 void setSmoothTransitionOff() { m_SmoothTransition
= false; }
181 vec3_t
getCellCentre(int cell
);
182 vec3_t
getFaceCentre(int i_cells
, int i_faces
);
183 vec3_t
getNodePosition(int cell
, int node
) { return m_Nodes
[m_Cells
[cell
].m_Node
[node
]].m_Position
; }
184 vec3_t
getNodePosition(int node
) { return m_Nodes
[node
].m_Position
; }
185 int getNode(int cell
, int node
) { return m_Cells
[cell
].m_Node
[node
]; }
186 int getNumCells() { return m_Cells
.size(); }
187 int getNumNodes() { return m_Nodes
.size(); }
188 void getEdges(int cell
, QVector
<SortedPair
<int> >& edges
);
189 int getLevel(int cell
) { return m_Cells
[cell
].m_Level
; }
190 double getDx(int cell
);
191 double getDy(int cell
);
192 double getDz(int cell
);
193 double getDx(const OctreeCell
& cell
);
194 double getDy(const OctreeCell
& cell
);
195 double getDz(const OctreeCell
& cell
);
196 bool hasChildren(int i_cells
) { return m_Cells
[i_cells
].m_Child
[0] != -1; }
197 int getParent(int cell
) { return m_Cells
[cell
].m_Parent
; }
198 int findCell(vec3_t x
);
199 bool intersectsFace(int cell
, int face
, vec3_t x1
, vec3_t x2
, double scale
, double &k
, double tol
= 1e-4);
200 void setMaxCells(int n
) { m_MaxCells
= n
; }
201 bool isInsideBounds(vec3_t x
);
202 bool isInsideCell(int cell
, vec3_t x
, double overlap
= 0);
205 * Convert the octree into a vtkUnstructuredGrid with hanging nodes.
206 * @param grid the resulting vtkUnstructuredGrid (object needs to be allocated before, but no space for cells and nodes)
207 * @param create_fields if this is set to true, the basic enGrid fields will be created
209 void toVtkGridHangingNodes(vtkUnstructuredGrid
*grid
, bool create_fields
= false);
212 * Convert the octree into a vtkUnstructuredGrid without hanging nodes.
213 * This method does currently not work for cells on the border of the octree domain.
214 * @param grid the resulting vtkUnstructuredGrid (object needs to be allocated before, but no space for cells and nodes)
215 * @param create_fields if this is set to true, the basic enGrid fields will be created
217 void toVtkGridConforming(vtkUnstructuredGrid
*grid
, bool create_fields
= false);
220 * Convert the octree into a vtkUnstructuredGrid with polyhedral cells.
221 * This method does currently not work for cells on the border of the octree domain.
222 * @param grid the resulting vtkUnstructuredGrid (object needs to be allocated before, but no space for cells and nodes)
223 * @param create_fields if this is set to true, the basic enGrid fields will be created
225 void toVtkGridPolyhedral(vtkUnstructuredGrid
*grid
, bool create_fields
= false);
228 * @brief Check if a triangle intersects a cell.
229 * @param cell the index of the octree cell
230 * @param tri the nodes of the triangle
231 * @return true if the triangle intersects the cell
233 bool triangleIntersectsCell(int cell
, QVector
<vec3_t
> tri
, double scale
);
236 * @brief get all cells which share at least one node with the current cell (and have no children)
237 * @param cell the index of the octree cell
238 * @param neighbour_cells a list which the neighbour cells will be added to
240 void getNeighbourRegion(int cell
, QList
<int> &neighbour_cells
);
245 inline double Octree::getDx(int cell
)
248 for (int i
= 0; i
< m_Cells
[cell
].m_Level
; ++i
) {
254 inline double Octree::getDx(const OctreeCell
& cell
)
257 for (int i
= 0; i
< cell
.m_Level
; ++i
) {
263 inline double Octree::getDy(int cell
)
266 for (int i
= 0; i
< m_Cells
[cell
].m_Level
; ++i
) {
272 inline double Octree::getDy(const OctreeCell
& cell
)
275 for (int i
= 0; i
< cell
.m_Level
; ++i
) {
281 inline double Octree::getDz(int cell
)
284 for (int i
= 0; i
< m_Cells
[cell
].m_Level
; ++i
) {
290 inline double Octree::getDz(const OctreeCell
& cell
)
293 for (int i
= 0; i
< cell
.m_Level
; ++i
) {