2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2013 enGits GmbH +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "pointfinder.h"
25 PointFinder::PointFinder()
31 void PointFinder::setGrid(vtkUnstructuredGrid
*grid
)
33 QVector
<vec3_t
> points(grid
->GetNumberOfPoints());
34 for (vtkIdType id_node
= 0; id_node
< grid
->GetNumberOfPoints(); ++id_node
) {
35 grid
->GetPoint(id_node
, points
[id_node
].data());
40 void PointFinder::setPoints(const QVector
<vec3_t
> &points
)
44 vec3_t
x1(1e99
, 1e99
, 1e99
);
45 vec3_t
x2(-1e99
, -1e99
, -1e99
);
46 foreach (vec3_t x
, m_Points
) {
47 x1
[0] = min(x
[0], x1
[0]);
48 x1
[1] = min(x
[1], x1
[1]);
49 x1
[2] = min(x
[2], x1
[2]);
50 x2
[0] = max(x
[0], x2
[0]);
51 x2
[1] = max(x
[1], x2
[1]);
52 x2
[2] = max(x
[2], x2
[2]);
54 vec3_t xc
= 0.5*(x1
+ x2
);
57 if (fabs(Dx1
[0]) >= fabs(Dx1
[1]) && fabs(Dx1
[0]) >= fabs(Dx1
[2])) {
58 Dx1
= vec3_t(Dx1
[0], Dx1
[0], Dx1
[0]);
59 } else if (fabs(Dx1
[1]) >= fabs(Dx1
[0]) && fabs(Dx1
[1]) >= fabs(Dx1
[2])) {
60 Dx1
= vec3_t(Dx1
[1], Dx1
[1], Dx1
[1]);
62 Dx1
= vec3_t(Dx1
[2], Dx1
[2], Dx1
[2]);
64 if (fabs(Dx2
[0]) >= fabs(Dx2
[1]) && fabs(Dx2
[0]) >= fabs(Dx2
[2])) {
65 Dx2
= vec3_t(Dx2
[0], Dx2
[0], Dx2
[0]);
66 } else if (fabs(Dx2
[1]) >= fabs(Dx2
[0]) && fabs(Dx2
[1]) >= fabs(Dx2
[2])) {
67 Dx2
= vec3_t(Dx2
[1], Dx2
[1], Dx2
[1]);
69 Dx2
= vec3_t(Dx2
[2], Dx2
[2], Dx2
[2]);
72 if (Dx2
.abs() > Dx1
.abs()) {
77 m_Octree
.setBounds(x1
, x2
);
78 m_MinSize
= 0.0001*Dx
[0];
81 for (int i_points
= 0; i_points
< points
.size(); ++i_points
) {
82 m_Buckets
[0].append(i_points
);
89 m_MinBucketSize
= points
.size();
90 for (int i
= 0; i
< m_Buckets
.size(); ++i
) {
91 m_MinBucketSize
= min(m_MinBucketSize
, m_Buckets
[i
].size());
92 m_MaxBucketSize
= max(m_MaxBucketSize
, m_Buckets
[i
].size());
96 int PointFinder::refine()
98 int N
= m_Octree
.getNumCells();
99 m_Octree
.setSmoothTransitionOff();
101 m_Octree
.resetRefineMarks();
102 for (int cell
= 0; cell
< m_Octree
.getNumCells(); ++cell
) {
103 double dx
= m_Octree
.getDx(cell
);
104 if (!m_Octree
.hasChildren(cell
) && m_Buckets
[cell
].size() > m_MaxPoints
&& dx
> 2*m_MinSize
) {
105 m_Octree
.markToRefine(cell
);
110 for (int cell
= 0; cell
< m_Octree
.getNumCells(); ++cell
) {
111 if (m_Octree
.markedForRefine(cell
)) {
116 m_Octree
.refineAll();
117 if (m_Octree
.getNumCells() != N
+ N_new
) {
120 m_Buckets
.insert(N
, N_new
, QList
<int>());
121 for (int cell
= N
; cell
< m_Octree
.getNumCells(); ++cell
) {
122 m_Timer
<< " " << m_Octree
.getNumCells() << " octree cells" << Timer::endl
;
123 if (m_Octree
.getNumCells() != N
+ N_new
) {
126 int parent
= m_Octree
.getParent(cell
);
130 foreach (int i_points
, m_Buckets
[parent
]) {
131 vec3_t xcell
= m_Octree
.getCellCentre(cell
);
132 vec3_t x
= m_Points
[i_points
];
135 double Dx
= m_Octree
.getDx(cell
);
136 double Dy
= m_Octree
.getDy(cell
);
137 double Dz
= m_Octree
.getDz(cell
);
138 if (x
[0] < xcell
[0] - 1.5*Dx
|| x
[0] > xcell
[0] + 1.5*Dx
) append
= false;
139 else if (x
[1] < xcell
[1] - 1.5*Dy
|| x
[1] > xcell
[1] + 1.5*Dy
) append
= false;
140 else if (x
[2] < xcell
[2] - 1.5*Dz
|| x
[2] > xcell
[2] + 1.5*Dz
) append
= false;
143 m_Buckets
[cell
].append(i_points
);
150 void PointFinder::getClosePoints(vec3_t x
, QVector
<int> &points
, double dist
)
152 int cell
= m_Octree
.findCell(x
);
156 if (m_Octree
.hasChildren(cell
)) {
159 while ((m_Buckets
[cell
].size() == 0 || dist
> m_Octree
.getDx(cell
)) && m_Octree
.getParent(cell
) >= 0) {
160 cell
= m_Octree
.getParent(cell
);
162 points
.resize(m_Buckets
[cell
].size());
163 qCopy(m_Buckets
[cell
].begin(), m_Buckets
[cell
].end(), points
.begin());
167 void PointFinder::writeOctreeMesh(QString file_name
)
169 EG_VTKSP(vtkUnstructuredGrid
, otg
);
170 m_Octree
.toVtkGrid(otg
);
171 writeGrid(otg
, file_name
);