2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008,2009 Oliver Gloth +
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 "swaptriangles.h"
25 #include <vtkCellArray.h>
27 void SwapTriangles::prepare()
29 getAllCellsOfType(VTK_TRIANGLE
, cells
, grid
);
30 QList
<vtkIdType
> ex_cells
;
31 EG_VTKDCC(vtkIntArray
, bc
, grid
, "cell_code");
32 foreach (vtkIdType id_cell
, cells
) {
33 if (!boundary_codes
.contains(bc
->GetValue(id_cell
))) {
34 ex_cells
.append(id_cell
);
36 if (grid
->GetCellType(id_cell
) != VTK_TRIANGLE
) {
40 cells
.resize(ex_cells
.size());
41 qCopy(ex_cells
.begin(), ex_cells
.end(), cells
.begin());
42 createCellMapping(cells
, _cells
, grid
);
43 createCellToCell(cells
, c2c
, grid
);
44 marked
.resize(cells
.size());
47 void SwapTriangles::operate()
49 cout
<< "swapping edges of boundary triangles (Delaunay)" << endl
;
50 using namespace GeometryTools
;
57 createCellToCell(cells
, c2c
, grid
);
58 //NOTE: This for loop can eventually be removed because if undefined, it's probably false.
59 for (int i_cells
= 0; i_cells
< cells
.size(); ++i_cells
) {
60 marked
[i_cells
] = false;
62 foreach (vtkIdType id_cell
, cells
) {
63 if (!marked
[_cells
[id_cell
]]) {
64 for (int j
= 0; j
< 3; ++j
) {
66 stencil_t S
= getStencil(id_cell
, j
);
68 if (!marked
[_cells
[S
.id_cell2
]]) {
69 vec3_t x3
[4], x3_0(0,0,0);
71 for (int k
= 0; k
< 4; ++k
) {
72 grid
->GetPoints()->GetPoint(S
.p
[k
], x3
[k
].data());
75 vec3_t n1
= triNormal(x3
[0], x3
[1], x3
[3]);
76 vec3_t n2
= triNormal(x3
[1], x3
[2], x3
[3]);
82 vec3_t ex
= orthogonalVector(n
);
83 vec3_t ey
= ex
.cross(n
);
84 for (int k
= 0; k
< 4; ++k
) {
85 x
[k
] = vec2_t(x3
[k
]*ex
, x3
[k
]*ey
);
87 vec2_t r1
, r2
, r3
, u1
, u2
, u3
;
88 r1
= 0.5*(x
[0] + x
[1]); u1
= turnLeft(x
[1] - x
[0]);
89 r2
= 0.5*(x
[1] + x
[2]); u2
= turnLeft(x
[2] - x
[1]);
90 r3
= 0.5*(x
[1] + x
[3]); u3
= turnLeft(x
[3] - x
[1]);
94 if (intersection(k
, l
, r1
, u1
, r3
, u3
)) {
96 if (intersection(k
, l
, r2
, u2
, r3
, u3
)) {
106 if ((xm1
- x
[2]).abs() < (xm1
- x
[0]).abs()) {
109 if ((xm2
- x
[0]).abs() < (xm2
- x
[2]).abs()) {
117 marked
[_cells
[S
.id_cell1
]] = true;
118 marked
[_cells
[S
.id_cell2
]] = true;
119 if (c2c
[_cells
[S
.id_cell1
]][0] != -1) {
120 marked
[c2c
[_cells
[S
.id_cell1
]][0]] = true;
121 } else if (c2c
[_cells
[S
.id_cell1
]][1] != -1) {
122 marked
[c2c
[_cells
[S
.id_cell1
]][1]] = true;
123 } else if (c2c
[_cells
[S
.id_cell1
]][2] != -1) {
124 marked
[c2c
[_cells
[S
.id_cell1
]][2]] = true;
126 if (c2c
[_cells
[S
.id_cell2
]][0] != -1) {
127 marked
[c2c
[_cells
[S
.id_cell2
]][0]] = true;
128 } else if (c2c
[_cells
[S
.id_cell2
]][1] != -1) {
129 marked
[c2c
[_cells
[S
.id_cell2
]][1]] = true;
130 } else if (c2c
[_cells
[S
.id_cell2
]][2] != -1) {
131 marked
[c2c
[_cells
[S
.id_cell2
]][2]] = true;
133 vtkIdType new_pts1
[3], new_pts2
[3];
134 new_pts1
[0] = S
.p
[1];
135 new_pts1
[1] = S
.p
[2];
136 new_pts1
[2] = S
.p
[0];
137 new_pts2
[0] = S
.p
[2];
138 new_pts2
[1] = S
.p
[3];
139 new_pts2
[2] = S
.p
[0];
140 grid
->ReplaceCell(S
.id_cell1
, 3, new_pts1
);
141 grid
->ReplaceCell(S
.id_cell2
, 3, new_pts2
);
150 } while ((N_swaps
> 0) && (loop
<= 20));
151 cout
<< N_total
<< " triangles have been swapped" << endl
;