get it to compile on MAC OSX 10.9
[engrid-github.git] / src / libengrid / guimainwindow.cpp
blob954cff336a957bb0d7f9ad9aa98ac11353db84c3
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 "guiselectboundarycodes.h"
23 #include "guiimproveaspectratio.h"
24 #include "guinormalextrusion.h"
25 #include "guisetboundarycode.h"
26 #include "guipick.h"
28 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
29 #include "stlreader.h"
30 #include "gmshreader.h"
31 #include "gmshwriter.h"
32 #include "neutralwriter.h"
33 #include "stlwriter.h"
34 #include "plywriter.h"
35 #include "correctsurfaceorientation.h"
36 #include "guieditboundaryconditions.h"
37 #include "laplacesmoother.h"
38 #include "swaptriangles.h"
39 #include "triangularcadinterface.h"
40 #include "cgaltricadinterface.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>
55 #include <vtkFileOutputWindow.h>
57 #include <QFileDialog>
58 #include <QFileSystemWatcher>
59 #include <QFileInfo>
60 #include <QAction>
61 #include <stdlib.h>
62 #include <stdio.h>
64 #if !defined( _WIN32 ) //required for "dup" and "dup2" on POSIX systems
65 #include <unistd.h>
66 #endif
68 #include "geometrytools.h"
69 #include "engrid_version.h"
71 using namespace GeometryTools;
73 #include "guisettingsviewer.h"
74 #include "guitransform.h"
75 #include "egvtkinteractorstyle.h"
76 #include "showinfo.h"
77 #include "engrid_version.h"
79 QString GuiMainWindow::m_cwd = ".";
80 QSettings GuiMainWindow::m_qset("enGits", QString("enGrid-") + ENGRID_VERSION_STRING);
81 GuiMainWindow* GuiMainWindow::THIS = NULL;
82 QMutex GuiMainWindow::m_Mutex;
83 bool GuiMainWindow::m_UnSaved = true;
85 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
87 setupGuiMainWindow();
88 if(m_open_last) {
89 if(m_qset.contains("LatestFile")) {
90 // qDebug()<<"Opening latest";
91 open(m_qset.value("LatestFile").toString());
96 GuiMainWindow::GuiMainWindow(QString file_name) : QMainWindow(NULL)
98 setupGuiMainWindow();
99 open(file_name);
102 void GuiMainWindow::setupGuiMainWindow()
104 //QMenuBar *menubar = new QMenuBar(0);
105 //menubar->setNativeMenuBar(true);
106 //setMenuBar(menubar);
107 ui.setupUi(this);
108 THIS = this;
110 // restore window size
111 if(m_qset.contains("GuiMainWindow")) {
112 setGeometry(m_qset.value("GuiMainWindow").toRect());
114 else {
115 this->setWindowState(Qt::WindowMaximized);
118 // restore dockwidget positions
119 if(m_qset.contains("dockWidget_states")) {
120 restoreState(m_qset.value("dockWidget_states").toByteArray());
122 else {
123 tabifyDockWidget(ui.dockWidget_output, ui.dockWidget_node_cell_info);
124 tabifyDockWidget(ui.dockWidget_DisplayOptions, ui.dockWidget_DebuggingUtilities);
125 ui.dockWidget_node_cell_info->hide();
126 ui.dockWidget_DebuggingUtilities->hide();
129 # include "std_connections.h"
131 if (m_qset.contains("working_directory")) {
132 m_cwd = m_qset.value("working_directory").toString();
135 setupVtk();
137 resetOperationCounter();//clears undo/redo list and disables undo/redo
138 m_CurrentFilename = "untitled.egc";
139 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
140 setUnsaved(true);
142 m_StatusInfoLabel = new QLabel(this);
143 statusBar()->addWidget(m_StatusInfoLabel);
144 m_StatusInfoLabel->setText("");
146 m_StatusProgressBar = new QProgressBar(this);
147 statusBar()->addWidget(m_StatusProgressBar);
149 m_StatusLabel = new QLabel(this);
150 statusBar()->addWidget(m_StatusLabel);
152 QString txt = "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms, 0 polys), ";
153 txt += "0 surface cells (0 triangles, 0 quads, 0 polys), 0 nodes";
154 m_StatusLabel->setText(txt);
155 ui.label_node_cell_info->setText(txt);
157 m_OriginalCoutBuffer = cout.rdbuf();
158 cout.rdbuf(&m_CoutBuffer);
159 m_Log = true;
161 m_Busy = false;
163 setPickMode(true,true);
164 m_PickedPoint = -1;
165 m_PickedCell = -1;
167 updateStatusBar();
169 connect(&m_GarbageTimer, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
170 m_GarbageTimer.start(1000);
172 connect(&m_LogTimer, SIGNAL(timeout()), this, SLOT(updateOutput()));
173 m_LogTimer.start(1000);
175 bool exp_features=false;
176 getSet("General","enable experimental features",false,exp_features);
177 getSet("General","enable undo+redo",false,m_undo_redo_enabled);
178 bool undo_redo_mode;
179 getSet("General","use RAM for undo+redo operations",false,undo_redo_mode);
180 getSet("General", "open last used file on startup", false, m_open_last);
182 ui.actionMirrorMesh->setEnabled(exp_features);
183 ui.actionBooleanOperation->setEnabled(exp_features);
184 ui.actionCreateHexCore->setEnabled(exp_features);
185 ui.actionOptimiseOrthogonalty->setEnabled(exp_features);
186 ui.actionImportFluentCase->setEnabled(exp_features);
188 m_ReferenceSize=0.2;
190 ui.doubleSpinBox_HueMin->setValue(0.667);
191 ui.doubleSpinBox_HueMax->setValue(0);
193 egvtkInteractorStyle *style = egvtkInteractorStyle::New();
194 getInteractor()->SetInteractorStyle(style);
195 style->Delete();
197 // initialise XML document
198 m_XmlHandler = new XmlHandler("engridcase");
199 // this->resetXmlDoc();
201 m_SolverIndex = 0;
203 readRecentFiles();
205 // load plugins
206 QString plugin_path;
207 getSet("General", "plugin path", "/usr/lib/engrid", plugin_path);
208 QDir plugin_dir(plugin_path);
209 m_PluginOperations.clear();
210 foreach (QString file_name, plugin_dir.entryList(QDir::Files)) {
211 if (file_name.right(3) == ".so") {
212 cout << qPrintable(plugin_dir.absoluteFilePath(file_name)) << endl;
213 QPluginLoader loader(plugin_dir.absoluteFilePath(file_name));
214 QObject *qobject = loader.instance();
215 if (!qobject) {
216 cout << "an error occurred while loading the plugins:\n";
217 cout << qPrintable(loader.errorString()) << "\n" << endl;
219 if (Operation *operation = qobject_cast<Operation*>(qobject)) {
220 //operation->setLockGui();
221 QAction *action = new QAction(operation->getMenuText(), this);
222 connect(action, SIGNAL(triggered()), this, SLOT(pluginCalled()));
223 m_PluginOperations[action] = operation;
224 ui.menuPlugins->addAction(action);
229 m_EscAction = new QAction("escape", this);
230 addAction(m_EscAction);
231 m_EscAction->setShortcut(QKeySequence(Qt::Key_Escape));
232 connect(m_EscAction, SIGNAL(triggered()), this, SLOT(onEsc()));
234 m_UniCadInterface = NULL;
236 //end of GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
238 void GuiMainWindow::pluginCalled()
240 QAction *action = qobject_cast<QAction*>(QObject::sender());
241 if (action) {
242 Operation *operation = m_PluginOperations[action];
243 operation->operator()();
247 void GuiMainWindow::resetXmlDoc()
249 m_XmlHandler->resetXmlDoc();
252 GuiMainWindow::~GuiMainWindow()
254 writeRecentFiles();
256 m_qset.setValue("GuiMainWindow", this->geometry());
257 m_qset.setValue("dockWidget_states", this->saveState());
259 cout.rdbuf(m_OriginalCoutBuffer);
261 delete m_XmlHandler;
264 void GuiMainWindow::setupVtk()
267 // avoid VTK pop-up window on Windows
268 #ifdef WIN32
269 vtkFileOutputWindow *w = vtkFileOutputWindow::New();
270 QString vtk_log_file = m_qset.value("tmp_directory").toString() + "/enGrid-vtk-errors.txt";
271 w->SetFileName(qPrintable(vtk_log_file));
272 vtkOutputWindow::SetInstance(w);
273 w->Delete();
274 #endif
276 // colour settings
277 getSet("Colours", "'A' faces (1-red)", 0.5, m_ColAR);
278 getSet("Colours", "'A' faces (2-green)", 1.0, m_ColAG);
279 getSet("Colours", "'A' faces (3-blue)", 0.5, m_ColAB);
281 getSet("Colours", "'B' faces (1-red)", 1.0, m_ColBR);
282 getSet("Colours", "'B' faces (2-green)", 1.0, m_ColBG);
283 getSet("Colours", "'B' faces (3-blue)", 0.5, m_ColBB);
285 getSet("Colours", " tetras (1-red)", 1.0, m_ColTetraR);
286 getSet("Colours", " tetras (2-green)", 0.0, m_ColTetraG);
287 getSet("Colours", " tetras (3-blue)", 0.0, m_ColTetraB);
289 getSet("Colours", " prisms (1-red)", 0.0, m_ColPrismR);
290 getSet("Colours", " prisms (2-green)", 1.0, m_ColPrismG);
291 getSet("Colours", " prisms (3-blue)", 0.0, m_ColPrismB);
293 getSet("Colours", " pyramids (1-red)", 1.0, m_ColPyraR);
294 getSet("Colours", " pyramids (2-green)", 1.0, m_ColPyraG);
295 getSet("Colours", " pyramids (3-blue)", 0.0, m_ColPyraB);
297 getSet("Colours", " hexes (1-red)", 0.0, m_ColHexR);
298 getSet("Colours", " hexes (2-green)", 0.7, m_ColHexG);
299 getSet("Colours", " hexes (3-blue)", 1.0, m_ColHexB);
301 getSet("Colours", " polys (1-red)", 0.7, m_ColPolyR);
302 getSet("Colours", " polys (2-green)", 1.0, m_ColPolyG);
303 getSet("Colours", " polys (3-blue)", 1.0, m_ColPolyB);
305 m_Grid = vtkUnstructuredGrid::New();
306 m_Renderer = vtkRenderer::New();
307 getRenderWindow()->AddRenderer(m_Renderer);
309 // coordinate axes
310 m_Axes = vtkCubeAxesActor2D::New();
312 m_Axes->SetCamera(getRenderer()->GetActiveCamera());
313 getRenderer()->AddActor(m_Axes);
314 m_Axes->SetVisibility(0);
316 // surface pipelines
317 m_BackfaceProperty = vtkProperty::New();
318 m_SurfaceFilter = vtkDataSetSurfaceFilter::New();
319 m_SurfaceMapper = vtkPolyDataMapper::New();
320 m_SurfaceWireMapper = vtkPolyDataMapper::New();
321 m_BCodesFilter = vtkEgBoundaryCodesFilter::New();
322 m_LookupTable = vtkLookupTable::New();
323 m_SurfaceActor = vtkActor::New();
324 m_SurfaceWireActor = vtkActor::New();
325 m_LegendActor = vtkScalarBarActor::New();
327 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
328 m_BCodesFilter->SetInputData(m_Grid);
329 m_SurfaceFilter->SetInputConnection(m_BCodesFilter->GetOutputPort());
330 m_SurfaceMapper->SetInputConnection(m_SurfaceFilter->GetOutputPort());
331 m_SurfaceWireMapper->SetInputConnection(m_SurfaceFilter->GetOutputPort());
332 m_SurfaceMapper->SetLookupTable(m_LookupTable);
333 m_SurfaceActor->GetProperty()->SetRepresentationToSurface();
334 m_SurfaceActor->GetProperty()->SetColor(m_ColAR, m_ColAG, m_ColAB);
335 m_SurfaceActor->SetBackfaceProperty(m_BackfaceProperty);
336 m_SurfaceActor->GetBackfaceProperty()->SetColor(m_ColBR, m_ColBG, m_ColBB);
337 m_SurfaceActor->SetMapper(m_SurfaceMapper);
338 getRenderer()->AddActor(m_SurfaceActor);
339 m_SurfaceActor->SetVisibility(1);
340 m_LegendActor->SetLookupTable(m_LookupTable);
341 getRenderer()->AddActor(m_LegendActor);
342 m_LegendActor->SetVisibility(0);
343 m_SurfaceWireActor->GetProperty()->SetRepresentationToWireframe();
344 m_SurfaceWireActor->GetProperty()->SetColor(0,0,1);
345 m_SurfaceWireActor->SetMapper(m_SurfaceWireMapper);
346 getRenderer()->AddActor(m_SurfaceWireActor);
347 m_SurfaceWireActor->SetVisibility(1);
349 // tetra pipline
350 m_ExtrTetras = vtkEgExtractVolumeCells::New();
351 m_TetraActor = vtkActor::New();
352 m_TetraGeometry = vtkDataSetSurfaceFilter::New();
353 m_TetraMapper = vtkPolyDataMapper::New();
355 m_ExtrTetras->SetInputData(m_Grid);
356 m_ExtrTetras->SetAllOff();
357 m_ExtrTetras->SetTetrasOn();;
358 m_TetraGeometry->SetInputConnection(m_ExtrTetras->GetOutputPort());
359 m_TetraMapper->SetInputConnection(m_TetraGeometry->GetOutputPort());
360 m_TetraActor->SetMapper(m_TetraMapper);
361 m_TetraActor->GetProperty()->SetColor(m_ColTetraR, m_ColTetraG, m_ColTetraB);
362 getRenderer()->AddActor(m_TetraActor);
363 m_TetraActor->SetVisibility(0);
365 // pyramid pipeline
366 m_PyramidActor = vtkActor::New();
367 m_ExtrPyramids = vtkEgExtractVolumeCells::New();
368 m_PyramidGeometry = vtkDataSetSurfaceFilter::New();
369 m_PyramidMapper = vtkPolyDataMapper::New();
371 m_ExtrPyramids->SetInputData(m_Grid);
372 m_ExtrPyramids->SetAllOff();
373 m_ExtrPyramids->SetPyramidsOn();
374 m_PyramidGeometry->SetInputConnection(m_ExtrPyramids->GetOutputPort());
375 m_PyramidMapper->SetInputConnection(m_PyramidGeometry->GetOutputPort());
376 m_PyramidActor->SetMapper(m_PyramidMapper);
377 m_PyramidActor->GetProperty()->SetColor(m_ColPyraR, m_ColPyraG, m_ColPyraB);
378 getRenderer()->AddActor(m_PyramidActor);
379 m_PyramidActor->SetVisibility(0);
381 // wedge pipeline
382 m_WedgeActor = vtkActor::New();
383 m_ExtrWedges = vtkEgExtractVolumeCells::New();
384 m_WedgeGeometry = vtkDataSetSurfaceFilter::New();
385 m_WedgeMapper = vtkPolyDataMapper::New();
387 m_ExtrWedges->SetInputData(m_Grid);
388 m_ExtrWedges->SetAllOff();
389 m_ExtrWedges->SetWedgesOn();
390 m_WedgeGeometry->SetInputConnection(m_ExtrWedges->GetOutputPort());
391 m_WedgeMapper->SetInputConnection(m_WedgeGeometry->GetOutputPort());
392 m_WedgeActor->SetMapper(m_WedgeMapper);
393 m_WedgeActor->GetProperty()->SetColor(m_ColPrismR, m_ColPrismG, m_ColPrismB);
394 getRenderer()->AddActor(m_WedgeActor);
395 m_WedgeActor->SetVisibility(0);
397 // hexa pipeline
398 m_HexaActor = vtkActor::New();
399 m_ExtrHexes = vtkEgExtractVolumeCells::New();
400 m_HexaGeometry = vtkDataSetSurfaceFilter::New();
401 m_HexaMapper = vtkPolyDataMapper::New();
403 m_ExtrHexes->SetInputData(m_Grid);
404 m_ExtrHexes->SetAllOff();
405 m_ExtrHexes->SetHexesOn();
406 m_HexaGeometry->SetInputConnection(m_ExtrHexes->GetOutputPort());
407 m_HexaMapper->SetInputConnection(m_HexaGeometry->GetOutputPort());
408 m_HexaActor->SetMapper(m_HexaMapper);
409 m_HexaActor->GetProperty()->SetColor(m_ColHexR, m_ColHexG, m_ColHexB);
410 getRenderer()->AddActor(m_HexaActor);
411 m_HexaActor->SetVisibility(0);
413 // polyhedra pipeline
414 m_PolyhedraActor = vtkActor::New();
415 m_ExtrPolyhedra = vtkEgExtractVolumeCells::New();
416 m_PolyhedraGeometry = vtkDataSetSurfaceFilter::New();
417 m_PolyhedraMapper = vtkPolyDataMapper::New();
419 m_ExtrPolyhedra->SetInputData(m_Grid);
420 m_ExtrPolyhedra->SetAllOff();
421 m_ExtrPolyhedra->SetPolysOn();
422 m_PolyhedraGeometry->SetInputConnection(m_ExtrPolyhedra->GetOutputPort());
423 m_PolyhedraMapper->SetInputConnection(m_PolyhedraGeometry->GetOutputPort());
424 m_PolyhedraActor->SetMapper(m_PolyhedraMapper);
425 m_PolyhedraActor->GetProperty()->SetColor(m_ColPolyR, m_ColPolyG, m_ColPolyB);
426 getRenderer()->AddActor(m_PolyhedraActor);
427 m_PolyhedraActor->SetVisibility(0);
429 // volume wire pipeline
430 m_VolumeWireActor = vtkActor::New();
431 m_ExtrVol = vtkEgExtractVolumeCells::New();
432 m_VolumeGeometry = vtkDataSetSurfaceFilter::New();
433 m_VolumeWireMapper = vtkPolyDataMapper::New();
435 m_ExtrVol->SetInputData(m_Grid);
436 m_ExtrVol->SetAllOn();
437 m_VolumeGeometry->SetInputConnection(m_ExtrVol->GetOutputPort());
438 m_VolumeWireMapper->SetInputConnection(m_VolumeGeometry->GetOutputPort());
439 m_VolumeWireActor->SetMapper(m_VolumeWireMapper);
440 m_VolumeWireActor->GetProperty()->SetRepresentationToWireframe();
441 m_VolumeWireActor->GetProperty()->SetColor(0,0,1);
442 getRenderer()->AddActor(m_VolumeWireActor);
443 m_VolumeWireActor->SetVisibility(0);
445 // picker stuff
446 m_PickSphere = vtkSphereSource::New();
447 m_PickMapper = vtkPolyDataMapper::New();
448 m_PickActor = vtkActor::New();
449 m_CellPicker = vtkCellPicker::New();
450 m_PointPicker = vtkPointPicker::New();
452 m_PickSphere->SetRadius(0.25); //in case the user starts picking points instead of cells
453 m_PickMapper->SetInputConnection(m_PickSphere->GetOutputPort());
454 m_PickActor->SetMapper(m_PickMapper);
455 m_PickActor->GetProperty()->SetRepresentationToSurface();
456 m_PickActor->GetProperty()->SetColor(0,0,1);
457 m_PickActor->VisibilityOff();
458 getRenderer()->AddActor(m_PickActor);
460 vtkCallbackCommand *cbc = vtkCallbackCommand::New();
461 cbc->SetCallback(pickCallBack);
463 m_CellPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
464 m_PointPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
465 m_PickedObject = 0;
467 viewFront();
470 void GuiMainWindow::updateOutput()
472 if (m_Log) {
473 QString txt = m_CoutBuffer.str().c_str();
474 m_CoutBuffer.str("");
475 if (txt.right(1) == "\n") {
476 txt = txt.left(txt.size()-1);
478 if (txt.size() > 0) {
479 ui.textEditOutput->append(txt);
484 void GuiMainWindow::exit()
486 QCoreApplication::exit();
489 vtkRenderWindow* GuiMainWindow::getRenderWindow()
491 return ui.qvtkWidget->GetRenderWindow();
494 vtkRenderer* GuiMainWindow::getRenderer()
496 return m_Renderer;
499 QVTKInteractor* GuiMainWindow::getInteractor()
501 return ui.qvtkWidget->GetInteractor();
504 QString GuiMainWindow::getCwd()
506 return m_cwd;
509 void GuiMainWindow::setCwd(QString dir)
511 m_cwd = dir;
512 m_qset.setValue("working_directory",dir);
515 void GuiMainWindow::setUnsaved(bool unsaved)
517 m_UnSaved = unsaved;
520 void GuiMainWindow::scaleToData()
522 int current_field=ui.comboBox_Field->currentIndex();
523 if(current_field>0)
525 double range[2];
527 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
528 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
529 cout<<"current_field="<<current_field<<endl;
530 cout<<"range[0]="<<range[0]<<endl;
531 cout<<"range[1]="<<range[1]<<endl;
532 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
533 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
534 ui.doubleSpinBox_FieldMin->setValue(range[0]);
535 ui.doubleSpinBox_FieldMax->setValue(range[1]);
539 void GuiMainWindow::setClipX(const QString &txt)
541 m_ExtrVol->Setx(txt.toDouble());
542 m_ExtrTetras->Setx(txt.toDouble());
543 m_ExtrPyramids->Setx(txt.toDouble());
544 m_ExtrWedges->Setx(txt.toDouble());
545 m_ExtrHexes->Setx(txt.toDouble());
546 m_ExtrPolyhedra->Setx(txt.toDouble());
549 void GuiMainWindow::setClipY(const QString &txt)
551 m_ExtrVol->Sety(txt.toDouble());
552 m_ExtrTetras->Sety(txt.toDouble());
553 m_ExtrPyramids->Sety(txt.toDouble());
554 m_ExtrWedges->Sety(txt.toDouble());
555 m_ExtrHexes->Sety(txt.toDouble());
556 m_ExtrPolyhedra->Sety(txt.toDouble());
559 void GuiMainWindow::setClipZ(const QString &txt)
561 m_ExtrVol->Setz(txt.toDouble());
562 m_ExtrTetras->Setz(txt.toDouble());
563 m_ExtrPyramids->Setz(txt.toDouble());
564 m_ExtrWedges->Setz(txt.toDouble());
565 m_ExtrHexes->Setz(txt.toDouble());
566 m_ExtrPolyhedra->Setz(txt.toDouble());
569 void GuiMainWindow::setClipNX(const QString &txt)
571 m_ExtrVol->Setnx(txt.toDouble());
572 m_ExtrTetras->Setnx(txt.toDouble());
573 m_ExtrPyramids->Setnx(txt.toDouble());
574 m_ExtrWedges->Setnx(txt.toDouble());
575 m_ExtrHexes->Setnx(txt.toDouble());
576 m_ExtrPolyhedra->Setnx(txt.toDouble());
579 void GuiMainWindow::setClipNY(const QString &txt)
581 m_ExtrVol->Setny(txt.toDouble());
582 m_ExtrTetras->Setny(txt.toDouble());
583 m_ExtrPyramids->Setny(txt.toDouble());
584 m_ExtrWedges->Setny(txt.toDouble());
585 m_ExtrHexes->Setny(txt.toDouble());
586 m_ExtrPolyhedra->Setny(txt.toDouble());
589 void GuiMainWindow::setClipNZ(const QString &txt)
591 m_ExtrVol->Setnz(txt.toDouble());
592 m_ExtrTetras->Setnz(txt.toDouble());
593 m_ExtrPyramids->Setnz(txt.toDouble());
594 m_ExtrWedges->Setnz(txt.toDouble());
595 m_ExtrHexes->Setnz(txt.toDouble());
596 m_ExtrPolyhedra->Setnz(txt.toDouble());
599 void GuiMainWindow::updateSurfaceActors(bool forced)
601 if (ui.checkBoxSurface->isChecked()) {
602 if (forced) {
603 m_SurfaceFilter->Update();
606 // fill node field combobox
607 int current_field=ui.comboBox_Field->currentIndex();
608 ui.comboBox_Field->clear();
609 ui.comboBox_Field->addItem("None");
610 for (int i = 0; i < m_Grid->GetPointData()->GetNumberOfArrays(); ++i) {
611 ui.comboBox_Field->addItem(m_Grid->GetPointData()->GetArrayName(i));
613 if(current_field == -1) {
614 ui.comboBox_Field->setCurrentIndex(0);
615 } else {
616 ui.comboBox_Field->setCurrentIndex(current_field);
619 // fill cell field combobox
620 int current_cell_field = ui.comboBox_CellTextField->currentIndex();
621 ui.comboBox_CellTextField->clear();
622 ui.comboBox_CellTextField->addItem("Cell ID");
623 for (int i = 0; i < m_SurfaceFilter->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i) {
624 ui.comboBox_CellTextField->addItem(m_Grid->GetCellData()->GetArrayName(i));
626 if(current_cell_field == -1) {
627 ui.comboBox_CellTextField->setCurrentIndex(0);
628 } else {
629 ui.comboBox_CellTextField->setCurrentIndex(current_cell_field);
631 current_field = ui.comboBox_Field->currentIndex();
632 if(current_field > 0) {
633 double range[2];
634 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
635 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
636 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
639 if(ui.comboBox_Field->currentIndex() > 0) {
640 m_SurfaceMapper->SetColorModeToMapScalars();
641 m_LookupTable->SetNumberOfColors(ui.spinBox_Color->value());
642 m_LookupTable->SetHueRange(ui.doubleSpinBox_HueMin->value(),ui.doubleSpinBox_HueMax->value());
643 m_LookupTable->Build();
644 m_SurfaceMapper->SetScalarModeToUsePointFieldData();
645 m_SurfaceMapper->ColorByArrayComponent(qPrintable(ui.comboBox_Field->currentText()),0);
646 m_SurfaceMapper->SetScalarRange(ui.doubleSpinBox_FieldMin->value(),ui.doubleSpinBox_FieldMax->value());
647 m_SurfaceMapper->ScalarVisibilityOn();
648 if(ui.checkBox_Legend->checkState()) {
649 m_LegendActor->SetVisibility(1);
650 } else {
651 m_LegendActor->SetVisibility(0);
653 } else {
654 m_SurfaceMapper->SetColorModeToDefault();
655 m_SurfaceMapper->ScalarVisibilityOff();
656 m_LegendActor->SetVisibility(0);
658 if (forced) {
659 m_BCodesFilter->Update();
661 if(ui.checkBox_ShowPickSphere->checkState()) {
662 if(m_UseVTKInteractor) {
663 if(ui.radioButton_CellPicker->isChecked()) {
664 getInteractor()->SetPicker(m_CellPicker);
665 vtkIdType id_cell = getPickedCell();
666 pickCell(id_cell);
667 } else {
668 getInteractor()->SetPicker(m_PointPicker);
669 vtkIdType id_node = getPickedPoint();
670 pickPoint(id_node);
672 } else {
673 if (ui.radioButton_CellPicker->isChecked()) {
674 pickCell(m_PickedCell);
675 } else {
676 pickPoint(m_PickedPoint);
680 m_SurfaceActor->SetVisibility(1);
681 m_SurfaceWireActor->SetVisibility(1);
682 } else {
683 m_SurfaceActor->SetVisibility(0);
684 m_SurfaceWireActor->SetVisibility(0);
688 void GuiMainWindow::updateVolumeActors(bool forced)
690 if (ui.checkBoxVolume->isChecked()) {
691 if (ui.checkBoxTetra->isChecked()) {
692 m_ExtrVol->SetTetrasOn();
693 if (ui.checkBoxClip->isChecked()) {
694 m_ExtrTetras->SetClippingOn();
695 } else {
696 m_ExtrTetras->SetClippingOff();
698 if (forced) {
699 m_TetraGeometry->Update();
701 m_TetraActor->SetVisibility(1);
702 } else {
703 m_ExtrVol->SetTetrasOff();
704 m_TetraActor->SetVisibility(0);
706 if (ui.checkBoxPyramid->isChecked()) {
707 m_ExtrVol->SetPyramidsOn();
708 if (ui.checkBoxClip->isChecked()) {
709 m_ExtrPyramids->SetClippingOn();
710 } else {
711 m_ExtrPyramids->SetClippingOff();
713 if (forced) {
714 m_PyramidGeometry->Update();
716 m_PyramidActor->SetVisibility(1);
717 } else {
718 m_ExtrVol->SetPyramidsOff();
719 m_PyramidActor->SetVisibility(0);
721 if (ui.checkBoxWedge->isChecked()) {
722 m_ExtrVol->SetWedgesOn();
723 if (ui.checkBoxClip->isChecked()) {
724 m_ExtrWedges->SetClippingOn();
725 } else {
726 m_ExtrWedges->SetClippingOff();
728 if (forced) {
729 m_WedgeGeometry->Update();
731 m_WedgeActor->SetVisibility(1);
732 } else {
733 m_ExtrVol->SetWedgesOff();
734 m_WedgeActor->SetVisibility(0);
736 if (ui.checkBoxHexa->isChecked()) {
737 m_ExtrVol->SetHexesOn();
738 if (ui.checkBoxClip->isChecked()) {
739 m_ExtrHexes->SetClippingOn();
740 } else {
741 m_ExtrHexes->SetClippingOff();
743 if (forced) {
744 m_HexaGeometry->Update();
746 m_HexaActor->SetVisibility(1);
747 } else {
748 m_ExtrVol->SetHexesOff();
749 m_HexaActor->SetVisibility(0);
751 if (ui.checkBoxPoly->isChecked()) {
752 m_ExtrVol->SetPolysOn();
753 if (ui.checkBoxClip->isChecked()) {
754 m_ExtrPolyhedra->SetClippingOn();
755 } else {
756 m_ExtrPolyhedra->SetClippingOff();
758 if (forced) {
759 m_PolyhedraGeometry->Update();
761 m_PolyhedraActor->SetVisibility(1);
762 } else {
763 m_ExtrVol->SetPolysOff();
764 m_PolyhedraActor->SetVisibility(0);
767 // wireframe
768 if (ui.checkBoxClip->isChecked()) {
769 m_ExtrVol->SetClippingOn();
770 } else {
771 m_ExtrVol->SetClippingOff();
773 if (forced) {
774 m_VolumeGeometry->Update();
776 m_VolumeWireActor->SetVisibility(1);
777 } else {
778 m_TetraActor->VisibilityOff();
779 m_PyramidActor->VisibilityOff();
780 m_WedgeActor->VisibilityOff();
781 m_HexaActor->VisibilityOff();
782 m_PolyhedraActor->VisibilityOff();
783 m_VolumeWireActor->VisibilityOff();
787 void GuiMainWindow::updateActors(bool forced)
789 // qDebug()<<"QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); called()";
790 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
792 //if (!tryLock()) return;
793 try {
794 m_Axes->SetInputData(m_Grid);
795 updateSurfaceActors(forced);
796 updateVolumeActors(forced);
797 updateStatusBar();
798 } catch (Error err) {
799 err.display();
801 //unlock();
803 // qDebug()<<"QApplication::restoreOverrideCursor(); called()";
804 QApplication::restoreOverrideCursor();
809 void GuiMainWindow::forceUpdateActors()
811 // qDebug()<<"void GuiMainWindow::forceUpdateActors() START";
812 updateActors(true);
813 getRenderWindow()->Render();
814 // qDebug()<<"void GuiMainWindow::forceUpdateActors() END";
817 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor,bool a_CellPickerMode)
819 m_UseVTKInteractor=a_UseVTKInteractor;
820 if (a_UseVTKInteractor) {
821 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Checked);
822 } else {
823 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Unchecked);
825 if (a_CellPickerMode) {
826 ui.radioButton_CellPicker->toggle();
827 } else {
828 ui.radioButton_PointPicker->toggle();
832 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor)
834 m_UseVTKInteractor = a_UseVTKInteractor;
837 bool GuiMainWindow::pickPoint(vtkIdType id_node)
839 if ((id_node >= 0) && (id_node < m_Grid->GetNumberOfPoints())) {
840 vec3_t x(0,0,0);
841 m_Grid->GetPoints()->GetPoint(id_node, x.data());
842 m_PickSphere->SetCenter(x.data());
843 m_PickedPoint = id_node;
844 m_PickActor->GetProperty()->SetColor(0,0,1);
845 m_PickActor->VisibilityOn();
846 m_PickedObject = 1;
847 return(true);
848 } else {
849 m_PickActor->VisibilityOff();
850 m_PickedObject = 0;
851 return(false);
855 bool GuiMainWindow::pickCell(vtkIdType id_cell)
857 if ((id_cell >= 0) && (id_cell < m_Grid->GetNumberOfCells())) {
858 vtkIdType *pts, Npts;
859 m_Grid->GetCellPoints(id_cell, Npts, pts);
860 vec3_t x(0,0,0);
861 for (vtkIdType i = 0; i < Npts; ++i) {
862 vec3_t xp;
863 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
864 x += double(1)/Npts * xp;
866 m_PickSphere->SetCenter(x.data());
867 double R = 1e99;
868 for (vtkIdType i = 0; i < Npts; ++i) {
869 vec3_t xp;
870 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
871 R = min(R, 0.25*(xp-x).abs());
873 m_ReferenceSize = R; //Used for text annotations too!
874 m_PickSphere->SetRadius(R);
875 m_PickedCell = id_cell;
876 m_PickActor->GetProperty()->SetColor(1,0,0);
877 m_PickActor->VisibilityOn();
878 m_PickedObject = 2;
879 return(true);
880 } else {
881 m_PickActor->VisibilityOff();
882 m_PickedObject = 0;
883 return(false);
887 void GuiMainWindow::importSTL()
889 StlReader stl;
890 stl();
891 //FIXME: emits an error if no file is imported, so check if there is a valid file
892 updateBoundaryCodes(true);
893 updateActors();
894 updateStatusBar();
895 zoomAll();
898 void GuiMainWindow::importGmsh1Ascii()
900 GmshReader gmsh;
901 gmsh.setV1Ascii();
902 gmsh();
903 updateBoundaryCodes(true);
904 updateActors();
905 updateStatusBar();
906 zoomAll();
909 void GuiMainWindow::exportGmsh1Ascii()
911 GmshWriter gmsh;
912 gmsh.setV1Ascii();
913 gmsh();
916 void GuiMainWindow::importGmsh2Ascii()
918 GmshReader gmsh;
919 gmsh.setV2Ascii();
920 gmsh();
921 updateBoundaryCodes(true);
922 updateActors();
923 updateStatusBar();
924 zoomAll();
927 void GuiMainWindow::exportGmsh2Ascii()
929 GmshWriter gmsh;
930 gmsh.setV2Ascii();
931 gmsh();
934 void GuiMainWindow::exportNeutral()
936 NeutralWriter neutral;
937 neutral();
940 void GuiMainWindow::zoomAll()
942 getRenderer()->ResetCamera();
943 getRenderWindow()->Render();
946 void GuiMainWindow::zoomOnPickedObject()
948 if(m_PickActor->GetVisibility()) {
949 getRenderer()->ResetCamera(m_PickActor->GetBounds());
950 getRenderWindow()->Render();
954 void GuiMainWindow::deselectAll()
956 cout << "void GuiMainWindow::deselectAll()" << endl;
957 m_PickActor->VisibilityOff();
958 updateActors();
961 ///\todo Should display a window
962 void GuiMainWindow::info()
964 ShowInfo info(ui.radioButton_CellPicker->isChecked(), m_PickedPoint, m_PickedCell);
965 info();
968 int GuiMainWindow::quickSave()
970 ///\todo add RAM support
971 if(m_undo_redo_enabled) {
972 if(m_Grid->GetNumberOfPoints()>0)
974 m_CurrentOperation++;
975 QFileInfo fileinfo(m_CurrentFilename);
976 QString l_filename = m_qset.value("tmp_directory").toString() + fileinfo.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation);
977 m_LastOperation=m_CurrentOperation;
978 cout<<"Operation "<<m_CurrentOperation<<endl;
979 saveAs(l_filename, false);
980 if(m_CurrentOperation>0) ui.actionUndo->setEnabled(true);
981 ui.actionRedo->setEnabled(false);
983 else cout<<"No grid to save!"<<endl;
984 return(m_CurrentOperation);
986 return 0;
989 void GuiMainWindow::quickLoad(int a_operation)
991 ///\todo add RAM support
992 if(m_undo_redo_enabled) {
993 QFileInfo fileinfo(m_CurrentFilename);
994 QString l_filename = m_qset.value("tmp_directory").toString() + fileinfo.completeBaseName() + "_" + QString("%1").arg(a_operation) + ".egc";
995 open(l_filename, false);
999 void GuiMainWindow::undo()
1001 if(m_undo_redo_enabled) {
1002 cout << "Undoing operation " << m_CurrentOperation << endl;
1003 m_CurrentOperation--;
1004 quickLoad(m_CurrentOperation);
1005 ui.actionRedo->setEnabled(true);
1006 if(m_CurrentOperation<=0) ui.actionUndo->setEnabled(false);
1008 else {
1009 resetOperationCounter();
1010 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
1014 void GuiMainWindow::redo()
1016 if(m_undo_redo_enabled) {
1017 m_CurrentOperation++;
1018 cout << "Redoing operation " << m_CurrentOperation << endl;
1019 quickLoad(m_CurrentOperation);
1020 ui.actionUndo->setEnabled(true);
1021 if(m_CurrentOperation>=m_LastOperation) ui.actionRedo->setEnabled(false);
1023 else {
1024 resetOperationCounter();
1025 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
1029 void GuiMainWindow::resetOperationCounter()
1031 m_CurrentOperation=-1;
1032 m_LastOperation=m_CurrentOperation;
1033 ui.actionUndo->setEnabled(false);
1034 ui.actionRedo->setEnabled(false);
1037 QString GuiMainWindow::getXmlSection(QString name)
1039 return m_XmlHandler->getXmlSection(name);
1042 void GuiMainWindow::setXmlSection(QString name, QString contents)
1044 m_XmlHandler->setXmlSection(name,contents);
1047 void GuiMainWindow::openPhysicalBoundaryConditions()
1049 m_PhysicalBoundaryConditionsMap.clear();
1050 QString buffer = getXmlSection("engrid/physical");
1051 QTextStream f(&buffer, QIODevice::ReadOnly);
1052 while (!f.atEnd()) {
1053 QString name, type;
1054 int index;
1055 f >> index >> name >> type;
1056 if ((name != "") && (type != "")) {
1057 PhysicalBoundaryCondition PBC;
1058 PBC.setName(name);
1059 PBC.setIndex(index);
1060 PBC.setType(type);
1061 for (int i = 0; i < PBC.getNumVars(); ++i) {
1062 double v;
1063 f >> v;
1064 PBC.setValue(i, v);
1066 m_PhysicalBoundaryConditionsMap[name] = PBC;
1071 void GuiMainWindow::savePhysicalBoundaryConditions()
1073 QString buffer("");
1074 QTextStream f(&buffer, QIODevice::WriteOnly);
1075 f << "\n";
1076 foreach (PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
1077 f << PBC.getIndex() << " " << PBC.getName() << " " << PBC.getType();
1078 for (int i = 0; i < PBC.getNumVars(); ++i) {
1079 f << " " << PBC.getVarValue(i);
1081 f << "\n";
1083 setXmlSection("engrid/physical", buffer);
1086 void GuiMainWindow::openBC()
1088 m_bcmap.clear();
1089 m_VolMap.clear();
1090 QString buffer = getXmlSection("engrid/bc");
1091 QTextStream f(&buffer, QIODevice::ReadOnly);
1092 while (!f.atEnd()) {
1093 QString name, type;
1094 int i;
1095 f >> i >> name >> type;
1096 if(name!="" && type!="") {
1097 if (i > 0) {
1098 m_bcmap[i] = BoundaryCondition(name,type);
1099 } else {
1100 VolumeDefinition V(name, -i);
1101 QString text = type.replace(",", " ").replace(":", " ");
1102 QTextStream s(&text);
1103 while (!s.atEnd()) {
1104 QString bc_txt, sign_txt;
1105 s >> bc_txt >> sign_txt;
1106 V.addBC(bc_txt.toInt(), sign_txt.toInt());
1108 m_VolMap[name] = V;
1114 void GuiMainWindow::saveBC()
1116 QString buffer("");
1117 QTextStream f(&buffer, QIODevice::WriteOnly);
1118 f << "\n";
1119 foreach (int i, m_AllBoundaryCodes) {
1120 BoundaryCondition bc = m_bcmap[i];
1121 f << i << " " << bc.getName() << " " << bc.getType() << "\n";
1123 foreach (VolumeDefinition V, m_VolMap) {
1124 QString dirs = "";
1125 bool first = true;
1126 foreach (int i, m_AllBoundaryCodes) {
1127 BoundaryCondition bc = m_bcmap[i];
1128 if (!first) {
1129 dirs += ",";
1130 } else {
1131 first = false;
1133 QString num;
1134 num.setNum(i);
1135 dirs += num + ":";
1136 num.setNum(V.getSign(i));
1137 dirs += num;
1139 f << "-" << V.getVC() << " " << V.getName() << " " << dirs << "\n";
1141 setXmlSection("engrid/bc", buffer);
1144 void GuiMainWindow::openGrid(QString file_name)
1146 file_name += ".vtu";
1147 EG_VTKSP(vtkXMLUnstructuredGridReader,vtu);
1148 vtu->SetFileName(qPrintable(file_name));
1149 vtu->Update();
1150 m_Grid->DeepCopy(vtu->GetOutput());
1151 if (m_Grid->GetPointData()->GetArray("node_meshdensity_current")) {
1152 m_Grid->GetPointData()->RemoveArray("node_meshdensity_current");
1154 if (m_Grid->GetCellData()->GetArray("cell_VA")) {
1155 m_Grid->GetCellData()->RemoveArray("cell_VA");
1157 createBasicFields(m_Grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints());
1158 openBC();
1159 openPhysicalBoundaryConditions();
1160 updateBoundaryCodes(true);
1161 createIndices(m_Grid);
1162 updateActors();
1163 updateStatusBar();
1164 zoomAll();
1167 ///\todo I think this should also be a done by a subclass of IOOperation just like for import operations
1168 void GuiMainWindow::open()
1170 QString file_name = QFileDialog::getOpenFileName(NULL, "open grid from file", getCwd(), "enGrid case files (*.egc *.EGC);; legacy grid files(*.vtu *.VTU)");
1171 if (!file_name.isNull()) {
1172 this->open(file_name);
1176 void GuiMainWindow::open(QString file_name, bool update_current_filename)
1178 cout << "Opening " << qPrintable(file_name) << endl;
1180 //QFileInfo file_info(file_name);
1181 bool no_case_file = false;
1182 QString file_extension = getExtension(file_name);
1183 QString grid_file_name = file_name;
1184 if (file_extension.toLower() == "vtu") {
1185 no_case_file = true;
1186 grid_file_name = stripFromExtension(file_name);
1188 if (!no_case_file) {
1189 if(!m_XmlHandler->openXml(file_name)) {
1190 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name));
1191 return;
1194 if(update_current_filename) {
1195 GuiMainWindow::setCwd(QFileInfo(file_name).absolutePath());
1197 resetCadInterfaces();
1199 QFile geo_file(file_name + ".geo.vtu");
1200 if (geo_file.exists()) {
1201 openGrid(file_name + ".geo");
1202 storeCadInterfaces(true);
1205 openGrid(grid_file_name);
1206 openBC();
1207 openPhysicalBoundaryConditions();
1208 // update current filename
1209 if(update_current_filename) m_CurrentFilename = stripFromExtension(file_name) + ".egc";
1210 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1211 setUnsaved(false);
1213 if(update_current_filename) {
1214 this->addRecentFile(file_name,QDateTime::currentDateTime());
1215 m_qset.setValue("LatestFile",file_name);
1216 resetOperationCounter();
1217 quickSave();
1221 QString GuiMainWindow::saveAs(QString file_name, bool update_current_filename)
1223 QString buffer = m_XmlHandler->getBuffer(0);
1224 if(update_current_filename) {
1225 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1227 QFileInfo file_info(file_name);
1228 if (file_info.suffix().toLower() != "egc") {
1229 file_name += ".egc";
1231 if(update_current_filename) {
1232 GuiMainWindow::setCwd(file_info.absolutePath());
1233 m_CurrentFilename = file_name;
1235 if(!saveGrid(m_Grid, file_name)) {
1236 QMessageBox::critical(this, QObject::tr("Save failed"), QObject::tr("The grid could not be saved as:\n%1").arg(file_name));
1238 saveBC();
1239 savePhysicalBoundaryConditions();
1240 m_XmlHandler->saveXml(file_name);
1241 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1242 setUnsaved(false);
1243 if(update_current_filename) {
1244 QApplication::restoreOverrideCursor();
1246 if(update_current_filename) {
1247 this->addRecentFile(file_name,QDateTime::currentDateTime());
1248 m_qset.setValue("LatestFile",file_name);
1250 return(file_name);
1253 void GuiMainWindow::save()
1255 if ( m_CurrentFilename == "untitled.egc" || m_UnSaved ) {
1257 //FIXME: This is more of a hack than a fix...
1258 if(GuiMainWindow::tryLock()) {
1259 GuiMainWindow::unlock(); //must unlock before continuing.
1260 saveAs();
1261 } else {
1262 cout <<endl
1263 << "WARNING: Please save the project before running the requested operation "
1264 "or after the current operation is complete."
1265 <<endl;
1267 } else {
1268 saveAs(m_CurrentFilename);
1272 void GuiMainWindow::saveAs()
1274 QApplication::restoreOverrideCursor();
1275 //saveGrid(m_Grid, m_CurrentFilename + ".geo");
1276 bool geo_file_exists = false;
1277 QString old_geo_file = m_CurrentFilename + ".geo.vtu";
1279 if (QFileInfo(old_geo_file).exists()) {
1280 geo_file_exists = true;
1283 QFileDialog dialog(NULL, "write case to file", getCwd(), "enGrid case files (*.egc)");
1284 QFileInfo file_info(m_CurrentFilename);
1285 dialog.selectFile(file_info.completeBaseName() + ".egc");
1286 dialog.setAcceptMode(QFileDialog::AcceptSave);
1287 dialog.setConfirmOverwrite(true);
1288 if (dialog.exec()) {
1289 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1290 QStringList selected_files = dialog.selectedFiles();
1291 QString file_name = selected_files[0];
1292 if (!file_name.isNull()) {
1293 QString new_geo_file = file_name + ".geo.vtu";
1295 QFile file(new_geo_file);
1296 file.remove();
1298 QFile geo_file(old_geo_file);
1299 geo_file.copy(new_geo_file);
1300 saveAs(file_name);
1301 //for the undo/redo operations
1302 resetOperationCounter();
1303 quickSave();
1306 QApplication::restoreOverrideCursor();
1309 void GuiMainWindow::updateStatusBar()
1311 QString num, txt = "enGrid is currently busy with an operation ...";
1312 if (!m_Busy) {
1313 txt = "";
1315 if (!tryLock()) {
1316 m_StatusLabel->setText(txt);
1317 ui.label_node_cell_info->setText(txt);
1318 return;
1320 vtkIdType Ncells = m_Grid->GetNumberOfCells();
1321 vtkIdType Nnodes = m_Grid->GetNumberOfPoints();
1322 vtkIdType Ntris = 0;
1323 vtkIdType Nquads = 0;
1324 vtkIdType Nplgs = 0;
1325 vtkIdType Ntets = 0;
1326 vtkIdType Npyras = 0;
1327 vtkIdType Nprism = 0;
1328 vtkIdType Nhexas = 0;
1329 vtkIdType Npolys = 0;
1330 for (vtkIdType i = 0; i < Ncells; ++i) {
1331 int ct = m_Grid->GetCellType(i);
1332 if (ct == VTK_TRIANGLE) ++Ntris;
1333 else if (ct == VTK_QUAD) ++Nquads;
1334 else if (ct == VTK_POLYGON) ++Nplgs;
1335 else if (ct == VTK_TETRA) ++Ntets;
1336 else if (ct == VTK_WEDGE) ++Nprism;
1337 else if (ct == VTK_PYRAMID) ++Npyras;
1338 else if (ct == VTK_HEXAHEDRON) ++Nhexas;
1339 else if (ct == VTK_POLYHEDRON) ++Npolys;
1341 num.setNum(Ntets + Npyras + Nprism + Nhexas + Npolys); txt += num + " volume cells(";
1342 num.setNum(Ntets); txt += num + " tetras, ";
1343 num.setNum(Npyras); txt += num + " pyramids, ";
1344 num.setNum(Nprism); txt += num + " prisms, ";
1345 num.setNum(Nhexas); txt += num + " hexas, ";
1346 num.setNum(Npolys); txt += num + " polys), ";
1347 num.setNum(Ntris + Nquads + Nplgs); txt += num + " surface cells(";
1348 num.setNum(Ntris); txt += num + " triangles, ";
1349 num.setNum(Nquads); txt += num + " quads, ";
1350 num.setNum(Nplgs); txt += num + " polys), ";
1351 num.setNum(Nnodes); txt += num + " nodes";
1353 if(ui.radioButton_CellPicker->isChecked())
1355 QString pick_txt = ", picked cell: ";
1356 vtkIdType id_cell = m_PickedCell;
1357 if (id_cell < 0 || id_cell>=m_Grid->GetNumberOfCells()) {
1358 pick_txt += "no cell picked";
1359 } else {
1360 vtkIdType type_cell = m_Grid->GetCellType(id_cell);
1361 if (type_cell == VTK_TRIANGLE) pick_txt += "tri";
1362 else if (type_cell == VTK_QUAD) pick_txt += "qua";
1363 else if (type_cell == VTK_POLYGON) pick_txt += "plg";
1364 else if (type_cell == VTK_TETRA) pick_txt += "tet";
1365 else if (type_cell == VTK_PYRAMID) pick_txt += "pyr";
1366 else if (type_cell == VTK_WEDGE) pick_txt += "pri";
1367 else if (type_cell == VTK_HEXAHEDRON) pick_txt += "hex";
1368 else if (type_cell == VTK_POLYHEDRON) pick_txt += "pol";
1369 vtkIdType N_pts, *pts;
1370 m_Grid->GetCellPoints(id_cell, N_pts, pts);
1371 pick_txt += " [";
1372 for (int i_pts = 0; i_pts < N_pts; ++i_pts) {
1373 QString num;
1374 num.setNum(pts[i_pts]);
1375 pick_txt += num;
1376 if (i_pts < N_pts-1) {
1377 pick_txt += ",";
1380 pick_txt += "]";
1381 QString tmp;
1382 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1383 tmp.setNum(cell_code->GetValue(id_cell));
1384 pick_txt += " code=" + tmp;
1385 tmp.setNum(id_cell);
1386 pick_txt += " id=" + tmp;
1388 txt += pick_txt;
1390 else
1392 QString pick_txt = ", picked node: ";
1393 vtkIdType id_node = m_PickedPoint;
1394 if (id_node < 0) {
1395 pick_txt += "no node picked";
1396 } else {
1397 QString tmp;
1398 EG_VTKDCN(vtkDoubleArray, characteristic_length_desired, m_Grid, "node_meshdensity_desired");
1399 tmp.setNum(characteristic_length_desired->GetValue(id_node));
1400 pick_txt += " wanted density=" + tmp;
1401 EG_VTKDCN(vtkIntArray, node_specified_density, m_Grid, "node_specified_density");
1402 tmp.setNum(node_specified_density->GetValue(id_node));
1403 pick_txt += " node_specified_density=" + tmp;
1404 EG_VTKDCN(vtkCharArray, node_type, m_Grid, "node_type");
1405 pick_txt += " type=" + QString(VertexType2Str( node_type->GetValue(id_node)));
1406 tmp.setNum(id_node);
1407 pick_txt += " id_node=" + tmp;
1410 txt += pick_txt;
1413 m_StatusLabel->setText(txt);
1414 ui.label_node_cell_info->setText(txt);
1415 unlock();
1418 void GuiMainWindow::selectBoundaryCodes()
1420 GuiSelectBoundaryCodes bcodes;
1421 bcodes.setDisplayBoundaryCodes(m_DisplayBoundaryCodes);
1422 bcodes.setBoundaryCodes(m_AllBoundaryCodes);
1423 bcodes();
1424 bcodes.getThread().wait();
1425 bcodes.getSelectedBoundaryCodes(m_DisplayBoundaryCodes);
1426 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1427 updateActors();
1430 void GuiMainWindow::updateBoundaryCodes(bool all_on)
1432 try {
1433 m_AllBoundaryCodes.clear();
1434 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1435 for (vtkIdType i = 0; i < m_Grid->GetNumberOfCells(); ++i) {
1436 int ct = m_Grid->GetCellType(i);
1437 if ((ct == VTK_TRIANGLE) || (ct == VTK_QUAD) || (ct == VTK_POLYGON)) {
1438 m_AllBoundaryCodes.insert(cell_code->GetValue(i));
1441 if (all_on) {
1442 m_DisplayBoundaryCodes.clear();
1443 foreach (int bc, m_AllBoundaryCodes) {
1444 m_DisplayBoundaryCodes.insert(bc);
1446 } else {
1447 QSet<int> dbcs;
1448 foreach (int bc, m_DisplayBoundaryCodes) {
1449 if (m_AllBoundaryCodes.contains(bc)) {
1450 dbcs.insert(bc);
1453 m_DisplayBoundaryCodes.clear();
1454 foreach (int bc, m_AllBoundaryCodes) {
1455 if (dbcs.contains(bc)) {
1456 m_DisplayBoundaryCodes.insert(bc);
1460 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1461 } catch (Error err) {
1462 err.display();
1466 void GuiMainWindow::normalExtrusion()
1468 GuiNormalExtrusion extr;
1469 extr();
1470 updateBoundaryCodes(false);
1471 updateActors();
1474 void GuiMainWindow::setAxesVisibility()
1476 if (ui.actionViewAxes->isChecked()) {
1477 m_Axes->VisibilityOn();
1478 } else {
1479 m_Axes->VisibilityOff();
1481 getRenderWindow()->Render();
1484 void GuiMainWindow::setViewingMode()
1486 if (ui.actionViewOrthogonal->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1487 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1488 getRenderWindow()->Render();
1491 void GuiMainWindow::viewNodeIDs()
1493 int N = m_Grid->GetNumberOfPoints();
1494 cout<<"N="<<N<<endl;
1495 if (ui.actionViewNodeIDs->isChecked()) {
1496 cout<<"Activating node ID view"<<endl;
1497 m_NodeTextVectorText.resize(N);
1498 m_NodeTextPolyDataMapper.resize(N);
1499 m_NodeTextFollower.resize(N);
1500 for(int i = 0; i < N; ++i){
1501 m_NodeTextVectorText[i]=vtkVectorText::New();
1502 QString tmp;
1503 tmp.setNum(i);
1504 m_NodeTextVectorText[i]->SetText(qPrintable(tmp));
1505 m_NodeTextPolyDataMapper[i]=vtkPolyDataMapper::New();
1506 m_NodeTextPolyDataMapper[i]->SetInputConnection(m_NodeTextVectorText[i]->GetOutputPort());
1507 m_NodeTextFollower[i]=vtkFollower::New();
1508 m_NodeTextFollower[i]->SetMapper(m_NodeTextPolyDataMapper[i]);
1509 m_NodeTextFollower[i]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1510 vec3_t M;
1511 m_Grid->GetPoint(i, M.data());
1512 vec3_t tmp_M = M;
1513 vec3_t OffSet = m_ReferenceSize*tmp_M.normalise();
1514 M = M + OffSet;
1515 m_NodeTextFollower[i]->AddPosition(M[0], M[1], M[2]);
1516 m_NodeTextFollower[i]->SetCamera(getRenderer()->GetActiveCamera());
1517 m_NodeTextFollower[i]->GetProperty()->SetColor(0,0,1);
1518 getRenderer()->AddActor(m_NodeTextFollower[i]);
1521 else {
1522 cout<<"Deactivating node ID view"<<endl;
1523 for(unsigned int i = 0; i < m_NodeTextFollower.size();i++){
1524 getRenderer()->RemoveActor(m_NodeTextFollower[i]);
1525 m_NodeTextFollower[i]->Delete();
1526 m_NodeTextPolyDataMapper[i]->Delete();
1527 m_NodeTextVectorText[i]->Delete();
1529 m_NodeTextFollower.clear();
1530 m_NodeTextPolyDataMapper.clear();
1531 m_NodeTextVectorText.clear();
1534 getRenderWindow()->Render();
1537 void GuiMainWindow::viewCellIDs()
1539 vtkIdType N = m_Grid->GetNumberOfCells();
1540 cout<<"N="<<N<<endl;
1541 if (ui.actionViewCellIDs->isChecked()) {
1542 cout<<"Activating cell ID view"<<endl;
1543 m_CellTextVectorText.resize(N);
1544 m_CellTextPolyDataMapper.resize(N);
1545 m_CellTextFollower.resize(N);
1546 for (vtkIdType id_cell = 0; id_cell < N; ++id_cell){
1547 m_CellTextVectorText[id_cell] = vtkVectorText::New();
1549 QString tmp;
1551 if(ui.comboBox_CellTextField->currentIndex()==0) {
1552 tmp.setNum(id_cell);
1553 } else if (ui.comboBox_CellTextField->currentIndex()>0) {
1554 EG_VTKDCC(vtkIntArray, current_cell_field, m_Grid, qPrintable(ui.comboBox_CellTextField->currentText()));
1555 tmp.setNum(current_cell_field->GetValue(id_cell));
1557 else EG_BUG;
1559 m_CellTextVectorText[id_cell]->SetText(qPrintable(tmp));
1560 m_CellTextPolyDataMapper[id_cell]=vtkPolyDataMapper::New();
1561 m_CellTextPolyDataMapper[id_cell]->SetInputConnection(m_CellTextVectorText[id_cell]->GetOutputPort());
1562 m_CellTextFollower[id_cell]=vtkFollower::New();
1563 m_CellTextFollower[id_cell]->SetMapper(m_CellTextPolyDataMapper[id_cell]);
1564 m_CellTextFollower[id_cell]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1565 vtkIdType N_pts,*pts;
1566 m_Grid->GetCellPoints(id_cell,N_pts,pts);
1567 vec3_t Center(0,0,0);
1568 for (int p = 0; p < N_pts; ++p) {
1569 vec3_t M;
1570 m_Grid->GetPoint(pts[p],M.data());
1571 Center+=M.data();
1573 vec3_t OffSet = m_ReferenceSize*triNormal(m_Grid, pts[0], pts[1], pts[2]).normalise();
1574 Center = 1.0/(double)N_pts*Center+OffSet;
1575 m_CellTextFollower[id_cell]->AddPosition(Center[0], Center[1], Center[2]);
1576 m_CellTextFollower[id_cell]->SetCamera(getRenderer()->GetActiveCamera());
1577 m_CellTextFollower[id_cell]->GetProperty()->SetColor(1, 0, 0);
1578 getRenderer()->AddActor(m_CellTextFollower[id_cell]);
1580 } else {
1581 cout<<"Deactivating cell ID view"<<endl;
1582 for (vtkIdType id_cell = 0; id_cell < (vtkIdType) m_CellTextFollower.size(); ++id_cell) {
1583 getRenderer()->RemoveActor(m_CellTextFollower[id_cell]);
1584 m_CellTextFollower[id_cell]->Delete();
1585 m_CellTextPolyDataMapper[id_cell]->Delete();
1586 m_CellTextVectorText[id_cell]->Delete();
1588 m_CellTextFollower.clear();
1589 m_CellTextPolyDataMapper.clear();
1590 m_CellTextVectorText.clear();
1593 getRenderWindow()->Render();
1596 void GuiMainWindow::pickCallBack
1598 vtkObject *caller,
1599 unsigned long int eid,
1600 void *clientdata,
1601 void *calldata
1604 caller = caller;
1605 eid = eid;
1606 clientdata = clientdata;
1607 calldata = calldata;
1608 THIS->updateActors();
1609 THIS->updateStatusBar();
1612 vtkIdType GuiMainWindow::getPickedCell()
1614 if(!ui.radioButton_CellPicker->isChecked()) return(-1);
1616 vtkIdType picked_cell = -1;
1617 if (m_Grid->GetNumberOfCells() > 0) {
1618 m_BCodesFilter->Update();
1619 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1620 EG_VTKDCC(vtkLongArray_t, cell_index, m_BCodesFilter->GetOutput(), "cell_index");
1621 if (m_UseVTKInteractor) {
1622 picked_cell = m_CellPicker->GetCellId();
1623 if (picked_cell >= 0) {
1624 picked_cell = cell_index->GetValue(picked_cell);
1626 } else {
1627 picked_cell = m_PickedCell;
1631 return picked_cell;
1634 vtkIdType GuiMainWindow::getPickedPoint()
1636 if(ui.radioButton_CellPicker->isChecked()) return(-1);
1638 vtkIdType picked_point = -1;
1639 if (m_Grid->GetNumberOfCells() > 0) {
1640 m_BCodesFilter->Update();
1641 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1642 EG_VTKDCN(vtkLongArray_t, node_index, m_BCodesFilter->GetOutput(), "node_index");
1643 if (m_UseVTKInteractor) {
1644 picked_point = m_PointPicker->GetPointId();
1645 if (picked_point >= 0) {
1646 picked_point = node_index->GetValue(picked_point);
1648 } else {
1649 picked_point = m_PickedPoint;
1653 return picked_point;
1656 void GuiMainWindow::changeSurfaceOrientation()
1658 for (vtkIdType cellId = 0; cellId < m_Grid->GetNumberOfCells(); ++cellId) {
1659 vtkIdType Npts, *pts;
1660 m_Grid->GetCellPoints(cellId, Npts, pts);
1661 QVector<vtkIdType> nodes(Npts);
1662 for (vtkIdType j = 0; j < Npts; ++j) nodes[j] = pts[j];
1663 for (vtkIdType j = 0; j < Npts; ++j) pts[Npts - j - 1] = nodes[j];
1665 updateActors();
1666 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1667 //m_Renderer->GetRenderWindow()->Render();
1670 void GuiMainWindow::checkSurfaceOrientation()
1672 CorrectSurfaceOrientation corr_surf;
1673 corr_surf();
1674 updateActors();
1675 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1676 //m_Renderer->GetRenderWindow()->Render();
1679 void GuiMainWindow::improveAspectRatio()
1681 GuiImproveAspectRatio impr_ar;
1682 impr_ar();
1683 updateActors();
1686 void GuiMainWindow::exportAsciiStl()
1688 StlWriter stl;
1689 stl.setFileTypeToASCII();
1690 stl();
1693 void GuiMainWindow::exportBinaryStl()
1695 StlWriter stl;
1696 stl.setFileTypeToBinary();
1697 stl();
1700 void GuiMainWindow::exportAsciiPly()
1702 PlyWriter ply;
1703 ply.setFileTypeToASCII();
1704 ply();
1707 void GuiMainWindow::exportBinaryPly()
1709 PlyWriter ply;
1710 ply.setFileTypeToBinary();
1711 ply();
1714 void GuiMainWindow::periodicUpdate()
1716 Operation::collectGarbage();
1717 updateStatusBar();
1720 void GuiMainWindow::viewRight()
1722 bool use_blender;
1723 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1724 getRenderer()->ResetCamera();
1725 double x[3];
1726 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1727 if (use_blender) {
1728 x[0] += 1;
1729 getRenderer()->GetActiveCamera()->SetPosition(x);
1730 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1731 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1732 } else {
1733 x[0] += 1;
1734 getRenderer()->GetActiveCamera()->SetPosition(x);
1735 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1736 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1738 getRenderer()->ResetCamera();
1739 getRenderWindow()->Render();
1742 void GuiMainWindow::viewLeft()
1744 bool use_blender;
1745 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1746 getRenderer()->ResetCamera();
1747 double x[3];
1748 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1749 if (use_blender) {
1750 x[0] -= 1;
1751 getRenderer()->GetActiveCamera()->SetPosition(x);
1752 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1753 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1754 } else {
1755 x[0] -= 1;
1756 getRenderer()->GetActiveCamera()->SetPosition(x);
1757 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1758 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1760 getRenderer()->ResetCamera();
1761 getRenderWindow()->Render();
1764 void GuiMainWindow::viewTop()
1766 bool use_blender;
1767 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1768 getRenderer()->ResetCamera();
1769 double x[3];
1770 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1771 if (use_blender) {
1772 x[2] += 1;
1773 getRenderer()->GetActiveCamera()->SetPosition(x);
1774 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1775 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1776 } else {
1777 x[1] += 1;
1778 getRenderer()->GetActiveCamera()->SetPosition(x);
1779 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1780 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1782 getRenderer()->ResetCamera();
1783 getRenderWindow()->Render();
1786 void GuiMainWindow::viewBottom()
1788 bool use_blender;
1789 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1790 getRenderer()->ResetCamera();
1791 double x[3];
1792 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1793 if (use_blender) {
1794 x[2] -= 1;
1795 getRenderer()->GetActiveCamera()->SetPosition(x);
1796 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1797 getRenderer()->GetActiveCamera()->SetViewUp(0,-1,0);
1798 } else {
1799 x[1] -= 1;
1800 getRenderer()->GetActiveCamera()->SetPosition(x);
1801 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1802 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1804 getRenderer()->ResetCamera();
1805 getRenderWindow()->Render();
1808 void GuiMainWindow::viewFront()
1810 bool use_blender;
1811 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1812 getRenderer()->ResetCamera();
1813 double x[3];
1814 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1815 if (use_blender) {
1816 x[1] -= 1;
1817 getRenderer()->GetActiveCamera()->SetPosition(x);
1818 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1819 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1820 } else {
1821 x[2] += 1;
1822 getRenderer()->GetActiveCamera()->SetPosition(x);
1823 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1824 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1826 getRenderer()->ResetCamera();
1827 getRenderWindow()->Render();
1830 void GuiMainWindow::viewBack()
1832 bool use_blender;
1833 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1834 getRenderer()->ResetCamera();
1835 double x[3];
1836 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1837 if (use_blender) {
1838 x[1] += 1;
1839 getRenderer()->GetActiveCamera()->SetPosition(x);
1840 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1841 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1842 } else {
1843 x[2] -= 1;
1844 getRenderer()->GetActiveCamera()->SetPosition(x);
1845 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1846 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1848 getRenderer()->ResetCamera();
1849 getRenderWindow()->Render();
1852 void GuiMainWindow::callFixSTL()
1854 FixSTL *fix;
1855 fix = new FixSTL();
1856 fix->setLockGui();
1857 (*fix)();
1858 updateBoundaryCodes(false);
1859 updateActors();
1862 void GuiMainWindow::callDeletePickedPoint()
1864 EG_STDINTERSLOT( DeletePickedPoint );
1867 void GuiMainWindow::editBoundaryConditions()
1869 GuiEditBoundaryConditions editbcs;
1870 editbcs.setBoundaryCodes(m_AllBoundaryCodes);
1871 editbcs.setMap(&m_bcmap);
1872 editbcs();
1875 void GuiMainWindow::configure()
1878 // Just to create initial entries in the settings file
1879 // so that the options menu isn't empty at first start.
1880 try {
1881 GridSmoother tmp01;
1882 GuiCreateBoundaryLayer tmp02;
1883 //TriSurfaceProjection tmp03;
1884 SurfaceMesher tmp04;
1885 UpdateDesiredMeshDensity tmp05;
1886 InsertPoints tmp06;
1887 RemovePoints tmp07;
1888 LaplaceSmoother tmp08;
1889 SwapTriangles tmp09;
1890 OpenFOAMTools tmp10;
1891 BlenderReader tmp11;
1892 } catch (Error err) {
1893 err.display();
1896 GuiSettingsViewer settings(&m_qset);
1897 settings.CreateViewer();
1898 settings.exec();
1900 getSet("General","enable undo+redo",false,m_undo_redo_enabled);
1903 void GuiMainWindow::about()
1905 //Load the HTML code snippet with the list of contributions
1906 QFileInfo fileinfo;
1907 fileinfo.setFile(":/contributions.htm");
1908 QFile file(fileinfo.filePath());
1909 if (!file.exists()) {
1910 qDebug() << "ERROR: " << fileinfo.filePath() << " not found.";
1911 EG_BUG;
1913 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1914 qDebug() << "ERROR: Failed to open file " << fileinfo.filePath();
1915 EG_BUG;
1917 QTextStream text_stream(&file);
1918 QString contributionsIncluded = text_stream.readAll();
1919 file.close();
1922 //Do the About box
1923 QMessageBox box(this);
1925 QString title="ENGRID";
1926 QString version = QString("version=") + ENGRID_VERSION + "<br/>branch=" + GIT_BRANCH + "<br/>commit=" + GIT_SHA1;
1927 version += "<br/>built on ";
1928 version += QString(__DATE__);
1929 version += " at ";
1930 version += QString(__TIME__);
1932 QString address = tr("ENGRID is being developed and maintained by:<br/>"
1933 "enGits GmbH<br/>"
1934 "Langenbachstrasse 3<br/>"
1935 "79674 Todtnau<br/>"
1936 "Germany<br/>");
1938 QString mainurl="<a href=\"http://engits.eu/\">http://engits.eu</a>";
1939 QString mail="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1940 QString gnuurl="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1941 QString license=tr("ENGRID is licenced under the GPL version 3.<br/>"
1942 "(see ")+gnuurl+tr(" for details)<br/>");
1943 QString contributions=tr("Contributions:");
1945 box.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1946 "<h3>%1</h3>"
1947 "<p>%2</p>"
1948 "<p>%3</p>"
1949 "<p>Homepage: %4</p>"
1950 "<p>E-mail: %5</p>"
1951 "<p>%6</p></center>"
1952 "<p>%7</p><blockquote>%8</blockquote>")
1953 .arg(title).arg(version).arg(address).arg(mainurl).arg(mail).arg(license)
1954 .arg(contributions).arg(contributionsIncluded));
1955 box.setWindowTitle(tr("about ENGRID"));
1956 box.setIcon(QMessageBox::NoIcon);
1957 box.exec();
1961 ///\todo Why not use bcs = m_AllBoundaryCodes; ?
1962 void GuiMainWindow::getAllBoundaryCodes(QVector<int> &bcs)
1964 m_AllBoundaryCodes;
1965 bcs.resize(m_AllBoundaryCodes.size());
1966 qCopy(m_AllBoundaryCodes.begin(), m_AllBoundaryCodes.end(), bcs.begin());
1967 qSort(bcs);
1970 QSet<int> GuiMainWindow::getAllBoundaryCodes()
1972 return m_AllBoundaryCodes;
1975 void GuiMainWindow::getDisplayBoundaryCodes(QSet<int> &bcs)
1977 bcs.clear();
1978 foreach (int bc, m_DisplayBoundaryCodes) {
1979 bcs.insert(bc);
1983 QList<VolumeDefinition> GuiMainWindow::getAllVols()
1985 QList<VolumeDefinition> vols;
1986 foreach(VolumeDefinition vol, m_VolMap) {
1987 vols.push_back(vol);
1989 return vols;
1992 void GuiMainWindow::setAllVols(QList<VolumeDefinition> vols)
1994 m_VolMap.clear();
1995 foreach (VolumeDefinition V, vols) {
1996 m_VolMap[V.getName()] = V;
2000 QList<PhysicalBoundaryCondition> GuiMainWindow::getAllPhysicalBoundaryConditions()
2002 QList<PhysicalBoundaryCondition> physical_boundary_conditions;
2003 foreach(PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
2004 physical_boundary_conditions.push_back(PBC);
2006 return physical_boundary_conditions;
2009 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList<PhysicalBoundaryCondition> physical_boundary_conditions)
2011 m_PhysicalBoundaryConditionsMap.clear();
2012 foreach (PhysicalBoundaryCondition PBC, physical_boundary_conditions) {
2013 m_PhysicalBoundaryConditionsMap[PBC.getName()] = PBC;
2017 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap<QString,PhysicalBoundaryCondition> physical_boundary_conditions) {
2018 m_PhysicalBoundaryConditionsMap = physical_boundary_conditions;
2021 void GuiMainWindow::createDefaultVol()
2023 QList<VolumeDefinition> vols = getAllVols();
2024 if (vols.size() == 0) {
2025 VolumeDefinition V("default", 1);
2026 QVector<int> bcs;
2027 getAllBoundaryCodes(bcs);
2028 foreach (int bc, bcs) {
2029 V.addBC(bc, 1);
2031 vols.append(V);
2032 setAllVols(vols);
2036 QString GuiMainWindow::getFilePath()
2038 QFileInfo fileinfo(m_CurrentFilename);
2039 return fileinfo.absolutePath()+"/";
2042 void GuiMainWindow::markOutputLine()
2044 cout << "\n****************************************\n";
2045 cout << qPrintable(QTime::currentTime().toString("hh:mm:ss"));
2046 cout << "\n****************************************\n" << endl;
2049 void GuiMainWindow::storeCadInterfaces(bool nosave)
2051 try {
2052 resetCadInterfaces();
2053 CgalTriCadInterface *cad = new CgalTriCadInterface(m_Grid);
2054 setUniversalCadInterface(cad);
2055 if (!nosave) {
2056 save();
2057 saveGrid(m_Grid, m_CurrentFilename + ".geo");
2060 } catch (Error E) {
2061 E.display();
2065 void GuiMainWindow::setUniversalCadInterface(CadInterface *cad_interface)
2067 m_UniCadInterface = cad_interface;
2068 cad_interface->setForegroundGrid(m_Grid);
2071 void GuiMainWindow::resetCadInterfaces()
2073 delete m_UniCadInterface;
2074 m_UniCadInterface = NULL;
2075 foreach (CadInterface* cad_interface, m_CadInterfaces) {
2076 delete cad_interface;
2078 m_CadInterfaces.clear();
2081 CadInterface *GuiMainWindow::getCadInterface(int bc, bool allow_null)
2083 QString bc_txt;
2084 bc_txt.setNum(bc);
2085 if (!m_CadInterfaces.contains(bc)) {
2086 bc = 0;
2088 if (!m_CadInterfaces.contains(bc)) {
2089 if (m_UniCadInterface) {
2090 return m_UniCadInterface;
2092 if (allow_null) {
2093 return NULL;
2095 EG_ERR_RETURN("No surface projection found for boundary code " + bc_txt);
2097 return m_CadInterfaces[bc];
2100 bool GuiMainWindow::checkCadInterfaces()
2102 bool ok = true;
2103 if (!m_UniCadInterface) {
2104 foreach (int bc, m_AllBoundaryCodes) {
2105 if (!m_CadInterfaces.contains(bc)) {
2106 ok = false;
2107 break;
2111 return ok;
2114 void GuiMainWindow::openRecent(QAction *action)
2116 qDebug()<<"GuiMainWindow::openRecent called";
2117 QString file_name = action->text().right(action->text().length()-23);
2118 this->open(file_name);
2121 void GuiMainWindow::readRecentFiles()
2123 m_RecentFiles.clear();
2124 this->recentFileMenu()->clear();
2125 QStringList file_names = m_qset.value("FileNames").toStringList();
2126 QStringList file_dates = m_qset.value("FileDates").toStringList();
2127 int N = min(10,m_qset.value("NumberOfFiles").toInt());
2128 // cout << "NumberOfFiles=" << N << endl;
2129 for (int i = 0; i < N; ++i) {
2130 QString new_file = file_names.at(i);
2131 QString date_text = file_dates.at(i);
2132 QDateTime date = QDateTime::fromString(date_text,"dd.MM.yyyy_hh:mm:ss");
2133 addRecentFile(new_file,date);
2137 void GuiMainWindow::writeRecentFiles()
2139 m_qset.setValue("NumberOfFiles",m_RecentFiles.size());
2140 QStringList file_names;
2141 QStringList file_dates;
2142 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2143 QString file_name = i.key();
2144 QString date_text = i.value().toString("dd.MM.yyyy_hh:mm:ss");
2145 file_names.append(file_name);
2146 file_dates.append(date_text);
2148 m_qset.setValue("FileNames",file_names);
2149 m_qset.setValue("FileDates",file_dates);
2152 void GuiMainWindow::addRecentFile(QString file_name, QDateTime date)
2154 m_RecentFiles[file_name] = date;
2155 while (m_RecentFiles.size() > 10) {
2156 QMap<QString,QDateTime>::iterator i,j;
2157 QDateTime old = QDateTime::currentDateTime();
2158 for (i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2159 if (i.value() <= old) {
2160 old = i.value();
2161 j = i;
2164 m_RecentFiles.erase(j);
2166 this->recentFileMenu()->clear();
2167 QMap<int,QString> menu_map;
2168 QDateTime now = QDateTime::currentDateTime();
2169 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2170 QString action_text = i.value().toString("dd.MM.yyyy hh:mm:ss");
2171 action_text += " -> ";
2172 action_text += i.key();
2173 menu_map[i.value().secsTo(now)] = action_text;
2176 for (QMap<int,QString>::iterator i = menu_map.begin(); i != menu_map.end(); ++i) {
2177 QAction *action = new QAction(i.value(),this);
2178 this->recentFileMenu()->addAction(action);
2183 void GuiMainWindow::callInsertNewCell()
2185 bool ok1,ok2,ok3,ok4;
2186 vtkIdType pts[3];
2187 #if QT_VERSION < 0x040500
2188 pts[0] = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2189 pts[1] = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2190 pts[2] = QInputDialog::getInteger(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
2191 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);
2192 #else
2193 pts[0] = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2194 pts[1] = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2195 pts[2] = QInputDialog::getInt(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
2196 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);
2197 #endif
2198 if (ok1 && ok2 && ok3 && ok4) {
2199 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2200 allocateGrid( new_grid, m_Grid->GetNumberOfCells() + 1, m_Grid->GetNumberOfPoints() );
2201 makeCopyNoAlloc(m_Grid, new_grid);
2202 vtkIdType id_new_cell = new_grid->InsertNextCell(VTK_TRIANGLE, 3, pts);
2203 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2204 makeCopy(new_grid, m_Grid);
2205 m_Grid->Modified();
2206 QMessageBox::information(NULL, "new cell", tr("The new cell has ID = %1").arg(id_new_cell));
2207 qDebug()<<tr("The new cell has ID = %1").arg(id_new_cell);
2211 void GuiMainWindow::callMergeNodes()
2213 bool ok1,ok2;
2214 #if QT_VERSION < 0x040500
2215 vtkIdType id_node1 = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2216 vtkIdType id_node2 = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2217 #else
2218 vtkIdType id_node1 = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2219 vtkIdType id_node2 = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2220 #endif
2221 if (ok1 && ok2) {
2222 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2223 allocateGrid( new_grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints() - 1 );
2225 QVector<vtkIdType> old2new_nodes(m_Grid->GetNumberOfPoints(), -1);
2226 QVector<vtkIdType> old2new_cells(m_Grid->GetNumberOfCells(), -1);
2228 vtkIdType id_new_node = 0;
2229 for (vtkIdType id_node = 0; id_node < m_Grid->GetNumberOfPoints(); ++id_node) {
2230 if(id_node!=id_node1 && id_node!=id_node2) {
2231 vec3_t x;
2232 m_Grid->GetPoints()->GetPoint(id_node, x.data());
2233 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2234 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2235 old2new_nodes[id_node] = id_new_node;
2236 id_new_node++;
2238 else if(id_node==id_node1) {
2239 vec3_t x1;
2240 m_Grid->GetPoints()->GetPoint(id_node1, x1.data());
2241 vec3_t x2;
2242 m_Grid->GetPoints()->GetPoint(id_node2, x2.data());
2243 vec3_t x = 0.5*(x1+x2);
2244 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2245 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2246 old2new_nodes[id_node1] = id_new_node;
2247 old2new_nodes[id_node2] = id_new_node;
2248 id_new_node++;
2250 else {
2254 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
2255 vtkIdType N_pts, *pts;
2256 vtkIdType type_cell = m_Grid->GetCellType(id_cell);
2257 m_Grid->GetCellPoints(id_cell, N_pts, pts);
2258 QVector<vtkIdType> new_pts(N_pts);
2259 for (int i = 0; i < N_pts; ++i) {
2260 new_pts[i] = old2new_nodes[pts[i]];
2262 vtkIdType id_new_cell = new_grid->InsertNextCell(type_cell, N_pts, new_pts.data());
2263 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2266 makeCopy(new_grid, m_Grid);
2267 m_Grid->Modified();
2268 qDebug()<<"The fusion is complete.";
2273 void GuiMainWindow::onEsc()
2275 setPickMode(true, true);
2276 pickCell(-1);
2277 m_CellPicker->Pick(-1e99,-1e99,0,m_Renderer);
2278 updateActors(true);
2279 updateStatusBar();
2282 void GuiMainWindow::resetProgress(QString info_text, int p_max)
2284 m_StatusInfoLabel->setText(info_text);
2285 m_StatusProgressBar->setMaximum(p_max);
2286 m_StatusProgressBar->setValue(0);
2287 QApplication::processEvents();
2290 void GuiMainWindow::setProgress(int p)
2292 m_StatusProgressBar->setValue(p);
2293 for (int i = 0; i < 3; ++i) {
2294 QApplication::processEvents();
2298 void GuiMainWindow::lock()
2300 m_Mutex.lock();
2303 void GuiMainWindow::unlock()
2305 m_Mutex.unlock();
2308 bool GuiMainWindow::tryLock()
2310 return m_Mutex.tryLock();