2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008,2009 Oliver Gloth +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "guimainwindow.h"
24 #include "guiselectboundarycodes.h"
25 #include "guiimproveaspectratio.h"
26 #include "guinormalextrusion.h"
27 #include "guisetboundarycode.h"
30 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
31 #include "stlreader.h"
32 #include "gmshreader.h"
33 #include "gmshwriter.h"
34 #include "neutralwriter.h"
35 #include "stlwriter.h"
36 #include "correctsurfaceorientation.h"
37 #include "guieditboundaryconditions.h"
39 #include <vtkRenderer.h>
40 #include <vtkRenderWindow.h>
41 #include <vtkXMLUnstructuredGridWriter.h>
42 #include <vtkXMLUnstructuredGridReader.h>
43 #include <vtkProperty.h>
44 #include <vtkCallbackCommand.h>
45 #include <vtkCamera.h>
46 #include <vtkCharArray.h>
47 #include <vtkTextActor.h>
48 #include <vtkVectorText.h>
49 #include <vtkFollower.h>
51 #include <QFileDialog>
52 #include <QFileSystemWatcher>
56 #include "geometrytools.h"
57 using namespace GeometryTools
;
59 #include "guisettingsviewer.h"
60 #include "guitransform.h"
62 GuiOutputWindow::GuiOutputWindow()
67 QString
GuiMainWindow::cwd
= ".";
68 QSettings
GuiMainWindow::qset("enGits","enGrid");
69 GuiMainWindow
* GuiMainWindow::THIS
= NULL
;
70 QMutex
GuiMainWindow::mutex
;
71 vtkIdType
GuiMainWindow::PickedPoint
;
72 vtkIdType
GuiMainWindow::PickedCell
;
73 bool GuiMainWindow::m_UseVTKInteractor
;
75 GuiMainWindow::GuiMainWindow() : QMainWindow(NULL
)
79 dock_widget
= new QDockWidget(tr("output"), this);
80 dock_widget
->setFeatures(QDockWidget::AllDockWidgetFeatures
);
81 output_window
= new GuiOutputWindow();
82 dock_widget
->setWidget(output_window
);
83 addDockWidget(Qt::LeftDockWidgetArea
, dock_widget
);
84 ui
.menuView
->addAction(dock_widget
->toggleViewAction());
86 connect(ui
.actionImportSTL
, SIGNAL(activated()), this, SLOT(importSTL()));
87 connect(ui
.actionImportGmsh1Ascii
, SIGNAL(activated()), this, SLOT(importGmsh1Ascii()));
88 connect(ui
.actionImportGmsh2Ascii
, SIGNAL(activated()), this, SLOT(importGmsh2Ascii()));
89 connect(ui
.actionExportGmsh1Ascii
, SIGNAL(activated()), this, SLOT(exportGmsh1Ascii()));
90 connect(ui
.actionExportGmsh2Ascii
, SIGNAL(activated()), this, SLOT(exportGmsh2Ascii()));
91 connect(ui
.actionExportNeutral
, SIGNAL(activated()), this, SLOT(exportNeutral()));
92 connect(ui
.actionExportAsciiStl
, SIGNAL(activated()), this, SLOT(exportAsciiStl()));
93 connect(ui
.actionExportBinaryStl
, SIGNAL(activated()), this, SLOT(exportBinaryStl()));
94 connect(ui
.actionExit
, SIGNAL(activated()), this, SLOT(exit()));
95 connect(ui
.actionZoomAll
, SIGNAL(activated()), this, SLOT(zoomAll()));
96 connect(ui
.actionOpen
, SIGNAL(activated()), this, SLOT(open()));
97 connect(ui
.actionSave
, SIGNAL(activated()), this, SLOT(save()));
98 connect(ui
.actionSaveAs
, SIGNAL(activated()), this, SLOT(saveAs()));
99 connect(ui
.actionBoundaryCodes
, SIGNAL(activated()), this, SLOT(selectBoundaryCodes()));
100 connect(ui
.actionNormalExtrusion
, SIGNAL(activated()), this, SLOT(normalExtrusion()));
101 connect(ui
.actionViewAxes
, SIGNAL(changed()), this, SLOT(setAxesVisibility()));
102 connect(ui
.actionViewOrthogonal
, SIGNAL(changed()), this, SLOT(setViewingMode()));
103 connect(ui
.actionViewNodeIDs
, SIGNAL(changed()), this, SLOT(ViewNodeIDs()));
104 connect(ui
.actionViewCellIDs
, SIGNAL(changed()), this, SLOT(ViewCellIDs()));
105 connect(ui
.actionChangeOrientation
, SIGNAL(activated()), this, SLOT(changeSurfaceOrientation()));
106 connect(ui
.actionCheckOrientation
, SIGNAL(activated()), this, SLOT(checkSurfaceOrientation()));
107 connect(ui
.actionImproveAspectRatio
, SIGNAL(activated()), this, SLOT(improveAspectRatio()));
108 connect(ui
.actionRedraw
, SIGNAL(activated()), this, SLOT(updateActors()));
109 connect(ui
.actionClearOutputWindow
, SIGNAL(activated()), this, SLOT(clearOutput()));
110 connect(ui
.actionEditBoundaryConditions
, SIGNAL(activated()), this, SLOT(editBoundaryConditions()));
111 connect(ui
.actionConfigure
, SIGNAL(activated()), this, SLOT(configure()));
112 connect(ui
.actionAbout
, SIGNAL(activated()), this, SLOT(about()));
114 connect(ui
.checkBox_UseVTKInteractor
, SIGNAL(stateChanged(int)), this, SLOT(setUseVTKInteractor(int)));
116 connect(ui
.actionViewXP
, SIGNAL(activated()), this, SLOT(viewXP()));
117 connect(ui
.actionViewXM
, SIGNAL(activated()), this, SLOT(viewXM()));
118 connect(ui
.actionViewYP
, SIGNAL(activated()), this, SLOT(viewYP()));
119 connect(ui
.actionViewYM
, SIGNAL(activated()), this, SLOT(viewYM()));
120 connect(ui
.actionViewZP
, SIGNAL(activated()), this, SLOT(viewZP()));
121 connect(ui
.actionViewZM
, SIGNAL(activated()), this, SLOT(viewZM()));
124 #include "std_connections.h"
126 if (qset
.contains("working_directory")) {
127 cwd
= qset
.value("working_directory").toString();
129 grid
= vtkUnstructuredGrid::New();
130 renderer
= vtkRenderer::New();
131 getRenderWindow()->AddRenderer(renderer
);
132 surface_actor
= vtkActor::New();
133 surface_wire_actor
= vtkActor::New();
135 tetra_mapper
= vtkPolyDataMapper::New();
136 pyramid_mapper
= vtkPolyDataMapper::New();
137 wedge_mapper
= vtkPolyDataMapper::New();
138 hexa_mapper
= vtkPolyDataMapper::New();
139 volume_wire_mapper
= vtkPolyDataMapper::New();
140 surface_mapper
= vtkPolyDataMapper::New();
141 surface_wire_mapper
= vtkPolyDataMapper::New();
143 backface_property
= vtkProperty::New();
146 pyramid_actor
= NULL
;
149 volume_wire_actor
= NULL
;
151 surface_filter
= vtkGeometryFilter::New();
152 bcodes_filter
= vtkEgBoundaryCodesFilter::New();
153 renderer
->AddActor(surface_actor
);
154 renderer
->AddActor(surface_wire_actor
);
155 pick_sphere
= vtkSphereSource::New();
156 pick_mapper
= vtkPolyDataMapper::New();
159 extr_vol
= vtkEgExtractVolumeCells::New();
160 extr_tetras
= vtkEgExtractVolumeCells::New();
161 extr_pyramids
= vtkEgExtractVolumeCells::New();
162 extr_wedges
= vtkEgExtractVolumeCells::New();
163 extr_hexas
= vtkEgExtractVolumeCells::New();
165 volume_geometry
= vtkGeometryFilter::New();
166 tetra_geometry
= vtkGeometryFilter::New();
167 pyramid_geometry
= vtkGeometryFilter::New();
168 wedge_geometry
= vtkGeometryFilter::New();
169 hexa_geometry
= vtkGeometryFilter::New();
171 extr_tetras
->SetAllOff();
172 extr_tetras
->SetTetrasOn();
173 extr_pyramids
->SetAllOff();
174 extr_pyramids
->SetPyramidsOn();
175 extr_wedges
->SetAllOff();
176 extr_wedges
->SetWedgesOn();
177 extr_hexas
->SetAllOff();
178 extr_hexas
->SetHexasOn();
180 boundary_pd
= vtkPolyData::New();
181 tetras_pd
= vtkPolyData::New();
182 wedges_pd
= vtkPolyData::New();
183 pyras_pd
= vtkPolyData::New();
184 hexas_pd
= vtkPolyData::New();
185 volume_pd
= vtkPolyData::New();
187 current_filename
= "untitled.vtu";
188 setWindowTitle(current_filename
+ " - enGrid");
190 status_bar
= new QStatusBar(this);
191 setStatusBar(status_bar
);
192 status_label
= new QLabel(this);
193 status_bar
->addWidget(status_label
);
194 QString txt
= "0 volume cells (0 tetras, 0 hexas, 0 pyramids, 0 prisms), ";
195 txt
+= "0 surface cells (0 triangles, 0 quads), 0 nodes";
196 status_label
->setText(txt
);
198 axes
= vtkCubeAxesActor2D::New();
199 axes
->SetCamera(getRenderer()->GetActiveCamera());
200 getRenderer()->AddActor(axes
);
203 CellPicker
= vtkCellPicker::New();
204 // getInteractor()->SetPicker(CellPicker);
205 PointPicker
= vtkPointPicker::New();
206 // getInteractor()->SetPicker(PointPicker);
208 pick_sphere
->SetRadius(0.25);//in case the user starts picking points instead of cells
210 vtkCallbackCommand
*cbc
= vtkCallbackCommand::New();
211 cbc
->SetCallback(pickCellCallBack
);
212 CellPicker
->AddObserver(vtkCommand::EndPickEvent
, cbc
);
213 cbc
->SetCallback(pickPointCallBack
);
214 PointPicker
->AddObserver(vtkCommand::EndPickEvent
, cbc
);
217 QString user
= QString(getenv("USER"));
218 QString basename
="enGrid_output_"+user
+".txt";
220 if (qset
.contains("tmp_directory")) {
221 log_file_name
= qset
.value("tmp_directory").toString() + "/" + basename
;
223 log_file_name
= "/tmp/" + basename
;
225 system_stdout
= stdout
;
226 freopen (log_file_name
.toAscii().data(), "w", stdout
);
231 connect(&garbage_timer
, SIGNAL(timeout()), this, SLOT(periodicUpdate()));
232 garbage_timer
.start(1000);
234 connect(&log_timer
, SIGNAL(timeout()), this, SLOT(updateOutput()));
235 log_timer
.start(1000);
240 getSet("","enable experimental features",false,exp_features
);
241 ui
.actionFoamWriter
->setEnabled(exp_features
);
245 // ui.checkBox_UseVTKInteractor->setCheckState(Qt::Checked);
246 // ui.radioButton_CellPicker->setChecked(true);
247 setPickMode(true,true);
252 GuiMainWindow::~GuiMainWindow()
256 void GuiMainWindow::updateOutput()
258 QFile
log_file(log_file_name
);
259 log_file
.open(QIODevice::ReadOnly
);
260 QByteArray buffer
= log_file
.readAll();
261 if (buffer
.size() > N_chars
) {
262 QByteArray newchars
= buffer
.right(buffer
.size() - N_chars
);
263 N_chars
= buffer
.size();
264 QString
txt(newchars
);
265 if (txt
.right(1) == "\n") {
266 txt
= txt
.left(txt
.size()-1);
268 output_window
->ui
.textEditOutput
->append(txt
);
272 void GuiMainWindow::exit()
274 QCoreApplication::exit();
277 vtkRenderWindow
* GuiMainWindow::getRenderWindow()
279 return ui
.qvtkWidget
->GetRenderWindow();
282 vtkRenderer
* GuiMainWindow::getRenderer()
287 QVTKInteractor
* GuiMainWindow::getInteractor()
289 return ui
.qvtkWidget
->GetInteractor();
292 QString
GuiMainWindow::getCwd()
297 void GuiMainWindow::setCwd(QString dir
)
300 qset
.setValue("working_directory",dir
);
303 void GuiMainWindow::updateActors()
305 if (!tryLock()) return;
309 if (!grid
->GetCellData()->GetScalars("cell_index")) {
310 EG_VTKSP(vtkLongArray_t
, cell_idx
);
311 cell_idx
->SetName("cell_index");
312 cell_idx
->SetNumberOfValues(grid
->GetNumberOfCells());
313 grid
->GetCellData()->AddArray(cell_idx
);
316 EG_VTKDCC(vtkLongArray_t
, cell_index
, grid
, "cell_index");
317 for (vtkIdType cellId
= 0; cellId
< grid
->GetNumberOfCells(); ++cellId
) {
318 cell_index
->SetValue(cellId
, cellId
);
322 axes
->SetInput(grid
);
330 for (vtkIdType nodeId
= 0; nodeId
< grid
->GetNumberOfPoints(); ++nodeId
) {
332 grid
->GetPoints()->GetPoint(nodeId
, x
.data());
333 xmin
= min(x
[0], xmin
);
334 xmax
= max(x
[0], xmax
);
335 ymin
= min(x
[1], ymin
);
336 ymax
= max(x
[1], ymax
);
337 zmin
= min(x
[2], zmin
);
338 zmax
= max(x
[2], zmax
);
342 getRenderer()->RemoveActor(surface_actor
);
343 surface_actor
->Delete();
344 surface_actor
= NULL
;
346 if (surface_wire_actor
) {
347 getRenderer()->RemoveActor(surface_wire_actor
);
348 surface_wire_actor
->Delete();
349 surface_wire_actor
= NULL
;
352 getRenderer()->RemoveActor(tetra_actor
);
353 tetra_actor
->Delete();
357 getRenderer()->RemoveActor(pyramid_actor
);
358 pyramid_actor
->Delete();
359 pyramid_actor
= NULL
;
362 getRenderer()->RemoveActor(wedge_actor
);
363 wedge_actor
->Delete();
367 getRenderer()->RemoveActor(hexa_actor
);
368 hexa_actor
->Delete();
371 if (volume_wire_actor
) {
372 getRenderer()->RemoveActor(volume_wire_actor
);
373 volume_wire_actor
->Delete();
374 volume_wire_actor
= NULL
;
377 getRenderer()->RemoveActor(pick_actor
);
378 pick_actor
->Delete();
382 if (ui
.checkBoxSurface
->isChecked()) {
383 bcodes_filter
->SetBoundaryCodes(&display_boundary_codes
);
384 bcodes_filter
->SetInput(grid
);
385 surface_filter
->SetInput(bcodes_filter
->GetOutput());
386 surface_filter
->Update();
387 boundary_pd
->DeepCopy(surface_filter
->GetOutput());
388 surface_mapper
->SetInput(boundary_pd
);
389 surface_wire_mapper
->SetInput(boundary_pd
);
390 surface_actor
= vtkActor::New();
391 surface_actor
->GetProperty()->SetRepresentationToSurface();
392 surface_actor
->GetProperty()->SetColor(0.5,1,0.5);
393 surface_actor
->SetBackfaceProperty(backface_property
);
394 surface_actor
->GetBackfaceProperty()->SetColor(1,1,0.5);
395 surface_wire_actor
= vtkActor::New();
396 surface_wire_actor
->GetProperty()->SetRepresentationToWireframe();
397 surface_wire_actor
->GetProperty()->SetColor(0,0,1);
398 surface_actor
->SetMapper(surface_mapper
);
399 surface_wire_actor
->SetMapper(surface_wire_mapper
);
400 getRenderer()->AddActor(surface_actor
);
401 getRenderer()->AddActor(surface_wire_actor
);
402 bcodes_filter
->Update();
404 if(m_UseVTKInteractor
)
406 if(ui
.radioButton_CellPicker
->isChecked())
408 // CellPicker->Pick(0,0,0, getRenderer());
409 getInteractor()->SetPicker(CellPicker
);
410 // CellPicker->Pick(0,0,0, getRenderer());
411 vtkIdType cellId
= getPickedCell();
416 getInteractor()->SetPicker(PointPicker
);
417 vtkIdType nodeId
= getPickedPoint();
423 if(ui
.radioButton_CellPicker
->isChecked()) pickCell(PickedCell
);
424 else pickPoint(PickedPoint
);
426 /* getInteractor()->SetPicker(CellPicker);
427 vtkIdType cellId = getPickedCell();
429 getInteractor()->SetPicker(PointPicker);
430 vtkIdType nodeId = getPickedPoint();
436 x
[0] = ui
.lineEditClipX
->text().toDouble();
437 x
[1] = ui
.lineEditClipY
->text().toDouble();
438 x
[2] = ui
.lineEditClipZ
->text().toDouble();
439 n
[0] = ui
.lineEditClipNX
->text().toDouble();
440 n
[1] = ui
.lineEditClipNY
->text().toDouble();
441 n
[2] = ui
.lineEditClipNZ
->text().toDouble();
443 x
= x
+ ui
.lineEditOffset
->text().toDouble()*n
;
444 extr_vol
->SetAllOff();
445 if (ui
.checkBoxTetra
->isChecked()) {
446 extr_vol
->SetTetrasOn();
447 extr_tetras
->SetInput(grid
);
448 if (ui
.checkBoxClip
->isChecked()) {
449 extr_tetras
->SetClippingOn();
450 extr_tetras
->SetX(x
);
451 extr_tetras
->SetN(n
);
453 extr_tetras
->SetClippingOff();
455 tetra_actor
= vtkActor::New();
456 tetra_geometry
->SetInput(extr_tetras
->GetOutput());
457 tetra_geometry
->Update();
458 tetras_pd
->DeepCopy(tetra_geometry
->GetOutput());
459 tetra_mapper
->SetInput(tetras_pd
);
460 tetra_actor
= vtkActor::New();
461 tetra_actor
->SetMapper(tetra_mapper
);
462 tetra_actor
->GetProperty()->SetColor(1,0,0);
463 getRenderer()->AddActor(tetra_actor
);
465 if (ui
.checkBoxPyramid
->isChecked()) {
466 extr_vol
->SetPyramidsOn();
467 extr_pyramids
->SetInput(grid
);
468 if (ui
.checkBoxClip
->isChecked()) {
469 extr_pyramids
->SetClippingOn();
470 extr_pyramids
->SetX(x
);
471 extr_pyramids
->SetN(n
);
473 extr_pyramids
->SetClippingOff();
475 pyramid_actor
= vtkActor::New();
476 pyramid_geometry
->SetInput(extr_pyramids
->GetOutput());
477 pyramid_geometry
->Update();
478 pyras_pd
->DeepCopy(pyramid_geometry
->GetOutput());
479 pyramid_mapper
->SetInput(pyras_pd
);
480 pyramid_actor
= vtkActor::New();
481 pyramid_actor
->SetMapper(pyramid_mapper
);
482 pyramid_actor
->GetProperty()->SetColor(1,1,0);
483 getRenderer()->AddActor(pyramid_actor
);
485 if (ui
.checkBoxWedge
->isChecked()) {
486 extr_vol
->SetWedgesOn();
487 extr_wedges
->SetInput(grid
);
488 if (ui
.checkBoxClip
->isChecked()) {
489 extr_wedges
->SetClippingOn();
490 extr_wedges
->SetX(x
);
491 extr_wedges
->SetN(n
);
493 extr_wedges
->SetClippingOff();
495 wedge_actor
= vtkActor::New();
496 wedge_geometry
->SetInput(extr_wedges
->GetOutput());
497 wedge_geometry
->Update();
498 wedges_pd
->DeepCopy(wedge_geometry
->GetOutput());
499 wedge_mapper
->SetInput(wedges_pd
);
500 wedge_actor
= vtkActor::New();
501 wedge_actor
->SetMapper(wedge_mapper
);
502 wedge_actor
->GetProperty()->SetColor(0,1,0);
503 getRenderer()->AddActor(wedge_actor
);
505 if (ui
.checkBoxHexa
->isChecked()) {
506 extr_vol
->SetHexasOn();
507 extr_hexas
->SetInput(grid
);
508 if (ui
.checkBoxClip
->isChecked()) {
509 extr_hexas
->SetClippingOn();
513 extr_hexas
->SetClippingOff();
515 hexa_actor
= vtkActor::New();
516 hexa_geometry
->SetInput(extr_hexas
->GetOutput());
517 hexa_geometry
->Update();
518 hexas_pd
->DeepCopy(hexa_geometry
->GetOutput());
519 hexa_mapper
->SetInput(hexas_pd
);
520 hexa_actor
= vtkActor::New();
521 hexa_actor
->SetMapper(hexa_mapper
);
522 hexa_actor
->GetProperty()->SetColor(0,0.7,1);
523 getRenderer()->AddActor(hexa_actor
);
527 extr_vol
->SetInput(grid
);
528 if (ui
.checkBoxClip
->isChecked()) {
529 extr_vol
->SetClippingOn();
533 extr_vol
->SetClippingOff();
535 volume_wire_actor
= vtkActor::New();
536 volume_geometry
->SetInput(extr_vol
->GetOutput());
537 volume_geometry
->Update();
538 volume_pd
->DeepCopy(volume_geometry
->GetOutput());
539 volume_wire_mapper
->SetInput(volume_pd
);
540 volume_wire_actor
->SetMapper(volume_wire_mapper
);
541 volume_wire_actor
->GetProperty()->SetRepresentationToWireframe();
542 volume_wire_actor
->GetProperty()->SetColor(0,0,1);
543 getRenderer()->AddActor(volume_wire_actor
);
547 getRenderWindow()->Render();
548 } catch (Error err
) {
554 void GuiMainWindow::setPickMode(bool a_UseVTKInteractor
,bool a_CellPickerMode
)
556 m_UseVTKInteractor
=a_UseVTKInteractor
;
557 if(a_UseVTKInteractor
) ui
.checkBox_UseVTKInteractor
->setCheckState(Qt::Checked
);
558 else ui
.checkBox_UseVTKInteractor
->setCheckState(Qt::Unchecked
);
559 if(a_CellPickerMode
) ui
.radioButton_CellPicker
->toggle();
560 else ui
.radioButton_PointPicker
->toggle();
561 // cout<<"m_UseVTKInteractor="<<m_UseVTKInteractor<<endl;
564 void GuiMainWindow::setUseVTKInteractor(int a_UseVTKInteractor
)
566 m_UseVTKInteractor
=a_UseVTKInteractor
;
567 // cout<<"m_UseVTKInteractor="<<m_UseVTKInteractor<<endl;
570 bool GuiMainWindow::pickPoint(vtkIdType nodeId
)
572 if (nodeId
>= 0 && nodeId
<grid
->GetNumberOfPoints()) {
574 grid
->GetPoints()->GetPoint(nodeId
, x
.data());
575 pick_sphere
->SetCenter(x
.data());
576 pick_mapper
->SetInput(pick_sphere
->GetOutput());
577 pick_actor
= vtkActor::New();
578 pick_actor
->SetMapper(pick_mapper
);
579 pick_actor
->GetProperty()->SetRepresentationToSurface();
580 pick_actor
->GetProperty()->SetColor(0,0,1);
581 getRenderer()->AddActor(pick_actor
);
588 bool GuiMainWindow::pickCell(vtkIdType cellId
)
590 if (cellId
>= 0 && cellId
<grid
->GetNumberOfCells()) {
591 vtkIdType
*pts
, Npts
;
592 grid
->GetCellPoints(cellId
, Npts
, pts
);
594 for (vtkIdType i
= 0; i
< Npts
; ++i
) {
596 grid
->GetPoints()->GetPoint(pts
[i
], xp
.data());
597 x
+= double(1)/Npts
* xp
;
599 pick_sphere
->SetCenter(x
.data());
601 for (vtkIdType i
= 0; i
< Npts
; ++i
) {
603 grid
->GetPoints()->GetPoint(pts
[i
], xp
.data());
604 R
= min(R
, 0.25*(xp
-x
).abs());
606 ReferenceSize
=R
;//Used for text annotations too!
607 pick_sphere
->SetRadius(R
);
608 pick_mapper
->SetInput(pick_sphere
->GetOutput());
609 pick_actor
= vtkActor::New();
610 pick_actor
->SetMapper(pick_mapper
);
611 pick_actor
->GetProperty()->SetRepresentationToSurface();
612 pick_actor
->GetProperty()->SetColor(1,0,0);
613 getRenderer()->AddActor(pick_actor
);
620 void GuiMainWindow::importSTL()
624 updateBoundaryCodes(true);
630 void GuiMainWindow::importGmsh1Ascii()
635 updateBoundaryCodes(true);
641 void GuiMainWindow::exportGmsh1Ascii()
648 void GuiMainWindow::importGmsh2Ascii()
653 updateBoundaryCodes(true);
659 void GuiMainWindow::exportGmsh2Ascii()
666 void GuiMainWindow::exportNeutral()
668 NeutralWriter neutral
;
672 void GuiMainWindow::zoomAll()
674 getRenderer()->ResetCamera();
675 getRenderWindow()->Render();
678 void GuiMainWindow::open()
680 current_filename
= QFileDialog::getOpenFileName
683 "open grid from file",
685 "VTK unstructured grid files (*.vtu *.VTU)"
687 if (!current_filename
.isNull()) {
688 GuiMainWindow::setCwd(QFileInfo(current_filename
).absolutePath());
689 EG_VTKSP(vtkXMLUnstructuredGridReader
,vtu
);
690 vtu
->SetFileName(current_filename
.toAscii().data());
692 grid
->DeepCopy(vtu
->GetOutput());
693 createBasicFields(grid
, grid
->GetNumberOfCells(), grid
->GetNumberOfPoints(), false);
694 setWindowTitle(current_filename
+ " - enGrid");
696 updateBoundaryCodes(true);
703 void GuiMainWindow::undo()
707 void GuiMainWindow::redo()
711 void GuiMainWindow::openBC()
713 QString bc_file
= current_filename
+ ".bcs";
717 file
.open(QIODevice::ReadOnly
| QIODevice::Text
);
718 QTextStream
f(&file
);
722 f
>> i
>> name
>> type
;
723 bcmap
[i
] = BoundaryCondition(name
,type
);
728 void GuiMainWindow::saveBC()
730 QString bc_file
= current_filename
+ ".bcs";
732 file
.open(QIODevice::WriteOnly
| QIODevice::Text
);
733 QTextStream
f(&file
);
734 foreach(int i
, all_boundary_codes
) {
735 BoundaryCondition bc
= bcmap
[i
];
736 f
<< i
<< " " << bc
.getName() << " " << bc
.getType() << "\n";
740 void GuiMainWindow::save()
742 cout
<< current_filename
.toAscii().data() << endl
;
743 if (current_filename
== "untitled.vtu") {
746 EG_VTKDCC(vtkDoubleArray
, cell_VA
, grid
, "cell_VA");
747 for (vtkIdType cellId
= 0; cellId
< grid
->GetNumberOfCells(); ++cellId
) {
748 cell_VA
->SetValue(cellId
, GeometryTools::cellVA(grid
, cellId
, true));
750 EG_VTKSP(vtkXMLUnstructuredGridWriter
,vtu
);
753 vtu
->SetFileName(current_filename
.toAscii().data());
754 vtu
->SetDataModeToBinary();
761 void GuiMainWindow::saveAs()
763 current_filename
= QFileDialog::getSaveFileName
766 "write grid to file",
768 "VTK unstructured grid files (*.vtu *.VTU)"
770 if (!current_filename
.isNull()) {
771 if (current_filename
.right(4) != ".vtu") {
772 if (current_filename
.right(4) != ".VTU") {
773 current_filename
+= ".vtu";
776 EG_VTKDCC(vtkDoubleArray
, cell_VA
, grid
, "cell_VA");
777 for (vtkIdType cellId
= 0; cellId
< grid
->GetNumberOfCells(); ++cellId
) {
778 cell_VA
->SetValue(cellId
, GeometryTools::cellVA(grid
, cellId
, true));
780 GuiMainWindow::setCwd(QFileInfo(current_filename
).absolutePath());
781 EG_VTKSP(vtkXMLUnstructuredGridWriter
,vtu
);
784 vtu
->SetFileName(current_filename
.toAscii().data());
785 vtu
->SetDataModeToBinary();
789 setWindowTitle(current_filename
+ " - enGrid");
793 void GuiMainWindow::QuickSave(QString a_filename
)
795 cout
<< a_filename
.toAscii().data() << endl
;
796 EG_VTKDCC(vtkDoubleArray
, cell_VA
, grid
, "cell_VA");
797 for (vtkIdType cellId
= 0; cellId
< grid
->GetNumberOfCells(); ++cellId
) {
798 cell_VA
->SetValue(cellId
, GeometryTools::cellVA(grid
, cellId
, true));
800 EG_VTKSP(vtkXMLUnstructuredGridWriter
,vtu
);
803 vtu
->SetFileName(a_filename
.toAscii().data());
804 vtu
->SetDataModeToBinary();
811 void GuiMainWindow::updateStatusBar()
813 QString num
, txt
= "enGrid is currently busy with an operation ...";
818 status_label
->setText(txt
);
821 vtkIdType Ncells
= grid
->GetNumberOfCells();
822 vtkIdType Nnodes
= grid
->GetNumberOfPoints();
824 vtkIdType Nquads
= 0;
826 vtkIdType Npyras
= 0;
827 vtkIdType Nprism
= 0;
828 vtkIdType Nhexas
= 0;
829 for (vtkIdType i
= 0; i
< Ncells
; ++i
) {
830 int ct
= grid
->GetCellType(i
);
831 if (ct
== VTK_TRIANGLE
) ++Ntris
;
832 else if (ct
== VTK_QUAD
) ++Nquads
;
833 else if (ct
== VTK_TETRA
) ++Ntets
;
834 else if (ct
== VTK_WEDGE
) ++Nprism
;
835 else if (ct
== VTK_PYRAMID
) ++Npyras
;
836 else if (ct
== VTK_HEXAHEDRON
) ++Nhexas
;
838 num
.setNum(Ntets
+ Npyras
+ Nprism
+ Nhexas
); txt
+= num
+ " volume cells(";
839 num
.setNum(Ntets
); txt
+= num
+ " tetras, ";
840 num
.setNum(Npyras
); txt
+= num
+ " pyramids, ";
841 num
.setNum(Nprism
); txt
+= num
+ " prisms, ";
842 num
.setNum(Nhexas
); txt
+= num
+ " hexas), ";
843 num
.setNum(Ntris
+ Nquads
); txt
+= num
+ " surface cells(";
844 num
.setNum(Ntris
); txt
+= num
+ " triangles, ";
845 num
.setNum(Nquads
); txt
+= num
+ " quads), ";
846 num
.setNum(Nnodes
); txt
+= num
+ " nodes";
848 if(ui
.radioButton_CellPicker
->isChecked())
850 QString pick_txt
= ", picked cell: ";
851 vtkIdType id_cell
= getPickedCell();
853 pick_txt
+= "no cell picked";
855 vtkIdType type_cell
= grid
->GetCellType(id_cell
);
856 if (type_cell
== VTK_TRIANGLE
) pick_txt
+= "triangle";
857 else if (type_cell
== VTK_QUAD
) pick_txt
+= "quad";
858 else if (type_cell
== VTK_TETRA
) pick_txt
+= "tetrahedron";
859 else if (type_cell
== VTK_PYRAMID
) pick_txt
+= "pyramid";
860 else if (type_cell
== VTK_WEDGE
) pick_txt
+= "prism";
861 else if (type_cell
== VTK_HEXAHEDRON
) pick_txt
+= "hexahedron";
862 vtkIdType N_pts
, *pts
;
863 grid
->GetCellPoints(id_cell
, N_pts
, pts
);
865 for (int i_pts
= 0; i_pts
< N_pts
; ++i_pts
) {
867 num
.setNum(pts
[i_pts
]);
869 if (i_pts
< N_pts
-1) {
876 pick_txt
+= " id_cell=" + tmp
;
882 QString pick_txt
= ", picked node: ";
883 vtkIdType id_node
= getPickedPoint();
885 pick_txt
+= "no node picked";
888 grid
->GetPoints()->GetPoint(id_node
,x
.data());
890 for (int i
= 0; i
< 3; i
++) {
901 pick_txt
+= " id_node=" + tmp
;
902 EG_VTKDCN(vtkDoubleArray
, node_meshdensity
, grid
, "node_meshdensity");
903 tmp
.setNum(node_meshdensity
->GetValue(id_node
));
904 pick_txt
+= " wanted density=" + tmp
;
905 EG_VTKDCN(vtkDoubleArray
, node_meshdensity_current
, grid
, "node_meshdensity_current");
906 tmp
.setNum(node_meshdensity_current
->GetValue(id_node
));
907 pick_txt
+= " current density=" + tmp
;
908 EG_VTKDCN(vtkCharArray
, node_type
, grid
, "node_type");
909 pick_txt
+= " type=" + QString(VertexType2Str( node_type
->GetValue(id_node
)));
915 status_label
->setText(txt
);
919 void GuiMainWindow::selectBoundaryCodes()
921 GuiSelectBoundaryCodes bcodes
;
922 bcodes
.setDisplayBoundaryCodes(display_boundary_codes
);
923 bcodes
.setBoundaryCodes(all_boundary_codes
);
925 bcodes
.getThread().wait();
926 bcodes
.getSelectedBoundaryCodes(display_boundary_codes
);
930 void GuiMainWindow::updateBoundaryCodes(bool all_on
)
933 all_boundary_codes
.clear();
934 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
935 for (vtkIdType i
= 0; i
< grid
->GetNumberOfCells(); ++i
) {
936 int ct
= grid
->GetCellType(i
);
937 if ((ct
== VTK_TRIANGLE
) || (ct
== VTK_QUAD
)) {
938 all_boundary_codes
.insert(cell_code
->GetValue(i
));
942 display_boundary_codes
.clear();
943 foreach (int bc
, all_boundary_codes
) {
944 display_boundary_codes
.insert(bc
);
948 foreach (int bc
, display_boundary_codes
) {
949 if (all_boundary_codes
.contains(bc
)) {
953 display_boundary_codes
.clear();
954 foreach (int bc
, all_boundary_codes
) {
955 if (dbcs
.contains(bc
)) {
956 display_boundary_codes
.insert(bc
);
960 } catch (Error err
) {
965 void GuiMainWindow::normalExtrusion()
967 GuiNormalExtrusion extr
;
969 updateBoundaryCodes(false);
973 void GuiMainWindow::setAxesVisibility()
975 if (ui
.actionViewAxes
->isChecked()) axes
->SetVisibility(1);
976 else axes
->SetVisibility(0);
977 getRenderWindow()->Render();
980 void GuiMainWindow::setViewingMode()
982 if (ui
.actionViewOrthogonal
->isChecked()) getRenderer()->GetActiveCamera()->ParallelProjectionOn();
983 else getRenderer()->GetActiveCamera()->ParallelProjectionOff();
984 getRenderWindow()->Render();
987 void GuiMainWindow::ViewNodeIDs()
989 int N
=grid
->GetNumberOfPoints();
991 if (ui
.actionViewNodeIDs
->isChecked()) {
992 cout
<<"Activating node ID view"<<endl
;
993 NodeText_VectorText
.resize(N
);
994 NodeText_PolyDataMapper
.resize(N
);
995 NodeText_Follower
.resize(N
);
996 for(int i
=0;i
<N
;i
++){
997 NodeText_VectorText
[i
]=vtkVectorText::New();
1000 NodeText_VectorText
[i
]->SetText(tmp
.toLatin1().data());
1001 NodeText_PolyDataMapper
[i
]=vtkPolyDataMapper::New();
1002 NodeText_PolyDataMapper
[i
]->SetInputConnection(NodeText_VectorText
[i
]->GetOutputPort());
1003 NodeText_Follower
[i
]=vtkFollower::New();
1004 NodeText_Follower
[i
]->SetMapper(NodeText_PolyDataMapper
[i
]);
1005 NodeText_Follower
[i
]->SetScale(ReferenceSize
,ReferenceSize
,ReferenceSize
);
1007 grid
->GetPoint(i
,M
.data());
1008 NodeText_Follower
[i
]->AddPosition(M
[0],M
[1],M
[2]+ReferenceSize
);
1009 NodeText_Follower
[i
]->SetCamera(getRenderer()->GetActiveCamera());
1010 NodeText_Follower
[i
]->GetProperty()->SetColor(0,0,1);
1011 getRenderer()->AddActor(NodeText_Follower
[i
]);
1015 cout
<<"Deactivating node ID view"<<endl
;
1016 for(unsigned int i
=0;i
<NodeText_Follower
.size();i
++){
1017 getRenderer()->RemoveActor(NodeText_Follower
[i
]);
1018 NodeText_Follower
[i
]->Delete();
1019 NodeText_PolyDataMapper
[i
]->Delete();
1020 NodeText_VectorText
[i
]->Delete();
1022 NodeText_Follower
.clear();
1023 NodeText_PolyDataMapper
.clear();
1024 NodeText_VectorText
.clear();
1027 getRenderWindow()->Render();
1030 void GuiMainWindow::ViewCellIDs()
1032 int N
=grid
->GetNumberOfCells();
1033 cout
<<"N="<<N
<<endl
;
1034 if (ui
.actionViewCellIDs
->isChecked()) {
1035 cout
<<"Activating cell ID view"<<endl
;
1036 CellText_VectorText
.resize(N
);
1037 CellText_PolyDataMapper
.resize(N
);
1038 CellText_Follower
.resize(N
);
1039 for(int i
=0;i
<N
;i
++){
1040 CellText_VectorText
[i
]=vtkVectorText::New();
1043 CellText_VectorText
[i
]->SetText(tmp
.toLatin1().data());
1044 CellText_PolyDataMapper
[i
]=vtkPolyDataMapper::New();
1045 CellText_PolyDataMapper
[i
]->SetInputConnection(CellText_VectorText
[i
]->GetOutputPort());
1046 CellText_Follower
[i
]=vtkFollower::New();
1047 CellText_Follower
[i
]->SetMapper(CellText_PolyDataMapper
[i
]);
1048 CellText_Follower
[i
]->SetScale(ReferenceSize
,ReferenceSize
,ReferenceSize
);
1049 vtkIdType N_pts
,*pts
;
1050 grid
->GetCellPoints(i
,N_pts
,pts
);
1051 vec3_t
Center(0,0,0);
1052 for(int p
=0;p
<N_pts
;p
++)
1055 grid
->GetPoint(pts
[p
],M
.data());
1058 vec3_t OffSet
=ReferenceSize
*triNormal(grid
,pts
[0],pts
[1],pts
[2]).normalise();
1059 Center
=1.0/(double)N_pts
*Center
+OffSet
;
1060 CellText_Follower
[i
]->AddPosition(Center
[0],Center
[1],Center
[2]);
1061 CellText_Follower
[i
]->SetCamera(getRenderer()->GetActiveCamera());
1062 CellText_Follower
[i
]->GetProperty()->SetColor(1,0,0);
1063 getRenderer()->AddActor(CellText_Follower
[i
]);
1067 cout
<<"Deactivating cell ID view"<<endl
;
1068 for(unsigned int i
=0;i
<CellText_Follower
.size();i
++){
1069 getRenderer()->RemoveActor(CellText_Follower
[i
]);
1070 CellText_Follower
[i
]->Delete();
1071 CellText_PolyDataMapper
[i
]->Delete();
1072 CellText_VectorText
[i
]->Delete();
1074 CellText_Follower
.clear();
1075 CellText_PolyDataMapper
.clear();
1076 CellText_VectorText
.clear();
1079 getRenderWindow()->Render();
1082 void GuiMainWindow::addVtkTypeInfo()
1084 EG_VTKSP(vtkIntArray
, vtk_type
);
1085 vtk_type
->SetName("vtk_type");
1086 vtk_type
->SetNumberOfValues(grid
->GetNumberOfCells());
1087 for (vtkIdType cellId
= 0; cellId
< grid
->GetNumberOfCells(); ++cellId
) {
1088 vtk_type
->SetValue(cellId
, grid
->GetCellType(cellId
));
1090 grid
->GetCellData()->AddArray(vtk_type
);
1093 void GuiMainWindow::pickCellCallBack
1096 unsigned long int eid
,
1103 clientdata
= clientdata
;
1104 calldata
= calldata
;
1105 THIS
->updateActors();
1106 THIS
->updateStatusBar();
1109 void GuiMainWindow::pickPointCallBack
1112 unsigned long int eid
,
1119 clientdata
= clientdata
;
1120 calldata
= calldata
;
1121 THIS
->updateActors();
1122 THIS
->updateStatusBar();
1125 vtkIdType
GuiMainWindow::getPickedCell()
1127 vtkIdType picked_cell
= -1;
1128 if (THIS
->grid
->GetNumberOfCells() > 0) {
1129 THIS
->bcodes_filter
->Update();
1130 EG_VTKDCC(vtkLongArray_t
, cell_index
, THIS
->bcodes_filter
->GetOutput(), "cell_index");
1133 if(m_UseVTKInteractor
) cellId
= THIS
->CellPicker
->GetCellId();
1134 else cellId
= PickedCell
;
1137 if (cellId
< THIS
->bcodes_filter
->GetOutput()->GetNumberOfCells()) {
1138 picked_cell
= cell_index
->GetValue(cellId
);
1145 vtkIdType
GuiMainWindow::getPickedPoint()
1147 vtkIdType picked_point
= -1;
1148 if (THIS
->grid
->GetNumberOfCells() > 0) {
1149 THIS
->bcodes_filter
->Update();
1152 if(m_UseVTKInteractor
) pointId
= THIS
->PointPicker
->GetPointId();
1153 else pointId
= PickedPoint
;
1156 picked_point
= pointId
;
1159 return picked_point
;
1162 void GuiMainWindow::changeSurfaceOrientation()
1164 for (vtkIdType cellId
= 0; cellId
< grid
->GetNumberOfCells(); ++cellId
) {
1165 vtkIdType Npts
, *pts
;
1166 grid
->GetCellPoints(cellId
, Npts
, pts
);
1167 QVector
<vtkIdType
> nodes(Npts
);
1168 for (vtkIdType j
= 0; j
< Npts
; ++j
) nodes
[j
] = pts
[j
];
1169 for (vtkIdType j
= 0; j
< Npts
; ++j
) pts
[Npts
- j
- 1] = nodes
[j
];
1174 void GuiMainWindow::checkSurfaceOrientation()
1176 CorrectSurfaceOrientation corr_surf
;
1177 vtkIdType picked_cell
= getPickedCell();
1178 if (picked_cell
>= 0) {
1179 corr_surf
.setStart(picked_cell
);
1185 void GuiMainWindow::improveAspectRatio()
1187 GuiImproveAspectRatio impr_ar
;
1192 void GuiMainWindow::exportAsciiStl()
1198 void GuiMainWindow::exportBinaryStl()
1202 void GuiMainWindow::periodicUpdate()
1204 Operation::collectGarbage();
1208 void GuiMainWindow::viewXP()
1210 getRenderer()->ResetCamera();
1212 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1214 getRenderer()->GetActiveCamera()->SetPosition(x
);
1215 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1216 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1217 getRenderer()->ResetCamera();
1218 getRenderWindow()->Render();
1221 void GuiMainWindow::viewXM()
1223 getRenderer()->ResetCamera();
1225 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1227 getRenderer()->GetActiveCamera()->SetPosition(x
);
1228 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1229 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1230 getRenderer()->ResetCamera();
1231 getRenderWindow()->Render();
1234 void GuiMainWindow::viewYP()
1236 getRenderer()->ResetCamera();
1238 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1240 getRenderer()->GetActiveCamera()->SetPosition(x
);
1241 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1242 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1243 getRenderer()->ResetCamera();
1244 getRenderWindow()->Render();
1247 void GuiMainWindow::viewYM()
1249 getRenderer()->ResetCamera();
1251 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1253 getRenderer()->GetActiveCamera()->SetPosition(x
);
1254 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1255 getRenderer()->GetActiveCamera()->SetViewUp(0,0,-1);
1256 getRenderer()->ResetCamera();
1257 getRenderWindow()->Render();
1260 void GuiMainWindow::viewZP()
1262 getRenderer()->ResetCamera();
1264 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1266 getRenderer()->GetActiveCamera()->SetPosition(x
);
1267 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1268 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1269 getRenderer()->ResetCamera();
1270 getRenderWindow()->Render();
1273 void GuiMainWindow::viewZM()
1275 getRenderer()->ResetCamera();
1277 getRenderer()->GetActiveCamera()->GetFocalPoint(x
);
1279 getRenderer()->GetActiveCamera()->SetPosition(x
);
1280 getRenderer()->GetActiveCamera()->ComputeViewPlaneNormal();
1281 getRenderer()->GetActiveCamera()->SetViewUp(0,1,0);
1282 getRenderer()->ResetCamera();
1283 getRenderWindow()->Render();
1286 void GuiMainWindow::callFixSTL()
1292 updateBoundaryCodes(false);
1296 void GuiMainWindow::editBoundaryConditions()
1298 GuiEditBoundaryConditions editbcs
;
1299 editbcs
.setBoundaryCodes(all_boundary_codes
);
1300 editbcs
.setMap(&bcmap
);
1304 void GuiMainWindow::configure()
1307 // Just to create initial entries in the settings file
1308 // so that the options menu isn't empty at first start.
1310 GuiCreateBoundaryLayer tmp02
;
1312 GuiSettingsViewer
settings(&qset
);
1316 void GuiMainWindow::about()
1318 QMessageBox
box(this);
1320 QString title
="ENGRID";
1321 QString version
= QString("version ") + ENGRID_VERSION
;
1322 if (version
== "version CVS") {
1323 version
+= " build on ";
1324 version
+= QString(__DATE__
);
1326 version
+= QString(__TIME__
);
1328 QString address
= tr("ENGRID is being developed and maintained by:<br/>"
1330 "Marie-Curie-Strasse 8<br/>"
1331 "79539 Loerrach<br/>"
1334 QString mainurl
="<a href=\"http://www.engits.com\">www.engits.com</a>";
1335 QString mail
="<a href=\"mailto:info@engits.com\">info@engits.com</a>";
1336 QString gnuurl
="<a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses</a>";
1337 QString license
=tr("ENGRID is licenced under the GPL version 3.<br/>"
1338 "(see ")+gnuurl
+tr(" for details)<br/>");
1339 QString bugurl
="<a href=\"http://sourceforge.net/tracker2/?func=add&group_id=245110&atid=1126548\">the bugtracker available on Sourceforge</a>";
1340 QString bugreporting
=tr("To submit a bug report, please use ")+bugurl
;
1341 box
.setText(QString::fromLatin1("<center><img src=\":/icons/resources/icons/G.png\">"
1345 "<p>Homepage: %4</p>"
1348 "<p>%7</p></center>")
1349 .arg(title
).arg(version
).arg(address
).arg(mainurl
).arg(mail
).arg(license
).arg(bugreporting
));
1350 box
.setWindowTitle(tr("about ENGRID"));
1351 box
.setIcon(QMessageBox::NoIcon
);
1356 void GuiMainWindow::getAllBoundaryCodes(QSet
<int> &bcs
)
1359 foreach (int bc
, all_boundary_codes
) {