From 831931e8dc3dad8f70ff003fbf99fadbf936de50 Mon Sep 17 00:00:00 2001 From: papush! Date: Sat, 27 Nov 2021 15:28:47 +0100 Subject: [PATCH] add ui controls to the implicit hole filling --- src/hole_filling.cpp | 10 +++-- src/hole_filling.h | 8 ++-- src/main.cpp | 4 ++ src/main_window.cpp | 83 +++++++++++++++++++++++++++++++++++++----- src/main_window.h | 2 + src/mesh_processor.cpp | 15 +++++++- src/mesh_processor.h | 4 ++ 7 files changed, 108 insertions(+), 18 deletions(-) diff --git a/src/hole_filling.cpp b/src/hole_filling.cpp index 2b25405..9878849 100644 --- a/src/hole_filling.cpp +++ b/src/hole_filling.cpp @@ -86,7 +86,10 @@ float Implicit_RBF::val(MyMesh::Point X) const /* ************** Hole Filling ************** */ -Hole_Filling::Hole_Filling(MyMesh &mesh) : _mesh(mesh) +Hole_Filling::Hole_Filling(MyMesh &mesh, float scale, float discr) + : _mesh(mesh), + _scale(scale), + _discr(discr) { _mesh.add_property(_vprop, "vprop_flag"); cout << "Starting hole filling ..." << endl ; @@ -346,8 +349,9 @@ MyMesh fillHoleImplicit(MyMesh &mesh, Hole_Filling &hf, } -std::vector fillHolesImplicit(MyMesh &mesh) { - Hole_Filling hf(mesh); +std::vector fillHolesImplicit(MyMesh &mesh, + float scale, float discr) { + Hole_Filling hf(mesh, scale, discr); mesh.holes = findHoles(mesh); std::vector fillings; for (auto hole : mesh.holes) { diff --git a/src/hole_filling.h b/src/hole_filling.h index 5dc76f0..700cc3c 100644 --- a/src/hole_filling.h +++ b/src/hole_filling.h @@ -14,7 +14,7 @@ void fillHoleDumb(MyMesh &mesh, std::vector &hole); void fillHolesDumb(MyMesh &mesh); -std::vector fillHolesImplicit(MyMesh &mesh); +std::vector fillHolesImplicit(MyMesh &mesh, float scale, float discr); using namespace std ; using namespace MeshReconstruction; @@ -90,10 +90,10 @@ private: // Constantes servant au rendu // TODO : à mettre dans des boutons ... - const float _scale = 4 ; // Boîte englobante de rendu = _scale * BB des centres - const float _discr = 1./40. ; // BB discrétisée en 1/_discr voxels + const float _scale; // Boîte englobante de rendu = _scale * BB des centres + const float _discr; // BB discrétisée en 1/_discr voxels public: - Hole_Filling(MyMesh &mesh); + Hole_Filling(MyMesh &mesh, float scale, float discr); inline ~Hole_Filling() { std::cout << "Ending hole filling" << std::endl ; } // Computation of boundary and its neighborhood diff --git a/src/main.cpp b/src/main.cpp index fc77854..65c1689 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,10 @@ static MeshProcessor *create_mesh_processor(const QString &path, mesh_processor, &MeshProcessor::smooth); QObject::connect(&main_window, &MainWindow::patchViewToggled, mesh_processor, &MeshProcessor::setPatchView); + QObject::connect(&main_window, &MainWindow::fillHolesImplicitScaleChanged, + mesh_processor, &MeshProcessor::setImplicitHoleFillingScale); + QObject::connect(&main_window, &MainWindow::fillHolesImplicitDiscrChanged, + mesh_processor, &MeshProcessor::setImplicitHoleFillingDiscr); return mesh_processor; } diff --git a/src/main_window.cpp b/src/main_window.cpp index e9faac3..b60148e 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include MainWindow::MainWindow(QWidget *parent) @@ -54,38 +57,98 @@ MainWindow::MainWindow(QWidget *parent) // Hole filling tools QGroupBox *hole_box = new QGroupBox("Remplissage de trous"); - QLayout *hole_vbox = new QVBoxLayout(); - hole_box->setLayout(hole_vbox); + QGridLayout *hole_layout = new QGridLayout(); + hole_box->setLayout(hole_layout); + QPushButton *fill_holes_dumb = new QPushButton("Remplir bêtement"); connect(fill_holes_dumb, &QPushButton::clicked, this, &MainWindow::fillHolesDumbClicked); - hole_vbox->addWidget(fill_holes_dumb); + hole_layout->addWidget(fill_holes_dumb, 0, 0); + QPushButton *fill_holes_implicit = new QPushButton("Remplir par une surface implicite"); connect(fill_holes_implicit, &QPushButton::clicked, this, &MainWindow::fillHolesImplicitClicked); - hole_vbox->addWidget(fill_holes_implicit); + hole_layout->addWidget(fill_holes_implicit, 1, 0); + + const double implicit_scale_min = 0; + const double implicit_scale_max = 10; + QLabel *implicit_scale_text = + new QLabel("Échelle du remplissage implicite", this); + hole_layout->addWidget(implicit_scale_text, 2, 0); + QDoubleSpinBox *implicit_scale_sb = new QDoubleSpinBox(this); + implicit_scale_sb->setMinimum(implicit_scale_min); + implicit_scale_sb->setMaximum(implicit_scale_max); + hole_layout->addWidget(implicit_scale_sb, 3, 0); + QSlider *implicit_scale = new QSlider(Qt::Horizontal, this); + connect(implicit_scale, &QSlider::valueChanged, + [=](int v) { + double val = v / 100. * (implicit_scale_max + - implicit_scale_min) + + implicit_scale_min; + fillHolesImplicitScaleChanged(val); + if (val != implicit_scale_sb->value()) { + implicit_scale_sb->setValue(val); + } + }); + connect(implicit_scale_sb, QOverload::of(&QDoubleSpinBox::valueChanged), + [=](double v) { + if (v != implicit_scale_sb->value()) { + implicit_scale->setValue(v); + } + }); + hole_layout->addWidget(implicit_scale, 3, 1); + + const double implicit_discr_min = 0; + const double implicit_discr_max = .1; + QLabel *implicit_discr_text = + new QLabel("Taux de discrétisation du remplissage implicite", this); + hole_layout->addWidget(implicit_discr_text, 4, 0); + QDoubleSpinBox *implicit_discr_sb = new QDoubleSpinBox(this); + implicit_discr_sb->setMinimum(implicit_discr_min); + implicit_discr_sb->setMaximum(implicit_discr_max); + hole_layout->addWidget(implicit_discr_sb, 5, 0); + QSlider *implicit_discr = new QSlider(Qt::Horizontal, this); + connect(implicit_discr, &QSlider::valueChanged, + [=](int v) { + double val = v / 100. * (implicit_discr_max + - implicit_discr_min) + + implicit_discr_min; + fillHolesImplicitDiscrChanged(val); + if (val != implicit_discr_sb->value()) { + implicit_discr_sb->setValue(val); + } + }); + connect(implicit_discr_sb, QOverload::of(&QDoubleSpinBox::valueChanged), + [=](double v) { + if (v != implicit_discr_sb->value()) { + implicit_discr->setValue(v); + } + }); + hole_layout->addWidget(implicit_discr, 5, 1); toolbar.addWidget(hole_box); + // Smoothing tools QGroupBox *smooth_box = new QGroupBox("Adoucissement"); - QLayout *smooth_vbox = new QVBoxLayout(); - smooth_box->setLayout(smooth_vbox); + QLayout *smooth_layout = new QVBoxLayout(); + smooth_box->setLayout(smooth_layout); QPushButton *smooth = new QPushButton("Adoucir"); connect(smooth, &QPushButton::clicked, this, &MainWindow::smoothClicked); - smooth_vbox->addWidget(smooth); + smooth_layout->addWidget(smooth); toolbar.addWidget(smooth_box); + // Curvature tools QGroupBox *curvature_box = new QGroupBox("Analyse de courbure"); - QLayout *curvature_vbox = new QVBoxLayout(); - curvature_box->setLayout(curvature_vbox); + QLayout *curvature_layout = new QVBoxLayout(); + curvature_box->setLayout(curvature_layout); QPushButton *patch_mode = new QPushButton( "Afficher le patch de la sélection"); patch_mode->setCheckable(true); connect(patch_mode, &QPushButton::toggled, this, &MainWindow::patchViewToggled); - curvature_vbox->addWidget(patch_mode); + curvature_layout->addWidget(patch_mode); toolbar.addWidget(curvature_box); } diff --git a/src/main_window.h b/src/main_window.h index 76832de..c6e3a82 100644 --- a/src/main_window.h +++ b/src/main_window.h @@ -21,6 +21,8 @@ signals: void save(const QString &path); void fillHolesDumbClicked(); void fillHolesImplicitClicked(); + void fillHolesImplicitScaleChanged(float value); + void fillHolesImplicitDiscrChanged(float value); void smoothClicked(); void patchViewToggled(bool checked); diff --git a/src/mesh_processor.cpp b/src/mesh_processor.cpp index b8bead2..0cc40a3 100644 --- a/src/mesh_processor.cpp +++ b/src/mesh_processor.cpp @@ -60,7 +60,10 @@ void MeshProcessor::fillHolesDumb() { void MeshProcessor::fillHolesImplicit() { - std::vector fillings = ::fillHolesImplicit(mesh); + std::vector fillings = + ::fillHolesImplicit(mesh, + implicit_hole_filling_scale, + implicit_hole_filling_discr); for (MyMesh &filling : fillings) { mesh_viewer.addMesh(filling); } @@ -68,6 +71,16 @@ void MeshProcessor::fillHolesImplicit() { } +void MeshProcessor::setImplicitHoleFillingScale(float scale) { + implicit_hole_filling_scale = scale; +} + + +void MeshProcessor::setImplicitHoleFillingDiscr(float discr) { + implicit_hole_filling_discr = discr; +} + + void MeshProcessor::smooth() { ::smooth(mesh); updateView(); diff --git a/src/mesh_processor.h b/src/mesh_processor.h index 06c07e1..0250081 100644 --- a/src/mesh_processor.h +++ b/src/mesh_processor.h @@ -14,6 +14,8 @@ class MeshProcessor : public QObject { Courbures *courbure = nullptr; MeshViewer &mesh_viewer; bool view_patches = false; + float implicit_hole_filling_scale = 4; + float implicit_hole_filling_discr = 1./40; void updateView() const; @@ -27,6 +29,8 @@ public: public slots: void fillHolesDumb(); void fillHolesImplicit(); + void setImplicitHoleFillingScale(float scale); + void setImplicitHoleFillingDiscr(float discr); void smooth(); void setPatchView(bool on); void click(QVector3D position);