From a8f9e1db56b29d19264c27d0f579fc421f068eee Mon Sep 17 00:00:00 2001 From: ccolin Date: Sat, 13 Nov 2021 17:53:21 +0100 Subject: [PATCH] add vertex picking --- src/main.cpp | 9 ++++++--- src/main_window.cpp | 2 +- src/mesh_processor.cpp | 40 ++++++++++++++++++++++++++++++-------- src/mesh_processor.h | 9 ++++++++- src/mesh_viewer.cpp | 44 ++++++++++++++++++++++++++++++++++++------ src/mesh_viewer.h | 9 ++++++++- 6 files changed, 93 insertions(+), 20 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a0c9be1..fff197d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,7 +22,6 @@ int main(int argc, char *argv[]) { [&]() { if (mesh_processor) { mesh_viewer->addMesh(mesh_processor->mesh); - mesh_viewer->addMesh(mesh_processor->patch); } }); @@ -30,7 +29,9 @@ int main(int argc, char *argv[]) { qWarning("Utilisation : %s [MAILLAGE]", argv[0]); return 1; } else if (argc == 2) { - mesh_processor = new MeshProcessor(argv[1]); + mesh_processor = new MeshProcessor(argv[1], *mesh_viewer); + QObject::connect(mesh_viewer, &MeshViewer::clicked, + mesh_processor, &MeshProcessor::click); } QObject::connect(&main_window, &MainWindow::open, [&](const QString &path) { @@ -38,8 +39,10 @@ int main(int argc, char *argv[]) { mesh_viewer->removeMesh(mesh_processor->mesh); delete mesh_processor; } - mesh_processor = new MeshProcessor(path); + mesh_processor = new MeshProcessor(path, *mesh_viewer); mesh_viewer->addMesh(mesh_processor->mesh); + QObject::connect(mesh_viewer, &MeshViewer::clicked, + mesh_processor, &MeshProcessor::click); }); main_window.show(); return app.exec(); diff --git a/src/main_window.cpp b/src/main_window.cpp index ff8c68e..012e27a 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -8,7 +8,7 @@ MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), toolbar(this), - mesh_viewer(this) { + mesh_viewer() { connect(&mesh_viewer, &MeshViewer::initialized, [&]() { open_action->setEnabled(true); }); diff --git a/src/mesh_processor.cpp b/src/mesh_processor.cpp index c4a1f46..c79e0dc 100644 --- a/src/mesh_processor.cpp +++ b/src/mesh_processor.cpp @@ -26,7 +26,8 @@ static std::vector> findHoles(MyMesh &mesh) { } -MeshProcessor::MeshProcessor(const QString &path) { +MeshProcessor::MeshProcessor(const QString &path, MeshViewer &mesh_viewer) + :mesh_viewer(mesh_viewer) { OpenMesh::IO::Options options; options.set(OpenMesh::IO::Options::VertexColor); if (!OpenMesh::IO::read_mesh(mesh, path.toUtf8().constData(), options)) { @@ -34,18 +35,20 @@ MeshProcessor::MeshProcessor(const QString &path) { return; } mesh.update_normals(); - Courbures courb(mesh); - courb.compute_KH(); - courb.set_K_colors(); - VertexHandle vh = mesh.vertex_handle(16); - QuadPatch q = mesh.property(courb.vprop_quad, vh); - patch = tesselate_quad_patch(q, mesh, vh); + courbure = new Courbures(mesh); + courbure->compute_KH(); + courbure->set_K_colors(); // mesh.holes = findHoles(mesh); // fillHoles(); // smooth(mesh); } +MeshProcessor::~MeshProcessor() { + if (courbure) delete courbure; +} + + void fillHoleDumb(MyMesh &mesh, std::vector &hole) { mesh.request_vertex_status(); mesh.request_edge_status(); @@ -68,8 +71,29 @@ void fillHoleDumb(MyMesh &mesh, std::vector &hole) { } } + void MeshProcessor::fillHoles() { for (auto hole : mesh.holes) { fillHoleDumb(mesh, hole); } -} \ No newline at end of file +} + + +void MeshProcessor::click(QVector3D position) { + Eigen::Vector3d pos {position.x(), position.y(), position.z()}; + MyMesh::VertexIter it = mesh.vertices_begin(); + VertexHandle min_vert = *it; + double min_dist = (mesh.point(*it) - pos).squaredNorm(); + for (; it != mesh.vertices_end(); ++it) { + double dist = (mesh.point(*it) - pos).squaredNorm(); + if (dist < min_dist) { + min_dist = dist; + min_vert = *it; + } + } + QuadPatch q = mesh.property(courbure->vprop_quad, min_vert); + patch = tesselate_quad_patch(q, mesh, min_vert); + mesh_viewer.removeMesh(patch); + mesh_viewer.addMesh(patch); + mesh_viewer.updateForReal(); +} diff --git a/src/mesh_processor.h b/src/mesh_processor.h index dd045a8..51d43ed 100644 --- a/src/mesh_processor.h +++ b/src/mesh_processor.h @@ -2,7 +2,9 @@ #define MESH_PROCESSING_H #include "my_mesh.h" +#include "curvature.h" #include "mesh_processor_painter.h" +#include "mesh_viewer.h" #include #include @@ -10,14 +12,19 @@ class MeshProcessor : public QObject { Q_OBJECT + Courbures *courbure = nullptr; + MeshViewer &mesh_viewer; + public: MyMesh mesh; MyMesh patch; - MeshProcessor(const QString &path); + MeshProcessor(const QString &path, MeshViewer &mesh_viewer); + ~MeshProcessor(); public slots: void fillHoles(); + void click(QVector3D position); }; diff --git a/src/mesh_viewer.cpp b/src/mesh_viewer.cpp index 8662b65..6cf2a93 100644 --- a/src/mesh_viewer.cpp +++ b/src/mesh_viewer.cpp @@ -12,6 +12,11 @@ MeshViewer::MeshViewer(QWidget *parent) : QOpenGLWidget(parent) { } +void MeshViewer::updateViewMatrix() { + view = trans * rot; +} + + QSize MeshViewer::sizeHint() const { return QSize(640, 480); } @@ -64,17 +69,16 @@ void MeshViewer::initializeGL() { void MeshViewer::resizeGL(int w, int h) { - QMatrix4x4 projection; - projection.perspective(FOV, (float) w/h, .01, 100); - program.setUniformValue("proj", projection); + proj.setToIdentity(); + proj.perspective(FOV, (float) w/h, .01, 100); + program.setUniformValue("proj", proj); + update(); } void MeshViewer::paintGL() { // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); QMatrix4x4 trans; - trans.translate(0, 0, -cam_dist); - QMatrix4x4 view = trans * rot; program.bind(); program.setUniformValue("view", view); for (MeshView &m : meshes) { @@ -102,9 +106,34 @@ void MeshViewer::removeMesh(const MyMesh &mesh) { } +void MeshViewer::updateForReal() { + qDebug() << "trying to update"; + setEnabled(true); + setVisible(true); + update(); + repaint(); + makeCurrent(); + paintGL(); + doneCurrent(); +} + + void MeshViewer::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::MiddleButton) { mouse_pos = e->pos(); + } else if (e->button() == Qt::LeftButton) { + float x = e->x(); + float y = height() - e->y(); + float depth; + makeCurrent(); + QOpenGLFunctions *glf = context()->functions(); + glf->glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + doneCurrent(); + QVector3D position {x, y, depth}; + position = position.unproject(view, proj, rect()); + emit clicked(QVector3D(position)); + } else { + e->ignore(); } } @@ -121,12 +150,15 @@ void MeshViewer::mouseMoveEvent(QMouseEvent *e) { rot = rot_start; rot.rotate(delta.x() / 5., 0, 1, 0); rot.rotate(delta.y() / 5., QVector3D(1, 0, 0) * rot); + updateViewMatrix(); update(); } } void MeshViewer::wheelEvent(QWheelEvent *e) { - cam_dist -= e->angleDelta().y() / 1000. * cam_dist; + trans(2, 3) -= e->angleDelta().y() / 1000. * trans(2, 3); + trans.optimize(); + updateViewMatrix(); update(); } diff --git a/src/mesh_viewer.h b/src/mesh_viewer.h index 3c7a94f..67a41ea 100644 --- a/src/mesh_viewer.h +++ b/src/mesh_viewer.h @@ -27,9 +27,14 @@ class MeshViewer : public QOpenGLWidget { std::list meshes; QOpenGLShaderProgram program; QMatrix4x4 proj; + QMatrix4x4 trans = QMatrix4x4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, -1, + 0, 0, 0, 1); QMatrix4x4 rot, rot_start; - GLfloat cam_dist = 1; + QMatrix4x4 view = trans * rot; QPoint mouse_pos; + void updateViewMatrix(); public: MeshViewer(QWidget *parent=nullptr); @@ -41,6 +46,7 @@ public: public slots: void addMesh(const MyMesh &mesh); void removeMesh(const MyMesh &mesh); + void updateForReal(); protected: virtual void mousePressEvent(QMouseEvent *e); @@ -50,6 +56,7 @@ protected: signals: void initialized(); + void clicked(QVector3D position); };