added methods to convert between Cartesian and spherical coordinates
[engrid-github.git] / src / libengrid / egvtkobject.cpp
blobf83e933b8cffd6b28cbb44193b9cac19d9fb880e
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008-2012 enGits GmbH +
7 // + +
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. +
12 // + +
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. +
17 // + +
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/>. +
20 // + +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 //
23 #include "egvtkobject.h"
24 #include "guimainwindow.h"
26 #include <vtkCellData.h>
27 #include <vtkPointData.h>
28 #include <vtkCellLinks.h>
29 #include <vtkCellType.h>
30 #include <vtkIdList.h>
31 #include <vtkCell.h>
32 #include <vtkCharArray.h>
34 int EgVtkObject::DebugLevel;
36 void EgVtkObject::computeNormals
38 QVector<vec3_t> &cell_normals,
39 QVector<vec3_t> &node_normals,
40 QVector<vtkIdType> &cells,
41 QVector<vtkIdType> &nodes,
42 vtkUnstructuredGrid *grid
45 using namespace GeometryTools;
47 cell_normals.resize(cells.size());
48 node_normals.fill(vec3_t(0,0,0), nodes.size());
49 QVector<int> g2s;
50 createNodeMapping(nodes, g2s, grid);
51 for (int i_cell = 0; i_cell < cells.count(); ++i_cell) {
52 vtkIdType id_cell = cells[i_cell];
53 vtkIdType *pts;
54 vtkIdType npts;
55 grid->GetCellPoints(id_cell, npts, pts);
56 cell_normals[i_cell] = cellNormal(grid, id_cell);
57 cell_normals[i_cell].normalise();
58 for (int i_pts = 0; i_pts < npts; ++i_pts) {
59 if (g2s[pts[i_pts]] != -1) {
60 node_normals[g2s[pts[i_pts]]] += cell_normals[i_cell];
64 for (int i_node = 0; i_node < nodes.count(); ++i_node) {
65 node_normals[i_node].normalise();
66 //cout << node_normals[i_node] << endl;
70 void EgVtkObject::createNodeMapping
72 QVector<vtkIdType> &nodes,
73 QVector<int> &_nodes,
74 vtkUnstructuredGrid *grid
77 _nodes.fill(-1,grid->GetNumberOfPoints());
78 for (int i_nodes = 0; i_nodes < nodes.size(); ++i_nodes) {
79 _nodes[nodes[i_nodes]] = i_nodes;
83 void EgVtkObject::createCellMapping
85 QVector<vtkIdType> &cells,
86 QVector<int> &_cells,
87 vtkUnstructuredGrid *grid
90 _cells.fill(-1,grid->GetNumberOfCells());
91 for (int i_cells = 0; i_cells < cells.size(); ++i_cells) {
92 _cells[cells[i_cells]] = i_cells;
96 void EgVtkObject::createNodeToBcMapping
98 QVector<QSet<int> > &bcs,
99 vtkUnstructuredGrid *grid
102 EG_BUG;
103 bcs.fill(QSet<int>(), grid->GetNumberOfPoints());
104 grid->BuildLinks();
105 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
106 for (vtkIdType nodeId = 0; nodeId < grid->GetNumberOfPoints(); ++nodeId) {
107 int Ncells = grid->GetCellLinks()->GetNcells(nodeId);
108 for (int i = 0; i < Ncells; ++i) {
109 vtkIdType id_cell = grid->GetCellLinks()->GetCells(nodeId)[i];
110 vtkIdType ct = grid->GetCellType(id_cell);
111 if ((ct == VTK_TRIANGLE) || (ct = VTK_QUAD)) {
112 if (cell_code->GetValue(id_cell) > 0) {
113 bcs[nodeId].insert(cell_code->GetValue(id_cell));
120 void EgVtkObject::createNodeToCell
122 QVector<vtkIdType> &cells,
123 QVector<vtkIdType> &nodes,
124 QVector<int> &_nodes,
125 QVector<QSet<int> > &n2c,
126 vtkUnstructuredGrid *grid
129 n2c.fill(QSet<int>(), nodes.size());
130 for (vtkIdType i_cells = 0; i_cells < cells.size(); ++i_cells) {
131 vtkIdType *pts;
132 vtkIdType Npts;
133 grid->GetCellPoints(cells[i_cells], Npts, pts);
134 for (int i_pts = 0; i_pts < Npts; ++i_pts) {
135 n2c[_nodes[pts[i_pts]]].insert(i_cells);
140 void EgVtkObject::createNodeToCell
142 QVector<vtkIdType> &cells,
143 QVector<vtkIdType> &nodes,
144 QVector<int> &_nodes,
145 QVector<QVector<int> > &n2c,
146 vtkUnstructuredGrid *grid
149 n2c.fill(QVector<int>(), nodes.size());
150 QVector<int> count(nodes.size(),0);
151 for (vtkIdType i_cells = 0; i_cells < cells.size(); ++i_cells) {
152 vtkIdType *pts;
153 vtkIdType Npts;
154 grid->GetCellPoints(cells[i_cells], Npts, pts);
155 for (int i_pts = 0; i_pts < Npts; ++i_pts) {
156 ++count[_nodes[pts[i_pts]]];
159 for (int i = 0; i < nodes.size(); ++i) {
160 n2c[i].resize(count[i]);
161 count[i] = 0;
163 for (vtkIdType i_cells = 0; i_cells < cells.size(); ++i_cells) {
164 vtkIdType *pts;
165 vtkIdType Npts;
166 grid->GetCellPoints(cells[i_cells], Npts, pts);
167 for (int i_pts = 0; i_pts < Npts; ++i_pts) {
168 int i_nodes = _nodes[pts[i_pts]];
169 n2c[i_nodes][count[i_nodes]] = i_cells;
170 ++count[i_nodes];
175 void EgVtkObject::addToN2N(QVector<QSet<int> > &n2n, int n1, int n2)
177 n2n[n1].insert(n2);
178 n2n[n2].insert(n1);
181 void EgVtkObject::createNodeToNode(QVector<vtkIdType> &cells, QVector<vtkIdType> &nodes, QVector<int> &_nodes, QVector<QSet<int> > &n2n, vtkUnstructuredGrid *grid)
183 n2n.fill(QSet<int>(), nodes.size());
184 foreach (vtkIdType id_cell, cells) {
185 vtkIdType *pts;
186 vtkIdType Npts;
187 grid->GetCellPoints(id_cell, Npts, pts);
188 vector<int> n(Npts);
189 for (int i = 0; i < Npts; ++i) {
190 n[i] = _nodes[pts[i]];
192 vtkIdType cellType = grid->GetCellType(id_cell);
193 if (cellType == VTK_TRIANGLE) {
194 addToN2N(n2n, n[0], n[1]);
195 addToN2N(n2n, n[1], n[2]);
196 addToN2N(n2n, n[2], n[0]);
197 } else if (cellType == VTK_QUAD) {
198 addToN2N(n2n, n[0], n[1]);
199 addToN2N(n2n, n[1], n[2]);
200 addToN2N(n2n, n[2], n[3]);
201 addToN2N(n2n, n[3], n[0]);
202 } else if (cellType == VTK_TETRA) {
203 addToN2N(n2n, n[0], n[1]);
204 addToN2N(n2n, n[0], n[2]);
205 addToN2N(n2n, n[0], n[3]);
206 addToN2N(n2n, n[1], n[2]);
207 addToN2N(n2n, n[1], n[3]);
208 addToN2N(n2n, n[2], n[3]);
209 } else if (cellType == VTK_PYRAMID) {
210 addToN2N(n2n, n[0], n[1]);
211 addToN2N(n2n, n[0], n[3]);
212 addToN2N(n2n, n[0], n[4]);
213 addToN2N(n2n, n[1], n[2]);
214 addToN2N(n2n, n[1], n[4]);
215 addToN2N(n2n, n[2], n[3]);
216 addToN2N(n2n, n[2], n[4]);
217 addToN2N(n2n, n[3], n[4]);
218 } else if (cellType == VTK_WEDGE) {
219 addToN2N(n2n, n[0], n[1]);
220 addToN2N(n2n, n[0], n[2]);
221 addToN2N(n2n, n[0], n[3]);
222 addToN2N(n2n, n[1], n[2]);
223 addToN2N(n2n, n[1], n[4]);
224 addToN2N(n2n, n[2], n[5]);
225 addToN2N(n2n, n[3], n[4]);
226 addToN2N(n2n, n[3], n[5]);
227 addToN2N(n2n, n[4], n[5]);
228 } else if (cellType == VTK_HEXAHEDRON) {
229 addToN2N(n2n, n[0], n[1]);
230 addToN2N(n2n, n[0], n[3]);
231 addToN2N(n2n, n[0], n[4]);
232 addToN2N(n2n, n[1], n[2]);
233 addToN2N(n2n, n[1], n[5]);
234 addToN2N(n2n, n[2], n[3]);
235 addToN2N(n2n, n[2], n[6]);
236 addToN2N(n2n, n[3], n[7]);
237 addToN2N(n2n, n[4], n[5]);
238 addToN2N(n2n, n[4], n[7]);
239 addToN2N(n2n, n[5], n[6]);
240 addToN2N(n2n, n[6], n[7]);
245 void EgVtkObject::createNodeToNode
247 QVector<vtkIdType> &cells,
248 QVector<vtkIdType> &nodes,
249 QVector<int> &_nodes,
250 QVector<QVector<int> > &n2n,
251 vtkUnstructuredGrid *grid
254 QVector<QSet<int> > n2n_set;
255 createNodeToNode(cells, nodes, _nodes, n2n_set, grid);
256 n2n.resize(n2n_set.size());
257 for (int i = 0; i < n2n.size(); ++i) {
258 n2n[i].resize(n2n_set[i].size());
259 qCopy(n2n_set[i].begin(), n2n_set[i].end(), n2n[i].begin());
263 void EgVtkObject::getAllCells
265 QVector<vtkIdType> &cells,
266 vtkUnstructuredGrid *grid
269 int N = 0;
270 cells.resize(grid->GetNumberOfCells());
271 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
272 cells[N] = id_cell;
273 ++N;
277 void EgVtkObject::getAllCellsOfType
279 vtkIdType type,
280 QVector<vtkIdType> &cells,
281 vtkUnstructuredGrid *grid
284 int N = 0;
285 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
286 if (grid->GetCellType(id_cell) == type) {
287 ++N;
290 cells.resize(N);
291 N = 0;
292 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
293 if (grid->GetCellType(id_cell) == type) {
294 cells[N] = id_cell;
295 ++N;
301 void EgVtkObject::getAllVolumeCells
303 QVector<vtkIdType> &cells,
304 vtkUnstructuredGrid *grid
307 int N = 0;
308 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
309 if (isVolume(id_cell, grid)) {
310 ++N;
313 cells.resize(N);
314 N = 0;
315 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
316 if (isVolume(id_cell, grid)) {
317 cells[N] = id_cell;
318 ++N;
323 void EgVtkObject::getAllSurfaceCells
325 QVector<vtkIdType> &cells,
326 vtkUnstructuredGrid *grid
329 int N = 0;
330 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
331 if (isSurface(id_cell, grid)) {
332 ++N;
335 cells.resize(N);
336 N = 0;
337 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
338 if (isSurface(id_cell, grid)) {
339 cells[N] = id_cell;
340 ++N;
345 void EgVtkObject::getSurfaceCells
347 QSet<int> &bcs,
348 QVector<vtkIdType> &cells,
349 vtkUnstructuredGrid *grid
352 int N = 0;
353 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
354 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
355 if (isSurface(id_cell, grid)) {
356 if (bcs.contains(cell_code->GetValue(id_cell))) {
357 ++N;
361 cells.resize(N);
362 N = 0;
363 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
364 if (isSurface(id_cell, grid)) {
365 if (bcs.contains(cell_code->GetValue(id_cell))) {
366 cells[N] = id_cell;
367 ++N;
373 void EgVtkObject::addToC2C(vtkIdType id_cell, QVector<int> &_cells, QVector<QVector<int> > &c2c, int j, vtkIdList *nds, vtkIdList *cls, vtkUnstructuredGrid *grid)
375 c2c[_cells[id_cell]][j] = -1;
376 grid->GetCellNeighbors(id_cell, nds, cls);
377 if (isSurface(id_cell, grid)) {
378 for (int i = 0; i < cls->GetNumberOfIds(); ++i) {
379 if (cls->GetId(i) != id_cell) {
380 if (_cells[cls->GetId(i)] != -1) {
381 if (isSurface(cls->GetId(i), grid)) {
382 c2c[_cells[id_cell]][j] = _cells[cls->GetId(i)];
387 } else {
388 for (int i = 0; i < cls->GetNumberOfIds(); ++i) {
389 if (cls->GetId(i) != id_cell) {
390 if (_cells[cls->GetId(i)] != -1) {
391 if (isVolume(cls->GetId(i), grid) || c2c[_cells[id_cell]][j] == -1) {
392 c2c[_cells[id_cell]][j] = _cells[cls->GetId(i)];
401 void EgVtkObject::createCellToCell(QVector<vtkIdType> &cells, QVector<QVector<int> > &c2c, vtkUnstructuredGrid *grid)
403 // GetCellNeighbors(vtkIdType id_cell, vtkIdList *ptIds, vtkIdList *id_cells)
404 grid->BuildLinks();
405 QVector<int> _cells;
406 createCellMapping(cells, _cells, grid);
407 c2c.fill(QVector<int>(), cells.size());
408 EG_VTKSP(vtkIdList, nds);
409 EG_VTKSP(vtkIdList, cls);
410 for (int i = 0; i < cells.size(); ++i) {
411 vtkIdType id_cell = cells[i];
412 vtkIdType *pts;
413 vtkIdType Npts;
414 grid->GetCellPoints(id_cell, Npts, pts);
415 if (grid->GetCellType(id_cell) == VTK_TRIANGLE) {
416 c2c[i].resize(3);
417 nds->Reset();
418 nds->InsertNextId(pts[0]);
419 nds->InsertNextId(pts[1]);
420 addToC2C(id_cell, _cells, c2c, 0, nds, cls, grid);
421 nds->Reset();
422 nds->InsertNextId(pts[1]);
423 nds->InsertNextId(pts[2]);
424 addToC2C(id_cell, _cells, c2c, 1, nds, cls, grid);
425 nds->Reset();
426 nds->InsertNextId(pts[2]);
427 nds->InsertNextId(pts[0]);
428 addToC2C(id_cell, _cells, c2c, 2, nds, cls, grid);
429 } else if (grid->GetCellType(id_cell) == VTK_QUAD) {
430 c2c[i].resize(4);
431 nds->Reset();
432 nds->InsertNextId(pts[0]);
433 nds->InsertNextId(pts[1]);
434 addToC2C(id_cell, _cells, c2c, 0, nds, cls, grid);
435 nds->Reset();
436 nds->InsertNextId(pts[1]);
437 nds->InsertNextId(pts[2]);
438 addToC2C(id_cell, _cells, c2c, 1, nds, cls, grid);
439 nds->Reset();
440 nds->InsertNextId(pts[2]);
441 nds->InsertNextId(pts[3]);
442 addToC2C(id_cell, _cells, c2c, 2, nds, cls, grid);
443 nds->Reset();
444 nds->InsertNextId(pts[3]);
445 nds->InsertNextId(pts[0]);
446 addToC2C(id_cell, _cells, c2c, 3, nds, cls, grid);
447 } else if (grid->GetCellType(id_cell) == VTK_TETRA) {
448 c2c[i].resize(4);
449 nds->Reset();
450 nds->InsertNextId(pts[0]);
451 nds->InsertNextId(pts[1]);
452 nds->InsertNextId(pts[2]);
453 addToC2C(id_cell, _cells, c2c, 0, nds, cls, grid);
454 nds->Reset();
455 nds->InsertNextId(pts[0]);
456 nds->InsertNextId(pts[1]);
457 nds->InsertNextId(pts[3]);
458 addToC2C(id_cell, _cells, c2c, 1, nds, cls, grid);
459 nds->Reset();
460 nds->InsertNextId(pts[0]);
461 nds->InsertNextId(pts[3]);
462 nds->InsertNextId(pts[2]);
463 addToC2C(id_cell, _cells, c2c, 2, nds, cls, grid);
464 nds->Reset();
465 nds->InsertNextId(pts[1]);
466 nds->InsertNextId(pts[2]);
467 nds->InsertNextId(pts[3]);
468 addToC2C(id_cell, _cells, c2c, 3, nds, cls, grid);
469 } else if (grid->GetCellType(id_cell) == VTK_PYRAMID) {
470 c2c[i].resize(5);
471 nds->Reset();
472 nds->InsertNextId(pts[0]);
473 nds->InsertNextId(pts[1]);
474 nds->InsertNextId(pts[2]);
475 nds->InsertNextId(pts[3]);
476 addToC2C(id_cell, _cells, c2c, 0, nds, cls, grid);
477 nds->Reset();
478 nds->InsertNextId(pts[0]);
479 nds->InsertNextId(pts[1]);
480 nds->InsertNextId(pts[4]);
481 addToC2C(id_cell, _cells, c2c, 1, nds, cls, grid);
482 nds->Reset();
483 nds->InsertNextId(pts[1]);
484 nds->InsertNextId(pts[2]);
485 nds->InsertNextId(pts[4]);
486 addToC2C(id_cell, _cells, c2c, 2, nds, cls, grid);
487 nds->Reset();
488 nds->InsertNextId(pts[2]);
489 nds->InsertNextId(pts[3]);
490 nds->InsertNextId(pts[4]);
491 addToC2C(id_cell, _cells, c2c, 3, nds, cls, grid);
492 nds->Reset();
493 nds->InsertNextId(pts[3]);
494 nds->InsertNextId(pts[0]);
495 nds->InsertNextId(pts[4]);
496 addToC2C(id_cell, _cells, c2c, 4, nds, cls, grid);
497 } else if (grid->GetCellType(id_cell) == VTK_WEDGE) {
498 c2c[i].resize(5);
499 nds->Reset();
500 nds->InsertNextId(pts[0]);
501 nds->InsertNextId(pts[1]);
502 nds->InsertNextId(pts[2]);
503 addToC2C(id_cell, _cells, c2c, 0, nds, cls, grid);
504 nds->Reset();
505 nds->InsertNextId(pts[3]);
506 nds->InsertNextId(pts[4]);
507 nds->InsertNextId(pts[5]);
508 addToC2C(id_cell, _cells, c2c, 1, nds, cls, grid);
509 nds->Reset();
510 nds->InsertNextId(pts[0]);
511 nds->InsertNextId(pts[1]);
512 nds->InsertNextId(pts[4]);
513 nds->InsertNextId(pts[3]);
514 addToC2C(id_cell, _cells, c2c, 2, nds, cls, grid);
515 nds->Reset();
516 nds->InsertNextId(pts[1]);
517 nds->InsertNextId(pts[4]);
518 nds->InsertNextId(pts[5]);
519 nds->InsertNextId(pts[2]);
520 addToC2C(id_cell, _cells, c2c, 3, nds, cls, grid);
521 nds->Reset();
522 nds->InsertNextId(pts[0]);
523 nds->InsertNextId(pts[2]);
524 nds->InsertNextId(pts[5]);
525 nds->InsertNextId(pts[3]);
526 addToC2C(id_cell, _cells, c2c, 4, nds, cls, grid);
527 } else if (grid->GetCellType(id_cell) == VTK_HEXAHEDRON) {
528 c2c[i].resize(6);
529 nds->Reset();
530 nds->InsertNextId(pts[0]);
531 nds->InsertNextId(pts[3]);
532 nds->InsertNextId(pts[2]);
533 nds->InsertNextId(pts[1]);
534 addToC2C(id_cell, _cells, c2c, 0, nds, cls, grid);
535 nds->Reset();
536 nds->InsertNextId(pts[4]);
537 nds->InsertNextId(pts[5]);
538 nds->InsertNextId(pts[6]);
539 nds->InsertNextId(pts[7]);
540 addToC2C(id_cell, _cells, c2c, 1, nds, cls, grid);
541 nds->Reset();
542 nds->InsertNextId(pts[0]);
543 nds->InsertNextId(pts[1]);
544 nds->InsertNextId(pts[5]);
545 nds->InsertNextId(pts[4]);
546 addToC2C(id_cell, _cells, c2c, 2, nds, cls, grid);
547 nds->Reset();
548 nds->InsertNextId(pts[3]);
549 nds->InsertNextId(pts[7]);
550 nds->InsertNextId(pts[6]);
551 nds->InsertNextId(pts[2]);
552 addToC2C(id_cell, _cells, c2c, 3, nds, cls, grid);
553 nds->Reset();
554 nds->InsertNextId(pts[0]);
555 nds->InsertNextId(pts[4]);
556 nds->InsertNextId(pts[7]);
557 nds->InsertNextId(pts[3]);
558 addToC2C(id_cell, _cells, c2c, 4, nds, cls, grid);
559 nds->Reset();
560 nds->InsertNextId(pts[1]);
561 nds->InsertNextId(pts[2]);
562 nds->InsertNextId(pts[6]);
563 nds->InsertNextId(pts[5]);
564 addToC2C(id_cell, _cells, c2c, 5, nds, cls, grid);
569 bool EgVtkObject::isVolume(vtkIdType id_cell, vtkUnstructuredGrid *grid)
571 bool isVol = false;
572 if (grid->GetCellType(id_cell) == VTK_TETRA) isVol = true;
573 else if (grid->GetCellType(id_cell) == VTK_PYRAMID) isVol = true;
574 else if (grid->GetCellType(id_cell) == VTK_WEDGE) isVol = true;
575 else if (grid->GetCellType(id_cell) == VTK_HEXAHEDRON) isVol = true;
576 return isVol;
579 bool EgVtkObject::isSurface(vtkIdType id_cell, vtkUnstructuredGrid *grid)
581 bool isSurf = false;
582 if (grid->GetCellType(id_cell) == VTK_TRIANGLE) isSurf = true;
583 else if (grid->GetCellType(id_cell) == VTK_QUAD) isSurf = true;
584 return isSurf;
587 void EgVtkObject::UpdateCellIndex(vtkUnstructuredGrid *grid)
589 if (!grid->GetCellData()->GetArray("cell_index")) {
590 EG_VTKSP(vtkLongArray_t, cell_index);
591 cell_index->SetName("cell_index");
592 cell_index->SetNumberOfValues(grid->GetNumberOfCells());
593 grid->GetCellData()->AddArray(cell_index);
595 EG_VTKDCC(vtkLongArray_t, cell_index, grid, "cell_index");
596 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
597 cell_index->SetValue(id_cell, id_cell);
601 void EgVtkObject::UpdateNodeIndex(vtkUnstructuredGrid *grid)
603 if (!grid->GetPointData()->GetArray("node_index")) {
604 EG_VTKSP(vtkLongArray_t, node_index);
605 node_index->SetName("node_index");
606 node_index->SetNumberOfValues(grid->GetNumberOfPoints());
607 grid->GetPointData()->AddArray(node_index);
609 EG_VTKDCN(vtkLongArray_t, node_index, grid, "node_index");
610 for (vtkIdType pointId = 0; pointId < grid->GetNumberOfPoints(); ++pointId) {
611 node_index->SetValue(pointId, pointId);
615 void EgVtkObject::addToPolyData
617 QVector<vtkIdType> &cells,
618 vtkPolyData *pdata,
619 vtkUnstructuredGrid *grid
622 UpdateCellIndex(grid);
623 UpdateNodeIndex(grid);
624 QVector<vtkIdType> nodes;
625 QVector<int> _nodes;
626 getNodesFromCells(cells, nodes, grid);
627 createNodeMapping(nodes, _nodes, grid);
628 EG_VTKSP(vtkDoubleArray, pcoords);
629 pcoords->SetNumberOfComponents(3);
630 pcoords->SetNumberOfTuples(nodes.size());
631 EG_VTKSP(vtkPoints, points);
632 points->SetData(pcoords);
633 pdata->SetPoints(points);
634 pdata->Allocate(cells.size());
635 if (!pdata->GetCellData()->GetArray("cell_index")) {
636 EG_VTKSP(vtkLongArray_t, cell_index);
637 cell_index->SetName("cell_index");
638 //cell_index->SetNumberOfValues(cells.size());
639 pdata->GetCellData()->AddArray(cell_index);
641 if (!pdata->GetPointData()->GetArray("node_index")) {
642 EG_VTKSP(vtkLongArray_t, node_index);
643 node_index->SetName("node_index");
644 //node_index->SetNumberOfValues(nodes.size());
645 pdata->GetPointData()->AddArray(node_index);
647 EG_VTKDCC(vtkLongArray_t, pd_cell_index, pdata, "cell_index");
648 EG_VTKDCN(vtkLongArray_t, pd_node_index, pdata, "node_index");
649 pd_cell_index->SetNumberOfValues(cells.size());
650 pd_node_index->SetNumberOfValues(nodes.size());
651 for (int i_cell = 0; i_cell < cells.size(); ++i_cell) {
652 vtkIdType id_cell = cells[i_cell];
653 vtkIdType cellType = grid->GetCellType(id_cell);
654 if ((cellType != VTK_TRIANGLE) && (cellType != VTK_QUAD)) {
655 EG_ERR_RETURN("unsupported cell type for this operation");
657 vtkIdType Npts, *pts;
658 grid->GetCellPoints(id_cell, Npts, pts);
659 vtkIdType *new_pts = new vtkIdType[Npts];
660 for (int i = 0; i < Npts; ++i) {
661 new_pts[i] = _nodes[pts[i]];
663 vtkIdType newCellId = pdata->InsertNextCell(cellType, Npts, new_pts);
664 pd_cell_index->SetValue(newCellId, id_cell);
665 delete [] new_pts;
667 for (int i_node = 0; i_node < nodes.size(); ++i_node) {
668 vec3_t x;
669 grid->GetPoints()->GetPoint(nodes[i_node], x.data());
670 pdata->GetPoints()->SetPoint(i_node, x.data());
671 pd_node_index->SetValue(i_node, nodes[i_node]);
675 #define EGVTKOBJECT_COPYCELLDATA(FIELD,TYPE) \
677 if (old_grid->GetCellData()->GetArray(FIELD)) { \
678 EG_VTKDCC(TYPE, var1, old_grid, FIELD); \
679 EG_VTKDCC(TYPE, var2, new_grid, FIELD); \
680 var2->SetValue(newId, var1->GetValue(oldId)); \
684 void EgVtkObject::copyCellData
686 vtkUnstructuredGrid *old_grid,
687 vtkIdType oldId,
688 vtkUnstructuredGrid *new_grid,
689 vtkIdType newId
692 EGVTKOBJECT_COPYCELLDATA("vtk_type", vtkIntArray);
693 EGVTKOBJECT_COPYCELLDATA("cell_code", vtkIntArray);
694 EGVTKOBJECT_COPYCELLDATA("cell_orgdir", vtkIntArray);
695 EGVTKOBJECT_COPYCELLDATA("cell_curdir", vtkIntArray);
696 EGVTKOBJECT_COPYCELLDATA("cell_voldir", vtkIntArray);
697 EGVTKOBJECT_COPYCELLDATA("cell_index", vtkLongArray_t);
700 #define EGVTKOBJECT_COPYNODEDATA(FIELD,TYPE) \
702 if (old_grid->GetPointData()->GetArray(FIELD)) { \
703 EG_VTKDCN(TYPE, var1, old_grid, FIELD); \
704 EG_VTKDCN(TYPE, var2, new_grid, FIELD); \
705 var2->SetValue(newId, var1->GetValue(oldId)); \
709 void EgVtkObject::copyNodeData
711 vtkUnstructuredGrid *old_grid,
712 vtkIdType oldId,
713 vtkUnstructuredGrid *new_grid,
714 vtkIdType newId
717 EGVTKOBJECT_COPYNODEDATA("node_status", vtkIntArray);
718 EGVTKOBJECT_COPYNODEDATA("node_layer", vtkIntArray);
719 EGVTKOBJECT_COPYNODEDATA("node_index", vtkLongArray_t);
720 EGVTKOBJECT_COPYNODEDATA("node_specified_density", vtkIntArray);
721 EGVTKOBJECT_COPYNODEDATA("node_meshdensity_desired", vtkDoubleArray);
722 //EGVTKOBJECT_COPYNODEDATA("node_meshdensity_current", vtkDoubleArray);
723 EGVTKOBJECT_COPYNODEDATA("node_type", vtkCharArray);
724 EGVTKOBJECT_COPYNODEDATA("node_pindex", vtkLongArray_t);
727 #define EGVTKOBJECT_CREATECELLFIELD(FIELD,TYPE,OW) \
728 if (!grid->GetCellData()->GetArray(FIELD)) { \
729 EG_VTKSP(TYPE, var); \
730 var->SetName(FIELD); \
731 var->SetNumberOfValues(Ncells); \
732 grid->GetCellData()->AddArray(var); \
733 for (int i = 0; i < grid->GetNumberOfCells(); ++i) { \
734 var->SetValue(i,0); \
736 } else if (OW) { \
737 EG_VTKDCC(TYPE, var, grid, FIELD); \
738 var->SetNumberOfValues(Ncells); \
739 for (int i = 0; i < grid->GetNumberOfCells(); ++i) { \
740 var->SetValue(i,0); \
744 #define EGVTKOBJECT_CREATENODEFIELD(FIELD,TYPE,OW) \
745 if (!grid->GetPointData()->GetArray(FIELD)) { \
746 EG_VTKSP(TYPE, var); \
747 var->SetName(FIELD); \
748 var->SetNumberOfValues(Nnodes); \
749 grid->GetPointData()->AddArray(var); \
750 for (int i = 0; i < grid->GetNumberOfPoints(); ++i) { \
751 var->SetValue(i,0); \
753 } else if (OW) { \
754 EG_VTKDCN(TYPE, var, grid, FIELD); \
755 var->SetNumberOfValues(Nnodes); \
756 for (int i = 0; i < grid->GetNumberOfPoints(); ++i) { \
757 var->SetValue(i,0); \
761 void EgVtkObject::createBasicFields(vtkUnstructuredGrid *grid, vtkIdType Ncells, vtkIdType Nnodes, bool overwrite)
763 createBasicNodeFields(grid, Nnodes, overwrite);
764 createBasicCellFields(grid, Ncells, overwrite);
767 void EgVtkObject::createBasicCellFields(vtkUnstructuredGrid *grid, vtkIdType Ncells, bool overwrite)
769 EGVTKOBJECT_CREATECELLFIELD("vtk_type" , vtkIntArray, overwrite);
770 EGVTKOBJECT_CREATECELLFIELD("cell_code", vtkIntArray, overwrite);
771 EGVTKOBJECT_CREATECELLFIELD("cell_index", vtkLongArray_t, overwrite);
772 EGVTKOBJECT_CREATECELLFIELD("cell_orgdir", vtkIntArray, overwrite); // original orientation
773 EGVTKOBJECT_CREATECELLFIELD("cell_curdir", vtkIntArray, overwrite); // current orientation
774 EGVTKOBJECT_CREATECELLFIELD("cell_voldir", vtkIntArray, overwrite); // volume orientation -- only valid for a single (i.e. the current) volume
775 //EGVTKOBJECT_CREATECELLFIELD("cell_VA", vtkDoubleArray, overwrite);
778 void EgVtkObject::createBasicNodeFields(vtkUnstructuredGrid *grid, vtkIdType Nnodes, bool overwrite)
780 EGVTKOBJECT_CREATENODEFIELD("node_status", vtkIntArray, overwrite);
781 EGVTKOBJECT_CREATENODEFIELD("node_layer", vtkIntArray, overwrite);
782 EGVTKOBJECT_CREATENODEFIELD("node_index", vtkLongArray_t, overwrite);
783 EGVTKOBJECT_CREATENODEFIELD("node_specified_density", vtkIntArray, overwrite); //density index from table
784 EGVTKOBJECT_CREATENODEFIELD("node_meshdensity_desired", vtkDoubleArray, overwrite); //what we want
785 //EGVTKOBJECT_CREATENODEFIELD("node_meshdensity_current", vtkDoubleArray, overwrite); //what we have
786 EGVTKOBJECT_CREATENODEFIELD("node_type", vtkCharArray, overwrite); //node type
787 EGVTKOBJECT_CREATENODEFIELD("node_pindex", vtkLongArray_t, overwrite);
790 void EgVtkObject::allocateGrid(vtkUnstructuredGrid *grid, vtkIdType Ncells, vtkIdType Nnodes, bool create_fields)
792 EG_VTKSP(vtkPoints,points);
793 points->SetNumberOfPoints(Nnodes);
794 grid->SetPoints(points);
795 grid->Allocate(Ncells,max(vtkIdType(1),Ncells/10));
796 if (create_fields) {
797 createBasicFields(grid, Ncells, Nnodes, true);
801 vec3_t EgVtkObject::cellCentre(vtkUnstructuredGrid *grid, vtkIdType id_cell)
803 vec3_t x,xc(0,0,0);
804 vtkIdType *pts, N_pts;
805 grid->GetCellPoints(id_cell, N_pts, pts);
806 double f = 1.0/N_pts;
807 for (int i_pts = 0; i_pts < N_pts; ++i_pts) {
808 grid->GetPoint(pts[i_pts], x.data());
809 xc += f*x;
811 return xc;
814 double EgVtkObject::faceAngle(vtkUnstructuredGrid *grid, vtkIdType id_face1, vtkIdType id_face2)
816 QList<vtkIdType> edge_nodes;
817 sharedNodesOfCells(grid, id_face1, id_face2, edge_nodes);
818 if (edge_nodes.size() != 2) {
819 EG_BUG;
821 vec3_t x1, x2;
822 grid->GetPoint(edge_nodes[0], x1.data());
823 grid->GetPoint(edge_nodes[1], x2.data());
824 vec3_t xf1 = cellCentre(grid, id_face1);
825 vec3_t xf2 = cellCentre(grid, id_face2);
826 vec3_t xe = 0.5*(x1 + x2);
827 vec3_t xfe = 0.5*(xf1 + xf2);
828 vec3_t n1 = cellNormal(grid, id_face1);
829 vec3_t n2 = cellNormal(grid, id_face2);
830 vec3_t ve = xe - xfe;
831 double alpha = angle(n1, n2);
832 if ((n1 + n2)*ve < 0) {
833 return -alpha;
835 return alpha;
838 void EgVtkObject::getRestCells(vtkUnstructuredGrid *grid,
839 const QVector<vtkIdType> &cells,
840 QVector<vtkIdType> &rest_cells)
842 QVector<bool> is_in_cells(grid->GetNumberOfCells(), false);
843 foreach (vtkIdType id_cell, cells) {
844 is_in_cells[id_cell] = true;
846 rest_cells.resize(grid->GetNumberOfCells() - cells.size());
847 int i_rest_cells = 0;
848 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
849 if (!is_in_cells[id_cell]) {
850 rest_cells[i_rest_cells] = id_cell;
851 ++i_rest_cells;
856 void EgVtkObject::makeCopy(vtkUnstructuredGrid *src, vtkUnstructuredGrid *dst, bool copy_data)
858 allocateGrid(dst, src->GetNumberOfCells(), src->GetNumberOfPoints(), copy_data);
859 for (vtkIdType id_node = 0; id_node < src->GetNumberOfPoints(); ++id_node) {
860 vec3_t x;
861 src->GetPoints()->GetPoint(id_node, x.data());
862 dst->GetPoints()->SetPoint(id_node, x.data());
863 if (copy_data) {
864 copyNodeData(src, id_node, dst, id_node);
867 for (vtkIdType id_cell = 0; id_cell < src->GetNumberOfCells(); ++id_cell) {
868 vtkIdType N_pts, *pts;
869 vtkIdType type_cell = src->GetCellType(id_cell);
870 src->GetCellPoints(id_cell, N_pts, pts);
871 vtkIdType id_new_cell = dst->InsertNextCell(type_cell, N_pts, pts);
872 if (copy_data) {
873 copyCellData(src, id_cell, dst, id_new_cell);
878 void EgVtkObject::makeCopyNoAlloc(vtkUnstructuredGrid *src, vtkUnstructuredGrid *dst)
880 for (vtkIdType id_node = 0; id_node < src->GetNumberOfPoints(); ++id_node) {
881 vec3_t x;
882 src->GetPoints()->GetPoint(id_node, x.data());
883 dst->GetPoints()->SetPoint(id_node, x.data());
884 copyNodeData(src, id_node, dst, id_node);
886 for (vtkIdType id_cell = 0; id_cell < src->GetNumberOfCells(); ++id_cell) {
887 vtkIdType N_pts, *pts;
888 vtkIdType type_cell = src->GetCellType(id_cell);
889 src->GetCellPoints(id_cell, N_pts, pts);
890 vtkIdType id_new_cell = dst->InsertNextCell(type_cell, N_pts, pts);
891 copyCellData(src, id_cell, dst, id_new_cell);
895 void EgVtkObject::reorientateFace(vtkUnstructuredGrid *grid, vtkIdType id_face)
897 EG_VTKDCC(vtkIntArray, cell_curdir, grid, "cell_curdir");
898 vtkIdType N_pts, *pts;
899 grid->GetCellPoints(id_face, N_pts, pts);
900 QVector<vtkIdType> new_pts(N_pts);
901 for (int i = 0; i < N_pts; ++i) {
902 new_pts[i] = pts[N_pts - i - 1];
904 if (cell_curdir->GetValue(id_face) == 0) {
905 cell_curdir->SetValue(id_face, 1);
906 } else {
907 cell_curdir->SetValue(id_face, 0);
909 grid->ReplaceCell(id_face, N_pts, new_pts.data());
912 void EgVtkObject::resetOrientation(vtkUnstructuredGrid *grid)
914 EG_VTKDCC(vtkIntArray, cell_orgdir, grid, "cell_orgdir");
915 EG_VTKDCC(vtkIntArray, cell_curdir, grid, "cell_curdir");
916 EG_VTKDCC(vtkIntArray, cell_voldir, grid, "cell_voldir");
917 QVector<vtkIdType> faces;
918 getAllSurfaceCells(faces, grid);
919 foreach (vtkIdType id_face, faces) {
920 if (cell_curdir->GetValue(id_face) != cell_orgdir->GetValue(id_face)) {
921 reorientateFace(grid, id_face);
922 cell_curdir->SetValue(id_face, cell_orgdir->GetValue(id_face));
924 cell_voldir->SetValue(id_face, 0);
928 vtkIdType EgVtkObject::findVolumeCell(vtkUnstructuredGrid *grid, vtkIdType id_surf, g2l_t _nodes, l2g_t cells, g2l_t _cells, l2l_t n2c)
930 vtkIdType N_pts=0, *pts=NULL; //allways initialize variables, otherwise unexpected results will occur!
931 grid->GetCellPoints(id_surf, N_pts, pts);
932 QVector<QSet<int> > inters(N_pts-1);
933 qcontIntersection(n2c[_nodes[pts[0]]], n2c[_nodes[pts[1]]], inters[0]);
934 int i_pts = 2;
935 while (i_pts < N_pts) {
936 qcontIntersection(inters[i_pts-2], n2c[_nodes[pts[i_pts]]], inters[i_pts-1]);
937 ++i_pts;
939 if (inters[N_pts-2].size() == 0) {
940 return -1;
941 } else if (inters[N_pts-2].size() > 2) {
942 EG_BUG;
944 vtkIdType id_vol = -1;
945 foreach (int i_cells, inters[N_pts-2]) {
946 if (cells[i_cells] != id_surf) {
947 id_vol = cells[i_cells];
950 return id_vol;
953 void EgVtkObject::setBoundaryCodes(const QSet<int> &bcs)
955 m_BoundaryCodes = bcs;
958 QSet<int> EgVtkObject::getBoundaryCodes()
960 return m_BoundaryCodes;
963 void EgVtkObject::createIndices(vtkUnstructuredGrid *grid)
965 if (!grid->GetCellData()->GetArray("cell_index")) {
966 EG_VTKSP(vtkLongArray_t, var);
967 var->SetName("cell_index");
968 var->SetNumberOfValues(grid->GetNumberOfCells());
969 grid->GetCellData()->AddArray(var);
970 } else {
971 EG_VTKDCC(vtkLongArray_t, var, grid, "cell_index");
972 var->SetNumberOfValues(grid->GetNumberOfCells());
974 EG_VTKDCC(vtkLongArray_t, cell_index, grid, "cell_index");
975 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
976 cell_index->SetValue(id_cell, id_cell);
979 if (!grid->GetCellData()->GetArray("vtk_type")) {
980 EG_VTKSP(vtkIntArray, var);
981 var->SetName("vtk_type");
982 var->SetNumberOfValues(grid->GetNumberOfCells());
983 grid->GetCellData()->AddArray(var);
984 } else {
985 EG_VTKDCC(vtkIntArray, var, grid, "vtk_type");
986 var->SetNumberOfValues(grid->GetNumberOfCells());
988 EG_VTKDCC(vtkIntArray, vtk_type, grid, "vtk_type");
989 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
990 vtk_type->SetValue(id_cell, grid->GetCellType(id_cell));
993 if (!grid->GetCellData()->GetArray("node_index")) {
994 EG_VTKSP(vtkLongArray_t, var);
995 var->SetName("node_index");
996 var->SetNumberOfValues(grid->GetNumberOfPoints());
997 grid->GetPointData()->AddArray(var);
998 } else {
999 EG_VTKDCC(vtkLongArray_t, var, grid, "node_index");
1000 var->SetNumberOfValues(grid->GetNumberOfPoints());
1002 EG_VTKDCN(vtkLongArray_t, node_index, grid, "node_index");
1003 for (vtkIdType id_node = 0; id_node < grid->GetNumberOfPoints(); ++id_node) {
1004 node_index->SetValue(id_node, id_node);
1008 BoundaryCondition EgVtkObject::getBC(int bc)
1010 return GuiMainWindow::pointer()->getBC(bc);
1013 int EgVtkObject::getSet(QString group, QString key, int value, int& variable)
1015 QSettings *qset = GuiMainWindow::settings();
1016 QString typed_key = "int/" + key;
1017 if(group!=QObject::tr("General")) qset->beginGroup(group);
1018 //if key=value pair not found in settings file, write it
1019 if (!qset->contains(typed_key)) qset->setValue(typed_key,value);
1020 //read key value from settings file and assign it to variable
1021 variable = (qset->value(typed_key,variable)).toInt();
1022 if(group!=QObject::tr("General")) qset->endGroup();
1023 return(variable);
1026 double EgVtkObject::getSet(QString group, QString key, double value, double& variable)
1028 QSettings *qset = GuiMainWindow::settings();
1029 QString typed_key = "double/" + key;
1030 if(group!=QObject::tr("General")) qset->beginGroup(group);
1031 //if key=value pair not found in settings file, write it
1032 if (!qset->contains(typed_key)) qset->setValue(typed_key,value);
1033 //read key value from settings file and assign it to variable
1034 variable = (qset->value(typed_key,variable)).toDouble();
1035 if(group!=QObject::tr("General")) qset->endGroup();
1036 return(variable);
1039 bool EgVtkObject::getSet(QString group, QString key, bool value, bool& variable)
1041 QSettings *qset = GuiMainWindow::settings();
1042 QString typed_key = "bool/" + key;
1043 if(group!=QObject::tr("General")) qset->beginGroup(group);
1044 Qt::CheckState state = (Qt::CheckState) ( value ? 2 : 0 );
1045 //if key=value pair not found in settings file, write it
1046 if (!qset->contains(typed_key)) qset->setValue(typed_key,state);
1047 //read key value from settings file and assign it to variable
1048 variable = (qset->value(typed_key,variable)).toBool();
1049 if(group!=QObject::tr("General")) qset->endGroup();
1050 return(variable);
1053 QString EgVtkObject::getSet(QString group, QString key, QString value, QString& variable)
1055 QSettings *qset = GuiMainWindow::settings();
1056 QString typed_key;
1057 typed_key = QObject::tr("QString/") + key;
1058 if (group != QObject::tr("General")) qset->beginGroup(group);
1059 //if key=value pair not found in settings file, write it
1060 if (!qset->contains(typed_key)) qset->setValue(typed_key, value);
1061 //read key value from settings file and assign it to variable
1062 variable = (qset->value(typed_key)).toString();
1063 if (group != QObject::tr("General")) qset->endGroup();
1064 return(variable);
1067 QString EgVtkObject::getSet(QString group, QString key, QString value, QString& variable, int type)
1069 QSettings *qset = GuiMainWindow::settings();
1070 QString typed_key;
1071 if (type == 0) {
1072 typed_key = QObject::tr("QString/") + key;
1074 else if (type == 1) {
1075 typed_key = QObject::tr("Filename/") + key;
1077 else {
1078 typed_key = QObject::tr("Directory/") + key;
1080 if (group != QObject::tr("General")) qset->beginGroup(group);
1081 //if key=value pair not found in settings file, write it
1082 if (!qset->contains(typed_key)) qset->setValue(typed_key, value);
1083 //read key value from settings file and assign it to variable
1084 variable = (qset->value(typed_key)).toString();
1085 if (group != QObject::tr("General")) qset->endGroup();
1086 return(variable);
1089 void EgVtkObject::writeGrid(vtkUnstructuredGrid *grid, QString name)
1091 QVector<vtkIdType> cells;
1092 getAllCells(cells, grid);
1093 name = GuiMainWindow::pointer()->getCwd() + "/" + name + ".vtu";
1094 writeCells(grid, cells, name);
1095 // qDebug()<<"Saved grid as "<<name;
1098 void EgVtkObject::getAllNodeDataNames(QVector<QString> &field_names, vtkUnstructuredGrid *grid)
1100 int N = grid->GetPointData()->GetNumberOfArrays();
1101 field_names.resize(N);
1102 for (int i = 0; i < N; ++i) {
1103 field_names[i] = grid->GetPointData()->GetArrayName(i);
1107 void EgVtkObject::getAllCellDataNames(QVector<QString> &field_names, vtkUnstructuredGrid *grid)
1109 int N = grid->GetCellData()->GetNumberOfArrays();
1110 field_names.resize(N);
1111 for (int i = 0; i < N; ++i) {
1112 field_names[i] = grid->GetCellData()->GetArrayName(i);
1116 QString EgVtkObject::stripFromExtension(QString file_name)
1118 int i = file_name.size() - 1;
1119 while ((i > 0) && (file_name[i] != '.') && (file_name[i] != '/') && (file_name[i] != '\\')) {
1120 --i;
1122 if (file_name[i] == '.') {
1123 return file_name.left(i);
1125 return file_name;
1128 QString EgVtkObject::getExtension(QString file_name)
1130 int i = file_name.size();
1131 while ((i > 0) && (file_name[i] != '.') && (file_name[i] != '/') && (file_name[i] != '\\')) {
1132 --i;
1134 if (file_name[i] == '.') {
1135 return (file_name.right(file_name.size() - i - 1)).toLower();
1137 return "";
1140 ///////////////////////////////////////////
1142 void EgVtkObject::getFaceOfCell(vtkUnstructuredGrid *grid, vtkIdType id_cell, int i_face, QVector<vtkIdType> &ids)
1144 vtkIdType type_cell = grid->GetCellType(id_cell);
1145 ids.clear();
1146 vtkIdType *pts, N_pts;
1147 grid->GetCellPoints(id_cell, N_pts, pts);
1149 if (type_cell == VTK_TETRA) {
1150 if (i_face == 0) { ids.resize(3); ids[0] = pts[2]; ids[1] = pts[1]; ids[2] = pts[0]; }
1151 else if (i_face == 1) { ids.resize(3); ids[0] = pts[1]; ids[1] = pts[3]; ids[2] = pts[0]; }
1152 else if (i_face == 2) { ids.resize(3); ids[0] = pts[3]; ids[1] = pts[2]; ids[2] = pts[0]; }
1153 else if (i_face == 3) { ids.resize(3); ids[0] = pts[2]; ids[1] = pts[3]; ids[2] = pts[1]; }
1155 } else if (type_cell == VTK_PYRAMID) {
1156 if (i_face == 0) { ids.resize(4); ids[0] = pts[0]; ids[1] = pts[3]; ids[2] = pts[2]; ids[3] = pts[1]; }
1157 else if (i_face == 1) { ids.resize(3); ids[0] = pts[0]; ids[1] = pts[1]; ids[2] = pts[4]; }
1158 else if (i_face == 2) { ids.resize(3); ids[0] = pts[1]; ids[1] = pts[2]; ids[2] = pts[4]; }
1159 else if (i_face == 3) { ids.resize(3); ids[0] = pts[2]; ids[1] = pts[3]; ids[2] = pts[4]; }
1160 else if (i_face == 4) { ids.resize(3); ids[0] = pts[3]; ids[1] = pts[0]; ids[2] = pts[4]; }
1162 } else if (type_cell == VTK_WEDGE) {
1163 if (i_face == 0) { ids.resize(3); ids[0] = pts[0]; ids[1] = pts[1]; ids[2] = pts[2]; }
1164 else if (i_face == 1) { ids.resize(3); ids[0] = pts[3]; ids[1] = pts[5]; ids[2] = pts[4]; }
1165 else if (i_face == 2) { ids.resize(4); ids[0] = pts[3]; ids[1] = pts[4]; ids[2] = pts[1]; ids[3] = pts[0]; }
1166 else if (i_face == 3) { ids.resize(4); ids[0] = pts[1]; ids[1] = pts[4]; ids[2] = pts[5]; ids[3] = pts[2]; }
1167 else if (i_face == 4) { ids.resize(4); ids[0] = pts[0]; ids[1] = pts[2]; ids[2] = pts[5]; ids[3] = pts[3]; }
1169 } else if (type_cell == VTK_HEXAHEDRON) {
1170 if (i_face == 0) { ids.resize(4); ids[0] = pts[0]; ids[1] = pts[3]; ids[2] = pts[2]; ids[3] = pts[1]; }
1171 else if (i_face == 1) { ids.resize(4); ids[0] = pts[4]; ids[1] = pts[5]; ids[2] = pts[6]; ids[3] = pts[7]; }
1172 else if (i_face == 2) { ids.resize(4); ids[0] = pts[0]; ids[1] = pts[1]; ids[2] = pts[5]; ids[3] = pts[4]; }
1173 else if (i_face == 3) { ids.resize(4); ids[0] = pts[3]; ids[1] = pts[7]; ids[2] = pts[6]; ids[3] = pts[2]; }
1174 else if (i_face == 4) { ids.resize(4); ids[0] = pts[0]; ids[1] = pts[4]; ids[2] = pts[7]; ids[3] = pts[3]; }
1175 else if (i_face == 5) { ids.resize(4); ids[0] = pts[1]; ids[1] = pts[2]; ids[2] = pts[6]; ids[3] = pts[5]; }
1177 } else {
1178 EG_BUG; // not implemented
1182 vec3_t EgVtkObject::getNormalOfCell(vtkUnstructuredGrid *grid, vtkIdType id_cell, int i_face)
1184 QVector<vtkIdType> ids;
1185 getFaceOfCell(grid, id_cell, i_face, ids);
1186 if (ids.size() == 0) {
1187 EG_BUG;
1189 QVector<vec3_t> x(ids.size() + 1);
1190 vec3_t xc(0,0,0);
1191 for (int i = 0; i < ids.size(); ++i) {
1192 grid->GetPoint(ids[i], x[i].data());
1193 xc += x[i];
1195 x[ids.size()] = x[0];
1196 xc *= 1.0/ids.size();
1197 vec3_t n(0,0,0);
1198 for (int i = 0; i < ids.size(); ++i) {
1199 vec3_t u = x[i] - xc;
1200 vec3_t v = x[i+1] - xc;
1201 n += 0.5*u.cross(v);
1203 return n;
1206 void EgVtkObject::getEdgeOfCell(vtkUnstructuredGrid *grid, vtkIdType id_cell, int i_edge, QVector<vtkIdType> &ids)
1208 vtkIdType type_cell = grid->GetCellType(id_cell);
1209 ids.clear();
1210 vtkIdType *pts, N_pts;
1211 grid->GetCellPoints(id_cell, N_pts, pts);
1212 if (type_cell == VTK_TETRA) {
1213 ids.resize(2);
1214 if (i_edge == 0) { ids[0] = pts[0]; ids[1] = pts[1]; }
1215 else if (i_edge == 1) { ids[0] = pts[0]; ids[1] = pts[2]; }
1216 else if (i_edge == 2) { ids[0] = pts[0]; ids[1] = pts[3]; }
1217 else if (i_edge == 3) { ids[0] = pts[1]; ids[1] = pts[2]; }
1218 else if (i_edge == 4) { ids[0] = pts[1]; ids[1] = pts[3]; }
1219 else if (i_edge == 5) { ids[0] = pts[2]; ids[1] = pts[3]; }
1220 } else {
1221 EG_BUG; // not implemented
1225 bool EgVtkObject::saveGrid(vtkUnstructuredGrid* a_grid, QString file_name)
1227 file_name += ".vtu";
1228 addVtkTypeInfo(a_grid);
1229 createIndices(a_grid);
1230 EG_VTKSP(vtkXMLUnstructuredGridWriter,vtu);
1231 vtu->SetFileName(qPrintable(file_name));
1232 vtu->SetDataModeToBinary();
1233 vtu->SetInput(a_grid);
1234 vtu->Write();
1235 if(vtu->GetErrorCode()) {
1236 return false;
1238 else {
1239 return true;
1243 void EgVtkObject::addVtkTypeInfo(vtkUnstructuredGrid* a_grid)
1245 EG_VTKSP(vtkIntArray, vtk_type);
1246 vtk_type->SetName("vtk_type");
1247 vtk_type->SetNumberOfValues(a_grid->GetNumberOfCells());
1248 //EG_VTKDCC(vtkDoubleArray, cell_VA, a_grid, "cell_VA");
1249 for (vtkIdType cellId = 0; cellId < a_grid->GetNumberOfCells(); ++cellId) {
1250 vtk_type->SetValue(cellId, a_grid->GetCellType(cellId));
1251 //cell_VA->SetValue(cellId, GeometryTools::cellVA(a_grid, cellId, true));
1253 a_grid->GetCellData()->AddArray(vtk_type);
1256 vtkIdType EgVtkObject::addGrid(vtkUnstructuredGrid *main_grid, vtkUnstructuredGrid *grid_to_add, vtkIdType offset)
1258 for (vtkIdType id_node = 0; id_node < grid_to_add->GetNumberOfPoints(); ++id_node) {
1259 vec3_t x;
1260 grid_to_add->GetPoints()->GetPoint(id_node, x.data());
1261 main_grid->GetPoints()->SetPoint(offset + id_node, x.data());
1262 copyNodeData(grid_to_add, id_node, main_grid, offset + id_node);
1264 for (vtkIdType id_cell = 0; id_cell < grid_to_add->GetNumberOfCells(); ++id_cell) {
1265 vtkIdType N_pts, *pts;
1266 vtkIdType type_cell = grid_to_add->GetCellType(id_cell);
1267 grid_to_add->GetCellPoints(id_cell, N_pts, pts);
1268 QVector <vtkIdType> new_pts(N_pts);
1269 for(int i=0;i<N_pts;i++) new_pts[i] = offset + pts[i];
1270 vtkIdType id_new_cell = main_grid->InsertNextCell(type_cell, N_pts, new_pts.data());
1271 copyCellData(grid_to_add, id_cell, main_grid, id_new_cell);
1273 return( offset + grid_to_add->GetNumberOfPoints() );
1276 QSet<int> EgVtkObject::getAllBoundaryCodes(vtkUnstructuredGrid *grid)
1278 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
1279 QSet<int> bcs;
1280 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
1281 if (isSurface(id_cell, grid)) {
1282 bcs.insert(cell_code->GetValue(id_cell));
1285 return bcs;
1288 bool EgVtkObject::cellContainsNode(vtkUnstructuredGrid *grid, vtkIdType id_cell, vtkIdType id_node)
1290 vtkIdType num_pts, *pts;
1291 grid->GetCellPoints(id_cell, num_pts, pts);
1292 for (int i = 0; i < num_pts; ++i) {
1293 if (pts[i] == id_node) {
1294 return true;
1297 return false;
1300 void EgVtkObject::createPolyDataC2C(vtkPolyData *poly_data, QVector<QVector<vtkIdType> > &c2c)
1302 c2c.clear();
1303 c2c.resize(poly_data->GetNumberOfCells());
1304 QVector<QSet<vtkIdType> > n2c;
1305 createPolyDataN2C(poly_data, n2c);
1306 EG_FORALL_CELLS(id_poly, poly_data) {
1307 EG_GET_CELL(id_poly, poly_data);
1308 QSet<vtkIdType> ids;
1309 for (int i = 0; i < num_pts; ++i) {
1310 vtkIdType p1 = pts[i];
1311 vtkIdType p2 = pts[0];
1312 if (i < num_pts - 1) {
1313 p2 = pts[i+1];
1315 QSet<vtkIdType> shared_polys = n2c[p1];
1316 shared_polys.intersect(n2c[p2]);
1317 if (shared_polys.size() == 0) {
1318 EG_BUG;
1320 if (shared_polys.size() > 2) {
1321 EG_BUG;
1323 foreach (vtkIdType id_neigh, shared_polys) {
1324 if (id_neigh != id_poly) {
1325 ids.insert(id_neigh);
1330 c2c[id_poly].resize(ids.size());
1331 int i = 0;
1332 foreach (vtkIdType id_neigh, ids) {
1333 c2c[id_poly][i] = id_neigh;
1334 ++i;
1340 void EgVtkObject::createPolyDataN2C(vtkPolyData *poly_data, QVector<QSet<vtkIdType> > &n2c)
1342 n2c.clear();
1343 n2c.resize(poly_data->GetNumberOfPoints());
1344 EG_FORALL_CELLS(id_face, poly_data) {
1345 EG_GET_CELL(id_face, poly_data);
1346 for (int i = 0; i < num_pts; ++i) {
1347 n2c[pts[i]].insert(id_face);
1352 void EgVtkObject::createPolyDataN2N(vtkPolyData *poly_data, QVector<QSet<vtkIdType> > &n2n)
1354 n2n.clear();
1355 n2n.resize(poly_data->GetNumberOfPoints());
1356 EG_FORALL_CELLS(id_face, poly_data) {
1357 EG_GET_CELL(id_face, poly_data);
1358 n2n[pts[0]].insert(pts[num_pts - 1]);
1359 n2n[pts[num_pts-1]].insert(pts[0]);
1360 for (int i = 1; i < num_pts; ++i) {
1361 n2n[pts[i]].insert(pts[i-1]);
1362 n2n[pts[i-1]].insert(pts[i]);