2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2012 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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 #include "sharpenedges.h"
25 #include "guimainwindow.h"
26 #include "laplacesmoother.h"
28 SharpenEdges::SharpenEdges()
31 m_PerformGeometricTests
= true;
32 m_UseProjectionForSmoothing
= true;
33 m_UseNormalCorrectionForSmoothing
= false;
34 m_AllowFeatureEdgeSwapping
= false;
35 m_RespectFeatureEdgesForDeleteNodes
= false;
36 m_FeatureAngle
= deg2rad(180);
37 m_EdgeAngle
= deg2rad(180);
38 m_FeatureAngleForDeleteNodes
= deg2rad(20);
39 m_NumDelaunaySweeps
= 5;
44 void SharpenEdges::assignBCs()
46 QVector
<int> bc_set(m_Grid
->GetNumberOfCells(),0);
47 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
48 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
49 bool certain_bc
= true;
50 vtkIdType N_pts
, *pts
;
51 m_Grid
->GetCellPoints(id_cell
, N_pts
, pts
);
52 for (int i
= 0; i
< N_pts
; ++i
) {
53 vtkIdType id_node
= pts
[i
];
54 for (int j
= 0; j
< m_Part
.n2cGSize(pts
[i
]); ++j
) {
55 if (cell_code
->GetValue(id_cell
) != cell_code
->GetValue(m_Part
.n2cGG(pts
[i
], j
))) {
62 bc_set
[id_cell
] = cell_code
->GetValue(id_cell
);
65 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
66 if (bc_set
[id_cell
] == 0) {
67 cell_code
->SetValue(id_cell
, 9999);
70 GuiMainWindow::pointer()->storeSurfaceProjection();
73 double scal_par
= 1.0;
76 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
77 if (bc_set
[id_cell
] == 0) {
79 vec3_t n1
= cellNormal(m_Grid
, id_cell
);
82 vtkIdType id_copy
= -1;
83 for (int i
= 0; i
< m_Part
.c2cGSize(id_cell
); ++i
) {
84 vtkIdType id_neigh
= m_Part
.c2cGG(id_cell
, i
);
85 vec3_t n2
= cellNormal(m_Grid
, id_neigh
);
89 bool parallel
= false;
90 if (scal
>= scal_par
&& cell_code
->GetValue(id_neigh
) < 9999) {
94 if (scal
> scal_max
|| parallel
) {
95 bc
= cell_code
->GetValue(id_neigh
);
100 bc_set
[id_cell
] = bc
;
101 cell_code
->SetValue(id_cell
, bc
);
106 cout
<< scal_par
<< ',' << N
<< endl
;
108 } while (N
> 0 && count
< 1000);
113 void SharpenEdges::assignBCs()
115 QVector<int> bc_set(m_Grid->GetNumberOfCells(),0);
116 QVector<int> bc_old(m_Grid->GetNumberOfCells(),0);
117 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
118 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
119 bool certain_bc = true;
120 vtkIdType N_pts, *pts;
121 m_Grid->GetCellPoints(id_cell, N_pts, pts);
122 bc_old[id_cell] = cell_code->GetValue(id_cell);
123 for (int i = 0; i < N_pts; ++i) {
124 for (int j = 0; j < m_Part.n2cGSize(pts[i]); ++j) {
125 if (cell_code->GetValue(id_cell) != cell_code->GetValue(m_Part.n2cGG(pts[i], j))) {
132 bc_set[id_cell] = cell_code->GetValue(id_cell);
135 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
136 if (bc_set[id_cell] == 0) {
137 cell_code->SetValue(id_cell, 9999);
140 GuiMainWindow::pointer()->storeSurfaceProjection();
142 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
143 if (cell_code->GetValue(id_cell) == 9999) {
144 cell_code->SetValue(id_cell, bc_old[id_cell]);
152 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
155 for (int i = 0; i < m_Part.c2cGSize(id_cell); ++i) {
156 bc = cell_code->GetValue(m_Part.c2cGG(id_cell, i));
157 if (bc == cell_code->GetValue(id_cell)) {
163 cell_code->SetValue(id_cell, bc);
168 } while (N > 0 && count < 1000);
172 void SharpenEdges::operate()
174 cout
<< "sharpening edges" << endl
;
179 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
180 QVector
<QSet
<int> > n2bc(m_Grid
->GetNumberOfPoints());
181 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
182 vtkIdType N_pts
, *pts
;
183 m_Grid
->GetCellPoints(id_cell
, N_pts
, pts
);
184 int bc
= cell_code
->GetValue(id_cell
);
185 for (int i
= 0; i
< N_pts
; ++i
) {
186 n2bc
[pts
[i
]].insert(bc
);
190 for (vtkIdType id_node
= 0; id_node
< m_Grid
->GetNumberOfPoints(); ++id_node
) {
191 if (n2bc
[id_node
].size() > 1) {
197 for (vtkIdType id_node
= 0; id_node
< m_Grid
->GetNumberOfPoints(); ++id_node
) {
198 if (n2bc
[id_node
].size() > 1) {
202 m_Grid
->GetPoint(id_node
, x
.data());
203 for (int i_proj_iter
= 0; i_proj_iter
< 20; ++i_proj_iter
) {
204 foreach (int bc
, n2bc
[id_node
]) {
205 x
= GuiMainWindow::pointer()->getSurfProj(bc
)->project(x
, id_node
);
208 m_Grid
->GetPoints()->SetPoint(id_node
, x
.data());
210 cout
<< total_count
<< " of " << N
<< " nodes corrected" << endl
;
215 GuiMainWindow::pointer()->storeSurfaceProjection();
222 QVector<vtkIdType> cls;
223 m_BoundaryCodes = GuiMainWindow::pointer()->getAllBoundaryCodes();
224 getSurfaceCells(m_BoundaryCodes, cls, m_Grid);
226 lap.setNumberOfIterations(5);
227 lap.setBoundaryCodes(m_BoundaryCodes);//IMPORTANT: so that unselected nodes become fixed when node types are updated!
228 lap.setProjectionOn();
229 lap.setNormalCorrectionOff();
230 lap.setFreeProjectionForEdgesOn();
235 UpdateCellIndex(m_Grid
);
236 GuiMainWindow::pointer()->updateBoundaryCodes(true);
237 GuiMainWindow::pointer()->updateActors();