limited volume meshing to boundary layer only
[engrid-github.git] / src / libengrid / guimainwindow.cpp
blob9553f66cbef27f302897b8439fdc575b58051835
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
11 // + +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
16 // + +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "guimainwindow.h"
22 #include "engrid.h"
23 #include "guiselectboundarycodes.h"
24 #include "guiimproveaspectratio.h"
25 #include "guinormalextrusion.h"
26 #include "guisetboundarycode.h"
27 #include "guipick.h"
29 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
30 #include "stlreader.h"
31 #include "gmshreader.h"
32 #include "gmshwriter.h"
33 #include "neutralwriter.h"
34 #include "stlwriter.h"
35 #include "plywriter.h"
36 #include "correctsurfaceorientation.h"
37 #include "guieditboundaryconditions.h"
38 #include "laplacesmoother.h"
39 #include "swaptriangles.h"
40 #include "triangularcadinterface.h"
41 #include "cgaltricadinterface.h"
43 #include <qmessagebox.h>
44 #include <vtkRenderer.h>
45 #include <vtkRenderWindow.h>
46 #include <vtkXMLUnstructuredGridWriter.h>
47 #include <vtkXMLUnstructuredGridReader.h>
48 #include <vtkProperty.h>
49 #include <vtkCallbackCommand.h>
50 #include <vtkCamera.h>
51 #include <vtkSignedCharArray.h>
52 #include <vtkTextActor.h>
53 #include <vtkVectorText.h>
54 #include <vtkFollower.h>
55 #include <vtkLookupTable.h>
56 #include <vtkScalarBarActor.h>
57 #include <vtkFileOutputWindow.h>
58 #include <QVTKInteractor.h>
60 #include <QFileDialog>
61 #include <QFileSystemWatcher>
62 #include <QFileInfo>
63 #include <QAction>
64 #include <QStatusBar>
65 #include <QInputDialog>
67 #include <stdlib.h>
68 #include <stdio.h>
70 #if !defined( _WIN32 ) //required for "dup" and "dup2" on POSIX systems
71 #include <unistd.h>
72 #endif
74 #include "geometrytools.h"
75 #include "engrid_version.h"
77 using namespace GeometryTools;
79 #include "guisettingsviewer.h"
80 #include "guitransform.h"
81 #include "egvtkinteractorstyle.h"
82 #include "showinfo.h"
83 #include "engrid_version.h"
85 #include <csignal>
87 QString GuiMainWindow::m_cwd = ".";
88 QSettings GuiMainWindow::m_qset("enGits", QString("enGrid-") + ENGRID_VERSION_STRING);
89 GuiMainWindow* GuiMainWindow::THIS = NULL;
90 QMutex GuiMainWindow::m_Mutex;
91 bool GuiMainWindow::m_UnSaved = true;
93 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
95 setupGuiMainWindow();
96 if(m_open_last) {
97 if(m_qset.contains("LatestFile")) {
98 // qDebug()<<"Opening latest";
99 open(m_qset.value("LatestFile").toString());
104 GuiMainWindow::GuiMainWindow(QString file_name) : QMainWindow(NULL)
106 setupGuiMainWindow();
107 open(file_name);
110 void GuiMainWindow::setupGuiMainWindow()
112 //QMenuBar *menubar = new QMenuBar(0);
113 ui.setupUi(this);
114 #ifdef __APPLE__
115 QMenuBar *menubar = ui.menubar;
116 menubar->setNativeMenuBar(true);
117 #endif
118 THIS = this;
120 // restore window size
121 if(m_qset.contains("GuiMainWindow")) {
122 setGeometry(m_qset.value("GuiMainWindow").toRect());
124 else {
125 this->setWindowState(Qt::WindowMaximized);
128 // restore dockwidget positions
129 if(m_qset.contains("dockWidget_states")) {
130 restoreState(m_qset.value("dockWidget_states").toByteArray());
132 else {
133 tabifyDockWidget(ui.dockWidget_output, ui.dockWidget_node_cell_info);
134 tabifyDockWidget(ui.dockWidget_DisplayOptions, ui.dockWidget_DebuggingUtilities);
135 ui.dockWidget_node_cell_info->hide();
136 ui.dockWidget_DebuggingUtilities->hide();
139 # include "std_connections.h"
141 if (m_qset.contains("working_directory")) {
142 m_cwd = m_qset.value("working_directory").toString();
145 setupVtk();
147 resetOperationCounter();//clears undo/redo list and disables undo/redo
148 m_CurrentFilename = "untitled.egc";
149 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
150 setUnsaved(true);
152 m_StatusInfoLabel = new QLabel(this);
153 statusBar()->addWidget(m_StatusInfoLabel);
154 m_StatusInfoLabel->setText("");
156 m_StatusProgressBar = new QProgressBar(this);
157 statusBar()->addWidget(m_StatusProgressBar);
159 m_StatusLabel = new QLabel(this);
160 statusBar()->addWidget(m_StatusLabel);
162 QString txt = "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms, 0 polys), ";
163 txt += "0 surface cells (0 triangles, 0 quads, 0 polys), 0 nodes";
164 m_StatusLabel->setText(txt);
165 ui.label_node_cell_info->setText(txt);
167 m_OriginalCoutBuffer = cout.rdbuf();
168 cout.rdbuf(&m_CoutBuffer);
169 m_Log = true;
171 m_Busy = false;
173 setPickMode(true,true);
174 m_PickedPoint = -1;
175 m_PickedCell = -1;
177 updateStatusBar();
179 connect(&m_GarbageTimer, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
180 m_GarbageTimer.start(1000);
182 connect(&m_LogTimer, SIGNAL(timeout()), this, SLOT(updateOutput()));
183 m_LogTimer.start(1000);
185 bool exp_features=false;
186 getSet("General","enable experimental features",false,exp_features);
187 getSet("General","enable undo+redo",false,m_undo_redo_enabled);
188 bool undo_redo_mode;
189 getSet("General","use RAM for undo+redo operations",false,undo_redo_mode);
190 getSet("General", "open last used file on startup", false, m_open_last);
192 ui.actionMirrorMesh->setEnabled(exp_features);
193 ui.actionCreateHexCore->setEnabled(exp_features);
194 ui.actionImportFluentCase->setEnabled(exp_features);
196 m_ReferenceSize=0.2;
198 ui.doubleSpinBox_HueMin->setValue(0.667);
199 ui.doubleSpinBox_HueMax->setValue(0);
201 // egvtkInteractorStyle *style = egvtkInteractorStyle::New();
202 // getInteractor()->SetInteractorStyle(style);
203 // style->Delete();
205 // initialise XML document
206 m_XmlHandler = new XmlHandler("engridcase");
207 // this->resetXmlDoc();
209 m_SolverIndex = 0;
211 readRecentFiles();
213 // load plugins
214 QString plugin_path;
215 getSet("General", "plugin path", "/usr/lib/engrid", plugin_path);
216 QDir plugin_dir(plugin_path);
217 m_PluginOperations.clear();
218 foreach (QString file_name, plugin_dir.entryList(QDir::Files)) {
219 if (file_name.right(3) == ".so") {
220 cout << qPrintable(plugin_dir.absoluteFilePath(file_name)) << endl;
221 QPluginLoader loader(plugin_dir.absoluteFilePath(file_name));
222 QObject *qobject = loader.instance();
223 if (!qobject) {
224 cout << "an error occurred while loading the plugins:\n";
225 cout << qPrintable(loader.errorString()) << "\n" << endl;
227 if (Operation *operation = qobject_cast<Operation*>(qobject)) {
228 //operation->setLockGui();
229 QAction *action = new QAction(operation->getMenuText(), this);
230 connect(action, SIGNAL(triggered()), this, SLOT(pluginCalled()));
231 m_PluginOperations[action] = operation;
232 ui.menuPlugins->addAction(action);
237 m_EscAction = new QAction("escape", this);
238 addAction(m_EscAction);
239 m_EscAction->setShortcut(QKeySequence(Qt::Key_Escape));
240 connect(m_EscAction, SIGNAL(triggered()), this, SLOT(onEsc()));
242 m_UniCadInterface = NULL;
244 //end of GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
246 void GuiMainWindow::pluginCalled()
248 QAction *action = qobject_cast<QAction*>(QObject::sender());
249 if (action) {
250 Operation *operation = m_PluginOperations[action];
251 operation->operator()();
255 void GuiMainWindow::resetXmlDoc()
257 m_XmlHandler->resetXmlDoc();
260 GuiMainWindow::~GuiMainWindow()
262 writeRecentFiles();
264 m_qset.setValue("GuiMainWindow", this->geometry());
265 m_qset.setValue("dockWidget_states", this->saveState());
267 cout.rdbuf(m_OriginalCoutBuffer);
269 delete m_XmlHandler;
272 void GuiMainWindow::setupVtk()
275 // avoid VTK pop-up window on Windows
276 #ifdef WIN32
277 vtkFileOutputWindow *w = vtkFileOutputWindow::New();
278 QString vtk_log_file = m_qset.value("tmp_directory").toString() + "/enGrid-vtk-errors.txt";
279 w->SetFileName(qPrintable(vtk_log_file));
280 vtkOutputWindow::SetInstance(w);
281 w->Delete();
282 #endif
284 // colour settings
285 getSet("Colours", "'A' faces (1-red)", 0.5, m_ColAR);
286 getSet("Colours", "'A' faces (2-green)", 1.0, m_ColAG);
287 getSet("Colours", "'A' faces (3-blue)", 0.5, m_ColAB);
289 getSet("Colours", "'B' faces (1-red)", 1.0, m_ColBR);
290 getSet("Colours", "'B' faces (2-green)", 1.0, m_ColBG);
291 getSet("Colours", "'B' faces (3-blue)", 0.5, m_ColBB);
293 getSet("Colours", " tetras (1-red)", 1.0, m_ColTetraR);
294 getSet("Colours", " tetras (2-green)", 0.0, m_ColTetraG);
295 getSet("Colours", " tetras (3-blue)", 0.0, m_ColTetraB);
297 getSet("Colours", " prisms (1-red)", 0.0, m_ColPrismR);
298 getSet("Colours", " prisms (2-green)", 1.0, m_ColPrismG);
299 getSet("Colours", " prisms (3-blue)", 0.0, m_ColPrismB);
301 getSet("Colours", " pyramids (1-red)", 1.0, m_ColPyraR);
302 getSet("Colours", " pyramids (2-green)", 1.0, m_ColPyraG);
303 getSet("Colours", " pyramids (3-blue)", 0.0, m_ColPyraB);
305 getSet("Colours", " hexes (1-red)", 0.0, m_ColHexR);
306 getSet("Colours", " hexes (2-green)", 0.7, m_ColHexG);
307 getSet("Colours", " hexes (3-blue)", 1.0, m_ColHexB);
309 getSet("Colours", " polys (1-red)", 0.7, m_ColPolyR);
310 getSet("Colours", " polys (2-green)", 1.0, m_ColPolyG);
311 getSet("Colours", " polys (3-blue)", 1.0, m_ColPolyB);
313 m_Grid = vtkUnstructuredGrid::New();
314 m_Renderer = vtkRenderer::New();
315 getRenderWindow()->AddRenderer(m_Renderer);
317 // coordinate axes
318 m_Axes = vtkCubeAxesActor2D::New();
320 m_Axes->SetCamera(getRenderer()->GetActiveCamera());
321 getRenderer()->AddActor(m_Axes);
322 m_Axes->SetVisibility(0);
324 // surface pipelines
325 m_BackfaceProperty = vtkProperty::New();
326 m_SurfaceFilter = vtkDataSetSurfaceFilter::New();
327 m_SurfaceMapper = vtkPolyDataMapper::New();
328 m_BCodesFilter = vtkEgBoundaryCodesFilter::New();
329 m_LookupTable = vtkLookupTable::New();
330 m_SurfaceActor = vtkActor::New();
331 m_LegendActor = vtkScalarBarActor::New();
333 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
334 m_BCodesFilter->SetInputData(m_Grid);
335 m_SurfaceFilter->SetInputConnection(m_BCodesFilter->GetOutputPort());
336 m_SurfaceMapper->SetInputConnection(m_SurfaceFilter->GetOutputPort());
337 m_SurfaceMapper->SetLookupTable(m_LookupTable);
338 m_SurfaceActor->GetProperty()->SetRepresentationToSurface();
339 m_SurfaceActor->GetProperty()->SetColor(m_ColAR, m_ColAG, m_ColAB);
340 m_SurfaceActor->SetBackfaceProperty(m_BackfaceProperty);
341 m_SurfaceActor->GetBackfaceProperty()->SetColor(m_ColBR, m_ColBG, m_ColBB);
342 m_SurfaceActor->GetProperty()->EdgeVisibilityOn();
343 m_SurfaceActor->GetProperty()->SetEdgeColor(0,0,1);
344 m_SurfaceActor->SetMapper(m_SurfaceMapper);
345 getRenderer()->AddActor(m_SurfaceActor);
346 m_SurfaceActor->SetVisibility(1);
347 m_LegendActor->SetLookupTable(m_LookupTable);
348 getRenderer()->AddActor(m_LegendActor);
349 m_LegendActor->SetVisibility(0);
351 // tetra pipline
352 m_ExtrTetras = vtkEgExtractVolumeCells::New();
353 m_TetraActor = vtkActor::New();
354 m_TetraGeometry = vtkDataSetSurfaceFilter::New();
355 m_TetraMapper = vtkPolyDataMapper::New();
357 m_ExtrTetras->SetInputData(m_Grid);
358 m_ExtrTetras->SetAllOff();
359 m_ExtrTetras->SetTetrasOn();;
360 m_TetraGeometry->SetInputConnection(m_ExtrTetras->GetOutputPort());
361 m_TetraMapper->SetInputConnection(m_TetraGeometry->GetOutputPort());
362 m_TetraActor->SetMapper(m_TetraMapper);
363 m_TetraActor->GetProperty()->SetColor(m_ColTetraR, m_ColTetraG, m_ColTetraB);
364 m_TetraActor->GetProperty()->EdgeVisibilityOn();
365 m_TetraActor->GetProperty()->SetEdgeColor(0,0,1);
366 getRenderer()->AddActor(m_TetraActor);
367 m_TetraActor->SetVisibility(0);
369 // pyramid pipeline
370 m_PyramidActor = vtkActor::New();
371 m_ExtrPyramids = vtkEgExtractVolumeCells::New();
372 m_PyramidGeometry = vtkDataSetSurfaceFilter::New();
373 m_PyramidMapper = vtkPolyDataMapper::New();
375 m_ExtrPyramids->SetInputData(m_Grid);
376 m_ExtrPyramids->SetAllOff();
377 m_ExtrPyramids->SetPyramidsOn();
378 m_PyramidGeometry->SetInputConnection(m_ExtrPyramids->GetOutputPort());
379 m_PyramidMapper->SetInputConnection(m_PyramidGeometry->GetOutputPort());
380 m_PyramidActor->SetMapper(m_PyramidMapper);
381 m_PyramidActor->GetProperty()->SetColor(m_ColPyraR, m_ColPyraG, m_ColPyraB);
382 m_PyramidActor->GetProperty()->EdgeVisibilityOn();
383 m_PyramidActor->GetProperty()->SetEdgeColor(0,0,1);
384 getRenderer()->AddActor(m_PyramidActor);
385 m_PyramidActor->SetVisibility(0);
387 // wedge pipeline
388 m_WedgeActor = vtkActor::New();
389 m_ExtrWedges = vtkEgExtractVolumeCells::New();
390 m_WedgeGeometry = vtkDataSetSurfaceFilter::New();
391 m_WedgeMapper = vtkPolyDataMapper::New();
393 m_ExtrWedges->SetInputData(m_Grid);
394 m_ExtrWedges->SetAllOff();
395 m_ExtrWedges->SetWedgesOn();
396 m_WedgeGeometry->SetInputConnection(m_ExtrWedges->GetOutputPort());
397 m_WedgeMapper->SetInputConnection(m_WedgeGeometry->GetOutputPort());
398 m_WedgeActor->SetMapper(m_WedgeMapper);
399 m_WedgeActor->GetProperty()->SetColor(m_ColPrismR, m_ColPrismG, m_ColPrismB);
400 m_WedgeActor->GetProperty()->EdgeVisibilityOn();
401 m_WedgeActor->GetProperty()->SetEdgeColor(0,0,1);
402 getRenderer()->AddActor(m_WedgeActor);
403 m_WedgeActor->SetVisibility(0);
405 // hexa pipeline
406 m_HexaActor = vtkActor::New();
407 m_ExtrHexes = vtkEgExtractVolumeCells::New();
408 m_HexaGeometry = vtkDataSetSurfaceFilter::New();
409 m_HexaMapper = vtkPolyDataMapper::New();
411 m_ExtrHexes->SetInputData(m_Grid);
412 m_ExtrHexes->SetAllOff();
413 m_ExtrHexes->SetHexesOn();
414 m_HexaGeometry->SetInputConnection(m_ExtrHexes->GetOutputPort());
415 m_HexaMapper->SetInputConnection(m_HexaGeometry->GetOutputPort());
416 m_HexaActor->SetMapper(m_HexaMapper);
417 m_HexaActor->GetProperty()->SetColor(m_ColHexR, m_ColHexG, m_ColHexB);
418 m_HexaActor->GetProperty()->EdgeVisibilityOn();
419 m_HexaActor->GetProperty()->SetEdgeColor(0,0,1);
420 getRenderer()->AddActor(m_HexaActor);
421 m_HexaActor->SetVisibility(0);
423 // polyhedra pipeline
424 m_PolyhedraActor = vtkActor::New();
425 m_ExtrPolyhedra = vtkEgExtractVolumeCells::New();
426 m_PolyhedraGeometry = vtkDataSetSurfaceFilter::New();
427 m_PolyhedraMapper = vtkPolyDataMapper::New();
429 m_ExtrPolyhedra->SetInputData(m_Grid);
430 m_ExtrPolyhedra->SetAllOff();
431 m_ExtrPolyhedra->SetPolysOn();
432 m_PolyhedraGeometry->SetInputConnection(m_ExtrPolyhedra->GetOutputPort());
433 m_PolyhedraMapper->SetInputConnection(m_PolyhedraGeometry->GetOutputPort());
434 m_PolyhedraActor->SetMapper(m_PolyhedraMapper);
435 m_PolyhedraActor->GetProperty()->SetColor(m_ColPolyR, m_ColPolyG, m_ColPolyB);
436 m_PolyhedraActor->GetProperty()->EdgeVisibilityOn();
437 m_PolyhedraActor->GetProperty()->SetEdgeColor(0,0,1);
438 getRenderer()->AddActor(m_PolyhedraActor);
439 m_PolyhedraActor->SetVisibility(0);
441 // picker stuff
442 m_PickSphere = vtkSphereSource::New();
443 m_PickMapper = vtkPolyDataMapper::New();
444 m_PickActor = vtkActor::New();
445 m_CellPicker = vtkCellPicker::New();
446 m_PointPicker = vtkPointPicker::New();
448 m_PickSphere->SetRadius(0.25); //in case the user starts picking points instead of cells
449 m_PickMapper->SetInputConnection(m_PickSphere->GetOutputPort());
450 m_PickActor->SetMapper(m_PickMapper);
451 m_PickActor->GetProperty()->SetRepresentationToSurface();
452 m_PickActor->GetProperty()->SetColor(0,0,1);
453 m_PickActor->VisibilityOff();
454 getRenderer()->AddActor(m_PickActor);
456 vtkCallbackCommand *cbc = vtkCallbackCommand::New();
457 cbc->SetCallback(pickCallBack);
459 m_CellPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
460 m_PointPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
461 m_PickedObject = 0;
463 viewFront();
465 // Create a new QVTKInteractor instance
466 //vtkSmartPointer<QVTKInteractor> interactor = vtkSmartPointer<QVTKInteractor>::New();
468 // Set the interactor for your QVTKOpenGLNativeWidget or QVTKOpenGLStereoWidget
469 //ui.centralwidget->GetRenderWindow()->SetInteractor(interactor);
471 // Initialize the interactor
472 //interactor->Initialize();
474 // Render the scene
475 //ui.myVtkWidget->GetRenderWindow()->Render();
478 // ui.centralwidget->setFocusPolicy(Qt::StrongFocus);
479 // vtkSmartPointer<vtkRenderWindowInteractor> interactor = ui.centralwidget->GetInteractor();
480 // interactor->Initialize();
481 //interactor->Start();
486 void GuiMainWindow::updateOutput()
488 if (m_Log) {
489 QString txt = m_CoutBuffer.str().c_str();
490 m_CoutBuffer.str("");
491 if (txt.right(1) == "\n") {
492 txt = txt.left(txt.size()-1);
494 if (txt.size() > 0) {
495 ui.textEditOutput->append(txt);
500 void GuiMainWindow::exit()
502 QCoreApplication::exit();
505 vtkRenderWindow* GuiMainWindow::getRenderWindow()
507 return ui.centralwidget->GetRenderWindow();
510 vtkRenderer* GuiMainWindow::getRenderer()
512 return m_Renderer;
515 QVTKInteractor* GuiMainWindow::getInteractor()
517 return ui.centralwidget->GetInteractor();
520 QString GuiMainWindow::getCwd()
522 return m_cwd;
525 void GuiMainWindow::setCwd(QString dir)
527 m_cwd = dir;
528 m_qset.setValue("working_directory",dir);
531 void GuiMainWindow::setUnsaved(bool unsaved)
533 m_UnSaved = unsaved;
536 void GuiMainWindow::scaleToData()
538 int current_field=ui.comboBox_Field->currentIndex();
539 if(current_field>0)
541 double range[2];
543 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
544 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
545 cout<<"current_field="<<current_field<<endl;
546 cout<<"range[0]="<<range[0]<<endl;
547 cout<<"range[1]="<<range[1]<<endl;
548 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
549 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
550 ui.doubleSpinBox_FieldMin->setValue(range[0]);
551 ui.doubleSpinBox_FieldMax->setValue(range[1]);
555 void GuiMainWindow::setClipX(const QString &txt)
557 m_ExtrTetras->Setx(txt.toDouble());
558 m_ExtrPyramids->Setx(txt.toDouble());
559 m_ExtrWedges->Setx(txt.toDouble());
560 m_ExtrHexes->Setx(txt.toDouble());
561 m_ExtrPolyhedra->Setx(txt.toDouble());
564 void GuiMainWindow::setClipY(const QString &txt)
566 m_ExtrTetras->Sety(txt.toDouble());
567 m_ExtrPyramids->Sety(txt.toDouble());
568 m_ExtrWedges->Sety(txt.toDouble());
569 m_ExtrHexes->Sety(txt.toDouble());
570 m_ExtrPolyhedra->Sety(txt.toDouble());
573 void GuiMainWindow::setClipZ(const QString &txt)
575 m_ExtrTetras->Setz(txt.toDouble());
576 m_ExtrPyramids->Setz(txt.toDouble());
577 m_ExtrWedges->Setz(txt.toDouble());
578 m_ExtrHexes->Setz(txt.toDouble());
579 m_ExtrPolyhedra->Setz(txt.toDouble());
582 void GuiMainWindow::setClipNX(const QString &txt)
584 m_ExtrTetras->Setnx(txt.toDouble());
585 m_ExtrPyramids->Setnx(txt.toDouble());
586 m_ExtrWedges->Setnx(txt.toDouble());
587 m_ExtrHexes->Setnx(txt.toDouble());
588 m_ExtrPolyhedra->Setnx(txt.toDouble());
591 void GuiMainWindow::setClipNY(const QString &txt)
593 m_ExtrTetras->Setny(txt.toDouble());
594 m_ExtrPyramids->Setny(txt.toDouble());
595 m_ExtrWedges->Setny(txt.toDouble());
596 m_ExtrHexes->Setny(txt.toDouble());
597 m_ExtrPolyhedra->Setny(txt.toDouble());
600 void GuiMainWindow::setClipNZ(const QString &txt)
602 m_ExtrTetras->Setnz(txt.toDouble());
603 m_ExtrPyramids->Setnz(txt.toDouble());
604 m_ExtrWedges->Setnz(txt.toDouble());
605 m_ExtrHexes->Setnz(txt.toDouble());
606 m_ExtrPolyhedra->Setnz(txt.toDouble());
609 void GuiMainWindow::updateSurfaceActors(bool forced)
611 if (ui.checkBoxSurface->isChecked()) {
612 if (forced) {
613 m_SurfaceFilter->Update();
616 // fill node field combobox
617 int current_field=ui.comboBox_Field->currentIndex();
618 ui.comboBox_Field->clear();
619 ui.comboBox_Field->addItem("None");
620 for (int i = 0; i < m_Grid->GetPointData()->GetNumberOfArrays(); ++i) {
621 ui.comboBox_Field->addItem(m_Grid->GetPointData()->GetArrayName(i));
623 if(current_field == -1) {
624 ui.comboBox_Field->setCurrentIndex(0);
625 } else {
626 ui.comboBox_Field->setCurrentIndex(current_field);
629 // fill cell field combobox
630 int current_cell_field = ui.comboBox_CellTextField->currentIndex();
631 ui.comboBox_CellTextField->clear();
632 ui.comboBox_CellTextField->addItem("Cell ID");
633 for (int i = 0; i < m_SurfaceFilter->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i) {
634 ui.comboBox_CellTextField->addItem(m_Grid->GetCellData()->GetArrayName(i));
636 if(current_cell_field == -1) {
637 ui.comboBox_CellTextField->setCurrentIndex(0);
638 } else {
639 ui.comboBox_CellTextField->setCurrentIndex(current_cell_field);
641 current_field = ui.comboBox_Field->currentIndex();
642 if(current_field > 0) {
643 double range[2];
644 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
645 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
646 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
649 if(ui.comboBox_Field->currentIndex() > 0) {
650 m_SurfaceMapper->SetColorModeToMapScalars();
651 m_LookupTable->SetNumberOfColors(ui.spinBox_Color->value());
652 m_LookupTable->SetHueRange(ui.doubleSpinBox_HueMin->value(),ui.doubleSpinBox_HueMax->value());
653 m_LookupTable->Build();
654 m_SurfaceMapper->SetScalarModeToUsePointFieldData();
655 m_SurfaceMapper->ColorByArrayComponent(qPrintable(ui.comboBox_Field->currentText()),0);
656 m_SurfaceMapper->SetScalarRange(ui.doubleSpinBox_FieldMin->value(),ui.doubleSpinBox_FieldMax->value());
657 m_SurfaceMapper->ScalarVisibilityOn();
658 if(ui.checkBox_Legend->checkState()) {
659 m_LegendActor->SetVisibility(1);
660 } else {
661 m_LegendActor->SetVisibility(0);
663 } else {
664 m_SurfaceMapper->SetColorModeToDefault();
665 m_SurfaceMapper->ScalarVisibilityOff();
666 m_LegendActor->SetVisibility(0);
668 if (forced) {
669 m_BCodesFilter->Update();
671 if(ui.checkBox_ShowPickSphere->checkState()) {
672 if(m_UseVTKInteractor) {
673 if(ui.radioButton_CellPicker->isChecked()) {
674 getInteractor()->SetPicker(m_CellPicker);
675 vtkIdType id_cell = getPickedCell();
676 pickCell(id_cell);
677 } else {
678 getInteractor()->SetPicker(m_PointPicker);
679 vtkIdType id_node = getPickedPoint();
680 pickPoint(id_node);
682 } else {
683 if (ui.radioButton_CellPicker->isChecked()) {
684 pickCell(m_PickedCell);
685 } else {
686 pickPoint(m_PickedPoint);
690 m_SurfaceActor->SetVisibility(1);
691 } else {
692 m_SurfaceActor->SetVisibility(0);
696 void GuiMainWindow::updateVolumeActors(bool forced)
698 if (ui.checkBoxVolume->isChecked()) {
699 if (ui.checkBoxTetra->isChecked()) {
700 if (ui.checkBoxClip->isChecked()) {
701 m_ExtrTetras->SetClippingOn();
702 } else {
703 m_ExtrTetras->SetClippingOff();
705 if (forced) {
706 m_TetraGeometry->Update();
708 m_TetraActor->SetVisibility(1);
709 } else {
710 m_TetraActor->SetVisibility(0);
712 if (ui.checkBoxPyramid->isChecked()) {
713 if (ui.checkBoxClip->isChecked()) {
714 m_ExtrPyramids->SetClippingOn();
715 } else {
716 m_ExtrPyramids->SetClippingOff();
718 if (forced) {
719 m_PyramidGeometry->Update();
721 m_PyramidActor->SetVisibility(1);
722 } else {
723 m_PyramidActor->SetVisibility(0);
725 if (ui.checkBoxWedge->isChecked()) {
726 if (ui.checkBoxClip->isChecked()) {
727 m_ExtrWedges->SetClippingOn();
728 } else {
729 m_ExtrWedges->SetClippingOff();
731 if (forced) {
732 m_WedgeGeometry->Update();
734 m_WedgeActor->SetVisibility(1);
735 } else {
736 m_WedgeActor->SetVisibility(0);
738 if (ui.checkBoxHexa->isChecked()) {
739 if (ui.checkBoxClip->isChecked()) {
740 m_ExtrHexes->SetClippingOn();
741 } else {
742 m_ExtrHexes->SetClippingOff();
744 if (forced) {
745 m_HexaGeometry->Update();
747 m_HexaActor->SetVisibility(1);
748 } else {
749 m_HexaActor->SetVisibility(0);
751 if (ui.checkBoxPoly->isChecked()) {
752 if (ui.checkBoxClip->isChecked()) {
753 m_ExtrPolyhedra->SetClippingOn();
754 } else {
755 m_ExtrPolyhedra->SetClippingOff();
757 if (forced) {
758 m_PolyhedraGeometry->Update();
760 m_PolyhedraActor->SetVisibility(1);
761 } else {
762 m_PolyhedraActor->SetVisibility(0);
765 } else {
766 m_TetraActor->VisibilityOff();
767 m_PyramidActor->VisibilityOff();
768 m_WedgeActor->VisibilityOff();
769 m_HexaActor->VisibilityOff();
770 m_PolyhedraActor->VisibilityOff();
774 void GuiMainWindow::updateActors(bool forced)
776 // qDebug()<<"QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); called()";
777 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
779 //if (!tryLock()) return;
780 try {
781 m_Axes->SetInputData(m_Grid);
782 updateSurfaceActors(forced);
783 updateVolumeActors(forced);
784 updateStatusBar();
785 } catch (Error err) {
786 err.display();
788 //unlock();
790 // qDebug()<<"QApplication::restoreOverrideCursor(); called()";
791 QApplication::restoreOverrideCursor();
796 void GuiMainWindow::forceUpdateActors()
798 // qDebug()<<"void GuiMainWindow::forceUpdateActors() START";
799 updateActors(true);
800 getRenderWindow()->Render();
801 // qDebug()<<"void GuiMainWindow::forceUpdateActors() END";
804 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor,bool a_CellPickerMode)
806 m_UseVTKInteractor=a_UseVTKInteractor;
807 if (a_UseVTKInteractor) {
808 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Checked);
809 } else {
810 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Unchecked);
812 if (a_CellPickerMode) {
813 ui.radioButton_CellPicker->toggle();
814 } else {
815 ui.radioButton_PointPicker->toggle();
819 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor)
821 m_UseVTKInteractor = a_UseVTKInteractor;
824 bool GuiMainWindow::pickPoint(vtkIdType id_node)
826 if ((id_node >= 0) && (id_node < m_Grid->GetNumberOfPoints())) {
827 vec3_t x(0,0,0);
828 m_Grid->GetPoints()->GetPoint(id_node, x.data());
829 m_PickSphere->SetCenter(x.data());
830 m_PickedPoint = id_node;
831 m_PickActor->GetProperty()->SetColor(0,0,1);
832 m_PickActor->VisibilityOn();
833 m_PickedObject = 1;
834 return(true);
835 } else {
836 m_PickActor->VisibilityOff();
837 m_PickedObject = 0;
838 return(false);
842 bool GuiMainWindow::pickCell(vtkIdType id_cell)
844 if ((id_cell >= 0) && (id_cell < m_Grid->GetNumberOfCells())) {
845 EG_GET_CELL(id_cell, m_Grid);
846 vec3_t x(0,0,0);
847 for (vtkIdType i = 0; i < num_pts; ++i) {
848 vec3_t xp;
849 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
850 x += double(1)/num_pts * xp;
852 m_PickSphere->SetCenter(x.data());
853 double R = 1e99;
854 for (vtkIdType i = 0; i < num_pts; ++i) {
855 vec3_t xp;
856 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
857 R = min(R, 0.25*(xp-x).abs());
859 m_ReferenceSize = R; //Used for text annotations too!
860 m_PickSphere->SetRadius(R);
861 m_PickedCell = id_cell;
862 m_PickActor->GetProperty()->SetColor(1,0,0);
863 m_PickActor->VisibilityOn();
864 m_PickedObject = 2;
865 return(true);
866 } else {
867 m_PickActor->VisibilityOff();
868 m_PickedObject = 0;
869 return(false);
873 void GuiMainWindow::importSTL()
875 StlReader stl;
876 stl();
877 //FIXME: emits an error if no file is imported, so check if there is a valid file
878 updateBoundaryCodes(true);
879 updateActors();
880 updateStatusBar();
881 zoomAll();
884 void GuiMainWindow::importGmsh1Ascii()
886 GmshReader gmsh;
887 gmsh.setV1Ascii();
888 gmsh();
889 updateBoundaryCodes(true);
890 updateActors();
891 updateStatusBar();
892 zoomAll();
895 void GuiMainWindow::exportGmsh1Ascii()
897 GmshWriter gmsh;
898 gmsh.setV1Ascii();
899 gmsh();
902 void GuiMainWindow::importGmsh2Ascii()
904 GmshReader gmsh;
905 gmsh.setV2Ascii();
906 gmsh();
907 updateBoundaryCodes(true);
908 updateActors();
909 updateStatusBar();
910 zoomAll();
913 void GuiMainWindow::exportGmsh2Ascii()
915 GmshWriter gmsh;
916 gmsh.setV2Ascii();
917 gmsh();
920 void GuiMainWindow::exportNeutral()
922 NeutralWriter neutral;
923 neutral();
926 void GuiMainWindow::zoomAll()
928 getRenderer()->ResetCamera();
929 getRenderWindow()->Render();
932 void GuiMainWindow::zoomOnPickedObject()
934 if(m_PickActor->GetVisibility()) {
935 getRenderer()->ResetCamera(m_PickActor->GetBounds());
936 getRenderWindow()->Render();
940 void GuiMainWindow::deselectAll()
942 cout << "void GuiMainWindow::deselectAll()" << endl;
943 m_PickActor->VisibilityOff();
944 updateActors();
947 ///\todo Should display a window
948 void GuiMainWindow::info()
950 ShowInfo info(ui.radioButton_CellPicker->isChecked(), m_PickedPoint, m_PickedCell);
951 info();
954 int GuiMainWindow::quickSave()
956 ///\todo add RAM support
957 if(m_undo_redo_enabled) {
958 if(m_Grid->GetNumberOfPoints()>0)
960 m_CurrentOperation++;
961 QFileInfo fileinfo(m_CurrentFilename);
962 QString l_filename = m_qset.value("tmp_directory").toString() + fileinfo.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation);
963 m_LastOperation=m_CurrentOperation;
964 cout<<"Operation "<<m_CurrentOperation<<endl;
965 saveAs(l_filename, false);
966 if(m_CurrentOperation>0) ui.actionUndo->setEnabled(true);
967 ui.actionRedo->setEnabled(false);
969 else cout<<"No grid to save!"<<endl;
970 return(m_CurrentOperation);
972 return 0;
975 void GuiMainWindow::quickLoad(int a_operation)
977 ///\todo add RAM support
978 if(m_undo_redo_enabled) {
979 QFileInfo fileinfo(m_CurrentFilename);
980 QString l_filename = m_qset.value("tmp_directory").toString() + fileinfo.completeBaseName() + "_" + QString("%1").arg(a_operation) + ".egc";
981 open(l_filename, false);
985 void GuiMainWindow::undo()
987 if(m_undo_redo_enabled) {
988 cout << "Undoing operation " << m_CurrentOperation << endl;
989 m_CurrentOperation--;
990 quickLoad(m_CurrentOperation);
991 ui.actionRedo->setEnabled(true);
992 if(m_CurrentOperation<=0) ui.actionUndo->setEnabled(false);
994 else {
995 resetOperationCounter();
996 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
1000 void GuiMainWindow::redo()
1002 if(m_undo_redo_enabled) {
1003 m_CurrentOperation++;
1004 cout << "Redoing operation " << m_CurrentOperation << endl;
1005 quickLoad(m_CurrentOperation);
1006 ui.actionUndo->setEnabled(true);
1007 if(m_CurrentOperation>=m_LastOperation) ui.actionRedo->setEnabled(false);
1009 else {
1010 resetOperationCounter();
1011 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
1015 void GuiMainWindow::resetOperationCounter()
1017 m_CurrentOperation=-1;
1018 m_LastOperation=m_CurrentOperation;
1019 ui.actionUndo->setEnabled(false);
1020 ui.actionRedo->setEnabled(false);
1023 QString GuiMainWindow::getXmlSection(QString name)
1025 return m_XmlHandler->getXmlSection(name);
1028 void GuiMainWindow::setXmlSection(QString name, QString contents)
1030 m_XmlHandler->setXmlSection(name,contents);
1033 void GuiMainWindow::openPhysicalBoundaryConditions()
1035 m_PhysicalBoundaryConditionsMap.clear();
1036 QString buffer = getXmlSection("engrid/physical").trimmed();
1037 QStringList lines = buffer.split("\n");
1038 foreach (QString line, lines) {
1039 line = line.trimmed();
1040 QStringList parts = line.split(";", QString::SkipEmptyParts);
1041 if (parts.size() > 0) {
1042 QStringList words = parts[0].split(" ", QString::SkipEmptyParts);
1043 int index = words[0].trimmed().toInt();
1044 QString name = words[1].trimmed();
1045 QString type = words[2].trimmed();
1046 if ((name != "") && (type != "")) {
1047 PhysicalBoundaryCondition PBC;
1048 PBC.setName(name);
1049 PBC.setType(type);
1050 if (PBC.getNumVars() == parts.size() - 1) {
1051 PBC.setIndex(index);
1052 for (int i = 0; i < PBC.getNumVars(); ++i) {
1053 QStringList words = parts[i+1].split("=");
1054 PBC.setValueFromString(i, words[1].trimmed());
1056 m_PhysicalBoundaryConditionsMap[name] = PBC;
1063 void GuiMainWindow::savePhysicalBoundaryConditions()
1065 QString buffer("");
1066 QTextStream f(&buffer, QIODevice::WriteOnly);
1067 foreach (PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
1068 f << PBC.xmlText() << "\n";
1070 setXmlSection("engrid/physical", buffer);
1073 void GuiMainWindow::openBC()
1075 m_bcmap.clear();
1076 m_VolMap.clear();
1077 QString buffer = getXmlSection("engrid/bc");
1078 QTextStream f(&buffer, QIODevice::ReadOnly);
1079 while (!f.atEnd()) {
1080 QString name, type;
1081 int i;
1082 f >> i >> name >> type;
1083 if(name!="" && type!="") {
1084 if (i > 0) {
1085 m_bcmap[i] = BoundaryCondition(name,type,i);
1086 } else {
1087 VolumeDefinition V(name, -i);
1088 QString text = type.replace(",", " ").replace(":", " ");
1089 QTextStream s(&text);
1090 while (!s.atEnd()) {
1091 QString bc_txt, sign_txt;
1092 s >> bc_txt >> sign_txt;
1093 V.addBC(bc_txt.toInt(), sign_txt.toInt());
1095 m_VolMap[name] = V;
1101 void GuiMainWindow::saveBC()
1103 QString buffer("");
1104 QTextStream f(&buffer, QIODevice::WriteOnly);
1105 f << "\n";
1106 foreach (int i, m_AllBoundaryCodes) {
1107 BoundaryCondition bc = m_bcmap[i];
1108 f << i << " " << bc.getName() << " " << bc.getType() << "\n";
1110 foreach (VolumeDefinition V, m_VolMap) {
1111 QString dirs = "";
1112 bool first = true;
1113 foreach (int i, m_AllBoundaryCodes) {
1114 BoundaryCondition bc = m_bcmap[i];
1115 if (!first) {
1116 dirs += ",";
1117 } else {
1118 first = false;
1120 QString num;
1121 num.setNum(i);
1122 dirs += num + ":";
1123 num.setNum(V.getSign(i));
1124 dirs += num;
1126 f << "-" << V.getVC() << " " << V.getName() << " " << dirs << "\n";
1128 setXmlSection("engrid/bc", buffer);
1131 void GuiMainWindow::openGrid(QString file_name)
1133 file_name += ".vtu";
1134 EG_VTKSP(vtkXMLUnstructuredGridReader,vtu);
1135 vtu->SetFileName(qPrintable(file_name));
1136 vtu->Update();
1137 m_Grid->DeepCopy(vtu->GetOutput());
1138 if (m_Grid->GetPointData()->GetArray("node_meshdensity_current")) {
1139 m_Grid->GetPointData()->RemoveArray("node_meshdensity_current");
1141 if (m_Grid->GetCellData()->GetArray("cell_VA")) {
1142 m_Grid->GetCellData()->RemoveArray("cell_VA");
1144 createBasicFields(m_Grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints());
1145 openBC();
1146 openPhysicalBoundaryConditions();
1147 updateBoundaryCodes(true);
1148 createIndices(m_Grid);
1149 updateActors();
1150 updateStatusBar();
1151 zoomAll();
1154 ///\todo I think this should also be a done by a subclass of IOOperation just like for import operations
1155 void GuiMainWindow::open()
1157 QString file_name = QFileDialog::getOpenFileName(NULL, "open grid from file", getCwd(), "enGrid case files (*.egc *.EGC);; legacy grid files(*.vtu *.VTU)");
1158 if (!file_name.isNull()) {
1159 this->open(file_name);
1163 void GuiMainWindow::open(QString file_name, bool update_current_filename)
1165 cout << "Opening " << qPrintable(file_name) << endl;
1167 //QFileInfo file_info(file_name);
1168 bool no_case_file = false;
1169 QString file_extension = getExtension(file_name);
1170 QString grid_file_name = file_name;
1171 if (file_extension.toLower() == "vtu") {
1172 no_case_file = true;
1173 grid_file_name = stripFromExtension(file_name);
1175 if (!no_case_file) {
1176 if(!m_XmlHandler->openXml(file_name)) {
1177 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name));
1178 return;
1181 if(update_current_filename) {
1182 GuiMainWindow::setCwd(QFileInfo(file_name).absolutePath());
1184 resetCadInterfaces();
1186 QFile geo_file(file_name + ".geo.vtu");
1187 if (geo_file.exists()) {
1188 openGrid(file_name + ".geo");
1189 storeCadInterfaces(true);
1192 openGrid(grid_file_name);
1193 openBC();
1194 openPhysicalBoundaryConditions();
1195 // update current filename
1196 if(update_current_filename) m_CurrentFilename = stripFromExtension(file_name) + ".egc";
1197 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1198 setUnsaved(false);
1200 if(update_current_filename) {
1201 this->addRecentFile(file_name,QDateTime::currentDateTime());
1202 m_qset.setValue("LatestFile",file_name);
1203 resetOperationCounter();
1204 quickSave();
1208 QString GuiMainWindow::saveAs(QString file_name, bool update_current_filename)
1210 QString buffer = m_XmlHandler->getBuffer(0);
1211 if(update_current_filename) {
1212 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1214 QFileInfo file_info(file_name);
1215 if (file_info.suffix().toLower() != "egc") {
1216 file_name += ".egc";
1218 if(update_current_filename) {
1219 GuiMainWindow::setCwd(file_info.absolutePath());
1220 m_CurrentFilename = file_name;
1222 if(!saveGrid(m_Grid, file_name)) {
1223 QMessageBox::critical(this, QObject::tr("Save failed"), QObject::tr("The grid could not be saved as:\n%1").arg(file_name));
1225 saveBC();
1226 savePhysicalBoundaryConditions();
1227 m_XmlHandler->saveXml(file_name);
1228 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1229 setUnsaved(false);
1230 if(update_current_filename) {
1231 QApplication::restoreOverrideCursor();
1233 if(update_current_filename) {
1234 this->addRecentFile(file_name,QDateTime::currentDateTime());
1235 m_qset.setValue("LatestFile",file_name);
1237 return(file_name);
1240 void GuiMainWindow::save()
1242 if ( m_CurrentFilename == "untitled.egc" || m_UnSaved ) {
1244 //FIXME: This is more of a hack than a fix...
1245 if(GuiMainWindow::tryLock()) {
1246 GuiMainWindow::unlock(); //must unlock before continuing.
1247 saveAs();
1248 } else {
1249 cout <<endl
1250 << "WARNING: Please save the project before running the requested operation "
1251 "or after the current operation is complete."
1252 <<endl;
1254 } else {
1255 saveAs(m_CurrentFilename);
1259 void GuiMainWindow::saveAs()
1261 QApplication::restoreOverrideCursor();
1262 //saveGrid(m_Grid, m_CurrentFilename + ".geo");
1263 bool geo_file_exists = false;
1264 QString old_geo_file = m_CurrentFilename + ".geo.vtu";
1266 if (QFileInfo(old_geo_file).exists()) {
1267 geo_file_exists = true;
1270 QFileDialog dialog(NULL, "write case to file", getCwd(), "enGrid case files (*.egc)");
1271 QFileInfo file_info(m_CurrentFilename);
1272 dialog.selectFile(file_info.completeBaseName() + ".egc");
1273 dialog.setAcceptMode(QFileDialog::AcceptSave);
1274 dialog.setConfirmOverwrite(true);
1275 if (dialog.exec()) {
1276 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1277 QStringList selected_files = dialog.selectedFiles();
1278 QString file_name = selected_files[0];
1279 if (!file_name.isNull()) {
1280 QString new_geo_file = file_name + ".geo.vtu";
1282 QFile file(new_geo_file);
1283 file.remove();
1285 QFile geo_file(old_geo_file);
1286 geo_file.copy(new_geo_file);
1287 saveAs(file_name);
1288 //for the undo/redo operations
1289 resetOperationCounter();
1290 quickSave();
1293 QApplication::restoreOverrideCursor();
1296 void GuiMainWindow::updateStatusBar()
1298 QString num, txt = "enGrid is currently busy with an operation ...";
1299 if (!m_Busy) {
1300 txt = "";
1302 if (!tryLock()) {
1303 m_StatusLabel->setText(txt);
1304 ui.label_node_cell_info->setText(txt);
1305 return;
1307 vtkIdType Ncells = m_Grid->GetNumberOfCells();
1308 vtkIdType Nnodes = m_Grid->GetNumberOfPoints();
1309 vtkIdType Ntris = 0;
1310 vtkIdType Nquads = 0;
1311 vtkIdType Nplgs = 0;
1312 vtkIdType Ntets = 0;
1313 vtkIdType Npyras = 0;
1314 vtkIdType Nprism = 0;
1315 vtkIdType Nhexas = 0;
1316 vtkIdType Npolys = 0;
1317 for (vtkIdType i = 0; i < Ncells; ++i) {
1318 int ct = m_Grid->GetCellType(i);
1319 if (ct == VTK_TRIANGLE) ++Ntris;
1320 else if (ct == VTK_QUAD) ++Nquads;
1321 else if (ct == VTK_POLYGON) ++Nplgs;
1322 else if (ct == VTK_TETRA) ++Ntets;
1323 else if (ct == VTK_WEDGE) ++Nprism;
1324 else if (ct == VTK_PYRAMID) ++Npyras;
1325 else if (ct == VTK_HEXAHEDRON) ++Nhexas;
1326 else if (ct == VTK_POLYHEDRON) ++Npolys;
1328 num.setNum(Ntets + Npyras + Nprism + Nhexas + Npolys); txt += num + " volume cells(";
1329 num.setNum(Ntets); txt += num + " tetras, ";
1330 num.setNum(Npyras); txt += num + " pyramids, ";
1331 num.setNum(Nprism); txt += num + " prisms, ";
1332 num.setNum(Nhexas); txt += num + " hexas, ";
1333 num.setNum(Npolys); txt += num + " polys), ";
1334 num.setNum(Ntris + Nquads + Nplgs); txt += num + " surface cells(";
1335 num.setNum(Ntris); txt += num + " triangles, ";
1336 num.setNum(Nquads); txt += num + " quads, ";
1337 num.setNum(Nplgs); txt += num + " polys), ";
1338 num.setNum(Nnodes); txt += num + " nodes";
1340 if(ui.radioButton_CellPicker->isChecked())
1342 QString pick_txt = ", picked cell: ";
1343 vtkIdType id_cell = m_PickedCell;
1344 if (id_cell < 0 || id_cell>=m_Grid->GetNumberOfCells()) {
1345 pick_txt += "no cell picked";
1346 } else {
1347 EG_GET_CELL(id_cell, m_Grid);
1348 if (type_cell == VTK_TRIANGLE) pick_txt += "tri";
1349 else if (type_cell == VTK_QUAD) pick_txt += "qua";
1350 else if (type_cell == VTK_POLYGON) pick_txt += "plg";
1351 else if (type_cell == VTK_TETRA) pick_txt += "tet";
1352 else if (type_cell == VTK_PYRAMID) pick_txt += "pyr";
1353 else if (type_cell == VTK_WEDGE) pick_txt += "pri";
1354 else if (type_cell == VTK_HEXAHEDRON) pick_txt += "hex";
1355 else if (type_cell == VTK_POLYHEDRON) pick_txt += "pol";
1356 pick_txt += " [";
1357 for (int i_pts = 0; i_pts < num_pts; ++i_pts) {
1358 QString num;
1359 num.setNum(pts[i_pts]);
1360 pick_txt += num;
1361 if (i_pts < num_pts-1) {
1362 pick_txt += ",";
1365 pick_txt += "]";
1366 QString tmp;
1367 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1368 tmp.setNum(cell_code->GetValue(id_cell));
1369 pick_txt += " code=" + tmp;
1370 tmp.setNum(id_cell);
1371 pick_txt += " id=" + tmp;
1373 txt += pick_txt;
1375 else
1377 QString pick_txt = ", picked node: ";
1378 vtkIdType id_node = m_PickedPoint;
1379 if (id_node < 0) {
1380 pick_txt += "no node picked";
1381 } else {
1382 QString tmp;
1383 EG_VTKDCN(vtkDoubleArray, characteristic_length_desired, m_Grid, "node_meshdensity_desired");
1384 tmp.setNum(characteristic_length_desired->GetValue(id_node));
1385 pick_txt += " wanted density=" + tmp;
1386 EG_VTKDCN(vtkIntArray, node_specified_density, m_Grid, "node_specified_density");
1387 tmp.setNum(node_specified_density->GetValue(id_node));
1388 pick_txt += " node_specified_density=" + tmp;
1389 EG_VTKDCN(vtkCharArray_t, node_type, m_Grid, "node_type");
1390 pick_txt += " type=" + QString(VertexType2Str( node_type->GetValue(id_node)));
1391 tmp.setNum(id_node);
1392 pick_txt += " id_node=" + tmp;
1395 txt += pick_txt;
1398 m_StatusLabel->setText(txt);
1399 ui.label_node_cell_info->setText(txt);
1400 unlock();
1403 void GuiMainWindow::selectBoundaryCodes()
1405 GuiSelectBoundaryCodes bcodes;
1406 bcodes.setDisplayBoundaryCodes(m_DisplayBoundaryCodes);
1407 bcodes.setBoundaryCodes(m_AllBoundaryCodes);
1408 bcodes();
1409 bcodes.getThread().wait();
1410 bcodes.getSelectedBoundaryCodes(m_DisplayBoundaryCodes);
1411 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1412 updateActors();
1415 void GuiMainWindow::updateBoundaryCodes(bool all_on)
1417 try {
1418 m_AllBoundaryCodes.clear();
1419 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1420 for (vtkIdType i = 0; i < m_Grid->GetNumberOfCells(); ++i) {
1421 int ct = m_Grid->GetCellType(i);
1422 if ((ct == VTK_TRIANGLE) || (ct == VTK_QUAD) || (ct == VTK_POLYGON)) {
1423 m_AllBoundaryCodes.insert(cell_code->GetValue(i));
1426 if (all_on) {
1427 m_DisplayBoundaryCodes.clear();
1428 foreach (int bc, m_AllBoundaryCodes) {
1429 m_DisplayBoundaryCodes.insert(bc);
1431 } else {
1432 QSet<int> dbcs;
1433 foreach (int bc, m_DisplayBoundaryCodes) {
1434 if (m_AllBoundaryCodes.contains(bc)) {
1435 dbcs.insert(bc);
1438 m_DisplayBoundaryCodes.clear();
1439 foreach (int bc, m_AllBoundaryCodes) {
1440 if (dbcs.contains(bc)) {
1441 m_DisplayBoundaryCodes.insert(bc);
1445 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1446 } catch (Error err) {
1447 err.display();
1451 void GuiMainWindow::normalExtrusion()
1453 GuiNormalExtrusion extr;
1454 extr();
1455 updateBoundaryCodes(false);
1456 updateActors();
1459 void GuiMainWindow::setAxesVisibility()
1461 if (ui.actionViewAxes->isChecked()) {
1462 m_Axes->VisibilityOn();
1463 } else {
1464 m_Axes->VisibilityOff();
1466 getRenderWindow()->Render();
1469 void GuiMainWindow::setViewingMode()
1471 if (ui.actionViewOrthogonal->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1472 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1473 getRenderWindow()->Render();
1476 void GuiMainWindow::viewNodeIDs()
1478 int N = m_Grid->GetNumberOfPoints();
1479 cout<<"N="<<N<<endl;
1480 if (ui.actionViewNodeIDs->isChecked()) {
1481 cout<<"Activating node ID view"<<endl;
1482 m_NodeTextVectorText.resize(N);
1483 m_NodeTextPolyDataMapper.resize(N);
1484 m_NodeTextFollower.resize(N);
1485 for(int i = 0; i < N; ++i){
1486 m_NodeTextVectorText[i]=vtkVectorText::New();
1487 QString tmp;
1488 tmp.setNum(i);
1489 m_NodeTextVectorText[i]->SetText(qPrintable(tmp));
1490 m_NodeTextPolyDataMapper[i]=vtkPolyDataMapper::New();
1491 m_NodeTextPolyDataMapper[i]->SetInputConnection(m_NodeTextVectorText[i]->GetOutputPort());
1492 m_NodeTextFollower[i]=vtkFollower::New();
1493 m_NodeTextFollower[i]->SetMapper(m_NodeTextPolyDataMapper[i]);
1494 m_NodeTextFollower[i]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1495 vec3_t M;
1496 m_Grid->GetPoint(i, M.data());
1497 vec3_t tmp_M = M;
1498 vec3_t OffSet = m_ReferenceSize*tmp_M.normalise();
1499 M = M + OffSet;
1500 m_NodeTextFollower[i]->AddPosition(M[0], M[1], M[2]);
1501 m_NodeTextFollower[i]->SetCamera(getRenderer()->GetActiveCamera());
1502 m_NodeTextFollower[i]->GetProperty()->SetColor(0,0,1);
1503 getRenderer()->AddActor(m_NodeTextFollower[i]);
1506 else {
1507 cout<<"Deactivating node ID view"<<endl;
1508 for(unsigned int i = 0; i < m_NodeTextFollower.size();i++){
1509 getRenderer()->RemoveActor(m_NodeTextFollower[i]);
1510 m_NodeTextFollower[i]->Delete();
1511 m_NodeTextPolyDataMapper[i]->Delete();
1512 m_NodeTextVectorText[i]->Delete();
1514 m_NodeTextFollower.clear();
1515 m_NodeTextPolyDataMapper.clear();
1516 m_NodeTextVectorText.clear();
1519 getRenderWindow()->Render();
1522 void GuiMainWindow::viewCellIDs()
1524 vtkIdType N = m_Grid->GetNumberOfCells();
1525 cout<<"N="<<N<<endl;
1526 if (ui.actionViewCellIDs->isChecked()) {
1527 cout<<"Activating cell ID view"<<endl;
1528 m_CellTextVectorText.resize(N);
1529 m_CellTextPolyDataMapper.resize(N);
1530 m_CellTextFollower.resize(N);
1531 for (vtkIdType id_cell = 0; id_cell < N; ++id_cell){
1532 m_CellTextVectorText[id_cell] = vtkVectorText::New();
1534 QString tmp;
1536 if(ui.comboBox_CellTextField->currentIndex()==0) {
1537 tmp.setNum(id_cell);
1538 } else if (ui.comboBox_CellTextField->currentIndex()>0) {
1539 EG_VTKDCC(vtkIntArray, current_cell_field, m_Grid, qPrintable(ui.comboBox_CellTextField->currentText()));
1540 tmp.setNum(current_cell_field->GetValue(id_cell));
1542 else EG_BUG;
1544 m_CellTextVectorText[id_cell]->SetText(qPrintable(tmp));
1545 m_CellTextPolyDataMapper[id_cell]=vtkPolyDataMapper::New();
1546 m_CellTextPolyDataMapper[id_cell]->SetInputConnection(m_CellTextVectorText[id_cell]->GetOutputPort());
1547 m_CellTextFollower[id_cell]=vtkFollower::New();
1548 m_CellTextFollower[id_cell]->SetMapper(m_CellTextPolyDataMapper[id_cell]);
1549 m_CellTextFollower[id_cell]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1550 EG_GET_CELL(id_cell, m_Grid);
1551 vec3_t Center(0,0,0);
1552 for (int p = 0; p < num_pts; ++p) {
1553 vec3_t M;
1554 m_Grid->GetPoint(pts[p],M.data());
1555 Center+=M.data();
1557 vec3_t OffSet = m_ReferenceSize*triNormal(m_Grid, pts[0], pts[1], pts[2]).normalise();
1558 Center = 1.0/(double)num_pts*Center+OffSet;
1559 m_CellTextFollower[id_cell]->AddPosition(Center[0], Center[1], Center[2]);
1560 m_CellTextFollower[id_cell]->SetCamera(getRenderer()->GetActiveCamera());
1561 m_CellTextFollower[id_cell]->GetProperty()->SetColor(1, 0, 0);
1562 getRenderer()->AddActor(m_CellTextFollower[id_cell]);
1564 } else {
1565 cout<<"Deactivating cell ID view"<<endl;
1566 for (vtkIdType id_cell = 0; id_cell < (vtkIdType) m_CellTextFollower.size(); ++id_cell) {
1567 getRenderer()->RemoveActor(m_CellTextFollower[id_cell]);
1568 m_CellTextFollower[id_cell]->Delete();
1569 m_CellTextPolyDataMapper[id_cell]->Delete();
1570 m_CellTextVectorText[id_cell]->Delete();
1572 m_CellTextFollower.clear();
1573 m_CellTextPolyDataMapper.clear();
1574 m_CellTextVectorText.clear();
1577 getRenderWindow()->Render();
1580 void GuiMainWindow::pickCallBack
1582 vtkObject *caller,
1583 unsigned long int eid,
1584 void *clientdata,
1585 void *calldata
1588 caller = caller;
1589 eid = eid;
1590 clientdata = clientdata;
1591 calldata = calldata;
1592 THIS->updateActors();
1593 THIS->updateStatusBar();
1596 vtkIdType GuiMainWindow::getPickedCell()
1598 if(!ui.radioButton_CellPicker->isChecked()) return(-1);
1600 vtkIdType picked_cell = -1;
1601 if (m_Grid->GetNumberOfCells() > 0) {
1602 m_BCodesFilter->Update();
1603 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1604 EG_VTKDCC(vtkLongArray_t, cell_index, m_BCodesFilter->GetOutput(), "cell_index");
1605 if (m_UseVTKInteractor) {
1606 picked_cell = m_CellPicker->GetCellId();
1607 if (picked_cell >= 0) {
1608 picked_cell = cell_index->GetValue(picked_cell);
1610 } else {
1611 picked_cell = m_PickedCell;
1615 return picked_cell;
1618 vtkIdType GuiMainWindow::getPickedPoint()
1620 if(ui.radioButton_CellPicker->isChecked()) return(-1);
1622 vtkIdType picked_point = -1;
1623 if (m_Grid->GetNumberOfCells() > 0) {
1624 m_BCodesFilter->Update();
1625 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1626 EG_VTKDCN(vtkLongArray_t, node_index, m_BCodesFilter->GetOutput(), "node_index");
1627 if (m_UseVTKInteractor) {
1628 picked_point = m_PointPicker->GetPointId();
1629 if (picked_point >= 0) {
1630 picked_point = node_index->GetValue(picked_point);
1632 } else {
1633 picked_point = m_PickedPoint;
1637 return picked_point;
1640 void GuiMainWindow::changeSurfaceOrientation()
1642 for (vtkIdType cellId = 0; cellId < m_Grid->GetNumberOfCells(); ++cellId) {
1643 EG_GET_CELL(cellId, m_Grid);
1644 QVector<vtkIdType> nodes(num_pts);
1645 for (vtkIdType j = 0; j < num_pts; ++j) nodes[j] = pts[j];
1646 for (vtkIdType j = 0; j < num_pts; ++j) pts[num_pts - j - 1] = nodes[j];
1648 updateActors();
1649 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1650 //m_Renderer->GetRenderWindow()->Render();
1653 void GuiMainWindow::checkSurfaceOrientation()
1655 CorrectSurfaceOrientation corr_surf;
1656 corr_surf();
1657 updateActors();
1658 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1659 //m_Renderer->GetRenderWindow()->Render();
1662 void GuiMainWindow::improveAspectRatio()
1664 GuiImproveAspectRatio impr_ar;
1665 impr_ar();
1666 updateActors();
1669 void GuiMainWindow::exportAsciiStl()
1671 StlWriter stl;
1672 stl.setFileTypeToASCII();
1673 stl();
1676 void GuiMainWindow::exportBinaryStl()
1678 StlWriter stl;
1679 stl.setFileTypeToBinary();
1680 stl();
1683 void GuiMainWindow::exportAsciiPly()
1685 PlyWriter ply;
1686 ply.setFileTypeToASCII();
1687 ply();
1690 void GuiMainWindow::exportBinaryPly()
1692 PlyWriter ply;
1693 ply.setFileTypeToBinary();
1694 ply();
1697 void GuiMainWindow::periodicUpdate()
1699 Operation::collectGarbage();
1700 updateStatusBar();
1703 void GuiMainWindow::viewRight()
1705 bool use_blender;
1706 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1707 getRenderer()->ResetCamera();
1708 double x[3];
1709 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1710 if (use_blender) {
1711 x[0] += 1;
1712 getRenderer()->GetActiveCamera()->SetPosition(x);
1713 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1714 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1715 } else {
1716 x[0] += 1;
1717 getRenderer()->GetActiveCamera()->SetPosition(x);
1718 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1719 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1721 getRenderer()->ResetCamera();
1722 getRenderWindow()->Render();
1725 void GuiMainWindow::viewLeft()
1727 bool use_blender;
1728 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1729 getRenderer()->ResetCamera();
1730 double x[3];
1731 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1732 if (use_blender) {
1733 x[0] -= 1;
1734 getRenderer()->GetActiveCamera()->SetPosition(x);
1735 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1736 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1737 } else {
1738 x[0] -= 1;
1739 getRenderer()->GetActiveCamera()->SetPosition(x);
1740 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1741 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1743 getRenderer()->ResetCamera();
1744 getRenderWindow()->Render();
1747 void GuiMainWindow::viewTop()
1749 bool use_blender;
1750 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1751 getRenderer()->ResetCamera();
1752 double x[3];
1753 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1754 if (use_blender) {
1755 x[2] += 1;
1756 getRenderer()->GetActiveCamera()->SetPosition(x);
1757 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1758 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1759 } else {
1760 x[1] += 1;
1761 getRenderer()->GetActiveCamera()->SetPosition(x);
1762 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1763 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1765 getRenderer()->ResetCamera();
1766 getRenderWindow()->Render();
1769 void GuiMainWindow::viewBottom()
1771 bool use_blender;
1772 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1773 getRenderer()->ResetCamera();
1774 double x[3];
1775 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1776 if (use_blender) {
1777 x[2] -= 1;
1778 getRenderer()->GetActiveCamera()->SetPosition(x);
1779 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1780 getRenderer()->GetActiveCamera()->SetViewUp(0,-1,0);
1781 } else {
1782 x[1] -= 1;
1783 getRenderer()->GetActiveCamera()->SetPosition(x);
1784 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1785 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1787 getRenderer()->ResetCamera();
1788 getRenderWindow()->Render();
1791 void GuiMainWindow::viewFront()
1793 bool use_blender;
1794 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1795 getRenderer()->ResetCamera();
1796 double x[3];
1797 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1798 if (use_blender) {
1799 x[1] -= 1;
1800 getRenderer()->GetActiveCamera()->SetPosition(x);
1801 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1802 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1803 } else {
1804 x[2] += 1;
1805 getRenderer()->GetActiveCamera()->SetPosition(x);
1806 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1807 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1809 getRenderer()->ResetCamera();
1810 getRenderWindow()->Render();
1813 void GuiMainWindow::viewBack()
1815 bool use_blender;
1816 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1817 getRenderer()->ResetCamera();
1818 double x[3];
1819 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1820 if (use_blender) {
1821 x[1] += 1;
1822 getRenderer()->GetActiveCamera()->SetPosition(x);
1823 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1824 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1825 } else {
1826 x[2] -= 1;
1827 getRenderer()->GetActiveCamera()->SetPosition(x);
1828 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1829 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1831 getRenderer()->ResetCamera();
1832 getRenderWindow()->Render();
1835 void GuiMainWindow::callFixSTL()
1837 FixSTL *fix;
1838 fix = new FixSTL();
1839 fix->setLockGui();
1840 (*fix)();
1841 updateBoundaryCodes(false);
1842 updateActors();
1845 void GuiMainWindow::callDeletePickedPoint()
1847 EG_STDINTERSLOT( DeletePickedPoint );
1850 void GuiMainWindow::editBoundaryConditions()
1852 GuiEditBoundaryConditions editbcs;
1853 editbcs.setBoundaryCodes(m_AllBoundaryCodes);
1854 editbcs.setMap(&m_bcmap);
1855 editbcs();
1858 void GuiMainWindow::configure()
1861 // Just to create initial entries in the settings file
1862 // so that the options menu isn't empty at first start.
1863 try {
1864 GridSmoother tmp01;
1865 GuiCreateBoundaryLayer tmp02;
1866 //TriSurfaceProjection tmp03;
1867 SurfaceMesher tmp04;
1868 UpdateDesiredMeshDensity tmp05;
1869 InsertPoints tmp06;
1870 RemovePoints tmp07;
1871 LaplaceSmoother tmp08;
1872 SwapTriangles tmp09;
1873 SolverTools tmp10;
1874 BlenderReader tmp11;
1875 } catch (Error err) {
1876 err.display();
1879 GuiSettingsViewer settings(&m_qset);
1880 settings.CreateViewer();
1881 settings.exec();
1883 getSet("General","enable undo+redo",false,m_undo_redo_enabled);
1886 void GuiMainWindow::about()
1888 //Load the HTML code snippet with the list of contributions
1889 QFileInfo fileinfo;
1890 fileinfo.setFile(":/contributions.htm");
1891 QFile file(fileinfo.filePath());
1892 if (!file.exists()) {
1893 qDebug() << "ERROR: " << fileinfo.filePath() << " not found.";
1894 EG_BUG;
1896 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1897 qDebug() << "ERROR: Failed to open file " << fileinfo.filePath();
1898 EG_BUG;
1900 QTextStream text_stream(&file);
1901 QString contributionsIncluded = text_stream.readAll();
1902 file.close();
1905 //Do the About box
1906 QMessageBox box(this);
1908 QString title="ENGRID";
1909 QString version = QString("version=") + ENGRID_VERSION + "<br/>branch=" + GIT_BRANCH + "<br/>commit=" + GIT_SHA1;
1910 version += "<br/>built on ";
1911 version += QString(__DATE__);
1912 version += " at ";
1913 version += QString(__TIME__);
1915 QString address = tr("ENGRID is being developed and maintained by:<br/>"
1916 "enGits GmbH<br/>"
1917 "Langenbachstrasse 3<br/>"
1918 "79674 Todtnau<br/>"
1919 "Germany<br/>");
1921 QString mainurl="<a href=\"http://engits.eu/\">http://engits.eu</a>";
1922 QString mail="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1923 QString gnuurl="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1924 QString license=tr("ENGRID is licenced under the GPL version 3.<br/>"
1925 "(see ")+gnuurl+tr(" for details)<br/>");
1926 QString contributions=tr("Contributions:");
1928 box.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1929 "<h3>%1</h3>"
1930 "<p>%2</p>"
1931 "<p>%3</p>"
1932 "<p>Homepage: %4</p>"
1933 "<p>E-mail: %5</p>"
1934 "<p>%6</p></center>"
1935 "<p>%7</p><blockquote>%8</blockquote>")
1936 .arg(title).arg(version).arg(address).arg(mainurl).arg(mail).arg(license)
1937 .arg(contributions).arg(contributionsIncluded));
1938 box.setWindowTitle(tr("about ENGRID"));
1939 box.setIcon(QMessageBox::NoIcon);
1940 box.exec();
1944 ///\todo Why not use bcs = m_AllBoundaryCodes; ?
1945 void GuiMainWindow::getAllBoundaryCodes(QVector<int> &bcs)
1947 bcs.resize(m_AllBoundaryCodes.size());
1948 qCopy(m_AllBoundaryCodes.begin(), m_AllBoundaryCodes.end(), bcs.begin());
1949 qSort(bcs);
1952 QSet<int> GuiMainWindow::getAllBoundaryCodes()
1954 return m_AllBoundaryCodes;
1957 void GuiMainWindow::getDisplayBoundaryCodes(QSet<int> &bcs)
1959 bcs.clear();
1960 foreach (int bc, m_DisplayBoundaryCodes) {
1961 bcs.insert(bc);
1965 QList<VolumeDefinition> GuiMainWindow::getAllVols()
1967 QList<VolumeDefinition> vols;
1968 foreach(VolumeDefinition vol, m_VolMap) {
1969 vols.push_back(vol);
1971 return vols;
1974 void GuiMainWindow::setAllVols(QList<VolumeDefinition> vols)
1976 m_VolMap.clear();
1977 foreach (VolumeDefinition V, vols) {
1978 m_VolMap[V.getName()] = V;
1982 QList<PhysicalBoundaryCondition> GuiMainWindow::getAllPhysicalBoundaryConditions()
1984 QList<PhysicalBoundaryCondition> physical_boundary_conditions;
1985 foreach(PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
1986 physical_boundary_conditions.push_back(PBC);
1988 return physical_boundary_conditions;
1991 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList<PhysicalBoundaryCondition> physical_boundary_conditions)
1993 m_PhysicalBoundaryConditionsMap.clear();
1994 foreach (PhysicalBoundaryCondition PBC, physical_boundary_conditions) {
1995 m_PhysicalBoundaryConditionsMap[PBC.getName()] = PBC;
1999 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap<QString,PhysicalBoundaryCondition> physical_boundary_conditions) {
2000 m_PhysicalBoundaryConditionsMap = physical_boundary_conditions;
2003 void GuiMainWindow::createDefaultVol()
2005 QList<VolumeDefinition> vols = getAllVols();
2006 if (vols.size() == 0) {
2007 VolumeDefinition V("default", 1);
2008 QVector<int> bcs;
2009 getAllBoundaryCodes(bcs);
2010 foreach (int bc, bcs) {
2011 V.addBC(bc, 1);
2013 vols.append(V);
2014 setAllVols(vols);
2018 QString GuiMainWindow::getFilePath()
2020 QFileInfo fileinfo(m_CurrentFilename);
2021 return fileinfo.absolutePath()+"/";
2024 void GuiMainWindow::markOutputLine()
2026 cout << "\n****************************************\n";
2027 cout << qPrintable(QTime::currentTime().toString("hh:mm:ss"));
2028 cout << "\n****************************************\n" << endl;
2031 void GuiMainWindow::storeCadInterfaces(bool nosave)
2033 try {
2034 resetCadInterfaces();
2035 CgalTriCadInterface *cad = new CgalTriCadInterface(m_Grid);
2036 setUniversalCadInterface(cad);
2037 if (!nosave) {
2038 save();
2039 saveGrid(m_Grid, m_CurrentFilename + ".geo");
2042 } catch (Error E) {
2043 E.display();
2047 void GuiMainWindow::setUniversalCadInterface(CadInterface *cad_interface)
2049 m_UniCadInterface = cad_interface;
2050 cad_interface->setForegroundGrid(m_Grid);
2053 void GuiMainWindow::resetCadInterfaces()
2055 delete m_UniCadInterface;
2056 m_UniCadInterface = NULL;
2057 foreach (CadInterface* cad_interface, m_CadInterfaces) {
2058 delete cad_interface;
2060 m_CadInterfaces.clear();
2063 CadInterface *GuiMainWindow::getCadInterface(int bc, bool allow_null)
2065 QString bc_txt;
2066 bc_txt.setNum(bc);
2067 if (!m_CadInterfaces.contains(bc)) {
2068 bc = 0;
2070 if (!m_CadInterfaces.contains(bc)) {
2071 if (m_UniCadInterface) {
2072 return m_UniCadInterface;
2074 if (allow_null) {
2075 return NULL;
2077 EG_ERR_RETURN("No surface projection found for boundary code " + bc_txt);
2079 return m_CadInterfaces[bc];
2082 bool GuiMainWindow::checkCadInterfaces()
2084 bool ok = true;
2085 if (!m_UniCadInterface) {
2086 foreach (int bc, m_AllBoundaryCodes) {
2087 if (!m_CadInterfaces.contains(bc)) {
2088 ok = false;
2089 break;
2093 return ok;
2096 void GuiMainWindow::openRecent(QAction *action)
2098 qDebug()<<"GuiMainWindow::openRecent called";
2099 QString file_name = action->text().right(action->text().length()-23);
2100 this->open(file_name);
2103 void GuiMainWindow::readRecentFiles()
2105 m_RecentFiles.clear();
2106 this->recentFileMenu()->clear();
2107 QStringList file_names = m_qset.value("FileNames").toStringList();
2108 QStringList file_dates = m_qset.value("FileDates").toStringList();
2109 int N = min(10,m_qset.value("NumberOfFiles").toInt());
2110 // cout << "NumberOfFiles=" << N << endl;
2111 for (int i = 0; i < N; ++i) {
2112 QString new_file = file_names.at(i);
2113 QString date_text = file_dates.at(i);
2114 QDateTime date = QDateTime::fromString(date_text,"dd.MM.yyyy_hh:mm:ss");
2115 addRecentFile(new_file,date);
2119 void GuiMainWindow::writeRecentFiles()
2121 m_qset.setValue("NumberOfFiles",m_RecentFiles.size());
2122 QStringList file_names;
2123 QStringList file_dates;
2124 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2125 QString file_name = i.key();
2126 QString date_text = i.value().toString("dd.MM.yyyy_hh:mm:ss");
2127 file_names.append(file_name);
2128 file_dates.append(date_text);
2130 m_qset.setValue("FileNames",file_names);
2131 m_qset.setValue("FileDates",file_dates);
2134 void GuiMainWindow::addRecentFile(QString file_name, QDateTime date)
2136 m_RecentFiles[file_name] = date;
2137 while (m_RecentFiles.size() > 10) {
2138 QMap<QString,QDateTime>::iterator i,j;
2139 QDateTime old = QDateTime::currentDateTime();
2140 for (i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2141 if (i.value() <= old) {
2142 old = i.value();
2143 j = i;
2146 m_RecentFiles.erase(j);
2148 this->recentFileMenu()->clear();
2149 QMap<int,QString> menu_map;
2150 QDateTime now = QDateTime::currentDateTime();
2151 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2152 QString action_text = i.value().toString("dd.MM.yyyy hh:mm:ss");
2153 action_text += " -> ";
2154 action_text += i.key();
2155 menu_map[i.value().secsTo(now)] = action_text;
2158 for (QMap<int,QString>::iterator i = menu_map.begin(); i != menu_map.end(); ++i) {
2159 QAction *action = new QAction(i.value(),this);
2160 this->recentFileMenu()->addAction(action);
2165 void GuiMainWindow::callInsertNewCell()
2167 bool ok1,ok2,ok3,ok4;
2168 vtkIdType pts[3];
2169 #if QT_VERSION < 0x040500
2170 pts[0] = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2171 pts[1] = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2172 pts[2] = QInputDialog::getInteger(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
2173 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);
2174 #else
2175 pts[0] = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2176 pts[1] = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2177 pts[2] = QInputDialog::getInt(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
2178 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);
2179 #endif
2180 if (ok1 && ok2 && ok3 && ok4) {
2181 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2182 allocateGrid( new_grid, m_Grid->GetNumberOfCells() + 1, m_Grid->GetNumberOfPoints() );
2183 makeCopyNoAlloc(m_Grid, new_grid);
2184 vtkIdType id_new_cell = new_grid->InsertNextCell(VTK_TRIANGLE, 3, pts);
2185 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2186 makeCopy(new_grid, m_Grid);
2187 m_Grid->Modified();
2188 QMessageBox::information(NULL, "new cell", tr("The new cell has ID = %1").arg(id_new_cell));
2189 qDebug()<<tr("The new cell has ID = %1").arg(id_new_cell);
2193 void GuiMainWindow::callMergeNodes()
2195 bool ok1,ok2;
2196 #if QT_VERSION < 0x040500
2197 vtkIdType id_node1 = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2198 vtkIdType id_node2 = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2199 #else
2200 vtkIdType id_node1 = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2201 vtkIdType id_node2 = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2202 #endif
2203 if (ok1 && ok2) {
2204 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2205 allocateGrid( new_grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints() - 1 );
2207 QVector<vtkIdType> old2new_nodes(m_Grid->GetNumberOfPoints(), -1);
2208 QVector<vtkIdType> old2new_cells(m_Grid->GetNumberOfCells(), -1);
2210 vtkIdType id_new_node = 0;
2211 for (vtkIdType id_node = 0; id_node < m_Grid->GetNumberOfPoints(); ++id_node) {
2212 if(id_node!=id_node1 && id_node!=id_node2) {
2213 vec3_t x;
2214 m_Grid->GetPoints()->GetPoint(id_node, x.data());
2215 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2216 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2217 old2new_nodes[id_node] = id_new_node;
2218 id_new_node++;
2220 else if(id_node==id_node1) {
2221 vec3_t x1;
2222 m_Grid->GetPoints()->GetPoint(id_node1, x1.data());
2223 vec3_t x2;
2224 m_Grid->GetPoints()->GetPoint(id_node2, x2.data());
2225 vec3_t x = 0.5*(x1+x2);
2226 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2227 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2228 old2new_nodes[id_node1] = id_new_node;
2229 old2new_nodes[id_node2] = id_new_node;
2230 id_new_node++;
2232 else {
2236 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
2237 EG_GET_CELL(id_cell, m_Grid);
2238 for (int i = 0; i < num_pts; ++i) {
2239 ptIds->SetId(i, old2new_nodes[pts[i]]);
2241 vtkIdType id_new_cell = new_grid->InsertNextCell(type_cell, ptIds);
2242 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2245 makeCopy(new_grid, m_Grid);
2246 m_Grid->Modified();
2247 qDebug()<<"The fusion is complete.";
2252 void GuiMainWindow::onEsc()
2254 setPickMode(true, true);
2255 pickCell(-1);
2256 m_CellPicker->Pick(-1e99,-1e99,0,m_Renderer);
2257 updateActors(true);
2258 updateStatusBar();
2261 void GuiMainWindow::resetProgress(QString info_text, int p_max)
2263 m_StatusInfoLabel->setText(info_text);
2264 m_StatusProgressBar->setMaximum(p_max);
2265 m_StatusProgressBar->setValue(0);
2266 QApplication::processEvents();
2269 void GuiMainWindow::setProgress(int p)
2271 m_StatusProgressBar->setValue(p);
2272 for (int i = 0; i < 3; ++i) {
2273 QApplication::processEvents();
2277 void GuiMainWindow::lock()
2279 m_Mutex.lock();
2282 void GuiMainWindow::unlock()
2284 m_Mutex.unlock();
2287 bool GuiMainWindow::tryLock()
2289 return m_Mutex.tryLock();
2292 BoundaryCondition GuiMainWindow::getBC(BoundaryCondition BC)
2294 int last_code = 0;
2295 foreach (BoundaryCondition bc, m_bcmap.values()) {
2296 if (bc == BC) {
2297 return bc;
2299 last_code = max(last_code, bc.getCode());
2301 BC.setCode(last_code + 1);
2302 setBC(BC.getCode(), BC);
2303 return BC;