added possibility to merge volumes
[engrid.git] / src / guimainwindow.cpp
blob902a5758762ef3a4ecb0cce9520170147a3ffac6
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008,2009 Oliver Gloth +
7 // + +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
12 // + +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
17 // + +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // + +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "guimainwindow.h"
24 #include "guiselectboundarycodes.h"
25 #include "guiimproveaspectratio.h"
26 #include "guinormalextrusion.h"
27 #include "guisetboundarycode.h"
28 #include "guipick.h"
30 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
31 #include "stlreader.h"
32 #include "gmshreader.h"
33 #include "gmshwriter.h"
34 #include "neutralwriter.h"
35 #include "stlwriter.h"
36 #include "plywriter.h"
37 #include "correctsurfaceorientation.h"
38 #include "guieditboundaryconditions.h"
39 #include "laplacesmoother.h"
40 #include "swaptriangles.h"
42 #include <vtkRenderer.h>
43 #include <vtkRenderWindow.h>
44 #include <vtkXMLUnstructuredGridWriter.h>
45 #include <vtkXMLUnstructuredGridReader.h>
46 #include <vtkProperty.h>
47 #include <vtkCallbackCommand.h>
48 #include <vtkCamera.h>
49 #include <vtkCharArray.h>
50 #include <vtkTextActor.h>
51 #include <vtkVectorText.h>
52 #include <vtkFollower.h>
53 #include <vtkLookupTable.h>
54 #include <vtkScalarBarActor.h>
56 #include <QFileDialog>
57 #include <QFileSystemWatcher>
58 #include <QFileInfo>
59 #include <stdlib.h>
60 #include <stdio.h>
62 #include "geometrytools.h"
64 using namespace GeometryTools;
66 #include "guisettingsviewer.h"
67 #include "guitransform.h"
68 #include "egvtkinteractorstyle.h"
69 #include "showinfo.h"
71 QString GuiMainWindow::m_cwd = ".";
72 QSettings GuiMainWindow::m_qset("enGits","enGrid");
73 GuiMainWindow* GuiMainWindow::THIS = NULL;
74 QMutex GuiMainWindow::m_Mutex;
75 bool GuiMainWindow::m_UnSaved = true;
77 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
79 setupGuiMainWindow();
80 if(m_open_last) {
81 if(m_qset.contains("LatestFile")) {
82 // qDebug()<<"Opening latest";
83 open(m_qset.value("LatestFile").toString());
88 GuiMainWindow::GuiMainWindow(QString file_name) : QMainWindow(NULL)
90 setupGuiMainWindow();
91 open(file_name);
94 void GuiMainWindow::setupGuiMainWindow()
96 ui.setupUi(this);
97 THIS = this;
99 // restore window size
100 if(m_qset.contains("GuiMainWindow")) {
101 setGeometry(m_qset.value("GuiMainWindow").toRect());
103 else {
104 this->setWindowState(Qt::WindowMaximized);
107 // restore dockwidget positions
108 if(m_qset.contains("dockWidget_states")) {
109 restoreState(m_qset.value("dockWidget_states").toByteArray());
111 else {
112 tabifyDockWidget(ui.dockWidget_output, ui.dockWidget_node_cell_info);
113 tabifyDockWidget(ui.dockWidget_DisplayOptions, ui.dockWidget_DebuggingUtilities);
114 ui.dockWidget_node_cell_info->hide();
115 ui.dockWidget_DebuggingUtilities->hide();
118 # include "std_connections.h"
120 if (m_qset.contains("working_directory")) {
121 m_cwd = m_qset.value("working_directory").toString();
124 setupVtk();
126 resetOperationCounter();//clears undo/redo list and disables undo/redo
127 m_CurrentFilename = "untitled.egc";
128 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
129 setUnsaved(true);
131 m_StatusLabel = new QLabel(this);
132 statusBar()->addWidget(m_StatusLabel);
134 QString txt = "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms), ";
135 txt += "0 surface cells (0 triangles, 0 quads), 0 nodes";
136 m_StatusLabel->setText(txt);
137 ui.label_node_cell_info->setText(txt);
139 QString user = QString(getenv("USER"));
140 QString basename="enGrid_output.txt";
142 // define temporary path
143 QDir dir("/");
144 if (m_qset.contains("tmp_directory")) {
145 m_LogDir = m_qset.value("tmp_directory").toString();
146 } else {
147 m_LogDir = dir.tempPath();
149 QDateTime now = QDateTime::currentDateTime();
150 m_LogDir = m_LogDir + "/" + "enGrid_" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz") + "/";
151 dir.mkpath(m_LogDir);
153 m_LogFileName = m_LogDir + basename;
154 cout << "m_LogFileName = " << qPrintable(m_LogFileName) << endl;
156 m_SystemStdout = stdout;
157 if(freopen (qPrintable(m_LogFileName), "w", stdout)==NULL) EG_BUG;
159 m_Busy = false;
161 setPickMode(true,true);
162 m_PickedPoint = -1;
163 m_PickedCell = -1;
165 updateStatusBar();
167 connect(&m_GarbageTimer, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
168 m_GarbageTimer.start(1000);
170 connect(&m_LogTimer, SIGNAL(timeout()), this, SLOT(updateOutput()));
171 m_LogTimer.start(1000);
173 m_N_chars = 0;
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.actionFoamWriter->setEnabled(exp_features);
184 m_ReferenceSize=0.2;
186 ui.doubleSpinBox_HueMin->setValue(0.667);
187 ui.doubleSpinBox_HueMax->setValue(0);
189 egvtkInteractorStyle *style = egvtkInteractorStyle::New();
190 getInteractor()->SetInteractorStyle(style);
191 style->Delete();
193 // initialise XML document
194 m_XmlHandler = new XmlHandler("engridcase");
195 // this->resetXmlDoc();
197 m_SolverIndex = 0;
199 readRecentFiles();
202 //end of GuiMainWindow::GuiMainWindow() : QMainWindow(NULL)
204 void GuiMainWindow::resetXmlDoc()
206 m_XmlHandler->resetXmlDoc();
209 GuiMainWindow::~GuiMainWindow()
211 writeRecentFiles();
213 m_qset.setValue("GuiMainWindow", this->geometry());
214 m_qset.setValue("dockWidget_states", this->saveState());
216 #ifndef QT_DEBUG
217 QDirIterator it(m_LogDir);
218 while (it.hasNext()) {
219 QString str = it.next();
220 QFileInfo fileinfo(str);
221 if(fileinfo.isFile()) {
222 QFile file(str);
223 if(!file.remove()) qDebug() << "Failed to remove " << file.fileName();
226 QDir dir(m_LogDir);
227 dir.rmdir(m_LogDir);
228 #endif
230 delete m_XmlHandler;
233 void GuiMainWindow::setupVtk()
235 m_Grid = vtkUnstructuredGrid::New();
236 m_Renderer = vtkRenderer::New();
237 getRenderWindow()->AddRenderer(m_Renderer);
239 // coordinate axes
240 m_Axes = vtkCubeAxesActor2D::New();
242 m_Axes->SetCamera(getRenderer()->GetActiveCamera());
243 getRenderer()->AddActor(m_Axes);
244 m_Axes->SetVisibility(0);
246 // surface pipelines
247 m_BackfaceProperty = vtkProperty::New();
248 m_SurfaceFilter = vtkGeometryFilter::New();
249 m_SurfaceMapper = vtkPolyDataMapper::New();
250 m_SurfaceWireMapper = vtkPolyDataMapper::New();
251 m_BCodesFilter = vtkEgBoundaryCodesFilter::New();
252 m_LookupTable = vtkLookupTable::New();
253 m_SurfaceActor = vtkActor::New();
254 m_SurfaceWireActor = vtkActor::New();
255 m_LegendActor = vtkScalarBarActor::New();
257 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
258 m_BCodesFilter->SetInput(m_Grid);
259 m_SurfaceFilter->SetInput(m_BCodesFilter->GetOutput());
260 m_SurfaceMapper->SetInput(m_SurfaceFilter->GetOutput());
261 m_SurfaceWireMapper->SetInput(m_SurfaceFilter->GetOutput());
262 m_SurfaceMapper->SetLookupTable(m_LookupTable);
263 m_SurfaceActor->GetProperty()->SetRepresentationToSurface();
264 m_SurfaceActor->GetProperty()->SetColor(0.5,1,0.5);
265 m_SurfaceActor->SetBackfaceProperty(m_BackfaceProperty);
266 m_SurfaceActor->GetBackfaceProperty()->SetColor(1,1,0.5);
267 m_SurfaceActor->SetMapper(m_SurfaceMapper);
268 getRenderer()->AddActor(m_SurfaceActor);
269 m_SurfaceActor->SetVisibility(1);
270 m_LegendActor->SetLookupTable(m_LookupTable);
271 getRenderer()->AddActor(m_LegendActor);
272 m_LegendActor->SetVisibility(0);
273 m_SurfaceWireActor->GetProperty()->SetRepresentationToWireframe();
274 m_SurfaceWireActor->GetProperty()->SetColor(0,0,1);
275 m_SurfaceWireActor->SetMapper(m_SurfaceWireMapper);
276 getRenderer()->AddActor(m_SurfaceWireActor);
277 m_SurfaceWireActor->SetVisibility(1);
279 // tetra pipline
280 m_ExtrTetras = vtkEgExtractVolumeCells::New();
281 m_TetraActor = vtkActor::New();
282 m_TetraGeometry = vtkGeometryFilter::New();
283 m_TetraMapper = vtkPolyDataMapper::New();
285 m_ExtrTetras->SetInput(m_Grid);
286 m_ExtrTetras->SetAllOff();
287 m_ExtrTetras->SetTetrasOn();;
288 m_TetraGeometry->SetInput(m_ExtrTetras->GetOutput());
289 m_TetraMapper->SetInput(m_TetraGeometry->GetOutput());
290 m_TetraActor->SetMapper(m_TetraMapper);
291 m_TetraActor->GetProperty()->SetColor(1,0,0);
292 getRenderer()->AddActor(m_TetraActor);
293 m_TetraActor->SetVisibility(0);
295 // pyramid pipeline
296 m_PyramidActor = vtkActor::New();
297 m_ExtrPyramids = vtkEgExtractVolumeCells::New();
298 m_PyramidGeometry = vtkGeometryFilter::New();
299 m_PyramidMapper = vtkPolyDataMapper::New();
301 m_ExtrPyramids->SetInput(m_Grid);
302 m_ExtrPyramids->SetAllOff();
303 m_ExtrPyramids->SetPyramidsOn();
304 m_PyramidGeometry->SetInput(m_ExtrPyramids->GetOutput());
305 m_PyramidMapper->SetInput(m_PyramidGeometry->GetOutput());
306 m_PyramidActor->SetMapper(m_PyramidMapper);
307 m_PyramidActor->GetProperty()->SetColor(1,1,0);
308 getRenderer()->AddActor(m_PyramidActor);
309 m_PyramidActor->SetVisibility(0);
311 // wedge pipeline
312 m_WedgeActor = vtkActor::New();
313 m_ExtrWedges = vtkEgExtractVolumeCells::New();
314 m_WedgeGeometry = vtkGeometryFilter::New();
315 m_WedgeMapper = vtkPolyDataMapper::New();
317 m_ExtrWedges->SetInput(m_Grid);
318 m_ExtrWedges->SetAllOff();
319 m_ExtrWedges->SetWedgesOn();
320 m_WedgeGeometry->SetInput(m_ExtrWedges->GetOutput());
321 m_WedgeMapper->SetInput(m_WedgeGeometry->GetOutput());
322 m_WedgeActor->SetMapper(m_WedgeMapper);
323 m_WedgeActor->GetProperty()->SetColor(0,1,0);
324 getRenderer()->AddActor(m_WedgeActor);
325 m_WedgeActor->SetVisibility(0);
327 // hexa pipeline
328 m_HexaActor = vtkActor::New();
329 m_ExtrHexes = vtkEgExtractVolumeCells::New();
330 m_HexaGeometry = vtkGeometryFilter::New();
331 m_HexaMapper = vtkPolyDataMapper::New();
333 m_ExtrHexes->SetInput(m_Grid);
334 m_ExtrHexes->SetAllOff();
335 m_ExtrHexes->SetHexesOn();
336 m_HexaGeometry->SetInput(m_ExtrHexes->GetOutput());
337 m_HexaMapper->SetInput(m_HexaGeometry->GetOutput());
338 m_HexaActor->SetMapper(m_HexaMapper);
339 m_HexaActor->GetProperty()->SetColor(0,0.7,1);
340 getRenderer()->AddActor(m_HexaActor);
341 m_HexaActor->SetVisibility(0);
343 // volume wire pipeline
344 m_VolumeWireActor = vtkActor::New();
345 m_ExtrVol = vtkEgExtractVolumeCells::New();
346 m_VolumeGeometry = vtkGeometryFilter::New();
347 m_VolumeWireMapper = vtkPolyDataMapper::New();
349 m_ExtrVol->SetInput(m_Grid);
350 m_ExtrVol->SetAllOn();
351 m_VolumeGeometry->SetInput(m_ExtrVol->GetOutput());
352 m_VolumeWireMapper->SetInput(m_VolumeGeometry->GetOutput());
353 m_VolumeWireActor->SetMapper(m_VolumeWireMapper);
354 m_VolumeWireActor->GetProperty()->SetRepresentationToWireframe();
355 m_VolumeWireActor->GetProperty()->SetColor(0,0,1);
356 getRenderer()->AddActor(m_VolumeWireActor);
357 m_VolumeWireActor->SetVisibility(0);
359 // picker stuff
360 m_PickSphere = vtkSphereSource::New();
361 m_PickMapper = vtkPolyDataMapper::New();
362 m_PickActor = vtkActor::New();
363 m_CellPicker = vtkCellPicker::New();
364 m_PointPicker = vtkPointPicker::New();
366 m_PickSphere->SetRadius(0.25); //in case the user starts picking points instead of cells
367 m_PickMapper->SetInput(m_PickSphere->GetOutput());
368 m_PickActor->SetMapper(m_PickMapper);
369 m_PickActor->GetProperty()->SetRepresentationToSurface();
370 m_PickActor->GetProperty()->SetColor(0,0,1);
371 m_PickActor->VisibilityOff();
372 getRenderer()->AddActor(m_PickActor);
374 vtkCallbackCommand *cbc = vtkCallbackCommand::New();
375 cbc->SetCallback(pickCallBack);
377 m_CellPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
378 m_PointPicker->AddObserver(vtkCommand::EndPickEvent, cbc);
379 m_PickedObject = 0;
380 // cbc->Delete();
383 void GuiMainWindow::updateOutput()
385 QFile log_file(m_LogFileName);
386 log_file.open(QIODevice::ReadOnly);
387 QByteArray buffer = log_file.readAll();
388 if (buffer.size() > m_N_chars) {
389 QByteArray newchars = buffer.right(buffer.size() - m_N_chars);
390 m_N_chars = buffer.size();
391 QString txt(newchars);
392 if (txt.right(1) == "\n") {
393 txt = txt.left(txt.size()-1);
395 ui.textEditOutput->append(txt);
399 void GuiMainWindow::exit()
401 QCoreApplication::exit();
404 vtkRenderWindow* GuiMainWindow::getRenderWindow()
406 return ui.qvtkWidget->GetRenderWindow();
409 vtkRenderer* GuiMainWindow::getRenderer()
411 return m_Renderer;
414 QVTKInteractor* GuiMainWindow::getInteractor()
416 return ui.qvtkWidget->GetInteractor();
419 QString GuiMainWindow::getCwd()
421 return m_cwd;
424 void GuiMainWindow::setCwd(QString dir)
426 m_cwd = dir;
427 m_qset.setValue("working_directory",dir);
430 void GuiMainWindow::setUnsaved(bool unsaved)
432 m_UnSaved = unsaved;
435 void GuiMainWindow::scaleToData()
437 int current_field=ui.comboBox_Field->currentIndex();
438 if(current_field>0)
440 double range[2];
442 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
443 //boundary_pd->GetPointData()->GetArray(current_field-1)->GetRange(range);
444 cout<<"current_field="<<current_field<<endl;
445 cout<<"range[0]="<<range[0]<<endl;
446 cout<<"range[1]="<<range[1]<<endl;
447 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
448 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
449 ui.doubleSpinBox_FieldMin->setValue(range[0]);
450 ui.doubleSpinBox_FieldMax->setValue(range[1]);
454 void GuiMainWindow::setClipX(const QString &txt)
456 m_ExtrVol->Setx(txt.toDouble());
457 m_ExtrTetras->Setx(txt.toDouble());
458 m_ExtrPyramids->Setx(txt.toDouble());
459 m_ExtrWedges->Setx(txt.toDouble());
460 m_ExtrHexes->Setx(txt.toDouble());
463 void GuiMainWindow::setClipY(const QString &txt)
465 m_ExtrVol->Sety(txt.toDouble());
466 m_ExtrTetras->Sety(txt.toDouble());
467 m_ExtrPyramids->Sety(txt.toDouble());
468 m_ExtrWedges->Sety(txt.toDouble());
469 m_ExtrHexes->Sety(txt.toDouble());
472 void GuiMainWindow::setClipZ(const QString &txt)
474 m_ExtrVol->Setz(txt.toDouble());
475 m_ExtrTetras->Setz(txt.toDouble());
476 m_ExtrPyramids->Setz(txt.toDouble());
477 m_ExtrWedges->Setz(txt.toDouble());
478 m_ExtrHexes->Setz(txt.toDouble());
481 void GuiMainWindow::setClipNX(const QString &txt)
483 m_ExtrVol->Setnx(txt.toDouble());
484 m_ExtrTetras->Setnx(txt.toDouble());
485 m_ExtrPyramids->Setnx(txt.toDouble());
486 m_ExtrWedges->Setnx(txt.toDouble());
487 m_ExtrHexes->Setnx(txt.toDouble());
490 void GuiMainWindow::setClipNY(const QString &txt)
492 m_ExtrVol->Setny(txt.toDouble());
493 m_ExtrTetras->Setny(txt.toDouble());
494 m_ExtrPyramids->Setny(txt.toDouble());
495 m_ExtrWedges->Setny(txt.toDouble());
496 m_ExtrHexes->Setny(txt.toDouble());
499 void GuiMainWindow::setClipNZ(const QString &txt)
501 m_ExtrVol->Setnz(txt.toDouble());
502 m_ExtrTetras->Setnz(txt.toDouble());
503 m_ExtrPyramids->Setnz(txt.toDouble());
504 m_ExtrWedges->Setnz(txt.toDouble());
505 m_ExtrHexes->Setnz(txt.toDouble());
508 void GuiMainWindow::updateSurfaceActors(bool forced)
510 if (ui.checkBoxSurface->isChecked()) {
511 if (forced) {
512 m_SurfaceFilter->Update();
515 // fill node field combobox
516 int current_field=ui.comboBox_Field->currentIndex();
517 ui.comboBox_Field->clear();
518 ui.comboBox_Field->addItem("None");
519 for (int i = 0; i < m_Grid->GetPointData()->GetNumberOfArrays(); ++i) {
520 ui.comboBox_Field->addItem(m_Grid->GetPointData()->GetArrayName(i));
522 if(current_field == -1) {
523 ui.comboBox_Field->setCurrentIndex(0);
524 } else {
525 ui.comboBox_Field->setCurrentIndex(current_field);
528 // fill cell field combobox
529 int current_cell_field = ui.comboBox_CellTextField->currentIndex();
530 ui.comboBox_CellTextField->clear();
531 ui.comboBox_CellTextField->addItem("Cell ID");
532 for (int i = 0; i < m_SurfaceFilter->GetOutput()->GetCellData()->GetNumberOfArrays(); ++i) {
533 ui.comboBox_CellTextField->addItem(m_Grid->GetCellData()->GetArrayName(i));
535 if(current_cell_field == -1) {
536 ui.comboBox_CellTextField->setCurrentIndex(0);
537 } else {
538 ui.comboBox_CellTextField->setCurrentIndex(current_cell_field);
540 current_field = ui.comboBox_Field->currentIndex();
541 if(current_field > 0) {
542 double range[2];
543 m_SurfaceFilter->GetOutput()->GetPointData()->GetArray(current_field-1)->GetRange(range);
544 ui.doubleSpinBox_FieldMin->setRange(range[0],range[1]);
545 ui.doubleSpinBox_FieldMax->setRange(range[0],range[1]);
548 if(ui.comboBox_Field->currentIndex() > 0) {
549 m_SurfaceMapper->SetColorModeToMapScalars();
550 m_LookupTable->SetNumberOfColors(ui.spinBox_Color->value());
551 m_LookupTable->SetHueRange(ui.doubleSpinBox_HueMin->value(),ui.doubleSpinBox_HueMax->value());
552 m_LookupTable->Build();
553 m_SurfaceMapper->SetScalarModeToUsePointFieldData();
554 m_SurfaceMapper->ColorByArrayComponent(qPrintable(ui.comboBox_Field->currentText()),0);
555 m_SurfaceMapper->SetScalarRange(ui.doubleSpinBox_FieldMin->value(),ui.doubleSpinBox_FieldMax->value());
556 m_SurfaceMapper->ScalarVisibilityOn();
557 if(ui.checkBox_Legend->checkState()) {
558 m_LegendActor->SetVisibility(1);
559 } else {
560 m_LegendActor->SetVisibility(0);
562 } else {
563 m_SurfaceMapper->SetColorModeToDefault();
564 m_SurfaceMapper->ScalarVisibilityOff();
565 m_LegendActor->SetVisibility(0);
567 if (forced) {
568 m_BCodesFilter->Update();
570 if(ui.checkBox_ShowPickSphere->checkState()) {
571 if(m_UseVTKInteractor) {
572 if(ui.radioButton_CellPicker->isChecked()) {
573 getInteractor()->SetPicker(m_CellPicker);
574 vtkIdType id_cell = getPickedCell();
575 pickCell(id_cell);
576 } else {
577 getInteractor()->SetPicker(m_PointPicker);
578 vtkIdType id_node = getPickedPoint();
579 pickPoint(id_node);
581 } else {
582 if (ui.radioButton_CellPicker->isChecked()) {
583 pickCell(m_PickedCell);
584 } else {
585 pickPoint(m_PickedPoint);
589 m_SurfaceActor->SetVisibility(1);
590 m_SurfaceWireActor->SetVisibility(1);
591 } else {
592 m_SurfaceActor->SetVisibility(0);
593 m_SurfaceWireActor->SetVisibility(0);
597 void GuiMainWindow::updateVolumeActors(bool forced)
599 if (ui.checkBoxVolume->isChecked()) {
600 if (ui.checkBoxTetra->isChecked()) {
601 m_ExtrVol->SetTetrasOn();
602 if (ui.checkBoxClip->isChecked()) {
603 m_ExtrTetras->SetClippingOn();
604 } else {
605 m_ExtrTetras->SetClippingOff();
607 if (forced) {
608 m_TetraGeometry->Update();
610 m_TetraActor->SetVisibility(1);
611 } else {
612 m_ExtrVol->SetTetrasOff();
613 m_TetraActor->SetVisibility(0);
615 if (ui.checkBoxPyramid->isChecked()) {
616 m_ExtrVol->SetPyramidsOn();
617 if (ui.checkBoxClip->isChecked()) {
618 m_ExtrPyramids->SetClippingOn();
619 } else {
620 m_ExtrPyramids->SetClippingOff();
622 if (forced) {
623 m_PyramidGeometry->Update();
625 m_PyramidActor->SetVisibility(1);
626 } else {
627 m_ExtrVol->SetPyramidsOff();
628 m_PyramidActor->SetVisibility(0);
630 if (ui.checkBoxWedge->isChecked()) {
631 m_ExtrVol->SetWedgesOn();
632 if (ui.checkBoxClip->isChecked()) {
633 m_ExtrWedges->SetClippingOn();
634 } else {
635 m_ExtrWedges->SetClippingOff();
637 if (forced) {
638 m_WedgeGeometry->Update();
640 m_WedgeActor->SetVisibility(1);
641 } else {
642 m_ExtrVol->SetWedgesOff();
643 m_WedgeActor->SetVisibility(0);
645 if (ui.checkBoxHexa->isChecked()) {
646 m_ExtrVol->SetHexesOn();
647 if (ui.checkBoxClip->isChecked()) {
648 m_ExtrHexes->SetClippingOn();
649 } else {
650 m_ExtrHexes->SetClippingOff();
652 if (forced) {
653 m_HexaGeometry->Update();
655 m_HexaActor->SetVisibility(1);
656 } else {
657 m_ExtrVol->SetHexesOff();
658 m_HexaActor->SetVisibility(0);
661 // wireframe
662 if (ui.checkBoxClip->isChecked()) {
663 m_ExtrVol->SetClippingOn();
664 } else {
665 m_ExtrVol->SetClippingOff();
667 if (forced) {
668 m_VolumeGeometry->Update();
670 m_VolumeWireActor->SetVisibility(1);
671 } else {
672 m_TetraActor->VisibilityOff();
673 m_PyramidActor->VisibilityOff();
674 m_WedgeActor->VisibilityOff();
675 m_HexaActor->VisibilityOff();
676 m_VolumeWireActor->VisibilityOff();
680 void GuiMainWindow::updateActors(bool forced)
682 // qDebug()<<"QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); called()";
683 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
685 //if (!tryLock()) return;
686 try {
687 m_Axes->SetInput(m_Grid);
688 updateSurfaceActors(forced);
689 updateVolumeActors(forced);
690 updateStatusBar();
691 } catch (Error err) {
692 err.display();
694 //unlock();
696 // qDebug()<<"QApplication::restoreOverrideCursor(); called()";
697 QApplication::restoreOverrideCursor();
702 void GuiMainWindow::forceUpdateActors()
704 // qDebug()<<"void GuiMainWindow::forceUpdateActors() START";
705 updateActors(true);
706 getRenderWindow()->Render();
707 // qDebug()<<"void GuiMainWindow::forceUpdateActors() END";
710 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor,bool a_CellPickerMode)
712 m_UseVTKInteractor=a_UseVTKInteractor;
713 if (a_UseVTKInteractor) {
714 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Checked);
715 } else {
716 ui.checkBox_UseVTKInteractor->setCheckState(Qt::Unchecked);
718 if (a_CellPickerMode) {
719 ui.radioButton_CellPicker->toggle();
720 } else {
721 ui.radioButton_PointPicker->toggle();
725 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor)
727 m_UseVTKInteractor = a_UseVTKInteractor;
730 bool GuiMainWindow::pickPoint(vtkIdType id_node)
732 if ((id_node >= 0) && (id_node < m_Grid->GetNumberOfPoints())) {
733 vec3_t x(0,0,0);
734 m_Grid->GetPoints()->GetPoint(id_node, x.data());
735 m_PickSphere->SetCenter(x.data());
736 m_PickedPoint = id_node;
737 m_PickActor->GetProperty()->SetColor(0,0,1);
738 m_PickActor->VisibilityOn();
739 m_PickedObject = 1;
740 return(true);
741 } else {
742 m_PickActor->VisibilityOff();
743 m_PickedObject = 0;
744 return(false);
748 bool GuiMainWindow::pickCell(vtkIdType id_cell)
750 if ((id_cell >= 0) && (id_cell < m_Grid->GetNumberOfCells())) {
751 vtkIdType *pts, Npts;
752 m_Grid->GetCellPoints(id_cell, Npts, pts);
753 vec3_t x(0,0,0);
754 for (vtkIdType i = 0; i < Npts; ++i) {
755 vec3_t xp;
756 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
757 x += double(1)/Npts * xp;
759 m_PickSphere->SetCenter(x.data());
760 double R = 1e99;
761 for (vtkIdType i = 0; i < Npts; ++i) {
762 vec3_t xp;
763 m_Grid->GetPoints()->GetPoint(pts[i], xp.data());
764 R = min(R, 0.25*(xp-x).abs());
766 m_ReferenceSize = R; //Used for text annotations too!
767 m_PickSphere->SetRadius(R);
768 m_PickedCell = id_cell;
769 m_PickActor->GetProperty()->SetColor(1,0,0);
770 m_PickActor->VisibilityOn();
771 m_PickedObject = 2;
772 return(true);
773 } else {
774 m_PickActor->VisibilityOff();
775 m_PickedObject = 0;
776 return(false);
780 void GuiMainWindow::importSTL()
782 StlReader stl;
783 stl();
784 updateBoundaryCodes(true);
785 updateActors();
786 updateStatusBar();
787 zoomAll();
790 void GuiMainWindow::importGmsh1Ascii()
792 GmshReader gmsh;
793 gmsh.setV1Ascii();
794 gmsh();
795 updateBoundaryCodes(true);
796 updateActors();
797 updateStatusBar();
798 zoomAll();
801 void GuiMainWindow::exportGmsh1Ascii()
803 GmshWriter gmsh;
804 gmsh.setV1Ascii();
805 gmsh();
808 void GuiMainWindow::importGmsh2Ascii()
810 GmshReader gmsh;
811 gmsh.setV2Ascii();
812 gmsh();
813 updateBoundaryCodes(true);
814 updateActors();
815 updateStatusBar();
816 zoomAll();
819 void GuiMainWindow::exportGmsh2Ascii()
821 GmshWriter gmsh;
822 gmsh.setV2Ascii();
823 gmsh();
826 void GuiMainWindow::exportNeutral()
828 NeutralWriter neutral;
829 neutral();
832 void GuiMainWindow::zoomAll()
834 getRenderer()->ResetCamera();
835 getRenderWindow()->Render();
838 void GuiMainWindow::zoomOnPickedObject()
840 if(m_PickActor->GetVisibility()) {
841 getRenderer()->ResetCamera(m_PickActor->GetBounds());
842 getRenderWindow()->Render();
846 void GuiMainWindow::deselectAll()
848 cout << "void GuiMainWindow::deselectAll()" << endl;
849 m_PickActor->VisibilityOff();
850 updateActors();
853 ///\todo Should display a window
854 void GuiMainWindow::info()
856 ShowInfo info(ui.radioButton_CellPicker->isChecked(), m_PickedPoint, m_PickedCell);
857 info();
860 int GuiMainWindow::quickSave()
862 ///\todo add RAM support
863 if(m_undo_redo_enabled) {
864 if(m_Grid->GetNumberOfPoints()>0)
866 m_CurrentOperation++;
867 QFileInfo fileinfo(m_CurrentFilename);
868 QString l_filename = m_LogDir + fileinfo.completeBaseName() + "_" + QString("%1").arg(m_CurrentOperation);
869 m_LastOperation=m_CurrentOperation;
870 cout<<"Operation "<<m_CurrentOperation<<endl;
871 saveAs(l_filename, false);
872 if(m_CurrentOperation>0) ui.actionUndo->setEnabled(true);
873 ui.actionRedo->setEnabled(false);
875 else cout<<"No grid to save!"<<endl;
876 return(m_CurrentOperation);
878 return 0;
881 void GuiMainWindow::quickLoad(int a_operation)
883 ///\todo add RAM support
884 if(m_undo_redo_enabled) {
885 QFileInfo fileinfo(m_CurrentFilename);
886 QString l_filename = m_LogDir + fileinfo.completeBaseName() + "_" + QString("%1").arg(a_operation) + ".egc";
887 open(l_filename, false);
891 void GuiMainWindow::undo()
893 if(m_undo_redo_enabled) {
894 cout << "Undoing operation " << m_CurrentOperation << endl;
895 m_CurrentOperation--;
896 quickLoad(m_CurrentOperation);
897 ui.actionRedo->setEnabled(true);
898 if(m_CurrentOperation<=0) ui.actionUndo->setEnabled(false);
900 else {
901 resetOperationCounter();
902 QMessageBox::critical(this, "de-activated", "Undo is not doing anything at the moment!");
906 void GuiMainWindow::redo()
908 if(m_undo_redo_enabled) {
909 m_CurrentOperation++;
910 cout << "Redoing operation " << m_CurrentOperation << endl;
911 quickLoad(m_CurrentOperation);
912 ui.actionUndo->setEnabled(true);
913 if(m_CurrentOperation>=m_LastOperation) ui.actionRedo->setEnabled(false);
915 else {
916 resetOperationCounter();
917 QMessageBox::critical(this, "de-activated", "Redo is not doing anything at the moment!");
921 void GuiMainWindow::resetOperationCounter()
923 m_CurrentOperation=-1;
924 m_LastOperation=m_CurrentOperation;
925 ui.actionUndo->setEnabled(false);
926 ui.actionRedo->setEnabled(false);
929 QString GuiMainWindow::getXmlSection(QString name)
931 return m_XmlHandler->getXmlSection(name);
934 void GuiMainWindow::setXmlSection(QString name, QString contents)
936 m_XmlHandler->setXmlSection(name,contents);
939 void GuiMainWindow::openPhysicalBoundaryConditions()
941 m_PhysicalBoundaryConditionsMap.clear();
942 QString buffer = getXmlSection("engrid/physical");
943 QTextStream f(&buffer, QIODevice::ReadOnly);
944 while (!f.atEnd()) {
945 QString name, type;
946 int index;
947 f >> index >> name >> type;
948 if ((name != "") && (type != "")) {
949 PhysicalBoundaryCondition PBC;
950 PBC.setName(name);
951 PBC.setIndex(index);
952 PBC.setType(type);
953 for (int i = 0; i < PBC.getNumVars(); ++i) {
954 double v;
955 f >> v;
956 PBC.setValue(i, v);
958 m_PhysicalBoundaryConditionsMap[name] = PBC;
963 void GuiMainWindow::savePhysicalBoundaryConditions()
965 QString buffer("");
966 QTextStream f(&buffer, QIODevice::WriteOnly);
967 f << "\n";
968 foreach (PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
969 f << PBC.getIndex() << " " << PBC.getName() << " " << PBC.getType();
970 for (int i = 0; i < PBC.getNumVars(); ++i) {
971 f << " " << PBC.getVarValue(i);
973 f << "\n";
975 setXmlSection("engrid/physical", buffer);
978 void GuiMainWindow::openBC()
980 m_bcmap.clear();
981 m_VolMap.clear();
982 QString buffer = getXmlSection("engrid/bc");
983 QTextStream f(&buffer, QIODevice::ReadOnly);
984 while (!f.atEnd()) {
985 QString name, type;
986 int i;
987 f >> i >> name >> type;
988 if(name!="" && type!="") {
989 if (i >= 0) {
990 m_bcmap[i] = BoundaryCondition(name,type);
991 } else {
992 VolumeDefinition V(name, -i);
993 QString text = type.replace(",", " ").replace(":", " ");
994 QTextStream s(&text);
995 while (!s.atEnd()) {
996 QString bc_txt, sign_txt;
997 s >> bc_txt >> sign_txt;
998 V.addBC(bc_txt.toInt(), sign_txt.toInt());
1000 m_VolMap[name] = V;
1006 void GuiMainWindow::saveBC()
1008 QString buffer("");
1009 QTextStream f(&buffer, QIODevice::WriteOnly);
1010 f << "\n";
1011 foreach (int i, m_AllBoundaryCodes) {
1012 BoundaryCondition bc = m_bcmap[i];
1013 f << i << " " << bc.getName() << " " << bc.getType() << "\n";
1015 foreach (VolumeDefinition V, m_VolMap) {
1016 QString dirs = "";
1017 bool first = true;
1018 foreach (int i, m_AllBoundaryCodes) {
1019 BoundaryCondition bc = m_bcmap[i];
1020 if (!first) {
1021 dirs += ",";
1022 } else {
1023 first = false;
1025 QString num;
1026 num.setNum(i);
1027 dirs += num + ":";
1028 num.setNum(V.getSign(i));
1029 dirs += num;
1031 f << "-" << V.getVC() << " " << V.getName() << " " << dirs << "\n";
1033 setXmlSection("engrid/bc", buffer);
1036 void GuiMainWindow::openGrid(QString file_name)
1038 file_name += ".vtu";
1039 EG_VTKSP(vtkXMLUnstructuredGridReader,vtu);
1040 vtu->SetFileName(qPrintable(file_name));
1041 vtu->Update();
1042 m_Grid->DeepCopy(vtu->GetOutput());
1043 createBasicFields(m_Grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints());
1044 openBC();
1045 openPhysicalBoundaryConditions();
1046 updateBoundaryCodes(true);
1047 createIndices(m_Grid);
1048 updateActors();
1049 updateStatusBar();
1050 zoomAll();
1053 ///\todo I think this should also be a done by a subclass of IOOperation just like for import operations
1054 void GuiMainWindow::open()
1056 QFileDialog dialog(NULL, "open grid from file", getCwd(), "enGrid case files (*.egc *.EGC);; legacy grid files(*.vtu *.VTU)");
1057 QFileInfo file_info(m_CurrentFilename);
1058 // qDebug()<<"m_CurrentFilename="<<m_CurrentFilename;
1059 dialog.selectFile(file_info.completeBaseName() + ".egc");
1060 if (dialog.exec()) {
1061 QStringList selected_files = dialog.selectedFiles();
1062 QString file_name = selected_files[0];
1063 if (!file_name.isNull()) {
1064 this->open(file_name);
1069 void GuiMainWindow::open(QString file_name, bool update_current_filename)
1071 cout << "Opening " << qPrintable(file_name) << endl;
1073 QFileInfo file_info(file_name);
1074 bool no_case_file = false;
1075 QString file_extension = getExtension(file_name);
1076 QString grid_file_name = file_name;
1077 if (file_extension.toLower() == "vtu") {
1078 no_case_file = true;
1079 grid_file_name = stripFromExtension(file_name);
1081 if (!no_case_file) {
1082 if(!m_XmlHandler->openXml(file_name)) {
1083 QMessageBox::critical(this, tr("Open failed"), tr("Error reading enGrid case file:\n%1").arg(file_name));
1084 return;
1087 if(update_current_filename) {
1088 GuiMainWindow::setCwd(QFileInfo(file_name).absolutePath());
1090 openGrid(grid_file_name);
1091 openBC();
1092 openPhysicalBoundaryConditions();
1093 // update current filename
1094 if(update_current_filename) m_CurrentFilename = stripFromExtension(file_name) + ".egc";
1095 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1096 setUnsaved(false);
1098 if(update_current_filename) {
1099 this->addRecentFile(file_name,QDateTime::currentDateTime());
1100 // qDebug()<<"Setting new latest file to "<<file_name;
1101 m_qset.setValue("LatestFile",file_name);
1102 resetOperationCounter();
1103 quickSave();
1107 QString GuiMainWindow::saveAs(QString file_name, bool update_current_filename)
1109 QString buffer = m_XmlHandler->getBuffer(0);
1111 if(update_current_filename) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1113 QFileInfo file_info(file_name);
1114 if (file_info.suffix().toLower() != "egc") {
1115 file_name += ".egc";
1117 cout << "Saving as " << qPrintable(file_name) << endl;
1118 if(update_current_filename) {
1119 // update current filename
1120 GuiMainWindow::setCwd(file_info.absolutePath());
1121 m_CurrentFilename = file_name;
1123 if(!saveGrid(m_Grid, file_name)) {
1124 QMessageBox::critical(this, QObject::tr("Save failed"), QObject::tr("The grid could not be saved as:\n%1").arg(file_name));
1127 saveBC();
1128 savePhysicalBoundaryConditions();
1129 // saveXml(file_name);
1130 m_XmlHandler->saveXml(file_name);
1132 setWindowTitle(m_CurrentFilename + " - enGrid - " + QString("%1").arg(m_CurrentOperation) );
1133 setUnsaved(false);
1135 if(update_current_filename) QApplication::restoreOverrideCursor();
1137 if(update_current_filename) {
1138 this->addRecentFile(file_name,QDateTime::currentDateTime());
1139 // qDebug()<<"Setting new latest file to "<<file_name;
1140 m_qset.setValue("LatestFile",file_name);
1143 return(file_name);
1146 void GuiMainWindow::save()
1148 if ( m_CurrentFilename == "untitled.egc" || m_UnSaved ) {
1149 saveAs();
1150 } else {
1151 saveAs(m_CurrentFilename);
1155 void GuiMainWindow::saveAs()
1157 QFileDialog dialog(NULL, "write case to file", getCwd(), "enGrid case files (*.egc)");
1158 QFileInfo file_info(m_CurrentFilename);
1159 dialog.selectFile(file_info.completeBaseName() + ".egc");
1160 dialog.setAcceptMode(QFileDialog::AcceptSave);
1161 dialog.setConfirmOverwrite(true);
1162 if (dialog.exec()) {
1163 QStringList selected_files = dialog.selectedFiles();
1164 QString file_name = selected_files[0];
1165 if (!file_name.isNull()) {
1166 saveAs(file_name);
1167 //for the undo/redo operations
1168 resetOperationCounter();
1169 quickSave();
1174 void GuiMainWindow::updateStatusBar()
1176 QString num, txt = "enGrid is currently busy with an operation ...";
1177 if (!m_Busy) {
1178 txt = "";
1180 if (!tryLock()) {
1181 m_StatusLabel->setText(txt);
1182 ui.label_node_cell_info->setText(txt);
1183 return;
1185 vtkIdType Ncells = m_Grid->GetNumberOfCells();
1186 vtkIdType Nnodes = m_Grid->GetNumberOfPoints();
1187 vtkIdType Ntris = 0;
1188 vtkIdType Nquads = 0;
1189 vtkIdType Ntets = 0;
1190 vtkIdType Npyras = 0;
1191 vtkIdType Nprism = 0;
1192 vtkIdType Nhexas = 0;
1193 for (vtkIdType i = 0; i < Ncells; ++i) {
1194 int ct = m_Grid->GetCellType(i);
1195 if (ct == VTK_TRIANGLE) ++Ntris;
1196 else if (ct == VTK_QUAD) ++Nquads;
1197 else if (ct == VTK_TETRA) ++Ntets;
1198 else if (ct == VTK_WEDGE) ++Nprism;
1199 else if (ct == VTK_PYRAMID) ++Npyras;
1200 else if (ct == VTK_HEXAHEDRON) ++Nhexas;
1202 num.setNum(Ntets + Npyras + Nprism + Nhexas); txt += num + " volume cells(";
1203 num.setNum(Ntets); txt += num + " tetras, ";
1204 num.setNum(Npyras); txt += num + " pyramids, ";
1205 num.setNum(Nprism); txt += num + " prisms, ";
1206 num.setNum(Nhexas); txt += num + " hexas), ";
1207 num.setNum(Ntris + Nquads); txt += num + " surface cells(";
1208 num.setNum(Ntris); txt += num + " triangles, ";
1209 num.setNum(Nquads); txt += num + " quads), ";
1210 num.setNum(Nnodes); txt += num + " nodes";
1212 if(ui.radioButton_CellPicker->isChecked())
1214 QString pick_txt = ", picked cell: ";
1215 vtkIdType id_cell = m_PickedCell;
1216 if (id_cell < 0 || id_cell>=m_Grid->GetNumberOfCells()) {
1217 pick_txt += "no cell picked";
1218 } else {
1219 vtkIdType type_cell = m_Grid->GetCellType(id_cell);
1220 if (type_cell == VTK_TRIANGLE) pick_txt += "tri";
1221 else if (type_cell == VTK_QUAD) pick_txt += "qua";
1222 else if (type_cell == VTK_TETRA) pick_txt += "tet";
1223 else if (type_cell == VTK_PYRAMID) pick_txt += "pyr";
1224 else if (type_cell == VTK_WEDGE) pick_txt += "pri";
1225 else if (type_cell == VTK_HEXAHEDRON) pick_txt += "hex";
1226 vtkIdType N_pts, *pts;
1227 m_Grid->GetCellPoints(id_cell, N_pts, pts);
1228 pick_txt += " [";
1229 for (int i_pts = 0; i_pts < N_pts; ++i_pts) {
1230 QString num;
1231 num.setNum(pts[i_pts]);
1232 pick_txt += num;
1233 if (i_pts < N_pts-1) {
1234 pick_txt += ",";
1237 pick_txt += "]";
1238 QString tmp;
1239 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1240 tmp.setNum(cell_code->GetValue(id_cell));
1241 pick_txt += " code=" + tmp;
1242 tmp.setNum(id_cell);
1243 pick_txt += " id=" + tmp;
1245 txt += pick_txt;
1247 else
1249 QString pick_txt = ", picked node: ";
1250 vtkIdType id_node = m_PickedPoint;
1251 if (id_node < 0) {
1252 pick_txt += "no node picked";
1253 } else {
1254 vec3_t x;
1255 m_Grid->GetPoints()->GetPoint(id_node,x.data());
1256 pick_txt += " [";
1257 for (int i = 0; i < 3; i++) {
1258 QString num;
1259 num.setNum(x[i]);
1260 pick_txt += num;
1261 if (i < 2) {
1262 pick_txt += ",";
1265 pick_txt += "]";
1266 QString tmp;
1267 EG_VTKDCN(vtkDoubleArray, characteristic_length_desired, m_Grid, "node_meshdensity_desired");
1268 tmp.setNum(characteristic_length_desired->GetValue(id_node));
1269 pick_txt += " wanted density=" + tmp;
1270 EG_VTKDCN(vtkDoubleArray, node_meshdensity_current, m_Grid, "node_meshdensity_current");
1271 tmp.setNum(node_meshdensity_current->GetValue(id_node));
1272 pick_txt += " current density=" + tmp;
1273 EG_VTKDCN(vtkIntArray, node_specified_density, m_Grid, "node_specified_density");
1274 tmp.setNum(node_specified_density->GetValue(id_node));
1275 pick_txt += " node_specified_density=" + tmp;
1276 EG_VTKDCN(vtkCharArray, node_type, m_Grid, "node_type");
1277 pick_txt += " type=" + QString(VertexType2Str( node_type->GetValue(id_node)));
1278 tmp.setNum(id_node);
1279 pick_txt += " id_node=" + tmp;
1282 txt += pick_txt;
1285 m_StatusLabel->setText(txt);
1286 ui.label_node_cell_info->setText(txt);
1287 unlock();
1290 void GuiMainWindow::selectBoundaryCodes()
1292 GuiSelectBoundaryCodes bcodes;
1293 bcodes.setDisplayBoundaryCodes(m_DisplayBoundaryCodes);
1294 bcodes.setBoundaryCodes(m_AllBoundaryCodes);
1295 bcodes();
1296 bcodes.getThread().wait();
1297 bcodes.getSelectedBoundaryCodes(m_DisplayBoundaryCodes);
1298 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1299 updateActors();
1302 void GuiMainWindow::updateBoundaryCodes(bool all_on)
1304 try {
1305 m_AllBoundaryCodes.clear();
1306 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
1307 for (vtkIdType i = 0; i < m_Grid->GetNumberOfCells(); ++i) {
1308 int ct = m_Grid->GetCellType(i);
1309 if ((ct == VTK_TRIANGLE) || (ct == VTK_QUAD)) {
1310 m_AllBoundaryCodes.insert(cell_code->GetValue(i));
1313 if (all_on) {
1314 m_DisplayBoundaryCodes.clear();
1315 foreach (int bc, m_AllBoundaryCodes) {
1316 m_DisplayBoundaryCodes.insert(bc);
1318 } else {
1319 QSet<int> dbcs;
1320 foreach (int bc, m_DisplayBoundaryCodes) {
1321 if (m_AllBoundaryCodes.contains(bc)) {
1322 dbcs.insert(bc);
1325 m_DisplayBoundaryCodes.clear();
1326 foreach (int bc, m_AllBoundaryCodes) {
1327 if (dbcs.contains(bc)) {
1328 m_DisplayBoundaryCodes.insert(bc);
1332 m_BCodesFilter->SetBoundaryCodes(m_DisplayBoundaryCodes);
1333 } catch (Error err) {
1334 err.display();
1338 void GuiMainWindow::normalExtrusion()
1340 GuiNormalExtrusion extr;
1341 extr();
1342 updateBoundaryCodes(false);
1343 updateActors();
1346 void GuiMainWindow::setAxesVisibility()
1348 if (ui.actionViewAxes->isChecked()) {
1349 m_Axes->VisibilityOn();
1350 } else {
1351 m_Axes->VisibilityOff();
1353 getRenderWindow()->Render();
1356 void GuiMainWindow::setViewingMode()
1358 if (ui.actionViewOrthogonal->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
1359 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
1360 getRenderWindow()->Render();
1363 void GuiMainWindow::viewNodeIDs()
1365 int N = m_Grid->GetNumberOfPoints();
1366 cout<<"N="<<N<<endl;
1367 if (ui.actionViewNodeIDs->isChecked()) {
1368 cout<<"Activating node ID view"<<endl;
1369 m_NodeTextVectorText.resize(N);
1370 m_NodeTextPolyDataMapper.resize(N);
1371 m_NodeTextFollower.resize(N);
1372 for(int i = 0; i < N; ++i){
1373 m_NodeTextVectorText[i]=vtkVectorText::New();
1374 QString tmp;
1375 tmp.setNum(i);
1376 m_NodeTextVectorText[i]->SetText(qPrintable(tmp));
1377 m_NodeTextPolyDataMapper[i]=vtkPolyDataMapper::New();
1378 m_NodeTextPolyDataMapper[i]->SetInputConnection(m_NodeTextVectorText[i]->GetOutputPort());
1379 m_NodeTextFollower[i]=vtkFollower::New();
1380 m_NodeTextFollower[i]->SetMapper(m_NodeTextPolyDataMapper[i]);
1381 m_NodeTextFollower[i]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1382 vec3_t M;
1383 m_Grid->GetPoint(i, M.data());
1384 vec3_t tmp_M = M;
1385 vec3_t OffSet = m_ReferenceSize*tmp_M.normalise();
1386 M = M + OffSet;
1387 m_NodeTextFollower[i]->AddPosition(M[0], M[1], M[2]);
1388 m_NodeTextFollower[i]->SetCamera(getRenderer()->GetActiveCamera());
1389 m_NodeTextFollower[i]->GetProperty()->SetColor(0,0,1);
1390 getRenderer()->AddActor(m_NodeTextFollower[i]);
1393 else {
1394 cout<<"Deactivating node ID view"<<endl;
1395 for(unsigned int i = 0; i < m_NodeTextFollower.size();i++){
1396 getRenderer()->RemoveActor(m_NodeTextFollower[i]);
1397 m_NodeTextFollower[i]->Delete();
1398 m_NodeTextPolyDataMapper[i]->Delete();
1399 m_NodeTextVectorText[i]->Delete();
1401 m_NodeTextFollower.clear();
1402 m_NodeTextPolyDataMapper.clear();
1403 m_NodeTextVectorText.clear();
1406 getRenderWindow()->Render();
1409 void GuiMainWindow::viewCellIDs()
1411 vtkIdType N = m_Grid->GetNumberOfCells();
1412 cout<<"N="<<N<<endl;
1413 if (ui.actionViewCellIDs->isChecked()) {
1414 cout<<"Activating cell ID view"<<endl;
1415 m_CellTextVectorText.resize(N);
1416 m_CellTextPolyDataMapper.resize(N);
1417 m_CellTextFollower.resize(N);
1418 for (vtkIdType id_cell = 0; id_cell < N; ++id_cell){
1419 m_CellTextVectorText[id_cell] = vtkVectorText::New();
1421 QString tmp;
1423 if(ui.comboBox_CellTextField->currentIndex()==0) {
1424 tmp.setNum(id_cell);
1425 } else if (ui.comboBox_CellTextField->currentIndex()>0) {
1426 EG_VTKDCC(vtkIntArray, current_cell_field, m_Grid, qPrintable(ui.comboBox_CellTextField->currentText()));
1427 tmp.setNum(current_cell_field->GetValue(id_cell));
1429 else EG_BUG;
1431 m_CellTextVectorText[id_cell]->SetText(qPrintable(tmp));
1432 m_CellTextPolyDataMapper[id_cell]=vtkPolyDataMapper::New();
1433 m_CellTextPolyDataMapper[id_cell]->SetInputConnection(m_CellTextVectorText[id_cell]->GetOutputPort());
1434 m_CellTextFollower[id_cell]=vtkFollower::New();
1435 m_CellTextFollower[id_cell]->SetMapper(m_CellTextPolyDataMapper[id_cell]);
1436 m_CellTextFollower[id_cell]->SetScale(m_ReferenceSize, m_ReferenceSize, m_ReferenceSize);
1437 vtkIdType N_pts,*pts;
1438 m_Grid->GetCellPoints(id_cell,N_pts,pts);
1439 vec3_t Center(0,0,0);
1440 for (int p = 0; p < N_pts; ++p) {
1441 vec3_t M;
1442 m_Grid->GetPoint(pts[p],M.data());
1443 Center+=M.data();
1445 vec3_t OffSet = m_ReferenceSize*triNormal(m_Grid, pts[0], pts[1], pts[2]).normalise();
1446 Center = 1.0/(double)N_pts*Center+OffSet;
1447 m_CellTextFollower[id_cell]->AddPosition(Center[0], Center[1], Center[2]);
1448 m_CellTextFollower[id_cell]->SetCamera(getRenderer()->GetActiveCamera());
1449 m_CellTextFollower[id_cell]->GetProperty()->SetColor(1, 0, 0);
1450 getRenderer()->AddActor(m_CellTextFollower[id_cell]);
1452 } else {
1453 cout<<"Deactivating cell ID view"<<endl;
1454 for (vtkIdType id_cell = 0; id_cell < (vtkIdType) m_CellTextFollower.size(); ++id_cell) {
1455 getRenderer()->RemoveActor(m_CellTextFollower[id_cell]);
1456 m_CellTextFollower[id_cell]->Delete();
1457 m_CellTextPolyDataMapper[id_cell]->Delete();
1458 m_CellTextVectorText[id_cell]->Delete();
1460 m_CellTextFollower.clear();
1461 m_CellTextPolyDataMapper.clear();
1462 m_CellTextVectorText.clear();
1465 getRenderWindow()->Render();
1468 void GuiMainWindow::pickCallBack
1470 vtkObject *caller,
1471 unsigned long int eid,
1472 void *clientdata,
1473 void *calldata
1476 caller = caller;
1477 eid = eid;
1478 clientdata = clientdata;
1479 calldata = calldata;
1480 THIS->updateActors();
1481 THIS->updateStatusBar();
1484 vtkIdType GuiMainWindow::getPickedCell()
1486 if(!ui.radioButton_CellPicker->isChecked()) return(-1);
1488 vtkIdType picked_cell = -1;
1489 if (m_Grid->GetNumberOfCells() > 0) {
1490 m_BCodesFilter->Update();
1491 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1492 EG_VTKDCC(vtkLongArray_t, cell_index, m_BCodesFilter->GetOutput(), "cell_index");
1493 if (m_UseVTKInteractor) {
1494 picked_cell = cell_index->GetValue(m_CellPicker->GetCellId());
1495 } else {
1496 picked_cell = m_PickedCell;
1500 return picked_cell;
1503 vtkIdType GuiMainWindow::getPickedPoint()
1505 if(ui.radioButton_CellPicker->isChecked()) return(-1);
1507 vtkIdType picked_point = -1;
1508 if (m_Grid->GetNumberOfCells() > 0) {
1509 m_BCodesFilter->Update();
1510 if (m_BCodesFilter->GetOutput()->GetNumberOfCells() > 0) {
1511 EG_VTKDCN(vtkLongArray_t, node_index, m_BCodesFilter->GetOutput(), "node_index");
1512 if (m_UseVTKInteractor) {
1513 picked_point = node_index->GetValue(m_PointPicker->GetPointId());
1514 } else {
1515 picked_point = m_PickedPoint;
1519 return picked_point;
1522 void GuiMainWindow::changeSurfaceOrientation()
1524 for (vtkIdType cellId = 0; cellId < m_Grid->GetNumberOfCells(); ++cellId) {
1525 vtkIdType Npts, *pts;
1526 m_Grid->GetCellPoints(cellId, Npts, pts);
1527 QVector<vtkIdType> nodes(Npts);
1528 for (vtkIdType j = 0; j < Npts; ++j) nodes[j] = pts[j];
1529 for (vtkIdType j = 0; j < Npts; ++j) pts[Npts - j - 1] = nodes[j];
1531 updateActors();
1532 m_Grid->Modified();// to make sure VTK notices the changes and changes the cell colors
1535 void GuiMainWindow::checkSurfaceOrientation()
1537 CorrectSurfaceOrientation corr_surf;
1538 vtkIdType picked_cell = getPickedCell();
1539 if (picked_cell >= 0) {
1540 corr_surf.setStart(picked_cell);
1542 corr_surf();
1543 updateActors();
1546 void GuiMainWindow::improveAspectRatio()
1548 GuiImproveAspectRatio impr_ar;
1549 impr_ar();
1550 updateActors();
1553 void GuiMainWindow::exportAsciiStl()
1555 StlWriter stl;
1556 stl.setFileTypeToASCII();
1557 stl();
1560 void GuiMainWindow::exportBinaryStl()
1562 StlWriter stl;
1563 stl.setFileTypeToBinary();
1564 stl();
1567 void GuiMainWindow::exportAsciiPly()
1569 PlyWriter ply;
1570 ply.setFileTypeToASCII();
1571 ply();
1574 void GuiMainWindow::exportBinaryPly()
1576 PlyWriter ply;
1577 ply.setFileTypeToBinary();
1578 ply();
1581 void GuiMainWindow::periodicUpdate()
1583 Operation::collectGarbage();
1584 updateStatusBar();
1587 void GuiMainWindow::viewXP()
1589 getRenderer()->ResetCamera();
1590 double x[3];
1591 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1592 x[0] += 1;
1593 getRenderer()->GetActiveCamera()->SetPosition(x);
1594 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1595 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1596 getRenderer()->ResetCamera();
1597 getRenderWindow()->Render();
1600 void GuiMainWindow::viewXM()
1602 getRenderer()->ResetCamera();
1603 double x[3];
1604 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1605 x[0] -= 1;
1606 getRenderer()->GetActiveCamera()->SetPosition(x);
1607 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1608 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1609 getRenderer()->ResetCamera();
1610 getRenderWindow()->Render();
1613 void GuiMainWindow::viewYP()
1615 getRenderer()->ResetCamera();
1616 double x[3];
1617 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1618 x[1] += 1;
1619 getRenderer()->GetActiveCamera()->SetPosition(x);
1620 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1621 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1622 getRenderer()->ResetCamera();
1623 getRenderWindow()->Render();
1626 void GuiMainWindow::viewYM()
1628 getRenderer()->ResetCamera();
1629 double x[3];
1630 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1631 x[1] -= 1;
1632 getRenderer()->GetActiveCamera()->SetPosition(x);
1633 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1634 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1635 getRenderer()->ResetCamera();
1636 getRenderWindow()->Render();
1639 void GuiMainWindow::viewZP()
1641 getRenderer()->ResetCamera();
1642 double x[3];
1643 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1644 x[2] += 1;
1645 getRenderer()->GetActiveCamera()->SetPosition(x);
1646 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1647 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1648 getRenderer()->ResetCamera();
1649 getRenderWindow()->Render();
1652 void GuiMainWindow::viewZM()
1654 getRenderer()->ResetCamera();
1655 double x[3];
1656 getRenderer()->GetActiveCamera()->GetFocalPoint(x);
1657 x[2] -= 1;
1658 getRenderer()->GetActiveCamera()->SetPosition(x);
1659 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1660 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1661 getRenderer()->ResetCamera();
1662 getRenderWindow()->Render();
1665 void GuiMainWindow::callFixSTL()
1667 FixSTL *fix;
1668 fix = new FixSTL();
1669 fix->setLockGui();
1670 (*fix)();
1671 updateBoundaryCodes(false);
1672 updateActors();
1675 void GuiMainWindow::callDeletePickedPoint()
1677 EG_STDINTERSLOT( DeletePickedPoint );
1680 void GuiMainWindow::editBoundaryConditions()
1682 GuiEditBoundaryConditions editbcs;
1683 editbcs.setBoundaryCodes(m_AllBoundaryCodes);
1684 editbcs.setMap(&m_bcmap);
1685 editbcs();
1688 void GuiMainWindow::configure()
1691 // Just to create initial entries in the settings file
1692 // so that the options menu isn't empty at first start.
1693 try {
1694 GridSmoother tmp01;
1695 GuiCreateBoundaryLayer tmp02;
1696 SurfaceProjection tmp03;
1697 SurfaceMesher tmp04;
1698 UpdateDesiredMeshDensity tmp05;
1699 InsertPoints tmp06;
1700 RemovePoints tmp07;
1701 LaplaceSmoother tmp08;
1702 SwapTriangles tmp09;
1703 OpenFOAMTools tmp10;
1704 } catch (Error err) {
1705 err.display();
1708 GuiSettingsViewer settings(&m_qset);
1709 settings.CreateViewer();
1710 settings.exec();
1712 getSet("General","enable undo+redo",false,m_undo_redo_enabled);
1715 void GuiMainWindow::about()
1717 QMessageBox box(this);
1719 QString title="ENGRID";
1720 QString version = QString("version ") + ENGRID_VERSION;
1721 #ifdef GIT_DESCRIBE
1722 if(!QString(GIT_DESCRIBE).isEmpty()) {
1723 version += QString(" - ") + GIT_DESCRIBE;
1725 #endif
1727 version += " built on ";
1728 version += QString(__DATE__);
1729 version += " at ";
1730 version += QString(__TIME__);
1732 QString address = tr("ENGRID is being developed and maintained by:<br/>"
1733 "enGits GmbH<br/>"
1734 "Marie-Curie-Strasse 8<br/>"
1735 "79539 Loerrach<br/>"
1736 "Germany<br/>");
1738 QString mainurl="<a href=\"http://www.engits.com\">www.engits.com</a>";
1739 QString mail="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1740 QString gnuurl="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1741 QString license=tr("ENGRID is licenced under the GPL version 3.<br/>"
1742 "(see ")+gnuurl+tr(" for details)<br/>");
1743 QString bugurl="<a href=\"http://sourceforge.net/tracker2/?func=add&group_id=245110&atid=1126548\">the bugtracker available on Sourceforge</a>";
1744 QString bugreporting=tr("To submit a bug report, please use ")+bugurl;
1745 box.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1746 "<h3>%1</h3>"
1747 "<p>%2</p>"
1748 "<p>%3</p>"
1749 "<p>Homepage: %4</p>"
1750 "<p>E-mail: %5</p>"
1751 "<p>%6</p>"
1752 "<p>%7</p></center>")
1753 .arg(title).arg(version).arg(address).arg(mainurl).arg(mail).arg(license).arg(bugreporting));
1754 box.setWindowTitle(tr("about ENGRID"));
1755 box.setIcon(QMessageBox::NoIcon);
1756 box.exec();
1760 ///\todo Why not use bcs = m_AllBoundaryCodes; ?
1761 void GuiMainWindow::getAllBoundaryCodes(QSet<int> &bcs)
1763 bcs = m_AllBoundaryCodes;
1764 // qWarning()<<"m_AllBoundaryCodes="<<m_AllBoundaryCodes;
1765 // bcs.clear();
1766 // foreach (int bc, m_AllBoundaryCodes) {
1767 // bcs.insert(bc);
1768 // }
1771 QSet<int> GuiMainWindow::getAllBoundaryCodes()
1773 return m_AllBoundaryCodes;
1776 void GuiMainWindow::getDisplayBoundaryCodes(QSet<int> &bcs)
1778 bcs.clear();
1779 foreach (int bc, m_DisplayBoundaryCodes) {
1780 bcs.insert(bc);
1784 QList<VolumeDefinition> GuiMainWindow::getAllVols()
1786 QList<VolumeDefinition> vols;
1787 foreach(VolumeDefinition vol, m_VolMap) {
1788 vols.push_back(vol);
1790 return vols;
1793 void GuiMainWindow::setAllVols(QList<VolumeDefinition> vols)
1795 m_VolMap.clear();
1796 foreach (VolumeDefinition V, vols) {
1797 m_VolMap[V.getName()] = V;
1801 QList<PhysicalBoundaryCondition> GuiMainWindow::getAllPhysicalBoundaryConditions()
1803 QList<PhysicalBoundaryCondition> physical_boundary_conditions;
1804 foreach(PhysicalBoundaryCondition PBC, m_PhysicalBoundaryConditionsMap) {
1805 physical_boundary_conditions.push_back(PBC);
1807 return physical_boundary_conditions;
1810 void GuiMainWindow::setAllPhysicalBoundaryConditions(QList<PhysicalBoundaryCondition> physical_boundary_conditions)
1812 m_PhysicalBoundaryConditionsMap.clear();
1813 foreach (PhysicalBoundaryCondition PBC, physical_boundary_conditions) {
1814 m_PhysicalBoundaryConditionsMap[PBC.getName()] = PBC;
1818 void GuiMainWindow::setAllPhysicalBoundaryConditions(QMap<QString,PhysicalBoundaryCondition> physical_boundary_conditions) {
1819 m_PhysicalBoundaryConditionsMap = physical_boundary_conditions;
1822 void GuiMainWindow::createDefaultVol()
1824 QList<VolumeDefinition> vols = getAllVols();
1825 if (vols.size() == 0) {
1826 VolumeDefinition V("default", 1);
1827 QSet<int> bcs;
1828 getAllBoundaryCodes(bcs);
1829 foreach (int bc, bcs) {
1830 V.addBC(bc, 1);
1832 vols.append(V);
1833 setAllVols(vols);
1837 QString GuiMainWindow::getFilePath()
1839 QFileInfo fileinfo(m_CurrentFilename);
1840 return fileinfo.absolutePath()+"/";
1843 void GuiMainWindow::markOutputLine()
1845 cout << "\n****************************************\n";
1846 cout << qPrintable(QTime::currentTime().toString("hh:mm:ss"));
1847 cout << "\n****************************************\n" << endl;
1850 void GuiMainWindow::storeSurfaceProjection()
1852 qDebug()<<"@@@ GuiMainWindow::storeSurfaceProjection called";
1853 foreach (SurfaceProjection* proj, m_SurfProj) {
1854 delete proj;
1856 m_SurfProj.clear();
1857 cout << "storing background grid for surface projection:" << endl;
1858 // EG_VTKSP(vtkUnstructuredGrid,new_grid);
1859 MeshPartition new_grid_partition;
1860 bool first = true;
1862 QFileInfo file_info(m_CurrentFilename);
1864 foreach (int bc, m_AllBoundaryCodes) {
1865 SurfaceProjection *proj = new SurfaceProjection();
1866 m_SurfProj[bc] = proj;
1867 QSet<int> bcs;
1868 bcs.insert(bc);
1869 QVector<vtkIdType> cls;
1870 getSurfaceCells(bcs, cls, m_Grid);
1871 proj->setBackgroundGrid(m_Grid, cls);
1872 QString basename = file_info.completeBaseName() + "_" + QString::number(bc);
1874 proj->m_ExactMode = 0;
1876 // DebugLevel = 100;
1877 if(DebugLevel>100) {
1878 proj->writeGridWithNormals(basename);
1879 proj->writeInterpolationGrid(basename);
1880 proj->writeTriangleGrid(basename);
1881 qDebug()<<"=====> bc="<<bc<<" proj->getBezierGrid()->GetNumberOfPoints()="<<proj->getBezierGrid()->GetNumberOfPoints()
1882 <<" proj->getBezierGrid()->GetNumberOfCells()="<<proj->getBezierGrid()->GetNumberOfCells();
1884 if(first) {
1885 first = false;
1886 new_grid_partition.setGrid(proj->getBezierGrid());
1887 new_grid_partition.setAllCells();
1889 else {
1890 MeshPartition grid_partition(proj->getBezierGrid(), true);
1891 new_grid_partition.addPartition(grid_partition);
1896 if(DebugLevel>100) writeGrid(new_grid_partition.getGrid(), file_info.completeBaseName() + "_projection_surface");
1897 // DebugLevel = 0;
1900 SurfaceProjection* GuiMainWindow::getSurfProj(int bc)
1902 if (!m_SurfProj.contains(bc)) {
1903 QString bc_txt;
1904 bc_txt.setNum(bc);
1905 EG_ERR_RETURN("No surface projection found for boundary code " + bc_txt);
1907 return m_SurfProj[bc];
1910 bool GuiMainWindow::checkSurfProj()
1912 bool ok = true;
1913 foreach (int bc, m_AllBoundaryCodes) {
1914 if (!m_SurfProj.contains(bc)) {
1915 ok = false;
1916 break;
1919 return ok;
1922 void GuiMainWindow::openRecent(QAction *action)
1924 qDebug()<<"GuiMainWindow::openRecent called";
1925 QString file_name = action->text().right(action->text().length()-23);
1926 this->open(file_name);
1929 void GuiMainWindow::readRecentFiles()
1931 m_RecentFiles.clear();
1932 this->recentFileMenu()->clear();
1933 QStringList file_names = m_qset.value("FileNames").toStringList();
1934 QStringList file_dates = m_qset.value("FileDates").toStringList();
1935 int N = min(10,m_qset.value("NumberOfFiles").toInt());
1936 // cout << "NumberOfFiles=" << N << endl;
1937 for (int i = 0; i < N; ++i) {
1938 QString new_file = file_names.at(i);
1939 QString date_text = file_dates.at(i);
1940 QDateTime date = QDateTime::fromString(date_text,"dd.MM.yyyy_hh:mm:ss");
1941 addRecentFile(new_file,date);
1945 void GuiMainWindow::writeRecentFiles()
1947 m_qset.setValue("NumberOfFiles",m_RecentFiles.size());
1948 QStringList file_names;
1949 QStringList file_dates;
1950 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
1951 QString file_name = i.key();
1952 QString date_text = i.value().toString("dd.MM.yyyy_hh:mm:ss");
1953 file_names.append(file_name);
1954 file_dates.append(date_text);
1956 m_qset.setValue("FileNames",file_names);
1957 m_qset.setValue("FileDates",file_dates);
1960 void GuiMainWindow::addRecentFile(QString file_name, QDateTime date)
1962 m_RecentFiles[file_name] = date;
1963 while (m_RecentFiles.size() > 10) {
1964 QMap<QString,QDateTime>::iterator i,j;
1965 QDateTime old = QDateTime::currentDateTime();
1966 for (i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
1967 if (i.value() <= old) {
1968 old = i.value();
1969 j = i;
1972 m_RecentFiles.erase(j);
1974 this->recentFileMenu()->clear();
1975 QMap<int,QString> menu_map;
1976 QDateTime now = QDateTime::currentDateTime();
1977 for (QMap<QString,QDateTime>::iterator i = m_RecentFiles.begin(); i != m_RecentFiles.end(); ++i) {
1978 QString action_text = i.value().toString("dd.MM.yyyy hh:mm:ss");
1979 action_text += " -> ";
1980 action_text += i.key();
1981 menu_map[i.value().secsTo(now)] = action_text;
1984 for (QMap<int,QString>::iterator i = menu_map.begin(); i != menu_map.end(); ++i) {
1985 QAction *action = new QAction(i.value(),this);
1986 this->recentFileMenu()->addAction(action);
1991 void GuiMainWindow::callInsertNewCell()
1993 bool ok1,ok2,ok3,ok4;
1994 vtkIdType pts[3];
1995 pts[0] = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
1996 pts[1] = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
1997 pts[2] = QInputDialog::getInt(this, tr("id_node3"),tr("id_node3:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok3);
1998 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);
1999 if (ok1 && ok2 && ok3 && ok4) {
2000 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2001 allocateGrid( new_grid, m_Grid->GetNumberOfCells() + 1, m_Grid->GetNumberOfPoints() );
2002 makeCopyNoAlloc(m_Grid, new_grid);
2003 vtkIdType id_new_cell = new_grid->InsertNextCell(VTK_TRIANGLE, 3, pts);
2004 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2005 makeCopy(new_grid, m_Grid);
2006 m_Grid->Modified();
2007 QMessageBox::information(NULL, "new cell", tr("The new cell has ID = %1").arg(id_new_cell));
2008 qDebug()<<tr("The new cell has ID = %1").arg(id_new_cell);
2012 void GuiMainWindow::callMergeNodes()
2014 bool ok1,ok2;
2015 vtkIdType id_node1 = QInputDialog::getInt(this, tr("id_node1"),tr("id_node1:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok1);
2016 vtkIdType id_node2 = QInputDialog::getInt(this, tr("id_node2"),tr("id_node2:"), 0, 0, m_Grid->GetNumberOfPoints(), 1, &ok2);
2017 if (ok1 && ok2) {
2018 EG_VTKSP( vtkUnstructuredGrid, new_grid );
2019 allocateGrid( new_grid, m_Grid->GetNumberOfCells(), m_Grid->GetNumberOfPoints() - 1 );
2021 QVector<vtkIdType> old2new_nodes(m_Grid->GetNumberOfPoints(), -1);
2022 QVector<vtkIdType> old2new_cells(m_Grid->GetNumberOfCells(), -1);
2024 vtkIdType id_new_node = 0;
2025 for (vtkIdType id_node = 0; id_node < m_Grid->GetNumberOfPoints(); ++id_node) {
2026 if(id_node!=id_node1 && id_node!=id_node2) {
2027 vec3_t x;
2028 m_Grid->GetPoints()->GetPoint(id_node, x.data());
2029 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2030 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2031 old2new_nodes[id_node] = id_new_node;
2032 id_new_node++;
2034 else if(id_node==id_node1) {
2035 vec3_t x1;
2036 m_Grid->GetPoints()->GetPoint(id_node1, x1.data());
2037 vec3_t x2;
2038 m_Grid->GetPoints()->GetPoint(id_node2, x2.data());
2039 vec3_t x = 0.5*(x1+x2);
2040 new_grid->GetPoints()->SetPoint(id_new_node, x.data());
2041 copyNodeData(m_Grid, id_node, new_grid, id_new_node);
2042 old2new_nodes[id_node1] = id_new_node;
2043 old2new_nodes[id_node2] = id_new_node;
2044 id_new_node++;
2046 else {
2050 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
2051 vtkIdType N_pts, *pts;
2052 vtkIdType type_cell = m_Grid->GetCellType(id_cell);
2053 m_Grid->GetCellPoints(id_cell, N_pts, pts);
2054 QVector<vtkIdType> new_pts(N_pts);
2055 for (int i = 0; i < N_pts; ++i) {
2056 new_pts[i] = old2new_nodes[pts[i]];
2058 vtkIdType id_new_cell = new_grid->InsertNextCell(type_cell, N_pts, new_pts.data());
2059 copyCellData(m_Grid, id_cell, new_grid, id_new_cell);
2062 makeCopy(new_grid, m_Grid);
2063 m_Grid->Modified();
2064 qDebug()<<"The fusion is complete.";