2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008 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 "vtkEgNormalExtrusion.h"
25 vtkStandardNewMacro(vtkEgNormalExtrusion
);
27 void vtkEgNormalExtrusion::ExecuteEg()
29 QVector
<vtkIdType
> cells
, nodes
, n1
, n2
;
30 QVector
<vec3_t
> cell_normals
, node_normals
;
31 ExtractBoundary(cells
, nodes
, *BoundaryCodes
, input
);
33 computeNormals(cell_normals
, node_normals
, cells
, nodes
,input
);
34 } else if (mode
== cylinder
) {
36 node_normals
.resize(nodes
.size());
37 for (int i
= 0; i
< node_normals
.size(); ++i
) {
39 input
->GetPoint(nodes
[i
],x
.data());
40 vec3_t x0
= x
- ((x
-origin
)*axis
)*axis
;
41 node_normals
[i
] = x0
- origin
;
42 node_normals
[i
].normalise();
44 } else if ((mode
== fixed
) || (mode
== planar
)) {
45 fixed_normal
.normalise();
46 node_normals
.resize(nodes
.size());
47 for (int i
= 0; i
< node_normals
.size(); ++i
) {
48 node_normals
[i
] = fixed_normal
;
51 n1
.resize(nodes
.size());
52 n2
.resize(nodes
.size());
55 QVector
<int> _cells
, _nodes
;
56 createNodeMapping(nodes
, _nodes
, input
);
57 createCellMapping(cells
, _cells
, input
);
58 QVector
<QSet
<int> > n2c
;
59 createNodeToCell(cells
, nodes
, _nodes
, n2c
, input
);
61 vtkIdType NnewNodes
= input
->GetNumberOfPoints() + (layer_y
.size()-1)*nodes
.size();
62 vtkIdType NnewCells
= input
->GetNumberOfCells() + (layer_y
.size()-1)*cells
.size();
64 // count the number of new surface elements (side walls)
65 for (int i_cell
= 0; i_cell
< cells
.size(); ++i_cell
) {
68 input
->GetCellPoints(cells
[i_cell
], Npts
, pts
);
69 QVector
<vtkIdType
> surf_pts(Npts
);
70 for (int i_pts
= 0; i_pts
< Npts
; ++i_pts
) {
71 surf_pts
[i_pts
] = _nodes
[pts
[i_pts
]];
73 for (int i_surf_pts
= 0; i_surf_pts
< Npts
; ++i_surf_pts
) {
74 vtkIdType p1
= surf_pts
[i_surf_pts
];
76 if (i_surf_pts
< Npts
- 1) {
77 p2
= surf_pts
[i_surf_pts
+ 1];
85 foreach(cell
, n2c
[p1
]) {
86 if (n2c
[p2
].contains(cell
)) ++N
;
88 if (N
== 1) add_bd
= true;
91 NnewCells
+= layer_y
.size();
96 // count the number of new surface elements (base)
97 QVector
<bool> is_boundary
;
98 is_boundary
.fill(false, cells
.size());
103 nvol
.fill(0, nodes
.size());
104 for (vtkIdType cellId
= 0; cellId
< input
->GetNumberOfCells(); ++cellId
) {
105 if (isVolume(cellId
, input
)) {
106 vtkIdType Npts
, *pts
;
107 input
->GetCellPoints(cellId
, Npts
, pts
);
108 for (int i
= 0; i
< Npts
; ++i
) {
109 if (_nodes
[pts
[i
]] >= 0) {
110 ++nvol
[_nodes
[pts
[i
]]];
115 for (int i_cell
= 0; i_cell
< cells
.size(); ++i_cell
) {
116 vtkIdType cellId
= cells
[i_cell
];
117 vtkIdType Npts
, *pts
;
118 input
->GetCellPoints(cellId
, Npts
, pts
);
119 for (int i
= 0; i
< Npts
; ++i
) {
120 if (nvol
[_nodes
[pts
[i
]]] == 0) {
121 is_boundary
[i_cell
] = true;
124 if (is_boundary
[i_cell
]) {
131 qDebug() << Nvol
<< Nsurf
;
134 // allocate memory for the new grid
135 allocateGrid(output
, NnewCells
, NnewNodes
);
137 // boundary conditions
138 EG_VTKDCC(vtkIntArray
, cell_code1
, input
, "cell_code");
139 EG_VTKDCC(vtkIntArray
, cell_code2
, output
, "cell_code");
142 for (vtkIdType cellId
= 0; cellId
< input
->GetNumberOfCells(); ++cellId
) {
143 if (isSurface(input
, cellId
)) {
144 if (cell_code1
->GetValue(cellId
) >= new_bc
) {
145 new_bc
= cell_code1
->GetValue(cellId
) + 1;
150 for (int i
= 0; i
< nodes
.size(); ++i
) {
153 input
->GetPoint(nodes
[i
],x
.data());
154 output
->GetPoints()->SetPoint(n2
[i
],x
.data());
156 double total_layers
= layer_y
[layer_y
.size()-1] - layer_y
[0];
157 QVector
<double> total_dist(nodes
.size());
158 double L_max
= -1e99
;
160 if (mode
== planar
) {
161 for (int i
= 0; i
< nodes
.size(); ++i
) {
162 total_dist
[i
] = total_layers
;
163 vec3_t x_origin
, x_target
;
164 input
->GetPoint(nodes
[i
],x_origin
.data());
165 x_target
= x_origin
+ total_layers
*node_normals
[i
];
166 double L
= x_target
*fixed_normal
;
173 input
->GetPoint(nodes
[i_max
],x_far
.data());
174 x_far
+= min_dist
*fixed_normal
;
175 for (int i
= 0; i
< nodes
.size(); ++i
) {
176 total_dist
[i
] = total_layers
;
177 if (mode
== planar
) {
179 input
->GetPoint(nodes
[i
],x_origin
.data());
180 total_dist
[i
] = (x_far
-x_origin
)*fixed_normal
;
184 for (int i_layer
= 0; i_layer
< layer_y
.size() - 1; ++i_layer
) {
185 for (int i
= 0; i
< n1
.size(); ++i
) {
187 n2
[i
] = i_layer
*nodes
.size() + i
+ input
->GetNumberOfPoints();
189 output
->GetPoint(n1
[i
],x1
.data());
190 if (mode
== rotation
) {
192 double alpha
= (layer_y
[i_layer
+ 1] - layer_y
[i_layer
])*M_PI
/180.0;
193 x2
= GeometryTools::rotate(x2
,axis
,alpha
);
196 double dist
= (layer_y
[i_layer
+ 1] - layer_y
[i_layer
]);
197 if (mode
== planar
) {
198 dist
*= total_dist
[i
]/total_layers
;
200 x2
= x1
+ dist
*node_normals
[i
];
202 output
->GetPoints()->SetPoint(n2
[i
],x2
.data());
203 //qDebug() << n1[i] << n2[i];
206 for (int i_cell
= 0; i_cell
< cells
.size(); ++i_cell
) {
209 input
->GetCellPoints(cells
[i_cell
], Npts
, pts
);
210 QVector
<vtkIdType
> surf_pts(Npts
);
211 for (int i_pts
= 0; i_pts
< Npts
; ++i_pts
) {
212 surf_pts
[i_pts
] = _nodes
[pts
[i_pts
]];
214 for (int i_surf_pts
= 0; i_surf_pts
< Npts
; ++i_surf_pts
) {
215 vtkIdType p1
= surf_pts
[i_surf_pts
];
217 if (i_surf_pts
< Npts
- 1) {
218 p2
= surf_pts
[i_surf_pts
+ 1];
226 foreach(cell
, n2c
[p1
]) {
227 if (n2c
[p2
].contains(cell
)) ++N
;
229 if (N
== 1) add_bd
= true;
232 vtkIdType quad_pts
[4];
233 quad_pts
[0] = n1
[p1
];
234 quad_pts
[1] = n1
[p2
];
235 quad_pts
[2] = n2
[p2
];
236 quad_pts
[3] = n2
[p1
];
237 vtkIdType newCellId
= output
->InsertNextCell(VTK_QUAD
,4,quad_pts
);
238 cell_code2
->SetValue(newCellId
, new_bc
);
239 //qDebug() << "-" << newCellId << new_bc;
244 vtkIdType pri_pts
[6];
245 pri_pts
[0] = n1
[surf_pts
[0]];
246 pri_pts
[1] = n1
[surf_pts
[2]];
247 pri_pts
[2] = n1
[surf_pts
[1]];
248 pri_pts
[3] = n2
[surf_pts
[0]];
249 pri_pts
[4] = n2
[surf_pts
[2]];
250 pri_pts
[5] = n2
[surf_pts
[1]];
251 vtkIdType newCellId
= output
->InsertNextCell(VTK_WEDGE
,6,pri_pts
);
252 cell_code2
->SetValue(newCellId
, 0);
253 //qDebug() << "-" << newCellId << 0;
255 if (i_layer
== layer_y
.size() - 2) {
256 vtkIdType tri_pts
[3];
257 tri_pts
[0] = n2
[surf_pts
[0]];
258 tri_pts
[1] = n2
[surf_pts
[1]];
259 tri_pts
[2] = n2
[surf_pts
[2]];
260 vtkIdType newCellId
= output
->InsertNextCell(VTK_TRIANGLE
,3,tri_pts
);
261 cell_code2
->SetValue(newCellId
, cell_code1
->GetValue(cells
[i_cell
]));
262 //qDebug() << "-" << newCellId << cell_code1->GetValue(cells[i_cell]);
267 vtkIdType pri_pts
[8];
268 pri_pts
[0] = n1
[surf_pts
[0]];
269 pri_pts
[1] = n1
[surf_pts
[1]];
270 pri_pts
[2] = n1
[surf_pts
[2]];
271 pri_pts
[3] = n1
[surf_pts
[3]];
272 pri_pts
[4] = n2
[surf_pts
[0]];
273 pri_pts
[5] = n2
[surf_pts
[1]];
274 pri_pts
[6] = n2
[surf_pts
[2]];
275 pri_pts
[7] = n2
[surf_pts
[3]];
276 vtkIdType newCellId
= output
->InsertNextCell(VTK_HEXAHEDRON
,8,pri_pts
);
277 cell_code2
->SetValue(newCellId
, 0);
278 //qDebug() << "-" << newCellId << 0;
280 if (i_layer
== layer_y
.size() - 2) {
281 vtkIdType quad_pts
[4];
282 quad_pts
[0] = n2
[surf_pts
[0]];
283 quad_pts
[1] = n2
[surf_pts
[1]];
284 quad_pts
[2] = n2
[surf_pts
[2]];
285 quad_pts
[3] = n2
[surf_pts
[3]];
286 vtkIdType newCellId
= output
->InsertNextCell(VTK_QUAD
,4,quad_pts
);
287 cell_code2
->SetValue(newCellId
, cell_code1
->GetValue(cells
[i_cell
]));
288 //qDebug() << "-" << newCellId << cell_code1->GetValue(cells[i_cell]);
295 for (vtkIdType nodeId
= 0; nodeId
< input
->GetNumberOfPoints(); ++nodeId
) {
297 input
->GetPoints()->GetPoint(nodeId
, x
.data());
298 output
->GetPoints()->SetPoint(nodeId
, x
.data());
301 // copy all original cells that were not part of the extrusion
302 for (vtkIdType cellId
= 0; cellId
< input
->GetNumberOfCells(); ++cellId
) {
303 if (_cells
[cellId
] == -1) {
306 input
->GetCellPoints(cellId
, Npts
, pts
);
307 vtkIdType newCellId
= output
->InsertNextCell(input
->GetCellType(cellId
), Npts
, pts
);
308 copyCellData(input
, cellId
, output
, newCellId
);
312 // close boundary where no volume cells were present in the original grid
314 for (int i_cell
= 0; i_cell
< cells
.size(); ++i_cell
) {
315 if (is_boundary
[i_cell
]) {
316 vtkIdType cellId
= cells
[i_cell
];
319 input
->GetCellPoints(cellId
, Npts
, pts
);
320 vtkIdType newCellId
= output
->InsertNextCell(input
->GetCellType(cellId
), Npts
, pts
);
321 output
->GetCellPoints(newCellId
, Npts
, pts
);
322 QVector
<vtkIdType
> nodes(Npts
);
323 for (vtkIdType j
= 0; j
< Npts
; ++j
) nodes
[j
] = pts
[j
];
324 for (vtkIdType j
= 0; j
< Npts
; ++j
) pts
[Npts
- j
- 1] = nodes
[j
];
325 copyCellData(input
, cellId
, output
, newCellId
);
329 UpdateCellIndex(output
);
333 void vtkEgNormalExtrusion::SetLayers(const QVector
<double> &y
)
335 layer_y
.resize(y
.size());
336 qCopy(y
.begin(), y
.end(), layer_y
.begin());