1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 #define VTK_USE_RENDERING
27 #if defined(LIBENGRID_EXPORTS) || defined(libengrid_EXPORTS)
28 #define LIBENGRID_DLL __declspec(dllexport)
30 #define LIBENGRID_DLL __declspec(dllimport)
32 #define CLASS_LIBENGRID_DLL LIBENGRID_DLL
35 #define CLASS_LIBENGRID_DLL
40 #include <QMainWindow>
44 #include <QFileSystemWatcher>
47 #include <QDockWidget>
48 #include <QDomDocument>
49 #include <QProgressBar>
51 #include <vtkUnstructuredGrid.h>
53 #include <vtkPolyDataMapper.h>
54 #include <vtkGeometryFilter.h>
55 #include <vtkCubeAxesActor2D.h>
56 #include <vtkCellPicker.h>
57 #include <vtkPointPicker.h>
58 #include <vtkSphereSource.h>
59 #include <vtkTextActor.h>
60 #include <vtkVectorText.h>
61 #include <vtkFollower.h>
62 #include <vtkScalarBarActor.h>
63 #include <vtkLookupTable.h>
64 #include <vtkDataSetSurfaceFilter.h>
66 #include "ui_guimainwindow.h"
67 #include "vtkEgBoundaryCodesFilter.h"
68 #include "vtkEgExtractVolumeCells.h"
69 #include "egvtkobject.h"
70 #include "boundarycondition.h"
71 #include "volumedefinition.h"
72 #include "physicalboundarycondition.h"
73 #include "checksurfaceintegrity.h"
75 #include "cadinterface.h"
77 #include "openfoamcase.h"
78 #include "guitransform.h"
79 #include "openfoamtools.h"
80 #include "std_includes.h"
81 #include "fixcadgeometry.h"
82 #include "xmlhandler.h"
85 * This is the main GUI class of enGrid.
87 class CLASS_LIBENGRID_DLL GuiMainWindow
: public QMainWindow
, public EgVtkObject
92 private: // attributes
94 XmlHandler
* m_XmlHandler
;
96 Ui::GuiMainWindow ui
; ///< The user interface definition -- created by QtDesigner.
97 vtkUnstructuredGrid
*m_Grid
; ///< The current state of the grid that is being generated.
99 vtkRenderer
*m_Renderer
; ///< The VTK renderer object, used for visualising the grid
101 vtkActor
* m_SurfaceActor
;
102 vtkActor
* m_TetraActor
;
103 vtkActor
* m_WedgeActor
;
104 vtkActor
* m_PyramidActor
;
105 vtkActor
* m_HexaActor
;
106 vtkActor
* m_PolyhedraActor
;
108 vtkProperty
* m_BackfaceProperty
;
109 vtkLookupTable
* m_LookupTable
;
110 vtkScalarBarActor
* m_LegendActor
;
112 vtkPolyDataMapper
* m_SurfaceMapper
;
113 vtkPolyDataMapper
* m_TetraMapper
;
114 vtkPolyDataMapper
* m_PyramidMapper
;
115 vtkPolyDataMapper
* m_WedgeMapper
;
116 vtkPolyDataMapper
* m_HexaMapper
;
117 vtkPolyDataMapper
* m_PolyhedraMapper
;
119 double m_ColTetraR
, m_ColTetraG
, m_ColTetraB
;
120 double m_ColPyraR
, m_ColPyraG
, m_ColPyraB
;
121 double m_ColPrismR
, m_ColPrismG
, m_ColPrismB
;
122 double m_ColHexR
, m_ColHexG
, m_ColHexB
;
123 double m_ColPolyR
, m_ColPolyG
, m_ColPolyB
;
124 double m_ColAR
, m_ColAG
, m_ColAB
;
125 double m_ColBR
, m_ColBG
, m_ColBB
;
127 vtkEgExtractVolumeCells
*m_ExtrTetras
;
128 vtkEgExtractVolumeCells
*m_ExtrPyramids
;
129 vtkEgExtractVolumeCells
*m_ExtrWedges
;
130 vtkEgExtractVolumeCells
*m_ExtrHexes
;
131 vtkEgExtractVolumeCells
*m_ExtrPolyhedra
;
133 vtkDataSetSurfaceFilter
*m_TetraGeometry
;
134 vtkDataSetSurfaceFilter
*m_PyramidGeometry
;
135 vtkDataSetSurfaceFilter
*m_WedgeGeometry
;
136 vtkDataSetSurfaceFilter
*m_HexaGeometry
;
137 vtkDataSetSurfaceFilter
*m_PolyhedraGeometry
;
139 vtkIdType m_PickedPoint
; ///< Picked point
140 vtkIdType m_PickedCell
; ///< Picked cell
141 bool m_UseVTKInteractor
; ///< Boolean value specifying whether the VTK Interactor should be used or not
143 static QMutex m_Mutex
;
145 vtkDataSetSurfaceFilter
* m_SurfaceFilter
; ///< VTK filter to extract the surface of the current grid.
146 double m_ReferenceSize
; ///< Size to use for picker objects and annotations
148 vector
<vtkTextActor
*> m_NodeText
; ///< 2D Text actor to display node IDs
149 vector
<vtkTextActor
*> m_CellText
; ///< 2D Text actor to display cell IDs
150 vector
<vtkVectorText
*> m_NodeTextVectorText
; ///< 3D Text actor to display node IDs
151 vector
<vtkPolyDataMapper
*> m_NodeTextPolyDataMapper
;
152 vector
<vtkFollower
*> m_NodeTextFollower
;
153 vector
<vtkVectorText
*> m_CellTextVectorText
; ///< 3D Text actor to display cell IDs
154 vector
<vtkPolyDataMapper
*> m_CellTextPolyDataMapper
;
155 vector
<vtkFollower
*> m_CellTextFollower
;
157 vtkPolyDataMapper
* m_PickMapper
; ///< VTK mapper to map pick marker
158 vtkActor
* m_PickActor
; ///< VTK actor to display pick marker
159 vtkSphereSource
* m_PickSphere
; ///< sphere to mark picked cell/points
160 vtkCubeAxesActor2D
* m_Axes
; ///< VTK actor to display the coordinate system
161 vtkEgBoundaryCodesFilter
* m_BCodesFilter
; ///< VTK filter to extract boundary elements with certain codes
162 vtkCellPicker
* m_CellPicker
; ///< VTK CellPicker to pick cells for various user interactions
163 vtkPointPicker
* m_PointPicker
; ///< VTK PointPicker to pick points for various user interactions
164 int m_PickedObject
; ///< 0=none, 1=node, 2=cell
166 QString m_CurrentFilename
; ///< The current file name of the grid.
167 int m_CurrentOperation
; ///< The current operation number. (used for undo/redo)
168 bool m_undo_redo_enabled
; ///< if true, undo/redo operations will be usable.
169 int m_LastOperation
; ///< The last operation number. (used for undo/redo)
170 QLabel
* m_StatusLabel
; ///< Label for the information in the status bar
171 QLabel
* m_StatusInfoLabel
;
172 QProgressBar
* m_StatusProgressBar
;
173 QSet
<int> m_DisplayBoundaryCodes
; ///< A QList with all active boundary codes.
174 QSet
<int> m_AllBoundaryCodes
; ///< A QList with all boundary codes.
175 bool m_Busy
; ///< flag to indicate that enGrid is busy with an operation
177 stringbuf m_CoutBuffer
;
178 streambuf
*m_OriginalCoutBuffer
;
180 QTimer m_GarbageTimer
;
184 QMap
<int, BoundaryCondition
> m_bcmap
; ///< mapping between numerical and symbolic boundary codes
185 QMap
<QString
, VolumeDefinition
> m_VolMap
; ///< all volume definitions
186 QMap
<QString
, PhysicalBoundaryCondition
> m_PhysicalBoundaryConditionsMap
; ///< all physical boundary conditions definitions
188 QMap
<int, CadInterface
*> m_CadInterfaces
; ///< all CAD interfaces
189 CadInterface
* m_UniCadInterface
; ///< universal CAD interface for all boundary conditions
191 QMap
<QAction
*, Operation
*> m_PluginOperations
;
192 QAction
* m_EscAction
;
194 int m_SolverIndex
;// deprecated
195 OpenFOAMTools m_OpenFoamTools
;
197 // recent file list support
199 QMap
<QString
,QDateTime
> m_RecentFiles
;
200 QMenu
* recentFileMenu() { return ui
.menuOpen_recent
; }
201 void readRecentFiles();
202 void writeRecentFiles();
203 void addRecentFile(QString file_name
, QDateTime date
);
205 void openRecent(QAction
*action
);
210 private: // static attributes
213 * Platform independant access to application settings.
214 * For a UNIX system the user preferences will be stored in the file
215 * folder ".config/enGits/enGrid.conf" in the user's home directory;
216 * on Windows preferences will be stored in the registry.
218 static QSettings m_qset
;
221 * The current working directory of enGrid
223 static QString m_cwd
;
226 * Is the current case unsaved?
228 static bool m_UnSaved
;
230 /** a static this pointer (somewhat ugly, but there is only one MainWindow) */
231 static GuiMainWindow
* THIS
;
236 static void pickCallBack( vtkObject
*caller
, unsigned long int eid
, void *clientdata
, void *calldata
);
237 void updateSurfaceActors( bool forced
);
238 void updateVolumeActors( bool forced
);
242 void setClipX( const QString
&txt
);
243 void setClipY( const QString
&txt
);
244 void setClipZ( const QString
&txt
);
245 void setClipNX( const QString
&txt
);
246 void setClipNY( const QString
&txt
);
247 void setClipNZ( const QString
&txt
);
252 void openPhysicalBoundaryConditions();
253 void savePhysicalBoundaryConditions();
255 void openGrid(QString file_name
);
261 GuiMainWindow();///< Default constructor.
262 GuiMainWindow(QString file_name
);///< Constructor which opens a file directly.
266 * This function connects the menu and toolbar actions and
267 * the VTK basics(i.e. renderer, actor, ...) will be set up.
268 * Furthermore preferences will be read from qset.
270 void setupGuiMainWindow();
275 * Preferences will be written back.
277 virtual ~GuiMainWindow();
280 * Get the VTK render window
281 * @return the VTK render window
283 vtkRenderWindow
* getRenderWindow();
286 * Get the VTK renderer
287 * @return the VTK renderer
289 vtkRenderer
* getRenderer();
292 * Get the Qt-VTK interactor
293 * @return the Qt-VTK interactor
295 QVTKInteractor
* getInteractor();
298 * Get a pointer to the current grid object
299 * @return a pointer to the current vtkUnstructuredGrid object
301 vtkUnstructuredGrid
* getGrid() { return m_Grid
; }
303 void setBusy() { m_Busy
= true; updateStatusBar(); }
304 void setIdle() { m_Busy
= false; updateStatusBar(); }
306 /// Returns the path to the currently loaded file
307 QString
getFilePath();
309 /// Returns the index of the solver to use. The index corresponds to the position in solvers.txt .
310 void setSolverIndex(int x
) {m_SolverIndex
= x
;}
311 int getSolverIndex() {return m_SolverIndex
;}
313 public: // static methods
316 * Get the current working directory.
317 * @return the current working directory
319 static QString
getCwd();
322 * Set the current working directory
323 * @param dir the current working directory
325 static void setCwd( QString dir
);
329 * @param unsaved Do you want to be asked where to save when clicking on save next time?
331 static void setUnsaved( bool unsaved
);
334 * Get the currently picked cell.
335 * @return the picked cell ID or -1 if no cell has been picked
337 vtkIdType
getPickedCell();
340 * Get the currently picked point.
341 * @return the picked point ID or -1 if no point has been picked
343 vtkIdType
getPickedPoint();
345 vtkIdType
getPickedObject() { return m_PickedObject
; }
348 * Access to the QSettings object
350 static QSettings
* settings() { return &m_qset
; }
352 BoundaryCondition
getBC( int bc
) { return m_bcmap
[bc
]; }
353 VolumeDefinition
getVol( QString volname
) { return m_VolMap
[volname
]; }
354 void clearBCs() { m_bcmap
.clear(); }
355 void addBC(int bc
, BoundaryCondition BC
) { m_bcmap
[bc
] = BC
; }
357 QList
<VolumeDefinition
> getAllVols();
358 void setAllVols( QList
<VolumeDefinition
> vols
);
359 void createDefaultVol();
361 QList
<PhysicalBoundaryCondition
> getAllPhysicalBoundaryConditions();
362 void setAllPhysicalBoundaryConditions (QList
<PhysicalBoundaryCondition
> physical_boundary_conditions
);
363 void setAllPhysicalBoundaryConditions (QMap
<QString
, PhysicalBoundaryCondition
> physical_boundary_conditions
);
364 bool physicalTypeDefined(QString name
) { return m_PhysicalBoundaryConditionsMap
.contains(name
); }
365 PhysicalBoundaryCondition
getPhysicalBoundaryCondition(QString name
) { return m_PhysicalBoundaryConditionsMap
[name
]; }
367 static GuiMainWindow
* pointer() { return THIS
; }
369 static void unlock();
370 static bool tryLock();
371 void getAllBoundaryCodes(QVector
<int> &bcs
);
372 QSet
<int> getAllBoundaryCodes();
373 void getDisplayBoundaryCodes(QSet
<int> &bcs
);
374 vtkPointPicker
* getPointPicker() { return ( m_PointPicker
);}
375 vtkSphereSource
* getPickSphere() { return ( m_PickSphere
);}
376 bool pickPoint( vtkIdType id_point
);
377 bool pickCell( vtkIdType id_cell
);
379 QString
getFilename() { return( m_CurrentFilename
); }
380 void setFilename(QString filename
) { m_CurrentFilename
= filename
; }
382 CadInterface
* getCadInterface(int bc
, bool allow_null
= false);
383 void setCadInterface(CadInterface
* cad_interface
, int bc
) { m_CadInterfaces
[bc
] = cad_interface
; }
384 void setUniversalCadInterface(CadInterface
* cad_interface
);
385 bool checkCadInterfaces();
387 void resetProgress(QString info_text
, int p_max
);
388 void setProgress(int p
);
392 void setUseVTKInteractor( int a_UseVTKInteractor
);
393 void setPickMode( bool a_UseVTKInteractor
, bool a_CellPickerMode
);
395 void exit(); ///< Exit the application
396 void importSTL(); ///< Import an STL file (ASCII or binary)
397 void importGmsh1Ascii(); ///< Import a Gmsh grid from an ASCII file -- using version 1.0 of the Gmsh file format
398 void exportGmsh1Ascii(); ///< Export a grid from to an ASCII Gmsh file -- using version 1.0 of the Gmsh file format
399 void importGmsh2Ascii(); ///< Import a Gmsh grid from an ASCII file -- using version 2.0 of the Gmsh file format
400 void exportGmsh2Ascii(); ///< Export a grid from to an ASCII Gmsh file -- using version 2.0 of the Gmsh file format
401 void exportNeutral(); ///< Export a grid to neutral format for NETGEN
402 void updateActors( bool force
= false ); ///< Update the VTK output
403 void forceUpdateActors(); ///< Force an update of the VTK output
404 void scaleToData(); ///< Scale to data
405 void zoomAll(); ///< Move the camera in order to show everything on the screen
406 void zoomOnPickedObject();
408 void printGrid() {cout
<< "PrintGrid() called!" << endl
; cout_grid( cout
, m_Grid
, true, true, true, true );}
414 void resetOperationCounter();
416 void open(); ///< Open an existing case
417 void open( QString file_name
, bool update_current_filename
= true ); ///< Open case file_name
418 void save(); ///< Save the current case
419 void saveAs(); ///< Save the current case -- using a different file name
420 QString
saveAs( QString file_name
, bool update_current_filename
= true ); ///< Save the current case as file_name. Returns name under which file was saved (with missing .egc extension for example).
422 int quickSave(); ///< Save the current grid as a_filename_a_operation
423 void quickLoad( int a_operation
); ///< Load a_filename_a_operation
424 void updateStatusBar(); ///< Update the status bar
425 void selectBoundaryCodes(); ///< Select the boundary codes to be displayed/hidden
426 void updateBoundaryCodes( bool all_on
); ///< Update the boundary code book keeping (e.g. after reading a mesh).
427 void normalExtrusion(); ///< Normal extrusion of boundary elements (no validity check).
428 void setAxesVisibility(); ///< Toggle the visibility of the axes annotation.
429 void setViewingMode(); ///< Toggle orthogonal viewing mode.
430 void viewNodeIDs(); ///< Toggle node ID viewing mode.
431 void viewCellIDs(); ///< Toggle cell ID viewing mode.
432 void changeSurfaceOrientation(); ///< Change the orientation of all surface elements
433 void checkSurfaceOrientation(); ///< Check and, if required, change the orientation of all surface elements
434 void improveAspectRatio(); ///< Eliminate edges in order to improve the aspect ratio of the cells
435 void exportAsciiStl(); ///< Write surface elements to an ASCII STL file.
436 void exportBinaryStl(); ///< Write surface elements to a binary STL file.
437 void exportAsciiPly(); ///< Write surface elements to an ASCII PLY file.
438 void exportBinaryPly(); ///< Write surface elements to a binary PLY file.
439 void editBoundaryConditions(); ///< Edit boundary conditions (names and types)
440 void configure(); ///< Edit settings
441 void about(); ///< Display an about message
442 void markOutputLine(); ///< Mark the current position in the output window
444 QString
getXmlSection( QString name
); ///< Get a section from the XML case description
445 void setXmlSection( QString name
, QString contents
); ///< Set a section of the XML case description
454 void appendOutput( QString txt
) { ui
.textEditOutput
->append( txt
); }
455 void clearOutput() { ui
.textEditOutput
->clear(); }
457 void periodicUpdate();
459 void storeCadInterfaces(bool nosave
= false);
460 void resetCadInterfaces();
462 void logOn() { m_CoutBuffer
.str(""); m_Log
= true; }
463 void logOff() { m_Log
= false; }
465 // SLOTS for all standard operations should be defined below;
466 // entries should look like this:
467 // void callOperationName() { EG_STDSLOT(OperationName); };
468 // The actual class name in this case, however, would be GuiOperationName.
470 // the following line can be used as a template:
471 // void call() { EG_STDSLOT(); };
472 // IMPORTANT: Using EG_STDSLOT sets lock_gui to true, while EG_STDINTERSLOT does not (default is lock_gui = false)
473 // This is important to determine whether an operation should try to lock the main mutex or not.
474 // If lock_gui is true, the operation will try to lock the main mutex. If it fails (mutex locked by other operation), the operation is stopped.
476 // EG_STDSLOT = background operation (There can not be more than one background operation!)
477 // EG_STDINTERSLOT = foreground operation
478 // Note: In practice, EG_STDINTERSLOT locks everything, while EG_STDSLOT prevents other operations, but doesn't lock the text output or prevent minimizing the window.
480 void callCreateSurfaceMesh() { EG_STDINTERSLOT( GuiCreateSurfaceMesh
); }
481 void callCreateBoundaryLayer() { EG_STDSLOT( GuiCreateBoundaryLayer
); }
482 void callDivideBoundaryLayer() { EG_STDSLOT( GuiDivideBoundaryLayer
); }
483 void callDeleteVolumeGrid() { EG_STDINTERSLOT( DeleteVolumeGrid
); }
484 void callDeleteTetras() { EG_STDSLOT( DeleteTetras
); }
485 void callCreateVolumeMesh() { EG_STDSLOT( GuiCreateVolumeMesh
); }
486 void callSmoothVolumeGrid() { EG_STDSLOT( SmoothVolumeGrid
); }
487 void callSetBoundaryCode() { EG_STDINTERSLOT( GuiSetBoundaryCode
); }
488 void callDeleteBadAspectTris() { EG_STDINTERSLOT( GuiDeleteBadAspectTris
); }
489 void callDeletePickedCell() { EG_STDSLOT( DeletePickedCell
); }
490 void callMergeNodes();
491 void callInsertNewCell();
492 void callDeletePickedPoint();
493 void callBoxSelect() { EG_STDINTERSLOT( BoxSelect
); }
494 void callCheckSurfaceIntegrity() { EG_STDINTERSLOT( CheckSurfaceIntegrity
); }
495 void callPick_cell_point() { EG_STDINTERSLOT( GuiPick
); }
496 void callTransform() { EG_STDINTERSLOT( GuiTransform
); }
497 void callUpdateSurfProj() { EG_STDINTERSLOT( UpdateSurfProj
); }
498 void callImportOpenFoamCase() { EG_STDREADERSLOT(FoamReader
); }
499 void callMergeVolumes() { EG_STDSLOT(GuiMergeVolumes
); }
500 void callMirrorMesh() { EG_STDSLOT(GuiMirrorMesh
); }
501 void callCreateHexCore() { EG_STDSLOT( GuiCreateHexCore
); }
502 void callCreateHexIbMesh() { EG_STDSLOT( GuiCreateHexIbMesh
); }
503 void callFillPlane() { EG_STDSLOT( GuiFillPlane
); }
504 void callConvertToPolyMesh() { EG_STDSLOT(GuiConvertToPolyMesh
); }
505 void callCreateHexShellMesh() { EG_STDSLOT(GuiCreateHexShell
); }
506 void callRestrictToAvailableVolumeCells() { EG_STDSLOT(RestrictToAvailableVolumeCells
); }
510 void callFoamWriter() { EG_STDINTERSLOT( FoamWriter
); }
511 void callSimpleFoamWriter() { EG_STDINTERSLOT( SimpleFoamWriter
); }
512 void callFoamCaseWriter() { EG_STDINTERSLOT( OpenFOAMcase
); }
513 void callCgnsWriter() { EG_STDINTERSLOT( CgnsWriter
); }
514 void callVtkReader() { EG_STDREADERSLOT( VtkReader
); }
515 void callBlenderReader() { EG_STDREADERSLOT( BlenderReader
); }
516 void callBlenderWriter() { EG_STDREADERSLOT( BlenderWriter
); }
517 void callPolyDataReader() { EG_STDREADERSLOT( PolyDataReader
); }
518 void callReducedPolyDataReader() { EG_STDREADERSLOT( ReducedPolyDataReader
); }
519 void callSeligAirfoilReader() { EG_STDREADERSLOT( SeligAirfoilReader
); }
520 void callMultiSolidAsciiStlReader() { EG_STDREADERSLOT( MultiSolidAsciiStlReader
); }
522 #ifdef BRLCAD_SUPPORT
523 void callBrlcadReader() { EG_STDREADERSLOT( BrlcadReader
); }
526 void callExportSu2() { EG_STDREADERSLOT( Su2Writer
); }
527 void callExportDolfyn() { EG_STDREADERSLOT( DolfynWriter
); }
530 void callExportTau() { EG_STDREADERSLOT( TauWriter
); }
533 void callExportDrNum() { EG_STDREADERSLOT( DrNumWriter
); }
535 void callSurfaceMesher() { EG_STDSLOT(GuiSurfaceMesher
); }
536 void callReduceSurfaceTriangulation() { EG_STDSLOT(ReduceSurfaceTriangulation
); }
537 void callEliminateSmallBranches() { EG_STDSLOT(EliminateSmallBranches
); }
538 void callSmoothAndSwapSurface() { EG_STDSLOT(SmoothAndSwapSurface
); }
539 void callCheckForOverlap() { EG_STDSLOT(CheckForOverlap
); }
541 void callFixCADGeometry() { EG_STDSLOT(FixCadGeometry
); }