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 )
{
ui - > lblLoadTime - > setText ( QString ( " %1 " ) . arg ( time_begin . secsTo ( QTime : : currentTime ( ) ) ) ) ;
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 ( ) ;
ui - > cbxLighting - > setChecked ( true ) , mGLView - > Lighting_Enable ( ) ;
ui - > cbxBBox - > setChecked ( false ) ; mGLView - > Enable_SceneBBox ( false ) ;
ui - > cbxTextures - > setChecked ( true ) , mGLView - > Enable_Textures ( true ) ;
//
// Fill info labels
//
// Cameras
ui - > lblCameraCount - > setText ( QString ( " %1 " ) . arg ( mScene - > mNumCameras ) ) ;
// Lights
ui - > lblLightCount - > setText ( QString ( " %1 " ) . arg ( mScene - > mNumLights ) ) ;
// 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 ;
}
ui - > lblMeshCount - > setText ( QString ( " %1 " ) . arg ( mScene - > mNumMeshes ) ) ;
ui - > lblFaceCount - > setText ( QString ( " %1 " ) . arg ( qty_face ) ) ;
ui - > lblVertexCount - > setText ( QString ( " %1 " ) . arg ( qty_vert ) ) ;
// 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. " ) ;
mGLView - > updateGL ( ) ;
}
else
{
ui - > lblLoadTime - > clear ( ) ;
LogError ( QString ( " Error parsing \' %1 \' : \' %2 \' " ) . arg ( pFileName ) . arg ( mImporter . GetErrorString ( ) ) ) ;
} // if(mScene != nullptr)
}
/********************************************************************/
/************************ 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 ( ) ) ;
}
/********************************************************************/
/*********************** Overrided functions ************************/
/********************************************************************/
void MainWindow : : mousePressEvent ( QMouseEvent * pEvent )
{
if ( pEvent - > button ( ) & Qt : : LeftButton )
mPosition_Pressed_LMB = pEvent - > pos ( ) ;
else if ( pEvent - > button ( ) & Qt : : RightButton )
mPosition_Pressed_RMB = pEvent - > pos ( ) ;
}
void MainWindow : : mouseMoveEvent ( QMouseEvent * pEvent )
{
if ( pEvent - > buttons ( ) & Qt : : LeftButton )
{
GLfloat dx = 180 * GLfloat ( pEvent - > x ( ) - mPosition_Pressed_LMB . x ( ) ) / mGLView - > width ( ) ;
GLfloat dy = 180 * GLfloat ( pEvent - > y ( ) - mPosition_Pressed_LMB . y ( ) ) / mGLView - > height ( ) ;
if ( pEvent - > modifiers ( ) & Qt : : ShiftModifier )
mGLView - > Camera_RotateScene ( dy , 0 , dx ) ; // Rotate around oX and oZ axises.
else
mGLView - > Camera_RotateScene ( dy , dx , 0 ) ; // Rotate around oX and oY axises.
mGLView - > updateGL ( ) ;
mPosition_Pressed_LMB = pEvent - > pos ( ) ;
}
if ( pEvent - > buttons ( ) & Qt : : RightButton )
{
GLfloat dx = 180 * GLfloat ( pEvent - > x ( ) - mPosition_Pressed_RMB . x ( ) ) / mGLView - > width ( ) ;
GLfloat dy = 180 * GLfloat ( pEvent - > y ( ) - mPosition_Pressed_RMB . y ( ) ) / mGLView - > height ( ) ;
if ( pEvent - > modifiers ( ) & Qt : : ShiftModifier )
mGLView - > Camera_Rotate ( dy , 0 , dx ) ; // Rotate around oX and oZ axises.
else
mGLView - > Camera_Rotate ( dy , dx , 0 ) ; // Rotate around oX and oY axises.
mGLView - > updateGL ( ) ;
mPosition_Pressed_RMB = pEvent - > pos ( ) ;
}
}
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 ) ;
mGLView - > updateGL ( ) ;
}
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
MainWindow : : MainWindow ( QWidget * parent )
: QMainWindow ( parent ) , ui ( new Ui : : MainWindow ) ,
mScene ( nullptr )
{
using namespace Assimp ;
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 ) ;
}
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 )
{
ui - > lblRenderTime - > setText ( QString ( " %1 " ) . arg ( pPaintTime_ms ) ) ;
ui - > lblDistance - > setText ( QString ( " %1 " ) . arg ( pDistance ) ) ;
}
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 ( ) ;
}
void MainWindow : : on_butOpenFile_clicked ( )
{
aiString filter_temp ;
QString filename , filter ;
mImporter . GetExtensionList ( filter_temp ) ;
filter = filter_temp . C_Str ( ) ;
filter . replace ( ' ; ' , ' ' ) ;
filter . append ( " ;; All (*.*) " ) ;
filename = QFileDialog : : getOpenFileName ( this , " Choose the file " , " " , filter ) ;
if ( ! filename . isEmpty ( ) ) ImportFile ( filename ) ;
}
void MainWindow : : on_butExport_clicked ( )
{
using namespace Assimp ;
QString filename , filter , format_id ;
Exporter exporter ;
QTime time_begin ;
aiReturn rv ;
if ( mScene = = nullptr )
{
QMessageBox : : critical ( this , " Export error " , " Scene is empty " ) ;
return ;
}
// build filter
{
aiString filter_temp ;
mImporter . GetExtensionList ( filter_temp ) ;
filter = filter_temp . C_Str ( ) ;
filter . replace ( ' ; ' , ' ' ) ;
}
// get file path
filename = QFileDialog : : getSaveFileName ( this , " Set file name " , " " , filter ) ;
// extract format ID
format_id = filename . right ( filename . length ( ) - filename . lastIndexOf ( ' . ' ) - 1 ) ;
if ( format_id . isEmpty ( ) )
{
QMessageBox : : critical ( this , " Export error " , " File name must has extension. " ) ;
return ;
}
// begin export
time_begin = QTime : : currentTime ( ) ;
rv = exporter . Export ( mScene , format_id . toLocal8Bit ( ) , filename . toLocal8Bit ( ) ) ;
ui - > lblExportTime - > setText ( QString ( " %1 " ) . arg ( time_begin . secsTo ( QTime : : currentTime ( ) ) ) ) ;
if ( rv = = aiReturn_SUCCESS )
LogInfo ( " Export done: " + filename ) ;
else
LogError ( " Export failed: " + filename ) ;
}
void MainWindow : : on_cbxLighting_clicked ( bool pChecked )
{
if ( pChecked )
mGLView - > Lighting_Enable ( ) ;
else
mGLView - > Lighting_Disable ( ) ;
mGLView - > updateGL ( ) ;
}
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 ( ) ) ;
mGLView - > updateGL ( ) ;
}
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 ( ) ) ;
mGLView - > updateGL ( ) ;
}
void MainWindow : : on_cbxBBox_clicked ( bool checked )
{
mGLView - > Enable_SceneBBox ( checked ) ;
mGLView - > updateGL ( ) ;
}
void MainWindow : : on_cbxTextures_clicked ( bool checked )
{
mGLView - > Enable_Textures ( checked ) ;
mGLView - > updateGL ( ) ;
}