2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2012 enGits GmbH +
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>
63 #include "geometrytools.h"
64 #include "engrid_version.h"
66 using namespace GeometryTools
;
68 #include "guisettingsviewer.h"
69 #include "guitransform.h"
70 #include "egvtkinteractorstyle.h"
72 #include "engrid_version.h"
74 QString
GuiMainWindow::m_cwd
= ".";
75 QSettings
GuiMainWindow::m_qset("enGits","enGrid");
76 GuiMainWindow
* GuiMainWindow::THIS
= NULL
;
77 QMutex
GuiMainWindow::m_Mutex
;
78 bool GuiMainWindow::m_UnSaved
= true;
80 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL
)
84 if(m_qset
.contains("LatestFile")) {
85 // qDebug()<<"Opening latest";
86 open(m_qset
.value("LatestFile").toString());
91 GuiMainWindow::GuiMainWindow(QString file_name
) : QMainWindow(NULL
)
97 void GuiMainWindow::setupGuiMainWindow()
102 // restore window size
103 if(m_qset
.contains("GuiMainWindow")) {
104 setGeometry(m_qset
.value("GuiMainWindow").toRect());
107 this->setWindowState(Qt::WindowMaximized
);
110 // restore dockwidget positions
111 if(m_qset
.contains("dockWidget_states")) {
112 restoreState(m_qset
.value("dockWidget_states").toByteArray());
115 tabifyDockWidget(ui
.dockWidget_output
, ui
.dockWidget_node_cell_info
);
116 tabifyDockWidget(ui
.dockWidget_DisplayOptions
, ui
.dockWidget_DebuggingUtilities
);
117 ui
.dockWidget_node_cell_info
->hide();
118 ui
.dockWidget_DebuggingUtilities
->hide();
121 # include "std_connections.h"
123 if (m_qset
.contains("working_directory")) {
124 m_cwd
= m_qset
.value("working_directory").toString();
129 resetOperationCounter();//clears undo/redo list and disables undo/redo
130 m_CurrentFilename
= "untitled.egc";
131 setWindowTitle(m_CurrentFilename
+ " - enGrid - " + QString("%1").arg(m_CurrentOperation
) );
134 m_StatusInfoLabel
= new QLabel(this);
135 statusBar()->addWidget(m_StatusInfoLabel
);
136 m_StatusInfoLabel
->setText("");
138 m_StatusProgressBar
= new QProgressBar(this);
139 statusBar()->addWidget(m_StatusProgressBar
);
141 m_StatusLabel
= new QLabel(this);
142 statusBar()->addWidget(m_StatusLabel
);
144 QString txt
= "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms), ";
145 txt
+= "0 surface cells (0 triangles, 0 quads), 0 nodes";
146 m_StatusLabel
->setText(txt
);
147 ui
.label_node_cell_info
->setText(txt
);
150 QString user
= QString(getenv("USERNAME"));
152 QString user
= QString(getenv("USER"));
154 QString basename
="enGrid_output.txt";
156 // define temporary path
158 if (m_qset
.contains("tmp_directory")) {
159 m_LogDir
= m_qset
.value("tmp_directory").toString();
161 m_LogDir
= dir
.tempPath();
163 QDateTime now
= QDateTime::currentDateTime();
164 m_LogDir
= m_LogDir
+ "/" + "enGrid_" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz") + "/";
165 dir
.mkpath(m_LogDir
);
167 m_LogFileName
= m_LogDir
+ basename
;
168 cout
<< "m_LogFileName = " << qPrintable(m_LogFileName
) << endl
;
170 #if defined( __linux__ ) //for Linux
171 //Sources for POSIX redirection:
172 // http://c-faq.com/stdio/undofreopen.html
173 // http://stackoverflow.com/questions/4832603/how-could-i-temporary-redirect-stdout-to-a-file-in-a-c-program
176 fgetpos(stdout
, &m_SystemStdout_pos
);
177 m_SystemStdout
= dup(fileno(stdout
)); //backup a duplicate of the stdout
178 if (freopen (qPrintable(m_LogFileName
), "w", stdout
)==NULL
) {
181 m_LogFileStdout
= dup(fileno(stdout
)); //backup a duplicate of the log_out
183 #elif defined( _WIN32 ) //for Windows
184 m_SystemStdout
= stdout
;
185 if (freopen (qPrintable(m_LogFileName
), "w", stdout
)==NULL
) {
188 m_LogFileStdout
= stdout
;
191 #error "Please define the proper way to save the stdout."
196 setPickMode(true,true);
202 connect(&m_GarbageTimer
, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
203 m_GarbageTimer
.start(1000);
205 connect(&m_LogTimer
, SIGNAL(timeout()), this, SLOT(updateOutput()));
206 m_LogTimer
.start(1000);
210 bool exp_features
=false;
211 getSet("General","enable experimental features",false,exp_features
);
212 getSet("General","enable undo+redo",false,m_undo_redo_enabled
);
214 getSet("General","use RAM for undo+redo operations",false,undo_redo_mode
);
215 getSet("General", "open last used file on startup", false, m_open_last
);
217 ui
.actionMirrorMesh
->setEnabled(exp_features
);
218 ui
.actionBooleanOperation
->setEnabled(exp_features
);
219 ui
.actionCreateHexCore
->setEnabled(exp_features
);
220 ui
.actionOptimiseOrthogonalty
->setEnabled(exp_features
);
221 ui
.actionImportFluentCase
->setEnabled(exp_features
);
225 ui
.doubleSpinBox_HueMin
->setValue(0.667);
226 ui
.doubleSpinBox_HueMax
->setValue(0);
228 egvtkInteractorStyle
*style
= egvtkInteractorStyle::New();
229 getInteractor()->SetInteractorStyle(style
);
232 // initialise XML document
233 m_XmlHandler
= new XmlHandler("engridcase");
234 // this->resetXmlDoc();
242 getSet("General", "plugin path", "/usr/lib/engrid", plugin_path
);
243 QDir
plugin_dir(plugin_path
);
244 m_PluginOperations
.clear();
245 foreach (QString file_name
, plugin_dir
.entryList(QDir::Files
)) {
246 if (file_name
.right(3) == ".so") {
247 cout
<< qPrintable(plugin_dir
.absoluteFilePath(file_name
)) << endl
;
248 QPluginLoader
loader(plugin_dir
.absoluteFilePath(file_name
));
249 QObject
*qobject
= loader
.instance();
251 cout
<< "an error occurred while loading the plugins:\n";
252 cout
<< qPrintable(loader
.errorString()) << "\n" << endl
;
254 if (Operation
*operation
= qobject_cast
<Operation
*>(qobject
)) {
255 //operation->setLockGui();
256 QAction
*action
= new QAction(operation
->getMenuText(), this);
257 connect(action
, SIGNAL(triggered()), this, SLOT(pluginCalled()));
258 m_PluginOperations
[action
] = operation
;
259 ui
.menuPlugins
->addAction(action
);
264 m_EscAction
= new QAction("escape", this);
265 addAction(m_EscAction
);
266 m_EscAction
->setShortcut(QKeySequence(Qt::Key_Escape
));
267 connect(m_EscAction
, SIGNAL(triggered()), this, SLOT(onEsc()));
270 //end of GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
272 void GuiMainWindow::pluginCalled()
274 QAction
*action
= qobject_cast
<QAction
*>(QObject::sender());
276 Operation
*operation
= m_PluginOperations
[action
];
277 operation
->operator()();
281 void GuiMainWindow::resetXmlDoc()
283 m_XmlHandler
->resetXmlDoc();
286 GuiMainWindow::~GuiMainWindow()
290 m_qset
.setValue("GuiMainWindow", this->geometry());
291 m_qset
.setValue("dockWidget_states", this->saveState());
294 setSystemOutput(); //close the output to the log file
295 QDirIterator
it(m_LogDir
);
296 while (it
.hasNext()) {
297 QString str
= it
.next();
298 QFileInfo
fileinfo(str
);
299 if(fileinfo
.isFile()) {
302 setLogFileOutput(); //reinstate the connection to the log file
303 qDebug() << "Failed to remove " << file
.fileName();
313 #if defined( __linux__ ) //for Linux
314 ::close(m_SystemStdout
); //close this duplicate
315 ::close(m_LogFileStdout
); //close this duplicate
317 #elif defined( _WIN32 ) //for Windows
318 //Nothing to do so far
320 #error "Please define the proper way to close the saved stdouts."
324 void GuiMainWindow::setupVtk()
327 getSet("Colours", "'A' faces (1-red)", 0.5, m_ColAR
);
328 getSet("Colours", "'A' faces (2-green)", 1.0, m_ColAG
);
329 getSet("Colours", "'A' faces (3-blue)", 0.5, m_ColAB
);
331 getSet("Colours", "'B' faces (1-red)", 1.0, m_ColBR
);
332 getSet("Colours", "'B' faces (2-green)", 1.0, m_ColBG
);
333 getSet("Colours", "'B' faces (3-blue)", 0.5, m_ColBB
);
335 getSet("Colours", " tetras (1-red)", 1.0, m_ColTetraR
);
336 getSet("Colours", " tetras (2-green)", 0.0, m_ColTetraG
);
337 getSet("Colours", " tetras (3-blue)", 0.0, m_ColTetraB
);
339 getSet("Colours", " prisms (1-red)", 0.0, m_ColPrismR
);
340 getSet("Colours", " prisms (2-green)", 1.0, m_ColPrismG
);
341 getSet("Colours", " prisms (3-blue)", 0.0, m_ColPrismB
);
343 getSet("Colours", " pyramids (1-red)", 1.0, m_ColPyraR
);
344 getSet("Colours", " pyramids (2-green)", 1.0, m_ColPyraG
);
345 getSet("Colours", " pyramids (3-blue)", 0.0, m_ColPyraB
);
347 getSet("Colours", " hexes (1-red)", 0.0, m_ColHexR
);
348 getSet("Colours", " hexes (2-green)", 0.7, m_ColHexG
);
349 getSet("Colours", " hexes (3-blue)", 1.0, m_ColHexB
);
351 m_Grid
= vtkUnstructuredGrid::New();
352 m_Renderer
= vtkRenderer::New();
353 getRenderWindow()->AddRenderer(m_Renderer
);
356 m_Axes
= vtkCubeAxesActor2D::New();
358 m_Axes
->SetCamera(getRenderer()->GetActiveCamera());
359 getRenderer()->AddActor(m_Axes
);
360 m_Axes
->SetVisibility(0);
363 m_BackfaceProperty
= vtkProperty::New();
364 m_SurfaceFilter
= vtkGeometryFilter::New();
365 m_SurfaceMapper
= vtkPolyDataMapper::New();
366 m_SurfaceWireMapper
= vtkPolyDataMapper::New();
367 m_BCodesFilter
= vtkEgBoundaryCodesFilter::New();
368 m_LookupTable
= vtkLookupTable::New();
369 m_SurfaceActor
= vtkActor::New();
370 m_SurfaceWireActor
= vtkActor::New();
371 m_LegendActor
= vtkScalarBarActor::New();
373 m_BCodesFilter
->SetBoundaryCodes(m_DisplayBoundaryCodes
);
374 m_BCodesFilter
->SetInput(m_Grid
);
375 m_SurfaceFilter
->SetInput(m_BCodesFilter
->GetOutput());
376 m_SurfaceMapper
->SetInput(m_SurfaceFilter
->GetOutput());
377 m_SurfaceWireMapper
->SetInput(m_SurfaceFilter
->GetOutput());
378 m_SurfaceMapper
->SetLookupTable(m_LookupTable
);
379 m_SurfaceActor
->GetProperty()->SetRepresentationToSurface();
380 m_SurfaceActor
->GetProperty()->SetColor(m_ColAR
, m_ColAG
, m_ColAB
);
381 m_SurfaceActor
->SetBackfaceProperty(m_BackfaceProperty
);
382 m_SurfaceActor
->GetBackfaceProperty()->SetColor(m_ColBR
, m_ColBG
, m_ColBB
);
383 m_SurfaceActor
->SetMapper(m_SurfaceMapper
);
384 getRenderer()->AddActor(m_SurfaceActor
);
385 m_SurfaceActor
->SetVisibility(1);
386 m_LegendActor
->SetLookupTable(m_LookupTable
);
387 getRenderer()->AddActor(m_LegendActor
);
388 m_LegendActor
->SetVisibility(0);
389 m_SurfaceWireActor
->GetProperty()->SetRepresentationToWireframe();
390 m_SurfaceWireActor
->GetProperty()->SetColor(0,0,1);
391 m_SurfaceWireActor
->SetMapper(m_SurfaceWireMapper
);
392 getRenderer()->AddActor(m_SurfaceWireActor
);
393 m_SurfaceWireActor
->SetVisibility(1);
396 m_ExtrTetras
= vtkEgExtractVolumeCells::New();
397 m_TetraActor
= vtkActor::New();
398 m_TetraGeometry
= vtkGeometryFilter::New();
399 m_TetraMapper
= vtkPolyDataMapper::New();
401 m_ExtrTetras
->SetInput(m_Grid
);
402 m_ExtrTetras
->SetAllOff();
403 m_ExtrTetras
->SetTetrasOn();;
404 m_TetraGeometry
->SetInput(m_ExtrTetras
->GetOutput());
405 m_TetraMapper
->SetInput(m_TetraGeometry
->GetOutput());
406 m_TetraActor
->SetMapper(m_TetraMapper
);
407 m_TetraActor
->GetProperty()->SetColor(m_ColTetraR
, m_ColTetraG
, m_ColTetraB
);
408 getRenderer()->AddActor(m_TetraActor
);
409 m_TetraActor
->SetVisibility(0);
412 m_PyramidActor
= vtkActor::New();
413 m_ExtrPyramids
= vtkEgExtractVolumeCells::New();
414 m_PyramidGeometry
= vtkGeometryFilter::New();
415 m_PyramidMapper
= vtkPolyDataMapper::New();
417 m_ExtrPyramids
->SetInput(m_Grid
);
418 m_ExtrPyramids
->SetAllOff();
419 m_ExtrPyramids
->SetPyramidsOn();
420 m_PyramidGeometry
->SetInput(m_ExtrPyramids
->GetOutput());
421 m_PyramidMapper
->SetInput(m_PyramidGeometry
->GetOutput());
422 m_PyramidActor
->SetMapper(m_PyramidMapper
);
423 m_PyramidActor
->GetProperty()->SetColor(m_ColPyraR
, m_ColPyraG
, m_ColPyraB
);
424 getRenderer()->AddActor(m_PyramidActor
);
425 m_PyramidActor
->SetVisibility(0);
428 m_WedgeActor
= vtkActor::New();
429 m_ExtrWedges
= vtkEgExtractVolumeCells::New();
430 m_WedgeGeometry
= vtkGeometryFilter::New();
431 m_WedgeMapper
= vtkPolyDataMapper::New();
433 m_ExtrWedges
->SetInput(m_Grid
);
434 m_ExtrWedges
->SetAllOff();
435 m_ExtrWedges
->SetWedgesOn();
436 m_WedgeGeometry
->SetInput(m_ExtrWedges
->GetOutput());
437 m_WedgeMapper
->SetInput(m_WedgeGeometry
->GetOutput());
438 m_WedgeActor
->SetMapper(m_WedgeMapper
);
439 m_WedgeActor
->GetProperty()->SetColor(m_ColPrismR
, m_ColPrismG
, m_ColPrismB
);
440 getRenderer()->AddActor(m_WedgeActor
);
441 m_WedgeActor
->SetVisibility(0);
444 m_HexaActor
= vtkActor::New();
445 m_ExtrHexes
= vtkEgExtractVolumeCells::New();
446 m_HexaGeometry
= vtkGeometryFilter::New();
447 m_HexaMapper
= vtkPolyDataMapper::New();
449 m_ExtrHexes
->SetInput(m_Grid
);
450 m_ExtrHexes
->SetAllOff();
451 m_ExtrHexes
->SetHexesOn();
452 m_HexaGeometry
->SetInput(m_ExtrHexes
->GetOutput());
453 m_HexaMapper
->SetInput(m_HexaGeometry
->GetOutput());
454 m_HexaActor
->SetMapper(m_HexaMapper
);
455 m_HexaActor
->GetProperty()->SetColor(m_ColHexR
, m_ColHexG
, m_ColHexB
);
456 getRenderer()->AddActor(m_HexaActor
);
457 m_HexaActor
->SetVisibility(0);
459 // polyhedra pipeline
460 m_PolyhedraActor
= vtkActor::New();
461 m_ExtrPolyhedra
= vtkEgExtractVolumeCells::New();
462 m_PolyhedraGeometry
= vtkGeometryFilter::New();
463 m_PolyhedraMapper
= vtkPolyDataMapper::New();
465 m_ExtrPolyhedra
->SetInput(m_Grid
);
466 m_ExtrPolyhedra
->SetAllOff();
467 m_ExtrPolyhedra
->SetPolysOn();
468 m_PolyhedraGeometry
->SetInput(m_ExtrPolyhedra
->GetOutput());
469 m_PolyhedraMapper
->SetInput(m_PolyhedraGeometry
->GetOutput());
470 m_PolyhedraActor
->SetMapper(m_PolyhedraMapper
);
471 m_PolyhedraActor
->GetProperty()->SetColor(1,0.5,0);
472 getRenderer()->AddActor(m_PolyhedraActor
);
473 m_PolyhedraActor
->SetVisibility(0);
475 // volume wire pipeline
476 m_VolumeWireActor
= vtkActor::New();
477 m_ExtrVol
= vtkEgExtractVolumeCells::New();
478 m_VolumeGeometry
= vtkGeometryFilter::New();
479 m_VolumeWireMapper
= vtkPolyDataMapper::New();
481 m_ExtrVol
->SetInput(m_Grid
);
482 m_ExtrVol
->SetAllOn();
483 m_VolumeGeometry
->SetInput(m_ExtrVol
->GetOutput());
484 m_VolumeWireMapper
->SetInput(m_VolumeGeometry
->GetOutput());
485 m_VolumeWireActor
->SetMapper(m_VolumeWireMapper
);
486 m_VolumeWireActor
->GetProperty()->SetRepresentationToWireframe();
487 m_VolumeWireActor
->GetProperty()->SetColor(0,0,1);
488 getRenderer()->AddActor(m_VolumeWireActor
);
489 m_VolumeWireActor
->SetVisibility(0);
492 m_PickSphere
= vtkSphereSource::New();
493 m_PickMapper
= vtkPolyDataMapper::New();
494 m_PickActor
= vtkActor::New();
495 m_CellPicker
= vtkCellPicker::New();
496 m_PointPicker
= vtkPointPicker::New();
498 m_PickSphere
->SetRadius(0.25); //in case the user starts picking points instead of cells
499 m_PickMapper
->SetInput(m_PickSphere
->GetOutput());
500 m_PickActor
->SetMapper(m_PickMapper
);
501 m_PickActor
->GetProperty()->SetRepresentationToSurface();
502 m_PickActor
->GetProperty()->SetColor(0,0,1);
503 m_PickActor
->VisibilityOff();
504 getRenderer()->AddActor(m_PickActor
);
506 vtkCallbackCommand
*cbc
= vtkCallbackCommand::New();
507 cbc
->SetCallback(pickCallBack
);
509 m_CellPicker
->AddObserver(vtkCommand::EndPickEvent
, cbc
);
510 m_PointPicker
->AddObserver(vtkCommand::EndPickEvent
, cbc
);
517 void GuiMainWindow::updateOutput()
519 QFile
log_file(m_LogFileName
);
520 log_file
.open(QIODevice::ReadOnly
);
521 QByteArray buffer
= log_file
.readAll();
522 if (buffer
.size() > m_N_chars
) {
523 QByteArray newchars
= buffer
.right(buffer
.size() - m_N_chars
);
524 m_N_chars
= buffer
.size();
525 QString
txt(newchars
);
526 if (txt
.right(1) == "\n") {
527 txt
= txt
.left(txt
.size()-1);
529 ui
.textEditOutput
->append(txt
);
533 void GuiMainWindow::exit()
535 QCoreApplication::exit();
538 vtkRenderWindow
* GuiMainWindow::getRenderWindow()
540 return ui
.qvtkWidget
->GetRenderWindow();
543 vtkRenderer
* GuiMainWindow::getRenderer()
548 QVTKInteractor
* GuiMainWindow::getInteractor()
550 return ui
.qvtkWidget
->GetInteractor();
553 QString
GuiMainWindow::getCwd()
558 void GuiMainWindow::setCwd(QString dir
)
561 m_qset
.setValue("working_directory",dir
);
564 void GuiMainWindow::setUnsaved(bool unsaved
)
569 void GuiMainWindow::scaleToData()
571 int current_field
=ui
.comboBox_Field
->currentIndex();
576 m_SurfaceFilter
->GetOutput()->GetPointData()->GetArray(current_field
-1)->GetRange(range
);
577 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
578 cout
<<"current_field="<<current_field
<<endl
;
579 cout
<<"range[0]="<<range
[0]<<endl
;
580 cout
<<"range[1]="<<range
[1]<<endl
;
581 ui
.doubleSpinBox_FieldMin
->setRange(range
[0],range
[1]);
582 ui
.doubleSpinBox_FieldMax
->setRange(range
[0],range
[1]);
583 ui
.doubleSpinBox_FieldMin
->setValue(range
[0]);
584 ui
.doubleSpinBox_FieldMax
->setValue(range
[1]);
588 void GuiMainWindow::setClipX(const QString
&txt
)
590 m_ExtrVol
->Setx(txt
.toDouble());
591 m_ExtrTetras
->Setx(txt
.toDouble());
592 m_ExtrPyramids
->Setx(txt
.toDouble());
593 m_ExtrWedges
->Setx(txt
.toDouble());
594 m_ExtrHexes
->Setx(txt
.toDouble());
595 m_ExtrPolyhedra
->Setx(txt
.toDouble());
598 void GuiMainWindow::setClipY(const QString
&txt
)
600 m_ExtrVol
->Sety(txt
.toDouble());
601 m_ExtrTetras
->Sety(txt
.toDouble());
602 m_ExtrPyramids
->Sety(txt
.toDouble());
603 m_ExtrWedges
->Sety(txt
.toDouble());
604 m_ExtrHexes
->Sety(txt
.toDouble());
605 m_ExtrPolyhedra
->Sety(txt
.toDouble());
608 void GuiMainWindow::setClipZ(const QString
&txt
)
610 m_ExtrVol
->Setz(txt
.toDouble());
611 m_ExtrTetras
->Setz(txt
.toDouble());
612 m_ExtrPyramids
->Setz(txt
.toDouble());
613 m_ExtrWedges
->Setz(txt
.toDouble());
614 m_ExtrHexes
->Setz(txt
.toDouble());
615 m_ExtrPolyhedra
->Setz(txt
.toDouble());
618 void GuiMainWindow::setClipNX(const QString
&txt
)
620 m_ExtrVol
->Setnx(txt
.toDouble());
621 m_ExtrTetras
->Setnx(txt
.toDouble());
622 m_ExtrPyramids
->Setnx(txt
.toDouble());
623 m_ExtrWedges
->Setnx(txt
.toDouble());
624 m_ExtrHexes
->Setnx(txt
.toDouble());
625 m_ExtrPolyhedra
->Setnx(txt
.toDouble());
628 void GuiMainWindow::setClipNY(const QString
&txt
)
630 m_ExtrVol
->Setny(txt
.toDouble());
631 m_ExtrTetras
->Setny(txt
.toDouble());
632 m_ExtrPyramids
->Setny(txt
.toDouble());
633 m_ExtrWedges
->Setny(txt
.toDouble());
634 m_ExtrHexes
->Setny(txt
.toDouble());
635 m_ExtrPolyhedra
->Setny(txt
.toDouble());
638 void GuiMainWindow::setClipNZ(const QString
&txt
)
640 m_ExtrVol
->Setnz(txt
.toDouble());
641 m_ExtrTetras
->Setnz(txt
.toDouble());
642 m_ExtrPyramids
->Setnz(txt
.toDouble());
643 m_ExtrWedges
->Setnz(txt
.toDouble());
644 m_ExtrHexes
->Setnz(txt
.toDouble());
645 m_ExtrPolyhedra
->Setnz(txt
.toDouble());
648 void GuiMainWindow::updateSurfaceActors(bool forced
)
650 if (ui
.checkBoxSurface
->isChecked()) {
652 m_SurfaceFilter
->Update();
655 // fill node field combobox
656 int current_field
=ui
.comboBox_Field
->currentIndex();
657 ui
.comboBox_Field
->clear();
658 ui
.comboBox_Field
->addItem("None");
659 for (int i
= 0; i
< m_Grid
->GetPointData()->GetNumberOfArrays(); ++i
) {
660 ui
.comboBox_Field
->addItem(m_Grid
->GetPointData()->GetArrayName(i
));
662 if(current_field
== -1) {
663 ui
.comboBox_Field
->setCurrentIndex(0);
665 ui
.comboBox_Field
->setCurrentIndex(current_field
);
668 // fill cell field combobox
669 int current_cell_field
= ui
.comboBox_CellTextField
->currentIndex();
670 ui
.comboBox_CellTextField
->clear();
671 ui
.comboBox_CellTextField
->addItem("Cell ID");
672 for (int i
= 0; i
< m_SurfaceFilter
->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i
) {
673 ui
.comboBox_CellTextField
->addItem(m_Grid
->GetCellData()->GetArrayName(i
));
675 if(current_cell_field
== -1) {
676 ui
.comboBox_CellTextField
->setCurrentIndex(0);
678 ui
.comboBox_CellTextField
->setCurrentIndex(current_cell_field
);
680 current_field
= ui
.comboBox_Field
->currentIndex();
681 if(current_field
> 0) {
683 m_SurfaceFilter
->GetOutput()->GetPointData()->GetArray(current_field
-1)->GetRange(range
);
684 ui
.doubleSpinBox_FieldMin
->setRange(range
[0],range
[1]);
685 ui
.doubleSpinBox_FieldMax
->setRange(range
[0],range
[1]);
688 if(ui
.comboBox_Field
->currentIndex() > 0) {
689 m_SurfaceMapper
->SetColorModeToMapScalars();
690 m_LookupTable
->SetNumberOfColors(ui
.spinBox_Color
->value());
691 m_LookupTable
->SetHueRange(ui
.doubleSpinBox_HueMin
->value(),ui
.doubleSpinBox_HueMax
->value());
692 m_LookupTable
->Build();
693 m_SurfaceMapper
->SetScalarModeToUsePointFieldData();
694 m_SurfaceMapper
->ColorByArrayComponent(qPrintable(ui
.comboBox_Field
->currentText()),0);
695 m_SurfaceMapper
->SetScalarRange(ui
.doubleSpinBox_FieldMin
->value(),ui
.doubleSpinBox_FieldMax
->value());
696 m_SurfaceMapper
->ScalarVisibilityOn();
697 if(ui
.checkBox_Legend
->checkState()) {
698 m_LegendActor
->SetVisibility(1);
700 m_LegendActor
->SetVisibility(0);
703 m_SurfaceMapper
->SetColorModeToDefault();
704 m_SurfaceMapper
->ScalarVisibilityOff();
705 m_LegendActor
->SetVisibility(0);
708 m_BCodesFilter
->Update();
710 if(ui
.checkBox_ShowPickSphere
->checkState()) {
711 if(m_UseVTKInteractor
) {
712 if(ui
.radioButton_CellPicker
->isChecked()) {
713 getInteractor()->SetPicker(m_CellPicker
);
714 vtkIdType id_cell
= getPickedCell();
717 getInteractor()->SetPicker(m_PointPicker
);
718 vtkIdType id_node
= getPickedPoint();
722 if (ui
.radioButton_CellPicker
->isChecked()) {
723 pickCell(m_PickedCell
);
725 pickPoint(m_PickedPoint
);
729 m_SurfaceActor
->SetVisibility(1);
730 m_SurfaceWireActor
->SetVisibility(1);
732 m_SurfaceActor
->SetVisibility(0);
733 m_SurfaceWireActor
->SetVisibility(0);
737 void GuiMainWindow::updateVolumeActors(bool forced
)
739 if (ui
.checkBoxVolume
->isChecked()) {
740 if (ui
.checkBoxTetra
->isChecked()) {
741 m_ExtrVol
->SetTetrasOn();
742 if (ui
.checkBoxClip
->isChecked()) {
743 m_ExtrTetras
->SetClippingOn();
745 m_ExtrTetras
->SetClippingOff();
748 m_TetraGeometry
->Update();
750 m_TetraActor
->SetVisibility(1);
752 m_ExtrVol
->SetTetrasOff();
753 m_TetraActor
->SetVisibility(0);
755 if (ui
.checkBoxPyramid
->isChecked()) {
756 m_ExtrVol
->SetPyramidsOn();
757 if (ui
.checkBoxClip
->isChecked()) {
758 m_ExtrPyramids
->SetClippingOn();
760 m_ExtrPyramids
->SetClippingOff();
763 m_PyramidGeometry
->Update();
765 m_PyramidActor
->SetVisibility(1);
767 m_ExtrVol
->SetPyramidsOff();
768 m_PyramidActor
->SetVisibility(0);
770 if (ui
.checkBoxWedge
->isChecked()) {
771 m_ExtrVol
->SetWedgesOn();
772 if (ui
.checkBoxClip
->isChecked()) {
773 m_ExtrWedges
->SetClippingOn();
775 m_ExtrWedges
->SetClippingOff();
778 m_WedgeGeometry
->Update();
780 m_WedgeActor
->SetVisibility(1);
782 m_ExtrVol
->SetWedgesOff();
783 m_WedgeActor
->SetVisibility(0);
785 if (ui
.checkBoxHexa
->isChecked()) {
786 m_ExtrVol
->SetHexesOn();
787 if (ui
.checkBoxClip
->isChecked()) {
788 m_ExtrHexes
->SetClippingOn();
790 m_ExtrHexes
->SetClippingOff();
793 m_HexaGeometry
->Update();
795 m_HexaActor
->SetVisibility(1);
797 m_ExtrVol
->SetHexesOff();
798 m_HexaActor
->SetVisibility(0);
800 if (ui
.checkBoxPoly
->isChecked()) {
801 m_ExtrVol
->SetPolysOn();
802 if (ui
.checkBoxClip
->isChecked()) {
803 m_ExtrPolyhedra
->SetClippingOn();
805 m_ExtrPolyhedra
->SetClippingOff();
808 m_PolyhedraGeometry
->Update();
810 m_PolyhedraActor
->SetVisibility(1);
812 m_ExtrVol
->SetPolysOff();
813 m_PolyhedraActor
->SetVisibility(0);
817 if (ui
.checkBoxClip
->isChecked()) {
818 m_ExtrVol
->SetClippingOn();
820 m_ExtrVol
->SetClippingOff();
823 m_VolumeGeometry
->Update();
825 m_VolumeWireActor
->SetVisibility(1);
827 m_TetraActor
->VisibilityOff();
828 m_PyramidActor
->VisibilityOff();
829 m_WedgeActor
->VisibilityOff();
830 m_HexaActor
->VisibilityOff();
831 m_PolyhedraActor
->VisibilityOff();
832 m_VolumeWireActor
->VisibilityOff();
836 void GuiMainWindow::updateActors(bool forced
)
838 // qDebug()<<"QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); called()";
839 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
841 //if (!tryLock()) return;
843 m_Axes
->SetInput(m_Grid
);
844 updateSurfaceActors(forced
);
845 updateVolumeActors(forced
);
847 } catch (Error err
) {
852 // qDebug()<<"QApplication::restoreOverrideCursor(); called()";
853 QApplication::restoreOverrideCursor();
858 void GuiMainWindow::forceUpdateActors()
860 // qDebug()<<"void GuiMainWindow::forceUpdateActors() START";
862 getRenderWindow()->Render();
863 // qDebug()<<"void GuiMainWindow::forceUpdateActors() END";
866 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor
,bool a_CellPickerMode
)
868 m_UseVTKInteractor
=a_UseVTKInteractor
;
869 if (a_UseVTKInteractor
) {
870 ui
.checkBox_UseVTKInteractor
->setCheckState(Qt::Checked
);
872 ui
.checkBox_UseVTKInteractor
->setCheckState(Qt::Unchecked
);
874 if (a_CellPickerMode
) {
875 ui
.radioButton_CellPicker
->toggle();
877 ui
.radioButton_PointPicker
->toggle();
881 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor
)
883 m_UseVTKInteractor
= a_UseVTKInteractor
;
886 bool GuiMainWindow::pickPoint(vtkIdType id_node
)
888 if ((id_node
>= 0) && (id_node
< m_Grid
->GetNumberOfPoints())) {
890 m_Grid
->GetPoints()->GetPoint(id_node
, x
.data());
891 m_PickSphere
->SetCenter(x
.data());
892 m_PickedPoint
= id_node
;
893 m_PickActor
->GetProperty()->SetColor(0,0,1);
894 m_PickActor
->VisibilityOn();
898 m_PickActor
->VisibilityOff();
904 bool GuiMainWindow::pickCell(vtkIdType id_cell
)
906 if ((id_cell
>= 0) && (id_cell
< m_Grid
->GetNumberOfCells())) {
907 vtkIdType
*pts
, Npts
;
908 m_Grid
->GetCellPoints(id_cell
, Npts
, pts
);
910 for (vtkIdType i
= 0; i
< Npts
; ++i
) {
912 m_Grid
->GetPoints()->GetPoint(pts
[i
], xp
.data());
913 x
+= double(1)/Npts
* xp
;
915 m_PickSphere
->SetCenter(x
.data());
917 for (vtkIdType i
= 0; i
< Npts
; ++i
) {
919 m_Grid
->GetPoints()->GetPoint(pts
[i
], xp
.data());
920 R
= min(R
, 0.25*(xp
-x
).abs());
922 m_ReferenceSize
= R
; //Used for text annotations too!
923 m_PickSphere
->SetRadius(R
);
924 m_PickedCell
= id_cell
;
925 m_PickActor
->GetProperty()->SetColor(1,0,0);
926 m_PickActor
->VisibilityOn();
930 m_PickActor
->VisibilityOff();
936 void GuiMainWindow::importSTL()
940 //FIXME: emits an error if no file is imported, so check if there is a valid file
941 updateBoundaryCodes(true);
947 void GuiMainWindow::importGmsh1Ascii()
952 updateBoundaryCodes(true);
958 void GuiMainWindow::exportGmsh1Ascii()
965 void GuiMainWindow::importGmsh2Ascii()
970 updateBoundaryCodes(true);
976 void GuiMainWindow::exportGmsh2Ascii()
983 void GuiMainWindow::exportNeutral()
985 NeutralWriter neutral
;
989 void GuiMainWindow::zoomAll()
991 getRenderer()->ResetCamera();
992 getRenderWindow()->Render();
995 void GuiMainWindow::zoomOnPickedObject()
997 if(m_PickActor
->GetVisibility()) {
998 getRenderer()->ResetCamera(m_PickActor
->GetBounds());
999 getRenderWindow()->Render();
1003 void GuiMainWindow::deselectAll()
1005 cout
<< "void GuiMainWindow::deselectAll()" << endl
;
1006 m_PickActor
->VisibilityOff();
1010 ///\todo Should display a window
1011 void GuiMainWindow::info()
1013 ShowInfo
info(ui
.radioButton_CellPicker
->isChecked(), m_PickedPoint
, m_PickedCell
);
1017 int GuiMainWindow::quickSave()
1019 ///\todo add RAM support
1020 if(m_undo_redo_enabled
) {
1021 if(m_Grid
->GetNumberOfPoints()>0)
1023 m_CurrentOperation
++;
1024 QFileInfo
fileinfo(m_CurrentFilename
);
1025 QString l_filename
= m_LogDir
+ fileinfo
.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation
);
1026 m_LastOperation
=m_CurrentOperation
;
1027 cout
<<"Operation "<<m_CurrentOperation
<<endl
;
1028 saveAs(l_filename
, false);
1029 if(m_CurrentOperation
>0) ui
.actionUndo
->setEnabled(true);
1030 ui
.actionRedo
->setEnabled(false);
1032 else cout
<<"No grid to save!"<<endl
;
1033 return(m_CurrentOperation
);
1038 void GuiMainWindow::quickLoad(int a_operation
)
1040 ///\todo add RAM support
1041 if(m_undo_redo_enabled
) {
1042 QFileInfo
fileinfo(m_CurrentFilename
);
1043 QString l_filename
= m_LogDir
+ fileinfo
.completeBaseName() + "_" + QString("%1").arg(a_operation
) + ".egc";
1044 open(l_filename
, false);
1048 void GuiMainWindow::undo()
1050 if(m_undo_redo_enabled
) {
1051 cout
<< "Undoing operation " << m_CurrentOperation
<< endl
;
1052 m_CurrentOperation
--;
1053 quickLoad(m_CurrentOperation
);
1054 ui
.actionRedo
->setEnabled(true);
1055 if(m_CurrentOperation
<=0) ui
.actionUndo
->setEnabled(false);
1058 resetOperationCounter();
1059 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
1063 void GuiMainWindow::redo()
1065 if(m_undo_redo_enabled
) {
1066 m_CurrentOperation
++;
1067 cout
<< "Redoing operation " << m_CurrentOperation
<< endl
;
1068 quickLoad(m_CurrentOperation
);
1069 ui
.actionUndo
->setEnabled(true);
1070 if(m_CurrentOperation
>=m_LastOperation
) ui
.actionRedo
->setEnabled(false);
1073 resetOperationCounter();
1074 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
1078 void GuiMainWindow::resetOperationCounter()
1080 m_CurrentOperation
=-1;
1081 m_LastOperation
=m_CurrentOperation
;
1082 ui
.actionUndo
->setEnabled(false);
1083 ui
.actionRedo
->setEnabled(false);
1086 QString
GuiMainWindow::getXmlSection(QString name
)
1088 return m_XmlHandler
->getXmlSection(name
);
1091 void GuiMainWindow::setXmlSection(QString name
, QString contents
)
1093 m_XmlHandler
->setXmlSection(name
,contents
);
1096 void GuiMainWindow::openPhysicalBoundaryConditions()
1098 m_PhysicalBoundaryConditionsMap
.clear();
1099 QString buffer
= getXmlSection("engrid/physical");
1100 QTextStream
f(&buffer
, QIODevice::ReadOnly
);
1101 while (!f
.atEnd()) {
1104 f
>> index
>> name
>> type
;
1105 if ((name
!= "") && (type
!= "")) {
1106 PhysicalBoundaryCondition PBC
;
1108 PBC
.setIndex(index
);
1110 for (int i
= 0; i
< PBC
.getNumVars(); ++i
) {
1115 m_PhysicalBoundaryConditionsMap
[name
] = PBC
;
1120 void GuiMainWindow::savePhysicalBoundaryConditions()
1123 QTextStream
f(&buffer
, QIODevice::WriteOnly
);
1125 foreach (PhysicalBoundaryCondition PBC
, m_PhysicalBoundaryConditionsMap
) {
1126 f
<< PBC
.getIndex() << " " << PBC
.getName() << " " << PBC
.getType();
1127 for (int i
= 0; i
< PBC
.getNumVars(); ++i
) {
1128 f
<< " " << PBC
.getVarValue(i
);
1132 setXmlSection("engrid/physical", buffer
);
1135 void GuiMainWindow::openBC()
1139 QString buffer
= getXmlSection("engrid/bc");
1140 QTextStream
f(&buffer
, QIODevice::ReadOnly
);
1141 while (!f
.atEnd()) {
1144 f
>> i
>> name
>> type
;
1145 if(name
!="" && type
!="") {
1147 m_bcmap
[i
] = BoundaryCondition(name
,type
);
1149 VolumeDefinition
V(name
, -i
);
1150 QString text
= type
.replace(",", " ").replace(":", " ");
1151 QTextStream
s(&text
);
1152 while (!s
.atEnd()) {
1153 QString bc_txt
, sign_txt
;
1154 s
>> bc_txt
>> sign_txt
;
1155 V
.addBC(bc_txt
.toInt(), sign_txt
.toInt());
1163 void GuiMainWindow::saveBC()
1166 QTextStream
f(&buffer
, QIODevice::WriteOnly
);
1168 foreach (int i
, m_AllBoundaryCodes
) {
1169 BoundaryCondition bc
= m_bcmap
[i
];
1170 f
<< i
<< " " << bc
.getName() << " " << bc
.getType() << "\n";
1172 foreach (VolumeDefinition V
, m_VolMap
) {
1175 foreach (int i
, m_AllBoundaryCodes
) {
1176 BoundaryCondition bc
= m_bcmap
[i
];
1185 num
.setNum(V
.getSign(i
));
1188 f
<< "-" << V
.getVC() << " " << V
.getName() << " " << dirs
<< "\n";
1190 setXmlSection("engrid/bc", buffer
);
1193 void GuiMainWindow::openGrid(QString file_name
)
1195 file_name
+= ".vtu";
1196 EG_VTKSP(vtkXMLUnstructuredGridReader
,vtu
);
1197 vtu
->SetFileName(qPrintable(file_name
));
1199 m_Grid
->DeepCopy(vtu
->GetOutput());
1200 if (m_Grid
->GetPointData()->GetArray("node_meshdensity_current")) {
1201 m_Grid
->GetPointData()->RemoveArray("node_meshdensity_current");
1203 if (m_Grid
->GetCellData()->GetArray("cell_VA")) {
1204 m_Grid
->GetCellData()->RemoveArray("cell_VA");
1206 createBasicFields(m_Grid
, m_Grid
->GetNumberOfCells(), m_Grid
->GetNumberOfPoints());
1208 openPhysicalBoundaryConditions();
1209 updateBoundaryCodes(true);
1210 createIndices(m_Grid
);
1216 ///\todo I think this should also be a done by a subclass of IOOperation just like for import operations
1217 void GuiMainWindow::open()
1219 QFileDialog
dialog(NULL
, "open grid from file", getCwd(), "enGrid case files (*.egc *.EGC);; legacy grid files(*.vtu *.VTU)");
1220 QFileInfo
file_info(m_CurrentFilename
);
1221 dialog
.selectFile(file_info
.completeBaseName() + ".egc");
1222 if (dialog
.exec()) {
1223 QStringList selected_files
= dialog
.selectedFiles();
1224 QString file_name
= selected_files
[0];
1225 if (!file_name
.isNull()) {
1226 this->open(file_name
);
1231 void GuiMainWindow::open(QString file_name
, bool update_current_filename
)
1233 cout
<< "Opening " << qPrintable(file_name
) << endl
;
1235 //QFileInfo file_info(file_name);
1236 bool no_case_file
= false;
1237 QString file_extension
= getExtension(file_name
);
1238 QString grid_file_name
= file_name
;
1239 if (file_extension
.toLower() == "vtu") {
1240 no_case_file
= true;
1241 grid_file_name
= stripFromExtension(file_name
);
1243 if (!no_case_file
) {
1244 if(!m_XmlHandler
->openXml(file_name
)) {
1245 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name
));
1249 if(update_current_filename
) {
1250 GuiMainWindow::setCwd(QFileInfo(file_name
).absolutePath());
1252 resetSurfaceProjection();
1254 QFile
geo_file(file_name
+ ".geo.vtu");
1255 if (geo_file
.exists()) {
1256 openGrid(file_name
+ ".geo");
1257 storeSurfaceProjection(true);
1260 openGrid(grid_file_name
);
1262 openPhysicalBoundaryConditions();
1263 // update current filename
1264 if(update_current_filename
) m_CurrentFilename
= stripFromExtension(file_name
) + ".egc";
1265 setWindowTitle(m_CurrentFilename
+ " - enGrid - " + QString("%1").arg(m_CurrentOperation
) );
1268 if(update_current_filename
) {
1269 this->addRecentFile(file_name
,QDateTime::currentDateTime());
1270 m_qset
.setValue("LatestFile",file_name
);
1271 resetOperationCounter();
1276 QString
GuiMainWindow::saveAs(QString file_name
, bool update_current_filename
)
1278 QString buffer
= m_XmlHandler
->getBuffer(0);
1279 if(update_current_filename
) {
1280 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
1282 QFileInfo
file_info(file_name
);
1283 if (file_info
.suffix().toLower() != "egc") {
1284 file_name
+= ".egc";
1286 if(update_current_filename
) {
1287 GuiMainWindow::setCwd(file_info
.absolutePath());
1288 m_CurrentFilename
= file_name
;
1290 if(!saveGrid(m_Grid
, file_name
)) {
1291 QMessageBox::critical(this, QObject::tr("Save failed"), QObject::tr("The grid could not be saved as:\n%1").arg(file_name
));
1294 savePhysicalBoundaryConditions();
1295 m_XmlHandler
->saveXml(file_name
);
1296 setWindowTitle(m_CurrentFilename
+ " - enGrid - " + QString("%1").arg(m_CurrentOperation
) );
1298 if(update_current_filename
) {
1299 QApplication::restoreOverrideCursor();
1301 if(update_current_filename
) {
1302 this->addRecentFile(file_name
,QDateTime::currentDateTime());
1303 m_qset
.setValue("LatestFile",file_name
);
1308 void GuiMainWindow::save()
1310 if ( m_CurrentFilename
== "untitled.egc" || m_UnSaved
) {
1312 //FIXME: This is more of a hack than a fix...
1313 if(GuiMainWindow::tryLock()) {
1314 GuiMainWindow::unlock(); //must unlock before continuing.
1318 << "WARNING: Please save the project before running the requested operation "
1319 "or after the current operation is complete."
1323 saveAs(m_CurrentFilename
);
1327 void GuiMainWindow::saveAs()
1329 QApplication::restoreOverrideCursor();
1330 //saveGrid(m_Grid, m_CurrentFilename + ".geo");
1331 bool geo_file_exists
= false;
1332 QString old_geo_file
= m_CurrentFilename
+ ".geo.vtu";
1334 if (QFileInfo(old_geo_file
).exists()) {
1335 geo_file_exists
= true;
1338 QFileDialog
dialog(NULL
, "write case to file", getCwd(), "enGrid case files (*.egc)");
1339 QFileInfo
file_info(m_CurrentFilename
);
1340 dialog
.selectFile(file_info
.completeBaseName() + ".egc");
1341 dialog
.setAcceptMode(QFileDialog::AcceptSave
);
1342 dialog
.setConfirmOverwrite(true);
1343 if (dialog
.exec()) {
1344 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
1345 QStringList selected_files
= dialog
.selectedFiles();
1346 QString file_name
= selected_files
[0];
1347 if (!file_name
.isNull()) {
1348 QString new_geo_file
= file_name
+ ".geo.vtu";
1350 QFile
file(new_geo_file
);
1353 QFile
geo_file(old_geo_file
);
1354 geo_file
.copy(new_geo_file
);
1356 //for the undo/redo operations
1357 resetOperationCounter();
1361 QApplication::restoreOverrideCursor();
1364 void GuiMainWindow::updateStatusBar()
1366 QString num
, txt
= "enGrid is currently busy with an operation ...";
1371 m_StatusLabel
->setText(txt
);
1372 ui
.label_node_cell_info
->setText(txt
);
1375 vtkIdType Ncells
= m_Grid
->GetNumberOfCells();
1376 vtkIdType Nnodes
= m_Grid
->GetNumberOfPoints();
1377 vtkIdType Ntris
= 0;
1378 vtkIdType Nquads
= 0;
1379 vtkIdType Ntets
= 0;
1380 vtkIdType Npyras
= 0;
1381 vtkIdType Nprism
= 0;
1382 vtkIdType Nhexas
= 0;
1383 for (vtkIdType i
= 0; i
< Ncells
; ++i
) {
1384 int ct
= m_Grid
->GetCellType(i
);
1385 if (ct
== VTK_TRIANGLE
) ++Ntris
;
1386 else if (ct
== VTK_QUAD
) ++Nquads
;
1387 else if (ct
== VTK_TETRA
) ++Ntets
;
1388 else if (ct
== VTK_WEDGE
) ++Nprism
;
1389 else if (ct
== VTK_PYRAMID
) ++Npyras
;
1390 else if (ct
== VTK_HEXAHEDRON
) ++Nhexas
;
1392 num
.setNum(Ntets
+ Npyras
+ Nprism
+ Nhexas
); txt
+= num
+ " volume cells(";
1393 num
.setNum(Ntets
); txt
+= num
+ " tetras, ";
1394 num
.setNum(Npyras
); txt
+= num
+ " pyramids, ";
1395 num
.setNum(Nprism
); txt
+= num
+ " prisms, ";
1396 num
.setNum(Nhexas
); txt
+= num
+ " hexas), ";
1397 num
.setNum(Ntris
+ Nquads
); txt
+= num
+ " surface cells(";
1398 num
.setNum(Ntris
); txt
+= num
+ " triangles, ";
1399 num
.setNum(Nquads
); txt
+= num
+ " quads), ";
1400 num
.setNum(Nnodes
); txt
+= num
+ " nodes";
1402 if(ui
.radioButton_CellPicker
->isChecked())
1404 QString pick_txt
= ", picked cell: ";
1405 vtkIdType id_cell
= m_PickedCell
;
1406 if (id_cell
< 0 || id_cell
>=m_Grid
->GetNumberOfCells()) {
1407 pick_txt
+= "no cell picked";
1409 vtkIdType type_cell
= m_Grid
->GetCellType(id_cell
);
1410 if (type_cell
== VTK_TRIANGLE
) pick_txt
+= "tri";
1411 else if (type_cell
== VTK_QUAD
) pick_txt
+= "qua";
1412 else if (type_cell
== VTK_TETRA
) pick_txt
+= "tet";
1413 else if (type_cell
== VTK_PYRAMID
) pick_txt
+= "pyr";
1414 else if (type_cell
== VTK_WEDGE
) pick_txt
+= "pri";
1415 else if (type_cell
== VTK_HEXAHEDRON
) pick_txt
+= "hex";
1416 vtkIdType N_pts
, *pts
;
1417 m_Grid
->GetCellPoints(id_cell
, N_pts
, pts
);
1419 for (int i_pts
= 0; i_pts
< N_pts
; ++i_pts
) {
1421 num
.setNum(pts
[i_pts
]);
1423 if (i_pts
< N_pts
-1) {
1429 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
1430 tmp
.setNum(cell_code
->GetValue(id_cell
));
1431 pick_txt
+= " code=" + tmp
;
1432 tmp
.setNum(id_cell
);
1433 pick_txt
+= " id=" + tmp
;
1439 QString pick_txt
= ", picked node: ";
1440 vtkIdType id_node
= m_PickedPoint
;
1442 pick_txt
+= "no node picked";
1446 m_Grid->GetPoints()->GetPoint(id_node,x.data());
1448 for (int i = 0; i < 3; i++) {
1459 EG_VTKDCN(vtkDoubleArray
, characteristic_length_desired
, m_Grid
, "node_meshdensity_desired");
1460 tmp
.setNum(characteristic_length_desired
->GetValue(id_node
));
1461 pick_txt
+= " wanted density=" + tmp
;
1462 //EG_VTKDCN(vtkDoubleArray, node_meshdensity_current, m_Grid, "node_meshdensity_current");
1463 //tmp.setNum(node_meshdensity_current->GetValue(id_node));
1464 //pick_txt += " current density=" + tmp;
1465 EG_VTKDCN(vtkIntArray
, node_specified_density
, m_Grid
, "node_specified_density");
1466 tmp
.setNum(node_specified_density
->GetValue(id_node
));
1467 pick_txt
+= " node_specified_density=" + tmp
;
1468 EG_VTKDCN(vtkCharArray
, node_type
, m_Grid
, "node_type");
1469 pick_txt
+= " type=" + QString(VertexType2Str( node_type
->GetValue(id_node
)));
1470 tmp
.setNum(id_node
);
1471 pick_txt
+= " id_node=" + tmp
;
1477 m_StatusLabel
->setText(txt
);
1478 ui
.label_node_cell_info
->setText(txt
);
1482 void GuiMainWindow::selectBoundaryCodes()
1484 GuiSelectBoundaryCodes bcodes
;
1485 bcodes
.setDisplayBoundaryCodes(m_DisplayBoundaryCodes
);
1486 bcodes
.setBoundaryCodes(m_AllBoundaryCodes
);
1488 bcodes
.getThread().wait();
1489 bcodes
.getSelectedBoundaryCodes(m_DisplayBoundaryCodes
);
1490 m_BCodesFilter
->SetBoundaryCodes(m_DisplayBoundaryCodes
);
1494 void GuiMainWindow::updateBoundaryCodes(bool all_on
)
1497 m_AllBoundaryCodes
.clear();
1498 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
1499 for (vtkIdType i
= 0; i
< m_Grid
->GetNumberOfCells(); ++i
) {
1500 int ct
= m_Grid
->GetCellType(i
);
1501 if ((ct
== VTK_TRIANGLE
) || (ct
== VTK_QUAD
)) {
1502 m_AllBoundaryCodes
.insert(cell_code
->GetValue(i
));
1506 m_DisplayBoundaryCodes
.clear();
1507 foreach (int bc
, m_AllBoundaryCodes
) {
1508 m_DisplayBoundaryCodes
.insert(bc
);
1512 foreach (int bc
, m_DisplayBoundaryCodes
) {
1513 if (m_AllBoundaryCodes
.contains(bc
)) {
1517 m_DisplayBoundaryCodes
.clear();
1518 foreach (int bc
, m_AllBoundaryCodes
) {
1519 if (dbcs
.contains(bc
)) {
1520 m_DisplayBoundaryCodes
.insert(bc
);
1524 m_BCodesFilter
->SetBoundaryCodes(m_DisplayBoundaryCodes
);
1525 } catch (Error err
) {
1530 void GuiMainWindow::normalExtrusion()
1532 GuiNormalExtrusion extr
;
1534 updateBoundaryCodes(false);
1538 void GuiMainWindow::setAxesVisibility()
1540 if (ui
.actionViewAxes
->isChecked()) {
1541 m_Axes
->VisibilityOn();
1543 m_Axes
->VisibilityOff();
1545 getRenderWindow()->Render();
1548 void GuiMainWindow::setViewingMode()
1550 if (ui
.actionViewOrthogonal
->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1551 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1552 getRenderWindow()->Render();
1555 void GuiMainWindow::viewNodeIDs()
1557 int N
= m_Grid
->GetNumberOfPoints();
1558 cout
<<"N="<<N
<<endl
;
1559 if (ui
.actionViewNodeIDs
->isChecked()) {
1560 cout
<<"Activating node ID view"<<endl
;
1561 m_NodeTextVectorText
.resize(N
);
1562 m_NodeTextPolyDataMapper
.resize(N
);
1563 m_NodeTextFollower
.resize(N
);
1564 for(int i
= 0; i
< N
; ++i
){
1565 m_NodeTextVectorText
[i
]=vtkVectorText::New();
1568 m_NodeTextVectorText
[i
]->SetText(qPrintable(tmp
));
1569 m_NodeTextPolyDataMapper
[i
]=vtkPolyDataMapper::New();
1570 m_NodeTextPolyDataMapper
[i
]->SetInputConnection(m_NodeTextVectorText
[i
]->GetOutputPort());
1571 m_NodeTextFollower
[i
]=vtkFollower::New();
1572 m_NodeTextFollower
[i
]->SetMapper(m_NodeTextPolyDataMapper
[i
]);
1573 m_NodeTextFollower
[i
]->SetScale(m_ReferenceSize
, m_ReferenceSize
, m_ReferenceSize
);
1575 m_Grid
->GetPoint(i
, M
.data());
1577 vec3_t OffSet
= m_ReferenceSize
*tmp_M
.normalise();
1579 m_NodeTextFollower
[i
]->AddPosition(M
[0], M
[1], M
[2]);
1580 m_NodeTextFollower
[i
]->SetCamera(getRenderer()->GetActiveCamera());
1581 m_NodeTextFollower
[i
]->GetProperty()->SetColor(0,0,1);
1582 getRenderer()->AddActor(m_NodeTextFollower
[i
]);
1586 cout
<<"Deactivating node ID view"<<endl
;
1587 for(unsigned int i
= 0; i
< m_NodeTextFollower
.size();i
++){
1588 getRenderer()->RemoveActor(m_NodeTextFollower
[i
]);
1589 m_NodeTextFollower
[i
]->Delete();
1590 m_NodeTextPolyDataMapper
[i
]->Delete();
1591 m_NodeTextVectorText
[i
]->Delete();
1593 m_NodeTextFollower
.clear();
1594 m_NodeTextPolyDataMapper
.clear();
1595 m_NodeTextVectorText
.clear();
1598 getRenderWindow()->Render();
1601 void GuiMainWindow::viewCellIDs()
1603 vtkIdType N
= m_Grid
->GetNumberOfCells();
1604 cout
<<"N="<<N
<<endl
;
1605 if (ui
.actionViewCellIDs
->isChecked()) {
1606 cout
<<"Activating cell ID view"<<endl
;
1607 m_CellTextVectorText
.resize(N
);
1608 m_CellTextPolyDataMapper
.resize(N
);
1609 m_CellTextFollower
.resize(N
);
1610 for (vtkIdType id_cell
= 0; id_cell
< N
; ++id_cell
){
1611 m_CellTextVectorText
[id_cell
] = vtkVectorText::New();
1615 if(ui
.comboBox_CellTextField
->currentIndex()==0) {
1616 tmp
.setNum(id_cell
);
1617 } else if (ui
.comboBox_CellTextField
->currentIndex()>0) {
1618 EG_VTKDCC(vtkIntArray
, current_cell_field
, m_Grid
, qPrintable(ui
.comboBox_CellTextField
->currentText()));
1619 tmp
.setNum(current_cell_field
->GetValue(id_cell
));
1623 m_CellTextVectorText
[id_cell
]->SetText(qPrintable(tmp
));
1624 m_CellTextPolyDataMapper
[id_cell
]=vtkPolyDataMapper::New();
1625 m_CellTextPolyDataMapper
[id_cell
]->SetInputConnection(m_CellTextVectorText
[id_cell
]->GetOutputPort());
1626 m_CellTextFollower
[id_cell
]=vtkFollower::New();
1627 m_CellTextFollower
[id_cell
]->SetMapper(m_CellTextPolyDataMapper
[id_cell
]);
1628 m_CellTextFollower
[id_cell
]->SetScale(m_ReferenceSize
, m_ReferenceSize
, m_ReferenceSize
);
1629 vtkIdType N_pts
,*pts
;
1630 m_Grid
->GetCellPoints(id_cell
,N_pts
,pts
);
1631 vec3_t
Center(0,0,0);
1632 for (int p
= 0; p
< N_pts
; ++p
) {
1634 m_Grid
->GetPoint(pts
[p
],M
.data());
1637 vec3_t OffSet
= m_ReferenceSize
*triNormal(m_Grid
, pts
[0], pts
[1], pts
[2]).normalise();
1638 Center
= 1.0/(double)N_pts
*Center
+OffSet
;
1639 m_CellTextFollower
[id_cell
]->AddPosition(Center
[0], Center
[1], Center
[2]);
1640 m_CellTextFollower
[id_cell
]->SetCamera(getRenderer()->GetActiveCamera());
1641 m_CellTextFollower
[id_cell
]->GetProperty()->SetColor(1, 0, 0);
1642 getRenderer()->AddActor(m_CellTextFollower
[id_cell
]);
1645 cout
<<"Deactivating cell ID view"<<endl
;
1646 for (vtkIdType id_cell
= 0; id_cell
< (vtkIdType
) m_CellTextFollower
.size(); ++id_cell
) {
1647 getRenderer()->RemoveActor(m_CellTextFollower
[id_cell
]);
1648 m_CellTextFollower
[id_cell
]->Delete();
1649 m_CellTextPolyDataMapper
[id_cell
]->Delete();
1650 m_CellTextVectorText
[id_cell
]->Delete();
1652 m_CellTextFollower
.clear();
1653 m_CellTextPolyDataMapper
.clear();
1654 m_CellTextVectorText
.clear();
1657 getRenderWindow()->Render();
1660 void GuiMainWindow::pickCallBack
1663 unsigned long int eid
,
1670 clientdata
= clientdata
;
1671 calldata
= calldata
;
1672 THIS
->updateActors();
1673 THIS
->updateStatusBar();
1676 vtkIdType
GuiMainWindow::getPickedCell()
1678 if(!ui
.radioButton_CellPicker
->isChecked()) return(-1);
1680 vtkIdType picked_cell
= -1;
1681 if (m_Grid
->GetNumberOfCells() > 0) {
1682 m_BCodesFilter
->Update();
1683 if (m_BCodesFilter
->GetOutput()->GetNumberOfCells() > 0) {
1684 EG_VTKDCC(vtkLongArray_t
, cell_index
, m_BCodesFilter
->GetOutput(), "cell_index");
1685 if (m_UseVTKInteractor
) {
1686 picked_cell
= cell_index
->GetValue(m_CellPicker
->GetCellId());
1688 picked_cell
= m_PickedCell
;
1695 vtkIdType
GuiMainWindow::getPickedPoint()
1697 if(ui
.radioButton_CellPicker
->isChecked()) return(-1);
1699 vtkIdType picked_point
= -1;
1700 if (m_Grid
->GetNumberOfCells() > 0) {
1701 m_BCodesFilter
->Update();
1702 if (m_BCodesFilter
->GetOutput()->GetNumberOfCells() > 0) {
1703 EG_VTKDCN(vtkLongArray_t
, node_index
, m_BCodesFilter
->GetOutput(), "node_index");
1704 if (m_UseVTKInteractor
) {
1705 picked_point
= node_index
->GetValue(m_PointPicker
->GetPointId());
1707 picked_point
= m_PickedPoint
;
1711 return picked_point
;
1714 void GuiMainWindow::changeSurfaceOrientation()
1716 for (vtkIdType cellId
= 0; cellId
< m_Grid
->GetNumberOfCells(); ++cellId
) {
1717 vtkIdType Npts
, *pts
;
1718 m_Grid
->GetCellPoints(cellId
, Npts
, pts
);
1719 QVector
<vtkIdType
> nodes(Npts
);
1720 for (vtkIdType j
= 0; j
< Npts
; ++j
) nodes
[j
] = pts
[j
];
1721 for (vtkIdType j
= 0; j
< Npts
; ++j
) pts
[Npts
- j
- 1] = nodes
[j
];
1724 m_Grid
->Modified();// to make sure VTK notices the changes and changes the cell colors
1725 //m_Renderer->GetRenderWindow()->Render();
1728 void GuiMainWindow::checkSurfaceOrientation()
1730 CorrectSurfaceOrientation corr_surf
;
1731 vtkIdType picked_cell
= getPickedCell();
1732 if (picked_cell
>= 0) {
1733 corr_surf
.setStart(picked_cell
);
1737 m_Grid
->Modified();// to make sure VTK notices the changes and changes the cell colors
1738 //m_Renderer->GetRenderWindow()->Render();
1741 void GuiMainWindow::improveAspectRatio()
1743 GuiImproveAspectRatio impr_ar
;
1748 void GuiMainWindow::exportAsciiStl()
1751 stl
.setFileTypeToASCII();
1755 void GuiMainWindow::exportBinaryStl()
1758 stl
.setFileTypeToBinary();
1762 void GuiMainWindow::exportAsciiPly()
1765 ply
.setFileTypeToASCII();
1769 void GuiMainWindow::exportBinaryPly()
1772 ply
.setFileTypeToBinary();
1776 void GuiMainWindow::periodicUpdate()
1778 Operation::collectGarbage();
1782 void GuiMainWindow::viewRight()
1785 getSet("General","use Blender definition for front, top, etc.", true, use_blender
);
1786 getRenderer()->ResetCamera();
1788 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1791 getRenderer()->GetActiveCamera()->SetPosition(x
);
1792 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1793 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1796 getRenderer()->GetActiveCamera()->SetPosition(x
);
1797 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1798 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1800 getRenderer()->ResetCamera();
1801 getRenderWindow()->Render();
1804 void GuiMainWindow::viewLeft()
1807 getSet("General","use Blender definition for front, top, etc.", true, use_blender
);
1808 getRenderer()->ResetCamera();
1810 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1813 getRenderer()->GetActiveCamera()->SetPosition(x
);
1814 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1815 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1818 getRenderer()->GetActiveCamera()->SetPosition(x
);
1819 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1820 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1822 getRenderer()->ResetCamera();
1823 getRenderWindow()->Render();
1826 void GuiMainWindow::viewTop()
1829 getSet("General","use Blender definition for front, top, etc.", true, use_blender
);
1830 getRenderer()->ResetCamera();
1832 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1835 getRenderer()->GetActiveCamera()->SetPosition(x
);
1836 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1837 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1840 getRenderer()->GetActiveCamera()->SetPosition(x
);
1841 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1842 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1844 getRenderer()->ResetCamera();
1845 getRenderWindow()->Render();
1848 void GuiMainWindow::viewBottom()
1851 getSet("General","use Blender definition for front, top, etc.", true, use_blender
);
1852 getRenderer()->ResetCamera();
1854 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1857 getRenderer()->GetActiveCamera()->SetPosition(x
);
1858 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1859 getRenderer()->GetActiveCamera()->SetViewUp(0,-1,0);
1862 getRenderer()->GetActiveCamera()->SetPosition(x
);
1863 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1864 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1866 getRenderer()->ResetCamera();
1867 getRenderWindow()->Render();
1870 void GuiMainWindow::viewFront()
1873 getSet("General","use Blender definition for front, top, etc.", true, use_blender
);
1874 getRenderer()->ResetCamera();
1876 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1879 getRenderer()->GetActiveCamera()->SetPosition(x
);
1880 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1881 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1884 getRenderer()->GetActiveCamera()->SetPosition(x
);
1885 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1886 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1888 getRenderer()->ResetCamera();
1889 getRenderWindow()->Render();
1892 void GuiMainWindow::viewBack()
1895 getSet("General","use Blender definition for front, top, etc.", true, use_blender
);
1896 getRenderer()->ResetCamera();
1898 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1901 getRenderer()->GetActiveCamera()->SetPosition(x
);
1902 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1903 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1906 getRenderer()->GetActiveCamera()->SetPosition(x
);
1907 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1908 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1910 getRenderer()->ResetCamera();
1911 getRenderWindow()->Render();
1914 void GuiMainWindow::callFixSTL()
1920 updateBoundaryCodes(false);
1924 void GuiMainWindow::callDeletePickedPoint()
1926 EG_STDINTERSLOT( DeletePickedPoint
);
1929 void GuiMainWindow::editBoundaryConditions()
1931 GuiEditBoundaryConditions editbcs
;
1932 editbcs
.setBoundaryCodes(m_AllBoundaryCodes
);
1933 editbcs
.setMap(&m_bcmap
);
1937 void GuiMainWindow::configure()
1940 // Just to create initial entries in the settings file
1941 // so that the options menu isn't empty at first start.
1944 GuiCreateBoundaryLayer tmp02
;
1945 SurfaceProjection tmp03
;
1946 SurfaceMesher tmp04
;
1947 UpdateDesiredMeshDensity tmp05
;
1950 LaplaceSmoother tmp08
;
1951 SwapTriangles tmp09
;
1952 OpenFOAMTools tmp10
;
1953 BlenderReader tmp11
;
1954 } catch (Error err
) {
1958 GuiSettingsViewer
settings(&m_qset
);
1959 settings
.CreateViewer();
1962 getSet("General","enable undo+redo",false,m_undo_redo_enabled
);
1965 void GuiMainWindow::about()
1967 //Load the HTML code snippet with the list of contributions
1969 fileinfo
.setFile(":/contributions.htm");
1970 QFile
file(fileinfo
.filePath());
1971 if (!file
.exists()) {
1972 qDebug() << "ERROR: " << fileinfo
.filePath() << " not found.";
1975 if (!file
.open(QIODevice::ReadOnly
| QIODevice::Text
)) {
1976 qDebug() << "ERROR: Failed to open file " << fileinfo
.filePath();
1979 QTextStream
text_stream(&file
);
1980 QString contributionsIncluded
= text_stream
.readAll();
1985 QMessageBox
box(this);
1987 QString title
="ENGRID";
1988 QString version
= ENGRID_VERSION
;
1989 version
+= " built on ";
1990 version
+= QString(__DATE__
);
1992 version
+= QString(__TIME__
);
1994 QString address
= tr("ENGRID is being developed and maintained by:<br/>"
1997 "79674 Todtnau<br/>"
2000 QString mainurl
="<a href=\"http://engits.eu/\">http://engits.eu</a>";
2001 QString mail
="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
2002 QString gnuurl
="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
2003 QString license
=tr("ENGRID is licenced under the GPL version 3.<br/>"
2004 "(see ")+gnuurl
+tr(" for details)<br/>");
2005 QString contributions
=tr("Contributions:");
2007 box
.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
2011 "<p>Homepage: %4</p>"
2013 "<p>%6</p></center>"
2014 "<p>%7</p><blockquote>%8</blockquote>")
2015 .arg(title
).arg(version
).arg(address
).arg(mainurl
).arg(mail
).arg(license
)
2016 .arg(contributions
).arg(contributionsIncluded
));
2017 box
.setWindowTitle(tr("about ENGRID"));
2018 box
.setIcon(QMessageBox::NoIcon
);
2023 ///\todo Why not use bcs = m_AllBoundaryCodes; ?
2024 void GuiMainWindow::getAllBoundaryCodes(QVector
<int> &bcs
)
2027 bcs
.resize(m_AllBoundaryCodes
.size());
2028 qCopy(m_AllBoundaryCodes
.begin(), m_AllBoundaryCodes
.end(), bcs
.begin());
2032 QSet
<int> GuiMainWindow::getAllBoundaryCodes()
2034 return m_AllBoundaryCodes
;
2037 void GuiMainWindow::getDisplayBoundaryCodes(QSet
<int> &bcs
)
2040 foreach (int bc
, m_DisplayBoundaryCodes
) {
2045 QList
<VolumeDefinition
> GuiMainWindow::getAllVols()
2047 QList
<VolumeDefinition
> vols
;
2048 foreach(VolumeDefinition vol
, m_VolMap
) {
2049 vols
.push_back(vol
);
2054 void GuiMainWindow::setAllVols(QList
<VolumeDefinition
> vols
)
2057 foreach (VolumeDefinition V
, vols
) {
2058 m_VolMap
[V
.getName()] = V
;
2062 QList
<PhysicalBoundaryCondition
> GuiMainWindow::getAllPhysicalBoundaryConditions()
2064 QList
<PhysicalBoundaryCondition
> physical_boundary_conditions
;
2065 foreach(PhysicalBoundaryCondition PBC
, m_PhysicalBoundaryConditionsMap
) {
2066 physical_boundary_conditions
.push_back(PBC
);
2068 return physical_boundary_conditions
;
2071 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList
<PhysicalBoundaryCondition
> physical_boundary_conditions
)
2073 m_PhysicalBoundaryConditionsMap
.clear();
2074 foreach (PhysicalBoundaryCondition PBC
, physical_boundary_conditions
) {
2075 m_PhysicalBoundaryConditionsMap
[PBC
.getName()] = PBC
;
2079 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap
<QString
,PhysicalBoundaryCondition
> physical_boundary_conditions
) {
2080 m_PhysicalBoundaryConditionsMap
= physical_boundary_conditions
;
2083 void GuiMainWindow::createDefaultVol()
2085 QList
<VolumeDefinition
> vols
= getAllVols();
2086 if (vols
.size() == 0) {
2087 VolumeDefinition
V("default", 1);
2089 getAllBoundaryCodes(bcs
);
2090 foreach (int bc
, bcs
) {
2098 QString
GuiMainWindow::getFilePath()
2100 QFileInfo
fileinfo(m_CurrentFilename
);
2101 return fileinfo
.absolutePath()+"/";
2104 void GuiMainWindow::markOutputLine()
2106 cout
<< "\n****************************************\n";
2107 cout
<< qPrintable(QTime::currentTime().toString("hh:mm:ss"));
2108 cout
<< "\n****************************************\n" << endl
;
2111 void GuiMainWindow::storeSurfaceProjection(bool nosave
)
2114 resetSurfaceProjection();
2115 foreach (int bc
, m_AllBoundaryCodes
) {
2116 SurfaceProjection
*proj
= new SurfaceProjection();
2117 m_SurfProj
[bc
] = proj
;
2120 QVector
<vtkIdType
> cls
;
2121 getSurfaceCells(bcs
, cls
, m_Grid
);
2122 proj
->setBackgroundGrid(m_Grid
, cls
);
2126 saveGrid(m_Grid
, m_CurrentFilename
+ ".geo");
2133 void GuiMainWindow::resetSurfaceProjection()
2135 foreach (SurfaceProjection
* proj
, m_SurfProj
) {
2140 EG_VTKDCN(vtkLongArray_t
, pindex
, m_Grid
, "node_pindex");
2141 for (vtkIdType id_node
= 0; id_node
< m_Grid
->GetNumberOfPoints(); ++id_node
) {
2142 pindex
->SetValue(id_node
, -1);
2144 SurfaceProjection::resetPindex();
2149 SurfaceProjection
* GuiMainWindow::getSurfProj(int bc
)
2153 if (!m_SurfProj
.contains(bc
)) {
2156 if (!m_SurfProj
.contains(bc
)) {
2157 EG_ERR_RETURN("No surface projection found for boundary code " + bc_txt
);
2159 return m_SurfProj
[bc
];
2162 bool GuiMainWindow::checkSurfProj()
2165 foreach (int bc
, m_AllBoundaryCodes
) {
2166 if (!m_SurfProj
.contains(bc
)) {
2174 void GuiMainWindow::setSystemOutput()
2176 #if defined( __linux__ ) //for Linux
2178 if(m_SystemStdout
!= fileno(stdout
))
2181 fgetpos(stdout
, &m_LogFileStdout_pos
); //store current position
2182 dup2(m_SystemStdout
, fileno(stdout
)); //reassign the original stdout to stdout
2184 fsetpos(stdout
, &m_SystemStdout_pos
); /* for C9X */
2187 #elif defined( _WIN32 ) //for Windows
2189 freopen("CON","a",m_SystemStdout
);
2192 #error "Please define the proper way to recover the stdout."
2196 void GuiMainWindow::setLogFileOutput()
2198 #if defined( __linux__ ) //for Linux
2200 if(m_SystemStdout
!= fileno(stdout
))
2203 fgetpos(stdout
, &m_SystemStdout_pos
); //store current position
2204 dup2(m_LogFileStdout
, fileno(stdout
)); //reassign the log_out to stdout
2206 fsetpos(stdout
, &m_LogFileStdout_pos
); /* for C9X */
2209 #elif defined( _WIN32 ) //for Windows
2211 freopen(qPrintable(m_LogFileName
),"a",m_LogFileStdout
);
2214 #error "Please define the proper way to recover the stdout."
2219 void GuiMainWindow::openRecent(QAction
*action
)
2221 qDebug()<<"GuiMainWindow::openRecent called";
2222 QString file_name
= action
->text().right(action
->text().length()-23);
2223 this->open(file_name
);
2226 void GuiMainWindow::readRecentFiles()
2228 m_RecentFiles
.clear();
2229 this->recentFileMenu()->clear();
2230 QStringList file_names
= m_qset
.value("FileNames").toStringList();
2231 QStringList file_dates
= m_qset
.value("FileDates").toStringList();
2232 int N
= min(10,m_qset
.value("NumberOfFiles").toInt());
2233 // cout << "NumberOfFiles=" << N << endl;
2234 for (int i
= 0; i
< N
; ++i
) {
2235 QString new_file
= file_names
.at(i
);
2236 QString date_text
= file_dates
.at(i
);
2237 QDateTime date
= QDateTime::fromString(date_text
,"dd.MM.yyyy_hh:mm:ss");
2238 addRecentFile(new_file
,date
);
2242 void GuiMainWindow::writeRecentFiles()
2244 m_qset
.setValue("NumberOfFiles",m_RecentFiles
.size());
2245 QStringList file_names
;
2246 QStringList file_dates
;
2247 for (QMap
<QString
,QDateTime
>::iterator i
= m_RecentFiles
.begin(); i
!= m_RecentFiles
.end(); ++i
) {
2248 QString file_name
= i
.key();
2249 QString date_text
= i
.value().toString("dd.MM.yyyy_hh:mm:ss");
2250 file_names
.append(file_name
);
2251 file_dates
.append(date_text
);
2253 m_qset
.setValue("FileNames",file_names
);
2254 m_qset
.setValue("FileDates",file_dates
);
2257 void GuiMainWindow::addRecentFile(QString file_name
, QDateTime date
)
2259 m_RecentFiles
[file_name
] = date
;
2260 while (m_RecentFiles
.size() > 10) {
2261 QMap
<QString
,QDateTime
>::iterator i
,j
;
2262 QDateTime old
= QDateTime::currentDateTime();
2263 for (i
= m_RecentFiles
.begin(); i
!= m_RecentFiles
.end(); ++i
) {
2264 if (i
.value() <= old
) {
2269 m_RecentFiles
.erase(j
);
2271 this->recentFileMenu()->clear();
2272 QMap
<int,QString
> menu_map
;
2273 QDateTime now
= QDateTime::currentDateTime();
2274 for (QMap
<QString
,QDateTime
>::iterator i
= m_RecentFiles
.begin(); i
!= m_RecentFiles
.end(); ++i
) {
2275 QString action_text
= i
.value().toString("dd.MM.yyyy hh:mm:ss");
2276 action_text
+= " -> ";
2277 action_text
+= i
.key();
2278 menu_map
[i
.value().secsTo(now
)] = action_text
;
2281 for (QMap
<int,QString
>::iterator i
= menu_map
.begin(); i
!= menu_map
.end(); ++i
) {
2282 QAction
*action
= new QAction(i
.value(),this);
2283 this->recentFileMenu()->addAction(action
);
2288 void GuiMainWindow::callInsertNewCell()
2290 bool ok1
,ok2
,ok3
,ok4
;
2292 #if QT_VERSION < 0x040500
2293 pts
[0] = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok1
);
2294 pts
[1] = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok2
);
2295 pts
[2] = QInputDialog::getInteger(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok3
);
2296 vtkIdType id_cell
= QInputDialog::getInteger(this, tr("copy cell data from id_cell"),tr("copy cell data from id_cell:"), 0, 0, m_Grid
->GetNumberOfCells(), 1, &ok4
);
2298 pts
[0] = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok1
);
2299 pts
[1] = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok2
);
2300 pts
[2] = QInputDialog::getInt(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok3
);
2301 vtkIdType id_cell
= QInputDialog::getInt(this, tr("copy cell data from id_cell"),tr("copy cell data from id_cell:"), 0, 0, m_Grid
->GetNumberOfCells(), 1, &ok4
);
2303 if (ok1
&& ok2
&& ok3
&& ok4
) {
2304 EG_VTKSP( vtkUnstructuredGrid
, new_grid
);
2305 allocateGrid( new_grid
, m_Grid
->GetNumberOfCells() + 1, m_Grid
->GetNumberOfPoints() );
2306 makeCopyNoAlloc(m_Grid
, new_grid
);
2307 vtkIdType id_new_cell
= new_grid
->InsertNextCell(VTK_TRIANGLE
, 3, pts
);
2308 copyCellData(m_Grid
, id_cell
, new_grid
, id_new_cell
);
2309 makeCopy(new_grid
, m_Grid
);
2311 QMessageBox::information(NULL
, "new cell", tr("The new cell has ID = %1").arg(id_new_cell
));
2312 qDebug()<<tr("The new cell has ID = %1").arg(id_new_cell
);
2316 void GuiMainWindow::callMergeNodes()
2319 #if QT_VERSION < 0x040500
2320 vtkIdType id_node1
= QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok1
);
2321 vtkIdType id_node2
= QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok2
);
2323 vtkIdType id_node1
= QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok1
);
2324 vtkIdType id_node2
= QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid
->GetNumberOfPoints(), 1, &ok2
);
2327 EG_VTKSP( vtkUnstructuredGrid
, new_grid
);
2328 allocateGrid( new_grid
, m_Grid
->GetNumberOfCells(), m_Grid
->GetNumberOfPoints() - 1 );
2330 QVector
<vtkIdType
> old2new_nodes(m_Grid
->GetNumberOfPoints(), -1);
2331 QVector
<vtkIdType
> old2new_cells(m_Grid
->GetNumberOfCells(), -1);
2333 vtkIdType id_new_node
= 0;
2334 for (vtkIdType id_node
= 0; id_node
< m_Grid
->GetNumberOfPoints(); ++id_node
) {
2335 if(id_node
!=id_node1
&& id_node
!=id_node2
) {
2337 m_Grid
->GetPoints()->GetPoint(id_node
, x
.data());
2338 new_grid
->GetPoints()->SetPoint(id_new_node
, x
.data());
2339 copyNodeData(m_Grid
, id_node
, new_grid
, id_new_node
);
2340 old2new_nodes
[id_node
] = id_new_node
;
2343 else if(id_node
==id_node1
) {
2345 m_Grid
->GetPoints()->GetPoint(id_node1
, x1
.data());
2347 m_Grid
->GetPoints()->GetPoint(id_node2
, x2
.data());
2348 vec3_t x
= 0.5*(x1
+x2
);
2349 new_grid
->GetPoints()->SetPoint(id_new_node
, x
.data());
2350 copyNodeData(m_Grid
, id_node
, new_grid
, id_new_node
);
2351 old2new_nodes
[id_node1
] = id_new_node
;
2352 old2new_nodes
[id_node2
] = id_new_node
;
2359 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
2360 vtkIdType N_pts
, *pts
;
2361 vtkIdType type_cell
= m_Grid
->GetCellType(id_cell
);
2362 m_Grid
->GetCellPoints(id_cell
, N_pts
, pts
);
2363 QVector
<vtkIdType
> new_pts(N_pts
);
2364 for (int i
= 0; i
< N_pts
; ++i
) {
2365 new_pts
[i
] = old2new_nodes
[pts
[i
]];
2367 vtkIdType id_new_cell
= new_grid
->InsertNextCell(type_cell
, N_pts
, new_pts
.data());
2368 copyCellData(m_Grid
, id_cell
, new_grid
, id_new_cell
);
2371 makeCopy(new_grid
, m_Grid
);
2373 qDebug()<<"The fusion is complete.";
2378 void GuiMainWindow::onEsc()
2380 setPickMode(true, true);
2382 m_CellPicker
->Pick(-1e99
,-1e99
,0,m_Renderer
);
2387 void GuiMainWindow::resetProgress(QString info_text
, int p_max
)
2389 m_StatusInfoLabel
->setText(info_text
);
2390 m_StatusProgressBar
->setMaximum(p_max
);
2391 m_StatusProgressBar
->setValue(0);
2392 QApplication::processEvents();
2395 void GuiMainWindow::setProgress(int p
)
2397 m_StatusProgressBar
->setValue(p
);
2398 for (int i
= 0; i
< 3; ++i
) {
2399 QApplication::processEvents();