fixed bug with the boundary codes filter
[engrid-github.git] / src / libengrid / guimainwindow.cpp
blob25d4c681613d0e50c5f8a78a2f3e3b783d64900f
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_BCodesFilter = vtkEgBoundaryCodesFilter::New();
321 m_LookupTable = vtkLookupTable::New();
322 m_SurfaceActor = vtkActor::New();
323 m_LegendActor = vtkScalarBarActor::New();
325 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
326 m_BCodesFilter->SetInputData(m_Grid);
327 m_SurfaceFilter->SetInputConnection(m_BCodesFilter->GetOutputPort());
328 m_SurfaceMapper->SetInputConnection(m_SurfaceFilter->GetOutputPort());
329 m_SurfaceMapper->SetLookupTable(m_LookupTable);
330 m_SurfaceActor->GetProperty()->SetRepresentationToSurface();
331 m_SurfaceActor->GetProperty()->SetColor(m_ColAR, m_ColAG, m_ColAB);
332 m_SurfaceActor->SetBackfaceProperty(m_BackfaceProperty);
333 m_SurfaceActor->GetBackfaceProperty()->SetColor(m_ColBR, m_ColBG, m_ColBB);
334 m_SurfaceActor->GetProperty()->EdgeVisibilityOn();
335 m_SurfaceActor->GetProperty()->SetEdgeColor(0,0,1);
336 m_SurfaceActor->SetMapper(m_SurfaceMapper);
337 getRenderer()->AddActor(m_SurfaceActor);
338 m_SurfaceActor->SetVisibility(1);
339 m_LegendActor->SetLookupTable(m_LookupTable);
340 getRenderer()->AddActor(m_LegendActor);
341 m_LegendActor->SetVisibility(0);
343 // tetra pipline
344 m_ExtrTetras = vtkEgExtractVolumeCells::New();
345 m_TetraActor = vtkActor::New();
346 m_TetraGeometry = vtkDataSetSurfaceFilter::New();
347 m_TetraMapper = vtkPolyDataMapper::New();
349 m_ExtrTetras->SetInputData(m_Grid);
350 m_ExtrTetras->SetAllOff();
351 m_ExtrTetras->SetTetrasOn();;
352 m_TetraGeometry->SetInputConnection(m_ExtrTetras->GetOutputPort());
353 m_TetraMapper->SetInputConnection(m_TetraGeometry->GetOutputPort());
354 m_TetraActor->SetMapper(m_TetraMapper);
355 m_TetraActor->GetProperty()->SetColor(m_ColTetraR, m_ColTetraG, m_ColTetraB);
356 m_TetraActor->GetProperty()->EdgeVisibilityOn();
357 m_TetraActor->GetProperty()->SetEdgeColor(0,0,1);
358 getRenderer()->AddActor(m_TetraActor);
359 m_TetraActor->SetVisibility(0);
361 // pyramid pipeline
362 m_PyramidActor = vtkActor::New();
363 m_ExtrPyramids = vtkEgExtractVolumeCells::New();
364 m_PyramidGeometry = vtkDataSetSurfaceFilter::New();
365 m_PyramidMapper = vtkPolyDataMapper::New();
367 m_ExtrPyramids->SetInputData(m_Grid);
368 m_ExtrPyramids->SetAllOff();
369 m_ExtrPyramids->SetPyramidsOn();
370 m_PyramidGeometry->SetInputConnection(m_ExtrPyramids->GetOutputPort());
371 m_PyramidMapper->SetInputConnection(m_PyramidGeometry->GetOutputPort());
372 m_PyramidActor->SetMapper(m_PyramidMapper);
373 m_PyramidActor->GetProperty()->SetColor(m_ColPyraR, m_ColPyraG, m_ColPyraB);
374 m_PyramidActor->GetProperty()->EdgeVisibilityOn();
375 m_PyramidActor->GetProperty()->SetEdgeColor(0,0,1);
376 getRenderer()->AddActor(m_PyramidActor);
377 m_PyramidActor->SetVisibility(0);
379 // wedge pipeline
380 m_WedgeActor = vtkActor::New();
381 m_ExtrWedges = vtkEgExtractVolumeCells::New();
382 m_WedgeGeometry = vtkDataSetSurfaceFilter::New();
383 m_WedgeMapper = vtkPolyDataMapper::New();
385 m_ExtrWedges->SetInputData(m_Grid);
386 m_ExtrWedges->SetAllOff();
387 m_ExtrWedges->SetWedgesOn();
388 m_WedgeGeometry->SetInputConnection(m_ExtrWedges->GetOutputPort());
389 m_WedgeMapper->SetInputConnection(m_WedgeGeometry->GetOutputPort());
390 m_WedgeActor->SetMapper(m_WedgeMapper);
391 m_WedgeActor->GetProperty()->SetColor(m_ColPrismR, m_ColPrismG, m_ColPrismB);
392 m_WedgeActor->GetProperty()->EdgeVisibilityOn();
393 m_WedgeActor->GetProperty()->SetEdgeColor(0,0,1);
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 m_HexaActor->GetProperty()->EdgeVisibilityOn();
411 m_HexaActor->GetProperty()->SetEdgeColor(0,0,1);
412 getRenderer()->AddActor(m_HexaActor);
413 m_HexaActor->SetVisibility(0);
415 // polyhedra pipeline
416 m_PolyhedraActor = vtkActor::New();
417 m_ExtrPolyhedra = vtkEgExtractVolumeCells::New();
418 m_PolyhedraGeometry = vtkDataSetSurfaceFilter::New();
419 m_PolyhedraMapper = vtkPolyDataMapper::New();
421 m_ExtrPolyhedra->SetInputData(m_Grid);
422 m_ExtrPolyhedra->SetAllOff();
423 m_ExtrPolyhedra->SetPolysOn();
424 m_PolyhedraGeometry->SetInputConnection(m_ExtrPolyhedra->GetOutputPort());
425 m_PolyhedraMapper->SetInputConnection(m_PolyhedraGeometry->GetOutputPort());
426 m_PolyhedraActor->SetMapper(m_PolyhedraMapper);
427 m_PolyhedraActor->GetProperty()->SetColor(m_ColPolyR, m_ColPolyG, m_ColPolyB);
428 m_PolyhedraActor->GetProperty()->EdgeVisibilityOn();
429 m_PolyhedraActor->GetProperty()->SetEdgeColor(0,0,1);
430 getRenderer()->AddActor(m_PolyhedraActor);
431 m_PolyhedraActor->SetVisibility(0);
433 // picker stuff
434 m_PickSphere = vtkSphereSource::New();
435 m_PickMapper = vtkPolyDataMapper::New();
436 m_PickActor = vtkActor::New();
437 m_CellPicker = vtkCellPicker::New();
438 m_PointPicker = vtkPointPicker::New();
440 m_PickSphere->SetRadius(0.25); //in case the user starts picking points instead of cells
441 m_PickMapper->SetInputConnection(m_PickSphere->GetOutputPort());
442 m_PickActor->SetMapper(m_PickMapper);
443 m_PickActor->GetProperty()->SetRepresentationToSurface();
444 m_PickActor->GetProperty()->SetColor(0,0,1);
445 m_PickActor->VisibilityOff();
446 getRenderer()->AddActor(m_PickActor);
448 vtkCallbackCommand *cbc = vtkCallbackCommand::New();
449 cbc->SetCallback(pickCallBack);
451 m_CellPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
452 m_PointPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
453 m_PickedObject = 0;
455 viewFront();
458 void GuiMainWindow::updateOutput()
460 if (m_Log) {
461 QString txt = m_CoutBuffer.str().c_str();
462 m_CoutBuffer.str("");
463 if (txt.right(1) == "\n") {
464 txt = txt.left(txt.size()-1);
466 if (txt.size() > 0) {
467 ui.textEditOutput->append(txt);
472 void GuiMainWindow::exit()
474 QCoreApplication::exit();
477 vtkRenderWindow* GuiMainWindow::getRenderWindow()
479 return ui.qvtkWidget->GetRenderWindow();
482 vtkRenderer* GuiMainWindow::getRenderer()
484 return m_Renderer;
487 QVTKInteractor* GuiMainWindow::getInteractor()
489 return ui.qvtkWidget->GetInteractor();
492 QString GuiMainWindow::getCwd()
494 return m_cwd;
497 void GuiMainWindow::setCwd(QString dir)
499 m_cwd = dir;
500 m_qset.setValue("working_directory",dir);
503 void GuiMainWindow::setUnsaved(bool unsaved)
505 m_UnSaved = unsaved;
508 void GuiMainWindow::scaleToData()
510 int current_field=ui.comboBox_Field->currentIndex();
511 if(current_field>0)
513 double range[2];
515 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
516 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
517 cout<<"current_field="<<current_field<<endl;
518 cout<<"range[0]="<<range[0]<<endl;
519 cout<<"range[1]="<<range[1]<<endl;
520 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
521 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
522 ui.doubleSpinBox_FieldMin->setValue(range[0]);
523 ui.doubleSpinBox_FieldMax->setValue(range[1]);
527 void GuiMainWindow::setClipX(const QString &txt)
529 m_ExtrTetras->Setx(txt.toDouble());
530 m_ExtrPyramids->Setx(txt.toDouble());
531 m_ExtrWedges->Setx(txt.toDouble());
532 m_ExtrHexes->Setx(txt.toDouble());
533 m_ExtrPolyhedra->Setx(txt.toDouble());
536 void GuiMainWindow::setClipY(const QString &txt)
538 m_ExtrTetras->Sety(txt.toDouble());
539 m_ExtrPyramids->Sety(txt.toDouble());
540 m_ExtrWedges->Sety(txt.toDouble());
541 m_ExtrHexes->Sety(txt.toDouble());
542 m_ExtrPolyhedra->Sety(txt.toDouble());
545 void GuiMainWindow::setClipZ(const QString &txt)
547 m_ExtrTetras->Setz(txt.toDouble());
548 m_ExtrPyramids->Setz(txt.toDouble());
549 m_ExtrWedges->Setz(txt.toDouble());
550 m_ExtrHexes->Setz(txt.toDouble());
551 m_ExtrPolyhedra->Setz(txt.toDouble());
554 void GuiMainWindow::setClipNX(const QString &txt)
556 m_ExtrTetras->Setnx(txt.toDouble());
557 m_ExtrPyramids->Setnx(txt.toDouble());
558 m_ExtrWedges->Setnx(txt.toDouble());
559 m_ExtrHexes->Setnx(txt.toDouble());
560 m_ExtrPolyhedra->Setnx(txt.toDouble());
563 void GuiMainWindow::setClipNY(const QString &txt)
565 m_ExtrTetras->Setny(txt.toDouble());
566 m_ExtrPyramids->Setny(txt.toDouble());
567 m_ExtrWedges->Setny(txt.toDouble());
568 m_ExtrHexes->Setny(txt.toDouble());
569 m_ExtrPolyhedra->Setny(txt.toDouble());
572 void GuiMainWindow::setClipNZ(const QString &txt)
574 m_ExtrTetras->Setnz(txt.toDouble());
575 m_ExtrPyramids->Setnz(txt.toDouble());
576 m_ExtrWedges->Setnz(txt.toDouble());
577 m_ExtrHexes->Setnz(txt.toDouble());
578 m_ExtrPolyhedra->Setnz(txt.toDouble());
581 void GuiMainWindow::updateSurfaceActors(bool forced)
583 if (ui.checkBoxSurface->isChecked()) {
584 if (forced) {
585 m_SurfaceFilter->Update();
588 // fill node field combobox
589 int current_field=ui.comboBox_Field->currentIndex();
590 ui.comboBox_Field->clear();
591 ui.comboBox_Field->addItem("None");
592 for (int i = 0; i < m_Grid->GetPointData()->GetNumberOfArrays(); ++i) {
593 ui.comboBox_Field->addItem(m_Grid->GetPointData()->GetArrayName(i));
595 if(current_field == -1) {
596 ui.comboBox_Field->setCurrentIndex(0);
597 } else {
598 ui.comboBox_Field->setCurrentIndex(current_field);
601 // fill cell field combobox
602 int current_cell_field = ui.comboBox_CellTextField->currentIndex();
603 ui.comboBox_CellTextField->clear();
604 ui.comboBox_CellTextField->addItem("Cell ID");
605 for (int i = 0; i < m_SurfaceFilter->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i) {
606 ui.comboBox_CellTextField->addItem(m_Grid->GetCellData()->GetArrayName(i));
608 if(current_cell_field == -1) {
609 ui.comboBox_CellTextField->setCurrentIndex(0);
610 } else {
611 ui.comboBox_CellTextField->setCurrentIndex(current_cell_field);
613 current_field = ui.comboBox_Field->currentIndex();
614 if(current_field > 0) {
615 double range[2];
616 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
617 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
618 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
621 if(ui.comboBox_Field->currentIndex() > 0) {
622 m_SurfaceMapper->SetColorModeToMapScalars();
623 m_LookupTable->SetNumberOfColors(ui.spinBox_Color->value());
624 m_LookupTable->SetHueRange(ui.doubleSpinBox_HueMin->value(),ui.doubleSpinBox_HueMax->value());
625 m_LookupTable->Build();
626 m_SurfaceMapper->SetScalarModeToUsePointFieldData();
627 m_SurfaceMapper->ColorByArrayComponent(qPrintable(ui.comboBox_Field->currentText()),0);
628 m_SurfaceMapper->SetScalarRange(ui.doubleSpinBox_FieldMin->value(),ui.doubleSpinBox_FieldMax->value());
629 m_SurfaceMapper->ScalarVisibilityOn();
630 if(ui.checkBox_Legend->checkState()) {
631 m_LegendActor->SetVisibility(1);
632 } else {
633 m_LegendActor->SetVisibility(0);
635 } else {
636 m_SurfaceMapper->SetColorModeToDefault();
637 m_SurfaceMapper->ScalarVisibilityOff();
638 m_LegendActor->SetVisibility(0);
640 if (forced) {
641 m_BCodesFilter->Update();
643 if(ui.checkBox_ShowPickSphere->checkState()) {
644 if(m_UseVTKInteractor) {
645 if(ui.radioButton_CellPicker->isChecked()) {
646 getInteractor()->SetPicker(m_CellPicker);
647 vtkIdType id_cell = getPickedCell();
648 pickCell(id_cell);
649 } else {
650 getInteractor()->SetPicker(m_PointPicker);
651 vtkIdType id_node = getPickedPoint();
652 pickPoint(id_node);
654 } else {
655 if (ui.radioButton_CellPicker->isChecked()) {
656 pickCell(m_PickedCell);
657 } else {
658 pickPoint(m_PickedPoint);
662 m_SurfaceActor->SetVisibility(1);
663 } else {
664 m_SurfaceActor->SetVisibility(0);
668 void GuiMainWindow::updateVolumeActors(bool forced)
670 if (ui.checkBoxVolume->isChecked()) {
671 if (ui.checkBoxTetra->isChecked()) {
672 if (ui.checkBoxClip->isChecked()) {
673 m_ExtrTetras->SetClippingOn();
674 } else {
675 m_ExtrTetras->SetClippingOff();
677 if (forced) {
678 m_TetraGeometry->Update();
680 m_TetraActor->SetVisibility(1);
681 } else {
682 m_TetraActor->SetVisibility(0);
684 if (ui.checkBoxPyramid->isChecked()) {
685 if (ui.checkBoxClip->isChecked()) {
686 m_ExtrPyramids->SetClippingOn();
687 } else {
688 m_ExtrPyramids->SetClippingOff();
690 if (forced) {
691 m_PyramidGeometry->Update();
693 m_PyramidActor->SetVisibility(1);
694 } else {
695 m_PyramidActor->SetVisibility(0);
697 if (ui.checkBoxWedge->isChecked()) {
698 if (ui.checkBoxClip->isChecked()) {
699 m_ExtrWedges->SetClippingOn();
700 } else {
701 m_ExtrWedges->SetClippingOff();
703 if (forced) {
704 m_WedgeGeometry->Update();
706 m_WedgeActor->SetVisibility(1);
707 } else {
708 m_WedgeActor->SetVisibility(0);
710 if (ui.checkBoxHexa->isChecked()) {
711 if (ui.checkBoxClip->isChecked()) {
712 m_ExtrHexes->SetClippingOn();
713 } else {
714 m_ExtrHexes->SetClippingOff();
716 if (forced) {
717 m_HexaGeometry->Update();
719 m_HexaActor->SetVisibility(1);
720 } else {
721 m_HexaActor->SetVisibility(0);
723 if (ui.checkBoxPoly->isChecked()) {
724 if (ui.checkBoxClip->isChecked()) {
725 m_ExtrPolyhedra->SetClippingOn();
726 } else {
727 m_ExtrPolyhedra->SetClippingOff();
729 if (forced) {
730 m_PolyhedraGeometry->Update();
732 m_PolyhedraActor->SetVisibility(1);
733 } else {
734 m_PolyhedraActor->SetVisibility(0);
737 } else {
738 m_TetraActor->VisibilityOff();
739 m_PyramidActor->VisibilityOff();
740 m_WedgeActor->VisibilityOff();
741 m_HexaActor->VisibilityOff();
742 m_PolyhedraActor->VisibilityOff();
746 void GuiMainWindow::updateActors(bool forced)
748 // qDebug()<<"QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); called()";
749 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
751 //if (!tryLock()) return;
752 try {
753 m_Axes->SetInputData(m_Grid);
754 updateSurfaceActors(forced);
755 updateVolumeActors(forced);
756 updateStatusBar();
757 } catch (Error err) {
758 err.display();
760 //unlock();
762 // qDebug()<<"QApplication::restoreOverrideCursor(); called()";
763 QApplication::restoreOverrideCursor();
768 void GuiMainWindow::forceUpdateActors()
770 // qDebug()<<"void GuiMainWindow::forceUpdateActors() START";
771 updateActors(true);
772 getRenderWindow()->Render();
773 // qDebug()<<"void GuiMainWindow::forceUpdateActors() END";
776 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor,bool a_CellPickerMode)
778 m_UseVTKInteractor=a_UseVTKInteractor;
779 if (a_UseVTKInteractor) {
780 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Checked);
781 } else {
782 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Unchecked);
784 if (a_CellPickerMode) {
785 ui.radioButton_CellPicker->toggle();
786 } else {
787 ui.radioButton_PointPicker->toggle();
791 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor)
793 m_UseVTKInteractor = a_UseVTKInteractor;
796 bool GuiMainWindow::pickPoint(vtkIdType id_node)
798 if ((id_node >= 0) && (id_node < m_Grid->GetNumberOfPoints())) {
799 vec3_t x(0,0,0);
800 m_Grid->GetPoints()->GetPoint(id_node, x.data());
801 m_PickSphere->SetCenter(x.data());
802 m_PickedPoint = id_node;
803 m_PickActor->GetProperty()->SetColor(0,0,1);
804 m_PickActor->VisibilityOn();
805 m_PickedObject = 1;
806 return(true);
807 } else {
808 m_PickActor->VisibilityOff();
809 m_PickedObject = 0;
810 return(false);
814 bool GuiMainWindow::pickCell(vtkIdType id_cell)
816 if ((id_cell >= 0) && (id_cell < m_Grid->GetNumberOfCells())) {
817 vtkIdType *pts, Npts;
818 m_Grid->GetCellPoints(id_cell, Npts, pts);
819 vec3_t x(0,0,0);
820 for (vtkIdType i = 0; i < Npts; ++i) {
821 vec3_t xp;
822 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
823 x += double(1)/Npts * xp;
825 m_PickSphere->SetCenter(x.data());
826 double R = 1e99;
827 for (vtkIdType i = 0; i < Npts; ++i) {
828 vec3_t xp;
829 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
830 R = min(R, 0.25*(xp-x).abs());
832 m_ReferenceSize = R; //Used for text annotations too!
833 m_PickSphere->SetRadius(R);
834 m_PickedCell = id_cell;
835 m_PickActor->GetProperty()->SetColor(1,0,0);
836 m_PickActor->VisibilityOn();
837 m_PickedObject = 2;
838 return(true);
839 } else {
840 m_PickActor->VisibilityOff();
841 m_PickedObject = 0;
842 return(false);
846 void GuiMainWindow::importSTL()
848 StlReader stl;
849 stl();
850 //FIXME: emits an error if no file is imported, so check if there is a valid file
851 updateBoundaryCodes(true);
852 updateActors();
853 updateStatusBar();
854 zoomAll();
857 void GuiMainWindow::importGmsh1Ascii()
859 GmshReader gmsh;
860 gmsh.setV1Ascii();
861 gmsh();
862 updateBoundaryCodes(true);
863 updateActors();
864 updateStatusBar();
865 zoomAll();
868 void GuiMainWindow::exportGmsh1Ascii()
870 GmshWriter gmsh;
871 gmsh.setV1Ascii();
872 gmsh();
875 void GuiMainWindow::importGmsh2Ascii()
877 GmshReader gmsh;
878 gmsh.setV2Ascii();
879 gmsh();
880 updateBoundaryCodes(true);
881 updateActors();
882 updateStatusBar();
883 zoomAll();
886 void GuiMainWindow::exportGmsh2Ascii()
888 GmshWriter gmsh;
889 gmsh.setV2Ascii();
890 gmsh();
893 void GuiMainWindow::exportNeutral()
895 NeutralWriter neutral;
896 neutral();
899 void GuiMainWindow::zoomAll()
901 getRenderer()->ResetCamera();
902 getRenderWindow()->Render();
905 void GuiMainWindow::zoomOnPickedObject()
907 if(m_PickActor->GetVisibility()) {
908 getRenderer()->ResetCamera(m_PickActor->GetBounds());
909 getRenderWindow()->Render();
913 void GuiMainWindow::deselectAll()
915 cout << "void GuiMainWindow::deselectAll()" << endl;
916 m_PickActor->VisibilityOff();
917 updateActors();
920 ///\todo Should display a window
921 void GuiMainWindow::info()
923 ShowInfo info(ui.radioButton_CellPicker->isChecked(), m_PickedPoint, m_PickedCell);
924 info();
927 int GuiMainWindow::quickSave()
929 ///\todo add RAM support
930 if(m_undo_redo_enabled) {
931 if(m_Grid->GetNumberOfPoints()>0)
933 m_CurrentOperation++;
934 QFileInfo fileinfo(m_CurrentFilename);
935 QString l_filename = m_qset.value("tmp_directory").toString() + fileinfo.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation);
936 m_LastOperation=m_CurrentOperation;
937 cout<<"Operation "<<m_CurrentOperation<<endl;
938 saveAs(l_filename, false);
939 if(m_CurrentOperation>0) ui.actionUndo->setEnabled(true);
940 ui.actionRedo->setEnabled(false);
942 else cout<<"No grid to save!"<<endl;
943 return(m_CurrentOperation);
945 return 0;
948 void GuiMainWindow::quickLoad(int a_operation)
950 ///\todo add RAM support
951 if(m_undo_redo_enabled) {
952 QFileInfo fileinfo(m_CurrentFilename);
953 QString l_filename = m_qset.value("tmp_directory").toString() + fileinfo.completeBaseName() + "_" + QString("%1").arg(a_operation) + ".egc";
954 open(l_filename, false);
958 void GuiMainWindow::undo()
960 if(m_undo_redo_enabled) {
961 cout << "Undoing operation " << m_CurrentOperation << endl;
962 m_CurrentOperation--;
963 quickLoad(m_CurrentOperation);
964 ui.actionRedo->setEnabled(true);
965 if(m_CurrentOperation<=0) ui.actionUndo->setEnabled(false);
967 else {
968 resetOperationCounter();
969 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
973 void GuiMainWindow::redo()
975 if(m_undo_redo_enabled) {
976 m_CurrentOperation++;
977 cout << "Redoing operation " << m_CurrentOperation << endl;
978 quickLoad(m_CurrentOperation);
979 ui.actionUndo->setEnabled(true);
980 if(m_CurrentOperation>=m_LastOperation) ui.actionRedo->setEnabled(false);
982 else {
983 resetOperationCounter();
984 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
988 void GuiMainWindow::resetOperationCounter()
990 m_CurrentOperation=-1;
991 m_LastOperation=m_CurrentOperation;
992 ui.actionUndo->setEnabled(false);
993 ui.actionRedo->setEnabled(false);
996 QString GuiMainWindow::getXmlSection(QString name)
998 return m_XmlHandler->getXmlSection(name);
1001 void GuiMainWindow::setXmlSection(QString name, QString contents)
1003 m_XmlHandler->setXmlSection(name,contents);
1006 void GuiMainWindow::openPhysicalBoundaryConditions()
1008 m_PhysicalBoundaryConditionsMap.clear();
1009 QString buffer = getXmlSection("engrid/physical");
1010 QTextStream f(&buffer, QIODevice::ReadOnly);
1011 while (!f.atEnd()) {
1012 QString name, type;
1013 int index;
1014 f >> index >> name >> type;
1015 if ((name != "") && (type != "")) {
1016 PhysicalBoundaryCondition PBC;
1017 PBC.setName(name);
1018 PBC.setIndex(index);
1019 PBC.setType(type);
1020 for (int i = 0; i < PBC.getNumVars(); ++i) {
1021 double v;
1022 f >> v;
1023 PBC.setValue(i, v);
1025 m_PhysicalBoundaryConditionsMap[name] = PBC;
1030 void GuiMainWindow::savePhysicalBoundaryConditions()
1032 QString buffer("");
1033 QTextStream f(&buffer, QIODevice::WriteOnly);
1034 f << "\n";
1035 foreach (PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
1036 f << PBC.getIndex() << " " << PBC.getName() << " " << PBC.getType();
1037 for (int i = 0; i < PBC.getNumVars(); ++i) {
1038 f << " " << PBC.getVarValue(i);
1040 f << "\n";
1042 setXmlSection("engrid/physical", buffer);
1045 void GuiMainWindow::openBC()
1047 m_bcmap.clear();
1048 m_VolMap.clear();
1049 QString buffer = getXmlSection("engrid/bc");
1050 QTextStream f(&buffer, QIODevice::ReadOnly);
1051 while (!f.atEnd()) {
1052 QString name, type;
1053 int i;
1054 f >> i >> name >> type;
1055 if(name!="" && type!="") {
1056 if (i > 0) {
1057 m_bcmap[i] = BoundaryCondition(name,type);
1058 } else {
1059 VolumeDefinition V(name, -i);
1060 QString text = type.replace(",", " ").replace(":", " ");
1061 QTextStream s(&text);
1062 while (!s.atEnd()) {
1063 QString bc_txt, sign_txt;
1064 s >> bc_txt >> sign_txt;
1065 V.addBC(bc_txt.toInt(), sign_txt.toInt());
1067 m_VolMap[name] = V;
1073 void GuiMainWindow::saveBC()
1075 QString buffer("");
1076 QTextStream f(&buffer, QIODevice::WriteOnly);
1077 f << "\n";
1078 foreach (int i, m_AllBoundaryCodes) {
1079 BoundaryCondition bc = m_bcmap[i];
1080 f << i << " " << bc.getName() << " " << bc.getType() << "\n";
1082 foreach (VolumeDefinition V, m_VolMap) {
1083 QString dirs = "";
1084 bool first = true;
1085 foreach (int i, m_AllBoundaryCodes) {
1086 BoundaryCondition bc = m_bcmap[i];
1087 if (!first) {
1088 dirs += ",";
1089 } else {
1090 first = false;
1092 QString num;
1093 num.setNum(i);
1094 dirs += num + ":";
1095 num.setNum(V.getSign(i));
1096 dirs += num;
1098 f << "-" << V.getVC() << " " << V.getName() << " " << dirs << "\n";
1100 setXmlSection("engrid/bc", buffer);
1103 void GuiMainWindow::openGrid(QString file_name)
1105 file_name += ".vtu";
1106 EG_VTKSP(vtkXMLUnstructuredGridReader,vtu);
1107 vtu->SetFileName(qPrintable(file_name));
1108 vtu->Update();
1109 m_Grid->DeepCopy(vtu->GetOutput());
1110 if (m_Grid->GetPointData()->GetArray("node_meshdensity_current")) {
1111 m_Grid->GetPointData()->RemoveArray("node_meshdensity_current");
1113 if (m_Grid->GetCellData()->GetArray("cell_VA")) {
1114 m_Grid->GetCellData()->RemoveArray("cell_VA");
1116 createBasicFields(m_Grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints());
1117 openBC();
1118 openPhysicalBoundaryConditions();
1119 updateBoundaryCodes(true);
1120 createIndices(m_Grid);
1121 updateActors();
1122 updateStatusBar();
1123 zoomAll();
1126 ///\todo I think this should also be a done by a subclass of IOOperation just like for import operations
1127 void GuiMainWindow::open()
1129 QString file_name = QFileDialog::getOpenFileName(NULL, "open grid from file", getCwd(), "enGrid case files (*.egc *.EGC);; legacy grid files(*.vtu *.VTU)");
1130 if (!file_name.isNull()) {
1131 this->open(file_name);
1135 void GuiMainWindow::open(QString file_name, bool update_current_filename)
1137 cout << "Opening " << qPrintable(file_name) << endl;
1139 //QFileInfo file_info(file_name);
1140 bool no_case_file = false;
1141 QString file_extension = getExtension(file_name);
1142 QString grid_file_name = file_name;
1143 if (file_extension.toLower() == "vtu") {
1144 no_case_file = true;
1145 grid_file_name = stripFromExtension(file_name);
1147 if (!no_case_file) {
1148 if(!m_XmlHandler->openXml(file_name)) {
1149 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name));
1150 return;
1153 if(update_current_filename) {
1154 GuiMainWindow::setCwd(QFileInfo(file_name).absolutePath());
1156 resetCadInterfaces();
1158 QFile geo_file(file_name + ".geo.vtu");
1159 if (geo_file.exists()) {
1160 openGrid(file_name + ".geo");
1161 storeCadInterfaces(true);
1164 openGrid(grid_file_name);
1165 openBC();
1166 openPhysicalBoundaryConditions();
1167 // update current filename
1168 if(update_current_filename) m_CurrentFilename = stripFromExtension(file_name) + ".egc";
1169 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1170 setUnsaved(false);
1172 if(update_current_filename) {
1173 this->addRecentFile(file_name,QDateTime::currentDateTime());
1174 m_qset.setValue("LatestFile",file_name);
1175 resetOperationCounter();
1176 quickSave();
1180 QString GuiMainWindow::saveAs(QString file_name, bool update_current_filename)
1182 QString buffer = m_XmlHandler->getBuffer(0);
1183 if(update_current_filename) {
1184 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1186 QFileInfo file_info(file_name);
1187 if (file_info.suffix().toLower() != "egc") {
1188 file_name += ".egc";
1190 if(update_current_filename) {
1191 GuiMainWindow::setCwd(file_info.absolutePath());
1192 m_CurrentFilename = file_name;
1194 if(!saveGrid(m_Grid, file_name)) {
1195 QMessageBox::critical(this, QObject::tr("Save failed"), QObject::tr("The grid could not be saved as:\n%1").arg(file_name));
1197 saveBC();
1198 savePhysicalBoundaryConditions();
1199 m_XmlHandler->saveXml(file_name);
1200 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1201 setUnsaved(false);
1202 if(update_current_filename) {
1203 QApplication::restoreOverrideCursor();
1205 if(update_current_filename) {
1206 this->addRecentFile(file_name,QDateTime::currentDateTime());
1207 m_qset.setValue("LatestFile",file_name);
1209 return(file_name);
1212 void GuiMainWindow::save()
1214 if ( m_CurrentFilename == "untitled.egc" || m_UnSaved ) {
1216 //FIXME: This is more of a hack than a fix...
1217 if(GuiMainWindow::tryLock()) {
1218 GuiMainWindow::unlock(); //must unlock before continuing.
1219 saveAs();
1220 } else {
1221 cout <<endl
1222 << "WARNING: Please save the project before running the requested operation "
1223 "or after the current operation is complete."
1224 <<endl;
1226 } else {
1227 saveAs(m_CurrentFilename);
1231 void GuiMainWindow::saveAs()
1233 QApplication::restoreOverrideCursor();
1234 //saveGrid(m_Grid, m_CurrentFilename + ".geo");
1235 bool geo_file_exists = false;
1236 QString old_geo_file = m_CurrentFilename + ".geo.vtu";
1238 if (QFileInfo(old_geo_file).exists()) {
1239 geo_file_exists = true;
1242 QFileDialog dialog(NULL, "write case to file", getCwd(), "enGrid case files (*.egc)");
1243 QFileInfo file_info(m_CurrentFilename);
1244 dialog.selectFile(file_info.completeBaseName() + ".egc");
1245 dialog.setAcceptMode(QFileDialog::AcceptSave);
1246 dialog.setConfirmOverwrite(true);
1247 if (dialog.exec()) {
1248 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1249 QStringList selected_files = dialog.selectedFiles();
1250 QString file_name = selected_files[0];
1251 if (!file_name.isNull()) {
1252 QString new_geo_file = file_name + ".geo.vtu";
1254 QFile file(new_geo_file);
1255 file.remove();
1257 QFile geo_file(old_geo_file);
1258 geo_file.copy(new_geo_file);
1259 saveAs(file_name);
1260 //for the undo/redo operations
1261 resetOperationCounter();
1262 quickSave();
1265 QApplication::restoreOverrideCursor();
1268 void GuiMainWindow::updateStatusBar()
1270 QString num, txt = "enGrid is currently busy with an operation ...";
1271 if (!m_Busy) {
1272 txt = "";
1274 if (!tryLock()) {
1275 m_StatusLabel->setText(txt);
1276 ui.label_node_cell_info->setText(txt);
1277 return;
1279 vtkIdType Ncells = m_Grid->GetNumberOfCells();
1280 vtkIdType Nnodes = m_Grid->GetNumberOfPoints();
1281 vtkIdType Ntris = 0;
1282 vtkIdType Nquads = 0;
1283 vtkIdType Nplgs = 0;
1284 vtkIdType Ntets = 0;
1285 vtkIdType Npyras = 0;
1286 vtkIdType Nprism = 0;
1287 vtkIdType Nhexas = 0;
1288 vtkIdType Npolys = 0;
1289 for (vtkIdType i = 0; i < Ncells; ++i) {
1290 int ct = m_Grid->GetCellType(i);
1291 if (ct == VTK_TRIANGLE) ++Ntris;
1292 else if (ct == VTK_QUAD) ++Nquads;
1293 else if (ct == VTK_POLYGON) ++Nplgs;
1294 else if (ct == VTK_TETRA) ++Ntets;
1295 else if (ct == VTK_WEDGE) ++Nprism;
1296 else if (ct == VTK_PYRAMID) ++Npyras;
1297 else if (ct == VTK_HEXAHEDRON) ++Nhexas;
1298 else if (ct == VTK_POLYHEDRON) ++Npolys;
1300 num.setNum(Ntets + Npyras + Nprism + Nhexas + Npolys); txt += num + " volume cells(";
1301 num.setNum(Ntets); txt += num + " tetras, ";
1302 num.setNum(Npyras); txt += num + " pyramids, ";
1303 num.setNum(Nprism); txt += num + " prisms, ";
1304 num.setNum(Nhexas); txt += num + " hexas, ";
1305 num.setNum(Npolys); txt += num + " polys), ";
1306 num.setNum(Ntris + Nquads + Nplgs); txt += num + " surface cells(";
1307 num.setNum(Ntris); txt += num + " triangles, ";
1308 num.setNum(Nquads); txt += num + " quads, ";
1309 num.setNum(Nplgs); txt += num + " polys), ";
1310 num.setNum(Nnodes); txt += num + " nodes";
1312 if(ui.radioButton_CellPicker->isChecked())
1314 QString pick_txt = ", picked cell: ";
1315 vtkIdType id_cell = m_PickedCell;
1316 if (id_cell < 0 || id_cell>=m_Grid->GetNumberOfCells()) {
1317 pick_txt += "no cell picked";
1318 } else {
1319 vtkIdType type_cell = m_Grid->GetCellType(id_cell);
1320 if (type_cell == VTK_TRIANGLE) pick_txt += "tri";
1321 else if (type_cell == VTK_QUAD) pick_txt += "qua";
1322 else if (type_cell == VTK_POLYGON) pick_txt += "plg";
1323 else if (type_cell == VTK_TETRA) pick_txt += "tet";
1324 else if (type_cell == VTK_PYRAMID) pick_txt += "pyr";
1325 else if (type_cell == VTK_WEDGE) pick_txt += "pri";
1326 else if (type_cell == VTK_HEXAHEDRON) pick_txt += "hex";
1327 else if (type_cell == VTK_POLYHEDRON) pick_txt += "pol";
1328 vtkIdType N_pts, *pts;
1329 m_Grid->GetCellPoints(id_cell, N_pts, pts);
1330 pick_txt += " [";
1331 for (int i_pts = 0; i_pts < N_pts; ++i_pts) {
1332 QString num;
1333 num.setNum(pts[i_pts]);
1334 pick_txt += num;
1335 if (i_pts < N_pts-1) {
1336 pick_txt += ",";
1339 pick_txt += "]";
1340 QString tmp;
1341 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1342 tmp.setNum(cell_code->GetValue(id_cell));
1343 pick_txt += " code=" + tmp;
1344 tmp.setNum(id_cell);
1345 pick_txt += " id=" + tmp;
1347 txt += pick_txt;
1349 else
1351 QString pick_txt = ", picked node: ";
1352 vtkIdType id_node = m_PickedPoint;
1353 if (id_node < 0) {
1354 pick_txt += "no node picked";
1355 } else {
1356 QString tmp;
1357 EG_VTKDCN(vtkDoubleArray, characteristic_length_desired, m_Grid, "node_meshdensity_desired");
1358 tmp.setNum(characteristic_length_desired->GetValue(id_node));
1359 pick_txt += " wanted density=" + tmp;
1360 EG_VTKDCN(vtkIntArray, node_specified_density, m_Grid, "node_specified_density");
1361 tmp.setNum(node_specified_density->GetValue(id_node));
1362 pick_txt += " node_specified_density=" + tmp;
1363 EG_VTKDCN(vtkCharArray, node_type, m_Grid, "node_type");
1364 pick_txt += " type=" + QString(VertexType2Str( node_type->GetValue(id_node)));
1365 tmp.setNum(id_node);
1366 pick_txt += " id_node=" + tmp;
1369 txt += pick_txt;
1372 m_StatusLabel->setText(txt);
1373 ui.label_node_cell_info->setText(txt);
1374 unlock();
1377 void GuiMainWindow::selectBoundaryCodes()
1379 GuiSelectBoundaryCodes bcodes;
1380 bcodes.setDisplayBoundaryCodes(m_DisplayBoundaryCodes);
1381 bcodes.setBoundaryCodes(m_AllBoundaryCodes);
1382 bcodes();
1383 bcodes.getThread().wait();
1384 bcodes.getSelectedBoundaryCodes(m_DisplayBoundaryCodes);
1385 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1386 updateActors();
1389 void GuiMainWindow::updateBoundaryCodes(bool all_on)
1391 try {
1392 m_AllBoundaryCodes.clear();
1393 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1394 for (vtkIdType i = 0; i < m_Grid->GetNumberOfCells(); ++i) {
1395 int ct = m_Grid->GetCellType(i);
1396 if ((ct == VTK_TRIANGLE) || (ct == VTK_QUAD) || (ct == VTK_POLYGON)) {
1397 m_AllBoundaryCodes.insert(cell_code->GetValue(i));
1400 if (all_on) {
1401 m_DisplayBoundaryCodes.clear();
1402 foreach (int bc, m_AllBoundaryCodes) {
1403 m_DisplayBoundaryCodes.insert(bc);
1405 } else {
1406 QSet<int> dbcs;
1407 foreach (int bc, m_DisplayBoundaryCodes) {
1408 if (m_AllBoundaryCodes.contains(bc)) {
1409 dbcs.insert(bc);
1412 m_DisplayBoundaryCodes.clear();
1413 foreach (int bc, m_AllBoundaryCodes) {
1414 if (dbcs.contains(bc)) {
1415 m_DisplayBoundaryCodes.insert(bc);
1419 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1420 } catch (Error err) {
1421 err.display();
1425 void GuiMainWindow::normalExtrusion()
1427 GuiNormalExtrusion extr;
1428 extr();
1429 updateBoundaryCodes(false);
1430 updateActors();
1433 void GuiMainWindow::setAxesVisibility()
1435 if (ui.actionViewAxes->isChecked()) {
1436 m_Axes->VisibilityOn();
1437 } else {
1438 m_Axes->VisibilityOff();
1440 getRenderWindow()->Render();
1443 void GuiMainWindow::setViewingMode()
1445 if (ui.actionViewOrthogonal->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1446 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1447 getRenderWindow()->Render();
1450 void GuiMainWindow::viewNodeIDs()
1452 int N = m_Grid->GetNumberOfPoints();
1453 cout<<"N="<<N<<endl;
1454 if (ui.actionViewNodeIDs->isChecked()) {
1455 cout<<"Activating node ID view"<<endl;
1456 m_NodeTextVectorText.resize(N);
1457 m_NodeTextPolyDataMapper.resize(N);
1458 m_NodeTextFollower.resize(N);
1459 for(int i = 0; i < N; ++i){
1460 m_NodeTextVectorText[i]=vtkVectorText::New();
1461 QString tmp;
1462 tmp.setNum(i);
1463 m_NodeTextVectorText[i]->SetText(qPrintable(tmp));
1464 m_NodeTextPolyDataMapper[i]=vtkPolyDataMapper::New();
1465 m_NodeTextPolyDataMapper[i]->SetInputConnection(m_NodeTextVectorText[i]->GetOutputPort());
1466 m_NodeTextFollower[i]=vtkFollower::New();
1467 m_NodeTextFollower[i]->SetMapper(m_NodeTextPolyDataMapper[i]);
1468 m_NodeTextFollower[i]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1469 vec3_t M;
1470 m_Grid->GetPoint(i, M.data());
1471 vec3_t tmp_M = M;
1472 vec3_t OffSet = m_ReferenceSize*tmp_M.normalise();
1473 M = M + OffSet;
1474 m_NodeTextFollower[i]->AddPosition(M[0], M[1], M[2]);
1475 m_NodeTextFollower[i]->SetCamera(getRenderer()->GetActiveCamera());
1476 m_NodeTextFollower[i]->GetProperty()->SetColor(0,0,1);
1477 getRenderer()->AddActor(m_NodeTextFollower[i]);
1480 else {
1481 cout<<"Deactivating node ID view"<<endl;
1482 for(unsigned int i = 0; i < m_NodeTextFollower.size();i++){
1483 getRenderer()->RemoveActor(m_NodeTextFollower[i]);
1484 m_NodeTextFollower[i]->Delete();
1485 m_NodeTextPolyDataMapper[i]->Delete();
1486 m_NodeTextVectorText[i]->Delete();
1488 m_NodeTextFollower.clear();
1489 m_NodeTextPolyDataMapper.clear();
1490 m_NodeTextVectorText.clear();
1493 getRenderWindow()->Render();
1496 void GuiMainWindow::viewCellIDs()
1498 vtkIdType N = m_Grid->GetNumberOfCells();
1499 cout<<"N="<<N<<endl;
1500 if (ui.actionViewCellIDs->isChecked()) {
1501 cout<<"Activating cell ID view"<<endl;
1502 m_CellTextVectorText.resize(N);
1503 m_CellTextPolyDataMapper.resize(N);
1504 m_CellTextFollower.resize(N);
1505 for (vtkIdType id_cell = 0; id_cell < N; ++id_cell){
1506 m_CellTextVectorText[id_cell] = vtkVectorText::New();
1508 QString tmp;
1510 if(ui.comboBox_CellTextField->currentIndex()==0) {
1511 tmp.setNum(id_cell);
1512 } else if (ui.comboBox_CellTextField->currentIndex()>0) {
1513 EG_VTKDCC(vtkIntArray, current_cell_field, m_Grid, qPrintable(ui.comboBox_CellTextField->currentText()));
1514 tmp.setNum(current_cell_field->GetValue(id_cell));
1516 else EG_BUG;
1518 m_CellTextVectorText[id_cell]->SetText(qPrintable(tmp));
1519 m_CellTextPolyDataMapper[id_cell]=vtkPolyDataMapper::New();
1520 m_CellTextPolyDataMapper[id_cell]->SetInputConnection(m_CellTextVectorText[id_cell]->GetOutputPort());
1521 m_CellTextFollower[id_cell]=vtkFollower::New();
1522 m_CellTextFollower[id_cell]->SetMapper(m_CellTextPolyDataMapper[id_cell]);
1523 m_CellTextFollower[id_cell]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1524 vtkIdType N_pts,*pts;
1525 m_Grid->GetCellPoints(id_cell,N_pts,pts);
1526 vec3_t Center(0,0,0);
1527 for (int p = 0; p < N_pts; ++p) {
1528 vec3_t M;
1529 m_Grid->GetPoint(pts[p],M.data());
1530 Center+=M.data();
1532 vec3_t OffSet = m_ReferenceSize*triNormal(m_Grid, pts[0], pts[1], pts[2]).normalise();
1533 Center = 1.0/(double)N_pts*Center+OffSet;
1534 m_CellTextFollower[id_cell]->AddPosition(Center[0], Center[1], Center[2]);
1535 m_CellTextFollower[id_cell]->SetCamera(getRenderer()->GetActiveCamera());
1536 m_CellTextFollower[id_cell]->GetProperty()->SetColor(1, 0, 0);
1537 getRenderer()->AddActor(m_CellTextFollower[id_cell]);
1539 } else {
1540 cout<<"Deactivating cell ID view"<<endl;
1541 for (vtkIdType id_cell = 0; id_cell < (vtkIdType) m_CellTextFollower.size(); ++id_cell) {
1542 getRenderer()->RemoveActor(m_CellTextFollower[id_cell]);
1543 m_CellTextFollower[id_cell]->Delete();
1544 m_CellTextPolyDataMapper[id_cell]->Delete();
1545 m_CellTextVectorText[id_cell]->Delete();
1547 m_CellTextFollower.clear();
1548 m_CellTextPolyDataMapper.clear();
1549 m_CellTextVectorText.clear();
1552 getRenderWindow()->Render();
1555 void GuiMainWindow::pickCallBack
1557 vtkObject *caller,
1558 unsigned long int eid,
1559 void *clientdata,
1560 void *calldata
1563 caller = caller;
1564 eid = eid;
1565 clientdata = clientdata;
1566 calldata = calldata;
1567 THIS->updateActors();
1568 THIS->updateStatusBar();
1571 vtkIdType GuiMainWindow::getPickedCell()
1573 if(!ui.radioButton_CellPicker->isChecked()) return(-1);
1575 vtkIdType picked_cell = -1;
1576 if (m_Grid->GetNumberOfCells() > 0) {
1577 m_BCodesFilter->Update();
1578 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1579 EG_VTKDCC(vtkLongArray_t, cell_index, m_BCodesFilter->GetOutput(), "cell_index");
1580 if (m_UseVTKInteractor) {
1581 picked_cell = m_CellPicker->GetCellId();
1582 if (picked_cell >= 0) {
1583 picked_cell = cell_index->GetValue(picked_cell);
1585 } else {
1586 picked_cell = m_PickedCell;
1590 return picked_cell;
1593 vtkIdType GuiMainWindow::getPickedPoint()
1595 if(ui.radioButton_CellPicker->isChecked()) return(-1);
1597 vtkIdType picked_point = -1;
1598 if (m_Grid->GetNumberOfCells() > 0) {
1599 m_BCodesFilter->Update();
1600 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1601 EG_VTKDCN(vtkLongArray_t, node_index, m_BCodesFilter->GetOutput(), "node_index");
1602 if (m_UseVTKInteractor) {
1603 picked_point = m_PointPicker->GetPointId();
1604 if (picked_point >= 0) {
1605 picked_point = node_index->GetValue(picked_point);
1607 } else {
1608 picked_point = m_PickedPoint;
1612 return picked_point;
1615 void GuiMainWindow::changeSurfaceOrientation()
1617 for (vtkIdType cellId = 0; cellId < m_Grid->GetNumberOfCells(); ++cellId) {
1618 vtkIdType Npts, *pts;
1619 m_Grid->GetCellPoints(cellId, Npts, pts);
1620 QVector<vtkIdType> nodes(Npts);
1621 for (vtkIdType j = 0; j < Npts; ++j) nodes[j] = pts[j];
1622 for (vtkIdType j = 0; j < Npts; ++j) pts[Npts - j - 1] = nodes[j];
1624 updateActors();
1625 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1626 //m_Renderer->GetRenderWindow()->Render();
1629 void GuiMainWindow::checkSurfaceOrientation()
1631 CorrectSurfaceOrientation corr_surf;
1632 corr_surf();
1633 updateActors();
1634 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1635 //m_Renderer->GetRenderWindow()->Render();
1638 void GuiMainWindow::improveAspectRatio()
1640 GuiImproveAspectRatio impr_ar;
1641 impr_ar();
1642 updateActors();
1645 void GuiMainWindow::exportAsciiStl()
1647 StlWriter stl;
1648 stl.setFileTypeToASCII();
1649 stl();
1652 void GuiMainWindow::exportBinaryStl()
1654 StlWriter stl;
1655 stl.setFileTypeToBinary();
1656 stl();
1659 void GuiMainWindow::exportAsciiPly()
1661 PlyWriter ply;
1662 ply.setFileTypeToASCII();
1663 ply();
1666 void GuiMainWindow::exportBinaryPly()
1668 PlyWriter ply;
1669 ply.setFileTypeToBinary();
1670 ply();
1673 void GuiMainWindow::periodicUpdate()
1675 Operation::collectGarbage();
1676 updateStatusBar();
1679 void GuiMainWindow::viewRight()
1681 bool use_blender;
1682 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1683 getRenderer()->ResetCamera();
1684 double x[3];
1685 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1686 if (use_blender) {
1687 x[0] += 1;
1688 getRenderer()->GetActiveCamera()->SetPosition(x);
1689 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1690 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1691 } else {
1692 x[0] += 1;
1693 getRenderer()->GetActiveCamera()->SetPosition(x);
1694 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1695 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1697 getRenderer()->ResetCamera();
1698 getRenderWindow()->Render();
1701 void GuiMainWindow::viewLeft()
1703 bool use_blender;
1704 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1705 getRenderer()->ResetCamera();
1706 double x[3];
1707 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1708 if (use_blender) {
1709 x[0] -= 1;
1710 getRenderer()->GetActiveCamera()->SetPosition(x);
1711 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1712 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1713 } else {
1714 x[0] -= 1;
1715 getRenderer()->GetActiveCamera()->SetPosition(x);
1716 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1717 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1719 getRenderer()->ResetCamera();
1720 getRenderWindow()->Render();
1723 void GuiMainWindow::viewTop()
1725 bool use_blender;
1726 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1727 getRenderer()->ResetCamera();
1728 double x[3];
1729 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1730 if (use_blender) {
1731 x[2] += 1;
1732 getRenderer()->GetActiveCamera()->SetPosition(x);
1733 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1734 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1735 } else {
1736 x[1] += 1;
1737 getRenderer()->GetActiveCamera()->SetPosition(x);
1738 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1739 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1741 getRenderer()->ResetCamera();
1742 getRenderWindow()->Render();
1745 void GuiMainWindow::viewBottom()
1747 bool use_blender;
1748 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1749 getRenderer()->ResetCamera();
1750 double x[3];
1751 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1752 if (use_blender) {
1753 x[2] -= 1;
1754 getRenderer()->GetActiveCamera()->SetPosition(x);
1755 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1756 getRenderer()->GetActiveCamera()->SetViewUp(0,-1,0);
1757 } else {
1758 x[1] -= 1;
1759 getRenderer()->GetActiveCamera()->SetPosition(x);
1760 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1761 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1763 getRenderer()->ResetCamera();
1764 getRenderWindow()->Render();
1767 void GuiMainWindow::viewFront()
1769 bool use_blender;
1770 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1771 getRenderer()->ResetCamera();
1772 double x[3];
1773 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1774 if (use_blender) {
1775 x[1] -= 1;
1776 getRenderer()->GetActiveCamera()->SetPosition(x);
1777 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1778 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1779 } else {
1780 x[2] += 1;
1781 getRenderer()->GetActiveCamera()->SetPosition(x);
1782 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1783 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1785 getRenderer()->ResetCamera();
1786 getRenderWindow()->Render();
1789 void GuiMainWindow::viewBack()
1791 bool use_blender;
1792 getSet("General","use Blender definition for front, top, etc.", true, use_blender);
1793 getRenderer()->ResetCamera();
1794 double x[3];
1795 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1796 if (use_blender) {
1797 x[1] += 1;
1798 getRenderer()->GetActiveCamera()->SetPosition(x);
1799 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1800 getRenderer()->GetActiveCamera()->SetViewUp(0,0,1);
1801 } else {
1802 x[2] -= 1;
1803 getRenderer()->GetActiveCamera()->SetPosition(x);
1804 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1805 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1807 getRenderer()->ResetCamera();
1808 getRenderWindow()->Render();
1811 void GuiMainWindow::callFixSTL()
1813 FixSTL *fix;
1814 fix = new FixSTL();
1815 fix->setLockGui();
1816 (*fix)();
1817 updateBoundaryCodes(false);
1818 updateActors();
1821 void GuiMainWindow::callDeletePickedPoint()
1823 EG_STDINTERSLOT( DeletePickedPoint );
1826 void GuiMainWindow::editBoundaryConditions()
1828 GuiEditBoundaryConditions editbcs;
1829 editbcs.setBoundaryCodes(m_AllBoundaryCodes);
1830 editbcs.setMap(&m_bcmap);
1831 editbcs();
1834 void GuiMainWindow::configure()
1837 // Just to create initial entries in the settings file
1838 // so that the options menu isn't empty at first start.
1839 try {
1840 GridSmoother tmp01;
1841 GuiCreateBoundaryLayer tmp02;
1842 //TriSurfaceProjection tmp03;
1843 SurfaceMesher tmp04;
1844 UpdateDesiredMeshDensity tmp05;
1845 InsertPoints tmp06;
1846 RemovePoints tmp07;
1847 LaplaceSmoother tmp08;
1848 SwapTriangles tmp09;
1849 OpenFOAMTools tmp10;
1850 BlenderReader tmp11;
1851 } catch (Error err) {
1852 err.display();
1855 GuiSettingsViewer settings(&m_qset);
1856 settings.CreateViewer();
1857 settings.exec();
1859 getSet("General","enable undo+redo",false,m_undo_redo_enabled);
1862 void GuiMainWindow::about()
1864 //Load the HTML code snippet with the list of contributions
1865 QFileInfo fileinfo;
1866 fileinfo.setFile(":/contributions.htm");
1867 QFile file(fileinfo.filePath());
1868 if (!file.exists()) {
1869 qDebug() << "ERROR: " << fileinfo.filePath() << " not found.";
1870 EG_BUG;
1872 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1873 qDebug() << "ERROR: Failed to open file " << fileinfo.filePath();
1874 EG_BUG;
1876 QTextStream text_stream(&file);
1877 QString contributionsIncluded = text_stream.readAll();
1878 file.close();
1881 //Do the About box
1882 QMessageBox box(this);
1884 QString title="ENGRID";
1885 QString version = QString("version=") + ENGRID_VERSION + "<br/>branch=" + GIT_BRANCH + "<br/>commit=" + GIT_SHA1;
1886 version += "<br/>built on ";
1887 version += QString(__DATE__);
1888 version += " at ";
1889 version += QString(__TIME__);
1891 QString address = tr("ENGRID is being developed and maintained by:<br/>"
1892 "enGits GmbH<br/>"
1893 "Langenbachstrasse 3<br/>"
1894 "79674 Todtnau<br/>"
1895 "Germany<br/>");
1897 QString mainurl="<a href=\"http://engits.eu/\">http://engits.eu</a>";
1898 QString mail="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1899 QString gnuurl="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1900 QString license=tr("ENGRID is licenced under the GPL version 3.<br/>"
1901 "(see ")+gnuurl+tr(" for details)<br/>");
1902 QString contributions=tr("Contributions:");
1904 box.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1905 "<h3>%1</h3>"
1906 "<p>%2</p>"
1907 "<p>%3</p>"
1908 "<p>Homepage: %4</p>"
1909 "<p>E-mail: %5</p>"
1910 "<p>%6</p></center>"
1911 "<p>%7</p><blockquote>%8</blockquote>")
1912 .arg(title).arg(version).arg(address).arg(mainurl).arg(mail).arg(license)
1913 .arg(contributions).arg(contributionsIncluded));
1914 box.setWindowTitle(tr("about ENGRID"));
1915 box.setIcon(QMessageBox::NoIcon);
1916 box.exec();
1920 ///\todo Why not use bcs = m_AllBoundaryCodes; ?
1921 void GuiMainWindow::getAllBoundaryCodes(QVector<int> &bcs)
1923 bcs.resize(m_AllBoundaryCodes.size());
1924 qCopy(m_AllBoundaryCodes.begin(), m_AllBoundaryCodes.end(), bcs.begin());
1925 qSort(bcs);
1928 QSet<int> GuiMainWindow::getAllBoundaryCodes()
1930 return m_AllBoundaryCodes;
1933 void GuiMainWindow::getDisplayBoundaryCodes(QSet<int> &bcs)
1935 bcs.clear();
1936 foreach (int bc, m_DisplayBoundaryCodes) {
1937 bcs.insert(bc);
1941 QList<VolumeDefinition> GuiMainWindow::getAllVols()
1943 QList<VolumeDefinition> vols;
1944 foreach(VolumeDefinition vol, m_VolMap) {
1945 vols.push_back(vol);
1947 return vols;
1950 void GuiMainWindow::setAllVols(QList<VolumeDefinition> vols)
1952 m_VolMap.clear();
1953 foreach (VolumeDefinition V, vols) {
1954 m_VolMap[V.getName()] = V;
1958 QList<PhysicalBoundaryCondition> GuiMainWindow::getAllPhysicalBoundaryConditions()
1960 QList<PhysicalBoundaryCondition> physical_boundary_conditions;
1961 foreach(PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
1962 physical_boundary_conditions.push_back(PBC);
1964 return physical_boundary_conditions;
1967 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList<PhysicalBoundaryCondition> physical_boundary_conditions)
1969 m_PhysicalBoundaryConditionsMap.clear();
1970 foreach (PhysicalBoundaryCondition PBC, physical_boundary_conditions) {
1971 m_PhysicalBoundaryConditionsMap[PBC.getName()] = PBC;
1975 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap<QString,PhysicalBoundaryCondition> physical_boundary_conditions) {
1976 m_PhysicalBoundaryConditionsMap = physical_boundary_conditions;
1979 void GuiMainWindow::createDefaultVol()
1981 QList<VolumeDefinition> vols = getAllVols();
1982 if (vols.size() == 0) {
1983 VolumeDefinition V("default", 1);
1984 QVector<int> bcs;
1985 getAllBoundaryCodes(bcs);
1986 foreach (int bc, bcs) {
1987 V.addBC(bc, 1);
1989 vols.append(V);
1990 setAllVols(vols);
1994 QString GuiMainWindow::getFilePath()
1996 QFileInfo fileinfo(m_CurrentFilename);
1997 return fileinfo.absolutePath()+"/";
2000 void GuiMainWindow::markOutputLine()
2002 cout << "\n****************************************\n";
2003 cout << qPrintable(QTime::currentTime().toString("hh:mm:ss"));
2004 cout << "\n****************************************\n" << endl;
2007 void GuiMainWindow::storeCadInterfaces(bool nosave)
2009 try {
2010 resetCadInterfaces();
2011 CgalTriCadInterface *cad = new CgalTriCadInterface(m_Grid);
2012 setUniversalCadInterface(cad);
2013 if (!nosave) {
2014 save();
2015 saveGrid(m_Grid, m_CurrentFilename + ".geo");
2018 } catch (Error E) {
2019 E.display();
2023 void GuiMainWindow::setUniversalCadInterface(CadInterface *cad_interface)
2025 m_UniCadInterface = cad_interface;
2026 cad_interface->setForegroundGrid(m_Grid);
2029 void GuiMainWindow::resetCadInterfaces()
2031 delete m_UniCadInterface;
2032 m_UniCadInterface = NULL;
2033 foreach (CadInterface* cad_interface, m_CadInterfaces) {
2034 delete cad_interface;
2036 m_CadInterfaces.clear();
2039 CadInterface *GuiMainWindow::getCadInterface(int bc, bool allow_null)
2041 QString bc_txt;
2042 bc_txt.setNum(bc);
2043 if (!m_CadInterfaces.contains(bc)) {
2044 bc = 0;
2046 if (!m_CadInterfaces.contains(bc)) {
2047 if (m_UniCadInterface) {
2048 return m_UniCadInterface;
2050 if (allow_null) {
2051 return NULL;
2053 EG_ERR_RETURN("No surface projection found for boundary code " + bc_txt);
2055 return m_CadInterfaces[bc];
2058 bool GuiMainWindow::checkCadInterfaces()
2060 bool ok = true;
2061 if (!m_UniCadInterface) {
2062 foreach (int bc, m_AllBoundaryCodes) {
2063 if (!m_CadInterfaces.contains(bc)) {
2064 ok = false;
2065 break;
2069 return ok;
2072 void GuiMainWindow::openRecent(QAction *action)
2074 qDebug()<<"GuiMainWindow::openRecent called";
2075 QString file_name = action->text().right(action->text().length()-23);
2076 this->open(file_name);
2079 void GuiMainWindow::readRecentFiles()
2081 m_RecentFiles.clear();
2082 this->recentFileMenu()->clear();
2083 QStringList file_names = m_qset.value("FileNames").toStringList();
2084 QStringList file_dates = m_qset.value("FileDates").toStringList();
2085 int N = min(10,m_qset.value("NumberOfFiles").toInt());
2086 // cout << "NumberOfFiles=" << N << endl;
2087 for (int i = 0; i < N; ++i) {
2088 QString new_file = file_names.at(i);
2089 QString date_text = file_dates.at(i);
2090 QDateTime date = QDateTime::fromString(date_text,"dd.MM.yyyy_hh:mm:ss");
2091 addRecentFile(new_file,date);
2095 void GuiMainWindow::writeRecentFiles()
2097 m_qset.setValue("NumberOfFiles",m_RecentFiles.size());
2098 QStringList file_names;
2099 QStringList file_dates;
2100 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2101 QString file_name = i.key();
2102 QString date_text = i.value().toString("dd.MM.yyyy_hh:mm:ss");
2103 file_names.append(file_name);
2104 file_dates.append(date_text);
2106 m_qset.setValue("FileNames",file_names);
2107 m_qset.setValue("FileDates",file_dates);
2110 void GuiMainWindow::addRecentFile(QString file_name, QDateTime date)
2112 m_RecentFiles[file_name] = date;
2113 while (m_RecentFiles.size() > 10) {
2114 QMap<QString,QDateTime>::iterator i,j;
2115 QDateTime old = QDateTime::currentDateTime();
2116 for (i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2117 if (i.value() <= old) {
2118 old = i.value();
2119 j = i;
2122 m_RecentFiles.erase(j);
2124 this->recentFileMenu()->clear();
2125 QMap<int,QString> menu_map;
2126 QDateTime now = QDateTime::currentDateTime();
2127 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
2128 QString action_text = i.value().toString("dd.MM.yyyy hh:mm:ss");
2129 action_text += " -> ";
2130 action_text += i.key();
2131 menu_map[i.value().secsTo(now)] = action_text;
2134 for (QMap<int,QString>::iterator i = menu_map.begin(); i != menu_map.end(); ++i) {
2135 QAction *action = new QAction(i.value(),this);
2136 this->recentFileMenu()->addAction(action);
2141 void GuiMainWindow::callInsertNewCell()
2143 bool ok1,ok2,ok3,ok4;
2144 vtkIdType pts[3];
2145 #if QT_VERSION < 0x040500
2146 pts[0] = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2147 pts[1] = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2148 pts[2] = QInputDialog::getInteger(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
2149 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);
2150 #else
2151 pts[0] = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2152 pts[1] = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2153 pts[2] = QInputDialog::getInt(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
2154 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);
2155 #endif
2156 if (ok1 && ok2 && ok3 && ok4) {
2157 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2158 allocateGrid( new_grid, m_Grid->GetNumberOfCells() + 1, m_Grid->GetNumberOfPoints() );
2159 makeCopyNoAlloc(m_Grid, new_grid);
2160 vtkIdType id_new_cell = new_grid->InsertNextCell(VTK_TRIANGLE, 3, pts);
2161 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2162 makeCopy(new_grid, m_Grid);
2163 m_Grid->Modified();
2164 QMessageBox::information(NULL, "new cell", tr("The new cell has ID = %1").arg(id_new_cell));
2165 qDebug()<<tr("The new cell has ID = %1").arg(id_new_cell);
2169 void GuiMainWindow::callMergeNodes()
2171 bool ok1,ok2;
2172 #if QT_VERSION < 0x040500
2173 vtkIdType id_node1 = QInputDialog::getInteger(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2174 vtkIdType id_node2 = QInputDialog::getInteger(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2175 #else
2176 vtkIdType id_node1 = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2177 vtkIdType id_node2 = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2178 #endif
2179 if (ok1 && ok2) {
2180 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2181 allocateGrid( new_grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints() - 1 );
2183 QVector<vtkIdType> old2new_nodes(m_Grid->GetNumberOfPoints(), -1);
2184 QVector<vtkIdType> old2new_cells(m_Grid->GetNumberOfCells(), -1);
2186 vtkIdType id_new_node = 0;
2187 for (vtkIdType id_node = 0; id_node < m_Grid->GetNumberOfPoints(); ++id_node) {
2188 if(id_node!=id_node1 && id_node!=id_node2) {
2189 vec3_t x;
2190 m_Grid->GetPoints()->GetPoint(id_node, x.data());
2191 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2192 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2193 old2new_nodes[id_node] = id_new_node;
2194 id_new_node++;
2196 else if(id_node==id_node1) {
2197 vec3_t x1;
2198 m_Grid->GetPoints()->GetPoint(id_node1, x1.data());
2199 vec3_t x2;
2200 m_Grid->GetPoints()->GetPoint(id_node2, x2.data());
2201 vec3_t x = 0.5*(x1+x2);
2202 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2203 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2204 old2new_nodes[id_node1] = id_new_node;
2205 old2new_nodes[id_node2] = id_new_node;
2206 id_new_node++;
2208 else {
2212 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
2213 vtkIdType N_pts, *pts;
2214 vtkIdType type_cell = m_Grid->GetCellType(id_cell);
2215 m_Grid->GetCellPoints(id_cell, N_pts, pts);
2216 QVector<vtkIdType> new_pts(N_pts);
2217 for (int i = 0; i < N_pts; ++i) {
2218 new_pts[i] = old2new_nodes[pts[i]];
2220 vtkIdType id_new_cell = new_grid->InsertNextCell(type_cell, N_pts, new_pts.data());
2221 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2224 makeCopy(new_grid, m_Grid);
2225 m_Grid->Modified();
2226 qDebug()<<"The fusion is complete.";
2231 void GuiMainWindow::onEsc()
2233 setPickMode(true, true);
2234 pickCell(-1);
2235 m_CellPicker->Pick(-1e99,-1e99,0,m_Renderer);
2236 updateActors(true);
2237 updateStatusBar();
2240 void GuiMainWindow::resetProgress(QString info_text, int p_max)
2242 m_StatusInfoLabel->setText(info_text);
2243 m_StatusProgressBar->setMaximum(p_max);
2244 m_StatusProgressBar->setValue(0);
2245 QApplication::processEvents();
2248 void GuiMainWindow::setProgress(int p)
2250 m_StatusProgressBar->setValue(p);
2251 for (int i = 0; i < 3; ++i) {
2252 QApplication::processEvents();
2256 void GuiMainWindow::lock()
2258 m_Mutex.lock();
2261 void GuiMainWindow::unlock()
2263 m_Mutex.unlock();
2266 bool GuiMainWindow::tryLock()
2268 return m_Mutex.tryLock();