compiles on openSUSE 15.4 part 2
[engrid-github.git] / src / libengrid / operation.cpp
blob06668859ec2f81b999f999fe7d9a1dfd7deaebf1
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
11 // + +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
16 // + +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "operation.h"
23 #include "guimainwindow.h"
24 #include "egvtkobject.h"
25 #include "setboundarycode.h"
27 #include <vtkTriangleFilter.h>
28 #include <vtkInformation.h>
29 #include <vtkInformationVector.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkPointData.h>
32 #include <vtkPolyData.h>
33 #include <vtkPolygon.h>
34 #include <vtkStreamingDemandDrivenPipeline.h>
35 #include <vtkCellArray.h>
36 #include <vtkCellData.h>
37 #include <vtkCellLocator.h>
38 #include <vtkFloatArray.h>
39 #include <vtkMath.h>
40 #include <vtkCharArray.h>
42 #include <QApplication>
43 #include <QTime>
45 #include "geometrytools.h"
47 using namespace GeometryTools;
49 QSet<Operation*> Operation::garbage_operations;
51 QVector<vtkIdType> m_static_DummyCells;
52 QVector<int> m_static_DummyRCells;
53 QVector<vtkIdType> m_static_DummyNodes;
54 QVector<int> m_static_DummyRNodes;
55 QVector<QVector<int> > m_static_DummyN2N;
56 QVector<QVector<int> > m_static_DummyN2C;
57 QVector<QVector<int> > m_static_DummyC2C;
59 void Operation::collectGarbage()
61 QSet<Operation*> delete_operations;
63 foreach (Operation *op, garbage_operations)
65 if (!op->getThread().isRunning()) {
66 delete_operations.insert(op);
67 cout << "deleting Operation " << op << endl;
68 delete op;
72 foreach (Operation *op, delete_operations)
74 garbage_operations.remove(op);
78 Operation::Operation()
80 m_Grid = NULL;
81 lock_gui = false;
82 m_quicksave = false;
83 m_resetoperationcounter = false;
84 err = NULL;
85 autoset = true;
86 m_TypeName = "undefined";
87 m_MenuText = "undefined";
88 m_Verbose = false;
91 Operation::~Operation()
93 if (err) {
94 err->display();
95 delete err;
99 void Operation::del()
101 garbage_operations.insert(this);
104 void OperationThread::run()
106 try {
107 GuiMainWindow::lock();
108 GuiMainWindow::pointer()->setBusy();
109 op->operate();
110 cout << "secs. for " << qPrintable(op->getTypeName()) << ": " << op->elapsedTime() << endl;
111 } catch (Error err) {
112 op->err = new Error();
113 *(op->err) = err;
115 GuiMainWindow::unlock();
116 GuiMainWindow::pointer()->setIdle();
119 void Operation::setTypeName(QString name)
121 int i = 0;
122 while ((i < name.size()) && (name[i].isDigit())) {
123 ++i;
125 m_TypeName = name.right(name.size() - i);
128 void Operation::operator()()
130 setStartTime();
131 if (lock_gui) {
132 if (GuiMainWindow::tryLock()) {
133 checkGrid();
134 thread.setOperation(this);
135 GuiMainWindow::unlock();
136 thread.start(QThread::LowPriority);
137 } else {
138 QMessageBox::warning(NULL, "not permitted", "Operation is not permitted while background process is running!");
140 } else {
141 checkGrid();
142 const bool gui_thread = QThread::currentThread() == QCoreApplication::instance()->thread();
143 if (gui_thread) {
144 try {
145 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
146 operate();
147 QApplication::restoreOverrideCursor();
148 cout << "secs. for " << qPrintable(getTypeName()) << ": " << elapsedTime() << endl;
149 } catch (Error err) {
150 err.display();
152 } else {
153 operate();
155 if(m_resetoperationcounter) GuiMainWindow::pointer()->resetOperationCounter();
156 if(m_quicksave) GuiMainWindow::pointer()->quickSave();
160 void Operation::setAllCells()
162 QVector<vtkIdType> all_cells;
163 getAllCells(all_cells, m_Grid);
164 setCells(all_cells);
167 void Operation::setAllVolumeCells()
169 QVector<vtkIdType> cells;
170 getAllVolumeCells(cells, m_Grid);
171 setCells(cells);
174 void Operation::setAllSurfaceCells()
176 QVector<vtkIdType> cells;
177 getAllSurfaceCells(cells, m_Grid);
178 setCells(cells);
181 void Operation::setVolume(QString volume_name)
183 m_Part.setGrid(m_Grid);
184 m_Part.setVolume(volume_name);
187 void Operation::setMeshPartition(const MeshPartition &part)
189 m_Part.setGrid(part.getGrid());
190 m_Part.setCells(part.getCells());
191 m_Grid = m_Part.getGrid();
194 void Operation::checkGrid()
196 if (m_Grid == NULL) {
197 m_Grid = GuiMainWindow::pointer()->getGrid();
199 l2g_t cells = getPartCells();
200 if ((cells.size() == 0) && autoset) {
201 setAllCells();
205 void Operation::updateActors()
207 mainWindow()->updateActors();
210 GuiMainWindow* Operation::mainWindow()
212 return GuiMainWindow::pointer();
215 void Operation::populateBoundaryCodes(QListWidget *lw)
217 QVector<int> bcs;
218 mainWindow()->getAllBoundaryCodes(bcs);
219 foreach(int bc, bcs) {
220 QListWidgetItem *lwi = new QListWidgetItem(lw);
221 lwi->setCheckState(Qt::Unchecked);
222 QString text = "";
223 QTextStream ts(&text);
224 ts << bc << " : " << GuiMainWindow::pointer()->getBC(bc).getName();
225 lwi->setText(text);
226 lwi->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
230 void Operation::populateVolumes(QListWidget *lw)
232 QList<VolumeDefinition> vols = mainWindow()->getAllVols();
233 foreach (VolumeDefinition V, vols) {
234 QListWidgetItem *lwi = new QListWidgetItem(lw);
235 lwi->setText(V.getName());
239 void Operation::eliminateDuplicateCells(bool surf_only)
241 QVector<QVector<vtkIdType> > cell_nodes(m_Grid->GetNumberOfCells());
243 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
244 if (!surf_only || isSurface(id_cell, m_Grid)) {
245 EG_GET_CELL(id_cell, m_Grid);
246 QVector<vtkIdType> nodes(num_pts);
247 for (int i = 0; i < num_pts; ++i) {
248 nodes[i] = pts[i];
250 qSort(nodes);
251 cell_nodes[id_cell] = nodes;
254 QList<vtkIdType> new_cells;
255 for (vtkIdType id_cell1 = 0; id_cell1 < m_Grid->GetNumberOfCells(); ++id_cell1) {
256 bool duplicate_cell = false;
257 if (!surf_only || isSurface(id_cell1, m_Grid)) {
258 EG_GET_CELL(id_cell1, m_Grid);
259 for (int i = 0; i < num_pts; ++i) {
260 for (int j = 0; j < m_Part.n2cGSize(pts[i]); ++j) {
261 vtkIdType id_cell2 = m_Part.n2cGG(pts[i], j);
262 if (id_cell1 != id_cell2) {
263 if (!surf_only || isSurface(id_cell2, m_Grid)) {
264 if (cell_nodes[id_cell1] == cell_nodes[id_cell2]) {
265 duplicate_cell = true;
266 break;
273 if (!duplicate_cell) {
274 new_cells.append(id_cell1);
277 EG_VTKSP(vtkUnstructuredGrid, new_grid);
278 makeCopy(m_Grid, new_grid, new_cells);
279 makeCopy(new_grid, m_Grid);
282 void Operation::createFeatureBcs(double feature_angle)
284 m_New2OldBc.clear();
285 SetBoundaryCode set_bc;
286 set_bc.setGrid(m_Grid);
287 set_bc.setAllSurfaceCells();
288 QSet <int> all_bcs = GuiMainWindow::pointer()->getAllBoundaryCodes();
289 foreach (int bc, all_bcs) {
290 m_New2OldBc[bc] = bc;
293 QMap<int, QList<vtkIdType> > oldbc2cells;
294 int max_bc = 1;
295 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
296 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
297 int bc = cell_code->GetValue(id_cell);
298 max_bc = max(max_bc, bc + 1);
299 if (all_bcs.contains(bc)) {
300 oldbc2cells[bc] << id_cell;
303 bool done = false;
304 int old_max_bc = max_bc;
305 do {
306 vtkIdType id_start = -1;
307 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
308 if (cell_code->GetValue(id_cell) < old_max_bc && isSurface(id_cell, m_Grid)) {
309 id_start = id_cell;
310 set_bc.setOLdBC(cell_code->GetValue(id_cell));
311 break;
314 if (id_start == -1) {
315 done = true;
316 } else {
317 set_bc.setFeatureAngle(feature_angle);
318 set_bc.setNewBC(max_bc);
319 set_bc.setProcessAll(true);
320 set_bc.setSelectAllVisible(false);
321 set_bc.setOnlyPickedCell(false);
322 set_bc.setOnlyPickedCellAndNeighbours(false);
323 set_bc.setStart(id_start);
324 set_bc();
325 ++max_bc;
327 } while (!done);
328 m_New2OldBc.clear();
329 foreach (int bc, oldbc2cells.keys()) {
330 foreach (vtkIdType id_cell, oldbc2cells[bc]) {
331 m_New2OldBc[cell_code->GetValue(id_cell)] = bc;
336 void Operation::restoreNormalBcs()
338 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
339 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
340 int bc = cell_code->GetValue(id_cell);
341 cell_code->SetValue(id_cell, m_New2OldBc[bc]);