This repository has been archived on 2020-03-10. You can view files and clone it, but cannot push or open issues or pull requests.
mgm-tp2/mainwindow.cpp
2020-03-10 23:45:03 +01:00

319 lines
12 KiB
C++

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <vector>
#include <queue>
#include <map>
#include <QDebug>
void MainWindow::showParts(MyMesh* _mesh)
{
using namespace std;
map<unsigned, bool> trace;
for (auto v_it = _mesh->vertices_begin(); v_it != _mesh->vertices_end(); ++v_it) {
trace[v_it->idx()] = false;
}
queue<VertexHandle> remaining;
vector<MyMesh::Color> colors {
MyMesh::Color(0, 0, 255),
MyMesh::Color(0, 255, 0),
MyMesh::Color(0, 255, 255),
MyMesh::Color(255, 0, 0),
MyMesh::Color(255, 0, 255),
MyMesh::Color(255, 255, 0)
};
size_t i = 0;
for (auto it : trace) {
if (it.second) continue;
remaining.push(_mesh->vertex_handle(it.first));
trace[it.first] = true;
while (!remaining.empty()) {
VertexHandle vh = remaining.front();
remaining.pop();
for (auto vf_it = _mesh->vf_iter(vh); vf_it.is_valid(); ++vf_it) {
_mesh->set_color(*vf_it, colors[i % colors.size()]);
}
for (auto vv_it = _mesh->vv_iter(vh); vv_it.is_valid(); ++vv_it) {
if (trace[vv_it->idx()]) continue;
remaining.push(*vv_it);
trace[vv_it->idx()] = true;
}
}
i++;
}
}
/* **** début de la partie boutons et IHM **** */
void MainWindow::on_pushButton_clicked()
{
// on réinitialise l'affichage
resetAllColorsAndThickness(&mesh);
/* **** à compléter ! (avec la fonction showParts) **** */
showParts(&mesh);
// on affiche le nouveau maillage
displayMesh(&mesh);
}
void MainWindow::on_pushButton_chargement_clicked()
{
// fenêtre de sélection des fichiers
// QString fileName = QFileDialog::getOpenFileName(this, tr("Open Mesh"), "", tr("Mesh Files (*.obj)"));
// // chargement du fichier .obj dans la variable globale "mesh"
// OpenMesh::IO::read_mesh(mesh, fileName.toUtf8().constData());
OpenMesh::IO::read_mesh(mesh, "../meshFiles/cc.obj");
// initialisation des couleurs et épaisseurs (sommets et arêtes) du mesh
resetAllColorsAndThickness(&mesh);
// on affiche le maillage
displayMesh(&mesh);
}
/* **** fin de la partie boutons et IHM **** */
/* **** fonctions supplémentaires **** */
// permet d'initialiser les couleurs et les épaisseurs des élements du maillage
void MainWindow::resetAllColorsAndThickness(MyMesh* _mesh)
{
for (MyMesh::VertexIter curVert = _mesh->vertices_begin(); curVert != _mesh->vertices_end(); curVert++)
{
_mesh->data(*curVert).thickness = 1;
_mesh->set_color(*curVert, MyMesh::Color(0, 0, 0));
}
for (MyMesh::FaceIter curFace = _mesh->faces_begin(); curFace != _mesh->faces_end(); curFace++)
{
_mesh->set_color(*curFace, MyMesh::Color(150, 150, 150));
}
for (MyMesh::EdgeIter curEdge = _mesh->edges_begin(); curEdge != _mesh->edges_end(); curEdge++)
{
_mesh->data(*curEdge).thickness = 1;
_mesh->set_color(*curEdge, MyMesh::Color(0, 0, 0));
}
}
// charge un objet MyMesh dans l'environnement OpenGL
void MainWindow::displayMesh(MyMesh* _mesh, DisplayMode mode)
{
GLuint* triIndiceArray = new GLuint[_mesh->n_faces() * 3];
GLfloat* triCols = new GLfloat[_mesh->n_faces() * 3 * 3];
GLfloat* triVerts = new GLfloat[_mesh->n_faces() * 3 * 3];
int i = 0;
if(mode == DisplayMode::TemperatureMap)
{
QVector<float> values;
for (MyMesh::VertexIter curVert = _mesh->vertices_begin(); curVert != _mesh->vertices_end(); curVert++)
values.append(fabs(_mesh->data(*curVert).value));
std::sort(values.begin(), values.end());
float range = values.at(values.size()*0.8);
MyMesh::ConstFaceIter fIt(_mesh->faces_begin()), fEnd(_mesh->faces_end());
MyMesh::ConstFaceVertexIter fvIt;
for (; fIt!=fEnd; ++fIt)
{
fvIt = _mesh->cfv_iter(*fIt);
if(_mesh->data(*fvIt).value > 0){triCols[3*i+0] = 255; triCols[3*i+1] = 255 - std::min((_mesh->data(*fvIt).value/range) * 255.0, 255.0); triCols[3*i+2] = 255 - std::min((_mesh->data(*fvIt).value/range) * 255.0, 255.0);}
else{triCols[3*i+2] = 255; triCols[3*i+1] = 255 - std::min((-_mesh->data(*fvIt).value/range) * 255.0, 255.0); triCols[3*i+0] = 255 - std::min((-_mesh->data(*fvIt).value/range) * 255.0, 255.0);}
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++; ++fvIt;
if(_mesh->data(*fvIt).value > 0){triCols[3*i+0] = 255; triCols[3*i+1] = 255 - std::min((_mesh->data(*fvIt).value/range) * 255.0, 255.0); triCols[3*i+2] = 255 - std::min((_mesh->data(*fvIt).value/range) * 255.0, 255.0);}
else{triCols[3*i+2] = 255; triCols[3*i+1] = 255 - std::min((-_mesh->data(*fvIt).value/range) * 255.0, 255.0); triCols[3*i+0] = 255 - std::min((-_mesh->data(*fvIt).value/range) * 255.0, 255.0);}
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++; ++fvIt;
if(_mesh->data(*fvIt).value > 0){triCols[3*i+0] = 255; triCols[3*i+1] = 255 - std::min((_mesh->data(*fvIt).value/range) * 255.0, 255.0); triCols[3*i+2] = 255 - std::min((_mesh->data(*fvIt).value/range) * 255.0, 255.0);}
else{triCols[3*i+2] = 255; triCols[3*i+1] = 255 - std::min((-_mesh->data(*fvIt).value/range) * 255.0, 255.0); triCols[3*i+0] = 255 - std::min((-_mesh->data(*fvIt).value/range) * 255.0, 255.0);}
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++;
}
}
if(mode == DisplayMode::Normal)
{
MyMesh::ConstFaceIter fIt(_mesh->faces_begin()), fEnd(_mesh->faces_end());
MyMesh::ConstFaceVertexIter fvIt;
for (; fIt!=fEnd; ++fIt)
{
fvIt = _mesh->cfv_iter(*fIt);
triCols[3*i+0] = _mesh->color(*fIt)[0]; triCols[3*i+1] = _mesh->color(*fIt)[1]; triCols[3*i+2] = _mesh->color(*fIt)[2];
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++; ++fvIt;
triCols[3*i+0] = _mesh->color(*fIt)[0]; triCols[3*i+1] = _mesh->color(*fIt)[1]; triCols[3*i+2] = _mesh->color(*fIt)[2];
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++; ++fvIt;
triCols[3*i+0] = _mesh->color(*fIt)[0]; triCols[3*i+1] = _mesh->color(*fIt)[1]; triCols[3*i+2] = _mesh->color(*fIt)[2];
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++;
}
}
if(mode == DisplayMode::ColorShading)
{
MyMesh::ConstFaceIter fIt(_mesh->faces_begin()), fEnd(_mesh->faces_end());
MyMesh::ConstFaceVertexIter fvIt;
for (; fIt!=fEnd; ++fIt)
{
fvIt = _mesh->cfv_iter(*fIt);
triCols[3*i+0] = _mesh->data(*fvIt).faceShadingColor[0]; triCols[3*i+1] = _mesh->data(*fvIt).faceShadingColor[1]; triCols[3*i+2] = _mesh->data(*fvIt).faceShadingColor[2];
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++; ++fvIt;
triCols[3*i+0] = _mesh->data(*fvIt).faceShadingColor[0]; triCols[3*i+1] = _mesh->data(*fvIt).faceShadingColor[1]; triCols[3*i+2] = _mesh->data(*fvIt).faceShadingColor[2];
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++; ++fvIt;
triCols[3*i+0] = _mesh->data(*fvIt).faceShadingColor[0]; triCols[3*i+1] = _mesh->data(*fvIt).faceShadingColor[1]; triCols[3*i+2] = _mesh->data(*fvIt).faceShadingColor[2];
triVerts[3*i+0] = _mesh->point(*fvIt)[0]; triVerts[3*i+1] = _mesh->point(*fvIt)[1]; triVerts[3*i+2] = _mesh->point(*fvIt)[2];
triIndiceArray[i] = i;
i++;
}
}
ui->displayWidget->loadMesh(triVerts, triCols, _mesh->n_faces() * 3 * 3, triIndiceArray, _mesh->n_faces() * 3);
delete[] triIndiceArray;
delete[] triCols;
delete[] triVerts;
GLuint* linesIndiceArray = new GLuint[_mesh->n_edges() * 2];
GLfloat* linesCols = new GLfloat[_mesh->n_edges() * 2 * 3];
GLfloat* linesVerts = new GLfloat[_mesh->n_edges() * 2 * 3];
i = 0;
QHash<float, QList<int> > edgesIDbyThickness;
for (MyMesh::EdgeIter eit = _mesh->edges_begin(); eit != _mesh->edges_end(); ++eit)
{
float t = _mesh->data(*eit).thickness;
if(t > 0)
{
if(!edgesIDbyThickness.contains(t))
edgesIDbyThickness[t] = QList<int>();
edgesIDbyThickness[t].append((*eit).idx());
}
}
QHashIterator<float, QList<int> > it(edgesIDbyThickness);
QList<QPair<float, int> > edgeSizes;
while (it.hasNext())
{
it.next();
for(int e = 0; e < it.value().size(); e++)
{
int eidx = it.value().at(e);
MyMesh::VertexHandle vh1 = _mesh->to_vertex_handle(_mesh->halfedge_handle(_mesh->edge_handle(eidx), 0));
linesVerts[3*i+0] = _mesh->point(vh1)[0];
linesVerts[3*i+1] = _mesh->point(vh1)[1];
linesVerts[3*i+2] = _mesh->point(vh1)[2];
linesCols[3*i+0] = _mesh->color(_mesh->edge_handle(eidx))[0];
linesCols[3*i+1] = _mesh->color(_mesh->edge_handle(eidx))[1];
linesCols[3*i+2] = _mesh->color(_mesh->edge_handle(eidx))[2];
linesIndiceArray[i] = i;
i++;
MyMesh::VertexHandle vh2 = _mesh->from_vertex_handle(_mesh->halfedge_handle(_mesh->edge_handle(eidx), 0));
linesVerts[3*i+0] = _mesh->point(vh2)[0];
linesVerts[3*i+1] = _mesh->point(vh2)[1];
linesVerts[3*i+2] = _mesh->point(vh2)[2];
linesCols[3*i+0] = _mesh->color(_mesh->edge_handle(eidx))[0];
linesCols[3*i+1] = _mesh->color(_mesh->edge_handle(eidx))[1];
linesCols[3*i+2] = _mesh->color(_mesh->edge_handle(eidx))[2];
linesIndiceArray[i] = i;
i++;
}
edgeSizes.append(qMakePair(it.key(), it.value().size()));
}
ui->displayWidget->loadLines(linesVerts, linesCols, i * 3, linesIndiceArray, i, edgeSizes);
delete[] linesIndiceArray;
delete[] linesCols;
delete[] linesVerts;
GLuint* pointsIndiceArray = new GLuint[_mesh->n_vertices()];
GLfloat* pointsCols = new GLfloat[_mesh->n_vertices() * 3];
GLfloat* pointsVerts = new GLfloat[_mesh->n_vertices() * 3];
i = 0;
QHash<float, QList<int> > vertsIDbyThickness;
for (MyMesh::VertexIter vit = _mesh->vertices_begin(); vit != _mesh->vertices_end(); ++vit)
{
float t = _mesh->data(*vit).thickness;
if(t > 0)
{
if(!vertsIDbyThickness.contains(t))
vertsIDbyThickness[t] = QList<int>();
vertsIDbyThickness[t].append((*vit).idx());
}
}
QHashIterator<float, QList<int> > vitt(vertsIDbyThickness);
QList<QPair<float, int> > vertsSizes;
while (vitt.hasNext())
{
vitt.next();
for(int v = 0; v < vitt.value().size(); v++)
{
int vidx = vitt.value().at(v);
pointsVerts[3*i+0] = _mesh->point(_mesh->vertex_handle(vidx))[0];
pointsVerts[3*i+1] = _mesh->point(_mesh->vertex_handle(vidx))[1];
pointsVerts[3*i+2] = _mesh->point(_mesh->vertex_handle(vidx))[2];
pointsCols[3*i+0] = _mesh->color(_mesh->vertex_handle(vidx))[0];
pointsCols[3*i+1] = _mesh->color(_mesh->vertex_handle(vidx))[1];
pointsCols[3*i+2] = _mesh->color(_mesh->vertex_handle(vidx))[2];
pointsIndiceArray[i] = i;
i++;
}
vertsSizes.append(qMakePair(vitt.key(), vitt.value().size()));
}
ui->displayWidget->loadPoints(pointsVerts, pointsCols, i * 3, pointsIndiceArray, i, vertsSizes);
delete[] pointsIndiceArray;
delete[] pointsCols;
delete[] pointsVerts;
}
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}