123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- /// \file mainwindow.hpp
- /// \brief Main window and algorhytms.
- /// \author [email protected]
- /// \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.
- mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
- aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
- 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();
- }
- void MainWindow::on_lstCamera_clicked( const QModelIndex &)
- {
- 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();
- }
|