From 24dabed48c1c0b9a1c6d512de5f45f0236041236 Mon Sep 17 00:00:00 2001 From: papush! Date: Sat, 27 Nov 2021 11:20:08 +0100 Subject: [PATCH] implement implicit hole filling --- src/hole_filling.cpp | 72 +++++++++++++++++++++++++++++++++++++----- src/hole_filling.h | 4 +-- src/main_window.cpp | 3 +- src/mesh_processor.cpp | 5 ++- 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/hole_filling.cpp b/src/hole_filling.cpp index df641dd..2b25405 100644 --- a/src/hole_filling.cpp +++ b/src/hole_filling.cpp @@ -179,15 +179,25 @@ pair, vector &> Hole_F B << Eigen::VectorXd::Zero(n), Eigen::VectorXd::Ones(n), -Eigen::VectorXd::Ones(n), Eigen::VectorXd::Zero(d) ; // Fill Phi matrix - // TODO + //TODO + for (int i = 0; i < 3*n; i++) { + for (int j = 0; j <= i; j++) { + Phi(i, j) = myphi((pts_list[i] - pts_list[j]).norm()); + Phi(j, i) = Phi(i, j); + } + } // Fill P matrix - //TODO + for (int i = 0; i < 3*n; i++) { + for (int j = 0; j < d; j++) { + P(i, j) = myp(j, pts_list[i]); + } + } // Set final A matrix /* A = Phi | P * P' | 0 */ - + A << Phi, P, P.transpose(), Eigen::MatrixXd::Zero(d, d); // TODO cout << "size of pts_list : " << nn << endl ; @@ -243,7 +253,7 @@ void Hole_Filling::colorize_prop() if(_mesh.property(_vprop, *v_it) == true) _mesh.set_color(*v_it, MyMesh::Color(255, 0, 0)) ; else - _mesh.set_color(*v_it, MyMesh::Color(200, 200, 200)) ; + _mesh.set_color(*v_it, MyMesh::Color(200, 200, 200)) ; } } @@ -278,7 +288,7 @@ Rect3 Hole_Filling::estimate_BB(const vector &vlist) return domain ; } -void Hole_Filling::poly_n_out(const Implicit_RBF &implicit, Rect3 domain, string filename) +Mesh Hole_Filling::poly_n_out(const Implicit_RBF &implicit, Rect3 domain, string filename) { auto implicitEq = [&implicit](Vec3 const& pos) { @@ -292,10 +302,56 @@ void Hole_Filling::poly_n_out(const Implicit_RBF &implicit, Rect3 domain, string cout << "sized" << domain.size << endl ; cout << "cubesize "<< cubeSize << endl ; - auto mesh = MarchCube(implicitEq, domain, cubeSize); - WriteObjFile(mesh, filename); + return MarchCube(implicitEq, domain, cubeSize); + // WriteObjFile(mesh, filename); } -void fillHolesImplicit(MyMesh &mesh) { +MyMesh fillHoleImplicit(MyMesh &mesh, Hole_Filling &hf, + std::vector &hole) { + std::vector verts; + for (HalfedgeHandle hh : hole) { + verts.push_back(mesh.to_vertex_handle(hh)); + } + auto [system, pts_list] = hf.compute_approx_mat(verts); + auto [alpha, beta] = hf.solve_approx(system, pts_list.size(), 10); + Implicit_RBF rbf(alpha, beta, pts_list); + + // qDebug() << ""; + // for (const Point &p : pts_list) { + // qDebug() << rbf.val(p); + // } + + auto bb = hf.estimate_BB(verts) ; + const QString path = "out.obj"; + Mesh filling = hf.poly_n_out(rbf, bb, path.toStdString()); + // MyMesh out_mesh; + // OpenMesh::IO::Options options; + // options.set(OpenMesh::IO::Options::VertexNormal); + // if (!OpenMesh::IO::read_mesh(mesh, path.toUtf8().constData(), options)) { + // qWarning() << "Failed to read" << path; + // throw runtime_error("Failed to read marching cube output mesh"); + // } + MyMesh ret; + for (const Vec3 &v : filling.vertices) { + VertexHandle vh = ret.new_vertex({v.x, v.y, v.z}); + ret.set_color(vh, ret.default_color); + } + for (const Triangle &t : filling.triangles) { + ret.add_face(ret.vertex_handle(t[0]), + ret.vertex_handle(t[1]), + ret.vertex_handle(t[2])); + } + return ret; +} + + +std::vector fillHolesImplicit(MyMesh &mesh) { + Hole_Filling hf(mesh); + mesh.holes = findHoles(mesh); + std::vector fillings; + for (auto hole : mesh.holes) { + fillings.push_back(fillHoleImplicit(mesh, hf, hole)); + } + return fillings; } diff --git a/src/hole_filling.h b/src/hole_filling.h index 8e47367..5dc76f0 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); -void fillHolesImplicit(MyMesh &mesh); +std::vector fillHolesImplicit(MyMesh &mesh); using namespace std ; using namespace MeshReconstruction; @@ -113,7 +113,7 @@ public: void colorize_prop() ; void colorize_verts(const vector &vlist) ; Rect3 estimate_BB(const vector &vlist) ; - void poly_n_out (const Implicit_RBF & implicit, Rect3 domain, std::string filename) ; + Mesh poly_n_out (const Implicit_RBF & implicit, Rect3 domain, std::string filename) ; }; // Other .... diff --git a/src/main_window.cpp b/src/main_window.cpp index 47bf221..e9faac3 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -60,7 +60,8 @@ MainWindow::MainWindow(QWidget *parent) connect(fill_holes_dumb, &QPushButton::clicked, this, &MainWindow::fillHolesDumbClicked); hole_vbox->addWidget(fill_holes_dumb); - QPushButton *fill_holes_implicit = new QPushButton("Remplir bĂȘtement"); + 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); diff --git a/src/mesh_processor.cpp b/src/mesh_processor.cpp index cec4ad4..b8bead2 100644 --- a/src/mesh_processor.cpp +++ b/src/mesh_processor.cpp @@ -60,7 +60,10 @@ void MeshProcessor::fillHolesDumb() { void MeshProcessor::fillHolesImplicit() { - ::fillHolesImplicit(mesh); + std::vector fillings = ::fillHolesImplicit(mesh); + for (MyMesh &filling : fillings) { + mesh_viewer.addMesh(filling); + } updateView(); }