-Added class OpenFOAMTools
[engrid.git] / src / guimainwindow.cpp
blob267d2ce8f3758271568c49dfb63db91803c05ae9
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008,2009 Oliver Gloth +
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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "guimainwindow.h"
24 #include "guiselectboundarycodes.h"
25 #include "guiimproveaspectratio.h"
26 #include "guinormalextrusion.h"
27 #include "guisetboundarycode.h"
28 #include "guipick.h"
30 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
31 #include "stlreader.h"
32 #include "gmshreader.h"
33 #include "gmshwriter.h"
34 #include "neutralwriter.h"
35 #include "stlwriter.h"
36 #include "correctsurfaceorientation.h"
37 #include "guieditboundaryconditions.h"
39 #include <vtkRenderer.h>
40 #include <vtkRenderWindow.h>
41 #include <vtkXMLUnstructuredGridWriter.h>
42 #include <vtkXMLUnstructuredGridReader.h>
43 #include <vtkProperty.h>
44 #include <vtkCallbackCommand.h>
45 #include <vtkCamera.h>
46 #include <vtkCharArray.h>
47 #include <vtkTextActor.h>
48 #include <vtkVectorText.h>
49 #include <vtkFollower.h>
50 #include <vtkLookupTable.h>
51 #include <vtkScalarBarActor.h>
53 #include <QFileDialog>
54 #include <QFileSystemWatcher>
55 #include <QFileInfo>
56 #include <stdlib.h>
57 #include <stdio.h>
59 #include "geometrytools.h"
60 using namespace GeometryTools;
62 #include "guisettingsviewer.h"
63 #include "guitransform.h"
64 #include "egvtkinteractorstyle.h"
65 #include "showinfo.h"
67 QString GuiMainWindow::m_cwd = ".";
68 QSettings GuiMainWindow::m_qset("enGits","enGrid");
69 GuiMainWindow* GuiMainWindow::THIS = NULL;
70 QMutex GuiMainWindow::m_Mutex;
72 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
74 ui.setupUi(this);
75 THIS = this;
77 setGeometry(m_qset.value("GuiMainWindow", QRect(200,200,400,400)).toRect());
78 restoreState(m_qset.value("dockWidget_states").toByteArray());
80 # include "std_connections.h"
82 if (m_qset.contains("working_directory")) {
83 m_cwd = m_qset.value("working_directory").toString();
86 setupVtk();
88 resetOperationCounter();//clears undo/redo list and disables undo/redo
89 m_CurrentFilename = "untitled.egc";
90 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
92 m_StatusBar = new QStatusBar(this);
93 setStatusBar(m_StatusBar);
94 m_StatusLabel = new QLabel(this);
95 m_StatusBar->addWidget(m_StatusLabel);
97 QString txt = "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms), ";
98 txt += "0 surface cells (0 triangles, 0 quads), 0 nodes";
99 m_StatusLabel->setText(txt);
100 ui.label_node_cell_info->setText(txt);
102 QString user = QString(getenv("USER"));
103 QString basename="enGrid_output.txt";
105 // define temporary path
106 QDir dir("/");
107 if (m_qset.contains("tmp_directory")) {
108 m_LogDir = m_qset.value("tmp_directory").toString();
109 } else {
110 m_LogDir = dir.tempPath();
112 QDateTime now = QDateTime::currentDateTime();
113 m_LogDir = m_LogDir + "/" + "enGrid_" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz") + "/";
114 dir.mkpath(m_LogDir);
116 m_LogFileName = m_LogDir + basename;
117 cout << "m_LogFileName=" << qPrintable(m_LogFileName) << endl;
119 m_SystemStdout = stdout;
120 freopen (m_LogFileName.toAscii().data(), "w", stdout);
122 m_Busy = false;
124 setPickMode(true,true);
125 m_PickedPoint = -1;
126 m_PickedCell = -1;
128 updateStatusBar();
130 connect(&m_GarbageTimer, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
131 m_GarbageTimer.start(1000);
133 connect(&m_LogTimer, SIGNAL(timeout()), this, SLOT(updateOutput()));
134 m_LogTimer.start(1000);
136 m_N_chars = 0;
138 bool exp_features=false;
139 getSet("","enable experimental features",false,exp_features);
140 bool undo_redo;
141 getSet("","enable undo/redo",false,undo_redo);
142 bool undo_redo_mode;
143 getSet("","use RAM for undo/redo oprations",false,undo_redo_mode);
145 ui.actionFoamWriter->setEnabled(exp_features);
147 m_ReferenceSize=0.2;
149 ui.doubleSpinBox_HueMin->setValue(0.667);
150 ui.doubleSpinBox_HueMax->setValue(0);
152 egvtkInteractorStyle *style = egvtkInteractorStyle::New();
153 getInteractor()->SetInteractorStyle(style);
154 style->Delete();
156 // initialise XML document
157 QDomElement root = m_XmlDoc.createElement("engridcase");
158 m_XmlDoc.appendChild(root);
160 m_SolverIndex = 0;
163 //end of GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
165 GuiMainWindow::~GuiMainWindow()
167 m_qset.setValue("GuiMainWindow", this->geometry());
168 m_qset.setValue("dockWidget_states", this->saveState());
170 #ifndef QT_DEBUG
171 QDirIterator it(m_LogDir);
172 while (it.hasNext()) {
173 QString str = it.next();
174 QFileInfo fileinfo(str);
175 if(fileinfo.isFile()) {
176 QFile file(str);
177 if(!file.remove()) qDebug() << "Failed to remove " << file.fileName();
180 QDir dir(m_LogDir);
181 dir.rmdir(m_LogDir);
182 #endif
186 void GuiMainWindow::setupVtk()
188 grid = vtkUnstructuredGrid::New();
189 m_Renderer = vtkRenderer::New();
190 getRenderWindow()->AddRenderer(m_Renderer);
192 // coordinate axes
193 m_Axes = vtkCubeAxesActor2D::New();
195 m_Axes->SetCamera(getRenderer()->GetActiveCamera());
196 getRenderer()->AddActor(m_Axes);
197 m_Axes->SetVisibility(0);
199 // surface pipelines
200 m_BackfaceProperty = vtkProperty::New();
201 m_SurfaceFilter = vtkGeometryFilter::New();
202 m_SurfaceMapper = vtkPolyDataMapper::New();
203 m_SurfaceWireMapper = vtkPolyDataMapper::New();
204 m_BCodesFilter = vtkEgBoundaryCodesFilter::New();
205 m_LookupTable = vtkLookupTable::New();
206 m_SurfaceActor = vtkActor::New();
207 m_SurfaceWireActor = vtkActor::New();
208 m_LegendActor = vtkScalarBarActor::New();
210 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
211 m_BCodesFilter->SetInput(grid);
212 m_SurfaceFilter->SetInput(m_BCodesFilter->GetOutput());
213 m_SurfaceMapper->SetInput(m_SurfaceFilter->GetOutput());
214 m_SurfaceWireMapper->SetInput(m_SurfaceFilter->GetOutput());
215 m_SurfaceMapper->SetLookupTable(m_LookupTable);
216 m_SurfaceActor->GetProperty()->SetRepresentationToSurface();
217 m_SurfaceActor->GetProperty()->SetColor(0.5,1,0.5);
218 m_SurfaceActor->SetBackfaceProperty(m_BackfaceProperty);
219 m_SurfaceActor->GetBackfaceProperty()->SetColor(1,1,0.5);
220 m_SurfaceActor->SetMapper(m_SurfaceMapper);
221 getRenderer()->AddActor(m_SurfaceActor);
222 m_SurfaceActor->SetVisibility(1);
223 m_LegendActor->SetLookupTable(m_LookupTable);
224 getRenderer()->AddActor(m_LegendActor);
225 m_LegendActor->SetVisibility(0);
226 m_SurfaceWireActor->GetProperty()->SetRepresentationToWireframe();
227 m_SurfaceWireActor->GetProperty()->SetColor(0,0,1);
228 m_SurfaceWireActor->SetMapper(m_SurfaceWireMapper);
229 getRenderer()->AddActor(m_SurfaceWireActor);
230 m_SurfaceWireActor->SetVisibility(1);
232 // tetra pipline
233 m_ExtrTetras = vtkEgExtractVolumeCells::New();
234 m_TetraActor = vtkActor::New();
235 m_TetraGeometry = vtkGeometryFilter::New();
236 m_TetraMapper = vtkPolyDataMapper::New();
238 m_ExtrTetras->SetInput(grid);
239 m_ExtrTetras->SetAllOff();
240 m_ExtrTetras->SetTetrasOn();;
241 m_TetraGeometry->SetInput(m_ExtrTetras->GetOutput());
242 m_TetraMapper->SetInput(m_TetraGeometry->GetOutput());
243 m_TetraActor->SetMapper(m_TetraMapper);
244 m_TetraActor->GetProperty()->SetColor(1,0,0);
245 getRenderer()->AddActor(m_TetraActor);
246 m_TetraActor->SetVisibility(0);
248 // pyramid pipeline
249 m_PyramidActor = vtkActor::New();
250 m_ExtrPyramids = vtkEgExtractVolumeCells::New();
251 m_PyramidGeometry = vtkGeometryFilter::New();
252 m_PyramidMapper = vtkPolyDataMapper::New();
254 m_ExtrPyramids->SetInput(grid);
255 m_ExtrPyramids->SetAllOff();
256 m_ExtrPyramids->SetPyramidsOn();
257 m_PyramidGeometry->SetInput(m_ExtrPyramids->GetOutput());
258 m_PyramidMapper->SetInput(m_PyramidGeometry->GetOutput());
259 m_PyramidActor->SetMapper(m_PyramidMapper);
260 m_PyramidActor->GetProperty()->SetColor(1,1,0);
261 getRenderer()->AddActor(m_PyramidActor);
262 m_PyramidActor->SetVisibility(0);
264 // wedge pipeline
265 m_WedgeActor = vtkActor::New();
266 m_ExtrWedges = vtkEgExtractVolumeCells::New();
267 m_WedgeGeometry = vtkGeometryFilter::New();
268 m_WedgeMapper = vtkPolyDataMapper::New();
270 m_ExtrWedges->SetInput(grid);
271 m_ExtrWedges->SetAllOff();
272 m_ExtrWedges->SetWedgesOn();
273 m_WedgeGeometry->SetInput(m_ExtrWedges->GetOutput());
274 m_WedgeMapper->SetInput(m_WedgeGeometry->GetOutput());
275 m_WedgeActor->SetMapper(m_WedgeMapper);
276 m_WedgeActor->GetProperty()->SetColor(0,1,0);
277 getRenderer()->AddActor(m_WedgeActor);
278 m_WedgeActor->SetVisibility(0);
280 // hexa pipeline
281 m_HexaActor = vtkActor::New();
282 m_ExtrHexes = vtkEgExtractVolumeCells::New();
283 m_HexaGeometry = vtkGeometryFilter::New();
284 m_HexaMapper = vtkPolyDataMapper::New();
286 m_ExtrHexes->SetInput(grid);
287 m_ExtrHexes->SetAllOff();
288 m_ExtrHexes->SetHexesOn();
289 m_HexaGeometry->SetInput(m_ExtrHexes->GetOutput());
290 m_HexaMapper->SetInput(m_HexaGeometry->GetOutput());
291 m_HexaActor->SetMapper(m_HexaMapper);
292 m_HexaActor->GetProperty()->SetColor(0,0.7,1);
293 getRenderer()->AddActor(m_HexaActor);
294 m_HexaActor->SetVisibility(0);
296 // volume wire pipeline
297 m_VolumeWireActor = vtkActor::New();
298 m_ExtrVol = vtkEgExtractVolumeCells::New();
299 m_VolumeGeometry = vtkGeometryFilter::New();
300 m_VolumeWireMapper = vtkPolyDataMapper::New();
302 m_ExtrVol->SetInput(grid);
303 m_ExtrVol->SetAllOn();
304 m_VolumeGeometry->SetInput(m_ExtrVol->GetOutput());
305 m_VolumeWireMapper->SetInput(m_VolumeGeometry->GetOutput());
306 m_VolumeWireActor->SetMapper(m_VolumeWireMapper);
307 m_VolumeWireActor->GetProperty()->SetRepresentationToWireframe();
308 m_VolumeWireActor->GetProperty()->SetColor(0,0,1);
309 getRenderer()->AddActor(m_VolumeWireActor);
310 m_VolumeWireActor->SetVisibility(0);
312 // picker stuff
313 m_PickSphere = vtkSphereSource::New();
314 m_PickMapper = vtkPolyDataMapper::New();
315 m_PickActor = vtkActor::New();
316 m_CellPicker = vtkCellPicker::New();
317 m_PointPicker = vtkPointPicker::New();
319 m_PickSphere->SetRadius(0.25); //in case the user starts picking points instead of cells
320 m_PickMapper->SetInput(m_PickSphere->GetOutput());
321 m_PickActor->SetMapper(m_PickMapper);
322 m_PickActor->GetProperty()->SetRepresentationToSurface();
323 m_PickActor->GetProperty()->SetColor(0,0,1);
324 m_PickActor->VisibilityOff();
325 getRenderer()->AddActor(m_PickActor);
327 vtkCallbackCommand *cbc = vtkCallbackCommand::New();
328 cbc->SetCallback(pickCallBack);
330 m_CellPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
331 m_PointPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
333 // cbc->Delete();
336 void GuiMainWindow::updateOutput()
338 QFile log_file(m_LogFileName);
339 log_file.open(QIODevice::ReadOnly);
340 QByteArray buffer = log_file.readAll();
341 if (buffer.size() > m_N_chars) {
342 QByteArray newchars = buffer.right(buffer.size() - m_N_chars);
343 m_N_chars = buffer.size();
344 QString txt(newchars);
345 if (txt.right(1) == "\n") {
346 txt = txt.left(txt.size()-1);
348 ui.textEditOutput->append(txt);
352 void GuiMainWindow::exit()
354 QCoreApplication::exit();
357 vtkRenderWindow* GuiMainWindow::getRenderWindow()
359 return ui.qvtkWidget->GetRenderWindow();
362 vtkRenderer* GuiMainWindow::getRenderer()
364 return m_Renderer;
367 QVTKInteractor* GuiMainWindow::getInteractor()
369 return ui.qvtkWidget->GetInteractor();
372 QString GuiMainWindow::getCwd()
374 return m_cwd;
377 void GuiMainWindow::setCwd(QString dir)
379 m_cwd = dir;
380 m_qset.setValue("working_directory",dir);
383 void GuiMainWindow::scaleToData()
385 int current_field=ui.comboBox_Field->currentIndex();
386 if(current_field>0)
388 double range[2];
390 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
391 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
392 cout<<"current_field="<<current_field<<endl;
393 cout<<"range[0]="<<range[0]<<endl;
394 cout<<"range[1]="<<range[1]<<endl;
395 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
396 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
397 ui.doubleSpinBox_FieldMin->setValue(range[0]);
398 ui.doubleSpinBox_FieldMax->setValue(range[1]);
402 void GuiMainWindow::setClipX(const QString &txt)
404 m_ExtrVol->Setx(txt.toDouble());
405 m_ExtrTetras->Setx(txt.toDouble());
406 m_ExtrPyramids->Setx(txt.toDouble());
407 m_ExtrWedges->Setx(txt.toDouble());
408 m_ExtrHexes->Setx(txt.toDouble());
411 void GuiMainWindow::setClipY(const QString &txt)
413 m_ExtrVol->Sety(txt.toDouble());
414 m_ExtrTetras->Sety(txt.toDouble());
415 m_ExtrPyramids->Sety(txt.toDouble());
416 m_ExtrWedges->Sety(txt.toDouble());
417 m_ExtrHexes->Sety(txt.toDouble());
420 void GuiMainWindow::setClipZ(const QString &txt)
422 m_ExtrVol->Setz(txt.toDouble());
423 m_ExtrTetras->Setz(txt.toDouble());
424 m_ExtrPyramids->Setz(txt.toDouble());
425 m_ExtrWedges->Setz(txt.toDouble());
426 m_ExtrHexes->Setz(txt.toDouble());
429 void GuiMainWindow::setClipNX(const QString &txt)
431 m_ExtrVol->Setnx(txt.toDouble());
432 m_ExtrTetras->Setnx(txt.toDouble());
433 m_ExtrPyramids->Setnx(txt.toDouble());
434 m_ExtrWedges->Setnx(txt.toDouble());
435 m_ExtrHexes->Setnx(txt.toDouble());
438 void GuiMainWindow::setClipNY(const QString &txt)
440 m_ExtrVol->Setny(txt.toDouble());
441 m_ExtrTetras->Setny(txt.toDouble());
442 m_ExtrPyramids->Setny(txt.toDouble());
443 m_ExtrWedges->Setny(txt.toDouble());
444 m_ExtrHexes->Setny(txt.toDouble());
447 void GuiMainWindow::setClipNZ(const QString &txt)
449 m_ExtrVol->Setnz(txt.toDouble());
450 m_ExtrTetras->Setnz(txt.toDouble());
451 m_ExtrPyramids->Setnz(txt.toDouble());
452 m_ExtrWedges->Setnz(txt.toDouble());
453 m_ExtrHexes->Setnz(txt.toDouble());
456 void GuiMainWindow::updateSurfaceActors(bool forced)
458 if (ui.checkBoxSurface->isChecked()) {
459 if (forced) {
460 m_SurfaceFilter->Update();
463 // fill node field combobox
464 int current_field=ui.comboBox_Field->currentIndex();
465 ui.comboBox_Field->clear();
466 ui.comboBox_Field->addItem("None");
467 for (int i = 0; i < grid->GetPointData()->GetNumberOfArrays(); ++i) {
468 ui.comboBox_Field->addItem(grid->GetPointData()->GetArrayName(i));
470 if(current_field == -1) {
471 ui.comboBox_Field->setCurrentIndex(0);
472 } else {
473 ui.comboBox_Field->setCurrentIndex(current_field);
476 // fill cell field combobox
477 int current_cell_field = ui.comboBox_CellTextField->currentIndex();
478 ui.comboBox_CellTextField->clear();
479 ui.comboBox_CellTextField->addItem("Cell ID");
480 for (int i = 0; i < m_SurfaceFilter->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i) {
481 ui.comboBox_CellTextField->addItem(grid->GetCellData()->GetArrayName(i));
483 if(current_cell_field == -1) {
484 ui.comboBox_CellTextField->setCurrentIndex(0);
485 } else {
486 ui.comboBox_CellTextField->setCurrentIndex(current_cell_field);
488 current_field = ui.comboBox_Field->currentIndex();
489 if(current_field > 0) {
490 double range[2];
491 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
492 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
493 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
496 if(ui.comboBox_Field->currentIndex() > 0) {
497 m_SurfaceMapper->SetColorModeToMapScalars();
498 m_LookupTable->SetNumberOfColors(ui.spinBox_Color->value());
499 m_LookupTable->SetHueRange(ui.doubleSpinBox_HueMin->value(),ui.doubleSpinBox_HueMax->value());
500 m_LookupTable->Build();
501 m_SurfaceMapper->SetScalarModeToUsePointFieldData();
502 m_SurfaceMapper->ColorByArrayComponent(qPrintable(ui.comboBox_Field->currentText()),0);
503 m_SurfaceMapper->SetScalarRange(ui.doubleSpinBox_FieldMin->value(),ui.doubleSpinBox_FieldMax->value());
504 m_SurfaceMapper->ScalarVisibilityOn();
505 if(ui.checkBox_Legend->checkState()) {
506 m_LegendActor->SetVisibility(1);
507 } else {
508 m_LegendActor->SetVisibility(0);
510 } else {
511 m_SurfaceMapper->SetColorModeToDefault();
512 m_SurfaceMapper->ScalarVisibilityOff();
513 m_LegendActor->SetVisibility(0);
515 if (forced) {
516 m_BCodesFilter->Update();
518 if(ui.checkBox_ShowPickSphere->checkState()) {
519 if(m_UseVTKInteractor) {
520 if(ui.radioButton_CellPicker->isChecked()) {
521 getInteractor()->SetPicker(m_CellPicker);
522 vtkIdType id_cell = getPickedCell();
523 pickCell(id_cell);
524 } else {
525 getInteractor()->SetPicker(m_PointPicker);
526 vtkIdType id_node = getPickedPoint();
527 pickPoint(id_node);
529 } else {
530 if (ui.radioButton_CellPicker->isChecked()) {
531 pickCell(m_PickedCell);
532 } else {
533 pickPoint(m_PickedPoint);
537 m_SurfaceActor->SetVisibility(1);
538 m_SurfaceWireActor->SetVisibility(1);
539 } else {
540 m_SurfaceActor->SetVisibility(0);
541 m_SurfaceWireActor->SetVisibility(0);
545 void GuiMainWindow::updateVolumeActors(bool forced)
547 if (ui.checkBoxVolume->isChecked()) {
548 if (ui.checkBoxTetra->isChecked()) {
549 m_ExtrVol->SetTetrasOn();
550 if (ui.checkBoxClip->isChecked()) {
551 m_ExtrTetras->SetClippingOn();
552 } else {
553 m_ExtrTetras->SetClippingOff();
555 if (forced) {
556 m_TetraGeometry->Update();
558 m_TetraActor->SetVisibility(1);
559 } else {
560 m_ExtrVol->SetTetrasOff();
561 m_TetraActor->SetVisibility(0);
563 if (ui.checkBoxPyramid->isChecked()) {
564 m_ExtrVol->SetPyramidsOn();
565 if (ui.checkBoxClip->isChecked()) {
566 m_ExtrPyramids->SetClippingOn();
567 } else {
568 m_ExtrPyramids->SetClippingOff();
570 if (forced) {
571 m_PyramidGeometry->Update();
573 m_PyramidActor->SetVisibility(1);
574 } else {
575 m_ExtrVol->SetPyramidsOff();
576 m_PyramidActor->SetVisibility(0);
578 if (ui.checkBoxWedge->isChecked()) {
579 m_ExtrVol->SetWedgesOn();
580 if (ui.checkBoxClip->isChecked()) {
581 m_ExtrWedges->SetClippingOn();
582 } else {
583 m_ExtrWedges->SetClippingOff();
585 if (forced) {
586 m_WedgeGeometry->Update();
588 m_WedgeActor->SetVisibility(1);
589 } else {
590 m_ExtrVol->SetWedgesOff();
591 m_WedgeActor->SetVisibility(0);
593 if (ui.checkBoxHexa->isChecked()) {
594 m_ExtrVol->SetHexesOn();
595 if (ui.checkBoxClip->isChecked()) {
596 m_ExtrHexes->SetClippingOn();
597 } else {
598 m_ExtrHexes->SetClippingOff();
600 if (forced) {
601 m_HexaGeometry->Update();
603 m_HexaActor->SetVisibility(1);
604 } else {
605 m_ExtrVol->SetHexesOff();
606 m_HexaActor->SetVisibility(0);
609 // wireframe
610 if (ui.checkBoxClip->isChecked()) {
611 m_ExtrVol->SetClippingOn();
612 } else {
613 m_ExtrVol->SetClippingOff();
615 if (forced) {
616 m_VolumeGeometry->Update();
618 m_VolumeWireActor->SetVisibility(1);
619 } else {
620 m_TetraActor->VisibilityOff();
621 m_PyramidActor->VisibilityOff();
622 m_WedgeActor->VisibilityOff();
623 m_HexaActor->VisibilityOff();
624 m_VolumeWireActor->VisibilityOff();
628 void GuiMainWindow::updateActors(bool forced)
630 //if (!tryLock()) return;
631 try {
632 m_Axes->SetInput(grid);
633 updateSurfaceActors(forced);
634 updateVolumeActors(forced);
635 updateStatusBar();
636 } catch (Error err) {
637 err.display();
639 //unlock();
644 void GuiMainWindow::forceUpdateActors()
646 updateActors(true);
647 getRenderWindow()->Render();
650 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor,bool a_CellPickerMode)
652 m_UseVTKInteractor=a_UseVTKInteractor;
653 if (a_UseVTKInteractor) {
654 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Checked);
655 } else {
656 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Unchecked);
658 if (a_CellPickerMode) {
659 ui.radioButton_CellPicker->toggle();
660 } else {
661 ui.radioButton_PointPicker->toggle();
665 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor)
667 m_UseVTKInteractor = a_UseVTKInteractor;
670 bool GuiMainWindow::pickPoint(vtkIdType id_node)
672 if ((id_node >= 0) && (id_node < grid->GetNumberOfPoints())) {
673 vec3_t x(0,0,0);
674 grid->GetPoints()->GetPoint(id_node, x.data());
675 m_PickSphere->SetCenter(x.data());
676 m_PickedPoint = id_node;
677 m_PickActor->GetProperty()->SetColor(0,0,1);
678 m_PickActor->VisibilityOn();
679 return(true);
680 } else {
681 m_PickActor->VisibilityOff();
682 return(false);
686 bool GuiMainWindow::pickCell(vtkIdType id_cell)
688 if ((id_cell >= 0) && (id_cell < grid->GetNumberOfCells())) {
689 vtkIdType *pts, Npts;
690 grid->GetCellPoints(id_cell, Npts, pts);
691 vec3_t x(0,0,0);
692 for (vtkIdType i = 0; i < Npts; ++i) {
693 vec3_t xp;
694 grid->GetPoints()->GetPoint(pts[i], xp.data());
695 x += double(1)/Npts * xp;
697 m_PickSphere->SetCenter(x.data());
698 double R = 1e99;
699 for (vtkIdType i = 0; i < Npts; ++i) {
700 vec3_t xp;
701 grid->GetPoints()->GetPoint(pts[i], xp.data());
702 R = min(R, 0.25*(xp-x).abs());
704 m_ReferenceSize = R; //Used for text annotations too!
705 m_PickSphere->SetRadius(R);
706 m_PickedCell = id_cell;
707 m_PickActor->GetProperty()->SetColor(1,0,0);
708 m_PickActor->VisibilityOn();
709 return(true);
710 } else {
711 m_PickActor->VisibilityOff();
712 return(false);
716 void GuiMainWindow::importSTL()
718 StlReader stl;
719 stl();
720 updateBoundaryCodes(true);
721 updateActors();
722 updateStatusBar();
723 zoomAll();
726 void GuiMainWindow::importGmsh1Ascii()
728 GmshReader gmsh;
729 gmsh.setV1Ascii();
730 gmsh();
731 updateBoundaryCodes(true);
732 updateActors();
733 updateStatusBar();
734 zoomAll();
737 void GuiMainWindow::exportGmsh1Ascii()
739 GmshWriter gmsh;
740 gmsh.setV1Ascii();
741 gmsh();
744 void GuiMainWindow::importGmsh2Ascii()
746 GmshReader gmsh;
747 gmsh.setV2Ascii();
748 gmsh();
749 updateBoundaryCodes(true);
750 updateActors();
751 updateStatusBar();
752 zoomAll();
755 void GuiMainWindow::exportGmsh2Ascii()
757 GmshWriter gmsh;
758 gmsh.setV2Ascii();
759 gmsh();
762 void GuiMainWindow::exportNeutral()
764 NeutralWriter neutral;
765 neutral();
768 void GuiMainWindow::zoomAll()
770 getRenderer()->ResetCamera();
771 getRenderWindow()->Render();
774 void GuiMainWindow::zoomOnPickedObject()
776 if(m_PickActor->GetVisibility()) {
777 getRenderer()->ResetCamera(m_PickActor->GetBounds());
778 getRenderWindow()->Render();
782 void GuiMainWindow::deselectAll()
784 cout << "void GuiMainWindow::deselectAll()" << endl;
785 m_PickActor->VisibilityOff();
786 updateActors();
789 ///@@@ TODO: Should display a window
790 void GuiMainWindow::info()
792 ShowInfo info(ui.radioButton_CellPicker->isChecked(), m_PickedPoint, m_PickedCell);
793 info();
796 int GuiMainWindow::quickSave()
798 ///@@@ might be re-activated with RAM support
800 /* if(grid->GetNumberOfPoints()>0)
802 m_CurrentOperation++;
803 QFileInfo fileinfo(m_CurrentFilename);
804 QString l_filename = m_LogDir + fileinfo.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation);
805 m_LastOperation=m_CurrentOperation;
806 cout<<"Operation "<<m_CurrentOperation<<endl;
807 saveAs(l_filename, false);
808 if(m_CurrentOperation>0) ui.actionUndo->setEnabled(true);
809 ui.actionRedo->setEnabled(false);
811 else cout<<"No grid to save!"<<endl;
812 return(m_CurrentOperation);*/
814 return 0;
817 void GuiMainWindow::quickLoad(int a_operation)
819 ///@@@ might be re-activated with RAM support
821 /* QFileInfo fileinfo(m_CurrentFilename);
822 QString l_filename = m_LogDir + fileinfo.completeBaseName() + "_" + QString("%1").arg(a_operation) + ".vtu";
823 open(l_filename, false);*/
826 void GuiMainWindow::undo()
828 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
830 /* cout << "Undoing operation " << m_CurrentOperation << endl;
831 m_CurrentOperation--;
832 quickLoad(m_CurrentOperation);
833 ui.actionRedo->setEnabled(true);
834 if(m_CurrentOperation<=0) ui.actionUndo->setEnabled(false);*/
838 void GuiMainWindow::redo()
840 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
842 /* m_CurrentOperation++;
843 cout << "Redoing operation " << m_CurrentOperation << endl;
844 quickLoad(m_CurrentOperation);
845 ui.actionUndo->setEnabled(true);
846 if(m_CurrentOperation>=m_LastOperation) ui.actionRedo->setEnabled(false);*/
850 void GuiMainWindow::resetOperationCounter()
852 m_CurrentOperation=-1;
853 m_LastOperation=m_CurrentOperation;
854 ui.actionUndo->setEnabled(false);
855 ui.actionRedo->setEnabled(false);
858 QString GuiMainWindow::getXmlSection(QString name)
860 QStringList tags = name.toLower().split("/", QString::SkipEmptyParts);
861 QDomElement element = m_XmlDoc.documentElement();
862 bool found = true;
863 QString section_text = "";
864 try {
865 foreach (QString tag, tags) {
866 QDomNodeList nodes = element.elementsByTagName(tag);
867 if (nodes.size() > 1) {
868 EG_ERR_RETURN("error retrieving XML section '" + name + "'");
870 if (nodes.size() == 0) {
871 found = false;
872 break;
874 if (!nodes.at(0).isElement()) {
875 EG_ERR_RETURN("error retrieving XML section '" + name + "'");
877 element = nodes.at(0).toElement();
879 } catch (Error err) {
880 err.display();
882 if (found) {
883 section_text = element.text();
885 return section_text;
888 void GuiMainWindow::setXmlSection(QString name, QString contents)
890 QStringList tags = name.toLower().split("/", QString::SkipEmptyParts);
891 QDomElement element = m_XmlDoc.documentElement();
892 try {
893 foreach (QString tag, tags) {
894 QDomNodeList nodes = element.elementsByTagName(tag);
895 if (nodes.size() > 1) {
896 EG_ERR_RETURN("error retrieving XML section '" + name + "'");
898 if (nodes.size() == 0) {
899 QDomElement new_element = m_XmlDoc.createElement(tag);
900 element.appendChild(new_element);
901 element = new_element;
902 } else if (!nodes.at(0).isElement()) {
903 EG_ERR_RETURN("error retrieving XML section '" + name + "'");
904 } else {
905 element = nodes.at(0).toElement();
908 while (element.hasChildNodes()) {
909 element.removeChild(element.firstChild());
911 QDomText text_node = m_XmlDoc.createTextNode(contents);
912 element.appendChild(text_node);
913 } catch (Error err) {
914 err.display();
918 void GuiMainWindow::openPhysicalBoundaryConditions()
920 m_PhysicalBoundaryConditionsMap.clear();
921 QString buffer = getXmlSection("engrid/physical");
922 QTextStream f(&buffer, QIODevice::ReadOnly);
923 while (!f.atEnd()) {
924 QString name, values;
925 int i;
926 f >> i >> name >> values;
927 if(name!="" && values!="") {
928 qWarning()<<"i="<<i<<"name="<<name<<"values="<<values;
929 PhysicalBoundaryConditions PBC(name, i, values);
930 m_PhysicalBoundaryConditionsMap[name] = PBC;
935 void GuiMainWindow::savePhysicalBoundaryConditions()
937 QString buffer("");
938 QTextStream f(&buffer, QIODevice::WriteOnly);
939 f << "\n";
940 foreach (PhysicalBoundaryConditions PBC, m_PhysicalBoundaryConditionsMap) {
941 f << " " << PBC.getIndex() << " " << PBC.getName() << " " << PBC.getValues() << "\n";
943 f << " ";
944 setXmlSection("engrid/physical", buffer);
947 void GuiMainWindow::openBC()
949 m_bcmap.clear();
950 m_VolMap.clear();
951 QString buffer = getXmlSection("engrid/bc");
952 QTextStream f(&buffer, QIODevice::ReadOnly);
953 while (!f.atEnd()) {
954 QString name, type;
955 int i;
956 f >> i >> name >> type;
957 if(name!="" && type!="") {
958 qWarning()<<"i="<<i<<"name="<<name<<"type="<<type;
959 if (i >= 0) {
960 m_bcmap[i] = BoundaryCondition(name,type);
961 } else {
962 VolumeDefinition V(name, -i);
963 QString text = type.replace(",", " ").replace(":", " ");
964 QTextStream s(&text);
965 while (!s.atEnd()) {
966 QString bc_txt, sign_txt;
967 s >> bc_txt >> sign_txt;
968 V.addBC(bc_txt.toInt(), sign_txt.toInt());
970 m_VolMap[name] = V;
976 void GuiMainWindow::saveBC()
978 QString buffer("");
979 QTextStream f(&buffer, QIODevice::WriteOnly);
980 f << "\n";
981 foreach (int i, m_AllBoundaryCodes) {
982 BoundaryCondition bc = m_bcmap[i];
983 f << " " << i << " " << bc.getName() << " " << bc.getType() << "\n";
985 foreach (VolumeDefinition V, m_VolMap) {
986 QString dirs = "";
987 bool first = true;
988 foreach (int i, m_AllBoundaryCodes) {
989 BoundaryCondition bc = m_bcmap[i];
990 if (!first) {
991 dirs += ",";
992 } else {
993 first = false;
995 QString num;
996 num.setNum(i);
997 dirs += num + ":";
998 num.setNum(V.getSign(i));
999 dirs += num;
1001 f << " " << "-" << V.getVC() << " " << V.getName() << " " << dirs << "\n";
1003 f << " ";
1004 setXmlSection("engrid/bc", buffer);
1007 void GuiMainWindow::openGrid(QString file_name)
1009 file_name += ".vtu";
1010 EG_VTKSP(vtkXMLUnstructuredGridReader,vtu);
1011 vtu->SetFileName(qPrintable(file_name));
1012 vtu->Update();
1013 grid->DeepCopy(vtu->GetOutput());
1014 createBasicFields(grid, grid->GetNumberOfCells(), grid->GetNumberOfPoints());
1015 openBC();
1016 openPhysicalBoundaryConditions();
1017 updateBoundaryCodes(true);
1018 createIndices(grid);
1019 updateActors();
1020 updateStatusBar();
1021 zoomAll();
1022 resetOperationCounter();
1023 quickSave();
1026 void GuiMainWindow::saveGrid(QString file_name)
1028 file_name += ".vtu";
1029 EG_VTKDCC(vtkDoubleArray, cell_VA, grid, "cell_VA");
1030 for (vtkIdType cellId = 0; cellId < grid->GetNumberOfCells(); ++cellId) {
1031 cell_VA->SetValue(cellId, GeometryTools::cellVA(grid, cellId, true));
1033 EG_VTKSP(vtkXMLUnstructuredGridWriter,vtu);
1034 addVtkTypeInfo();
1035 createIndices(grid);
1036 vtu->SetFileName(file_name.toAscii().data());
1037 vtu->SetDataModeToBinary();
1038 vtu->SetInput(grid);
1039 vtu->Write();
1040 if(vtu->GetErrorCode()) {
1041 QMessageBox::critical(this, tr("Save failed"), tr("The grid could not be saved as:\n%1").arg(file_name));
1045 ///@@@ TODO: I think this should also be a done by a subclass of IOOperation just like for import operations
1046 void GuiMainWindow::open()
1048 QString file_name = QFileDialog::getOpenFileName(NULL, "open grid from file", getCwd(), "enGrid case files/VTK unstr. grid files (*.egc *.EGC *.vtu *.VTU)");
1049 if (!file_name.isNull()) {
1050 this->open(file_name);
1054 void GuiMainWindow::open(QString file_name, bool update_current_filename)
1056 cout << "Opening " << qPrintable(file_name) << endl;
1057 QFileInfo file_info(file_name);
1058 bool no_case_file = false;
1059 QString file_extension = getExtension(file_name);
1060 QString grid_file_name = file_name;
1061 if (file_extension.toLower() == "vtu") {
1062 no_case_file = true;
1063 grid_file_name = stripFromExtension(file_name);
1065 GuiMainWindow::setCwd(QFileInfo(file_name).absolutePath());
1066 if (!no_case_file) {
1067 openXml(file_name);
1069 openGrid(grid_file_name);
1070 openBC();
1071 openPhysicalBoundaryConditions();
1072 // update current filename
1073 if(update_current_filename) m_CurrentFilename = stripFromExtension(file_name) + ".egc";
1074 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1077 void GuiMainWindow::openXml(QString file_name)
1079 QFile xml_file(file_name);
1080 if (!xml_file.open(QIODevice::ReadOnly)) {
1081 qWarning()<<"Failed to open xml_file "<<xml_file.fileName();
1082 qWarning()<<"QDir::current()="<<QDir::current();
1083 qWarning()<<"QDir::currentPath()="<<QDir::currentPath();
1084 qWarning()<<"getCwd()="<<getCwd();
1085 EG_BUG;
1087 if (!m_XmlDoc.setContent(&xml_file)) {
1088 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name));
1090 xml_file.close();
1093 void GuiMainWindow::saveXml(QString file_name)
1095 QString buffer = m_XmlDoc.toString(0);
1096 QFile xml_file(file_name);
1097 xml_file.open(QIODevice::WriteOnly | QIODevice::Text);
1098 QTextStream f(&xml_file);
1099 f << buffer << endl;
1102 QString GuiMainWindow::saveAs(QString file_name, bool update_current_filename) {
1103 QFileInfo file_info(file_name);
1104 if (file_info.suffix().toLower() != "egc") {
1105 file_name += ".egc";
1107 GuiMainWindow::setCwd(file_info.absolutePath());
1108 cout << "Saving as " << qPrintable(file_name) << endl;
1109 saveGrid(file_name);
1110 saveBC();
1111 savePhysicalBoundaryConditions();
1112 saveXml(file_name);
1113 // update current filename
1114 if(update_current_filename) m_CurrentFilename = file_name;
1115 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1116 return(file_name);
1119 void GuiMainWindow::save()
1121 if (m_CurrentFilename == "untitled.egc") {
1122 saveAs();
1123 } else {
1124 saveAs(m_CurrentFilename);
1128 void GuiMainWindow::saveAs()
1130 QString file_name = QFileDialog::getSaveFileName(NULL, "write case to file", getCwd(), "enGrid case files (*.egc)");
1131 if (!file_name.isNull()) {
1132 saveAs(file_name);
1133 //for the undo/redo operations
1134 resetOperationCounter();
1135 quickSave();
1139 void GuiMainWindow::updateStatusBar()
1141 QString num, txt = "enGrid is currently busy with an operation ...";
1142 if (!m_Busy) {
1143 txt = "";
1145 if (!tryLock()) {
1146 m_StatusLabel->setText(txt);
1147 ui.label_node_cell_info->setText(txt);
1148 return;
1150 vtkIdType Ncells = grid->GetNumberOfCells();
1151 vtkIdType Nnodes = grid->GetNumberOfPoints();
1152 vtkIdType Ntris = 0;
1153 vtkIdType Nquads = 0;
1154 vtkIdType Ntets = 0;
1155 vtkIdType Npyras = 0;
1156 vtkIdType Nprism = 0;
1157 vtkIdType Nhexas = 0;
1158 for (vtkIdType i = 0; i < Ncells; ++i) {
1159 int ct = grid->GetCellType(i);
1160 if (ct == VTK_TRIANGLE) ++Ntris;
1161 else if (ct == VTK_QUAD) ++Nquads;
1162 else if (ct == VTK_TETRA) ++Ntets;
1163 else if (ct == VTK_WEDGE) ++Nprism;
1164 else if (ct == VTK_PYRAMID) ++Npyras;
1165 else if (ct == VTK_HEXAHEDRON) ++Nhexas;
1167 num.setNum(Ntets + Npyras + Nprism + Nhexas); txt += num + " volume cells(";
1168 num.setNum(Ntets); txt += num + " tetras, ";
1169 num.setNum(Npyras); txt += num + " pyramids, ";
1170 num.setNum(Nprism); txt += num + " prisms, ";
1171 num.setNum(Nhexas); txt += num + " hexas), ";
1172 num.setNum(Ntris + Nquads); txt += num + " surface cells(";
1173 num.setNum(Ntris); txt += num + " triangles, ";
1174 num.setNum(Nquads); txt += num + " quads), ";
1175 num.setNum(Nnodes); txt += num + " nodes";
1177 if(ui.radioButton_CellPicker->isChecked())
1179 QString pick_txt = ", picked cell: ";
1180 vtkIdType id_cell = m_PickedCell;
1181 if (id_cell < 0) {
1182 pick_txt += "no cell picked";
1183 } else {
1184 vtkIdType type_cell = grid->GetCellType(id_cell);
1185 if (type_cell == VTK_TRIANGLE) pick_txt += "tri";
1186 else if (type_cell == VTK_QUAD) pick_txt += "qua";
1187 else if (type_cell == VTK_TETRA) pick_txt += "tet";
1188 else if (type_cell == VTK_PYRAMID) pick_txt += "pyr";
1189 else if (type_cell == VTK_WEDGE) pick_txt += "pri";
1190 else if (type_cell == VTK_HEXAHEDRON) pick_txt += "hex";
1191 vtkIdType N_pts, *pts;
1192 grid->GetCellPoints(id_cell, N_pts, pts);
1193 pick_txt += " [";
1194 for (int i_pts = 0; i_pts < N_pts; ++i_pts) {
1195 QString num;
1196 num.setNum(pts[i_pts]);
1197 pick_txt += num;
1198 if (i_pts < N_pts-1) {
1199 pick_txt += ",";
1202 pick_txt += "]";
1203 QString tmp;
1204 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
1205 tmp.setNum(cell_code->GetValue(id_cell));
1206 pick_txt += " code=" + tmp;
1207 tmp.setNum(id_cell);
1208 pick_txt += " id=" + tmp;
1210 txt += pick_txt;
1212 else
1214 QString pick_txt = ", picked node: ";
1215 vtkIdType id_node = m_PickedPoint;
1216 if (id_node < 0) {
1217 pick_txt += "no node picked";
1218 } else {
1219 vec3_t x;
1220 grid->GetPoints()->GetPoint(id_node,x.data());
1221 pick_txt += " [";
1222 for (int i = 0; i < 3; i++) {
1223 QString num;
1224 num.setNum(x[i]);
1225 pick_txt += num;
1226 if (i < 2) {
1227 pick_txt += ",";
1230 pick_txt += "]";
1231 QString tmp;
1232 EG_VTKDCN(vtkDoubleArray, node_meshdensity_desired, grid, "node_meshdensity_desired");
1233 tmp.setNum(node_meshdensity_desired->GetValue(id_node));
1234 pick_txt += " wanted density=" + tmp;
1235 EG_VTKDCN(vtkDoubleArray, node_meshdensity_current, grid, "node_meshdensity_current");
1236 tmp.setNum(node_meshdensity_current->GetValue(id_node));
1237 pick_txt += " current density=" + tmp;
1238 EG_VTKDCN(vtkIntArray, node_specified_density, grid, "node_specified_density");
1239 tmp.setNum(node_specified_density->GetValue(id_node));
1240 pick_txt += " node_specified_density=" + tmp;
1241 EG_VTKDCN(vtkCharArray, node_type, grid, "node_type");
1242 pick_txt += " type=" + QString(VertexType2Str( node_type->GetValue(id_node)));
1243 tmp.setNum(id_node);
1244 pick_txt += " id_node=" + tmp;
1247 txt += pick_txt;
1250 ///@@@ TODO: Reduce size of text for small screens or better: allow making the window smaller than the text
1251 m_StatusLabel->setText(txt);
1252 ui.label_node_cell_info->setText(txt);
1253 unlock();
1256 void GuiMainWindow::selectBoundaryCodes()
1258 GuiSelectBoundaryCodes bcodes;
1259 bcodes.setDisplayBoundaryCodes(m_DisplayBoundaryCodes);
1260 bcodes.setBoundaryCodes(m_AllBoundaryCodes);
1261 bcodes();
1262 bcodes.getThread().wait();
1263 bcodes.getSelectedBoundaryCodes(m_DisplayBoundaryCodes);
1264 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1265 updateActors();
1268 void GuiMainWindow::updateBoundaryCodes(bool all_on)
1270 try {
1271 m_AllBoundaryCodes.clear();
1272 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
1273 for (vtkIdType i = 0; i < grid->GetNumberOfCells(); ++i) {
1274 int ct = grid->GetCellType(i);
1275 if ((ct == VTK_TRIANGLE) || (ct == VTK_QUAD)) {
1276 m_AllBoundaryCodes.insert(cell_code->GetValue(i));
1279 if (all_on) {
1280 m_DisplayBoundaryCodes.clear();
1281 foreach (int bc, m_AllBoundaryCodes) {
1282 m_DisplayBoundaryCodes.insert(bc);
1284 } else {
1285 QSet<int> dbcs;
1286 foreach (int bc, m_DisplayBoundaryCodes) {
1287 if (m_AllBoundaryCodes.contains(bc)) {
1288 dbcs.insert(bc);
1291 m_DisplayBoundaryCodes.clear();
1292 foreach (int bc, m_AllBoundaryCodes) {
1293 if (dbcs.contains(bc)) {
1294 m_DisplayBoundaryCodes.insert(bc);
1298 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1299 } catch (Error err) {
1300 err.display();
1304 void GuiMainWindow::normalExtrusion()
1306 GuiNormalExtrusion extr;
1307 extr();
1308 updateBoundaryCodes(false);
1309 updateActors();
1312 void GuiMainWindow::setAxesVisibility()
1314 if (ui.actionViewAxes->isChecked()) {
1315 m_Axes->VisibilityOn();
1316 } else {
1317 m_Axes->VisibilityOff();
1319 getRenderWindow()->Render();
1322 void GuiMainWindow::setViewingMode()
1324 if (ui.actionViewOrthogonal->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1325 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1326 getRenderWindow()->Render();
1329 void GuiMainWindow::viewNodeIDs()
1331 int N=grid->GetNumberOfPoints();
1332 cout<<"N="<<N<<endl;
1333 if (ui.actionViewNodeIDs->isChecked()) {
1334 cout<<"Activating node ID view"<<endl;
1335 m_NodeTextVectorText.resize(N);
1336 m_NodeTextPolyDataMapper.resize(N);
1337 m_NodeTextFollower.resize(N);
1338 for(int i = 0; i < N; ++i){
1339 m_NodeTextVectorText[i]=vtkVectorText::New();
1340 QString tmp;
1341 tmp.setNum(i);
1342 m_NodeTextVectorText[i]->SetText(tmp.toLatin1().data());
1343 m_NodeTextPolyDataMapper[i]=vtkPolyDataMapper::New();
1344 m_NodeTextPolyDataMapper[i]->SetInputConnection(m_NodeTextVectorText[i]->GetOutputPort());
1345 m_NodeTextFollower[i]=vtkFollower::New();
1346 m_NodeTextFollower[i]->SetMapper(m_NodeTextPolyDataMapper[i]);
1347 m_NodeTextFollower[i]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1348 vec3_t M;
1349 grid->GetPoint(i, M.data());
1350 vec3_t tmp_M = M;
1351 vec3_t OffSet = m_ReferenceSize*tmp_M.normalise();
1352 M = M + OffSet;
1353 m_NodeTextFollower[i]->AddPosition(M[0], M[1], M[2]);
1354 m_NodeTextFollower[i]->SetCamera(getRenderer()->GetActiveCamera());
1355 m_NodeTextFollower[i]->GetProperty()->SetColor(0,0,1);
1356 getRenderer()->AddActor(m_NodeTextFollower[i]);
1359 else {
1360 cout<<"Deactivating node ID view"<<endl;
1361 for(unsigned int i = 0; i < m_NodeTextFollower.size();i++){
1362 getRenderer()->RemoveActor(m_NodeTextFollower[i]);
1363 m_NodeTextFollower[i]->Delete();
1364 m_NodeTextPolyDataMapper[i]->Delete();
1365 m_NodeTextVectorText[i]->Delete();
1367 m_NodeTextFollower.clear();
1368 m_NodeTextPolyDataMapper.clear();
1369 m_NodeTextVectorText.clear();
1372 getRenderWindow()->Render();
1375 void GuiMainWindow::viewCellIDs()
1377 vtkIdType N=grid->GetNumberOfCells();
1378 cout<<"N="<<N<<endl;
1379 if (ui.actionViewCellIDs->isChecked()) {
1380 cout<<"Activating cell ID view"<<endl;
1381 m_CellTextVectorText.resize(N);
1382 m_CellTextPolyDataMapper.resize(N);
1383 m_CellTextFollower.resize(N);
1384 for (vtkIdType id_cell = 0; id_cell < N; ++id_cell){
1385 m_CellTextVectorText[id_cell] = vtkVectorText::New();
1387 QString tmp;
1389 if(ui.comboBox_CellTextField->currentIndex()==0) {
1390 tmp.setNum(id_cell);
1391 } else if (ui.comboBox_CellTextField->currentIndex()>0) {
1392 EG_VTKDCC(vtkIntArray, current_cell_field, grid, ui.comboBox_CellTextField->currentText().toLatin1().data());
1393 tmp.setNum(current_cell_field->GetValue(id_cell));
1395 else EG_BUG;
1397 m_CellTextVectorText[id_cell]->SetText(tmp.toLatin1().data());
1398 m_CellTextPolyDataMapper[id_cell]=vtkPolyDataMapper::New();
1399 m_CellTextPolyDataMapper[id_cell]->SetInputConnection(m_CellTextVectorText[id_cell]->GetOutputPort());
1400 m_CellTextFollower[id_cell]=vtkFollower::New();
1401 m_CellTextFollower[id_cell]->SetMapper(m_CellTextPolyDataMapper[id_cell]);
1402 m_CellTextFollower[id_cell]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1403 vtkIdType N_pts,*pts;
1404 grid->GetCellPoints(id_cell,N_pts,pts);
1405 vec3_t Center(0,0,0);
1406 for (int p = 0; p < N_pts; ++p) {
1407 vec3_t M;
1408 grid->GetPoint(pts[p],M.data());
1409 Center+=M.data();
1411 vec3_t OffSet = m_ReferenceSize*triNormal(grid, pts[0], pts[1], pts[2]).normalise();
1412 Center = 1.0/(double)N_pts*Center+OffSet;
1413 m_CellTextFollower[id_cell]->AddPosition(Center[0], Center[1], Center[2]);
1414 m_CellTextFollower[id_cell]->SetCamera(getRenderer()->GetActiveCamera());
1415 m_CellTextFollower[id_cell]->GetProperty()->SetColor(1, 0, 0);
1416 getRenderer()->AddActor(m_CellTextFollower[id_cell]);
1418 } else {
1419 cout<<"Deactivating cell ID view"<<endl;
1420 for (vtkIdType id_cell = 0; id_cell < (vtkIdType) m_CellTextFollower.size(); ++id_cell) {
1421 getRenderer()->RemoveActor(m_CellTextFollower[id_cell]);
1422 m_CellTextFollower[id_cell]->Delete();
1423 m_CellTextPolyDataMapper[id_cell]->Delete();
1424 m_CellTextVectorText[id_cell]->Delete();
1426 m_CellTextFollower.clear();
1427 m_CellTextPolyDataMapper.clear();
1428 m_CellTextVectorText.clear();
1431 getRenderWindow()->Render();
1434 void GuiMainWindow::addVtkTypeInfo()
1436 EG_VTKSP(vtkIntArray, vtk_type);
1437 vtk_type->SetName("vtk_type");
1438 vtk_type->SetNumberOfValues(grid->GetNumberOfCells());
1439 for (vtkIdType cellId = 0; cellId < grid->GetNumberOfCells(); ++cellId) {
1440 vtk_type->SetValue(cellId, grid->GetCellType(cellId));
1442 grid->GetCellData()->AddArray(vtk_type);
1445 void GuiMainWindow::pickCallBack
1447 vtkObject *caller,
1448 unsigned long int eid,
1449 void *clientdata,
1450 void *calldata
1453 caller = caller;
1454 eid = eid;
1455 clientdata = clientdata;
1456 calldata = calldata;
1457 THIS->updateActors();
1458 THIS->updateStatusBar();
1461 vtkIdType GuiMainWindow::getPickedCell()
1463 vtkIdType picked_cell = -1;
1464 if (grid->GetNumberOfCells() > 0) {
1465 m_BCodesFilter->Update();
1466 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1467 EG_VTKDCC(vtkLongArray_t, cell_index, m_BCodesFilter->GetOutput(), "cell_index");
1468 if (m_UseVTKInteractor) {
1469 picked_cell = cell_index->GetValue(m_CellPicker->GetCellId());
1470 } else {
1471 picked_cell = m_PickedCell;
1475 return picked_cell;
1478 vtkIdType GuiMainWindow::getPickedPoint()
1480 vtkIdType picked_point = -1;
1481 if (grid->GetNumberOfCells() > 0) {
1482 m_BCodesFilter->Update();
1483 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1484 EG_VTKDCN(vtkLongArray_t, node_index, m_BCodesFilter->GetOutput(), "node_index");
1485 if (m_UseVTKInteractor) {
1486 picked_point = node_index->GetValue(m_PointPicker->GetPointId());
1487 } else {
1488 picked_point = m_PickedPoint;
1492 return picked_point;
1495 void GuiMainWindow::changeSurfaceOrientation()
1497 for (vtkIdType cellId = 0; cellId < grid->GetNumberOfCells(); ++cellId) {
1498 vtkIdType Npts, *pts;
1499 grid->GetCellPoints(cellId, Npts, pts);
1500 QVector<vtkIdType> nodes(Npts);
1501 for (vtkIdType j = 0; j < Npts; ++j) nodes[j] = pts[j];
1502 for (vtkIdType j = 0; j < Npts; ++j) pts[Npts - j - 1] = nodes[j];
1504 updateActors();
1505 grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1508 void GuiMainWindow::checkSurfaceOrientation()
1510 CorrectSurfaceOrientation corr_surf;
1511 vtkIdType picked_cell = getPickedCell();
1512 if (picked_cell >= 0) {
1513 corr_surf.setStart(picked_cell);
1515 corr_surf();
1516 updateActors();
1519 void GuiMainWindow::improveAspectRatio()
1521 GuiImproveAspectRatio impr_ar;
1522 impr_ar();
1523 updateActors();
1526 void GuiMainWindow::exportAsciiStl()
1528 StlWriter stl;
1529 stl();
1532 void GuiMainWindow::exportBinaryStl()
1536 void GuiMainWindow::periodicUpdate()
1538 Operation::collectGarbage();
1539 updateStatusBar();
1542 void GuiMainWindow::viewXP()
1544 getRenderer()->ResetCamera();
1545 double x[3];
1546 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1547 x[0] += 1;
1548 getRenderer()->GetActiveCamera()->SetPosition(x);
1549 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1550 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1551 getRenderer()->ResetCamera();
1552 getRenderWindow()->Render();
1555 void GuiMainWindow::viewXM()
1557 getRenderer()->ResetCamera();
1558 double x[3];
1559 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1560 x[0] -= 1;
1561 getRenderer()->GetActiveCamera()->SetPosition(x);
1562 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1563 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1564 getRenderer()->ResetCamera();
1565 getRenderWindow()->Render();
1568 void GuiMainWindow::viewYP()
1570 getRenderer()->ResetCamera();
1571 double x[3];
1572 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1573 x[1] += 1;
1574 getRenderer()->GetActiveCamera()->SetPosition(x);
1575 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1576 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1577 getRenderer()->ResetCamera();
1578 getRenderWindow()->Render();
1581 void GuiMainWindow::viewYM()
1583 getRenderer()->ResetCamera();
1584 double x[3];
1585 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1586 x[1] -= 1;
1587 getRenderer()->GetActiveCamera()->SetPosition(x);
1588 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1589 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1590 getRenderer()->ResetCamera();
1591 getRenderWindow()->Render();
1594 void GuiMainWindow::viewZP()
1596 getRenderer()->ResetCamera();
1597 double x[3];
1598 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1599 x[2] += 1;
1600 getRenderer()->GetActiveCamera()->SetPosition(x);
1601 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1602 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1603 getRenderer()->ResetCamera();
1604 getRenderWindow()->Render();
1607 void GuiMainWindow::viewZM()
1609 getRenderer()->ResetCamera();
1610 double x[3];
1611 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1612 x[2] -= 1;
1613 getRenderer()->GetActiveCamera()->SetPosition(x);
1614 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1615 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1616 getRenderer()->ResetCamera();
1617 getRenderWindow()->Render();
1620 void GuiMainWindow::callFixSTL()
1622 FixSTL *fix;
1623 fix = new FixSTL();
1624 fix->setGui();
1625 (*fix)();
1626 updateBoundaryCodes(false);
1627 updateActors();
1630 void GuiMainWindow::editBoundaryConditions()
1632 GuiEditBoundaryConditions editbcs;
1633 editbcs.setBoundaryCodes(m_AllBoundaryCodes);
1634 editbcs.setMap(&m_bcmap);
1635 editbcs();
1638 void GuiMainWindow::configure()
1641 // Just to create initial entries in the settings file
1642 // so that the options menu isn't empty at first start.
1643 GridSmoother tmp01;
1644 GuiCreateBoundaryLayer tmp02;
1645 SurfaceProjection tmp03;
1646 SurfaceMesher tmp04;
1647 UpdateDesiredMeshDensity tmp05;
1649 GuiSettingsViewer settings(&m_qset);
1650 settings.exec();
1653 void GuiMainWindow::about()
1655 QMessageBox box(this);
1657 QString title="ENGRID";
1658 QString version = QString("version ") + ENGRID_VERSION;
1660 version += " built on ";
1661 version += QString(__DATE__);
1662 version += " at ";
1663 version += QString(__TIME__);
1665 QString address = tr("ENGRID is being developed and maintained by:<br/>"
1666 "enGits GmbH<br/>"
1667 "Marie-Curie-Strasse 8<br/>"
1668 "79539 Loerrach<br/>"
1669 "Germany<br/>");
1671 QString mainurl="<a href=\"http://www.engits.com\">www.engits.com</a>";
1672 QString mail="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1673 QString gnuurl="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1674 QString license=tr("ENGRID is licenced under the GPL version 3.<br/>"
1675 "(see ")+gnuurl+tr(" for details)<br/>");
1676 QString bugurl="<a href=\"http://sourceforge.net/tracker2/?func=add&group_id=245110&atid=1126548\">the bugtracker available on Sourceforge</a>";
1677 QString bugreporting=tr("To submit a bug report, please use ")+bugurl;
1678 box.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1679 "<h3>%1</h3>"
1680 "<p>%2</p>"
1681 "<p>%3</p>"
1682 "<p>Homepage: %4</p>"
1683 "<p>E-mail: %5</p>"
1684 "<p>%6</p>"
1685 "<p>%7</p></center>")
1686 .arg(title).arg(version).arg(address).arg(mainurl).arg(mail).arg(license).arg(bugreporting));
1687 box.setWindowTitle(tr("about ENGRID"));
1688 box.setIcon(QMessageBox::NoIcon);
1689 box.exec();
1693 void GuiMainWindow::getAllBoundaryCodes(QSet<int> &bcs)
1695 bcs.clear();
1696 foreach (int bc, m_AllBoundaryCodes) {
1697 bcs.insert(bc);
1701 void GuiMainWindow::getDisplayBoundaryCodes(QSet<int> &bcs)
1703 bcs.clear();
1704 foreach (int bc, m_DisplayBoundaryCodes) {
1705 bcs.insert(bc);
1709 QList<VolumeDefinition> GuiMainWindow::getAllVols()
1711 QList<VolumeDefinition> vols;
1712 foreach(VolumeDefinition vol, m_VolMap) {
1713 vols.push_back(vol);
1715 return vols;
1718 void GuiMainWindow::setAllVols(QList<VolumeDefinition> vols)
1720 m_VolMap.clear();
1721 foreach (VolumeDefinition V, vols) {
1722 m_VolMap[V.getName()] = V;
1726 QList<PhysicalBoundaryConditions> GuiMainWindow::getAllPhysicalBoundaryConditions()
1728 QList<PhysicalBoundaryConditions> physical_boundary_conditions;
1729 foreach(PhysicalBoundaryConditions PBC, m_PhysicalBoundaryConditionsMap) {
1730 physical_boundary_conditions.push_back(PBC);
1732 return physical_boundary_conditions;
1735 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList<PhysicalBoundaryConditions> physical_boundary_conditions)
1737 m_PhysicalBoundaryConditionsMap.clear();
1738 foreach (PhysicalBoundaryConditions PBC, physical_boundary_conditions) {
1739 m_PhysicalBoundaryConditionsMap[PBC.getName()] = PBC;
1743 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap<QString,PhysicalBoundaryConditions> physical_boundary_conditions) {
1744 m_PhysicalBoundaryConditionsMap = physical_boundary_conditions;
1747 // PhysicalBoundaryConditions GuiMainWindow::getPhysicalBoundaryConditions(QString name)
1748 // {
1749 // return m_PhysicalBoundaryConditionsMap[name];
1750 // }
1752 // void GuiMainWindow::setPhysicalBoundaryConditions(PhysicalBoundaryConditions physical_boundary_conditions)
1753 // {
1754 // m_PhysicalBoundaryConditionsMap[physical_boundary_conditions.getName()] = physical_boundary_conditions;
1755 // }
1757 void GuiMainWindow::createDefaultVol()
1759 QList<VolumeDefinition> vols = getAllVols();
1760 if (vols.size() == 0) {
1761 VolumeDefinition V("default", 1);
1762 QSet<int> bcs;
1763 getAllBoundaryCodes(bcs);
1764 foreach (int bc, bcs) {
1765 V.addBC(bc, 1);
1767 vols.append(V);
1768 setAllVols(vols);
1772 QString GuiMainWindow::getFilePath()
1774 QFileInfo fileinfo(m_CurrentFilename);
1775 return fileinfo.absolutePath()+"/";
1778 void GuiMainWindow::markOutputLine()
1780 cout << "\n****************************************\n";
1781 cout << QTime::currentTime().toString("hh:mm:ss").toAscii().data();
1782 cout << "\n****************************************\n" << endl;
1785 void GuiMainWindow::storeSurfaceProjection()
1787 foreach (SurfaceProjection* proj, m_SurfProj) {
1788 delete proj;
1790 m_SurfProj.clear();
1791 cout << "creating octrees for surface projection:" << endl;
1792 foreach (int bc, m_AllBoundaryCodes) {
1793 SurfaceProjection *proj = new SurfaceProjection();
1794 m_SurfProj[bc] = proj;
1795 QSet<int> bcs;
1796 bcs.insert(bc);
1797 QVector<vtkIdType> cls;
1798 getSurfaceCells(bcs, cls, grid);
1799 proj->setBackgroundGrid(grid, cls);
1800 QString file_name;
1801 file_name.setNum(bc);
1802 file_name = "OctreeBC" + file_name;
1803 proj->writeOctree(file_name);
1804 cout << " bc " << bc << ": " << proj->getNumOctreeCells() << endl;
1808 SurfaceProjection* GuiMainWindow::getSurfProj(int bc)
1810 if (!m_SurfProj.contains(bc)) {
1811 EG_ERR_RETURN("No surface projection found");
1813 return m_SurfProj[bc];