1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
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. +
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. +
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/>. +
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>
40 #include <vtkCharArray.h>
42 #include <QApplication>
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
;
72 foreach (Operation
*op
, delete_operations
)
74 garbage_operations
.remove(op
);
78 Operation::Operation()
83 m_resetoperationcounter
= false;
86 m_TypeName
= "undefined";
87 m_MenuText
= "undefined";
91 Operation::~Operation()
101 garbage_operations
.insert(this);
104 void OperationThread::run()
107 GuiMainWindow::lock();
108 GuiMainWindow::pointer()->setBusy();
110 cout
<< "secs. for " << qPrintable(op
->getTypeName()) << ": " << op
->elapsedTime() << endl
;
111 } catch (Error err
) {
112 op
->err
= new Error();
115 GuiMainWindow::unlock();
116 GuiMainWindow::pointer()->setIdle();
119 void Operation::setTypeName(QString name
)
122 while ((i
< name
.size()) && (name
[i
].isDigit())) {
125 m_TypeName
= name
.right(name
.size() - i
);
128 void Operation::operator()()
132 if (GuiMainWindow::tryLock()) {
134 thread
.setOperation(this);
135 GuiMainWindow::unlock();
136 thread
.start(QThread::LowPriority
);
138 QMessageBox::warning(NULL
, "not permitted", "Operation is not permitted while background process is running!");
142 const bool gui_thread
= QThread::currentThread() == QCoreApplication::instance()->thread();
145 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
147 QApplication::restoreOverrideCursor();
148 cout
<< "secs. for " << qPrintable(getTypeName()) << ": " << elapsedTime() << endl
;
149 } catch (Error err
) {
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
);
167 void Operation::setAllVolumeCells()
169 QVector
<vtkIdType
> cells
;
170 getAllVolumeCells(cells
, m_Grid
);
174 void Operation::setAllSurfaceCells()
176 QVector
<vtkIdType
> cells
;
177 getAllSurfaceCells(cells
, m_Grid
);
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
) {
205 void Operation::updateActors()
207 mainWindow()->updateActors();
210 GuiMainWindow
* Operation::mainWindow()
212 return GuiMainWindow::pointer();
215 void Operation::populateBoundaryCodes(QListWidget
*lw
)
218 mainWindow()->getAllBoundaryCodes(bcs
);
219 foreach(int bc
, bcs
) {
220 QListWidgetItem
*lwi
= new QListWidgetItem(lw
);
221 lwi
->setCheckState(Qt::Unchecked
);
223 QTextStream
ts(&text
);
224 ts
<< bc
<< " : " << GuiMainWindow::pointer()->getBC(bc
).getName();
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
) {
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;
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
)
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
;
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
;
306 int old_max_bc
= max_bc
;
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
)) {
312 set_bc
.setOLdBC(cell_code
->GetValue(id_cell
));
316 if (id_start
== -1) {
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
);
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
]);