Added basic compilation instructions to README.md
[engrid-github.git] / src / libengrid / operation.cpp
blob6177c5699ccea773b0985ae28c08f11cab761ab6
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 vtkIdType N_pts, *pts;
246 m_Grid->GetCellPoints(id_cell, N_pts, pts);
247 QVector<vtkIdType> nodes(N_pts);
248 for (int i = 0; i < N_pts; ++i) {
249 nodes[i] = pts[i];
251 qSort(nodes);
252 cell_nodes[id_cell] = nodes;
255 QList<vtkIdType> new_cells;
256 for (vtkIdType id_cell1 = 0; id_cell1 < m_Grid->GetNumberOfCells(); ++id_cell1) {
257 bool duplicate_cell = false;
258 if (!surf_only || isSurface(id_cell1, m_Grid)) {
259 vtkIdType N_pts, *pts;
260 m_Grid->GetCellPoints(id_cell1, N_pts, pts);
261 for (int i = 0; i < N_pts; ++i) {
262 for (int j = 0; j < m_Part.n2cGSize(pts[i]); ++j) {
263 vtkIdType id_cell2 = m_Part.n2cGG(pts[i], j);
264 if (id_cell1 != id_cell2) {
265 if (!surf_only || isSurface(id_cell2, m_Grid)) {
266 if (cell_nodes[id_cell1] == cell_nodes[id_cell2]) {
267 duplicate_cell = true;
268 break;
275 if (!duplicate_cell) {
276 new_cells.append(id_cell1);
279 EG_VTKSP(vtkUnstructuredGrid, new_grid);
280 makeCopy(m_Grid, new_grid, new_cells);
281 makeCopy(new_grid, m_Grid);
284 void Operation::createFeatureBcs(double feature_angle)
286 m_New2OldBc.clear();
287 SetBoundaryCode set_bc;
288 set_bc.setGrid(m_Grid);
289 set_bc.setAllSurfaceCells();
290 QSet <int> all_bcs = GuiMainWindow::pointer()->getAllBoundaryCodes();
291 foreach (int bc, all_bcs) {
292 m_New2OldBc[bc] = bc;
295 QMap<int, QList<vtkIdType> > oldbc2cells;
296 int max_bc = 1;
297 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
298 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
299 int bc = cell_code->GetValue(id_cell);
300 max_bc = max(max_bc, bc + 1);
301 if (all_bcs.contains(bc)) {
302 oldbc2cells[bc] << id_cell;
305 bool done = false;
306 int old_max_bc = max_bc;
307 do {
308 vtkIdType id_start = -1;
309 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
310 if (cell_code->GetValue(id_cell) < old_max_bc && isSurface(id_cell, m_Grid)) {
311 id_start = id_cell;
312 set_bc.setOLdBC(cell_code->GetValue(id_cell));
313 break;
316 if (id_start == -1) {
317 done = true;
318 } else {
319 set_bc.setFeatureAngle(feature_angle);
320 set_bc.setNewBC(max_bc);
321 set_bc.setProcessAll(true);
322 set_bc.setSelectAllVisible(false);
323 set_bc.setOnlyPickedCell(false);
324 set_bc.setOnlyPickedCellAndNeighbours(false);
325 set_bc.setStart(id_start);
326 set_bc();
327 ++max_bc;
329 } while (!done);
330 m_New2OldBc.clear();
331 foreach (int bc, oldbc2cells.keys()) {
332 foreach (vtkIdType id_cell, oldbc2cells[bc]) {
333 m_New2OldBc[cell_code->GetValue(id_cell)] = bc;
338 void Operation::restoreNormalBcs()
340 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
341 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
342 int bc = cell_code->GetValue(id_cell);
343 cell_code->SetValue(id_cell, m_New2OldBc[bc]);