2016-07-31 11:56:30 +00:00
/// \file mainwindow.hpp
/// \brief Main window and algorhytms.
/// \author smal.root@gmail.com
/// \date 2016
# include "mainwindow.hpp"
# include "ui_mainwindow.h"
// Header files, Assimp.
# include <assimp/Exporter.hpp>
# include <assimp/postprocess.h>
# ifndef __unused
# define __unused __attribute__((unused))
# endif // __unused
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
void MainWindow : : ImportFile ( const QString & pFileName )
{
using namespace Assimp ;
QTime time_begin = QTime : : currentTime ( ) ;
if ( mScene ! = nullptr )
{
mImporter . FreeScene ( ) ;
mGLView - > FreeScene ( ) ;
}
// Try to import scene.
2016-08-01 10:13:35 +00:00
mScene = mImporter . ReadFile ( pFileName . toStdString ( ) , aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs ) ;
2016-07-31 11:56:30 +00:00
if ( mScene ! = nullptr )
{
2017-12-28 14:10:55 +00:00
ui - > lblLoadTime - > setText ( QString : : number ( time_begin . secsTo ( QTime : : currentTime ( ) ) ) ) ;
2016-07-31 11:56:30 +00:00
LogInfo ( " Import done: " + pFileName ) ;
// Prepare widgets for new scene.
ui - > leFileName - > setText ( pFileName . right ( pFileName . length ( ) - pFileName . lastIndexOf ( ' / ' ) - 1 ) ) ;
ui - > lstLight - > clear ( ) ;
ui - > lstCamera - > clear ( ) ;
2017-12-28 12:55:41 +00:00
ui - > cbxLighting - > setChecked ( true ) ; mGLView - > Lighting_Enable ( ) ;
ui - > cbxBBox - > setChecked ( false ) ; mGLView - > Enable_SceneBBox ( false ) ;
ui - > cbxTextures - > setChecked ( true ) ; mGLView - > Enable_Textures ( true ) ;
2018-05-24 09:31:49 +00:00
2016-07-31 11:56:30 +00:00
//
// Fill info labels
//
// Cameras
2017-12-28 12:55:41 +00:00
ui - > lblCameraCount - > setText ( QString : : number ( mScene - > mNumCameras ) ) ;
2016-07-31 11:56:30 +00:00
// Lights
2017-12-28 12:55:41 +00:00
ui - > lblLightCount - > setText ( QString : : number ( mScene - > mNumLights ) ) ;
2016-07-31 11:56:30 +00:00
// Meshes, faces, vertices.
size_t qty_face = 0 ;
size_t qty_vert = 0 ;
for ( size_t idx_mesh = 0 ; idx_mesh < mScene - > mNumMeshes ; idx_mesh + + )
{
qty_face + = mScene - > mMeshes [ idx_mesh ] - > mNumFaces ;
qty_vert + = mScene - > mMeshes [ idx_mesh ] - > mNumVertices ;
}
2017-12-28 12:55:41 +00:00
ui - > lblMeshCount - > setText ( QString : : number ( mScene - > mNumMeshes ) ) ;
ui - > lblFaceCount - > setText ( QString : : number ( qty_face ) ) ;
ui - > lblVertexCount - > setText ( QString : : number ( qty_vert ) ) ;
2016-07-31 11:56:30 +00:00
// Animation
if ( mScene - > mNumAnimations )
ui - > lblHasAnimation - > setText ( " yes " ) ;
else
ui - > lblHasAnimation - > setText ( " no " ) ;
//
// Set scene for GL viewer.
//
mGLView - > SetScene ( mScene , pFileName ) ;
// Select first camera
ui - > lstCamera - > setCurrentRow ( 0 ) ;
mGLView - > Camera_Set ( 0 ) ;
// Scene is loaded, do first rendering.
LogInfo ( " Scene is ready for rendering. " ) ;
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
}
else
{
2017-12-28 12:55:41 +00:00
ResetSceneInfos ( ) ;
2017-12-28 14:10:55 +00:00
QString errorMessage = QString ( " Error parsing \' %1 \' : \' %2 \' " ) . arg ( pFileName ) . arg ( mImporter . GetErrorString ( ) ) ;
2017-12-28 12:55:41 +00:00
QMessageBox : : critical ( this , " Import error " , errorMessage ) ;
LogError ( errorMessage ) ;
2016-07-31 11:56:30 +00:00
} // if(mScene != nullptr)
}
2017-12-28 12:55:41 +00:00
void MainWindow : : ResetSceneInfos ( )
{
ui - > lblLoadTime - > clear ( ) ;
ui - > leFileName - > clear ( ) ;
ui - > lblMeshCount - > setText ( " 0 " ) ;
ui - > lblFaceCount - > setText ( " 0 " ) ;
ui - > lblVertexCount - > setText ( " 0 " ) ;
ui - > lblCameraCount - > setText ( " 0 " ) ;
ui - > lblLightCount - > setText ( " 0 " ) ;
ui - > lblHasAnimation - > setText ( " no " ) ;
}
2016-07-31 11:56:30 +00:00
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
void MainWindow : : LogInfo ( const QString & pMessage )
{
Assimp : : DefaultLogger : : get ( ) - > info ( pMessage . toStdString ( ) ) ;
}
void MainWindow : : LogError ( const QString & pMessage )
{
Assimp : : DefaultLogger : : get ( ) - > error ( pMessage . toStdString ( ) ) ;
}
/********************************************************************/
2017-11-09 22:19:26 +00:00
/*********************** Override functions ************************/
2016-07-31 11:56:30 +00:00
/********************************************************************/
void MainWindow : : mousePressEvent ( QMouseEvent * pEvent )
{
2018-06-17 18:37:09 +00:00
const QPoint ms_pt = pEvent - > pos ( ) ;
aiVector3D temp_v3 ;
2018-05-24 14:11:21 +00:00
2018-05-24 10:05:50 +00:00
// Check if GLView is pointed.
if ( childAt ( ms_pt ) = = mGLView )
{
2018-05-24 14:11:21 +00:00
if ( ! mMouse_Transformation . Position_Pressed_Valid )
{
mMouse_Transformation . Position_Pressed_Valid = true ; // set flag
// Store current transformation matrices.
mGLView - > Camera_Matrix ( mMouse_Transformation . Rotation_AroundCamera , mMouse_Transformation . Rotation_Scene , temp_v3 ) ;
}
2018-05-24 10:05:50 +00:00
if ( pEvent - > button ( ) & Qt : : LeftButton )
2018-05-24 14:11:21 +00:00
mMouse_Transformation . Position_Pressed_LMB = ms_pt ;
2018-05-24 10:05:50 +00:00
else if ( pEvent - > button ( ) & Qt : : RightButton )
2018-05-24 14:11:21 +00:00
mMouse_Transformation . Position_Pressed_RMB = ms_pt ;
2018-05-24 10:05:50 +00:00
}
else
{
2018-05-24 14:11:21 +00:00
mMouse_Transformation . Position_Pressed_Valid = false ;
2018-05-24 10:05:50 +00:00
}
2016-07-31 11:56:30 +00:00
}
2018-05-24 14:11:21 +00:00
void MainWindow : : mouseReleaseEvent ( QMouseEvent * pEvent )
{
if ( pEvent - > buttons ( ) = = 0 ) mMouse_Transformation . Position_Pressed_Valid = false ;
}
2016-07-31 11:56:30 +00:00
void MainWindow : : mouseMoveEvent ( QMouseEvent * pEvent )
{
2018-05-24 14:11:21 +00:00
if ( mMouse_Transformation . Position_Pressed_Valid )
2016-07-31 11:56:30 +00:00
{
2018-05-24 10:05:50 +00:00
if ( pEvent - > buttons ( ) & Qt : : LeftButton )
{
2018-05-24 14:11:21 +00:00
GLfloat dx = 180 * GLfloat ( pEvent - > x ( ) - mMouse_Transformation . Position_Pressed_LMB . x ( ) ) / mGLView - > width ( ) ;
GLfloat dy = 180 * GLfloat ( pEvent - > y ( ) - mMouse_Transformation . Position_Pressed_LMB . y ( ) ) / mGLView - > height ( ) ;
2016-07-31 11:56:30 +00:00
2018-05-24 10:05:50 +00:00
if ( pEvent - > modifiers ( ) & Qt : : ShiftModifier )
2018-05-24 14:11:21 +00:00
mGLView - > Camera_RotateScene ( dy , 0 , dx , & mMouse_Transformation . Rotation_Scene ) ; // Rotate around oX and oZ axises.
2018-05-24 10:05:50 +00:00
else
2018-05-24 14:11:21 +00:00
mGLView - > Camera_RotateScene ( dy , dx , 0 , & mMouse_Transformation . Rotation_Scene ) ; // Rotate around oX and oY axises.
2016-07-31 11:56:30 +00:00
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2018-05-24 10:05:50 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2018-05-24 10:05:50 +00:00
}
2016-07-31 11:56:30 +00:00
2018-05-24 10:05:50 +00:00
if ( pEvent - > buttons ( ) & Qt : : RightButton )
{
2018-05-24 14:11:21 +00:00
GLfloat dx = 180 * GLfloat ( pEvent - > x ( ) - mMouse_Transformation . Position_Pressed_RMB . x ( ) ) / mGLView - > width ( ) ;
GLfloat dy = 180 * GLfloat ( pEvent - > y ( ) - mMouse_Transformation . Position_Pressed_RMB . y ( ) ) / mGLView - > height ( ) ;
2016-07-31 11:56:30 +00:00
2018-05-24 10:05:50 +00:00
if ( pEvent - > modifiers ( ) & Qt : : ShiftModifier )
2018-05-24 14:11:21 +00:00
mGLView - > Camera_Rotate ( dy , 0 , dx , & mMouse_Transformation . Rotation_AroundCamera ) ; // Rotate around oX and oZ axises.
2018-05-24 10:05:50 +00:00
else
2018-05-24 14:11:21 +00:00
mGLView - > Camera_Rotate ( dy , dx , 0 , & mMouse_Transformation . Rotation_AroundCamera ) ; // Rotate around oX and oY axises.
2016-07-31 11:56:30 +00:00
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2018-05-24 10:05:50 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2018-05-24 10:05:50 +00:00
}
2016-07-31 11:56:30 +00:00
}
}
void MainWindow : : keyPressEvent ( QKeyEvent * pEvent )
{
GLfloat step ;
if ( pEvent - > modifiers ( ) & Qt : : ControlModifier )
step = 10 ;
else if ( pEvent - > modifiers ( ) & Qt : : AltModifier )
step = 100 ;
else
step = 1 ;
if ( pEvent - > key ( ) = = Qt : : Key_A )
mGLView - > Camera_Translate ( - step , 0 , 0 ) ;
else if ( pEvent - > key ( ) = = Qt : : Key_D )
mGLView - > Camera_Translate ( step , 0 , 0 ) ;
else if ( pEvent - > key ( ) = = Qt : : Key_W )
mGLView - > Camera_Translate ( 0 , step , 0 ) ;
else if ( pEvent - > key ( ) = = Qt : : Key_S )
mGLView - > Camera_Translate ( 0 , - step , 0 ) ;
else if ( pEvent - > key ( ) = = Qt : : Key_Up )
mGLView - > Camera_Translate ( 0 , 0 , - step ) ;
else if ( pEvent - > key ( ) = = Qt : : Key_Down )
mGLView - > Camera_Translate ( 0 , 0 , step ) ;
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
}
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
MainWindow : : MainWindow ( QWidget * parent )
: QMainWindow ( parent ) , ui ( new Ui : : MainWindow ) ,
2018-05-24 14:11:21 +00:00
mScene ( nullptr )
2016-07-31 11:56:30 +00:00
{
using namespace Assimp ;
2018-05-24 14:11:21 +00:00
// other variables
mMouse_Transformation . Position_Pressed_Valid = false ;
2016-07-31 11:56:30 +00:00
ui - > setupUi ( this ) ;
// Create OpenGL widget
mGLView = new CGLView ( this ) ;
mGLView - > setMinimumSize ( 800 , 600 ) ;
mGLView - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : MinimumExpanding ) ;
mGLView - > setFocusPolicy ( Qt : : StrongFocus ) ;
// Connect to GLView signals.
connect ( mGLView , SIGNAL ( Paint_Finished ( size_t , GLfloat ) ) , SLOT ( Paint_Finished ( size_t , GLfloat ) ) ) ;
connect ( mGLView , SIGNAL ( SceneObject_Camera ( QString ) ) , SLOT ( SceneObject_Camera ( QString ) ) ) ;
connect ( mGLView , SIGNAL ( SceneObject_LightSource ( QString ) ) , SLOT ( SceneObject_LightSource ( QString ) ) ) ;
// and add it to layout
ui - > hlMainView - > insertWidget ( 0 , mGLView , 4 ) ;
// Create logger
mLoggerView = new CLoggerView ( ui - > tbLog ) ;
DefaultLogger : : create ( " " , Logger : : VERBOSE ) ;
DefaultLogger : : get ( ) - > attachStream ( mLoggerView , DefaultLogger : : Debugging | DefaultLogger : : Info | DefaultLogger : : Err | DefaultLogger : : Warn ) ;
2017-12-28 12:55:41 +00:00
ResetSceneInfos ( ) ;
2016-07-31 11:56:30 +00:00
}
MainWindow : : ~ MainWindow ( )
{
using namespace Assimp ;
DefaultLogger : : get ( ) - > detatchStream ( mLoggerView , DefaultLogger : : Debugging | DefaultLogger : : Info | DefaultLogger : : Err | DefaultLogger : : Warn ) ;
DefaultLogger : : kill ( ) ;
if ( mScene ! = nullptr ) mImporter . FreeScene ( ) ;
if ( mLoggerView ! = nullptr ) delete mLoggerView ;
if ( mGLView ! = nullptr ) delete mGLView ;
delete ui ;
}
/********************************************************************/
/****************************** Slots *******************************/
/********************************************************************/
void MainWindow : : Paint_Finished ( const size_t pPaintTime_ms , const GLfloat pDistance )
{
2017-12-28 14:10:55 +00:00
ui - > lblRenderTime - > setText ( QString : : number ( pPaintTime_ms ) ) ;
ui - > lblDistance - > setText ( QString : : number ( pDistance ) ) ;
2016-07-31 11:56:30 +00:00
}
void MainWindow : : SceneObject_Camera ( const QString & pName )
{
ui - > lstCamera - > addItem ( pName ) ;
}
void MainWindow : : SceneObject_LightSource ( const QString & pName )
{
ui - > lstLight - > addItem ( pName ) ;
// After item added "currentRow" is still contain old value (even '-1' if first item added). Because "currentRow"/"currentItem" is changed by user interaction,
// not by "addItem". So, "currentRow" must be set manually.
ui - > lstLight - > setCurrentRow ( ui - > lstLight - > count ( ) - 1 ) ;
// And after "selectAll" handler of "signal itemSelectionChanged" will get right "currentItem" and "currentRow" values.
ui - > lstLight - > selectAll ( ) ;
}
2018-06-17 18:37:09 +00:00
void MainWindow : : on_butOpenFile_clicked ( ) {
aiString filter_temp ;
mImporter . GetExtensionList ( filter_temp ) ;
2016-07-31 11:56:30 +00:00
2018-06-17 18:37:09 +00:00
QString filename , filter ;
filter = filter_temp . C_Str ( ) ;
2016-07-31 11:56:30 +00:00
filter . replace ( ' ; ' , ' ' ) ;
filter . append ( " ;; All (*.*) " ) ;
filename = QFileDialog : : getOpenFileName ( this , " Choose the file " , " " , filter ) ;
2018-06-17 18:37:09 +00:00
if ( ! filename . isEmpty ( ) ) {
ImportFile ( filename ) ;
}
2016-07-31 11:56:30 +00:00
}
void MainWindow : : on_butExport_clicked ( )
{
2018-06-17 18:37:09 +00:00
using namespace Assimp ;
2016-07-31 11:56:30 +00:00
2018-06-17 18:37:09 +00:00
# ifndef ASSIMP_BUILD_NO_EXPORT
QString filename , filter , format_id ;
Exporter exporter ;
QTime time_begin ;
aiReturn rv ;
QStringList exportersList ;
QMap < QString , const aiExportFormatDesc * > exportersMap ;
2016-07-31 11:56:30 +00:00
2017-12-28 14:10:55 +00:00
2016-07-31 11:56:30 +00:00
if ( mScene = = nullptr )
{
QMessageBox : : critical ( this , " Export error " , " Scene is empty " ) ;
return ;
}
2018-05-21 14:38:43 +00:00
for ( size_t i = 0 ; i < exporter . GetExportFormatCount ( ) ; + + i )
2016-07-31 11:56:30 +00:00
{
2017-12-27 18:08:20 +00:00
const aiExportFormatDesc * desc = exporter . GetExportFormatDescription ( i ) ;
2017-12-28 14:10:55 +00:00
exportersList . push_back ( desc - > id + QString ( " : " ) + desc - > description ) ;
2017-12-27 18:08:20 +00:00
exportersMap . insert ( desc - > id , desc ) ;
2016-07-31 11:56:30 +00:00
}
2017-12-27 18:08:20 +00:00
// get an exporter
bool dialogSelectExporterOk ;
2017-12-28 14:10:55 +00:00
QString selectedExporter = QInputDialog : : getItem ( this , " Export format " , " Select the exporter : " , exportersList , 0 , false , & dialogSelectExporterOk ) ;
2017-12-27 18:08:20 +00:00
if ( ! dialogSelectExporterOk )
return ;
// build the filter
QString selectedId = selectedExporter . left ( selectedExporter . indexOf ( ' : ' ) ) ;
filter = QString ( " *. " ) + exportersMap [ selectedId ] - > fileExtension ;
2016-07-31 11:56:30 +00:00
// get file path
filename = QFileDialog : : getSaveFileName ( this , " Set file name " , " " , filter ) ;
2017-12-27 18:08:20 +00:00
// if it's canceled
if ( filename = = " " )
2016-07-31 11:56:30 +00:00
return ;
// begin export
time_begin = QTime : : currentTime ( ) ;
2017-12-27 18:08:20 +00:00
rv = exporter . Export ( mScene , selectedId . toLocal8Bit ( ) , filename . toLocal8Bit ( ) , aiProcess_FlipUVs ) ;
2017-12-28 14:10:55 +00:00
ui - > lblExportTime - > setText ( QString : : number ( time_begin . secsTo ( QTime : : currentTime ( ) ) ) ) ;
2016-07-31 11:56:30 +00:00
if ( rv = = aiReturn_SUCCESS )
LogInfo ( " Export done: " + filename ) ;
else
2017-12-27 18:08:20 +00:00
{
2017-12-28 14:10:55 +00:00
QString errorMessage = QString ( " Export failed: " ) + filename ;
LogError ( errorMessage ) ;
QMessageBox : : critical ( this , " Export error " , errorMessage ) ;
2017-12-27 18:08:20 +00:00
}
2018-06-17 18:37:09 +00:00
# endif
2016-07-31 11:56:30 +00:00
}
void MainWindow : : on_cbxLighting_clicked ( bool pChecked )
{
if ( pChecked )
mGLView - > Lighting_Enable ( ) ;
else
mGLView - > Lighting_Disable ( ) ;
2018-05-25 18:19:06 +00:00
mGLView - > update ( ) ;
2016-07-31 11:56:30 +00:00
}
void MainWindow : : on_lstLight_itemSelectionChanged ( )
{
bool selected = ui - > lstLight - > isItemSelected ( ui - > lstLight - > currentItem ( ) ) ;
if ( selected )
mGLView - > Lighting_EnableSource ( ui - > lstLight - > currentRow ( ) ) ;
else
mGLView - > Lighting_DisableSource ( ui - > lstLight - > currentRow ( ) ) ;
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
}
2016-10-21 10:50:41 +00:00
void MainWindow : : on_lstCamera_clicked ( const QModelIndex & )
2016-07-31 11:56:30 +00:00
{
mGLView - > Camera_Set ( ui - > lstLight - > currentRow ( ) ) ;
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
}
void MainWindow : : on_cbxBBox_clicked ( bool checked )
{
mGLView - > Enable_SceneBBox ( checked ) ;
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2016-07-31 11:56:30 +00:00
}
2018-04-05 07:50:30 +00:00
void MainWindow : : on_cbxDrawAxes_clicked ( bool checked )
{
mGLView - > Enable_Axes ( checked ) ;
2018-05-25 18:19:06 +00:00
# if ASSIMP_QT4_VIEWER
2018-04-05 07:50:30 +00:00
mGLView - > updateGL ( ) ;
2018-05-25 18:19:06 +00:00
# else
mGLView - > update ( ) ;
# endif // ASSIMP_QT4_VIEWER
2018-04-05 07:50:30 +00:00
}
2016-07-31 11:56:30 +00:00
void MainWindow : : on_cbxTextures_clicked ( bool checked )
{
mGLView - > Enable_Textures ( checked ) ;
2018-05-25 18:19:06 +00:00
mGLView - > update ( ) ;
2016-07-31 11:56:30 +00:00
}