2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008,2009 Oliver Gloth +
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. +
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. +
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/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "guimainwindow.h"
24 #include "guiselectboundarycodes.h"
25 #include "guiimproveaspectratio.h"
26 #include "guinormalextrusion.h"
27 #include "guisetboundarycode.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 "plywriter.h"
37 #include "correctsurfaceorientation.h"
38 #include "guieditboundaryconditions.h"
39 #include "laplacesmoother.h"
40 #include "swaptriangles.h"
42 #include <vtkRenderer.h>
43 #include <vtkRenderWindow.h>
44 #include <vtkXMLUnstructuredGridWriter.h>
45 #include <vtkXMLUnstructuredGridReader.h>
46 #include <vtkProperty.h>
47 #include <vtkCallbackCommand.h>
48 #include <vtkCamera.h>
49 #include <vtkCharArray.h>
50 #include <vtkTextActor.h>
51 #include <vtkVectorText.h>
52 #include <vtkFollower.h>
53 #include <vtkLookupTable.h>
54 #include <vtkScalarBarActor.h>
56 #include <QFileDialog>
57 #include <QFileSystemWatcher>
62 #include "geometrytools.h"
64 using namespace GeometryTools
;
66 #include "guisettingsviewer.h"
67 #include "guitransform.h"
68 #include "egvtkinteractorstyle.h"
71 QString
GuiMainWindow::m_cwd
= ".";
72 QSettings
GuiMainWindow::m_qset("enGits","enGrid");
73 GuiMainWindow
* GuiMainWindow::THIS
= NULL
;
74 QMutex
GuiMainWindow::m_Mutex
;
75 bool GuiMainWindow::m_UnSaved
= true;
77 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL
)
82 // restore window size
83 if(m_qset
.contains("GuiMainWindow")) {
84 setGeometry(m_qset
.value("GuiMainWindow").toRect());
87 this->setWindowState(Qt::WindowMaximized
);
90 // restore dockwidget positions
91 if(m_qset
.contains("dockWidget_states")) {
92 restoreState(m_qset
.value("dockWidget_states").toByteArray());
95 tabifyDockWidget(ui
.dockWidget_output
, ui
.dockWidget_node_cell_info
);
96 tabifyDockWidget(ui
.dockWidget_DisplayOptions
, ui
.dockWidget_DebuggingUtilities
);
97 ui
.dockWidget_node_cell_info
->hide();
98 ui
.dockWidget_DebuggingUtilities
->hide();
101 # include "std_connections.h"
103 if (m_qset
.contains("working_directory")) {
104 m_cwd
= m_qset
.value("working_directory").toString();
109 resetOperationCounter();//clears undo/redo list and disables undo/redo
110 m_CurrentFilename
= "untitled.egc";
111 setWindowTitle(m_CurrentFilename
+ " - enGrid - " + QString("%1").arg(m_CurrentOperation
) );
114 m_StatusLabel
= new QLabel(this);
115 statusBar()->addWidget(m_StatusLabel
);
117 QString txt
= "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms), ";
118 txt
+= "0 surface cells (0 triangles, 0 quads), 0 nodes";
119 m_StatusLabel
->setText(txt
);
120 ui
.label_node_cell_info
->setText(txt
);
122 QString user
= QString(getenv("USER"));
123 QString basename
="enGrid_output.txt";
125 // define temporary path
127 if (m_qset
.contains("tmp_directory")) {
128 m_LogDir
= m_qset
.value("tmp_directory").toString();
130 m_LogDir
= dir
.tempPath();
132 QDateTime now
= QDateTime::currentDateTime();
133 m_LogDir
= m_LogDir
+ "/" + "enGrid_" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz") + "/";
134 dir
.mkpath(m_LogDir
);
136 m_LogFileName
= m_LogDir
+ basename
;
137 cout
<< "m_LogFileName = " << qPrintable(m_LogFileName
) << endl
;
139 m_SystemStdout
= stdout
;
140 if(freopen (qPrintable(m_LogFileName
), "w", stdout
)==NULL
) EG_BUG
;
144 setPickMode(true,true);
150 connect(&m_GarbageTimer
, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
151 m_GarbageTimer
.start(1000);
153 connect(&m_LogTimer
, SIGNAL(timeout()), this, SLOT(updateOutput()));
154 m_LogTimer
.start(1000);
158 bool exp_features
=false;
159 getSet("General","enable experimental features",false,exp_features
);
160 getSet("General","enable undo+redo",false,m_undo_redo_enabled
);
162 getSet("General","use RAM for undo+redo operations",false,undo_redo_mode
);
164 ui
.actionFoamWriter
->setEnabled(exp_features
);
168 ui
.doubleSpinBox_HueMin
->setValue(0.667);
169 ui
.doubleSpinBox_HueMax
->setValue(0);
171 egvtkInteractorStyle
*style
= egvtkInteractorStyle::New();
172 getInteractor()->SetInteractorStyle(style
);
175 // initialise XML document
176 // QDomElement root = m_XmlDoc.createElement("engridcase");
177 // m_XmlDoc.appendChild(root);
184 //end of GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
186 void GuiMainWindow::resetXmlDoc()
189 QDomElement root
= m_XmlDoc
.createElement("engridcase");
190 m_XmlDoc
.appendChild(root
);
193 GuiMainWindow::~GuiMainWindow()
197 m_qset
.setValue("GuiMainWindow", this->geometry());
198 m_qset
.setValue("dockWidget_states", this->saveState());
201 QDirIterator
it(m_LogDir
);
202 while (it
.hasNext()) {
203 QString str
= it
.next();
204 QFileInfo
fileinfo(str
);
205 if(fileinfo
.isFile()) {
207 if(!file
.remove()) qDebug() << "Failed to remove " << file
.fileName();
216 void GuiMainWindow::setupVtk()
218 m_Grid
= vtkUnstructuredGrid::New();
219 m_Renderer
= vtkRenderer::New();
220 getRenderWindow()->AddRenderer(m_Renderer
);
223 m_Axes
= vtkCubeAxesActor2D::New();
225 m_Axes
->SetCamera(getRenderer()->GetActiveCamera());
226 getRenderer()->AddActor(m_Axes
);
227 m_Axes
->SetVisibility(0);
230 m_BackfaceProperty
= vtkProperty::New();
231 m_SurfaceFilter
= vtkGeometryFilter::New();
232 m_SurfaceMapper
= vtkPolyDataMapper::New();
233 m_SurfaceWireMapper
= vtkPolyDataMapper::New();
234 m_BCodesFilter
= vtkEgBoundaryCodesFilter::New();
235 m_LookupTable
= vtkLookupTable::New();
236 m_SurfaceActor
= vtkActor::New();
237 m_SurfaceWireActor
= vtkActor::New();
238 m_LegendActor
= vtkScalarBarActor::New();
240 m_BCodesFilter
->SetBoundaryCodes(m_DisplayBoundaryCodes
);
241 m_BCodesFilter
->SetInput(m_Grid
);
242 m_SurfaceFilter
->SetInput(m_BCodesFilter
->GetOutput());
243 m_SurfaceMapper
->SetInput(m_SurfaceFilter
->GetOutput());
244 m_SurfaceWireMapper
->SetInput(m_SurfaceFilter
->GetOutput());
245 m_SurfaceMapper
->SetLookupTable(m_LookupTable
);
246 m_SurfaceActor
->GetProperty()->SetRepresentationToSurface();
247 m_SurfaceActor
->GetProperty()->SetColor(0.5,1,0.5);
248 m_SurfaceActor
->SetBackfaceProperty(m_BackfaceProperty
);
249 m_SurfaceActor
->GetBackfaceProperty()->SetColor(1,1,0.5);
250 m_SurfaceActor
->SetMapper(m_SurfaceMapper
);
251 getRenderer()->AddActor(m_SurfaceActor
);
252 m_SurfaceActor
->SetVisibility(1);
253 m_LegendActor
->SetLookupTable(m_LookupTable
);
254 getRenderer()->AddActor(m_LegendActor
);
255 m_LegendActor
->SetVisibility(0);
256 m_SurfaceWireActor
->GetProperty()->SetRepresentationToWireframe();
257 m_SurfaceWireActor
->GetProperty()->SetColor(0,0,1);
258 m_SurfaceWireActor
->SetMapper(m_SurfaceWireMapper
);
259 getRenderer()->AddActor(m_SurfaceWireActor
);
260 m_SurfaceWireActor
->SetVisibility(1);
263 m_ExtrTetras
= vtkEgExtractVolumeCells::New();
264 m_TetraActor
= vtkActor::New();
265 m_TetraGeometry
= vtkGeometryFilter::New();
266 m_TetraMapper
= vtkPolyDataMapper::New();
268 m_ExtrTetras
->SetInput(m_Grid
);
269 m_ExtrTetras
->SetAllOff();
270 m_ExtrTetras
->SetTetrasOn();;
271 m_TetraGeometry
->SetInput(m_ExtrTetras
->GetOutput());
272 m_TetraMapper
->SetInput(m_TetraGeometry
->GetOutput());
273 m_TetraActor
->SetMapper(m_TetraMapper
);
274 m_TetraActor
->GetProperty()->SetColor(1,0,0);
275 getRenderer()->AddActor(m_TetraActor
);
276 m_TetraActor
->SetVisibility(0);
279 m_PyramidActor
= vtkActor::New();
280 m_ExtrPyramids
= vtkEgExtractVolumeCells::New();
281 m_PyramidGeometry
= vtkGeometryFilter::New();
282 m_PyramidMapper
= vtkPolyDataMapper::New();
284 m_ExtrPyramids
->SetInput(m_Grid
);
285 m_ExtrPyramids
->SetAllOff();
286 m_ExtrPyramids
->SetPyramidsOn();
287 m_PyramidGeometry
->SetInput(m_ExtrPyramids
->GetOutput());
288 m_PyramidMapper
->SetInput(m_PyramidGeometry
->GetOutput());
289 m_PyramidActor
->SetMapper(m_PyramidMapper
);
290 m_PyramidActor
->GetProperty()->SetColor(1,1,0);
291 getRenderer()->AddActor(m_PyramidActor
);
292 m_PyramidActor
->SetVisibility(0);
295 m_WedgeActor
= vtkActor::New();
296 m_ExtrWedges
= vtkEgExtractVolumeCells::New();
297 m_WedgeGeometry
= vtkGeometryFilter::New();
298 m_WedgeMapper
= vtkPolyDataMapper::New();
300 m_ExtrWedges
->SetInput(m_Grid
);
301 m_ExtrWedges
->SetAllOff();
302 m_ExtrWedges
->SetWedgesOn();
303 m_WedgeGeometry
->SetInput(m_ExtrWedges
->GetOutput());
304 m_WedgeMapper
->SetInput(m_WedgeGeometry
->GetOutput());
305 m_WedgeActor
->SetMapper(m_WedgeMapper
);
306 m_WedgeActor
->GetProperty()->SetColor(0,1,0);
307 getRenderer()->AddActor(m_WedgeActor
);
308 m_WedgeActor
->SetVisibility(0);
311 m_HexaActor
= vtkActor::New();
312 m_ExtrHexes
= vtkEgExtractVolumeCells::New();
313 m_HexaGeometry
= vtkGeometryFilter::New();
314 m_HexaMapper
= vtkPolyDataMapper::New();
316 m_ExtrHexes
->SetInput(m_Grid
);
317 m_ExtrHexes
->SetAllOff();
318 m_ExtrHexes
->SetHexesOn();
319 m_HexaGeometry
->SetInput(m_ExtrHexes
->GetOutput());
320 m_HexaMapper
->SetInput(m_HexaGeometry
->GetOutput());
321 m_HexaActor
->SetMapper(m_HexaMapper
);
322 m_HexaActor
->GetProperty()->SetColor(0,0.7,1);
323 getRenderer()->AddActor(m_HexaActor
);
324 m_HexaActor
->SetVisibility(0);
326 // volume wire pipeline
327 m_VolumeWireActor
= vtkActor::New();
328 m_ExtrVol
= vtkEgExtractVolumeCells::New();
329 m_VolumeGeometry
= vtkGeometryFilter::New();
330 m_VolumeWireMapper
= vtkPolyDataMapper::New();
332 m_ExtrVol
->SetInput(m_Grid
);
333 m_ExtrVol
->SetAllOn();
334 m_VolumeGeometry
->SetInput(m_ExtrVol
->GetOutput());
335 m_VolumeWireMapper
->SetInput(m_VolumeGeometry
->GetOutput());
336 m_VolumeWireActor
->SetMapper(m_VolumeWireMapper
);
337 m_VolumeWireActor
->GetProperty()->SetRepresentationToWireframe();
338 m_VolumeWireActor
->GetProperty()->SetColor(0,0,1);
339 getRenderer()->AddActor(m_VolumeWireActor
);
340 m_VolumeWireActor
->SetVisibility(0);
343 m_PickSphere
= vtkSphereSource::New();
344 m_PickMapper
= vtkPolyDataMapper::New();
345 m_PickActor
= vtkActor::New();
346 m_CellPicker
= vtkCellPicker::New();
347 m_PointPicker
= vtkPointPicker::New();
349 m_PickSphere
->SetRadius(0.25); //in case the user starts picking points instead of cells
350 m_PickMapper
->SetInput(m_PickSphere
->GetOutput());
351 m_PickActor
->SetMapper(m_PickMapper
);
352 m_PickActor
->GetProperty()->SetRepresentationToSurface();
353 m_PickActor
->GetProperty()->SetColor(0,0,1);
354 m_PickActor
->VisibilityOff();
355 getRenderer()->AddActor(m_PickActor
);
357 vtkCallbackCommand
*cbc
= vtkCallbackCommand::New();
358 cbc
->SetCallback(pickCallBack
);
360 m_CellPicker
->AddObserver(vtkCommand::EndPickEvent
, cbc
);
361 m_PointPicker
->AddObserver(vtkCommand::EndPickEvent
, cbc
);
366 void GuiMainWindow::updateOutput()
368 QFile
log_file(m_LogFileName
);
369 log_file
.open(QIODevice::ReadOnly
);
370 QByteArray buffer
= log_file
.readAll();
371 if (buffer
.size() > m_N_chars
) {
372 QByteArray newchars
= buffer
.right(buffer
.size() - m_N_chars
);
373 m_N_chars
= buffer
.size();
374 QString
txt(newchars
);
375 if (txt
.right(1) == "\n") {
376 txt
= txt
.left(txt
.size()-1);
378 ui
.textEditOutput
->append(txt
);
382 void GuiMainWindow::exit()
384 QCoreApplication::exit();
387 vtkRenderWindow
* GuiMainWindow::getRenderWindow()
389 return ui
.qvtkWidget
->GetRenderWindow();
392 vtkRenderer
* GuiMainWindow::getRenderer()
397 QVTKInteractor
* GuiMainWindow::getInteractor()
399 return ui
.qvtkWidget
->GetInteractor();
402 QString
GuiMainWindow::getCwd()
407 void GuiMainWindow::setCwd(QString dir
)
410 m_qset
.setValue("working_directory",dir
);
413 void GuiMainWindow::setUnsaved(bool unsaved
)
418 void GuiMainWindow::scaleToData()
420 int current_field
=ui
.comboBox_Field
->currentIndex();
425 m_SurfaceFilter
->GetOutput()->GetPointData()->GetArray(current_field
-1)->GetRange(range
);
426 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
427 cout
<<"current_field="<<current_field
<<endl
;
428 cout
<<"range[0]="<<range
[0]<<endl
;
429 cout
<<"range[1]="<<range
[1]<<endl
;
430 ui
.doubleSpinBox_FieldMin
->setRange(range
[0],range
[1]);
431 ui
.doubleSpinBox_FieldMax
->setRange(range
[0],range
[1]);
432 ui
.doubleSpinBox_FieldMin
->setValue(range
[0]);
433 ui
.doubleSpinBox_FieldMax
->setValue(range
[1]);
437 void GuiMainWindow::setClipX(const QString
&txt
)
439 m_ExtrVol
->Setx(txt
.toDouble());
440 m_ExtrTetras
->Setx(txt
.toDouble());
441 m_ExtrPyramids
->Setx(txt
.toDouble());
442 m_ExtrWedges
->Setx(txt
.toDouble());
443 m_ExtrHexes
->Setx(txt
.toDouble());
446 void GuiMainWindow::setClipY(const QString
&txt
)
448 m_ExtrVol
->Sety(txt
.toDouble());
449 m_ExtrTetras
->Sety(txt
.toDouble());
450 m_ExtrPyramids
->Sety(txt
.toDouble());
451 m_ExtrWedges
->Sety(txt
.toDouble());
452 m_ExtrHexes
->Sety(txt
.toDouble());
455 void GuiMainWindow::setClipZ(const QString
&txt
)
457 m_ExtrVol
->Setz(txt
.toDouble());
458 m_ExtrTetras
->Setz(txt
.toDouble());
459 m_ExtrPyramids
->Setz(txt
.toDouble());
460 m_ExtrWedges
->Setz(txt
.toDouble());
461 m_ExtrHexes
->Setz(txt
.toDouble());
464 void GuiMainWindow::setClipNX(const QString
&txt
)
466 m_ExtrVol
->Setnx(txt
.toDouble());
467 m_ExtrTetras
->Setnx(txt
.toDouble());
468 m_ExtrPyramids
->Setnx(txt
.toDouble());
469 m_ExtrWedges
->Setnx(txt
.toDouble());
470 m_ExtrHexes
->Setnx(txt
.toDouble());
473 void GuiMainWindow::setClipNY(const QString
&txt
)
475 m_ExtrVol
->Setny(txt
.toDouble());
476 m_ExtrTetras
->Setny(txt
.toDouble());
477 m_ExtrPyramids
->Setny(txt
.toDouble());
478 m_ExtrWedges
->Setny(txt
.toDouble());
479 m_ExtrHexes
->Setny(txt
.toDouble());
482 void GuiMainWindow::setClipNZ(const QString
&txt
)
484 m_ExtrVol
->Setnz(txt
.toDouble());
485 m_ExtrTetras
->Setnz(txt
.toDouble());
486 m_ExtrPyramids
->Setnz(txt
.toDouble());
487 m_ExtrWedges
->Setnz(txt
.toDouble());
488 m_ExtrHexes
->Setnz(txt
.toDouble());
491 void GuiMainWindow::updateSurfaceActors(bool forced
)
493 if (ui
.checkBoxSurface
->isChecked()) {
495 m_SurfaceFilter
->Update();
498 // fill node field combobox
499 int current_field
=ui
.comboBox_Field
->currentIndex();
500 ui
.comboBox_Field
->clear();
501 ui
.comboBox_Field
->addItem("None");
502 for (int i
= 0; i
< m_Grid
->GetPointData()->GetNumberOfArrays(); ++i
) {
503 ui
.comboBox_Field
->addItem(m_Grid
->GetPointData()->GetArrayName(i
));
505 if(current_field
== -1) {
506 ui
.comboBox_Field
->setCurrentIndex(0);
508 ui
.comboBox_Field
->setCurrentIndex(current_field
);
511 // fill cell field combobox
512 int current_cell_field
= ui
.comboBox_CellTextField
->currentIndex();
513 ui
.comboBox_CellTextField
->clear();
514 ui
.comboBox_CellTextField
->addItem("Cell ID");
515 for (int i
= 0; i
< m_SurfaceFilter
->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i
) {
516 ui
.comboBox_CellTextField
->addItem(m_Grid
->GetCellData()->GetArrayName(i
));
518 if(current_cell_field
== -1) {
519 ui
.comboBox_CellTextField
->setCurrentIndex(0);
521 ui
.comboBox_CellTextField
->setCurrentIndex(current_cell_field
);
523 current_field
= ui
.comboBox_Field
->currentIndex();
524 if(current_field
> 0) {
526 m_SurfaceFilter
->GetOutput()->GetPointData()->GetArray(current_field
-1)->GetRange(range
);
527 ui
.doubleSpinBox_FieldMin
->setRange(range
[0],range
[1]);
528 ui
.doubleSpinBox_FieldMax
->setRange(range
[0],range
[1]);
531 if(ui
.comboBox_Field
->currentIndex() > 0) {
532 m_SurfaceMapper
->SetColorModeToMapScalars();
533 m_LookupTable
->SetNumberOfColors(ui
.spinBox_Color
->value());
534 m_LookupTable
->SetHueRange(ui
.doubleSpinBox_HueMin
->value(),ui
.doubleSpinBox_HueMax
->value());
535 m_LookupTable
->Build();
536 m_SurfaceMapper
->SetScalarModeToUsePointFieldData();
537 m_SurfaceMapper
->ColorByArrayComponent(qPrintable(ui
.comboBox_Field
->currentText()),0);
538 m_SurfaceMapper
->SetScalarRange(ui
.doubleSpinBox_FieldMin
->value(),ui
.doubleSpinBox_FieldMax
->value());
539 m_SurfaceMapper
->ScalarVisibilityOn();
540 if(ui
.checkBox_Legend
->checkState()) {
541 m_LegendActor
->SetVisibility(1);
543 m_LegendActor
->SetVisibility(0);
546 m_SurfaceMapper
->SetColorModeToDefault();
547 m_SurfaceMapper
->ScalarVisibilityOff();
548 m_LegendActor
->SetVisibility(0);
551 m_BCodesFilter
->Update();
553 if(ui
.checkBox_ShowPickSphere
->checkState()) {
554 if(m_UseVTKInteractor
) {
555 if(ui
.radioButton_CellPicker
->isChecked()) {
556 getInteractor()->SetPicker(m_CellPicker
);
557 vtkIdType id_cell
= getPickedCell();
560 getInteractor()->SetPicker(m_PointPicker
);
561 vtkIdType id_node
= getPickedPoint();
565 if (ui
.radioButton_CellPicker
->isChecked()) {
566 pickCell(m_PickedCell
);
568 pickPoint(m_PickedPoint
);
572 m_SurfaceActor
->SetVisibility(1);
573 m_SurfaceWireActor
->SetVisibility(1);
575 m_SurfaceActor
->SetVisibility(0);
576 m_SurfaceWireActor
->SetVisibility(0);
580 void GuiMainWindow::updateVolumeActors(bool forced
)
582 if (ui
.checkBoxVolume
->isChecked()) {
583 if (ui
.checkBoxTetra
->isChecked()) {
584 m_ExtrVol
->SetTetrasOn();
585 if (ui
.checkBoxClip
->isChecked()) {
586 m_ExtrTetras
->SetClippingOn();
588 m_ExtrTetras
->SetClippingOff();
591 m_TetraGeometry
->Update();
593 m_TetraActor
->SetVisibility(1);
595 m_ExtrVol
->SetTetrasOff();
596 m_TetraActor
->SetVisibility(0);
598 if (ui
.checkBoxPyramid
->isChecked()) {
599 m_ExtrVol
->SetPyramidsOn();
600 if (ui
.checkBoxClip
->isChecked()) {
601 m_ExtrPyramids
->SetClippingOn();
603 m_ExtrPyramids
->SetClippingOff();
606 m_PyramidGeometry
->Update();
608 m_PyramidActor
->SetVisibility(1);
610 m_ExtrVol
->SetPyramidsOff();
611 m_PyramidActor
->SetVisibility(0);
613 if (ui
.checkBoxWedge
->isChecked()) {
614 m_ExtrVol
->SetWedgesOn();
615 if (ui
.checkBoxClip
->isChecked()) {
616 m_ExtrWedges
->SetClippingOn();
618 m_ExtrWedges
->SetClippingOff();
621 m_WedgeGeometry
->Update();
623 m_WedgeActor
->SetVisibility(1);
625 m_ExtrVol
->SetWedgesOff();
626 m_WedgeActor
->SetVisibility(0);
628 if (ui
.checkBoxHexa
->isChecked()) {
629 m_ExtrVol
->SetHexesOn();
630 if (ui
.checkBoxClip
->isChecked()) {
631 m_ExtrHexes
->SetClippingOn();
633 m_ExtrHexes
->SetClippingOff();
636 m_HexaGeometry
->Update();
638 m_HexaActor
->SetVisibility(1);
640 m_ExtrVol
->SetHexesOff();
641 m_HexaActor
->SetVisibility(0);
645 if (ui
.checkBoxClip
->isChecked()) {
646 m_ExtrVol
->SetClippingOn();
648 m_ExtrVol
->SetClippingOff();
651 m_VolumeGeometry
->Update();
653 m_VolumeWireActor
->SetVisibility(1);
655 m_TetraActor
->VisibilityOff();
656 m_PyramidActor
->VisibilityOff();
657 m_WedgeActor
->VisibilityOff();
658 m_HexaActor
->VisibilityOff();
659 m_VolumeWireActor
->VisibilityOff();
663 void GuiMainWindow::updateActors(bool forced
)
665 // qDebug()<<"QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); called()";
666 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
668 //if (!tryLock()) return;
670 m_Axes
->SetInput(m_Grid
);
671 updateSurfaceActors(forced
);
672 updateVolumeActors(forced
);
674 } catch (Error err
) {
679 // qDebug()<<"QApplication::restoreOverrideCursor(); called()";
680 QApplication::restoreOverrideCursor();
685 void GuiMainWindow::forceUpdateActors()
687 // qDebug()<<"void GuiMainWindow::forceUpdateActors() START";
689 getRenderWindow()->Render();
690 // qDebug()<<"void GuiMainWindow::forceUpdateActors() END";
693 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor
,bool a_CellPickerMode
)
695 m_UseVTKInteractor
=a_UseVTKInteractor
;
696 if (a_UseVTKInteractor
) {
697 ui
.checkBox_UseVTKInteractor
->setCheckState(Qt::Checked
);
699 ui
.checkBox_UseVTKInteractor
->setCheckState(Qt::Unchecked
);
701 if (a_CellPickerMode
) {
702 ui
.radioButton_CellPicker
->toggle();
704 ui
.radioButton_PointPicker
->toggle();
708 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor
)
710 m_UseVTKInteractor
= a_UseVTKInteractor
;
713 bool GuiMainWindow::pickPoint(vtkIdType id_node
)
715 if ((id_node
>= 0) && (id_node
< m_Grid
->GetNumberOfPoints())) {
717 m_Grid
->GetPoints()->GetPoint(id_node
, x
.data());
718 m_PickSphere
->SetCenter(x
.data());
719 m_PickedPoint
= id_node
;
720 m_PickActor
->GetProperty()->SetColor(0,0,1);
721 m_PickActor
->VisibilityOn();
724 m_PickActor
->VisibilityOff();
729 bool GuiMainWindow::pickCell(vtkIdType id_cell
)
731 if ((id_cell
>= 0) && (id_cell
< m_Grid
->GetNumberOfCells())) {
732 vtkIdType
*pts
, Npts
;
733 m_Grid
->GetCellPoints(id_cell
, Npts
, pts
);
735 for (vtkIdType i
= 0; i
< Npts
; ++i
) {
737 m_Grid
->GetPoints()->GetPoint(pts
[i
], xp
.data());
738 x
+= double(1)/Npts
* xp
;
740 m_PickSphere
->SetCenter(x
.data());
742 for (vtkIdType i
= 0; i
< Npts
; ++i
) {
744 m_Grid
->GetPoints()->GetPoint(pts
[i
], xp
.data());
745 R
= min(R
, 0.25*(xp
-x
).abs());
747 m_ReferenceSize
= R
; //Used for text annotations too!
748 m_PickSphere
->SetRadius(R
);
749 m_PickedCell
= id_cell
;
750 m_PickActor
->GetProperty()->SetColor(1,0,0);
751 m_PickActor
->VisibilityOn();
754 m_PickActor
->VisibilityOff();
759 void GuiMainWindow::importSTL()
763 updateBoundaryCodes(true);
769 void GuiMainWindow::importGmsh1Ascii()
774 updateBoundaryCodes(true);
780 void GuiMainWindow::exportGmsh1Ascii()
787 void GuiMainWindow::importGmsh2Ascii()
792 updateBoundaryCodes(true);
798 void GuiMainWindow::exportGmsh2Ascii()
805 void GuiMainWindow::exportNeutral()
807 NeutralWriter neutral
;
811 void GuiMainWindow::zoomAll()
813 getRenderer()->ResetCamera();
814 getRenderWindow()->Render();
817 void GuiMainWindow::zoomOnPickedObject()
819 if(m_PickActor
->GetVisibility()) {
820 getRenderer()->ResetCamera(m_PickActor
->GetBounds());
821 getRenderWindow()->Render();
825 void GuiMainWindow::deselectAll()
827 cout
<< "void GuiMainWindow::deselectAll()" << endl
;
828 m_PickActor
->VisibilityOff();
832 ///\todo Should display a window
833 void GuiMainWindow::info()
835 ShowInfo
info(ui
.radioButton_CellPicker
->isChecked(), m_PickedPoint
, m_PickedCell
);
839 int GuiMainWindow::quickSave()
841 ///\todo add RAM support
842 if(m_undo_redo_enabled
) {
843 if(m_Grid
->GetNumberOfPoints()>0)
845 m_CurrentOperation
++;
846 QFileInfo
fileinfo(m_CurrentFilename
);
847 QString l_filename
= m_LogDir
+ fileinfo
.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation
);
848 m_LastOperation
=m_CurrentOperation
;
849 cout
<<"Operation "<<m_CurrentOperation
<<endl
;
850 saveAs(l_filename
, false);
851 if(m_CurrentOperation
>0) ui
.actionUndo
->setEnabled(true);
852 ui
.actionRedo
->setEnabled(false);
854 else cout
<<"No grid to save!"<<endl
;
855 return(m_CurrentOperation
);
860 void GuiMainWindow::quickLoad(int a_operation
)
862 ///\todo add RAM support
863 if(m_undo_redo_enabled
) {
864 QFileInfo
fileinfo(m_CurrentFilename
);
865 QString l_filename
= m_LogDir
+ fileinfo
.completeBaseName() + "_" + QString("%1").arg(a_operation
) + ".egc";
866 open(l_filename
, false);
870 void GuiMainWindow::undo()
872 if(m_undo_redo_enabled
) {
873 cout
<< "Undoing operation " << m_CurrentOperation
<< endl
;
874 m_CurrentOperation
--;
875 quickLoad(m_CurrentOperation
);
876 ui
.actionRedo
->setEnabled(true);
877 if(m_CurrentOperation
<=0) ui
.actionUndo
->setEnabled(false);
880 resetOperationCounter();
881 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
885 void GuiMainWindow::redo()
887 if(m_undo_redo_enabled
) {
888 m_CurrentOperation
++;
889 cout
<< "Redoing operation " << m_CurrentOperation
<< endl
;
890 quickLoad(m_CurrentOperation
);
891 ui
.actionUndo
->setEnabled(true);
892 if(m_CurrentOperation
>=m_LastOperation
) ui
.actionRedo
->setEnabled(false);
895 resetOperationCounter();
896 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
900 void GuiMainWindow::resetOperationCounter()
902 m_CurrentOperation
=-1;
903 m_LastOperation
=m_CurrentOperation
;
904 ui
.actionUndo
->setEnabled(false);
905 ui
.actionRedo
->setEnabled(false);
908 QString
GuiMainWindow::getXmlSection(QString name
)
910 QStringList tags
= name
.toLower().split("/", QString::SkipEmptyParts
);
911 QDomElement element
= m_XmlDoc
.documentElement();
913 QString section_text
= "";
915 foreach (QString tag
, tags
) {
916 QDomNodeList nodes
= element
.elementsByTagName(tag
);
917 if (nodes
.size() > 1) {
918 EG_ERR_RETURN("error retrieving XML section '" + name
+ "'");
920 if (nodes
.size() == 0) {
924 if (!nodes
.at(0).isElement()) {
925 EG_ERR_RETURN("error retrieving XML section '" + name
+ "'");
927 element
= nodes
.at(0).toElement();
929 } catch (Error err
) {
933 section_text
= element
.text();
938 void GuiMainWindow::setXmlSection(QString name
, QString contents
)
940 QStringList tags
= name
.toLower().split("/", QString::SkipEmptyParts
);
941 QDomElement element
= m_XmlDoc
.documentElement();
943 foreach (QString tag
, tags
) {
944 QDomNodeList nodes
= element
.elementsByTagName(tag
);
945 if (nodes
.size() > 1) {
946 EG_ERR_RETURN("error retrieving XML section '" + name
+ "'");
948 if (nodes
.size() == 0) {
949 QDomElement new_element
= m_XmlDoc
.createElement(tag
);
950 element
.appendChild(new_element
);
951 element
= new_element
;
952 } else if (!nodes
.at(0).isElement()) {
953 EG_ERR_RETURN("error retrieving XML section '" + name
+ "'");
955 element
= nodes
.at(0).toElement();
958 while (element
.hasChildNodes()) {
959 element
.removeChild(element
.firstChild());
961 QDomText text_node
= m_XmlDoc
.createTextNode(contents
);
962 element
.appendChild(text_node
);
963 } catch (Error err
) {
968 void GuiMainWindow::openPhysicalBoundaryConditions()
970 m_PhysicalBoundaryConditionsMap
.clear();
971 QString buffer
= getXmlSection("engrid/physical");
972 QTextStream
f(&buffer
, QIODevice::ReadOnly
);
976 f
>> index
>> name
>> type
;
977 if ((name
!= "") && (type
!= "")) {
978 PhysicalBoundaryCondition PBC
;
982 for (int i
= 0; i
< PBC
.getNumVars(); ++i
) {
987 m_PhysicalBoundaryConditionsMap
[name
] = PBC
;
992 void GuiMainWindow::savePhysicalBoundaryConditions()
995 QTextStream
f(&buffer
, QIODevice::WriteOnly
);
997 foreach (PhysicalBoundaryCondition PBC
, m_PhysicalBoundaryConditionsMap
) {
998 f
<< PBC
.getIndex() << " " << PBC
.getName() << " " << PBC
.getType();
999 for (int i
= 0; i
< PBC
.getNumVars(); ++i
) {
1000 f
<< " " << PBC
.getVarValue(i
);
1004 setXmlSection("engrid/physical", buffer
);
1007 void GuiMainWindow::openBC()
1011 QString buffer
= getXmlSection("engrid/bc");
1012 QTextStream
f(&buffer
, QIODevice::ReadOnly
);
1013 while (!f
.atEnd()) {
1016 f
>> i
>> name
>> type
;
1017 if(name
!="" && type
!="") {
1019 m_bcmap
[i
] = BoundaryCondition(name
,type
);
1021 VolumeDefinition
V(name
, -i
);
1022 QString text
= type
.replace(",", " ").replace(":", " ");
1023 QTextStream
s(&text
);
1024 while (!s
.atEnd()) {
1025 QString bc_txt
, sign_txt
;
1026 s
>> bc_txt
>> sign_txt
;
1027 V
.addBC(bc_txt
.toInt(), sign_txt
.toInt());
1035 void GuiMainWindow::saveBC()
1038 QTextStream
f(&buffer
, QIODevice::WriteOnly
);
1040 foreach (int i
, m_AllBoundaryCodes
) {
1041 BoundaryCondition bc
= m_bcmap
[i
];
1042 f
<< i
<< " " << bc
.getName() << " " << bc
.getType() << "\n";
1044 foreach (VolumeDefinition V
, m_VolMap
) {
1047 foreach (int i
, m_AllBoundaryCodes
) {
1048 BoundaryCondition bc
= m_bcmap
[i
];
1057 num
.setNum(V
.getSign(i
));
1060 f
<< "-" << V
.getVC() << " " << V
.getName() << " " << dirs
<< "\n";
1062 setXmlSection("engrid/bc", buffer
);
1065 void GuiMainWindow::openGrid(QString file_name
)
1067 file_name
+= ".vtu";
1068 EG_VTKSP(vtkXMLUnstructuredGridReader
,vtu
);
1069 vtu
->SetFileName(qPrintable(file_name
));
1071 m_Grid
->DeepCopy(vtu
->GetOutput());
1072 createBasicFields(m_Grid
, m_Grid
->GetNumberOfCells(), m_Grid
->GetNumberOfPoints());
1074 openPhysicalBoundaryConditions();
1075 updateBoundaryCodes(true);
1076 createIndices(m_Grid
);
1082 ///\todo I think this should also be a done by a subclass of IOOperation just like for import operations
1083 void GuiMainWindow::open()
1085 QFileDialog
dialog(NULL
, "open grid from file", getCwd(), "enGrid case files (*.egc *.EGC);; legacy grid files(*.vtu *.VTU)");
1086 QFileInfo
file_info(m_CurrentFilename
);
1087 qDebug()<<"m_CurrentFilename="<<m_CurrentFilename
;
1088 dialog
.selectFile(file_info
.completeBaseName() + ".egc");
1089 if (dialog
.exec()) {
1090 QStringList selected_files
= dialog
.selectedFiles();
1091 QString file_name
= selected_files
[0];
1092 if (!file_name
.isNull()) {
1093 this->open(file_name
);
1098 void GuiMainWindow::open(QString file_name
, bool update_current_filename
)
1100 cout
<< "Opening " << qPrintable(file_name
) << endl
;
1102 QFileInfo
file_info(file_name
);
1103 bool no_case_file
= false;
1104 QString file_extension
= getExtension(file_name
);
1105 QString grid_file_name
= file_name
;
1106 if (file_extension
.toLower() == "vtu") {
1107 no_case_file
= true;
1108 grid_file_name
= stripFromExtension(file_name
);
1110 if(update_current_filename
) {
1111 GuiMainWindow::setCwd(QFileInfo(file_name
).absolutePath());
1113 if (!no_case_file
) {
1116 openGrid(grid_file_name
);
1118 openPhysicalBoundaryConditions();
1119 // update current filename
1120 if(update_current_filename
) m_CurrentFilename
= stripFromExtension(file_name
) + ".egc";
1121 setWindowTitle(m_CurrentFilename
+ " - enGrid - " + QString("%1").arg(m_CurrentOperation
) );
1124 if(update_current_filename
) {
1125 this->addRecentFile(file_name
,QDateTime::currentDateTime());
1126 resetOperationCounter();
1131 void GuiMainWindow::openXml(QString file_name
)
1133 QFile
xml_file(file_name
);
1134 if (!xml_file
.open(QIODevice::ReadOnly
)) {
1135 qWarning()<<"Failed to open xml_file "<<xml_file
.fileName();
1136 qWarning()<<"QDir::current()="<<QDir::current();
1137 qWarning()<<"QDir::currentPath()="<<QDir::currentPath();
1138 qWarning()<<"getCwd()="<<getCwd();
1141 if (!m_XmlDoc
.setContent(&xml_file
)) {
1142 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name
));
1147 void GuiMainWindow::saveXml(QString file_name
)
1149 QString buffer
= m_XmlDoc
.toString(0);
1150 QFile
xml_file(file_name
);
1151 xml_file
.open(QIODevice::WriteOnly
| QIODevice::Text
);
1152 QTextStream
f(&xml_file
);
1153 f
<< buffer
<< endl
;
1156 QString
GuiMainWindow::saveAs(QString file_name
, bool update_current_filename
)
1158 QString buffer
= m_XmlDoc
.toString(0);
1160 if(update_current_filename
) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
1162 QFileInfo
file_info(file_name
);
1163 if (file_info
.suffix().toLower() != "egc") {
1164 file_name
+= ".egc";
1166 cout
<< "Saving as " << qPrintable(file_name
) << endl
;
1167 if(update_current_filename
) {
1168 // update current filename
1169 GuiMainWindow::setCwd(file_info
.absolutePath());
1170 m_CurrentFilename
= file_name
;
1172 if(!saveGrid(m_Grid
, file_name
)) {
1173 QMessageBox::critical(this, QObject::tr("Save failed"), QObject::tr("The grid could not be saved as:\n%1").arg(file_name
));
1177 savePhysicalBoundaryConditions();
1180 setWindowTitle(m_CurrentFilename
+ " - enGrid - " + QString("%1").arg(m_CurrentOperation
) );
1183 if(update_current_filename
) QApplication::restoreOverrideCursor();
1185 if(update_current_filename
) {
1186 this->addRecentFile(file_name
,QDateTime::currentDateTime());
1192 void GuiMainWindow::save()
1194 if ( m_CurrentFilename
== "untitled.egc" || m_UnSaved
) {
1197 saveAs(m_CurrentFilename
);
1201 void GuiMainWindow::saveAs()
1203 QFileDialog
dialog(NULL
, "write case to file", getCwd(), "enGrid case files (*.egc)");
1204 QFileInfo
file_info(m_CurrentFilename
);
1205 dialog
.selectFile(file_info
.completeBaseName() + ".egc");
1206 dialog
.setAcceptMode(QFileDialog::AcceptSave
);
1207 dialog
.setConfirmOverwrite(true);
1208 if (dialog
.exec()) {
1209 QStringList selected_files
= dialog
.selectedFiles();
1210 QString file_name
= selected_files
[0];
1211 if (!file_name
.isNull()) {
1213 //for the undo/redo operations
1214 resetOperationCounter();
1220 void GuiMainWindow::updateStatusBar()
1222 QString num
, txt
= "enGrid is currently busy with an operation ...";
1227 m_StatusLabel
->setText(txt
);
1228 ui
.label_node_cell_info
->setText(txt
);
1231 vtkIdType Ncells
= m_Grid
->GetNumberOfCells();
1232 vtkIdType Nnodes
= m_Grid
->GetNumberOfPoints();
1233 vtkIdType Ntris
= 0;
1234 vtkIdType Nquads
= 0;
1235 vtkIdType Ntets
= 0;
1236 vtkIdType Npyras
= 0;
1237 vtkIdType Nprism
= 0;
1238 vtkIdType Nhexas
= 0;
1239 for (vtkIdType i
= 0; i
< Ncells
; ++i
) {
1240 int ct
= m_Grid
->GetCellType(i
);
1241 if (ct
== VTK_TRIANGLE
) ++Ntris
;
1242 else if (ct
== VTK_QUAD
) ++Nquads
;
1243 else if (ct
== VTK_TETRA
) ++Ntets
;
1244 else if (ct
== VTK_WEDGE
) ++Nprism
;
1245 else if (ct
== VTK_PYRAMID
) ++Npyras
;
1246 else if (ct
== VTK_HEXAHEDRON
) ++Nhexas
;
1248 num
.setNum(Ntets
+ Npyras
+ Nprism
+ Nhexas
); txt
+= num
+ " volume cells(";
1249 num
.setNum(Ntets
); txt
+= num
+ " tetras, ";
1250 num
.setNum(Npyras
); txt
+= num
+ " pyramids, ";
1251 num
.setNum(Nprism
); txt
+= num
+ " prisms, ";
1252 num
.setNum(Nhexas
); txt
+= num
+ " hexas), ";
1253 num
.setNum(Ntris
+ Nquads
); txt
+= num
+ " surface cells(";
1254 num
.setNum(Ntris
); txt
+= num
+ " triangles, ";
1255 num
.setNum(Nquads
); txt
+= num
+ " quads), ";
1256 num
.setNum(Nnodes
); txt
+= num
+ " nodes";
1258 if(ui
.radioButton_CellPicker
->isChecked())
1260 QString pick_txt
= ", picked cell: ";
1261 vtkIdType id_cell
= m_PickedCell
;
1262 if (id_cell
< 0 || id_cell
>=m_Grid
->GetNumberOfCells()) {
1263 pick_txt
+= "no cell picked";
1265 vtkIdType type_cell
= m_Grid
->GetCellType(id_cell
);
1266 if (type_cell
== VTK_TRIANGLE
) pick_txt
+= "tri";
1267 else if (type_cell
== VTK_QUAD
) pick_txt
+= "qua";
1268 else if (type_cell
== VTK_TETRA
) pick_txt
+= "tet";
1269 else if (type_cell
== VTK_PYRAMID
) pick_txt
+= "pyr";
1270 else if (type_cell
== VTK_WEDGE
) pick_txt
+= "pri";
1271 else if (type_cell
== VTK_HEXAHEDRON
) pick_txt
+= "hex";
1272 vtkIdType N_pts
, *pts
;
1273 m_Grid
->GetCellPoints(id_cell
, N_pts
, pts
);
1275 for (int i_pts
= 0; i_pts
< N_pts
; ++i_pts
) {
1277 num
.setNum(pts
[i_pts
]);
1279 if (i_pts
< N_pts
-1) {
1285 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
1286 tmp
.setNum(cell_code
->GetValue(id_cell
));
1287 pick_txt
+= " code=" + tmp
;
1288 tmp
.setNum(id_cell
);
1289 pick_txt
+= " id=" + tmp
;
1295 QString pick_txt
= ", picked node: ";
1296 vtkIdType id_node
= m_PickedPoint
;
1298 pick_txt
+= "no node picked";
1301 m_Grid
->GetPoints()->GetPoint(id_node
,x
.data());
1303 for (int i
= 0; i
< 3; i
++) {
1313 EG_VTKDCN(vtkDoubleArray
, characteristic_length_desired
, m_Grid
, "node_meshdensity_desired");
1314 tmp
.setNum(characteristic_length_desired
->GetValue(id_node
));
1315 pick_txt
+= " wanted density=" + tmp
;
1316 EG_VTKDCN(vtkDoubleArray
, node_meshdensity_current
, m_Grid
, "node_meshdensity_current");
1317 tmp
.setNum(node_meshdensity_current
->GetValue(id_node
));
1318 pick_txt
+= " current density=" + tmp
;
1319 EG_VTKDCN(vtkIntArray
, node_specified_density
, m_Grid
, "node_specified_density");
1320 tmp
.setNum(node_specified_density
->GetValue(id_node
));
1321 pick_txt
+= " node_specified_density=" + tmp
;
1322 EG_VTKDCN(vtkCharArray
, node_type
, m_Grid
, "node_type");
1323 pick_txt
+= " type=" + QString(VertexType2Str( node_type
->GetValue(id_node
)));
1324 tmp
.setNum(id_node
);
1325 pick_txt
+= " id_node=" + tmp
;
1331 m_StatusLabel
->setText(txt
);
1332 ui
.label_node_cell_info
->setText(txt
);
1336 void GuiMainWindow::selectBoundaryCodes()
1338 GuiSelectBoundaryCodes bcodes
;
1339 bcodes
.setDisplayBoundaryCodes(m_DisplayBoundaryCodes
);
1340 bcodes
.setBoundaryCodes(m_AllBoundaryCodes
);
1342 bcodes
.getThread().wait();
1343 bcodes
.getSelectedBoundaryCodes(m_DisplayBoundaryCodes
);
1344 m_BCodesFilter
->SetBoundaryCodes(m_DisplayBoundaryCodes
);
1348 void GuiMainWindow::updateBoundaryCodes(bool all_on
)
1351 m_AllBoundaryCodes
.clear();
1352 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
1353 for (vtkIdType i
= 0; i
< m_Grid
->GetNumberOfCells(); ++i
) {
1354 int ct
= m_Grid
->GetCellType(i
);
1355 if ((ct
== VTK_TRIANGLE
) || (ct
== VTK_QUAD
)) {
1356 m_AllBoundaryCodes
.insert(cell_code
->GetValue(i
));
1360 m_DisplayBoundaryCodes
.clear();
1361 foreach (int bc
, m_AllBoundaryCodes
) {
1362 m_DisplayBoundaryCodes
.insert(bc
);
1366 foreach (int bc
, m_DisplayBoundaryCodes
) {
1367 if (m_AllBoundaryCodes
.contains(bc
)) {
1371 m_DisplayBoundaryCodes
.clear();
1372 foreach (int bc
, m_AllBoundaryCodes
) {
1373 if (dbcs
.contains(bc
)) {
1374 m_DisplayBoundaryCodes
.insert(bc
);
1378 m_BCodesFilter
->SetBoundaryCodes(m_DisplayBoundaryCodes
);
1379 } catch (Error err
) {
1384 void GuiMainWindow::normalExtrusion()
1386 GuiNormalExtrusion extr
;
1388 updateBoundaryCodes(false);
1392 void GuiMainWindow::setAxesVisibility()
1394 if (ui
.actionViewAxes
->isChecked()) {
1395 m_Axes
->VisibilityOn();
1397 m_Axes
->VisibilityOff();
1399 getRenderWindow()->Render();
1402 void GuiMainWindow::setViewingMode()
1404 if (ui
.actionViewOrthogonal
->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1405 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1406 getRenderWindow()->Render();
1409 void GuiMainWindow::viewNodeIDs()
1411 int N
= m_Grid
->GetNumberOfPoints();
1412 cout
<<"N="<<N
<<endl
;
1413 if (ui
.actionViewNodeIDs
->isChecked()) {
1414 cout
<<"Activating node ID view"<<endl
;
1415 m_NodeTextVectorText
.resize(N
);
1416 m_NodeTextPolyDataMapper
.resize(N
);
1417 m_NodeTextFollower
.resize(N
);
1418 for(int i
= 0; i
< N
; ++i
){
1419 m_NodeTextVectorText
[i
]=vtkVectorText::New();
1422 m_NodeTextVectorText
[i
]->SetText(qPrintable(tmp
));
1423 m_NodeTextPolyDataMapper
[i
]=vtkPolyDataMapper::New();
1424 m_NodeTextPolyDataMapper
[i
]->SetInputConnection(m_NodeTextVectorText
[i
]->GetOutputPort());
1425 m_NodeTextFollower
[i
]=vtkFollower::New();
1426 m_NodeTextFollower
[i
]->SetMapper(m_NodeTextPolyDataMapper
[i
]);
1427 m_NodeTextFollower
[i
]->SetScale(m_ReferenceSize
, m_ReferenceSize
, m_ReferenceSize
);
1429 m_Grid
->GetPoint(i
, M
.data());
1431 vec3_t OffSet
= m_ReferenceSize
*tmp_M
.normalise();
1433 m_NodeTextFollower
[i
]->AddPosition(M
[0], M
[1], M
[2]);
1434 m_NodeTextFollower
[i
]->SetCamera(getRenderer()->GetActiveCamera());
1435 m_NodeTextFollower
[i
]->GetProperty()->SetColor(0,0,1);
1436 getRenderer()->AddActor(m_NodeTextFollower
[i
]);
1440 cout
<<"Deactivating node ID view"<<endl
;
1441 for(unsigned int i
= 0; i
< m_NodeTextFollower
.size();i
++){
1442 getRenderer()->RemoveActor(m_NodeTextFollower
[i
]);
1443 m_NodeTextFollower
[i
]->Delete();
1444 m_NodeTextPolyDataMapper
[i
]->Delete();
1445 m_NodeTextVectorText
[i
]->Delete();
1447 m_NodeTextFollower
.clear();
1448 m_NodeTextPolyDataMapper
.clear();
1449 m_NodeTextVectorText
.clear();
1452 getRenderWindow()->Render();
1455 void GuiMainWindow::viewCellIDs()
1457 vtkIdType N
= m_Grid
->GetNumberOfCells();
1458 cout
<<"N="<<N
<<endl
;
1459 if (ui
.actionViewCellIDs
->isChecked()) {
1460 cout
<<"Activating cell ID view"<<endl
;
1461 m_CellTextVectorText
.resize(N
);
1462 m_CellTextPolyDataMapper
.resize(N
);
1463 m_CellTextFollower
.resize(N
);
1464 for (vtkIdType id_cell
= 0; id_cell
< N
; ++id_cell
){
1465 m_CellTextVectorText
[id_cell
] = vtkVectorText::New();
1469 if(ui
.comboBox_CellTextField
->currentIndex()==0) {
1470 tmp
.setNum(id_cell
);
1471 } else if (ui
.comboBox_CellTextField
->currentIndex()>0) {
1472 EG_VTKDCC(vtkIntArray
, current_cell_field
, m_Grid
, qPrintable(ui
.comboBox_CellTextField
->currentText()));
1473 tmp
.setNum(current_cell_field
->GetValue(id_cell
));
1477 m_CellTextVectorText
[id_cell
]->SetText(qPrintable(tmp
));
1478 m_CellTextPolyDataMapper
[id_cell
]=vtkPolyDataMapper::New();
1479 m_CellTextPolyDataMapper
[id_cell
]->SetInputConnection(m_CellTextVectorText
[id_cell
]->GetOutputPort());
1480 m_CellTextFollower
[id_cell
]=vtkFollower::New();
1481 m_CellTextFollower
[id_cell
]->SetMapper(m_CellTextPolyDataMapper
[id_cell
]);
1482 m_CellTextFollower
[id_cell
]->SetScale(m_ReferenceSize
, m_ReferenceSize
, m_ReferenceSize
);
1483 vtkIdType N_pts
,*pts
;
1484 m_Grid
->GetCellPoints(id_cell
,N_pts
,pts
);
1485 vec3_t
Center(0,0,0);
1486 for (int p
= 0; p
< N_pts
; ++p
) {
1488 m_Grid
->GetPoint(pts
[p
],M
.data());
1491 vec3_t OffSet
= m_ReferenceSize
*triNormal(m_Grid
, pts
[0], pts
[1], pts
[2]).normalise();
1492 Center
= 1.0/(double)N_pts
*Center
+OffSet
;
1493 m_CellTextFollower
[id_cell
]->AddPosition(Center
[0], Center
[1], Center
[2]);
1494 m_CellTextFollower
[id_cell
]->SetCamera(getRenderer()->GetActiveCamera());
1495 m_CellTextFollower
[id_cell
]->GetProperty()->SetColor(1, 0, 0);
1496 getRenderer()->AddActor(m_CellTextFollower
[id_cell
]);
1499 cout
<<"Deactivating cell ID view"<<endl
;
1500 for (vtkIdType id_cell
= 0; id_cell
< (vtkIdType
) m_CellTextFollower
.size(); ++id_cell
) {
1501 getRenderer()->RemoveActor(m_CellTextFollower
[id_cell
]);
1502 m_CellTextFollower
[id_cell
]->Delete();
1503 m_CellTextPolyDataMapper
[id_cell
]->Delete();
1504 m_CellTextVectorText
[id_cell
]->Delete();
1506 m_CellTextFollower
.clear();
1507 m_CellTextPolyDataMapper
.clear();
1508 m_CellTextVectorText
.clear();
1511 getRenderWindow()->Render();
1514 void GuiMainWindow::pickCallBack
1517 unsigned long int eid
,
1524 clientdata
= clientdata
;
1525 calldata
= calldata
;
1526 THIS
->updateActors();
1527 THIS
->updateStatusBar();
1530 vtkIdType
GuiMainWindow::getPickedCell()
1532 vtkIdType picked_cell
= -1;
1533 if (m_Grid
->GetNumberOfCells() > 0) {
1534 m_BCodesFilter
->Update();
1535 if (m_BCodesFilter
->GetOutput()->GetNumberOfCells() > 0) {
1536 EG_VTKDCC(vtkLongArray_t
, cell_index
, m_BCodesFilter
->GetOutput(), "cell_index");
1537 if (m_UseVTKInteractor
) {
1538 picked_cell
= cell_index
->GetValue(m_CellPicker
->GetCellId());
1540 picked_cell
= m_PickedCell
;
1547 vtkIdType
GuiMainWindow::getPickedPoint()
1549 vtkIdType picked_point
= -1;
1550 if (m_Grid
->GetNumberOfCells() > 0) {
1551 m_BCodesFilter
->Update();
1552 if (m_BCodesFilter
->GetOutput()->GetNumberOfCells() > 0) {
1553 EG_VTKDCN(vtkLongArray_t
, node_index
, m_BCodesFilter
->GetOutput(), "node_index");
1554 if (m_UseVTKInteractor
) {
1555 picked_point
= node_index
->GetValue(m_PointPicker
->GetPointId());
1557 picked_point
= m_PickedPoint
;
1561 return picked_point
;
1564 void GuiMainWindow::changeSurfaceOrientation()
1566 for (vtkIdType cellId
= 0; cellId
< m_Grid
->GetNumberOfCells(); ++cellId
) {
1567 vtkIdType Npts
, *pts
;
1568 m_Grid
->GetCellPoints(cellId
, Npts
, pts
);
1569 QVector
<vtkIdType
> nodes(Npts
);
1570 for (vtkIdType j
= 0; j
< Npts
; ++j
) nodes
[j
] = pts
[j
];
1571 for (vtkIdType j
= 0; j
< Npts
; ++j
) pts
[Npts
- j
- 1] = nodes
[j
];
1574 m_Grid
->Modified();// to make sure VTK notices the changes and changes the cell colors
1577 void GuiMainWindow::checkSurfaceOrientation()
1579 CorrectSurfaceOrientation corr_surf
;
1580 vtkIdType picked_cell
= getPickedCell();
1581 if (picked_cell
>= 0) {
1582 corr_surf
.setStart(picked_cell
);
1588 void GuiMainWindow::improveAspectRatio()
1590 GuiImproveAspectRatio impr_ar
;
1595 void GuiMainWindow::exportAsciiStl()
1598 stl
.setFileTypeToASCII();
1602 void GuiMainWindow::exportBinaryStl()
1605 stl
.setFileTypeToBinary();
1609 void GuiMainWindow::exportAsciiPly()
1612 ply
.setFileTypeToASCII();
1616 void GuiMainWindow::exportBinaryPly()
1619 ply
.setFileTypeToBinary();
1623 void GuiMainWindow::periodicUpdate()
1625 Operation::collectGarbage();
1629 void GuiMainWindow::viewXP()
1631 getRenderer()->ResetCamera();
1633 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1635 getRenderer()->GetActiveCamera()->SetPosition(x
);
1636 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1637 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1638 getRenderer()->ResetCamera();
1639 getRenderWindow()->Render();
1642 void GuiMainWindow::viewXM()
1644 getRenderer()->ResetCamera();
1646 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1648 getRenderer()->GetActiveCamera()->SetPosition(x
);
1649 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1650 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1651 getRenderer()->ResetCamera();
1652 getRenderWindow()->Render();
1655 void GuiMainWindow::viewYP()
1657 getRenderer()->ResetCamera();
1659 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1661 getRenderer()->GetActiveCamera()->SetPosition(x
);
1662 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1663 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1664 getRenderer()->ResetCamera();
1665 getRenderWindow()->Render();
1668 void GuiMainWindow::viewYM()
1670 getRenderer()->ResetCamera();
1672 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1674 getRenderer()->GetActiveCamera()->SetPosition(x
);
1675 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1676 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1677 getRenderer()->ResetCamera();
1678 getRenderWindow()->Render();
1681 void GuiMainWindow::viewZP()
1683 getRenderer()->ResetCamera();
1685 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1687 getRenderer()->GetActiveCamera()->SetPosition(x
);
1688 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1689 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1690 getRenderer()->ResetCamera();
1691 getRenderWindow()->Render();
1694 void GuiMainWindow::viewZM()
1696 getRenderer()->ResetCamera();
1698 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1700 getRenderer()->GetActiveCamera()->SetPosition(x
);
1701 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1702 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1703 getRenderer()->ResetCamera();
1704 getRenderWindow()->Render();
1707 void GuiMainWindow::callFixSTL()
1713 updateBoundaryCodes(false);
1717 void GuiMainWindow::callDeletePickedPoint()
1719 EG_STDINTERSLOT( DeletePickedPoint
);
1722 void GuiMainWindow::editBoundaryConditions()
1724 GuiEditBoundaryConditions editbcs
;
1725 editbcs
.setBoundaryCodes(m_AllBoundaryCodes
);
1726 editbcs
.setMap(&m_bcmap
);
1730 void GuiMainWindow::configure()
1733 // Just to create initial entries in the settings file
1734 // so that the options menu isn't empty at first start.
1737 GuiCreateBoundaryLayer tmp02
;
1738 SurfaceProjection tmp03
;
1739 SurfaceMesher tmp04
;
1740 UpdateDesiredMeshDensity tmp05
;
1743 LaplaceSmoother tmp08
;
1744 SwapTriangles tmp09
;
1745 OpenFOAMTools tmp10
;
1746 } catch (Error err
) {
1750 GuiSettingsViewer
settings(&m_qset
);
1751 settings
.CreateViewer();
1754 getSet("General","enable undo+redo",false,m_undo_redo_enabled
);
1757 void GuiMainWindow::about()
1759 QMessageBox
box(this);
1761 QString title
="ENGRID";
1762 QString version
= QString("version ") + ENGRID_VERSION
;
1764 if(!QString(GIT_DESCRIBE
).isEmpty()) {
1765 version
+= QString(" - ") + GIT_DESCRIBE
;
1769 version
+= " built on ";
1770 version
+= QString(__DATE__
);
1772 version
+= QString(__TIME__
);
1774 QString address
= tr("ENGRID is being developed and maintained by:<br/>"
1776 "Marie-Curie-Strasse 8<br/>"
1777 "79539 Loerrach<br/>"
1780 QString mainurl
="<a href=\"http://www.engits.com\">www.engits.com</a>";
1781 QString mail
="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1782 QString gnuurl
="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1783 QString license
=tr("ENGRID is licenced under the GPL version 3.<br/>"
1784 "(see ")+gnuurl
+tr(" for details)<br/>");
1785 QString bugurl
="<a href=\"http://sourceforge.net/tracker2/?func=add&group_id=245110&atid=1126548\">the bugtracker available on Sourceforge</a>";
1786 QString bugreporting
=tr("To submit a bug report, please use ")+bugurl
;
1787 box
.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1791 "<p>Homepage: %4</p>"
1794 "<p>%7</p></center>")
1795 .arg(title
).arg(version
).arg(address
).arg(mainurl
).arg(mail
).arg(license
).arg(bugreporting
));
1796 box
.setWindowTitle(tr("about ENGRID"));
1797 box
.setIcon(QMessageBox::NoIcon
);
1802 ///\todo Why not use bcs = m_AllBoundaryCodes; ?
1803 void GuiMainWindow::getAllBoundaryCodes(QSet
<int> &bcs
)
1805 bcs
= m_AllBoundaryCodes
;
1806 // qWarning()<<"m_AllBoundaryCodes="<<m_AllBoundaryCodes;
1808 // foreach (int bc, m_AllBoundaryCodes) {
1813 QSet
<int> GuiMainWindow::getAllBoundaryCodes()
1815 return m_AllBoundaryCodes
;
1818 void GuiMainWindow::getDisplayBoundaryCodes(QSet
<int> &bcs
)
1821 foreach (int bc
, m_DisplayBoundaryCodes
) {
1826 QList
<VolumeDefinition
> GuiMainWindow::getAllVols()
1828 QList
<VolumeDefinition
> vols
;
1829 foreach(VolumeDefinition vol
, m_VolMap
) {
1830 vols
.push_back(vol
);
1835 void GuiMainWindow::setAllVols(QList
<VolumeDefinition
> vols
)
1838 foreach (VolumeDefinition V
, vols
) {
1839 m_VolMap
[V
.getName()] = V
;
1843 QList
<PhysicalBoundaryCondition
> GuiMainWindow::getAllPhysicalBoundaryConditions()
1845 QList
<PhysicalBoundaryCondition
> physical_boundary_conditions
;
1846 foreach(PhysicalBoundaryCondition PBC
, m_PhysicalBoundaryConditionsMap
) {
1847 physical_boundary_conditions
.push_back(PBC
);
1849 return physical_boundary_conditions
;
1852 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList
<PhysicalBoundaryCondition
> physical_boundary_conditions
)
1854 m_PhysicalBoundaryConditionsMap
.clear();
1855 foreach (PhysicalBoundaryCondition PBC
, physical_boundary_conditions
) {
1856 m_PhysicalBoundaryConditionsMap
[PBC
.getName()] = PBC
;
1860 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap
<QString
,PhysicalBoundaryCondition
> physical_boundary_conditions
) {
1861 m_PhysicalBoundaryConditionsMap
= physical_boundary_conditions
;
1864 void GuiMainWindow::createDefaultVol()
1866 QList
<VolumeDefinition
> vols
= getAllVols();
1867 if (vols
.size() == 0) {
1868 VolumeDefinition
V("default", 1);
1870 getAllBoundaryCodes(bcs
);
1871 foreach (int bc
, bcs
) {
1879 QString
GuiMainWindow::getFilePath()
1881 QFileInfo
fileinfo(m_CurrentFilename
);
1882 return fileinfo
.absolutePath()+"/";
1885 void GuiMainWindow::markOutputLine()
1887 cout
<< "\n****************************************\n";
1888 cout
<< qPrintable(QTime::currentTime().toString("hh:mm:ss"));
1889 cout
<< "\n****************************************\n" << endl
;
1892 void GuiMainWindow::storeSurfaceProjection()
1894 qDebug()<<"@@@ GuiMainWindow::storeSurfaceProjection called";
1895 foreach (SurfaceProjection
* proj
, m_SurfProj
) {
1899 cout
<< "storing background grid for surface projection:" << endl
;
1901 foreach (int bc
, m_AllBoundaryCodes
) {
1902 SurfaceProjection
*proj
= new SurfaceProjection();
1903 m_SurfProj
[bc
] = proj
;
1906 QVector
<vtkIdType
> cls
;
1907 getSurfaceCells(bcs
, cls
, m_Grid
);
1908 proj
->setBackgroundGrid(m_Grid
, cls
);
1909 if (proj
->usesLevelSet()) {
1911 file_name
.setNum(bc
);
1912 file_name
= "OctreeBC" + file_name
;
1913 proj
->writeOctree(file_name
);
1914 cout
<< " bc " << bc
<< ": " << proj
->getNumOctreeCells() << endl
;
1919 SurfaceProjection
* GuiMainWindow::getSurfProj(int bc
)
1921 if (!m_SurfProj
.contains(bc
)) {
1924 EG_ERR_RETURN("No surface projection found for boundary code " + bc_txt
);
1926 return m_SurfProj
[bc
];
1929 bool GuiMainWindow::checkSurfProj()
1932 foreach (int bc
, m_AllBoundaryCodes
) {
1933 if (!m_SurfProj
.contains(bc
)) {
1941 void GuiMainWindow::openRecent(QAction
*action
)
1943 qDebug()<<"GuiMainWindow::openRecent called";
1944 QString file_name
= action
->text().right(action
->text().length()-23);
1945 this->open(file_name
);
1946 // this->addRecentFile(file_name,QDateTime::currentDateTime());
1949 void GuiMainWindow::readRecentFiles()
1951 m_RecentFiles
.clear();
1952 this->recentFileMenu()->clear();
1953 QStringList file_names
= m_qset
.value("FileNames").toStringList();
1954 QStringList file_dates
= m_qset
.value("FileDates").toStringList();
1955 int N
= min(10,m_qset
.value("NumberOfFiles").toInt());
1956 cout
<< "NumberOfFiles=" << N
<< endl
;
1957 for (int i
= 0; i
< N
; ++i
) {
1958 QString new_file
= file_names
.at(i
);
1959 QString date_text
= file_dates
.at(i
);
1960 QDateTime date
= QDateTime::fromString(date_text
,"dd.MM.yyyy_hh:mm:ss");
1961 addRecentFile(new_file
,date
);
1965 void GuiMainWindow::writeRecentFiles()
1967 m_qset
.setValue("NumberOfFiles",m_RecentFiles
.size());
1968 QStringList file_names
;
1969 QStringList file_dates
;
1970 for (QMap
<QString
,QDateTime
>::iterator i
= m_RecentFiles
.begin(); i
!= m_RecentFiles
.end(); ++i
) {
1971 QString file_name
= i
.key();
1972 QString date_text
= i
.value().toString("dd.MM.yyyy_hh:mm:ss");
1973 file_names
.append(file_name
);
1974 file_dates
.append(date_text
);
1976 m_qset
.setValue("FileNames",file_names
);
1977 m_qset
.setValue("FileDates",file_dates
);
1980 void GuiMainWindow::addRecentFile(QString file_name
, QDateTime date
)
1982 m_RecentFiles
[file_name
] = date
;
1983 while (m_RecentFiles
.size() > 10) {
1984 QMap
<QString
,QDateTime
>::iterator i
,j
;
1985 QDateTime old
= QDateTime::currentDateTime();
1986 for (i
= m_RecentFiles
.begin(); i
!= m_RecentFiles
.end(); ++i
) {
1987 if (i
.value() <= old
) {
1992 m_RecentFiles
.erase(j
);
1994 this->recentFileMenu()->clear();
1995 QMap
<int,QString
> menu_map
;
1996 QDateTime now
= QDateTime::currentDateTime();
1997 for (QMap
<QString
,QDateTime
>::iterator i
= m_RecentFiles
.begin(); i
!= m_RecentFiles
.end(); ++i
) {
1998 QString action_text
= i
.value().toString("dd.MM.yyyy hh:mm:ss");
1999 action_text
+= " -> ";
2000 action_text
+= i
.key();
2001 menu_map
[i
.value().secsTo(now
)] = action_text
;
2004 for (QMap
<int,QString
>::iterator i
= menu_map
.begin(); i
!= menu_map
.end(); ++i
) {
2005 QAction
*action
= new QAction(i
.value(),this);
2006 this->recentFileMenu()->addAction(action
);